xref: /freebsd/crypto/openssl/providers/implementations/signature/eddsa_sig.c (revision e7be843b4a162e68651d3911f0357ed464915629)
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 
eddsa_newctx(void * provctx,const char * propq_unused)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 
eddsa_setup_instance(void * vpeddsactx,int instance_id,unsigned int instance_id_preset,unsigned int prehash_by_caller)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     case ID_Ed25519ctx:
195         if (peddsactx->key->type != ECX_KEY_TYPE_ED25519)
196             return 0;
197         peddsactx->dom2_flag = 1;
198         peddsactx->prehash_flag = 0;
199         peddsactx->context_string_flag = 1;
200         break;
201     case ID_Ed25519ph:
202         if (peddsactx->key->type != ECX_KEY_TYPE_ED25519)
203             return 0;
204         peddsactx->dom2_flag = 1;
205         peddsactx->prehash_flag = 1;
206         peddsactx->context_string_flag = 0;
207         break;
208     case ID_Ed448:
209         if (peddsactx->key->type != ECX_KEY_TYPE_ED448)
210             return 0;
211         peddsactx->prehash_flag = 0;
212         peddsactx->context_string_flag = 0;
213         break;
214     case ID_Ed448ph:
215         if (peddsactx->key->type != ECX_KEY_TYPE_ED448)
216             return 0;
217         peddsactx->prehash_flag = 1;
218         peddsactx->context_string_flag = 0;
219         break;
220     default:
221         /* we did not recognize the instance */
222         return 0;
223     }
224     peddsactx->instance_id = instance_id;
225     peddsactx->instance_id_preset_flag = instance_id_preset;
226     peddsactx->prehash_by_caller_flag = prehash_by_caller;
227     return 1;
228 }
229 
eddsa_signverify_init(void * vpeddsactx,void * vedkey)230 static int eddsa_signverify_init(void *vpeddsactx, void *vedkey)
231 {
232     PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
233     ECX_KEY *edkey = (ECX_KEY *)vedkey;
234     WPACKET pkt;
235     int ret;
236     unsigned char *aid = NULL;
237 
238     if (!ossl_prov_is_running())
239         return 0;
240 
241     if (edkey == NULL) {
242         ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
243         return 0;
244     }
245 
246     if (!ossl_ecx_key_up_ref(edkey)) {
247         ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
248         return 0;
249     }
250 
251     peddsactx->instance_id_preset_flag = 0;
252     peddsactx->dom2_flag = 0;
253     peddsactx->prehash_flag = 0;
254     peddsactx->context_string_flag = 0;
255     peddsactx->context_string_len = 0;
256 
257     peddsactx->key = edkey;
258 
259     /*
260      * We do not care about DER writing errors.
261      * All it really means is that for some reason, there's no
262      * AlgorithmIdentifier to be had, but the operation itself is
263      * still valid, just as long as it's not used to construct
264      * anything that needs an AlgorithmIdentifier.
265      */
266     peddsactx->aid_len = 0;
267     ret = WPACKET_init_der(&pkt, peddsactx->aid_buf, sizeof(peddsactx->aid_buf));
268     switch (edkey->type) {
269     case ECX_KEY_TYPE_ED25519:
270         ret = ret && ossl_DER_w_algorithmIdentifier_ED25519(&pkt, -1, edkey);
271         break;
272     case ECX_KEY_TYPE_ED448:
273         ret = ret && ossl_DER_w_algorithmIdentifier_ED448(&pkt, -1, edkey);
274         break;
275     default:
276         /* Should never happen */
277         ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
278         ossl_ecx_key_free(edkey);
279         peddsactx->key = NULL;
280         WPACKET_cleanup(&pkt);
281         return 0;
282     }
283     if (ret && WPACKET_finish(&pkt)) {
284         WPACKET_get_total_written(&pkt, &peddsactx->aid_len);
285         aid = WPACKET_get_curr(&pkt);
286     }
287     WPACKET_cleanup(&pkt);
288     if (aid != NULL && peddsactx->aid_len != 0)
289         memmove(peddsactx->aid_buf, aid, peddsactx->aid_len);
290 
291     return 1;
292 }
293 
ed25519_signverify_message_init(void * vpeddsactx,void * vedkey,const OSSL_PARAM params[])294 static int ed25519_signverify_message_init(void *vpeddsactx, void *vedkey,
295                                              const OSSL_PARAM params[])
296 {
297     return eddsa_signverify_init(vpeddsactx, vedkey)
298         && eddsa_setup_instance(vpeddsactx, ID_Ed25519, 1, 0)
299         && eddsa_set_ctx_params(vpeddsactx, params);
300 }
301 
ed25519ph_signverify_message_init(void * vpeddsactx,void * vedkey,const OSSL_PARAM params[])302 static int ed25519ph_signverify_message_init(void *vpeddsactx, void *vedkey,
303                                              const OSSL_PARAM params[])
304 {
305     return eddsa_signverify_init(vpeddsactx, vedkey)
306         && eddsa_setup_instance(vpeddsactx, ID_Ed25519ph, 1, 0)
307         && eddsa_set_ctx_params(vpeddsactx, params);
308 }
309 
ed25519ph_signverify_init(void * vpeddsactx,void * vedkey,const OSSL_PARAM params[])310 static int ed25519ph_signverify_init(void *vpeddsactx, void *vedkey,
311                                      const OSSL_PARAM params[])
312 {
313     return eddsa_signverify_init(vpeddsactx, vedkey)
314         && eddsa_setup_instance(vpeddsactx, ID_Ed25519ph, 1, 1)
315         && eddsa_set_ctx_params(vpeddsactx, params);
316 }
317 
318 /*
319  * This supports using ED25519 with EVP_PKEY_{sign,verify}_init_ex() and
320  * EVP_PKEY_{sign,verify}_init_ex2(), under the condition that the caller
321  * explicitly sets the Ed25519ph instance (this is verified by ed25519_sign()
322  * and ed25519_verify())
323  */
ed25519_signverify_init(void * vpeddsactx,void * vedkey,const OSSL_PARAM params[])324 static int ed25519_signverify_init(void *vpeddsactx, void *vedkey,
325                                    const OSSL_PARAM params[])
326 {
327     return eddsa_signverify_init(vpeddsactx, vedkey)
328         && eddsa_setup_instance(vpeddsactx, ID_Ed25519, 0, 1)
329         && eddsa_set_ctx_params(vpeddsactx, params);
330 }
331 
ed25519ctx_signverify_message_init(void * vpeddsactx,void * vedkey,const OSSL_PARAM params[])332 static int ed25519ctx_signverify_message_init(void *vpeddsactx, void *vedkey,
333                                              const OSSL_PARAM params[])
334 {
335     return eddsa_signverify_init(vpeddsactx, vedkey)
336         && eddsa_setup_instance(vpeddsactx, ID_Ed25519ctx, 1, 0)
337         && eddsa_set_ctx_params(vpeddsactx, params);
338 }
339 
ed448_signverify_message_init(void * vpeddsactx,void * vedkey,const OSSL_PARAM params[])340 static int ed448_signverify_message_init(void *vpeddsactx, void *vedkey,
341                                          const OSSL_PARAM params[])
342 {
343     return eddsa_signverify_init(vpeddsactx, vedkey)
344         && eddsa_setup_instance(vpeddsactx, ID_Ed448, 1, 0)
345         && eddsa_set_ctx_params(vpeddsactx, params);
346 }
347 
ed448ph_signverify_message_init(void * vpeddsactx,void * vedkey,const OSSL_PARAM params[])348 static int ed448ph_signverify_message_init(void *vpeddsactx, void *vedkey,
349                                            const OSSL_PARAM params[])
350 {
351     return eddsa_signverify_init(vpeddsactx, vedkey)
352         && eddsa_setup_instance(vpeddsactx, ID_Ed448ph, 1, 0)
353         && eddsa_set_ctx_params(vpeddsactx, params);
354 }
355 
ed448ph_signverify_init(void * vpeddsactx,void * vedkey,const OSSL_PARAM params[])356 static int ed448ph_signverify_init(void *vpeddsactx, void *vedkey,
357                                    const OSSL_PARAM params[])
358 {
359     return eddsa_signverify_init(vpeddsactx, vedkey)
360         && eddsa_setup_instance(vpeddsactx, ID_Ed448ph, 1, 1)
361         && eddsa_set_ctx_params(vpeddsactx, params);
362 }
363 
364 /*
365  * This supports using ED448 with EVP_PKEY_{sign,verify}_init_ex() and
366  * EVP_PKEY_{sign,verify}_init_ex2(), under the condition that the caller
367  * explicitly sets the Ed448ph instance (this is verified by ed448_sign()
368  * and ed448_verify())
369  */
ed448_signverify_init(void * vpeddsactx,void * vedkey,const OSSL_PARAM params[])370 static int ed448_signverify_init(void *vpeddsactx, void *vedkey,
371                                    const OSSL_PARAM params[])
372 {
373     return eddsa_signverify_init(vpeddsactx, vedkey)
374         && eddsa_setup_instance(vpeddsactx, ID_Ed448, 0, 1)
375         && eddsa_set_ctx_params(vpeddsactx, params);
376 }
377 
378 /*
379  * This is used directly for OSSL_FUNC_SIGNATURE_SIGN and indirectly
380  * for OSSL_FUNC_SIGNATURE_DIGEST_SIGN
381  */
ed25519_sign(void * vpeddsactx,unsigned char * sigret,size_t * siglen,size_t sigsize,const unsigned char * tbs,size_t tbslen)382 static int ed25519_sign(void *vpeddsactx,
383                         unsigned char *sigret, size_t *siglen, size_t sigsize,
384                         const unsigned char *tbs, size_t tbslen)
385 {
386     PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
387     const ECX_KEY *edkey = peddsactx->key;
388     uint8_t md[EVP_MAX_MD_SIZE];
389     size_t mdlen;
390 
391     if (!ossl_prov_is_running())
392         return 0;
393 
394     if (sigret == NULL) {
395         *siglen = ED25519_SIGSIZE;
396         return 1;
397     }
398     if (sigsize < ED25519_SIGSIZE) {
399         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
400         return 0;
401     }
402     if (edkey->privkey == NULL) {
403         ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
404         return 0;
405     }
406 #ifdef S390X_EC_ASM
407     /*
408      * s390x_ed25519_digestsign() does not yet support dom2 or context-strings.
409      * fall back to non-accelerated sign if those options are set, or pre-hasing
410      * is provided.
411      */
412     if (S390X_CAN_SIGN(ED25519)
413             && !peddsactx->dom2_flag
414             && !peddsactx->context_string_flag
415             && peddsactx->context_string_len == 0
416             && !peddsactx->prehash_flag
417             && !peddsactx->prehash_by_caller_flag) {
418         if (s390x_ed25519_digestsign(edkey, sigret, tbs, tbslen) == 0) {
419             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
420             return 0;
421         }
422         *siglen = ED25519_SIGSIZE;
423         return 1;
424     }
425 #endif /* S390X_EC_ASM */
426 
427     if (peddsactx->prehash_flag) {
428         if (!peddsactx->prehash_by_caller_flag) {
429             if (!EVP_Q_digest(peddsactx->libctx, SN_sha512, NULL,
430                               tbs, tbslen, md, &mdlen)
431                 || mdlen != EDDSA_PREHASH_OUTPUT_LEN) {
432                 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PREHASHED_DIGEST_LENGTH);
433                 return 0;
434             }
435             tbs = md;
436             tbslen = mdlen;
437         } else if (tbslen != EDDSA_PREHASH_OUTPUT_LEN) {
438             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
439             return 0;
440         }
441     } else if (peddsactx->prehash_by_caller_flag) {
442         /* The caller is supposed to set up a ph instance! */
443         ERR_raise(ERR_LIB_PROV,
444                   PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION);
445         return 0;
446     }
447 
448     if (ossl_ed25519_sign(sigret, tbs, tbslen, edkey->pubkey, edkey->privkey,
449             peddsactx->dom2_flag, peddsactx->prehash_flag, peddsactx->context_string_flag,
450             peddsactx->context_string, peddsactx->context_string_len,
451             peddsactx->libctx, NULL) == 0) {
452         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
453         return 0;
454     }
455     *siglen = ED25519_SIGSIZE;
456     return 1;
457 }
458 
459 /* EVP_Q_digest() does not allow variable output length for XOFs,
460    so we use this function */
ed448_shake256(OSSL_LIB_CTX * libctx,const char * propq,const uint8_t * in,size_t inlen,uint8_t * out,size_t outlen)461 static int ed448_shake256(OSSL_LIB_CTX *libctx,
462                           const char *propq,
463                           const uint8_t *in, size_t inlen,
464                           uint8_t *out, size_t outlen)
465 {
466     int ret = 0;
467     EVP_MD_CTX *hash_ctx = EVP_MD_CTX_new();
468     EVP_MD *shake256 = EVP_MD_fetch(libctx, SN_shake256, propq);
469 
470     if (hash_ctx == NULL || shake256 == NULL)
471         goto err;
472 
473     if (!EVP_DigestInit_ex(hash_ctx, shake256, NULL)
474             || !EVP_DigestUpdate(hash_ctx, in, inlen)
475             || !EVP_DigestFinalXOF(hash_ctx, out, outlen))
476         goto err;
477 
478     ret = 1;
479 
480  err:
481     EVP_MD_CTX_free(hash_ctx);
482     EVP_MD_free(shake256);
483     return ret;
484 }
485 
486 /*
487  * This is used directly for OSSL_FUNC_SIGNATURE_SIGN and indirectly
488  * for OSSL_FUNC_SIGNATURE_DIGEST_SIGN
489  */
ed448_sign(void * vpeddsactx,unsigned char * sigret,size_t * siglen,size_t sigsize,const unsigned char * tbs,size_t tbslen)490 static int ed448_sign(void *vpeddsactx,
491                       unsigned char *sigret, size_t *siglen, size_t sigsize,
492                       const unsigned char *tbs, size_t tbslen)
493 {
494     PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
495     const ECX_KEY *edkey = peddsactx->key;
496     uint8_t md[EDDSA_PREHASH_OUTPUT_LEN];
497     size_t mdlen = sizeof(md);
498 
499     if (!ossl_prov_is_running())
500         return 0;
501 
502     if (sigret == NULL) {
503         *siglen = ED448_SIGSIZE;
504         return 1;
505     }
506     if (sigsize < ED448_SIGSIZE) {
507         ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
508         return 0;
509     }
510     if (edkey->privkey == NULL) {
511         ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
512         return 0;
513     }
514 #ifdef S390X_EC_ASM
515     /*
516      * s390x_ed448_digestsign() does not yet support context-strings or
517      * pre-hashing. Fall back to non-accelerated sign if a context-string or
518      * pre-hasing is provided.
519      */
520     if (S390X_CAN_SIGN(ED448)
521             && peddsactx->context_string_len == 0
522             && !peddsactx->prehash_flag
523             && !peddsactx->prehash_by_caller_flag) {
524         if (s390x_ed448_digestsign(edkey, sigret, tbs, tbslen) == 0) {
525             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
526             return 0;
527         }
528         *siglen = ED448_SIGSIZE;
529         return 1;
530     }
531 #endif /* S390X_EC_ASM */
532 
533     if (peddsactx->prehash_flag) {
534         if (!peddsactx->prehash_by_caller_flag) {
535             if (!ed448_shake256(peddsactx->libctx, NULL, tbs, tbslen, md, mdlen))
536                 return 0;
537             tbs = md;
538             tbslen = mdlen;
539         } else if (tbslen != EDDSA_PREHASH_OUTPUT_LEN) {
540             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
541             return 0;
542         }
543     } else if (peddsactx->prehash_by_caller_flag) {
544         /* The caller is supposed to set up a ph instance! */
545         ERR_raise(ERR_LIB_PROV,
546                   PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION);
547         return 0;
548     }
549 
550     if (ossl_ed448_sign(peddsactx->libctx, sigret, tbs, tbslen,
551                         edkey->pubkey, edkey->privkey,
552                         peddsactx->context_string, peddsactx->context_string_len,
553                         peddsactx->prehash_flag, edkey->propq) == 0) {
554         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
555         return 0;
556     }
557     *siglen = ED448_SIGSIZE;
558     return 1;
559 }
560 
561 /*
562  * This is used directly for OSSL_FUNC_SIGNATURE_VERIFY and indirectly
563  * for OSSL_FUNC_SIGNATURE_DIGEST_VERIFY
564  */
ed25519_verify(void * vpeddsactx,const unsigned char * sig,size_t siglen,const unsigned char * tbs,size_t tbslen)565 static int ed25519_verify(void *vpeddsactx,
566                           const unsigned char *sig, size_t siglen,
567                           const unsigned char *tbs, size_t tbslen)
568 {
569     PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
570     const ECX_KEY *edkey = peddsactx->key;
571     uint8_t md[EVP_MAX_MD_SIZE];
572     size_t mdlen;
573 
574     if (!ossl_prov_is_running() || siglen != ED25519_SIGSIZE)
575         return 0;
576 
577 #ifdef S390X_EC_ASM
578     /*
579      * s390x_ed25519_digestverify() does not yet support dom2 or context-strings.
580      * fall back to non-accelerated verify if those options are set, or
581      * pre-hasing is provided.
582      */
583     if (S390X_CAN_SIGN(ED25519)
584             && !peddsactx->dom2_flag
585             && !peddsactx->context_string_flag
586             && peddsactx->context_string_len == 0
587             && !peddsactx->prehash_flag
588             && !peddsactx->prehash_by_caller_flag)
589         return s390x_ed25519_digestverify(edkey, sig, tbs, tbslen);
590 #endif /* S390X_EC_ASM */
591 
592     if (peddsactx->prehash_flag) {
593         if (!peddsactx->prehash_by_caller_flag) {
594             if (!EVP_Q_digest(peddsactx->libctx, SN_sha512, NULL,
595                               tbs, tbslen, md, &mdlen)
596                 || mdlen != EDDSA_PREHASH_OUTPUT_LEN) {
597                 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PREHASHED_DIGEST_LENGTH);
598                 return 0;
599             }
600             tbs = md;
601             tbslen = mdlen;
602         } else if (tbslen != EDDSA_PREHASH_OUTPUT_LEN) {
603             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
604             return 0;
605         }
606     } else if (peddsactx->prehash_by_caller_flag) {
607         /* The caller is supposed to set up a ph instance! */
608         ERR_raise(ERR_LIB_PROV,
609                   PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION);
610         return 0;
611     }
612 
613     return ossl_ed25519_verify(tbs, tbslen, sig, edkey->pubkey,
614                                peddsactx->dom2_flag, peddsactx->prehash_flag, peddsactx->context_string_flag,
615                                peddsactx->context_string, peddsactx->context_string_len,
616                                peddsactx->libctx, edkey->propq);
617 }
618 
619 /*
620  * This is used directly for OSSL_FUNC_SIGNATURE_VERIFY and indirectly
621  * for OSSL_FUNC_SIGNATURE_DIGEST_VERIFY
622  */
ed448_verify(void * vpeddsactx,const unsigned char * sig,size_t siglen,const unsigned char * tbs,size_t tbslen)623 static int ed448_verify(void *vpeddsactx,
624                         const unsigned char *sig, size_t siglen,
625                         const unsigned char *tbs, size_t tbslen)
626 {
627     PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
628     const ECX_KEY *edkey = peddsactx->key;
629     uint8_t md[EDDSA_PREHASH_OUTPUT_LEN];
630     size_t mdlen = sizeof(md);
631 
632     if (!ossl_prov_is_running() || siglen != ED448_SIGSIZE)
633         return 0;
634 
635 #ifdef S390X_EC_ASM
636     /*
637      * s390x_ed448_digestverify() does not yet support context-strings or
638      * pre-hashing. Fall back to non-accelerated verify if a context-string or
639      * pre-hasing is provided.
640      */
641     if (S390X_CAN_SIGN(ED448)
642             && peddsactx->context_string_len == 0
643             && !peddsactx->prehash_flag
644             && !peddsactx->prehash_by_caller_flag)
645         return s390x_ed448_digestverify(edkey, sig, tbs, tbslen);
646 #endif /* S390X_EC_ASM */
647 
648     if (peddsactx->prehash_flag) {
649         if (!peddsactx->prehash_by_caller_flag) {
650             if (!ed448_shake256(peddsactx->libctx, NULL, tbs, tbslen, md, mdlen))
651                 return 0;
652             tbs = md;
653             tbslen = mdlen;
654         } else if (tbslen != EDDSA_PREHASH_OUTPUT_LEN) {
655             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH);
656             return 0;
657         }
658     } else if (peddsactx->prehash_by_caller_flag) {
659         /* The caller is supposed to set up a ph instance! */
660         ERR_raise(ERR_LIB_PROV,
661                   PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION);
662         return 0;
663     }
664 
665     return ossl_ed448_verify(peddsactx->libctx, tbs, tbslen, sig, edkey->pubkey,
666                              peddsactx->context_string, peddsactx->context_string_len,
667                              peddsactx->prehash_flag, edkey->propq);
668 }
669 
670 /* All digest_{sign,verify} are simple wrappers around the functions above */
671 
ed25519_digest_signverify_init(void * vpeddsactx,const char * mdname,void * vedkey,const OSSL_PARAM params[])672 static int ed25519_digest_signverify_init(void *vpeddsactx, const char *mdname,
673                                           void *vedkey,
674                                           const OSSL_PARAM params[])
675 {
676     PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
677 
678     if (mdname != NULL && mdname[0] != '\0') {
679         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
680                         "Explicit digest not allowed with EdDSA operations");
681         return 0;
682     }
683 
684     if (vedkey == NULL && peddsactx->key != NULL)
685         return eddsa_set_ctx_params(peddsactx, params);
686 
687     return eddsa_signverify_init(vpeddsactx, vedkey)
688         && eddsa_setup_instance(vpeddsactx, ID_Ed25519, 0, 0)
689         && eddsa_set_ctx_params(vpeddsactx, params);
690 }
691 
ed25519_digest_sign(void * vpeddsactx,unsigned char * sigret,size_t * siglen,size_t sigsize,const unsigned char * tbs,size_t tbslen)692 static int ed25519_digest_sign(void *vpeddsactx,
693                                unsigned char *sigret, size_t *siglen, size_t sigsize,
694                                const unsigned char *tbs, size_t tbslen)
695 {
696     return ed25519_sign(vpeddsactx, sigret, siglen, sigsize, tbs, tbslen);
697 }
698 
ed25519_digest_verify(void * vpeddsactx,const unsigned char * sigret,size_t siglen,const unsigned char * tbs,size_t tbslen)699 static int ed25519_digest_verify(void *vpeddsactx,
700                                  const unsigned char *sigret, size_t siglen,
701                                  const unsigned char *tbs, size_t tbslen)
702 {
703     return ed25519_verify(vpeddsactx, sigret, siglen, tbs, tbslen);
704 }
705 
ed448_digest_signverify_init(void * vpeddsactx,const char * mdname,void * vedkey,const OSSL_PARAM params[])706 static int ed448_digest_signverify_init(void *vpeddsactx, const char *mdname,
707                                         void *vedkey,
708                                         const OSSL_PARAM params[])
709 {
710     PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
711 
712     if (mdname != NULL && mdname[0] != '\0') {
713         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST,
714                         "Explicit digest not allowed with EdDSA operations");
715         return 0;
716     }
717 
718     if (vedkey == NULL && peddsactx->key != NULL)
719         return eddsa_set_ctx_params(peddsactx, params);
720 
721     return eddsa_signverify_init(vpeddsactx, vedkey)
722         && eddsa_setup_instance(vpeddsactx, ID_Ed448, 0, 0)
723         && eddsa_set_ctx_params(vpeddsactx, params);
724 }
725 
ed448_digest_sign(void * vpeddsactx,unsigned char * sigret,size_t * siglen,size_t sigsize,const unsigned char * tbs,size_t tbslen)726 static int ed448_digest_sign(void *vpeddsactx,
727                              unsigned char *sigret, size_t *siglen, size_t sigsize,
728                              const unsigned char *tbs, size_t tbslen)
729 {
730     return ed448_sign(vpeddsactx, sigret, siglen, sigsize, tbs, tbslen);
731 }
732 
ed448_digest_verify(void * vpeddsactx,const unsigned char * sigret,size_t siglen,const unsigned char * tbs,size_t tbslen)733 static int ed448_digest_verify(void *vpeddsactx,
734                                const unsigned char *sigret, size_t siglen,
735                                const unsigned char *tbs, size_t tbslen)
736 {
737     return ed448_verify(vpeddsactx, sigret, siglen, tbs, tbslen);
738 }
739 
eddsa_freectx(void * vpeddsactx)740 static void eddsa_freectx(void *vpeddsactx)
741 {
742     PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
743 
744     ossl_ecx_key_free(peddsactx->key);
745 
746     OPENSSL_free(peddsactx);
747 }
748 
eddsa_dupctx(void * vpeddsactx)749 static void *eddsa_dupctx(void *vpeddsactx)
750 {
751     PROV_EDDSA_CTX *srcctx = (PROV_EDDSA_CTX *)vpeddsactx;
752     PROV_EDDSA_CTX *dstctx;
753 
754     if (!ossl_prov_is_running())
755         return NULL;
756 
757     dstctx = OPENSSL_zalloc(sizeof(*srcctx));
758     if (dstctx == NULL)
759         return NULL;
760 
761     *dstctx = *srcctx;
762     dstctx->key = NULL;
763 
764     if (srcctx->key != NULL && !ossl_ecx_key_up_ref(srcctx->key)) {
765         ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
766         goto err;
767     }
768     dstctx->key = srcctx->key;
769 
770     return dstctx;
771  err:
772     eddsa_freectx(dstctx);
773     return NULL;
774 }
775 
ed25519_sigalg_query_key_types(void)776 static const char **ed25519_sigalg_query_key_types(void)
777 {
778     static const char *keytypes[] = { "ED25519", NULL };
779 
780     return keytypes;
781 }
782 
ed448_sigalg_query_key_types(void)783 static const char **ed448_sigalg_query_key_types(void)
784 {
785     static const char *keytypes[] = { "ED448", NULL };
786 
787     return keytypes;
788 }
789 
790 
791 
eddsa_get_ctx_params(void * vpeddsactx,OSSL_PARAM * params)792 static int eddsa_get_ctx_params(void *vpeddsactx, OSSL_PARAM *params)
793 {
794     PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
795     OSSL_PARAM *p;
796 
797     if (peddsactx == NULL)
798         return 0;
799 
800     p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID);
801     if (p != NULL
802         && !OSSL_PARAM_set_octet_string(p,
803                                         peddsactx->aid_len == 0 ? NULL : peddsactx->aid_buf,
804                                         peddsactx->aid_len))
805         return 0;
806 
807     return 1;
808 }
809 
810 static const OSSL_PARAM known_gettable_ctx_params[] = {
811     OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
812     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_INSTANCE, NULL, 0),
813     OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0),
814     OSSL_PARAM_END
815 };
816 
eddsa_gettable_ctx_params(ossl_unused void * vpeddsactx,ossl_unused void * provctx)817 static const OSSL_PARAM *eddsa_gettable_ctx_params(ossl_unused void *vpeddsactx,
818                                                    ossl_unused void *provctx)
819 {
820     return known_gettable_ctx_params;
821 }
822 
eddsa_set_ctx_params(void * vpeddsactx,const OSSL_PARAM params[])823 static int eddsa_set_ctx_params(void *vpeddsactx, const OSSL_PARAM params[])
824 {
825     PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
826     const OSSL_PARAM *p;
827 
828     if (peddsactx == NULL)
829         return 0;
830     if (ossl_param_is_empty(params))
831         return 1;
832 
833     p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_INSTANCE);
834     if (p != NULL) {
835         char instance_name[OSSL_MAX_NAME_SIZE] = "";
836         char *pinstance_name = instance_name;
837 
838         if (peddsactx->instance_id_preset_flag) {
839             /* When the instance is preset, the caller must no try to set it */
840             ERR_raise_data(ERR_LIB_PROV, PROV_R_NO_INSTANCE_ALLOWED,
841                            "the EdDSA instance is preset, you may not try to specify it",
842                            NULL);
843             return 0;
844         }
845 
846         if (!OSSL_PARAM_get_utf8_string(p, &pinstance_name, sizeof(instance_name)))
847             return 0;
848 
849         /*
850          * When setting the new instance, we're careful not to change the
851          * prehash_by_caller flag, as that's always preset by the init
852          * functions.  The sign functions will determine if the instance
853          * matches this flag.
854          */
855         if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519) == 0) {
856             eddsa_setup_instance(peddsactx, ID_Ed25519, 0,
857                                  peddsactx->prehash_by_caller_flag);
858         } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519ctx) == 0) {
859             eddsa_setup_instance(peddsactx, ID_Ed25519ctx, 0,
860                                  peddsactx->prehash_by_caller_flag);
861         } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519ph) == 0) {
862             eddsa_setup_instance(peddsactx, ID_Ed25519ph, 0,
863                                  peddsactx->prehash_by_caller_flag);
864         } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed448) == 0) {
865             eddsa_setup_instance(peddsactx, ID_Ed448, 0,
866                                  peddsactx->prehash_by_caller_flag);
867         } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed448ph) == 0) {
868             eddsa_setup_instance(peddsactx, ID_Ed448ph, 0,
869                                  peddsactx->prehash_by_caller_flag);
870         } else {
871             /* we did not recognize the instance */
872             return 0;
873         }
874 
875     }
876 
877     p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_CONTEXT_STRING);
878     if (p != NULL) {
879         void *vp_context_string = peddsactx->context_string;
880 
881         if (!OSSL_PARAM_get_octet_string(p, &vp_context_string, sizeof(peddsactx->context_string), &(peddsactx->context_string_len))) {
882             peddsactx->context_string_len = 0;
883             return 0;
884         }
885     }
886 
887     return 1;
888 }
889 
890 static const OSSL_PARAM settable_ctx_params[] = {
891     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_INSTANCE, NULL, 0),
892     OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0),
893     OSSL_PARAM_END
894 };
895 
eddsa_settable_ctx_params(ossl_unused void * vpeddsactx,ossl_unused void * provctx)896 static const OSSL_PARAM *eddsa_settable_ctx_params(ossl_unused void *vpeddsactx,
897                                                    ossl_unused void *provctx)
898 {
899     return settable_ctx_params;
900 }
901 
902 static const OSSL_PARAM settable_variant_ctx_params[] = {
903     OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0),
904     OSSL_PARAM_END
905 };
906 
907 static const OSSL_PARAM *
eddsa_settable_variant_ctx_params(ossl_unused void * vpeddsactx,ossl_unused void * provctx)908 eddsa_settable_variant_ctx_params(ossl_unused void *vpeddsactx,
909                                   ossl_unused void *provctx)
910 {
911     return settable_variant_ctx_params;
912 }
913 
914 /*
915  * Ed25519 can be used with:
916  * - EVP_PKEY_sign_init_ex2()   [ instance and prehash assumed done by caller ]
917  * - EVP_PKEY_verify_init_ex2() [ instance and prehash assumed done by caller ]
918  * - EVP_PKEY_sign_message_init()
919  * - EVP_PKEY_verify_message_init()
920  * - EVP_DigestSignInit_ex()
921  * - EVP_DigestVerifyInit_ex()
922  * Ed25519ph can be used with:
923  * - EVP_PKEY_sign_init_ex2()   [ prehash assumed done by caller ]
924  * - EVP_PKEY_verify_init_ex2() [ prehash assumed done by caller ]
925  * - EVP_PKEY_sign_message_init()
926  * - EVP_PKEY_verify_message_init()
927  * Ed25519ctx can be used with:
928  * - EVP_PKEY_sign_message_init()
929  * - EVP_PKEY_verify_message_init()
930  * Ed448 can be used with:
931  * - EVP_PKEY_sign_init_ex2()   [ instance and prehash assumed done by caller ]
932  * - EVP_PKEY_verify_init_ex2() [ instance and prehash assumed done by caller ]
933  * - EVP_PKEY_sign_message_init()
934  * - EVP_PKEY_verify_message_init()
935  * - EVP_DigestSignInit_ex()
936  * - EVP_DigestVerifyInit_ex()
937  * Ed448ph can be used with:
938  * - EVP_PKEY_sign_init_ex2()   [ prehash assumed done by caller ]
939  * - EVP_PKEY_verify_init_ex2() [ prehash assumed done by caller ]
940  * - EVP_PKEY_sign_message_init()
941  * - EVP_PKEY_verify_message_init()
942  */
943 
944 #define ed25519_DISPATCH_END                                            \
945     { OSSL_FUNC_SIGNATURE_SIGN_INIT,                                    \
946         (void (*)(void))ed25519_signverify_init },                      \
947     { OSSL_FUNC_SIGNATURE_VERIFY_INIT,                                  \
948         (void (*)(void))ed25519_signverify_init },                      \
949     { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,                             \
950         (void (*)(void))ed25519_digest_signverify_init },               \
951     { OSSL_FUNC_SIGNATURE_DIGEST_SIGN,                                  \
952         (void (*)(void))ed25519_digest_sign },                          \
953     { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,                           \
954         (void (*)(void))ed25519_digest_signverify_init },               \
955     { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY,                                \
956         (void (*)(void))ed25519_digest_verify },                        \
957     { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS,                               \
958         (void (*)(void))eddsa_get_ctx_params },                         \
959     { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,                          \
960         (void (*)(void))eddsa_gettable_ctx_params },                    \
961     { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS,                               \
962         (void (*)(void))eddsa_set_ctx_params },                         \
963     { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,                          \
964         (void (*)(void))eddsa_settable_ctx_params },                    \
965     OSSL_DISPATCH_END
966 
967 #define eddsa_variant_DISPATCH_END(v)                                   \
968     { OSSL_FUNC_SIGNATURE_SIGN_INIT,                                    \
969         (void (*)(void))v##_signverify_message_init },                  \
970     { OSSL_FUNC_SIGNATURE_VERIFY_INIT,                                  \
971         (void (*)(void))v##_signverify_message_init },                  \
972     { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS,                               \
973         (void (*)(void))eddsa_get_ctx_params },                         \
974     { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,                          \
975         (void (*)(void))eddsa_gettable_ctx_params },                    \
976     { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS,                               \
977         (void (*)(void))eddsa_set_ctx_params },                         \
978     { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,                          \
979         (void (*)(void))eddsa_settable_variant_ctx_params },            \
980     OSSL_DISPATCH_END
981 
982 #define ed25519ph_DISPATCH_END                                          \
983     { OSSL_FUNC_SIGNATURE_SIGN_INIT,                                    \
984         (void (*)(void))ed25519ph_signverify_init },                    \
985     { OSSL_FUNC_SIGNATURE_VERIFY_INIT,                                  \
986         (void (*)(void))ed25519ph_signverify_init },                    \
987     eddsa_variant_DISPATCH_END(ed25519ph)
988 
989 #define ed25519ctx_DISPATCH_END eddsa_variant_DISPATCH_END(ed25519ctx)
990 
991 #define ed448_DISPATCH_END                                              \
992     { OSSL_FUNC_SIGNATURE_SIGN_INIT,                                    \
993         (void (*)(void))ed448_signverify_init },                        \
994     { OSSL_FUNC_SIGNATURE_VERIFY_INIT,                                  \
995         (void (*)(void))ed448_signverify_init },                        \
996     { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,                             \
997         (void (*)(void))ed448_digest_signverify_init },                 \
998     { OSSL_FUNC_SIGNATURE_DIGEST_SIGN,                                  \
999         (void (*)(void))ed448_digest_sign },                            \
1000     { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,                           \
1001         (void (*)(void))ed448_digest_signverify_init },                 \
1002     { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY,                                \
1003         (void (*)(void))ed448_digest_verify },                          \
1004     { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS,                               \
1005         (void (*)(void))eddsa_get_ctx_params },                         \
1006     { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,                          \
1007         (void (*)(void))eddsa_gettable_ctx_params },                    \
1008     { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS,                               \
1009         (void (*)(void))eddsa_set_ctx_params },                         \
1010     { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,                          \
1011         (void (*)(void))eddsa_settable_ctx_params },                    \
1012     OSSL_DISPATCH_END
1013 
1014 #define ed448ph_DISPATCH_END                                            \
1015     { OSSL_FUNC_SIGNATURE_SIGN_INIT,                                    \
1016         (void (*)(void))ed448ph_signverify_init },                      \
1017     { OSSL_FUNC_SIGNATURE_VERIFY_INIT,                                  \
1018         (void (*)(void))ed448ph_signverify_init },                      \
1019     eddsa_variant_DISPATCH_END(ed448ph)
1020 
1021 /* vn = variant name, bn = base name */
1022 #define IMPL_EDDSA_DISPATCH(vn,bn)                                      \
1023     const OSSL_DISPATCH ossl_##vn##_signature_functions[] = {           \
1024         { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx },   \
1025         { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_INIT,                        \
1026           (void (*)(void))vn##_signverify_message_init },               \
1027         { OSSL_FUNC_SIGNATURE_SIGN,                                     \
1028           (void (*)(void))bn##_sign },                                  \
1029         { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_INIT,                      \
1030           (void (*)(void))vn##_signverify_message_init },               \
1031         { OSSL_FUNC_SIGNATURE_VERIFY,                                   \
1032           (void (*)(void))bn##_verify },                                \
1033         { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx }, \
1034         { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx },   \
1035         { OSSL_FUNC_SIGNATURE_QUERY_KEY_TYPES,                          \
1036           (void (*)(void))bn##_sigalg_query_key_types },                \
1037         vn##_DISPATCH_END                                               \
1038     }
1039 
1040 IMPL_EDDSA_DISPATCH(ed25519,ed25519);
1041 IMPL_EDDSA_DISPATCH(ed25519ph,ed25519);
1042 IMPL_EDDSA_DISPATCH(ed25519ctx,ed25519);
1043 IMPL_EDDSA_DISPATCH(ed448,ed448);
1044 IMPL_EDDSA_DISPATCH(ed448ph,ed448);
1045 
1046 #ifdef S390X_EC_ASM
1047 
s390x_ed25519_digestsign(const ECX_KEY * edkey,unsigned char * sig,const unsigned char * tbs,size_t tbslen)1048 static int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig,
1049                                     const unsigned char *tbs, size_t tbslen)
1050 {
1051     int rc;
1052     union {
1053         struct {
1054             unsigned char sig[64];
1055             unsigned char priv[32];
1056         } ed25519;
1057         unsigned long long buff[512];
1058     } param;
1059 
1060     memset(&param, 0, sizeof(param));
1061     memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1062 
1063     rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, &param.ed25519, tbs, tbslen);
1064     OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1065     if (rc != 0)
1066         return 0;
1067 
1068     s390x_flip_endian32(sig, param.ed25519.sig);
1069     s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1070     return 1;
1071 }
1072 
s390x_ed448_digestsign(const ECX_KEY * edkey,unsigned char * sig,const unsigned char * tbs,size_t tbslen)1073 static int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig,
1074                                   const unsigned char *tbs, size_t tbslen)
1075 {
1076     int rc;
1077     union {
1078         struct {
1079             unsigned char sig[128];
1080             unsigned char priv[64];
1081         } ed448;
1082         unsigned long long buff[512];
1083     } param;
1084 
1085     memset(&param, 0, sizeof(param));
1086     memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1087 
1088     rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, &param.ed448, tbs, tbslen);
1089     OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1090     if (rc != 0)
1091         return 0;
1092 
1093     s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1094     s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1095     memcpy(sig, param.ed448.sig, 57);
1096     memcpy(sig + 57, param.ed448.sig + 64, 57);
1097     return 1;
1098 }
1099 
s390x_ed25519_digestverify(const ECX_KEY * edkey,const unsigned char * sig,const unsigned char * tbs,size_t tbslen)1100 static int s390x_ed25519_digestverify(const ECX_KEY *edkey,
1101                                       const unsigned char *sig,
1102                                       const unsigned char *tbs, size_t tbslen)
1103 {
1104     union {
1105         struct {
1106             unsigned char sig[64];
1107             unsigned char pub[32];
1108         } ed25519;
1109         unsigned long long buff[512];
1110     } param;
1111 
1112     memset(&param, 0, sizeof(param));
1113     s390x_flip_endian32(param.ed25519.sig, sig);
1114     s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1115     s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1116 
1117     return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1118                       &param.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1119 }
1120 
s390x_ed448_digestverify(const ECX_KEY * edkey,const unsigned char * sig,const unsigned char * tbs,size_t tbslen)1121 static int s390x_ed448_digestverify(const ECX_KEY *edkey,
1122                                     const unsigned char *sig,
1123                                     const unsigned char *tbs,
1124                                     size_t tbslen)
1125 {
1126     union {
1127         struct {
1128             unsigned char sig[128];
1129             unsigned char pub[64];
1130         } ed448;
1131         unsigned long long buff[512];
1132     } param;
1133 
1134     memset(&param, 0, sizeof(param));
1135     memcpy(param.ed448.sig, sig, 57);
1136     s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1137     memcpy(param.ed448.sig + 64, sig + 57, 57);
1138     s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1139     memcpy(param.ed448.pub, edkey->pubkey, 57);
1140     s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1141 
1142     return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1143                       &param.ed448, tbs, tbslen) == 0 ? 1 : 0;
1144 }
1145 
1146 #endif /* S390X_EC_ASM */
1147