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