pkey_mac.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. /*
  2. * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <string.h>
  10. #include <openssl/err.h>
  11. #include <openssl/evp.h>
  12. #include <openssl/engine.h>
  13. #include <openssl/params.h>
  14. #include <openssl/core_names.h>
  15. #include "crypto/evp.h"
  16. #include "evp_local.h"
  17. /* MAC PKEY context structure */
  18. typedef struct {
  19. EVP_MAC_CTX *ctx;
  20. /*
  21. * We know of two MAC types:
  22. *
  23. * 1. those who take a secret in raw form, i.e. raw data as a
  24. * ASN1_OCTET_STRING embedded in a EVP_PKEY. So far, that's
  25. * all of them but CMAC.
  26. * 2. those who take a secret with associated cipher in very generic
  27. * form, i.e. a complete EVP_MAC_CTX embedded in a PKEY. So far,
  28. * only CMAC does this.
  29. *
  30. * (one might wonder why the second form isn't used for all)
  31. */
  32. #define MAC_TYPE_RAW 1 /* HMAC like MAC type (all but CMAC so far) */
  33. #define MAC_TYPE_MAC 2 /* CMAC like MAC type (only CMAC known so far) */
  34. int type;
  35. /* The following is only used for MAC_TYPE_RAW implementations */
  36. struct {
  37. const EVP_MD *md; /* temp storage of MD */
  38. ASN1_OCTET_STRING ktmp; /* temp storage for key */
  39. } raw_data;
  40. } MAC_PKEY_CTX;
  41. static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx);
  42. static int pkey_mac_init(EVP_PKEY_CTX *ctx)
  43. {
  44. MAC_PKEY_CTX *hctx;
  45. /* We're being smart and using the same base NIDs for PKEY and for MAC */
  46. int nid = ctx->pmeth->pkey_id;
  47. EVP_MAC *mac = EVP_MAC_fetch(NULL, OBJ_nid2sn(nid), NULL);
  48. if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
  49. EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE);
  50. return 0;
  51. }
  52. hctx->ctx = EVP_MAC_CTX_new(mac);
  53. if (hctx->ctx == NULL) {
  54. OPENSSL_free(hctx);
  55. return 0;
  56. }
  57. if (nid == EVP_PKEY_CMAC) {
  58. hctx->type = MAC_TYPE_MAC;
  59. } else {
  60. hctx->type = MAC_TYPE_RAW;
  61. hctx->raw_data.ktmp.type = V_ASN1_OCTET_STRING;
  62. }
  63. pkey_mac_cleanup(ctx);
  64. EVP_PKEY_CTX_set_data(ctx, hctx);
  65. ctx->keygen_info_count = 0;
  66. return 1;
  67. }
  68. static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
  69. {
  70. MAC_PKEY_CTX *sctx, *dctx;
  71. sctx = EVP_PKEY_CTX_get_data(src);
  72. if (sctx->ctx->data == NULL)
  73. return 0;
  74. dctx = OPENSSL_zalloc(sizeof(*dctx));
  75. if (dctx == NULL) {
  76. EVPerr(EVP_F_PKEY_MAC_COPY, ERR_R_MALLOC_FAILURE);
  77. return 0;
  78. }
  79. EVP_PKEY_CTX_set_data(dst, dctx);
  80. dst->keygen_info_count = 0;
  81. dctx->ctx = EVP_MAC_CTX_dup(sctx->ctx);
  82. if (dctx->ctx == NULL)
  83. goto err;
  84. /*
  85. * Normally, nothing special would be done with the MAC method. In
  86. * this particular case, though, the MAC method was fetched internally
  87. * by pkey_mac_init() above or by EVP_PKEY_new_CMAC_key() and passed
  88. * via the EVP_MAC_CTX, so it is effectively like every new EVP_MAC_CTX
  89. * fetches the MAC method anew in this case. Therefore, its reference
  90. * count must be adjusted here.
  91. */
  92. if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(dctx->ctx)))
  93. goto err;
  94. dctx->type = sctx->type;
  95. switch (dctx->type) {
  96. case MAC_TYPE_RAW:
  97. dctx->raw_data.md = sctx->raw_data.md;
  98. if (ASN1_STRING_get0_data(&sctx->raw_data.ktmp) != NULL &&
  99. !ASN1_STRING_copy(&dctx->raw_data.ktmp, &sctx->raw_data.ktmp))
  100. goto err;
  101. break;
  102. case MAC_TYPE_MAC:
  103. /* Nothing more to do */
  104. break;
  105. default:
  106. /* This should be dead code */
  107. return 0;
  108. }
  109. return 1;
  110. err:
  111. pkey_mac_cleanup(dst);
  112. return 0;
  113. }
  114. static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
  115. {
  116. /*
  117. * For the exact same reasons the MAC reference count is incremented
  118. * in pkey_mac_copy() above, it must be explicitly freed here.
  119. */
  120. MAC_PKEY_CTX *hctx = ctx == NULL ? NULL : EVP_PKEY_CTX_get_data(ctx);
  121. if (hctx != NULL) {
  122. EVP_MAC *mac = EVP_MAC_CTX_mac(hctx->ctx);
  123. switch (hctx->type) {
  124. case MAC_TYPE_RAW:
  125. OPENSSL_clear_free(hctx->raw_data.ktmp.data,
  126. hctx->raw_data.ktmp.length);
  127. break;
  128. }
  129. EVP_MAC_CTX_free(hctx->ctx);
  130. EVP_MAC_free(mac);
  131. OPENSSL_free(hctx);
  132. EVP_PKEY_CTX_set_data(ctx, NULL);
  133. }
  134. }
  135. static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
  136. {
  137. MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
  138. int nid = ctx->pmeth->pkey_id;
  139. switch (hctx->type) {
  140. case MAC_TYPE_RAW:
  141. {
  142. ASN1_OCTET_STRING *hkey = NULL;
  143. if (!hctx->raw_data.ktmp.data)
  144. return 0;
  145. hkey = ASN1_OCTET_STRING_dup(&hctx->raw_data.ktmp);
  146. if (!hkey)
  147. return 0;
  148. EVP_PKEY_assign(pkey, nid, hkey);
  149. }
  150. break;
  151. case MAC_TYPE_MAC:
  152. {
  153. EVP_MAC_CTX *cmkey = EVP_MAC_CTX_dup(hctx->ctx);
  154. if (cmkey == NULL)
  155. return 0;
  156. if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx->ctx)))
  157. return 0;
  158. EVP_PKEY_assign(pkey, nid, cmkey);
  159. }
  160. break;
  161. default:
  162. /* This should be dead code */
  163. return 0;
  164. }
  165. return 1;
  166. }
  167. static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
  168. {
  169. MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx));
  170. if (!EVP_MAC_update(hctx->ctx, data, count))
  171. return 0;
  172. return 1;
  173. }
  174. static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
  175. {
  176. MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
  177. ASN1_OCTET_STRING *key = NULL;
  178. int rv = 1;
  179. /*
  180. * For MACs with the EVP_PKEY_FLAG_SIGCTX_CUSTOM flag set and that
  181. * gets the key passed as an ASN.1 OCTET STRING, we set the key here,
  182. * as this may be only time it's set during a DigestSign.
  183. *
  184. * MACs that pass around the key in form of EVP_MAC_CTX are setting
  185. * the key through other mechanisms. (this is only CMAC for now)
  186. */
  187. int set_key =
  188. hctx->type == MAC_TYPE_RAW
  189. && (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;
  190. if (set_key) {
  191. if (!EVP_MAC_is_a(EVP_MAC_CTX_mac(hctx->ctx),
  192. OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx)))))
  193. return 0;
  194. key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx));
  195. if (key == NULL)
  196. return 0;
  197. }
  198. EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
  199. EVP_MD_CTX_set_update_fn(mctx, int_update);
  200. /* Some MACs don't support this control... that's fine */
  201. {
  202. OSSL_PARAM params[3];
  203. size_t params_n = 0;
  204. int flags = EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT);
  205. /* TODO(3.0) "flags" isn't quite right, i.e. a quick hack for now */
  206. params[params_n++] =
  207. OSSL_PARAM_construct_int(OSSL_MAC_PARAM_FLAGS, &flags);
  208. if (set_key)
  209. params[params_n++] =
  210. OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
  211. key->data, key->length);
  212. params[params_n++] = OSSL_PARAM_construct_end();
  213. rv = EVP_MAC_CTX_set_params(hctx->ctx, params);
  214. }
  215. return rv;
  216. }
  217. static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
  218. size_t *siglen, EVP_MD_CTX *mctx)
  219. {
  220. MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
  221. return EVP_MAC_final(hctx->ctx, sig, siglen, EVP_MAC_size(hctx->ctx));
  222. }
  223. static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
  224. {
  225. MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
  226. switch (type) {
  227. case EVP_PKEY_CTRL_CIPHER:
  228. switch (hctx->type) {
  229. case MAC_TYPE_RAW:
  230. return -2; /* The raw types don't support ciphers */
  231. case MAC_TYPE_MAC:
  232. {
  233. OSSL_PARAM params[3];
  234. size_t params_n = 0;
  235. char *ciphname = (char *)OBJ_nid2sn(EVP_CIPHER_nid(p2));
  236. #ifndef OPENSSL_NO_ENGINE
  237. char *engineid = (char *)ENGINE_get_id(ctx->engine);
  238. params[params_n++] =
  239. OSSL_PARAM_construct_utf8_string("engine", engineid, 0);
  240. #endif
  241. params[params_n++] =
  242. OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
  243. ciphname, 0);
  244. params[params_n] = OSSL_PARAM_construct_end();
  245. if (!EVP_MAC_CTX_set_params(hctx->ctx, params)
  246. || !EVP_MAC_init(hctx->ctx))
  247. return 0;
  248. }
  249. break;
  250. default:
  251. /* This should be dead code */
  252. return 0;
  253. }
  254. break;
  255. case EVP_PKEY_CTRL_MD:
  256. switch (hctx->type) {
  257. case MAC_TYPE_RAW:
  258. hctx->raw_data.md = p2;
  259. break;
  260. case MAC_TYPE_MAC: {
  261. EVP_MAC_CTX *new_mac_ctx;
  262. if (ctx->pkey == NULL)
  263. return 0;
  264. new_mac_ctx = EVP_MAC_CTX_dup((EVP_MAC_CTX *)ctx->pkey
  265. ->pkey.ptr);
  266. if (new_mac_ctx == NULL)
  267. return 0;
  268. EVP_MAC_CTX_free(hctx->ctx);
  269. hctx->ctx = new_mac_ctx;
  270. }
  271. break;
  272. default:
  273. /* This should be dead code */
  274. return 0;
  275. }
  276. break;
  277. case EVP_PKEY_CTRL_SET_DIGEST_SIZE:
  278. {
  279. OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
  280. size_t size = (size_t)p1;
  281. size_t verify = 0;
  282. /*
  283. * We verify that the length is actually set by getting back
  284. * the same parameter and checking that it matches what we
  285. * tried to set.
  286. * TODO(3.0) when we have a more direct mechanism to check if
  287. * a parameter was used, we must refactor this to use that.
  288. */
  289. params[0] =
  290. OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &size);
  291. if (!EVP_MAC_CTX_set_params(hctx->ctx, params))
  292. return 0;
  293. params[0] =
  294. OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &verify);
  295. if (!EVP_MAC_CTX_get_params(hctx->ctx, params))
  296. return 0;
  297. /*
  298. * Since EVP_MAC_CTX_{get,set}_params() returned successfully,
  299. * we can only assume that the size was ignored, i.e. this
  300. * control is unsupported.
  301. */
  302. if (verify != size)
  303. return -2;
  304. }
  305. break;
  306. case EVP_PKEY_CTRL_SET_MAC_KEY:
  307. switch (hctx->type) {
  308. case MAC_TYPE_RAW:
  309. if ((!p2 && p1 > 0) || (p1 < -1))
  310. return 0;
  311. if (!ASN1_OCTET_STRING_set(&hctx->raw_data.ktmp, p2, p1))
  312. return 0;
  313. break;
  314. case MAC_TYPE_MAC:
  315. {
  316. OSSL_PARAM params[2];
  317. size_t params_n = 0;
  318. params[params_n++] =
  319. OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
  320. p2, p1);
  321. params[params_n] = OSSL_PARAM_construct_end();
  322. return EVP_MAC_CTX_set_params(hctx->ctx, params);
  323. }
  324. break;
  325. default:
  326. /* This should be dead code */
  327. return 0;
  328. }
  329. break;
  330. case EVP_PKEY_CTRL_DIGESTINIT:
  331. switch (hctx->type) {
  332. case MAC_TYPE_RAW:
  333. /* Ensure that we have attached the implementation */
  334. if (!EVP_MAC_init(hctx->ctx))
  335. return 0;
  336. {
  337. ASN1_OCTET_STRING *key =
  338. (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
  339. OSSL_PARAM params[4];
  340. size_t params_n = 0;
  341. char *mdname =
  342. (char *)OBJ_nid2sn(EVP_MD_nid(hctx->raw_data.md));
  343. #ifndef OPENSSL_NO_ENGINE
  344. char *engineid = ctx->engine == NULL
  345. ? NULL : (char *)ENGINE_get_id(ctx->engine);
  346. if (engineid != NULL)
  347. params[params_n++] =
  348. OSSL_PARAM_construct_utf8_string("engine", engineid, 0);
  349. #endif
  350. params[params_n++] =
  351. OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
  352. mdname, 0);
  353. params[params_n++] =
  354. OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
  355. key->data, key->length);
  356. params[params_n] = OSSL_PARAM_construct_end();
  357. return EVP_MAC_CTX_set_params(hctx->ctx, params);
  358. }
  359. break;
  360. case MAC_TYPE_MAC:
  361. return -2; /* The mac types don't support ciphers */
  362. default:
  363. /* This should be dead code */
  364. return 0;
  365. }
  366. break;
  367. default:
  368. return -2;
  369. }
  370. return 1;
  371. }
  372. static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx,
  373. const char *type, const char *value)
  374. {
  375. MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
  376. const EVP_MAC *mac = EVP_MAC_CTX_mac(hctx->ctx);
  377. OSSL_PARAM params[2];
  378. int ok = 0;
  379. /*
  380. * Translation of some control names that are equivalent to a single
  381. * parameter name.
  382. *
  383. * "md" and "digest" are the same thing, we use the single "digest"
  384. *
  385. * "digestsize" was a setting control in siphash, but naming wise,
  386. * it's really the same as "size".
  387. */
  388. if (strcmp(type, "md") == 0)
  389. type = OSSL_MAC_PARAM_DIGEST;
  390. else if (strcmp(type, "digestsize") == 0)
  391. type = OSSL_MAC_PARAM_SIZE;
  392. if (!OSSL_PARAM_allocate_from_text(&params[0],
  393. EVP_MAC_settable_ctx_params(mac),
  394. type, value, strlen(value) + 1))
  395. return 0;
  396. params[1] = OSSL_PARAM_construct_end();
  397. ok = EVP_MAC_CTX_set_params(hctx->ctx, params);
  398. OPENSSL_free(params[0].data);
  399. return ok;
  400. }
  401. static const EVP_PKEY_METHOD cmac_pkey_meth = {
  402. EVP_PKEY_CMAC,
  403. EVP_PKEY_FLAG_SIGCTX_CUSTOM,
  404. pkey_mac_init,
  405. pkey_mac_copy,
  406. pkey_mac_cleanup,
  407. 0, 0,
  408. 0,
  409. pkey_mac_keygen,
  410. 0, 0,
  411. 0, 0,
  412. 0, 0,
  413. pkey_mac_signctx_init,
  414. pkey_mac_signctx,
  415. 0, 0,
  416. 0, 0,
  417. 0, 0,
  418. 0, 0,
  419. pkey_mac_ctrl,
  420. pkey_mac_ctrl_str
  421. };
  422. const EVP_PKEY_METHOD *cmac_pkey_method(void)
  423. {
  424. return &cmac_pkey_meth;
  425. }
  426. static const EVP_PKEY_METHOD hmac_pkey_meth = {
  427. EVP_PKEY_HMAC,
  428. 0,
  429. pkey_mac_init,
  430. pkey_mac_copy,
  431. pkey_mac_cleanup,
  432. 0, 0,
  433. 0,
  434. pkey_mac_keygen,
  435. 0, 0,
  436. 0, 0,
  437. 0, 0,
  438. pkey_mac_signctx_init,
  439. pkey_mac_signctx,
  440. 0, 0,
  441. 0, 0,
  442. 0, 0,
  443. 0, 0,
  444. pkey_mac_ctrl,
  445. pkey_mac_ctrl_str
  446. };
  447. const EVP_PKEY_METHOD *hmac_pkey_method(void)
  448. {
  449. return &hmac_pkey_meth;
  450. }
  451. static const EVP_PKEY_METHOD siphash_pkey_meth = {
  452. EVP_PKEY_SIPHASH,
  453. EVP_PKEY_FLAG_SIGCTX_CUSTOM,
  454. pkey_mac_init,
  455. pkey_mac_copy,
  456. pkey_mac_cleanup,
  457. 0, 0,
  458. 0,
  459. pkey_mac_keygen,
  460. 0, 0,
  461. 0, 0,
  462. 0, 0,
  463. pkey_mac_signctx_init,
  464. pkey_mac_signctx,
  465. 0, 0,
  466. 0, 0,
  467. 0, 0,
  468. 0, 0,
  469. pkey_mac_ctrl,
  470. pkey_mac_ctrl_str
  471. };
  472. const EVP_PKEY_METHOD *siphash_pkey_method(void)
  473. {
  474. return &siphash_pkey_meth;
  475. }
  476. static const EVP_PKEY_METHOD poly1305_pkey_meth = {
  477. EVP_PKEY_POLY1305,
  478. EVP_PKEY_FLAG_SIGCTX_CUSTOM,
  479. pkey_mac_init,
  480. pkey_mac_copy,
  481. pkey_mac_cleanup,
  482. 0, 0,
  483. 0,
  484. pkey_mac_keygen,
  485. 0, 0,
  486. 0, 0,
  487. 0, 0,
  488. pkey_mac_signctx_init,
  489. pkey_mac_signctx,
  490. 0, 0,
  491. 0, 0,
  492. 0, 0,
  493. 0, 0,
  494. pkey_mac_ctrl,
  495. pkey_mac_ctrl_str
  496. };
  497. const EVP_PKEY_METHOD *poly1305_pkey_method(void)
  498. {
  499. return &poly1305_pkey_meth;
  500. }