2 * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
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
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"
26 # include "s390x_arch.h"
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)))
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
);
44 #endif /* S390X_EC_ASM */
46 enum ID_EdDSA_INSTANCE
{
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"
61 #define EDDSA_MAX_CONTEXT_STRING_LEN 255
62 #define EDDSA_PREHASH_OUTPUT_LEN 64
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
;
77 /* there are five EdDSA instances:
85 Quoting from RFC 8032, Section 5.1:
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
92 For Ed25519ctx, phflag=0. The context input SHOULD NOT be empty.
94 For Ed25519ph, phflag=1 and PH is SHA512 instead. That is, the input
95 is hashed using SHA-512 before signing with Ed25519.
97 Quoting from RFC 8032, Section 5.2:
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.
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.
107 Quoting from RFC 8032, Section 2:
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).
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).
121 Note above that x is the pre-hash flag, and y is the context string.
125 OSSL_LIB_CTX
*libctx
;
128 /* The Algorithm Identifier of the signature algorithm */
129 unsigned char aid_buf
[OSSL_MAX_ALGORITHM_ID_SIZE
];
133 /* id indicating the EdDSA instance */
136 unsigned int dom2_flag
: 1;
137 unsigned int prehash_flag
: 1;
139 /* indicates that a non-empty context string is required, as in Ed25519ctx */
140 unsigned int context_string_flag
: 1;
142 unsigned char context_string
[EDDSA_MAX_CONTEXT_STRING_LEN
];
143 size_t context_string_len
;
147 static void *eddsa_newctx(void *provctx
, const char *propq_unused
)
149 PROV_EDDSA_CTX
*peddsactx
;
151 if (!ossl_prov_is_running())
154 peddsactx
= OPENSSL_zalloc(sizeof(PROV_EDDSA_CTX
));
155 if (peddsactx
== NULL
)
158 peddsactx
->libctx
= PROV_LIBCTX_OF(provctx
);
163 static int eddsa_digest_signverify_init(void *vpeddsactx
, const char *mdname
,
165 const OSSL_PARAM params
[])
167 PROV_EDDSA_CTX
*peddsactx
= (PROV_EDDSA_CTX
*)vpeddsactx
;
168 ECX_KEY
*edkey
= (ECX_KEY
*)vedkey
;
172 if (!ossl_prov_is_running())
175 if (mdname
!= NULL
&& mdname
[0] != '\0') {
176 ERR_raise(ERR_LIB_PROV
, PROV_R_INVALID_DIGEST
);
181 if (peddsactx
->key
!= NULL
)
182 return eddsa_set_ctx_params(peddsactx
, params
);
183 ERR_raise(ERR_LIB_PROV
, PROV_R_NO_KEY_SET
);
187 if (!ossl_ecx_key_up_ref(edkey
)) {
188 ERR_raise(ERR_LIB_PROV
, ERR_R_INTERNAL_ERROR
);
192 peddsactx
->dom2_flag
= 0;
193 peddsactx
->prehash_flag
= 0;
194 peddsactx
->context_string_flag
= 0;
195 peddsactx
->context_string_len
= 0;
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.
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
;
211 case ECX_KEY_TYPE_ED448
:
212 ret
= ret
&& ossl_DER_w_algorithmIdentifier_ED448(&pkt
, -1, edkey
);
213 peddsactx
->instance_id
= ID_Ed448
;
216 /* Should never happen */
217 ERR_raise(ERR_LIB_PROV
, ERR_R_INTERNAL_ERROR
);
218 ossl_ecx_key_free(edkey
);
221 if (ret
&& WPACKET_finish(&pkt
)) {
222 WPACKET_get_total_written(&pkt
, &peddsactx
->aid_len
);
223 peddsactx
->aid
= WPACKET_get_curr(&pkt
);
225 WPACKET_cleanup(&pkt
);
227 peddsactx
->key
= edkey
;
229 if (!eddsa_set_ctx_params(peddsactx
, params
))
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
)
239 PROV_EDDSA_CTX
*peddsactx
= (PROV_EDDSA_CTX
*)vpeddsactx
;
240 const ECX_KEY
*edkey
= peddsactx
->key
;
241 uint8_t md
[EVP_MAX_MD_SIZE
];
244 if (!ossl_prov_is_running())
247 if (sigret
== NULL
) {
248 *siglen
= ED25519_SIGSIZE
;
251 if (sigsize
< ED25519_SIGSIZE
) {
252 ERR_raise(ERR_LIB_PROV
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
255 if (edkey
->privkey
== NULL
) {
256 ERR_raise(ERR_LIB_PROV
, PROV_R_NOT_A_PRIVATE_KEY
);
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
);
270 *siglen
= ED25519_SIGSIZE
;
273 #endif /* S390X_EC_ASM */
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
)
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
);
290 *siglen
= ED25519_SIGSIZE
;
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
,
298 const uint8_t *in
, size_t inlen
,
299 uint8_t *out
, size_t outlen
)
302 EVP_MD_CTX
*hash_ctx
= EVP_MD_CTX_new();
303 EVP_MD
*shake256
= EVP_MD_fetch(libctx
, SN_shake256
, propq
);
305 if (hash_ctx
== NULL
|| shake256
== NULL
)
308 if (!EVP_DigestInit_ex(hash_ctx
, shake256
, NULL
)
309 || !EVP_DigestUpdate(hash_ctx
, in
, inlen
)
310 || !EVP_DigestFinalXOF(hash_ctx
, out
, outlen
))
316 EVP_MD_CTX_free(hash_ctx
);
317 EVP_MD_free(shake256
);
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
)
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
);
330 if (!ossl_prov_is_running())
333 if (sigret
== NULL
) {
334 *siglen
= ED448_SIGSIZE
;
337 if (sigsize
< ED448_SIGSIZE
) {
338 ERR_raise(ERR_LIB_PROV
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
341 if (edkey
->privkey
== NULL
) {
342 ERR_raise(ERR_LIB_PROV
, PROV_R_NOT_A_PRIVATE_KEY
);
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
);
355 *siglen
= ED448_SIGSIZE
;
358 #endif /* S390X_EC_ASM */
360 if (peddsactx
->prehash_flag
) {
361 if (!ed448_shake256(peddsactx
->libctx
, NULL
, tbs
, tbslen
, md
, mdlen
))
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
);
374 *siglen
= ED448_SIGSIZE
;
378 int ed25519_digest_verify(void *vpeddsactx
, const unsigned char *sig
,
379 size_t siglen
, const unsigned char *tbs
,
382 PROV_EDDSA_CTX
*peddsactx
= (PROV_EDDSA_CTX
*)vpeddsactx
;
383 const ECX_KEY
*edkey
= peddsactx
->key
;
384 uint8_t md
[EVP_MAX_MD_SIZE
];
387 if (!ossl_prov_is_running() || siglen
!= ED25519_SIGSIZE
)
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
);
399 #endif /* S390X_EC_ASM */
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
)
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
);
415 int ed448_digest_verify(void *vpeddsactx
, const unsigned char *sig
,
416 size_t siglen
, const unsigned char *tbs
,
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
);
424 if (!ossl_prov_is_running() || siglen
!= ED448_SIGSIZE
)
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
);
435 #endif /* S390X_EC_ASM */
437 if (peddsactx
->prehash_flag
) {
438 if (!ed448_shake256(peddsactx
->libctx
, NULL
, tbs
, tbslen
, md
, mdlen
))
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
);
449 static void eddsa_freectx(void *vpeddsactx
)
451 PROV_EDDSA_CTX
*peddsactx
= (PROV_EDDSA_CTX
*)vpeddsactx
;
453 ossl_ecx_key_free(peddsactx
->key
);
455 OPENSSL_free(peddsactx
);
458 static void *eddsa_dupctx(void *vpeddsactx
)
460 PROV_EDDSA_CTX
*srcctx
= (PROV_EDDSA_CTX
*)vpeddsactx
;
461 PROV_EDDSA_CTX
*dstctx
;
463 if (!ossl_prov_is_running())
466 dstctx
= OPENSSL_zalloc(sizeof(*srcctx
));
473 if (srcctx
->key
!= NULL
&& !ossl_ecx_key_up_ref(srcctx
->key
)) {
474 ERR_raise(ERR_LIB_PROV
, ERR_R_INTERNAL_ERROR
);
477 dstctx
->key
= srcctx
->key
;
481 eddsa_freectx(dstctx
);
485 static int eddsa_get_ctx_params(void *vpeddsactx
, OSSL_PARAM
*params
)
487 PROV_EDDSA_CTX
*peddsactx
= (PROV_EDDSA_CTX
*)vpeddsactx
;
490 if (peddsactx
== NULL
)
493 p
= OSSL_PARAM_locate(params
, OSSL_SIGNATURE_PARAM_ALGORITHM_ID
);
494 if (p
!= NULL
&& !OSSL_PARAM_set_octet_string(p
, peddsactx
->aid
,
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),
508 static const OSSL_PARAM
*eddsa_gettable_ctx_params(ossl_unused
void *vpeddsactx
,
509 ossl_unused
void *provctx
)
511 return known_gettable_ctx_params
;
514 static int eddsa_set_ctx_params(void *vpeddsactx
, const OSSL_PARAM params
[])
516 PROV_EDDSA_CTX
*peddsactx
= (PROV_EDDSA_CTX
*)vpeddsactx
;
519 if (peddsactx
== NULL
)
524 p
= OSSL_PARAM_locate_const(params
, OSSL_SIGNATURE_PARAM_INSTANCE
);
526 char instance_name
[OSSL_MAX_NAME_SIZE
] = "";
527 char *pinstance_name
= instance_name
;
529 if (!OSSL_PARAM_get_utf8_string(p
, &pinstance_name
, sizeof(instance_name
)))
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;
561 /* we did not recognize the instance */
567 p
= OSSL_PARAM_locate_const(params
, OSSL_SIGNATURE_PARAM_CONTEXT_STRING
);
569 void *vp_context_string
= peddsactx
->context_string
;
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;
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),
586 static const OSSL_PARAM
*eddsa_settable_ctx_params(ossl_unused
void *vpeddsactx
,
587 ossl_unused
void *provctx
)
589 return settable_ctx_params
;
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
},
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
},
636 static int s390x_ed25519_digestsign(const ECX_KEY
*edkey
, unsigned char *sig
,
637 const unsigned char *tbs
, size_t tbslen
)
642 unsigned char sig
[64];
643 unsigned char priv
[32];
645 unsigned long long buff
[512];
648 memset(¶m
, 0, sizeof(param
));
649 memcpy(param
.ed25519
.priv
, edkey
->privkey
, sizeof(param
.ed25519
.priv
));
651 rc
= s390x_kdsa(S390X_EDDSA_SIGN_ED25519
, ¶m
.ed25519
, tbs
, tbslen
);
652 OPENSSL_cleanse(param
.ed25519
.priv
, sizeof(param
.ed25519
.priv
));
656 s390x_flip_endian32(sig
, param
.ed25519
.sig
);
657 s390x_flip_endian32(sig
+ 32, param
.ed25519
.sig
+ 32);
661 static int s390x_ed448_digestsign(const ECX_KEY
*edkey
, unsigned char *sig
,
662 const unsigned char *tbs
, size_t tbslen
)
667 unsigned char sig
[128];
668 unsigned char priv
[64];
670 unsigned long long buff
[512];
673 memset(¶m
, 0, sizeof(param
));
674 memcpy(param
.ed448
.priv
+ 64 - 57, edkey
->privkey
, 57);
676 rc
= s390x_kdsa(S390X_EDDSA_SIGN_ED448
, ¶m
.ed448
, tbs
, tbslen
);
677 OPENSSL_cleanse(param
.ed448
.priv
, sizeof(param
.ed448
.priv
));
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);
688 static int s390x_ed25519_digestverify(const ECX_KEY
*edkey
,
689 const unsigned char *sig
,
690 const unsigned char *tbs
, size_t tbslen
)
694 unsigned char sig
[64];
695 unsigned char pub
[32];
697 unsigned long long buff
[512];
700 memset(¶m
, 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
);
705 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519
,
706 ¶m
.ed25519
, tbs
, tbslen
) == 0 ? 1 : 0;
709 static int s390x_ed448_digestverify(const ECX_KEY
*edkey
,
710 const unsigned char *sig
,
711 const unsigned char *tbs
,
716 unsigned char sig
[128];
717 unsigned char pub
[64];
719 unsigned long long buff
[512];
722 memset(¶m
, 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
);
730 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448
,
731 ¶m
.ed448
, tbs
, tbslen
) == 0 ? 1 : 0;
734 #endif /* S390X_EC_ASM */