Coverage Report

Created: 2023-06-08 06:40

/src/openssl/providers/implementations/signature/eddsa_sig.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2020-2021 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
0
{
149
0
    PROV_EDDSA_CTX *peddsactx;
150
151
0
    if (!ossl_prov_is_running())
152
0
        return NULL;
153
154
0
    peddsactx = OPENSSL_zalloc(sizeof(PROV_EDDSA_CTX));
155
0
    if (peddsactx == NULL)
156
0
        return NULL;
157
158
0
    peddsactx->libctx = PROV_LIBCTX_OF(provctx);
159
160
0
    return peddsactx;
161
0
}
162
163
static int eddsa_digest_signverify_init(void *vpeddsactx, const char *mdname,
164
                                        void *vedkey,
165
                                        const OSSL_PARAM params[])
166
0
{
167
0
    PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
168
0
    ECX_KEY *edkey = (ECX_KEY *)vedkey;
169
0
    WPACKET pkt;
170
0
    int ret;
171
172
0
    if (!ossl_prov_is_running())
173
0
        return 0;
174
175
0
    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
0
    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
0
    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
0
    peddsactx->dom2_flag = 0;
193
0
    peddsactx->prehash_flag = 0;
194
0
    peddsactx->context_string_flag = 0;
195
0
    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
0
    peddsactx->aid_len = 0;
205
0
    ret = WPACKET_init_der(&pkt, peddsactx->aid_buf, sizeof(peddsactx->aid_buf));
206
0
    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
0
    case ECX_KEY_TYPE_ED448:
212
0
        ret = ret && ossl_DER_w_algorithmIdentifier_ED448(&pkt, -1, edkey);
213
0
        peddsactx->instance_id = ID_Ed448;
214
0
        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
        return 0;
220
0
    }
221
0
    if (ret && WPACKET_finish(&pkt)) {
222
0
        WPACKET_get_total_written(&pkt, &peddsactx->aid_len);
223
0
        peddsactx->aid = WPACKET_get_curr(&pkt);
224
0
    }
225
0
    WPACKET_cleanup(&pkt);
226
227
0
    peddsactx->key = edkey;
228
229
0
    if (!eddsa_set_ctx_params(peddsactx, params))
230
0
        return 0;
231
232
0
    return 1;
233
0
}
234
235
int ed25519_digest_sign(void *vpeddsactx, unsigned char *sigret,
236
                        size_t *siglen, size_t sigsize,
237
                        const unsigned char *tbs, size_t tbslen)
238
0
{
239
0
    PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
240
0
    const ECX_KEY *edkey = peddsactx->key;
241
0
    uint8_t md[EVP_MAX_MD_SIZE];
242
0
    size_t mdlen;
243
244
0
    if (!ossl_prov_is_running())
245
0
        return 0;
246
247
0
    if (sigret == NULL) {
248
0
        *siglen = ED25519_SIGSIZE;
249
0
        return 1;
250
0
    }
251
0
    if (sigsize < ED25519_SIGSIZE) {
252
0
        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
253
0
        return 0;
254
0
    }
255
0
    if (edkey->privkey == NULL) {
256
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
257
0
        return 0;
258
0
    }
259
#ifdef S390X_EC_ASM
260
    /* s390x_ed25519_digestsign() does not yet support dom2 or context-strings.
261
       fall back to non-accelerated sign if those options are set. */
262
    if (S390X_CAN_SIGN(ED25519)
263
            && !peddsactx->dom2_flag
264
            && !peddsactx->context_string_flag
265
            && peddsactx->context_string_len == 0) {
266
        if (s390x_ed25519_digestsign(edkey, sigret, tbs, tbslen) == 0) {
267
            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
268
            return 0;
269
        }
270
        *siglen = ED25519_SIGSIZE;
271
        return 1;
272
    }
273
#endif /* S390X_EC_ASM */
274
275
0
    if (peddsactx->prehash_flag) {
276
0
        if (!EVP_Q_digest(peddsactx->libctx, SN_sha512, NULL, tbs, tbslen, md, &mdlen)
277
0
                || mdlen != EDDSA_PREHASH_OUTPUT_LEN)
278
0
            return 0;
279
0
        tbs = md;
280
0
        tbslen = mdlen;
281
0
    }
282
283
0
    if (ossl_ed25519_sign(sigret, tbs, tbslen, edkey->pubkey, edkey->privkey,
284
0
            peddsactx->dom2_flag, peddsactx->prehash_flag, peddsactx->context_string_flag,
285
0
            peddsactx->context_string, peddsactx->context_string_len,
286
0
            peddsactx->libctx, NULL) == 0) {
287
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
288
0
        return 0;
289
0
    }
290
0
    *siglen = ED25519_SIGSIZE;
291
0
    return 1;
292
0
}
293
294
/* EVP_Q_digest() does not allow variable output length for XOFs,
295
   so we use this function */
296
static int ed448_shake256(OSSL_LIB_CTX *libctx,
297
                          const char *propq,
298
                          const uint8_t *in, size_t inlen,
299
                          uint8_t *out, size_t outlen)
300
0
{
301
0
    int ret = 0;
302
0
    EVP_MD_CTX *hash_ctx = EVP_MD_CTX_new();
303
0
    EVP_MD *shake256 = EVP_MD_fetch(libctx, SN_shake256, propq);
304
305
0
    if (hash_ctx == NULL || shake256 == NULL)
306
0
        goto err;
307
308
0
    if (!EVP_DigestInit_ex(hash_ctx, shake256, NULL)
309
0
            || !EVP_DigestUpdate(hash_ctx, in, inlen)
310
0
            || !EVP_DigestFinalXOF(hash_ctx, out, outlen))
311
0
        goto err;
312
313
0
    ret = 1;
314
315
0
 err:
316
0
    EVP_MD_CTX_free(hash_ctx);
317
0
    EVP_MD_free(shake256);
318
0
    return ret;
319
0
}
320
321
int ed448_digest_sign(void *vpeddsactx, unsigned char *sigret,
322
                      size_t *siglen, size_t sigsize,
323
                      const unsigned char *tbs, size_t tbslen)
324
0
{
325
0
    PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
326
0
    const ECX_KEY *edkey = peddsactx->key;
327
0
    uint8_t md[EDDSA_PREHASH_OUTPUT_LEN];
328
0
    size_t mdlen = sizeof(md);
329
330
0
    if (!ossl_prov_is_running())
331
0
        return 0;
332
333
0
    if (sigret == NULL) {
334
0
        *siglen = ED448_SIGSIZE;
335
0
        return 1;
336
0
    }
337
0
    if (sigsize < ED448_SIGSIZE) {
338
0
        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
339
0
        return 0;
340
0
    }
341
0
    if (edkey->privkey == NULL) {
342
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
343
0
        return 0;
344
0
    }
345
#ifdef S390X_EC_ASM
346
    /* s390x_ed448_digestsign() does not yet support context-strings or pre-hashing.
347
       fall back to non-accelerated sign if a context-string or pre-hasing is provided. */
348
    if (S390X_CAN_SIGN(ED448)
349
            && peddsactx->context_string_len == 0
350
            && peddsactx->prehash_flag == 0) {
351
        if (s390x_ed448_digestsign(edkey, sigret, tbs, tbslen) == 0) {
352
            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
353
            return 0;
354
        }
355
        *siglen = ED448_SIGSIZE;
356
        return 1;
357
    }
358
#endif /* S390X_EC_ASM */
359
360
0
    if (peddsactx->prehash_flag) {
361
0
        if (!ed448_shake256(peddsactx->libctx, NULL, tbs, tbslen, md, mdlen))
362
0
            return 0;
363
0
        tbs = md;
364
0
        tbslen = mdlen;
365
0
    }
366
367
0
    if (ossl_ed448_sign(peddsactx->libctx, sigret, tbs, tbslen,
368
0
                        edkey->pubkey, edkey->privkey,
369
0
                        peddsactx->context_string, peddsactx->context_string_len,
370
0
                        peddsactx->prehash_flag, edkey->propq) == 0) {
371
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
372
0
        return 0;
373
0
    }
374
0
    *siglen = ED448_SIGSIZE;
375
0
    return 1;
376
0
}
377
378
int ed25519_digest_verify(void *vpeddsactx, const unsigned char *sig,
379
                          size_t siglen, const unsigned char *tbs,
380
                          size_t tbslen)
381
0
{
382
0
    PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
383
0
    const ECX_KEY *edkey = peddsactx->key;
384
0
    uint8_t md[EVP_MAX_MD_SIZE];
385
0
    size_t mdlen;
386
387
0
    if (!ossl_prov_is_running() || siglen != ED25519_SIGSIZE)
388
0
        return 0;
389
390
#ifdef S390X_EC_ASM
391
    /* s390x_ed25519_digestverify() does not yet support dom2 or context-strings.
392
       fall back to non-accelerated verify if those options are set. */
393
    if (S390X_CAN_SIGN(ED25519)
394
            && !peddsactx->dom2_flag
395
            && !peddsactx->context_string_flag
396
            && peddsactx->context_string_len == 0) {
397
        return s390x_ed25519_digestverify(edkey, sig, tbs, tbslen);
398
    }
399
#endif /* S390X_EC_ASM */
400
401
0
    if (peddsactx->prehash_flag) {
402
0
        if (!EVP_Q_digest(peddsactx->libctx, SN_sha512, NULL, tbs, tbslen, md, &mdlen)
403
0
                || mdlen != EDDSA_PREHASH_OUTPUT_LEN)
404
0
            return 0;
405
0
        tbs = md;
406
0
        tbslen = mdlen;
407
0
    }
408
409
0
    return ossl_ed25519_verify(tbs, tbslen, sig, edkey->pubkey,
410
0
                               peddsactx->dom2_flag, peddsactx->prehash_flag, peddsactx->context_string_flag,
411
0
                               peddsactx->context_string, peddsactx->context_string_len,
412
0
                               peddsactx->libctx, edkey->propq);
413
0
}
414
415
int ed448_digest_verify(void *vpeddsactx, const unsigned char *sig,
416
                        size_t siglen, const unsigned char *tbs,
417
                        size_t tbslen)
418
0
{
419
0
    PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
420
0
    const ECX_KEY *edkey = peddsactx->key;
421
0
    uint8_t md[EDDSA_PREHASH_OUTPUT_LEN];
422
0
    size_t mdlen = sizeof(md);
423
424
0
    if (!ossl_prov_is_running() || siglen != ED448_SIGSIZE)
425
0
        return 0;
426
427
#ifdef S390X_EC_ASM
428
    /* s390x_ed448_digestverify() does not yet support context-strings or pre-hashing.
429
       fall back to non-accelerated verify if a context-string or pre-hasing is provided. */
430
    if (S390X_CAN_SIGN(ED448)
431
            && peddsactx->context_string_len == 0
432
            && peddsactx->prehash_flag == 0) {
433
        return s390x_ed448_digestverify(edkey, sig, tbs, tbslen);
434
    }
435
#endif /* S390X_EC_ASM */
436
437
0
    if (peddsactx->prehash_flag) {
438
0
        if (!ed448_shake256(peddsactx->libctx, NULL, tbs, tbslen, md, mdlen))
439
0
            return 0;
440
0
        tbs = md;
441
0
        tbslen = mdlen;
442
0
    }
443
444
0
    return ossl_ed448_verify(peddsactx->libctx, tbs, tbslen, sig, edkey->pubkey,
445
0
                             peddsactx->context_string, peddsactx->context_string_len,
446
0
                             peddsactx->prehash_flag, edkey->propq);
447
0
}
448
449
static void eddsa_freectx(void *vpeddsactx)
450
0
{
451
0
    PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
452
453
0
    ossl_ecx_key_free(peddsactx->key);
454
455
0
    OPENSSL_free(peddsactx);
456
0
}
457
458
static void *eddsa_dupctx(void *vpeddsactx)
459
0
{
460
0
    PROV_EDDSA_CTX *srcctx = (PROV_EDDSA_CTX *)vpeddsactx;
461
0
    PROV_EDDSA_CTX *dstctx;
462
463
0
    if (!ossl_prov_is_running())
464
0
        return NULL;
465
466
0
    dstctx = OPENSSL_zalloc(sizeof(*srcctx));
467
0
    if (dstctx == NULL)
468
0
        return NULL;
469
470
0
    *dstctx = *srcctx;
471
0
    dstctx->key = NULL;
472
473
0
    if (srcctx->key != NULL && !ossl_ecx_key_up_ref(srcctx->key)) {
474
0
        ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
475
0
        goto err;
476
0
    }
477
0
    dstctx->key = srcctx->key;
478
479
0
    return dstctx;
480
0
 err:
481
0
    eddsa_freectx(dstctx);
482
0
    return NULL;
483
0
}
484
485
static int eddsa_get_ctx_params(void *vpeddsactx, OSSL_PARAM *params)
486
0
{
487
0
    PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
488
0
    OSSL_PARAM *p;
489
490
0
    if (peddsactx == NULL)
491
0
        return 0;
492
493
0
    p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID);
494
0
    if (p != NULL && !OSSL_PARAM_set_octet_string(p, peddsactx->aid,
495
0
                                                  peddsactx->aid_len))
496
0
        return 0;
497
498
0
    return 1;
499
0
}
500
501
static const OSSL_PARAM known_gettable_ctx_params[] = {
502
    OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
503
    OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_INSTANCE, NULL, 0),
504
    OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0),
505
    OSSL_PARAM_END
506
};
507
508
static const OSSL_PARAM *eddsa_gettable_ctx_params(ossl_unused void *vpeddsactx,
509
                                                   ossl_unused void *provctx)
510
0
{
511
0
    return known_gettable_ctx_params;
512
0
}
513
514
static int eddsa_set_ctx_params(void *vpeddsactx, const OSSL_PARAM params[])
515
0
{
516
0
    PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
517
0
    const OSSL_PARAM *p;
518
519
0
    if (peddsactx == NULL)
520
0
        return 0;
521
0
    if (params == NULL)
522
0
        return 1;
523
524
0
    p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_INSTANCE);
525
0
    if (p != NULL) {
526
0
        char instance_name[OSSL_MAX_NAME_SIZE] = "";
527
0
        char *pinstance_name = instance_name;
528
529
0
        if (!OSSL_PARAM_get_utf8_string(p, &pinstance_name, sizeof(instance_name)))
530
0
            return 0;
531
532
0
        if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519) == 0) {
533
0
            peddsactx->instance_id = ID_Ed25519;
534
0
            if (peddsactx->key->type != ECX_KEY_TYPE_ED25519) return 0;
535
0
            peddsactx->dom2_flag = 0;
536
0
            peddsactx->prehash_flag = 0;
537
0
            peddsactx->context_string_flag = 0;
538
0
        } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519ctx) == 0) {
539
0
            peddsactx->instance_id = ID_Ed25519ctx;
540
0
            if (peddsactx->key->type != ECX_KEY_TYPE_ED25519) return 0;
541
0
            peddsactx->dom2_flag = 1;
542
0
            peddsactx->prehash_flag = 0;
543
0
            peddsactx->context_string_flag = 1;
544
0
        } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519ph) == 0) {
545
0
            peddsactx->instance_id = ID_Ed25519ph;
546
0
            if (peddsactx->key->type != ECX_KEY_TYPE_ED25519) return 0;
547
0
            peddsactx->dom2_flag = 1;
548
0
            peddsactx->prehash_flag = 1;
549
0
            peddsactx->context_string_flag = 0;
550
0
        } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed448) == 0) {
551
0
            peddsactx->instance_id = ID_Ed448;
552
0
            if (peddsactx->key->type != ECX_KEY_TYPE_ED448) return 0;
553
0
            peddsactx->prehash_flag = 0;
554
0
            peddsactx->context_string_flag = 0;
555
0
        } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed448ph) == 0) {
556
0
            peddsactx->instance_id = ID_Ed448ph;
557
0
            if (peddsactx->key->type != ECX_KEY_TYPE_ED448) return 0;
558
0
            peddsactx->prehash_flag = 1;
559
0
            peddsactx->context_string_flag = 0;
560
0
        } else {
561
            /* we did not recognize the instance */
562
0
            return 0;
563
0
        }
564
565
0
    }
566
567
0
    p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_CONTEXT_STRING);
568
0
    if (p != NULL) {
569
0
        void *vp_context_string = peddsactx->context_string;
570
571
0
        if (!OSSL_PARAM_get_octet_string(p, &vp_context_string, sizeof(peddsactx->context_string), &(peddsactx->context_string_len))) {
572
0
            peddsactx->context_string_len = 0;
573
0
            return 0;
574
0
        }
575
0
    }
576
577
0
    return 1;
578
0
}
579
580
static const OSSL_PARAM settable_ctx_params[] = {
581
    OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_INSTANCE, NULL, 0),
582
    OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0),
583
    OSSL_PARAM_END
584
};
585
586
static const OSSL_PARAM *eddsa_settable_ctx_params(ossl_unused void *vpeddsactx,
587
                                                   ossl_unused void *provctx)
588
0
{
589
0
    return settable_ctx_params;
590
0
}
591
592
const OSSL_DISPATCH ossl_ed25519_signature_functions[] = {
593
    { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx },
594
    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
595
      (void (*)(void))eddsa_digest_signverify_init },
596
    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN,
597
      (void (*)(void))ed25519_digest_sign },
598
    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
599
      (void (*)(void))eddsa_digest_signverify_init },
600
    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY,
601
      (void (*)(void))ed25519_digest_verify },
602
    { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx },
603
    { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx },
604
    { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))eddsa_get_ctx_params },
605
    { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
606
      (void (*)(void))eddsa_gettable_ctx_params },
607
    { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))eddsa_set_ctx_params },
608
    { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,
609
      (void (*)(void))eddsa_settable_ctx_params },
610
    OSSL_DISPATCH_END
611
};
612
613
const OSSL_DISPATCH ossl_ed448_signature_functions[] = {
614
    { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx },
615
    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
616
      (void (*)(void))eddsa_digest_signverify_init },
617
    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN,
618
      (void (*)(void))ed448_digest_sign },
619
    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
620
      (void (*)(void))eddsa_digest_signverify_init },
621
    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY,
622
      (void (*)(void))ed448_digest_verify },
623
    { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx },
624
    { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx },
625
    { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))eddsa_get_ctx_params },
626
    { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
627
      (void (*)(void))eddsa_gettable_ctx_params },
628
    { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))eddsa_set_ctx_params },
629
    { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,
630
      (void (*)(void))eddsa_settable_ctx_params },
631
    OSSL_DISPATCH_END
632
};
633
634
#ifdef S390X_EC_ASM
635
636
static int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig,
637
                                    const unsigned char *tbs, size_t tbslen)
638
{
639
    int rc;
640
    union {
641
        struct {
642
            unsigned char sig[64];
643
            unsigned char priv[32];
644
        } ed25519;
645
        unsigned long long buff[512];
646
    } param;
647
648
    memset(&param, 0, sizeof(param));
649
    memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
650
651
    rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, &param.ed25519, tbs, tbslen);
652
    OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
653
    if (rc != 0)
654
        return 0;
655
656
    s390x_flip_endian32(sig, param.ed25519.sig);
657
    s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
658
    return 1;
659
}
660
661
static int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig,
662
                                  const unsigned char *tbs, size_t tbslen)
663
{
664
    int rc;
665
    union {
666
        struct {
667
            unsigned char sig[128];
668
            unsigned char priv[64];
669
        } ed448;
670
        unsigned long long buff[512];
671
    } param;
672
673
    memset(&param, 0, sizeof(param));
674
    memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
675
676
    rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, &param.ed448, tbs, tbslen);
677
    OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
678
    if (rc != 0)
679
        return 0;
680
681
    s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
682
    s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
683
    memcpy(sig, param.ed448.sig, 57);
684
    memcpy(sig + 57, param.ed448.sig + 64, 57);
685
    return 1;
686
}
687
688
static int s390x_ed25519_digestverify(const ECX_KEY *edkey,
689
                                      const unsigned char *sig,
690
                                      const unsigned char *tbs, size_t tbslen)
691
{
692
    union {
693
        struct {
694
            unsigned char sig[64];
695
            unsigned char pub[32];
696
        } ed25519;
697
        unsigned long long buff[512];
698
    } param;
699
700
    memset(&param, 0, sizeof(param));
701
    s390x_flip_endian32(param.ed25519.sig, sig);
702
    s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
703
    s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
704
705
    return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
706
                      &param.ed25519, tbs, tbslen) == 0 ? 1 : 0;
707
}
708
709
static int s390x_ed448_digestverify(const ECX_KEY *edkey,
710
                                    const unsigned char *sig,
711
                                    const unsigned char *tbs,
712
                                    size_t tbslen)
713
{
714
    union {
715
        struct {
716
            unsigned char sig[128];
717
            unsigned char pub[64];
718
        } ed448;
719
        unsigned long long buff[512];
720
    } param;
721
722
    memset(&param, 0, sizeof(param));
723
    memcpy(param.ed448.sig, sig, 57);
724
    s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
725
    memcpy(param.ed448.sig + 64, sig + 57, 57);
726
    s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
727
    memcpy(param.ed448.pub, edkey->pubkey, 57);
728
    s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
729
730
    return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
731
                      &param.ed448, tbs, tbslen) == 0 ? 1 : 0;
732
}
733
734
#endif /* S390X_EC_ASM */