Define OSSL_CAPABILITY_TLS_GROUP_IS_KEM
[openssl.git] / test / tls-provider.c
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>
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
18 int 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  */
31 static 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
37 typedef 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
44 /* We define a dummy TLS group called "xorgroup" for test purposes */
45 struct tls_group_st {
46     unsigned int group_id; /* for "tls-group-id", see provider-base(7) */
47     unsigned int secbits;
48     unsigned int mintls;
49     unsigned int maxtls;
50     unsigned int mindtls;
51     unsigned int maxdtls;
52     unsigned int is_kem; /* boolean */
53 };
54
55 #define XORGROUP_NAME "xorgroup"
56 #define XORGROUP_NAME_INTERNAL "xorgroup-int"
57 static struct tls_group_st xor_group = {
58     0,                  /* group_id, set by randomize_tls_group_id() */
59     128,                /* secbits */
60     TLS1_3_VERSION,     /* mintls */
61     0,                  /* maxtls */
62     -1,                 /* mindtls */
63     -1,                 /* maxdtls */
64     0                   /* is_kem */
65 };
66
67 #define XORKEMGROUP_NAME "xorkemgroup"
68 #define XORKEMGROUP_NAME_INTERNAL "xorkemgroup-int"
69 static struct tls_group_st xor_kemgroup = {
70     0,                  /* group_id, set by randomize_tls_group_id() */
71     128,                /* secbits */
72     TLS1_3_VERSION,     /* mintls */
73     0,                  /* maxtls */
74     -1,                 /* mindtls */
75     -1,                 /* maxdtls */
76     1                   /* is_kem */
77 };
78
79 #define ALGORITHM "XOR"
80
81 static const OSSL_PARAM xor_group_params[] = {
82     OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME,
83                            XORGROUP_NAME, sizeof(XORGROUP_NAME)),
84     OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL,
85                            XORGROUP_NAME_INTERNAL,
86                            sizeof(XORGROUP_NAME_INTERNAL)),
87     OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_ALG, ALGORITHM,
88                            sizeof(ALGORITHM)),
89     OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_ID, &xor_group.group_id),
90     OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS,
91                     &xor_group.secbits),
92     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_TLS, &xor_group.mintls),
93     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_TLS, &xor_group.maxtls),
94     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS, &xor_group.mindtls),
95     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS, &xor_group.maxdtls),
96     OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_IS_KEM, &xor_group.is_kem),
97     OSSL_PARAM_END
98 };
99
100 static const OSSL_PARAM xor_kemgroup_params[] = {
101     OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME,
102                            XORKEMGROUP_NAME, sizeof(XORKEMGROUP_NAME)),
103     OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL,
104                            XORKEMGROUP_NAME_INTERNAL,
105                            sizeof(XORKEMGROUP_NAME_INTERNAL)),
106     OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_ALG, ALGORITHM,
107                            sizeof(ALGORITHM)),
108     OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_ID, &xor_kemgroup.group_id),
109     OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS,
110                     &xor_kemgroup.secbits),
111     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_TLS, &xor_kemgroup.mintls),
112     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_TLS, &xor_kemgroup.maxtls),
113     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS, &xor_kemgroup.mindtls),
114     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS, &xor_kemgroup.maxdtls),
115     OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_IS_KEM, &xor_kemgroup.is_kem),
116     OSSL_PARAM_END
117 };
118
119
120 static int tls_prov_get_capabilities(void *provctx, const char *capability,
121                                      OSSL_CALLBACK *cb, void *arg)
122 {
123     if (strcmp(capability, "TLS-GROUP") == 0)
124         return cb(xor_group_params, arg)
125             && cb(xor_kemgroup_params, arg);
126
127     /* We don't support this capability */
128     return 0;
129 }
130
131 /*
132  * Dummy "XOR" Key Exchange algorithm. We just xor the private and public keys
133  * together. Don't use this!
134  */
135
136 static OSSL_FUNC_keyexch_newctx_fn xor_newctx;
137 static OSSL_FUNC_keyexch_init_fn xor_init;
138 static OSSL_FUNC_keyexch_set_peer_fn xor_set_peer;
139 static OSSL_FUNC_keyexch_derive_fn xor_derive;
140 static OSSL_FUNC_keyexch_freectx_fn xor_freectx;
141 static OSSL_FUNC_keyexch_dupctx_fn xor_dupctx;
142
143 typedef struct {
144     XORKEY *key;
145     XORKEY *peerkey;
146 } PROV_XOR_CTX;
147
148 static void *xor_newctx(void *provctx)
149 {
150     PROV_XOR_CTX *pxorctx = OPENSSL_zalloc(sizeof(PROV_XOR_CTX));
151
152     if (pxorctx == NULL)
153         return NULL;
154
155     return pxorctx;
156 }
157
158 static int xor_init(void *vpxorctx, void *vkey)
159 {
160     PROV_XOR_CTX *pxorctx = (PROV_XOR_CTX *)vpxorctx;
161
162     if (pxorctx == NULL || vkey == NULL)
163         return 0;
164     pxorctx->key = vkey;
165     return 1;
166 }
167
168 static int xor_set_peer(void *vpxorctx, void *vpeerkey)
169 {
170     PROV_XOR_CTX *pxorctx = (PROV_XOR_CTX *)vpxorctx;
171
172     if (pxorctx == NULL || vpeerkey == NULL)
173         return 0;
174     pxorctx->peerkey = vpeerkey;
175     return 1;
176 }
177
178 static int xor_derive(void *vpxorctx, unsigned char *secret, size_t *secretlen,
179                       size_t outlen)
180 {
181     PROV_XOR_CTX *pxorctx = (PROV_XOR_CTX *)vpxorctx;
182     int i;
183
184     if (pxorctx->key == NULL || pxorctx->peerkey == NULL)
185         return 0;
186
187     *secretlen = XOR_KEY_SIZE;
188     if (secret == NULL)
189         return 1;
190
191     if (outlen < XOR_KEY_SIZE)
192         return 0;
193
194     for (i = 0; i < XOR_KEY_SIZE; i++)
195         secret[i] = pxorctx->key->privkey[i] ^ pxorctx->peerkey->pubkey[i];
196
197     return 1;
198 }
199
200 static void xor_freectx(void *pxorctx)
201 {
202     OPENSSL_free(pxorctx);
203 }
204
205 static void *xor_dupctx(void *vpxorctx)
206 {
207     PROV_XOR_CTX *srcctx = (PROV_XOR_CTX *)vpxorctx;
208     PROV_XOR_CTX *dstctx;
209
210     dstctx = OPENSSL_zalloc(sizeof(*srcctx));
211     if (dstctx == NULL)
212         return NULL;
213
214     *dstctx = *srcctx;
215
216     return dstctx;
217 }
218
219 static const OSSL_DISPATCH xor_keyexch_functions[] = {
220     { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))xor_newctx },
221     { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))xor_init },
222     { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))xor_derive },
223     { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))xor_set_peer },
224     { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))xor_freectx },
225     { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))xor_dupctx },
226     { 0, NULL }
227 };
228
229 static const OSSL_ALGORITHM tls_prov_keyexch[] = {
230     /*
231      * Obviously this is not FIPS approved, but in order to test in conjuction
232      * with the FIPS provider we pretend that it is.
233      */
234     { "XOR", "provider=tls-provider,fips=yes", xor_keyexch_functions },
235     { NULL, NULL, NULL }
236 };
237
238 /* Key Management for the dummy XOR key exchange algorithm */
239
240 static OSSL_FUNC_keymgmt_new_fn xor_newdata;
241 static OSSL_FUNC_keymgmt_free_fn xor_freedata;
242 static OSSL_FUNC_keymgmt_has_fn xor_has;
243 static OSSL_FUNC_keymgmt_copy_fn xor_copy;
244 static OSSL_FUNC_keymgmt_gen_init_fn xor_gen_init;
245 static OSSL_FUNC_keymgmt_gen_set_params_fn xor_gen_set_params;
246 static OSSL_FUNC_keymgmt_gen_settable_params_fn xor_gen_settable_params;
247 static OSSL_FUNC_keymgmt_gen_fn xor_gen;
248 static OSSL_FUNC_keymgmt_gen_cleanup_fn xor_gen_cleanup;
249 static OSSL_FUNC_keymgmt_get_params_fn xor_get_params;
250 static OSSL_FUNC_keymgmt_gettable_params_fn xor_gettable_params;
251 static OSSL_FUNC_keymgmt_set_params_fn xor_set_params;
252 static OSSL_FUNC_keymgmt_settable_params_fn xor_settable_params;
253
254 static void *xor_newdata(void *provctx)
255 {
256     return OPENSSL_zalloc(sizeof(XORKEY));
257 }
258
259 static void xor_freedata(void *keydata)
260 {
261     OPENSSL_free(keydata);
262 }
263
264 static int xor_has(void *vkey, int selection)
265 {
266     XORKEY *key = vkey;
267     int ok = 0;
268
269     if (key != NULL) {
270         ok = 1;
271
272         if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
273             ok = ok && key->haspubkey;
274         if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
275             ok = ok && key->hasprivkey;
276     }
277     return ok;
278 }
279
280 static int xor_copy(void *vtokey, const void *vfromkey, int selection)
281 {
282     XORKEY *tokey = vtokey;
283     const XORKEY *fromkey = vfromkey;
284     int ok = 0;
285
286     if (tokey != NULL && fromkey != NULL) {
287         ok = 1;
288
289         if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
290             if (fromkey->haspubkey) {
291                 memcpy(tokey->pubkey, fromkey->pubkey, XOR_KEY_SIZE);
292                 tokey->haspubkey = 1;
293             } else {
294                 tokey->haspubkey = 0;
295             }
296         }
297         if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
298             if (fromkey->hasprivkey) {
299                 memcpy(tokey->privkey, fromkey->privkey, XOR_KEY_SIZE);
300                 tokey->hasprivkey = 1;
301             } else {
302                 tokey->hasprivkey = 0;
303             }
304         }
305     }
306     return ok;
307 }
308
309 static ossl_inline int xor_get_params(void *vkey, OSSL_PARAM params[])
310 {
311     XORKEY *key = vkey;
312     OSSL_PARAM *p;
313
314     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
315         && !OSSL_PARAM_set_int(p, XOR_KEY_SIZE))
316         return 0;
317
318     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
319         && !OSSL_PARAM_set_int(p, xor_group.secbits))
320         return 0;
321
322     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT)) != NULL) {
323         if (p->data_type != OSSL_PARAM_OCTET_STRING)
324             return 0;
325         p->return_size = XOR_KEY_SIZE;
326         if (p->data != NULL && p->data_size >= XOR_KEY_SIZE)
327             memcpy(p->data, key->pubkey, XOR_KEY_SIZE);
328     }
329
330     return 1;
331 }
332
333 static const OSSL_PARAM xor_params[] = {
334     OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
335     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
336     OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
337     OSSL_PARAM_END
338 };
339
340 static const OSSL_PARAM *xor_gettable_params(void *provctx)
341 {
342     return xor_params;
343 }
344
345 static int xor_set_params(void *vkey, const OSSL_PARAM params[])
346 {
347     XORKEY *key = vkey;
348     const OSSL_PARAM *p;
349
350     p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT);
351     if (p != NULL) {
352         if (p->data_type != OSSL_PARAM_OCTET_STRING
353                 || p->data_size != XOR_KEY_SIZE)
354             return 0;
355         memcpy(key->pubkey, p->data, XOR_KEY_SIZE);
356         key->haspubkey = 1;
357     }
358
359     return 1;
360 }
361
362 static const OSSL_PARAM xor_known_settable_params[] = {
363     OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
364     OSSL_PARAM_END
365 };
366
367 static const OSSL_PARAM *xor_settable_params(void *provctx)
368 {
369     return xor_known_settable_params;
370 }
371
372 struct xor_gen_ctx {
373     int selection;
374     OPENSSL_CTX *libctx;
375 };
376
377 static void *xor_gen_init(void *provctx, int selection)
378 {
379     struct xor_gen_ctx *gctx = NULL;
380
381     if ((selection & (OSSL_KEYMGMT_SELECT_KEYPAIR
382                       | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)) == 0)
383         return NULL;
384
385     if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL)
386         gctx->selection = selection;
387
388     /* Our provctx is really just an OPENSSL_CTX */
389     gctx->libctx = (OPENSSL_CTX *)provctx;
390
391     return gctx;
392 }
393
394 static int xor_gen_set_params(void *genctx, const OSSL_PARAM params[])
395 {
396     struct xor_gen_ctx *gctx = genctx;
397     const OSSL_PARAM *p;
398
399     if (gctx == NULL)
400         return 0;
401
402     p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME);
403     if (p != NULL) {
404         if (p->data_type != OSSL_PARAM_UTF8_STRING
405                 || (strcmp(p->data, XORGROUP_NAME_INTERNAL) != 0
406                     &&  strcmp(p->data, XORKEMGROUP_NAME_INTERNAL) != 0))
407             return 0;
408     }
409
410     return 1;
411 }
412
413 static const OSSL_PARAM *xor_gen_settable_params(void *provctx)
414 {
415     static OSSL_PARAM settable[] = {
416         OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
417         OSSL_PARAM_END
418     };
419     return settable;
420 }
421
422 static void *xor_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
423 {
424     struct xor_gen_ctx *gctx = genctx;
425     XORKEY *key = OPENSSL_zalloc(sizeof(*key));
426     size_t i;
427
428     if (key == NULL)
429         return NULL;
430
431     if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
432         if (RAND_bytes_ex(gctx->libctx, key->privkey, XOR_KEY_SIZE) <= 0) {
433             OPENSSL_free(key);
434             return NULL;
435         }
436         for (i = 0; i < XOR_KEY_SIZE; i++)
437             key->pubkey[i] = key->privkey[i] ^ private_constant[i];
438         key->hasprivkey = 1;
439         key->haspubkey = 1;
440     }
441
442     return key;
443 }
444
445 static void xor_gen_cleanup(void *genctx)
446 {
447     OPENSSL_free(genctx);
448 }
449
450 static const OSSL_DISPATCH xor_keymgmt_functions[] = {
451     { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))xor_newdata },
452     { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))xor_gen_init },
453     { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))xor_gen_set_params },
454     { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,
455       (void (*)(void))xor_gen_settable_params },
456     { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))xor_gen },
457     { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))xor_gen_cleanup },
458     { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))xor_get_params },
459     { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))xor_gettable_params },
460     { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))xor_set_params },
461     { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))xor_settable_params },
462     { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))xor_has },
463     { OSSL_FUNC_KEYMGMT_COPY, (void (*)(void))xor_copy },
464     { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))xor_freedata },
465     { 0, NULL }
466 };
467
468 static const OSSL_ALGORITHM tls_prov_keymgmt[] = {
469     /*
470      * Obviously this is not FIPS approved, but in order to test in conjuction
471      * with the FIPS provider we pretend that it is.
472      */
473     { "XOR", "provider=tls-provider,fips=yes", xor_keymgmt_functions },
474     { NULL, NULL, NULL }
475 };
476
477 static const OSSL_ALGORITHM *tls_prov_query(void *provctx, int operation_id,
478                                             int *no_cache)
479 {
480     *no_cache = 0;
481     switch (operation_id) {
482     case OSSL_OP_KEYMGMT:
483         return tls_prov_keymgmt;
484     case OSSL_OP_KEYEXCH:
485         return tls_prov_keyexch;
486     }
487     return NULL;
488 }
489
490 /* Functions we provide to the core */
491 static const OSSL_DISPATCH tls_prov_dispatch_table[] = {
492     { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))OPENSSL_CTX_free },
493     { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))tls_prov_query },
494     { OSSL_FUNC_PROVIDER_GET_CAPABILITIES, (void (*)(void))tls_prov_get_capabilities },
495     { 0, NULL }
496 };
497
498 static
499 unsigned int randomize_tls_group_id(OPENSSL_CTX *libctx)
500 {
501     /*
502      * Randomise the group_id we're going to use to ensure we don't interoperate
503      * with anything but ourselves.
504      */
505     unsigned int group_id;
506     static unsigned int mem[10] = { 0 };
507     static int in_mem = 0;
508     int i;
509
510  retry:
511     if (!RAND_bytes_ex(libctx, (unsigned char *)&group_id, sizeof(group_id)))
512         return 0;
513     /*
514      * Ensure group_id is within the IANA Reserved for private use range
515      * (65024-65279)
516      */
517     group_id %= 65279 - 65024;
518     group_id += 65024;
519
520     /* Ensure we did not already issue this group_id */
521     for (i = 0; i < in_mem; i++)
522         if (mem[i] == group_id)
523             goto retry;
524
525     /* Add this group_id to the list of ids issued by this function */
526     mem[in_mem++] = group_id;
527
528     return group_id;
529 }
530
531 int tls_provider_init(const OSSL_CORE_HANDLE *handle,
532                       const OSSL_DISPATCH *in,
533                       const OSSL_DISPATCH **out,
534                       void **provctx)
535 {
536     OPENSSL_CTX *libctx = OPENSSL_CTX_new();
537
538     *provctx = libctx;
539
540     /*
541      * Randomise the group_id we're going to use to ensure we don't interoperate
542      * with anything but ourselves.
543      */
544     xor_group.group_id = randomize_tls_group_id(libctx);
545     xor_kemgroup.group_id = randomize_tls_group_id(libctx);
546
547     *out = tls_prov_dispatch_table;
548     return 1;
549 }