Coverage Report

Created: 2025-12-31 06:58

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