dh_pmeth.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. /*
  2. * Copyright 2006-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. /*
  10. * DH & DSA low level APIs are deprecated for public use, but still ok for
  11. * internal use.
  12. */
  13. #include "internal/deprecated.h"
  14. #include <stdio.h>
  15. #include "internal/cryptlib.h"
  16. #include <openssl/asn1t.h>
  17. #include <openssl/x509.h>
  18. #include <openssl/evp.h>
  19. #include "dh_local.h"
  20. #include <openssl/bn.h>
  21. #include <openssl/dsa.h>
  22. #include <openssl/objects.h>
  23. #include "crypto/evp.h"
  24. /* DH pkey context structure */
  25. typedef struct {
  26. /* Parameter gen parameters */
  27. int prime_len;
  28. int generator;
  29. int paramgen_type;
  30. int subprime_len;
  31. int pad;
  32. /* message digest used for parameter generation */
  33. const EVP_MD *md;
  34. int param_nid;
  35. /* Keygen callback info */
  36. int gentmp[2];
  37. /* KDF (if any) to use for DH */
  38. char kdf_type;
  39. /* OID to use for KDF */
  40. ASN1_OBJECT *kdf_oid;
  41. /* Message digest to use for key derivation */
  42. const EVP_MD *kdf_md;
  43. /* User key material */
  44. unsigned char *kdf_ukm;
  45. size_t kdf_ukmlen;
  46. /* KDF output length */
  47. size_t kdf_outlen;
  48. } DH_PKEY_CTX;
  49. static int pkey_dh_init(EVP_PKEY_CTX *ctx)
  50. {
  51. DH_PKEY_CTX *dctx;
  52. if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) {
  53. ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
  54. return 0;
  55. }
  56. dctx->prime_len = 2048;
  57. dctx->subprime_len = -1;
  58. dctx->generator = 2;
  59. dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
  60. ctx->data = dctx;
  61. ctx->keygen_info = dctx->gentmp;
  62. ctx->keygen_info_count = 2;
  63. return 1;
  64. }
  65. static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
  66. {
  67. DH_PKEY_CTX *dctx = ctx->data;
  68. if (dctx != NULL) {
  69. OPENSSL_free(dctx->kdf_ukm);
  70. ASN1_OBJECT_free(dctx->kdf_oid);
  71. OPENSSL_free(dctx);
  72. }
  73. }
  74. static int pkey_dh_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
  75. {
  76. DH_PKEY_CTX *dctx, *sctx;
  77. if (!pkey_dh_init(dst))
  78. return 0;
  79. sctx = src->data;
  80. dctx = dst->data;
  81. dctx->prime_len = sctx->prime_len;
  82. dctx->subprime_len = sctx->subprime_len;
  83. dctx->generator = sctx->generator;
  84. dctx->paramgen_type = sctx->paramgen_type;
  85. dctx->pad = sctx->pad;
  86. dctx->md = sctx->md;
  87. dctx->param_nid = sctx->param_nid;
  88. dctx->kdf_type = sctx->kdf_type;
  89. dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
  90. if (dctx->kdf_oid == NULL)
  91. return 0;
  92. dctx->kdf_md = sctx->kdf_md;
  93. if (sctx->kdf_ukm != NULL) {
  94. dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
  95. if (dctx->kdf_ukm == NULL)
  96. return 0;
  97. dctx->kdf_ukmlen = sctx->kdf_ukmlen;
  98. }
  99. dctx->kdf_outlen = sctx->kdf_outlen;
  100. return 1;
  101. }
  102. static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
  103. {
  104. DH_PKEY_CTX *dctx = ctx->data;
  105. switch (type) {
  106. case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
  107. if (p1 < 256)
  108. return -2;
  109. dctx->prime_len = p1;
  110. return 1;
  111. case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
  112. if (dctx->paramgen_type == DH_PARAMGEN_TYPE_GENERATOR)
  113. return -2;
  114. dctx->subprime_len = p1;
  115. return 1;
  116. case EVP_PKEY_CTRL_DH_PAD:
  117. dctx->pad = p1;
  118. return 1;
  119. case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
  120. if (dctx->paramgen_type != DH_PARAMGEN_TYPE_GENERATOR)
  121. return -2;
  122. dctx->generator = p1;
  123. return 1;
  124. case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
  125. #ifdef OPENSSL_NO_DSA
  126. if (p1 != DH_PARAMGEN_TYPE_GENERATOR)
  127. return -2;
  128. #else
  129. if (p1 < 0 || p1 > 2)
  130. return -2;
  131. #endif
  132. dctx->paramgen_type = p1;
  133. return 1;
  134. case EVP_PKEY_CTRL_DH_RFC5114:
  135. if (p1 < 1 || p1 > 3 || dctx->param_nid != NID_undef)
  136. return -2;
  137. dctx->param_nid = p1;
  138. return 1;
  139. case EVP_PKEY_CTRL_DH_NID:
  140. if (p1 <= 0 || dctx->param_nid != NID_undef)
  141. return -2;
  142. dctx->param_nid = p1;
  143. return 1;
  144. case EVP_PKEY_CTRL_PEER_KEY:
  145. /* Default behaviour is OK */
  146. return 1;
  147. case EVP_PKEY_CTRL_DH_KDF_TYPE:
  148. if (p1 == -2)
  149. return dctx->kdf_type;
  150. if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
  151. return -2;
  152. dctx->kdf_type = p1;
  153. return 1;
  154. case EVP_PKEY_CTRL_DH_KDF_MD:
  155. dctx->kdf_md = p2;
  156. return 1;
  157. case EVP_PKEY_CTRL_GET_DH_KDF_MD:
  158. *(const EVP_MD **)p2 = dctx->kdf_md;
  159. return 1;
  160. case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
  161. if (p1 <= 0)
  162. return -2;
  163. dctx->kdf_outlen = (size_t)p1;
  164. return 1;
  165. case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
  166. *(int *)p2 = dctx->kdf_outlen;
  167. return 1;
  168. case EVP_PKEY_CTRL_DH_KDF_UKM:
  169. OPENSSL_free(dctx->kdf_ukm);
  170. dctx->kdf_ukm = p2;
  171. if (p2)
  172. dctx->kdf_ukmlen = p1;
  173. else
  174. dctx->kdf_ukmlen = 0;
  175. return 1;
  176. case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
  177. *(unsigned char **)p2 = dctx->kdf_ukm;
  178. return dctx->kdf_ukmlen;
  179. case EVP_PKEY_CTRL_DH_KDF_OID:
  180. ASN1_OBJECT_free(dctx->kdf_oid);
  181. dctx->kdf_oid = p2;
  182. return 1;
  183. case EVP_PKEY_CTRL_GET_DH_KDF_OID:
  184. *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
  185. return 1;
  186. default:
  187. return -2;
  188. }
  189. }
  190. static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
  191. const char *type, const char *value)
  192. {
  193. if (strcmp(type, "dh_paramgen_prime_len") == 0) {
  194. int len;
  195. len = atoi(value);
  196. return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
  197. }
  198. if (strcmp(type, "dh_rfc5114") == 0) {
  199. DH_PKEY_CTX *dctx = ctx->data;
  200. int id;
  201. id = atoi(value);
  202. if (id < 0 || id > 3)
  203. return -2;
  204. dctx->param_nid = id;
  205. return 1;
  206. }
  207. if (strcmp(type, "dh_param") == 0) {
  208. DH_PKEY_CTX *dctx = ctx->data;
  209. int nid = OBJ_sn2nid(value);
  210. if (nid == NID_undef) {
  211. ERR_raise(ERR_LIB_DH, DH_R_INVALID_PARAMETER_NAME);
  212. return -2;
  213. }
  214. dctx->param_nid = nid;
  215. return 1;
  216. }
  217. if (strcmp(type, "dh_paramgen_generator") == 0) {
  218. int len;
  219. len = atoi(value);
  220. return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
  221. }
  222. if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
  223. int len;
  224. len = atoi(value);
  225. return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
  226. }
  227. if (strcmp(type, "dh_paramgen_type") == 0) {
  228. int typ;
  229. typ = atoi(value);
  230. return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
  231. }
  232. if (strcmp(type, "dh_pad") == 0) {
  233. int pad;
  234. pad = atoi(value);
  235. return EVP_PKEY_CTX_set_dh_pad(ctx, pad);
  236. }
  237. return -2;
  238. }
  239. static DH *ffc_params_generate(OSSL_LIB_CTX *libctx, DH_PKEY_CTX *dctx,
  240. BN_GENCB *pcb)
  241. {
  242. DH *ret;
  243. int rv = 0;
  244. int res;
  245. int prime_len = dctx->prime_len;
  246. int subprime_len = dctx->subprime_len;
  247. if (dctx->paramgen_type > DH_PARAMGEN_TYPE_FIPS_186_4)
  248. return NULL;
  249. ret = DH_new();
  250. if (ret == NULL)
  251. return NULL;
  252. if (subprime_len == -1) {
  253. if (prime_len >= 2048)
  254. subprime_len = 256;
  255. else
  256. subprime_len = 160;
  257. }
  258. if (dctx->md != NULL)
  259. ossl_ffc_set_digest(&ret->params, EVP_MD_get0_name(dctx->md), NULL);
  260. # ifndef FIPS_MODULE
  261. if (dctx->paramgen_type == DH_PARAMGEN_TYPE_FIPS_186_2)
  262. rv = ossl_ffc_params_FIPS186_2_generate(libctx, &ret->params,
  263. FFC_PARAM_TYPE_DH,
  264. prime_len, subprime_len, &res,
  265. pcb);
  266. else
  267. # endif
  268. /* For FIPS we always use the DH_PARAMGEN_TYPE_FIPS_186_4 generator */
  269. if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2)
  270. rv = ossl_ffc_params_FIPS186_4_generate(libctx, &ret->params,
  271. FFC_PARAM_TYPE_DH,
  272. prime_len, subprime_len, &res,
  273. pcb);
  274. if (rv <= 0) {
  275. DH_free(ret);
  276. return NULL;
  277. }
  278. return ret;
  279. }
  280. static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx,
  281. EVP_PKEY *pkey)
  282. {
  283. DH *dh = NULL;
  284. DH_PKEY_CTX *dctx = ctx->data;
  285. BN_GENCB *pcb = NULL;
  286. int ret;
  287. /*
  288. * Look for a safe prime group for key establishment. Which uses
  289. * either RFC_3526 (modp_XXXX) or RFC_7919 (ffdheXXXX).
  290. * RFC_5114 is also handled here for param_nid = (1..3)
  291. */
  292. if (dctx->param_nid != NID_undef) {
  293. int type = dctx->param_nid <= 3 ? EVP_PKEY_DHX : EVP_PKEY_DH;
  294. if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
  295. return 0;
  296. EVP_PKEY_assign(pkey, type, dh);
  297. return 1;
  298. }
  299. if (ctx->pkey_gencb != NULL) {
  300. pcb = BN_GENCB_new();
  301. if (pcb == NULL)
  302. return 0;
  303. evp_pkey_set_cb_translate(pcb, ctx);
  304. }
  305. # ifdef FIPS_MODULE
  306. dctx->paramgen_type = DH_PARAMGEN_TYPE_FIPS_186_4;
  307. # endif /* FIPS_MODULE */
  308. if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2) {
  309. dh = ffc_params_generate(NULL, dctx, pcb);
  310. BN_GENCB_free(pcb);
  311. if (dh == NULL)
  312. return 0;
  313. EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
  314. return 1;
  315. }
  316. dh = DH_new();
  317. if (dh == NULL) {
  318. BN_GENCB_free(pcb);
  319. return 0;
  320. }
  321. ret = DH_generate_parameters_ex(dh,
  322. dctx->prime_len, dctx->generator, pcb);
  323. BN_GENCB_free(pcb);
  324. if (ret)
  325. EVP_PKEY_assign_DH(pkey, dh);
  326. else
  327. DH_free(dh);
  328. return ret;
  329. }
  330. static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
  331. {
  332. DH_PKEY_CTX *dctx = ctx->data;
  333. DH *dh = NULL;
  334. if (ctx->pkey == NULL && dctx->param_nid == NID_undef) {
  335. ERR_raise(ERR_LIB_DH, DH_R_NO_PARAMETERS_SET);
  336. return 0;
  337. }
  338. if (dctx->param_nid != NID_undef)
  339. dh = DH_new_by_nid(dctx->param_nid);
  340. else
  341. dh = DH_new();
  342. if (dh == NULL)
  343. return 0;
  344. EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
  345. /* Note: if error return, pkey is freed by parent routine */
  346. if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
  347. return 0;
  348. return DH_generate_key(pkey->pkey.dh);
  349. }
  350. static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
  351. size_t *keylen)
  352. {
  353. int ret;
  354. DH *dh;
  355. const DH *dhpub;
  356. DH_PKEY_CTX *dctx = ctx->data;
  357. BIGNUM *dhpubbn;
  358. if (ctx->pkey == NULL || ctx->peerkey == NULL) {
  359. ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET);
  360. return 0;
  361. }
  362. dh = ctx->pkey->pkey.dh;
  363. dhpub = EVP_PKEY_get0_DH(ctx->peerkey);
  364. if (dhpub == NULL) {
  365. ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET);
  366. return 0;
  367. }
  368. dhpubbn = dhpub->pub_key;
  369. if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
  370. if (key == NULL) {
  371. *keylen = DH_size(dh);
  372. return 1;
  373. }
  374. if (dctx->pad)
  375. ret = DH_compute_key_padded(key, dhpubbn, dh);
  376. else
  377. ret = DH_compute_key(key, dhpubbn, dh);
  378. if (ret < 0)
  379. return ret;
  380. *keylen = ret;
  381. return 1;
  382. }
  383. else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
  384. unsigned char *Z = NULL;
  385. size_t Zlen = 0;
  386. if (!dctx->kdf_outlen || !dctx->kdf_oid)
  387. return 0;
  388. if (key == NULL) {
  389. *keylen = dctx->kdf_outlen;
  390. return 1;
  391. }
  392. if (*keylen != dctx->kdf_outlen)
  393. return 0;
  394. ret = 0;
  395. if ((Zlen = DH_size(dh)) <= 0)
  396. return 0;
  397. if ((Z = OPENSSL_malloc(Zlen)) == NULL) {
  398. ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
  399. return 0;
  400. }
  401. if (DH_compute_key_padded(Z, dhpubbn, dh) <= 0)
  402. goto err;
  403. if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
  404. dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
  405. goto err;
  406. *keylen = dctx->kdf_outlen;
  407. ret = 1;
  408. err:
  409. OPENSSL_clear_free(Z, Zlen);
  410. return ret;
  411. }
  412. return 0;
  413. }
  414. static const EVP_PKEY_METHOD dh_pkey_meth = {
  415. EVP_PKEY_DH,
  416. 0,
  417. pkey_dh_init,
  418. pkey_dh_copy,
  419. pkey_dh_cleanup,
  420. 0,
  421. pkey_dh_paramgen,
  422. 0,
  423. pkey_dh_keygen,
  424. 0,
  425. 0,
  426. 0,
  427. 0,
  428. 0, 0,
  429. 0, 0, 0, 0,
  430. 0, 0,
  431. 0, 0,
  432. 0,
  433. pkey_dh_derive,
  434. pkey_dh_ctrl,
  435. pkey_dh_ctrl_str
  436. };
  437. const EVP_PKEY_METHOD *ossl_dh_pkey_method(void)
  438. {
  439. return &dh_pkey_meth;
  440. }
  441. static const EVP_PKEY_METHOD dhx_pkey_meth = {
  442. EVP_PKEY_DHX,
  443. 0,
  444. pkey_dh_init,
  445. pkey_dh_copy,
  446. pkey_dh_cleanup,
  447. 0,
  448. pkey_dh_paramgen,
  449. 0,
  450. pkey_dh_keygen,
  451. 0,
  452. 0,
  453. 0,
  454. 0,
  455. 0, 0,
  456. 0, 0, 0, 0,
  457. 0, 0,
  458. 0, 0,
  459. 0,
  460. pkey_dh_derive,
  461. pkey_dh_ctrl,
  462. pkey_dh_ctrl_str
  463. };
  464. const EVP_PKEY_METHOD *ossl_dhx_pkey_method(void)
  465. {
  466. return &dhx_pkey_meth;
  467. }