Coverage Report

Created: 2026-10-28 06:28

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