Coverage Report

Created: 2025-06-13 06:58

/src/openssl32/providers/implementations/signature/eddsa_sig.c
Line
Count
Source (jump to first uncovered line)
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/provider_ctx.h"
22
#include "prov/der_ecx.h"
23
#include "crypto/ecx.h"
24
25
#ifdef S390X_EC_ASM
26
# include "s390x_arch.h"
27
28
# define S390X_CAN_SIGN(edtype)                                                \
29
((OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_##edtype))    \
30
&& (OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_##edtype))      \
31
&& (OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_##edtype)))
32
33
static int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig,
34
                                    const unsigned char *tbs, size_t tbslen);
35
static int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig,
36
                                  const unsigned char *tbs, size_t tbslen);
37
static int s390x_ed25519_digestverify(const ECX_KEY *edkey,
38
                                      const unsigned char *sig,
39
                                      const unsigned char *tbs, size_t tbslen);
40
static int s390x_ed448_digestverify(const ECX_KEY *edkey,
41
                                    const unsigned char *sig,
42
                                    const unsigned char *tbs, size_t tbslen);
43
44
#endif /* S390X_EC_ASM */
45
46
enum ID_EdDSA_INSTANCE {
47
    ID_NOT_SET = 0,
48
    ID_Ed25519,
49
    ID_Ed25519ctx,
50
    ID_Ed25519ph,
51
    ID_Ed448,
52
    ID_Ed448ph
53
};
54
55
0
#define SN_Ed25519    "Ed25519"
56
0
#define SN_Ed25519ph  "Ed25519ph"
57
0
#define SN_Ed25519ctx "Ed25519ctx"
58
0
#define SN_Ed448      "Ed448"
59
0
#define SN_Ed448ph    "Ed448ph"
60
61
#define EDDSA_MAX_CONTEXT_STRING_LEN 255
62
0
#define EDDSA_PREHASH_OUTPUT_LEN 64
63
64
static OSSL_FUNC_signature_newctx_fn eddsa_newctx;
65
static OSSL_FUNC_signature_digest_sign_init_fn eddsa_digest_signverify_init;
66
static OSSL_FUNC_signature_digest_sign_fn ed25519_digest_sign;
67
static OSSL_FUNC_signature_digest_sign_fn ed448_digest_sign;
68
static OSSL_FUNC_signature_digest_verify_fn ed25519_digest_verify;
69
static OSSL_FUNC_signature_digest_verify_fn ed448_digest_verify;
70
static OSSL_FUNC_signature_freectx_fn eddsa_freectx;
71
static OSSL_FUNC_signature_dupctx_fn eddsa_dupctx;
72
static OSSL_FUNC_signature_get_ctx_params_fn eddsa_get_ctx_params;
73
static OSSL_FUNC_signature_gettable_ctx_params_fn eddsa_gettable_ctx_params;
74
static OSSL_FUNC_signature_set_ctx_params_fn eddsa_set_ctx_params;
75
static OSSL_FUNC_signature_settable_ctx_params_fn eddsa_settable_ctx_params;
76
77
/* there are five EdDSA instances:
78
79
         Ed25519
80
         Ed25519ph
81
         Ed25519ctx
82
         Ed448
83
         Ed448ph
84
85
   Quoting from RFC 8032, Section 5.1:
86
87
     For Ed25519, dom2(f,c) is the empty string.  The phflag value is
88
     irrelevant.  The context (if present at all) MUST be empty.  This
89
     causes the scheme to be one and the same with the Ed25519 scheme
90
     published earlier.
91
92
     For Ed25519ctx, phflag=0.  The context input SHOULD NOT be empty.
93
94
     For Ed25519ph, phflag=1 and PH is SHA512 instead.  That is, the input
95
     is hashed using SHA-512 before signing with Ed25519.
96
97
   Quoting from RFC 8032, Section 5.2:
98
99
     Ed448ph is the same but with PH being SHAKE256(x, 64) and phflag
100
     being 1, i.e., the input is hashed before signing with Ed448 with a
101
     hash constant modified.
102
103
     Value of context is set by signer and verifier (maximum of 255
104
     octets; the default is empty string) and has to match octet by octet
105
     for verification to be successful.
106
107
   Quoting from RFC 8032, Section 2:
108
109
     dom2(x, y)     The blank octet string when signing or verifying
110
                    Ed25519.  Otherwise, the octet string: "SigEd25519 no
111
                    Ed25519 collisions" || octet(x) || octet(OLEN(y)) ||
112
                    y, where x is in range 0-255 and y is an octet string
113
                    of at most 255 octets.  "SigEd25519 no Ed25519
114
                    collisions" is in ASCII (32 octets).
115
116
     dom4(x, y)     The octet string "SigEd448" || octet(x) ||
117
                    octet(OLEN(y)) || y, where x is in range 0-255 and y
118
                    is an octet string of at most 255 octets.  "SigEd448"
119
                    is in ASCII (8 octets).
120
121
   Note above that x is the pre-hash flag, and y is the context string.
122
*/
123
124
typedef struct {
125
    OSSL_LIB_CTX *libctx;
126
    ECX_KEY *key;
127
128
    /* The Algorithm Identifier of the signature algorithm */
129
    unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE];
130
    unsigned char *aid;
131
    size_t  aid_len;
132
133
    /* id indicating the EdDSA instance */
134
    int instance_id;
135
136
    unsigned int dom2_flag : 1;
137
    unsigned int prehash_flag : 1;
138
139
    /* indicates that a non-empty context string is required, as in Ed25519ctx */
140
    unsigned int context_string_flag : 1;
141
142
    unsigned char context_string[EDDSA_MAX_CONTEXT_STRING_LEN];
143
    size_t context_string_len;
144
145
} PROV_EDDSA_CTX;
146
147
static void *eddsa_newctx(void *provctx, const char *propq_unused)
148
198
{
149
198
    PROV_EDDSA_CTX *peddsactx;
150
151
198
    if (!ossl_prov_is_running())
152
0
        return NULL;
153
154
198
    peddsactx = OPENSSL_zalloc(sizeof(PROV_EDDSA_CTX));
155
198
    if (peddsactx == NULL)
156
0
        return NULL;
157
158
198
    peddsactx->libctx = PROV_LIBCTX_OF(provctx);
159
160
198
    return peddsactx;
161
198
}
162
163
static int eddsa_digest_signverify_init(void *vpeddsactx, const char *mdname,
164
                                        void *vedkey,
165
                                        const OSSL_PARAM params[])
166
74
{
167
74
    PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
168
74
    ECX_KEY *edkey = (ECX_KEY *)vedkey;
169
74
    WPACKET pkt;
170
74
    int ret;
171
172
74
    if (!ossl_prov_is_running())
173
0
        return 0;
174
175
74
    if (mdname != NULL && mdname[0] != '\0') {
176
0
        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST);
177
0
        return 0;
178
0
    }
179
180
74
    if (edkey == NULL) {
181
0
        if (peddsactx->key != NULL)
182
0
            return eddsa_set_ctx_params(peddsactx, params);
183
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
184
0
        return 0;
185
0
    }
186
187
74
    if (!ossl_ecx_key_up_ref(edkey)) {
188
0
        ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
189
0
        return 0;
190
0
    }
191
192
74
    peddsactx->dom2_flag = 0;
193
74
    peddsactx->prehash_flag = 0;
194
74
    peddsactx->context_string_flag = 0;
195
74
    peddsactx->context_string_len = 0;
196
197
    /*
198
     * We do not care about DER writing errors.
199
     * All it really means is that for some reason, there's no
200
     * AlgorithmIdentifier to be had, but the operation itself is
201
     * still valid, just as long as it's not used to construct
202
     * anything that needs an AlgorithmIdentifier.
203
     */
204
74
    peddsactx->aid_len = 0;
205
74
    ret = WPACKET_init_der(&pkt, peddsactx->aid_buf, sizeof(peddsactx->aid_buf));
206
74
    switch (edkey->type) {
207
0
    case ECX_KEY_TYPE_ED25519:
208
0
        ret = ret && ossl_DER_w_algorithmIdentifier_ED25519(&pkt, -1, edkey);
209
0
        peddsactx->instance_id = ID_Ed25519;
210
0
        break;
211
74
    case ECX_KEY_TYPE_ED448:
212
74
        ret = ret && ossl_DER_w_algorithmIdentifier_ED448(&pkt, -1, edkey);
213
74
        peddsactx->instance_id = ID_Ed448;
214
74
        break;
215
0
    default:
216
        /* Should never happen */
217
0
        ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
218
0
        ossl_ecx_key_free(edkey);
219
0
        WPACKET_cleanup(&pkt);
220
0
        return 0;
221
74
    }
222
74
    if (ret && WPACKET_finish(&pkt)) {
223
74
        WPACKET_get_total_written(&pkt, &peddsactx->aid_len);
224
74
        peddsactx->aid = WPACKET_get_curr(&pkt);
225
74
    }
226
74
    WPACKET_cleanup(&pkt);
227
228
74
    peddsactx->key = edkey;
229
230
74
    if (!eddsa_set_ctx_params(peddsactx, params))
231
0
        return 0;
232
233
74
    return 1;
234
74
}
235
236
int ed25519_digest_sign(void *vpeddsactx, unsigned char *sigret,
237
                        size_t *siglen, size_t sigsize,
238
                        const unsigned char *tbs, size_t tbslen)
239
0
{
240
0
    PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
241
0
    const ECX_KEY *edkey = peddsactx->key;
242
0
    uint8_t md[EVP_MAX_MD_SIZE];
243
0
    size_t mdlen;
244
245
0
    if (!ossl_prov_is_running())
246
0
        return 0;
247
248
0
    if (sigret == NULL) {
249
0
        *siglen = ED25519_SIGSIZE;
250
0
        return 1;
251
0
    }
252
0
    if (sigsize < ED25519_SIGSIZE) {
253
0
        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
254
0
        return 0;
255
0
    }
256
0
    if (edkey->privkey == NULL) {
257
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
258
0
        return 0;
259
0
    }
260
#ifdef S390X_EC_ASM
261
    /* s390x_ed25519_digestsign() does not yet support dom2 or context-strings.
262
       fall back to non-accelerated sign if those options are set. */
263
    if (S390X_CAN_SIGN(ED25519)
264
            && !peddsactx->dom2_flag
265
            && !peddsactx->context_string_flag
266
            && peddsactx->context_string_len == 0) {
267
        if (s390x_ed25519_digestsign(edkey, sigret, tbs, tbslen) == 0) {
268
            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
269
            return 0;
270
        }
271
        *siglen = ED25519_SIGSIZE;
272
        return 1;
273
    }
274
#endif /* S390X_EC_ASM */
275
276
0
    if (peddsactx->prehash_flag) {
277
0
        if (!EVP_Q_digest(peddsactx->libctx, SN_sha512, NULL, tbs, tbslen, md, &mdlen)
278
0
                || mdlen != EDDSA_PREHASH_OUTPUT_LEN)
279
0
            return 0;
280
0
        tbs = md;
281
0
        tbslen = mdlen;
282
0
    }
283
284
0
    if (ossl_ed25519_sign(sigret, tbs, tbslen, edkey->pubkey, edkey->privkey,
285
0
            peddsactx->dom2_flag, peddsactx->prehash_flag, peddsactx->context_string_flag,
286
0
            peddsactx->context_string, peddsactx->context_string_len,
287
0
            peddsactx->libctx, NULL) == 0) {
288
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
289
0
        return 0;
290
0
    }
291
0
    *siglen = ED25519_SIGSIZE;
292
0
    return 1;
293
0
}
294
295
/* EVP_Q_digest() does not allow variable output length for XOFs,
296
   so we use this function */
297
static int ed448_shake256(OSSL_LIB_CTX *libctx,
298
                          const char *propq,
299
                          const uint8_t *in, size_t inlen,
300
                          uint8_t *out, size_t outlen)
301
0
{
302
0
    int ret = 0;
303
0
    EVP_MD_CTX *hash_ctx = EVP_MD_CTX_new();
304
0
    EVP_MD *shake256 = EVP_MD_fetch(libctx, SN_shake256, propq);
305
306
0
    if (hash_ctx == NULL || shake256 == NULL)
307
0
        goto err;
308
309
0
    if (!EVP_DigestInit_ex(hash_ctx, shake256, NULL)
310
0
            || !EVP_DigestUpdate(hash_ctx, in, inlen)
311
0
            || !EVP_DigestFinalXOF(hash_ctx, out, outlen))
312
0
        goto err;
313
314
0
    ret = 1;
315
316
0
 err:
317
0
    EVP_MD_CTX_free(hash_ctx);
318
0
    EVP_MD_free(shake256);
319
0
    return ret;
320
0
}
321
322
int ed448_digest_sign(void *vpeddsactx, unsigned char *sigret,
323
                      size_t *siglen, size_t sigsize,
324
                      const unsigned char *tbs, size_t tbslen)
325
0
{
326
0
    PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
327
0
    const ECX_KEY *edkey = peddsactx->key;
328
0
    uint8_t md[EDDSA_PREHASH_OUTPUT_LEN];
329
0
    size_t mdlen = sizeof(md);
330
331
0
    if (!ossl_prov_is_running())
332
0
        return 0;
333
334
0
    if (sigret == NULL) {
335
0
        *siglen = ED448_SIGSIZE;
336
0
        return 1;
337
0
    }
338
0
    if (sigsize < ED448_SIGSIZE) {
339
0
        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
340
0
        return 0;
341
0
    }
342
0
    if (edkey->privkey == NULL) {
343
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
344
0
        return 0;
345
0
    }
346
#ifdef S390X_EC_ASM
347
    /* s390x_ed448_digestsign() does not yet support context-strings or pre-hashing.
348
       fall back to non-accelerated sign if a context-string or pre-hasing is provided. */
349
    if (S390X_CAN_SIGN(ED448)
350
            && peddsactx->context_string_len == 0
351
            && peddsactx->prehash_flag == 0) {
352
        if (s390x_ed448_digestsign(edkey, sigret, tbs, tbslen) == 0) {
353
            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
354
            return 0;
355
        }
356
        *siglen = ED448_SIGSIZE;
357
        return 1;
358
    }
359
#endif /* S390X_EC_ASM */
360
361
0
    if (peddsactx->prehash_flag) {
362
0
        if (!ed448_shake256(peddsactx->libctx, NULL, tbs, tbslen, md, mdlen))
363
0
            return 0;
364
0
        tbs = md;
365
0
        tbslen = mdlen;
366
0
    }
367
368
0
    if (ossl_ed448_sign(peddsactx->libctx, sigret, tbs, tbslen,
369
0
                        edkey->pubkey, edkey->privkey,
370
0
                        peddsactx->context_string, peddsactx->context_string_len,
371
0
                        peddsactx->prehash_flag, edkey->propq) == 0) {
372
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
373
0
        return 0;
374
0
    }
375
0
    *siglen = ED448_SIGSIZE;
376
0
    return 1;
377
0
}
378
379
int ed25519_digest_verify(void *vpeddsactx, const unsigned char *sig,
380
                          size_t siglen, const unsigned char *tbs,
381
                          size_t tbslen)
382
0
{
383
0
    PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
384
0
    const ECX_KEY *edkey = peddsactx->key;
385
0
    uint8_t md[EVP_MAX_MD_SIZE];
386
0
    size_t mdlen;
387
388
0
    if (!ossl_prov_is_running() || siglen != ED25519_SIGSIZE)
389
0
        return 0;
390
391
#ifdef S390X_EC_ASM
392
    /* s390x_ed25519_digestverify() does not yet support dom2 or context-strings.
393
       fall back to non-accelerated verify if those options are set. */
394
    if (S390X_CAN_SIGN(ED25519)
395
            && !peddsactx->dom2_flag
396
            && !peddsactx->context_string_flag
397
            && peddsactx->context_string_len == 0) {
398
        return s390x_ed25519_digestverify(edkey, sig, tbs, tbslen);
399
    }
400
#endif /* S390X_EC_ASM */
401
402
0
    if (peddsactx->prehash_flag) {
403
0
        if (!EVP_Q_digest(peddsactx->libctx, SN_sha512, NULL, tbs, tbslen, md, &mdlen)
404
0
                || mdlen != EDDSA_PREHASH_OUTPUT_LEN)
405
0
            return 0;
406
0
        tbs = md;
407
0
        tbslen = mdlen;
408
0
    }
409
410
0
    return ossl_ed25519_verify(tbs, tbslen, sig, edkey->pubkey,
411
0
                               peddsactx->dom2_flag, peddsactx->prehash_flag, peddsactx->context_string_flag,
412
0
                               peddsactx->context_string, peddsactx->context_string_len,
413
0
                               peddsactx->libctx, edkey->propq);
414
0
}
415
416
int ed448_digest_verify(void *vpeddsactx, const unsigned char *sig,
417
                        size_t siglen, const unsigned char *tbs,
418
                        size_t tbslen)
419
74
{
420
74
    PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
421
74
    const ECX_KEY *edkey = peddsactx->key;
422
74
    uint8_t md[EDDSA_PREHASH_OUTPUT_LEN];
423
74
    size_t mdlen = sizeof(md);
424
425
74
    if (!ossl_prov_is_running() || siglen != ED448_SIGSIZE)
426
11
        return 0;
427
428
#ifdef S390X_EC_ASM
429
    /* s390x_ed448_digestverify() does not yet support context-strings or pre-hashing.
430
       fall back to non-accelerated verify if a context-string or pre-hasing is provided. */
431
    if (S390X_CAN_SIGN(ED448)
432
            && peddsactx->context_string_len == 0
433
            && peddsactx->prehash_flag == 0) {
434
        return s390x_ed448_digestverify(edkey, sig, tbs, tbslen);
435
    }
436
#endif /* S390X_EC_ASM */
437
438
63
    if (peddsactx->prehash_flag) {
439
0
        if (!ed448_shake256(peddsactx->libctx, NULL, tbs, tbslen, md, mdlen))
440
0
            return 0;
441
0
        tbs = md;
442
0
        tbslen = mdlen;
443
0
    }
444
445
63
    return ossl_ed448_verify(peddsactx->libctx, tbs, tbslen, sig, edkey->pubkey,
446
63
                             peddsactx->context_string, peddsactx->context_string_len,
447
63
                             peddsactx->prehash_flag, edkey->propq);
448
63
}
449
450
static void eddsa_freectx(void *vpeddsactx)
451
198
{
452
198
    PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
453
454
198
    ossl_ecx_key_free(peddsactx->key);
455
456
198
    OPENSSL_free(peddsactx);
457
198
}
458
459
static void *eddsa_dupctx(void *vpeddsactx)
460
0
{
461
0
    PROV_EDDSA_CTX *srcctx = (PROV_EDDSA_CTX *)vpeddsactx;
462
0
    PROV_EDDSA_CTX *dstctx;
463
464
0
    if (!ossl_prov_is_running())
465
0
        return NULL;
466
467
0
    dstctx = OPENSSL_zalloc(sizeof(*srcctx));
468
0
    if (dstctx == NULL)
469
0
        return NULL;
470
471
0
    *dstctx = *srcctx;
472
0
    dstctx->key = NULL;
473
474
0
    if (srcctx->key != NULL && !ossl_ecx_key_up_ref(srcctx->key)) {
475
0
        ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
476
0
        goto err;
477
0
    }
478
0
    dstctx->key = srcctx->key;
479
480
0
    return dstctx;
481
0
 err:
482
0
    eddsa_freectx(dstctx);
483
0
    return NULL;
484
0
}
485
486
static int eddsa_get_ctx_params(void *vpeddsactx, OSSL_PARAM *params)
487
0
{
488
0
    PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
489
0
    OSSL_PARAM *p;
490
491
0
    if (peddsactx == NULL)
492
0
        return 0;
493
494
0
    p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID);
495
0
    if (p != NULL && !OSSL_PARAM_set_octet_string(p, peddsactx->aid,
496
0
                                                  peddsactx->aid_len))
497
0
        return 0;
498
499
0
    return 1;
500
0
}
501
502
static const OSSL_PARAM known_gettable_ctx_params[] = {
503
    OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
504
    OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_INSTANCE, NULL, 0),
505
    OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0),
506
    OSSL_PARAM_END
507
};
508
509
static const OSSL_PARAM *eddsa_gettable_ctx_params(ossl_unused void *vpeddsactx,
510
                                                   ossl_unused void *provctx)
511
0
{
512
0
    return known_gettable_ctx_params;
513
0
}
514
515
static int eddsa_set_ctx_params(void *vpeddsactx, const OSSL_PARAM params[])
516
74
{
517
74
    PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
518
74
    const OSSL_PARAM *p;
519
520
74
    if (peddsactx == NULL)
521
0
        return 0;
522
74
    if (params == NULL)
523
74
        return 1;
524
525
0
    p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_INSTANCE);
526
0
    if (p != NULL) {
527
0
        char instance_name[OSSL_MAX_NAME_SIZE] = "";
528
0
        char *pinstance_name = instance_name;
529
530
0
        if (!OSSL_PARAM_get_utf8_string(p, &pinstance_name, sizeof(instance_name)))
531
0
            return 0;
532
533
0
        if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519) == 0) {
534
0
            peddsactx->instance_id = ID_Ed25519;
535
0
            if (peddsactx->key->type != ECX_KEY_TYPE_ED25519) return 0;
536
0
            peddsactx->dom2_flag = 0;
537
0
            peddsactx->prehash_flag = 0;
538
0
            peddsactx->context_string_flag = 0;
539
0
        } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519ctx) == 0) {
540
0
            peddsactx->instance_id = ID_Ed25519ctx;
541
0
            if (peddsactx->key->type != ECX_KEY_TYPE_ED25519) return 0;
542
0
            peddsactx->dom2_flag = 1;
543
0
            peddsactx->prehash_flag = 0;
544
0
            peddsactx->context_string_flag = 1;
545
0
        } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519ph) == 0) {
546
0
            peddsactx->instance_id = ID_Ed25519ph;
547
0
            if (peddsactx->key->type != ECX_KEY_TYPE_ED25519) return 0;
548
0
            peddsactx->dom2_flag = 1;
549
0
            peddsactx->prehash_flag = 1;
550
0
            peddsactx->context_string_flag = 0;
551
0
        } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed448) == 0) {
552
0
            peddsactx->instance_id = ID_Ed448;
553
0
            if (peddsactx->key->type != ECX_KEY_TYPE_ED448) return 0;
554
0
            peddsactx->prehash_flag = 0;
555
0
            peddsactx->context_string_flag = 0;
556
0
        } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed448ph) == 0) {
557
0
            peddsactx->instance_id = ID_Ed448ph;
558
0
            if (peddsactx->key->type != ECX_KEY_TYPE_ED448) return 0;
559
0
            peddsactx->prehash_flag = 1;
560
0
            peddsactx->context_string_flag = 0;
561
0
        } else {
562
            /* we did not recognize the instance */
563
0
            return 0;
564
0
        }
565
566
0
    }
567
568
0
    p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_CONTEXT_STRING);
569
0
    if (p != NULL) {
570
0
        void *vp_context_string = peddsactx->context_string;
571
572
0
        if (!OSSL_PARAM_get_octet_string(p, &vp_context_string, sizeof(peddsactx->context_string), &(peddsactx->context_string_len))) {
573
0
            peddsactx->context_string_len = 0;
574
0
            return 0;
575
0
        }
576
0
    }
577
578
0
    return 1;
579
0
}
580
581
static const OSSL_PARAM settable_ctx_params[] = {
582
    OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_INSTANCE, NULL, 0),
583
    OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0),
584
    OSSL_PARAM_END
585
};
586
587
static const OSSL_PARAM *eddsa_settable_ctx_params(ossl_unused void *vpeddsactx,
588
                                                   ossl_unused void *provctx)
589
1
{
590
1
    return settable_ctx_params;
591
1
}
592
593
const OSSL_DISPATCH ossl_ed25519_signature_functions[] = {
594
    { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx },
595
    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
596
      (void (*)(void))eddsa_digest_signverify_init },
597
    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN,
598
      (void (*)(void))ed25519_digest_sign },
599
    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
600
      (void (*)(void))eddsa_digest_signverify_init },
601
    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY,
602
      (void (*)(void))ed25519_digest_verify },
603
    { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx },
604
    { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx },
605
    { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))eddsa_get_ctx_params },
606
    { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
607
      (void (*)(void))eddsa_gettable_ctx_params },
608
    { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))eddsa_set_ctx_params },
609
    { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,
610
      (void (*)(void))eddsa_settable_ctx_params },
611
    OSSL_DISPATCH_END
612
};
613
614
const OSSL_DISPATCH ossl_ed448_signature_functions[] = {
615
    { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx },
616
    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
617
      (void (*)(void))eddsa_digest_signverify_init },
618
    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN,
619
      (void (*)(void))ed448_digest_sign },
620
    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
621
      (void (*)(void))eddsa_digest_signverify_init },
622
    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY,
623
      (void (*)(void))ed448_digest_verify },
624
    { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx },
625
    { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx },
626
    { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))eddsa_get_ctx_params },
627
    { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
628
      (void (*)(void))eddsa_gettable_ctx_params },
629
    { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))eddsa_set_ctx_params },
630
    { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,
631
      (void (*)(void))eddsa_settable_ctx_params },
632
    OSSL_DISPATCH_END
633
};
634
635
#ifdef S390X_EC_ASM
636
637
static int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig,
638
                                    const unsigned char *tbs, size_t tbslen)
639
{
640
    int rc;
641
    union {
642
        struct {
643
            unsigned char sig[64];
644
            unsigned char priv[32];
645
        } ed25519;
646
        unsigned long long buff[512];
647
    } param;
648
649
    memset(&param, 0, sizeof(param));
650
    memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
651
652
    rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, &param.ed25519, tbs, tbslen);
653
    OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
654
    if (rc != 0)
655
        return 0;
656
657
    s390x_flip_endian32(sig, param.ed25519.sig);
658
    s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
659
    return 1;
660
}
661
662
static int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig,
663
                                  const unsigned char *tbs, size_t tbslen)
664
{
665
    int rc;
666
    union {
667
        struct {
668
            unsigned char sig[128];
669
            unsigned char priv[64];
670
        } ed448;
671
        unsigned long long buff[512];
672
    } param;
673
674
    memset(&param, 0, sizeof(param));
675
    memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
676
677
    rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, &param.ed448, tbs, tbslen);
678
    OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
679
    if (rc != 0)
680
        return 0;
681
682
    s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
683
    s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
684
    memcpy(sig, param.ed448.sig, 57);
685
    memcpy(sig + 57, param.ed448.sig + 64, 57);
686
    return 1;
687
}
688
689
static int s390x_ed25519_digestverify(const ECX_KEY *edkey,
690
                                      const unsigned char *sig,
691
                                      const unsigned char *tbs, size_t tbslen)
692
{
693
    union {
694
        struct {
695
            unsigned char sig[64];
696
            unsigned char pub[32];
697
        } ed25519;
698
        unsigned long long buff[512];
699
    } param;
700
701
    memset(&param, 0, sizeof(param));
702
    s390x_flip_endian32(param.ed25519.sig, sig);
703
    s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
704
    s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
705
706
    return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
707
                      &param.ed25519, tbs, tbslen) == 0 ? 1 : 0;
708
}
709
710
static int s390x_ed448_digestverify(const ECX_KEY *edkey,
711
                                    const unsigned char *sig,
712
                                    const unsigned char *tbs,
713
                                    size_t tbslen)
714
{
715
    union {
716
        struct {
717
            unsigned char sig[128];
718
            unsigned char pub[64];
719
        } ed448;
720
        unsigned long long buff[512];
721
    } param;
722
723
    memset(&param, 0, sizeof(param));
724
    memcpy(param.ed448.sig, sig, 57);
725
    s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
726
    memcpy(param.ed448.sig + 64, sig + 57, 57);
727
    s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
728
    memcpy(param.ed448.pub, edkey->pubkey, 57);
729
    s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
730
731
    return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
732
                      &param.ed448, tbs, tbslen) == 0 ? 1 : 0;
733
}
734
735
#endif /* S390X_EC_ASM */