1 /* $OpenBSD: pmeth_lib.c,v 1.24 2022/11/09 18:25:36 jsing Exp $ */ 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * project 2006. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 2006 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 <limits.h> 60 #include <stdio.h> 61 #include <stdlib.h> 62 #include <string.h> 63 64 #include <openssl/opensslconf.h> 65 66 #include <openssl/err.h> 67 #include <openssl/evp.h> 68 #include <openssl/objects.h> 69 #include <openssl/x509v3.h> 70 71 #ifndef OPENSSL_NO_ENGINE 72 #include <openssl/engine.h> 73 #endif 74 75 #include "asn1_locl.h" 76 #include "evp_locl.h" 77 78 DECLARE_STACK_OF(EVP_PKEY_METHOD) 79 STACK_OF(EVP_PKEY_METHOD) *pkey_app_methods = NULL; 80 81 extern const EVP_PKEY_METHOD cmac_pkey_meth; 82 extern const EVP_PKEY_METHOD dh_pkey_meth; 83 extern const EVP_PKEY_METHOD dsa_pkey_meth; 84 extern const EVP_PKEY_METHOD ec_pkey_meth; 85 extern const EVP_PKEY_METHOD gostimit_pkey_meth; 86 extern const EVP_PKEY_METHOD gostr01_pkey_meth; 87 extern const EVP_PKEY_METHOD hkdf_pkey_meth; 88 extern const EVP_PKEY_METHOD hmac_pkey_meth; 89 extern const EVP_PKEY_METHOD rsa_pkey_meth; 90 extern const EVP_PKEY_METHOD rsa_pss_pkey_meth; 91 92 static const EVP_PKEY_METHOD *pkey_methods[] = { 93 &cmac_pkey_meth, 94 &dh_pkey_meth, 95 &dsa_pkey_meth, 96 &ec_pkey_meth, 97 &gostimit_pkey_meth, 98 &gostr01_pkey_meth, 99 &hkdf_pkey_meth, 100 &hmac_pkey_meth, 101 &rsa_pkey_meth, 102 &rsa_pss_pkey_meth, 103 }; 104 105 static const size_t pkey_methods_count = 106 sizeof(pkey_methods) / sizeof(pkey_methods[0]); 107 108 int 109 evp_pkey_meth_get_count(void) 110 { 111 int num = pkey_methods_count; 112 113 if (pkey_app_methods != NULL) 114 num += sk_EVP_PKEY_METHOD_num(pkey_app_methods); 115 116 return num; 117 } 118 119 const EVP_PKEY_METHOD * 120 evp_pkey_meth_get0(int idx) 121 { 122 int num = pkey_methods_count; 123 124 if (idx < 0) 125 return NULL; 126 if (idx < num) 127 return pkey_methods[idx]; 128 129 idx -= num; 130 131 return sk_EVP_PKEY_METHOD_value(pkey_app_methods, idx); 132 } 133 134 const EVP_PKEY_METHOD * 135 EVP_PKEY_meth_find(int type) 136 { 137 const EVP_PKEY_METHOD *pmeth; 138 int i; 139 140 for (i = evp_pkey_meth_get_count() - 1; i >= 0; i--) { 141 pmeth = evp_pkey_meth_get0(i); 142 if (pmeth->pkey_id == type) 143 return pmeth; 144 } 145 146 return NULL; 147 } 148 149 static EVP_PKEY_CTX * 150 int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) 151 { 152 EVP_PKEY_CTX *ret; 153 const EVP_PKEY_METHOD *pmeth; 154 155 if (id == -1) { 156 if (!pkey || !pkey->ameth) 157 return NULL; 158 id = pkey->ameth->pkey_id; 159 } 160 #ifndef OPENSSL_NO_ENGINE 161 if (pkey && pkey->engine) 162 e = pkey->engine; 163 /* Try to find an ENGINE which implements this method */ 164 if (e) { 165 if (!ENGINE_init(e)) { 166 EVPerror(ERR_R_ENGINE_LIB); 167 return NULL; 168 } 169 } else 170 e = ENGINE_get_pkey_meth_engine(id); 171 172 /* If an ENGINE handled this method look it up. Othewise 173 * use internal tables. 174 */ 175 176 if (e) 177 pmeth = ENGINE_get_pkey_meth(e, id); 178 else 179 #endif 180 pmeth = EVP_PKEY_meth_find(id); 181 182 if (pmeth == NULL) { 183 EVPerror(EVP_R_UNSUPPORTED_ALGORITHM); 184 return NULL; 185 } 186 187 ret = malloc(sizeof(EVP_PKEY_CTX)); 188 if (ret == NULL) { 189 #ifndef OPENSSL_NO_ENGINE 190 ENGINE_finish(e); 191 #endif 192 EVPerror(ERR_R_MALLOC_FAILURE); 193 return NULL; 194 } 195 ret->engine = e; 196 ret->pmeth = pmeth; 197 ret->operation = EVP_PKEY_OP_UNDEFINED; 198 ret->pkey = pkey; 199 ret->peerkey = NULL; 200 ret->pkey_gencb = 0; 201 if (pkey) 202 CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); 203 ret->data = NULL; 204 205 if (pmeth->init) { 206 if (pmeth->init(ret) <= 0) { 207 EVP_PKEY_CTX_free(ret); 208 return NULL; 209 } 210 } 211 212 return ret; 213 } 214 215 EVP_PKEY_METHOD* 216 EVP_PKEY_meth_new(int id, int flags) 217 { 218 EVP_PKEY_METHOD *pmeth; 219 220 if ((pmeth = calloc(1, sizeof(EVP_PKEY_METHOD))) == NULL) 221 return NULL; 222 223 pmeth->pkey_id = id; 224 pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC; 225 226 return pmeth; 227 } 228 229 void 230 EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, const EVP_PKEY_METHOD *meth) 231 { 232 if (ppkey_id) 233 *ppkey_id = meth->pkey_id; 234 if (pflags) 235 *pflags = meth->flags; 236 } 237 238 void 239 EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src) 240 { 241 EVP_PKEY_METHOD preserve; 242 243 preserve.pkey_id = dst->pkey_id; 244 preserve.flags = dst->flags; 245 246 *dst = *src; 247 248 dst->pkey_id = preserve.pkey_id; 249 dst->flags = preserve.flags; 250 } 251 252 void 253 EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth) 254 { 255 if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC)) 256 free(pmeth); 257 } 258 259 EVP_PKEY_CTX * 260 EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) 261 { 262 return int_ctx_new(pkey, e, -1); 263 } 264 265 EVP_PKEY_CTX * 266 EVP_PKEY_CTX_new_id(int id, ENGINE *e) 267 { 268 return int_ctx_new(NULL, e, id); 269 } 270 271 EVP_PKEY_CTX * 272 EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) 273 { 274 EVP_PKEY_CTX *rctx; 275 276 if (!pctx->pmeth || !pctx->pmeth->copy) 277 return NULL; 278 #ifndef OPENSSL_NO_ENGINE 279 /* Make sure it's safe to copy a pkey context using an ENGINE */ 280 if (pctx->engine && !ENGINE_init(pctx->engine)) { 281 EVPerror(ERR_R_ENGINE_LIB); 282 return 0; 283 } 284 #endif 285 rctx = malloc(sizeof(EVP_PKEY_CTX)); 286 if (!rctx) 287 return NULL; 288 289 rctx->pmeth = pctx->pmeth; 290 #ifndef OPENSSL_NO_ENGINE 291 rctx->engine = pctx->engine; 292 #endif 293 294 if (pctx->pkey) 295 CRYPTO_add(&pctx->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); 296 297 rctx->pkey = pctx->pkey; 298 299 if (pctx->peerkey) 300 CRYPTO_add(&pctx->peerkey->references, 1, CRYPTO_LOCK_EVP_PKEY); 301 302 rctx->peerkey = pctx->peerkey; 303 304 rctx->data = NULL; 305 rctx->app_data = NULL; 306 rctx->operation = pctx->operation; 307 308 if (pctx->pmeth->copy(rctx, pctx) > 0) 309 return rctx; 310 311 EVP_PKEY_CTX_free(rctx); 312 return NULL; 313 } 314 315 int 316 EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth) 317 { 318 if (pkey_app_methods == NULL) { 319 pkey_app_methods = sk_EVP_PKEY_METHOD_new(NULL); 320 if (pkey_app_methods == NULL) 321 return 0; 322 } 323 324 if (!sk_EVP_PKEY_METHOD_push(pkey_app_methods, pmeth)) 325 return 0; 326 327 return 1; 328 } 329 330 void 331 EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) 332 { 333 if (ctx == NULL) 334 return; 335 if (ctx->pmeth && ctx->pmeth->cleanup) 336 ctx->pmeth->cleanup(ctx); 337 EVP_PKEY_free(ctx->pkey); 338 EVP_PKEY_free(ctx->peerkey); 339 #ifndef OPENSSL_NO_ENGINE 340 ENGINE_finish(ctx->engine); 341 #endif 342 free(ctx); 343 } 344 345 int 346 EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, 347 int p1, void *p2) 348 { 349 int ret; 350 351 if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) { 352 EVPerror(EVP_R_COMMAND_NOT_SUPPORTED); 353 return -2; 354 } 355 if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype)) 356 return -1; 357 358 if (ctx->operation == EVP_PKEY_OP_UNDEFINED) { 359 EVPerror(EVP_R_NO_OPERATION_SET); 360 return -1; 361 } 362 363 if ((optype != -1) && !(ctx->operation & optype)) { 364 EVPerror(EVP_R_INVALID_OPERATION); 365 return -1; 366 } 367 368 ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2); 369 370 if (ret == -2) 371 EVPerror(EVP_R_COMMAND_NOT_SUPPORTED); 372 373 return ret; 374 375 } 376 377 int 378 EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *name, const char *value) 379 { 380 if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) { 381 EVPerror(EVP_R_COMMAND_NOT_SUPPORTED); 382 return -2; 383 } 384 if (!strcmp(name, "digest")) { 385 return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_SIG, 386 EVP_PKEY_CTRL_MD, value); 387 } 388 return ctx->pmeth->ctrl_str(ctx, name, value); 389 } 390 391 int 392 EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str) 393 { 394 size_t len; 395 396 if ((len = strlen(str)) > INT_MAX) 397 return -1; 398 399 return ctx->pmeth->ctrl(ctx, cmd, len, (void *)str); 400 } 401 402 int 403 EVP_PKEY_CTX_hex2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *hexstr) 404 { 405 unsigned char *hex = NULL; 406 long length; 407 int ret = 0; 408 409 if ((hex = string_to_hex(hexstr, &length)) == NULL) 410 goto err; 411 if (length < 0 || length > INT_MAX) { 412 ret = -1; 413 goto err; 414 } 415 416 ret = ctx->pmeth->ctrl(ctx, cmd, length, hex); 417 418 err: 419 free(hex); 420 return ret; 421 } 422 423 int 424 EVP_PKEY_CTX_md(EVP_PKEY_CTX *ctx, int optype, int cmd, const char *md_name) 425 { 426 const EVP_MD *md; 427 428 if ((md = EVP_get_digestbyname(md_name)) == NULL) { 429 EVPerror(EVP_R_INVALID_DIGEST); 430 return 0; 431 } 432 return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, 0, (void *)md); 433 } 434 435 int 436 EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx) 437 { 438 return ctx->operation; 439 } 440 441 void 442 EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen) 443 { 444 ctx->keygen_info = dat; 445 ctx->keygen_info_count = datlen; 446 } 447 448 void 449 EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data) 450 { 451 ctx->data = data; 452 } 453 454 void * 455 EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx) 456 { 457 return ctx->data; 458 } 459 460 EVP_PKEY * 461 EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) 462 { 463 return ctx->pkey; 464 } 465 466 EVP_PKEY * 467 EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx) 468 { 469 return ctx->peerkey; 470 } 471 472 void 473 EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data) 474 { 475 ctx->app_data = data; 476 } 477 478 void * 479 EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx) 480 { 481 return ctx->app_data; 482 } 483 484 void 485 EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, 486 int (*init)(EVP_PKEY_CTX *ctx)) 487 { 488 pmeth->init = init; 489 } 490 491 void 492 EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, 493 int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)) 494 { 495 pmeth->copy = copy; 496 } 497 498 void 499 EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, 500 void (*cleanup)(EVP_PKEY_CTX *ctx)) 501 { 502 pmeth->cleanup = cleanup; 503 } 504 505 void 506 EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, 507 int (*paramgen_init)(EVP_PKEY_CTX *ctx), 508 int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)) 509 { 510 pmeth->paramgen_init = paramgen_init; 511 pmeth->paramgen = paramgen; 512 } 513 514 void 515 EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, 516 int (*keygen_init)(EVP_PKEY_CTX *ctx), 517 int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)) 518 { 519 pmeth->keygen_init = keygen_init; 520 pmeth->keygen = keygen; 521 } 522 523 void 524 EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, 525 int (*sign_init)(EVP_PKEY_CTX *ctx), 526 int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, 527 const unsigned char *tbs, size_t tbslen)) 528 { 529 pmeth->sign_init = sign_init; 530 pmeth->sign = sign; 531 } 532 533 void 534 EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, 535 int (*verify_init)(EVP_PKEY_CTX *ctx), 536 int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, 537 const unsigned char *tbs, size_t tbslen)) 538 { 539 pmeth->verify_init = verify_init; 540 pmeth->verify = verify; 541 } 542 543 void 544 EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, 545 int (*verify_recover_init)(EVP_PKEY_CTX *ctx), 546 int (*verify_recover)(EVP_PKEY_CTX *ctx, 547 unsigned char *sig, size_t *siglen, 548 const unsigned char *tbs, size_t tbslen)) 549 { 550 pmeth->verify_recover_init = verify_recover_init; 551 pmeth->verify_recover = verify_recover; 552 } 553 554 void 555 EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, 556 int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx), 557 int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, 558 EVP_MD_CTX *mctx)) 559 { 560 pmeth->signctx_init = signctx_init; 561 pmeth->signctx = signctx; 562 } 563 564 void 565 EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, 566 int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx), 567 int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen, 568 EVP_MD_CTX *mctx)) 569 { 570 pmeth->verifyctx_init = verifyctx_init; 571 pmeth->verifyctx = verifyctx; 572 } 573 574 void 575 EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, 576 int (*encrypt_init)(EVP_PKEY_CTX *ctx), 577 int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, 578 const unsigned char *in, size_t inlen)) 579 { 580 pmeth->encrypt_init = encrypt_init; 581 pmeth->encrypt = encryptfn; 582 } 583 584 void 585 EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, 586 int (*decrypt_init)(EVP_PKEY_CTX *ctx), 587 int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, 588 const unsigned char *in, size_t inlen)) 589 { 590 pmeth->decrypt_init = decrypt_init; 591 pmeth->decrypt = decrypt; 592 } 593 594 void 595 EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, 596 int (*derive_init)(EVP_PKEY_CTX *ctx), 597 int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)) 598 { 599 pmeth->derive_init = derive_init; 600 pmeth->derive = derive; 601 } 602 603 void 604 EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, 605 int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2), 606 int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value)) 607 { 608 pmeth->ctrl = ctrl; 609 pmeth->ctrl_str = ctrl_str; 610 } 611 612 void 613 EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth, int (*check)(EVP_PKEY *pkey)) 614 { 615 pmeth->check = check; 616 } 617 618 void 619 EVP_PKEY_meth_set_public_check(EVP_PKEY_METHOD *pmeth, 620 int (*public_check)(EVP_PKEY *pkey)) 621 { 622 pmeth->public_check = public_check; 623 } 624 625 void 626 EVP_PKEY_meth_set_param_check(EVP_PKEY_METHOD *pmeth, 627 int (*param_check)(EVP_PKEY *pkey)) 628 { 629 pmeth->param_check = param_check; 630 } 631