mac.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835
  1. /* mac.c - message authentication code dispatcher
  2. * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
  3. *
  4. * This file is part of Libgcrypt.
  5. *
  6. * Libgcrypt is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as
  8. * published by the Free Software Foundation; either version 2.1 of
  9. * the License, or (at your option) any later version.
  10. *
  11. * Libgcrypt is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <config.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <errno.h>
  24. #include "g10lib.h"
  25. #include "mac-internal.h"
  26. /* This is the list of the digest implementations included in
  27. libgcrypt. */
  28. static const gcry_mac_spec_t * const mac_list[] = {
  29. #if USE_SHA1
  30. &_gcry_mac_type_spec_hmac_sha1,
  31. #endif
  32. #if USE_SHA256
  33. &_gcry_mac_type_spec_hmac_sha256,
  34. &_gcry_mac_type_spec_hmac_sha224,
  35. #endif
  36. #if USE_SHA512
  37. &_gcry_mac_type_spec_hmac_sha512,
  38. &_gcry_mac_type_spec_hmac_sha384,
  39. &_gcry_mac_type_spec_hmac_sha512_256,
  40. &_gcry_mac_type_spec_hmac_sha512_224,
  41. #endif
  42. #if USE_SHA3
  43. &_gcry_mac_type_spec_hmac_sha3_224,
  44. &_gcry_mac_type_spec_hmac_sha3_256,
  45. &_gcry_mac_type_spec_hmac_sha3_384,
  46. &_gcry_mac_type_spec_hmac_sha3_512,
  47. #endif
  48. #if USE_GOST_R_3411_94
  49. &_gcry_mac_type_spec_hmac_gost3411_94,
  50. &_gcry_mac_type_spec_hmac_gost3411_cp,
  51. #endif
  52. #if USE_GOST_R_3411_12
  53. &_gcry_mac_type_spec_hmac_stribog256,
  54. &_gcry_mac_type_spec_hmac_stribog512,
  55. #endif
  56. #if USE_WHIRLPOOL
  57. &_gcry_mac_type_spec_hmac_whirlpool,
  58. #endif
  59. #if USE_RMD160
  60. &_gcry_mac_type_spec_hmac_rmd160,
  61. #endif
  62. #if USE_TIGER
  63. &_gcry_mac_type_spec_hmac_tiger1,
  64. #endif
  65. #if USE_MD5
  66. &_gcry_mac_type_spec_hmac_md5,
  67. #endif
  68. #if USE_MD4
  69. &_gcry_mac_type_spec_hmac_md4,
  70. #endif
  71. #if USE_BLAKE2
  72. &_gcry_mac_type_spec_hmac_blake2b_512,
  73. &_gcry_mac_type_spec_hmac_blake2b_384,
  74. &_gcry_mac_type_spec_hmac_blake2b_256,
  75. &_gcry_mac_type_spec_hmac_blake2b_160,
  76. &_gcry_mac_type_spec_hmac_blake2s_256,
  77. &_gcry_mac_type_spec_hmac_blake2s_224,
  78. &_gcry_mac_type_spec_hmac_blake2s_160,
  79. &_gcry_mac_type_spec_hmac_blake2s_128,
  80. #endif
  81. #if USE_SM3
  82. &_gcry_mac_type_spec_hmac_sm3,
  83. #endif
  84. #if USE_BLOWFISH
  85. &_gcry_mac_type_spec_cmac_blowfish,
  86. #endif
  87. #if USE_DES
  88. &_gcry_mac_type_spec_cmac_tripledes,
  89. #endif
  90. #if USE_CAST5
  91. &_gcry_mac_type_spec_cmac_cast5,
  92. #endif
  93. #if USE_AES
  94. &_gcry_mac_type_spec_cmac_aes,
  95. &_gcry_mac_type_spec_gmac_aes,
  96. &_gcry_mac_type_spec_poly1305mac_aes,
  97. #endif
  98. #if USE_TWOFISH
  99. &_gcry_mac_type_spec_cmac_twofish,
  100. &_gcry_mac_type_spec_gmac_twofish,
  101. &_gcry_mac_type_spec_poly1305mac_twofish,
  102. #endif
  103. #if USE_SERPENT
  104. &_gcry_mac_type_spec_cmac_serpent,
  105. &_gcry_mac_type_spec_gmac_serpent,
  106. &_gcry_mac_type_spec_poly1305mac_serpent,
  107. #endif
  108. #if USE_RFC2268
  109. &_gcry_mac_type_spec_cmac_rfc2268,
  110. #endif
  111. #if USE_SEED
  112. &_gcry_mac_type_spec_cmac_seed,
  113. &_gcry_mac_type_spec_gmac_seed,
  114. &_gcry_mac_type_spec_poly1305mac_seed,
  115. #endif
  116. #if USE_CAMELLIA
  117. &_gcry_mac_type_spec_cmac_camellia,
  118. &_gcry_mac_type_spec_gmac_camellia,
  119. &_gcry_mac_type_spec_poly1305mac_camellia,
  120. #endif
  121. #if USE_IDEA
  122. &_gcry_mac_type_spec_cmac_idea,
  123. #endif
  124. #if USE_GOST28147
  125. &_gcry_mac_type_spec_cmac_gost28147,
  126. &_gcry_mac_type_spec_gost28147_imit,
  127. #endif
  128. &_gcry_mac_type_spec_poly1305mac,
  129. #if USE_SM4
  130. &_gcry_mac_type_spec_cmac_sm4,
  131. &_gcry_mac_type_spec_gmac_sm4,
  132. &_gcry_mac_type_spec_poly1305mac_sm4,
  133. #endif
  134. #if USE_ARIA
  135. &_gcry_mac_type_spec_cmac_aria,
  136. &_gcry_mac_type_spec_gmac_aria,
  137. &_gcry_mac_type_spec_poly1305mac_aria,
  138. #endif
  139. NULL
  140. };
  141. /* HMAC implementations start with index 101 (enum gcry_mac_algos) */
  142. static const gcry_mac_spec_t * const mac_list_algo101[] =
  143. {
  144. #if USE_SHA256
  145. &_gcry_mac_type_spec_hmac_sha256,
  146. &_gcry_mac_type_spec_hmac_sha224,
  147. #else
  148. NULL,
  149. NULL,
  150. #endif
  151. #if USE_SHA512
  152. &_gcry_mac_type_spec_hmac_sha512,
  153. &_gcry_mac_type_spec_hmac_sha384,
  154. #else
  155. NULL,
  156. NULL,
  157. #endif
  158. #if USE_SHA1
  159. &_gcry_mac_type_spec_hmac_sha1,
  160. #else
  161. NULL,
  162. #endif
  163. #if USE_MD5
  164. &_gcry_mac_type_spec_hmac_md5,
  165. #else
  166. NULL,
  167. #endif
  168. #if USE_MD4
  169. &_gcry_mac_type_spec_hmac_md4,
  170. #else
  171. NULL,
  172. #endif
  173. #if USE_RMD160
  174. &_gcry_mac_type_spec_hmac_rmd160,
  175. #else
  176. NULL,
  177. #endif
  178. #if USE_TIGER
  179. &_gcry_mac_type_spec_hmac_tiger1,
  180. #else
  181. NULL,
  182. #endif
  183. #if USE_WHIRLPOOL
  184. &_gcry_mac_type_spec_hmac_whirlpool,
  185. #else
  186. NULL,
  187. #endif
  188. #if USE_GOST_R_3411_94
  189. &_gcry_mac_type_spec_hmac_gost3411_94,
  190. #else
  191. NULL,
  192. #endif
  193. #if USE_GOST_R_3411_12
  194. &_gcry_mac_type_spec_hmac_stribog256,
  195. &_gcry_mac_type_spec_hmac_stribog512,
  196. #else
  197. NULL,
  198. NULL,
  199. #endif
  200. #if USE_MD2
  201. &_gcry_mac_type_spec_hmac_md2,
  202. #else
  203. NULL,
  204. #endif
  205. #if USE_SHA3
  206. &_gcry_mac_type_spec_hmac_sha3_224,
  207. &_gcry_mac_type_spec_hmac_sha3_256,
  208. &_gcry_mac_type_spec_hmac_sha3_384,
  209. &_gcry_mac_type_spec_hmac_sha3_512,
  210. #else
  211. NULL,
  212. NULL,
  213. NULL,
  214. NULL,
  215. #endif
  216. #if USE_GOST_R_3411_94
  217. &_gcry_mac_type_spec_hmac_gost3411_cp,
  218. #else
  219. NULL,
  220. #endif
  221. #if USE_BLAKE2
  222. &_gcry_mac_type_spec_hmac_blake2b_512,
  223. &_gcry_mac_type_spec_hmac_blake2b_384,
  224. &_gcry_mac_type_spec_hmac_blake2b_256,
  225. &_gcry_mac_type_spec_hmac_blake2b_160,
  226. &_gcry_mac_type_spec_hmac_blake2s_256,
  227. &_gcry_mac_type_spec_hmac_blake2s_224,
  228. &_gcry_mac_type_spec_hmac_blake2s_160,
  229. &_gcry_mac_type_spec_hmac_blake2s_128,
  230. #else
  231. NULL,
  232. NULL,
  233. NULL,
  234. NULL,
  235. NULL,
  236. NULL,
  237. NULL,
  238. NULL,
  239. #endif
  240. #if USE_SM3
  241. &_gcry_mac_type_spec_hmac_sm3,
  242. #else
  243. NULL,
  244. #endif
  245. #if USE_SHA512
  246. &_gcry_mac_type_spec_hmac_sha512_256,
  247. &_gcry_mac_type_spec_hmac_sha512_224
  248. #else
  249. NULL,
  250. NULL
  251. #endif
  252. };
  253. /* CMAC implementations start with index 201 (enum gcry_mac_algos) */
  254. static const gcry_mac_spec_t * const mac_list_algo201[] =
  255. {
  256. #if USE_AES
  257. &_gcry_mac_type_spec_cmac_aes,
  258. #else
  259. NULL,
  260. #endif
  261. #if USE_DES
  262. &_gcry_mac_type_spec_cmac_tripledes,
  263. #else
  264. NULL,
  265. #endif
  266. #if USE_CAMELLIA
  267. &_gcry_mac_type_spec_cmac_camellia,
  268. #else
  269. NULL,
  270. #endif
  271. #if USE_CAST5
  272. &_gcry_mac_type_spec_cmac_cast5,
  273. #else
  274. NULL,
  275. #endif
  276. #if USE_BLOWFISH
  277. &_gcry_mac_type_spec_cmac_blowfish,
  278. #else
  279. NULL,
  280. #endif
  281. #if USE_TWOFISH
  282. &_gcry_mac_type_spec_cmac_twofish,
  283. #else
  284. NULL,
  285. #endif
  286. #if USE_SERPENT
  287. &_gcry_mac_type_spec_cmac_serpent,
  288. #else
  289. NULL,
  290. #endif
  291. #if USE_SEED
  292. &_gcry_mac_type_spec_cmac_seed,
  293. #else
  294. NULL,
  295. #endif
  296. #if USE_RFC2268
  297. &_gcry_mac_type_spec_cmac_rfc2268,
  298. #else
  299. NULL,
  300. #endif
  301. #if USE_IDEA
  302. &_gcry_mac_type_spec_cmac_idea,
  303. #else
  304. NULL,
  305. #endif
  306. #if USE_GOST28147
  307. &_gcry_mac_type_spec_cmac_gost28147,
  308. #else
  309. NULL,
  310. #endif
  311. #if USE_SM4
  312. &_gcry_mac_type_spec_cmac_sm4,
  313. #else
  314. NULL,
  315. #endif
  316. #if USE_ARIA
  317. &_gcry_mac_type_spec_cmac_aria
  318. #else
  319. NULL
  320. #endif
  321. };
  322. /* GMAC implementations start with index 401 (enum gcry_mac_algos) */
  323. static const gcry_mac_spec_t * const mac_list_algo401[] =
  324. {
  325. #if USE_AES
  326. &_gcry_mac_type_spec_gmac_aes,
  327. #else
  328. NULL,
  329. #endif
  330. #if USE_CAMELLIA
  331. &_gcry_mac_type_spec_gmac_camellia,
  332. #else
  333. NULL,
  334. #endif
  335. #if USE_TWOFISH
  336. &_gcry_mac_type_spec_gmac_twofish,
  337. #else
  338. NULL,
  339. #endif
  340. #if USE_SERPENT
  341. &_gcry_mac_type_spec_gmac_serpent,
  342. #else
  343. NULL,
  344. #endif
  345. #if USE_SEED
  346. &_gcry_mac_type_spec_gmac_seed,
  347. #else
  348. NULL,
  349. #endif
  350. #if USE_SM4
  351. &_gcry_mac_type_spec_gmac_sm4,
  352. #else
  353. NULL,
  354. #endif
  355. #if USE_ARIA
  356. &_gcry_mac_type_spec_gmac_aria
  357. #else
  358. NULL
  359. #endif
  360. };
  361. /* Poly1305-MAC implementations start with index 501 (enum gcry_mac_algos) */
  362. static const gcry_mac_spec_t * const mac_list_algo501[] =
  363. {
  364. &_gcry_mac_type_spec_poly1305mac,
  365. #if USE_AES
  366. &_gcry_mac_type_spec_poly1305mac_aes,
  367. #else
  368. NULL,
  369. #endif
  370. #if USE_CAMELLIA
  371. &_gcry_mac_type_spec_poly1305mac_camellia,
  372. #else
  373. NULL,
  374. #endif
  375. #if USE_TWOFISH
  376. &_gcry_mac_type_spec_poly1305mac_twofish,
  377. #else
  378. NULL,
  379. #endif
  380. #if USE_SERPENT
  381. &_gcry_mac_type_spec_poly1305mac_serpent,
  382. #else
  383. NULL,
  384. #endif
  385. #if USE_SEED
  386. &_gcry_mac_type_spec_poly1305mac_seed,
  387. #else
  388. NULL,
  389. #endif
  390. #if USE_SM4
  391. &_gcry_mac_type_spec_poly1305mac_sm4,
  392. #else
  393. NULL,
  394. #endif
  395. #if USE_ARIA
  396. &_gcry_mac_type_spec_poly1305mac_aria
  397. #else
  398. NULL
  399. #endif
  400. };
  401. /* Explicitly initialize this module. */
  402. gcry_err_code_t
  403. _gcry_mac_init (void)
  404. {
  405. return 0;
  406. }
  407. /* Return the spec structure for the MAC algorithm ALGO. For an
  408. unknown algorithm NULL is returned. */
  409. static const gcry_mac_spec_t *
  410. spec_from_algo (int algo)
  411. {
  412. const gcry_mac_spec_t *spec = NULL;
  413. if (algo >= 101 && algo < 101 + DIM(mac_list_algo101))
  414. spec = mac_list_algo101[algo - 101];
  415. else if (algo >= 201 && algo < 201 + DIM(mac_list_algo201))
  416. spec = mac_list_algo201[algo - 201];
  417. else if (algo >= 401 && algo < 401 + DIM(mac_list_algo401))
  418. spec = mac_list_algo401[algo - 401];
  419. else if (algo >= 501 && algo < 501 + DIM(mac_list_algo501))
  420. spec = mac_list_algo501[algo - 501];
  421. #if USE_GOST28147
  422. else if (algo == GCRY_MAC_GOST28147_IMIT)
  423. spec = &_gcry_mac_type_spec_gost28147_imit;
  424. #endif
  425. if (spec)
  426. gcry_assert (spec->algo == algo);
  427. return spec;
  428. }
  429. /* Lookup a mac's spec by its name. */
  430. static const gcry_mac_spec_t *
  431. spec_from_name (const char *name)
  432. {
  433. const gcry_mac_spec_t *spec;
  434. int idx;
  435. for (idx = 0; (spec = mac_list[idx]); idx++)
  436. if (!stricmp (name, spec->name))
  437. return spec;
  438. return NULL;
  439. }
  440. /****************
  441. * Map a string to the mac algo
  442. */
  443. int
  444. _gcry_mac_map_name (const char *string)
  445. {
  446. const gcry_mac_spec_t *spec;
  447. if (!string)
  448. return 0;
  449. /* Not found, search a matching mac name. */
  450. spec = spec_from_name (string);
  451. if (spec)
  452. return spec->algo;
  453. return 0;
  454. }
  455. /****************
  456. * This function simply returns the name of the algorithm or some constant
  457. * string when there is no algo. It will never return NULL.
  458. * Use the macro gcry_mac_test_algo() to check whether the algorithm
  459. * is valid.
  460. */
  461. const char *
  462. _gcry_mac_algo_name (int algorithm)
  463. {
  464. const gcry_mac_spec_t *spec;
  465. spec = spec_from_algo (algorithm);
  466. return spec ? spec->name : "?";
  467. }
  468. static gcry_err_code_t
  469. check_mac_algo (int algorithm)
  470. {
  471. const gcry_mac_spec_t *spec;
  472. spec = spec_from_algo (algorithm);
  473. if (spec && !spec->flags.disabled && (spec->flags.fips || !fips_mode ()))
  474. return 0;
  475. return GPG_ERR_MAC_ALGO;
  476. }
  477. /****************
  478. * Open a message digest handle for use with algorithm ALGO.
  479. */
  480. static gcry_err_code_t
  481. mac_open (gcry_mac_hd_t * hd, int algo, int secure, gcry_ctx_t ctx)
  482. {
  483. const gcry_mac_spec_t *spec;
  484. gcry_err_code_t err;
  485. gcry_mac_hd_t h;
  486. spec = spec_from_algo (algo);
  487. if (!spec)
  488. return GPG_ERR_MAC_ALGO;
  489. else if (spec->flags.disabled)
  490. return GPG_ERR_MAC_ALGO;
  491. else if (!spec->flags.fips && fips_mode ())
  492. return GPG_ERR_MAC_ALGO;
  493. else if (!spec->ops)
  494. return GPG_ERR_MAC_ALGO;
  495. else if (!spec->ops->open || !spec->ops->write || !spec->ops->setkey ||
  496. !spec->ops->read || !spec->ops->verify || !spec->ops->reset)
  497. return GPG_ERR_MAC_ALGO;
  498. if (secure)
  499. h = xtrycalloc_secure (1, sizeof (*h));
  500. else
  501. h = xtrycalloc (1, sizeof (*h));
  502. if (!h)
  503. return gpg_err_code_from_syserror ();
  504. h->magic = secure ? CTX_MAC_MAGIC_SECURE : CTX_MAC_MAGIC_NORMAL;
  505. h->spec = spec;
  506. h->algo = algo;
  507. h->gcry_ctx = ctx;
  508. err = h->spec->ops->open (h);
  509. if (err)
  510. xfree (h);
  511. else
  512. *hd = h;
  513. return err;
  514. }
  515. static gcry_err_code_t
  516. mac_reset (gcry_mac_hd_t hd)
  517. {
  518. if (hd->spec->ops->reset)
  519. return hd->spec->ops->reset (hd);
  520. return 0;
  521. }
  522. static void
  523. mac_close (gcry_mac_hd_t hd)
  524. {
  525. if (hd->spec->ops->close)
  526. hd->spec->ops->close (hd);
  527. wipememory (hd, sizeof (*hd));
  528. xfree (hd);
  529. }
  530. static gcry_err_code_t
  531. mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
  532. {
  533. if (!hd->spec->ops->setkey)
  534. return GPG_ERR_INV_ARG;
  535. if (keylen > 0 && !key)
  536. return GPG_ERR_INV_ARG;
  537. return hd->spec->ops->setkey (hd, key, keylen);
  538. }
  539. static gcry_err_code_t
  540. mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
  541. {
  542. if (!hd->spec->ops->setiv)
  543. return GPG_ERR_INV_ARG;
  544. if (ivlen > 0 && !iv)
  545. return GPG_ERR_INV_ARG;
  546. return hd->spec->ops->setiv (hd, iv, ivlen);
  547. }
  548. static gcry_err_code_t
  549. mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
  550. {
  551. if (!hd->spec->ops->write)
  552. return GPG_ERR_INV_ARG;
  553. if (inlen > 0 && !inbuf)
  554. return GPG_ERR_INV_ARG;
  555. return hd->spec->ops->write (hd, inbuf, inlen);
  556. }
  557. static gcry_err_code_t
  558. mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
  559. {
  560. if (!outbuf || !outlen || *outlen == 0 || !hd->spec->ops->read)
  561. return GPG_ERR_INV_ARG;
  562. return hd->spec->ops->read (hd, outbuf, outlen);
  563. }
  564. static gcry_err_code_t
  565. mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
  566. {
  567. if (!buf || buflen == 0 || !hd->spec->ops->verify)
  568. return GPG_ERR_INV_ARG;
  569. return hd->spec->ops->verify (hd, buf, buflen);
  570. }
  571. /* Create a MAC object for algorithm ALGO. FLAGS may be
  572. given as an bitwise OR of the gcry_mac_flags values.
  573. H is guaranteed to be a valid handle or NULL on error. */
  574. gpg_err_code_t
  575. _gcry_mac_open (gcry_mac_hd_t * h, int algo, unsigned int flags,
  576. gcry_ctx_t ctx)
  577. {
  578. gcry_err_code_t rc;
  579. gcry_mac_hd_t hd = NULL;
  580. if ((flags & ~GCRY_MAC_FLAG_SECURE))
  581. rc = GPG_ERR_INV_ARG;
  582. else
  583. rc = mac_open (&hd, algo, !!(flags & GCRY_MAC_FLAG_SECURE), ctx);
  584. *h = rc ? NULL : hd;
  585. return rc;
  586. }
  587. void
  588. _gcry_mac_close (gcry_mac_hd_t hd)
  589. {
  590. if (hd)
  591. mac_close (hd);
  592. }
  593. gcry_err_code_t
  594. _gcry_mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
  595. {
  596. return mac_setkey (hd, key, keylen);
  597. }
  598. gcry_err_code_t
  599. _gcry_mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
  600. {
  601. return mac_setiv (hd, iv, ivlen);
  602. }
  603. gcry_err_code_t
  604. _gcry_mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
  605. {
  606. return mac_write (hd, inbuf, inlen);
  607. }
  608. gcry_err_code_t
  609. _gcry_mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
  610. {
  611. return mac_read (hd, outbuf, outlen);
  612. }
  613. gcry_err_code_t
  614. _gcry_mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
  615. {
  616. return mac_verify (hd, buf, buflen);
  617. }
  618. int
  619. _gcry_mac_get_algo (gcry_mac_hd_t hd)
  620. {
  621. return hd->algo;
  622. }
  623. unsigned int
  624. _gcry_mac_get_algo_maclen (int algo)
  625. {
  626. const gcry_mac_spec_t *spec;
  627. spec = spec_from_algo (algo);
  628. if (!spec || !spec->ops || !spec->ops->get_maclen)
  629. return 0;
  630. return spec->ops->get_maclen (algo);
  631. }
  632. unsigned int
  633. _gcry_mac_get_algo_keylen (int algo)
  634. {
  635. const gcry_mac_spec_t *spec;
  636. spec = spec_from_algo (algo);
  637. if (!spec || !spec->ops || !spec->ops->get_keylen)
  638. return 0;
  639. return spec->ops->get_keylen (algo);
  640. }
  641. gcry_err_code_t
  642. _gcry_mac_ctl (gcry_mac_hd_t hd, int cmd, void *buffer, size_t buflen)
  643. {
  644. gcry_err_code_t rc;
  645. /* Currently not used. */
  646. (void) hd;
  647. (void) buffer;
  648. (void) buflen;
  649. switch (cmd)
  650. {
  651. case GCRYCTL_RESET:
  652. rc = mac_reset (hd);
  653. break;
  654. case GCRYCTL_SET_SBOX:
  655. if (hd->spec->ops->set_extra_info)
  656. rc = hd->spec->ops->set_extra_info
  657. (hd, GCRYCTL_SET_SBOX, buffer, buflen);
  658. else
  659. rc = GPG_ERR_NOT_SUPPORTED;
  660. break;
  661. default:
  662. rc = GPG_ERR_INV_OP;
  663. }
  664. return rc;
  665. }
  666. /* Return information about the given MAC algorithm ALGO.
  667. GCRYCTL_TEST_ALGO:
  668. Returns 0 if the specified algorithm ALGO is available for use.
  669. BUFFER and NBYTES must be zero.
  670. Note: Because this function is in most cases used to return an
  671. integer value, we can make it easier for the caller to just look at
  672. the return value. The caller will in all cases consult the value
  673. and thereby detecting whether a error occurred or not (i.e. while
  674. checking the block size)
  675. */
  676. gcry_err_code_t
  677. _gcry_mac_algo_info (int algo, int what, void *buffer, size_t * nbytes)
  678. {
  679. gcry_err_code_t rc = 0;
  680. unsigned int ui;
  681. switch (what)
  682. {
  683. case GCRYCTL_GET_KEYLEN:
  684. if (buffer || (!nbytes))
  685. rc = GPG_ERR_INV_ARG;
  686. else
  687. {
  688. ui = _gcry_mac_get_algo_keylen (algo);
  689. if (ui > 0)
  690. *nbytes = (size_t) ui;
  691. else
  692. /* The only reason for an error is an invalid algo. */
  693. rc = GPG_ERR_MAC_ALGO;
  694. }
  695. break;
  696. case GCRYCTL_TEST_ALGO:
  697. if (buffer || nbytes)
  698. rc = GPG_ERR_INV_ARG;
  699. else
  700. rc = check_mac_algo (algo);
  701. break;
  702. default:
  703. rc = GPG_ERR_INV_OP;
  704. }
  705. return rc;
  706. }
  707. /* Run the self-tests for the MAC. */
  708. gpg_error_t
  709. _gcry_mac_selftest (int algo, int extended, selftest_report_func_t report)
  710. {
  711. gcry_err_code_t ec;
  712. const gcry_mac_spec_t *spec;
  713. spec = spec_from_algo (algo);
  714. if (spec && !spec->flags.disabled
  715. && (spec->flags.fips || !fips_mode ())
  716. && spec->ops && spec->ops->selftest)
  717. ec = spec->ops->selftest (algo, extended, report);
  718. else
  719. {
  720. ec = GPG_ERR_MAC_ALGO;
  721. if (report)
  722. report ("mac", algo, "module",
  723. spec && !spec->flags.disabled
  724. && (spec->flags.fips || !fips_mode ())?
  725. "no selftest available" :
  726. spec? "algorithm disabled" :
  727. "algorithm not found");
  728. }
  729. return gpg_error (ec);
  730. }