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
101200 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))
337
!= NULL
338
&& !OSSL_PARAM_set_utf8_string(p, ""))
339
return 0;
340
return 1;
341
}
342
343
static int x25519_get_params(void *key, OSSL_PARAM params[])
344
{
345
return ecx_get_params(key, params, X25519_BITS, X25519_SECURITY_BITS,
346
X25519_KEYLEN);
347
}
348
349
static int x448_get_params(void *key, OSSL_PARAM params[])
350
{
351
return ecx_get_params(key, params, X448_BITS, X448_SECURITY_BITS,
352
X448_KEYLEN);
353
}
354
355
static int ed25519_get_params(void *key, OSSL_PARAM params[])
356
{
357
return ecx_get_params(key, params, ED25519_BITS, ED25519_SECURITY_BITS,
358
ED25519_SIGSIZE)
359
&& ed_get_params(key, params);
360
}
361
362
static int ed448_get_params(void *key, OSSL_PARAM params[])
363
{
364
return ecx_get_params(key, params, ED448_BITS, ED448_SECURITY_BITS,
365
ED448_SIGSIZE)
366
&& ed_get_params(key, params);
367
}
368
369
static const OSSL_PARAM ecx_gettable_params[] = {
370
OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
371
OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
372
OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
373
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
374
ECX_KEY_TYPES(),
375
OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
376
OSSL_PARAM_END
377
};
378
379
static const OSSL_PARAM ed_gettable_params[] = {
380
OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
381
OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
382
OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
383
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0),
384
ECX_KEY_TYPES(),
385
OSSL_PARAM_END
386
};
387
388
static const OSSL_PARAM *x25519_gettable_params(void *provctx)
389
{
390
return ecx_gettable_params;
391
}
392
393
static const OSSL_PARAM *x448_gettable_params(void *provctx)
394
{
395
return ecx_gettable_params;
396
}
397
398
static const OSSL_PARAM *ed25519_gettable_params(void *provctx)
399
{
400
return ed_gettable_params;
401
}
402
403
static const OSSL_PARAM *ed448_gettable_params(void *provctx)
404
{
405
return ed_gettable_params;
406
}
407
408
static int set_property_query(ECX_KEY *ecxkey, const char *propq)
409
{
410
OPENSSL_free(ecxkey->propq);
411
ecxkey->propq = NULL;
412
if (propq != NULL) {
413
ecxkey->propq = OPENSSL_strdup(propq);
414
if (ecxkey->propq == NULL)
415
return 0;
416
}
417
return 1;
418
}
419
420
static int ecx_set_params(void *key, const OSSL_PARAM params[])
421
{
422
ECX_KEY *ecxkey = key;
423
const OSSL_PARAM *p;
424
425
if (ossl_param_is_empty(params))
426
return 1;
427
428
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);
429
if (p != NULL) {
430
void *buf = ecxkey->pubkey;
431
432
if (p->data_size != ecxkey->keylen
433
|| !OSSL_PARAM_get_octet_string(p, &buf, sizeof(ecxkey->pubkey),
434
NULL))
435
return 0;
436
OPENSSL_clear_free(ecxkey->privkey, ecxkey->keylen);
437
ecxkey->privkey = NULL;
438
ecxkey->haspubkey = 1;
439
}
440
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PROPERTIES);
441
if (p != NULL) {
442
if (p->data_type != OSSL_PARAM_UTF8_STRING
443
|| !set_property_query(ecxkey, p->data))
444
return 0;
445
}
446
447
return 1;
448
}
449
450
static int x25519_set_params(void *key, const OSSL_PARAM params[])
451
{
452
return ecx_set_params(key, params);
453
}
454
455
static int x448_set_params(void *key, const OSSL_PARAM params[])
456
{
457
return ecx_set_params(key, params);
458
}
459
460
static int ed25519_set_params(void *key, const OSSL_PARAM params[])
461
{
462
return 1;
463
}
464
465
static int ed448_set_params(void *key, const OSSL_PARAM params[])
466
{
467
return 1;
468
}
469
470
static const OSSL_PARAM ecx_settable_params[] = {
471
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
472
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0),
473
OSSL_PARAM_END
474
};
475
476
static const OSSL_PARAM ed_settable_params[] = {
477
OSSL_PARAM_END
478
};
479
480
static const OSSL_PARAM *x25519_settable_params(void *provctx)
481
{
482
return ecx_settable_params;
483
}
484
485
static const OSSL_PARAM *x448_settable_params(void *provctx)
486
{
487
return ecx_settable_params;
488
}
489
490
static const OSSL_PARAM *ed25519_settable_params(void *provctx)
491
{
492
return ed_settable_params;
493
}
494
495
static const OSSL_PARAM *ed448_settable_params(void *provctx)
496
{
497
return ed_settable_params;
498
}
499
500
static void *ecx_gen_init(void *provctx, int selection,
501
const OSSL_PARAM params[], ECX_KEY_TYPE type,
502
const char *algdesc)
503
{
504
OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);
505
struct ecx_gen_ctx *gctx = NULL;
506
507
if (!ossl_prov_is_running())
508
return NULL;
509
510
if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
511
gctx->libctx = libctx;
512
gctx->type = type;
513
gctx->selection = selection;
514
#ifdef FIPS_MODULE
515
/* X25519/X448 are not FIPS approved, (ED25519/ED448 are approved) */
516
if (algdesc != NULL
517
&& !ossl_FIPS_IND_callback(libctx, algdesc, "KeyGen Init")) {
518
OPENSSL_free(gctx);
519
return NULL;
520
}
521
#endif
522
} else {
523
return NULL;
524
}
525
if (!ecx_gen_set_params(gctx, params)) {
526
ecx_gen_cleanup(gctx);
527
gctx = NULL;
528
}
529
return gctx;
530
}
531
532
static void *x25519_gen_init(void *provctx, int selection,
533
const OSSL_PARAM params[])
534
{
535
return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X25519, "X25519");
536
}
537
538
static void *x448_gen_init(void *provctx, int selection,
539
const OSSL_PARAM params[])
540
{
541
return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X448, "X448");
542
}
543
544
static void *ed25519_gen_init(void *provctx, int selection,
545
const OSSL_PARAM params[])
546
{
547
return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_ED25519, NULL);
548
}
549
550
static void *ed448_gen_init(void *provctx, int selection,
551
const OSSL_PARAM params[])
552
{
553
return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_ED448, NULL);
554
}
555
556
static int ecx_gen_set_params(void *genctx, const OSSL_PARAM params[])
557
{
558
struct ecx_gen_ctx *gctx = genctx;
559
const OSSL_PARAM *p;
560
561
if (gctx == NULL)
562
return 0;
563
564
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME);
565
if (p != NULL) {
566
const char *groupname = NULL;
567
568
/*
569
* We optionally allow setting a group name - but each algorithm only
570
* support one such name, so all we do is verify that it is the one we
571
* expected.
572
*/
573
switch (gctx->type) {
574
case ECX_KEY_TYPE_X25519:
575
groupname = "x25519";
576
break;
577
case ECX_KEY_TYPE_X448:
578
groupname = "x448";
579
break;
580
default:
581
/* We only support this for key exchange at the moment */
582
break;
583
}
584
if (p->data_type != OSSL_PARAM_UTF8_STRING
585
|| groupname == NULL
586
|| OPENSSL_strcasecmp(p->data, groupname) != 0) {
587
ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
588
return 0;
589
}
590
}
591
p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES);
592
if (p != NULL) {
593
if (p->data_type != OSSL_PARAM_UTF8_STRING)
594
return 0;
595
OPENSSL_free(gctx->propq);
596
gctx->propq = OPENSSL_strdup(p->data);
597
if (gctx->propq == NULL)
598
return 0;
599
}
600
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DHKEM_IKM);
601
if (p != NULL) {
602
if (p->data_size != 0 && p->data != NULL) {
603
OPENSSL_free(gctx->dhkem_ikm);
604
gctx->dhkem_ikm = NULL;
605
if (!OSSL_PARAM_get_octet_string(p, (void **)&gctx->dhkem_ikm, 0,
606
&gctx->dhkem_ikmlen))
607
return 0;
608
}
609
}
610
611
return 1;
612
}
613
614
static const OSSL_PARAM *ecx_gen_settable_params(ossl_unused void *genctx,
615
ossl_unused void *provctx)
616
{
617
static OSSL_PARAM settable[] = {
618
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
619
OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
620
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM, NULL, 0),
621
OSSL_PARAM_END
622
};
623
return settable;
624
}
625
626
#ifdef FIPS_MODULE
627
/*
628
* Refer: FIPS 140-3 IG 10.3.A Additional Comment 1
629
* Perform a pairwise test for EDDSA by signing and verifying signature.
630
*
631
* The parameter `self_test` is used to indicate whether to create OSSL_SELF_TEST
632
* instance.
633
*/
634
static int ecd_fips140_pairwise_test(const ECX_KEY *ecx, int type, int self_test)
635
{
636
int ret = 0;
637
OSSL_SELF_TEST *st = NULL;
638
OSSL_CALLBACK *cb = NULL;
639
void *cbarg = NULL;
640
641
unsigned char msg[16] = { 0 };
642
size_t msg_len = sizeof(msg);
643
unsigned char sig[ED448_SIGSIZE] = { 0 };
644
645
int is_ed25519 = (type == ECX_KEY_TYPE_ED25519) ? 1 : 0;
646
int operation_result = 0;
647
648
/*
649
* The functions `OSSL_SELF_TEST_*` will return directly if parameter `st`
650
* is NULL.
651
*/
652
if (self_test) {
653
OSSL_SELF_TEST_get_callback(ecx->libctx, &cb, &cbarg);
654
655
st = OSSL_SELF_TEST_new(cb, cbarg);
656
if (st == NULL)
657
return 0;
658
}
659
660
OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
661
OSSL_SELF_TEST_DESC_PCT_EDDSA);
662
663
if (is_ed25519)
664
operation_result = ossl_ed25519_sign(sig, msg, msg_len, ecx->pubkey,
665
ecx->privkey, 0, 0, 0, NULL, 0,
666
ecx->libctx, ecx->propq);
667
else
668
operation_result = ossl_ed448_sign(ecx->libctx, sig, msg, msg_len,
669
ecx->pubkey, ecx->privkey, NULL, 0,
670
0, ecx->propq);
671
if (operation_result != 1)
672
goto err;
673
674
OSSL_SELF_TEST_oncorrupt_byte(st, sig);
675
676
if (is_ed25519)
677
operation_result = ossl_ed25519_verify(msg, msg_len, sig, ecx->pubkey,
678
0, 0, 0, NULL, 0, ecx->libctx,
679
ecx->propq);
680
else
681
operation_result = ossl_ed448_verify(ecx->libctx, msg, msg_len, sig,
682
ecx->pubkey, NULL, 0, 0, ecx->propq);
683
if (operation_result != 1)
684
goto err;
685
686
ret = 1;
687
err:
688
OSSL_SELF_TEST_onend(st, ret);
689
OSSL_SELF_TEST_free(st);
690
return ret;
691
}
692
#endif
693
694
static void *ecx_gen(struct ecx_gen_ctx *gctx)
695
{
696
ECX_KEY *key;
697
unsigned char *privkey;
698
699
if (gctx == NULL)
700
return NULL;
701
if ((key = ossl_ecx_key_new(gctx->libctx, gctx->type, 0,
702
gctx->propq))
703
== NULL) {
704
ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
705
return NULL;
706
}
707
708
/* If we're doing parameter generation then we just return a blank key */
709
if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
710
return key;
711
712
if ((privkey = ossl_ecx_key_allocate_privkey(key)) == NULL) {
713
ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
714
goto err;
715
}
716
#ifndef FIPS_MODULE
717
if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) {
718
if (ecx_key_type_is_ed(gctx->type))
719
goto err;
720
if (!ossl_ecx_dhkem_derive_private(key, privkey,
721
gctx->dhkem_ikm, gctx->dhkem_ikmlen))
722
goto err;
723
} else
724
#endif
725
{
726
if (RAND_priv_bytes_ex(gctx->libctx, privkey, key->keylen, 0) <= 0)
727
goto err;
728
}
729
730
switch (gctx->type) {
731
case ECX_KEY_TYPE_X25519:
732
privkey[0] &= 248;
733
privkey[X25519_KEYLEN - 1] &= 127;
734
privkey[X25519_KEYLEN - 1] |= 64;
735
ossl_x25519_public_from_private(key->pubkey, privkey);
736
break;
737
case ECX_KEY_TYPE_X448:
738
privkey[0] &= 252;
739
privkey[X448_KEYLEN - 1] |= 128;
740
ossl_x448_public_from_private(key->pubkey, privkey);
741
break;
742
case ECX_KEY_TYPE_ED25519:
743
if (!ossl_ed25519_public_from_private(gctx->libctx, key->pubkey, privkey,
744
gctx->propq))
745
goto err;
746
break;
747
case ECX_KEY_TYPE_ED448:
748
if (!ossl_ed448_public_from_private(gctx->libctx, key->pubkey, privkey,
749
gctx->propq))
750
goto err;
751
break;
752
}
753
key->haspubkey = 1;
754
return key;
755
err:
756
ossl_ecx_key_free(key);
757
return NULL;
758
}
759
760
static void *x25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
761
{
762
struct ecx_gen_ctx *gctx = genctx;
763
764
if (!ossl_prov_is_running())
765
return 0;
766
767
#ifdef S390X_EC_ASM
768
if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
769
return s390x_ecx_keygen25519(gctx);
770
#endif
771
return ecx_gen(gctx);
772
}
773
774
static void *x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
775
{
776
struct ecx_gen_ctx *gctx = genctx;
777
778
if (!ossl_prov_is_running())
779
return 0;
780
781
#ifdef S390X_EC_ASM
782
if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
783
return s390x_ecx_keygen448(gctx);
784
#endif
785
return ecx_gen(gctx);
786
}
787
788
static void *ed25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
789
{
790
ECX_KEY *key = NULL;
791
struct ecx_gen_ctx *gctx = genctx;
792
793
if (!ossl_prov_is_running())
794
return 0;
795
796
#ifdef S390X_EC_ASM
797
if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
798
&& OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
799
&& OPENSSL_s390xcap_P.kdsa[0]
800
& S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519)) {
801
key = s390x_ecd_keygen25519(gctx);
802
} else
803
#endif
804
{
805
key = ecx_gen(gctx);
806
}
807
808
#ifdef FIPS_MODULE
809
/* Exit if keygen failed OR we are doing parameter generation (blank key) */
810
if (!key || ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0))
811
return key;
812
if (ecd_fips140_pairwise_test(key, ECX_KEY_TYPE_ED25519, 1) != 1) {
813
ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
814
ossl_ecx_key_free(key);
815
return NULL;
816
}
817
#endif
818
819
return key;
820
}
821
822
static void *ed448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
823
{
824
ECX_KEY *key = NULL;
825
struct ecx_gen_ctx *gctx = genctx;
826
827
if (!ossl_prov_is_running())
828
return 0;
829
830
#ifdef S390X_EC_ASM
831
if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
832
&& OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
833
&& OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448)) {
834
key = s390x_ecd_keygen448(gctx);
835
} else
836
#endif
837
{
838
key = ecx_gen(gctx);
839
}
840
841
#ifdef FIPS_MODULE
842
/* Exit if keygen failed OR we are doing parameter generation (blank key) */
843
if (!key || ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0))
844
return key;
845
if (ecd_fips140_pairwise_test(key, ECX_KEY_TYPE_ED448, 1) != 1) {
846
ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
847
ossl_ecx_key_free(key);
848
return NULL;
849
}
850
#endif
851
852
return key;
853
}
854
855
static void ecx_gen_cleanup(void *genctx)
856
{
857
struct ecx_gen_ctx *gctx = genctx;
858
859
if (gctx == NULL)
860
return;
861
862
OPENSSL_clear_free(gctx->dhkem_ikm, gctx->dhkem_ikmlen);
863
OPENSSL_free(gctx->propq);
864
OPENSSL_free(gctx);
865
}
866
867
void *ecx_load(const void *reference, size_t reference_sz)
868
{
869
ECX_KEY *key = NULL;
870
871
if (ossl_prov_is_running() && reference_sz == sizeof(key)) {
872
/* The contents of the reference is the address to our object */
873
key = *(ECX_KEY **)reference;
874
/* We grabbed, so we detach it */
875
*(ECX_KEY **)reference = NULL;
876
return key;
877
}
878
return NULL;
879
}
880
881
static void *ecx_dup(const void *keydata_from, int selection)
882
{
883
if (ossl_prov_is_running())
884
return ossl_ecx_key_dup(keydata_from, selection);
885
return NULL;
886
}
887
888
static int ecx_key_pairwise_check(const ECX_KEY *ecx, int type)
889
{
890
uint8_t pub[64];
891
892
switch (type) {
893
case ECX_KEY_TYPE_X25519:
894
ossl_x25519_public_from_private(pub, ecx->privkey);
895
break;
896
case ECX_KEY_TYPE_X448:
897
ossl_x448_public_from_private(pub, ecx->privkey);
898
break;
899
default:
900
return 0;
901
}
902
return CRYPTO_memcmp(ecx->pubkey, pub, ecx->keylen) == 0;
903
}
904
905
#ifdef FIPS_MODULE
906
/*
907
* FIPS ACVP testing requires the ability to check if the public key is valid
908
* This is not required normally since the ED signature verify does the test
909
* internally.
910
*/
911
static int ecd_key_pub_check(const ECX_KEY *ecx, int type)
912
{
913
switch (type) {
914
case ECX_KEY_TYPE_ED25519:
915
return ossl_ed25519_pubkey_verify(ecx->pubkey, ecx->keylen);
916
case ECX_KEY_TYPE_ED448:
917
return ossl_ed448_pubkey_verify(ecx->pubkey, ecx->keylen);
918
default:
919
return 1;
920
}
921
}
922
#endif
923
924
#ifdef FIPS_MODULE
925
static int ecd_key_pairwise_check(const ECX_KEY *ecx, int type)
926
{
927
return ecd_fips140_pairwise_test(ecx, type, 0);
928
}
929
#else
930
static int ecd_key_pairwise_check(const ECX_KEY *ecx, int type)
931
{
932
uint8_t pub[64];
933
934
switch (type) {
935
case ECX_KEY_TYPE_ED25519:
936
if (!ossl_ed25519_public_from_private(ecx->libctx, pub, ecx->privkey,
937
ecx->propq))
938
return 0;
939
break;
940
case ECX_KEY_TYPE_ED448:
941
if (!ossl_ed448_public_from_private(ecx->libctx, pub, ecx->privkey,
942
ecx->propq))
943
return 0;
944
break;
945
default:
946
return 0;
947
}
948
return CRYPTO_memcmp(ecx->pubkey, pub, ecx->keylen) == 0;
949
}
950
#endif
951
952
static int ecx_validate(const void *keydata, int selection, int type,
953
size_t keylen)
954
{
955
const ECX_KEY *ecx = keydata;
956
int ok = keylen == ecx->keylen;
957
958
if (!ossl_prov_is_running())
959
return 0;
960
961
if ((selection & ECX_POSSIBLE_SELECTIONS) == 0)
962
return 1; /* nothing to validate */
963
964
if (!ok) {
965
ERR_raise(ERR_LIB_PROV, PROV_R_ALGORITHM_MISMATCH);
966
return 0;
967
}
968
969
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
970
ok = ok && ecx->haspubkey;
971
#ifdef FIPS_MODULE
972
ok = ok && ecd_key_pub_check(ecx, type);
973
#endif
974
}
975
976
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
977
ok = ok && ecx->privkey != NULL;
978
979
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != OSSL_KEYMGMT_SELECT_KEYPAIR)
980
return ok;
981
982
if (ecx_key_type_is_ed(type))
983
ok = ok && ecd_key_pairwise_check(ecx, type);
984
else
985
ok = ok && ecx_key_pairwise_check(ecx, type);
986
987
return ok;
988
}
989
990
static int x25519_validate(const void *keydata, int selection, int checktype)
991
{
992
return ecx_validate(keydata, selection, ECX_KEY_TYPE_X25519, X25519_KEYLEN);
993
}
994
995
static int x448_validate(const void *keydata, int selection, int checktype)
996
{
997
return ecx_validate(keydata, selection, ECX_KEY_TYPE_X448, X448_KEYLEN);
998
}
999
1000
static int ed25519_validate(const void *keydata, int selection, int checktype)
1001
{
1002
return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED25519, ED25519_KEYLEN);
1003
}
1004
1005
static int ed448_validate(const void *keydata, int selection, int checktype)
1006
{
1007
return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED448, ED448_KEYLEN);
1008
}
1009
1010
#define MAKE_KEYMGMT_FUNCTIONS(alg) \
1011
const OSSL_DISPATCH ossl_##alg##_keymgmt_functions[] = { \
1012
{ OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \
1013
{ OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ossl_ecx_key_free }, \
1014
{ OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))alg##_get_params }, \
1015
{ OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))alg##_gettable_params }, \
1016
{ OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*)(void))alg##_set_params }, \
1017
{ OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*)(void))alg##_settable_params }, \
1018
{ OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has }, \
1019
{ OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ecx_match }, \
1020
{ OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))alg##_validate }, \
1021
{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import }, \
1022
{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
1023
{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ecx_export }, \
1024
{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
1025
{ OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))alg##_gen_init }, \
1026
{ OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ecx_gen_set_params }, \
1027
{ OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, \
1028
(void (*)(void))ecx_gen_settable_params }, \
1029
{ OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen }, \
1030
{ OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \
1031
{ OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ecx_load }, \
1032
{ OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ecx_dup }, \
1033
OSSL_DISPATCH_END \
1034
};
1035
1036
MAKE_KEYMGMT_FUNCTIONS(x25519)
1037
MAKE_KEYMGMT_FUNCTIONS(x448)
1038
MAKE_KEYMGMT_FUNCTIONS(ed25519)
1039
MAKE_KEYMGMT_FUNCTIONS(ed448)
1040
1041
#ifdef S390X_EC_ASM
1042
#include "s390x_arch.h"
1043
1044
static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx)
1045
{
1046
static const unsigned char generator[] = {
1047
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1048
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1049
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1050
};
1051
ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X25519, 1,
1052
gctx->propq);
1053
unsigned char *privkey = NULL, *pubkey;
1054
1055
if (key == NULL) {
1056
ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1057
goto err;
1058
}
1059
1060
/* If we're doing parameter generation then we just return a blank key */
1061
if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1062
return key;
1063
1064
pubkey = key->pubkey;
1065
1066
privkey = ossl_ecx_key_allocate_privkey(key);
1067
if (privkey == NULL) {
1068
ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1069
goto err;
1070
}
1071
1072
#ifndef FIPS_MODULE
1073
if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) {
1074
if (gctx->type != ECX_KEY_TYPE_X25519)
1075
goto err;
1076
if (!ossl_ecx_dhkem_derive_private(key, privkey,
1077
gctx->dhkem_ikm, gctx->dhkem_ikmlen))
1078
goto err;
1079
} else
1080
#endif
1081
{
1082
if (RAND_priv_bytes_ex(gctx->libctx, privkey, X25519_KEYLEN, 0) <= 0)
1083
goto err;
1084
}
1085
1086
privkey[0] &= 248;
1087
privkey[31] &= 127;
1088
privkey[31] |= 64;
1089
1090
if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
1091
goto err;
1092
key->haspubkey = 1;
1093
return key;
1094
err:
1095
ossl_ecx_key_free(key);
1096
return NULL;
1097
}
1098
1099
static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx)
1100
{
1101
static const unsigned char generator[] = {
1102
0x05, 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, 0x00, 0x00, 0x00, 0x00,
1105
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1106
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1107
};
1108
ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X448, 1,
1109
gctx->propq);
1110
unsigned char *privkey = NULL, *pubkey;
1111
1112
if (key == NULL) {
1113
ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1114
goto err;
1115
}
1116
1117
/* If we're doing parameter generation then we just return a blank key */
1118
if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1119
return key;
1120
1121
pubkey = key->pubkey;
1122
1123
privkey = ossl_ecx_key_allocate_privkey(key);
1124
if (privkey == NULL) {
1125
ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1126
goto err;
1127
}
1128
1129
#ifndef FIPS_MODULE
1130
if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) {
1131
if (gctx->type != ECX_KEY_TYPE_X448)
1132
goto err;
1133
if (!ossl_ecx_dhkem_derive_private(key, privkey,
1134
gctx->dhkem_ikm, gctx->dhkem_ikmlen))
1135
goto err;
1136
} else
1137
#endif
1138
{
1139
if (RAND_priv_bytes_ex(gctx->libctx, privkey, X448_KEYLEN, 0) <= 0)
1140
goto err;
1141
}
1142
1143
privkey[0] &= 252;
1144
privkey[55] |= 128;
1145
1146
if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1147
goto err;
1148
key->haspubkey = 1;
1149
return key;
1150
err:
1151
ossl_ecx_key_free(key);
1152
return NULL;
1153
}
1154
1155
static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx)
1156
{
1157
static const unsigned char generator_x[] = {
1158
0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1159
0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1160
0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1161
};
1162
static const unsigned char generator_y[] = {
1163
0x58,
1164
0x66,
1165
0x66,
1166
0x66,
1167
0x66,
1168
0x66,
1169
0x66,
1170
0x66,
1171
0x66,
1172
0x66,
1173
0x66,
1174
0x66,
1175
0x66,
1176
0x66,
1177
0x66,
1178
0x66,
1179
0x66,
1180
0x66,
1181
0x66,
1182
0x66,
1183
0x66,
1184
0x66,
1185
0x66,
1186
0x66,
1187
0x66,
1188
0x66,
1189
0x66,
1190
0x66,
1191
0x66,
1192
0x66,
1193
0x66,
1194
0x66,
1195
};
1196
unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1197
ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED25519, 1,
1198
gctx->propq);
1199
unsigned char *privkey = NULL, *pubkey;
1200
unsigned int sz;
1201
EVP_MD *sha = NULL;
1202
int j;
1203
1204
if (key == NULL) {
1205
ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1206
goto err;
1207
}
1208
1209
/* If we're doing parameter generation then we just return a blank key */
1210
if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1211
return key;
1212
1213
pubkey = key->pubkey;
1214
1215
privkey = ossl_ecx_key_allocate_privkey(key);
1216
if (privkey == NULL) {
1217
ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1218
goto err;
1219
}
1220
1221
if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED25519_KEYLEN, 0) <= 0)
1222
goto err;
1223
1224
sha = EVP_MD_fetch(gctx->libctx, "SHA512", gctx->propq);
1225
if (sha == NULL)
1226
goto err;
1227
j = EVP_Digest(privkey, 32, buff, &sz, sha, NULL);
1228
EVP_MD_free(sha);
1229
if (!j)
1230
goto err;
1231
1232
buff[0] &= 248;
1233
buff[31] &= 63;
1234
buff[31] |= 64;
1235
1236
if (s390x_ed25519_mul(x_dst, pubkey,
1237
generator_x, generator_y, buff)
1238
!= 1)
1239
goto err;
1240
1241
pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1242
key->haspubkey = 1;
1243
return key;
1244
err:
1245
ossl_ecx_key_free(key);
1246
return NULL;
1247
}
1248
1249
static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx)
1250
{
1251
static const unsigned char generator_x[] = {
1252
0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1253
0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1254
0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1255
0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1256
0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1257
};
1258
static const unsigned char generator_y[] = {
1259
0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1260
0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1261
0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1262
0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1263
0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1264
};
1265
unsigned char x_dst[57], buff[114];
1266
ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED448, 1,
1267
gctx->propq);
1268
unsigned char *privkey = NULL, *pubkey;
1269
EVP_MD_CTX *hashctx = NULL;
1270
EVP_MD *shake = NULL;
1271
1272
if (key == NULL) {
1273
ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1274
goto err;
1275
}
1276
1277
/* If we're doing parameter generation then we just return a blank key */
1278
if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1279
return key;
1280
1281
pubkey = key->pubkey;
1282
1283
privkey = ossl_ecx_key_allocate_privkey(key);
1284
if (privkey == NULL) {
1285
ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1286
goto err;
1287
}
1288
1289
shake = EVP_MD_fetch(gctx->libctx, "SHAKE256", gctx->propq);
1290
if (shake == NULL)
1291
goto err;
1292
if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED448_KEYLEN, 0) <= 0)
1293
goto err;
1294
1295
hashctx = EVP_MD_CTX_new();
1296
if (hashctx == NULL)
1297
goto err;
1298
if (EVP_DigestInit_ex(hashctx, shake, NULL) != 1)
1299
goto err;
1300
if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1301
goto err;
1302
if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1303
goto err;
1304
1305
buff[0] &= -4;
1306
buff[55] |= 0x80;
1307
buff[56] = 0;
1308
1309
if (s390x_ed448_mul(x_dst, pubkey,
1310
generator_x, generator_y, buff)
1311
!= 1)
1312
goto err;
1313
1314
pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1315
EVP_MD_CTX_free(hashctx);
1316
EVP_MD_free(shake);
1317
key->haspubkey = 1;
1318
return key;
1319
err:
1320
ossl_ecx_key_free(key);
1321
EVP_MD_CTX_free(hashctx);
1322
EVP_MD_free(shake);
1323
return NULL;
1324
}
1325
#endif
1326
1327