1 /* 2 * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 /* 11 * ECDSA low level APIs are deprecated for public use, but still ok for 12 * internal use. 13 */ 14 #include "internal/deprecated.h" 15 16 #include <stdio.h> 17 #include <openssl/x509.h> 18 #include <openssl/ec.h> 19 #include <openssl/core_names.h> 20 #include <openssl/param_build.h> 21 #include <openssl/rand.h> 22 #include "internal/cryptlib.h" 23 #include "internal/provider.h" 24 #include "crypto/asn1.h" 25 #include "crypto/evp.h" 26 #include "crypto/ecx.h" 27 #include "ec_local.h" 28 #include "curve448/curve448_local.h" 29 #include "ecx_backend.h" 30 31 static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) 32 { 33 const ECX_KEY *ecxkey = pkey->pkey.ecx; 34 unsigned char *penc; 35 36 if (ecxkey == NULL) { 37 ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); 38 return 0; 39 } 40 41 penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey)); 42 if (penc == NULL) { 43 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 44 return 0; 45 } 46 47 if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id), 48 V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) { 49 OPENSSL_free(penc); 50 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 51 return 0; 52 } 53 return 1; 54 } 55 56 static int ecx_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) 57 { 58 const unsigned char *p; 59 int pklen; 60 X509_ALGOR *palg; 61 ECX_KEY *ecx; 62 int ret = 0; 63 64 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) 65 return 0; 66 ecx = ossl_ecx_key_op(palg, p, pklen, pkey->ameth->pkey_id, 67 KEY_OP_PUBLIC, NULL, NULL); 68 if (ecx != NULL) { 69 ret = 1; 70 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx); 71 } 72 return ret; 73 } 74 75 static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) 76 { 77 const ECX_KEY *akey = a->pkey.ecx; 78 const ECX_KEY *bkey = b->pkey.ecx; 79 80 if (akey == NULL || bkey == NULL) 81 return -2; 82 83 return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0; 84 } 85 86 static int ecx_priv_decode_ex(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8, 87 OSSL_LIB_CTX *libctx, const char *propq) 88 { 89 int ret = 0; 90 ECX_KEY *ecx = ossl_ecx_key_from_pkcs8(p8, libctx, propq); 91 92 if (ecx != NULL) { 93 ret = 1; 94 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx); 95 } 96 97 return ret; 98 } 99 100 static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) 101 { 102 const ECX_KEY *ecxkey = pkey->pkey.ecx; 103 ASN1_OCTET_STRING oct; 104 unsigned char *penc = NULL; 105 int penclen; 106 107 if (ecxkey == NULL || ecxkey->privkey == NULL) { 108 ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY); 109 return 0; 110 } 111 112 oct.data = ecxkey->privkey; 113 oct.length = KEYLEN(pkey); 114 oct.flags = 0; 115 116 penclen = i2d_ASN1_OCTET_STRING(&oct, &penc); 117 if (penclen < 0) { 118 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 119 return 0; 120 } 121 122 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0, 123 V_ASN1_UNDEF, NULL, penc, penclen)) { 124 OPENSSL_clear_free(penc, penclen); 125 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 126 return 0; 127 } 128 129 return 1; 130 } 131 132 static int ecx_size(const EVP_PKEY *pkey) 133 { 134 return KEYLEN(pkey); 135 } 136 137 static int ecx_bits(const EVP_PKEY *pkey) 138 { 139 if (IS25519(pkey->ameth->pkey_id)) { 140 return X25519_BITS; 141 } else if(ISX448(pkey->ameth->pkey_id)) { 142 return X448_BITS; 143 } else { 144 return ED448_BITS; 145 } 146 } 147 148 static int ecx_security_bits(const EVP_PKEY *pkey) 149 { 150 if (IS25519(pkey->ameth->pkey_id)) { 151 return X25519_SECURITY_BITS; 152 } else { 153 return X448_SECURITY_BITS; 154 } 155 } 156 157 static void ecx_free(EVP_PKEY *pkey) 158 { 159 ossl_ecx_key_free(pkey->pkey.ecx); 160 } 161 162 /* "parameters" are always equal */ 163 static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) 164 { 165 return 1; 166 } 167 168 static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent, 169 ASN1_PCTX *ctx, ecx_key_op_t op) 170 { 171 const ECX_KEY *ecxkey = pkey->pkey.ecx; 172 const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id); 173 174 if (op == KEY_OP_PRIVATE) { 175 if (ecxkey == NULL || ecxkey->privkey == NULL) { 176 if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0) 177 return 0; 178 return 1; 179 } 180 if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0) 181 return 0; 182 if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0) 183 return 0; 184 if (ASN1_buf_print(bp, ecxkey->privkey, KEYLEN(pkey), 185 indent + 4) == 0) 186 return 0; 187 } else { 188 if (ecxkey == NULL) { 189 if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0) 190 return 0; 191 return 1; 192 } 193 if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0) 194 return 0; 195 } 196 if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0) 197 return 0; 198 199 if (ASN1_buf_print(bp, ecxkey->pubkey, KEYLEN(pkey), 200 indent + 4) == 0) 201 return 0; 202 return 1; 203 } 204 205 static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, 206 ASN1_PCTX *ctx) 207 { 208 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PRIVATE); 209 } 210 211 static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, 212 ASN1_PCTX *ctx) 213 { 214 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PUBLIC); 215 } 216 217 static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) 218 { 219 switch (op) { 220 221 case ASN1_PKEY_CTRL_SET1_TLS_ENCPT: { 222 ECX_KEY *ecx = ossl_ecx_key_op(NULL, arg2, arg1, pkey->ameth->pkey_id, 223 KEY_OP_PUBLIC, NULL, NULL); 224 225 if (ecx != NULL) { 226 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx); 227 return 1; 228 } 229 return 0; 230 } 231 case ASN1_PKEY_CTRL_GET1_TLS_ENCPT: 232 if (pkey->pkey.ecx != NULL) { 233 unsigned char **ppt = arg2; 234 235 *ppt = OPENSSL_memdup(pkey->pkey.ecx->pubkey, KEYLEN(pkey)); 236 if (*ppt != NULL) 237 return KEYLEN(pkey); 238 } 239 return 0; 240 241 default: 242 return -2; 243 244 } 245 } 246 247 static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) 248 { 249 switch (op) { 250 case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 251 /* We currently only support Pure EdDSA which takes no digest */ 252 *(int *)arg2 = NID_undef; 253 return 2; 254 255 default: 256 return -2; 257 258 } 259 } 260 261 static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv, 262 size_t len) 263 { 264 OSSL_LIB_CTX *libctx = NULL; 265 ECX_KEY *ecx = NULL; 266 267 if (pkey->keymgmt != NULL) 268 libctx = ossl_provider_libctx(EVP_KEYMGMT_get0_provider(pkey->keymgmt)); 269 270 ecx = ossl_ecx_key_op(NULL, priv, len, pkey->ameth->pkey_id, 271 KEY_OP_PRIVATE, libctx, NULL); 272 273 if (ecx != NULL) { 274 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx); 275 return 1; 276 } 277 return 0; 278 } 279 280 static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len) 281 { 282 OSSL_LIB_CTX *libctx = NULL; 283 ECX_KEY *ecx = NULL; 284 285 if (pkey->keymgmt != NULL) 286 libctx = ossl_provider_libctx(EVP_KEYMGMT_get0_provider(pkey->keymgmt)); 287 288 ecx = ossl_ecx_key_op(NULL, pub, len, pkey->ameth->pkey_id, 289 KEY_OP_PUBLIC, libctx, NULL); 290 291 if (ecx != NULL) { 292 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx); 293 return 1; 294 } 295 return 0; 296 } 297 298 static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv, 299 size_t *len) 300 { 301 const ECX_KEY *key = pkey->pkey.ecx; 302 303 if (priv == NULL) { 304 *len = KEYLENID(pkey->ameth->pkey_id); 305 return 1; 306 } 307 308 if (key == NULL 309 || key->privkey == NULL 310 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id)) 311 return 0; 312 313 *len = KEYLENID(pkey->ameth->pkey_id); 314 memcpy(priv, key->privkey, *len); 315 316 return 1; 317 } 318 319 static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub, 320 size_t *len) 321 { 322 const ECX_KEY *key = pkey->pkey.ecx; 323 324 if (pub == NULL) { 325 *len = KEYLENID(pkey->ameth->pkey_id); 326 return 1; 327 } 328 329 if (key == NULL 330 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id)) 331 return 0; 332 333 *len = KEYLENID(pkey->ameth->pkey_id); 334 memcpy(pub, key->pubkey, *len); 335 336 return 1; 337 } 338 339 static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey) 340 { 341 /* 342 * We provide no mechanism to "update" an ECX key once it has been set, 343 * therefore we do not have to maintain a dirty count. 344 */ 345 return 1; 346 } 347 348 static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata, 349 OSSL_FUNC_keymgmt_import_fn *importer, 350 OSSL_LIB_CTX *libctx, const char *propq) 351 { 352 const ECX_KEY *key = from->pkey.ecx; 353 OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new(); 354 OSSL_PARAM *params = NULL; 355 int selection = 0; 356 int rv = 0; 357 358 if (tmpl == NULL) 359 return 0; 360 361 /* A key must at least have a public part */ 362 if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY, 363 key->pubkey, key->keylen)) 364 goto err; 365 selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY; 366 367 if (key->privkey != NULL) { 368 if (!OSSL_PARAM_BLD_push_octet_string(tmpl, 369 OSSL_PKEY_PARAM_PRIV_KEY, 370 key->privkey, key->keylen)) 371 goto err; 372 selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY; 373 } 374 375 params = OSSL_PARAM_BLD_to_param(tmpl); 376 377 /* We export, the provider imports */ 378 rv = importer(to_keydata, selection, params); 379 380 err: 381 OSSL_PARAM_BLD_free(tmpl); 382 OSSL_PARAM_free(params); 383 return rv; 384 } 385 386 static int ecx_generic_import_from(const OSSL_PARAM params[], void *vpctx, 387 int keytype) 388 { 389 EVP_PKEY_CTX *pctx = vpctx; 390 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); 391 ECX_KEY *ecx = ossl_ecx_key_new(pctx->libctx, KEYNID2TYPE(keytype), 0, 392 pctx->propquery); 393 394 if (ecx == NULL) { 395 ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); 396 return 0; 397 } 398 399 if (!ossl_ecx_key_fromdata(ecx, params, 1) 400 || !EVP_PKEY_assign(pkey, keytype, ecx)) { 401 ossl_ecx_key_free(ecx); 402 return 0; 403 } 404 return 1; 405 } 406 407 static int ecx_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) 408 { 409 ECX_KEY *ecx = from->pkey.ecx, *dupkey = NULL; 410 int ret; 411 412 if (ecx != NULL) { 413 dupkey = ossl_ecx_key_dup(ecx, OSSL_KEYMGMT_SELECT_ALL); 414 if (dupkey == NULL) 415 return 0; 416 } 417 418 ret = EVP_PKEY_assign(to, from->type, dupkey); 419 if (!ret) 420 ossl_ecx_key_free(dupkey); 421 return ret; 422 } 423 424 static int x25519_import_from(const OSSL_PARAM params[], void *vpctx) 425 { 426 return ecx_generic_import_from(params, vpctx, EVP_PKEY_X25519); 427 } 428 429 const EVP_PKEY_ASN1_METHOD ossl_ecx25519_asn1_meth = { 430 EVP_PKEY_X25519, 431 EVP_PKEY_X25519, 432 0, 433 "X25519", 434 "OpenSSL X25519 algorithm", 435 436 ecx_pub_decode, 437 ecx_pub_encode, 438 ecx_pub_cmp, 439 ecx_pub_print, 440 441 NULL, 442 ecx_priv_encode, 443 ecx_priv_print, 444 445 ecx_size, 446 ecx_bits, 447 ecx_security_bits, 448 449 0, 0, 0, 0, 450 ecx_cmp_parameters, 451 0, 0, 452 453 ecx_free, 454 ecx_ctrl, 455 NULL, 456 NULL, 457 458 NULL, 459 NULL, 460 NULL, 461 462 NULL, 463 NULL, 464 NULL, 465 466 ecx_set_priv_key, 467 ecx_set_pub_key, 468 ecx_get_priv_key, 469 ecx_get_pub_key, 470 ecx_pkey_dirty_cnt, 471 ecx_pkey_export_to, 472 x25519_import_from, 473 ecx_pkey_copy, 474 475 ecx_priv_decode_ex 476 }; 477 478 static int x448_import_from(const OSSL_PARAM params[], void *vpctx) 479 { 480 return ecx_generic_import_from(params, vpctx, EVP_PKEY_X448); 481 } 482 483 const EVP_PKEY_ASN1_METHOD ossl_ecx448_asn1_meth = { 484 EVP_PKEY_X448, 485 EVP_PKEY_X448, 486 0, 487 "X448", 488 "OpenSSL X448 algorithm", 489 490 ecx_pub_decode, 491 ecx_pub_encode, 492 ecx_pub_cmp, 493 ecx_pub_print, 494 495 NULL, 496 ecx_priv_encode, 497 ecx_priv_print, 498 499 ecx_size, 500 ecx_bits, 501 ecx_security_bits, 502 503 0, 0, 0, 0, 504 ecx_cmp_parameters, 505 0, 0, 506 507 ecx_free, 508 ecx_ctrl, 509 NULL, 510 NULL, 511 512 NULL, 513 NULL, 514 NULL, 515 516 NULL, 517 NULL, 518 NULL, 519 520 ecx_set_priv_key, 521 ecx_set_pub_key, 522 ecx_get_priv_key, 523 ecx_get_pub_key, 524 ecx_pkey_dirty_cnt, 525 ecx_pkey_export_to, 526 x448_import_from, 527 ecx_pkey_copy, 528 529 ecx_priv_decode_ex 530 }; 531 532 static int ecd_size25519(const EVP_PKEY *pkey) 533 { 534 return ED25519_SIGSIZE; 535 } 536 537 static int ecd_size448(const EVP_PKEY *pkey) 538 { 539 return ED448_SIGSIZE; 540 } 541 542 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, 543 const void *asn, const X509_ALGOR *sigalg, 544 const ASN1_BIT_STRING *str, EVP_PKEY *pkey) 545 { 546 const ASN1_OBJECT *obj; 547 int ptype; 548 int nid; 549 550 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */ 551 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg); 552 nid = OBJ_obj2nid(obj); 553 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) { 554 ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); 555 return 0; 556 } 557 558 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey)) 559 return 0; 560 561 return 2; 562 } 563 564 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, 565 const void *asn, 566 X509_ALGOR *alg1, X509_ALGOR *alg2, 567 ASN1_BIT_STRING *str) 568 { 569 /* Set algorithms identifiers */ 570 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL); 571 if (alg2) 572 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL); 573 /* Algorithm identifiers set: carry on as normal */ 574 return 3; 575 } 576 577 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg, 578 const ASN1_STRING *sig) 579 { 580 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS, 581 X509_SIG_INFO_TLS); 582 return 1; 583 } 584 585 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, 586 const void *asn, 587 X509_ALGOR *alg1, X509_ALGOR *alg2, 588 ASN1_BIT_STRING *str) 589 { 590 /* Set algorithm identifier */ 591 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL); 592 if (alg2 != NULL) 593 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL); 594 /* Algorithm identifier set: carry on as normal */ 595 return 3; 596 } 597 598 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg, 599 const ASN1_STRING *sig) 600 { 601 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS, 602 X509_SIG_INFO_TLS); 603 return 1; 604 } 605 606 static int ed25519_import_from(const OSSL_PARAM params[], void *vpctx) 607 { 608 return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED25519); 609 } 610 611 const EVP_PKEY_ASN1_METHOD ossl_ed25519_asn1_meth = { 612 EVP_PKEY_ED25519, 613 EVP_PKEY_ED25519, 614 0, 615 "ED25519", 616 "OpenSSL ED25519 algorithm", 617 618 ecx_pub_decode, 619 ecx_pub_encode, 620 ecx_pub_cmp, 621 ecx_pub_print, 622 623 NULL, 624 ecx_priv_encode, 625 ecx_priv_print, 626 627 ecd_size25519, 628 ecx_bits, 629 ecx_security_bits, 630 631 0, 0, 0, 0, 632 ecx_cmp_parameters, 633 0, 0, 634 635 ecx_free, 636 ecd_ctrl, 637 NULL, 638 NULL, 639 ecd_item_verify, 640 ecd_item_sign25519, 641 ecd_sig_info_set25519, 642 643 NULL, 644 NULL, 645 NULL, 646 647 ecx_set_priv_key, 648 ecx_set_pub_key, 649 ecx_get_priv_key, 650 ecx_get_pub_key, 651 ecx_pkey_dirty_cnt, 652 ecx_pkey_export_to, 653 ed25519_import_from, 654 ecx_pkey_copy, 655 656 ecx_priv_decode_ex 657 }; 658 659 static int ed448_import_from(const OSSL_PARAM params[], void *vpctx) 660 { 661 return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED448); 662 } 663 664 const EVP_PKEY_ASN1_METHOD ossl_ed448_asn1_meth = { 665 EVP_PKEY_ED448, 666 EVP_PKEY_ED448, 667 0, 668 "ED448", 669 "OpenSSL ED448 algorithm", 670 671 ecx_pub_decode, 672 ecx_pub_encode, 673 ecx_pub_cmp, 674 ecx_pub_print, 675 676 NULL, 677 ecx_priv_encode, 678 ecx_priv_print, 679 680 ecd_size448, 681 ecx_bits, 682 ecx_security_bits, 683 684 0, 0, 0, 0, 685 ecx_cmp_parameters, 686 0, 0, 687 688 ecx_free, 689 ecd_ctrl, 690 NULL, 691 NULL, 692 ecd_item_verify, 693 ecd_item_sign448, 694 ecd_sig_info_set448, 695 696 NULL, 697 NULL, 698 NULL, 699 700 ecx_set_priv_key, 701 ecx_set_pub_key, 702 ecx_get_priv_key, 703 ecx_get_pub_key, 704 ecx_pkey_dirty_cnt, 705 ecx_pkey_export_to, 706 ed448_import_from, 707 ecx_pkey_copy, 708 709 ecx_priv_decode_ex 710 }; 711 712 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 713 { 714 ECX_KEY *ecx = ossl_ecx_key_op(NULL, NULL, 0, ctx->pmeth->pkey_id, 715 KEY_OP_KEYGEN, NULL, NULL); 716 717 if (ecx != NULL) { 718 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, ecx); 719 return 1; 720 } 721 return 0; 722 } 723 724 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key, 725 size_t *keylen, 726 const unsigned char **privkey, 727 const unsigned char **pubkey) 728 { 729 const ECX_KEY *ecxkey, *peerkey; 730 731 if (ctx->pkey == NULL || ctx->peerkey == NULL) { 732 ERR_raise(ERR_LIB_EC, EC_R_KEYS_NOT_SET); 733 return 0; 734 } 735 ecxkey = evp_pkey_get_legacy(ctx->pkey); 736 peerkey = evp_pkey_get_legacy(ctx->peerkey); 737 if (ecxkey == NULL || ecxkey->privkey == NULL) { 738 ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY); 739 return 0; 740 } 741 if (peerkey == NULL) { 742 ERR_raise(ERR_LIB_EC, EC_R_INVALID_PEER_KEY); 743 return 0; 744 } 745 *privkey = ecxkey->privkey; 746 *pubkey = peerkey->pubkey; 747 748 return 1; 749 } 750 751 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key, 752 size_t *keylen) 753 { 754 const unsigned char *privkey, *pubkey; 755 756 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey) 757 || (key != NULL 758 && ossl_x25519(key, privkey, pubkey) == 0)) 759 return 0; 760 *keylen = X25519_KEYLEN; 761 return 1; 762 } 763 764 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key, 765 size_t *keylen) 766 { 767 const unsigned char *privkey, *pubkey; 768 769 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey) 770 || (key != NULL 771 && ossl_x448(key, privkey, pubkey) == 0)) 772 return 0; 773 *keylen = X448_KEYLEN; 774 return 1; 775 } 776 777 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 778 { 779 /* Only need to handle peer key for derivation */ 780 if (type == EVP_PKEY_CTRL_PEER_KEY) 781 return 1; 782 return -2; 783 } 784 785 static const EVP_PKEY_METHOD ecx25519_pkey_meth = { 786 EVP_PKEY_X25519, 787 0, 0, 0, 0, 0, 0, 0, 788 pkey_ecx_keygen, 789 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 790 pkey_ecx_derive25519, 791 pkey_ecx_ctrl, 792 0 793 }; 794 795 static const EVP_PKEY_METHOD ecx448_pkey_meth = { 796 EVP_PKEY_X448, 797 0, 0, 0, 0, 0, 0, 0, 798 pkey_ecx_keygen, 799 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 800 pkey_ecx_derive448, 801 pkey_ecx_ctrl, 802 0 803 }; 804 805 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig, 806 size_t *siglen, const unsigned char *tbs, 807 size_t tbslen) 808 { 809 const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey); 810 811 if (edkey == NULL) { 812 ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); 813 return 0; 814 } 815 816 if (sig == NULL) { 817 *siglen = ED25519_SIGSIZE; 818 return 1; 819 } 820 if (*siglen < ED25519_SIGSIZE) { 821 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); 822 return 0; 823 } 824 825 if (ossl_ed25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL, 826 NULL) == 0) 827 return 0; 828 *siglen = ED25519_SIGSIZE; 829 return 1; 830 } 831 832 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig, 833 size_t *siglen, const unsigned char *tbs, 834 size_t tbslen) 835 { 836 const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey); 837 838 if (edkey == NULL) { 839 ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); 840 return 0; 841 } 842 843 if (sig == NULL) { 844 *siglen = ED448_SIGSIZE; 845 return 1; 846 } 847 if (*siglen < ED448_SIGSIZE) { 848 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); 849 return 0; 850 } 851 852 if (ossl_ed448_sign(edkey->libctx, sig, tbs, tbslen, edkey->pubkey, 853 edkey->privkey, NULL, 0, edkey->propq) == 0) 854 return 0; 855 *siglen = ED448_SIGSIZE; 856 return 1; 857 } 858 859 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig, 860 size_t siglen, const unsigned char *tbs, 861 size_t tbslen) 862 { 863 const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey); 864 865 if (edkey == NULL) { 866 ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); 867 return 0; 868 } 869 870 if (siglen != ED25519_SIGSIZE) 871 return 0; 872 873 return ossl_ed25519_verify(tbs, tbslen, sig, edkey->pubkey, 874 edkey->libctx, edkey->propq); 875 } 876 877 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig, 878 size_t siglen, const unsigned char *tbs, 879 size_t tbslen) 880 { 881 const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey); 882 883 if (edkey == NULL) { 884 ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); 885 return 0; 886 } 887 888 if (siglen != ED448_SIGSIZE) 889 return 0; 890 891 return ossl_ed448_verify(edkey->libctx, tbs, tbslen, sig, edkey->pubkey, 892 NULL, 0, edkey->propq); 893 } 894 895 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 896 { 897 switch (type) { 898 case EVP_PKEY_CTRL_MD: 899 /* Only NULL allowed as digest */ 900 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null()) 901 return 1; 902 ERR_raise(ERR_LIB_EC, EC_R_INVALID_DIGEST_TYPE); 903 return 0; 904 905 case EVP_PKEY_CTRL_DIGESTINIT: 906 return 1; 907 } 908 return -2; 909 } 910 911 static const EVP_PKEY_METHOD ed25519_pkey_meth = { 912 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM, 913 0, 0, 0, 0, 0, 0, 914 pkey_ecx_keygen, 915 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 916 pkey_ecd_ctrl, 917 0, 918 pkey_ecd_digestsign25519, 919 pkey_ecd_digestverify25519 920 }; 921 922 static const EVP_PKEY_METHOD ed448_pkey_meth = { 923 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM, 924 0, 0, 0, 0, 0, 0, 925 pkey_ecx_keygen, 926 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 927 pkey_ecd_ctrl, 928 0, 929 pkey_ecd_digestsign448, 930 pkey_ecd_digestverify448 931 }; 932 933 #ifdef S390X_EC_ASM 934 # include "s390x_arch.h" 935 936 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 937 { 938 static const unsigned char generator[] = { 939 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 940 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 941 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 942 }; 943 ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X25519, 1, 944 ctx->propquery); 945 unsigned char *privkey = NULL, *pubkey; 946 947 if (key == NULL) { 948 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 949 goto err; 950 } 951 952 pubkey = key->pubkey; 953 954 privkey = ossl_ecx_key_allocate_privkey(key); 955 if (privkey == NULL) { 956 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 957 goto err; 958 } 959 960 if (RAND_priv_bytes_ex(ctx->libctx, privkey, X25519_KEYLEN, 0) <= 0) 961 goto err; 962 963 privkey[0] &= 248; 964 privkey[31] &= 127; 965 privkey[31] |= 64; 966 967 if (s390x_x25519_mul(pubkey, generator, privkey) != 1) 968 goto err; 969 970 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key); 971 return 1; 972 err: 973 ossl_ecx_key_free(key); 974 return 0; 975 } 976 977 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 978 { 979 static const unsigned char generator[] = { 980 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 981 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 982 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 983 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 984 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 985 }; 986 ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X448, 1, 987 ctx->propquery); 988 unsigned char *privkey = NULL, *pubkey; 989 990 if (key == NULL) { 991 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 992 goto err; 993 } 994 995 pubkey = key->pubkey; 996 997 privkey = ossl_ecx_key_allocate_privkey(key); 998 if (privkey == NULL) { 999 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 1000 goto err; 1001 } 1002 1003 if (RAND_priv_bytes_ex(ctx->libctx, privkey, X448_KEYLEN, 0) <= 0) 1004 goto err; 1005 1006 privkey[0] &= 252; 1007 privkey[55] |= 128; 1008 1009 if (s390x_x448_mul(pubkey, generator, privkey) != 1) 1010 goto err; 1011 1012 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key); 1013 return 1; 1014 err: 1015 ossl_ecx_key_free(key); 1016 return 0; 1017 } 1018 1019 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 1020 { 1021 static const unsigned char generator_x[] = { 1022 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95, 1023 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, 1024 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21 1025 }; 1026 static const unsigned char generator_y[] = { 1027 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 1028 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 1029 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 1030 }; 1031 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH]; 1032 ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED25519, 1, 1033 ctx->propquery); 1034 unsigned char *privkey = NULL, *pubkey; 1035 unsigned int sz; 1036 EVP_MD *md = NULL; 1037 int rv; 1038 1039 if (key == NULL) { 1040 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 1041 goto err; 1042 } 1043 1044 pubkey = key->pubkey; 1045 1046 privkey = ossl_ecx_key_allocate_privkey(key); 1047 if (privkey == NULL) { 1048 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 1049 goto err; 1050 } 1051 1052 if (RAND_priv_bytes_ex(ctx->libctx, privkey, ED25519_KEYLEN, 0) <= 0) 1053 goto err; 1054 1055 md = EVP_MD_fetch(ctx->libctx, "SHA512", ctx->propquery); 1056 if (md == NULL) 1057 goto err; 1058 1059 rv = EVP_Digest(privkey, 32, buff, &sz, md, NULL); 1060 EVP_MD_free(md); 1061 if (!rv) 1062 goto err; 1063 1064 buff[0] &= 248; 1065 buff[31] &= 63; 1066 buff[31] |= 64; 1067 1068 if (s390x_ed25519_mul(x_dst, pubkey, 1069 generator_x, generator_y, buff) != 1) 1070 goto err; 1071 1072 pubkey[31] |= ((x_dst[0] & 0x01) << 7); 1073 1074 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key); 1075 return 1; 1076 err: 1077 ossl_ecx_key_free(key); 1078 return 0; 1079 } 1080 1081 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 1082 { 1083 static const unsigned char generator_x[] = { 1084 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b, 1085 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12, 1086 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47, 1087 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22, 1088 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00 1089 }; 1090 static const unsigned char generator_y[] = { 1091 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e, 1092 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a, 1093 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c, 1094 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88, 1095 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00 1096 }; 1097 unsigned char x_dst[57], buff[114]; 1098 ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED448, 1, 1099 ctx->propquery); 1100 unsigned char *privkey = NULL, *pubkey; 1101 EVP_MD_CTX *hashctx = NULL; 1102 EVP_MD *md = NULL; 1103 int rv; 1104 1105 if (key == NULL) { 1106 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 1107 goto err; 1108 } 1109 1110 pubkey = key->pubkey; 1111 1112 privkey = ossl_ecx_key_allocate_privkey(key); 1113 if (privkey == NULL) { 1114 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 1115 goto err; 1116 } 1117 1118 if (RAND_priv_bytes_ex(ctx->libctx, privkey, ED448_KEYLEN, 0) <= 0) 1119 goto err; 1120 1121 hashctx = EVP_MD_CTX_new(); 1122 if (hashctx == NULL) 1123 goto err; 1124 1125 md = EVP_MD_fetch(ctx->libctx, "SHAKE256", ctx->propquery); 1126 if (md == NULL) 1127 goto err; 1128 1129 rv = EVP_DigestInit_ex(hashctx, md, NULL); 1130 EVP_MD_free(md); 1131 if (rv != 1) 1132 goto err; 1133 1134 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1) 1135 goto err; 1136 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1) 1137 goto err; 1138 1139 buff[0] &= -4; 1140 buff[55] |= 0x80; 1141 buff[56] = 0; 1142 1143 if (s390x_ed448_mul(x_dst, pubkey, 1144 generator_x, generator_y, buff) != 1) 1145 goto err; 1146 1147 pubkey[56] |= ((x_dst[0] & 0x01) << 7); 1148 1149 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key); 1150 EVP_MD_CTX_free(hashctx); 1151 return 1; 1152 err: 1153 ossl_ecx_key_free(key); 1154 EVP_MD_CTX_free(hashctx); 1155 return 0; 1156 } 1157 1158 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key, 1159 size_t *keylen) 1160 { 1161 const unsigned char *privkey, *pubkey; 1162 1163 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey) 1164 || (key != NULL 1165 && s390x_x25519_mul(key, privkey, pubkey) == 0)) 1166 return 0; 1167 *keylen = X25519_KEYLEN; 1168 return 1; 1169 } 1170 1171 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key, 1172 size_t *keylen) 1173 { 1174 const unsigned char *privkey, *pubkey; 1175 1176 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey) 1177 || (key != NULL 1178 && s390x_x448_mul(key, pubkey, privkey) == 0)) 1179 return 0; 1180 *keylen = X448_KEYLEN; 1181 return 1; 1182 } 1183 1184 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, 1185 unsigned char *sig, size_t *siglen, 1186 const unsigned char *tbs, 1187 size_t tbslen) 1188 { 1189 union { 1190 struct { 1191 unsigned char sig[64]; 1192 unsigned char priv[32]; 1193 } ed25519; 1194 unsigned long long buff[512]; 1195 } param; 1196 const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey); 1197 int rc; 1198 1199 if (edkey == NULL) { 1200 ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); 1201 return 0; 1202 } 1203 1204 if (sig == NULL) { 1205 *siglen = ED25519_SIGSIZE; 1206 return 1; 1207 } 1208 1209 if (*siglen < ED25519_SIGSIZE) { 1210 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); 1211 return 0; 1212 } 1213 1214 memset(¶m, 0, sizeof(param)); 1215 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv)); 1216 1217 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen); 1218 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv)); 1219 if (rc != 0) 1220 return 0; 1221 1222 s390x_flip_endian32(sig, param.ed25519.sig); 1223 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32); 1224 1225 *siglen = ED25519_SIGSIZE; 1226 return 1; 1227 } 1228 1229 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx, 1230 unsigned char *sig, size_t *siglen, 1231 const unsigned char *tbs, 1232 size_t tbslen) 1233 { 1234 union { 1235 struct { 1236 unsigned char sig[128]; 1237 unsigned char priv[64]; 1238 } ed448; 1239 unsigned long long buff[512]; 1240 } param; 1241 const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey); 1242 int rc; 1243 1244 if (edkey == NULL) { 1245 ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); 1246 return 0; 1247 } 1248 1249 if (sig == NULL) { 1250 *siglen = ED448_SIGSIZE; 1251 return 1; 1252 } 1253 1254 if (*siglen < ED448_SIGSIZE) { 1255 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); 1256 return 0; 1257 } 1258 1259 memset(¶m, 0, sizeof(param)); 1260 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57); 1261 1262 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen); 1263 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv)); 1264 if (rc != 0) 1265 return 0; 1266 1267 s390x_flip_endian64(param.ed448.sig, param.ed448.sig); 1268 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64); 1269 memcpy(sig, param.ed448.sig, 57); 1270 memcpy(sig + 57, param.ed448.sig + 64, 57); 1271 1272 *siglen = ED448_SIGSIZE; 1273 return 1; 1274 } 1275 1276 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, 1277 const unsigned char *sig, 1278 size_t siglen, 1279 const unsigned char *tbs, 1280 size_t tbslen) 1281 { 1282 union { 1283 struct { 1284 unsigned char sig[64]; 1285 unsigned char pub[32]; 1286 } ed25519; 1287 unsigned long long buff[512]; 1288 } param; 1289 const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey); 1290 1291 if (edkey == NULL) { 1292 ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); 1293 return 0; 1294 } 1295 1296 if (siglen != ED25519_SIGSIZE) 1297 return 0; 1298 1299 memset(¶m, 0, sizeof(param)); 1300 s390x_flip_endian32(param.ed25519.sig, sig); 1301 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32); 1302 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey); 1303 1304 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519, 1305 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0; 1306 } 1307 1308 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx, 1309 const unsigned char *sig, 1310 size_t siglen, 1311 const unsigned char *tbs, 1312 size_t tbslen) 1313 { 1314 union { 1315 struct { 1316 unsigned char sig[128]; 1317 unsigned char pub[64]; 1318 } ed448; 1319 unsigned long long buff[512]; 1320 } param; 1321 const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey); 1322 1323 if (edkey == NULL) { 1324 ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY); 1325 return 0; 1326 } 1327 1328 if (siglen != ED448_SIGSIZE) 1329 return 0; 1330 1331 memset(¶m, 0, sizeof(param)); 1332 memcpy(param.ed448.sig, sig, 57); 1333 s390x_flip_endian64(param.ed448.sig, param.ed448.sig); 1334 memcpy(param.ed448.sig + 64, sig + 57, 57); 1335 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64); 1336 memcpy(param.ed448.pub, edkey->pubkey, 57); 1337 s390x_flip_endian64(param.ed448.pub, param.ed448.pub); 1338 1339 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448, 1340 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0; 1341 } 1342 1343 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = { 1344 EVP_PKEY_X25519, 1345 0, 0, 0, 0, 0, 0, 0, 1346 s390x_pkey_ecx_keygen25519, 1347 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1348 s390x_pkey_ecx_derive25519, 1349 pkey_ecx_ctrl, 1350 0 1351 }; 1352 1353 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = { 1354 EVP_PKEY_X448, 1355 0, 0, 0, 0, 0, 0, 0, 1356 s390x_pkey_ecx_keygen448, 1357 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1358 s390x_pkey_ecx_derive448, 1359 pkey_ecx_ctrl, 1360 0 1361 }; 1362 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = { 1363 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM, 1364 0, 0, 0, 0, 0, 0, 1365 s390x_pkey_ecd_keygen25519, 1366 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1367 pkey_ecd_ctrl, 1368 0, 1369 s390x_pkey_ecd_digestsign25519, 1370 s390x_pkey_ecd_digestverify25519 1371 }; 1372 1373 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = { 1374 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM, 1375 0, 0, 0, 0, 0, 0, 1376 s390x_pkey_ecd_keygen448, 1377 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1378 pkey_ecd_ctrl, 1379 0, 1380 s390x_pkey_ecd_digestsign448, 1381 s390x_pkey_ecd_digestverify448 1382 }; 1383 #endif 1384 1385 const EVP_PKEY_METHOD *ossl_ecx25519_pkey_method(void) 1386 { 1387 #ifdef S390X_EC_ASM 1388 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519)) 1389 return &ecx25519_s390x_pkey_meth; 1390 #endif 1391 return &ecx25519_pkey_meth; 1392 } 1393 1394 const EVP_PKEY_METHOD *ossl_ecx448_pkey_method(void) 1395 { 1396 #ifdef S390X_EC_ASM 1397 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448)) 1398 return &ecx448_s390x_pkey_meth; 1399 #endif 1400 return &ecx448_pkey_meth; 1401 } 1402 1403 const EVP_PKEY_METHOD *ossl_ed25519_pkey_method(void) 1404 { 1405 #ifdef S390X_EC_ASM 1406 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519) 1407 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519) 1408 && OPENSSL_s390xcap_P.kdsa[0] 1409 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519)) 1410 return &ed25519_s390x_pkey_meth; 1411 #endif 1412 return &ed25519_pkey_meth; 1413 } 1414 1415 const EVP_PKEY_METHOD *ossl_ed448_pkey_method(void) 1416 { 1417 #ifdef S390X_EC_ASM 1418 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448) 1419 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448) 1420 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448)) 1421 return &ed448_s390x_pkey_meth; 1422 #endif 1423 return &ed448_pkey_meth; 1424 } 1425