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