Coverage Report

Created: 2025-12-10 06:24

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