Branch data Line data Source code
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 : 0 : 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 : 0 : struct xfrm_algo_desc *list = algo_list->algs;
625 : : int i, status;
626 : :
627 [ # # ]: 0 : for (i = 0; i < algo_list->entries; i++) {
628 [ # # ]: 0 : if (!match(list + i, data))
629 : 0 : continue;
630 : :
631 [ # # ]: 0 : if (list[i].available)
632 : : return &list[i];
633 : :
634 [ # # ]: 0 : if (!probe)
635 : : break;
636 : :
637 : 0 : status = crypto_has_alg(list[i].name, algo_list->type,
638 : : algo_list->mask);
639 [ # # ]: 0 : if (!status)
640 : : break;
641 : :
642 : 0 : list[i].available = status;
643 : 0 : return &list[i];
644 : : }
645 : : return NULL;
646 : : }
647 : :
648 : 0 : static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
649 : : const void *data)
650 : : {
651 : 0 : return entry->desc.sadb_alg_id == (unsigned long)data;
652 : : }
653 : :
654 : 0 : struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
655 : : {
656 : 0 : 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 : 0 : struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
662 : : {
663 : 0 : 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 : 0 : struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
669 : : {
670 : 0 : 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 : 0 : static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry,
676 : : const void *data)
677 : : {
678 : : const char *name = data;
679 : :
680 [ # # ][ # # ]: 0 : return name && (!strcmp(name, entry->name) ||
[ # # ]
681 [ # # ]: 0 : (entry->compat && !strcmp(name, entry->compat)));
682 : : }
683 : :
684 : 0 : struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe)
685 : : {
686 : 0 : 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 : 0 : struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe)
692 : : {
693 : 0 : 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 : 0 : struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe)
699 : : {
700 : 0 : 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 : 0 : 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 : 0 : const char *name = aead->name;
715 : :
716 [ # # ][ # # ]: 0 : return aead->icvbits == entry->uinfo.aead.icv_truncbits && name &&
[ # # ]
717 : 0 : !strcmp(name, entry->name);
718 : : }
719 : :
720 : 0 : struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len, int probe)
721 : : {
722 : 0 : struct xfrm_aead_name data = {
723 : : .name = name,
724 : : .icvbits = icv_len,
725 : : };
726 : :
727 : 0 : 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 : 0 : struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
733 : : {
734 [ # # ]: 0 : if (idx >= aalg_entries())
735 : : return NULL;
736 : :
737 : 0 : return &aalg_list[idx];
738 : : }
739 : : EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
740 : :
741 : 0 : struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx)
742 : : {
743 [ # # ]: 0 : if (idx >= ealg_entries())
744 : : return NULL;
745 : :
746 : 0 : 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 : 0 : void xfrm_probe_algs(void)
756 : : {
757 : : int i, status;
758 : :
759 [ # # ]: 0 : BUG_ON(in_softirq());
760 : :
761 [ # # ]: 0 : for (i = 0; i < aalg_entries(); i++) {
762 : 0 : status = crypto_has_hash(aalg_list[i].name, 0,
763 : : CRYPTO_ALG_ASYNC);
764 [ # # ]: 0 : if (aalg_list[i].available != status)
765 : 0 : aalg_list[i].available = status;
766 : : }
767 : :
768 [ # # ]: 0 : for (i = 0; i < ealg_entries(); i++) {
769 : 0 : status = crypto_has_ablkcipher(ealg_list[i].name, 0, 0);
770 [ # # ]: 0 : if (ealg_list[i].available != status)
771 : 0 : ealg_list[i].available = status;
772 : : }
773 : :
774 [ # # ]: 0 : for (i = 0; i < calg_entries(); i++) {
775 : 0 : status = crypto_has_comp(calg_list[i].name, 0,
776 : : CRYPTO_ALG_ASYNC);
777 [ # # ]: 0 : if (calg_list[i].available != status)
778 : 0 : calg_list[i].available = status;
779 : : }
780 : 0 : }
781 : : EXPORT_SYMBOL_GPL(xfrm_probe_algs);
782 : :
783 : 0 : int xfrm_count_pfkey_auth_supported(void)
784 : : {
785 : : int i, n;
786 : :
787 [ # # ]: 0 : for (i = 0, n = 0; i < aalg_entries(); i++)
788 [ # # ][ # # ]: 0 : if (aalg_list[i].available && aalg_list[i].pfkey_supported)
789 : 0 : n++;
790 : 0 : return n;
791 : : }
792 : : EXPORT_SYMBOL_GPL(xfrm_count_pfkey_auth_supported);
793 : :
794 : 0 : int xfrm_count_pfkey_enc_supported(void)
795 : : {
796 : : int i, n;
797 : :
798 [ # # ]: 0 : for (i = 0, n = 0; i < ealg_entries(); i++)
799 [ # # ][ # # ]: 0 : if (ealg_list[i].available && ealg_list[i].pfkey_supported)
800 : 0 : n++;
801 : 0 : return n;
802 : : }
803 : : EXPORT_SYMBOL_GPL(xfrm_count_pfkey_enc_supported);
804 : :
805 : : MODULE_LICENSE("GPL");
|