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(¶m, 0, sizeof(param));
1060 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1061
1062 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.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(¶m, 0, sizeof(param));
1085 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1086
1087 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.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(¶m, 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 ¶m.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(¶m, 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 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1143 }
1144
1145 #endif /* S390X_EC_ASM */
1146