Linux Audio

Check our new training course

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