]> git.ipfire.org Git - thirdparty/openssl.git/blame - providers/implementations/keymgmt/ecx_kmgmt.c
Make EVP_PKEY_[get1|set1]_tls_encodedpoint work with provided keys
[thirdparty/openssl.git] / providers / implementations / keymgmt / ecx_kmgmt.c
CommitLineData
90d3cb57
MC
1/*
2 * Copyright 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 <assert.h>
11#include <openssl/core_numbers.h>
12#include <openssl/core_names.h>
43cd3701 13#include <openssl/params.h>
c1e48c51 14#include <openssl/err.h>
43cd3701
P
15#include <openssl/evp.h>
16#include <openssl/rand.h>
17#include "internal/param_build_set.h"
18#include "openssl/param_build.h"
90d3cb57
MC
19#include "crypto/ecx.h"
20#include "prov/implementations.h"
21#include "prov/providercommon.h"
43cd3701
P
22#include "prov/provider_ctx.h"
23#ifdef S390X_EC_ASM
24# include "s390x_arch.h"
c1e48c51 25# include <openssl/sha.h> /* For SHA512_DIGEST_LENGTH */
43cd3701 26#endif
90d3cb57
MC
27
28static OSSL_OP_keymgmt_new_fn x25519_new_key;
29static OSSL_OP_keymgmt_new_fn x448_new_key;
af6d8dd3
MC
30static OSSL_OP_keymgmt_new_fn ed25519_new_key;
31static OSSL_OP_keymgmt_new_fn ed448_new_key;
43cd3701
P
32static OSSL_OP_keymgmt_gen_init_fn x25519_gen_init;
33static OSSL_OP_keymgmt_gen_init_fn x448_gen_init;
34static OSSL_OP_keymgmt_gen_init_fn ed25519_gen_init;
35static OSSL_OP_keymgmt_gen_init_fn ed448_gen_init;
36static OSSL_OP_keymgmt_gen_fn x25519_gen;
37static OSSL_OP_keymgmt_gen_fn x448_gen;
38static OSSL_OP_keymgmt_gen_fn ed25519_gen;
39static OSSL_OP_keymgmt_gen_fn ed448_gen;
40static OSSL_OP_keymgmt_gen_cleanup_fn ecx_gen_cleanup;
90d3cb57
MC
41static OSSL_OP_keymgmt_get_params_fn x25519_get_params;
42static OSSL_OP_keymgmt_get_params_fn x448_get_params;
af6d8dd3
MC
43static OSSL_OP_keymgmt_get_params_fn ed25519_get_params;
44static OSSL_OP_keymgmt_get_params_fn ed448_get_params;
1a7328c8
RL
45static OSSL_OP_keymgmt_gettable_params_fn x25519_gettable_params;
46static OSSL_OP_keymgmt_gettable_params_fn x448_gettable_params;
47static OSSL_OP_keymgmt_gettable_params_fn ed25519_gettable_params;
48static OSSL_OP_keymgmt_gettable_params_fn ed448_gettable_params;
6a9bd929
MC
49static OSSL_OP_keymgmt_set_params_fn x25519_set_params;
50static OSSL_OP_keymgmt_set_params_fn x448_set_params;
51static OSSL_OP_keymgmt_set_params_fn ed25519_set_params;
52static OSSL_OP_keymgmt_set_params_fn ed448_set_params;
53static OSSL_OP_keymgmt_settable_params_fn x25519_settable_params;
54static OSSL_OP_keymgmt_settable_params_fn x448_settable_params;
55static OSSL_OP_keymgmt_settable_params_fn ed25519_settable_params;
56static OSSL_OP_keymgmt_settable_params_fn ed448_settable_params;
90d3cb57 57static OSSL_OP_keymgmt_has_fn ecx_has;
262ff123 58static OSSL_OP_keymgmt_match_fn ecx_match;
90d3cb57
MC
59static OSSL_OP_keymgmt_import_fn ecx_import;
60static OSSL_OP_keymgmt_import_types_fn ecx_imexport_types;
61static OSSL_OP_keymgmt_export_fn ecx_export;
62static OSSL_OP_keymgmt_export_types_fn ecx_imexport_types;
63
f552d900
SL
64#define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR)
65
43cd3701
P
66struct ecx_gen_ctx {
67 OPENSSL_CTX *libctx;
68 ECX_KEY_TYPE type;
69};
70
c1e48c51
P
71#ifdef S390X_EC_ASM
72static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx);
73static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx);
74static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx);
75static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx);
76#endif
43cd3701 77
90d3cb57
MC
78static void *x25519_new_key(void *provctx)
79{
f3336f40 80 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_X25519, 0);
90d3cb57
MC
81}
82
83static void *x448_new_key(void *provctx)
84{
f3336f40 85 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_X448, 0);
90d3cb57
MC
86}
87
af6d8dd3
MC
88static void *ed25519_new_key(void *provctx)
89{
f3336f40 90 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_ED25519, 0);
af6d8dd3
MC
91}
92
93static void *ed448_new_key(void *provctx)
94{
f3336f40 95 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_ED448, 0);
af6d8dd3
MC
96}
97
90d3cb57
MC
98static int ecx_has(void *keydata, int selection)
99{
100 ECX_KEY *key = keydata;
adc9f731 101 int ok = 0;
90d3cb57 102
adc9f731
RL
103 if (key != NULL) {
104 if ((selection & ECX_POSSIBLE_SELECTIONS) != 0)
105 ok = 1;
90d3cb57 106
adc9f731
RL
107 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
108 ok = ok && key->haspubkey;
90d3cb57 109
adc9f731
RL
110 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
111 ok = ok && key->privkey != NULL;
112 }
90d3cb57
MC
113 return ok;
114}
115
262ff123
MC
116static int ecx_match(const void *keydata1, const void *keydata2, int selection)
117{
118 const ECX_KEY *key1 = keydata1;
119 const ECX_KEY *key2 = keydata2;
120 int ok = 1;
121
122 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
123 ok = ok && key1->type == key2->type;
124 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
125 if ((key1->privkey == NULL && key2->privkey != NULL)
126 || (key1->privkey != NULL && key2->privkey == NULL)
127 || key1->type != key2->type)
128 ok = 0;
129 else
130 ok = ok && (key1->privkey == NULL /* implies key2->privkey == NULL */
131 || CRYPTO_memcmp(key1->privkey, key2->privkey,
132 key1->keylen) == 0);
133 }
134 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
135 if (key1->haspubkey != key2->haspubkey
136 || key1->type != key2->type)
137 ok = 0;
138 else
139 ok = ok && (key1->haspubkey == 0 /* implies key2->haspubkey == 0 */
140 || CRYPTO_memcmp(key1->pubkey, key2->pubkey,
141 key1->keylen) == 0);
142 }
143 return ok;
144}
145
90d3cb57
MC
146static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[])
147{
148 ECX_KEY *key = keydata;
0abae163
RL
149 int ok = 1;
150 int include_private = 0;
90d3cb57
MC
151
152 if (key == NULL)
153 return 0;
154
969024b4 155 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
90d3cb57
MC
156 return 0;
157
0abae163 158 include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
969024b4 159 ok = ok && ecx_key_fromdata(key, params, include_private);
90d3cb57 160
0abae163 161 return ok;
90d3cb57
MC
162}
163
96ebe52e
SL
164static int key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl,
165 OSSL_PARAM params[])
90d3cb57
MC
166{
167 if (key == NULL)
168 return 0;
169
96ebe52e
SL
170 if (!ossl_param_build_set_octet_string(tmpl, params,
171 OSSL_PKEY_PARAM_PUB_KEY,
172 key->pubkey, key->keylen))
90d3cb57
MC
173 return 0;
174
175 if (key->privkey != NULL
96ebe52e
SL
176 && !ossl_param_build_set_octet_string(tmpl, params,
177 OSSL_PKEY_PARAM_PRIV_KEY,
178 key->privkey, key->keylen))
90d3cb57
MC
179 return 0;
180
181 return 1;
182}
183
184static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
185 void *cbarg)
186{
187 ECX_KEY *key = keydata;
6d4e6009 188 OSSL_PARAM_BLD *tmpl;
90d3cb57 189 OSSL_PARAM *params = NULL;
96ebe52e 190 int ret = 0;
90d3cb57
MC
191
192 if (key == NULL)
193 return 0;
194
6d4e6009
P
195 tmpl = OSSL_PARAM_BLD_new();
196 if (tmpl == NULL)
90d3cb57
MC
197 return 0;
198
6d4e6009 199 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0
96ebe52e
SL
200 && !key_to_params(key, tmpl, NULL))
201 goto err;
202
6d4e6009 203 params = OSSL_PARAM_BLD_to_param(tmpl);
6d4e6009 204 if (params == NULL)
96ebe52e 205 goto err;
6d4e6009 206
90d3cb57 207 ret = param_cb(params, cbarg);
6d4e6009 208 OSSL_PARAM_BLD_free_params(params);
96ebe52e
SL
209err:
210 OSSL_PARAM_BLD_free(tmpl);
90d3cb57
MC
211 return ret;
212}
213
96ebe52e
SL
214#define ECX_KEY_TYPES() \
215OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \
216OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
217
90d3cb57 218static const OSSL_PARAM ecx_key_types[] = {
96ebe52e 219 ECX_KEY_TYPES(),
90d3cb57
MC
220 OSSL_PARAM_END
221};
222static const OSSL_PARAM *ecx_imexport_types(int selection)
223{
224 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
225 return ecx_key_types;
226 return NULL;
227}
228
96ebe52e 229static int ecx_get_params(void *key, OSSL_PARAM params[], int bits, int secbits,
90d3cb57
MC
230 int size)
231{
96ebe52e 232 ECX_KEY *ecx = key;
90d3cb57
MC
233 OSSL_PARAM *p;
234
235 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
236 && !OSSL_PARAM_set_int(p, bits))
237 return 0;
238 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
239 && !OSSL_PARAM_set_int(p, secbits))
240 return 0;
241 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
242 && !OSSL_PARAM_set_int(p, size))
243 return 0;
6a9bd929
MC
244 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT)) != NULL
245 && (ecx->type == ECX_KEY_TYPE_X25519
246 || ecx->type == ECX_KEY_TYPE_X448)) {
247 if (!OSSL_PARAM_set_octet_string(p, ecx->pubkey, ecx->keylen))
248 return 0;
249 }
250
96ebe52e 251 return key_to_params(ecx, NULL, params);
90d3cb57
MC
252}
253
1a7328c8
RL
254static int ed_get_params(void *key, OSSL_PARAM params[])
255{
256 OSSL_PARAM *p;
257
258 if ((p = OSSL_PARAM_locate(params,
259 OSSL_PKEY_PARAM_MANDATORY_DIGEST)) != NULL
260 && !OSSL_PARAM_set_utf8_string(p, ""))
261 return 0;
262 return 1;
263}
264
90d3cb57
MC
265static int x25519_get_params(void *key, OSSL_PARAM params[])
266{
96ebe52e
SL
267 return ecx_get_params(key, params, X25519_BITS, X25519_SECURITY_BITS,
268 X25519_KEYLEN);
90d3cb57
MC
269}
270
271static int x448_get_params(void *key, OSSL_PARAM params[])
272{
96ebe52e
SL
273 return ecx_get_params(key, params, X448_BITS, X448_SECURITY_BITS,
274 X448_KEYLEN);
90d3cb57
MC
275}
276
af6d8dd3
MC
277static int ed25519_get_params(void *key, OSSL_PARAM params[])
278{
96ebe52e 279 return ecx_get_params(key, params, ED25519_BITS, ED25519_SECURITY_BITS,
1a7328c8
RL
280 ED25519_KEYLEN)
281 && ed_get_params(key, params);
af6d8dd3
MC
282}
283
284static int ed448_get_params(void *key, OSSL_PARAM params[])
285{
96ebe52e 286 return ecx_get_params(key, params, ED448_BITS, ED448_SECURITY_BITS,
1a7328c8
RL
287 ED448_KEYLEN)
288 && ed_get_params(key, params);
af6d8dd3
MC
289}
290
6a9bd929 291static const OSSL_PARAM ecx_gettable_params[] = {
1a7328c8
RL
292 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
293 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
294 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
295 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0),
6a9bd929 296 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
1a7328c8
RL
297 ECX_KEY_TYPES(),
298 OSSL_PARAM_END
299};
300
6a9bd929 301static const OSSL_PARAM ed_gettable_params[] = {
90d3cb57
MC
302 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
303 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
304 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
96ebe52e 305 ECX_KEY_TYPES(),
90d3cb57
MC
306 OSSL_PARAM_END
307};
308
1a7328c8
RL
309static const OSSL_PARAM *x25519_gettable_params(void)
310{
6a9bd929 311 return ecx_gettable_params;
1a7328c8
RL
312}
313
314static const OSSL_PARAM *x448_gettable_params(void)
90d3cb57 315{
6a9bd929 316 return ecx_gettable_params;
90d3cb57
MC
317}
318
1a7328c8
RL
319static const OSSL_PARAM *ed25519_gettable_params(void)
320{
6a9bd929 321 return ed_gettable_params;
1a7328c8
RL
322}
323
324static const OSSL_PARAM *ed448_gettable_params(void)
325{
6a9bd929
MC
326 return ed_gettable_params;
327}
328
329static int ecx_set_params(void *key, const OSSL_PARAM params[])
330{
331 ECX_KEY *ecxkey = key;
332 const OSSL_PARAM *p;
333
334 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT);
335 if (p != NULL) {
336 void *buf = ecxkey->pubkey;
337
338 if (p->data_size != ecxkey->keylen
339 || !OSSL_PARAM_get_octet_string(p, &buf, sizeof(ecxkey->pubkey),
340 NULL))
341 return 0;
342 OPENSSL_clear_free(ecxkey->privkey, ecxkey->keylen);
343 ecxkey->privkey = NULL;
344 ecxkey->haspubkey = 1;
345 }
346
347 return 1;
348}
349
350static int x25519_set_params(void *key, const OSSL_PARAM params[])
351{
352 return ecx_set_params(key, params);
353}
354
355static int x448_set_params(void *key, const OSSL_PARAM params[])
356{
357 return ecx_set_params(key, params);
358}
359
360static int ed25519_set_params(void *key, const OSSL_PARAM params[])
361{
362 return 1;
363}
364
365static int ed448_set_params(void *key, const OSSL_PARAM params[])
366{
367 return 1;
368}
369
370static const OSSL_PARAM ecx_settable_params[] = {
371 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
372 OSSL_PARAM_END
373};
374
375static const OSSL_PARAM ed_settable_params[] = {
376 OSSL_PARAM_END
377};
378
379static const OSSL_PARAM *x25519_settable_params(void)
380{
381 return ecx_settable_params;
382}
383
384static const OSSL_PARAM *x448_settable_params(void)
385{
386 return ecx_settable_params;
387}
388
389static const OSSL_PARAM *ed25519_settable_params(void)
390{
391 return ed_settable_params;
392}
393
394static const OSSL_PARAM *ed448_settable_params(void)
395{
396 return ed_settable_params;
1a7328c8
RL
397}
398
43cd3701
P
399static void *ecx_gen_init(void *provctx, int selection, ECX_KEY_TYPE type)
400{
401 OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
402 struct ecx_gen_ctx *gctx = NULL;
403
404 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
405 return NULL;
406
407 if ((gctx = OPENSSL_malloc(sizeof(*gctx))) != NULL) {
408 gctx->libctx = libctx;
409 gctx->type = type;
410 }
411 return gctx;
412}
413
414static void *x25519_gen_init(void *provctx, int selection)
415{
416 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_X25519);
417}
418
419static void *x448_gen_init(void *provctx, int selection)
420{
421 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_X448);
422}
423
424static void *ed25519_gen_init(void *provctx, int selection)
425{
426 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_ED25519);
427}
428
429static void *ed448_gen_init(void *provctx, int selection)
430{
431 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_ED448);
432}
433
434static void *ecx_gen(struct ecx_gen_ctx *gctx)
435{
436 ECX_KEY *key;
437 unsigned char *privkey;
438
c1e48c51
P
439 if (gctx == NULL)
440 return NULL;
f3336f40 441 if ((key = ecx_key_new(gctx->libctx, gctx->type, 0)) == NULL) {
c1e48c51 442 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701 443 return NULL;
c1e48c51
P
444 }
445 if ((privkey = ecx_key_allocate_privkey(key)) == NULL) {
446 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
447 goto err;
448 }
449 if (RAND_priv_bytes_ex(gctx->libctx, privkey, key->keylen) <= 0)
43cd3701
P
450 goto err;
451 switch (gctx->type) {
452 case ECX_KEY_TYPE_X25519:
453 privkey[0] &= 248;
454 privkey[X25519_KEYLEN - 1] &= 127;
455 privkey[X25519_KEYLEN - 1] |= 64;
456 X25519_public_from_private(key->pubkey, privkey);
457 break;
458 case ECX_KEY_TYPE_X448:
459 privkey[0] &= 252;
460 privkey[X448_KEYLEN - 1] |= 128;
461 X448_public_from_private(key->pubkey, privkey);
462 break;
463 case ECX_KEY_TYPE_ED25519:
464 if (!ED25519_public_from_private(gctx->libctx, key->pubkey, privkey))
465 goto err;
466 break;
467 case ECX_KEY_TYPE_ED448:
468 if (!ED448_public_from_private(gctx->libctx, key->pubkey, privkey))
469 goto err;
470 break;
471 }
472 return key;
473err:
474 ecx_key_free(key);
475 return NULL;
476}
477
478static void *x25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
479{
480 struct ecx_gen_ctx *gctx = genctx;
481
482#ifdef S390X_EC_ASM
483 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
484 return s390x_ecx_keygen25519(gctx);
485#endif
486 return ecx_gen(gctx);
487}
488
489static void *x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
490{
491 struct ecx_gen_ctx *gctx = genctx;
492
493#ifdef S390X_EC_ASM
494 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
495 return s390x_ecx_keygen448(gctx);
496#endif
497 return ecx_gen(gctx);
498}
499
500static void *ed25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
501{
502 struct ecx_gen_ctx *gctx = genctx;
503#ifdef S390X_EC_ASM
504 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
505 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
506 && OPENSSL_s390xcap_P.kdsa[0]
507 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
508 return s390x_ecd_keygen25519(gctx);
509#endif
510 return ecx_gen(gctx);
511}
512
513static void *ed448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
514{
515 struct ecx_gen_ctx *gctx = genctx;
516
517#ifdef S390X_EC_ASM
518 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
519 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
520 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
521 return s390x_ecd_keygen448(gctx);
522#endif
523 return ecx_gen(gctx);
524}
525
526static void ecx_gen_cleanup(void *genctx)
527{
528 struct ecx_gen_ctx *gctx = genctx;
529
530 OPENSSL_free(gctx);
531}
532
af6d8dd3
MC
533#define MAKE_KEYMGMT_FUNCTIONS(alg) \
534 const OSSL_DISPATCH alg##_keymgmt_functions[] = { \
535 { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \
536 { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ecx_key_free }, \
537 { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))alg##_get_params }, \
1a7328c8 538 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))alg##_gettable_params }, \
6a9bd929
MC
539 { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))alg##_set_params }, \
540 { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))alg##_settable_params }, \
af6d8dd3 541 { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has }, \
262ff123 542 { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ecx_match }, \
af6d8dd3
MC
543 { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import }, \
544 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
545 { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ecx_export }, \
546 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
43cd3701
P
547 { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))alg##_gen_init }, \
548 { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen }, \
549 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \
af6d8dd3
MC
550 { 0, NULL } \
551 };
552
553MAKE_KEYMGMT_FUNCTIONS(x25519)
554MAKE_KEYMGMT_FUNCTIONS(x448)
555MAKE_KEYMGMT_FUNCTIONS(ed25519)
556MAKE_KEYMGMT_FUNCTIONS(ed448)
43cd3701
P
557
558#ifdef S390X_EC_ASM
559# include "s390x_arch.h"
43cd3701
P
560
561static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx)
562{
563 static const unsigned char generator[] = {
564 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
567 };
f3336f40 568 ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X25519, 1);
43cd3701
P
569 unsigned char *privkey = NULL, *pubkey;
570
571 if (key == NULL) {
c1e48c51 572 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701
P
573 goto err;
574 }
575
576 pubkey = key->pubkey;
577
578 privkey = ecx_key_allocate_privkey(key);
579 if (privkey == NULL) {
c1e48c51 580 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701
P
581 goto err;
582 }
583
c1e48c51 584 if (RAND_priv_bytes_ex(gctx->libctx, privkey, X25519_KEYLEN) <= 0)
43cd3701
P
585 goto err;
586
587 privkey[0] &= 248;
588 privkey[31] &= 127;
589 privkey[31] |= 64;
590
591 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
592 goto err;
43cd3701
P
593 return key;
594 err:
595 ecx_key_free(key);
596 return NULL;
597}
598
599static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx)
600{
601 static const unsigned char generator[] = {
602 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
607 };
f3336f40 608 ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X448, 1);
43cd3701
P
609 unsigned char *privkey = NULL, *pubkey;
610
611 if (key == NULL) {
c1e48c51 612 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701
P
613 goto err;
614 }
615
616 pubkey = key->pubkey;
617
618 privkey = ecx_key_allocate_privkey(key);
619 if (privkey == NULL) {
c1e48c51 620 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701
P
621 goto err;
622 }
623
c1e48c51 624 if (RAND_priv_bytes_ex(gctx->libctx, privkey, X448_KEYLEN) <= 0)
43cd3701
P
625 goto err;
626
627 privkey[0] &= 252;
628 privkey[55] |= 128;
629
630 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
631 goto err;
43cd3701
P
632 return key;
633 err:
634 ecx_key_free(key);
635 return NULL;
636}
637
638static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx)
639{
640 static const unsigned char generator_x[] = {
641 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
642 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
643 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
644 };
645 static const unsigned char generator_y[] = {
646 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
647 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
648 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
649 };
650 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
f3336f40 651 ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED25519, 1);
43cd3701
P
652 unsigned char *privkey = NULL, *pubkey;
653 unsigned int sz;
c1e48c51
P
654 EVP_MD *sha = NULL;
655 int j;
43cd3701
P
656
657 if (key == NULL) {
c1e48c51 658 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701
P
659 goto err;
660 }
661
662 pubkey = key->pubkey;
663
664 privkey = ecx_key_allocate_privkey(key);
665 if (privkey == NULL) {
c1e48c51 666 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701
P
667 goto err;
668 }
669
c1e48c51 670 if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED25519_KEYLEN) <= 0)
43cd3701
P
671 goto err;
672
c1e48c51
P
673 sha = EVP_MD_fetch(gctx->libctx, "SHA512", NULL);
674 if (sha == NULL)
675 goto err;
676 j = EVP_Digest(privkey, 32, buff, &sz, sha, NULL);
677 EVP_MD_free(sha);
678 if (!j)
43cd3701
P
679 goto err;
680
681 buff[0] &= 248;
682 buff[31] &= 63;
683 buff[31] |= 64;
684
685 if (s390x_ed25519_mul(x_dst, pubkey,
686 generator_x, generator_y, buff) != 1)
687 goto err;
688
689 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
690 return key;
691 err:
692 ecx_key_free(key);
693 return NULL;
694}
695
696static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx)
697{
698 static const unsigned char generator_x[] = {
699 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
700 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
701 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
702 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
703 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
704 };
705 static const unsigned char generator_y[] = {
706 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
707 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
708 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
709 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
710 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
711 };
712 unsigned char x_dst[57], buff[114];
f3336f40 713 ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED448, 1);
43cd3701
P
714 unsigned char *privkey = NULL, *pubkey;
715 EVP_MD_CTX *hashctx = NULL;
c1e48c51 716 EVP_MD *shake = NULL;
43cd3701
P
717
718 if (key == NULL) {
c1e48c51 719 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701
P
720 goto err;
721 }
722
723 pubkey = key->pubkey;
724
725 privkey = ecx_key_allocate_privkey(key);
726 if (privkey == NULL) {
c1e48c51 727 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701
P
728 goto err;
729 }
730
c1e48c51
P
731 shake = EVP_MD_fetch(gctx->libctx, "SHAKE256", NULL);
732 if (shake == NULL)
733 goto err;
734 if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED448_KEYLEN) <= 0)
43cd3701
P
735 goto err;
736
737 hashctx = EVP_MD_CTX_new();
738 if (hashctx == NULL)
739 goto err;
c1e48c51 740 if (EVP_DigestInit_ex(hashctx, shake, NULL) != 1)
43cd3701
P
741 goto err;
742 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
743 goto err;
744 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
745 goto err;
746
747 buff[0] &= -4;
748 buff[55] |= 0x80;
749 buff[56] = 0;
750
751 if (s390x_ed448_mul(x_dst, pubkey,
752 generator_x, generator_y, buff) != 1)
753 goto err;
754
755 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
43cd3701 756 EVP_MD_CTX_free(hashctx);
c1e48c51 757 EVP_MD_free(shake);
43cd3701
P
758 return key;
759 err:
760 ecx_key_free(key);
761 EVP_MD_CTX_free(hashctx);
c1e48c51 762 EVP_MD_free(shake);
43cd3701
P
763 return NULL;
764}
765#endif