Coverage Report

Created: 2026-10-28 06:28

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