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 <assert.h> 11 #include <string.h> 12 #include <openssl/core_dispatch.h> 13 #include <openssl/core_names.h> 14 #include <openssl/params.h> 15 #include <openssl/err.h> 16 #include <openssl/proverr.h> 17 #include <openssl/evp.h> 18 #include <openssl/rand.h> 19 #include <openssl/self_test.h> 20 #include "internal/param_build_set.h" 21 #include <openssl/param_build.h> 22 #include "crypto/ecx.h" 23 #include "prov/implementations.h" 24 #include "prov/providercommon.h" 25 #include "prov/provider_ctx.h" 26 #include "prov/ecx.h" 27 #include "prov/securitycheck.h" 28 #ifdef S390X_EC_ASM 29 # include "s390x_arch.h" 30 # include <openssl/sha.h> /* For SHA512_DIGEST_LENGTH */ 31 #endif 32 33 static OSSL_FUNC_keymgmt_new_fn x25519_new_key; 34 static OSSL_FUNC_keymgmt_new_fn x448_new_key; 35 static OSSL_FUNC_keymgmt_new_fn ed25519_new_key; 36 static OSSL_FUNC_keymgmt_new_fn ed448_new_key; 37 static OSSL_FUNC_keymgmt_gen_init_fn x25519_gen_init; 38 static OSSL_FUNC_keymgmt_gen_init_fn x448_gen_init; 39 static OSSL_FUNC_keymgmt_gen_init_fn ed25519_gen_init; 40 static OSSL_FUNC_keymgmt_gen_init_fn ed448_gen_init; 41 static OSSL_FUNC_keymgmt_gen_fn x25519_gen; 42 static OSSL_FUNC_keymgmt_gen_fn x448_gen; 43 static OSSL_FUNC_keymgmt_gen_fn ed25519_gen; 44 static OSSL_FUNC_keymgmt_gen_fn ed448_gen; 45 static OSSL_FUNC_keymgmt_gen_cleanup_fn ecx_gen_cleanup; 46 static OSSL_FUNC_keymgmt_gen_set_params_fn ecx_gen_set_params; 47 static OSSL_FUNC_keymgmt_gen_settable_params_fn ecx_gen_settable_params; 48 static OSSL_FUNC_keymgmt_load_fn ecx_load; 49 static OSSL_FUNC_keymgmt_get_params_fn x25519_get_params; 50 static OSSL_FUNC_keymgmt_get_params_fn x448_get_params; 51 static OSSL_FUNC_keymgmt_get_params_fn ed25519_get_params; 52 static OSSL_FUNC_keymgmt_get_params_fn ed448_get_params; 53 static OSSL_FUNC_keymgmt_gettable_params_fn x25519_gettable_params; 54 static OSSL_FUNC_keymgmt_gettable_params_fn x448_gettable_params; 55 static OSSL_FUNC_keymgmt_gettable_params_fn ed25519_gettable_params; 56 static OSSL_FUNC_keymgmt_gettable_params_fn ed448_gettable_params; 57 static OSSL_FUNC_keymgmt_set_params_fn x25519_set_params; 58 static OSSL_FUNC_keymgmt_set_params_fn x448_set_params; 59 static OSSL_FUNC_keymgmt_set_params_fn ed25519_set_params; 60 static OSSL_FUNC_keymgmt_set_params_fn ed448_set_params; 61 static OSSL_FUNC_keymgmt_settable_params_fn x25519_settable_params; 62 static OSSL_FUNC_keymgmt_settable_params_fn x448_settable_params; 63 static OSSL_FUNC_keymgmt_settable_params_fn ed25519_settable_params; 64 static OSSL_FUNC_keymgmt_settable_params_fn ed448_settable_params; 65 static OSSL_FUNC_keymgmt_has_fn ecx_has; 66 static OSSL_FUNC_keymgmt_match_fn ecx_match; 67 static OSSL_FUNC_keymgmt_validate_fn x25519_validate; 68 static OSSL_FUNC_keymgmt_validate_fn x448_validate; 69 static OSSL_FUNC_keymgmt_validate_fn ed25519_validate; 70 static OSSL_FUNC_keymgmt_validate_fn ed448_validate; 71 static OSSL_FUNC_keymgmt_import_fn ecx_import; 72 static OSSL_FUNC_keymgmt_import_types_fn ecx_imexport_types; 73 static OSSL_FUNC_keymgmt_export_fn ecx_export; 74 static OSSL_FUNC_keymgmt_export_types_fn ecx_imexport_types; 75 static OSSL_FUNC_keymgmt_dup_fn ecx_dup; 76 77 #define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR) 78 79 struct ecx_gen_ctx { 80 OSSL_LIB_CTX *libctx; 81 char *propq; 82 ECX_KEY_TYPE type; 83 int selection; 84 unsigned char *dhkem_ikm; 85 size_t dhkem_ikmlen; 86 }; 87 88 #ifdef S390X_EC_ASM 89 static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx); 90 static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx); 91 static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx); 92 static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx); 93 #endif 94 95 static void *x25519_new_key(void *provctx) 96 { 97 if (!ossl_prov_is_running()) 98 return 0; 99 return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_X25519, 0, 100 NULL); 101 } 102 103 static void *x448_new_key(void *provctx) 104 { 105 if (!ossl_prov_is_running()) 106 return 0; 107 return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_X448, 0, 108 NULL); 109 } 110 111 static void *ed25519_new_key(void *provctx) 112 { 113 if (!ossl_prov_is_running()) 114 return 0; 115 return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_ED25519, 0, 116 NULL); 117 } 118 119 static void *ed448_new_key(void *provctx) 120 { 121 if (!ossl_prov_is_running()) 122 return 0; 123 return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_ED448, 0, 124 NULL); 125 } 126 127 static int ecx_has(const void *keydata, int selection) 128 { 129 const ECX_KEY *key = keydata; 130 int ok = 0; 131 132 if (ossl_prov_is_running() && key != NULL) { 133 /* 134 * ECX keys always have all the parameters they need (i.e. none). 135 * Therefore we always return with 1, if asked about parameters. 136 */ 137 ok = 1; 138 139 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) 140 ok = ok && key->haspubkey; 141 142 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 143 ok = ok && key->privkey != NULL; 144 } 145 return ok; 146 } 147 148 static int ecx_match(const void *keydata1, const void *keydata2, int selection) 149 { 150 const ECX_KEY *key1 = keydata1; 151 const ECX_KEY *key2 = keydata2; 152 int ok = 1; 153 154 if (!ossl_prov_is_running()) 155 return 0; 156 157 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 158 ok = ok && key1->type == key2->type; 159 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { 160 int key_checked = 0; 161 162 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 163 const unsigned char *pa = key1->haspubkey ? key1->pubkey : NULL; 164 const unsigned char *pb = key2->haspubkey ? key2->pubkey : NULL; 165 size_t pal = key1->keylen; 166 size_t pbl = key2->keylen; 167 168 if (pa != NULL && pb != NULL) { 169 ok = ok 170 && key1->type == key2->type 171 && pal == pbl 172 && CRYPTO_memcmp(pa, pb, pal) == 0; 173 key_checked = 1; 174 } 175 } 176 if (!key_checked 177 && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 178 const unsigned char *pa = key1->privkey; 179 const unsigned char *pb = key2->privkey; 180 size_t pal = key1->keylen; 181 size_t pbl = key2->keylen; 182 183 if (pa != NULL && pb != NULL) { 184 ok = ok 185 && key1->type == key2->type 186 && pal == pbl 187 && CRYPTO_memcmp(pa, pb, pal) == 0; 188 key_checked = 1; 189 } 190 } 191 ok = ok && key_checked; 192 } 193 return ok; 194 } 195 196 static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[]) 197 { 198 ECX_KEY *key = keydata; 199 int ok = 1; 200 int include_private; 201 202 if (!ossl_prov_is_running() || key == NULL) 203 return 0; 204 205 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) 206 return 0; 207 208 include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0; 209 ok = ok && ossl_ecx_key_fromdata(key, params, include_private); 210 211 return ok; 212 } 213 214 static int key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl, 215 OSSL_PARAM params[], int include_private) 216 { 217 if (key == NULL) 218 return 0; 219 220 if (!ossl_param_build_set_octet_string(tmpl, params, 221 OSSL_PKEY_PARAM_PUB_KEY, 222 key->pubkey, key->keylen)) 223 return 0; 224 225 if (include_private 226 && key->privkey != NULL 227 && !ossl_param_build_set_octet_string(tmpl, params, 228 OSSL_PKEY_PARAM_PRIV_KEY, 229 key->privkey, key->keylen)) 230 return 0; 231 232 return 1; 233 } 234 235 static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, 236 void *cbarg) 237 { 238 ECX_KEY *key = keydata; 239 OSSL_PARAM_BLD *tmpl; 240 OSSL_PARAM *params = NULL; 241 int ret = 0; 242 243 if (!ossl_prov_is_running() || key == NULL) 244 return 0; 245 246 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) 247 return 0; 248 249 tmpl = OSSL_PARAM_BLD_new(); 250 if (tmpl == NULL) 251 return 0; 252 253 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { 254 int include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0); 255 256 if (!key_to_params(key, tmpl, NULL, include_private)) 257 goto err; 258 } 259 260 params = OSSL_PARAM_BLD_to_param(tmpl); 261 if (params == NULL) 262 goto err; 263 264 ret = param_cb(params, cbarg); 265 OSSL_PARAM_free(params); 266 err: 267 OSSL_PARAM_BLD_free(tmpl); 268 return ret; 269 } 270 271 #define ECX_KEY_TYPES() \ 272 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \ 273 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0) 274 275 static const OSSL_PARAM ecx_key_types[] = { 276 ECX_KEY_TYPES(), 277 OSSL_PARAM_END 278 }; 279 static const OSSL_PARAM *ecx_imexport_types(int selection) 280 { 281 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) 282 return ecx_key_types; 283 return NULL; 284 } 285 286 static int ecx_get_params(void *key, OSSL_PARAM params[], int bits, int secbits, 287 int size) 288 { 289 ECX_KEY *ecx = key; 290 OSSL_PARAM *p; 291 292 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL 293 && !OSSL_PARAM_set_int(p, bits)) 294 return 0; 295 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL 296 && !OSSL_PARAM_set_int(p, secbits)) 297 return 0; 298 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL 299 && !OSSL_PARAM_set_int(p, size)) 300 return 0; 301 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL 302 && (ecx->type == ECX_KEY_TYPE_X25519 303 || ecx->type == ECX_KEY_TYPE_X448)) { 304 if (!OSSL_PARAM_set_octet_string(p, ecx->pubkey, ecx->keylen)) 305 return 0; 306 } 307 #ifdef FIPS_MODULE 308 { 309 /* X25519 and X448 are not approved */ 310 int approved = 0; 311 312 p = OSSL_PARAM_locate(params, OSSL_ALG_PARAM_FIPS_APPROVED_INDICATOR); 313 if (p != NULL && !OSSL_PARAM_set_int(p, approved)) 314 return 0; 315 } 316 #endif 317 318 return key_to_params(ecx, NULL, params, 1); 319 } 320 321 static int ed_get_params(void *key, OSSL_PARAM params[]) 322 { 323 OSSL_PARAM *p; 324 325 if ((p = OSSL_PARAM_locate(params, 326 OSSL_PKEY_PARAM_MANDATORY_DIGEST)) != NULL 327 && !OSSL_PARAM_set_utf8_string(p, "")) 328 return 0; 329 return 1; 330 } 331 332 static int x25519_get_params(void *key, OSSL_PARAM params[]) 333 { 334 return ecx_get_params(key, params, X25519_BITS, X25519_SECURITY_BITS, 335 X25519_KEYLEN); 336 } 337 338 static int x448_get_params(void *key, OSSL_PARAM params[]) 339 { 340 return ecx_get_params(key, params, X448_BITS, X448_SECURITY_BITS, 341 X448_KEYLEN); 342 } 343 344 static int ed25519_get_params(void *key, OSSL_PARAM params[]) 345 { 346 return ecx_get_params(key, params, ED25519_BITS, ED25519_SECURITY_BITS, 347 ED25519_SIGSIZE) 348 && ed_get_params(key, params); 349 } 350 351 static int ed448_get_params(void *key, OSSL_PARAM params[]) 352 { 353 return ecx_get_params(key, params, ED448_BITS, ED448_SECURITY_BITS, 354 ED448_SIGSIZE) 355 && ed_get_params(key, params); 356 } 357 358 static const OSSL_PARAM ecx_gettable_params[] = { 359 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), 360 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), 361 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), 362 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), 363 ECX_KEY_TYPES(), 364 OSSL_FIPS_IND_GETTABLE_CTX_PARAM() 365 OSSL_PARAM_END 366 }; 367 368 static const OSSL_PARAM ed_gettable_params[] = { 369 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), 370 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), 371 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), 372 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0), 373 ECX_KEY_TYPES(), 374 OSSL_PARAM_END 375 }; 376 377 static const OSSL_PARAM *x25519_gettable_params(void *provctx) 378 { 379 return ecx_gettable_params; 380 } 381 382 static const OSSL_PARAM *x448_gettable_params(void *provctx) 383 { 384 return ecx_gettable_params; 385 } 386 387 static const OSSL_PARAM *ed25519_gettable_params(void *provctx) 388 { 389 return ed_gettable_params; 390 } 391 392 static const OSSL_PARAM *ed448_gettable_params(void *provctx) 393 { 394 return ed_gettable_params; 395 } 396 397 static int set_property_query(ECX_KEY *ecxkey, const char *propq) 398 { 399 OPENSSL_free(ecxkey->propq); 400 ecxkey->propq = NULL; 401 if (propq != NULL) { 402 ecxkey->propq = OPENSSL_strdup(propq); 403 if (ecxkey->propq == NULL) 404 return 0; 405 } 406 return 1; 407 } 408 409 static int ecx_set_params(void *key, const OSSL_PARAM params[]) 410 { 411 ECX_KEY *ecxkey = key; 412 const OSSL_PARAM *p; 413 414 if (ossl_param_is_empty(params)) 415 return 1; 416 417 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY); 418 if (p != NULL) { 419 void *buf = ecxkey->pubkey; 420 421 if (p->data_size != ecxkey->keylen 422 || !OSSL_PARAM_get_octet_string(p, &buf, sizeof(ecxkey->pubkey), 423 NULL)) 424 return 0; 425 OPENSSL_clear_free(ecxkey->privkey, ecxkey->keylen); 426 ecxkey->privkey = NULL; 427 ecxkey->haspubkey = 1; 428 } 429 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PROPERTIES); 430 if (p != NULL) { 431 if (p->data_type != OSSL_PARAM_UTF8_STRING 432 || !set_property_query(ecxkey, p->data)) 433 return 0; 434 } 435 436 return 1; 437 } 438 439 static int x25519_set_params(void *key, const OSSL_PARAM params[]) 440 { 441 return ecx_set_params(key, params); 442 } 443 444 static int x448_set_params(void *key, const OSSL_PARAM params[]) 445 { 446 return ecx_set_params(key, params); 447 } 448 449 static int ed25519_set_params(void *key, const OSSL_PARAM params[]) 450 { 451 return 1; 452 } 453 454 static int ed448_set_params(void *key, const OSSL_PARAM params[]) 455 { 456 return 1; 457 } 458 459 static const OSSL_PARAM ecx_settable_params[] = { 460 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), 461 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0), 462 OSSL_PARAM_END 463 }; 464 465 static const OSSL_PARAM ed_settable_params[] = { 466 OSSL_PARAM_END 467 }; 468 469 static const OSSL_PARAM *x25519_settable_params(void *provctx) 470 { 471 return ecx_settable_params; 472 } 473 474 static const OSSL_PARAM *x448_settable_params(void *provctx) 475 { 476 return ecx_settable_params; 477 } 478 479 static const OSSL_PARAM *ed25519_settable_params(void *provctx) 480 { 481 return ed_settable_params; 482 } 483 484 static const OSSL_PARAM *ed448_settable_params(void *provctx) 485 { 486 return ed_settable_params; 487 } 488 489 static void *ecx_gen_init(void *provctx, int selection, 490 const OSSL_PARAM params[], ECX_KEY_TYPE type, 491 const char *algdesc) 492 { 493 OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); 494 struct ecx_gen_ctx *gctx = NULL; 495 496 if (!ossl_prov_is_running()) 497 return NULL; 498 499 if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) { 500 gctx->libctx = libctx; 501 gctx->type = type; 502 gctx->selection = selection; 503 #ifdef FIPS_MODULE 504 /* X25519/X448 are not FIPS approved, (ED25519/ED448 are approved) */ 505 if (algdesc != NULL 506 && !ossl_FIPS_IND_callback(libctx, algdesc, "KeyGen Init")) { 507 OPENSSL_free(gctx); 508 return NULL; 509 } 510 #endif 511 } else { 512 return NULL; 513 } 514 if (!ecx_gen_set_params(gctx, params)) { 515 ecx_gen_cleanup(gctx); 516 gctx = NULL; 517 } 518 return gctx; 519 } 520 521 static void *x25519_gen_init(void *provctx, int selection, 522 const OSSL_PARAM params[]) 523 { 524 return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X25519, "X25519"); 525 } 526 527 static void *x448_gen_init(void *provctx, int selection, 528 const OSSL_PARAM params[]) 529 { 530 return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X448, "X448"); 531 } 532 533 static void *ed25519_gen_init(void *provctx, int selection, 534 const OSSL_PARAM params[]) 535 { 536 return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_ED25519, NULL); 537 } 538 539 static void *ed448_gen_init(void *provctx, int selection, 540 const OSSL_PARAM params[]) 541 { 542 return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_ED448, NULL); 543 } 544 545 static int ecx_gen_set_params(void *genctx, const OSSL_PARAM params[]) 546 { 547 struct ecx_gen_ctx *gctx = genctx; 548 const OSSL_PARAM *p; 549 550 if (gctx == NULL) 551 return 0; 552 553 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); 554 if (p != NULL) { 555 const char *groupname = NULL; 556 557 /* 558 * We optionally allow setting a group name - but each algorithm only 559 * support one such name, so all we do is verify that it is the one we 560 * expected. 561 */ 562 switch (gctx->type) { 563 case ECX_KEY_TYPE_X25519: 564 groupname = "x25519"; 565 break; 566 case ECX_KEY_TYPE_X448: 567 groupname = "x448"; 568 break; 569 default: 570 /* We only support this for key exchange at the moment */ 571 break; 572 } 573 if (p->data_type != OSSL_PARAM_UTF8_STRING 574 || groupname == NULL 575 || OPENSSL_strcasecmp(p->data, groupname) != 0) { 576 ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); 577 return 0; 578 } 579 } 580 p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES); 581 if (p != NULL) { 582 if (p->data_type != OSSL_PARAM_UTF8_STRING) 583 return 0; 584 OPENSSL_free(gctx->propq); 585 gctx->propq = OPENSSL_strdup(p->data); 586 if (gctx->propq == NULL) 587 return 0; 588 } 589 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DHKEM_IKM); 590 if (p != NULL) { 591 if (p->data_size != 0 && p->data != NULL) { 592 OPENSSL_free(gctx->dhkem_ikm); 593 gctx->dhkem_ikm = NULL; 594 if (!OSSL_PARAM_get_octet_string(p, (void **)&gctx->dhkem_ikm, 0, 595 &gctx->dhkem_ikmlen)) 596 return 0; 597 } 598 } 599 600 return 1; 601 } 602 603 static const OSSL_PARAM *ecx_gen_settable_params(ossl_unused void *genctx, 604 ossl_unused void *provctx) 605 { 606 static OSSL_PARAM settable[] = { 607 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), 608 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), 609 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM, NULL, 0), 610 OSSL_PARAM_END 611 }; 612 return settable; 613 } 614 615 #ifdef FIPS_MODULE 616 /* 617 * Refer: FIPS 140-3 IG 10.3.A Additional Comment 1 618 * Perform a pairwise test for EDDSA by signing and verifying signature. 619 * 620 * The parameter `self_test` is used to indicate whether to create OSSL_SELF_TEST 621 * instance. 622 */ 623 static int ecd_fips140_pairwise_test(const ECX_KEY *ecx, int type, int self_test) 624 { 625 int ret = 0; 626 OSSL_SELF_TEST *st = NULL; 627 OSSL_CALLBACK *cb = NULL; 628 void *cbarg = NULL; 629 630 unsigned char msg[16] = {0}; 631 size_t msg_len = sizeof(msg); 632 unsigned char sig[ED448_SIGSIZE] = {0}; 633 634 int is_ed25519 = (type == ECX_KEY_TYPE_ED25519) ? 1 : 0; 635 int operation_result = 0; 636 637 /* 638 * The functions `OSSL_SELF_TEST_*` will return directly if parameter `st` 639 * is NULL. 640 */ 641 if (self_test) { 642 OSSL_SELF_TEST_get_callback(ecx->libctx, &cb, &cbarg); 643 644 st = OSSL_SELF_TEST_new(cb, cbarg); 645 if (st == NULL) 646 return 0; 647 } 648 649 OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT, 650 OSSL_SELF_TEST_DESC_PCT_EDDSA); 651 652 if (is_ed25519) 653 operation_result = ossl_ed25519_sign(sig, msg, msg_len, ecx->pubkey, 654 ecx->privkey, 0, 0, 0, NULL, 0, 655 ecx->libctx, ecx->propq); 656 else 657 operation_result = ossl_ed448_sign(ecx->libctx, sig, msg, msg_len, 658 ecx->pubkey, ecx->privkey, NULL, 0, 659 0, ecx->propq); 660 if (operation_result != 1) 661 goto err; 662 663 OSSL_SELF_TEST_oncorrupt_byte(st, sig); 664 665 if (is_ed25519) 666 operation_result = ossl_ed25519_verify(msg, msg_len, sig, ecx->pubkey, 667 0, 0, 0, NULL, 0, ecx->libctx, 668 ecx->propq); 669 else 670 operation_result = ossl_ed448_verify(ecx->libctx, msg, msg_len, sig, 671 ecx->pubkey, NULL, 0, 0, ecx->propq); 672 if (operation_result != 1) 673 goto err; 674 675 ret = 1; 676 err: 677 OSSL_SELF_TEST_onend(st, ret); 678 OSSL_SELF_TEST_free(st); 679 return ret; 680 } 681 #endif 682 683 static void *ecx_gen(struct ecx_gen_ctx *gctx) 684 { 685 ECX_KEY *key; 686 unsigned char *privkey; 687 688 if (gctx == NULL) 689 return NULL; 690 if ((key = ossl_ecx_key_new(gctx->libctx, gctx->type, 0, 691 gctx->propq)) == NULL) { 692 ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); 693 return NULL; 694 } 695 696 /* If we're doing parameter generation then we just return a blank key */ 697 if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) 698 return key; 699 700 if ((privkey = ossl_ecx_key_allocate_privkey(key)) == NULL) { 701 ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); 702 goto err; 703 } 704 #ifndef FIPS_MODULE 705 if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) { 706 if (gctx->type == ECX_KEY_TYPE_ED25519 707 || gctx->type == ECX_KEY_TYPE_ED448) 708 goto err; 709 if (!ossl_ecx_dhkem_derive_private(key, privkey, 710 gctx->dhkem_ikm, gctx->dhkem_ikmlen)) 711 goto err; 712 } else 713 #endif 714 { 715 if (RAND_priv_bytes_ex(gctx->libctx, privkey, key->keylen, 0) <= 0) 716 goto err; 717 } 718 719 switch (gctx->type) { 720 case ECX_KEY_TYPE_X25519: 721 privkey[0] &= 248; 722 privkey[X25519_KEYLEN - 1] &= 127; 723 privkey[X25519_KEYLEN - 1] |= 64; 724 ossl_x25519_public_from_private(key->pubkey, privkey); 725 break; 726 case ECX_KEY_TYPE_X448: 727 privkey[0] &= 252; 728 privkey[X448_KEYLEN - 1] |= 128; 729 ossl_x448_public_from_private(key->pubkey, privkey); 730 break; 731 case ECX_KEY_TYPE_ED25519: 732 if (!ossl_ed25519_public_from_private(gctx->libctx, key->pubkey, privkey, 733 gctx->propq)) 734 goto err; 735 break; 736 case ECX_KEY_TYPE_ED448: 737 if (!ossl_ed448_public_from_private(gctx->libctx, key->pubkey, privkey, 738 gctx->propq)) 739 goto err; 740 break; 741 } 742 key->haspubkey = 1; 743 return key; 744 err: 745 ossl_ecx_key_free(key); 746 return NULL; 747 } 748 749 static void *x25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) 750 { 751 struct ecx_gen_ctx *gctx = genctx; 752 753 if (!ossl_prov_is_running()) 754 return 0; 755 756 #ifdef S390X_EC_ASM 757 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519)) 758 return s390x_ecx_keygen25519(gctx); 759 #endif 760 return ecx_gen(gctx); 761 } 762 763 static void *x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) 764 { 765 struct ecx_gen_ctx *gctx = genctx; 766 767 if (!ossl_prov_is_running()) 768 return 0; 769 770 #ifdef S390X_EC_ASM 771 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448)) 772 return s390x_ecx_keygen448(gctx); 773 #endif 774 return ecx_gen(gctx); 775 } 776 777 static void *ed25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) 778 { 779 ECX_KEY *key = NULL; 780 struct ecx_gen_ctx *gctx = genctx; 781 782 if (!ossl_prov_is_running()) 783 return 0; 784 785 #ifdef S390X_EC_ASM 786 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519) 787 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519) 788 && OPENSSL_s390xcap_P.kdsa[0] 789 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519)) { 790 key = s390x_ecd_keygen25519(gctx); 791 } else 792 #endif 793 { 794 key = ecx_gen(gctx); 795 } 796 797 #ifdef FIPS_MODULE 798 /* Exit if keygen failed OR we are doing parameter generation (blank key) */ 799 if (!key || ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)) 800 return key; 801 if (ecd_fips140_pairwise_test(key, ECX_KEY_TYPE_ED25519, 1) != 1) { 802 ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT); 803 ossl_ecx_key_free(key); 804 return NULL; 805 } 806 #endif 807 808 return key; 809 } 810 811 static void *ed448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) 812 { 813 ECX_KEY *key = NULL; 814 struct ecx_gen_ctx *gctx = genctx; 815 816 if (!ossl_prov_is_running()) 817 return 0; 818 819 #ifdef S390X_EC_ASM 820 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448) 821 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448) 822 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448)) { 823 key = s390x_ecd_keygen448(gctx); 824 } else 825 #endif 826 { 827 key = ecx_gen(gctx); 828 } 829 830 #ifdef FIPS_MODULE 831 /* Exit if keygen failed OR we are doing parameter generation (blank key) */ 832 if (!key || ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)) 833 return key; 834 if (ecd_fips140_pairwise_test(key, ECX_KEY_TYPE_ED448, 1) != 1) { 835 ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT); 836 ossl_ecx_key_free(key); 837 return NULL; 838 } 839 #endif 840 841 return key; 842 } 843 844 static void ecx_gen_cleanup(void *genctx) 845 { 846 struct ecx_gen_ctx *gctx = genctx; 847 848 if (gctx == NULL) 849 return; 850 851 OPENSSL_clear_free(gctx->dhkem_ikm, gctx->dhkem_ikmlen); 852 OPENSSL_free(gctx->propq); 853 OPENSSL_free(gctx); 854 } 855 856 void *ecx_load(const void *reference, size_t reference_sz) 857 { 858 ECX_KEY *key = NULL; 859 860 if (ossl_prov_is_running() && reference_sz == sizeof(key)) { 861 /* The contents of the reference is the address to our object */ 862 key = *(ECX_KEY **)reference; 863 /* We grabbed, so we detach it */ 864 *(ECX_KEY **)reference = NULL; 865 return key; 866 } 867 return NULL; 868 } 869 870 static void *ecx_dup(const void *keydata_from, int selection) 871 { 872 if (ossl_prov_is_running()) 873 return ossl_ecx_key_dup(keydata_from, selection); 874 return NULL; 875 } 876 877 static int ecx_key_pairwise_check(const ECX_KEY *ecx, int type) 878 { 879 uint8_t pub[64]; 880 881 switch (type) { 882 case ECX_KEY_TYPE_X25519: 883 ossl_x25519_public_from_private(pub, ecx->privkey); 884 break; 885 case ECX_KEY_TYPE_X448: 886 ossl_x448_public_from_private(pub, ecx->privkey); 887 break; 888 default: 889 return 0; 890 } 891 return CRYPTO_memcmp(ecx->pubkey, pub, ecx->keylen) == 0; 892 } 893 894 #ifdef FIPS_MODULE 895 /* 896 * FIPS ACVP testing requires the ability to check if the public key is valid 897 * This is not required normally since the ED signature verify does the test 898 * internally. 899 */ 900 static int ecd_key_pub_check(const ECX_KEY *ecx, int type) 901 { 902 switch (type) { 903 case ECX_KEY_TYPE_ED25519: 904 return ossl_ed25519_pubkey_verify(ecx->pubkey, ecx->keylen); 905 case ECX_KEY_TYPE_ED448: 906 return ossl_ed448_pubkey_verify(ecx->pubkey, ecx->keylen); 907 default: 908 return 1; 909 } 910 } 911 #endif 912 913 #ifdef FIPS_MODULE 914 static int ecd_key_pairwise_check(const ECX_KEY *ecx, int type) 915 { 916 return ecd_fips140_pairwise_test(ecx, type, 0); 917 } 918 #else 919 static int ecd_key_pairwise_check(const ECX_KEY *ecx, int type) 920 { 921 uint8_t pub[64]; 922 923 switch (type) { 924 case ECX_KEY_TYPE_ED25519: 925 if (!ossl_ed25519_public_from_private(ecx->libctx, pub, ecx->privkey, 926 ecx->propq)) 927 return 0; 928 break; 929 case ECX_KEY_TYPE_ED448: 930 if (!ossl_ed448_public_from_private(ecx->libctx, pub, ecx->privkey, 931 ecx->propq)) 932 return 0; 933 break; 934 default: 935 return 0; 936 } 937 return CRYPTO_memcmp(ecx->pubkey, pub, ecx->keylen) == 0; 938 } 939 #endif 940 941 static int ecx_validate(const void *keydata, int selection, int type, 942 size_t keylen) 943 { 944 const ECX_KEY *ecx = keydata; 945 int ok = keylen == ecx->keylen; 946 947 if (!ossl_prov_is_running()) 948 return 0; 949 950 if ((selection & ECX_POSSIBLE_SELECTIONS) == 0) 951 return 1; /* nothing to validate */ 952 953 if (!ok) { 954 ERR_raise(ERR_LIB_PROV, PROV_R_ALGORITHM_MISMATCH); 955 return 0; 956 } 957 958 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 959 ok = ok && ecx->haspubkey; 960 #ifdef FIPS_MODULE 961 ok = ok && ecd_key_pub_check(ecx, type); 962 #endif 963 } 964 965 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 966 ok = ok && ecx->privkey != NULL; 967 968 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != OSSL_KEYMGMT_SELECT_KEYPAIR) 969 return ok; 970 971 if (type == ECX_KEY_TYPE_ED25519 || type == ECX_KEY_TYPE_ED448) 972 ok = ok && ecd_key_pairwise_check(ecx, type); 973 else 974 ok = ok && ecx_key_pairwise_check(ecx, type); 975 976 return ok; 977 } 978 979 static int x25519_validate(const void *keydata, int selection, int checktype) 980 { 981 return ecx_validate(keydata, selection, ECX_KEY_TYPE_X25519, X25519_KEYLEN); 982 } 983 984 static int x448_validate(const void *keydata, int selection, int checktype) 985 { 986 return ecx_validate(keydata, selection, ECX_KEY_TYPE_X448, X448_KEYLEN); 987 } 988 989 static int ed25519_validate(const void *keydata, int selection, int checktype) 990 { 991 return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED25519, ED25519_KEYLEN); 992 } 993 994 static int ed448_validate(const void *keydata, int selection, int checktype) 995 { 996 return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED448, ED448_KEYLEN); 997 } 998 999 #define MAKE_KEYMGMT_FUNCTIONS(alg) \ 1000 const OSSL_DISPATCH ossl_##alg##_keymgmt_functions[] = { \ 1001 { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \ 1002 { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ossl_ecx_key_free }, \ 1003 { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))alg##_get_params }, \ 1004 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))alg##_gettable_params }, \ 1005 { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))alg##_set_params }, \ 1006 { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))alg##_settable_params }, \ 1007 { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has }, \ 1008 { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ecx_match }, \ 1009 { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))alg##_validate }, \ 1010 { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import }, \ 1011 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ecx_imexport_types }, \ 1012 { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ecx_export }, \ 1013 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ecx_imexport_types }, \ 1014 { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))alg##_gen_init }, \ 1015 { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ecx_gen_set_params }, \ 1016 { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, \ 1017 (void (*)(void))ecx_gen_settable_params }, \ 1018 { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen }, \ 1019 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \ 1020 { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ecx_load }, \ 1021 { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ecx_dup }, \ 1022 OSSL_DISPATCH_END \ 1023 }; 1024 1025 MAKE_KEYMGMT_FUNCTIONS(x25519) 1026 MAKE_KEYMGMT_FUNCTIONS(x448) 1027 MAKE_KEYMGMT_FUNCTIONS(ed25519) 1028 MAKE_KEYMGMT_FUNCTIONS(ed448) 1029 1030 #ifdef S390X_EC_ASM 1031 # include "s390x_arch.h" 1032 1033 static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx) 1034 { 1035 static const unsigned char generator[] = { 1036 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1037 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1038 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 1039 }; 1040 ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X25519, 1, 1041 gctx->propq); 1042 unsigned char *privkey = NULL, *pubkey; 1043 1044 if (key == NULL) { 1045 ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); 1046 goto err; 1047 } 1048 1049 /* If we're doing parameter generation then we just return a blank key */ 1050 if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) 1051 return key; 1052 1053 pubkey = key->pubkey; 1054 1055 privkey = ossl_ecx_key_allocate_privkey(key); 1056 if (privkey == NULL) { 1057 ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); 1058 goto err; 1059 } 1060 1061 #ifndef FIPS_MODULE 1062 if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) { 1063 if (gctx->type != ECX_KEY_TYPE_X25519) 1064 goto err; 1065 if (!ossl_ecx_dhkem_derive_private(key, privkey, 1066 gctx->dhkem_ikm, gctx->dhkem_ikmlen)) 1067 goto err; 1068 } else 1069 #endif 1070 { 1071 if (RAND_priv_bytes_ex(gctx->libctx, privkey, X25519_KEYLEN, 0) <= 0) 1072 goto err; 1073 } 1074 1075 privkey[0] &= 248; 1076 privkey[31] &= 127; 1077 privkey[31] |= 64; 1078 1079 if (s390x_x25519_mul(pubkey, generator, privkey) != 1) 1080 goto err; 1081 key->haspubkey = 1; 1082 return key; 1083 err: 1084 ossl_ecx_key_free(key); 1085 return NULL; 1086 } 1087 1088 static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx) 1089 { 1090 static const unsigned char generator[] = { 1091 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1092 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1093 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1094 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1095 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 1096 }; 1097 ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X448, 1, 1098 gctx->propq); 1099 unsigned char *privkey = NULL, *pubkey; 1100 1101 if (key == NULL) { 1102 ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); 1103 goto err; 1104 } 1105 1106 /* If we're doing parameter generation then we just return a blank key */ 1107 if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) 1108 return key; 1109 1110 pubkey = key->pubkey; 1111 1112 privkey = ossl_ecx_key_allocate_privkey(key); 1113 if (privkey == NULL) { 1114 ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); 1115 goto err; 1116 } 1117 1118 #ifndef FIPS_MODULE 1119 if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) { 1120 if (gctx->type != ECX_KEY_TYPE_X448) 1121 goto err; 1122 if (!ossl_ecx_dhkem_derive_private(key, privkey, 1123 gctx->dhkem_ikm, gctx->dhkem_ikmlen)) 1124 goto err; 1125 } else 1126 #endif 1127 { 1128 if (RAND_priv_bytes_ex(gctx->libctx, privkey, X448_KEYLEN, 0) <= 0) 1129 goto err; 1130 } 1131 1132 privkey[0] &= 252; 1133 privkey[55] |= 128; 1134 1135 if (s390x_x448_mul(pubkey, generator, privkey) != 1) 1136 goto err; 1137 key->haspubkey = 1; 1138 return key; 1139 err: 1140 ossl_ecx_key_free(key); 1141 return NULL; 1142 } 1143 1144 static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx) 1145 { 1146 static const unsigned char generator_x[] = { 1147 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95, 1148 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, 1149 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21 1150 }; 1151 static const unsigned char generator_y[] = { 1152 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 1153 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 1154 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 1155 }; 1156 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH]; 1157 ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED25519, 1, 1158 gctx->propq); 1159 unsigned char *privkey = NULL, *pubkey; 1160 unsigned int sz; 1161 EVP_MD *sha = NULL; 1162 int j; 1163 1164 if (key == NULL) { 1165 ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); 1166 goto err; 1167 } 1168 1169 /* If we're doing parameter generation then we just return a blank key */ 1170 if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) 1171 return key; 1172 1173 pubkey = key->pubkey; 1174 1175 privkey = ossl_ecx_key_allocate_privkey(key); 1176 if (privkey == NULL) { 1177 ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); 1178 goto err; 1179 } 1180 1181 if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED25519_KEYLEN, 0) <= 0) 1182 goto err; 1183 1184 sha = EVP_MD_fetch(gctx->libctx, "SHA512", gctx->propq); 1185 if (sha == NULL) 1186 goto err; 1187 j = EVP_Digest(privkey, 32, buff, &sz, sha, NULL); 1188 EVP_MD_free(sha); 1189 if (!j) 1190 goto err; 1191 1192 buff[0] &= 248; 1193 buff[31] &= 63; 1194 buff[31] |= 64; 1195 1196 if (s390x_ed25519_mul(x_dst, pubkey, 1197 generator_x, generator_y, buff) != 1) 1198 goto err; 1199 1200 pubkey[31] |= ((x_dst[0] & 0x01) << 7); 1201 key->haspubkey = 1; 1202 return key; 1203 err: 1204 ossl_ecx_key_free(key); 1205 return NULL; 1206 } 1207 1208 static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx) 1209 { 1210 static const unsigned char generator_x[] = { 1211 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b, 1212 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12, 1213 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47, 1214 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22, 1215 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00 1216 }; 1217 static const unsigned char generator_y[] = { 1218 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e, 1219 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a, 1220 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c, 1221 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88, 1222 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00 1223 }; 1224 unsigned char x_dst[57], buff[114]; 1225 ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED448, 1, 1226 gctx->propq); 1227 unsigned char *privkey = NULL, *pubkey; 1228 EVP_MD_CTX *hashctx = NULL; 1229 EVP_MD *shake = NULL; 1230 1231 if (key == NULL) { 1232 ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); 1233 goto err; 1234 } 1235 1236 /* If we're doing parameter generation then we just return a blank key */ 1237 if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) 1238 return key; 1239 1240 pubkey = key->pubkey; 1241 1242 privkey = ossl_ecx_key_allocate_privkey(key); 1243 if (privkey == NULL) { 1244 ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB); 1245 goto err; 1246 } 1247 1248 shake = EVP_MD_fetch(gctx->libctx, "SHAKE256", gctx->propq); 1249 if (shake == NULL) 1250 goto err; 1251 if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED448_KEYLEN, 0) <= 0) 1252 goto err; 1253 1254 hashctx = EVP_MD_CTX_new(); 1255 if (hashctx == NULL) 1256 goto err; 1257 if (EVP_DigestInit_ex(hashctx, shake, NULL) != 1) 1258 goto err; 1259 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1) 1260 goto err; 1261 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1) 1262 goto err; 1263 1264 buff[0] &= -4; 1265 buff[55] |= 0x80; 1266 buff[56] = 0; 1267 1268 if (s390x_ed448_mul(x_dst, pubkey, 1269 generator_x, generator_y, buff) != 1) 1270 goto err; 1271 1272 pubkey[56] |= ((x_dst[0] & 0x01) << 7); 1273 EVP_MD_CTX_free(hashctx); 1274 EVP_MD_free(shake); 1275 key->haspubkey = 1; 1276 return key; 1277 err: 1278 ossl_ecx_key_free(key); 1279 EVP_MD_CTX_free(hashctx); 1280 EVP_MD_free(shake); 1281 return NULL; 1282 } 1283 #endif 1284