]> git.ipfire.org Git - thirdparty/openssl.git/blame - providers/implementations/keymgmt/ecx_kmgmt.c
EVP: Fix EVP_Digest{Sign,Verify}Init() to handle no default digest
[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;
90d3cb57
MC
45static OSSL_OP_keymgmt_gettable_params_fn ecx_gettable_params;
46static OSSL_OP_keymgmt_has_fn ecx_has;
47static OSSL_OP_keymgmt_import_fn ecx_import;
48static OSSL_OP_keymgmt_import_types_fn ecx_imexport_types;
49static OSSL_OP_keymgmt_export_fn ecx_export;
50static OSSL_OP_keymgmt_export_types_fn ecx_imexport_types;
51
f552d900
SL
52#define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR)
53
43cd3701
P
54struct ecx_gen_ctx {
55 OPENSSL_CTX *libctx;
56 ECX_KEY_TYPE type;
57};
58
c1e48c51
P
59#ifdef S390X_EC_ASM
60static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx);
61static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx);
62static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx);
63static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx);
64#endif
43cd3701 65
90d3cb57
MC
66static void *x25519_new_key(void *provctx)
67{
244bc297 68 return ecx_key_new(ECX_KEY_TYPE_X25519, 0);
90d3cb57
MC
69}
70
71static void *x448_new_key(void *provctx)
72{
244bc297 73 return ecx_key_new(ECX_KEY_TYPE_X448, 0);
90d3cb57
MC
74}
75
af6d8dd3
MC
76static void *ed25519_new_key(void *provctx)
77{
244bc297 78 return ecx_key_new(ECX_KEY_TYPE_ED25519, 0);
af6d8dd3
MC
79}
80
81static void *ed448_new_key(void *provctx)
82{
244bc297 83 return ecx_key_new(ECX_KEY_TYPE_ED448, 0);
af6d8dd3
MC
84}
85
90d3cb57
MC
86static int ecx_has(void *keydata, int selection)
87{
88 ECX_KEY *key = keydata;
adc9f731 89 int ok = 0;
90d3cb57 90
adc9f731
RL
91 if (key != NULL) {
92 if ((selection & ECX_POSSIBLE_SELECTIONS) != 0)
93 ok = 1;
90d3cb57 94
adc9f731
RL
95 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
96 ok = ok && key->haspubkey;
90d3cb57 97
adc9f731
RL
98 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
99 ok = ok && key->privkey != NULL;
100 }
90d3cb57
MC
101 return ok;
102}
103
104static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[])
105{
106 ECX_KEY *key = keydata;
0abae163
RL
107 int ok = 1;
108 int include_private = 0;
90d3cb57
MC
109
110 if (key == NULL)
111 return 0;
112
f552d900 113 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0)
90d3cb57
MC
114 return 0;
115
0abae163
RL
116 include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
117 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
118 ok = ok && ecx_key_fromdata(key, params, include_private);
90d3cb57 119
0abae163 120 return ok;
90d3cb57
MC
121}
122
96ebe52e
SL
123static int key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl,
124 OSSL_PARAM params[])
90d3cb57
MC
125{
126 if (key == NULL)
127 return 0;
128
96ebe52e
SL
129 if (!ossl_param_build_set_octet_string(tmpl, params,
130 OSSL_PKEY_PARAM_PUB_KEY,
131 key->pubkey, key->keylen))
90d3cb57
MC
132 return 0;
133
134 if (key->privkey != NULL
96ebe52e
SL
135 && !ossl_param_build_set_octet_string(tmpl, params,
136 OSSL_PKEY_PARAM_PRIV_KEY,
137 key->privkey, key->keylen))
90d3cb57
MC
138 return 0;
139
140 return 1;
141}
142
143static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
144 void *cbarg)
145{
146 ECX_KEY *key = keydata;
6d4e6009 147 OSSL_PARAM_BLD *tmpl;
90d3cb57 148 OSSL_PARAM *params = NULL;
96ebe52e 149 int ret = 0;
90d3cb57
MC
150
151 if (key == NULL)
152 return 0;
153
6d4e6009
P
154 tmpl = OSSL_PARAM_BLD_new();
155 if (tmpl == NULL)
90d3cb57
MC
156 return 0;
157
6d4e6009 158 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0
96ebe52e
SL
159 && !key_to_params(key, tmpl, NULL))
160 goto err;
161
162 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0
163 && !key_to_params(key, tmpl, NULL))
164 goto err;
90d3cb57 165
6d4e6009 166 params = OSSL_PARAM_BLD_to_param(tmpl);
6d4e6009 167 if (params == NULL)
96ebe52e 168 goto err;
6d4e6009 169
90d3cb57 170 ret = param_cb(params, cbarg);
6d4e6009 171 OSSL_PARAM_BLD_free_params(params);
96ebe52e
SL
172err:
173 OSSL_PARAM_BLD_free(tmpl);
90d3cb57
MC
174 return ret;
175}
176
96ebe52e
SL
177#define ECX_KEY_TYPES() \
178OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \
179OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
180
90d3cb57 181static const OSSL_PARAM ecx_key_types[] = {
96ebe52e 182 ECX_KEY_TYPES(),
90d3cb57
MC
183 OSSL_PARAM_END
184};
185static const OSSL_PARAM *ecx_imexport_types(int selection)
186{
187 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
188 return ecx_key_types;
189 return NULL;
190}
191
96ebe52e 192static int ecx_get_params(void *key, OSSL_PARAM params[], int bits, int secbits,
90d3cb57
MC
193 int size)
194{
96ebe52e 195 ECX_KEY *ecx = key;
90d3cb57
MC
196 OSSL_PARAM *p;
197
198 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
199 && !OSSL_PARAM_set_int(p, bits))
200 return 0;
201 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
202 && !OSSL_PARAM_set_int(p, secbits))
203 return 0;
204 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
205 && !OSSL_PARAM_set_int(p, size))
206 return 0;
96ebe52e 207 return key_to_params(ecx, NULL, params);
90d3cb57
MC
208}
209
210static int x25519_get_params(void *key, OSSL_PARAM params[])
211{
96ebe52e
SL
212 return ecx_get_params(key, params, X25519_BITS, X25519_SECURITY_BITS,
213 X25519_KEYLEN);
90d3cb57
MC
214}
215
216static int x448_get_params(void *key, OSSL_PARAM params[])
217{
96ebe52e
SL
218 return ecx_get_params(key, params, X448_BITS, X448_SECURITY_BITS,
219 X448_KEYLEN);
90d3cb57
MC
220}
221
af6d8dd3
MC
222static int ed25519_get_params(void *key, OSSL_PARAM params[])
223{
96ebe52e
SL
224 return ecx_get_params(key, params, ED25519_BITS, ED25519_SECURITY_BITS,
225 ED25519_KEYLEN);
af6d8dd3
MC
226}
227
228static int ed448_get_params(void *key, OSSL_PARAM params[])
229{
96ebe52e
SL
230 return ecx_get_params(key, params, ED448_BITS, ED448_SECURITY_BITS,
231 ED448_KEYLEN);
af6d8dd3
MC
232}
233
90d3cb57
MC
234static const OSSL_PARAM ecx_params[] = {
235 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
236 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
237 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
96ebe52e 238 ECX_KEY_TYPES(),
90d3cb57
MC
239 OSSL_PARAM_END
240};
241
242static const OSSL_PARAM *ecx_gettable_params(void)
243{
244 return ecx_params;
245}
246
43cd3701
P
247static void *ecx_gen_init(void *provctx, int selection, ECX_KEY_TYPE type)
248{
249 OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
250 struct ecx_gen_ctx *gctx = NULL;
251
252 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
253 return NULL;
254
255 if ((gctx = OPENSSL_malloc(sizeof(*gctx))) != NULL) {
256 gctx->libctx = libctx;
257 gctx->type = type;
258 }
259 return gctx;
260}
261
262static void *x25519_gen_init(void *provctx, int selection)
263{
264 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_X25519);
265}
266
267static void *x448_gen_init(void *provctx, int selection)
268{
269 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_X448);
270}
271
272static void *ed25519_gen_init(void *provctx, int selection)
273{
274 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_ED25519);
275}
276
277static void *ed448_gen_init(void *provctx, int selection)
278{
279 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_ED448);
280}
281
282static void *ecx_gen(struct ecx_gen_ctx *gctx)
283{
284 ECX_KEY *key;
285 unsigned char *privkey;
286
c1e48c51
P
287 if (gctx == NULL)
288 return NULL;
289 if ((key = ecx_key_new(gctx->type, 0)) == NULL) {
290 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701 291 return NULL;
c1e48c51
P
292 }
293 if ((privkey = ecx_key_allocate_privkey(key)) == NULL) {
294 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
295 goto err;
296 }
297 if (RAND_priv_bytes_ex(gctx->libctx, privkey, key->keylen) <= 0)
43cd3701
P
298 goto err;
299 switch (gctx->type) {
300 case ECX_KEY_TYPE_X25519:
301 privkey[0] &= 248;
302 privkey[X25519_KEYLEN - 1] &= 127;
303 privkey[X25519_KEYLEN - 1] |= 64;
304 X25519_public_from_private(key->pubkey, privkey);
305 break;
306 case ECX_KEY_TYPE_X448:
307 privkey[0] &= 252;
308 privkey[X448_KEYLEN - 1] |= 128;
309 X448_public_from_private(key->pubkey, privkey);
310 break;
311 case ECX_KEY_TYPE_ED25519:
312 if (!ED25519_public_from_private(gctx->libctx, key->pubkey, privkey))
313 goto err;
314 break;
315 case ECX_KEY_TYPE_ED448:
316 if (!ED448_public_from_private(gctx->libctx, key->pubkey, privkey))
317 goto err;
318 break;
319 }
320 return key;
321err:
322 ecx_key_free(key);
323 return NULL;
324}
325
326static void *x25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
327{
328 struct ecx_gen_ctx *gctx = genctx;
329
330#ifdef S390X_EC_ASM
331 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
332 return s390x_ecx_keygen25519(gctx);
333#endif
334 return ecx_gen(gctx);
335}
336
337static void *x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
338{
339 struct ecx_gen_ctx *gctx = genctx;
340
341#ifdef S390X_EC_ASM
342 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
343 return s390x_ecx_keygen448(gctx);
344#endif
345 return ecx_gen(gctx);
346}
347
348static void *ed25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
349{
350 struct ecx_gen_ctx *gctx = genctx;
351#ifdef S390X_EC_ASM
352 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
353 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
354 && OPENSSL_s390xcap_P.kdsa[0]
355 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
356 return s390x_ecd_keygen25519(gctx);
357#endif
358 return ecx_gen(gctx);
359}
360
361static void *ed448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
362{
363 struct ecx_gen_ctx *gctx = genctx;
364
365#ifdef S390X_EC_ASM
366 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
367 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
368 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
369 return s390x_ecd_keygen448(gctx);
370#endif
371 return ecx_gen(gctx);
372}
373
374static void ecx_gen_cleanup(void *genctx)
375{
376 struct ecx_gen_ctx *gctx = genctx;
377
378 OPENSSL_free(gctx);
379}
380
af6d8dd3
MC
381#define MAKE_KEYMGMT_FUNCTIONS(alg) \
382 const OSSL_DISPATCH alg##_keymgmt_functions[] = { \
383 { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \
384 { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ecx_key_free }, \
385 { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))alg##_get_params }, \
386 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))ecx_gettable_params }, \
387 { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has }, \
388 { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import }, \
389 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
390 { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ecx_export }, \
391 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
43cd3701
P
392 { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))alg##_gen_init }, \
393 { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen }, \
394 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \
af6d8dd3
MC
395 { 0, NULL } \
396 };
397
398MAKE_KEYMGMT_FUNCTIONS(x25519)
399MAKE_KEYMGMT_FUNCTIONS(x448)
400MAKE_KEYMGMT_FUNCTIONS(ed25519)
401MAKE_KEYMGMT_FUNCTIONS(ed448)
43cd3701
P
402
403#ifdef S390X_EC_ASM
404# include "s390x_arch.h"
43cd3701
P
405
406static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx)
407{
408 static const unsigned char generator[] = {
409 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
412 };
413 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X25519, 1);
414 unsigned char *privkey = NULL, *pubkey;
415
416 if (key == NULL) {
c1e48c51 417 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701
P
418 goto err;
419 }
420
421 pubkey = key->pubkey;
422
423 privkey = ecx_key_allocate_privkey(key);
424 if (privkey == NULL) {
c1e48c51 425 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701
P
426 goto err;
427 }
428
c1e48c51 429 if (RAND_priv_bytes_ex(gctx->libctx, privkey, X25519_KEYLEN) <= 0)
43cd3701
P
430 goto err;
431
432 privkey[0] &= 248;
433 privkey[31] &= 127;
434 privkey[31] |= 64;
435
436 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
437 goto err;
43cd3701
P
438 return key;
439 err:
440 ecx_key_free(key);
441 return NULL;
442}
443
444static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx)
445{
446 static const unsigned char generator[] = {
447 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
448 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
449 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
451 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
452 };
453 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X448, 1);
454 unsigned char *privkey = NULL, *pubkey;
455
456 if (key == NULL) {
c1e48c51 457 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701
P
458 goto err;
459 }
460
461 pubkey = key->pubkey;
462
463 privkey = ecx_key_allocate_privkey(key);
464 if (privkey == NULL) {
c1e48c51 465 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701
P
466 goto err;
467 }
468
c1e48c51 469 if (RAND_priv_bytes_ex(gctx->libctx, privkey, X448_KEYLEN) <= 0)
43cd3701
P
470 goto err;
471
472 privkey[0] &= 252;
473 privkey[55] |= 128;
474
475 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
476 goto err;
43cd3701
P
477 return key;
478 err:
479 ecx_key_free(key);
480 return NULL;
481}
482
483static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx)
484{
485 static const unsigned char generator_x[] = {
486 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
487 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
488 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
489 };
490 static const unsigned char generator_y[] = {
491 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
492 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
493 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
494 };
495 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
496 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED25519, 1);
497 unsigned char *privkey = NULL, *pubkey;
498 unsigned int sz;
c1e48c51
P
499 EVP_MD *sha = NULL;
500 int j;
43cd3701
P
501
502 if (key == NULL) {
c1e48c51 503 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701
P
504 goto err;
505 }
506
507 pubkey = key->pubkey;
508
509 privkey = ecx_key_allocate_privkey(key);
510 if (privkey == NULL) {
c1e48c51 511 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701
P
512 goto err;
513 }
514
c1e48c51 515 if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED25519_KEYLEN) <= 0)
43cd3701
P
516 goto err;
517
c1e48c51
P
518 sha = EVP_MD_fetch(gctx->libctx, "SHA512", NULL);
519 if (sha == NULL)
520 goto err;
521 j = EVP_Digest(privkey, 32, buff, &sz, sha, NULL);
522 EVP_MD_free(sha);
523 if (!j)
43cd3701
P
524 goto err;
525
526 buff[0] &= 248;
527 buff[31] &= 63;
528 buff[31] |= 64;
529
530 if (s390x_ed25519_mul(x_dst, pubkey,
531 generator_x, generator_y, buff) != 1)
532 goto err;
533
534 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
535 return key;
536 err:
537 ecx_key_free(key);
538 return NULL;
539}
540
541static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx)
542{
543 static const unsigned char generator_x[] = {
544 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
545 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
546 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
547 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
548 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
549 };
550 static const unsigned char generator_y[] = {
551 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
552 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
553 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
554 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
555 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
556 };
557 unsigned char x_dst[57], buff[114];
558 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED448, 1);
559 unsigned char *privkey = NULL, *pubkey;
560 EVP_MD_CTX *hashctx = NULL;
c1e48c51 561 EVP_MD *shake = NULL;
43cd3701
P
562
563 if (key == NULL) {
c1e48c51 564 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701
P
565 goto err;
566 }
567
568 pubkey = key->pubkey;
569
570 privkey = ecx_key_allocate_privkey(key);
571 if (privkey == NULL) {
c1e48c51 572 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
43cd3701
P
573 goto err;
574 }
575
c1e48c51
P
576 shake = EVP_MD_fetch(gctx->libctx, "SHAKE256", NULL);
577 if (shake == NULL)
578 goto err;
579 if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED448_KEYLEN) <= 0)
43cd3701
P
580 goto err;
581
582 hashctx = EVP_MD_CTX_new();
583 if (hashctx == NULL)
584 goto err;
c1e48c51 585 if (EVP_DigestInit_ex(hashctx, shake, NULL) != 1)
43cd3701
P
586 goto err;
587 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
588 goto err;
589 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
590 goto err;
591
592 buff[0] &= -4;
593 buff[55] |= 0x80;
594 buff[56] = 0;
595
596 if (s390x_ed448_mul(x_dst, pubkey,
597 generator_x, generator_y, buff) != 1)
598 goto err;
599
600 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
43cd3701 601 EVP_MD_CTX_free(hashctx);
c1e48c51 602 EVP_MD_free(shake);
43cd3701
P
603 return key;
604 err:
605 ecx_key_free(key);
606 EVP_MD_CTX_free(hashctx);
c1e48c51 607 EVP_MD_free(shake);
43cd3701
P
608 return NULL;
609}
610#endif