Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
[platform/kernel/linux-starfive.git] / net / xfrm / xfrm_algo.c
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         .name = "hmac(sm3)",
346         .compat = "sm3",
347
348         .uinfo = {
349                 .auth = {
350                         .icv_truncbits = 256,
351                         .icv_fullbits = 256,
352                 }
353         },
354
355         .pfkey_supported = 1,
356
357         .desc = {
358                 .sadb_alg_id = SADB_X_AALG_SM3_256HMAC,
359                 .sadb_alg_ivlen = 0,
360                 .sadb_alg_minbits = 256,
361                 .sadb_alg_maxbits = 256
362         }
363 },
364 };
365
366 static struct xfrm_algo_desc ealg_list[] = {
367 {
368         .name = "ecb(cipher_null)",
369         .compat = "cipher_null",
370
371         .uinfo = {
372                 .encr = {
373                         .blockbits = 8,
374                         .defkeybits = 0,
375                 }
376         },
377
378         .pfkey_supported = 1,
379
380         .desc = {
381                 .sadb_alg_id =  SADB_EALG_NULL,
382                 .sadb_alg_ivlen = 0,
383                 .sadb_alg_minbits = 0,
384                 .sadb_alg_maxbits = 0
385         }
386 },
387 {
388         .name = "cbc(des)",
389         .compat = "des",
390
391         .uinfo = {
392                 .encr = {
393                         .geniv = "echainiv",
394                         .blockbits = 64,
395                         .defkeybits = 64,
396                 }
397         },
398
399         .pfkey_supported = 1,
400
401         .desc = {
402                 .sadb_alg_id = SADB_EALG_DESCBC,
403                 .sadb_alg_ivlen = 8,
404                 .sadb_alg_minbits = 64,
405                 .sadb_alg_maxbits = 64
406         }
407 },
408 {
409         .name = "cbc(des3_ede)",
410         .compat = "des3_ede",
411
412         .uinfo = {
413                 .encr = {
414                         .geniv = "echainiv",
415                         .blockbits = 64,
416                         .defkeybits = 192,
417                 }
418         },
419
420         .pfkey_supported = 1,
421
422         .desc = {
423                 .sadb_alg_id = SADB_EALG_3DESCBC,
424                 .sadb_alg_ivlen = 8,
425                 .sadb_alg_minbits = 192,
426                 .sadb_alg_maxbits = 192
427         }
428 },
429 {
430         .name = "cbc(cast5)",
431         .compat = "cast5",
432
433         .uinfo = {
434                 .encr = {
435                         .geniv = "echainiv",
436                         .blockbits = 64,
437                         .defkeybits = 128,
438                 }
439         },
440
441         .pfkey_supported = 1,
442
443         .desc = {
444                 .sadb_alg_id = SADB_X_EALG_CASTCBC,
445                 .sadb_alg_ivlen = 8,
446                 .sadb_alg_minbits = 40,
447                 .sadb_alg_maxbits = 128
448         }
449 },
450 {
451         .name = "cbc(blowfish)",
452         .compat = "blowfish",
453
454         .uinfo = {
455                 .encr = {
456                         .geniv = "echainiv",
457                         .blockbits = 64,
458                         .defkeybits = 128,
459                 }
460         },
461
462         .pfkey_supported = 1,
463
464         .desc = {
465                 .sadb_alg_id = SADB_X_EALG_BLOWFISHCBC,
466                 .sadb_alg_ivlen = 8,
467                 .sadb_alg_minbits = 40,
468                 .sadb_alg_maxbits = 448
469         }
470 },
471 {
472         .name = "cbc(aes)",
473         .compat = "aes",
474
475         .uinfo = {
476                 .encr = {
477                         .geniv = "echainiv",
478                         .blockbits = 128,
479                         .defkeybits = 128,
480                 }
481         },
482
483         .pfkey_supported = 1,
484
485         .desc = {
486                 .sadb_alg_id = SADB_X_EALG_AESCBC,
487                 .sadb_alg_ivlen = 8,
488                 .sadb_alg_minbits = 128,
489                 .sadb_alg_maxbits = 256
490         }
491 },
492 {
493         .name = "cbc(serpent)",
494         .compat = "serpent",
495
496         .uinfo = {
497                 .encr = {
498                         .geniv = "echainiv",
499                         .blockbits = 128,
500                         .defkeybits = 128,
501                 }
502         },
503
504         .pfkey_supported = 1,
505
506         .desc = {
507                 .sadb_alg_id = SADB_X_EALG_SERPENTCBC,
508                 .sadb_alg_ivlen = 8,
509                 .sadb_alg_minbits = 128,
510                 .sadb_alg_maxbits = 256,
511         }
512 },
513 {
514         .name = "cbc(camellia)",
515         .compat = "camellia",
516
517         .uinfo = {
518                 .encr = {
519                         .geniv = "echainiv",
520                         .blockbits = 128,
521                         .defkeybits = 128,
522                 }
523         },
524
525         .pfkey_supported = 1,
526
527         .desc = {
528                 .sadb_alg_id = SADB_X_EALG_CAMELLIACBC,
529                 .sadb_alg_ivlen = 8,
530                 .sadb_alg_minbits = 128,
531                 .sadb_alg_maxbits = 256
532         }
533 },
534 {
535         .name = "cbc(twofish)",
536         .compat = "twofish",
537
538         .uinfo = {
539                 .encr = {
540                         .geniv = "echainiv",
541                         .blockbits = 128,
542                         .defkeybits = 128,
543                 }
544         },
545
546         .pfkey_supported = 1,
547
548         .desc = {
549                 .sadb_alg_id = SADB_X_EALG_TWOFISHCBC,
550                 .sadb_alg_ivlen = 8,
551                 .sadb_alg_minbits = 128,
552                 .sadb_alg_maxbits = 256
553         }
554 },
555 {
556         .name = "rfc3686(ctr(aes))",
557
558         .uinfo = {
559                 .encr = {
560                         .geniv = "seqiv",
561                         .blockbits = 128,
562                         .defkeybits = 160, /* 128-bit key + 32-bit nonce */
563                 }
564         },
565
566         .pfkey_supported = 1,
567
568         .desc = {
569                 .sadb_alg_id = SADB_X_EALG_AESCTR,
570                 .sadb_alg_ivlen = 8,
571                 .sadb_alg_minbits = 160,
572                 .sadb_alg_maxbits = 288
573         }
574 },
575 {
576         .name = "cbc(sm4)",
577         .compat = "sm4",
578
579         .uinfo = {
580                 .encr = {
581                         .geniv = "echainiv",
582                         .blockbits = 128,
583                         .defkeybits = 128,
584                 }
585         },
586
587         .pfkey_supported = 1,
588
589         .desc = {
590                 .sadb_alg_id = SADB_X_EALG_SM4CBC,
591                 .sadb_alg_ivlen = 16,
592                 .sadb_alg_minbits = 128,
593                 .sadb_alg_maxbits = 256
594         }
595 },
596 };
597
598 static struct xfrm_algo_desc calg_list[] = {
599 {
600         .name = "deflate",
601         .uinfo = {
602                 .comp = {
603                         .threshold = 90,
604                 }
605         },
606         .pfkey_supported = 1,
607         .desc = { .sadb_alg_id = SADB_X_CALG_DEFLATE }
608 },
609 {
610         .name = "lzs",
611         .uinfo = {
612                 .comp = {
613                         .threshold = 90,
614                 }
615         },
616         .pfkey_supported = 1,
617         .desc = { .sadb_alg_id = SADB_X_CALG_LZS }
618 },
619 {
620         .name = "lzjh",
621         .uinfo = {
622                 .comp = {
623                         .threshold = 50,
624                 }
625         },
626         .pfkey_supported = 1,
627         .desc = { .sadb_alg_id = SADB_X_CALG_LZJH }
628 },
629 };
630
631 static inline int aalg_entries(void)
632 {
633         return ARRAY_SIZE(aalg_list);
634 }
635
636 static inline int ealg_entries(void)
637 {
638         return ARRAY_SIZE(ealg_list);
639 }
640
641 static inline int calg_entries(void)
642 {
643         return ARRAY_SIZE(calg_list);
644 }
645
646 struct xfrm_algo_list {
647         struct xfrm_algo_desc *algs;
648         int entries;
649         u32 type;
650         u32 mask;
651 };
652
653 static const struct xfrm_algo_list xfrm_aead_list = {
654         .algs = aead_list,
655         .entries = ARRAY_SIZE(aead_list),
656         .type = CRYPTO_ALG_TYPE_AEAD,
657         .mask = CRYPTO_ALG_TYPE_MASK,
658 };
659
660 static const struct xfrm_algo_list xfrm_aalg_list = {
661         .algs = aalg_list,
662         .entries = ARRAY_SIZE(aalg_list),
663         .type = CRYPTO_ALG_TYPE_HASH,
664         .mask = CRYPTO_ALG_TYPE_HASH_MASK,
665 };
666
667 static const struct xfrm_algo_list xfrm_ealg_list = {
668         .algs = ealg_list,
669         .entries = ARRAY_SIZE(ealg_list),
670         .type = CRYPTO_ALG_TYPE_SKCIPHER,
671         .mask = CRYPTO_ALG_TYPE_MASK,
672 };
673
674 static const struct xfrm_algo_list xfrm_calg_list = {
675         .algs = calg_list,
676         .entries = ARRAY_SIZE(calg_list),
677         .type = CRYPTO_ALG_TYPE_COMPRESS,
678         .mask = CRYPTO_ALG_TYPE_MASK,
679 };
680
681 static struct xfrm_algo_desc *xfrm_find_algo(
682         const struct xfrm_algo_list *algo_list,
683         int match(const struct xfrm_algo_desc *entry, const void *data),
684         const void *data, int probe)
685 {
686         struct xfrm_algo_desc *list = algo_list->algs;
687         int i, status;
688
689         for (i = 0; i < algo_list->entries; i++) {
690                 if (!match(list + i, data))
691                         continue;
692
693                 if (list[i].available)
694                         return &list[i];
695
696                 if (!probe)
697                         break;
698
699                 status = crypto_has_alg(list[i].name, algo_list->type,
700                                         algo_list->mask);
701                 if (!status)
702                         break;
703
704                 list[i].available = status;
705                 return &list[i];
706         }
707         return NULL;
708 }
709
710 static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
711                              const void *data)
712 {
713         return entry->desc.sadb_alg_id == (unsigned long)data;
714 }
715
716 struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
717 {
718         return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
719                               (void *)(unsigned long)alg_id, 1);
720 }
721 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
722
723 struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
724 {
725         return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
726                               (void *)(unsigned long)alg_id, 1);
727 }
728 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
729
730 struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
731 {
732         return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
733                               (void *)(unsigned long)alg_id, 1);
734 }
735 EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
736
737 static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry,
738                                const void *data)
739 {
740         const char *name = data;
741
742         return name && (!strcmp(name, entry->name) ||
743                         (entry->compat && !strcmp(name, entry->compat)));
744 }
745
746 struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe)
747 {
748         return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
749                               probe);
750 }
751 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
752
753 struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe)
754 {
755         return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
756                               probe);
757 }
758 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
759
760 struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe)
761 {
762         return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
763                               probe);
764 }
765 EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
766
767 struct xfrm_aead_name {
768         const char *name;
769         int icvbits;
770 };
771
772 static int xfrm_aead_name_match(const struct xfrm_algo_desc *entry,
773                                 const void *data)
774 {
775         const struct xfrm_aead_name *aead = data;
776         const char *name = aead->name;
777
778         return aead->icvbits == entry->uinfo.aead.icv_truncbits && name &&
779                !strcmp(name, entry->name);
780 }
781
782 struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len, int probe)
783 {
784         struct xfrm_aead_name data = {
785                 .name = name,
786                 .icvbits = icv_len,
787         };
788
789         return xfrm_find_algo(&xfrm_aead_list, xfrm_aead_name_match, &data,
790                               probe);
791 }
792 EXPORT_SYMBOL_GPL(xfrm_aead_get_byname);
793
794 struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
795 {
796         if (idx >= aalg_entries())
797                 return NULL;
798
799         return &aalg_list[idx];
800 }
801 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
802
803 struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx)
804 {
805         if (idx >= ealg_entries())
806                 return NULL;
807
808         return &ealg_list[idx];
809 }
810 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx);
811
812 /*
813  * Probe for the availability of crypto algorithms, and set the available
814  * flag for any algorithms found on the system.  This is typically called by
815  * pfkey during userspace SA add, update or register.
816  */
817 void xfrm_probe_algs(void)
818 {
819         int i, status;
820
821         BUG_ON(in_softirq());
822
823         for (i = 0; i < aalg_entries(); i++) {
824                 status = crypto_has_ahash(aalg_list[i].name, 0, 0);
825                 if (aalg_list[i].available != status)
826                         aalg_list[i].available = status;
827         }
828
829         for (i = 0; i < ealg_entries(); i++) {
830                 status = crypto_has_skcipher(ealg_list[i].name, 0, 0);
831                 if (ealg_list[i].available != status)
832                         ealg_list[i].available = status;
833         }
834
835         for (i = 0; i < calg_entries(); i++) {
836                 status = crypto_has_comp(calg_list[i].name, 0,
837                                          CRYPTO_ALG_ASYNC);
838                 if (calg_list[i].available != status)
839                         calg_list[i].available = status;
840         }
841 }
842 EXPORT_SYMBOL_GPL(xfrm_probe_algs);
843
844 int xfrm_count_pfkey_auth_supported(void)
845 {
846         int i, n;
847
848         for (i = 0, n = 0; i < aalg_entries(); i++)
849                 if (aalg_list[i].available && aalg_list[i].pfkey_supported)
850                         n++;
851         return n;
852 }
853 EXPORT_SYMBOL_GPL(xfrm_count_pfkey_auth_supported);
854
855 int xfrm_count_pfkey_enc_supported(void)
856 {
857         int i, n;
858
859         for (i = 0, n = 0; i < ealg_entries(); i++)
860                 if (ealg_list[i].available && ealg_list[i].pfkey_supported)
861                         n++;
862         return n;
863 }
864 EXPORT_SYMBOL_GPL(xfrm_count_pfkey_enc_supported);
865
866 MODULE_LICENSE("GPL");