1 /* 2 * Copyright 2019-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 <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 ret = cb(xor_group_params, arg); 189 ret &= cb(xor_kemgroup_params, arg); 190 191 /* 192 * Now register some dummy groups > GROUPLIST_INCREMENT (== 40) as defined 193 * in ssl/t1_lib.c, to make sure we exercise the code paths for registering 194 * large numbers of groups. 195 */ 196 197 for (i = 0; i < NUM_DUMMY_GROUPS; i++) { 198 OSSL_PARAM dummygroup[OSSL_NELEM(xor_group_params)]; 199 200 memcpy(dummygroup, xor_group_params, sizeof(xor_group_params)); 201 202 /* Give the dummy group a unique name */ 203 if (dummy_group_names[i] == NULL) { 204 dummy_group_names[i] = OPENSSL_zalloc(dummy_name_max_size); 205 if (dummy_group_names[i] == NULL) 206 return 0; 207 BIO_snprintf(dummy_group_names[i], 208 dummy_name_max_size, 209 "%s%d", dummy_base, i); 210 } 211 dummygroup[0].data = dummy_group_names[i]; 212 dummygroup[0].data_size = strlen(dummy_group_names[i]) + 1; 213 ret &= cb(dummygroup, arg); 214 } 215 216 return ret; 217 } 218 219 /* 220 * Dummy "XOR" Key Exchange algorithm. We just xor the private and public keys 221 * together. Don't use this! 222 */ 223 224 typedef struct { 225 XORKEY *key; 226 XORKEY *peerkey; 227 void *provctx; 228 } PROV_XOR_CTX; 229 230 static void *xor_newctx(void *provctx) 231 { 232 PROV_XOR_CTX *pxorctx = OPENSSL_zalloc(sizeof(PROV_XOR_CTX)); 233 234 if (pxorctx == NULL) 235 return NULL; 236 237 pxorctx->provctx = provctx; 238 239 return pxorctx; 240 } 241 242 static int xor_init(void *vpxorctx, void *vkey, 243 ossl_unused const OSSL_PARAM params[]) 244 { 245 PROV_XOR_CTX *pxorctx = (PROV_XOR_CTX *)vpxorctx; 246 247 if (pxorctx == NULL || vkey == NULL) 248 return 0; 249 pxorctx->key = vkey; 250 return 1; 251 } 252 253 static int xor_set_peer(void *vpxorctx, void *vpeerkey) 254 { 255 PROV_XOR_CTX *pxorctx = (PROV_XOR_CTX *)vpxorctx; 256 257 if (pxorctx == NULL || vpeerkey == NULL) 258 return 0; 259 pxorctx->peerkey = vpeerkey; 260 return 1; 261 } 262 263 static int xor_derive(void *vpxorctx, unsigned char *secret, size_t *secretlen, 264 size_t outlen) 265 { 266 PROV_XOR_CTX *pxorctx = (PROV_XOR_CTX *)vpxorctx; 267 int i; 268 269 if (pxorctx->key == NULL || pxorctx->peerkey == NULL) 270 return 0; 271 272 *secretlen = XOR_KEY_SIZE; 273 if (secret == NULL) 274 return 1; 275 276 if (outlen < XOR_KEY_SIZE) 277 return 0; 278 279 for (i = 0; i < XOR_KEY_SIZE; i++) 280 secret[i] = pxorctx->key->privkey[i] ^ pxorctx->peerkey->pubkey[i]; 281 282 return 1; 283 } 284 285 static void xor_freectx(void *pxorctx) 286 { 287 OPENSSL_free(pxorctx); 288 } 289 290 static void *xor_dupctx(void *vpxorctx) 291 { 292 PROV_XOR_CTX *srcctx = (PROV_XOR_CTX *)vpxorctx; 293 PROV_XOR_CTX *dstctx; 294 295 dstctx = OPENSSL_zalloc(sizeof(*srcctx)); 296 if (dstctx == NULL) 297 return NULL; 298 299 *dstctx = *srcctx; 300 301 return dstctx; 302 } 303 304 static const OSSL_DISPATCH xor_keyexch_functions[] = { 305 { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))xor_newctx }, 306 { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))xor_init }, 307 { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))xor_derive }, 308 { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))xor_set_peer }, 309 { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))xor_freectx }, 310 { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))xor_dupctx }, 311 { 0, NULL } 312 }; 313 314 static const OSSL_ALGORITHM tls_prov_keyexch[] = { 315 /* 316 * Obviously this is not FIPS approved, but in order to test in conjuction 317 * with the FIPS provider we pretend that it is. 318 */ 319 { "XOR", "provider=tls-provider,fips=yes", xor_keyexch_functions }, 320 { NULL, NULL, NULL } 321 }; 322 323 /* 324 * Dummy "XOR" Key Encapsulation Method. We just build a KEM over the xor KEX. 325 * Don't use this! 326 */ 327 328 static int xor_encapsulate(void *vpxorctx, 329 unsigned char *ct, size_t *ctlen, 330 unsigned char *ss, size_t *sslen) 331 { 332 /* 333 * We are building this around a KEX: 334 * 335 * 1. we generate ephemeral keypair 336 * 2. we encode our ephemeral pubkey as the outgoing ct 337 * 3. we derive using our ephemeral privkey in combination with the peer 338 * pubkey from the ctx; the result is our ss. 339 */ 340 int rv = 0; 341 void *genctx = NULL, *derivectx = NULL; 342 XORKEY *ourkey = NULL; 343 PROV_XOR_CTX *pxorctx = vpxorctx; 344 345 if (ct == NULL || ss == NULL) { 346 /* Just return sizes */ 347 348 if (ctlen == NULL && sslen == NULL) 349 return 0; 350 if (ctlen != NULL) 351 *ctlen = XOR_KEY_SIZE; 352 if (sslen != NULL) 353 *sslen = XOR_KEY_SIZE; 354 return 1; 355 } 356 357 /* 1. Generate keypair */ 358 genctx = xor_gen_init(pxorctx->provctx, OSSL_KEYMGMT_SELECT_KEYPAIR, NULL); 359 if (genctx == NULL) 360 goto end; 361 ourkey = xor_gen(genctx, NULL, NULL); 362 if (ourkey == NULL) 363 goto end; 364 365 /* 2. Encode ephemeral pubkey as ct */ 366 memcpy(ct, ourkey->pubkey, XOR_KEY_SIZE); 367 *ctlen = XOR_KEY_SIZE; 368 369 /* 3. Derive ss via KEX */ 370 derivectx = xor_newctx(pxorctx->provctx); 371 if (derivectx == NULL 372 || !xor_init(derivectx, ourkey, NULL) 373 || !xor_set_peer(derivectx, pxorctx->key) 374 || !xor_derive(derivectx, ss, sslen, XOR_KEY_SIZE)) 375 goto end; 376 377 rv = 1; 378 379 end: 380 xor_gen_cleanup(genctx); 381 xor_freedata(ourkey); 382 xor_freectx(derivectx); 383 return rv; 384 } 385 386 static int xor_decapsulate(void *vpxorctx, 387 unsigned char *ss, size_t *sslen, 388 const unsigned char *ct, size_t ctlen) 389 { 390 /* 391 * We are building this around a KEX: 392 * 393 * - ct is our peer's pubkey 394 * - decapsulate is just derive. 395 */ 396 int rv = 0; 397 void *derivectx = NULL; 398 XORKEY *peerkey = NULL; 399 PROV_XOR_CTX *pxorctx = vpxorctx; 400 401 if (ss == NULL) { 402 /* Just return size */ 403 if (sslen == NULL) 404 return 0; 405 *sslen = XOR_KEY_SIZE; 406 return 1; 407 } 408 409 if (ctlen != XOR_KEY_SIZE) 410 return 0; 411 peerkey = xor_newdata(pxorctx->provctx); 412 if (peerkey == NULL) 413 goto end; 414 memcpy(peerkey->pubkey, ct, XOR_KEY_SIZE); 415 416 /* Derive ss via KEX */ 417 derivectx = xor_newctx(pxorctx->provctx); 418 if (derivectx == NULL 419 || !xor_init(derivectx, pxorctx->key, NULL) 420 || !xor_set_peer(derivectx, peerkey) 421 || !xor_derive(derivectx, ss, sslen, XOR_KEY_SIZE)) 422 goto end; 423 424 rv = 1; 425 426 end: 427 xor_freedata(peerkey); 428 xor_freectx(derivectx); 429 return rv; 430 } 431 432 static const OSSL_DISPATCH xor_kem_functions[] = { 433 { OSSL_FUNC_KEM_NEWCTX, (void (*)(void))xor_newctx }, 434 { OSSL_FUNC_KEM_FREECTX, (void (*)(void))xor_freectx }, 435 { OSSL_FUNC_KEM_DUPCTX, (void (*)(void))xor_dupctx }, 436 { OSSL_FUNC_KEM_ENCAPSULATE_INIT, (void (*)(void))xor_init }, 437 { OSSL_FUNC_KEM_ENCAPSULATE, (void (*)(void))xor_encapsulate }, 438 { OSSL_FUNC_KEM_DECAPSULATE_INIT, (void (*)(void))xor_init }, 439 { OSSL_FUNC_KEM_DECAPSULATE, (void (*)(void))xor_decapsulate }, 440 { 0, NULL } 441 }; 442 443 static const OSSL_ALGORITHM tls_prov_kem[] = { 444 /* 445 * Obviously this is not FIPS approved, but in order to test in conjuction 446 * with the FIPS provider we pretend that it is. 447 */ 448 { "XOR", "provider=tls-provider,fips=yes", xor_kem_functions }, 449 { NULL, NULL, NULL } 450 }; 451 452 /* Key Management for the dummy XOR key exchange algorithm */ 453 454 static void *xor_newdata(void *provctx) 455 { 456 return OPENSSL_zalloc(sizeof(XORKEY)); 457 } 458 459 static void xor_freedata(void *keydata) 460 { 461 OPENSSL_free(keydata); 462 } 463 464 static int xor_has(const void *vkey, int selection) 465 { 466 const XORKEY *key = vkey; 467 int ok = 0; 468 469 if (key != NULL) { 470 ok = 1; 471 472 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) 473 ok = ok && key->haspubkey; 474 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 475 ok = ok && key->hasprivkey; 476 } 477 return ok; 478 } 479 480 static void *xor_dup(const void *vfromkey, int selection) 481 { 482 XORKEY *tokey = xor_newdata(NULL); 483 const XORKEY *fromkey = vfromkey; 484 int ok = 0; 485 486 if (tokey != NULL && fromkey != NULL) { 487 ok = 1; 488 489 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 490 if (fromkey->haspubkey) { 491 memcpy(tokey->pubkey, fromkey->pubkey, XOR_KEY_SIZE); 492 tokey->haspubkey = 1; 493 } else { 494 tokey->haspubkey = 0; 495 } 496 } 497 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 498 if (fromkey->hasprivkey) { 499 memcpy(tokey->privkey, fromkey->privkey, XOR_KEY_SIZE); 500 tokey->hasprivkey = 1; 501 } else { 502 tokey->hasprivkey = 0; 503 } 504 } 505 } 506 if (!ok) { 507 xor_freedata(tokey); 508 tokey = NULL; 509 } 510 return tokey; 511 } 512 513 static ossl_inline int xor_get_params(void *vkey, OSSL_PARAM params[]) 514 { 515 XORKEY *key = vkey; 516 OSSL_PARAM *p; 517 518 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL 519 && !OSSL_PARAM_set_int(p, XOR_KEY_SIZE)) 520 return 0; 521 522 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL 523 && !OSSL_PARAM_set_int(p, xor_group.secbits)) 524 return 0; 525 526 if ((p = OSSL_PARAM_locate(params, 527 OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL) { 528 if (p->data_type != OSSL_PARAM_OCTET_STRING) 529 return 0; 530 p->return_size = XOR_KEY_SIZE; 531 if (p->data != NULL && p->data_size >= XOR_KEY_SIZE) 532 memcpy(p->data, key->pubkey, XOR_KEY_SIZE); 533 } 534 535 return 1; 536 } 537 538 static const OSSL_PARAM xor_params[] = { 539 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), 540 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), 541 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), 542 OSSL_PARAM_END 543 }; 544 545 static const OSSL_PARAM *xor_gettable_params(void *provctx) 546 { 547 return xor_params; 548 } 549 550 static int xor_set_params(void *vkey, const OSSL_PARAM params[]) 551 { 552 XORKEY *key = vkey; 553 const OSSL_PARAM *p; 554 555 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY); 556 if (p != NULL) { 557 if (p->data_type != OSSL_PARAM_OCTET_STRING 558 || p->data_size != XOR_KEY_SIZE) 559 return 0; 560 memcpy(key->pubkey, p->data, XOR_KEY_SIZE); 561 key->haspubkey = 1; 562 } 563 564 return 1; 565 } 566 567 static const OSSL_PARAM xor_known_settable_params[] = { 568 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), 569 OSSL_PARAM_END 570 }; 571 572 static const OSSL_PARAM *xor_settable_params(void *provctx) 573 { 574 return xor_known_settable_params; 575 } 576 577 struct xor_gen_ctx { 578 int selection; 579 OSSL_LIB_CTX *libctx; 580 }; 581 582 static void *xor_gen_init(void *provctx, int selection, 583 const OSSL_PARAM params[]) 584 { 585 struct xor_gen_ctx *gctx = NULL; 586 587 if ((selection & (OSSL_KEYMGMT_SELECT_KEYPAIR 588 | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)) == 0) 589 return NULL; 590 591 if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) 592 gctx->selection = selection; 593 594 /* Our provctx is really just an OSSL_LIB_CTX */ 595 gctx->libctx = (OSSL_LIB_CTX *)provctx; 596 597 if (!xor_gen_set_params(gctx, params)) { 598 OPENSSL_free(gctx); 599 return NULL; 600 } 601 return gctx; 602 } 603 604 static int xor_gen_set_params(void *genctx, const OSSL_PARAM params[]) 605 { 606 struct xor_gen_ctx *gctx = genctx; 607 const OSSL_PARAM *p; 608 609 if (gctx == NULL) 610 return 0; 611 612 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); 613 if (p != NULL) { 614 if (p->data_type != OSSL_PARAM_UTF8_STRING 615 || (strcmp(p->data, XORGROUP_NAME_INTERNAL) != 0 616 && strcmp(p->data, XORKEMGROUP_NAME_INTERNAL) != 0)) 617 return 0; 618 } 619 620 return 1; 621 } 622 623 static const OSSL_PARAM *xor_gen_settable_params(ossl_unused void *genctx, 624 ossl_unused void *provctx) 625 { 626 static OSSL_PARAM settable[] = { 627 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), 628 OSSL_PARAM_END 629 }; 630 return settable; 631 } 632 633 static void *xor_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) 634 { 635 struct xor_gen_ctx *gctx = genctx; 636 XORKEY *key = OPENSSL_zalloc(sizeof(*key)); 637 size_t i; 638 639 if (key == NULL) 640 return NULL; 641 642 if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { 643 if (RAND_bytes_ex(gctx->libctx, key->privkey, XOR_KEY_SIZE, 0) <= 0) { 644 OPENSSL_free(key); 645 return NULL; 646 } 647 for (i = 0; i < XOR_KEY_SIZE; i++) 648 key->pubkey[i] = key->privkey[i] ^ private_constant[i]; 649 key->hasprivkey = 1; 650 key->haspubkey = 1; 651 } 652 653 return key; 654 } 655 656 /* IMPORT + EXPORT */ 657 658 static int xor_import(void *vkey, int select, const OSSL_PARAM params[]) 659 { 660 XORKEY *key = vkey; 661 const OSSL_PARAM *param_priv_key, *param_pub_key; 662 unsigned char privkey[XOR_KEY_SIZE]; 663 unsigned char pubkey[XOR_KEY_SIZE]; 664 void *pprivkey = privkey, *ppubkey = pubkey; 665 size_t priv_len = 0, pub_len = 0; 666 int res = 0; 667 668 if (key == NULL || (select & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) 669 return 0; 670 671 memset(privkey, 0, sizeof(privkey)); 672 memset(pubkey, 0, sizeof(pubkey)); 673 param_priv_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); 674 param_pub_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY); 675 676 if ((param_priv_key != NULL 677 && !OSSL_PARAM_get_octet_string(param_priv_key, &pprivkey, 678 sizeof(privkey), &priv_len)) 679 || (param_pub_key != NULL 680 && !OSSL_PARAM_get_octet_string(param_pub_key, &ppubkey, 681 sizeof(pubkey), &pub_len))) 682 goto err; 683 684 if (priv_len > 0) { 685 memcpy(key->privkey, privkey, priv_len); 686 key->hasprivkey = 1; 687 } 688 if (pub_len > 0) { 689 memcpy(key->pubkey, pubkey, pub_len); 690 key->haspubkey = 1; 691 } 692 res = 1; 693 err: 694 return res; 695 } 696 697 static int xor_export(void *vkey, int select, OSSL_CALLBACK *param_cb, 698 void *cbarg) 699 { 700 XORKEY *key = vkey; 701 OSSL_PARAM params[3], *p = params; 702 703 if (key == NULL || (select & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) 704 return 0; 705 706 *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, 707 key->privkey, 708 sizeof(key->privkey)); 709 *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY, 710 key->pubkey, sizeof(key->pubkey)); 711 *p++ = OSSL_PARAM_construct_end(); 712 713 return param_cb(params, cbarg); 714 } 715 716 static const OSSL_PARAM xor_key_types[] = { 717 OSSL_PARAM_BN(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), 718 OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), 719 OSSL_PARAM_END 720 }; 721 722 static const OSSL_PARAM *xor_import_types(int select) 723 { 724 return (select & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0 ? xor_key_types : NULL; 725 } 726 727 static const OSSL_PARAM *xor_export_types(int select) 728 { 729 return (select & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0 ? xor_key_types : NULL; 730 } 731 732 static void xor_gen_cleanup(void *genctx) 733 { 734 OPENSSL_free(genctx); 735 } 736 737 static const OSSL_DISPATCH xor_keymgmt_functions[] = { 738 { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))xor_newdata }, 739 { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))xor_gen_init }, 740 { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))xor_gen_set_params }, 741 { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, 742 (void (*)(void))xor_gen_settable_params }, 743 { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))xor_gen }, 744 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))xor_gen_cleanup }, 745 { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))xor_get_params }, 746 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))xor_gettable_params }, 747 { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))xor_set_params }, 748 { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))xor_settable_params }, 749 { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))xor_has }, 750 { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))xor_dup }, 751 { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))xor_freedata }, 752 { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))xor_import }, 753 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))xor_import_types }, 754 { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))xor_export }, 755 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))xor_export_types }, 756 { 0, NULL } 757 }; 758 759 static const OSSL_ALGORITHM tls_prov_keymgmt[] = { 760 /* 761 * Obviously this is not FIPS approved, but in order to test in conjuction 762 * with the FIPS provider we pretend that it is. 763 */ 764 { "XOR", "provider=tls-provider,fips=yes", xor_keymgmt_functions }, 765 { NULL, NULL, NULL } 766 }; 767 768 static const OSSL_ALGORITHM *tls_prov_query(void *provctx, int operation_id, 769 int *no_cache) 770 { 771 *no_cache = 0; 772 switch (operation_id) { 773 case OSSL_OP_KEYMGMT: 774 return tls_prov_keymgmt; 775 case OSSL_OP_KEYEXCH: 776 return tls_prov_keyexch; 777 case OSSL_OP_KEM: 778 return tls_prov_kem; 779 } 780 return NULL; 781 } 782 783 static void tls_prov_teardown(void *provctx) 784 { 785 int i; 786 787 OSSL_LIB_CTX_free(provctx); 788 789 for (i = 0; i < NUM_DUMMY_GROUPS; i++) { 790 OPENSSL_free(dummy_group_names[i]); 791 dummy_group_names[i] = NULL; 792 } 793 } 794 795 /* Functions we provide to the core */ 796 static const OSSL_DISPATCH tls_prov_dispatch_table[] = { 797 { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))tls_prov_teardown }, 798 { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))tls_prov_query }, 799 { OSSL_FUNC_PROVIDER_GET_CAPABILITIES, (void (*)(void))tls_prov_get_capabilities }, 800 { 0, NULL } 801 }; 802 803 static 804 unsigned int randomize_tls_group_id(OSSL_LIB_CTX *libctx) 805 { 806 /* 807 * Randomise the group_id we're going to use to ensure we don't interoperate 808 * with anything but ourselves. 809 */ 810 unsigned int group_id; 811 static unsigned int mem[10] = { 0 }; 812 static int in_mem = 0; 813 int i; 814 815 retry: 816 if (RAND_bytes_ex(libctx, (unsigned char *)&group_id, sizeof(group_id), 0) <= 0) 817 return 0; 818 /* 819 * Ensure group_id is within the IANA Reserved for private use range 820 * (65024-65279) 821 */ 822 group_id %= 65279 - 65024; 823 group_id += 65024; 824 825 /* Ensure we did not already issue this group_id */ 826 for (i = 0; i < in_mem; i++) 827 if (mem[i] == group_id) 828 goto retry; 829 830 /* Add this group_id to the list of ids issued by this function */ 831 mem[in_mem++] = group_id; 832 833 return group_id; 834 } 835 836 int tls_provider_init(const OSSL_CORE_HANDLE *handle, 837 const OSSL_DISPATCH *in, 838 const OSSL_DISPATCH **out, 839 void **provctx) 840 { 841 OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new(); 842 843 if (libctx == NULL) 844 return 0; 845 846 *provctx = libctx; 847 848 /* 849 * Randomise the group_id we're going to use to ensure we don't interoperate 850 * with anything but ourselves. 851 */ 852 xor_group.group_id = randomize_tls_group_id(libctx); 853 xor_kemgroup.group_id = randomize_tls_group_id(libctx); 854 855 *out = tls_prov_dispatch_table; 856 return 1; 857 } 858