exchange.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. /*
  2. * Copyright 2019-2020 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 <openssl/crypto.h>
  10. #include <openssl/evp.h>
  11. #include <openssl/err.h>
  12. #include "internal/refcount.h"
  13. #include "crypto/evp.h"
  14. #include "internal/provider.h"
  15. #include "internal/numbers.h" /* includes SIZE_MAX */
  16. #include "evp_local.h"
  17. static EVP_KEYEXCH *evp_keyexch_new(OSSL_PROVIDER *prov)
  18. {
  19. EVP_KEYEXCH *exchange = OPENSSL_zalloc(sizeof(EVP_KEYEXCH));
  20. if (exchange == NULL) {
  21. ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
  22. return NULL;
  23. }
  24. exchange->lock = CRYPTO_THREAD_lock_new();
  25. if (exchange->lock == NULL) {
  26. ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
  27. OPENSSL_free(exchange);
  28. return NULL;
  29. }
  30. exchange->prov = prov;
  31. ossl_provider_up_ref(prov);
  32. exchange->refcnt = 1;
  33. return exchange;
  34. }
  35. static void *evp_keyexch_from_dispatch(int name_id,
  36. const OSSL_DISPATCH *fns,
  37. OSSL_PROVIDER *prov)
  38. {
  39. EVP_KEYEXCH *exchange = NULL;
  40. int fncnt = 0, sparamfncnt = 0, gparamfncnt = 0;
  41. if ((exchange = evp_keyexch_new(prov)) == NULL) {
  42. ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
  43. goto err;
  44. }
  45. exchange->name_id = name_id;
  46. for (; fns->function_id != 0; fns++) {
  47. switch (fns->function_id) {
  48. case OSSL_FUNC_KEYEXCH_NEWCTX:
  49. if (exchange->newctx != NULL)
  50. break;
  51. exchange->newctx = OSSL_FUNC_keyexch_newctx(fns);
  52. fncnt++;
  53. break;
  54. case OSSL_FUNC_KEYEXCH_INIT:
  55. if (exchange->init != NULL)
  56. break;
  57. exchange->init = OSSL_FUNC_keyexch_init(fns);
  58. fncnt++;
  59. break;
  60. case OSSL_FUNC_KEYEXCH_SET_PEER:
  61. if (exchange->set_peer != NULL)
  62. break;
  63. exchange->set_peer = OSSL_FUNC_keyexch_set_peer(fns);
  64. break;
  65. case OSSL_FUNC_KEYEXCH_DERIVE:
  66. if (exchange->derive != NULL)
  67. break;
  68. exchange->derive = OSSL_FUNC_keyexch_derive(fns);
  69. fncnt++;
  70. break;
  71. case OSSL_FUNC_KEYEXCH_FREECTX:
  72. if (exchange->freectx != NULL)
  73. break;
  74. exchange->freectx = OSSL_FUNC_keyexch_freectx(fns);
  75. fncnt++;
  76. break;
  77. case OSSL_FUNC_KEYEXCH_DUPCTX:
  78. if (exchange->dupctx != NULL)
  79. break;
  80. exchange->dupctx = OSSL_FUNC_keyexch_dupctx(fns);
  81. break;
  82. case OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS:
  83. if (exchange->get_ctx_params != NULL)
  84. break;
  85. exchange->get_ctx_params = OSSL_FUNC_keyexch_get_ctx_params(fns);
  86. gparamfncnt++;
  87. break;
  88. case OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS:
  89. if (exchange->gettable_ctx_params != NULL)
  90. break;
  91. exchange->gettable_ctx_params
  92. = OSSL_FUNC_keyexch_gettable_ctx_params(fns);
  93. gparamfncnt++;
  94. break;
  95. case OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS:
  96. if (exchange->set_ctx_params != NULL)
  97. break;
  98. exchange->set_ctx_params = OSSL_FUNC_keyexch_set_ctx_params(fns);
  99. sparamfncnt++;
  100. break;
  101. case OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS:
  102. if (exchange->settable_ctx_params != NULL)
  103. break;
  104. exchange->settable_ctx_params
  105. = OSSL_FUNC_keyexch_settable_ctx_params(fns);
  106. sparamfncnt++;
  107. break;
  108. }
  109. }
  110. if (fncnt != 4
  111. || (gparamfncnt != 0 && gparamfncnt != 2)
  112. || (sparamfncnt != 0 && sparamfncnt != 2)) {
  113. /*
  114. * In order to be a consistent set of functions we must have at least
  115. * a complete set of "exchange" functions: init, derive, newctx,
  116. * and freectx. The set_ctx_params and settable_ctx_params functions are
  117. * optional, but if one of them is present then the other one must also
  118. * be present. Same goes for get_ctx_params and gettable_ctx_params.
  119. * The dupctx and set_peer functions are optional.
  120. */
  121. EVPerr(EVP_F_EVP_KEYEXCH_FROM_DISPATCH,
  122. EVP_R_INVALID_PROVIDER_FUNCTIONS);
  123. goto err;
  124. }
  125. return exchange;
  126. err:
  127. EVP_KEYEXCH_free(exchange);
  128. return NULL;
  129. }
  130. void EVP_KEYEXCH_free(EVP_KEYEXCH *exchange)
  131. {
  132. if (exchange != NULL) {
  133. int i;
  134. CRYPTO_DOWN_REF(&exchange->refcnt, &i, exchange->lock);
  135. if (i > 0)
  136. return;
  137. ossl_provider_free(exchange->prov);
  138. CRYPTO_THREAD_lock_free(exchange->lock);
  139. OPENSSL_free(exchange);
  140. }
  141. }
  142. int EVP_KEYEXCH_up_ref(EVP_KEYEXCH *exchange)
  143. {
  144. int ref = 0;
  145. CRYPTO_UP_REF(&exchange->refcnt, &ref, exchange->lock);
  146. return 1;
  147. }
  148. OSSL_PROVIDER *EVP_KEYEXCH_provider(const EVP_KEYEXCH *exchange)
  149. {
  150. return exchange->prov;
  151. }
  152. EVP_KEYEXCH *EVP_KEYEXCH_fetch(OPENSSL_CTX *ctx, const char *algorithm,
  153. const char *properties)
  154. {
  155. return evp_generic_fetch(ctx, OSSL_OP_KEYEXCH, algorithm, properties,
  156. evp_keyexch_from_dispatch,
  157. (int (*)(void *))EVP_KEYEXCH_up_ref,
  158. (void (*)(void *))EVP_KEYEXCH_free);
  159. }
  160. int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
  161. {
  162. int ret;
  163. void *provkey = NULL;
  164. EVP_KEYEXCH *exchange = NULL;
  165. EVP_KEYMGMT *tmp_keymgmt = NULL;
  166. const char *supported_exch = NULL;
  167. if (ctx == NULL) {
  168. EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
  169. return -2;
  170. }
  171. evp_pkey_ctx_free_old_ops(ctx);
  172. ctx->operation = EVP_PKEY_OP_DERIVE;
  173. /*
  174. * TODO when we stop falling back to legacy, this and the ERR_pop_to_mark()
  175. * calls can be removed.
  176. */
  177. ERR_set_mark();
  178. if (ctx->keymgmt == NULL)
  179. goto legacy;
  180. /*
  181. * Ensure that the key is provided, either natively, or as a cached export.
  182. * If not, go legacy
  183. */
  184. tmp_keymgmt = ctx->keymgmt;
  185. provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx,
  186. &tmp_keymgmt, ctx->propquery);
  187. if (provkey == NULL)
  188. goto legacy;
  189. if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) {
  190. ERR_clear_last_mark();
  191. ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
  192. goto err;
  193. }
  194. EVP_KEYMGMT_free(ctx->keymgmt);
  195. ctx->keymgmt = tmp_keymgmt;
  196. if (ctx->keymgmt->query_operation_name != NULL)
  197. supported_exch = ctx->keymgmt->query_operation_name(OSSL_OP_KEYEXCH);
  198. /*
  199. * If we didn't get a supported exch, assume there is one with the
  200. * same name as the key type.
  201. */
  202. if (supported_exch == NULL)
  203. supported_exch = ctx->keytype;
  204. /*
  205. * Because we cleared out old ops, we shouldn't need to worry about
  206. * checking if exchange is already there.
  207. */
  208. exchange = EVP_KEYEXCH_fetch(ctx->libctx, supported_exch, ctx->propquery);
  209. if (exchange == NULL
  210. || (EVP_KEYMGMT_provider(ctx->keymgmt)
  211. != EVP_KEYEXCH_provider(exchange))) {
  212. /*
  213. * We don't need to free ctx->keymgmt here, as it's not necessarily
  214. * tied to this operation. It will be freed by EVP_PKEY_CTX_free().
  215. */
  216. EVP_KEYEXCH_free(exchange);
  217. goto legacy;
  218. }
  219. /*
  220. * TODO remove this when legacy is gone
  221. * If we don't have the full support we need with provided methods,
  222. * let's go see if legacy does.
  223. */
  224. ERR_pop_to_mark();
  225. /* No more legacy from here down to legacy: */
  226. ctx->op.kex.exchange = exchange;
  227. ctx->op.kex.exchprovctx = exchange->newctx(ossl_provider_ctx(exchange->prov));
  228. if (ctx->op.kex.exchprovctx == NULL) {
  229. /* The provider key can stay in the cache */
  230. EVPerr(0, EVP_R_INITIALIZATION_ERROR);
  231. goto err;
  232. }
  233. ret = exchange->init(ctx->op.kex.exchprovctx, provkey);
  234. return ret ? 1 : 0;
  235. err:
  236. evp_pkey_ctx_free_old_ops(ctx);
  237. ctx->operation = EVP_PKEY_OP_UNDEFINED;
  238. return 0;
  239. legacy:
  240. /*
  241. * TODO remove this when legacy is gone
  242. * If we don't have the full support we need with provided methods,
  243. * let's go see if legacy does.
  244. */
  245. ERR_pop_to_mark();
  246. #ifdef FIPS_MODULE
  247. return 0;
  248. #else
  249. if (ctx->pmeth == NULL || ctx->pmeth->derive == NULL) {
  250. EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
  251. return -2;
  252. }
  253. if (ctx->pmeth->derive_init == NULL)
  254. return 1;
  255. ret = ctx->pmeth->derive_init(ctx);
  256. if (ret <= 0)
  257. ctx->operation = EVP_PKEY_OP_UNDEFINED;
  258. return ret;
  259. #endif
  260. }
  261. int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
  262. {
  263. int ret = 0;
  264. void *provkey = NULL;
  265. if (ctx == NULL) {
  266. EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
  267. EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
  268. return -2;
  269. }
  270. if (!EVP_PKEY_CTX_IS_DERIVE_OP(ctx) || ctx->op.kex.exchprovctx == NULL)
  271. goto legacy;
  272. if (ctx->op.kex.exchange->set_peer == NULL) {
  273. EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
  274. EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
  275. return -2;
  276. }
  277. provkey = evp_pkey_export_to_provider(peer, ctx->libctx, &ctx->keymgmt,
  278. ctx->propquery);
  279. /*
  280. * If making the key provided wasn't possible, legacy may be able to pick
  281. * it up
  282. */
  283. if (provkey == NULL)
  284. goto legacy;
  285. return ctx->op.kex.exchange->set_peer(ctx->op.kex.exchprovctx, provkey);
  286. legacy:
  287. #ifdef FIPS_MODULE
  288. return ret;
  289. #else
  290. /*
  291. * TODO(3.0) investigate the case where the operation is deemed legacy,
  292. * but the given peer key is provider only.
  293. */
  294. if (ctx->pmeth == NULL
  295. || !(ctx->pmeth->derive != NULL
  296. || ctx->pmeth->encrypt != NULL
  297. || ctx->pmeth->decrypt != NULL)
  298. || ctx->pmeth->ctrl == NULL) {
  299. EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
  300. EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
  301. return -2;
  302. }
  303. if (ctx->operation != EVP_PKEY_OP_DERIVE
  304. && ctx->operation != EVP_PKEY_OP_ENCRYPT
  305. && ctx->operation != EVP_PKEY_OP_DECRYPT) {
  306. EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
  307. EVP_R_OPERATON_NOT_INITIALIZED);
  308. return -1;
  309. }
  310. ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
  311. if (ret <= 0)
  312. return ret;
  313. if (ret == 2)
  314. return 1;
  315. if (ctx->pkey == NULL) {
  316. EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
  317. return -1;
  318. }
  319. if (ctx->pkey->type != peer->type) {
  320. EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_KEY_TYPES);
  321. return -1;
  322. }
  323. /*
  324. * For clarity. The error is if parameters in peer are
  325. * present (!missing) but don't match. EVP_PKEY_parameters_eq may return
  326. * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1
  327. * (different key types) is impossible here because it is checked earlier.
  328. * -2 is OK for us here, as well as 1, so we can check for 0 only.
  329. */
  330. if (!EVP_PKEY_missing_parameters(peer) &&
  331. !EVP_PKEY_parameters_eq(ctx->pkey, peer)) {
  332. EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS);
  333. return -1;
  334. }
  335. EVP_PKEY_free(ctx->peerkey);
  336. ctx->peerkey = peer;
  337. ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
  338. if (ret <= 0) {
  339. ctx->peerkey = NULL;
  340. return ret;
  341. }
  342. EVP_PKEY_up_ref(peer);
  343. return 1;
  344. #endif
  345. }
  346. int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
  347. {
  348. int ret;
  349. if (ctx == NULL) {
  350. EVPerr(EVP_F_EVP_PKEY_DERIVE,
  351. EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
  352. return -2;
  353. }
  354. if (!EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
  355. EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
  356. return -1;
  357. }
  358. if (ctx->op.kex.exchprovctx == NULL)
  359. goto legacy;
  360. ret = ctx->op.kex.exchange->derive(ctx->op.kex.exchprovctx, key, pkeylen,
  361. SIZE_MAX);
  362. return ret;
  363. legacy:
  364. if (ctx == NULL || ctx->pmeth == NULL || ctx->pmeth->derive == NULL) {
  365. EVPerr(EVP_F_EVP_PKEY_DERIVE,
  366. EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
  367. return -2;
  368. }
  369. M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
  370. return ctx->pmeth->derive(ctx, key, pkeylen);
  371. }
  372. int EVP_KEYEXCH_number(const EVP_KEYEXCH *keyexch)
  373. {
  374. return keyexch->name_id;
  375. }
  376. int EVP_KEYEXCH_is_a(const EVP_KEYEXCH *keyexch, const char *name)
  377. {
  378. return evp_is_a(keyexch->prov, keyexch->name_id, NULL, name);
  379. }
  380. void EVP_KEYEXCH_do_all_provided(OPENSSL_CTX *libctx,
  381. void (*fn)(EVP_KEYEXCH *keyexch, void *arg),
  382. void *arg)
  383. {
  384. evp_generic_do_all(libctx, OSSL_OP_KEYEXCH,
  385. (void (*)(void *, void *))fn, arg,
  386. evp_keyexch_from_dispatch,
  387. (void (*)(void *))EVP_KEYEXCH_free);
  388. }
  389. void EVP_KEYEXCH_names_do_all(const EVP_KEYEXCH *keyexch,
  390. void (*fn)(const char *name, void *data),
  391. void *data)
  392. {
  393. if (keyexch->prov != NULL)
  394. evp_names_do_all(keyexch->prov, keyexch->name_id, fn, data);
  395. }