Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * xfrm algorithm interface
0004  *
0005  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
0006  */
0007 
0008 #include <crypto/hash.h>
0009 #include <crypto/skcipher.h>
0010 #include <linux/module.h>
0011 #include <linux/kernel.h>
0012 #include <linux/pfkeyv2.h>
0013 #include <linux/crypto.h>
0014 #include <linux/scatterlist.h>
0015 #include <net/xfrm.h>
0016 #if IS_ENABLED(CONFIG_INET_ESP) || IS_ENABLED(CONFIG_INET6_ESP)
0017 #include <net/esp.h>
0018 #endif
0019 
0020 /*
0021  * Algorithms supported by IPsec.  These entries contain properties which
0022  * are used in key negotiation and xfrm processing, and are used to verify
0023  * that instantiated crypto transforms have correct parameters for IPsec
0024  * purposes.
0025  */
0026 static struct xfrm_algo_desc aead_list[] = {
0027 {
0028     .name = "rfc4106(gcm(aes))",
0029 
0030     .uinfo = {
0031         .aead = {
0032             .geniv = "seqiv",
0033             .icv_truncbits = 64,
0034         }
0035     },
0036 
0037     .pfkey_supported = 1,
0038 
0039     .desc = {
0040         .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV8,
0041         .sadb_alg_ivlen = 8,
0042         .sadb_alg_minbits = 128,
0043         .sadb_alg_maxbits = 256
0044     }
0045 },
0046 {
0047     .name = "rfc4106(gcm(aes))",
0048 
0049     .uinfo = {
0050         .aead = {
0051             .geniv = "seqiv",
0052             .icv_truncbits = 96,
0053         }
0054     },
0055 
0056     .pfkey_supported = 1,
0057 
0058     .desc = {
0059         .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV12,
0060         .sadb_alg_ivlen = 8,
0061         .sadb_alg_minbits = 128,
0062         .sadb_alg_maxbits = 256
0063     }
0064 },
0065 {
0066     .name = "rfc4106(gcm(aes))",
0067 
0068     .uinfo = {
0069         .aead = {
0070             .geniv = "seqiv",
0071             .icv_truncbits = 128,
0072         }
0073     },
0074 
0075     .pfkey_supported = 1,
0076 
0077     .desc = {
0078         .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV16,
0079         .sadb_alg_ivlen = 8,
0080         .sadb_alg_minbits = 128,
0081         .sadb_alg_maxbits = 256
0082     }
0083 },
0084 {
0085     .name = "rfc4309(ccm(aes))",
0086 
0087     .uinfo = {
0088         .aead = {
0089             .geniv = "seqiv",
0090             .icv_truncbits = 64,
0091         }
0092     },
0093 
0094     .pfkey_supported = 1,
0095 
0096     .desc = {
0097         .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV8,
0098         .sadb_alg_ivlen = 8,
0099         .sadb_alg_minbits = 128,
0100         .sadb_alg_maxbits = 256
0101     }
0102 },
0103 {
0104     .name = "rfc4309(ccm(aes))",
0105 
0106     .uinfo = {
0107         .aead = {
0108             .geniv = "seqiv",
0109             .icv_truncbits = 96,
0110         }
0111     },
0112 
0113     .pfkey_supported = 1,
0114 
0115     .desc = {
0116         .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV12,
0117         .sadb_alg_ivlen = 8,
0118         .sadb_alg_minbits = 128,
0119         .sadb_alg_maxbits = 256
0120     }
0121 },
0122 {
0123     .name = "rfc4309(ccm(aes))",
0124 
0125     .uinfo = {
0126         .aead = {
0127             .geniv = "seqiv",
0128             .icv_truncbits = 128,
0129         }
0130     },
0131 
0132     .pfkey_supported = 1,
0133 
0134     .desc = {
0135         .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV16,
0136         .sadb_alg_ivlen = 8,
0137         .sadb_alg_minbits = 128,
0138         .sadb_alg_maxbits = 256
0139     }
0140 },
0141 {
0142     .name = "rfc4543(gcm(aes))",
0143 
0144     .uinfo = {
0145         .aead = {
0146             .geniv = "seqiv",
0147             .icv_truncbits = 128,
0148         }
0149     },
0150 
0151     .pfkey_supported = 1,
0152 
0153     .desc = {
0154         .sadb_alg_id = SADB_X_EALG_NULL_AES_GMAC,
0155         .sadb_alg_ivlen = 8,
0156         .sadb_alg_minbits = 128,
0157         .sadb_alg_maxbits = 256
0158     }
0159 },
0160 {
0161     .name = "rfc7539esp(chacha20,poly1305)",
0162 
0163     .uinfo = {
0164         .aead = {
0165             .geniv = "seqiv",
0166             .icv_truncbits = 128,
0167         }
0168     },
0169 
0170     .pfkey_supported = 0,
0171 },
0172 };
0173 
0174 static struct xfrm_algo_desc aalg_list[] = {
0175 {
0176     .name = "digest_null",
0177 
0178     .uinfo = {
0179         .auth = {
0180             .icv_truncbits = 0,
0181             .icv_fullbits = 0,
0182         }
0183     },
0184 
0185     .pfkey_supported = 1,
0186 
0187     .desc = {
0188         .sadb_alg_id = SADB_X_AALG_NULL,
0189         .sadb_alg_ivlen = 0,
0190         .sadb_alg_minbits = 0,
0191         .sadb_alg_maxbits = 0
0192     }
0193 },
0194 {
0195     .name = "hmac(md5)",
0196     .compat = "md5",
0197 
0198     .uinfo = {
0199         .auth = {
0200             .icv_truncbits = 96,
0201             .icv_fullbits = 128,
0202         }
0203     },
0204 
0205     .pfkey_supported = 1,
0206 
0207     .desc = {
0208         .sadb_alg_id = SADB_AALG_MD5HMAC,
0209         .sadb_alg_ivlen = 0,
0210         .sadb_alg_minbits = 128,
0211         .sadb_alg_maxbits = 128
0212     }
0213 },
0214 {
0215     .name = "hmac(sha1)",
0216     .compat = "sha1",
0217 
0218     .uinfo = {
0219         .auth = {
0220             .icv_truncbits = 96,
0221             .icv_fullbits = 160,
0222         }
0223     },
0224 
0225     .pfkey_supported = 1,
0226 
0227     .desc = {
0228         .sadb_alg_id = SADB_AALG_SHA1HMAC,
0229         .sadb_alg_ivlen = 0,
0230         .sadb_alg_minbits = 160,
0231         .sadb_alg_maxbits = 160
0232     }
0233 },
0234 {
0235     .name = "hmac(sha256)",
0236     .compat = "sha256",
0237 
0238     .uinfo = {
0239         .auth = {
0240             .icv_truncbits = 96,
0241             .icv_fullbits = 256,
0242         }
0243     },
0244 
0245     .pfkey_supported = 1,
0246 
0247     .desc = {
0248         .sadb_alg_id = SADB_X_AALG_SHA2_256HMAC,
0249         .sadb_alg_ivlen = 0,
0250         .sadb_alg_minbits = 256,
0251         .sadb_alg_maxbits = 256
0252     }
0253 },
0254 {
0255     .name = "hmac(sha384)",
0256 
0257     .uinfo = {
0258         .auth = {
0259             .icv_truncbits = 192,
0260             .icv_fullbits = 384,
0261         }
0262     },
0263 
0264     .pfkey_supported = 1,
0265 
0266     .desc = {
0267         .sadb_alg_id = SADB_X_AALG_SHA2_384HMAC,
0268         .sadb_alg_ivlen = 0,
0269         .sadb_alg_minbits = 384,
0270         .sadb_alg_maxbits = 384
0271     }
0272 },
0273 {
0274     .name = "hmac(sha512)",
0275 
0276     .uinfo = {
0277         .auth = {
0278             .icv_truncbits = 256,
0279             .icv_fullbits = 512,
0280         }
0281     },
0282 
0283     .pfkey_supported = 1,
0284 
0285     .desc = {
0286         .sadb_alg_id = SADB_X_AALG_SHA2_512HMAC,
0287         .sadb_alg_ivlen = 0,
0288         .sadb_alg_minbits = 512,
0289         .sadb_alg_maxbits = 512
0290     }
0291 },
0292 {
0293     .name = "hmac(rmd160)",
0294     .compat = "rmd160",
0295 
0296     .uinfo = {
0297         .auth = {
0298             .icv_truncbits = 96,
0299             .icv_fullbits = 160,
0300         }
0301     },
0302 
0303     .pfkey_supported = 1,
0304 
0305     .desc = {
0306         .sadb_alg_id = SADB_X_AALG_RIPEMD160HMAC,
0307         .sadb_alg_ivlen = 0,
0308         .sadb_alg_minbits = 160,
0309         .sadb_alg_maxbits = 160
0310     }
0311 },
0312 {
0313     .name = "xcbc(aes)",
0314 
0315     .uinfo = {
0316         .auth = {
0317             .icv_truncbits = 96,
0318             .icv_fullbits = 128,
0319         }
0320     },
0321 
0322     .pfkey_supported = 1,
0323 
0324     .desc = {
0325         .sadb_alg_id = SADB_X_AALG_AES_XCBC_MAC,
0326         .sadb_alg_ivlen = 0,
0327         .sadb_alg_minbits = 128,
0328         .sadb_alg_maxbits = 128
0329     }
0330 },
0331 {
0332     /* rfc4494 */
0333     .name = "cmac(aes)",
0334 
0335     .uinfo = {
0336         .auth = {
0337             .icv_truncbits = 96,
0338             .icv_fullbits = 128,
0339         }
0340     },
0341 
0342     .pfkey_supported = 0,
0343 },
0344 {
0345     .name = "hmac(sm3)",
0346     .compat = "sm3",
0347 
0348     .uinfo = {
0349         .auth = {
0350             .icv_truncbits = 256,
0351             .icv_fullbits = 256,
0352         }
0353     },
0354 
0355     .pfkey_supported = 1,
0356 
0357     .desc = {
0358         .sadb_alg_id = SADB_X_AALG_SM3_256HMAC,
0359         .sadb_alg_ivlen = 0,
0360         .sadb_alg_minbits = 256,
0361         .sadb_alg_maxbits = 256
0362     }
0363 },
0364 };
0365 
0366 static struct xfrm_algo_desc ealg_list[] = {
0367 {
0368     .name = "ecb(cipher_null)",
0369     .compat = "cipher_null",
0370 
0371     .uinfo = {
0372         .encr = {
0373             .blockbits = 8,
0374             .defkeybits = 0,
0375         }
0376     },
0377 
0378     .pfkey_supported = 1,
0379 
0380     .desc = {
0381         .sadb_alg_id =  SADB_EALG_NULL,
0382         .sadb_alg_ivlen = 0,
0383         .sadb_alg_minbits = 0,
0384         .sadb_alg_maxbits = 0
0385     }
0386 },
0387 {
0388     .name = "cbc(des)",
0389     .compat = "des",
0390 
0391     .uinfo = {
0392         .encr = {
0393             .geniv = "echainiv",
0394             .blockbits = 64,
0395             .defkeybits = 64,
0396         }
0397     },
0398 
0399     .pfkey_supported = 1,
0400 
0401     .desc = {
0402         .sadb_alg_id = SADB_EALG_DESCBC,
0403         .sadb_alg_ivlen = 8,
0404         .sadb_alg_minbits = 64,
0405         .sadb_alg_maxbits = 64
0406     }
0407 },
0408 {
0409     .name = "cbc(des3_ede)",
0410     .compat = "des3_ede",
0411 
0412     .uinfo = {
0413         .encr = {
0414             .geniv = "echainiv",
0415             .blockbits = 64,
0416             .defkeybits = 192,
0417         }
0418     },
0419 
0420     .pfkey_supported = 1,
0421 
0422     .desc = {
0423         .sadb_alg_id = SADB_EALG_3DESCBC,
0424         .sadb_alg_ivlen = 8,
0425         .sadb_alg_minbits = 192,
0426         .sadb_alg_maxbits = 192
0427     }
0428 },
0429 {
0430     .name = "cbc(cast5)",
0431     .compat = "cast5",
0432 
0433     .uinfo = {
0434         .encr = {
0435             .geniv = "echainiv",
0436             .blockbits = 64,
0437             .defkeybits = 128,
0438         }
0439     },
0440 
0441     .pfkey_supported = 1,
0442 
0443     .desc = {
0444         .sadb_alg_id = SADB_X_EALG_CASTCBC,
0445         .sadb_alg_ivlen = 8,
0446         .sadb_alg_minbits = 40,
0447         .sadb_alg_maxbits = 128
0448     }
0449 },
0450 {
0451     .name = "cbc(blowfish)",
0452     .compat = "blowfish",
0453 
0454     .uinfo = {
0455         .encr = {
0456             .geniv = "echainiv",
0457             .blockbits = 64,
0458             .defkeybits = 128,
0459         }
0460     },
0461 
0462     .pfkey_supported = 1,
0463 
0464     .desc = {
0465         .sadb_alg_id = SADB_X_EALG_BLOWFISHCBC,
0466         .sadb_alg_ivlen = 8,
0467         .sadb_alg_minbits = 40,
0468         .sadb_alg_maxbits = 448
0469     }
0470 },
0471 {
0472     .name = "cbc(aes)",
0473     .compat = "aes",
0474 
0475     .uinfo = {
0476         .encr = {
0477             .geniv = "echainiv",
0478             .blockbits = 128,
0479             .defkeybits = 128,
0480         }
0481     },
0482 
0483     .pfkey_supported = 1,
0484 
0485     .desc = {
0486         .sadb_alg_id = SADB_X_EALG_AESCBC,
0487         .sadb_alg_ivlen = 8,
0488         .sadb_alg_minbits = 128,
0489         .sadb_alg_maxbits = 256
0490     }
0491 },
0492 {
0493     .name = "cbc(serpent)",
0494     .compat = "serpent",
0495 
0496     .uinfo = {
0497         .encr = {
0498             .geniv = "echainiv",
0499             .blockbits = 128,
0500             .defkeybits = 128,
0501         }
0502     },
0503 
0504     .pfkey_supported = 1,
0505 
0506     .desc = {
0507         .sadb_alg_id = SADB_X_EALG_SERPENTCBC,
0508         .sadb_alg_ivlen = 8,
0509         .sadb_alg_minbits = 128,
0510         .sadb_alg_maxbits = 256,
0511     }
0512 },
0513 {
0514     .name = "cbc(camellia)",
0515     .compat = "camellia",
0516 
0517     .uinfo = {
0518         .encr = {
0519             .geniv = "echainiv",
0520             .blockbits = 128,
0521             .defkeybits = 128,
0522         }
0523     },
0524 
0525     .pfkey_supported = 1,
0526 
0527     .desc = {
0528         .sadb_alg_id = SADB_X_EALG_CAMELLIACBC,
0529         .sadb_alg_ivlen = 8,
0530         .sadb_alg_minbits = 128,
0531         .sadb_alg_maxbits = 256
0532     }
0533 },
0534 {
0535     .name = "cbc(twofish)",
0536     .compat = "twofish",
0537 
0538     .uinfo = {
0539         .encr = {
0540             .geniv = "echainiv",
0541             .blockbits = 128,
0542             .defkeybits = 128,
0543         }
0544     },
0545 
0546     .pfkey_supported = 1,
0547 
0548     .desc = {
0549         .sadb_alg_id = SADB_X_EALG_TWOFISHCBC,
0550         .sadb_alg_ivlen = 8,
0551         .sadb_alg_minbits = 128,
0552         .sadb_alg_maxbits = 256
0553     }
0554 },
0555 {
0556     .name = "rfc3686(ctr(aes))",
0557 
0558     .uinfo = {
0559         .encr = {
0560             .geniv = "seqiv",
0561             .blockbits = 128,
0562             .defkeybits = 160, /* 128-bit key + 32-bit nonce */
0563         }
0564     },
0565 
0566     .pfkey_supported = 1,
0567 
0568     .desc = {
0569         .sadb_alg_id = SADB_X_EALG_AESCTR,
0570         .sadb_alg_ivlen = 8,
0571         .sadb_alg_minbits = 160,
0572         .sadb_alg_maxbits = 288
0573     }
0574 },
0575 {
0576     .name = "cbc(sm4)",
0577     .compat = "sm4",
0578 
0579     .uinfo = {
0580         .encr = {
0581             .geniv = "echainiv",
0582             .blockbits = 128,
0583             .defkeybits = 128,
0584         }
0585     },
0586 
0587     .pfkey_supported = 1,
0588 
0589     .desc = {
0590         .sadb_alg_id = SADB_X_EALG_SM4CBC,
0591         .sadb_alg_ivlen = 16,
0592         .sadb_alg_minbits = 128,
0593         .sadb_alg_maxbits = 256
0594     }
0595 },
0596 };
0597 
0598 static struct xfrm_algo_desc calg_list[] = {
0599 {
0600     .name = "deflate",
0601     .uinfo = {
0602         .comp = {
0603             .threshold = 90,
0604         }
0605     },
0606     .pfkey_supported = 1,
0607     .desc = { .sadb_alg_id = SADB_X_CALG_DEFLATE }
0608 },
0609 {
0610     .name = "lzs",
0611     .uinfo = {
0612         .comp = {
0613             .threshold = 90,
0614         }
0615     },
0616     .pfkey_supported = 1,
0617     .desc = { .sadb_alg_id = SADB_X_CALG_LZS }
0618 },
0619 {
0620     .name = "lzjh",
0621     .uinfo = {
0622         .comp = {
0623             .threshold = 50,
0624         }
0625     },
0626     .pfkey_supported = 1,
0627     .desc = { .sadb_alg_id = SADB_X_CALG_LZJH }
0628 },
0629 };
0630 
0631 static inline int aalg_entries(void)
0632 {
0633     return ARRAY_SIZE(aalg_list);
0634 }
0635 
0636 static inline int ealg_entries(void)
0637 {
0638     return ARRAY_SIZE(ealg_list);
0639 }
0640 
0641 static inline int calg_entries(void)
0642 {
0643     return ARRAY_SIZE(calg_list);
0644 }
0645 
0646 struct xfrm_algo_list {
0647     struct xfrm_algo_desc *algs;
0648     int entries;
0649     u32 type;
0650     u32 mask;
0651 };
0652 
0653 static const struct xfrm_algo_list xfrm_aead_list = {
0654     .algs = aead_list,
0655     .entries = ARRAY_SIZE(aead_list),
0656     .type = CRYPTO_ALG_TYPE_AEAD,
0657     .mask = CRYPTO_ALG_TYPE_MASK,
0658 };
0659 
0660 static const struct xfrm_algo_list xfrm_aalg_list = {
0661     .algs = aalg_list,
0662     .entries = ARRAY_SIZE(aalg_list),
0663     .type = CRYPTO_ALG_TYPE_HASH,
0664     .mask = CRYPTO_ALG_TYPE_HASH_MASK,
0665 };
0666 
0667 static const struct xfrm_algo_list xfrm_ealg_list = {
0668     .algs = ealg_list,
0669     .entries = ARRAY_SIZE(ealg_list),
0670     .type = CRYPTO_ALG_TYPE_SKCIPHER,
0671     .mask = CRYPTO_ALG_TYPE_MASK,
0672 };
0673 
0674 static const struct xfrm_algo_list xfrm_calg_list = {
0675     .algs = calg_list,
0676     .entries = ARRAY_SIZE(calg_list),
0677     .type = CRYPTO_ALG_TYPE_COMPRESS,
0678     .mask = CRYPTO_ALG_TYPE_MASK,
0679 };
0680 
0681 static struct xfrm_algo_desc *xfrm_find_algo(
0682     const struct xfrm_algo_list *algo_list,
0683     int match(const struct xfrm_algo_desc *entry, const void *data),
0684     const void *data, int probe)
0685 {
0686     struct xfrm_algo_desc *list = algo_list->algs;
0687     int i, status;
0688 
0689     for (i = 0; i < algo_list->entries; i++) {
0690         if (!match(list + i, data))
0691             continue;
0692 
0693         if (list[i].available)
0694             return &list[i];
0695 
0696         if (!probe)
0697             break;
0698 
0699         status = crypto_has_alg(list[i].name, algo_list->type,
0700                     algo_list->mask);
0701         if (!status)
0702             break;
0703 
0704         list[i].available = status;
0705         return &list[i];
0706     }
0707     return NULL;
0708 }
0709 
0710 static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
0711                  const void *data)
0712 {
0713     return entry->desc.sadb_alg_id == (unsigned long)data;
0714 }
0715 
0716 struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
0717 {
0718     return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
0719                   (void *)(unsigned long)alg_id, 1);
0720 }
0721 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
0722 
0723 struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
0724 {
0725     return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
0726                   (void *)(unsigned long)alg_id, 1);
0727 }
0728 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
0729 
0730 struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
0731 {
0732     return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
0733                   (void *)(unsigned long)alg_id, 1);
0734 }
0735 EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
0736 
0737 static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry,
0738                    const void *data)
0739 {
0740     const char *name = data;
0741 
0742     return name && (!strcmp(name, entry->name) ||
0743             (entry->compat && !strcmp(name, entry->compat)));
0744 }
0745 
0746 struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe)
0747 {
0748     return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
0749                   probe);
0750 }
0751 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
0752 
0753 struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe)
0754 {
0755     return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
0756                   probe);
0757 }
0758 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
0759 
0760 struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe)
0761 {
0762     return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
0763                   probe);
0764 }
0765 EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
0766 
0767 struct xfrm_aead_name {
0768     const char *name;
0769     int icvbits;
0770 };
0771 
0772 static int xfrm_aead_name_match(const struct xfrm_algo_desc *entry,
0773                 const void *data)
0774 {
0775     const struct xfrm_aead_name *aead = data;
0776     const char *name = aead->name;
0777 
0778     return aead->icvbits == entry->uinfo.aead.icv_truncbits && name &&
0779            !strcmp(name, entry->name);
0780 }
0781 
0782 struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len, int probe)
0783 {
0784     struct xfrm_aead_name data = {
0785         .name = name,
0786         .icvbits = icv_len,
0787     };
0788 
0789     return xfrm_find_algo(&xfrm_aead_list, xfrm_aead_name_match, &data,
0790                   probe);
0791 }
0792 EXPORT_SYMBOL_GPL(xfrm_aead_get_byname);
0793 
0794 struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
0795 {
0796     if (idx >= aalg_entries())
0797         return NULL;
0798 
0799     return &aalg_list[idx];
0800 }
0801 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
0802 
0803 struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx)
0804 {
0805     if (idx >= ealg_entries())
0806         return NULL;
0807 
0808     return &ealg_list[idx];
0809 }
0810 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx);
0811 
0812 /*
0813  * Probe for the availability of crypto algorithms, and set the available
0814  * flag for any algorithms found on the system.  This is typically called by
0815  * pfkey during userspace SA add, update or register.
0816  */
0817 void xfrm_probe_algs(void)
0818 {
0819     int i, status;
0820 
0821     BUG_ON(in_softirq());
0822 
0823     for (i = 0; i < aalg_entries(); i++) {
0824         status = crypto_has_ahash(aalg_list[i].name, 0, 0);
0825         if (aalg_list[i].available != status)
0826             aalg_list[i].available = status;
0827     }
0828 
0829     for (i = 0; i < ealg_entries(); i++) {
0830         status = crypto_has_skcipher(ealg_list[i].name, 0, 0);
0831         if (ealg_list[i].available != status)
0832             ealg_list[i].available = status;
0833     }
0834 
0835     for (i = 0; i < calg_entries(); i++) {
0836         status = crypto_has_comp(calg_list[i].name, 0,
0837                      CRYPTO_ALG_ASYNC);
0838         if (calg_list[i].available != status)
0839             calg_list[i].available = status;
0840     }
0841 }
0842 EXPORT_SYMBOL_GPL(xfrm_probe_algs);
0843 
0844 int xfrm_count_pfkey_auth_supported(void)
0845 {
0846     int i, n;
0847 
0848     for (i = 0, n = 0; i < aalg_entries(); i++)
0849         if (aalg_list[i].available && aalg_list[i].pfkey_supported)
0850             n++;
0851     return n;
0852 }
0853 EXPORT_SYMBOL_GPL(xfrm_count_pfkey_auth_supported);
0854 
0855 int xfrm_count_pfkey_enc_supported(void)
0856 {
0857     int i, n;
0858 
0859     for (i = 0, n = 0; i < ealg_entries(); i++)
0860         if (ealg_list[i].available && ealg_list[i].pfkey_supported)
0861             n++;
0862     return n;
0863 }
0864 EXPORT_SYMBOL_GPL(xfrm_count_pfkey_enc_supported);
0865 
0866 MODULE_LICENSE("GPL");