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