1/* $NetBSD: openssldh_link.c,v 1.10 2024/02/21 22:52:07 christos Exp $ */ 2 3/* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 AND ISC 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16/* 17 * Copyright (C) Network Associates, Inc. 18 * 19 * Permission to use, copy, modify, and/or distribute this software for any 20 * purpose with or without fee is hereby granted, provided that the above 21 * copyright notice and this permission notice appear in all copies. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS 24 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE 26 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 27 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 28 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 29 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 30 */ 31 32/*! \file */ 33 34#include <ctype.h> 35#include <inttypes.h> 36#include <stdbool.h> 37 38#include <openssl/bn.h> 39#include <openssl/opensslv.h> 40#if OPENSSL_VERSION_NUMBER >= 0x30000000L 41#include <openssl/core_names.h> 42#endif 43#include <openssl/err.h> 44#include <openssl/objects.h> 45#if OPENSSL_VERSION_NUMBER >= 0x30000000L 46#include <openssl/param_build.h> 47#endif 48#include <openssl/dh.h> 49 50#include <isc/mem.h> 51#include <isc/result.h> 52#include <isc/safe.h> 53#include <isc/string.h> 54#include <isc/util.h> 55 56#include "dst_internal.h" 57#include "dst_openssl.h" 58#include "dst_parse.h" 59#include "openssl_shim.h" 60 61#define PRIME2 "02" 62 63#define PRIME768 \ 64 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088" \ 65 "A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25" \ 66 "F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFF" \ 67 "F" 68 69#define PRIME1024 \ 70 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08" \ 71 "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF2" \ 72 "5F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406" \ 73 "B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF" 74 75#define PRIME1536 \ 76 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ 77 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ 78 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ 79 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ 80 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ 81 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ 82 "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ 83 "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF" 84 85#define DST_RET(a) \ 86 { \ 87 ret = a; \ 88 goto err; \ 89 } 90 91static BIGNUM *bn2 = NULL, *bn768 = NULL, *bn1024 = NULL, *bn1536 = NULL; 92 93static isc_result_t 94openssldh_computesecret(const dst_key_t *pub, const dst_key_t *priv, 95 isc_buffer_t *secret) { 96#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 97 DH *dhpub, *dhpriv; 98 const BIGNUM *pub_key = NULL; 99 int secret_len = 0; 100#else 101 EVP_PKEY_CTX *ctx = NULL; 102 EVP_PKEY *dhpub, *dhpriv; 103 size_t secret_len = 0; 104#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 105 isc_region_t r; 106 unsigned int len; 107 108#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 109 REQUIRE(pub->keydata.dh != NULL); 110 REQUIRE(priv->keydata.dh != NULL); 111 112 dhpub = pub->keydata.dh; 113 dhpriv = priv->keydata.dh; 114 115 len = DH_size(dhpriv); 116#else 117 REQUIRE(pub->keydata.pkey != NULL); 118 REQUIRE(priv->keydata.pkey != NULL); 119 120 dhpub = pub->keydata.pkey; 121 dhpriv = priv->keydata.pkey; 122 123 len = EVP_PKEY_get_size(dhpriv); 124#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 125 126 isc_buffer_availableregion(secret, &r); 127 if (r.length < len) { 128 return (ISC_R_NOSPACE); 129 } 130 131#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 132 DH_get0_key(dhpub, &pub_key, NULL); 133 secret_len = DH_compute_key(r.base, pub_key, dhpriv); 134 if (secret_len <= 0) { 135 return (dst__openssl_toresult2("DH_compute_key", 136 DST_R_COMPUTESECRETFAILURE)); 137 } 138#else 139 ctx = EVP_PKEY_CTX_new_from_pkey(NULL, dhpriv, NULL); 140 if (ctx == NULL) { 141 return (dst__openssl_toresult2("EVP_PKEY_CTX_new_from_pkey", 142 DST_R_OPENSSLFAILURE)); 143 } 144 if (EVP_PKEY_derive_init(ctx) != 1) { 145 EVP_PKEY_CTX_free(ctx); 146 return (dst__openssl_toresult2("EVP_PKEY_derive_init", 147 DST_R_OPENSSLFAILURE)); 148 } 149 if (EVP_PKEY_derive_set_peer(ctx, dhpub) != 1) { 150 EVP_PKEY_CTX_free(ctx); 151 return (dst__openssl_toresult2("EVP_PKEY_derive_set_peer", 152 DST_R_OPENSSLFAILURE)); 153 } 154 secret_len = r.length; 155 if (EVP_PKEY_derive(ctx, r.base, &secret_len) != 1 || secret_len == 0) { 156 EVP_PKEY_CTX_free(ctx); 157 return (dst__openssl_toresult2("EVP_PKEY_derive", 158 DST_R_COMPUTESECRETFAILURE)); 159 } 160 EVP_PKEY_CTX_free(ctx); 161#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 162 163 isc_buffer_add(secret, (unsigned int)secret_len); 164 165 return (ISC_R_SUCCESS); 166} 167 168static bool 169openssldh_compare(const dst_key_t *key1, const dst_key_t *key2) { 170 bool ret = true; 171#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 172 DH *dh1, *dh2; 173 const BIGNUM *pub_key1 = NULL, *pub_key2 = NULL; 174 const BIGNUM *priv_key1 = NULL, *priv_key2 = NULL; 175 const BIGNUM *p1 = NULL, *g1 = NULL, *p2 = NULL, *g2 = NULL; 176#else 177 EVP_PKEY *pkey1, *pkey2; 178 BIGNUM *pub_key1 = NULL, *pub_key2 = NULL; 179 BIGNUM *priv_key1 = NULL, *priv_key2 = NULL; 180 BIGNUM *p1 = NULL, *g1 = NULL, *p2 = NULL, *g2 = NULL; 181#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 182 183#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 184 dh1 = key1->keydata.dh; 185 dh2 = key2->keydata.dh; 186 187 if (dh1 == NULL && dh2 == NULL) { 188 return (true); 189 } else if (dh1 == NULL || dh2 == NULL) { 190 return (false); 191 } 192 193 DH_get0_key(dh1, &pub_key1, &priv_key1); 194 DH_get0_key(dh2, &pub_key2, &priv_key2); 195 DH_get0_pqg(dh1, &p1, NULL, &g1); 196 DH_get0_pqg(dh2, &p2, NULL, &g2); 197#else 198 pkey1 = key1->keydata.pkey; 199 pkey2 = key2->keydata.pkey; 200 201 if (pkey1 == NULL && pkey2 == NULL) { 202 return (true); 203 } else if (pkey1 == NULL || pkey2 == NULL) { 204 return (false); 205 } 206 207 EVP_PKEY_get_bn_param(pkey1, OSSL_PKEY_PARAM_FFC_P, &p1); 208 EVP_PKEY_get_bn_param(pkey2, OSSL_PKEY_PARAM_FFC_P, &p2); 209 EVP_PKEY_get_bn_param(pkey1, OSSL_PKEY_PARAM_FFC_G, &g1); 210 EVP_PKEY_get_bn_param(pkey2, OSSL_PKEY_PARAM_FFC_G, &g2); 211 EVP_PKEY_get_bn_param(pkey1, OSSL_PKEY_PARAM_PUB_KEY, &pub_key1); 212 EVP_PKEY_get_bn_param(pkey2, OSSL_PKEY_PARAM_PUB_KEY, &pub_key2); 213 EVP_PKEY_get_bn_param(pkey1, OSSL_PKEY_PARAM_PRIV_KEY, &priv_key1); 214 EVP_PKEY_get_bn_param(pkey2, OSSL_PKEY_PARAM_PRIV_KEY, &priv_key2); 215#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000*/ 216 217 if (BN_cmp(p1, p2) != 0 || BN_cmp(g1, g2) != 0 || 218 BN_cmp(pub_key1, pub_key2) != 0) 219 { 220 DST_RET(false); 221 } 222 223 if (priv_key1 != NULL || priv_key2 != NULL) { 224 if (priv_key1 == NULL || priv_key2 == NULL || 225 BN_cmp(priv_key1, priv_key2) != 0) 226 { 227 DST_RET(false); 228 } 229 } 230 231err: 232#if OPENSSL_VERSION_NUMBER >= 0x30000000L && OPENSSL_API_LEVEL >= 30000 233 if (p1 != NULL) { 234 BN_free(p1); 235 } 236 if (p2 != NULL) { 237 BN_free(p2); 238 } 239 if (g1 != NULL) { 240 BN_free(g1); 241 } 242 if (g2 != NULL) { 243 BN_free(g2); 244 } 245 if (pub_key1 != NULL) { 246 BN_free(pub_key1); 247 } 248 if (pub_key2 != NULL) { 249 BN_free(pub_key2); 250 } 251 if (priv_key1 != NULL) { 252 BN_clear_free(priv_key1); 253 } 254 if (priv_key2 != NULL) { 255 BN_clear_free(priv_key2); 256 } 257#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L && OPENSSL_API_LEVEL >= 30000 \ 258 */ 259 260 return (ret); 261} 262 263static bool 264openssldh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) { 265 bool ret = true; 266#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 267 DH *dh1, *dh2; 268 const BIGNUM *p1 = NULL, *g1 = NULL, *p2 = NULL, *g2 = NULL; 269#else 270 EVP_PKEY *pkey1, *pkey2; 271 BIGNUM *p1 = NULL, *g1 = NULL, *p2 = NULL, *g2 = NULL; 272#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 273 274#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 275 dh1 = key1->keydata.dh; 276 dh2 = key2->keydata.dh; 277 278 if (dh1 == NULL && dh2 == NULL) { 279 return (true); 280 } else if (dh1 == NULL || dh2 == NULL) { 281 return (false); 282 } 283 284 DH_get0_pqg(dh1, &p1, NULL, &g1); 285 DH_get0_pqg(dh2, &p2, NULL, &g2); 286#else 287 pkey1 = key1->keydata.pkey; 288 pkey2 = key2->keydata.pkey; 289 290 if (pkey1 == NULL && pkey2 == NULL) { 291 return (true); 292 } else if (pkey1 == NULL || pkey2 == NULL) { 293 return (false); 294 } 295 296 EVP_PKEY_get_bn_param(pkey1, OSSL_PKEY_PARAM_FFC_P, &p1); 297 EVP_PKEY_get_bn_param(pkey2, OSSL_PKEY_PARAM_FFC_P, &p2); 298 EVP_PKEY_get_bn_param(pkey1, OSSL_PKEY_PARAM_FFC_G, &g1); 299 EVP_PKEY_get_bn_param(pkey2, OSSL_PKEY_PARAM_FFC_G, &g2); 300#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 301 302 if (BN_cmp(p1, p2) != 0 || BN_cmp(g1, g2) != 0) { 303 DST_RET(false); 304 } 305 306err: 307#if OPENSSL_VERSION_NUMBER >= 0x30000000L && OPENSSL_API_LEVEL >= 30000 308 if (p1 != NULL) { 309 BN_free(p1); 310 } 311 if (p2 != NULL) { 312 BN_free(p2); 313 } 314 if (g1 != NULL) { 315 BN_free(g1); 316 } 317 if (g2 != NULL) { 318 BN_free(g2); 319 } 320#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L && OPENSSL_API_LEVEL >= 30000 \ 321 */ 322 323 return (ret); 324} 325 326#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 327static int 328progress_cb(int p, int n, BN_GENCB *cb) { 329 union { 330 void *dptr; 331 void (*fptr)(int); 332 } u; 333 334 UNUSED(n); 335 336 u.dptr = BN_GENCB_get_arg(cb); 337 if (u.fptr != NULL) { 338 u.fptr(p); 339 } 340 return (1); 341} 342#else 343static int 344progress_cb(EVP_PKEY_CTX *ctx) { 345 union { 346 void *dptr; 347 void (*fptr)(int); 348 } u; 349 350 u.dptr = EVP_PKEY_CTX_get_app_data(ctx); 351 if (u.fptr != NULL) { 352 int p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); 353 u.fptr(p); 354 } 355 return (1); 356} 357#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 358 359static isc_result_t 360openssldh_generate(dst_key_t *key, int generator, void (*callback)(int)) { 361 isc_result_t ret; 362 union { 363 void *dptr; 364 void (*fptr)(int); 365 } u; 366 BIGNUM *p = NULL, *g = NULL; 367#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 368 DH *dh = NULL; 369 BN_GENCB *cb = NULL; 370#if !HAVE_BN_GENCB_NEW 371 BN_GENCB _cb; 372#endif /* !HAVE_BN_GENCB_NEW */ 373#else 374 OSSL_PARAM_BLD *bld = NULL; 375 OSSL_PARAM *params = NULL; 376 EVP_PKEY_CTX *param_ctx = NULL; 377 EVP_PKEY_CTX *ctx = NULL; 378 EVP_PKEY *param_pkey = NULL; 379 EVP_PKEY *pkey = NULL; 380#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 381 382#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 383 dh = DH_new(); 384 if (dh == NULL) { 385 DST_RET(dst__openssl_toresult(ISC_R_NOMEMORY)); 386 } 387#else 388 bld = OSSL_PARAM_BLD_new(); 389 if (bld == NULL) { 390 DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); 391 } 392 param_ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL); 393 if (param_ctx == NULL) { 394 DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); 395 } 396#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 397 398 if (generator == 0) { 399 /* 400 * When `generator` is 0, we have three pre-computed `p` and `g` 401 * static parameters which we can use. 402 */ 403 if (key->key_size == 768 || key->key_size == 1024 || 404 key->key_size == 1536) 405 { 406 if (key->key_size == 768) { 407 p = BN_dup(bn768); 408 } else if (key->key_size == 1024) { 409 p = BN_dup(bn1024); 410 } else { 411 p = BN_dup(bn1536); 412 } 413 g = BN_dup(bn2); 414 if (p == NULL || g == NULL) { 415 DST_RET(dst__openssl_toresult(ISC_R_NOMEMORY)); 416 } 417#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 418 if (DH_set0_pqg(dh, p, NULL, g) != 1) { 419 DST_RET(dst__openssl_toresult2( 420 "DH_set0_pqg", DST_R_OPENSSLFAILURE)); 421 } 422#else 423 if (OSSL_PARAM_BLD_push_uint(bld, 424 OSSL_PKEY_PARAM_FFC_PBITS, 425 key->key_size) != 1) 426 { 427 DST_RET(dst__openssl_toresult2( 428 "OSSL_PARAM_BLD_push_uint", 429 DST_R_OPENSSLFAILURE)); 430 } 431 if (OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P, 432 p) != 1 || 433 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_G, 434 g) != 1) 435 { 436 DST_RET(dst__openssl_toresult2( 437 "OSSL_PARAM_BLD_push_BN", 438 DST_R_OPENSSLFAILURE)); 439 } 440 params = OSSL_PARAM_BLD_to_param(bld); 441#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 442 443 } else { 444 /* 445 * If the requested size is not present in our 446 * pre-computed set, we will use `generator` 2 to 447 * generate new parameters. 448 */ 449 generator = 2; 450 } 451 } 452 453 if (generator != 0) { 454#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 455 cb = BN_GENCB_new(); 456#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) 457 if (cb == NULL) { 458 DST_RET(dst__openssl_toresult(ISC_R_NOMEMORY)); 459 } 460#endif /* if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ 461 * !defined(LIBRESSL_VERSION_NUMBER) */ 462 if (callback == NULL) { 463 BN_GENCB_set_old(cb, NULL, NULL); 464 } else { 465 u.fptr = callback; 466 BN_GENCB_set(cb, progress_cb, u.dptr); 467 } 468 469 if (!DH_generate_parameters_ex(dh, key->key_size, generator, 470 cb)) 471 { 472 DST_RET(dst__openssl_toresult2("DH_generate_parameters_" 473 "ex", 474 DST_R_OPENSSLFAILURE)); 475 } 476#else 477 if (OSSL_PARAM_BLD_push_int(bld, OSSL_PKEY_PARAM_DH_GENERATOR, 478 generator) != 1) 479 { 480 DST_RET(dst__openssl_toresult2("OSSL_PARAM_BLD_push_" 481 "int", 482 DST_R_OPENSSLFAILURE)); 483 } 484 if (OSSL_PARAM_BLD_push_utf8_string( 485 bld, OSSL_PKEY_PARAM_FFC_TYPE, "generator", 0) != 1) 486 { 487 DST_RET(dst__openssl_toresult2("OSSL_PARAM_BLD_push_" 488 "utf8_string", 489 DST_R_OPENSSLFAILURE)); 490 } 491 if (OSSL_PARAM_BLD_push_uint(bld, OSSL_PKEY_PARAM_FFC_PBITS, 492 key->key_size) != 1) 493 { 494 DST_RET(dst__openssl_toresult2("OSSL_PARAM_BLD_push_" 495 "uint", 496 DST_R_OPENSSLFAILURE)); 497 } 498 params = OSSL_PARAM_BLD_to_param(bld); 499#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 500 } 501 502#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 503 if (DH_generate_key(dh) == 0) { 504 DST_RET(dst__openssl_toresult2("DH_generate_key", 505 DST_R_OPENSSLFAILURE)); 506 } 507 DH_clear_flags(dh, DH_FLAG_CACHE_MONT_P); 508 key->keydata.dh = dh; 509 dh = NULL; 510#else 511 if (params == NULL) { 512 DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); 513 } 514 515 if (generator == 0) { 516 if (EVP_PKEY_fromdata_init(param_ctx) != 1) { 517 DST_RET(dst__openssl_toresult2("EVP_PKEY_fromdata_init", 518 DST_R_OPENSSLFAILURE)); 519 } 520 if (EVP_PKEY_fromdata(param_ctx, ¶m_pkey, 521 OSSL_KEYMGMT_SELECT_ALL, params) != 1 || 522 param_pkey == NULL) 523 { 524 DST_RET(dst__openssl_toresult2("EVP_PKEY_fromdata", 525 DST_R_OPENSSLFAILURE)); 526 } 527 } else { 528 if (EVP_PKEY_paramgen_init(param_ctx) != 1) { 529 DST_RET(dst__openssl_toresult2("EVP_PKEY_paramgen_init", 530 DST_R_OPENSSLFAILURE)); 531 } 532 if (EVP_PKEY_CTX_set_params(param_ctx, params) != 1) { 533 DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_set_" 534 "params", 535 DST_R_OPENSSLFAILURE)); 536 } 537 if (EVP_PKEY_paramgen(param_ctx, ¶m_pkey) != 1 || 538 param_pkey == NULL) 539 { 540 DST_RET(dst__openssl_toresult2("EVP_PKEY_paramgen", 541 DST_R_OPENSSLFAILURE)); 542 } 543 } 544 545 /* 546 * Now `param_pkey` holds the DH parameters (either pre-coumputed or 547 * newly generated) so we will generate a new public/private key-pair 548 * using those parameters and put it into `pkey`. 549 */ 550 ctx = EVP_PKEY_CTX_new_from_pkey(NULL, param_pkey, NULL); 551 if (ctx == NULL) { 552 DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_new_from_pkey", 553 DST_R_OPENSSLFAILURE)); 554 } 555 if (callback != NULL) { 556 u.fptr = callback; 557 EVP_PKEY_CTX_set_app_data(ctx, u.dptr); 558 EVP_PKEY_CTX_set_cb(ctx, progress_cb); 559 } 560 if (EVP_PKEY_keygen_init(ctx) != 1) { 561 DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen_init", 562 DST_R_OPENSSLFAILURE)); 563 } 564 if (EVP_PKEY_keygen(ctx, &pkey) != 1 || pkey == NULL) { 565 DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen", 566 DST_R_OPENSSLFAILURE)); 567 } 568 569 key->keydata.pkey = pkey; 570 pkey = NULL; 571#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 572 573 ret = ISC_R_SUCCESS; 574 575err: 576#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 577 if (dh != NULL) { 578 DH_free(dh); 579 } 580 if (cb != NULL) { 581 BN_GENCB_free(cb); 582 } 583#else 584 if (param_pkey != NULL) { 585 EVP_PKEY_free(param_pkey); 586 } 587 if (pkey != NULL) { 588 EVP_PKEY_free(pkey); 589 } 590 if (param_ctx != NULL) { 591 EVP_PKEY_CTX_free(param_ctx); 592 } 593 if (ctx != NULL) { 594 EVP_PKEY_CTX_free(ctx); 595 } 596 if (params != NULL) { 597 OSSL_PARAM_free(params); 598 } 599 if (bld != NULL) { 600 OSSL_PARAM_BLD_free(bld); 601 } 602 if (p != NULL) { 603 BN_free(p); 604 } 605 if (g != NULL) { 606 BN_free(g); 607 } 608#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 609 610 return (ret); 611} 612 613static bool 614openssldh_isprivate(const dst_key_t *key) { 615#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 616 DH *dh = key->keydata.dh; 617 const BIGNUM *priv_key = NULL; 618 619 DH_get0_key(dh, NULL, &priv_key); 620 621 return (dh != NULL && priv_key != NULL); 622#else 623 bool ret; 624 EVP_PKEY *pkey; 625 BIGNUM *priv_key = NULL; 626 627 pkey = key->keydata.pkey; 628 if (pkey == NULL) { 629 return (false); 630 } 631 632 ret = (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, 633 &priv_key) == 1 && 634 priv_key != NULL); 635 if (priv_key != NULL) { 636 BN_clear_free(priv_key); 637 } 638 639 return (ret); 640#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 641} 642 643static void 644openssldh_destroy(dst_key_t *key) { 645#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 646 DH *dh = key->keydata.dh; 647 648 if (dh == NULL) { 649 return; 650 } 651 652 DH_free(dh); 653 key->keydata.dh = NULL; 654#else 655 EVP_PKEY *pkey = key->keydata.pkey; 656 657 if (pkey == NULL) { 658 return; 659 } 660 661 EVP_PKEY_free(pkey); 662 key->keydata.pkey = NULL; 663#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 664} 665 666static void 667uint16_toregion(uint16_t val, isc_region_t *region) { 668 *region->base = (val & 0xff00) >> 8; 669 isc_region_consume(region, 1); 670 *region->base = (val & 0x00ff); 671 isc_region_consume(region, 1); 672} 673 674static uint16_t 675uint16_fromregion(isc_region_t *region) { 676 uint16_t val; 677 unsigned char *cp = region->base; 678 679 val = ((unsigned int)(cp[0])) << 8; 680 val |= ((unsigned int)(cp[1])); 681 682 isc_region_consume(region, 2); 683 684 return (val); 685} 686 687static isc_result_t 688openssldh_todns(const dst_key_t *key, isc_buffer_t *data) { 689 isc_result_t ret = ISC_R_SUCCESS; 690#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 691 DH *dh; 692 const BIGNUM *pub_key = NULL, *p = NULL, *g = NULL; 693#else 694 EVP_PKEY *pkey; 695 BIGNUM *pub_key = NULL, *p = NULL, *g = NULL; 696#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 697 isc_region_t r; 698 uint16_t dnslen, plen, glen, publen; 699 700#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 701 REQUIRE(key->keydata.dh != NULL); 702 703 dh = key->keydata.dh; 704 DH_get0_pqg(dh, &p, NULL, &g); 705 DH_get0_key(dh, &pub_key, NULL); 706#else 707 REQUIRE(key->keydata.pkey != NULL); 708 709 pkey = key->keydata.pkey; 710 EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_FFC_P, &p); 711 EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_FFC_G, &g); 712 EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key); 713#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 714 715 isc_buffer_availableregion(data, &r); 716 717 if (BN_cmp(g, bn2) == 0 && 718 (BN_cmp(p, bn768) == 0 || BN_cmp(p, bn1024) == 0 || 719 BN_cmp(p, bn1536) == 0)) 720 { 721 plen = 1; 722 glen = 0; 723 } else { 724 plen = BN_num_bytes(p); 725 glen = BN_num_bytes(g); 726 } 727 728 publen = BN_num_bytes(pub_key); 729 dnslen = plen + glen + publen + 6; 730 if (r.length < (unsigned int)dnslen) { 731 DST_RET(ISC_R_NOSPACE); 732 } 733 734 uint16_toregion(plen, &r); 735 if (plen == 1) { 736 if (BN_cmp(p, bn768) == 0) { 737 *r.base = 1; 738 } else if (BN_cmp(p, bn1024) == 0) { 739 *r.base = 2; 740 } else { 741 *r.base = 3; 742 } 743 } else { 744 BN_bn2bin(p, r.base); 745 } 746 isc_region_consume(&r, plen); 747 748 uint16_toregion(glen, &r); 749 if (glen > 0) { 750 BN_bn2bin(g, r.base); 751 } 752 isc_region_consume(&r, glen); 753 754 uint16_toregion(publen, &r); 755 BN_bn2bin(pub_key, r.base); 756 isc_region_consume(&r, publen); 757 758 isc_buffer_add(data, dnslen); 759 760err: 761#if OPENSSL_VERSION_NUMBER >= 0x30000000L && OPENSSL_API_LEVEL >= 30000 762 if (p != NULL) { 763 BN_free(p); 764 } 765 if (g != NULL) { 766 BN_free(g); 767 } 768 if (pub_key != NULL) { 769 BN_free(pub_key); 770 } 771#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L && OPENSSL_API_LEVEL >= 30000 \ 772 */ 773 774 return (ret); 775} 776 777static isc_result_t 778openssldh_fromdns(dst_key_t *key, isc_buffer_t *data) { 779 isc_result_t ret; 780#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 781 DH *dh; 782#else 783 OSSL_PARAM_BLD *bld = NULL; 784 OSSL_PARAM *params = NULL; 785 EVP_PKEY_CTX *ctx = NULL; 786 EVP_PKEY *pkey = NULL; 787#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 788 BIGNUM *pub_key = NULL, *p = NULL, *g = NULL; 789 int key_size; 790 isc_region_t r; 791 uint16_t plen, glen, publen; 792 int special = 0; 793 794 isc_buffer_remainingregion(data, &r); 795 if (r.length == 0) { 796 return (ISC_R_SUCCESS); 797 } 798 799#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 800 dh = DH_new(); 801 if (dh == NULL) { 802 DST_RET(dst__openssl_toresult(ISC_R_NOMEMORY)); 803 } 804 DH_clear_flags(dh, DH_FLAG_CACHE_MONT_P); 805#else 806 bld = OSSL_PARAM_BLD_new(); 807 if (bld == NULL) { 808 DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); 809 } 810 ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL); 811 if (ctx == NULL) { 812 DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); 813 } 814#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 815 816 /* 817 * Read the prime length. 1 & 2 are table entries, > 16 means a 818 * prime follows, otherwise an error. 819 */ 820 if (r.length < 2) { 821 DST_RET(DST_R_INVALIDPUBLICKEY); 822 } 823 plen = uint16_fromregion(&r); 824 if (plen < 16 && plen != 1 && plen != 2) { 825 DST_RET(DST_R_INVALIDPUBLICKEY); 826 } 827 if (r.length < plen) { 828 DST_RET(DST_R_INVALIDPUBLICKEY); 829 } 830 if (plen == 1 || plen == 2) { 831 if (plen == 1) { 832 special = *r.base; 833 isc_region_consume(&r, 1); 834 } else { 835 special = uint16_fromregion(&r); 836 } 837 switch (special) { 838 case 1: 839 p = BN_dup(bn768); 840 break; 841 case 2: 842 p = BN_dup(bn1024); 843 break; 844 case 3: 845 p = BN_dup(bn1536); 846 break; 847 default: 848 DST_RET(DST_R_INVALIDPUBLICKEY); 849 } 850 } else { 851 p = BN_bin2bn(r.base, plen, NULL); 852 isc_region_consume(&r, plen); 853 } 854 855 /* 856 * Read the generator length. This should be 0 if the prime was 857 * special, but it might not be. If it's 0 and the prime is not 858 * special, we have a problem. 859 */ 860 if (r.length < 2) { 861 DST_RET(DST_R_INVALIDPUBLICKEY); 862 } 863 glen = uint16_fromregion(&r); 864 if (r.length < glen) { 865 DST_RET(DST_R_INVALIDPUBLICKEY); 866 } 867 if (special != 0) { 868 if (glen == 0) { 869 g = BN_dup(bn2); 870 } else { 871 g = BN_bin2bn(r.base, glen, NULL); 872 if (g != NULL && BN_cmp(g, bn2) != 0) { 873 DST_RET(DST_R_INVALIDPUBLICKEY); 874 } 875 } 876 } else { 877 if (glen == 0) { 878 DST_RET(DST_R_INVALIDPUBLICKEY); 879 } 880 g = BN_bin2bn(r.base, glen, NULL); 881 } 882 isc_region_consume(&r, glen); 883 884 if (p == NULL || g == NULL) { 885 DST_RET(dst__openssl_toresult(ISC_R_NOMEMORY)); 886 } 887 888 key_size = BN_num_bits(p); 889 890#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 891 if (DH_set0_pqg(dh, p, NULL, g) != 1) { 892 DST_RET(dst__openssl_toresult2("DH_set0_pqg", 893 DST_R_OPENSSLFAILURE)); 894 } 895 896 /* These are now managed by OpenSSL */ 897 p = NULL; 898 g = NULL; 899#else 900 if (OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P, p) != 1 || 901 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_G, g) != 1) 902 { 903 DST_RET(dst__openssl_toresult2("OSSL_PARAM_BLD_push_BN", 904 DST_R_OPENSSLFAILURE)); 905 } 906#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 907 908 if (r.length < 2) { 909 DST_RET(DST_R_INVALIDPUBLICKEY); 910 } 911 publen = uint16_fromregion(&r); 912 if (r.length < publen) { 913 DST_RET(DST_R_INVALIDPUBLICKEY); 914 } 915 pub_key = BN_bin2bn(r.base, publen, NULL); 916 if (pub_key == NULL) { 917 DST_RET(dst__openssl_toresult(ISC_R_NOMEMORY)); 918 } 919 920 isc_region_consume(&r, publen); 921 922 isc_buffer_forward(data, plen + glen + publen + 6); 923 924#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 925#if (LIBRESSL_VERSION_NUMBER >= 0x2070000fL) && \ 926 (LIBRESSL_VERSION_NUMBER <= 0x2070200fL) 927 /* 928 * LibreSSL << 2.7.3 DH_get0_key requires priv_key to be set when 929 * DH structure is empty, hence we cannot use DH_get0_key(). 930 */ 931 dh->pub_key = pub_key; 932#else /* LIBRESSL_VERSION_NUMBER */ 933 if (DH_set0_key(dh, pub_key, NULL) != 1) { 934 DST_RET(dst__openssl_toresult2("DH_set0_key", 935 DST_R_OPENSSLFAILURE)); 936 } 937#endif /* LIBRESSL_VERSION_NUMBER */ 938 939 /* This is now managed by OpenSSL */ 940 pub_key = NULL; 941 942 key->keydata.dh = dh; 943 dh = NULL; 944#else 945 if (OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, pub_key) != 1) 946 { 947 DST_RET(dst__openssl_toresult2("OSSL_PARAM_BLD_push_BN", 948 DST_R_OPENSSLFAILURE)); 949 } 950 params = OSSL_PARAM_BLD_to_param(bld); 951 if (params == NULL) { 952 DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); 953 } 954 if (EVP_PKEY_fromdata_init(ctx) != 1) { 955 DST_RET(dst__openssl_toresult2("EVP_PKEY_fromdata_init", 956 DST_R_OPENSSLFAILURE)); 957 } 958 if (EVP_PKEY_fromdata(ctx, &pkey, OSSL_KEYMGMT_SELECT_ALL, params) != 959 1 || 960 pkey == NULL) 961 { 962 DST_RET(dst__openssl_toresult2("EVP_PKEY_fromdata", 963 DST_R_OPENSSLFAILURE)); 964 } 965 966 key->keydata.pkey = pkey; 967 pkey = NULL; 968#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 969 970 key->key_size = (unsigned int)key_size; 971 972 ret = ISC_R_SUCCESS; 973 974err: 975#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 976 if (dh != NULL) { 977 DH_free(dh); 978 } 979#else 980 if (pkey != NULL) { 981 EVP_PKEY_free(pkey); 982 } 983 if (ctx != NULL) { 984 EVP_PKEY_CTX_free(ctx); 985 } 986 if (params != NULL) { 987 OSSL_PARAM_free(params); 988 } 989 if (bld != NULL) { 990 OSSL_PARAM_BLD_free(bld); 991 } 992#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 993 if (p != NULL) { 994 BN_free(p); 995 } 996 if (g != NULL) { 997 BN_free(g); 998 } 999 if (pub_key != NULL) { 1000 BN_free(pub_key); 1001 } 1002 1003 return (ret); 1004} 1005 1006static isc_result_t 1007openssldh_tofile(const dst_key_t *key, const char *directory) { 1008#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 1009 DH *dh; 1010 const BIGNUM *pub_key = NULL, *priv_key = NULL, *p = NULL, *g = NULL; 1011#else 1012 EVP_PKEY *pkey; 1013 BIGNUM *pub_key = NULL, *priv_key = NULL, *p = NULL, *g = NULL; 1014#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 1015 dst_private_t priv; 1016 unsigned char *bufs[4] = { NULL }; 1017 unsigned short i = 0; 1018 isc_result_t result; 1019 1020 if (key->external) { 1021 return (DST_R_EXTERNALKEY); 1022 } 1023 1024#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 1025 if (key->keydata.dh == NULL) { 1026 return (DST_R_NULLKEY); 1027 } 1028 1029 dh = key->keydata.dh; 1030 DH_get0_key(dh, &pub_key, &priv_key); 1031 DH_get0_pqg(dh, &p, NULL, &g); 1032#else 1033 if (key->keydata.pkey == NULL) { 1034 return (DST_R_NULLKEY); 1035 } 1036 1037 pkey = key->keydata.pkey; 1038 EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_FFC_P, &p); 1039 EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_FFC_G, &g); 1040 EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key); 1041 EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &priv_key); 1042#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 1043 1044 priv.elements[i].tag = TAG_DH_PRIME; 1045 priv.elements[i].length = BN_num_bytes(p); 1046 bufs[i] = isc_mem_get(key->mctx, priv.elements[i].length); 1047 BN_bn2bin(p, bufs[i]); 1048 priv.elements[i].data = bufs[i]; 1049 i++; 1050 1051 priv.elements[i].tag = TAG_DH_GENERATOR; 1052 priv.elements[i].length = BN_num_bytes(g); 1053 bufs[i] = isc_mem_get(key->mctx, priv.elements[i].length); 1054 BN_bn2bin(g, bufs[i]); 1055 priv.elements[i].data = bufs[i]; 1056 i++; 1057 1058 priv.elements[i].tag = TAG_DH_PRIVATE; 1059 priv.elements[i].length = BN_num_bytes(priv_key); 1060 bufs[i] = isc_mem_get(key->mctx, priv.elements[i].length); 1061 BN_bn2bin(priv_key, bufs[i]); 1062 priv.elements[i].data = bufs[i]; 1063 i++; 1064 1065 priv.elements[i].tag = TAG_DH_PUBLIC; 1066 priv.elements[i].length = BN_num_bytes(pub_key); 1067 bufs[i] = isc_mem_get(key->mctx, priv.elements[i].length); 1068 BN_bn2bin(pub_key, bufs[i]); 1069 priv.elements[i].data = bufs[i]; 1070 i++; 1071 1072 priv.nelements = i; 1073 result = dst__privstruct_writefile(key, &priv, directory); 1074 1075 while (i--) { 1076 if (bufs[i] != NULL) { 1077 isc_mem_put(key->mctx, bufs[i], 1078 priv.elements[i].length); 1079 } 1080 } 1081 1082#if OPENSSL_VERSION_NUMBER >= 0x30000000L && OPENSSL_API_LEVEL >= 30000 1083 if (p != NULL) { 1084 BN_free(p); 1085 } 1086 if (g != NULL) { 1087 BN_free(g); 1088 } 1089 if (pub_key != NULL) { 1090 BN_free(pub_key); 1091 } 1092 if (priv_key != NULL) { 1093 BN_clear_free(priv_key); 1094 } 1095#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L && OPENSSL_API_LEVEL >= 30000 \ 1096 */ 1097 1098 return (result); 1099} 1100 1101static isc_result_t 1102openssldh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { 1103 dst_private_t priv; 1104 isc_result_t ret; 1105 int i; 1106#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 1107 DH *dh = NULL; 1108#else 1109 OSSL_PARAM_BLD *bld = NULL; 1110 OSSL_PARAM *params = NULL; 1111 EVP_PKEY_CTX *ctx = NULL; 1112 EVP_PKEY *pkey = NULL; 1113#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 1114 BIGNUM *pub_key = NULL, *priv_key = NULL, *p = NULL, *g = NULL; 1115 int key_size = 0; 1116 isc_mem_t *mctx; 1117 1118 UNUSED(pub); 1119 mctx = key->mctx; 1120 1121 /* read private key file */ 1122 ret = dst__privstruct_parse(key, DST_ALG_DH, lexer, mctx, &priv); 1123 if (ret != ISC_R_SUCCESS) { 1124 return (ret); 1125 } 1126 1127 if (key->external) { 1128 DST_RET(DST_R_EXTERNALKEY); 1129 } 1130 1131#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 1132 dh = DH_new(); 1133 if (dh == NULL) { 1134 DST_RET(ISC_R_NOMEMORY); 1135 } 1136 DH_clear_flags(dh, DH_FLAG_CACHE_MONT_P); 1137#else 1138 bld = OSSL_PARAM_BLD_new(); 1139 if (bld == NULL) { 1140 DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); 1141 } 1142 ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL); 1143 if (ctx == NULL) { 1144 DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); 1145 } 1146#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 1147 1148 for (i = 0; i < priv.nelements; i++) { 1149 BIGNUM *bn; 1150 bn = BN_bin2bn(priv.elements[i].data, priv.elements[i].length, 1151 NULL); 1152 if (bn == NULL) { 1153 DST_RET(ISC_R_NOMEMORY); 1154 } 1155 1156 switch (priv.elements[i].tag) { 1157 case TAG_DH_PRIME: 1158 p = bn; 1159 key_size = BN_num_bits(p); 1160 break; 1161 case TAG_DH_GENERATOR: 1162 g = bn; 1163 break; 1164 case TAG_DH_PRIVATE: 1165 priv_key = bn; 1166 break; 1167 case TAG_DH_PUBLIC: 1168 pub_key = bn; 1169 break; 1170 } 1171 } 1172 1173#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 1174 if (DH_set0_key(dh, pub_key, priv_key) != 1) { 1175 DST_RET(dst__openssl_toresult2("DH_set0_key", 1176 DST_R_OPENSSLFAILURE)); 1177 } 1178 if (DH_set0_pqg(dh, p, NULL, g) != 1) { 1179 DST_RET(dst__openssl_toresult2("DH_set0_pqg", 1180 DST_R_OPENSSLFAILURE)); 1181 } 1182 1183 /* These are now managed by OpenSSL */ 1184 pub_key = NULL; 1185 priv_key = NULL; 1186 p = NULL; 1187 g = NULL; 1188 1189 key->keydata.dh = dh; 1190 dh = NULL; 1191#else 1192 if (OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, pub_key) != 1193 1 || 1194 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, priv_key) != 1195 1 || 1196 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P, p) != 1 || 1197 OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_G, g) != 1) 1198 { 1199 DST_RET(dst__openssl_toresult2("OSSL_PARAM_BLD_push_BN", 1200 DST_R_OPENSSLFAILURE)); 1201 } 1202 params = OSSL_PARAM_BLD_to_param(bld); 1203 if (params == NULL) { 1204 DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); 1205 } 1206 if (EVP_PKEY_fromdata_init(ctx) != 1) { 1207 DST_RET(dst__openssl_toresult2("EVP_PKEY_fromdata_init", 1208 DST_R_OPENSSLFAILURE)); 1209 } 1210 if (EVP_PKEY_fromdata(ctx, &pkey, OSSL_KEYMGMT_SELECT_ALL, params) != 1211 1 || 1212 pkey == NULL) 1213 { 1214 DST_RET(dst__openssl_toresult2("EVP_PKEY_fromdata", 1215 DST_R_OPENSSLFAILURE)); 1216 } 1217 1218 key->keydata.pkey = pkey; 1219 pkey = NULL; 1220#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 1221 1222 key->key_size = (unsigned int)key_size; 1223 ret = ISC_R_SUCCESS; 1224 1225err: 1226#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 1227 if (dh != NULL) { 1228 DH_free(dh); 1229 } 1230#else 1231 if (pkey != NULL) { 1232 EVP_PKEY_free(pkey); 1233 } 1234 if (ctx != NULL) { 1235 EVP_PKEY_CTX_free(ctx); 1236 } 1237 if (params != NULL) { 1238 OSSL_PARAM_free(params); 1239 } 1240 if (bld != NULL) { 1241 OSSL_PARAM_BLD_free(bld); 1242 } 1243#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */ 1244 if (p != NULL) { 1245 BN_free(p); 1246 } 1247 if (g != NULL) { 1248 BN_free(g); 1249 } 1250 if (pub_key != NULL) { 1251 BN_free(pub_key); 1252 } 1253 if (priv_key != NULL) { 1254 BN_clear_free(priv_key); 1255 } 1256 if (ret != ISC_R_SUCCESS) { 1257 openssldh_destroy(key); 1258 } 1259 dst__privstruct_free(&priv, mctx); 1260 isc_safe_memwipe(&priv, sizeof(priv)); 1261 1262 return (ret); 1263} 1264 1265static void 1266openssldh_cleanup(void) { 1267 BN_free(bn2); 1268 bn2 = NULL; 1269 1270 BN_free(bn768); 1271 bn768 = NULL; 1272 1273 BN_free(bn1024); 1274 bn1024 = NULL; 1275 1276 BN_free(bn1536); 1277 bn1536 = NULL; 1278} 1279 1280static dst_func_t openssldh_functions = { 1281 NULL, /*%< createctx */ 1282 NULL, /*%< createctx2 */ 1283 NULL, /*%< destroyctx */ 1284 NULL, /*%< adddata */ 1285 NULL, /*%< openssldh_sign */ 1286 NULL, /*%< openssldh_verify */ 1287 NULL, /*%< openssldh_verify2 */ 1288 openssldh_computesecret, 1289 openssldh_compare, 1290 openssldh_paramcompare, 1291 openssldh_generate, 1292 openssldh_isprivate, 1293 openssldh_destroy, 1294 openssldh_todns, 1295 openssldh_fromdns, 1296 openssldh_tofile, 1297 openssldh_parse, 1298 openssldh_cleanup, 1299 NULL, /*%< fromlabel */ 1300 NULL, /*%< dump */ 1301 NULL, /*%< restore */ 1302}; 1303 1304isc_result_t 1305dst__openssldh_init(dst_func_t **funcp) { 1306 REQUIRE(funcp != NULL); 1307 if (*funcp == NULL) { 1308 if (BN_hex2bn(&bn2, PRIME2) == 0 || bn2 == NULL) { 1309 goto cleanup; 1310 } 1311 if (BN_hex2bn(&bn768, PRIME768) == 0 || bn768 == NULL) { 1312 goto cleanup; 1313 } 1314 if (BN_hex2bn(&bn1024, PRIME1024) == 0 || bn1024 == NULL) { 1315 goto cleanup; 1316 } 1317 if (BN_hex2bn(&bn1536, PRIME1536) == 0 || bn1536 == NULL) { 1318 goto cleanup; 1319 } 1320 *funcp = &openssldh_functions; 1321 } 1322 return (ISC_R_SUCCESS); 1323 1324cleanup: 1325 if (bn2 != NULL) { 1326 BN_free(bn2); 1327 } 1328 if (bn768 != NULL) { 1329 BN_free(bn768); 1330 } 1331 if (bn1024 != NULL) { 1332 BN_free(bn1024); 1333 } 1334 if (bn1536 != NULL) { 1335 BN_free(bn1536); 1336 } 1337 return (ISC_R_NOMEMORY); 1338} 1339