xfrm_algo.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * xfrm algorithm interface
  4. *
  5. * Copyright (c) 2002 James Morris <[email protected]>
  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_GKI_NET_XFRM_HACKS) ? 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. .name = "hmac(sm3)",
  294. .compat = "sm3",
  295. .uinfo = {
  296. .auth = {
  297. .icv_truncbits = 256,
  298. .icv_fullbits = 256,
  299. }
  300. },
  301. .pfkey_supported = 1,
  302. .desc = {
  303. .sadb_alg_id = SADB_X_AALG_SM3_256HMAC,
  304. .sadb_alg_ivlen = 0,
  305. .sadb_alg_minbits = 256,
  306. .sadb_alg_maxbits = 256
  307. }
  308. },
  309. };
  310. static struct xfrm_algo_desc ealg_list[] = {
  311. {
  312. .name = "ecb(cipher_null)",
  313. .compat = "cipher_null",
  314. .uinfo = {
  315. .encr = {
  316. .blockbits = 8,
  317. .defkeybits = 0,
  318. }
  319. },
  320. .pfkey_supported = 1,
  321. .desc = {
  322. .sadb_alg_id = SADB_EALG_NULL,
  323. .sadb_alg_ivlen = 0,
  324. .sadb_alg_minbits = 0,
  325. .sadb_alg_maxbits = 0
  326. }
  327. },
  328. {
  329. .name = "cbc(des)",
  330. .compat = "des",
  331. .uinfo = {
  332. .encr = {
  333. .geniv = "echainiv",
  334. .blockbits = 64,
  335. .defkeybits = 64,
  336. }
  337. },
  338. .pfkey_supported = 1,
  339. .desc = {
  340. .sadb_alg_id = SADB_EALG_DESCBC,
  341. .sadb_alg_ivlen = 8,
  342. .sadb_alg_minbits = 64,
  343. .sadb_alg_maxbits = 64
  344. }
  345. },
  346. {
  347. .name = "cbc(des3_ede)",
  348. .compat = "des3_ede",
  349. .uinfo = {
  350. .encr = {
  351. .geniv = "echainiv",
  352. .blockbits = 64,
  353. .defkeybits = 192,
  354. }
  355. },
  356. .pfkey_supported = 1,
  357. .desc = {
  358. .sadb_alg_id = SADB_EALG_3DESCBC,
  359. .sadb_alg_ivlen = 8,
  360. .sadb_alg_minbits = 192,
  361. .sadb_alg_maxbits = 192
  362. }
  363. },
  364. {
  365. .name = "cbc(cast5)",
  366. .compat = "cast5",
  367. .uinfo = {
  368. .encr = {
  369. .geniv = "echainiv",
  370. .blockbits = 64,
  371. .defkeybits = 128,
  372. }
  373. },
  374. .pfkey_supported = 1,
  375. .desc = {
  376. .sadb_alg_id = SADB_X_EALG_CASTCBC,
  377. .sadb_alg_ivlen = 8,
  378. .sadb_alg_minbits = 40,
  379. .sadb_alg_maxbits = 128
  380. }
  381. },
  382. {
  383. .name = "cbc(blowfish)",
  384. .compat = "blowfish",
  385. .uinfo = {
  386. .encr = {
  387. .geniv = "echainiv",
  388. .blockbits = 64,
  389. .defkeybits = 128,
  390. }
  391. },
  392. .pfkey_supported = 1,
  393. .desc = {
  394. .sadb_alg_id = SADB_X_EALG_BLOWFISHCBC,
  395. .sadb_alg_ivlen = 8,
  396. .sadb_alg_minbits = 40,
  397. .sadb_alg_maxbits = 448
  398. }
  399. },
  400. {
  401. .name = "cbc(aes)",
  402. .compat = "aes",
  403. .uinfo = {
  404. .encr = {
  405. .geniv = "echainiv",
  406. .blockbits = 128,
  407. .defkeybits = 128,
  408. }
  409. },
  410. .pfkey_supported = 1,
  411. .desc = {
  412. .sadb_alg_id = SADB_X_EALG_AESCBC,
  413. .sadb_alg_ivlen = 8,
  414. .sadb_alg_minbits = 128,
  415. .sadb_alg_maxbits = 256
  416. }
  417. },
  418. {
  419. .name = "cbc(serpent)",
  420. .compat = "serpent",
  421. .uinfo = {
  422. .encr = {
  423. .geniv = "echainiv",
  424. .blockbits = 128,
  425. .defkeybits = 128,
  426. }
  427. },
  428. .pfkey_supported = 1,
  429. .desc = {
  430. .sadb_alg_id = SADB_X_EALG_SERPENTCBC,
  431. .sadb_alg_ivlen = 8,
  432. .sadb_alg_minbits = 128,
  433. .sadb_alg_maxbits = 256,
  434. }
  435. },
  436. {
  437. .name = "cbc(camellia)",
  438. .compat = "camellia",
  439. .uinfo = {
  440. .encr = {
  441. .geniv = "echainiv",
  442. .blockbits = 128,
  443. .defkeybits = 128,
  444. }
  445. },
  446. .pfkey_supported = 1,
  447. .desc = {
  448. .sadb_alg_id = SADB_X_EALG_CAMELLIACBC,
  449. .sadb_alg_ivlen = 8,
  450. .sadb_alg_minbits = 128,
  451. .sadb_alg_maxbits = 256
  452. }
  453. },
  454. {
  455. .name = "cbc(twofish)",
  456. .compat = "twofish",
  457. .uinfo = {
  458. .encr = {
  459. .geniv = "echainiv",
  460. .blockbits = 128,
  461. .defkeybits = 128,
  462. }
  463. },
  464. .pfkey_supported = 1,
  465. .desc = {
  466. .sadb_alg_id = SADB_X_EALG_TWOFISHCBC,
  467. .sadb_alg_ivlen = 8,
  468. .sadb_alg_minbits = 128,
  469. .sadb_alg_maxbits = 256
  470. }
  471. },
  472. {
  473. .name = "rfc3686(ctr(aes))",
  474. .uinfo = {
  475. .encr = {
  476. .geniv = "seqiv",
  477. .blockbits = 128,
  478. .defkeybits = 160, /* 128-bit key + 32-bit nonce */
  479. }
  480. },
  481. .pfkey_supported = 1,
  482. .desc = {
  483. .sadb_alg_id = SADB_X_EALG_AESCTR,
  484. .sadb_alg_ivlen = 8,
  485. .sadb_alg_minbits = 160,
  486. .sadb_alg_maxbits = 288
  487. }
  488. },
  489. {
  490. .name = "cbc(sm4)",
  491. .compat = "sm4",
  492. .uinfo = {
  493. .encr = {
  494. .geniv = "echainiv",
  495. .blockbits = 128,
  496. .defkeybits = 128,
  497. }
  498. },
  499. .pfkey_supported = 1,
  500. .desc = {
  501. .sadb_alg_id = SADB_X_EALG_SM4CBC,
  502. .sadb_alg_ivlen = 16,
  503. .sadb_alg_minbits = 128,
  504. .sadb_alg_maxbits = 256
  505. }
  506. },
  507. };
  508. static struct xfrm_algo_desc calg_list[] = {
  509. {
  510. .name = "deflate",
  511. .uinfo = {
  512. .comp = {
  513. .threshold = 90,
  514. }
  515. },
  516. .pfkey_supported = 1,
  517. .desc = { .sadb_alg_id = SADB_X_CALG_DEFLATE }
  518. },
  519. {
  520. .name = "lzs",
  521. .uinfo = {
  522. .comp = {
  523. .threshold = 90,
  524. }
  525. },
  526. .pfkey_supported = 1,
  527. .desc = { .sadb_alg_id = SADB_X_CALG_LZS }
  528. },
  529. {
  530. .name = "lzjh",
  531. .uinfo = {
  532. .comp = {
  533. .threshold = 50,
  534. }
  535. },
  536. .pfkey_supported = 1,
  537. .desc = { .sadb_alg_id = SADB_X_CALG_LZJH }
  538. },
  539. };
  540. static inline int aalg_entries(void)
  541. {
  542. return ARRAY_SIZE(aalg_list);
  543. }
  544. static inline int ealg_entries(void)
  545. {
  546. return ARRAY_SIZE(ealg_list);
  547. }
  548. static inline int calg_entries(void)
  549. {
  550. return ARRAY_SIZE(calg_list);
  551. }
  552. struct xfrm_algo_list {
  553. struct xfrm_algo_desc *algs;
  554. int entries;
  555. u32 type;
  556. u32 mask;
  557. };
  558. static const struct xfrm_algo_list xfrm_aead_list = {
  559. .algs = aead_list,
  560. .entries = ARRAY_SIZE(aead_list),
  561. .type = CRYPTO_ALG_TYPE_AEAD,
  562. .mask = CRYPTO_ALG_TYPE_MASK,
  563. };
  564. static const struct xfrm_algo_list xfrm_aalg_list = {
  565. .algs = aalg_list,
  566. .entries = ARRAY_SIZE(aalg_list),
  567. .type = CRYPTO_ALG_TYPE_HASH,
  568. .mask = CRYPTO_ALG_TYPE_HASH_MASK,
  569. };
  570. static const struct xfrm_algo_list xfrm_ealg_list = {
  571. .algs = ealg_list,
  572. .entries = ARRAY_SIZE(ealg_list),
  573. .type = CRYPTO_ALG_TYPE_SKCIPHER,
  574. .mask = CRYPTO_ALG_TYPE_MASK,
  575. };
  576. static const struct xfrm_algo_list xfrm_calg_list = {
  577. .algs = calg_list,
  578. .entries = ARRAY_SIZE(calg_list),
  579. .type = CRYPTO_ALG_TYPE_COMPRESS,
  580. .mask = CRYPTO_ALG_TYPE_MASK,
  581. };
  582. static struct xfrm_algo_desc *xfrm_find_algo(
  583. const struct xfrm_algo_list *algo_list,
  584. int match(const struct xfrm_algo_desc *entry, const void *data),
  585. const void *data, int probe)
  586. {
  587. struct xfrm_algo_desc *list = algo_list->algs;
  588. int i, status;
  589. for (i = 0; i < algo_list->entries; i++) {
  590. if (!match(list + i, data))
  591. continue;
  592. if (list[i].available)
  593. return &list[i];
  594. if (!probe)
  595. break;
  596. status = crypto_has_alg(list[i].name, algo_list->type,
  597. algo_list->mask);
  598. if (!status)
  599. break;
  600. list[i].available = status;
  601. return &list[i];
  602. }
  603. return NULL;
  604. }
  605. static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
  606. const void *data)
  607. {
  608. return entry->desc.sadb_alg_id == (unsigned long)data;
  609. }
  610. struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
  611. {
  612. return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
  613. (void *)(unsigned long)alg_id, 1);
  614. }
  615. EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
  616. struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
  617. {
  618. return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
  619. (void *)(unsigned long)alg_id, 1);
  620. }
  621. EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
  622. struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
  623. {
  624. return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
  625. (void *)(unsigned long)alg_id, 1);
  626. }
  627. EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
  628. static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry,
  629. const void *data)
  630. {
  631. const char *name = data;
  632. return name && (!strcmp(name, entry->name) ||
  633. (entry->compat && !strcmp(name, entry->compat)));
  634. }
  635. struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe)
  636. {
  637. return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
  638. probe);
  639. }
  640. EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
  641. struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe)
  642. {
  643. return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
  644. probe);
  645. }
  646. EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
  647. struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe)
  648. {
  649. return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
  650. probe);
  651. }
  652. EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
  653. struct xfrm_aead_name {
  654. const char *name;
  655. int icvbits;
  656. };
  657. static int xfrm_aead_name_match(const struct xfrm_algo_desc *entry,
  658. const void *data)
  659. {
  660. const struct xfrm_aead_name *aead = data;
  661. const char *name = aead->name;
  662. return aead->icvbits == entry->uinfo.aead.icv_truncbits && name &&
  663. !strcmp(name, entry->name);
  664. }
  665. struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len, int probe)
  666. {
  667. struct xfrm_aead_name data = {
  668. .name = name,
  669. .icvbits = icv_len,
  670. };
  671. return xfrm_find_algo(&xfrm_aead_list, xfrm_aead_name_match, &data,
  672. probe);
  673. }
  674. EXPORT_SYMBOL_GPL(xfrm_aead_get_byname);
  675. struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
  676. {
  677. if (idx >= aalg_entries())
  678. return NULL;
  679. return &aalg_list[idx];
  680. }
  681. EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
  682. struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx)
  683. {
  684. if (idx >= ealg_entries())
  685. return NULL;
  686. return &ealg_list[idx];
  687. }
  688. EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx);
  689. /*
  690. * Probe for the availability of crypto algorithms, and set the available
  691. * flag for any algorithms found on the system. This is typically called by
  692. * pfkey during userspace SA add, update or register.
  693. */
  694. void xfrm_probe_algs(void)
  695. {
  696. int i, status;
  697. BUG_ON(in_softirq());
  698. for (i = 0; i < aalg_entries(); i++) {
  699. status = crypto_has_ahash(aalg_list[i].name, 0, 0);
  700. if (aalg_list[i].available != status)
  701. aalg_list[i].available = status;
  702. }
  703. for (i = 0; i < ealg_entries(); i++) {
  704. status = crypto_has_skcipher(ealg_list[i].name, 0, 0);
  705. if (ealg_list[i].available != status)
  706. ealg_list[i].available = status;
  707. }
  708. for (i = 0; i < calg_entries(); i++) {
  709. status = crypto_has_comp(calg_list[i].name, 0,
  710. CRYPTO_ALG_ASYNC);
  711. if (calg_list[i].available != status)
  712. calg_list[i].available = status;
  713. }
  714. }
  715. EXPORT_SYMBOL_GPL(xfrm_probe_algs);
  716. int xfrm_count_pfkey_auth_supported(void)
  717. {
  718. int i, n;
  719. for (i = 0, n = 0; i < aalg_entries(); i++)
  720. if (aalg_list[i].available && aalg_list[i].pfkey_supported)
  721. n++;
  722. return n;
  723. }
  724. EXPORT_SYMBOL_GPL(xfrm_count_pfkey_auth_supported);
  725. int xfrm_count_pfkey_enc_supported(void)
  726. {
  727. int i, n;
  728. for (i = 0, n = 0; i < ealg_entries(); i++)
  729. if (ealg_list[i].available && ealg_list[i].pfkey_supported)
  730. n++;
  731. return n;
  732. }
  733. EXPORT_SYMBOL_GPL(xfrm_count_pfkey_enc_supported);
  734. MODULE_LICENSE("GPL");