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