Coverage Report

Created: 2025-10-28 06:56

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