1 /* $OpenBSD: ecx_methods.c,v 1.14 2024/08/28 07:15:04 tb Exp $ */ 2 /* 3 * Copyright (c) 2022 Joel Sing <jsing@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <string.h> 19 20 #include <openssl/cms.h> 21 #include <openssl/curve25519.h> 22 #include <openssl/ec.h> 23 #include <openssl/err.h> 24 #include <openssl/evp.h> 25 #include <openssl/x509.h> 26 27 #include "asn1_local.h" 28 #include "bytestring.h" 29 #include "curve25519_internal.h" 30 #include "evp_local.h" 31 #include "x509_local.h" 32 33 /* 34 * EVP PKEY and PKEY ASN.1 methods Ed25519 and X25519. 35 * 36 * RFC 7748 - Elliptic Curves for Security. 37 * RFC 8032 - Edwards-Curve Digital Signature Algorithm (EdDSA). 38 */ 39 40 #define ED25519_BITS 253 41 #define ED25519_SECURITY_BITS 128 42 #define ED25519_SIG_SIZE 64 43 44 #define X25519_BITS 253 45 #define X25519_SECURITY_BITS 128 46 47 static int 48 ecx_key_len(int nid) 49 { 50 switch (nid) { 51 case NID_ED25519: 52 return ED25519_KEYLEN; 53 case NID_X25519: 54 return X25519_KEYLEN; 55 } 56 57 return 0; 58 } 59 60 static struct ecx_key_st * 61 ecx_key_new(int nid) 62 { 63 struct ecx_key_st *ecx_key; 64 int key_len; 65 66 if ((key_len = ecx_key_len(nid)) == 0) 67 return NULL; 68 69 if ((ecx_key = calloc(1, sizeof(*ecx_key))) == NULL) 70 return NULL; 71 72 ecx_key->nid = nid; 73 ecx_key->key_len = key_len; 74 75 return ecx_key; 76 } 77 78 static void 79 ecx_key_clear(struct ecx_key_st *ecx_key) 80 { 81 freezero(ecx_key->priv_key, ecx_key->priv_key_len); 82 ecx_key->priv_key = NULL; 83 ecx_key->priv_key_len = 0; 84 85 freezero(ecx_key->pub_key, ecx_key->pub_key_len); 86 ecx_key->pub_key = NULL; 87 ecx_key->pub_key_len = 0; 88 } 89 90 static void 91 ecx_key_free(struct ecx_key_st *ecx_key) 92 { 93 if (ecx_key == NULL) 94 return; 95 96 ecx_key_clear(ecx_key); 97 98 freezero(ecx_key, sizeof(*ecx_key)); 99 } 100 101 static int 102 ecx_key_generate(struct ecx_key_st *ecx_key) 103 { 104 uint8_t *pub_key = NULL, *priv_key = NULL; 105 int ret = 0; 106 107 ecx_key_clear(ecx_key); 108 109 if ((pub_key = calloc(1, ecx_key->key_len)) == NULL) 110 goto err; 111 if ((priv_key = calloc(1, ecx_key->key_len)) == NULL) 112 goto err; 113 114 switch (ecx_key->nid) { 115 case NID_ED25519: 116 ED25519_keypair(pub_key, priv_key); 117 break; 118 case NID_X25519: 119 X25519_keypair(pub_key, priv_key); 120 break; 121 default: 122 goto err; 123 } 124 125 ecx_key->priv_key = priv_key; 126 ecx_key->priv_key_len = ecx_key->key_len; 127 priv_key = NULL; 128 129 ecx_key->pub_key = pub_key; 130 ecx_key->pub_key_len = ecx_key->key_len; 131 pub_key = NULL; 132 133 ret = 1; 134 135 err: 136 freezero(pub_key, ecx_key->key_len); 137 freezero(priv_key, ecx_key->key_len); 138 139 return ret; 140 } 141 142 static int 143 ecx_key_set_priv(struct ecx_key_st *ecx_key, const uint8_t *priv_key, 144 size_t priv_key_len) 145 { 146 uint8_t *pub_key = NULL; 147 CBS cbs; 148 149 ecx_key_clear(ecx_key); 150 151 if (priv_key_len != ecx_key->key_len) 152 goto err; 153 154 if ((pub_key = calloc(1, ecx_key->key_len)) == NULL) 155 goto err; 156 157 switch (ecx_key->nid) { 158 case NID_ED25519: 159 ED25519_public_from_private(pub_key, priv_key); 160 break; 161 case NID_X25519: 162 X25519_public_from_private(pub_key, priv_key); 163 break; 164 default: 165 goto err; 166 } 167 168 CBS_init(&cbs, priv_key, priv_key_len); 169 if (!CBS_stow(&cbs, &ecx_key->priv_key, &ecx_key->priv_key_len)) 170 goto err; 171 172 ecx_key->pub_key = pub_key; 173 ecx_key->pub_key_len = ecx_key->key_len; 174 pub_key = NULL; 175 176 err: 177 freezero(pub_key, ecx_key->key_len); 178 179 return 1; 180 } 181 182 static int 183 ecx_key_set_pub(struct ecx_key_st *ecx_key, const uint8_t *pub_key, 184 size_t pub_key_len) 185 { 186 CBS cbs; 187 188 ecx_key_clear(ecx_key); 189 190 if (pub_key_len != ecx_key->key_len) 191 return 0; 192 193 CBS_init(&cbs, pub_key, pub_key_len); 194 if (!CBS_stow(&cbs, &ecx_key->pub_key, &ecx_key->pub_key_len)) 195 return 0; 196 197 return 1; 198 } 199 200 static int 201 ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *xpubkey) 202 { 203 struct ecx_key_st *ecx_key = NULL; 204 X509_ALGOR *algor; 205 int algor_type; 206 const uint8_t *param; 207 int param_len; 208 int ret = 0; 209 210 if (!X509_PUBKEY_get0_param(NULL, ¶m, ¶m_len, &algor, xpubkey)) 211 goto err; 212 213 /* Ensure that parameters have not been specified in the encoding. */ 214 if (algor != NULL) { 215 X509_ALGOR_get0(NULL, &algor_type, NULL, algor); 216 if (algor_type != V_ASN1_UNDEF) { 217 ECerror(EC_R_INVALID_ENCODING); 218 goto err; 219 } 220 } 221 222 if (param == NULL || param_len != ecx_key_len(pkey->ameth->pkey_id)) { 223 ECerror(EC_R_INVALID_ENCODING); 224 goto err; 225 } 226 227 if ((ecx_key = ecx_key_new(pkey->ameth->pkey_id)) == NULL) 228 goto err; 229 if (!ecx_key_set_pub(ecx_key, param, param_len)) 230 goto err; 231 if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx_key)) 232 goto err; 233 ecx_key = NULL; 234 235 ret = 1; 236 237 err: 238 ecx_key_free(ecx_key); 239 240 return ret; 241 } 242 243 static int 244 ecx_pub_encode(X509_PUBKEY *xpubkey, const EVP_PKEY *pkey) 245 { 246 const struct ecx_key_st *ecx_key = pkey->pkey.ecx; 247 uint8_t *pub_key = NULL; 248 size_t pub_key_len = 0; 249 ASN1_OBJECT *aobj; 250 CBS cbs; 251 int ret = 0; 252 253 if (ecx_key == NULL) { 254 ECerror(EC_R_INVALID_KEY); 255 goto err; 256 } 257 258 if (ecx_key->pub_key_len != ecx_key->key_len) 259 goto err; 260 261 if ((aobj = OBJ_nid2obj(pkey->ameth->pkey_id)) == NULL) 262 goto err; 263 264 CBS_init(&cbs, ecx_key->pub_key, ecx_key->pub_key_len); 265 if (!CBS_stow(&cbs, &pub_key, &pub_key_len)) 266 goto err; 267 268 if (!X509_PUBKEY_set0_param(xpubkey, aobj, V_ASN1_UNDEF, NULL, 269 pub_key, pub_key_len)) 270 goto err; 271 272 pub_key = NULL; 273 pub_key_len = 0; 274 275 ret = 1; 276 277 err: 278 free(pub_key); 279 280 return ret; 281 } 282 283 static int 284 ecx_pub_cmp(const EVP_PKEY *pkey1, const EVP_PKEY *pkey2) 285 { 286 if (pkey1->pkey.ecx == NULL || pkey1->pkey.ecx->pub_key == NULL) 287 return -2; 288 if (pkey2->pkey.ecx == NULL || pkey2->pkey.ecx->pub_key == NULL) 289 return -2; 290 if (pkey1->pkey.ecx->pub_key_len != pkey2->pkey.ecx->pub_key_len) 291 return -2; 292 293 return timingsafe_memcmp(pkey1->pkey.ecx->pub_key, pkey2->pkey.ecx->pub_key, 294 pkey1->pkey.ecx->pub_key_len) == 0; 295 } 296 297 /* Reimplementation of ASN1_buf_print() that adds a secondary indent of 4. */ 298 static int 299 ecx_buf_print(BIO *bio, const uint8_t *buf, size_t buf_len, int indent) 300 { 301 uint8_t u8; 302 size_t octets = 0; 303 const char *sep = ":", *nl = ""; 304 CBS cbs; 305 306 if (indent > 60) 307 indent = 60; 308 indent += 4; 309 if (indent < 0) 310 indent = 0; 311 312 CBS_init(&cbs, buf, buf_len); 313 while (CBS_len(&cbs) > 0) { 314 if (!CBS_get_u8(&cbs, &u8)) 315 return 0; 316 if (octets++ % 15 == 0) { 317 if (BIO_printf(bio, "%s%*s", nl, indent, "") < 0) 318 return 0; 319 nl = "\n"; 320 } 321 if (CBS_len(&cbs) == 0) 322 sep = ""; 323 if (BIO_printf(bio, "%02x%s", u8, sep) <= 0) 324 return 0; 325 } 326 327 if (BIO_printf(bio, "\n") <= 0) 328 return 0; 329 330 return 1; 331 } 332 333 static int 334 ecx_pub_print(BIO *bio, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) 335 { 336 struct ecx_key_st *ecx_key = pkey->pkey.ecx; 337 const char *name; 338 339 if ((name = OBJ_nid2ln(pkey->ameth->pkey_id)) == NULL) 340 return 0; 341 342 if (ecx_key == NULL || ecx_key->pub_key == NULL) 343 return BIO_printf(bio, "%*s<INVALID PUBLIC KEY>\n", 344 indent, "") > 0; 345 346 if (BIO_printf(bio, "%*s%s Public-Key:\n", indent, "", name) <= 0) 347 return 0; 348 if (BIO_printf(bio, "%*spub:\n", indent, "") <= 0) 349 return 0; 350 if (!ecx_buf_print(bio, ecx_key->pub_key, ecx_key->pub_key_len, indent)) 351 return 0; 352 353 return 1; 354 } 355 356 static int 357 ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8pki) 358 { 359 struct ecx_key_st *ecx_key = NULL; 360 ASN1_OCTET_STRING *aos = NULL; 361 const X509_ALGOR *algor; 362 int algor_type; 363 const uint8_t *param; 364 int param_len; 365 int ret = 0; 366 367 if (!PKCS8_pkey_get0(NULL, ¶m, ¶m_len, &algor, p8pki)) 368 goto err; 369 if ((aos = d2i_ASN1_OCTET_STRING(NULL, ¶m, param_len)) == NULL) 370 goto err; 371 372 /* Ensure that parameters have not been specified in the encoding. */ 373 if (algor != NULL) { 374 X509_ALGOR_get0(NULL, &algor_type, NULL, algor); 375 if (algor_type != V_ASN1_UNDEF) { 376 ECerror(EC_R_INVALID_ENCODING); 377 goto err; 378 } 379 } 380 381 if (ASN1_STRING_get0_data(aos) == NULL || 382 ASN1_STRING_length(aos) != ecx_key_len(pkey->ameth->pkey_id)) { 383 ECerror(EC_R_INVALID_ENCODING); 384 goto err; 385 } 386 387 if ((ecx_key = ecx_key_new(pkey->ameth->pkey_id)) == NULL) 388 goto err; 389 if (!ecx_key_set_priv(ecx_key, ASN1_STRING_get0_data(aos), 390 ASN1_STRING_length(aos))) 391 goto err; 392 if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx_key)) 393 goto err; 394 ecx_key = NULL; 395 396 ret = 1; 397 398 err: 399 ASN1_OCTET_STRING_free(aos); 400 ecx_key_free(ecx_key); 401 402 return ret; 403 } 404 405 static int 406 ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8pki, const EVP_PKEY *pkey) 407 { 408 struct ecx_key_st *ecx_key = pkey->pkey.ecx; 409 ASN1_OCTET_STRING *aos = NULL; 410 ASN1_OBJECT *aobj; 411 uint8_t *der = NULL; 412 int der_len = 0; 413 int ret = 0; 414 415 if (ecx_key == NULL || ecx_key->priv_key == NULL) { 416 ECerror(EC_R_INVALID_PRIVATE_KEY); 417 goto err; 418 } 419 420 if ((aobj = OBJ_nid2obj(pkey->ameth->pkey_id)) == NULL) 421 goto err; 422 423 if ((aos = ASN1_OCTET_STRING_new()) == NULL) 424 goto err; 425 if (!ASN1_OCTET_STRING_set(aos, ecx_key->priv_key, 426 ecx_key->priv_key_len)) 427 goto err; 428 if ((der_len = i2d_ASN1_OCTET_STRING(aos, &der)) < 0) 429 goto err; 430 if (!PKCS8_pkey_set0(p8pki, aobj, 0, V_ASN1_UNDEF, NULL, der, der_len)) 431 goto err; 432 433 der = NULL; 434 der_len = 0; 435 436 ret = 1; 437 438 err: 439 freezero(der, der_len); 440 ASN1_OCTET_STRING_free(aos); 441 442 return ret; 443 } 444 445 static int 446 ecx_priv_print(BIO *bio, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) 447 { 448 struct ecx_key_st *ecx_key = pkey->pkey.ecx; 449 const char *name; 450 451 if ((name = OBJ_nid2ln(pkey->ameth->pkey_id)) == NULL) 452 return 0; 453 454 if (ecx_key == NULL || ecx_key->priv_key == NULL) 455 return BIO_printf(bio, "%*s<INVALID PRIVATE KEY>\n", 456 indent, "") > 0; 457 458 if (BIO_printf(bio, "%*s%s Private-Key:\n", indent, "", name) <= 0) 459 return 0; 460 if (BIO_printf(bio, "%*spriv:\n", indent, "") <= 0) 461 return 0; 462 if (!ecx_buf_print(bio, ecx_key->priv_key, ecx_key->priv_key_len, indent)) 463 return 0; 464 if (BIO_printf(bio, "%*spub:\n", indent, "") <= 0) 465 return 0; 466 if (!ecx_buf_print(bio, ecx_key->pub_key, ecx_key->pub_key_len, indent)) 467 return 0; 468 469 return 1; 470 } 471 472 static int 473 ecx_size(const EVP_PKEY *pkey) 474 { 475 return ecx_key_len(pkey->ameth->pkey_id); 476 } 477 478 static int 479 ecx_sig_size(const EVP_PKEY *pkey) 480 { 481 switch (pkey->ameth->pkey_id) { 482 case EVP_PKEY_ED25519: 483 return ED25519_SIG_SIZE; 484 } 485 return 0; 486 } 487 488 static int 489 ecx_bits(const EVP_PKEY *pkey) 490 { 491 switch (pkey->ameth->pkey_id) { 492 case EVP_PKEY_ED25519: 493 return ED25519_BITS; 494 case EVP_PKEY_X25519: 495 return X25519_BITS; 496 } 497 return 0; 498 } 499 500 static int 501 ecx_security_bits(const EVP_PKEY *pkey) 502 { 503 switch (pkey->ameth->pkey_id) { 504 case EVP_PKEY_ED25519: 505 return ED25519_SECURITY_BITS; 506 case EVP_PKEY_X25519: 507 return X25519_SECURITY_BITS; 508 } 509 return 0; 510 } 511 512 static int 513 ecx_signature_info(const X509_ALGOR *algor, int *md_nid, int *pkey_nid, 514 int *security_bits, uint32_t *flags) 515 { 516 const ASN1_OBJECT *aobj; 517 518 X509_ALGOR_get0(&aobj, NULL, NULL, algor); 519 if (OBJ_obj2nid(aobj) != EVP_PKEY_ED25519) 520 return 0; 521 522 *md_nid = NID_undef; 523 *pkey_nid = NID_ED25519; 524 *security_bits = ED25519_SECURITY_BITS; 525 *flags = X509_SIG_INFO_TLS | X509_SIG_INFO_VALID; 526 527 return 1; 528 } 529 530 static int 531 ecx_param_cmp(const EVP_PKEY *pkey1, const EVP_PKEY *pkey2) 532 { 533 /* No parameters, so always equivalent. */ 534 return 1; 535 } 536 537 static void 538 ecx_free(EVP_PKEY *pkey) 539 { 540 struct ecx_key_st *ecx_key = pkey->pkey.ecx; 541 542 ecx_key_free(ecx_key); 543 } 544 545 static int 546 ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) 547 { 548 /* Not supported. */ 549 return -2; 550 } 551 552 #ifndef OPENSSL_NO_CMS 553 static int 554 ecx_cms_sign_or_verify(EVP_PKEY *pkey, long verify, CMS_SignerInfo *si) 555 { 556 X509_ALGOR *digestAlgorithm, *signatureAlgorithm; 557 558 if (verify != 0 && verify != 1) 559 return -1; 560 561 /* Check that we have an Ed25519 public key. */ 562 if (EVP_PKEY_id(pkey) != NID_ED25519) 563 return -1; 564 565 CMS_SignerInfo_get0_algs(si, NULL, NULL, &digestAlgorithm, 566 &signatureAlgorithm); 567 568 /* RFC 8419, section 2.3: digestAlgorithm MUST be SHA-512. */ 569 if (digestAlgorithm == NULL) 570 return -1; 571 if (OBJ_obj2nid(digestAlgorithm->algorithm) != NID_sha512) 572 return -1; 573 574 /* 575 * RFC 8419, section 2.4: signatureAlgorithm MUST be Ed25519, and the 576 * parameters MUST be absent. For verification check that this is the 577 * case, for signing set the signatureAlgorithm accordingly. 578 */ 579 if (verify) { 580 const ASN1_OBJECT *obj; 581 int param_type; 582 583 if (signatureAlgorithm == NULL) 584 return -1; 585 586 X509_ALGOR_get0(&obj, ¶m_type, NULL, signatureAlgorithm); 587 if (OBJ_obj2nid(obj) != NID_ED25519) 588 return -1; 589 if (param_type != V_ASN1_UNDEF) 590 return -1; 591 592 return 1; 593 } 594 595 if (!X509_ALGOR_set0_by_nid(signatureAlgorithm, NID_ED25519, 596 V_ASN1_UNDEF, NULL)) 597 return -1; 598 599 return 1; 600 } 601 #endif 602 603 static int 604 ecx_sign_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) 605 { 606 switch (op) { 607 #ifndef OPENSSL_NO_CMS 608 case ASN1_PKEY_CTRL_CMS_SIGN: 609 return ecx_cms_sign_or_verify(pkey, arg1, arg2); 610 #endif 611 case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 612 /* PureEdDSA does its own hashing. */ 613 *(int *)arg2 = NID_undef; 614 return 2; 615 } 616 return -2; 617 } 618 619 static int 620 ecx_set_priv_key(EVP_PKEY *pkey, const uint8_t *priv, size_t len) 621 { 622 struct ecx_key_st *ecx_key = NULL; 623 int ret = 0; 624 625 if (priv == NULL || len != ecx_key_len(pkey->ameth->pkey_id)) { 626 ECerror(EC_R_INVALID_ENCODING); 627 goto err; 628 } 629 630 if ((ecx_key = ecx_key_new(pkey->ameth->pkey_id)) == NULL) 631 goto err; 632 if (!ecx_key_set_priv(ecx_key, priv, len)) 633 goto err; 634 if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx_key)) 635 goto err; 636 ecx_key = NULL; 637 638 ret = 1; 639 640 err: 641 ecx_key_free(ecx_key); 642 643 return ret; 644 } 645 646 static int 647 ecx_set_pub_key(EVP_PKEY *pkey, const uint8_t *pub, size_t len) 648 { 649 struct ecx_key_st *ecx_key = NULL; 650 int ret = 0; 651 652 if (pub == NULL || len != ecx_key_len(pkey->ameth->pkey_id)) { 653 ECerror(EC_R_INVALID_ENCODING); 654 goto err; 655 } 656 657 if ((ecx_key = ecx_key_new(pkey->ameth->pkey_id)) == NULL) 658 goto err; 659 if (!ecx_key_set_pub(ecx_key, pub, len)) 660 goto err; 661 if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx_key)) 662 goto err; 663 ecx_key = NULL; 664 665 ret = 1; 666 667 err: 668 ecx_key_free(ecx_key); 669 670 return ret; 671 } 672 673 static int 674 ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *out_priv, size_t *out_len) 675 { 676 struct ecx_key_st *ecx_key = pkey->pkey.ecx; 677 CBS cbs; 678 679 if (out_priv == NULL) { 680 *out_len = ecx_key_len(pkey->ameth->pkey_id); 681 return 1; 682 } 683 684 if (ecx_key == NULL || ecx_key->priv_key == NULL) 685 return 0; 686 687 CBS_init(&cbs, ecx_key->priv_key, ecx_key->priv_key_len); 688 if (!CBS_write_bytes(&cbs, out_priv, *out_len, out_len)) 689 return 0; 690 691 return 1; 692 } 693 694 static int 695 ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *out_pub, size_t *out_len) 696 { 697 struct ecx_key_st *ecx_key = pkey->pkey.ecx; 698 CBS cbs; 699 700 if (out_pub == NULL) { 701 *out_len = ecx_key_len(pkey->ameth->pkey_id); 702 return 1; 703 } 704 705 if (ecx_key == NULL || ecx_key->pub_key == NULL) 706 return 0; 707 708 CBS_init(&cbs, ecx_key->pub_key, ecx_key->pub_key_len); 709 if (!CBS_write_bytes(&cbs, out_pub, *out_len, out_len)) 710 return 0; 711 712 return 1; 713 } 714 715 static int 716 pkey_ecx_keygen(EVP_PKEY_CTX *pkey_ctx, EVP_PKEY *pkey) 717 { 718 struct ecx_key_st *ecx_key = NULL; 719 int ret = 0; 720 721 if ((ecx_key = ecx_key_new(pkey_ctx->pmeth->pkey_id)) == NULL) 722 goto err; 723 if (!ecx_key_generate(ecx_key)) 724 goto err; 725 if (!EVP_PKEY_assign(pkey, pkey_ctx->pmeth->pkey_id, ecx_key)) 726 goto err; 727 ecx_key = NULL; 728 729 ret = 1; 730 731 err: 732 ecx_key_free(ecx_key); 733 734 return ret; 735 } 736 737 static int 738 pkey_ecx_derive(EVP_PKEY_CTX *pkey_ctx, unsigned char *out_key, 739 size_t *out_key_len) 740 { 741 struct ecx_key_st *ecx_key, *ecx_peer_key; 742 743 if (pkey_ctx->pkey == NULL || pkey_ctx->peerkey == NULL) { 744 ECerror(EC_R_KEYS_NOT_SET); 745 return 0; 746 } 747 748 if ((ecx_key = pkey_ctx->pkey->pkey.ecx) == NULL) { 749 ECerror(EC_R_INVALID_PRIVATE_KEY); 750 return 0; 751 } 752 if (ecx_key->priv_key == NULL) { 753 ECerror(EC_R_INVALID_PRIVATE_KEY); 754 return 0; 755 } 756 757 if ((ecx_peer_key = pkey_ctx->peerkey->pkey.ecx) == NULL) { 758 ECerror(EC_R_INVALID_PEER_KEY); 759 return 0; 760 } 761 762 if (out_key != NULL) { 763 if (!X25519(out_key, ecx_key->priv_key, ecx_peer_key->pub_key)) 764 return 0; 765 } 766 767 *out_key_len = X25519_KEYLEN; 768 769 return 1; 770 } 771 772 static int 773 pkey_ecx_ctrl(EVP_PKEY_CTX *pkey_ctx, int op, int arg1, void *arg2) 774 { 775 if (op == EVP_PKEY_CTRL_PEER_KEY) 776 return 1; 777 778 return -2; 779 } 780 781 static int 782 ecx_item_verify(EVP_MD_CTX *md_ctx, const ASN1_ITEM *it, void *asn, 783 X509_ALGOR *algor, ASN1_BIT_STRING *abs, EVP_PKEY *pkey) 784 { 785 const ASN1_OBJECT *aobj; 786 int nid, param_type; 787 788 X509_ALGOR_get0(&aobj, ¶m_type, NULL, algor); 789 790 nid = OBJ_obj2nid(aobj); 791 792 if (nid != NID_ED25519 || param_type != V_ASN1_UNDEF) { 793 ECerror(EC_R_INVALID_ENCODING); 794 return -1; 795 } 796 797 if (!EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, pkey)) 798 return -1; 799 800 return 2; 801 } 802 803 static int 804 ecx_item_sign(EVP_MD_CTX *md_ctx, const ASN1_ITEM *it, void *asn, 805 X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *abs) 806 { 807 if (!X509_ALGOR_set0_by_nid(algor1, NID_ED25519, V_ASN1_UNDEF, NULL)) 808 return 0; 809 810 if (algor2 != NULL) { 811 if (!X509_ALGOR_set0_by_nid(algor2, NID_ED25519, V_ASN1_UNDEF, 812 NULL)) 813 return 0; 814 } 815 816 /* Tell ASN1_item_sign_ctx() that identifiers are set and it needs to sign. */ 817 return 3; 818 } 819 820 static int 821 pkey_ecx_digestsign(EVP_MD_CTX *md_ctx, unsigned char *out_sig, 822 size_t *out_sig_len, const unsigned char *message, size_t message_len) 823 { 824 struct ecx_key_st *ecx_key; 825 EVP_PKEY_CTX *pkey_ctx; 826 827 pkey_ctx = EVP_MD_CTX_pkey_ctx(md_ctx); 828 ecx_key = pkey_ctx->pkey->pkey.ecx; 829 830 if (out_sig == NULL) { 831 *out_sig_len = ecx_sig_size(pkey_ctx->pkey); 832 return 1; 833 } 834 if (*out_sig_len < ecx_sig_size(pkey_ctx->pkey)) { 835 ECerror(EC_R_BUFFER_TOO_SMALL); 836 return 0; 837 } 838 839 if (ecx_key == NULL) 840 return 0; 841 if (ecx_key->priv_key == NULL || ecx_key->pub_key == NULL) 842 return 0; 843 844 if (!ED25519_sign(out_sig, message, message_len, ecx_key->pub_key, 845 ecx_key->priv_key)) 846 return 0; 847 848 *out_sig_len = ecx_sig_size(pkey_ctx->pkey); 849 850 return 1; 851 } 852 853 static int 854 pkey_ecx_digestverify(EVP_MD_CTX *md_ctx, const unsigned char *sig, 855 size_t sig_len, const unsigned char *message, size_t message_len) 856 { 857 struct ecx_key_st *ecx_key; 858 EVP_PKEY_CTX *pkey_ctx; 859 860 pkey_ctx = EVP_MD_CTX_pkey_ctx(md_ctx); 861 ecx_key = pkey_ctx->pkey->pkey.ecx; 862 863 if (ecx_key == NULL || ecx_key->pub_key == NULL) 864 return -1; 865 if (sig_len != ecx_sig_size(pkey_ctx->pkey)) 866 return -1; 867 868 return ED25519_verify(message, message_len, sig, ecx_key->pub_key); 869 } 870 871 static int 872 pkey_ecx_ed_ctrl(EVP_PKEY_CTX *pkey_ctx, int op, int arg1, void *arg2) 873 { 874 switch (op) { 875 case EVP_PKEY_CTRL_MD: 876 /* PureEdDSA does its own hashing. */ 877 if (arg2 != NULL && (const EVP_MD *)arg2 != EVP_md_null()) { 878 ECerror(EC_R_INVALID_DIGEST_TYPE); 879 return 0; 880 } 881 return 1; 882 883 #ifndef OPENSSL_NO_CMS 884 case EVP_PKEY_CTRL_CMS_SIGN: 885 #endif 886 case EVP_PKEY_CTRL_DIGESTINIT: 887 return 1; 888 } 889 return -2; 890 } 891 892 const EVP_PKEY_ASN1_METHOD x25519_asn1_meth = { 893 .base_method = &x25519_asn1_meth, 894 .pkey_id = EVP_PKEY_X25519, 895 .pkey_flags = 0, 896 .pem_str = "X25519", 897 .info = "OpenSSL X25519 algorithm", 898 899 .pub_decode = ecx_pub_decode, 900 .pub_encode = ecx_pub_encode, 901 .pub_cmp = ecx_pub_cmp, 902 .pub_print = ecx_pub_print, 903 904 .priv_decode = ecx_priv_decode, 905 .priv_encode = ecx_priv_encode, 906 .priv_print = ecx_priv_print, 907 908 .pkey_size = ecx_size, 909 .pkey_bits = ecx_bits, 910 .pkey_security_bits = ecx_security_bits, 911 912 .param_cmp = ecx_param_cmp, 913 914 .pkey_free = ecx_free, 915 .pkey_ctrl = ecx_ctrl, 916 917 .set_priv_key = ecx_set_priv_key, 918 .set_pub_key = ecx_set_pub_key, 919 .get_priv_key = ecx_get_priv_key, 920 .get_pub_key = ecx_get_pub_key, 921 }; 922 923 const EVP_PKEY_METHOD x25519_pkey_meth = { 924 .pkey_id = EVP_PKEY_X25519, 925 .keygen = pkey_ecx_keygen, 926 .derive = pkey_ecx_derive, 927 .ctrl = pkey_ecx_ctrl, 928 }; 929 930 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { 931 .base_method = &ed25519_asn1_meth, 932 .pkey_id = EVP_PKEY_ED25519, 933 .pkey_flags = 0, 934 .pem_str = "ED25519", 935 .info = "OpenSSL ED25519 algorithm", 936 937 .pub_decode = ecx_pub_decode, 938 .pub_encode = ecx_pub_encode, 939 .pub_cmp = ecx_pub_cmp, 940 .pub_print = ecx_pub_print, 941 942 .priv_decode = ecx_priv_decode, 943 .priv_encode = ecx_priv_encode, 944 .priv_print = ecx_priv_print, 945 946 .pkey_size = ecx_sig_size, 947 .pkey_bits = ecx_bits, 948 .pkey_security_bits = ecx_security_bits, 949 950 .signature_info = ecx_signature_info, 951 952 .param_cmp = ecx_param_cmp, 953 954 .pkey_free = ecx_free, 955 .pkey_ctrl = ecx_sign_ctrl, 956 957 .item_verify = ecx_item_verify, 958 .item_sign = ecx_item_sign, 959 960 .set_priv_key = ecx_set_priv_key, 961 .set_pub_key = ecx_set_pub_key, 962 .get_priv_key = ecx_get_priv_key, 963 .get_pub_key = ecx_get_pub_key, 964 }; 965 966 const EVP_PKEY_METHOD ed25519_pkey_meth = { 967 .pkey_id = EVP_PKEY_ED25519, 968 .flags = EVP_PKEY_FLAG_SIGCTX_CUSTOM, 969 .keygen = pkey_ecx_keygen, 970 .ctrl = pkey_ecx_ed_ctrl, 971 .digestsign = pkey_ecx_digestsign, 972 .digestverify = pkey_ecx_digestverify, 973 }; 974