xfrm_algo.c 14 KB

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