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