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