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