1/*
2 * xfrm algorithm interface
3 *
4 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/pfkeyv2.h>
15#include <linux/crypto.h>
16#include <linux/scatterlist.h>
17#include <net/xfrm.h>
18#if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE)
19#include <net/esp.h>
20#endif
21
22/*
23 * Algorithms supported by IPsec.  These entries contain properties which
24 * are used in key negotiation and xfrm processing, and are used to verify
25 * that instantiated crypto transforms have correct parameters for IPsec
26 * purposes.
27 */
28static struct xfrm_algo_desc aead_list[] = {
29{
30	.name = "rfc4106(gcm(aes))",
31
32	.uinfo = {
33		.aead = {
34			.geniv = "seqiv",
35			.icv_truncbits = 64,
36		}
37	},
38
39	.pfkey_supported = 1,
40
41	.desc = {
42		.sadb_alg_id = SADB_X_EALG_AES_GCM_ICV8,
43		.sadb_alg_ivlen = 8,
44		.sadb_alg_minbits = 128,
45		.sadb_alg_maxbits = 256
46	}
47},
48{
49	.name = "rfc4106(gcm(aes))",
50
51	.uinfo = {
52		.aead = {
53			.geniv = "seqiv",
54			.icv_truncbits = 96,
55		}
56	},
57
58	.pfkey_supported = 1,
59
60	.desc = {
61		.sadb_alg_id = SADB_X_EALG_AES_GCM_ICV12,
62		.sadb_alg_ivlen = 8,
63		.sadb_alg_minbits = 128,
64		.sadb_alg_maxbits = 256
65	}
66},
67{
68	.name = "rfc4106(gcm(aes))",
69
70	.uinfo = {
71		.aead = {
72			.geniv = "seqiv",
73			.icv_truncbits = 128,
74		}
75	},
76
77	.pfkey_supported = 1,
78
79	.desc = {
80		.sadb_alg_id = SADB_X_EALG_AES_GCM_ICV16,
81		.sadb_alg_ivlen = 8,
82		.sadb_alg_minbits = 128,
83		.sadb_alg_maxbits = 256
84	}
85},
86{
87	.name = "rfc4309(ccm(aes))",
88
89	.uinfo = {
90		.aead = {
91			.geniv = "seqiv",
92			.icv_truncbits = 64,
93		}
94	},
95
96	.pfkey_supported = 1,
97
98	.desc = {
99		.sadb_alg_id = SADB_X_EALG_AES_CCM_ICV8,
100		.sadb_alg_ivlen = 8,
101		.sadb_alg_minbits = 128,
102		.sadb_alg_maxbits = 256
103	}
104},
105{
106	.name = "rfc4309(ccm(aes))",
107
108	.uinfo = {
109		.aead = {
110			.geniv = "seqiv",
111			.icv_truncbits = 96,
112		}
113	},
114
115	.pfkey_supported = 1,
116
117	.desc = {
118		.sadb_alg_id = SADB_X_EALG_AES_CCM_ICV12,
119		.sadb_alg_ivlen = 8,
120		.sadb_alg_minbits = 128,
121		.sadb_alg_maxbits = 256
122	}
123},
124{
125	.name = "rfc4309(ccm(aes))",
126
127	.uinfo = {
128		.aead = {
129			.geniv = "seqiv",
130			.icv_truncbits = 128,
131		}
132	},
133
134	.pfkey_supported = 1,
135
136	.desc = {
137		.sadb_alg_id = SADB_X_EALG_AES_CCM_ICV16,
138		.sadb_alg_ivlen = 8,
139		.sadb_alg_minbits = 128,
140		.sadb_alg_maxbits = 256
141	}
142},
143{
144	.name = "rfc4543(gcm(aes))",
145
146	.uinfo = {
147		.aead = {
148			.geniv = "seqiv",
149			.icv_truncbits = 128,
150		}
151	},
152
153	.pfkey_supported = 1,
154
155	.desc = {
156		.sadb_alg_id = SADB_X_EALG_NULL_AES_GMAC,
157		.sadb_alg_ivlen = 8,
158		.sadb_alg_minbits = 128,
159		.sadb_alg_maxbits = 256
160	}
161},
162{
163	.name = "rfc7539esp(chacha20,poly1305)",
164
165	.uinfo = {
166		.aead = {
167			.geniv = "seqiv",
168			.icv_truncbits = 128,
169		}
170	},
171
172	.pfkey_supported = 0,
173},
174};
175
176static struct xfrm_algo_desc aalg_list[] = {
177{
178	.name = "digest_null",
179
180	.uinfo = {
181		.auth = {
182			.icv_truncbits = 0,
183			.icv_fullbits = 0,
184		}
185	},
186
187	.pfkey_supported = 1,
188
189	.desc = {
190		.sadb_alg_id = SADB_X_AALG_NULL,
191		.sadb_alg_ivlen = 0,
192		.sadb_alg_minbits = 0,
193		.sadb_alg_maxbits = 0
194	}
195},
196{
197	.name = "hmac(md5)",
198	.compat = "md5",
199
200	.uinfo = {
201		.auth = {
202			.icv_truncbits = 96,
203			.icv_fullbits = 128,
204		}
205	},
206
207	.pfkey_supported = 1,
208
209	.desc = {
210		.sadb_alg_id = SADB_AALG_MD5HMAC,
211		.sadb_alg_ivlen = 0,
212		.sadb_alg_minbits = 128,
213		.sadb_alg_maxbits = 128
214	}
215},
216{
217	.name = "hmac(sha1)",
218	.compat = "sha1",
219
220	.uinfo = {
221		.auth = {
222			.icv_truncbits = 96,
223			.icv_fullbits = 160,
224		}
225	},
226
227	.pfkey_supported = 1,
228
229	.desc = {
230		.sadb_alg_id = SADB_AALG_SHA1HMAC,
231		.sadb_alg_ivlen = 0,
232		.sadb_alg_minbits = 160,
233		.sadb_alg_maxbits = 160
234	}
235},
236{
237	.name = "hmac(sha256)",
238	.compat = "sha256",
239
240	.uinfo = {
241		.auth = {
242			.icv_truncbits = 96,
243			.icv_fullbits = 256,
244		}
245	},
246
247	.pfkey_supported = 1,
248
249	.desc = {
250		.sadb_alg_id = SADB_X_AALG_SHA2_256HMAC,
251		.sadb_alg_ivlen = 0,
252		.sadb_alg_minbits = 256,
253		.sadb_alg_maxbits = 256
254	}
255},
256{
257	.name = "hmac(sha384)",
258
259	.uinfo = {
260		.auth = {
261			.icv_truncbits = 192,
262			.icv_fullbits = 384,
263		}
264	},
265
266	.pfkey_supported = 1,
267
268	.desc = {
269		.sadb_alg_id = SADB_X_AALG_SHA2_384HMAC,
270		.sadb_alg_ivlen = 0,
271		.sadb_alg_minbits = 384,
272		.sadb_alg_maxbits = 384
273	}
274},
275{
276	.name = "hmac(sha512)",
277
278	.uinfo = {
279		.auth = {
280			.icv_truncbits = 256,
281			.icv_fullbits = 512,
282		}
283	},
284
285	.pfkey_supported = 1,
286
287	.desc = {
288		.sadb_alg_id = SADB_X_AALG_SHA2_512HMAC,
289		.sadb_alg_ivlen = 0,
290		.sadb_alg_minbits = 512,
291		.sadb_alg_maxbits = 512
292	}
293},
294{
295	.name = "hmac(rmd160)",
296	.compat = "rmd160",
297
298	.uinfo = {
299		.auth = {
300			.icv_truncbits = 96,
301			.icv_fullbits = 160,
302		}
303	},
304
305	.pfkey_supported = 1,
306
307	.desc = {
308		.sadb_alg_id = SADB_X_AALG_RIPEMD160HMAC,
309		.sadb_alg_ivlen = 0,
310		.sadb_alg_minbits = 160,
311		.sadb_alg_maxbits = 160
312	}
313},
314{
315	.name = "xcbc(aes)",
316
317	.uinfo = {
318		.auth = {
319			.icv_truncbits = 96,
320			.icv_fullbits = 128,
321		}
322	},
323
324	.pfkey_supported = 1,
325
326	.desc = {
327		.sadb_alg_id = SADB_X_AALG_AES_XCBC_MAC,
328		.sadb_alg_ivlen = 0,
329		.sadb_alg_minbits = 128,
330		.sadb_alg_maxbits = 128
331	}
332},
333{
334	/* rfc4494 */
335	.name = "cmac(aes)",
336
337	.uinfo = {
338		.auth = {
339			.icv_truncbits = 96,
340			.icv_fullbits = 128,
341		}
342	},
343
344	.pfkey_supported = 0,
345},
346};
347
348static struct xfrm_algo_desc ealg_list[] = {
349{
350	.name = "ecb(cipher_null)",
351	.compat = "cipher_null",
352
353	.uinfo = {
354		.encr = {
355			.blockbits = 8,
356			.defkeybits = 0,
357		}
358	},
359
360	.pfkey_supported = 1,
361
362	.desc = {
363		.sadb_alg_id =	SADB_EALG_NULL,
364		.sadb_alg_ivlen = 0,
365		.sadb_alg_minbits = 0,
366		.sadb_alg_maxbits = 0
367	}
368},
369{
370	.name = "cbc(des)",
371	.compat = "des",
372
373	.uinfo = {
374		.encr = {
375			.geniv = "echainiv",
376			.blockbits = 64,
377			.defkeybits = 64,
378		}
379	},
380
381	.pfkey_supported = 1,
382
383	.desc = {
384		.sadb_alg_id = SADB_EALG_DESCBC,
385		.sadb_alg_ivlen = 8,
386		.sadb_alg_minbits = 64,
387		.sadb_alg_maxbits = 64
388	}
389},
390{
391	.name = "cbc(des3_ede)",
392	.compat = "des3_ede",
393
394	.uinfo = {
395		.encr = {
396			.geniv = "echainiv",
397			.blockbits = 64,
398			.defkeybits = 192,
399		}
400	},
401
402	.pfkey_supported = 1,
403
404	.desc = {
405		.sadb_alg_id = SADB_EALG_3DESCBC,
406		.sadb_alg_ivlen = 8,
407		.sadb_alg_minbits = 192,
408		.sadb_alg_maxbits = 192
409	}
410},
411{
412	.name = "cbc(cast5)",
413	.compat = "cast5",
414
415	.uinfo = {
416		.encr = {
417			.geniv = "echainiv",
418			.blockbits = 64,
419			.defkeybits = 128,
420		}
421	},
422
423	.pfkey_supported = 1,
424
425	.desc = {
426		.sadb_alg_id = SADB_X_EALG_CASTCBC,
427		.sadb_alg_ivlen = 8,
428		.sadb_alg_minbits = 40,
429		.sadb_alg_maxbits = 128
430	}
431},
432{
433	.name = "cbc(blowfish)",
434	.compat = "blowfish",
435
436	.uinfo = {
437		.encr = {
438			.geniv = "echainiv",
439			.blockbits = 64,
440			.defkeybits = 128,
441		}
442	},
443
444	.pfkey_supported = 1,
445
446	.desc = {
447		.sadb_alg_id = SADB_X_EALG_BLOWFISHCBC,
448		.sadb_alg_ivlen = 8,
449		.sadb_alg_minbits = 40,
450		.sadb_alg_maxbits = 448
451	}
452},
453{
454	.name = "cbc(aes)",
455	.compat = "aes",
456
457	.uinfo = {
458		.encr = {
459			.geniv = "echainiv",
460			.blockbits = 128,
461			.defkeybits = 128,
462		}
463	},
464
465	.pfkey_supported = 1,
466
467	.desc = {
468		.sadb_alg_id = SADB_X_EALG_AESCBC,
469		.sadb_alg_ivlen = 8,
470		.sadb_alg_minbits = 128,
471		.sadb_alg_maxbits = 256
472	}
473},
474{
475	.name = "cbc(serpent)",
476	.compat = "serpent",
477
478	.uinfo = {
479		.encr = {
480			.geniv = "echainiv",
481			.blockbits = 128,
482			.defkeybits = 128,
483		}
484	},
485
486	.pfkey_supported = 1,
487
488	.desc = {
489		.sadb_alg_id = SADB_X_EALG_SERPENTCBC,
490		.sadb_alg_ivlen = 8,
491		.sadb_alg_minbits = 128,
492		.sadb_alg_maxbits = 256,
493	}
494},
495{
496	.name = "cbc(camellia)",
497	.compat = "camellia",
498
499	.uinfo = {
500		.encr = {
501			.geniv = "echainiv",
502			.blockbits = 128,
503			.defkeybits = 128,
504		}
505	},
506
507	.pfkey_supported = 1,
508
509	.desc = {
510		.sadb_alg_id = SADB_X_EALG_CAMELLIACBC,
511		.sadb_alg_ivlen = 8,
512		.sadb_alg_minbits = 128,
513		.sadb_alg_maxbits = 256
514	}
515},
516{
517	.name = "cbc(twofish)",
518	.compat = "twofish",
519
520	.uinfo = {
521		.encr = {
522			.geniv = "echainiv",
523			.blockbits = 128,
524			.defkeybits = 128,
525		}
526	},
527
528	.pfkey_supported = 1,
529
530	.desc = {
531		.sadb_alg_id = SADB_X_EALG_TWOFISHCBC,
532		.sadb_alg_ivlen = 8,
533		.sadb_alg_minbits = 128,
534		.sadb_alg_maxbits = 256
535	}
536},
537{
538	.name = "rfc3686(ctr(aes))",
539
540	.uinfo = {
541		.encr = {
542			.geniv = "seqiv",
543			.blockbits = 128,
544			.defkeybits = 160, /* 128-bit key + 32-bit nonce */
545		}
546	},
547
548	.pfkey_supported = 1,
549
550	.desc = {
551		.sadb_alg_id = SADB_X_EALG_AESCTR,
552		.sadb_alg_ivlen	= 8,
553		.sadb_alg_minbits = 160,
554		.sadb_alg_maxbits = 288
555	}
556},
557};
558
559static struct xfrm_algo_desc calg_list[] = {
560{
561	.name = "deflate",
562	.uinfo = {
563		.comp = {
564			.threshold = 90,
565		}
566	},
567	.pfkey_supported = 1,
568	.desc = { .sadb_alg_id = SADB_X_CALG_DEFLATE }
569},
570{
571	.name = "lzs",
572	.uinfo = {
573		.comp = {
574			.threshold = 90,
575		}
576	},
577	.pfkey_supported = 1,
578	.desc = { .sadb_alg_id = SADB_X_CALG_LZS }
579},
580{
581	.name = "lzjh",
582	.uinfo = {
583		.comp = {
584			.threshold = 50,
585		}
586	},
587	.pfkey_supported = 1,
588	.desc = { .sadb_alg_id = SADB_X_CALG_LZJH }
589},
590};
591
592static inline int aalg_entries(void)
593{
594	return ARRAY_SIZE(aalg_list);
595}
596
597static inline int ealg_entries(void)
598{
599	return ARRAY_SIZE(ealg_list);
600}
601
602static inline int calg_entries(void)
603{
604	return ARRAY_SIZE(calg_list);
605}
606
607struct xfrm_algo_list {
608	struct xfrm_algo_desc *algs;
609	int entries;
610	u32 type;
611	u32 mask;
612};
613
614static const struct xfrm_algo_list xfrm_aead_list = {
615	.algs = aead_list,
616	.entries = ARRAY_SIZE(aead_list),
617	.type = CRYPTO_ALG_TYPE_AEAD,
618	.mask = CRYPTO_ALG_TYPE_MASK,
619};
620
621static const struct xfrm_algo_list xfrm_aalg_list = {
622	.algs = aalg_list,
623	.entries = ARRAY_SIZE(aalg_list),
624	.type = CRYPTO_ALG_TYPE_HASH,
625	.mask = CRYPTO_ALG_TYPE_HASH_MASK,
626};
627
628static const struct xfrm_algo_list xfrm_ealg_list = {
629	.algs = ealg_list,
630	.entries = ARRAY_SIZE(ealg_list),
631	.type = CRYPTO_ALG_TYPE_BLKCIPHER,
632	.mask = CRYPTO_ALG_TYPE_BLKCIPHER_MASK,
633};
634
635static const struct xfrm_algo_list xfrm_calg_list = {
636	.algs = calg_list,
637	.entries = ARRAY_SIZE(calg_list),
638	.type = CRYPTO_ALG_TYPE_COMPRESS,
639	.mask = CRYPTO_ALG_TYPE_MASK,
640};
641
642static struct xfrm_algo_desc *xfrm_find_algo(
643	const struct xfrm_algo_list *algo_list,
644	int match(const struct xfrm_algo_desc *entry, const void *data),
645	const void *data, int probe)
646{
647	struct xfrm_algo_desc *list = algo_list->algs;
648	int i, status;
649
650	for (i = 0; i < algo_list->entries; i++) {
651		if (!match(list + i, data))
652			continue;
653
654		if (list[i].available)
655			return &list[i];
656
657		if (!probe)
658			break;
659
660		status = crypto_has_alg(list[i].name, algo_list->type,
661					algo_list->mask);
662		if (!status)
663			break;
664
665		list[i].available = status;
666		return &list[i];
667	}
668	return NULL;
669}
670
671static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
672			     const void *data)
673{
674	return entry->desc.sadb_alg_id == (unsigned long)data;
675}
676
677struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
678{
679	return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
680			      (void *)(unsigned long)alg_id, 1);
681}
682EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
683
684struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
685{
686	return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
687			      (void *)(unsigned long)alg_id, 1);
688}
689EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
690
691struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
692{
693	return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
694			      (void *)(unsigned long)alg_id, 1);
695}
696EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
697
698static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry,
699			       const void *data)
700{
701	const char *name = data;
702
703	return name && (!strcmp(name, entry->name) ||
704			(entry->compat && !strcmp(name, entry->compat)));
705}
706
707struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe)
708{
709	return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
710			      probe);
711}
712EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
713
714struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe)
715{
716	return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
717			      probe);
718}
719EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
720
721struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe)
722{
723	return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
724			      probe);
725}
726EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
727
728struct xfrm_aead_name {
729	const char *name;
730	int icvbits;
731};
732
733static int xfrm_aead_name_match(const struct xfrm_algo_desc *entry,
734				const void *data)
735{
736	const struct xfrm_aead_name *aead = data;
737	const char *name = aead->name;
738
739	return aead->icvbits == entry->uinfo.aead.icv_truncbits && name &&
740	       !strcmp(name, entry->name);
741}
742
743struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len, int probe)
744{
745	struct xfrm_aead_name data = {
746		.name = name,
747		.icvbits = icv_len,
748	};
749
750	return xfrm_find_algo(&xfrm_aead_list, xfrm_aead_name_match, &data,
751			      probe);
752}
753EXPORT_SYMBOL_GPL(xfrm_aead_get_byname);
754
755struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
756{
757	if (idx >= aalg_entries())
758		return NULL;
759
760	return &aalg_list[idx];
761}
762EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
763
764struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx)
765{
766	if (idx >= ealg_entries())
767		return NULL;
768
769	return &ealg_list[idx];
770}
771EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx);
772
773/*
774 * Probe for the availability of crypto algorithms, and set the available
775 * flag for any algorithms found on the system.  This is typically called by
776 * pfkey during userspace SA add, update or register.
777 */
778void xfrm_probe_algs(void)
779{
780	int i, status;
781
782	BUG_ON(in_softirq());
783
784	for (i = 0; i < aalg_entries(); i++) {
785		status = crypto_has_hash(aalg_list[i].name, 0,
786					 CRYPTO_ALG_ASYNC);
787		if (aalg_list[i].available != status)
788			aalg_list[i].available = status;
789	}
790
791	for (i = 0; i < ealg_entries(); i++) {
792		status = crypto_has_ablkcipher(ealg_list[i].name, 0, 0);
793		if (ealg_list[i].available != status)
794			ealg_list[i].available = status;
795	}
796
797	for (i = 0; i < calg_entries(); i++) {
798		status = crypto_has_comp(calg_list[i].name, 0,
799					 CRYPTO_ALG_ASYNC);
800		if (calg_list[i].available != status)
801			calg_list[i].available = status;
802	}
803}
804EXPORT_SYMBOL_GPL(xfrm_probe_algs);
805
806int xfrm_count_pfkey_auth_supported(void)
807{
808	int i, n;
809
810	for (i = 0, n = 0; i < aalg_entries(); i++)
811		if (aalg_list[i].available && aalg_list[i].pfkey_supported)
812			n++;
813	return n;
814}
815EXPORT_SYMBOL_GPL(xfrm_count_pfkey_auth_supported);
816
817int xfrm_count_pfkey_enc_supported(void)
818{
819	int i, n;
820
821	for (i = 0, n = 0; i < ealg_entries(); i++)
822		if (ealg_list[i].available && ealg_list[i].pfkey_supported)
823			n++;
824	return n;
825}
826EXPORT_SYMBOL_GPL(xfrm_count_pfkey_enc_supported);
827
828MODULE_LICENSE("GPL");
829