dh_pmeth.c revision 337982
1/* 2 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 3 * 2006. 4 */ 5/* ==================================================================== 6 * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 59#include <stdio.h> 60#include "cryptlib.h" 61#include <openssl/asn1t.h> 62#include <openssl/x509.h> 63#include <openssl/evp.h> 64#include <openssl/dh.h> 65#include <openssl/bn.h> 66#ifndef OPENSSL_NO_DSA 67# include <openssl/dsa.h> 68#endif 69#include <openssl/objects.h> 70#include "evp_locl.h" 71 72/* DH pkey context structure */ 73 74typedef struct { 75 /* Parameter gen parameters */ 76 int prime_len; 77 int generator; 78 int use_dsa; 79 int subprime_len; 80 /* message digest used for parameter generation */ 81 const EVP_MD *md; 82 int rfc5114_param; 83 /* Keygen callback info */ 84 int gentmp[2]; 85 /* KDF (if any) to use for DH */ 86 char kdf_type; 87 /* OID to use for KDF */ 88 ASN1_OBJECT *kdf_oid; 89 /* Message digest to use for key derivation */ 90 const EVP_MD *kdf_md; 91 /* User key material */ 92 unsigned char *kdf_ukm; 93 size_t kdf_ukmlen; 94 /* KDF output length */ 95 size_t kdf_outlen; 96} DH_PKEY_CTX; 97 98static int pkey_dh_init(EVP_PKEY_CTX *ctx) 99{ 100 DH_PKEY_CTX *dctx; 101 dctx = OPENSSL_malloc(sizeof(DH_PKEY_CTX)); 102 if (!dctx) 103 return 0; 104 dctx->prime_len = 1024; 105 dctx->subprime_len = -1; 106 dctx->generator = 2; 107 dctx->use_dsa = 0; 108 dctx->md = NULL; 109 dctx->rfc5114_param = 0; 110 111 dctx->kdf_type = EVP_PKEY_DH_KDF_NONE; 112 dctx->kdf_oid = NULL; 113 dctx->kdf_md = NULL; 114 dctx->kdf_ukm = NULL; 115 dctx->kdf_ukmlen = 0; 116 dctx->kdf_outlen = 0; 117 118 ctx->data = dctx; 119 ctx->keygen_info = dctx->gentmp; 120 ctx->keygen_info_count = 2; 121 122 return 1; 123} 124 125static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) 126{ 127 DH_PKEY_CTX *dctx, *sctx; 128 if (!pkey_dh_init(dst)) 129 return 0; 130 sctx = src->data; 131 dctx = dst->data; 132 dctx->prime_len = sctx->prime_len; 133 dctx->subprime_len = sctx->subprime_len; 134 dctx->generator = sctx->generator; 135 dctx->use_dsa = sctx->use_dsa; 136 dctx->md = sctx->md; 137 dctx->rfc5114_param = sctx->rfc5114_param; 138 139 dctx->kdf_type = sctx->kdf_type; 140 dctx->kdf_oid = OBJ_dup(sctx->kdf_oid); 141 if (!dctx->kdf_oid) 142 return 0; 143 dctx->kdf_md = sctx->kdf_md; 144 if (dctx->kdf_ukm) { 145 dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen); 146 dctx->kdf_ukmlen = sctx->kdf_ukmlen; 147 } 148 dctx->kdf_outlen = sctx->kdf_outlen; 149 return 1; 150} 151 152static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx) 153{ 154 DH_PKEY_CTX *dctx = ctx->data; 155 if (dctx) { 156 if (dctx->kdf_ukm) 157 OPENSSL_free(dctx->kdf_ukm); 158 if (dctx->kdf_oid) 159 ASN1_OBJECT_free(dctx->kdf_oid); 160 OPENSSL_free(dctx); 161 } 162} 163 164static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 165{ 166 DH_PKEY_CTX *dctx = ctx->data; 167 switch (type) { 168 case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN: 169 if (p1 < 256) 170 return -2; 171 dctx->prime_len = p1; 172 return 1; 173 174 case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN: 175 if (dctx->use_dsa == 0) 176 return -2; 177 dctx->subprime_len = p1; 178 return 1; 179 180 case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR: 181 if (dctx->use_dsa) 182 return -2; 183 dctx->generator = p1; 184 return 1; 185 186 case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE: 187#ifdef OPENSSL_NO_DSA 188 if (p1 != 0) 189 return -2; 190#else 191 if (p1 < 0 || p1 > 2) 192 return -2; 193#endif 194 dctx->use_dsa = p1; 195 return 1; 196 197 case EVP_PKEY_CTRL_DH_RFC5114: 198 if (p1 < 1 || p1 > 3) 199 return -2; 200 dctx->rfc5114_param = p1; 201 return 1; 202 203 case EVP_PKEY_CTRL_PEER_KEY: 204 /* Default behaviour is OK */ 205 return 1; 206 207 case EVP_PKEY_CTRL_DH_KDF_TYPE: 208 if (p1 == -2) 209 return dctx->kdf_type; 210#ifdef OPENSSL_NO_CMS 211 if (p1 != EVP_PKEY_DH_KDF_NONE) 212#else 213 if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42) 214#endif 215 return -2; 216 dctx->kdf_type = p1; 217 return 1; 218 219 case EVP_PKEY_CTRL_DH_KDF_MD: 220 dctx->kdf_md = p2; 221 return 1; 222 223 case EVP_PKEY_CTRL_GET_DH_KDF_MD: 224 *(const EVP_MD **)p2 = dctx->kdf_md; 225 return 1; 226 227 case EVP_PKEY_CTRL_DH_KDF_OUTLEN: 228 if (p1 <= 0) 229 return -2; 230 dctx->kdf_outlen = (size_t)p1; 231 return 1; 232 233 case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN: 234 *(int *)p2 = dctx->kdf_outlen; 235 return 1; 236 237 case EVP_PKEY_CTRL_DH_KDF_UKM: 238 if (dctx->kdf_ukm) 239 OPENSSL_free(dctx->kdf_ukm); 240 dctx->kdf_ukm = p2; 241 if (p2) 242 dctx->kdf_ukmlen = p1; 243 else 244 dctx->kdf_ukmlen = 0; 245 return 1; 246 247 case EVP_PKEY_CTRL_GET_DH_KDF_UKM: 248 *(unsigned char **)p2 = dctx->kdf_ukm; 249 return dctx->kdf_ukmlen; 250 251 case EVP_PKEY_CTRL_DH_KDF_OID: 252 if (dctx->kdf_oid) 253 ASN1_OBJECT_free(dctx->kdf_oid); 254 dctx->kdf_oid = p2; 255 return 1; 256 257 case EVP_PKEY_CTRL_GET_DH_KDF_OID: 258 *(ASN1_OBJECT **)p2 = dctx->kdf_oid; 259 return 1; 260 261 default: 262 return -2; 263 264 } 265} 266 267static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, 268 const char *type, const char *value) 269{ 270 if (!strcmp(type, "dh_paramgen_prime_len")) { 271 int len; 272 len = atoi(value); 273 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len); 274 } 275 if (!strcmp(type, "dh_rfc5114")) { 276 DH_PKEY_CTX *dctx = ctx->data; 277 int len; 278 len = atoi(value); 279 if (len < 0 || len > 3) 280 return -2; 281 dctx->rfc5114_param = len; 282 return 1; 283 } 284 if (!strcmp(type, "dh_paramgen_generator")) { 285 int len; 286 len = atoi(value); 287 return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len); 288 } 289 if (!strcmp(type, "dh_paramgen_subprime_len")) { 290 int len; 291 len = atoi(value); 292 return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len); 293 } 294 if (!strcmp(type, "dh_paramgen_type")) { 295 int typ; 296 typ = atoi(value); 297 return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ); 298 } 299 return -2; 300} 301 302#ifndef OPENSSL_NO_DSA 303 304extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, 305 const EVP_MD *evpmd, 306 const unsigned char *seed_in, size_t seed_len, 307 unsigned char *seed_out, int *counter_ret, 308 unsigned long *h_ret, BN_GENCB *cb); 309 310extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, 311 const EVP_MD *evpmd, 312 const unsigned char *seed_in, 313 size_t seed_len, int idx, 314 unsigned char *seed_out, int *counter_ret, 315 unsigned long *h_ret, BN_GENCB *cb); 316 317static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb) 318{ 319 DSA *ret; 320 int rv = 0; 321 int prime_len = dctx->prime_len; 322 int subprime_len = dctx->subprime_len; 323 const EVP_MD *md = dctx->md; 324 if (dctx->use_dsa > 2) 325 return NULL; 326 ret = DSA_new(); 327 if (!ret) 328 return NULL; 329 if (subprime_len == -1) { 330 if (prime_len >= 2048) 331 subprime_len = 256; 332 else 333 subprime_len = 160; 334 } 335 if (md == NULL) { 336 if (prime_len >= 2048) 337 md = EVP_sha256(); 338 else 339 md = EVP_sha1(); 340 } 341 if (dctx->use_dsa == 1) 342 rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md, 343 NULL, 0, NULL, NULL, NULL, pcb); 344 else if (dctx->use_dsa == 2) 345 rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md, 346 NULL, 0, -1, NULL, NULL, NULL, pcb); 347 if (rv <= 0) { 348 DSA_free(ret); 349 return NULL; 350 } 351 return ret; 352} 353 354#endif 355 356static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 357{ 358 DH *dh = NULL; 359 DH_PKEY_CTX *dctx = ctx->data; 360 BN_GENCB *pcb, cb; 361 int ret; 362 if (dctx->rfc5114_param) { 363 switch (dctx->rfc5114_param) { 364 case 1: 365 dh = DH_get_1024_160(); 366 break; 367 368 case 2: 369 dh = DH_get_2048_224(); 370 break; 371 372 case 3: 373 dh = DH_get_2048_256(); 374 break; 375 376 default: 377 return -2; 378 } 379 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh); 380 return 1; 381 } 382 383 if (ctx->pkey_gencb) { 384 pcb = &cb; 385 evp_pkey_set_cb_translate(pcb, ctx); 386 } else 387 pcb = NULL; 388#ifndef OPENSSL_NO_DSA 389 if (dctx->use_dsa) { 390 DSA *dsa_dh; 391 dsa_dh = dsa_dh_generate(dctx, pcb); 392 if (!dsa_dh) 393 return 0; 394 dh = DSA_dup_DH(dsa_dh); 395 DSA_free(dsa_dh); 396 if (!dh) 397 return 0; 398 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh); 399 return 1; 400 } 401#endif 402 dh = DH_new(); 403 if (!dh) 404 return 0; 405 ret = DH_generate_parameters_ex(dh, 406 dctx->prime_len, dctx->generator, pcb); 407 408 if (ret) 409 EVP_PKEY_assign_DH(pkey, dh); 410 else 411 DH_free(dh); 412 return ret; 413} 414 415static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 416{ 417 DH *dh = NULL; 418 if (ctx->pkey == NULL) { 419 DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET); 420 return 0; 421 } 422 dh = DH_new(); 423 if (!dh) 424 return 0; 425 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh); 426 /* Note: if error return, pkey is freed by parent routine */ 427 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) 428 return 0; 429 return DH_generate_key(pkey->pkey.dh); 430} 431 432static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, 433 size_t *keylen) 434{ 435 int ret; 436 DH *dh; 437 DH_PKEY_CTX *dctx = ctx->data; 438 BIGNUM *dhpub; 439 if (!ctx->pkey || !ctx->peerkey) { 440 DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET); 441 return 0; 442 } 443 dh = ctx->pkey->pkey.dh; 444 dhpub = ctx->peerkey->pkey.dh->pub_key; 445 if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) { 446 if (key == NULL) { 447 *keylen = DH_size(dh); 448 return 1; 449 } 450 ret = DH_compute_key(key, dhpub, dh); 451 if (ret < 0) 452 return ret; 453 *keylen = ret; 454 return 1; 455 } 456#ifndef OPENSSL_NO_CMS 457 else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) { 458 unsigned char *Z = NULL; 459 size_t Zlen = 0; 460 if (!dctx->kdf_outlen || !dctx->kdf_oid) 461 return 0; 462 if (key == NULL) { 463 *keylen = dctx->kdf_outlen; 464 return 1; 465 } 466 if (*keylen != dctx->kdf_outlen) 467 return 0; 468 ret = 0; 469 Zlen = DH_size(dh); 470 Z = OPENSSL_malloc(Zlen); 471 if (!Z) { 472 goto err; 473 } 474 if (DH_compute_key_padded(Z, dhpub, dh) <= 0) 475 goto err; 476 if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid, 477 dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md)) 478 goto err; 479 *keylen = dctx->kdf_outlen; 480 ret = 1; 481 err: 482 if (Z) { 483 OPENSSL_cleanse(Z, Zlen); 484 OPENSSL_free(Z); 485 } 486 return ret; 487 } 488#endif 489 return 0; 490} 491 492const EVP_PKEY_METHOD dh_pkey_meth = { 493 EVP_PKEY_DH, 494 0, 495 pkey_dh_init, 496 pkey_dh_copy, 497 pkey_dh_cleanup, 498 499 0, 500 pkey_dh_paramgen, 501 502 0, 503 pkey_dh_keygen, 504 505 0, 506 0, 507 508 0, 509 0, 510 511 0, 0, 512 513 0, 0, 0, 0, 514 515 0, 0, 516 517 0, 0, 518 519 0, 520 pkey_dh_derive, 521 522 pkey_dh_ctrl, 523 pkey_dh_ctrl_str 524}; 525 526const EVP_PKEY_METHOD dhx_pkey_meth = { 527 EVP_PKEY_DHX, 528 0, 529 pkey_dh_init, 530 pkey_dh_copy, 531 pkey_dh_cleanup, 532 533 0, 534 pkey_dh_paramgen, 535 536 0, 537 pkey_dh_keygen, 538 539 0, 540 0, 541 542 0, 543 0, 544 545 0, 0, 546 547 0, 0, 0, 0, 548 549 0, 0, 550 551 0, 0, 552 553 0, 554 pkey_dh_derive, 555 556 pkey_dh_ctrl, 557 pkey_dh_ctrl_str 558}; 559