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
108817 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
#ifndef FIPS_MODULE
195
case ID_Ed25519ctx:
196
if (peddsactx->key->type != ECX_KEY_TYPE_ED25519)
197
return 0;
198
peddsactx->dom2_flag = 1;
199
peddsactx->prehash_flag = 0;
200
peddsactx->context_string_flag = 1;
201
break;
202
#endif
203
case ID_Ed25519ph:
204
if (peddsactx->key->type != ECX_KEY_TYPE_ED25519)
205
return 0;
206
peddsactx->dom2_flag = 1;
207
peddsactx->prehash_flag = 1;
208
peddsactx->context_string_flag = 0;
209
break;
210
case ID_Ed448:
211
if (peddsactx->key->type != ECX_KEY_TYPE_ED448)
212
return 0;
213
peddsactx->prehash_flag = 0;
214
peddsactx->context_string_flag = 0;
215
break;
216
case ID_Ed448ph:
217
if (peddsactx->key->type != ECX_KEY_TYPE_ED448)
218
return 0;
219
peddsactx->prehash_flag = 1;
220
peddsactx->context_string_flag = 0;
221
break;
222
default:
223
/* we did not recognize the instance */
224
return 0;
225
}
226
peddsactx->instance_id = instance_id;
227
peddsactx->instance_id_preset_flag = instance_id_preset;
228
peddsactx->prehash_by_caller_flag = prehash_by_caller;
229
return 1;
230
}
231
232
static int eddsa_signverify_init(void *vpeddsactx, void *vedkey)
233
{
234
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
235
ECX_KEY *edkey = (ECX_KEY *)vedkey;
236
WPACKET pkt;
237
int ret;
238
unsigned char *aid = NULL;
239
240
if (!ossl_prov_is_running())
241
return 0;
242
243
if (edkey == NULL) {
244
ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
245
return 0;
246
}
247
248
if (!ossl_ecx_key_up_ref(edkey)) {
249
ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
250
return 0;
251
}
252
253
peddsactx->instance_id_preset_flag = 0;
254
peddsactx->dom2_flag = 0;
255
peddsactx->prehash_flag = 0;
256
peddsactx->context_string_flag = 0;
257
peddsactx->context_string_len = 0;
258
259
peddsactx->key = edkey;
260
261
/*
262
* We do not care about DER writing errors.
263
* All it really means is that for some reason, there's no
264
* AlgorithmIdentifier to be had, but the operation itself is
265
* still valid, just as long as it's not used to construct
266
* anything that needs an AlgorithmIdentifier.
267
*/
268
peddsactx->aid_len = 0;
269
ret = WPACKET_init_der(&pkt, peddsactx->aid_buf, sizeof(peddsactx->aid_buf));
270
switch (edkey->type) {
271
case ECX_KEY_TYPE_ED25519:
272
ret = ret && ossl_DER_w_algorithmIdentifier_ED25519(&pkt, -1, edkey);
273
break;
274
case ECX_KEY_TYPE_ED448:
275
ret = ret && ossl_DER_w_algorithmIdentifier_ED448(&pkt, -1, edkey);
276
break;
277
default:
278
/* Should never happen */
279
ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
280
ossl_ecx_key_free(edkey);
281
peddsactx->key = NULL;
282
WPACKET_cleanup(&pkt);
283
return 0;
284
}
285
if (ret && WPACKET_finish(&pkt)) {
286
WPACKET_get_total_written(&pkt, &peddsactx->aid_len);
287
aid = WPACKET_get_curr(&pkt);
288
}
289
WPACKET_cleanup(&pkt);
290
if (aid != NULL && peddsactx->aid_len != 0)
291
memmove(peddsactx->aid_buf, aid, peddsactx->aid_len);
292
293
return 1;
294
}
295
296
static int ed25519_signverify_message_init(void *vpeddsactx, void *vedkey,
297
const OSSL_PARAM params[])
298
{
299
return eddsa_signverify_init(vpeddsactx, vedkey)
300
&& eddsa_setup_instance(vpeddsactx, ID_Ed25519, 1, 0)
301
&& eddsa_set_ctx_params(vpeddsactx, params);
302
}
303
304
static int ed25519ph_signverify_message_init(void *vpeddsactx, void *vedkey,
305
const OSSL_PARAM params[])
306
{
307
return eddsa_signverify_init(vpeddsactx, vedkey)
308
&& eddsa_setup_instance(vpeddsactx, ID_Ed25519ph, 1, 0)
309
&& eddsa_set_ctx_params(vpeddsactx, params);
310
}
311
312
static int ed25519ph_signverify_init(void *vpeddsactx, void *vedkey,
313
const OSSL_PARAM params[])
314
{
315
return eddsa_signverify_init(vpeddsactx, vedkey)
316
&& eddsa_setup_instance(vpeddsactx, ID_Ed25519ph, 1, 1)
317
&& eddsa_set_ctx_params(vpeddsactx, params);
318
}
319
320
/*
321
* This supports using ED25519 with EVP_PKEY_{sign,verify}_init_ex() and
322
* EVP_PKEY_{sign,verify}_init_ex2(), under the condition that the caller
323
* explicitly sets the Ed25519ph instance (this is verified by ed25519_sign()
324
* and ed25519_verify())
325
*/
326
static int ed25519_signverify_init(void *vpeddsactx, void *vedkey,
327
const OSSL_PARAM params[])
328
{
329
return eddsa_signverify_init(vpeddsactx, vedkey)
330
&& eddsa_setup_instance(vpeddsactx, ID_Ed25519, 0, 1)
331
&& eddsa_set_ctx_params(vpeddsactx, params);
332
}
333
334
static int ed25519ctx_signverify_message_init(void *vpeddsactx, void *vedkey,
335
const OSSL_PARAM params[])
336
{
337
return eddsa_signverify_init(vpeddsactx, vedkey)
338
&& eddsa_setup_instance(vpeddsactx, ID_Ed25519ctx, 1, 0)
339
&& eddsa_set_ctx_params(vpeddsactx, params);
340
}
341
342
static int ed448_signverify_message_init(void *vpeddsactx, void *vedkey,
343
const OSSL_PARAM params[])
344
{
345
return eddsa_signverify_init(vpeddsactx, vedkey)
346
&& eddsa_setup_instance(vpeddsactx, ID_Ed448, 1, 0)
347
&& eddsa_set_ctx_params(vpeddsactx, params);
348
}
349
350
static int ed448ph_signverify_message_init(void *vpeddsactx, void *vedkey,
351
const OSSL_PARAM params[])
352
{
353
return eddsa_signverify_init(vpeddsactx, vedkey)
354
&& eddsa_setup_instance(vpeddsactx, ID_Ed448ph, 1, 0)
355
&& eddsa_set_ctx_params(vpeddsactx, params);
356
}
357
358
static int ed448ph_signverify_init(void *vpeddsactx, void *vedkey,
359
const OSSL_PARAM params[])
360
{
361
return eddsa_signverify_init(vpeddsactx, vedkey)
362
&& eddsa_setup_instance(vpeddsactx, ID_Ed448ph, 1, 1)
363
&& eddsa_set_ctx_params(vpeddsactx, params);
364
}
365
366
/*
367
* This supports using ED448 with EVP_PKEY_{sign,verify}_init_ex() and
368
* EVP_PKEY_{sign,verify}_init_ex2(), under the condition that the caller
369
* explicitly sets the Ed448ph instance (this is verified by ed448_sign()
370
* and ed448_verify())
371
*/
372
static int ed448_signverify_init(void *vpeddsactx, void *vedkey,
373
const OSSL_PARAM params[])
374
{
375
return eddsa_signverify_init(vpeddsactx, vedkey)
376
&& eddsa_setup_instance(vpeddsactx, ID_Ed448, 0, 1)
377
&& eddsa_set_ctx_params(vpeddsactx, params);
378
}
379
380
/*
381
* This is used directly for OSSL_FUNC_SIGNATURE_SIGN and indirectly
382
* for OSSL_FUNC_SIGNATURE_DIGEST_SIGN
383
*/
384
static int ed25519_sign(void *vpeddsactx,
385
unsigned char *sigret, size_t *siglen, size_t sigsize,
386
const unsigned char *tbs, size_t tbslen)
387
{
388
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
389
const ECX_KEY *edkey = peddsactx->key;
390
uint8_t md[EVP_MAX_MD_SIZE];
391
size_t mdlen;
392
393
if (!ossl_prov_is_running())
394
return 0;
395
396
if (sigret == NULL) {
397
*siglen = ED25519_SIGSIZE;
398
return 1;
399
}
400
if (sigsize < ED25519_SIGSIZE) {
401
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
402
return 0;
403
}
404
if (edkey->privkey == NULL) {
405
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
406
return 0;
407
}
408
#ifdef S390X_EC_ASM
409
/*
410
* s390x_ed25519_digestsign() does not yet support dom2 or context-strings.
411
* fall back to non-accelerated sign if those options are set, or pre-hasing
412
* is provided.
413
*/
414
if (S390X_CAN_SIGN(ED25519)
415
&& !peddsactx->dom2_flag
416
&& !peddsactx->context_string_flag
417
&& peddsactx->context_string_len == 0
418
&& !peddsactx->prehash_flag
419
&& !peddsactx->prehash_by_caller_flag) {
420
if (s390x_ed25519_digestsign(edkey, sigret, tbs, tbslen) == 0) {
421
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
422
return 0;
423
}
424
*siglen = ED25519_SIGSIZE;
425
return 1;
426
}
427
#endif /* S390X_EC_ASM */
428
429
if (peddsactx->prehash_flag) {
430
if (!peddsactx->prehash_by_caller_flag) {
431
if (!EVP_Q_digest(peddsactx->libctx, SN_sha512, NULL,
432
tbs, tbslen, md, &mdlen)
433
|| mdlen != EDDSA_PREHASH_OUTPUT_LEN) {
434
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PREHASHED_DIGEST_LENGTH);
435
return 0;
436
}
437
tbs = md;
438
tbslen = mdlen;
439
} else if (tbslen != EDDSA_PREHASH_OUTPUT_LEN) {
440
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
441
return 0;
442
}
443
} else if (peddsactx->prehash_by_caller_flag) {
444
/* The caller is supposed to set up a ph instance! */
445
ERR_raise(ERR_LIB_PROV,
446
PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION);
447
return 0;
448
}
449
450
if (ossl_ed25519_sign(sigret, tbs, tbslen, edkey->pubkey, edkey->privkey,
451
peddsactx->dom2_flag, peddsactx->prehash_flag, peddsactx->context_string_flag,
452
peddsactx->context_string, peddsactx->context_string_len,
453
peddsactx->libctx, NULL)
454
== 0) {
455
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
456
return 0;
457
}
458
*siglen = ED25519_SIGSIZE;
459
return 1;
460
}
461
462
/* EVP_Q_digest() does not allow variable output length for XOFs,
463
so we use this function */
464
static int ed448_shake256(OSSL_LIB_CTX *libctx,
465
const char *propq,
466
const uint8_t *in, size_t inlen,
467
uint8_t *out, size_t outlen)
468
{
469
int ret = 0;
470
EVP_MD_CTX *hash_ctx = EVP_MD_CTX_new();
471
EVP_MD *shake256 = EVP_MD_fetch(libctx, SN_shake256, propq);
472
473
if (hash_ctx == NULL || shake256 == NULL)
474
goto err;
475
476
if (!EVP_DigestInit_ex(hash_ctx, shake256, NULL)
477
|| !EVP_DigestUpdate(hash_ctx, in, inlen)
478
|| !EVP_DigestFinalXOF(hash_ctx, out, outlen))
479
goto err;
480
481
ret = 1;
482
483
err:
484
EVP_MD_CTX_free(hash_ctx);
485
EVP_MD_free(shake256);
486
return ret;
487
}
488
489
/*
490
* This is used directly for OSSL_FUNC_SIGNATURE_SIGN and indirectly
491
* for OSSL_FUNC_SIGNATURE_DIGEST_SIGN
492
*/
493
static int ed448_sign(void *vpeddsactx,
494
unsigned char *sigret, size_t *siglen, size_t sigsize,
495
const unsigned char *tbs, size_t tbslen)
496
{
497
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
498
const ECX_KEY *edkey = peddsactx->key;
499
uint8_t md[EDDSA_PREHASH_OUTPUT_LEN];
500
size_t mdlen = sizeof(md);
501
502
if (!ossl_prov_is_running())
503
return 0;
504
505
if (sigret == NULL) {
506
*siglen = ED448_SIGSIZE;
507
return 1;
508
}
509
if (sigsize < ED448_SIGSIZE) {
510
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
511
return 0;
512
}
513
if (edkey->privkey == NULL) {
514
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
515
return 0;
516
}
517
#ifdef S390X_EC_ASM
518
/*
519
* s390x_ed448_digestsign() does not yet support context-strings or
520
* pre-hashing. Fall back to non-accelerated sign if a context-string or
521
* pre-hasing is provided.
522
*/
523
if (S390X_CAN_SIGN(ED448)
524
&& peddsactx->context_string_len == 0
525
&& !peddsactx->prehash_flag
526
&& !peddsactx->prehash_by_caller_flag) {
527
if (s390x_ed448_digestsign(edkey, sigret, tbs, tbslen) == 0) {
528
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
529
return 0;
530
}
531
*siglen = ED448_SIGSIZE;
532
return 1;
533
}
534
#endif /* S390X_EC_ASM */
535
536
if (peddsactx->prehash_flag) {
537
if (!peddsactx->prehash_by_caller_flag) {
538
if (!ed448_shake256(peddsactx->libctx, NULL, tbs, tbslen, md, mdlen))
539
return 0;
540
tbs = md;
541
tbslen = mdlen;
542
} else if (tbslen != EDDSA_PREHASH_OUTPUT_LEN) {
543
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
544
return 0;
545
}
546
} else if (peddsactx->prehash_by_caller_flag) {
547
/* The caller is supposed to set up a ph instance! */
548
ERR_raise(ERR_LIB_PROV,
549
PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION);
550
return 0;
551
}
552
553
if (ossl_ed448_sign(peddsactx->libctx, sigret, tbs, tbslen,
554
edkey->pubkey, edkey->privkey,
555
peddsactx->context_string, peddsactx->context_string_len,
556
peddsactx->prehash_flag, edkey->propq)
557
== 0) {
558
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
559
return 0;
560
}
561
*siglen = ED448_SIGSIZE;
562
return 1;
563
}
564
565
/*
566
* This is used directly for OSSL_FUNC_SIGNATURE_VERIFY and indirectly
567
* for OSSL_FUNC_SIGNATURE_DIGEST_VERIFY
568
*/
569
static int ed25519_verify(void *vpeddsactx,
570
const unsigned char *sig, size_t siglen,
571
const unsigned char *tbs, size_t tbslen)
572
{
573
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
574
const ECX_KEY *edkey = peddsactx->key;
575
uint8_t md[EVP_MAX_MD_SIZE];
576
size_t mdlen;
577
578
if (!ossl_prov_is_running() || siglen != ED25519_SIGSIZE)
579
return 0;
580
581
#ifdef S390X_EC_ASM
582
/*
583
* s390x_ed25519_digestverify() does not yet support dom2 or context-strings.
584
* fall back to non-accelerated verify if those options are set, or
585
* pre-hasing is provided.
586
*/
587
if (S390X_CAN_SIGN(ED25519)
588
&& !peddsactx->dom2_flag
589
&& !peddsactx->context_string_flag
590
&& peddsactx->context_string_len == 0
591
&& !peddsactx->prehash_flag
592
&& !peddsactx->prehash_by_caller_flag)
593
return s390x_ed25519_digestverify(edkey, sig, tbs, tbslen);
594
#endif /* S390X_EC_ASM */
595
596
if (peddsactx->prehash_flag) {
597
if (!peddsactx->prehash_by_caller_flag) {
598
if (!EVP_Q_digest(peddsactx->libctx, SN_sha512, NULL,
599
tbs, tbslen, md, &mdlen)
600
|| mdlen != EDDSA_PREHASH_OUTPUT_LEN) {
601
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PREHASHED_DIGEST_LENGTH);
602
return 0;
603
}
604
tbs = md;
605
tbslen = mdlen;
606
} else if (tbslen != EDDSA_PREHASH_OUTPUT_LEN) {
607
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
608
return 0;
609
}
610
} else if (peddsactx->prehash_by_caller_flag) {
611
/* The caller is supposed to set up a ph instance! */
612
ERR_raise(ERR_LIB_PROV,
613
PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION);
614
return 0;
615
}
616
617
return ossl_ed25519_verify(tbs, tbslen, sig, edkey->pubkey,
618
peddsactx->dom2_flag, peddsactx->prehash_flag, peddsactx->context_string_flag,
619
peddsactx->context_string, peddsactx->context_string_len,
620
peddsactx->libctx, edkey->propq);
621
}
622
623
/*
624
* This is used directly for OSSL_FUNC_SIGNATURE_VERIFY and indirectly
625
* for OSSL_FUNC_SIGNATURE_DIGEST_VERIFY
626
*/
627
static int ed448_verify(void *vpeddsactx,
628
const unsigned char *sig, size_t siglen,
629
const unsigned char *tbs, size_t tbslen)
630
{
631
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
632
const ECX_KEY *edkey = peddsactx->key;
633
uint8_t md[EDDSA_PREHASH_OUTPUT_LEN];
634
size_t mdlen = sizeof(md);
635
636
if (!ossl_prov_is_running() || siglen != ED448_SIGSIZE)
637
return 0;
638
639
#ifdef S390X_EC_ASM
640
/*
641
* s390x_ed448_digestverify() does not yet support context-strings or
642
* pre-hashing. Fall back to non-accelerated verify if a context-string or
643
* pre-hasing is provided.
644
*/
645
if (S390X_CAN_SIGN(ED448)
646
&& peddsactx->context_string_len == 0
647
&& !peddsactx->prehash_flag
648
&& !peddsactx->prehash_by_caller_flag)
649
return s390x_ed448_digestverify(edkey, sig, tbs, tbslen);
650
#endif /* S390X_EC_ASM */
651
652
if (peddsactx->prehash_flag) {
653
if (!peddsactx->prehash_by_caller_flag) {
654
if (!ed448_shake256(peddsactx->libctx, NULL, tbs, tbslen, md, mdlen))
655
return 0;
656
tbs = md;
657
tbslen = mdlen;
658
} else if (tbslen != EDDSA_PREHASH_OUTPUT_LEN) {
659
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
660
return 0;
661
}
662
} else if (peddsactx->prehash_by_caller_flag) {
663
/* The caller is supposed to set up a ph instance! */
664
ERR_raise(ERR_LIB_PROV,
665
PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION);
666
return 0;
667
}
668
669
return ossl_ed448_verify(peddsactx->libctx, tbs, tbslen, sig, edkey->pubkey,
670
peddsactx->context_string, peddsactx->context_string_len,
671
peddsactx->prehash_flag, edkey->propq);
672
}
673
674
/* All digest_{sign,verify} are simple wrappers around the functions above */
675
676
static int ed25519_digest_signverify_init(void *vpeddsactx, const char *mdname,
677
void *vedkey,
678
const OSSL_PARAM params[])
679
{
680
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
681
682
if (mdname != NULL && mdname[0] != '\0') {
683
ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
684
"Explicit digest not allowed with EdDSA operations");
685
return 0;
686
}
687
688
if (vedkey == NULL && peddsactx->key != NULL)
689
return eddsa_set_ctx_params(peddsactx, params);
690
691
return eddsa_signverify_init(vpeddsactx, vedkey)
692
&& eddsa_setup_instance(vpeddsactx, ID_Ed25519, 0, 0)
693
&& eddsa_set_ctx_params(vpeddsactx, params);
694
}
695
696
static int ed25519_digest_sign(void *vpeddsactx,
697
unsigned char *sigret, size_t *siglen, size_t sigsize,
698
const unsigned char *tbs, size_t tbslen)
699
{
700
return ed25519_sign(vpeddsactx, sigret, siglen, sigsize, tbs, tbslen);
701
}
702
703
static int ed25519_digest_verify(void *vpeddsactx,
704
const unsigned char *sigret, size_t siglen,
705
const unsigned char *tbs, size_t tbslen)
706
{
707
return ed25519_verify(vpeddsactx, sigret, siglen, tbs, tbslen);
708
}
709
710
static int ed448_digest_signverify_init(void *vpeddsactx, const char *mdname,
711
void *vedkey,
712
const OSSL_PARAM params[])
713
{
714
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
715
716
if (mdname != NULL && mdname[0] != '\0') {
717
ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
718
"Explicit digest not allowed with EdDSA operations");
719
return 0;
720
}
721
722
if (vedkey == NULL && peddsactx->key != NULL)
723
return eddsa_set_ctx_params(peddsactx, params);
724
725
return eddsa_signverify_init(vpeddsactx, vedkey)
726
&& eddsa_setup_instance(vpeddsactx, ID_Ed448, 0, 0)
727
&& eddsa_set_ctx_params(vpeddsactx, params);
728
}
729
730
static int ed448_digest_sign(void *vpeddsactx,
731
unsigned char *sigret, size_t *siglen, size_t sigsize,
732
const unsigned char *tbs, size_t tbslen)
733
{
734
return ed448_sign(vpeddsactx, sigret, siglen, sigsize, tbs, tbslen);
735
}
736
737
static int ed448_digest_verify(void *vpeddsactx,
738
const unsigned char *sigret, size_t siglen,
739
const unsigned char *tbs, size_t tbslen)
740
{
741
return ed448_verify(vpeddsactx, sigret, siglen, tbs, tbslen);
742
}
743
744
static void eddsa_freectx(void *vpeddsactx)
745
{
746
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
747
748
ossl_ecx_key_free(peddsactx->key);
749
750
OPENSSL_free(peddsactx);
751
}
752
753
static void *eddsa_dupctx(void *vpeddsactx)
754
{
755
PROV_EDDSA_CTX *srcctx = (PROV_EDDSA_CTX *)vpeddsactx;
756
PROV_EDDSA_CTX *dstctx;
757
758
if (!ossl_prov_is_running())
759
return NULL;
760
761
dstctx = OPENSSL_zalloc(sizeof(*srcctx));
762
if (dstctx == NULL)
763
return NULL;
764
765
*dstctx = *srcctx;
766
dstctx->key = NULL;
767
768
if (srcctx->key != NULL && !ossl_ecx_key_up_ref(srcctx->key)) {
769
ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
770
goto err;
771
}
772
dstctx->key = srcctx->key;
773
774
return dstctx;
775
err:
776
eddsa_freectx(dstctx);
777
return NULL;
778
}
779
780
static const char **ed25519_sigalg_query_key_types(void)
781
{
782
static const char *keytypes[] = { "ED25519", NULL };
783
784
return keytypes;
785
}
786
787
static const char **ed448_sigalg_query_key_types(void)
788
{
789
static const char *keytypes[] = { "ED448", NULL };
790
791
return keytypes;
792
}
793
794
static int eddsa_get_ctx_params(void *vpeddsactx, OSSL_PARAM *params)
795
{
796
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
797
OSSL_PARAM *p;
798
799
if (peddsactx == NULL)
800
return 0;
801
802
p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID);
803
if (p != NULL
804
&& !OSSL_PARAM_set_octet_string(p,
805
peddsactx->aid_len == 0 ? NULL : peddsactx->aid_buf,
806
peddsactx->aid_len))
807
return 0;
808
809
return 1;
810
}
811
812
static const OSSL_PARAM known_gettable_ctx_params[] = {
813
OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
814
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_INSTANCE, NULL, 0),
815
OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0),
816
OSSL_PARAM_END
817
};
818
819
static const OSSL_PARAM *eddsa_gettable_ctx_params(ossl_unused void *vpeddsactx,
820
ossl_unused void *provctx)
821
{
822
return known_gettable_ctx_params;
823
}
824
825
static int eddsa_set_ctx_params(void *vpeddsactx, const OSSL_PARAM params[])
826
{
827
PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
828
const OSSL_PARAM *p;
829
830
if (peddsactx == NULL)
831
return 0;
832
if (ossl_param_is_empty(params))
833
return 1;
834
835
p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_INSTANCE);
836
if (p != NULL) {
837
char instance_name[OSSL_MAX_NAME_SIZE] = "";
838
char *pinstance_name = instance_name;
839
840
if (peddsactx->instance_id_preset_flag) {
841
/* When the instance is preset, the caller must no try to set it */
842
ERR_raise_data(ERR_LIB_PROV, PROV_R_NO_INSTANCE_ALLOWED,
843
"the EdDSA instance is preset, you may not try to specify it",
844
NULL);
845
return 0;
846
}
847
848
if (!OSSL_PARAM_get_utf8_string(p, &pinstance_name, sizeof(instance_name)))
849
return 0;
850
851
/*
852
* When setting the new instance, we're careful not to change the
853
* prehash_by_caller flag, as that's always preset by the init
854
* functions. The sign functions will determine if the instance
855
* matches this flag.
856
*/
857
if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519) == 0) {
858
eddsa_setup_instance(peddsactx, ID_Ed25519, 0,
859
peddsactx->prehash_by_caller_flag);
860
#ifndef FIPS_MODULE
861
} else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519ctx) == 0) {
862
eddsa_setup_instance(peddsactx, ID_Ed25519ctx, 0,
863
peddsactx->prehash_by_caller_flag);
864
#endif
865
} else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519ph) == 0) {
866
eddsa_setup_instance(peddsactx, ID_Ed25519ph, 0,
867
peddsactx->prehash_by_caller_flag);
868
} else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed448) == 0) {
869
eddsa_setup_instance(peddsactx, ID_Ed448, 0,
870
peddsactx->prehash_by_caller_flag);
871
} else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed448ph) == 0) {
872
eddsa_setup_instance(peddsactx, ID_Ed448ph, 0,
873
peddsactx->prehash_by_caller_flag);
874
} else {
875
/* we did not recognize the instance */
876
ERR_raise_data(ERR_LIB_PROV,
877
PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION,
878
"unknown INSTANCE name: %s",
879
pinstance_name != NULL ? pinstance_name : "<null>");
880
return 0;
881
}
882
}
883
884
p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_CONTEXT_STRING);
885
if (p != NULL) {
886
void *vp_context_string = peddsactx->context_string;
887
888
if (!OSSL_PARAM_get_octet_string(p, &vp_context_string, sizeof(peddsactx->context_string), &(peddsactx->context_string_len))) {
889
peddsactx->context_string_len = 0;
890
return 0;
891
}
892
}
893
894
return 1;
895
}
896
897
static const OSSL_PARAM settable_ctx_params[] = {
898
OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_INSTANCE, NULL, 0),
899
OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0),
900
OSSL_PARAM_END
901
};
902
903
static const OSSL_PARAM *eddsa_settable_ctx_params(ossl_unused void *vpeddsactx,
904
ossl_unused void *provctx)
905
{
906
return settable_ctx_params;
907
}
908
909
static const OSSL_PARAM settable_variant_ctx_params[] = {
910
OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0),
911
OSSL_PARAM_END
912
};
913
914
static const OSSL_PARAM *
915
eddsa_settable_variant_ctx_params(ossl_unused void *vpeddsactx,
916
ossl_unused void *provctx)
917
{
918
return settable_variant_ctx_params;
919
}
920
921
/*
922
* Ed25519 can be used with:
923
* - EVP_PKEY_sign_init_ex2() [ instance and prehash assumed done by caller ]
924
* - EVP_PKEY_verify_init_ex2() [ instance and prehash assumed done by caller ]
925
* - EVP_PKEY_sign_message_init()
926
* - EVP_PKEY_verify_message_init()
927
* - EVP_DigestSignInit_ex()
928
* - EVP_DigestVerifyInit_ex()
929
* Ed25519ph can be used with:
930
* - EVP_PKEY_sign_init_ex2() [ prehash assumed done by caller ]
931
* - EVP_PKEY_verify_init_ex2() [ prehash assumed done by caller ]
932
* - EVP_PKEY_sign_message_init()
933
* - EVP_PKEY_verify_message_init()
934
* Ed25519ctx can be used with:
935
* - EVP_PKEY_sign_message_init()
936
* - EVP_PKEY_verify_message_init()
937
* Ed448 can be used with:
938
* - EVP_PKEY_sign_init_ex2() [ instance and prehash assumed done by caller ]
939
* - EVP_PKEY_verify_init_ex2() [ instance and prehash assumed done by caller ]
940
* - EVP_PKEY_sign_message_init()
941
* - EVP_PKEY_verify_message_init()
942
* - EVP_DigestSignInit_ex()
943
* - EVP_DigestVerifyInit_ex()
944
* Ed448ph can be used with:
945
* - EVP_PKEY_sign_init_ex2() [ prehash assumed done by caller ]
946
* - EVP_PKEY_verify_init_ex2() [ prehash assumed done by caller ]
947
* - EVP_PKEY_sign_message_init()
948
* - EVP_PKEY_verify_message_init()
949
*/
950
951
#define ed25519_DISPATCH_END \
952
{ OSSL_FUNC_SIGNATURE_SIGN_INIT, \
953
(void (*)(void))ed25519_signverify_init }, \
954
{ OSSL_FUNC_SIGNATURE_VERIFY_INIT, \
955
(void (*)(void))ed25519_signverify_init }, \
956
{ OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, \
957
(void (*)(void))ed25519_digest_signverify_init }, \
958
{ OSSL_FUNC_SIGNATURE_DIGEST_SIGN, \
959
(void (*)(void))ed25519_digest_sign }, \
960
{ OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, \
961
(void (*)(void))ed25519_digest_signverify_init }, \
962
{ OSSL_FUNC_SIGNATURE_DIGEST_VERIFY, \
963
(void (*)(void))ed25519_digest_verify }, \
964
{ OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \
965
(void (*)(void))eddsa_get_ctx_params }, \
966
{ OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \
967
(void (*)(void))eddsa_gettable_ctx_params }, \
968
{ OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \
969
(void (*)(void))eddsa_set_ctx_params }, \
970
{ OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \
971
(void (*)(void))eddsa_settable_ctx_params }, \
972
OSSL_DISPATCH_END
973
974
#define eddsa_variant_DISPATCH_END(v) \
975
{ OSSL_FUNC_SIGNATURE_SIGN_INIT, \
976
(void (*)(void))v##_signverify_message_init }, \
977
{ OSSL_FUNC_SIGNATURE_VERIFY_INIT, \
978
(void (*)(void))v##_signverify_message_init }, \
979
{ OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \
980
(void (*)(void))eddsa_get_ctx_params }, \
981
{ OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \
982
(void (*)(void))eddsa_gettable_ctx_params }, \
983
{ OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \
984
(void (*)(void))eddsa_set_ctx_params }, \
985
{ OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \
986
(void (*)(void))eddsa_settable_variant_ctx_params }, \
987
OSSL_DISPATCH_END
988
989
#define ed25519ph_DISPATCH_END \
990
{ OSSL_FUNC_SIGNATURE_SIGN_INIT, \
991
(void (*)(void))ed25519ph_signverify_init }, \
992
{ OSSL_FUNC_SIGNATURE_VERIFY_INIT, \
993
(void (*)(void))ed25519ph_signverify_init }, \
994
eddsa_variant_DISPATCH_END(ed25519ph)
995
996
#define ed25519ctx_DISPATCH_END eddsa_variant_DISPATCH_END(ed25519ctx)
997
998
#define ed448_DISPATCH_END \
999
{ OSSL_FUNC_SIGNATURE_SIGN_INIT, \
1000
(void (*)(void))ed448_signverify_init }, \
1001
{ OSSL_FUNC_SIGNATURE_VERIFY_INIT, \
1002
(void (*)(void))ed448_signverify_init }, \
1003
{ OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, \
1004
(void (*)(void))ed448_digest_signverify_init }, \
1005
{ OSSL_FUNC_SIGNATURE_DIGEST_SIGN, \
1006
(void (*)(void))ed448_digest_sign }, \
1007
{ OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, \
1008
(void (*)(void))ed448_digest_signverify_init }, \
1009
{ OSSL_FUNC_SIGNATURE_DIGEST_VERIFY, \
1010
(void (*)(void))ed448_digest_verify }, \
1011
{ OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \
1012
(void (*)(void))eddsa_get_ctx_params }, \
1013
{ OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \
1014
(void (*)(void))eddsa_gettable_ctx_params }, \
1015
{ OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \
1016
(void (*)(void))eddsa_set_ctx_params }, \
1017
{ OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \
1018
(void (*)(void))eddsa_settable_ctx_params }, \
1019
OSSL_DISPATCH_END
1020
1021
#define ed448ph_DISPATCH_END \
1022
{ OSSL_FUNC_SIGNATURE_SIGN_INIT, \
1023
(void (*)(void))ed448ph_signverify_init }, \
1024
{ OSSL_FUNC_SIGNATURE_VERIFY_INIT, \
1025
(void (*)(void))ed448ph_signverify_init }, \
1026
eddsa_variant_DISPATCH_END(ed448ph)
1027
1028
/* vn = variant name, bn = base name */
1029
#define IMPL_EDDSA_DISPATCH(vn, bn) \
1030
const OSSL_DISPATCH ossl_##vn##_signature_functions[] = { \
1031
{ OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx }, \
1032
{ OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_INIT, \
1033
(void (*)(void))vn##_signverify_message_init }, \
1034
{ OSSL_FUNC_SIGNATURE_SIGN, \
1035
(void (*)(void))bn##_sign }, \
1036
{ OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_INIT, \
1037
(void (*)(void))vn##_signverify_message_init }, \
1038
{ OSSL_FUNC_SIGNATURE_VERIFY, \
1039
(void (*)(void))bn##_verify }, \
1040
{ OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx }, \
1041
{ OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx }, \
1042
{ OSSL_FUNC_SIGNATURE_QUERY_KEY_TYPES, \
1043
(void (*)(void))bn##_sigalg_query_key_types }, \
1044
vn##_DISPATCH_END \
1045
}
1046
1047
IMPL_EDDSA_DISPATCH(ed25519, ed25519);
1048
IMPL_EDDSA_DISPATCH(ed25519ph, ed25519);
1049
IMPL_EDDSA_DISPATCH(ed25519ctx, ed25519);
1050
IMPL_EDDSA_DISPATCH(ed448, ed448);
1051
IMPL_EDDSA_DISPATCH(ed448ph, ed448);
1052
1053
#ifdef S390X_EC_ASM
1054
1055
static int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig,
1056
const unsigned char *tbs, size_t tbslen)
1057
{
1058
int rc;
1059
union {
1060
struct {
1061
unsigned char sig[64];
1062
unsigned char priv[32];
1063
} ed25519;
1064
unsigned long long buff[512];
1065
} param;
1066
1067
memset(&param, 0, sizeof(param));
1068
memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1069
1070
rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, &param.ed25519, tbs, tbslen);
1071
OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1072
if (rc != 0)
1073
return 0;
1074
1075
s390x_flip_endian32(sig, param.ed25519.sig);
1076
s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1077
return 1;
1078
}
1079
1080
static int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig,
1081
const unsigned char *tbs, size_t tbslen)
1082
{
1083
int rc;
1084
union {
1085
struct {
1086
unsigned char sig[128];
1087
unsigned char priv[64];
1088
} ed448;
1089
unsigned long long buff[512];
1090
} param;
1091
1092
memset(&param, 0, sizeof(param));
1093
memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1094
1095
rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, &param.ed448, tbs, tbslen);
1096
OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1097
if (rc != 0)
1098
return 0;
1099
1100
s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1101
s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1102
memcpy(sig, param.ed448.sig, 57);
1103
memcpy(sig + 57, param.ed448.sig + 64, 57);
1104
return 1;
1105
}
1106
1107
static int s390x_ed25519_digestverify(const ECX_KEY *edkey,
1108
const unsigned char *sig,
1109
const unsigned char *tbs, size_t tbslen)
1110
{
1111
union {
1112
struct {
1113
unsigned char sig[64];
1114
unsigned char pub[32];
1115
} ed25519;
1116
unsigned long long buff[512];
1117
} param;
1118
1119
memset(&param, 0, sizeof(param));
1120
s390x_flip_endian32(param.ed25519.sig, sig);
1121
s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1122
s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1123
1124
return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1125
&param.ed25519, tbs, tbslen)
1126
== 0
1127
? 1
1128
: 0;
1129
}
1130
1131
static int s390x_ed448_digestverify(const ECX_KEY *edkey,
1132
const unsigned char *sig,
1133
const unsigned char *tbs,
1134
size_t tbslen)
1135
{
1136
union {
1137
struct {
1138
unsigned char sig[128];
1139
unsigned char pub[64];
1140
} ed448;
1141
unsigned long long buff[512];
1142
} param;
1143
1144
memset(&param, 0, sizeof(param));
1145
memcpy(param.ed448.sig, sig, 57);
1146
s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1147
memcpy(param.ed448.sig + 64, sig + 57, 57);
1148
s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1149
memcpy(param.ed448.pub, edkey->pubkey, 57);
1150
s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1151
1152
return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1153
&param.ed448, tbs, tbslen)
1154
== 0
1155
? 1
1156
: 0;
1157
}
1158
1159
#endif /* S390X_EC_ASM */
1160
1161