1 /*
2  * Copyright 2020-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 <assert.h>
11 #include <string.h>
12 /* For strcasecmp on Windows */
13 #include "e_os.h"
14 #include <openssl/core_dispatch.h>
15 #include <openssl/core_names.h>
16 #include <openssl/params.h>
17 #include <openssl/err.h>
18 #include <openssl/proverr.h>
19 #include <openssl/evp.h>
20 #include <openssl/rand.h>
21 #include "internal/param_build_set.h"
22 #include <openssl/param_build.h>
23 #include "crypto/ecx.h"
24 #include "prov/implementations.h"
25 #include "prov/providercommon.h"
26 #include "prov/provider_ctx.h"
27 #ifdef S390X_EC_ASM
28 # include "s390x_arch.h"
29 # include <openssl/sha.h>   /* For SHA512_DIGEST_LENGTH */
30 #endif
31 
32 static OSSL_FUNC_keymgmt_new_fn x25519_new_key;
33 static OSSL_FUNC_keymgmt_new_fn x448_new_key;
34 static OSSL_FUNC_keymgmt_new_fn ed25519_new_key;
35 static OSSL_FUNC_keymgmt_new_fn ed448_new_key;
36 static OSSL_FUNC_keymgmt_gen_init_fn x25519_gen_init;
37 static OSSL_FUNC_keymgmt_gen_init_fn x448_gen_init;
38 static OSSL_FUNC_keymgmt_gen_init_fn ed25519_gen_init;
39 static OSSL_FUNC_keymgmt_gen_init_fn ed448_gen_init;
40 static OSSL_FUNC_keymgmt_gen_fn x25519_gen;
41 static OSSL_FUNC_keymgmt_gen_fn x448_gen;
42 static OSSL_FUNC_keymgmt_gen_fn ed25519_gen;
43 static OSSL_FUNC_keymgmt_gen_fn ed448_gen;
44 static OSSL_FUNC_keymgmt_gen_cleanup_fn ecx_gen_cleanup;
45 static OSSL_FUNC_keymgmt_gen_set_params_fn ecx_gen_set_params;
46 static OSSL_FUNC_keymgmt_gen_settable_params_fn ecx_gen_settable_params;
47 static OSSL_FUNC_keymgmt_load_fn ecx_load;
48 static OSSL_FUNC_keymgmt_get_params_fn x25519_get_params;
49 static OSSL_FUNC_keymgmt_get_params_fn x448_get_params;
50 static OSSL_FUNC_keymgmt_get_params_fn ed25519_get_params;
51 static OSSL_FUNC_keymgmt_get_params_fn ed448_get_params;
52 static OSSL_FUNC_keymgmt_gettable_params_fn x25519_gettable_params;
53 static OSSL_FUNC_keymgmt_gettable_params_fn x448_gettable_params;
54 static OSSL_FUNC_keymgmt_gettable_params_fn ed25519_gettable_params;
55 static OSSL_FUNC_keymgmt_gettable_params_fn ed448_gettable_params;
56 static OSSL_FUNC_keymgmt_set_params_fn x25519_set_params;
57 static OSSL_FUNC_keymgmt_set_params_fn x448_set_params;
58 static OSSL_FUNC_keymgmt_set_params_fn ed25519_set_params;
59 static OSSL_FUNC_keymgmt_set_params_fn ed448_set_params;
60 static OSSL_FUNC_keymgmt_settable_params_fn x25519_settable_params;
61 static OSSL_FUNC_keymgmt_settable_params_fn x448_settable_params;
62 static OSSL_FUNC_keymgmt_settable_params_fn ed25519_settable_params;
63 static OSSL_FUNC_keymgmt_settable_params_fn ed448_settable_params;
64 static OSSL_FUNC_keymgmt_has_fn ecx_has;
65 static OSSL_FUNC_keymgmt_match_fn ecx_match;
66 static OSSL_FUNC_keymgmt_validate_fn x25519_validate;
67 static OSSL_FUNC_keymgmt_validate_fn x448_validate;
68 static OSSL_FUNC_keymgmt_validate_fn ed25519_validate;
69 static OSSL_FUNC_keymgmt_validate_fn ed448_validate;
70 static OSSL_FUNC_keymgmt_import_fn ecx_import;
71 static OSSL_FUNC_keymgmt_import_types_fn ecx_imexport_types;
72 static OSSL_FUNC_keymgmt_export_fn ecx_export;
73 static OSSL_FUNC_keymgmt_export_types_fn ecx_imexport_types;
74 static OSSL_FUNC_keymgmt_dup_fn ecx_dup;
75 
76 #define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR)
77 
78 struct ecx_gen_ctx {
79     OSSL_LIB_CTX *libctx;
80     char *propq;
81     ECX_KEY_TYPE type;
82     int selection;
83 };
84 
85 #ifdef S390X_EC_ASM
86 static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx);
87 static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx);
88 static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx);
89 static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx);
90 #endif
91 
x25519_new_key(void * provctx)92 static void *x25519_new_key(void *provctx)
93 {
94     if (!ossl_prov_is_running())
95         return 0;
96     return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_X25519, 0,
97                             NULL);
98 }
99 
x448_new_key(void * provctx)100 static void *x448_new_key(void *provctx)
101 {
102     if (!ossl_prov_is_running())
103         return 0;
104     return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_X448, 0,
105                             NULL);
106 }
107 
ed25519_new_key(void * provctx)108 static void *ed25519_new_key(void *provctx)
109 {
110     if (!ossl_prov_is_running())
111         return 0;
112     return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_ED25519, 0,
113                             NULL);
114 }
115 
ed448_new_key(void * provctx)116 static void *ed448_new_key(void *provctx)
117 {
118     if (!ossl_prov_is_running())
119         return 0;
120     return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_ED448, 0,
121                             NULL);
122 }
123 
ecx_has(const void * keydata,int selection)124 static int ecx_has(const void *keydata, int selection)
125 {
126     const ECX_KEY *key = keydata;
127     int ok = 0;
128 
129     if (ossl_prov_is_running() && key != NULL) {
130         /*
131          * ECX keys always have all the parameters they need (i.e. none).
132          * Therefore we always return with 1, if asked about parameters.
133          */
134         ok = 1;
135 
136         if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
137             ok = ok && key->haspubkey;
138 
139         if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
140             ok = ok && key->privkey != NULL;
141     }
142     return ok;
143 }
144 
ecx_match(const void * keydata1,const void * keydata2,int selection)145 static int ecx_match(const void *keydata1, const void *keydata2, int selection)
146 {
147     const ECX_KEY *key1 = keydata1;
148     const ECX_KEY *key2 = keydata2;
149     int ok = 1;
150 
151     if (!ossl_prov_is_running())
152         return 0;
153 
154     if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
155         ok = ok && key1->type == key2->type;
156     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
157         int key_checked = 0;
158 
159         if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
160             const unsigned char *pa = key1->haspubkey ? key1->pubkey : NULL;
161             const unsigned char *pb = key2->haspubkey ? key2->pubkey : NULL;
162             size_t pal = key1->keylen;
163             size_t pbl = key2->keylen;
164 
165             if (pa != NULL && pb != NULL) {
166                 ok = ok
167                     && key1->type == key2->type
168                     && pal == pbl
169                     && CRYPTO_memcmp(pa, pb, pal) == 0;
170                 key_checked = 1;
171             }
172         }
173         if (!key_checked
174             && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
175             const unsigned char *pa = key1->privkey;
176             const unsigned char *pb = key2->privkey;
177             size_t pal = key1->keylen;
178             size_t pbl = key2->keylen;
179 
180             if (pa != NULL && pb != NULL) {
181                 ok = ok
182                     && key1->type == key2->type
183                     && pal == pbl
184                     && CRYPTO_memcmp(pa, pb, pal) == 0;
185                 key_checked = 1;
186             }
187         }
188         ok = ok && key_checked;
189     }
190     return ok;
191 }
192 
ecx_import(void * keydata,int selection,const OSSL_PARAM params[])193 static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[])
194 {
195     ECX_KEY *key = keydata;
196     int ok = 1;
197     int include_private;
198 
199     if (!ossl_prov_is_running() || key == NULL)
200         return 0;
201 
202     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
203         return 0;
204 
205     include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
206     ok = ok && ossl_ecx_key_fromdata(key, params, include_private);
207 
208     return ok;
209 }
210 
key_to_params(ECX_KEY * key,OSSL_PARAM_BLD * tmpl,OSSL_PARAM params[],int include_private)211 static int key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl,
212                          OSSL_PARAM params[], int include_private)
213 {
214     if (key == NULL)
215         return 0;
216 
217     if (!ossl_param_build_set_octet_string(tmpl, params,
218                                            OSSL_PKEY_PARAM_PUB_KEY,
219                                            key->pubkey, key->keylen))
220         return 0;
221 
222     if (include_private
223         && key->privkey != NULL
224         && !ossl_param_build_set_octet_string(tmpl, params,
225                                               OSSL_PKEY_PARAM_PRIV_KEY,
226                                               key->privkey, key->keylen))
227         return 0;
228 
229     return 1;
230 }
231 
ecx_export(void * keydata,int selection,OSSL_CALLBACK * param_cb,void * cbarg)232 static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
233                       void *cbarg)
234 {
235     ECX_KEY *key = keydata;
236     OSSL_PARAM_BLD *tmpl;
237     OSSL_PARAM *params = NULL;
238     int ret = 0;
239 
240     if (!ossl_prov_is_running() || key == NULL)
241         return 0;
242 
243     tmpl = OSSL_PARAM_BLD_new();
244     if (tmpl == NULL)
245         return 0;
246 
247     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
248         int include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
249 
250         if (!key_to_params(key, tmpl, NULL, include_private))
251             goto err;
252     }
253 
254     params = OSSL_PARAM_BLD_to_param(tmpl);
255     if (params == NULL)
256         goto err;
257 
258     ret = param_cb(params, cbarg);
259     OSSL_PARAM_free(params);
260 err:
261     OSSL_PARAM_BLD_free(tmpl);
262     return ret;
263 }
264 
265 #define ECX_KEY_TYPES()                                                        \
266 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0),                     \
267 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
268 
269 static const OSSL_PARAM ecx_key_types[] = {
270     ECX_KEY_TYPES(),
271     OSSL_PARAM_END
272 };
ecx_imexport_types(int selection)273 static const OSSL_PARAM *ecx_imexport_types(int selection)
274 {
275     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
276         return ecx_key_types;
277     return NULL;
278 }
279 
ecx_get_params(void * key,OSSL_PARAM params[],int bits,int secbits,int size)280 static int ecx_get_params(void *key, OSSL_PARAM params[], int bits, int secbits,
281                           int size)
282 {
283     ECX_KEY *ecx = key;
284     OSSL_PARAM *p;
285 
286     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
287         && !OSSL_PARAM_set_int(p, bits))
288         return 0;
289     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
290         && !OSSL_PARAM_set_int(p, secbits))
291         return 0;
292     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
293         && !OSSL_PARAM_set_int(p, size))
294         return 0;
295     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL
296             && (ecx->type == ECX_KEY_TYPE_X25519
297                 || ecx->type == ECX_KEY_TYPE_X448)) {
298         if (!OSSL_PARAM_set_octet_string(p, ecx->pubkey, ecx->keylen))
299             return 0;
300     }
301 
302     return key_to_params(ecx, NULL, params, 1);
303 }
304 
ed_get_params(void * key,OSSL_PARAM params[])305 static int ed_get_params(void *key, OSSL_PARAM params[])
306 {
307     OSSL_PARAM *p;
308 
309     if ((p = OSSL_PARAM_locate(params,
310                                OSSL_PKEY_PARAM_MANDATORY_DIGEST)) != NULL
311         && !OSSL_PARAM_set_utf8_string(p, ""))
312         return 0;
313     return 1;
314 }
315 
x25519_get_params(void * key,OSSL_PARAM params[])316 static int x25519_get_params(void *key, OSSL_PARAM params[])
317 {
318     return ecx_get_params(key, params, X25519_BITS, X25519_SECURITY_BITS,
319                           X25519_KEYLEN);
320 }
321 
x448_get_params(void * key,OSSL_PARAM params[])322 static int x448_get_params(void *key, OSSL_PARAM params[])
323 {
324     return ecx_get_params(key, params, X448_BITS, X448_SECURITY_BITS,
325                           X448_KEYLEN);
326 }
327 
ed25519_get_params(void * key,OSSL_PARAM params[])328 static int ed25519_get_params(void *key, OSSL_PARAM params[])
329 {
330     return ecx_get_params(key, params, ED25519_BITS, ED25519_SECURITY_BITS,
331                           ED25519_SIGSIZE)
332         && ed_get_params(key, params);
333 }
334 
ed448_get_params(void * key,OSSL_PARAM params[])335 static int ed448_get_params(void *key, OSSL_PARAM params[])
336 {
337     return ecx_get_params(key, params, ED448_BITS, ED448_SECURITY_BITS,
338                           ED448_SIGSIZE)
339         && ed_get_params(key, params);
340 }
341 
342 static const OSSL_PARAM ecx_gettable_params[] = {
343     OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
344     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
345     OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
346     OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0),
347     OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
348     ECX_KEY_TYPES(),
349     OSSL_PARAM_END
350 };
351 
352 static const OSSL_PARAM ed_gettable_params[] = {
353     OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
354     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
355     OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
356     ECX_KEY_TYPES(),
357     OSSL_PARAM_END
358 };
359 
x25519_gettable_params(void * provctx)360 static const OSSL_PARAM *x25519_gettable_params(void *provctx)
361 {
362     return ecx_gettable_params;
363 }
364 
x448_gettable_params(void * provctx)365 static const OSSL_PARAM *x448_gettable_params(void *provctx)
366 {
367     return ecx_gettable_params;
368 }
369 
ed25519_gettable_params(void * provctx)370 static const OSSL_PARAM *ed25519_gettable_params(void *provctx)
371 {
372     return ed_gettable_params;
373 }
374 
ed448_gettable_params(void * provctx)375 static const OSSL_PARAM *ed448_gettable_params(void *provctx)
376 {
377     return ed_gettable_params;
378 }
379 
set_property_query(ECX_KEY * ecxkey,const char * propq)380 static int set_property_query(ECX_KEY *ecxkey, const char *propq)
381 {
382     OPENSSL_free(ecxkey->propq);
383     ecxkey->propq = NULL;
384     if (propq != NULL) {
385         ecxkey->propq = OPENSSL_strdup(propq);
386         if (ecxkey->propq == NULL) {
387             ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
388             return 0;
389         }
390     }
391     return 1;
392 }
393 
ecx_set_params(void * key,const OSSL_PARAM params[])394 static int ecx_set_params(void *key, const OSSL_PARAM params[])
395 {
396     ECX_KEY *ecxkey = key;
397     const OSSL_PARAM *p;
398 
399     if (params == NULL)
400         return 1;
401 
402     p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);
403     if (p != NULL) {
404         void *buf = ecxkey->pubkey;
405 
406         if (p->data_size != ecxkey->keylen
407                 || !OSSL_PARAM_get_octet_string(p, &buf, sizeof(ecxkey->pubkey),
408                                                 NULL))
409             return 0;
410         OPENSSL_clear_free(ecxkey->privkey, ecxkey->keylen);
411         ecxkey->privkey = NULL;
412         ecxkey->haspubkey = 1;
413     }
414     p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PROPERTIES);
415     if (p != NULL) {
416         if (p->data_type != OSSL_PARAM_UTF8_STRING
417             || !set_property_query(ecxkey, p->data))
418             return 0;
419     }
420 
421     return 1;
422 }
423 
x25519_set_params(void * key,const OSSL_PARAM params[])424 static int x25519_set_params(void *key, const OSSL_PARAM params[])
425 {
426     return ecx_set_params(key, params);
427 }
428 
x448_set_params(void * key,const OSSL_PARAM params[])429 static int x448_set_params(void *key, const OSSL_PARAM params[])
430 {
431     return ecx_set_params(key, params);
432 }
433 
ed25519_set_params(void * key,const OSSL_PARAM params[])434 static int ed25519_set_params(void *key, const OSSL_PARAM params[])
435 {
436     return 1;
437 }
438 
ed448_set_params(void * key,const OSSL_PARAM params[])439 static int ed448_set_params(void *key, const OSSL_PARAM params[])
440 {
441     return 1;
442 }
443 
444 static const OSSL_PARAM ecx_settable_params[] = {
445     OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
446     OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0),
447     OSSL_PARAM_END
448 };
449 
450 static const OSSL_PARAM ed_settable_params[] = {
451     OSSL_PARAM_END
452 };
453 
x25519_settable_params(void * provctx)454 static const OSSL_PARAM *x25519_settable_params(void *provctx)
455 {
456     return ecx_settable_params;
457 }
458 
x448_settable_params(void * provctx)459 static const OSSL_PARAM *x448_settable_params(void *provctx)
460 {
461     return ecx_settable_params;
462 }
463 
ed25519_settable_params(void * provctx)464 static const OSSL_PARAM *ed25519_settable_params(void *provctx)
465 {
466     return ed_settable_params;
467 }
468 
ed448_settable_params(void * provctx)469 static const OSSL_PARAM *ed448_settable_params(void *provctx)
470 {
471     return ed_settable_params;
472 }
473 
ecx_gen_init(void * provctx,int selection,const OSSL_PARAM params[],ECX_KEY_TYPE type)474 static void *ecx_gen_init(void *provctx, int selection,
475                           const OSSL_PARAM params[], ECX_KEY_TYPE type)
476 {
477     OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);
478     struct ecx_gen_ctx *gctx = NULL;
479 
480     if (!ossl_prov_is_running())
481         return NULL;
482 
483     if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
484         gctx->libctx = libctx;
485         gctx->type = type;
486         gctx->selection = selection;
487     }
488     if (!ecx_gen_set_params(gctx, params)) {
489         OPENSSL_free(gctx);
490         gctx = NULL;
491     }
492     return gctx;
493 }
494 
x25519_gen_init(void * provctx,int selection,const OSSL_PARAM params[])495 static void *x25519_gen_init(void *provctx, int selection,
496                              const OSSL_PARAM params[])
497 {
498     return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X25519);
499 }
500 
x448_gen_init(void * provctx,int selection,const OSSL_PARAM params[])501 static void *x448_gen_init(void *provctx, int selection,
502                            const OSSL_PARAM params[])
503 {
504     return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X448);
505 }
506 
ed25519_gen_init(void * provctx,int selection,const OSSL_PARAM params[])507 static void *ed25519_gen_init(void *provctx, int selection,
508                               const OSSL_PARAM params[])
509 {
510     return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_ED25519);
511 }
512 
ed448_gen_init(void * provctx,int selection,const OSSL_PARAM params[])513 static void *ed448_gen_init(void *provctx, int selection,
514                             const OSSL_PARAM params[])
515 {
516     return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_ED448);
517 }
518 
ecx_gen_set_params(void * genctx,const OSSL_PARAM params[])519 static int ecx_gen_set_params(void *genctx, const OSSL_PARAM params[])
520 {
521     struct ecx_gen_ctx *gctx = genctx;
522     const OSSL_PARAM *p;
523 
524     if (gctx == NULL)
525         return 0;
526 
527     p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME);
528     if (p != NULL) {
529         const char *groupname = NULL;
530 
531         /*
532          * We optionally allow setting a group name - but each algorithm only
533          * support one such name, so all we do is verify that it is the one we
534          * expected.
535          */
536         switch (gctx->type) {
537             case ECX_KEY_TYPE_X25519:
538                 groupname = "x25519";
539                 break;
540             case ECX_KEY_TYPE_X448:
541                 groupname = "x448";
542                 break;
543             default:
544                 /* We only support this for key exchange at the moment */
545                 break;
546         }
547         if (p->data_type != OSSL_PARAM_UTF8_STRING
548                 || groupname == NULL
549                 || strcasecmp(p->data, groupname) != 0) {
550             ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
551             return 0;
552         }
553     }
554     p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES);
555     if (p != NULL) {
556         if (p->data_type != OSSL_PARAM_UTF8_STRING)
557             return 0;
558         OPENSSL_free(gctx->propq);
559         gctx->propq = OPENSSL_strdup(p->data);
560         if (gctx->propq == NULL)
561             return 0;
562     }
563 
564     return 1;
565 }
566 
ecx_gen_settable_params(ossl_unused void * genctx,ossl_unused void * provctx)567 static const OSSL_PARAM *ecx_gen_settable_params(ossl_unused void *genctx,
568                                                  ossl_unused void *provctx)
569 {
570     static OSSL_PARAM settable[] = {
571         OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
572         OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
573         OSSL_PARAM_END
574     };
575     return settable;
576 }
577 
ecx_gen(struct ecx_gen_ctx * gctx)578 static void *ecx_gen(struct ecx_gen_ctx *gctx)
579 {
580     ECX_KEY *key;
581     unsigned char *privkey;
582 
583     if (gctx == NULL)
584         return NULL;
585     if ((key = ossl_ecx_key_new(gctx->libctx, gctx->type, 0,
586                                 gctx->propq)) == NULL) {
587         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
588         return NULL;
589     }
590 
591     /* If we're doing parameter generation then we just return a blank key */
592     if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
593         return key;
594 
595     if ((privkey = ossl_ecx_key_allocate_privkey(key)) == NULL) {
596         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
597         goto err;
598     }
599     if (RAND_priv_bytes_ex(gctx->libctx, privkey, key->keylen, 0) <= 0)
600         goto err;
601     switch (gctx->type) {
602     case ECX_KEY_TYPE_X25519:
603         privkey[0] &= 248;
604         privkey[X25519_KEYLEN - 1] &= 127;
605         privkey[X25519_KEYLEN - 1] |= 64;
606         ossl_x25519_public_from_private(key->pubkey, privkey);
607         break;
608     case ECX_KEY_TYPE_X448:
609         privkey[0] &= 252;
610         privkey[X448_KEYLEN - 1] |= 128;
611         ossl_x448_public_from_private(key->pubkey, privkey);
612         break;
613     case ECX_KEY_TYPE_ED25519:
614         if (!ossl_ed25519_public_from_private(gctx->libctx, key->pubkey, privkey,
615                                               gctx->propq))
616             goto err;
617         break;
618     case ECX_KEY_TYPE_ED448:
619         if (!ossl_ed448_public_from_private(gctx->libctx, key->pubkey, privkey,
620                                             gctx->propq))
621             goto err;
622         break;
623     }
624     key->haspubkey = 1;
625     return key;
626 err:
627     ossl_ecx_key_free(key);
628     return NULL;
629 }
630 
x25519_gen(void * genctx,OSSL_CALLBACK * osslcb,void * cbarg)631 static void *x25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
632 {
633     struct ecx_gen_ctx *gctx = genctx;
634 
635     if (!ossl_prov_is_running())
636         return 0;
637 
638 #ifdef S390X_EC_ASM
639     if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
640         return s390x_ecx_keygen25519(gctx);
641 #endif
642     return ecx_gen(gctx);
643 }
644 
x448_gen(void * genctx,OSSL_CALLBACK * osslcb,void * cbarg)645 static void *x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
646 {
647     struct ecx_gen_ctx *gctx = genctx;
648 
649     if (!ossl_prov_is_running())
650         return 0;
651 
652 #ifdef S390X_EC_ASM
653     if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
654         return s390x_ecx_keygen448(gctx);
655 #endif
656     return ecx_gen(gctx);
657 }
658 
ed25519_gen(void * genctx,OSSL_CALLBACK * osslcb,void * cbarg)659 static void *ed25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
660 {
661     struct ecx_gen_ctx *gctx = genctx;
662 
663     if (!ossl_prov_is_running())
664         return 0;
665 
666 #ifdef S390X_EC_ASM
667     if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
668         && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
669         && OPENSSL_s390xcap_P.kdsa[0]
670             & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
671         return s390x_ecd_keygen25519(gctx);
672 #endif
673     return ecx_gen(gctx);
674 }
675 
ed448_gen(void * genctx,OSSL_CALLBACK * osslcb,void * cbarg)676 static void *ed448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
677 {
678     struct ecx_gen_ctx *gctx = genctx;
679 
680     if (!ossl_prov_is_running())
681         return 0;
682 
683 #ifdef S390X_EC_ASM
684     if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
685         && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
686         && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
687         return s390x_ecd_keygen448(gctx);
688 #endif
689     return ecx_gen(gctx);
690 }
691 
ecx_gen_cleanup(void * genctx)692 static void ecx_gen_cleanup(void *genctx)
693 {
694     struct ecx_gen_ctx *gctx = genctx;
695 
696     OPENSSL_free(gctx->propq);
697     OPENSSL_free(gctx);
698 }
699 
ecx_load(const void * reference,size_t reference_sz)700 void *ecx_load(const void *reference, size_t reference_sz)
701 {
702     ECX_KEY *key = NULL;
703 
704     if (ossl_prov_is_running() && reference_sz == sizeof(key)) {
705         /* The contents of the reference is the address to our object */
706         key = *(ECX_KEY **)reference;
707         /* We grabbed, so we detach it */
708         *(ECX_KEY **)reference = NULL;
709         return key;
710     }
711     return NULL;
712 }
713 
ecx_dup(const void * keydata_from,int selection)714 static void *ecx_dup(const void *keydata_from, int selection)
715 {
716     if (ossl_prov_is_running())
717         return ossl_ecx_key_dup(keydata_from, selection);
718     return NULL;
719 }
720 
ecx_key_pairwise_check(const ECX_KEY * ecx,int type)721 static int ecx_key_pairwise_check(const ECX_KEY *ecx, int type)
722 {
723     uint8_t pub[64];
724 
725     switch (type) {
726     case ECX_KEY_TYPE_X25519:
727         ossl_x25519_public_from_private(pub, ecx->privkey);
728         break;
729     case ECX_KEY_TYPE_X448:
730         ossl_x448_public_from_private(pub, ecx->privkey);
731         break;
732     case ECX_KEY_TYPE_ED25519:
733         if (!ossl_ed25519_public_from_private(ecx->libctx, pub, ecx->privkey,
734                                               ecx->propq))
735             return 0;
736         break;
737     case ECX_KEY_TYPE_ED448:
738         if (!ossl_ed448_public_from_private(ecx->libctx, pub, ecx->privkey,
739                                             ecx->propq))
740             return 0;
741         break;
742     default:
743         return 0;
744     }
745     return CRYPTO_memcmp(ecx->pubkey, pub, ecx->keylen) == 0;
746 }
747 
ecx_validate(const void * keydata,int selection,int type,size_t keylen)748 static int ecx_validate(const void *keydata, int selection, int type, size_t keylen)
749 {
750     const ECX_KEY *ecx = keydata;
751     int ok = keylen == ecx->keylen;
752 
753     if (!ossl_prov_is_running())
754         return 0;
755 
756     if ((selection & ECX_POSSIBLE_SELECTIONS) == 0)
757         return 1; /* nothing to validate */
758 
759     if (!ok) {
760         ERR_raise(ERR_LIB_PROV, PROV_R_ALGORITHM_MISMATCH);
761         return 0;
762     }
763 
764     if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
765         ok = ok && ecx->haspubkey;
766 
767     if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
768         ok = ok && ecx->privkey != NULL;
769 
770     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR)
771         ok = ok && ecx_key_pairwise_check(ecx, type);
772 
773     return ok;
774 }
775 
x25519_validate(const void * keydata,int selection,int checktype)776 static int x25519_validate(const void *keydata, int selection, int checktype)
777 {
778     return ecx_validate(keydata, selection, ECX_KEY_TYPE_X25519, X25519_KEYLEN);
779 }
780 
x448_validate(const void * keydata,int selection,int checktype)781 static int x448_validate(const void *keydata, int selection, int checktype)
782 {
783     return ecx_validate(keydata, selection, ECX_KEY_TYPE_X448, X448_KEYLEN);
784 }
785 
ed25519_validate(const void * keydata,int selection,int checktype)786 static int ed25519_validate(const void *keydata, int selection, int checktype)
787 {
788     return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED25519, ED25519_KEYLEN);
789 }
790 
ed448_validate(const void * keydata,int selection,int checktype)791 static int ed448_validate(const void *keydata, int selection, int checktype)
792 {
793     return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED448, ED448_KEYLEN);
794 }
795 
796 #define MAKE_KEYMGMT_FUNCTIONS(alg) \
797     const OSSL_DISPATCH ossl_##alg##_keymgmt_functions[] = { \
798         { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \
799         { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ossl_ecx_key_free }, \
800         { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))alg##_get_params }, \
801         { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))alg##_gettable_params }, \
802         { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))alg##_set_params }, \
803         { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))alg##_settable_params }, \
804         { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has }, \
805         { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ecx_match }, \
806         { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))alg##_validate }, \
807         { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import }, \
808         { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
809         { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ecx_export }, \
810         { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
811         { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))alg##_gen_init }, \
812         { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ecx_gen_set_params }, \
813         { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, \
814           (void (*)(void))ecx_gen_settable_params }, \
815         { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen }, \
816         { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \
817         { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ecx_load }, \
818         { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ecx_dup }, \
819         { 0, NULL } \
820     };
821 
822 MAKE_KEYMGMT_FUNCTIONS(x25519)
MAKE_KEYMGMT_FUNCTIONS(x448)823 MAKE_KEYMGMT_FUNCTIONS(x448)
824 MAKE_KEYMGMT_FUNCTIONS(ed25519)
825 MAKE_KEYMGMT_FUNCTIONS(ed448)
826 
827 #ifdef S390X_EC_ASM
828 # include "s390x_arch.h"
829 
830 static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx)
831 {
832     static const unsigned char generator[] = {
833         0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
834         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
835         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
836     };
837     ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X25519, 1,
838                                     gctx->propq);
839     unsigned char *privkey = NULL, *pubkey;
840 
841     if (key == NULL) {
842         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
843         goto err;
844     }
845 
846     /* If we're doing parameter generation then we just return a blank key */
847     if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
848         return key;
849 
850     pubkey = key->pubkey;
851 
852     privkey = ossl_ecx_key_allocate_privkey(key);
853     if (privkey == NULL) {
854         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
855         goto err;
856     }
857 
858     if (RAND_priv_bytes_ex(gctx->libctx, privkey, X25519_KEYLEN, 0) <= 0)
859         goto err;
860 
861     privkey[0] &= 248;
862     privkey[31] &= 127;
863     privkey[31] |= 64;
864 
865     if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
866         goto err;
867     key->haspubkey = 1;
868     return key;
869  err:
870     ossl_ecx_key_free(key);
871     return NULL;
872 }
873 
s390x_ecx_keygen448(struct ecx_gen_ctx * gctx)874 static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx)
875 {
876     static const unsigned char generator[] = {
877         0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
878         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
879         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
880         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
881         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
882     };
883     ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X448, 1,
884                                     gctx->propq);
885     unsigned char *privkey = NULL, *pubkey;
886 
887     if (key == NULL) {
888         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
889         goto err;
890     }
891 
892     /* If we're doing parameter generation then we just return a blank key */
893     if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
894         return key;
895 
896     pubkey = key->pubkey;
897 
898     privkey = ossl_ecx_key_allocate_privkey(key);
899     if (privkey == NULL) {
900         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
901         goto err;
902     }
903 
904     if (RAND_priv_bytes_ex(gctx->libctx, privkey, X448_KEYLEN, 0) <= 0)
905         goto err;
906 
907     privkey[0] &= 252;
908     privkey[55] |= 128;
909 
910     if (s390x_x448_mul(pubkey, generator, privkey) != 1)
911         goto err;
912     key->haspubkey = 1;
913     return key;
914  err:
915     ossl_ecx_key_free(key);
916     return NULL;
917 }
918 
s390x_ecd_keygen25519(struct ecx_gen_ctx * gctx)919 static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx)
920 {
921     static const unsigned char generator_x[] = {
922         0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
923         0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
924         0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
925     };
926     static const unsigned char generator_y[] = {
927         0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
928         0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
929         0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
930     };
931     unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
932     ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED25519, 1,
933                                     gctx->propq);
934     unsigned char *privkey = NULL, *pubkey;
935     unsigned int sz;
936     EVP_MD *sha = NULL;
937     int j;
938 
939     if (key == NULL) {
940         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
941         goto err;
942     }
943 
944     /* If we're doing parameter generation then we just return a blank key */
945     if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
946         return key;
947 
948     pubkey = key->pubkey;
949 
950     privkey = ossl_ecx_key_allocate_privkey(key);
951     if (privkey == NULL) {
952         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
953         goto err;
954     }
955 
956     if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED25519_KEYLEN, 0) <= 0)
957         goto err;
958 
959     sha = EVP_MD_fetch(gctx->libctx, "SHA512", gctx->propq);
960     if (sha == NULL)
961         goto err;
962     j = EVP_Digest(privkey, 32, buff, &sz, sha, NULL);
963     EVP_MD_free(sha);
964     if (!j)
965         goto err;
966 
967     buff[0] &= 248;
968     buff[31] &= 63;
969     buff[31] |= 64;
970 
971     if (s390x_ed25519_mul(x_dst, pubkey,
972                           generator_x, generator_y, buff) != 1)
973         goto err;
974 
975     pubkey[31] |= ((x_dst[0] & 0x01) << 7);
976     key->haspubkey = 1;
977     return key;
978  err:
979     ossl_ecx_key_free(key);
980     return NULL;
981 }
982 
s390x_ecd_keygen448(struct ecx_gen_ctx * gctx)983 static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx)
984 {
985     static const unsigned char generator_x[] = {
986         0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
987         0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
988         0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
989         0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
990         0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
991     };
992     static const unsigned char generator_y[] = {
993         0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
994         0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
995         0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
996         0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
997         0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
998     };
999     unsigned char x_dst[57], buff[114];
1000     ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED448, 1,
1001                                     gctx->propq);
1002     unsigned char *privkey = NULL, *pubkey;
1003     EVP_MD_CTX *hashctx = NULL;
1004     EVP_MD *shake = NULL;
1005 
1006     if (key == NULL) {
1007         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
1008         goto err;
1009     }
1010 
1011     /* If we're doing parameter generation then we just return a blank key */
1012     if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1013         return key;
1014 
1015     pubkey = key->pubkey;
1016 
1017     privkey = ossl_ecx_key_allocate_privkey(key);
1018     if (privkey == NULL) {
1019         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
1020         goto err;
1021     }
1022 
1023     shake = EVP_MD_fetch(gctx->libctx, "SHAKE256", gctx->propq);
1024     if (shake == NULL)
1025         goto err;
1026     if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED448_KEYLEN, 0) <= 0)
1027         goto err;
1028 
1029     hashctx = EVP_MD_CTX_new();
1030     if (hashctx == NULL)
1031         goto err;
1032     if (EVP_DigestInit_ex(hashctx, shake, NULL) != 1)
1033         goto err;
1034     if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1035         goto err;
1036     if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1037         goto err;
1038 
1039     buff[0] &= -4;
1040     buff[55] |= 0x80;
1041     buff[56] = 0;
1042 
1043     if (s390x_ed448_mul(x_dst, pubkey,
1044                         generator_x, generator_y, buff) != 1)
1045         goto err;
1046 
1047     pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1048     EVP_MD_CTX_free(hashctx);
1049     EVP_MD_free(shake);
1050     key->haspubkey = 1;
1051     return key;
1052  err:
1053     ossl_ecx_key_free(key);
1054     EVP_MD_CTX_free(hashctx);
1055     EVP_MD_free(shake);
1056     return NULL;
1057 }
1058 #endif
1059