xref: /openbmc/linux/net/xfrm/xfrm_algo.c (revision b34e08d5)
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 aead_entries(void)
565 {
566 	return ARRAY_SIZE(aead_list);
567 }
568 
569 static inline int aalg_entries(void)
570 {
571 	return ARRAY_SIZE(aalg_list);
572 }
573 
574 static inline int ealg_entries(void)
575 {
576 	return ARRAY_SIZE(ealg_list);
577 }
578 
579 static inline int calg_entries(void)
580 {
581 	return ARRAY_SIZE(calg_list);
582 }
583 
584 struct xfrm_algo_list {
585 	struct xfrm_algo_desc *algs;
586 	int entries;
587 	u32 type;
588 	u32 mask;
589 };
590 
591 static const struct xfrm_algo_list xfrm_aead_list = {
592 	.algs = aead_list,
593 	.entries = ARRAY_SIZE(aead_list),
594 	.type = CRYPTO_ALG_TYPE_AEAD,
595 	.mask = CRYPTO_ALG_TYPE_MASK,
596 };
597 
598 static const struct xfrm_algo_list xfrm_aalg_list = {
599 	.algs = aalg_list,
600 	.entries = ARRAY_SIZE(aalg_list),
601 	.type = CRYPTO_ALG_TYPE_HASH,
602 	.mask = CRYPTO_ALG_TYPE_HASH_MASK,
603 };
604 
605 static const struct xfrm_algo_list xfrm_ealg_list = {
606 	.algs = ealg_list,
607 	.entries = ARRAY_SIZE(ealg_list),
608 	.type = CRYPTO_ALG_TYPE_BLKCIPHER,
609 	.mask = CRYPTO_ALG_TYPE_BLKCIPHER_MASK,
610 };
611 
612 static const struct xfrm_algo_list xfrm_calg_list = {
613 	.algs = calg_list,
614 	.entries = ARRAY_SIZE(calg_list),
615 	.type = CRYPTO_ALG_TYPE_COMPRESS,
616 	.mask = CRYPTO_ALG_TYPE_MASK,
617 };
618 
619 static struct xfrm_algo_desc *xfrm_find_algo(
620 	const struct xfrm_algo_list *algo_list,
621 	int match(const struct xfrm_algo_desc *entry, const void *data),
622 	const void *data, int probe)
623 {
624 	struct xfrm_algo_desc *list = algo_list->algs;
625 	int i, status;
626 
627 	for (i = 0; i < algo_list->entries; i++) {
628 		if (!match(list + i, data))
629 			continue;
630 
631 		if (list[i].available)
632 			return &list[i];
633 
634 		if (!probe)
635 			break;
636 
637 		status = crypto_has_alg(list[i].name, algo_list->type,
638 					algo_list->mask);
639 		if (!status)
640 			break;
641 
642 		list[i].available = status;
643 		return &list[i];
644 	}
645 	return NULL;
646 }
647 
648 static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
649 			     const void *data)
650 {
651 	return entry->desc.sadb_alg_id == (unsigned long)data;
652 }
653 
654 struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
655 {
656 	return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
657 			      (void *)(unsigned long)alg_id, 1);
658 }
659 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
660 
661 struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
662 {
663 	return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
664 			      (void *)(unsigned long)alg_id, 1);
665 }
666 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
667 
668 struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
669 {
670 	return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
671 			      (void *)(unsigned long)alg_id, 1);
672 }
673 EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
674 
675 static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry,
676 			       const void *data)
677 {
678 	const char *name = data;
679 
680 	return name && (!strcmp(name, entry->name) ||
681 			(entry->compat && !strcmp(name, entry->compat)));
682 }
683 
684 struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe)
685 {
686 	return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
687 			      probe);
688 }
689 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
690 
691 struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe)
692 {
693 	return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
694 			      probe);
695 }
696 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
697 
698 struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe)
699 {
700 	return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
701 			      probe);
702 }
703 EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
704 
705 struct xfrm_aead_name {
706 	const char *name;
707 	int icvbits;
708 };
709 
710 static int xfrm_aead_name_match(const struct xfrm_algo_desc *entry,
711 				const void *data)
712 {
713 	const struct xfrm_aead_name *aead = data;
714 	const char *name = aead->name;
715 
716 	return aead->icvbits == entry->uinfo.aead.icv_truncbits && name &&
717 	       !strcmp(name, entry->name);
718 }
719 
720 struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len, int probe)
721 {
722 	struct xfrm_aead_name data = {
723 		.name = name,
724 		.icvbits = icv_len,
725 	};
726 
727 	return xfrm_find_algo(&xfrm_aead_list, xfrm_aead_name_match, &data,
728 			      probe);
729 }
730 EXPORT_SYMBOL_GPL(xfrm_aead_get_byname);
731 
732 struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
733 {
734 	if (idx >= aalg_entries())
735 		return NULL;
736 
737 	return &aalg_list[idx];
738 }
739 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
740 
741 struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx)
742 {
743 	if (idx >= ealg_entries())
744 		return NULL;
745 
746 	return &ealg_list[idx];
747 }
748 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx);
749 
750 /*
751  * Probe for the availability of crypto algorithms, and set the available
752  * flag for any algorithms found on the system.  This is typically called by
753  * pfkey during userspace SA add, update or register.
754  */
755 void xfrm_probe_algs(void)
756 {
757 	int i, status;
758 
759 	BUG_ON(in_softirq());
760 
761 	for (i = 0; i < aalg_entries(); i++) {
762 		status = crypto_has_hash(aalg_list[i].name, 0,
763 					 CRYPTO_ALG_ASYNC);
764 		if (aalg_list[i].available != status)
765 			aalg_list[i].available = status;
766 	}
767 
768 	for (i = 0; i < ealg_entries(); i++) {
769 		status = crypto_has_ablkcipher(ealg_list[i].name, 0, 0);
770 		if (ealg_list[i].available != status)
771 			ealg_list[i].available = status;
772 	}
773 
774 	for (i = 0; i < calg_entries(); i++) {
775 		status = crypto_has_comp(calg_list[i].name, 0,
776 					 CRYPTO_ALG_ASYNC);
777 		if (calg_list[i].available != status)
778 			calg_list[i].available = status;
779 	}
780 }
781 EXPORT_SYMBOL_GPL(xfrm_probe_algs);
782 
783 int xfrm_count_pfkey_auth_supported(void)
784 {
785 	int i, n;
786 
787 	for (i = 0, n = 0; i < aalg_entries(); i++)
788 		if (aalg_list[i].available && aalg_list[i].pfkey_supported)
789 			n++;
790 	return n;
791 }
792 EXPORT_SYMBOL_GPL(xfrm_count_pfkey_auth_supported);
793 
794 int xfrm_count_pfkey_enc_supported(void)
795 {
796 	int i, n;
797 
798 	for (i = 0, n = 0; i < ealg_entries(); i++)
799 		if (ealg_list[i].available && ealg_list[i].pfkey_supported)
800 			n++;
801 	return n;
802 }
803 EXPORT_SYMBOL_GPL(xfrm_count_pfkey_enc_supported);
804 
805 MODULE_LICENSE("GPL");
806