1 /* 2 * Copyright 2019-2024 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 <string.h> 11 #include <openssl/core_names.h> 12 #include <openssl/core_dispatch.h> 13 #include <openssl/rand.h> 14 #include <openssl/params.h> 15 /* For TLS1_3_VERSION */ 16 #include <openssl/ssl.h> 17 #include "internal/nelem.h" 18 19 static OSSL_FUNC_keymgmt_import_fn xor_import; 20 static OSSL_FUNC_keymgmt_import_types_fn xor_import_types; 21 static OSSL_FUNC_keymgmt_export_fn xor_export; 22 static OSSL_FUNC_keymgmt_export_types_fn xor_export_types; 23 24 int tls_provider_init(const OSSL_CORE_HANDLE *handle, 25 const OSSL_DISPATCH *in, 26 const OSSL_DISPATCH **out, 27 void **provctx); 28 29 #define XOR_KEY_SIZE 32 30 31 /* 32 * Top secret. This algorithm only works if no one knows what this number is. 33 * Please don't tell anyone what it is. 34 * 35 * This algorithm is for testing only - don't really use it! 36 */ 37 static const unsigned char private_constant[XOR_KEY_SIZE] = { 38 0xd3, 0x6b, 0x54, 0xec, 0x5b, 0xac, 0x89, 0x96, 0x8c, 0x2c, 0x66, 0xa5, 39 0x67, 0x0d, 0xe3, 0xdd, 0x43, 0x69, 0xbc, 0x83, 0x3d, 0x60, 0xc7, 0xb8, 40 0x2b, 0x1c, 0x5a, 0xfd, 0xb5, 0xcd, 0xd0, 0xf8 41 }; 42 43 typedef struct xorkey_st { 44 unsigned char privkey[XOR_KEY_SIZE]; 45 unsigned char pubkey[XOR_KEY_SIZE]; 46 int hasprivkey; 47 int haspubkey; 48 } XORKEY; 49 50 51 /* Key Management for the dummy XOR KEX and KEM algorithms */ 52 53 static OSSL_FUNC_keymgmt_new_fn xor_newdata; 54 static OSSL_FUNC_keymgmt_free_fn xor_freedata; 55 static OSSL_FUNC_keymgmt_has_fn xor_has; 56 static OSSL_FUNC_keymgmt_dup_fn xor_dup; 57 static OSSL_FUNC_keymgmt_gen_init_fn xor_gen_init; 58 static OSSL_FUNC_keymgmt_gen_set_params_fn xor_gen_set_params; 59 static OSSL_FUNC_keymgmt_gen_settable_params_fn xor_gen_settable_params; 60 static OSSL_FUNC_keymgmt_gen_fn xor_gen; 61 static OSSL_FUNC_keymgmt_gen_cleanup_fn xor_gen_cleanup; 62 static OSSL_FUNC_keymgmt_get_params_fn xor_get_params; 63 static OSSL_FUNC_keymgmt_gettable_params_fn xor_gettable_params; 64 static OSSL_FUNC_keymgmt_set_params_fn xor_set_params; 65 static OSSL_FUNC_keymgmt_settable_params_fn xor_settable_params; 66 67 /* 68 * Dummy "XOR" Key Exchange algorithm. We just xor the private and public keys 69 * together. Don't use this! 70 */ 71 72 static OSSL_FUNC_keyexch_newctx_fn xor_newctx; 73 static OSSL_FUNC_keyexch_init_fn xor_init; 74 static OSSL_FUNC_keyexch_set_peer_fn xor_set_peer; 75 static OSSL_FUNC_keyexch_derive_fn xor_derive; 76 static OSSL_FUNC_keyexch_freectx_fn xor_freectx; 77 static OSSL_FUNC_keyexch_dupctx_fn xor_dupctx; 78 79 /* 80 * Dummy "XOR" Key Encapsulation Method. We just build a KEM over the xor KEX. 81 * Don't use this! 82 */ 83 84 static OSSL_FUNC_kem_newctx_fn xor_newctx; 85 static OSSL_FUNC_kem_freectx_fn xor_freectx; 86 static OSSL_FUNC_kem_dupctx_fn xor_dupctx; 87 static OSSL_FUNC_kem_encapsulate_init_fn xor_init; 88 static OSSL_FUNC_kem_encapsulate_fn xor_encapsulate; 89 static OSSL_FUNC_kem_decapsulate_init_fn xor_init; 90 static OSSL_FUNC_kem_decapsulate_fn xor_decapsulate; 91 92 93 /* 94 * We define 2 dummy TLS groups called "xorgroup" and "xorkemgroup" for test 95 * purposes 96 */ 97 struct tls_group_st { 98 unsigned int group_id; /* for "tls-group-id", see provider-base(7) */ 99 unsigned int secbits; 100 unsigned int mintls; 101 unsigned int maxtls; 102 unsigned int mindtls; 103 unsigned int maxdtls; 104 unsigned int is_kem; /* boolean */ 105 }; 106 107 #define XORGROUP_NAME "xorgroup" 108 #define XORGROUP_NAME_INTERNAL "xorgroup-int" 109 static struct tls_group_st xor_group = { 110 0, /* group_id, set by randomize_tls_group_id() */ 111 128, /* secbits */ 112 TLS1_3_VERSION, /* mintls */ 113 0, /* maxtls */ 114 -1, /* mindtls */ 115 -1, /* maxdtls */ 116 0 /* is_kem */ 117 }; 118 119 #define XORKEMGROUP_NAME "xorkemgroup" 120 #define XORKEMGROUP_NAME_INTERNAL "xorkemgroup-int" 121 static struct tls_group_st xor_kemgroup = { 122 0, /* group_id, set by randomize_tls_group_id() */ 123 128, /* secbits */ 124 TLS1_3_VERSION, /* mintls */ 125 0, /* maxtls */ 126 -1, /* mindtls */ 127 -1, /* maxdtls */ 128 1 /* is_kem */ 129 }; 130 131 #define ALGORITHM "XOR" 132 133 static const OSSL_PARAM xor_group_params[] = { 134 OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME, 135 XORGROUP_NAME, sizeof(XORGROUP_NAME)), 136 OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL, 137 XORGROUP_NAME_INTERNAL, 138 sizeof(XORGROUP_NAME_INTERNAL)), 139 OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_ALG, ALGORITHM, 140 sizeof(ALGORITHM)), 141 OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_ID, &xor_group.group_id), 142 OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS, 143 &xor_group.secbits), 144 OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_TLS, &xor_group.mintls), 145 OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_TLS, &xor_group.maxtls), 146 OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS, &xor_group.mindtls), 147 OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS, &xor_group.maxdtls), 148 OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_IS_KEM, &xor_group.is_kem), 149 OSSL_PARAM_END 150 }; 151 152 static const OSSL_PARAM xor_kemgroup_params[] = { 153 OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME, 154 XORKEMGROUP_NAME, sizeof(XORKEMGROUP_NAME)), 155 OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL, 156 XORKEMGROUP_NAME_INTERNAL, 157 sizeof(XORKEMGROUP_NAME_INTERNAL)), 158 OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_ALG, ALGORITHM, 159 sizeof(ALGORITHM)), 160 OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_ID, &xor_kemgroup.group_id), 161 OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS, 162 &xor_kemgroup.secbits), 163 OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_TLS, &xor_kemgroup.mintls), 164 OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_TLS, &xor_kemgroup.maxtls), 165 OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS, &xor_kemgroup.mindtls), 166 OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS, &xor_kemgroup.maxdtls), 167 OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_IS_KEM, &xor_kemgroup.is_kem), 168 OSSL_PARAM_END 169 }; 170 171 #define NUM_DUMMY_GROUPS 50 172 static char *dummy_group_names[NUM_DUMMY_GROUPS]; 173 174 static int tls_prov_get_capabilities(void *provctx, const char *capability, 175 OSSL_CALLBACK *cb, void *arg) 176 { 177 int ret; 178 int i; 179 const char *dummy_base = "dummy"; 180 const size_t dummy_name_max_size = strlen(dummy_base) + 3; 181 182 if (strcmp(capability, "TLS-GROUP") != 0) { 183 /* We don't support this capability */ 184 return 0; 185 } 186 187 /* Register our 2 groups */ 188 OPENSSL_assert(xor_group.group_id >= 65024 189 && xor_group.group_id < 65279 - NUM_DUMMY_GROUPS); 190 ret = cb(xor_group_params, arg); 191 ret &= cb(xor_kemgroup_params, arg); 192 193 /* 194 * Now register some dummy groups > GROUPLIST_INCREMENT (== 40) as defined 195 * in ssl/t1_lib.c, to make sure we exercise the code paths for registering 196 * large numbers of groups. 197 */ 198 199 for (i = 0; i < NUM_DUMMY_GROUPS; i++) { 200 OSSL_PARAM dummygroup[OSSL_NELEM(xor_group_params)]; 201 unsigned int dummygroup_id; 202 203 memcpy(dummygroup, xor_group_params, sizeof(xor_group_params)); 204 205 /* Give the dummy group a unique name */ 206 if (dummy_group_names[i] == NULL) { 207 dummy_group_names[i] = OPENSSL_zalloc(dummy_name_max_size); 208 if (dummy_group_names[i] == NULL) 209 return 0; 210 BIO_snprintf(dummy_group_names[i], 211 dummy_name_max_size, 212 "%s%d", dummy_base, i); 213 } 214 dummygroup[0].data = dummy_group_names[i]; 215 dummygroup[0].data_size = strlen(dummy_group_names[i]) + 1; 216 /* assign unique group IDs also to dummy groups for registration */ 217 dummygroup_id = 65279 - NUM_DUMMY_GROUPS + i; 218 dummygroup[3].data = (unsigned char*)&dummygroup_id; 219 ret &= cb(dummygroup, arg); 220 } 221 222 return ret; 223 } 224 225 /* 226 * Dummy "XOR" Key Exchange algorithm. We just xor the private and public keys 227 * together. Don't use this! 228 */ 229 230 typedef struct { 231 XORKEY *key; 232 XORKEY *peerkey; 233 void *provctx; 234 } PROV_XOR_CTX; 235 236 static void *xor_newctx(void *provctx) 237 { 238 PROV_XOR_CTX *pxorctx = OPENSSL_zalloc(sizeof(PROV_XOR_CTX)); 239 240 if (pxorctx == NULL) 241 return NULL; 242 243 pxorctx->provctx = provctx; 244 245 return pxorctx; 246 } 247 248 static int xor_init(void *vpxorctx, void *vkey, 249 ossl_unused const OSSL_PARAM params[]) 250 { 251 PROV_XOR_CTX *pxorctx = (PROV_XOR_CTX *)vpxorctx; 252 253 if (pxorctx == NULL || vkey == NULL) 254 return 0; 255 pxorctx->key = vkey; 256 return 1; 257 } 258 259 static int xor_set_peer(void *vpxorctx, void *vpeerkey) 260 { 261 PROV_XOR_CTX *pxorctx = (PROV_XOR_CTX *)vpxorctx; 262 263 if (pxorctx == NULL || vpeerkey == NULL) 264 return 0; 265 pxorctx->peerkey = vpeerkey; 266 return 1; 267 } 268 269 static int xor_derive(void *vpxorctx, unsigned char *secret, size_t *secretlen, 270 size_t outlen) 271 { 272 PROV_XOR_CTX *pxorctx = (PROV_XOR_CTX *)vpxorctx; 273 int i; 274 275 if (pxorctx->key == NULL || pxorctx->peerkey == NULL) 276 return 0; 277 278 *secretlen = XOR_KEY_SIZE; 279 if (secret == NULL) 280 return 1; 281 282 if (outlen < XOR_KEY_SIZE) 283 return 0; 284 285 for (i = 0; i < XOR_KEY_SIZE; i++) 286 secret[i] = pxorctx->key->privkey[i] ^ pxorctx->peerkey->pubkey[i]; 287 288 return 1; 289 } 290 291 static void xor_freectx(void *pxorctx) 292 { 293 OPENSSL_free(pxorctx); 294 } 295 296 static void *xor_dupctx(void *vpxorctx) 297 { 298 PROV_XOR_CTX *srcctx = (PROV_XOR_CTX *)vpxorctx; 299 PROV_XOR_CTX *dstctx; 300 301 dstctx = OPENSSL_zalloc(sizeof(*srcctx)); 302 if (dstctx == NULL) 303 return NULL; 304 305 *dstctx = *srcctx; 306 307 return dstctx; 308 } 309 310 static const OSSL_DISPATCH xor_keyexch_functions[] = { 311 { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))xor_newctx }, 312 { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))xor_init }, 313 { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))xor_derive }, 314 { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))xor_set_peer }, 315 { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))xor_freectx }, 316 { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))xor_dupctx }, 317 { 0, NULL } 318 }; 319 320 static const OSSL_ALGORITHM tls_prov_keyexch[] = { 321 /* 322 * Obviously this is not FIPS approved, but in order to test in conjuction 323 * with the FIPS provider we pretend that it is. 324 */ 325 { "XOR", "provider=tls-provider,fips=yes", xor_keyexch_functions }, 326 { NULL, NULL, NULL } 327 }; 328 329 /* 330 * Dummy "XOR" Key Encapsulation Method. We just build a KEM over the xor KEX. 331 * Don't use this! 332 */ 333 334 static int xor_encapsulate(void *vpxorctx, 335 unsigned char *ct, size_t *ctlen, 336 unsigned char *ss, size_t *sslen) 337 { 338 /* 339 * We are building this around a KEX: 340 * 341 * 1. we generate ephemeral keypair 342 * 2. we encode our ephemeral pubkey as the outgoing ct 343 * 3. we derive using our ephemeral privkey in combination with the peer 344 * pubkey from the ctx; the result is our ss. 345 */ 346 int rv = 0; 347 void *genctx = NULL, *derivectx = NULL; 348 XORKEY *ourkey = NULL; 349 PROV_XOR_CTX *pxorctx = vpxorctx; 350 351 if (ct == NULL || ss == NULL) { 352 /* Just return sizes */ 353 354 if (ctlen == NULL && sslen == NULL) 355 return 0; 356 if (ctlen != NULL) 357 *ctlen = XOR_KEY_SIZE; 358 if (sslen != NULL) 359 *sslen = XOR_KEY_SIZE; 360 return 1; 361 } 362 363 /* 1. Generate keypair */ 364 genctx = xor_gen_init(pxorctx->provctx, OSSL_KEYMGMT_SELECT_KEYPAIR, NULL); 365 if (genctx == NULL) 366 goto end; 367 ourkey = xor_gen(genctx, NULL, NULL); 368 if (ourkey == NULL) 369 goto end; 370 371 /* 2. Encode ephemeral pubkey as ct */ 372 memcpy(ct, ourkey->pubkey, XOR_KEY_SIZE); 373 *ctlen = XOR_KEY_SIZE; 374 375 /* 3. Derive ss via KEX */ 376 derivectx = xor_newctx(pxorctx->provctx); 377 if (derivectx == NULL 378 || !xor_init(derivectx, ourkey, NULL) 379 || !xor_set_peer(derivectx, pxorctx->key) 380 || !xor_derive(derivectx, ss, sslen, XOR_KEY_SIZE)) 381 goto end; 382 383 rv = 1; 384 385 end: 386 xor_gen_cleanup(genctx); 387 xor_freedata(ourkey); 388 xor_freectx(derivectx); 389 return rv; 390 } 391 392 static int xor_decapsulate(void *vpxorctx, 393 unsigned char *ss, size_t *sslen, 394 const unsigned char *ct, size_t ctlen) 395 { 396 /* 397 * We are building this around a KEX: 398 * 399 * - ct is our peer's pubkey 400 * - decapsulate is just derive. 401 */ 402 int rv = 0; 403 void *derivectx = NULL; 404 XORKEY *peerkey = NULL; 405 PROV_XOR_CTX *pxorctx = vpxorctx; 406 407 if (ss == NULL) { 408 /* Just return size */ 409 if (sslen == NULL) 410 return 0; 411 *sslen = XOR_KEY_SIZE; 412 return 1; 413 } 414 415 if (ctlen != XOR_KEY_SIZE) 416 return 0; 417 peerkey = xor_newdata(pxorctx->provctx); 418 if (peerkey == NULL) 419 goto end; 420 memcpy(peerkey->pubkey, ct, XOR_KEY_SIZE); 421 422 /* Derive ss via KEX */ 423 derivectx = xor_newctx(pxorctx->provctx); 424 if (derivectx == NULL 425 || !xor_init(derivectx, pxorctx->key, NULL) 426 || !xor_set_peer(derivectx, peerkey) 427 || !xor_derive(derivectx, ss, sslen, XOR_KEY_SIZE)) 428 goto end; 429 430 rv = 1; 431 432 end: 433 xor_freedata(peerkey); 434 xor_freectx(derivectx); 435 return rv; 436 } 437 438 static const OSSL_DISPATCH xor_kem_functions[] = { 439 { OSSL_FUNC_KEM_NEWCTX, (void (*)(void))xor_newctx }, 440 { OSSL_FUNC_KEM_FREECTX, (void (*)(void))xor_freectx }, 441 { OSSL_FUNC_KEM_DUPCTX, (void (*)(void))xor_dupctx }, 442 { OSSL_FUNC_KEM_ENCAPSULATE_INIT, (void (*)(void))xor_init }, 443 { OSSL_FUNC_KEM_ENCAPSULATE, (void (*)(void))xor_encapsulate }, 444 { OSSL_FUNC_KEM_DECAPSULATE_INIT, (void (*)(void))xor_init }, 445 { OSSL_FUNC_KEM_DECAPSULATE, (void (*)(void))xor_decapsulate }, 446 { 0, NULL } 447 }; 448 449 static const OSSL_ALGORITHM tls_prov_kem[] = { 450 /* 451 * Obviously this is not FIPS approved, but in order to test in conjuction 452 * with the FIPS provider we pretend that it is. 453 */ 454 { "XOR", "provider=tls-provider,fips=yes", xor_kem_functions }, 455 { NULL, NULL, NULL } 456 }; 457 458 /* Key Management for the dummy XOR key exchange algorithm */ 459 460 static void *xor_newdata(void *provctx) 461 { 462 return OPENSSL_zalloc(sizeof(XORKEY)); 463 } 464 465 static void xor_freedata(void *keydata) 466 { 467 OPENSSL_free(keydata); 468 } 469 470 static int xor_has(const void *vkey, int selection) 471 { 472 const XORKEY *key = vkey; 473 int ok = 0; 474 475 if (key != NULL) { 476 ok = 1; 477 478 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) 479 ok = ok && key->haspubkey; 480 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 481 ok = ok && key->hasprivkey; 482 } 483 return ok; 484 } 485 486 static void *xor_dup(const void *vfromkey, int selection) 487 { 488 XORKEY *tokey = xor_newdata(NULL); 489 const XORKEY *fromkey = vfromkey; 490 int ok = 0; 491 492 if (tokey != NULL && fromkey != NULL) { 493 ok = 1; 494 495 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 496 if (fromkey->haspubkey) { 497 memcpy(tokey->pubkey, fromkey->pubkey, XOR_KEY_SIZE); 498 tokey->haspubkey = 1; 499 } else { 500 tokey->haspubkey = 0; 501 } 502 } 503 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 504 if (fromkey->hasprivkey) { 505 memcpy(tokey->privkey, fromkey->privkey, XOR_KEY_SIZE); 506 tokey->hasprivkey = 1; 507 } else { 508 tokey->hasprivkey = 0; 509 } 510 } 511 } 512 if (!ok) { 513 xor_freedata(tokey); 514 tokey = NULL; 515 } 516 return tokey; 517 } 518 519 static ossl_inline int xor_get_params(void *vkey, OSSL_PARAM params[]) 520 { 521 XORKEY *key = vkey; 522 OSSL_PARAM *p; 523 524 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL 525 && !OSSL_PARAM_set_int(p, XOR_KEY_SIZE)) 526 return 0; 527 528 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL 529 && !OSSL_PARAM_set_int(p, xor_group.secbits)) 530 return 0; 531 532 if ((p = OSSL_PARAM_locate(params, 533 OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL) { 534 if (p->data_type != OSSL_PARAM_OCTET_STRING) 535 return 0; 536 p->return_size = XOR_KEY_SIZE; 537 if (p->data != NULL && p->data_size >= XOR_KEY_SIZE) 538 memcpy(p->data, key->pubkey, XOR_KEY_SIZE); 539 } 540 541 return 1; 542 } 543 544 static const OSSL_PARAM xor_params[] = { 545 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), 546 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), 547 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), 548 OSSL_PARAM_END 549 }; 550 551 static const OSSL_PARAM *xor_gettable_params(void *provctx) 552 { 553 return xor_params; 554 } 555 556 static int xor_set_params(void *vkey, const OSSL_PARAM params[]) 557 { 558 XORKEY *key = vkey; 559 const OSSL_PARAM *p; 560 561 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY); 562 if (p != NULL) { 563 if (p->data_type != OSSL_PARAM_OCTET_STRING 564 || p->data_size != XOR_KEY_SIZE) 565 return 0; 566 memcpy(key->pubkey, p->data, XOR_KEY_SIZE); 567 key->haspubkey = 1; 568 } 569 570 return 1; 571 } 572 573 static const OSSL_PARAM xor_known_settable_params[] = { 574 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), 575 OSSL_PARAM_END 576 }; 577 578 static const OSSL_PARAM *xor_settable_params(void *provctx) 579 { 580 return xor_known_settable_params; 581 } 582 583 struct xor_gen_ctx { 584 int selection; 585 OSSL_LIB_CTX *libctx; 586 }; 587 588 static void *xor_gen_init(void *provctx, int selection, 589 const OSSL_PARAM params[]) 590 { 591 struct xor_gen_ctx *gctx = NULL; 592 593 if ((selection & (OSSL_KEYMGMT_SELECT_KEYPAIR 594 | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)) == 0) 595 return NULL; 596 597 if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) 598 gctx->selection = selection; 599 600 /* Our provctx is really just an OSSL_LIB_CTX */ 601 gctx->libctx = (OSSL_LIB_CTX *)provctx; 602 603 if (!xor_gen_set_params(gctx, params)) { 604 OPENSSL_free(gctx); 605 return NULL; 606 } 607 return gctx; 608 } 609 610 static int xor_gen_set_params(void *genctx, const OSSL_PARAM params[]) 611 { 612 struct xor_gen_ctx *gctx = genctx; 613 const OSSL_PARAM *p; 614 615 if (gctx == NULL) 616 return 0; 617 618 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); 619 if (p != NULL) { 620 if (p->data_type != OSSL_PARAM_UTF8_STRING 621 || (strcmp(p->data, XORGROUP_NAME_INTERNAL) != 0 622 && strcmp(p->data, XORKEMGROUP_NAME_INTERNAL) != 0)) 623 return 0; 624 } 625 626 return 1; 627 } 628 629 static const OSSL_PARAM *xor_gen_settable_params(ossl_unused void *genctx, 630 ossl_unused void *provctx) 631 { 632 static OSSL_PARAM settable[] = { 633 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), 634 OSSL_PARAM_END 635 }; 636 return settable; 637 } 638 639 static void *xor_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) 640 { 641 struct xor_gen_ctx *gctx = genctx; 642 XORKEY *key = OPENSSL_zalloc(sizeof(*key)); 643 size_t i; 644 645 if (key == NULL) 646 return NULL; 647 648 if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { 649 if (RAND_bytes_ex(gctx->libctx, key->privkey, XOR_KEY_SIZE, 0) <= 0) { 650 OPENSSL_free(key); 651 return NULL; 652 } 653 for (i = 0; i < XOR_KEY_SIZE; i++) 654 key->pubkey[i] = key->privkey[i] ^ private_constant[i]; 655 key->hasprivkey = 1; 656 key->haspubkey = 1; 657 } 658 659 return key; 660 } 661 662 /* IMPORT + EXPORT */ 663 664 static int xor_import(void *vkey, int select, const OSSL_PARAM params[]) 665 { 666 XORKEY *key = vkey; 667 const OSSL_PARAM *param_priv_key, *param_pub_key; 668 unsigned char privkey[XOR_KEY_SIZE]; 669 unsigned char pubkey[XOR_KEY_SIZE]; 670 void *pprivkey = privkey, *ppubkey = pubkey; 671 size_t priv_len = 0, pub_len = 0; 672 int res = 0; 673 674 if (key == NULL || (select & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) 675 return 0; 676 677 memset(privkey, 0, sizeof(privkey)); 678 memset(pubkey, 0, sizeof(pubkey)); 679 param_priv_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); 680 param_pub_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY); 681 682 if ((param_priv_key != NULL 683 && !OSSL_PARAM_get_octet_string(param_priv_key, &pprivkey, 684 sizeof(privkey), &priv_len)) 685 || (param_pub_key != NULL 686 && !OSSL_PARAM_get_octet_string(param_pub_key, &ppubkey, 687 sizeof(pubkey), &pub_len))) 688 goto err; 689 690 if (priv_len > 0) { 691 memcpy(key->privkey, privkey, priv_len); 692 key->hasprivkey = 1; 693 } 694 if (pub_len > 0) { 695 memcpy(key->pubkey, pubkey, pub_len); 696 key->haspubkey = 1; 697 } 698 res = 1; 699 err: 700 return res; 701 } 702 703 static int xor_export(void *vkey, int select, OSSL_CALLBACK *param_cb, 704 void *cbarg) 705 { 706 XORKEY *key = vkey; 707 OSSL_PARAM params[3], *p = params; 708 709 if (key == NULL || (select & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) 710 return 0; 711 712 *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, 713 key->privkey, 714 sizeof(key->privkey)); 715 *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY, 716 key->pubkey, sizeof(key->pubkey)); 717 *p++ = OSSL_PARAM_construct_end(); 718 719 return param_cb(params, cbarg); 720 } 721 722 static const OSSL_PARAM xor_key_types[] = { 723 OSSL_PARAM_BN(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), 724 OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), 725 OSSL_PARAM_END 726 }; 727 728 static const OSSL_PARAM *xor_import_types(int select) 729 { 730 return (select & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0 ? xor_key_types : NULL; 731 } 732 733 static const OSSL_PARAM *xor_export_types(int select) 734 { 735 return (select & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0 ? xor_key_types : NULL; 736 } 737 738 static void xor_gen_cleanup(void *genctx) 739 { 740 OPENSSL_free(genctx); 741 } 742 743 static const OSSL_DISPATCH xor_keymgmt_functions[] = { 744 { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))xor_newdata }, 745 { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))xor_gen_init }, 746 { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))xor_gen_set_params }, 747 { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, 748 (void (*)(void))xor_gen_settable_params }, 749 { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))xor_gen }, 750 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))xor_gen_cleanup }, 751 { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))xor_get_params }, 752 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))xor_gettable_params }, 753 { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))xor_set_params }, 754 { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))xor_settable_params }, 755 { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))xor_has }, 756 { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))xor_dup }, 757 { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))xor_freedata }, 758 { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))xor_import }, 759 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))xor_import_types }, 760 { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))xor_export }, 761 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))xor_export_types }, 762 { 0, NULL } 763 }; 764 765 static const OSSL_ALGORITHM tls_prov_keymgmt[] = { 766 /* 767 * Obviously this is not FIPS approved, but in order to test in conjuction 768 * with the FIPS provider we pretend that it is. 769 */ 770 { "XOR", "provider=tls-provider,fips=yes", xor_keymgmt_functions }, 771 { NULL, NULL, NULL } 772 }; 773 774 static const OSSL_ALGORITHM *tls_prov_query(void *provctx, int operation_id, 775 int *no_cache) 776 { 777 *no_cache = 0; 778 switch (operation_id) { 779 case OSSL_OP_KEYMGMT: 780 return tls_prov_keymgmt; 781 case OSSL_OP_KEYEXCH: 782 return tls_prov_keyexch; 783 case OSSL_OP_KEM: 784 return tls_prov_kem; 785 } 786 return NULL; 787 } 788 789 static void tls_prov_teardown(void *provctx) 790 { 791 int i; 792 793 OSSL_LIB_CTX_free(provctx); 794 795 for (i = 0; i < NUM_DUMMY_GROUPS; i++) { 796 OPENSSL_free(dummy_group_names[i]); 797 dummy_group_names[i] = NULL; 798 } 799 } 800 801 /* Functions we provide to the core */ 802 static const OSSL_DISPATCH tls_prov_dispatch_table[] = { 803 { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))tls_prov_teardown }, 804 { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))tls_prov_query }, 805 { OSSL_FUNC_PROVIDER_GET_CAPABILITIES, (void (*)(void))tls_prov_get_capabilities }, 806 { 0, NULL } 807 }; 808 809 static 810 unsigned int randomize_tls_group_id(OSSL_LIB_CTX *libctx) 811 { 812 /* 813 * Randomise the group_id we're going to use to ensure we don't interoperate 814 * with anything but ourselves. 815 */ 816 unsigned int group_id; 817 static unsigned int mem[10] = { 0 }; 818 static int in_mem = 0; 819 int i; 820 821 retry: 822 if (RAND_bytes_ex(libctx, (unsigned char *)&group_id, sizeof(group_id), 0) <= 0) 823 return 0; 824 /* 825 * Ensure group_id is within the IANA Reserved for private use range 826 * (65024-65279). 827 * Carve out NUM_DUMMY_GROUPS ids for properly registering those. 828 */ 829 group_id %= 65279 - NUM_DUMMY_GROUPS - 65024; 830 group_id += 65024; 831 832 /* Ensure we did not already issue this group_id */ 833 for (i = 0; i < in_mem; i++) 834 if (mem[i] == group_id) 835 goto retry; 836 837 /* Add this group_id to the list of ids issued by this function */ 838 mem[in_mem++] = group_id; 839 840 return group_id; 841 } 842 843 int tls_provider_init(const OSSL_CORE_HANDLE *handle, 844 const OSSL_DISPATCH *in, 845 const OSSL_DISPATCH **out, 846 void **provctx) 847 { 848 OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new(); 849 850 if (libctx == NULL) 851 return 0; 852 853 *provctx = libctx; 854 855 /* 856 * Randomise the group_id we're going to use to ensure we don't interoperate 857 * with anything but ourselves. 858 */ 859 xor_group.group_id = randomize_tls_group_id(libctx); 860 xor_kemgroup.group_id = randomize_tls_group_id(libctx); 861 862 *out = tls_prov_dispatch_table; 863 return 1; 864 } 865