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