xfrm_algo.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816
  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. #include <linux/module.h>
  12. #include <linux/kernel.h>
  13. #include <linux/pfkeyv2.h>
  14. #include <linux/crypto.h>
  15. #include <linux/scatterlist.h>
  16. #include <net/xfrm.h>
  17. #if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE)
  18. #include <net/esp.h>
  19. #endif
  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. .uinfo = {
  30. .aead = {
  31. .geniv = "seqniv",
  32. .icv_truncbits = 64,
  33. }
  34. },
  35. .pfkey_supported = 1,
  36. .desc = {
  37. .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV8,
  38. .sadb_alg_ivlen = 8,
  39. .sadb_alg_minbits = 128,
  40. .sadb_alg_maxbits = 256
  41. }
  42. },
  43. {
  44. .name = "rfc4106(gcm(aes))",
  45. .uinfo = {
  46. .aead = {
  47. .geniv = "seqniv",
  48. .icv_truncbits = 96,
  49. }
  50. },
  51. .pfkey_supported = 1,
  52. .desc = {
  53. .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV12,
  54. .sadb_alg_ivlen = 8,
  55. .sadb_alg_minbits = 128,
  56. .sadb_alg_maxbits = 256
  57. }
  58. },
  59. {
  60. .name = "rfc4106(gcm(aes))",
  61. .uinfo = {
  62. .aead = {
  63. .geniv = "seqniv",
  64. .icv_truncbits = 128,
  65. }
  66. },
  67. .pfkey_supported = 1,
  68. .desc = {
  69. .sadb_alg_id = SADB_X_EALG_AES_GCM_ICV16,
  70. .sadb_alg_ivlen = 8,
  71. .sadb_alg_minbits = 128,
  72. .sadb_alg_maxbits = 256
  73. }
  74. },
  75. {
  76. .name = "rfc4309(ccm(aes))",
  77. .uinfo = {
  78. .aead = {
  79. .geniv = "seqniv",
  80. .icv_truncbits = 64,
  81. }
  82. },
  83. .pfkey_supported = 1,
  84. .desc = {
  85. .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV8,
  86. .sadb_alg_ivlen = 8,
  87. .sadb_alg_minbits = 128,
  88. .sadb_alg_maxbits = 256
  89. }
  90. },
  91. {
  92. .name = "rfc4309(ccm(aes))",
  93. .uinfo = {
  94. .aead = {
  95. .geniv = "seqniv",
  96. .icv_truncbits = 96,
  97. }
  98. },
  99. .pfkey_supported = 1,
  100. .desc = {
  101. .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV12,
  102. .sadb_alg_ivlen = 8,
  103. .sadb_alg_minbits = 128,
  104. .sadb_alg_maxbits = 256
  105. }
  106. },
  107. {
  108. .name = "rfc4309(ccm(aes))",
  109. .uinfo = {
  110. .aead = {
  111. .geniv = "seqniv",
  112. .icv_truncbits = 128,
  113. }
  114. },
  115. .pfkey_supported = 1,
  116. .desc = {
  117. .sadb_alg_id = SADB_X_EALG_AES_CCM_ICV16,
  118. .sadb_alg_ivlen = 8,
  119. .sadb_alg_minbits = 128,
  120. .sadb_alg_maxbits = 256
  121. }
  122. },
  123. {
  124. .name = "rfc4543(gcm(aes))",
  125. .uinfo = {
  126. .aead = {
  127. .geniv = "seqiv",
  128. .icv_truncbits = 128,
  129. }
  130. },
  131. .pfkey_supported = 1,
  132. .desc = {
  133. .sadb_alg_id = SADB_X_EALG_NULL_AES_GMAC,
  134. .sadb_alg_ivlen = 8,
  135. .sadb_alg_minbits = 128,
  136. .sadb_alg_maxbits = 256
  137. }
  138. },
  139. };
  140. static struct xfrm_algo_desc aalg_list[] = {
  141. {
  142. .name = "digest_null",
  143. .uinfo = {
  144. .auth = {
  145. .icv_truncbits = 0,
  146. .icv_fullbits = 0,
  147. }
  148. },
  149. .pfkey_supported = 1,
  150. .desc = {
  151. .sadb_alg_id = SADB_X_AALG_NULL,
  152. .sadb_alg_ivlen = 0,
  153. .sadb_alg_minbits = 0,
  154. .sadb_alg_maxbits = 0
  155. }
  156. },
  157. {
  158. .name = "hmac(md5)",
  159. .compat = "md5",
  160. .uinfo = {
  161. .auth = {
  162. .icv_truncbits = 96,
  163. .icv_fullbits = 128,
  164. }
  165. },
  166. .pfkey_supported = 1,
  167. .desc = {
  168. .sadb_alg_id = SADB_AALG_MD5HMAC,
  169. .sadb_alg_ivlen = 0,
  170. .sadb_alg_minbits = 128,
  171. .sadb_alg_maxbits = 128
  172. }
  173. },
  174. {
  175. .name = "hmac(sha1)",
  176. .compat = "sha1",
  177. .uinfo = {
  178. .auth = {
  179. .icv_truncbits = 96,
  180. .icv_fullbits = 160,
  181. }
  182. },
  183. .pfkey_supported = 1,
  184. .desc = {
  185. .sadb_alg_id = SADB_AALG_SHA1HMAC,
  186. .sadb_alg_ivlen = 0,
  187. .sadb_alg_minbits = 160,
  188. .sadb_alg_maxbits = 160
  189. }
  190. },
  191. {
  192. .name = "hmac(sha256)",
  193. .compat = "sha256",
  194. .uinfo = {
  195. .auth = {
  196. .icv_truncbits = 96,
  197. .icv_fullbits = 256,
  198. }
  199. },
  200. .pfkey_supported = 1,
  201. .desc = {
  202. .sadb_alg_id = SADB_X_AALG_SHA2_256HMAC,
  203. .sadb_alg_ivlen = 0,
  204. .sadb_alg_minbits = 256,
  205. .sadb_alg_maxbits = 256
  206. }
  207. },
  208. {
  209. .name = "hmac(sha384)",
  210. .uinfo = {
  211. .auth = {
  212. .icv_truncbits = 192,
  213. .icv_fullbits = 384,
  214. }
  215. },
  216. .pfkey_supported = 1,
  217. .desc = {
  218. .sadb_alg_id = SADB_X_AALG_SHA2_384HMAC,
  219. .sadb_alg_ivlen = 0,
  220. .sadb_alg_minbits = 384,
  221. .sadb_alg_maxbits = 384
  222. }
  223. },
  224. {
  225. .name = "hmac(sha512)",
  226. .uinfo = {
  227. .auth = {
  228. .icv_truncbits = 256,
  229. .icv_fullbits = 512,
  230. }
  231. },
  232. .pfkey_supported = 1,
  233. .desc = {
  234. .sadb_alg_id = SADB_X_AALG_SHA2_512HMAC,
  235. .sadb_alg_ivlen = 0,
  236. .sadb_alg_minbits = 512,
  237. .sadb_alg_maxbits = 512
  238. }
  239. },
  240. {
  241. .name = "hmac(rmd160)",
  242. .compat = "rmd160",
  243. .uinfo = {
  244. .auth = {
  245. .icv_truncbits = 96,
  246. .icv_fullbits = 160,
  247. }
  248. },
  249. .pfkey_supported = 1,
  250. .desc = {
  251. .sadb_alg_id = SADB_X_AALG_RIPEMD160HMAC,
  252. .sadb_alg_ivlen = 0,
  253. .sadb_alg_minbits = 160,
  254. .sadb_alg_maxbits = 160
  255. }
  256. },
  257. {
  258. .name = "xcbc(aes)",
  259. .uinfo = {
  260. .auth = {
  261. .icv_truncbits = 96,
  262. .icv_fullbits = 128,
  263. }
  264. },
  265. .pfkey_supported = 1,
  266. .desc = {
  267. .sadb_alg_id = SADB_X_AALG_AES_XCBC_MAC,
  268. .sadb_alg_ivlen = 0,
  269. .sadb_alg_minbits = 128,
  270. .sadb_alg_maxbits = 128
  271. }
  272. },
  273. {
  274. /* rfc4494 */
  275. .name = "cmac(aes)",
  276. .uinfo = {
  277. .auth = {
  278. .icv_truncbits = 96,
  279. .icv_fullbits = 128,
  280. }
  281. },
  282. .pfkey_supported = 0,
  283. },
  284. };
  285. static struct xfrm_algo_desc ealg_list[] = {
  286. {
  287. .name = "ecb(cipher_null)",
  288. .compat = "cipher_null",
  289. .uinfo = {
  290. .encr = {
  291. .blockbits = 8,
  292. .defkeybits = 0,
  293. }
  294. },
  295. .pfkey_supported = 1,
  296. .desc = {
  297. .sadb_alg_id = SADB_EALG_NULL,
  298. .sadb_alg_ivlen = 0,
  299. .sadb_alg_minbits = 0,
  300. .sadb_alg_maxbits = 0
  301. }
  302. },
  303. {
  304. .name = "cbc(des)",
  305. .compat = "des",
  306. .uinfo = {
  307. .encr = {
  308. .geniv = "echainiv",
  309. .blockbits = 64,
  310. .defkeybits = 64,
  311. }
  312. },
  313. .pfkey_supported = 1,
  314. .desc = {
  315. .sadb_alg_id = SADB_EALG_DESCBC,
  316. .sadb_alg_ivlen = 8,
  317. .sadb_alg_minbits = 64,
  318. .sadb_alg_maxbits = 64
  319. }
  320. },
  321. {
  322. .name = "cbc(des3_ede)",
  323. .compat = "des3_ede",
  324. .uinfo = {
  325. .encr = {
  326. .geniv = "echainiv",
  327. .blockbits = 64,
  328. .defkeybits = 192,
  329. }
  330. },
  331. .pfkey_supported = 1,
  332. .desc = {
  333. .sadb_alg_id = SADB_EALG_3DESCBC,
  334. .sadb_alg_ivlen = 8,
  335. .sadb_alg_minbits = 192,
  336. .sadb_alg_maxbits = 192
  337. }
  338. },
  339. {
  340. .name = "cbc(cast5)",
  341. .compat = "cast5",
  342. .uinfo = {
  343. .encr = {
  344. .geniv = "echainiv",
  345. .blockbits = 64,
  346. .defkeybits = 128,
  347. }
  348. },
  349. .pfkey_supported = 1,
  350. .desc = {
  351. .sadb_alg_id = SADB_X_EALG_CASTCBC,
  352. .sadb_alg_ivlen = 8,
  353. .sadb_alg_minbits = 40,
  354. .sadb_alg_maxbits = 128
  355. }
  356. },
  357. {
  358. .name = "cbc(blowfish)",
  359. .compat = "blowfish",
  360. .uinfo = {
  361. .encr = {
  362. .geniv = "echainiv",
  363. .blockbits = 64,
  364. .defkeybits = 128,
  365. }
  366. },
  367. .pfkey_supported = 1,
  368. .desc = {
  369. .sadb_alg_id = SADB_X_EALG_BLOWFISHCBC,
  370. .sadb_alg_ivlen = 8,
  371. .sadb_alg_minbits = 40,
  372. .sadb_alg_maxbits = 448
  373. }
  374. },
  375. {
  376. .name = "cbc(aes)",
  377. .compat = "aes",
  378. .uinfo = {
  379. .encr = {
  380. .geniv = "echainiv",
  381. .blockbits = 128,
  382. .defkeybits = 128,
  383. }
  384. },
  385. .pfkey_supported = 1,
  386. .desc = {
  387. .sadb_alg_id = SADB_X_EALG_AESCBC,
  388. .sadb_alg_ivlen = 8,
  389. .sadb_alg_minbits = 128,
  390. .sadb_alg_maxbits = 256
  391. }
  392. },
  393. {
  394. .name = "cbc(serpent)",
  395. .compat = "serpent",
  396. .uinfo = {
  397. .encr = {
  398. .geniv = "echainiv",
  399. .blockbits = 128,
  400. .defkeybits = 128,
  401. }
  402. },
  403. .pfkey_supported = 1,
  404. .desc = {
  405. .sadb_alg_id = SADB_X_EALG_SERPENTCBC,
  406. .sadb_alg_ivlen = 8,
  407. .sadb_alg_minbits = 128,
  408. .sadb_alg_maxbits = 256,
  409. }
  410. },
  411. {
  412. .name = "cbc(camellia)",
  413. .compat = "camellia",
  414. .uinfo = {
  415. .encr = {
  416. .geniv = "echainiv",
  417. .blockbits = 128,
  418. .defkeybits = 128,
  419. }
  420. },
  421. .pfkey_supported = 1,
  422. .desc = {
  423. .sadb_alg_id = SADB_X_EALG_CAMELLIACBC,
  424. .sadb_alg_ivlen = 8,
  425. .sadb_alg_minbits = 128,
  426. .sadb_alg_maxbits = 256
  427. }
  428. },
  429. {
  430. .name = "cbc(twofish)",
  431. .compat = "twofish",
  432. .uinfo = {
  433. .encr = {
  434. .geniv = "echainiv",
  435. .blockbits = 128,
  436. .defkeybits = 128,
  437. }
  438. },
  439. .pfkey_supported = 1,
  440. .desc = {
  441. .sadb_alg_id = SADB_X_EALG_TWOFISHCBC,
  442. .sadb_alg_ivlen = 8,
  443. .sadb_alg_minbits = 128,
  444. .sadb_alg_maxbits = 256
  445. }
  446. },
  447. {
  448. .name = "rfc3686(ctr(aes))",
  449. .uinfo = {
  450. .encr = {
  451. .geniv = "seqiv",
  452. .blockbits = 128,
  453. .defkeybits = 160, /* 128-bit key + 32-bit nonce */
  454. }
  455. },
  456. .pfkey_supported = 1,
  457. .desc = {
  458. .sadb_alg_id = SADB_X_EALG_AESCTR,
  459. .sadb_alg_ivlen = 8,
  460. .sadb_alg_minbits = 160,
  461. .sadb_alg_maxbits = 288
  462. }
  463. },
  464. };
  465. static struct xfrm_algo_desc calg_list[] = {
  466. {
  467. .name = "deflate",
  468. .uinfo = {
  469. .comp = {
  470. .threshold = 90,
  471. }
  472. },
  473. .pfkey_supported = 1,
  474. .desc = { .sadb_alg_id = SADB_X_CALG_DEFLATE }
  475. },
  476. {
  477. .name = "lzs",
  478. .uinfo = {
  479. .comp = {
  480. .threshold = 90,
  481. }
  482. },
  483. .pfkey_supported = 1,
  484. .desc = { .sadb_alg_id = SADB_X_CALG_LZS }
  485. },
  486. {
  487. .name = "lzjh",
  488. .uinfo = {
  489. .comp = {
  490. .threshold = 50,
  491. }
  492. },
  493. .pfkey_supported = 1,
  494. .desc = { .sadb_alg_id = SADB_X_CALG_LZJH }
  495. },
  496. };
  497. static inline int aalg_entries(void)
  498. {
  499. return ARRAY_SIZE(aalg_list);
  500. }
  501. static inline int ealg_entries(void)
  502. {
  503. return ARRAY_SIZE(ealg_list);
  504. }
  505. static inline int calg_entries(void)
  506. {
  507. return ARRAY_SIZE(calg_list);
  508. }
  509. struct xfrm_algo_list {
  510. struct xfrm_algo_desc *algs;
  511. int entries;
  512. u32 type;
  513. u32 mask;
  514. };
  515. static const struct xfrm_algo_list xfrm_aead_list = {
  516. .algs = aead_list,
  517. .entries = ARRAY_SIZE(aead_list),
  518. .type = CRYPTO_ALG_TYPE_AEAD,
  519. .mask = CRYPTO_ALG_TYPE_MASK,
  520. };
  521. static const struct xfrm_algo_list xfrm_aalg_list = {
  522. .algs = aalg_list,
  523. .entries = ARRAY_SIZE(aalg_list),
  524. .type = CRYPTO_ALG_TYPE_HASH,
  525. .mask = CRYPTO_ALG_TYPE_HASH_MASK,
  526. };
  527. static const struct xfrm_algo_list xfrm_ealg_list = {
  528. .algs = ealg_list,
  529. .entries = ARRAY_SIZE(ealg_list),
  530. .type = CRYPTO_ALG_TYPE_BLKCIPHER,
  531. .mask = CRYPTO_ALG_TYPE_BLKCIPHER_MASK,
  532. };
  533. static const struct xfrm_algo_list xfrm_calg_list = {
  534. .algs = calg_list,
  535. .entries = ARRAY_SIZE(calg_list),
  536. .type = CRYPTO_ALG_TYPE_COMPRESS,
  537. .mask = CRYPTO_ALG_TYPE_MASK,
  538. };
  539. static struct xfrm_algo_desc *xfrm_find_algo(
  540. const struct xfrm_algo_list *algo_list,
  541. int match(const struct xfrm_algo_desc *entry, const void *data),
  542. const void *data, int probe)
  543. {
  544. struct xfrm_algo_desc *list = algo_list->algs;
  545. int i, status;
  546. for (i = 0; i < algo_list->entries; i++) {
  547. if (!match(list + i, data))
  548. continue;
  549. if (list[i].available)
  550. return &list[i];
  551. if (!probe)
  552. break;
  553. status = crypto_has_alg(list[i].name, algo_list->type,
  554. algo_list->mask);
  555. if (!status)
  556. break;
  557. list[i].available = status;
  558. return &list[i];
  559. }
  560. return NULL;
  561. }
  562. static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
  563. const void *data)
  564. {
  565. return entry->desc.sadb_alg_id == (unsigned long)data;
  566. }
  567. struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
  568. {
  569. return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
  570. (void *)(unsigned long)alg_id, 1);
  571. }
  572. EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
  573. struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
  574. {
  575. return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
  576. (void *)(unsigned long)alg_id, 1);
  577. }
  578. EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
  579. struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
  580. {
  581. return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
  582. (void *)(unsigned long)alg_id, 1);
  583. }
  584. EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
  585. static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry,
  586. const void *data)
  587. {
  588. const char *name = data;
  589. return name && (!strcmp(name, entry->name) ||
  590. (entry->compat && !strcmp(name, entry->compat)));
  591. }
  592. struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe)
  593. {
  594. return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
  595. probe);
  596. }
  597. EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
  598. struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe)
  599. {
  600. return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
  601. probe);
  602. }
  603. EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
  604. struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe)
  605. {
  606. return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
  607. probe);
  608. }
  609. EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
  610. struct xfrm_aead_name {
  611. const char *name;
  612. int icvbits;
  613. };
  614. static int xfrm_aead_name_match(const struct xfrm_algo_desc *entry,
  615. const void *data)
  616. {
  617. const struct xfrm_aead_name *aead = data;
  618. const char *name = aead->name;
  619. return aead->icvbits == entry->uinfo.aead.icv_truncbits && name &&
  620. !strcmp(name, entry->name);
  621. }
  622. struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len, int probe)
  623. {
  624. struct xfrm_aead_name data = {
  625. .name = name,
  626. .icvbits = icv_len,
  627. };
  628. return xfrm_find_algo(&xfrm_aead_list, xfrm_aead_name_match, &data,
  629. probe);
  630. }
  631. EXPORT_SYMBOL_GPL(xfrm_aead_get_byname);
  632. struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
  633. {
  634. if (idx >= aalg_entries())
  635. return NULL;
  636. return &aalg_list[idx];
  637. }
  638. EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
  639. struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx)
  640. {
  641. if (idx >= ealg_entries())
  642. return NULL;
  643. return &ealg_list[idx];
  644. }
  645. EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx);
  646. /*
  647. * Probe for the availability of crypto algorithms, and set the available
  648. * flag for any algorithms found on the system. This is typically called by
  649. * pfkey during userspace SA add, update or register.
  650. */
  651. void xfrm_probe_algs(void)
  652. {
  653. int i, status;
  654. BUG_ON(in_softirq());
  655. for (i = 0; i < aalg_entries(); i++) {
  656. status = crypto_has_hash(aalg_list[i].name, 0,
  657. CRYPTO_ALG_ASYNC);
  658. if (aalg_list[i].available != status)
  659. aalg_list[i].available = status;
  660. }
  661. for (i = 0; i < ealg_entries(); i++) {
  662. status = crypto_has_ablkcipher(ealg_list[i].name, 0, 0);
  663. if (ealg_list[i].available != status)
  664. ealg_list[i].available = status;
  665. }
  666. for (i = 0; i < calg_entries(); i++) {
  667. status = crypto_has_comp(calg_list[i].name, 0,
  668. CRYPTO_ALG_ASYNC);
  669. if (calg_list[i].available != status)
  670. calg_list[i].available = status;
  671. }
  672. }
  673. EXPORT_SYMBOL_GPL(xfrm_probe_algs);
  674. int xfrm_count_pfkey_auth_supported(void)
  675. {
  676. int i, n;
  677. for (i = 0, n = 0; i < aalg_entries(); i++)
  678. if (aalg_list[i].available && aalg_list[i].pfkey_supported)
  679. n++;
  680. return n;
  681. }
  682. EXPORT_SYMBOL_GPL(xfrm_count_pfkey_auth_supported);
  683. int xfrm_count_pfkey_enc_supported(void)
  684. {
  685. int i, n;
  686. for (i = 0, n = 0; i < ealg_entries(); i++)
  687. if (ealg_list[i].available && ealg_list[i].pfkey_supported)
  688. n++;
  689. return n;
  690. }
  691. EXPORT_SYMBOL_GPL(xfrm_count_pfkey_enc_supported);
  692. MODULE_LICENSE("GPL");