xfrm_algo.c 14 KB

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