Coverage Report

Created: 2025-12-04 06:33

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