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