Branch data Line data Source code
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 : : */
26 : : static 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 : :
174 : : static 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 : :
346 : : static 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 : :
557 : : static 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 : :
590 : : static inline int aalg_entries(void)
591 : : {
592 : : return ARRAY_SIZE(aalg_list);
593 : : }
594 : :
595 : : static inline int ealg_entries(void)
596 : : {
597 : : return ARRAY_SIZE(ealg_list);
598 : : }
599 : :
600 : : static inline int calg_entries(void)
601 : : {
602 : : return ARRAY_SIZE(calg_list);
603 : : }
604 : :
605 : : struct xfrm_algo_list {
606 : : struct xfrm_algo_desc *algs;
607 : : int entries;
608 : : u32 type;
609 : : u32 mask;
610 : : };
611 : :
612 : : static 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 : :
619 : : static 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 : :
626 : : static 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 : :
633 : : static 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 : :
640 : 0 : static 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 : 0 : struct xfrm_algo_desc *list = algo_list->algs;
646 : : int i, status;
647 : :
648 : 0 : for (i = 0; i < algo_list->entries; i++) {
649 : 0 : if (!match(list + i, data))
650 : 0 : continue;
651 : :
652 : 0 : if (list[i].available)
653 : 0 : return &list[i];
654 : :
655 : 0 : if (!probe)
656 : : break;
657 : :
658 : 0 : status = crypto_has_alg(list[i].name, algo_list->type,
659 : : algo_list->mask);
660 : 0 : if (!status)
661 : : break;
662 : :
663 : 0 : list[i].available = status;
664 : 0 : return &list[i];
665 : : }
666 : : return NULL;
667 : : }
668 : :
669 : 0 : static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
670 : : const void *data)
671 : : {
672 : 0 : return entry->desc.sadb_alg_id == (unsigned long)data;
673 : : }
674 : :
675 : 0 : struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
676 : : {
677 : 0 : return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
678 : : (void *)(unsigned long)alg_id, 1);
679 : : }
680 : : EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
681 : :
682 : 0 : struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
683 : : {
684 : 0 : return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
685 : : (void *)(unsigned long)alg_id, 1);
686 : : }
687 : : EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
688 : :
689 : 0 : struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
690 : : {
691 : 0 : return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
692 : : (void *)(unsigned long)alg_id, 1);
693 : : }
694 : : EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
695 : :
696 : 0 : static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry,
697 : : const void *data)
698 : : {
699 : : const char *name = data;
700 : :
701 : 0 : return name && (!strcmp(name, entry->name) ||
702 : 0 : (entry->compat && !strcmp(name, entry->compat)));
703 : : }
704 : :
705 : 0 : struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe)
706 : : {
707 : 0 : return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
708 : : probe);
709 : : }
710 : : EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
711 : :
712 : 0 : struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe)
713 : : {
714 : 0 : return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
715 : : probe);
716 : : }
717 : : EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
718 : :
719 : 0 : struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe)
720 : : {
721 : 0 : return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
722 : : probe);
723 : : }
724 : : EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
725 : :
726 : : struct xfrm_aead_name {
727 : : const char *name;
728 : : int icvbits;
729 : : };
730 : :
731 : 0 : static 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 : 0 : const char *name = aead->name;
736 : :
737 : 0 : return aead->icvbits == entry->uinfo.aead.icv_truncbits && name &&
738 : 0 : !strcmp(name, entry->name);
739 : : }
740 : :
741 : 0 : struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len, int probe)
742 : : {
743 : 0 : struct xfrm_aead_name data = {
744 : : .name = name,
745 : : .icvbits = icv_len,
746 : : };
747 : :
748 : 0 : return xfrm_find_algo(&xfrm_aead_list, xfrm_aead_name_match, &data,
749 : : probe);
750 : : }
751 : : EXPORT_SYMBOL_GPL(xfrm_aead_get_byname);
752 : :
753 : 0 : struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
754 : : {
755 : 0 : if (idx >= aalg_entries())
756 : : return NULL;
757 : :
758 : 0 : return &aalg_list[idx];
759 : : }
760 : : EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
761 : :
762 : 0 : struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx)
763 : : {
764 : 0 : if (idx >= ealg_entries())
765 : : return NULL;
766 : :
767 : 0 : return &ealg_list[idx];
768 : : }
769 : : EXPORT_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 : : */
776 : 0 : void xfrm_probe_algs(void)
777 : : {
778 : : int i, status;
779 : :
780 : 0 : BUG_ON(in_softirq());
781 : :
782 : 0 : for (i = 0; i < aalg_entries(); i++) {
783 : 0 : status = crypto_has_ahash(aalg_list[i].name, 0, 0);
784 : 0 : if (aalg_list[i].available != status)
785 : 0 : aalg_list[i].available = status;
786 : : }
787 : :
788 : 0 : for (i = 0; i < ealg_entries(); i++) {
789 : 0 : status = crypto_has_skcipher(ealg_list[i].name, 0, 0);
790 : 0 : if (ealg_list[i].available != status)
791 : 0 : ealg_list[i].available = status;
792 : : }
793 : :
794 : 0 : for (i = 0; i < calg_entries(); i++) {
795 : 0 : status = crypto_has_comp(calg_list[i].name, 0,
796 : : CRYPTO_ALG_ASYNC);
797 : 0 : if (calg_list[i].available != status)
798 : 0 : calg_list[i].available = status;
799 : : }
800 : 0 : }
801 : : EXPORT_SYMBOL_GPL(xfrm_probe_algs);
802 : :
803 : 0 : int xfrm_count_pfkey_auth_supported(void)
804 : : {
805 : : int i, n;
806 : :
807 : 0 : for (i = 0, n = 0; i < aalg_entries(); i++)
808 : 0 : if (aalg_list[i].available && aalg_list[i].pfkey_supported)
809 : 0 : n++;
810 : 0 : return n;
811 : : }
812 : : EXPORT_SYMBOL_GPL(xfrm_count_pfkey_auth_supported);
813 : :
814 : 0 : int xfrm_count_pfkey_enc_supported(void)
815 : : {
816 : : int i, n;
817 : :
818 : 0 : for (i = 0, n = 0; i < ealg_entries(); i++)
819 : 0 : if (ealg_list[i].available && ealg_list[i].pfkey_supported)
820 : 0 : n++;
821 : 0 : return n;
822 : : }
823 : : EXPORT_SYMBOL_GPL(xfrm_count_pfkey_enc_supported);
824 : :
825 : : MODULE_LICENSE("GPL");
|