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