Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/providers/implementations/signature/eddsa_sig.c
48383 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 <openssl/crypto.h>
11
#include <openssl/core_dispatch.h>
12
#include <openssl/core_names.h>
13
#include <openssl/err.h>
14
#include <openssl/params.h>
15
#include <openssl/evp.h>
16
#include <openssl/proverr.h>
17
#include "internal/nelem.h"
18
#include "internal/sizes.h"
19
#include "prov/providercommon.h"
20
#include "prov/implementations.h"
21
#include "prov/securitycheck.h"
22
#include "prov/provider_ctx.h"
23
#include "prov/der_ecx.h"
24
#include "crypto/ecx.h"
25
26
#ifdef S390X_EC_ASM
27
# include "s390x_arch.h"
28
29
# define S390X_CAN_SIGN(edtype) \
30
((OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_##edtype)) \
31
&& (OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_##edtype)) \
32
&& (OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_##edtype)))
33
34
static int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig,
35
const unsigned char *tbs, size_t tbslen);
36
static int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig,
37
const unsigned char *tbs, size_t tbslen);
38
static int s390x_ed25519_digestverify(const ECX_KEY *edkey,
39
const unsigned char *sig,
40
const unsigned char *tbs, size_t tbslen);
41
static int s390x_ed448_digestverify(const ECX_KEY *edkey,
42
const unsigned char *sig,
43
const unsigned char *tbs, size_t tbslen);
44
45
#endif /* S390X_EC_ASM */
46
47
enum ID_EdDSA_INSTANCE {
48
ID_NOT_SET = 0,
49
ID_Ed25519,
50
ID_Ed25519ctx,
51
ID_Ed25519ph,
52
ID_Ed448,
53
ID_Ed448ph
54
};
55
56
#define SN_Ed25519 "Ed25519"
57
#define SN_Ed25519ph "Ed25519ph"
58
#define SN_Ed25519ctx "Ed25519ctx"
59
#define SN_Ed448 "Ed448"
60
#define SN_Ed448ph "Ed448ph"
61
62
#define EDDSA_MAX_CONTEXT_STRING_LEN 255
63
#define EDDSA_PREHASH_OUTPUT_LEN 64
64
65
static OSSL_FUNC_signature_newctx_fn eddsa_newctx;
66
static OSSL_FUNC_signature_sign_message_init_fn ed25519_signverify_message_init;
67
static OSSL_FUNC_signature_sign_message_init_fn ed25519ph_signverify_message_init;
68
static OSSL_FUNC_signature_sign_message_init_fn ed25519ctx_signverify_message_init;
69
static OSSL_FUNC_signature_sign_message_init_fn ed448_signverify_message_init;
70
static OSSL_FUNC_signature_sign_message_init_fn ed448ph_signverify_message_init;
71
static OSSL_FUNC_signature_sign_fn ed25519_sign;
72
static OSSL_FUNC_signature_sign_fn ed448_sign;
73
static OSSL_FUNC_signature_verify_fn ed25519_verify;
74
static OSSL_FUNC_signature_verify_fn ed448_verify;
75
static OSSL_FUNC_signature_digest_sign_init_fn ed25519_digest_signverify_init;
76
static OSSL_FUNC_signature_digest_sign_init_fn ed448_digest_signverify_init;
77
static OSSL_FUNC_signature_digest_sign_fn ed25519_digest_sign;
78
static OSSL_FUNC_signature_digest_sign_fn ed448_digest_sign;
79
static OSSL_FUNC_signature_digest_verify_fn ed25519_digest_verify;
80
static OSSL_FUNC_signature_digest_verify_fn ed448_digest_verify;
81
static OSSL_FUNC_signature_freectx_fn eddsa_freectx;
82
static OSSL_FUNC_signature_dupctx_fn eddsa_dupctx;
83
static OSSL_FUNC_signature_query_key_types_fn ed25519_sigalg_query_key_types;
84
static OSSL_FUNC_signature_query_key_types_fn ed448_sigalg_query_key_types;
85
static OSSL_FUNC_signature_get_ctx_params_fn eddsa_get_ctx_params;
86
static OSSL_FUNC_signature_gettable_ctx_params_fn eddsa_gettable_ctx_params;
87
static OSSL_FUNC_signature_set_ctx_params_fn eddsa_set_ctx_params;
88
static OSSL_FUNC_signature_settable_ctx_params_fn eddsa_settable_ctx_params;
89
static OSSL_FUNC_signature_settable_ctx_params_fn eddsa_settable_variant_ctx_params;
90
91
/* there are five EdDSA instances:
92
93
Ed25519
94
Ed25519ph
95
Ed25519ctx
96
Ed448
97
Ed448ph
98
99
Quoting from RFC 8032, Section 5.1:
100
101
For Ed25519, dom2(f,c) is the empty string. The phflag value is
102
irrelevant. The context (if present at all) MUST be empty. This
103
causes the scheme to be one and the same with the Ed25519 scheme
104
published earlier.
105
106
For Ed25519ctx, phflag=0. The context input SHOULD NOT be empty.
107
108
For Ed25519ph, phflag=1 and PH is SHA512 instead. That is, the input
109
is hashed using SHA-512 before signing with Ed25519.
110
111
Quoting from RFC 8032, Section 5.2:
112
113
Ed448ph is the same but with PH being SHAKE256(x, 64) and phflag
114
being 1, i.e., the input is hashed before signing with Ed448 with a
115
hash constant modified.
116
117
Value of context is set by signer and verifier (maximum of 255
118
octets; the default is empty string) and has to match octet by octet
119
for verification to be successful.
120
121
Quoting from RFC 8032, Section 2:
122
123
dom2(x, y) The blank octet string when signing or verifying
124
Ed25519. Otherwise, the octet string: "SigEd25519 no
125
Ed25519 collisions" || octet(x) || octet(OLEN(y)) ||
126
y, where x is in range 0-255 and y is an octet string
127
of at most 255 octets. "SigEd25519 no Ed25519
128
collisions" is in ASCII (32 octets).
129
130
dom4(x, y) The octet string "SigEd448" || octet(x) ||
131
octet(OLEN(y)) || y, where x is in range 0-255 and y
132
is an octet string of at most 255 octets. "SigEd448"
133
is in ASCII (8 octets).
134
135
Note above that x is the pre-hash flag, and y is the context string.
136
*/
137
138
typedef struct {
139
OSSL_LIB_CTX *libctx;
140
ECX_KEY *key;
141
142
/* The Algorithm Identifier of the signature algorithm */
143
unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE];
144
size_t aid_len;
145
146
/* id indicating the EdDSA instance */
147
int instance_id;
148
/* indicates that instance_id and associated flags are preset / hardcoded */
149
unsigned int instance_id_preset_flag : 1;
150
/* for ph instances, this indicates whether the caller is expected to prehash */
151
unsigned int prehash_by_caller_flag : 1;
152
153
unsigned int dom2_flag : 1;
154
unsigned int prehash_flag : 1;
155
156
/* indicates that a non-empty context string is required, as in Ed25519ctx */
157
unsigned int context_string_flag : 1;
158
159
unsigned char context_string[EDDSA_MAX_CONTEXT_STRING_LEN];
160
size_t context_string_len;
161
162
} PROV_EDDSA_CTX;
163
164
static void *eddsa_newctx(void *provctx, const char *propq_unused)
165
{
166
PROV_EDDSA_CTX *peddsactx;
167
168
if (!ossl_prov_is_running())
169
return NULL;
170
171
peddsactx = OPENSSL_zalloc(sizeof(PROV_EDDSA_CTX));
172
if (peddsactx == NULL)
173
return NULL;
174
175
peddsactx->libctx = PROV_LIBCTX_OF(provctx);
176
177
return peddsactx;
178
}
179
180
static int eddsa_setup_instance(void *vpeddsactx, int instance_id,
181
unsigned int instance_id_preset,
182
unsigned int prehash_by_caller)
183
{
184
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
185
186
switch (instance_id) {
187
case ID_Ed25519:
188
if (peddsactx->key->type != ECX_KEY_TYPE_ED25519)
189
return 0;
190
peddsactx->dom2_flag = 0;
191
peddsactx->prehash_flag = 0;
192
peddsactx->context_string_flag = 0;
193
break;
194
case ID_Ed25519ctx:
195
if (peddsactx->key->type != ECX_KEY_TYPE_ED25519)
196
return 0;
197
peddsactx->dom2_flag = 1;
198
peddsactx->prehash_flag = 0;
199
peddsactx->context_string_flag = 1;
200
break;
201
case ID_Ed25519ph:
202
if (peddsactx->key->type != ECX_KEY_TYPE_ED25519)
203
return 0;
204
peddsactx->dom2_flag = 1;
205
peddsactx->prehash_flag = 1;
206
peddsactx->context_string_flag = 0;
207
break;
208
case ID_Ed448:
209
if (peddsactx->key->type != ECX_KEY_TYPE_ED448)
210
return 0;
211
peddsactx->prehash_flag = 0;
212
peddsactx->context_string_flag = 0;
213
break;
214
case ID_Ed448ph:
215
if (peddsactx->key->type != ECX_KEY_TYPE_ED448)
216
return 0;
217
peddsactx->prehash_flag = 1;
218
peddsactx->context_string_flag = 0;
219
break;
220
default:
221
/* we did not recognize the instance */
222
return 0;
223
}
224
peddsactx->instance_id = instance_id;
225
peddsactx->instance_id_preset_flag = instance_id_preset;
226
peddsactx->prehash_by_caller_flag = prehash_by_caller;
227
return 1;
228
}
229
230
static int eddsa_signverify_init(void *vpeddsactx, void *vedkey)
231
{
232
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
233
ECX_KEY *edkey = (ECX_KEY *)vedkey;
234
WPACKET pkt;
235
int ret;
236
unsigned char *aid = NULL;
237
238
if (!ossl_prov_is_running())
239
return 0;
240
241
if (edkey == NULL) {
242
ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
243
return 0;
244
}
245
246
if (!ossl_ecx_key_up_ref(edkey)) {
247
ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
248
return 0;
249
}
250
251
peddsactx->instance_id_preset_flag = 0;
252
peddsactx->dom2_flag = 0;
253
peddsactx->prehash_flag = 0;
254
peddsactx->context_string_flag = 0;
255
peddsactx->context_string_len = 0;
256
257
peddsactx->key = edkey;
258
259
/*
260
* We do not care about DER writing errors.
261
* All it really means is that for some reason, there's no
262
* AlgorithmIdentifier to be had, but the operation itself is
263
* still valid, just as long as it's not used to construct
264
* anything that needs an AlgorithmIdentifier.
265
*/
266
peddsactx->aid_len = 0;
267
ret = WPACKET_init_der(&pkt, peddsactx->aid_buf, sizeof(peddsactx->aid_buf));
268
switch (edkey->type) {
269
case ECX_KEY_TYPE_ED25519:
270
ret = ret && ossl_DER_w_algorithmIdentifier_ED25519(&pkt, -1, edkey);
271
break;
272
case ECX_KEY_TYPE_ED448:
273
ret = ret && ossl_DER_w_algorithmIdentifier_ED448(&pkt, -1, edkey);
274
break;
275
default:
276
/* Should never happen */
277
ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
278
ossl_ecx_key_free(edkey);
279
peddsactx->key = NULL;
280
WPACKET_cleanup(&pkt);
281
return 0;
282
}
283
if (ret && WPACKET_finish(&pkt)) {
284
WPACKET_get_total_written(&pkt, &peddsactx->aid_len);
285
aid = WPACKET_get_curr(&pkt);
286
}
287
WPACKET_cleanup(&pkt);
288
if (aid != NULL && peddsactx->aid_len != 0)
289
memmove(peddsactx->aid_buf, aid, peddsactx->aid_len);
290
291
return 1;
292
}
293
294
static int ed25519_signverify_message_init(void *vpeddsactx, void *vedkey,
295
const OSSL_PARAM params[])
296
{
297
return eddsa_signverify_init(vpeddsactx, vedkey)
298
&& eddsa_setup_instance(vpeddsactx, ID_Ed25519, 1, 0)
299
&& eddsa_set_ctx_params(vpeddsactx, params);
300
}
301
302
static int ed25519ph_signverify_message_init(void *vpeddsactx, void *vedkey,
303
const OSSL_PARAM params[])
304
{
305
return eddsa_signverify_init(vpeddsactx, vedkey)
306
&& eddsa_setup_instance(vpeddsactx, ID_Ed25519ph, 1, 0)
307
&& eddsa_set_ctx_params(vpeddsactx, params);
308
}
309
310
static int ed25519ph_signverify_init(void *vpeddsactx, void *vedkey,
311
const OSSL_PARAM params[])
312
{
313
return eddsa_signverify_init(vpeddsactx, vedkey)
314
&& eddsa_setup_instance(vpeddsactx, ID_Ed25519ph, 1, 1)
315
&& eddsa_set_ctx_params(vpeddsactx, params);
316
}
317
318
/*
319
* This supports using ED25519 with EVP_PKEY_{sign,verify}_init_ex() and
320
* EVP_PKEY_{sign,verify}_init_ex2(), under the condition that the caller
321
* explicitly sets the Ed25519ph instance (this is verified by ed25519_sign()
322
* and ed25519_verify())
323
*/
324
static int ed25519_signverify_init(void *vpeddsactx, void *vedkey,
325
const OSSL_PARAM params[])
326
{
327
return eddsa_signverify_init(vpeddsactx, vedkey)
328
&& eddsa_setup_instance(vpeddsactx, ID_Ed25519, 0, 1)
329
&& eddsa_set_ctx_params(vpeddsactx, params);
330
}
331
332
static int ed25519ctx_signverify_message_init(void *vpeddsactx, void *vedkey,
333
const OSSL_PARAM params[])
334
{
335
return eddsa_signverify_init(vpeddsactx, vedkey)
336
&& eddsa_setup_instance(vpeddsactx, ID_Ed25519ctx, 1, 0)
337
&& eddsa_set_ctx_params(vpeddsactx, params);
338
}
339
340
static int ed448_signverify_message_init(void *vpeddsactx, void *vedkey,
341
const OSSL_PARAM params[])
342
{
343
return eddsa_signverify_init(vpeddsactx, vedkey)
344
&& eddsa_setup_instance(vpeddsactx, ID_Ed448, 1, 0)
345
&& eddsa_set_ctx_params(vpeddsactx, params);
346
}
347
348
static int ed448ph_signverify_message_init(void *vpeddsactx, void *vedkey,
349
const OSSL_PARAM params[])
350
{
351
return eddsa_signverify_init(vpeddsactx, vedkey)
352
&& eddsa_setup_instance(vpeddsactx, ID_Ed448ph, 1, 0)
353
&& eddsa_set_ctx_params(vpeddsactx, params);
354
}
355
356
static int ed448ph_signverify_init(void *vpeddsactx, void *vedkey,
357
const OSSL_PARAM params[])
358
{
359
return eddsa_signverify_init(vpeddsactx, vedkey)
360
&& eddsa_setup_instance(vpeddsactx, ID_Ed448ph, 1, 1)
361
&& eddsa_set_ctx_params(vpeddsactx, params);
362
}
363
364
/*
365
* This supports using ED448 with EVP_PKEY_{sign,verify}_init_ex() and
366
* EVP_PKEY_{sign,verify}_init_ex2(), under the condition that the caller
367
* explicitly sets the Ed448ph instance (this is verified by ed448_sign()
368
* and ed448_verify())
369
*/
370
static int ed448_signverify_init(void *vpeddsactx, void *vedkey,
371
const OSSL_PARAM params[])
372
{
373
return eddsa_signverify_init(vpeddsactx, vedkey)
374
&& eddsa_setup_instance(vpeddsactx, ID_Ed448, 0, 1)
375
&& eddsa_set_ctx_params(vpeddsactx, params);
376
}
377
378
/*
379
* This is used directly for OSSL_FUNC_SIGNATURE_SIGN and indirectly
380
* for OSSL_FUNC_SIGNATURE_DIGEST_SIGN
381
*/
382
static int ed25519_sign(void *vpeddsactx,
383
unsigned char *sigret, size_t *siglen, size_t sigsize,
384
const unsigned char *tbs, size_t tbslen)
385
{
386
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
387
const ECX_KEY *edkey = peddsactx->key;
388
uint8_t md[EVP_MAX_MD_SIZE];
389
size_t mdlen;
390
391
if (!ossl_prov_is_running())
392
return 0;
393
394
if (sigret == NULL) {
395
*siglen = ED25519_SIGSIZE;
396
return 1;
397
}
398
if (sigsize < ED25519_SIGSIZE) {
399
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
400
return 0;
401
}
402
if (edkey->privkey == NULL) {
403
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
404
return 0;
405
}
406
#ifdef S390X_EC_ASM
407
/*
408
* s390x_ed25519_digestsign() does not yet support dom2 or context-strings.
409
* fall back to non-accelerated sign if those options are set, or pre-hasing
410
* is provided.
411
*/
412
if (S390X_CAN_SIGN(ED25519)
413
&& !peddsactx->dom2_flag
414
&& !peddsactx->context_string_flag
415
&& peddsactx->context_string_len == 0
416
&& !peddsactx->prehash_flag
417
&& !peddsactx->prehash_by_caller_flag) {
418
if (s390x_ed25519_digestsign(edkey, sigret, tbs, tbslen) == 0) {
419
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
420
return 0;
421
}
422
*siglen = ED25519_SIGSIZE;
423
return 1;
424
}
425
#endif /* S390X_EC_ASM */
426
427
if (peddsactx->prehash_flag) {
428
if (!peddsactx->prehash_by_caller_flag) {
429
if (!EVP_Q_digest(peddsactx->libctx, SN_sha512, NULL,
430
tbs, tbslen, md, &mdlen)
431
|| mdlen != EDDSA_PREHASH_OUTPUT_LEN) {
432
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PREHASHED_DIGEST_LENGTH);
433
return 0;
434
}
435
tbs = md;
436
tbslen = mdlen;
437
} else if (tbslen != EDDSA_PREHASH_OUTPUT_LEN) {
438
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
439
return 0;
440
}
441
} else if (peddsactx->prehash_by_caller_flag) {
442
/* The caller is supposed to set up a ph instance! */
443
ERR_raise(ERR_LIB_PROV,
444
PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION);
445
return 0;
446
}
447
448
if (ossl_ed25519_sign(sigret, tbs, tbslen, edkey->pubkey, edkey->privkey,
449
peddsactx->dom2_flag, peddsactx->prehash_flag, peddsactx->context_string_flag,
450
peddsactx->context_string, peddsactx->context_string_len,
451
peddsactx->libctx, NULL) == 0) {
452
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
453
return 0;
454
}
455
*siglen = ED25519_SIGSIZE;
456
return 1;
457
}
458
459
/* EVP_Q_digest() does not allow variable output length for XOFs,
460
so we use this function */
461
static int ed448_shake256(OSSL_LIB_CTX *libctx,
462
const char *propq,
463
const uint8_t *in, size_t inlen,
464
uint8_t *out, size_t outlen)
465
{
466
int ret = 0;
467
EVP_MD_CTX *hash_ctx = EVP_MD_CTX_new();
468
EVP_MD *shake256 = EVP_MD_fetch(libctx, SN_shake256, propq);
469
470
if (hash_ctx == NULL || shake256 == NULL)
471
goto err;
472
473
if (!EVP_DigestInit_ex(hash_ctx, shake256, NULL)
474
|| !EVP_DigestUpdate(hash_ctx, in, inlen)
475
|| !EVP_DigestFinalXOF(hash_ctx, out, outlen))
476
goto err;
477
478
ret = 1;
479
480
err:
481
EVP_MD_CTX_free(hash_ctx);
482
EVP_MD_free(shake256);
483
return ret;
484
}
485
486
/*
487
* This is used directly for OSSL_FUNC_SIGNATURE_SIGN and indirectly
488
* for OSSL_FUNC_SIGNATURE_DIGEST_SIGN
489
*/
490
static int ed448_sign(void *vpeddsactx,
491
unsigned char *sigret, size_t *siglen, size_t sigsize,
492
const unsigned char *tbs, size_t tbslen)
493
{
494
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
495
const ECX_KEY *edkey = peddsactx->key;
496
uint8_t md[EDDSA_PREHASH_OUTPUT_LEN];
497
size_t mdlen = sizeof(md);
498
499
if (!ossl_prov_is_running())
500
return 0;
501
502
if (sigret == NULL) {
503
*siglen = ED448_SIGSIZE;
504
return 1;
505
}
506
if (sigsize < ED448_SIGSIZE) {
507
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
508
return 0;
509
}
510
if (edkey->privkey == NULL) {
511
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
512
return 0;
513
}
514
#ifdef S390X_EC_ASM
515
/*
516
* s390x_ed448_digestsign() does not yet support context-strings or
517
* pre-hashing. Fall back to non-accelerated sign if a context-string or
518
* pre-hasing is provided.
519
*/
520
if (S390X_CAN_SIGN(ED448)
521
&& peddsactx->context_string_len == 0
522
&& !peddsactx->prehash_flag
523
&& !peddsactx->prehash_by_caller_flag) {
524
if (s390x_ed448_digestsign(edkey, sigret, tbs, tbslen) == 0) {
525
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
526
return 0;
527
}
528
*siglen = ED448_SIGSIZE;
529
return 1;
530
}
531
#endif /* S390X_EC_ASM */
532
533
if (peddsactx->prehash_flag) {
534
if (!peddsactx->prehash_by_caller_flag) {
535
if (!ed448_shake256(peddsactx->libctx, NULL, tbs, tbslen, md, mdlen))
536
return 0;
537
tbs = md;
538
tbslen = mdlen;
539
} else if (tbslen != EDDSA_PREHASH_OUTPUT_LEN) {
540
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
541
return 0;
542
}
543
} else if (peddsactx->prehash_by_caller_flag) {
544
/* The caller is supposed to set up a ph instance! */
545
ERR_raise(ERR_LIB_PROV,
546
PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION);
547
return 0;
548
}
549
550
if (ossl_ed448_sign(peddsactx->libctx, sigret, tbs, tbslen,
551
edkey->pubkey, edkey->privkey,
552
peddsactx->context_string, peddsactx->context_string_len,
553
peddsactx->prehash_flag, edkey->propq) == 0) {
554
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
555
return 0;
556
}
557
*siglen = ED448_SIGSIZE;
558
return 1;
559
}
560
561
/*
562
* This is used directly for OSSL_FUNC_SIGNATURE_VERIFY and indirectly
563
* for OSSL_FUNC_SIGNATURE_DIGEST_VERIFY
564
*/
565
static int ed25519_verify(void *vpeddsactx,
566
const unsigned char *sig, size_t siglen,
567
const unsigned char *tbs, size_t tbslen)
568
{
569
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
570
const ECX_KEY *edkey = peddsactx->key;
571
uint8_t md[EVP_MAX_MD_SIZE];
572
size_t mdlen;
573
574
if (!ossl_prov_is_running() || siglen != ED25519_SIGSIZE)
575
return 0;
576
577
#ifdef S390X_EC_ASM
578
/*
579
* s390x_ed25519_digestverify() does not yet support dom2 or context-strings.
580
* fall back to non-accelerated verify if those options are set, or
581
* pre-hasing is provided.
582
*/
583
if (S390X_CAN_SIGN(ED25519)
584
&& !peddsactx->dom2_flag
585
&& !peddsactx->context_string_flag
586
&& peddsactx->context_string_len == 0
587
&& !peddsactx->prehash_flag
588
&& !peddsactx->prehash_by_caller_flag)
589
return s390x_ed25519_digestverify(edkey, sig, tbs, tbslen);
590
#endif /* S390X_EC_ASM */
591
592
if (peddsactx->prehash_flag) {
593
if (!peddsactx->prehash_by_caller_flag) {
594
if (!EVP_Q_digest(peddsactx->libctx, SN_sha512, NULL,
595
tbs, tbslen, md, &mdlen)
596
|| mdlen != EDDSA_PREHASH_OUTPUT_LEN) {
597
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PREHASHED_DIGEST_LENGTH);
598
return 0;
599
}
600
tbs = md;
601
tbslen = mdlen;
602
} else if (tbslen != EDDSA_PREHASH_OUTPUT_LEN) {
603
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
604
return 0;
605
}
606
} else if (peddsactx->prehash_by_caller_flag) {
607
/* The caller is supposed to set up a ph instance! */
608
ERR_raise(ERR_LIB_PROV,
609
PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION);
610
return 0;
611
}
612
613
return ossl_ed25519_verify(tbs, tbslen, sig, edkey->pubkey,
614
peddsactx->dom2_flag, peddsactx->prehash_flag, peddsactx->context_string_flag,
615
peddsactx->context_string, peddsactx->context_string_len,
616
peddsactx->libctx, edkey->propq);
617
}
618
619
/*
620
* This is used directly for OSSL_FUNC_SIGNATURE_VERIFY and indirectly
621
* for OSSL_FUNC_SIGNATURE_DIGEST_VERIFY
622
*/
623
static int ed448_verify(void *vpeddsactx,
624
const unsigned char *sig, size_t siglen,
625
const unsigned char *tbs, size_t tbslen)
626
{
627
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
628
const ECX_KEY *edkey = peddsactx->key;
629
uint8_t md[EDDSA_PREHASH_OUTPUT_LEN];
630
size_t mdlen = sizeof(md);
631
632
if (!ossl_prov_is_running() || siglen != ED448_SIGSIZE)
633
return 0;
634
635
#ifdef S390X_EC_ASM
636
/*
637
* s390x_ed448_digestverify() does not yet support context-strings or
638
* pre-hashing. Fall back to non-accelerated verify if a context-string or
639
* pre-hasing is provided.
640
*/
641
if (S390X_CAN_SIGN(ED448)
642
&& peddsactx->context_string_len == 0
643
&& !peddsactx->prehash_flag
644
&& !peddsactx->prehash_by_caller_flag)
645
return s390x_ed448_digestverify(edkey, sig, tbs, tbslen);
646
#endif /* S390X_EC_ASM */
647
648
if (peddsactx->prehash_flag) {
649
if (!peddsactx->prehash_by_caller_flag) {
650
if (!ed448_shake256(peddsactx->libctx, NULL, tbs, tbslen, md, mdlen))
651
return 0;
652
tbs = md;
653
tbslen = mdlen;
654
} else if (tbslen != EDDSA_PREHASH_OUTPUT_LEN) {
655
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
656
return 0;
657
}
658
} else if (peddsactx->prehash_by_caller_flag) {
659
/* The caller is supposed to set up a ph instance! */
660
ERR_raise(ERR_LIB_PROV,
661
PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION);
662
return 0;
663
}
664
665
return ossl_ed448_verify(peddsactx->libctx, tbs, tbslen, sig, edkey->pubkey,
666
peddsactx->context_string, peddsactx->context_string_len,
667
peddsactx->prehash_flag, edkey->propq);
668
}
669
670
/* All digest_{sign,verify} are simple wrappers around the functions above */
671
672
static int ed25519_digest_signverify_init(void *vpeddsactx, const char *mdname,
673
void *vedkey,
674
const OSSL_PARAM params[])
675
{
676
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
677
678
if (mdname != NULL && mdname[0] != '\0') {
679
ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
680
"Explicit digest not allowed with EdDSA operations");
681
return 0;
682
}
683
684
if (vedkey == NULL && peddsactx->key != NULL)
685
return eddsa_set_ctx_params(peddsactx, params);
686
687
return eddsa_signverify_init(vpeddsactx, vedkey)
688
&& eddsa_setup_instance(vpeddsactx, ID_Ed25519, 0, 0)
689
&& eddsa_set_ctx_params(vpeddsactx, params);
690
}
691
692
static int ed25519_digest_sign(void *vpeddsactx,
693
unsigned char *sigret, size_t *siglen, size_t sigsize,
694
const unsigned char *tbs, size_t tbslen)
695
{
696
return ed25519_sign(vpeddsactx, sigret, siglen, sigsize, tbs, tbslen);
697
}
698
699
static int ed25519_digest_verify(void *vpeddsactx,
700
const unsigned char *sigret, size_t siglen,
701
const unsigned char *tbs, size_t tbslen)
702
{
703
return ed25519_verify(vpeddsactx, sigret, siglen, tbs, tbslen);
704
}
705
706
static int ed448_digest_signverify_init(void *vpeddsactx, const char *mdname,
707
void *vedkey,
708
const OSSL_PARAM params[])
709
{
710
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
711
712
if (mdname != NULL && mdname[0] != '\0') {
713
ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
714
"Explicit digest not allowed with EdDSA operations");
715
return 0;
716
}
717
718
if (vedkey == NULL && peddsactx->key != NULL)
719
return eddsa_set_ctx_params(peddsactx, params);
720
721
return eddsa_signverify_init(vpeddsactx, vedkey)
722
&& eddsa_setup_instance(vpeddsactx, ID_Ed448, 0, 0)
723
&& eddsa_set_ctx_params(vpeddsactx, params);
724
}
725
726
static int ed448_digest_sign(void *vpeddsactx,
727
unsigned char *sigret, size_t *siglen, size_t sigsize,
728
const unsigned char *tbs, size_t tbslen)
729
{
730
return ed448_sign(vpeddsactx, sigret, siglen, sigsize, tbs, tbslen);
731
}
732
733
static int ed448_digest_verify(void *vpeddsactx,
734
const unsigned char *sigret, size_t siglen,
735
const unsigned char *tbs, size_t tbslen)
736
{
737
return ed448_verify(vpeddsactx, sigret, siglen, tbs, tbslen);
738
}
739
740
static void eddsa_freectx(void *vpeddsactx)
741
{
742
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
743
744
ossl_ecx_key_free(peddsactx->key);
745
746
OPENSSL_free(peddsactx);
747
}
748
749
static void *eddsa_dupctx(void *vpeddsactx)
750
{
751
PROV_EDDSA_CTX *srcctx = (PROV_EDDSA_CTX *)vpeddsactx;
752
PROV_EDDSA_CTX *dstctx;
753
754
if (!ossl_prov_is_running())
755
return NULL;
756
757
dstctx = OPENSSL_zalloc(sizeof(*srcctx));
758
if (dstctx == NULL)
759
return NULL;
760
761
*dstctx = *srcctx;
762
dstctx->key = NULL;
763
764
if (srcctx->key != NULL && !ossl_ecx_key_up_ref(srcctx->key)) {
765
ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
766
goto err;
767
}
768
dstctx->key = srcctx->key;
769
770
return dstctx;
771
err:
772
eddsa_freectx(dstctx);
773
return NULL;
774
}
775
776
static const char **ed25519_sigalg_query_key_types(void)
777
{
778
static const char *keytypes[] = { "ED25519", NULL };
779
780
return keytypes;
781
}
782
783
static const char **ed448_sigalg_query_key_types(void)
784
{
785
static const char *keytypes[] = { "ED448", NULL };
786
787
return keytypes;
788
}
789
790
791
792
static int eddsa_get_ctx_params(void *vpeddsactx, OSSL_PARAM *params)
793
{
794
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
795
OSSL_PARAM *p;
796
797
if (peddsactx == NULL)
798
return 0;
799
800
p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID);
801
if (p != NULL
802
&& !OSSL_PARAM_set_octet_string(p,
803
peddsactx->aid_len == 0 ? NULL : peddsactx->aid_buf,
804
peddsactx->aid_len))
805
return 0;
806
807
return 1;
808
}
809
810
static const OSSL_PARAM known_gettable_ctx_params[] = {
811
OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
812
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_INSTANCE, NULL, 0),
813
OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0),
814
OSSL_PARAM_END
815
};
816
817
static const OSSL_PARAM *eddsa_gettable_ctx_params(ossl_unused void *vpeddsactx,
818
ossl_unused void *provctx)
819
{
820
return known_gettable_ctx_params;
821
}
822
823
static int eddsa_set_ctx_params(void *vpeddsactx, const OSSL_PARAM params[])
824
{
825
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
826
const OSSL_PARAM *p;
827
828
if (peddsactx == NULL)
829
return 0;
830
if (ossl_param_is_empty(params))
831
return 1;
832
833
p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_INSTANCE);
834
if (p != NULL) {
835
char instance_name[OSSL_MAX_NAME_SIZE] = "";
836
char *pinstance_name = instance_name;
837
838
if (peddsactx->instance_id_preset_flag) {
839
/* When the instance is preset, the caller must no try to set it */
840
ERR_raise_data(ERR_LIB_PROV, PROV_R_NO_INSTANCE_ALLOWED,
841
"the EdDSA instance is preset, you may not try to specify it",
842
NULL);
843
return 0;
844
}
845
846
if (!OSSL_PARAM_get_utf8_string(p, &pinstance_name, sizeof(instance_name)))
847
return 0;
848
849
/*
850
* When setting the new instance, we're careful not to change the
851
* prehash_by_caller flag, as that's always preset by the init
852
* functions. The sign functions will determine if the instance
853
* matches this flag.
854
*/
855
if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519) == 0) {
856
eddsa_setup_instance(peddsactx, ID_Ed25519, 0,
857
peddsactx->prehash_by_caller_flag);
858
} else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519ctx) == 0) {
859
eddsa_setup_instance(peddsactx, ID_Ed25519ctx, 0,
860
peddsactx->prehash_by_caller_flag);
861
} else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519ph) == 0) {
862
eddsa_setup_instance(peddsactx, ID_Ed25519ph, 0,
863
peddsactx->prehash_by_caller_flag);
864
} else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed448) == 0) {
865
eddsa_setup_instance(peddsactx, ID_Ed448, 0,
866
peddsactx->prehash_by_caller_flag);
867
} else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed448ph) == 0) {
868
eddsa_setup_instance(peddsactx, ID_Ed448ph, 0,
869
peddsactx->prehash_by_caller_flag);
870
} else {
871
/* we did not recognize the instance */
872
return 0;
873
}
874
875
}
876
877
p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_CONTEXT_STRING);
878
if (p != NULL) {
879
void *vp_context_string = peddsactx->context_string;
880
881
if (!OSSL_PARAM_get_octet_string(p, &vp_context_string, sizeof(peddsactx->context_string), &(peddsactx->context_string_len))) {
882
peddsactx->context_string_len = 0;
883
return 0;
884
}
885
}
886
887
return 1;
888
}
889
890
static const OSSL_PARAM settable_ctx_params[] = {
891
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_INSTANCE, NULL, 0),
892
OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0),
893
OSSL_PARAM_END
894
};
895
896
static const OSSL_PARAM *eddsa_settable_ctx_params(ossl_unused void *vpeddsactx,
897
ossl_unused void *provctx)
898
{
899
return settable_ctx_params;
900
}
901
902
static const OSSL_PARAM settable_variant_ctx_params[] = {
903
OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0),
904
OSSL_PARAM_END
905
};
906
907
static const OSSL_PARAM *
908
eddsa_settable_variant_ctx_params(ossl_unused void *vpeddsactx,
909
ossl_unused void *provctx)
910
{
911
return settable_variant_ctx_params;
912
}
913
914
/*
915
* Ed25519 can be used with:
916
* - EVP_PKEY_sign_init_ex2() [ instance and prehash assumed done by caller ]
917
* - EVP_PKEY_verify_init_ex2() [ instance and prehash assumed done by caller ]
918
* - EVP_PKEY_sign_message_init()
919
* - EVP_PKEY_verify_message_init()
920
* - EVP_DigestSignInit_ex()
921
* - EVP_DigestVerifyInit_ex()
922
* Ed25519ph can be used with:
923
* - EVP_PKEY_sign_init_ex2() [ prehash assumed done by caller ]
924
* - EVP_PKEY_verify_init_ex2() [ prehash assumed done by caller ]
925
* - EVP_PKEY_sign_message_init()
926
* - EVP_PKEY_verify_message_init()
927
* Ed25519ctx can be used with:
928
* - EVP_PKEY_sign_message_init()
929
* - EVP_PKEY_verify_message_init()
930
* Ed448 can be used with:
931
* - EVP_PKEY_sign_init_ex2() [ instance and prehash assumed done by caller ]
932
* - EVP_PKEY_verify_init_ex2() [ instance and prehash assumed done by caller ]
933
* - EVP_PKEY_sign_message_init()
934
* - EVP_PKEY_verify_message_init()
935
* - EVP_DigestSignInit_ex()
936
* - EVP_DigestVerifyInit_ex()
937
* Ed448ph can be used with:
938
* - EVP_PKEY_sign_init_ex2() [ prehash assumed done by caller ]
939
* - EVP_PKEY_verify_init_ex2() [ prehash assumed done by caller ]
940
* - EVP_PKEY_sign_message_init()
941
* - EVP_PKEY_verify_message_init()
942
*/
943
944
#define ed25519_DISPATCH_END \
945
{ OSSL_FUNC_SIGNATURE_SIGN_INIT, \
946
(void (*)(void))ed25519_signverify_init }, \
947
{ OSSL_FUNC_SIGNATURE_VERIFY_INIT, \
948
(void (*)(void))ed25519_signverify_init }, \
949
{ OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, \
950
(void (*)(void))ed25519_digest_signverify_init }, \
951
{ OSSL_FUNC_SIGNATURE_DIGEST_SIGN, \
952
(void (*)(void))ed25519_digest_sign }, \
953
{ OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, \
954
(void (*)(void))ed25519_digest_signverify_init }, \
955
{ OSSL_FUNC_SIGNATURE_DIGEST_VERIFY, \
956
(void (*)(void))ed25519_digest_verify }, \
957
{ OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \
958
(void (*)(void))eddsa_get_ctx_params }, \
959
{ OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \
960
(void (*)(void))eddsa_gettable_ctx_params }, \
961
{ OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \
962
(void (*)(void))eddsa_set_ctx_params }, \
963
{ OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \
964
(void (*)(void))eddsa_settable_ctx_params }, \
965
OSSL_DISPATCH_END
966
967
#define eddsa_variant_DISPATCH_END(v) \
968
{ OSSL_FUNC_SIGNATURE_SIGN_INIT, \
969
(void (*)(void))v##_signverify_message_init }, \
970
{ OSSL_FUNC_SIGNATURE_VERIFY_INIT, \
971
(void (*)(void))v##_signverify_message_init }, \
972
{ OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \
973
(void (*)(void))eddsa_get_ctx_params }, \
974
{ OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \
975
(void (*)(void))eddsa_gettable_ctx_params }, \
976
{ OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \
977
(void (*)(void))eddsa_set_ctx_params }, \
978
{ OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \
979
(void (*)(void))eddsa_settable_variant_ctx_params }, \
980
OSSL_DISPATCH_END
981
982
#define ed25519ph_DISPATCH_END \
983
{ OSSL_FUNC_SIGNATURE_SIGN_INIT, \
984
(void (*)(void))ed25519ph_signverify_init }, \
985
{ OSSL_FUNC_SIGNATURE_VERIFY_INIT, \
986
(void (*)(void))ed25519ph_signverify_init }, \
987
eddsa_variant_DISPATCH_END(ed25519ph)
988
989
#define ed25519ctx_DISPATCH_END eddsa_variant_DISPATCH_END(ed25519ctx)
990
991
#define ed448_DISPATCH_END \
992
{ OSSL_FUNC_SIGNATURE_SIGN_INIT, \
993
(void (*)(void))ed448_signverify_init }, \
994
{ OSSL_FUNC_SIGNATURE_VERIFY_INIT, \
995
(void (*)(void))ed448_signverify_init }, \
996
{ OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, \
997
(void (*)(void))ed448_digest_signverify_init }, \
998
{ OSSL_FUNC_SIGNATURE_DIGEST_SIGN, \
999
(void (*)(void))ed448_digest_sign }, \
1000
{ OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, \
1001
(void (*)(void))ed448_digest_signverify_init }, \
1002
{ OSSL_FUNC_SIGNATURE_DIGEST_VERIFY, \
1003
(void (*)(void))ed448_digest_verify }, \
1004
{ OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \
1005
(void (*)(void))eddsa_get_ctx_params }, \
1006
{ OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \
1007
(void (*)(void))eddsa_gettable_ctx_params }, \
1008
{ OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \
1009
(void (*)(void))eddsa_set_ctx_params }, \
1010
{ OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \
1011
(void (*)(void))eddsa_settable_ctx_params }, \
1012
OSSL_DISPATCH_END
1013
1014
#define ed448ph_DISPATCH_END \
1015
{ OSSL_FUNC_SIGNATURE_SIGN_INIT, \
1016
(void (*)(void))ed448ph_signverify_init }, \
1017
{ OSSL_FUNC_SIGNATURE_VERIFY_INIT, \
1018
(void (*)(void))ed448ph_signverify_init }, \
1019
eddsa_variant_DISPATCH_END(ed448ph)
1020
1021
/* vn = variant name, bn = base name */
1022
#define IMPL_EDDSA_DISPATCH(vn,bn) \
1023
const OSSL_DISPATCH ossl_##vn##_signature_functions[] = { \
1024
{ OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx }, \
1025
{ OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_INIT, \
1026
(void (*)(void))vn##_signverify_message_init }, \
1027
{ OSSL_FUNC_SIGNATURE_SIGN, \
1028
(void (*)(void))bn##_sign }, \
1029
{ OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_INIT, \
1030
(void (*)(void))vn##_signverify_message_init }, \
1031
{ OSSL_FUNC_SIGNATURE_VERIFY, \
1032
(void (*)(void))bn##_verify }, \
1033
{ OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx }, \
1034
{ OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx }, \
1035
{ OSSL_FUNC_SIGNATURE_QUERY_KEY_TYPES, \
1036
(void (*)(void))bn##_sigalg_query_key_types }, \
1037
vn##_DISPATCH_END \
1038
}
1039
1040
IMPL_EDDSA_DISPATCH(ed25519,ed25519);
1041
IMPL_EDDSA_DISPATCH(ed25519ph,ed25519);
1042
IMPL_EDDSA_DISPATCH(ed25519ctx,ed25519);
1043
IMPL_EDDSA_DISPATCH(ed448,ed448);
1044
IMPL_EDDSA_DISPATCH(ed448ph,ed448);
1045
1046
#ifdef S390X_EC_ASM
1047
1048
static int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig,
1049
const unsigned char *tbs, size_t tbslen)
1050
{
1051
int rc;
1052
union {
1053
struct {
1054
unsigned char sig[64];
1055
unsigned char priv[32];
1056
} ed25519;
1057
unsigned long long buff[512];
1058
} param;
1059
1060
memset(&param, 0, sizeof(param));
1061
memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1062
1063
rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, &param.ed25519, tbs, tbslen);
1064
OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1065
if (rc != 0)
1066
return 0;
1067
1068
s390x_flip_endian32(sig, param.ed25519.sig);
1069
s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1070
return 1;
1071
}
1072
1073
static int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig,
1074
const unsigned char *tbs, size_t tbslen)
1075
{
1076
int rc;
1077
union {
1078
struct {
1079
unsigned char sig[128];
1080
unsigned char priv[64];
1081
} ed448;
1082
unsigned long long buff[512];
1083
} param;
1084
1085
memset(&param, 0, sizeof(param));
1086
memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1087
1088
rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, &param.ed448, tbs, tbslen);
1089
OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1090
if (rc != 0)
1091
return 0;
1092
1093
s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1094
s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1095
memcpy(sig, param.ed448.sig, 57);
1096
memcpy(sig + 57, param.ed448.sig + 64, 57);
1097
return 1;
1098
}
1099
1100
static int s390x_ed25519_digestverify(const ECX_KEY *edkey,
1101
const unsigned char *sig,
1102
const unsigned char *tbs, size_t tbslen)
1103
{
1104
union {
1105
struct {
1106
unsigned char sig[64];
1107
unsigned char pub[32];
1108
} ed25519;
1109
unsigned long long buff[512];
1110
} param;
1111
1112
memset(&param, 0, sizeof(param));
1113
s390x_flip_endian32(param.ed25519.sig, sig);
1114
s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1115
s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1116
1117
return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1118
&param.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1119
}
1120
1121
static int s390x_ed448_digestverify(const ECX_KEY *edkey,
1122
const unsigned char *sig,
1123
const unsigned char *tbs,
1124
size_t tbslen)
1125
{
1126
union {
1127
struct {
1128
unsigned char sig[128];
1129
unsigned char pub[64];
1130
} ed448;
1131
unsigned long long buff[512];
1132
} param;
1133
1134
memset(&param, 0, sizeof(param));
1135
memcpy(param.ed448.sig, sig, 57);
1136
s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1137
memcpy(param.ed448.sig + 64, sig + 57, 57);
1138
s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1139
memcpy(param.ed448.pub, edkey->pubkey, 57);
1140
s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1141
1142
return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1143
&param.ed448, tbs, tbslen) == 0 ? 1 : 0;
1144
}
1145
1146
#endif /* S390X_EC_ASM */
1147
1148