Coverage Report

Created: 2026-09-12 06:55

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