kem.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. /*
  2. * Copyright 2020-2021 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 <stdio.h>
  10. #include <stdlib.h>
  11. #include <openssl/objects.h>
  12. #include <openssl/evp.h>
  13. #include "internal/cryptlib.h"
  14. #include "internal/provider.h"
  15. #include "internal/core.h"
  16. #include "crypto/evp.h"
  17. #include "evp_local.h"
  18. static int evp_kem_init(EVP_PKEY_CTX *ctx, int operation,
  19. const OSSL_PARAM params[])
  20. {
  21. int ret = 0;
  22. EVP_KEM *kem = NULL;
  23. EVP_KEYMGMT *tmp_keymgmt = NULL;
  24. const OSSL_PROVIDER *tmp_prov = NULL;
  25. void *provkey = NULL;
  26. const char *supported_kem = NULL;
  27. int iter;
  28. if (ctx == NULL || ctx->keytype == NULL) {
  29. ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
  30. return 0;
  31. }
  32. evp_pkey_ctx_free_old_ops(ctx);
  33. ctx->operation = operation;
  34. if (ctx->pkey == NULL) {
  35. ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET);
  36. goto err;
  37. }
  38. /*
  39. * Try to derive the supported kem from |ctx->keymgmt|.
  40. */
  41. if (!ossl_assert(ctx->pkey->keymgmt == NULL
  42. || ctx->pkey->keymgmt == ctx->keymgmt)) {
  43. ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
  44. goto err;
  45. }
  46. supported_kem = evp_keymgmt_util_query_operation_name(ctx->keymgmt,
  47. OSSL_OP_KEM);
  48. if (supported_kem == NULL) {
  49. ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
  50. goto err;
  51. }
  52. /*
  53. * Because we cleared out old ops, we shouldn't need to worry about
  54. * checking if kem is already there.
  55. * We perform two iterations:
  56. *
  57. * 1. Do the normal kem fetch, using the fetching data given by
  58. * the EVP_PKEY_CTX.
  59. * 2. Do the provider specific kem fetch, from the same provider
  60. * as |ctx->keymgmt|
  61. *
  62. * We then try to fetch the keymgmt from the same provider as the
  63. * kem, and try to export |ctx->pkey| to that keymgmt (when this
  64. * keymgmt happens to be the same as |ctx->keymgmt|, the export is
  65. * a no-op, but we call it anyway to not complicate the code even
  66. * more).
  67. * If the export call succeeds (returns a non-NULL provider key pointer),
  68. * we're done and can perform the operation itself. If not, we perform
  69. * the second iteration, or jump to legacy.
  70. */
  71. for (iter = 1, provkey = NULL; iter < 3 && provkey == NULL; iter++) {
  72. EVP_KEYMGMT *tmp_keymgmt_tofree = NULL;
  73. /*
  74. * If we're on the second iteration, free the results from the first.
  75. * They are NULL on the first iteration, so no need to check what
  76. * iteration we're on.
  77. */
  78. EVP_KEM_free(kem);
  79. EVP_KEYMGMT_free(tmp_keymgmt);
  80. switch (iter) {
  81. case 1:
  82. kem = EVP_KEM_fetch(ctx->libctx, supported_kem, ctx->propquery);
  83. if (kem != NULL)
  84. tmp_prov = EVP_KEM_get0_provider(kem);
  85. break;
  86. case 2:
  87. tmp_prov = EVP_KEYMGMT_get0_provider(ctx->keymgmt);
  88. kem = evp_kem_fetch_from_prov((OSSL_PROVIDER *)tmp_prov,
  89. supported_kem, ctx->propquery);
  90. if (kem == NULL) {
  91. ERR_raise(ERR_LIB_EVP,
  92. EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
  93. ret = -2;
  94. goto err;
  95. }
  96. }
  97. if (kem == NULL)
  98. continue;
  99. /*
  100. * Ensure that the key is provided, either natively, or as a cached
  101. * export. We start by fetching the keymgmt with the same name as
  102. * |ctx->pkey|, but from the provider of the kem method, using the
  103. * same property query as when fetching the kem method.
  104. * With the keymgmt we found (if we did), we try to export |ctx->pkey|
  105. * to it (evp_pkey_export_to_provider() is smart enough to only actually
  106. * export it if |tmp_keymgmt| is different from |ctx->pkey|'s keymgmt)
  107. */
  108. tmp_keymgmt_tofree = tmp_keymgmt =
  109. evp_keymgmt_fetch_from_prov((OSSL_PROVIDER *)tmp_prov,
  110. EVP_KEYMGMT_get0_name(ctx->keymgmt),
  111. ctx->propquery);
  112. if (tmp_keymgmt != NULL)
  113. provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx,
  114. &tmp_keymgmt, ctx->propquery);
  115. if (tmp_keymgmt == NULL)
  116. EVP_KEYMGMT_free(tmp_keymgmt_tofree);
  117. }
  118. if (provkey == NULL) {
  119. EVP_KEM_free(kem);
  120. ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
  121. goto err;
  122. }
  123. ctx->op.encap.kem = kem;
  124. ctx->op.encap.algctx = kem->newctx(ossl_provider_ctx(kem->prov));
  125. if (ctx->op.encap.algctx == NULL) {
  126. /* The provider key can stay in the cache */
  127. ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
  128. goto err;
  129. }
  130. switch (operation) {
  131. case EVP_PKEY_OP_ENCAPSULATE:
  132. if (kem->encapsulate_init == NULL) {
  133. ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
  134. ret = -2;
  135. goto err;
  136. }
  137. ret = kem->encapsulate_init(ctx->op.encap.algctx, provkey, params);
  138. break;
  139. case EVP_PKEY_OP_DECAPSULATE:
  140. if (kem->decapsulate_init == NULL) {
  141. ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
  142. ret = -2;
  143. goto err;
  144. }
  145. ret = kem->decapsulate_init(ctx->op.encap.algctx, provkey, params);
  146. break;
  147. default:
  148. ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
  149. goto err;
  150. }
  151. EVP_KEYMGMT_free(tmp_keymgmt);
  152. tmp_keymgmt = NULL;
  153. if (ret > 0)
  154. return 1;
  155. err:
  156. if (ret <= 0) {
  157. evp_pkey_ctx_free_old_ops(ctx);
  158. ctx->operation = EVP_PKEY_OP_UNDEFINED;
  159. }
  160. EVP_KEYMGMT_free(tmp_keymgmt);
  161. return ret;
  162. }
  163. int EVP_PKEY_encapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[])
  164. {
  165. return evp_kem_init(ctx, EVP_PKEY_OP_ENCAPSULATE, params);
  166. }
  167. int EVP_PKEY_encapsulate(EVP_PKEY_CTX *ctx,
  168. unsigned char *out, size_t *outlen,
  169. unsigned char *secret, size_t *secretlen)
  170. {
  171. if (ctx == NULL)
  172. return 0;
  173. if (ctx->operation != EVP_PKEY_OP_ENCAPSULATE) {
  174. ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED);
  175. return -1;
  176. }
  177. if (ctx->op.encap.algctx == NULL) {
  178. ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
  179. return -2;
  180. }
  181. if (out != NULL && secret == NULL)
  182. return 0;
  183. return ctx->op.encap.kem->encapsulate(ctx->op.encap.algctx,
  184. out, outlen, secret, secretlen);
  185. }
  186. int EVP_PKEY_decapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[])
  187. {
  188. return evp_kem_init(ctx, EVP_PKEY_OP_DECAPSULATE, params);
  189. }
  190. int EVP_PKEY_decapsulate(EVP_PKEY_CTX *ctx,
  191. unsigned char *secret, size_t *secretlen,
  192. const unsigned char *in, size_t inlen)
  193. {
  194. if (ctx == NULL
  195. || (in == NULL || inlen == 0)
  196. || (secret == NULL && secretlen == NULL))
  197. return 0;
  198. if (ctx->operation != EVP_PKEY_OP_DECAPSULATE) {
  199. ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED);
  200. return -1;
  201. }
  202. if (ctx->op.encap.algctx == NULL) {
  203. ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
  204. return -2;
  205. }
  206. return ctx->op.encap.kem->decapsulate(ctx->op.encap.algctx,
  207. secret, secretlen, in, inlen);
  208. }
  209. static EVP_KEM *evp_kem_new(OSSL_PROVIDER *prov)
  210. {
  211. EVP_KEM *kem = OPENSSL_zalloc(sizeof(EVP_KEM));
  212. if (kem == NULL) {
  213. ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
  214. return NULL;
  215. }
  216. kem->lock = CRYPTO_THREAD_lock_new();
  217. if (kem->lock == NULL) {
  218. ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
  219. OPENSSL_free(kem);
  220. return NULL;
  221. }
  222. kem->prov = prov;
  223. ossl_provider_up_ref(prov);
  224. kem->refcnt = 1;
  225. return kem;
  226. }
  227. static void *evp_kem_from_algorithm(int name_id, const OSSL_ALGORITHM *algodef,
  228. OSSL_PROVIDER *prov)
  229. {
  230. const OSSL_DISPATCH *fns = algodef->implementation;
  231. EVP_KEM *kem = NULL;
  232. int ctxfncnt = 0, encfncnt = 0, decfncnt = 0;
  233. int gparamfncnt = 0, sparamfncnt = 0;
  234. if ((kem = evp_kem_new(prov)) == NULL) {
  235. ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
  236. goto err;
  237. }
  238. kem->name_id = name_id;
  239. if ((kem->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL)
  240. goto err;
  241. kem->description = algodef->algorithm_description;
  242. for (; fns->function_id != 0; fns++) {
  243. switch (fns->function_id) {
  244. case OSSL_FUNC_KEM_NEWCTX:
  245. if (kem->newctx != NULL)
  246. break;
  247. kem->newctx = OSSL_FUNC_kem_newctx(fns);
  248. ctxfncnt++;
  249. break;
  250. case OSSL_FUNC_KEM_ENCAPSULATE_INIT:
  251. if (kem->encapsulate_init != NULL)
  252. break;
  253. kem->encapsulate_init = OSSL_FUNC_kem_encapsulate_init(fns);
  254. encfncnt++;
  255. break;
  256. case OSSL_FUNC_KEM_ENCAPSULATE:
  257. if (kem->encapsulate != NULL)
  258. break;
  259. kem->encapsulate = OSSL_FUNC_kem_encapsulate(fns);
  260. encfncnt++;
  261. break;
  262. case OSSL_FUNC_KEM_DECAPSULATE_INIT:
  263. if (kem->decapsulate_init != NULL)
  264. break;
  265. kem->decapsulate_init = OSSL_FUNC_kem_decapsulate_init(fns);
  266. decfncnt++;
  267. break;
  268. case OSSL_FUNC_KEM_DECAPSULATE:
  269. if (kem->decapsulate != NULL)
  270. break;
  271. kem->decapsulate = OSSL_FUNC_kem_decapsulate(fns);
  272. decfncnt++;
  273. break;
  274. case OSSL_FUNC_KEM_FREECTX:
  275. if (kem->freectx != NULL)
  276. break;
  277. kem->freectx = OSSL_FUNC_kem_freectx(fns);
  278. ctxfncnt++;
  279. break;
  280. case OSSL_FUNC_KEM_DUPCTX:
  281. if (kem->dupctx != NULL)
  282. break;
  283. kem->dupctx = OSSL_FUNC_kem_dupctx(fns);
  284. break;
  285. case OSSL_FUNC_KEM_GET_CTX_PARAMS:
  286. if (kem->get_ctx_params != NULL)
  287. break;
  288. kem->get_ctx_params
  289. = OSSL_FUNC_kem_get_ctx_params(fns);
  290. gparamfncnt++;
  291. break;
  292. case OSSL_FUNC_KEM_GETTABLE_CTX_PARAMS:
  293. if (kem->gettable_ctx_params != NULL)
  294. break;
  295. kem->gettable_ctx_params
  296. = OSSL_FUNC_kem_gettable_ctx_params(fns);
  297. gparamfncnt++;
  298. break;
  299. case OSSL_FUNC_KEM_SET_CTX_PARAMS:
  300. if (kem->set_ctx_params != NULL)
  301. break;
  302. kem->set_ctx_params
  303. = OSSL_FUNC_kem_set_ctx_params(fns);
  304. sparamfncnt++;
  305. break;
  306. case OSSL_FUNC_KEM_SETTABLE_CTX_PARAMS:
  307. if (kem->settable_ctx_params != NULL)
  308. break;
  309. kem->settable_ctx_params
  310. = OSSL_FUNC_kem_settable_ctx_params(fns);
  311. sparamfncnt++;
  312. break;
  313. }
  314. }
  315. if (ctxfncnt != 2
  316. || (encfncnt != 0 && encfncnt != 2)
  317. || (decfncnt != 0 && decfncnt != 2)
  318. || (encfncnt != 2 && decfncnt != 2)
  319. || (gparamfncnt != 0 && gparamfncnt != 2)
  320. || (sparamfncnt != 0 && sparamfncnt != 2)) {
  321. /*
  322. * In order to be a consistent set of functions we must have at least
  323. * a set of context functions (newctx and freectx) as well as a pair of
  324. * "kem" functions: (encapsulate_init, encapsulate) or
  325. * (decapsulate_init, decapsulate). set_ctx_params and settable_ctx_params are
  326. * optional, but if one of them is present then the other one must also
  327. * be present. The same applies to get_ctx_params and
  328. * gettable_ctx_params. The dupctx function is optional.
  329. */
  330. ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
  331. goto err;
  332. }
  333. return kem;
  334. err:
  335. EVP_KEM_free(kem);
  336. return NULL;
  337. }
  338. void EVP_KEM_free(EVP_KEM *kem)
  339. {
  340. int i;
  341. if (kem == NULL)
  342. return;
  343. CRYPTO_DOWN_REF(&kem->refcnt, &i, kem->lock);
  344. if (i > 0)
  345. return;
  346. OPENSSL_free(kem->type_name);
  347. ossl_provider_free(kem->prov);
  348. CRYPTO_THREAD_lock_free(kem->lock);
  349. OPENSSL_free(kem);
  350. }
  351. int EVP_KEM_up_ref(EVP_KEM *kem)
  352. {
  353. int ref = 0;
  354. CRYPTO_UP_REF(&kem->refcnt, &ref, kem->lock);
  355. return 1;
  356. }
  357. OSSL_PROVIDER *EVP_KEM_get0_provider(const EVP_KEM *kem)
  358. {
  359. return kem->prov;
  360. }
  361. EVP_KEM *EVP_KEM_fetch(OSSL_LIB_CTX *ctx, const char *algorithm,
  362. const char *properties)
  363. {
  364. return evp_generic_fetch(ctx, OSSL_OP_KEM, algorithm, properties,
  365. evp_kem_from_algorithm,
  366. (int (*)(void *))EVP_KEM_up_ref,
  367. (void (*)(void *))EVP_KEM_free);
  368. }
  369. EVP_KEM *evp_kem_fetch_from_prov(OSSL_PROVIDER *prov, const char *algorithm,
  370. const char *properties)
  371. {
  372. return evp_generic_fetch_from_prov(prov, OSSL_OP_KEM, algorithm, properties,
  373. evp_kem_from_algorithm,
  374. (int (*)(void *))EVP_KEM_up_ref,
  375. (void (*)(void *))EVP_KEM_free);
  376. }
  377. int EVP_KEM_is_a(const EVP_KEM *kem, const char *name)
  378. {
  379. return kem != NULL && evp_is_a(kem->prov, kem->name_id, NULL, name);
  380. }
  381. int evp_kem_get_number(const EVP_KEM *kem)
  382. {
  383. return kem->name_id;
  384. }
  385. const char *EVP_KEM_get0_name(const EVP_KEM *kem)
  386. {
  387. return kem->type_name;
  388. }
  389. const char *EVP_KEM_get0_description(const EVP_KEM *kem)
  390. {
  391. return kem->description;
  392. }
  393. void EVP_KEM_do_all_provided(OSSL_LIB_CTX *libctx,
  394. void (*fn)(EVP_KEM *kem, void *arg),
  395. void *arg)
  396. {
  397. evp_generic_do_all(libctx, OSSL_OP_KEM, (void (*)(void *, void *))fn, arg,
  398. evp_kem_from_algorithm,
  399. (int (*)(void *))EVP_KEM_up_ref,
  400. (void (*)(void *))EVP_KEM_free);
  401. }
  402. int EVP_KEM_names_do_all(const EVP_KEM *kem,
  403. void (*fn)(const char *name, void *data),
  404. void *data)
  405. {
  406. if (kem->prov != NULL)
  407. return evp_names_do_all(kem->prov, kem->name_id, fn, data);
  408. return 1;
  409. }
  410. const OSSL_PARAM *EVP_KEM_gettable_ctx_params(const EVP_KEM *kem)
  411. {
  412. void *provctx;
  413. if (kem == NULL || kem->gettable_ctx_params == NULL)
  414. return NULL;
  415. provctx = ossl_provider_ctx(EVP_KEM_get0_provider(kem));
  416. return kem->gettable_ctx_params(NULL, provctx);
  417. }
  418. const OSSL_PARAM *EVP_KEM_settable_ctx_params(const EVP_KEM *kem)
  419. {
  420. void *provctx;
  421. if (kem == NULL || kem->settable_ctx_params == NULL)
  422. return NULL;
  423. provctx = ossl_provider_ctx(EVP_KEM_get0_provider(kem));
  424. return kem->settable_ctx_params(NULL, provctx);
  425. }