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(¶m, 0, sizeof(param));
1056 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1057
1058 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.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(¶m, 0, sizeof(param));
1081 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1082
1083 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.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(¶m, 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 ¶m.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(¶m, 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 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1139 }
1140
1141 #endif /* S390X_EC_ASM */
1142