1 /* 2 * Copyright 2020-2025 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 #include <openssl/crypto.h> 11 #include <openssl/core_dispatch.h> 12 #include <openssl/core_names.h> 13 #include <openssl/err.h> 14 #include <openssl/params.h> 15 #include <openssl/evp.h> 16 #include <openssl/proverr.h> 17 #include "internal/nelem.h" 18 #include "internal/sizes.h" 19 #include "prov/providercommon.h" 20 #include "prov/implementations.h" 21 #include "prov/securitycheck.h" 22 #include "prov/provider_ctx.h" 23 #include "prov/der_ecx.h" 24 #include "crypto/ecx.h" 25 26 #ifdef S390X_EC_ASM 27 #include "s390x_arch.h" 28 29 #define S390X_CAN_SIGN(edtype) \ 30 ((OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_##edtype)) \ 31 && (OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_##edtype)) \ 32 && (OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_##edtype))) 33 34 static int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig, 35 const unsigned char *tbs, size_t tbslen); 36 static int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig, 37 const unsigned char *tbs, size_t tbslen); 38 static int s390x_ed25519_digestverify(const ECX_KEY *edkey, 39 const unsigned char *sig, 40 const unsigned char *tbs, size_t tbslen); 41 static int s390x_ed448_digestverify(const ECX_KEY *edkey, 42 const unsigned char *sig, 43 const unsigned char *tbs, size_t tbslen); 44 45 #endif /* S390X_EC_ASM */ 46 47 enum ID_EdDSA_INSTANCE { 48 ID_NOT_SET = 0, 49 ID_Ed25519, 50 ID_Ed25519ctx, 51 ID_Ed25519ph, 52 ID_Ed448, 53 ID_Ed448ph 54 }; 55 56 #define SN_Ed25519 "Ed25519" 57 #define SN_Ed25519ph "Ed25519ph" 58 #define SN_Ed25519ctx "Ed25519ctx" 59 #define SN_Ed448 "Ed448" 60 #define SN_Ed448ph "Ed448ph" 61 62 #define EDDSA_MAX_CONTEXT_STRING_LEN 255 63 #define EDDSA_PREHASH_OUTPUT_LEN 64 64 65 static OSSL_FUNC_signature_newctx_fn eddsa_newctx; 66 static OSSL_FUNC_signature_sign_message_init_fn ed25519_signverify_message_init; 67 static OSSL_FUNC_signature_sign_message_init_fn ed25519ph_signverify_message_init; 68 static OSSL_FUNC_signature_sign_message_init_fn ed25519ctx_signverify_message_init; 69 static OSSL_FUNC_signature_sign_message_init_fn ed448_signverify_message_init; 70 static OSSL_FUNC_signature_sign_message_init_fn ed448ph_signverify_message_init; 71 static OSSL_FUNC_signature_sign_fn ed25519_sign; 72 static OSSL_FUNC_signature_sign_fn ed448_sign; 73 static OSSL_FUNC_signature_verify_fn ed25519_verify; 74 static OSSL_FUNC_signature_verify_fn ed448_verify; 75 static OSSL_FUNC_signature_digest_sign_init_fn ed25519_digest_signverify_init; 76 static OSSL_FUNC_signature_digest_sign_init_fn ed448_digest_signverify_init; 77 static OSSL_FUNC_signature_digest_sign_fn ed25519_digest_sign; 78 static OSSL_FUNC_signature_digest_sign_fn ed448_digest_sign; 79 static OSSL_FUNC_signature_digest_verify_fn ed25519_digest_verify; 80 static OSSL_FUNC_signature_digest_verify_fn ed448_digest_verify; 81 static OSSL_FUNC_signature_freectx_fn eddsa_freectx; 82 static OSSL_FUNC_signature_dupctx_fn eddsa_dupctx; 83 static OSSL_FUNC_signature_query_key_types_fn ed25519_sigalg_query_key_types; 84 static OSSL_FUNC_signature_query_key_types_fn ed448_sigalg_query_key_types; 85 static OSSL_FUNC_signature_get_ctx_params_fn eddsa_get_ctx_params; 86 static OSSL_FUNC_signature_gettable_ctx_params_fn eddsa_gettable_ctx_params; 87 static OSSL_FUNC_signature_set_ctx_params_fn eddsa_set_ctx_params; 88 static OSSL_FUNC_signature_settable_ctx_params_fn eddsa_settable_ctx_params; 89 static OSSL_FUNC_signature_settable_ctx_params_fn eddsa_settable_variant_ctx_params; 90 91 /* there are five EdDSA instances: 92 93 Ed25519 94 Ed25519ph 95 Ed25519ctx 96 Ed448 97 Ed448ph 98 99 Quoting from RFC 8032, Section 5.1: 100 101 For Ed25519, dom2(f,c) is the empty string. The phflag value is 102 irrelevant. The context (if present at all) MUST be empty. This 103 causes the scheme to be one and the same with the Ed25519 scheme 104 published earlier. 105 106 For Ed25519ctx, phflag=0. The context input SHOULD NOT be empty. 107 108 For Ed25519ph, phflag=1 and PH is SHA512 instead. That is, the input 109 is hashed using SHA-512 before signing with Ed25519. 110 111 Quoting from RFC 8032, Section 5.2: 112 113 Ed448ph is the same but with PH being SHAKE256(x, 64) and phflag 114 being 1, i.e., the input is hashed before signing with Ed448 with a 115 hash constant modified. 116 117 Value of context is set by signer and verifier (maximum of 255 118 octets; the default is empty string) and has to match octet by octet 119 for verification to be successful. 120 121 Quoting from RFC 8032, Section 2: 122 123 dom2(x, y) The blank octet string when signing or verifying 124 Ed25519. Otherwise, the octet string: "SigEd25519 no 125 Ed25519 collisions" || octet(x) || octet(OLEN(y)) || 126 y, where x is in range 0-255 and y is an octet string 127 of at most 255 octets. "SigEd25519 no Ed25519 128 collisions" is in ASCII (32 octets). 129 130 dom4(x, y) The octet string "SigEd448" || octet(x) || 131 octet(OLEN(y)) || y, where x is in range 0-255 and y 132 is an octet string of at most 255 octets. "SigEd448" 133 is in ASCII (8 octets). 134 135 Note above that x is the pre-hash flag, and y is the context string. 136 */ 137 138 typedef struct { 139 OSSL_LIB_CTX *libctx; 140 ECX_KEY *key; 141 142 /* The Algorithm Identifier of the signature algorithm */ 143 unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE]; 144 size_t aid_len; 145 146 /* id indicating the EdDSA instance */ 147 int instance_id; 148 /* indicates that instance_id and associated flags are preset / hardcoded */ 149 unsigned int instance_id_preset_flag : 1; 150 /* for ph instances, this indicates whether the caller is expected to prehash */ 151 unsigned int prehash_by_caller_flag : 1; 152 153 unsigned int dom2_flag : 1; 154 unsigned int prehash_flag : 1; 155 156 /* indicates that a non-empty context string is required, as in Ed25519ctx */ 157 unsigned int context_string_flag : 1; 158 159 unsigned char context_string[EDDSA_MAX_CONTEXT_STRING_LEN]; 160 size_t context_string_len; 161 162 } PROV_EDDSA_CTX; 163 164 static void *eddsa_newctx(void *provctx, const char *propq_unused) 165 { 166 PROV_EDDSA_CTX *peddsactx; 167 168 if (!ossl_prov_is_running()) 169 return NULL; 170 171 peddsactx = OPENSSL_zalloc(sizeof(PROV_EDDSA_CTX)); 172 if (peddsactx == NULL) 173 return NULL; 174 175 peddsactx->libctx = PROV_LIBCTX_OF(provctx); 176 177 return peddsactx; 178 } 179 180 static int eddsa_setup_instance(void *vpeddsactx, int instance_id, 181 unsigned int instance_id_preset, 182 unsigned int prehash_by_caller) 183 { 184 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 185 186 switch (instance_id) { 187 case ID_Ed25519: 188 if (peddsactx->key->type != ECX_KEY_TYPE_ED25519) 189 return 0; 190 peddsactx->dom2_flag = 0; 191 peddsactx->prehash_flag = 0; 192 peddsactx->context_string_flag = 0; 193 break; 194 #ifndef FIPS_MODULE 195 case ID_Ed25519ctx: 196 if (peddsactx->key->type != ECX_KEY_TYPE_ED25519) 197 return 0; 198 peddsactx->dom2_flag = 1; 199 peddsactx->prehash_flag = 0; 200 peddsactx->context_string_flag = 1; 201 break; 202 #endif 203 case ID_Ed25519ph: 204 if (peddsactx->key->type != ECX_KEY_TYPE_ED25519) 205 return 0; 206 peddsactx->dom2_flag = 1; 207 peddsactx->prehash_flag = 1; 208 peddsactx->context_string_flag = 0; 209 break; 210 case ID_Ed448: 211 if (peddsactx->key->type != ECX_KEY_TYPE_ED448) 212 return 0; 213 peddsactx->prehash_flag = 0; 214 peddsactx->context_string_flag = 0; 215 break; 216 case ID_Ed448ph: 217 if (peddsactx->key->type != ECX_KEY_TYPE_ED448) 218 return 0; 219 peddsactx->prehash_flag = 1; 220 peddsactx->context_string_flag = 0; 221 break; 222 default: 223 /* we did not recognize the instance */ 224 return 0; 225 } 226 peddsactx->instance_id = instance_id; 227 peddsactx->instance_id_preset_flag = instance_id_preset; 228 peddsactx->prehash_by_caller_flag = prehash_by_caller; 229 return 1; 230 } 231 232 static int eddsa_signverify_init(void *vpeddsactx, void *vedkey) 233 { 234 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 235 ECX_KEY *edkey = (ECX_KEY *)vedkey; 236 WPACKET pkt; 237 int ret; 238 unsigned char *aid = NULL; 239 240 if (!ossl_prov_is_running()) 241 return 0; 242 243 if (edkey == NULL) { 244 ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); 245 return 0; 246 } 247 248 if (!ossl_ecx_key_up_ref(edkey)) { 249 ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); 250 return 0; 251 } 252 253 peddsactx->instance_id_preset_flag = 0; 254 peddsactx->dom2_flag = 0; 255 peddsactx->prehash_flag = 0; 256 peddsactx->context_string_flag = 0; 257 peddsactx->context_string_len = 0; 258 259 peddsactx->key = edkey; 260 261 /* 262 * We do not care about DER writing errors. 263 * All it really means is that for some reason, there's no 264 * AlgorithmIdentifier to be had, but the operation itself is 265 * still valid, just as long as it's not used to construct 266 * anything that needs an AlgorithmIdentifier. 267 */ 268 peddsactx->aid_len = 0; 269 ret = WPACKET_init_der(&pkt, peddsactx->aid_buf, sizeof(peddsactx->aid_buf)); 270 switch (edkey->type) { 271 case ECX_KEY_TYPE_ED25519: 272 ret = ret && ossl_DER_w_algorithmIdentifier_ED25519(&pkt, -1, edkey); 273 break; 274 case ECX_KEY_TYPE_ED448: 275 ret = ret && ossl_DER_w_algorithmIdentifier_ED448(&pkt, -1, edkey); 276 break; 277 default: 278 /* Should never happen */ 279 ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); 280 ossl_ecx_key_free(edkey); 281 peddsactx->key = NULL; 282 WPACKET_cleanup(&pkt); 283 return 0; 284 } 285 if (ret && WPACKET_finish(&pkt)) { 286 WPACKET_get_total_written(&pkt, &peddsactx->aid_len); 287 aid = WPACKET_get_curr(&pkt); 288 } 289 WPACKET_cleanup(&pkt); 290 if (aid != NULL && peddsactx->aid_len != 0) 291 memmove(peddsactx->aid_buf, aid, peddsactx->aid_len); 292 293 return 1; 294 } 295 296 static int ed25519_signverify_message_init(void *vpeddsactx, void *vedkey, 297 const OSSL_PARAM params[]) 298 { 299 return eddsa_signverify_init(vpeddsactx, vedkey) 300 && eddsa_setup_instance(vpeddsactx, ID_Ed25519, 1, 0) 301 && eddsa_set_ctx_params(vpeddsactx, params); 302 } 303 304 static int ed25519ph_signverify_message_init(void *vpeddsactx, void *vedkey, 305 const OSSL_PARAM params[]) 306 { 307 return eddsa_signverify_init(vpeddsactx, vedkey) 308 && eddsa_setup_instance(vpeddsactx, ID_Ed25519ph, 1, 0) 309 && eddsa_set_ctx_params(vpeddsactx, params); 310 } 311 312 static int ed25519ph_signverify_init(void *vpeddsactx, void *vedkey, 313 const OSSL_PARAM params[]) 314 { 315 return eddsa_signverify_init(vpeddsactx, vedkey) 316 && eddsa_setup_instance(vpeddsactx, ID_Ed25519ph, 1, 1) 317 && eddsa_set_ctx_params(vpeddsactx, params); 318 } 319 320 /* 321 * This supports using ED25519 with EVP_PKEY_{sign,verify}_init_ex() and 322 * EVP_PKEY_{sign,verify}_init_ex2(), under the condition that the caller 323 * explicitly sets the Ed25519ph instance (this is verified by ed25519_sign() 324 * and ed25519_verify()) 325 */ 326 static int ed25519_signverify_init(void *vpeddsactx, void *vedkey, 327 const OSSL_PARAM params[]) 328 { 329 return eddsa_signverify_init(vpeddsactx, vedkey) 330 && eddsa_setup_instance(vpeddsactx, ID_Ed25519, 0, 1) 331 && eddsa_set_ctx_params(vpeddsactx, params); 332 } 333 334 static int ed25519ctx_signverify_message_init(void *vpeddsactx, void *vedkey, 335 const OSSL_PARAM params[]) 336 { 337 return eddsa_signverify_init(vpeddsactx, vedkey) 338 && eddsa_setup_instance(vpeddsactx, ID_Ed25519ctx, 1, 0) 339 && eddsa_set_ctx_params(vpeddsactx, params); 340 } 341 342 static int ed448_signverify_message_init(void *vpeddsactx, void *vedkey, 343 const OSSL_PARAM params[]) 344 { 345 return eddsa_signverify_init(vpeddsactx, vedkey) 346 && eddsa_setup_instance(vpeddsactx, ID_Ed448, 1, 0) 347 && eddsa_set_ctx_params(vpeddsactx, params); 348 } 349 350 static int ed448ph_signverify_message_init(void *vpeddsactx, void *vedkey, 351 const OSSL_PARAM params[]) 352 { 353 return eddsa_signverify_init(vpeddsactx, vedkey) 354 && eddsa_setup_instance(vpeddsactx, ID_Ed448ph, 1, 0) 355 && eddsa_set_ctx_params(vpeddsactx, params); 356 } 357 358 static int ed448ph_signverify_init(void *vpeddsactx, void *vedkey, 359 const OSSL_PARAM params[]) 360 { 361 return eddsa_signverify_init(vpeddsactx, vedkey) 362 && eddsa_setup_instance(vpeddsactx, ID_Ed448ph, 1, 1) 363 && eddsa_set_ctx_params(vpeddsactx, params); 364 } 365 366 /* 367 * This supports using ED448 with EVP_PKEY_{sign,verify}_init_ex() and 368 * EVP_PKEY_{sign,verify}_init_ex2(), under the condition that the caller 369 * explicitly sets the Ed448ph instance (this is verified by ed448_sign() 370 * and ed448_verify()) 371 */ 372 static int ed448_signverify_init(void *vpeddsactx, void *vedkey, 373 const OSSL_PARAM params[]) 374 { 375 return eddsa_signverify_init(vpeddsactx, vedkey) 376 && eddsa_setup_instance(vpeddsactx, ID_Ed448, 0, 1) 377 && eddsa_set_ctx_params(vpeddsactx, params); 378 } 379 380 /* 381 * This is used directly for OSSL_FUNC_SIGNATURE_SIGN and indirectly 382 * for OSSL_FUNC_SIGNATURE_DIGEST_SIGN 383 */ 384 static int ed25519_sign(void *vpeddsactx, 385 unsigned char *sigret, size_t *siglen, size_t sigsize, 386 const unsigned char *tbs, size_t tbslen) 387 { 388 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 389 const ECX_KEY *edkey = peddsactx->key; 390 uint8_t md[EVP_MAX_MD_SIZE]; 391 size_t mdlen; 392 393 if (!ossl_prov_is_running()) 394 return 0; 395 396 if (sigret == NULL) { 397 *siglen = ED25519_SIGSIZE; 398 return 1; 399 } 400 if (sigsize < ED25519_SIGSIZE) { 401 ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); 402 return 0; 403 } 404 if (edkey->privkey == NULL) { 405 ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 406 return 0; 407 } 408 #ifdef S390X_EC_ASM 409 /* 410 * s390x_ed25519_digestsign() does not yet support dom2 or context-strings. 411 * fall back to non-accelerated sign if those options are set, or pre-hasing 412 * is provided. 413 */ 414 if (S390X_CAN_SIGN(ED25519) 415 && !peddsactx->dom2_flag 416 && !peddsactx->context_string_flag 417 && peddsactx->context_string_len == 0 418 && !peddsactx->prehash_flag 419 && !peddsactx->prehash_by_caller_flag) { 420 if (s390x_ed25519_digestsign(edkey, sigret, tbs, tbslen) == 0) { 421 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN); 422 return 0; 423 } 424 *siglen = ED25519_SIGSIZE; 425 return 1; 426 } 427 #endif /* S390X_EC_ASM */ 428 429 if (peddsactx->prehash_flag) { 430 if (!peddsactx->prehash_by_caller_flag) { 431 if (!EVP_Q_digest(peddsactx->libctx, SN_sha512, NULL, 432 tbs, tbslen, md, &mdlen) 433 || mdlen != EDDSA_PREHASH_OUTPUT_LEN) { 434 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PREHASHED_DIGEST_LENGTH); 435 return 0; 436 } 437 tbs = md; 438 tbslen = mdlen; 439 } else if (tbslen != EDDSA_PREHASH_OUTPUT_LEN) { 440 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH); 441 return 0; 442 } 443 } else if (peddsactx->prehash_by_caller_flag) { 444 /* The caller is supposed to set up a ph instance! */ 445 ERR_raise(ERR_LIB_PROV, 446 PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION); 447 return 0; 448 } 449 450 if (ossl_ed25519_sign(sigret, tbs, tbslen, edkey->pubkey, edkey->privkey, 451 peddsactx->dom2_flag, peddsactx->prehash_flag, peddsactx->context_string_flag, 452 peddsactx->context_string, peddsactx->context_string_len, 453 peddsactx->libctx, NULL) 454 == 0) { 455 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN); 456 return 0; 457 } 458 *siglen = ED25519_SIGSIZE; 459 return 1; 460 } 461 462 /* EVP_Q_digest() does not allow variable output length for XOFs, 463 so we use this function */ 464 static int ed448_shake256(OSSL_LIB_CTX *libctx, 465 const char *propq, 466 const uint8_t *in, size_t inlen, 467 uint8_t *out, size_t outlen) 468 { 469 int ret = 0; 470 EVP_MD_CTX *hash_ctx = EVP_MD_CTX_new(); 471 EVP_MD *shake256 = EVP_MD_fetch(libctx, SN_shake256, propq); 472 473 if (hash_ctx == NULL || shake256 == NULL) 474 goto err; 475 476 if (!EVP_DigestInit_ex(hash_ctx, shake256, NULL) 477 || !EVP_DigestUpdate(hash_ctx, in, inlen) 478 || !EVP_DigestFinalXOF(hash_ctx, out, outlen)) 479 goto err; 480 481 ret = 1; 482 483 err: 484 EVP_MD_CTX_free(hash_ctx); 485 EVP_MD_free(shake256); 486 return ret; 487 } 488 489 /* 490 * This is used directly for OSSL_FUNC_SIGNATURE_SIGN and indirectly 491 * for OSSL_FUNC_SIGNATURE_DIGEST_SIGN 492 */ 493 static int ed448_sign(void *vpeddsactx, 494 unsigned char *sigret, size_t *siglen, size_t sigsize, 495 const unsigned char *tbs, size_t tbslen) 496 { 497 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 498 const ECX_KEY *edkey = peddsactx->key; 499 uint8_t md[EDDSA_PREHASH_OUTPUT_LEN]; 500 size_t mdlen = sizeof(md); 501 502 if (!ossl_prov_is_running()) 503 return 0; 504 505 if (sigret == NULL) { 506 *siglen = ED448_SIGSIZE; 507 return 1; 508 } 509 if (sigsize < ED448_SIGSIZE) { 510 ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); 511 return 0; 512 } 513 if (edkey->privkey == NULL) { 514 ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 515 return 0; 516 } 517 #ifdef S390X_EC_ASM 518 /* 519 * s390x_ed448_digestsign() does not yet support context-strings or 520 * pre-hashing. Fall back to non-accelerated sign if a context-string or 521 * pre-hasing is provided. 522 */ 523 if (S390X_CAN_SIGN(ED448) 524 && peddsactx->context_string_len == 0 525 && !peddsactx->prehash_flag 526 && !peddsactx->prehash_by_caller_flag) { 527 if (s390x_ed448_digestsign(edkey, sigret, tbs, tbslen) == 0) { 528 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN); 529 return 0; 530 } 531 *siglen = ED448_SIGSIZE; 532 return 1; 533 } 534 #endif /* S390X_EC_ASM */ 535 536 if (peddsactx->prehash_flag) { 537 if (!peddsactx->prehash_by_caller_flag) { 538 if (!ed448_shake256(peddsactx->libctx, NULL, tbs, tbslen, md, mdlen)) 539 return 0; 540 tbs = md; 541 tbslen = mdlen; 542 } else if (tbslen != EDDSA_PREHASH_OUTPUT_LEN) { 543 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH); 544 return 0; 545 } 546 } else if (peddsactx->prehash_by_caller_flag) { 547 /* The caller is supposed to set up a ph instance! */ 548 ERR_raise(ERR_LIB_PROV, 549 PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION); 550 return 0; 551 } 552 553 if (ossl_ed448_sign(peddsactx->libctx, sigret, tbs, tbslen, 554 edkey->pubkey, edkey->privkey, 555 peddsactx->context_string, peddsactx->context_string_len, 556 peddsactx->prehash_flag, edkey->propq) 557 == 0) { 558 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN); 559 return 0; 560 } 561 *siglen = ED448_SIGSIZE; 562 return 1; 563 } 564 565 /* 566 * This is used directly for OSSL_FUNC_SIGNATURE_VERIFY and indirectly 567 * for OSSL_FUNC_SIGNATURE_DIGEST_VERIFY 568 */ 569 static int ed25519_verify(void *vpeddsactx, 570 const unsigned char *sig, size_t siglen, 571 const unsigned char *tbs, size_t tbslen) 572 { 573 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 574 const ECX_KEY *edkey = peddsactx->key; 575 uint8_t md[EVP_MAX_MD_SIZE]; 576 size_t mdlen; 577 578 if (!ossl_prov_is_running() || siglen != ED25519_SIGSIZE) 579 return 0; 580 581 #ifdef S390X_EC_ASM 582 /* 583 * s390x_ed25519_digestverify() does not yet support dom2 or context-strings. 584 * fall back to non-accelerated verify if those options are set, or 585 * pre-hasing is provided. 586 */ 587 if (S390X_CAN_SIGN(ED25519) 588 && !peddsactx->dom2_flag 589 && !peddsactx->context_string_flag 590 && peddsactx->context_string_len == 0 591 && !peddsactx->prehash_flag 592 && !peddsactx->prehash_by_caller_flag) 593 return s390x_ed25519_digestverify(edkey, sig, tbs, tbslen); 594 #endif /* S390X_EC_ASM */ 595 596 if (peddsactx->prehash_flag) { 597 if (!peddsactx->prehash_by_caller_flag) { 598 if (!EVP_Q_digest(peddsactx->libctx, SN_sha512, NULL, 599 tbs, tbslen, md, &mdlen) 600 || mdlen != EDDSA_PREHASH_OUTPUT_LEN) { 601 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PREHASHED_DIGEST_LENGTH); 602 return 0; 603 } 604 tbs = md; 605 tbslen = mdlen; 606 } else if (tbslen != EDDSA_PREHASH_OUTPUT_LEN) { 607 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH); 608 return 0; 609 } 610 } else if (peddsactx->prehash_by_caller_flag) { 611 /* The caller is supposed to set up a ph instance! */ 612 ERR_raise(ERR_LIB_PROV, 613 PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION); 614 return 0; 615 } 616 617 return ossl_ed25519_verify(tbs, tbslen, sig, edkey->pubkey, 618 peddsactx->dom2_flag, peddsactx->prehash_flag, peddsactx->context_string_flag, 619 peddsactx->context_string, peddsactx->context_string_len, 620 peddsactx->libctx, edkey->propq); 621 } 622 623 /* 624 * This is used directly for OSSL_FUNC_SIGNATURE_VERIFY and indirectly 625 * for OSSL_FUNC_SIGNATURE_DIGEST_VERIFY 626 */ 627 static int ed448_verify(void *vpeddsactx, 628 const unsigned char *sig, size_t siglen, 629 const unsigned char *tbs, size_t tbslen) 630 { 631 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 632 const ECX_KEY *edkey = peddsactx->key; 633 uint8_t md[EDDSA_PREHASH_OUTPUT_LEN]; 634 size_t mdlen = sizeof(md); 635 636 if (!ossl_prov_is_running() || siglen != ED448_SIGSIZE) 637 return 0; 638 639 #ifdef S390X_EC_ASM 640 /* 641 * s390x_ed448_digestverify() does not yet support context-strings or 642 * pre-hashing. Fall back to non-accelerated verify if a context-string or 643 * pre-hasing is provided. 644 */ 645 if (S390X_CAN_SIGN(ED448) 646 && peddsactx->context_string_len == 0 647 && !peddsactx->prehash_flag 648 && !peddsactx->prehash_by_caller_flag) 649 return s390x_ed448_digestverify(edkey, sig, tbs, tbslen); 650 #endif /* S390X_EC_ASM */ 651 652 if (peddsactx->prehash_flag) { 653 if (!peddsactx->prehash_by_caller_flag) { 654 if (!ed448_shake256(peddsactx->libctx, NULL, tbs, tbslen, md, mdlen)) 655 return 0; 656 tbs = md; 657 tbslen = mdlen; 658 } else if (tbslen != EDDSA_PREHASH_OUTPUT_LEN) { 659 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH); 660 return 0; 661 } 662 } else if (peddsactx->prehash_by_caller_flag) { 663 /* The caller is supposed to set up a ph instance! */ 664 ERR_raise(ERR_LIB_PROV, 665 PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION); 666 return 0; 667 } 668 669 return ossl_ed448_verify(peddsactx->libctx, tbs, tbslen, sig, edkey->pubkey, 670 peddsactx->context_string, peddsactx->context_string_len, 671 peddsactx->prehash_flag, edkey->propq); 672 } 673 674 /* All digest_{sign,verify} are simple wrappers around the functions above */ 675 676 static int ed25519_digest_signverify_init(void *vpeddsactx, const char *mdname, 677 void *vedkey, 678 const OSSL_PARAM params[]) 679 { 680 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 681 682 if (mdname != NULL && mdname[0] != '\0') { 683 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, 684 "Explicit digest not allowed with EdDSA operations"); 685 return 0; 686 } 687 688 if (vedkey == NULL && peddsactx->key != NULL) 689 return eddsa_set_ctx_params(peddsactx, params); 690 691 return eddsa_signverify_init(vpeddsactx, vedkey) 692 && eddsa_setup_instance(vpeddsactx, ID_Ed25519, 0, 0) 693 && eddsa_set_ctx_params(vpeddsactx, params); 694 } 695 696 static int ed25519_digest_sign(void *vpeddsactx, 697 unsigned char *sigret, size_t *siglen, size_t sigsize, 698 const unsigned char *tbs, size_t tbslen) 699 { 700 return ed25519_sign(vpeddsactx, sigret, siglen, sigsize, tbs, tbslen); 701 } 702 703 static int ed25519_digest_verify(void *vpeddsactx, 704 const unsigned char *sigret, size_t siglen, 705 const unsigned char *tbs, size_t tbslen) 706 { 707 return ed25519_verify(vpeddsactx, sigret, siglen, tbs, tbslen); 708 } 709 710 static int ed448_digest_signverify_init(void *vpeddsactx, const char *mdname, 711 void *vedkey, 712 const OSSL_PARAM params[]) 713 { 714 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 715 716 if (mdname != NULL && mdname[0] != '\0') { 717 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, 718 "Explicit digest not allowed with EdDSA operations"); 719 return 0; 720 } 721 722 if (vedkey == NULL && peddsactx->key != NULL) 723 return eddsa_set_ctx_params(peddsactx, params); 724 725 return eddsa_signverify_init(vpeddsactx, vedkey) 726 && eddsa_setup_instance(vpeddsactx, ID_Ed448, 0, 0) 727 && eddsa_set_ctx_params(vpeddsactx, params); 728 } 729 730 static int ed448_digest_sign(void *vpeddsactx, 731 unsigned char *sigret, size_t *siglen, size_t sigsize, 732 const unsigned char *tbs, size_t tbslen) 733 { 734 return ed448_sign(vpeddsactx, sigret, siglen, sigsize, tbs, tbslen); 735 } 736 737 static int ed448_digest_verify(void *vpeddsactx, 738 const unsigned char *sigret, size_t siglen, 739 const unsigned char *tbs, size_t tbslen) 740 { 741 return ed448_verify(vpeddsactx, sigret, siglen, tbs, tbslen); 742 } 743 744 static void eddsa_freectx(void *vpeddsactx) 745 { 746 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 747 748 ossl_ecx_key_free(peddsactx->key); 749 750 OPENSSL_free(peddsactx); 751 } 752 753 static void *eddsa_dupctx(void *vpeddsactx) 754 { 755 PROV_EDDSA_CTX *srcctx = (PROV_EDDSA_CTX *)vpeddsactx; 756 PROV_EDDSA_CTX *dstctx; 757 758 if (!ossl_prov_is_running()) 759 return NULL; 760 761 dstctx = OPENSSL_zalloc(sizeof(*srcctx)); 762 if (dstctx == NULL) 763 return NULL; 764 765 *dstctx = *srcctx; 766 dstctx->key = NULL; 767 768 if (srcctx->key != NULL && !ossl_ecx_key_up_ref(srcctx->key)) { 769 ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); 770 goto err; 771 } 772 dstctx->key = srcctx->key; 773 774 return dstctx; 775 err: 776 eddsa_freectx(dstctx); 777 return NULL; 778 } 779 780 static const char **ed25519_sigalg_query_key_types(void) 781 { 782 static const char *keytypes[] = { "ED25519", NULL }; 783 784 return keytypes; 785 } 786 787 static const char **ed448_sigalg_query_key_types(void) 788 { 789 static const char *keytypes[] = { "ED448", NULL }; 790 791 return keytypes; 792 } 793 794 static int eddsa_get_ctx_params(void *vpeddsactx, OSSL_PARAM *params) 795 { 796 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 797 OSSL_PARAM *p; 798 799 if (peddsactx == NULL) 800 return 0; 801 802 p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID); 803 if (p != NULL 804 && !OSSL_PARAM_set_octet_string(p, 805 peddsactx->aid_len == 0 ? NULL : peddsactx->aid_buf, 806 peddsactx->aid_len)) 807 return 0; 808 809 return 1; 810 } 811 812 static const OSSL_PARAM known_gettable_ctx_params[] = { 813 OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0), 814 OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_INSTANCE, NULL, 0), 815 OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0), 816 OSSL_PARAM_END 817 }; 818 819 static const OSSL_PARAM *eddsa_gettable_ctx_params(ossl_unused void *vpeddsactx, 820 ossl_unused void *provctx) 821 { 822 return known_gettable_ctx_params; 823 } 824 825 static int eddsa_set_ctx_params(void *vpeddsactx, const OSSL_PARAM params[]) 826 { 827 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 828 const OSSL_PARAM *p; 829 830 if (peddsactx == NULL) 831 return 0; 832 if (ossl_param_is_empty(params)) 833 return 1; 834 835 p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_INSTANCE); 836 if (p != NULL) { 837 char instance_name[OSSL_MAX_NAME_SIZE] = ""; 838 char *pinstance_name = instance_name; 839 840 if (peddsactx->instance_id_preset_flag) { 841 /* When the instance is preset, the caller must no try to set it */ 842 ERR_raise_data(ERR_LIB_PROV, PROV_R_NO_INSTANCE_ALLOWED, 843 "the EdDSA instance is preset, you may not try to specify it", 844 NULL); 845 return 0; 846 } 847 848 if (!OSSL_PARAM_get_utf8_string(p, &pinstance_name, sizeof(instance_name))) 849 return 0; 850 851 /* 852 * When setting the new instance, we're careful not to change the 853 * prehash_by_caller flag, as that's always preset by the init 854 * functions. The sign functions will determine if the instance 855 * matches this flag. 856 */ 857 if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519) == 0) { 858 eddsa_setup_instance(peddsactx, ID_Ed25519, 0, 859 peddsactx->prehash_by_caller_flag); 860 #ifndef FIPS_MODULE 861 } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519ctx) == 0) { 862 eddsa_setup_instance(peddsactx, ID_Ed25519ctx, 0, 863 peddsactx->prehash_by_caller_flag); 864 #endif 865 } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519ph) == 0) { 866 eddsa_setup_instance(peddsactx, ID_Ed25519ph, 0, 867 peddsactx->prehash_by_caller_flag); 868 } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed448) == 0) { 869 eddsa_setup_instance(peddsactx, ID_Ed448, 0, 870 peddsactx->prehash_by_caller_flag); 871 } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed448ph) == 0) { 872 eddsa_setup_instance(peddsactx, ID_Ed448ph, 0, 873 peddsactx->prehash_by_caller_flag); 874 } else { 875 /* we did not recognize the instance */ 876 ERR_raise_data(ERR_LIB_PROV, 877 PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION, 878 "unknown INSTANCE name: %s", 879 pinstance_name != NULL ? pinstance_name : "<null>"); 880 return 0; 881 } 882 } 883 884 p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_CONTEXT_STRING); 885 if (p != NULL) { 886 void *vp_context_string = peddsactx->context_string; 887 888 if (!OSSL_PARAM_get_octet_string(p, &vp_context_string, sizeof(peddsactx->context_string), &(peddsactx->context_string_len))) { 889 peddsactx->context_string_len = 0; 890 return 0; 891 } 892 } 893 894 return 1; 895 } 896 897 static const OSSL_PARAM settable_ctx_params[] = { 898 OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_INSTANCE, NULL, 0), 899 OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0), 900 OSSL_PARAM_END 901 }; 902 903 static const OSSL_PARAM *eddsa_settable_ctx_params(ossl_unused void *vpeddsactx, 904 ossl_unused void *provctx) 905 { 906 return settable_ctx_params; 907 } 908 909 static const OSSL_PARAM settable_variant_ctx_params[] = { 910 OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0), 911 OSSL_PARAM_END 912 }; 913 914 static const OSSL_PARAM * 915 eddsa_settable_variant_ctx_params(ossl_unused void *vpeddsactx, 916 ossl_unused void *provctx) 917 { 918 return settable_variant_ctx_params; 919 } 920 921 /* 922 * Ed25519 can be used with: 923 * - EVP_PKEY_sign_init_ex2() [ instance and prehash assumed done by caller ] 924 * - EVP_PKEY_verify_init_ex2() [ instance and prehash assumed done by caller ] 925 * - EVP_PKEY_sign_message_init() 926 * - EVP_PKEY_verify_message_init() 927 * - EVP_DigestSignInit_ex() 928 * - EVP_DigestVerifyInit_ex() 929 * Ed25519ph can be used with: 930 * - EVP_PKEY_sign_init_ex2() [ prehash assumed done by caller ] 931 * - EVP_PKEY_verify_init_ex2() [ prehash assumed done by caller ] 932 * - EVP_PKEY_sign_message_init() 933 * - EVP_PKEY_verify_message_init() 934 * Ed25519ctx can be used with: 935 * - EVP_PKEY_sign_message_init() 936 * - EVP_PKEY_verify_message_init() 937 * Ed448 can be used with: 938 * - EVP_PKEY_sign_init_ex2() [ instance and prehash assumed done by caller ] 939 * - EVP_PKEY_verify_init_ex2() [ instance and prehash assumed done by caller ] 940 * - EVP_PKEY_sign_message_init() 941 * - EVP_PKEY_verify_message_init() 942 * - EVP_DigestSignInit_ex() 943 * - EVP_DigestVerifyInit_ex() 944 * Ed448ph can be used with: 945 * - EVP_PKEY_sign_init_ex2() [ prehash assumed done by caller ] 946 * - EVP_PKEY_verify_init_ex2() [ prehash assumed done by caller ] 947 * - EVP_PKEY_sign_message_init() 948 * - EVP_PKEY_verify_message_init() 949 */ 950 951 #define ed25519_DISPATCH_END \ 952 { OSSL_FUNC_SIGNATURE_SIGN_INIT, \ 953 (void (*)(void))ed25519_signverify_init }, \ 954 { OSSL_FUNC_SIGNATURE_VERIFY_INIT, \ 955 (void (*)(void))ed25519_signverify_init }, \ 956 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, \ 957 (void (*)(void))ed25519_digest_signverify_init }, \ 958 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN, \ 959 (void (*)(void))ed25519_digest_sign }, \ 960 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, \ 961 (void (*)(void))ed25519_digest_signverify_init }, \ 962 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY, \ 963 (void (*)(void))ed25519_digest_verify }, \ 964 { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \ 965 (void (*)(void))eddsa_get_ctx_params }, \ 966 { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \ 967 (void (*)(void))eddsa_gettable_ctx_params }, \ 968 { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \ 969 (void (*)(void))eddsa_set_ctx_params }, \ 970 { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \ 971 (void (*)(void))eddsa_settable_ctx_params }, \ 972 OSSL_DISPATCH_END 973 974 #define eddsa_variant_DISPATCH_END(v) \ 975 { OSSL_FUNC_SIGNATURE_SIGN_INIT, \ 976 (void (*)(void))v##_signverify_message_init }, \ 977 { OSSL_FUNC_SIGNATURE_VERIFY_INIT, \ 978 (void (*)(void))v##_signverify_message_init }, \ 979 { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \ 980 (void (*)(void))eddsa_get_ctx_params }, \ 981 { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \ 982 (void (*)(void))eddsa_gettable_ctx_params }, \ 983 { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \ 984 (void (*)(void))eddsa_set_ctx_params }, \ 985 { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \ 986 (void (*)(void))eddsa_settable_variant_ctx_params }, \ 987 OSSL_DISPATCH_END 988 989 #define ed25519ph_DISPATCH_END \ 990 { OSSL_FUNC_SIGNATURE_SIGN_INIT, \ 991 (void (*)(void))ed25519ph_signverify_init }, \ 992 { OSSL_FUNC_SIGNATURE_VERIFY_INIT, \ 993 (void (*)(void))ed25519ph_signverify_init }, \ 994 eddsa_variant_DISPATCH_END(ed25519ph) 995 996 #define ed25519ctx_DISPATCH_END eddsa_variant_DISPATCH_END(ed25519ctx) 997 998 #define ed448_DISPATCH_END \ 999 { OSSL_FUNC_SIGNATURE_SIGN_INIT, \ 1000 (void (*)(void))ed448_signverify_init }, \ 1001 { OSSL_FUNC_SIGNATURE_VERIFY_INIT, \ 1002 (void (*)(void))ed448_signverify_init }, \ 1003 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, \ 1004 (void (*)(void))ed448_digest_signverify_init }, \ 1005 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN, \ 1006 (void (*)(void))ed448_digest_sign }, \ 1007 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, \ 1008 (void (*)(void))ed448_digest_signverify_init }, \ 1009 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY, \ 1010 (void (*)(void))ed448_digest_verify }, \ 1011 { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \ 1012 (void (*)(void))eddsa_get_ctx_params }, \ 1013 { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \ 1014 (void (*)(void))eddsa_gettable_ctx_params }, \ 1015 { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \ 1016 (void (*)(void))eddsa_set_ctx_params }, \ 1017 { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \ 1018 (void (*)(void))eddsa_settable_ctx_params }, \ 1019 OSSL_DISPATCH_END 1020 1021 #define ed448ph_DISPATCH_END \ 1022 { OSSL_FUNC_SIGNATURE_SIGN_INIT, \ 1023 (void (*)(void))ed448ph_signverify_init }, \ 1024 { OSSL_FUNC_SIGNATURE_VERIFY_INIT, \ 1025 (void (*)(void))ed448ph_signverify_init }, \ 1026 eddsa_variant_DISPATCH_END(ed448ph) 1027 1028 /* vn = variant name, bn = base name */ 1029 #define IMPL_EDDSA_DISPATCH(vn, bn) \ 1030 const OSSL_DISPATCH ossl_##vn##_signature_functions[] = { \ 1031 { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx }, \ 1032 { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_INIT, \ 1033 (void (*)(void))vn##_signverify_message_init }, \ 1034 { OSSL_FUNC_SIGNATURE_SIGN, \ 1035 (void (*)(void))bn##_sign }, \ 1036 { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_INIT, \ 1037 (void (*)(void))vn##_signverify_message_init }, \ 1038 { OSSL_FUNC_SIGNATURE_VERIFY, \ 1039 (void (*)(void))bn##_verify }, \ 1040 { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx }, \ 1041 { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx }, \ 1042 { OSSL_FUNC_SIGNATURE_QUERY_KEY_TYPES, \ 1043 (void (*)(void))bn##_sigalg_query_key_types }, \ 1044 vn##_DISPATCH_END \ 1045 } 1046 1047 IMPL_EDDSA_DISPATCH(ed25519, ed25519); 1048 IMPL_EDDSA_DISPATCH(ed25519ph, ed25519); 1049 IMPL_EDDSA_DISPATCH(ed25519ctx, ed25519); 1050 IMPL_EDDSA_DISPATCH(ed448, ed448); 1051 IMPL_EDDSA_DISPATCH(ed448ph, ed448); 1052 1053 #ifdef S390X_EC_ASM 1054 1055 static int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig, 1056 const unsigned char *tbs, size_t tbslen) 1057 { 1058 int rc; 1059 union { 1060 struct { 1061 unsigned char sig[64]; 1062 unsigned char priv[32]; 1063 } ed25519; 1064 unsigned long long buff[512]; 1065 } param; 1066 1067 memset(¶m, 0, sizeof(param)); 1068 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv)); 1069 1070 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen); 1071 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv)); 1072 if (rc != 0) 1073 return 0; 1074 1075 s390x_flip_endian32(sig, param.ed25519.sig); 1076 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32); 1077 return 1; 1078 } 1079 1080 static int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig, 1081 const unsigned char *tbs, size_t tbslen) 1082 { 1083 int rc; 1084 union { 1085 struct { 1086 unsigned char sig[128]; 1087 unsigned char priv[64]; 1088 } ed448; 1089 unsigned long long buff[512]; 1090 } param; 1091 1092 memset(¶m, 0, sizeof(param)); 1093 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57); 1094 1095 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen); 1096 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv)); 1097 if (rc != 0) 1098 return 0; 1099 1100 s390x_flip_endian64(param.ed448.sig, param.ed448.sig); 1101 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64); 1102 memcpy(sig, param.ed448.sig, 57); 1103 memcpy(sig + 57, param.ed448.sig + 64, 57); 1104 return 1; 1105 } 1106 1107 static int s390x_ed25519_digestverify(const ECX_KEY *edkey, 1108 const unsigned char *sig, 1109 const unsigned char *tbs, size_t tbslen) 1110 { 1111 union { 1112 struct { 1113 unsigned char sig[64]; 1114 unsigned char pub[32]; 1115 } ed25519; 1116 unsigned long long buff[512]; 1117 } param; 1118 1119 memset(¶m, 0, sizeof(param)); 1120 s390x_flip_endian32(param.ed25519.sig, sig); 1121 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32); 1122 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey); 1123 1124 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519, 1125 ¶m.ed25519, tbs, tbslen) 1126 == 0 1127 ? 1 1128 : 0; 1129 } 1130 1131 static int s390x_ed448_digestverify(const ECX_KEY *edkey, 1132 const unsigned char *sig, 1133 const unsigned char *tbs, 1134 size_t tbslen) 1135 { 1136 union { 1137 struct { 1138 unsigned char sig[128]; 1139 unsigned char pub[64]; 1140 } ed448; 1141 unsigned long long buff[512]; 1142 } param; 1143 1144 memset(¶m, 0, sizeof(param)); 1145 memcpy(param.ed448.sig, sig, 57); 1146 s390x_flip_endian64(param.ed448.sig, param.ed448.sig); 1147 memcpy(param.ed448.sig + 64, sig + 57, 57); 1148 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64); 1149 memcpy(param.ed448.pub, edkey->pubkey, 57); 1150 s390x_flip_endian64(param.ed448.pub, param.ed448.pub); 1151 1152 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448, 1153 ¶m.ed448, tbs, tbslen) 1154 == 0 1155 ? 1 1156 : 0; 1157 } 1158 1159 #endif /* S390X_EC_ASM */ 1160