]> git.ipfire.org Git - thirdparty/openssl.git/blob - providers/implementations/signature/eddsa_sig.c
Replaced '{ 0, NULL }' with OSSL_DISPATCH_END in OSSL_DISPATCH arrays
[thirdparty/openssl.git] / providers / implementations / signature / eddsa_sig.c
1 /*
2 * Copyright 2020-2021 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/provider_ctx.h"
22 #include "prov/der_ecx.h"
23 #include "crypto/ecx.h"
24
25 #ifdef S390X_EC_ASM
26 # include "s390x_arch.h"
27
28 # define S390X_CAN_SIGN(edtype) \
29 ((OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_##edtype)) \
30 && (OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_##edtype)) \
31 && (OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_##edtype)))
32
33 static int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig,
34 const unsigned char *tbs, size_t tbslen);
35 static int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig,
36 const unsigned char *tbs, size_t tbslen);
37 static int s390x_ed25519_digestverify(const ECX_KEY *edkey,
38 const unsigned char *sig,
39 const unsigned char *tbs, size_t tbslen);
40 static int s390x_ed448_digestverify(const ECX_KEY *edkey,
41 const unsigned char *sig,
42 const unsigned char *tbs, size_t tbslen);
43
44 #endif /* S390X_EC_ASM */
45
46 enum ID_EdDSA_INSTANCE {
47 ID_NOT_SET = 0,
48 ID_Ed25519,
49 ID_Ed25519ctx,
50 ID_Ed25519ph,
51 ID_Ed448,
52 ID_Ed448ph
53 };
54
55 #define SN_Ed25519 "Ed25519"
56 #define SN_Ed25519ph "Ed25519ph"
57 #define SN_Ed25519ctx "Ed25519ctx"
58 #define SN_Ed448 "Ed448"
59 #define SN_Ed448ph "Ed448ph"
60
61 #define EDDSA_MAX_CONTEXT_STRING_LEN 255
62 #define EDDSA_PREHASH_OUTPUT_LEN 64
63
64 static OSSL_FUNC_signature_newctx_fn eddsa_newctx;
65 static OSSL_FUNC_signature_digest_sign_init_fn eddsa_digest_signverify_init;
66 static OSSL_FUNC_signature_digest_sign_fn ed25519_digest_sign;
67 static OSSL_FUNC_signature_digest_sign_fn ed448_digest_sign;
68 static OSSL_FUNC_signature_digest_verify_fn ed25519_digest_verify;
69 static OSSL_FUNC_signature_digest_verify_fn ed448_digest_verify;
70 static OSSL_FUNC_signature_freectx_fn eddsa_freectx;
71 static OSSL_FUNC_signature_dupctx_fn eddsa_dupctx;
72 static OSSL_FUNC_signature_get_ctx_params_fn eddsa_get_ctx_params;
73 static OSSL_FUNC_signature_gettable_ctx_params_fn eddsa_gettable_ctx_params;
74 static OSSL_FUNC_signature_set_ctx_params_fn eddsa_set_ctx_params;
75 static OSSL_FUNC_signature_settable_ctx_params_fn eddsa_settable_ctx_params;
76
77 /* there are five EdDSA instances:
78
79 Ed25519
80 Ed25519ph
81 Ed25519ctx
82 Ed448
83 Ed448ph
84
85 Quoting from RFC 8032, Section 5.1:
86
87 For Ed25519, dom2(f,c) is the empty string. The phflag value is
88 irrelevant. The context (if present at all) MUST be empty. This
89 causes the scheme to be one and the same with the Ed25519 scheme
90 published earlier.
91
92 For Ed25519ctx, phflag=0. The context input SHOULD NOT be empty.
93
94 For Ed25519ph, phflag=1 and PH is SHA512 instead. That is, the input
95 is hashed using SHA-512 before signing with Ed25519.
96
97 Quoting from RFC 8032, Section 5.2:
98
99 Ed448ph is the same but with PH being SHAKE256(x, 64) and phflag
100 being 1, i.e., the input is hashed before signing with Ed448 with a
101 hash constant modified.
102
103 Value of context is set by signer and verifier (maximum of 255
104 octets; the default is empty string) and has to match octet by octet
105 for verification to be successful.
106
107 Quoting from RFC 8032, Section 2:
108
109 dom2(x, y) The blank octet string when signing or verifying
110 Ed25519. Otherwise, the octet string: "SigEd25519 no
111 Ed25519 collisions" || octet(x) || octet(OLEN(y)) ||
112 y, where x is in range 0-255 and y is an octet string
113 of at most 255 octets. "SigEd25519 no Ed25519
114 collisions" is in ASCII (32 octets).
115
116 dom4(x, y) The octet string "SigEd448" || octet(x) ||
117 octet(OLEN(y)) || y, where x is in range 0-255 and y
118 is an octet string of at most 255 octets. "SigEd448"
119 is in ASCII (8 octets).
120
121 Note above that x is the pre-hash flag, and y is the context string.
122 */
123
124 typedef struct {
125 OSSL_LIB_CTX *libctx;
126 ECX_KEY *key;
127
128 /* The Algorithm Identifier of the signature algorithm */
129 unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE];
130 unsigned char *aid;
131 size_t aid_len;
132
133 /* id indicating the EdDSA instance */
134 int instance_id;
135
136 unsigned int dom2_flag : 1;
137 unsigned int prehash_flag : 1;
138
139 /* indicates that a non-empty context string is required, as in Ed25519ctx */
140 unsigned int context_string_flag : 1;
141
142 unsigned char context_string[EDDSA_MAX_CONTEXT_STRING_LEN];
143 size_t context_string_len;
144
145 } PROV_EDDSA_CTX;
146
147 static void *eddsa_newctx(void *provctx, const char *propq_unused)
148 {
149 PROV_EDDSA_CTX *peddsactx;
150
151 if (!ossl_prov_is_running())
152 return NULL;
153
154 peddsactx = OPENSSL_zalloc(sizeof(PROV_EDDSA_CTX));
155 if (peddsactx == NULL)
156 return NULL;
157
158 peddsactx->libctx = PROV_LIBCTX_OF(provctx);
159
160 return peddsactx;
161 }
162
163 static int eddsa_digest_signverify_init(void *vpeddsactx, const char *mdname,
164 void *vedkey,
165 const OSSL_PARAM params[])
166 {
167 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
168 ECX_KEY *edkey = (ECX_KEY *)vedkey;
169 WPACKET pkt;
170 int ret;
171
172 if (!ossl_prov_is_running())
173 return 0;
174
175 if (mdname != NULL && mdname[0] != '\0') {
176 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST);
177 return 0;
178 }
179
180 if (edkey == NULL) {
181 if (peddsactx->key != NULL)
182 return eddsa_set_ctx_params(peddsactx, params);
183 ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
184 return 0;
185 }
186
187 if (!ossl_ecx_key_up_ref(edkey)) {
188 ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
189 return 0;
190 }
191
192 peddsactx->dom2_flag = 0;
193 peddsactx->prehash_flag = 0;
194 peddsactx->context_string_flag = 0;
195 peddsactx->context_string_len = 0;
196
197 /*
198 * We do not care about DER writing errors.
199 * All it really means is that for some reason, there's no
200 * AlgorithmIdentifier to be had, but the operation itself is
201 * still valid, just as long as it's not used to construct
202 * anything that needs an AlgorithmIdentifier.
203 */
204 peddsactx->aid_len = 0;
205 ret = WPACKET_init_der(&pkt, peddsactx->aid_buf, sizeof(peddsactx->aid_buf));
206 switch (edkey->type) {
207 case ECX_KEY_TYPE_ED25519:
208 ret = ret && ossl_DER_w_algorithmIdentifier_ED25519(&pkt, -1, edkey);
209 peddsactx->instance_id = ID_Ed25519;
210 break;
211 case ECX_KEY_TYPE_ED448:
212 ret = ret && ossl_DER_w_algorithmIdentifier_ED448(&pkt, -1, edkey);
213 peddsactx->instance_id = ID_Ed448;
214 break;
215 default:
216 /* Should never happen */
217 ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
218 ossl_ecx_key_free(edkey);
219 return 0;
220 }
221 if (ret && WPACKET_finish(&pkt)) {
222 WPACKET_get_total_written(&pkt, &peddsactx->aid_len);
223 peddsactx->aid = WPACKET_get_curr(&pkt);
224 }
225 WPACKET_cleanup(&pkt);
226
227 peddsactx->key = edkey;
228
229 if (!eddsa_set_ctx_params(peddsactx, params))
230 return 0;
231
232 return 1;
233 }
234
235 int ed25519_digest_sign(void *vpeddsactx, unsigned char *sigret,
236 size_t *siglen, size_t sigsize,
237 const unsigned char *tbs, size_t tbslen)
238 {
239 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
240 const ECX_KEY *edkey = peddsactx->key;
241 uint8_t md[EVP_MAX_MD_SIZE];
242 size_t mdlen;
243
244 if (!ossl_prov_is_running())
245 return 0;
246
247 if (sigret == NULL) {
248 *siglen = ED25519_SIGSIZE;
249 return 1;
250 }
251 if (sigsize < ED25519_SIGSIZE) {
252 ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
253 return 0;
254 }
255 if (edkey->privkey == NULL) {
256 ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
257 return 0;
258 }
259 #ifdef S390X_EC_ASM
260 /* s390x_ed25519_digestsign() does not yet support dom2 or context-strings.
261 fall back to non-accelerated sign if those options are set. */
262 if (S390X_CAN_SIGN(ED25519)
263 && !peddsactx->dom2_flag
264 && !peddsactx->context_string_flag
265 && peddsactx->context_string_len == 0) {
266 if (s390x_ed25519_digestsign(edkey, sigret, tbs, tbslen) == 0) {
267 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
268 return 0;
269 }
270 *siglen = ED25519_SIGSIZE;
271 return 1;
272 }
273 #endif /* S390X_EC_ASM */
274
275 if (peddsactx->prehash_flag) {
276 if (!EVP_Q_digest(peddsactx->libctx, SN_sha512, NULL, tbs, tbslen, md, &mdlen)
277 || mdlen != EDDSA_PREHASH_OUTPUT_LEN)
278 return 0;
279 tbs = md;
280 tbslen = mdlen;
281 }
282
283 if (ossl_ed25519_sign(sigret, tbs, tbslen, edkey->pubkey, edkey->privkey,
284 peddsactx->dom2_flag, peddsactx->prehash_flag, peddsactx->context_string_flag,
285 peddsactx->context_string, peddsactx->context_string_len,
286 peddsactx->libctx, NULL) == 0) {
287 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
288 return 0;
289 }
290 *siglen = ED25519_SIGSIZE;
291 return 1;
292 }
293
294 /* EVP_Q_digest() does not allow variable output length for XOFs,
295 so we use this function */
296 static int ed448_shake256(OSSL_LIB_CTX *libctx,
297 const char *propq,
298 const uint8_t *in, size_t inlen,
299 uint8_t *out, size_t outlen)
300 {
301 int ret = 0;
302 EVP_MD_CTX *hash_ctx = EVP_MD_CTX_new();
303 EVP_MD *shake256 = EVP_MD_fetch(libctx, SN_shake256, propq);
304
305 if (hash_ctx == NULL || shake256 == NULL)
306 goto err;
307
308 if (!EVP_DigestInit_ex(hash_ctx, shake256, NULL)
309 || !EVP_DigestUpdate(hash_ctx, in, inlen)
310 || !EVP_DigestFinalXOF(hash_ctx, out, outlen))
311 goto err;
312
313 ret = 1;
314
315 err:
316 EVP_MD_CTX_free(hash_ctx);
317 EVP_MD_free(shake256);
318 return ret;
319 }
320
321 int ed448_digest_sign(void *vpeddsactx, unsigned char *sigret,
322 size_t *siglen, size_t sigsize,
323 const unsigned char *tbs, size_t tbslen)
324 {
325 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
326 const ECX_KEY *edkey = peddsactx->key;
327 uint8_t md[EDDSA_PREHASH_OUTPUT_LEN];
328 size_t mdlen = sizeof(md);
329
330 if (!ossl_prov_is_running())
331 return 0;
332
333 if (sigret == NULL) {
334 *siglen = ED448_SIGSIZE;
335 return 1;
336 }
337 if (sigsize < ED448_SIGSIZE) {
338 ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
339 return 0;
340 }
341 if (edkey->privkey == NULL) {
342 ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
343 return 0;
344 }
345 #ifdef S390X_EC_ASM
346 /* s390x_ed448_digestsign() does not yet support context-strings or pre-hashing.
347 fall back to non-accelerated sign if a context-string or pre-hasing is provided. */
348 if (S390X_CAN_SIGN(ED448)
349 && peddsactx->context_string_len == 0
350 && peddsactx->prehash_flag == 0) {
351 if (s390x_ed448_digestsign(edkey, sigret, tbs, tbslen) == 0) {
352 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
353 return 0;
354 }
355 *siglen = ED448_SIGSIZE;
356 return 1;
357 }
358 #endif /* S390X_EC_ASM */
359
360 if (peddsactx->prehash_flag) {
361 if (!ed448_shake256(peddsactx->libctx, NULL, tbs, tbslen, md, mdlen))
362 return 0;
363 tbs = md;
364 tbslen = mdlen;
365 }
366
367 if (ossl_ed448_sign(peddsactx->libctx, sigret, tbs, tbslen,
368 edkey->pubkey, edkey->privkey,
369 peddsactx->context_string, peddsactx->context_string_len,
370 peddsactx->prehash_flag, edkey->propq) == 0) {
371 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
372 return 0;
373 }
374 *siglen = ED448_SIGSIZE;
375 return 1;
376 }
377
378 int ed25519_digest_verify(void *vpeddsactx, const unsigned char *sig,
379 size_t siglen, const unsigned char *tbs,
380 size_t tbslen)
381 {
382 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
383 const ECX_KEY *edkey = peddsactx->key;
384 uint8_t md[EVP_MAX_MD_SIZE];
385 size_t mdlen;
386
387 if (!ossl_prov_is_running() || siglen != ED25519_SIGSIZE)
388 return 0;
389
390 #ifdef S390X_EC_ASM
391 /* s390x_ed25519_digestverify() does not yet support dom2 or context-strings.
392 fall back to non-accelerated verify if those options are set. */
393 if (S390X_CAN_SIGN(ED25519)
394 && !peddsactx->dom2_flag
395 && !peddsactx->context_string_flag
396 && peddsactx->context_string_len == 0) {
397 return s390x_ed25519_digestverify(edkey, sig, tbs, tbslen);
398 }
399 #endif /* S390X_EC_ASM */
400
401 if (peddsactx->prehash_flag) {
402 if (!EVP_Q_digest(peddsactx->libctx, SN_sha512, NULL, tbs, tbslen, md, &mdlen)
403 || mdlen != EDDSA_PREHASH_OUTPUT_LEN)
404 return 0;
405 tbs = md;
406 tbslen = mdlen;
407 }
408
409 return ossl_ed25519_verify(tbs, tbslen, sig, edkey->pubkey,
410 peddsactx->dom2_flag, peddsactx->prehash_flag, peddsactx->context_string_flag,
411 peddsactx->context_string, peddsactx->context_string_len,
412 peddsactx->libctx, edkey->propq);
413 }
414
415 int ed448_digest_verify(void *vpeddsactx, const unsigned char *sig,
416 size_t siglen, const unsigned char *tbs,
417 size_t tbslen)
418 {
419 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
420 const ECX_KEY *edkey = peddsactx->key;
421 uint8_t md[EDDSA_PREHASH_OUTPUT_LEN];
422 size_t mdlen = sizeof(md);
423
424 if (!ossl_prov_is_running() || siglen != ED448_SIGSIZE)
425 return 0;
426
427 #ifdef S390X_EC_ASM
428 /* s390x_ed448_digestverify() does not yet support context-strings or pre-hashing.
429 fall back to non-accelerated verify if a context-string or pre-hasing is provided. */
430 if (S390X_CAN_SIGN(ED448)
431 && peddsactx->context_string_len == 0
432 && peddsactx->prehash_flag == 0) {
433 return s390x_ed448_digestverify(edkey, sig, tbs, tbslen);
434 }
435 #endif /* S390X_EC_ASM */
436
437 if (peddsactx->prehash_flag) {
438 if (!ed448_shake256(peddsactx->libctx, NULL, tbs, tbslen, md, mdlen))
439 return 0;
440 tbs = md;
441 tbslen = mdlen;
442 }
443
444 return ossl_ed448_verify(peddsactx->libctx, tbs, tbslen, sig, edkey->pubkey,
445 peddsactx->context_string, peddsactx->context_string_len,
446 peddsactx->prehash_flag, edkey->propq);
447 }
448
449 static void eddsa_freectx(void *vpeddsactx)
450 {
451 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
452
453 ossl_ecx_key_free(peddsactx->key);
454
455 OPENSSL_free(peddsactx);
456 }
457
458 static void *eddsa_dupctx(void *vpeddsactx)
459 {
460 PROV_EDDSA_CTX *srcctx = (PROV_EDDSA_CTX *)vpeddsactx;
461 PROV_EDDSA_CTX *dstctx;
462
463 if (!ossl_prov_is_running())
464 return NULL;
465
466 dstctx = OPENSSL_zalloc(sizeof(*srcctx));
467 if (dstctx == NULL)
468 return NULL;
469
470 *dstctx = *srcctx;
471 dstctx->key = NULL;
472
473 if (srcctx->key != NULL && !ossl_ecx_key_up_ref(srcctx->key)) {
474 ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
475 goto err;
476 }
477 dstctx->key = srcctx->key;
478
479 return dstctx;
480 err:
481 eddsa_freectx(dstctx);
482 return NULL;
483 }
484
485 static int eddsa_get_ctx_params(void *vpeddsactx, OSSL_PARAM *params)
486 {
487 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
488 OSSL_PARAM *p;
489
490 if (peddsactx == NULL)
491 return 0;
492
493 p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID);
494 if (p != NULL && !OSSL_PARAM_set_octet_string(p, peddsactx->aid,
495 peddsactx->aid_len))
496 return 0;
497
498 return 1;
499 }
500
501 static const OSSL_PARAM known_gettable_ctx_params[] = {
502 OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
503 OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_INSTANCE, NULL, 0),
504 OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0),
505 OSSL_PARAM_END
506 };
507
508 static const OSSL_PARAM *eddsa_gettable_ctx_params(ossl_unused void *vpeddsactx,
509 ossl_unused void *provctx)
510 {
511 return known_gettable_ctx_params;
512 }
513
514 static int eddsa_set_ctx_params(void *vpeddsactx, const OSSL_PARAM params[])
515 {
516 PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
517 const OSSL_PARAM *p;
518
519 if (peddsactx == NULL)
520 return 0;
521 if (params == NULL)
522 return 1;
523
524 p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_INSTANCE);
525 if (p != NULL) {
526 char instance_name[OSSL_MAX_NAME_SIZE] = "";
527 char *pinstance_name = instance_name;
528
529 if (!OSSL_PARAM_get_utf8_string(p, &pinstance_name, sizeof(instance_name)))
530 return 0;
531
532 if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519) == 0) {
533 peddsactx->instance_id = ID_Ed25519;
534 if (peddsactx->key->type != ECX_KEY_TYPE_ED25519) return 0;
535 peddsactx->dom2_flag = 0;
536 peddsactx->prehash_flag = 0;
537 peddsactx->context_string_flag = 0;
538 } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519ctx) == 0) {
539 peddsactx->instance_id = ID_Ed25519ctx;
540 if (peddsactx->key->type != ECX_KEY_TYPE_ED25519) return 0;
541 peddsactx->dom2_flag = 1;
542 peddsactx->prehash_flag = 0;
543 peddsactx->context_string_flag = 1;
544 } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed25519ph) == 0) {
545 peddsactx->instance_id = ID_Ed25519ph;
546 if (peddsactx->key->type != ECX_KEY_TYPE_ED25519) return 0;
547 peddsactx->dom2_flag = 1;
548 peddsactx->prehash_flag = 1;
549 peddsactx->context_string_flag = 0;
550 } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed448) == 0) {
551 peddsactx->instance_id = ID_Ed448;
552 if (peddsactx->key->type != ECX_KEY_TYPE_ED448) return 0;
553 peddsactx->prehash_flag = 0;
554 peddsactx->context_string_flag = 0;
555 } else if (OPENSSL_strcasecmp(pinstance_name, SN_Ed448ph) == 0) {
556 peddsactx->instance_id = ID_Ed448ph;
557 if (peddsactx->key->type != ECX_KEY_TYPE_ED448) return 0;
558 peddsactx->prehash_flag = 1;
559 peddsactx->context_string_flag = 0;
560 } else {
561 /* we did not recognize the instance */
562 return 0;
563 }
564
565 }
566
567 p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_CONTEXT_STRING);
568 if (p != NULL) {
569 void *vp_context_string = peddsactx->context_string;
570
571 if (!OSSL_PARAM_get_octet_string(p, &vp_context_string, sizeof(peddsactx->context_string), &(peddsactx->context_string_len))) {
572 peddsactx->context_string_len = 0;
573 return 0;
574 }
575 }
576
577 return 1;
578 }
579
580 static const OSSL_PARAM settable_ctx_params[] = {
581 OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_INSTANCE, NULL, 0),
582 OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING, NULL, 0),
583 OSSL_PARAM_END
584 };
585
586 static const OSSL_PARAM *eddsa_settable_ctx_params(ossl_unused void *vpeddsactx,
587 ossl_unused void *provctx)
588 {
589 return settable_ctx_params;
590 }
591
592 const OSSL_DISPATCH ossl_ed25519_signature_functions[] = {
593 { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx },
594 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
595 (void (*)(void))eddsa_digest_signverify_init },
596 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN,
597 (void (*)(void))ed25519_digest_sign },
598 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
599 (void (*)(void))eddsa_digest_signverify_init },
600 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY,
601 (void (*)(void))ed25519_digest_verify },
602 { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx },
603 { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx },
604 { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))eddsa_get_ctx_params },
605 { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
606 (void (*)(void))eddsa_gettable_ctx_params },
607 { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))eddsa_set_ctx_params },
608 { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,
609 (void (*)(void))eddsa_settable_ctx_params },
610 OSSL_DISPATCH_END
611 };
612
613 const OSSL_DISPATCH ossl_ed448_signature_functions[] = {
614 { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx },
615 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
616 (void (*)(void))eddsa_digest_signverify_init },
617 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN,
618 (void (*)(void))ed448_digest_sign },
619 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
620 (void (*)(void))eddsa_digest_signverify_init },
621 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY,
622 (void (*)(void))ed448_digest_verify },
623 { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx },
624 { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx },
625 { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))eddsa_get_ctx_params },
626 { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
627 (void (*)(void))eddsa_gettable_ctx_params },
628 { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))eddsa_set_ctx_params },
629 { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,
630 (void (*)(void))eddsa_settable_ctx_params },
631 OSSL_DISPATCH_END
632 };
633
634 #ifdef S390X_EC_ASM
635
636 static int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig,
637 const unsigned char *tbs, size_t tbslen)
638 {
639 int rc;
640 union {
641 struct {
642 unsigned char sig[64];
643 unsigned char priv[32];
644 } ed25519;
645 unsigned long long buff[512];
646 } param;
647
648 memset(&param, 0, sizeof(param));
649 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
650
651 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, &param.ed25519, tbs, tbslen);
652 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
653 if (rc != 0)
654 return 0;
655
656 s390x_flip_endian32(sig, param.ed25519.sig);
657 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
658 return 1;
659 }
660
661 static int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig,
662 const unsigned char *tbs, size_t tbslen)
663 {
664 int rc;
665 union {
666 struct {
667 unsigned char sig[128];
668 unsigned char priv[64];
669 } ed448;
670 unsigned long long buff[512];
671 } param;
672
673 memset(&param, 0, sizeof(param));
674 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
675
676 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, &param.ed448, tbs, tbslen);
677 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
678 if (rc != 0)
679 return 0;
680
681 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
682 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
683 memcpy(sig, param.ed448.sig, 57);
684 memcpy(sig + 57, param.ed448.sig + 64, 57);
685 return 1;
686 }
687
688 static int s390x_ed25519_digestverify(const ECX_KEY *edkey,
689 const unsigned char *sig,
690 const unsigned char *tbs, size_t tbslen)
691 {
692 union {
693 struct {
694 unsigned char sig[64];
695 unsigned char pub[32];
696 } ed25519;
697 unsigned long long buff[512];
698 } param;
699
700 memset(&param, 0, sizeof(param));
701 s390x_flip_endian32(param.ed25519.sig, sig);
702 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
703 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
704
705 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
706 &param.ed25519, tbs, tbslen) == 0 ? 1 : 0;
707 }
708
709 static int s390x_ed448_digestverify(const ECX_KEY *edkey,
710 const unsigned char *sig,
711 const unsigned char *tbs,
712 size_t tbslen)
713 {
714 union {
715 struct {
716 unsigned char sig[128];
717 unsigned char pub[64];
718 } ed448;
719 unsigned long long buff[512];
720 } param;
721
722 memset(&param, 0, sizeof(param));
723 memcpy(param.ed448.sig, sig, 57);
724 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
725 memcpy(param.ed448.sig + 64, sig + 57, 57);
726 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
727 memcpy(param.ed448.pub, edkey->pubkey, 57);
728 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
729
730 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
731 &param.ed448, tbs, tbslen) == 0 ? 1 : 0;
732 }
733
734 #endif /* S390X_EC_ASM */