1*b077aed3SPierre Pronchery /*
2*b077aed3SPierre Pronchery * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
3*b077aed3SPierre Pronchery *
4*b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use
5*b077aed3SPierre Pronchery * this file except in compliance with the License. You can obtain a copy
6*b077aed3SPierre Pronchery * in the file LICENSE in the source distribution or at
7*b077aed3SPierre Pronchery * https://www.openssl.org/source/license.html
8*b077aed3SPierre Pronchery */
9*b077aed3SPierre Pronchery
10*b077aed3SPierre Pronchery #include <openssl/crypto.h>
11*b077aed3SPierre Pronchery #include <openssl/core_dispatch.h>
12*b077aed3SPierre Pronchery #include <openssl/core_names.h>
13*b077aed3SPierre Pronchery #include <openssl/err.h>
14*b077aed3SPierre Pronchery #include <openssl/params.h>
15*b077aed3SPierre Pronchery #include <openssl/evp.h>
16*b077aed3SPierre Pronchery #include <openssl/err.h>
17*b077aed3SPierre Pronchery #include <openssl/proverr.h>
18*b077aed3SPierre Pronchery #include "internal/nelem.h"
19*b077aed3SPierre Pronchery #include "internal/sizes.h"
20*b077aed3SPierre Pronchery #include "prov/providercommon.h"
21*b077aed3SPierre Pronchery #include "prov/implementations.h"
22*b077aed3SPierre Pronchery #include "prov/provider_ctx.h"
23*b077aed3SPierre Pronchery #include "prov/der_ecx.h"
24*b077aed3SPierre Pronchery #include "crypto/ecx.h"
25*b077aed3SPierre Pronchery
26*b077aed3SPierre Pronchery #ifdef S390X_EC_ASM
27*b077aed3SPierre Pronchery # include "s390x_arch.h"
28*b077aed3SPierre Pronchery
29*b077aed3SPierre Pronchery # define S390X_CAN_SIGN(edtype) \
30*b077aed3SPierre Pronchery ((OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_##edtype)) \
31*b077aed3SPierre Pronchery && (OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_##edtype)) \
32*b077aed3SPierre Pronchery && (OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_##edtype)))
33*b077aed3SPierre Pronchery
34*b077aed3SPierre Pronchery static int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig,
35*b077aed3SPierre Pronchery const unsigned char *tbs, size_t tbslen);
36*b077aed3SPierre Pronchery static int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig,
37*b077aed3SPierre Pronchery const unsigned char *tbs, size_t tbslen);
38*b077aed3SPierre Pronchery static int s390x_ed25519_digestverify(const ECX_KEY *edkey,
39*b077aed3SPierre Pronchery const unsigned char *sig,
40*b077aed3SPierre Pronchery const unsigned char *tbs, size_t tbslen);
41*b077aed3SPierre Pronchery static int s390x_ed448_digestverify(const ECX_KEY *edkey,
42*b077aed3SPierre Pronchery const unsigned char *sig,
43*b077aed3SPierre Pronchery const unsigned char *tbs, size_t tbslen);
44*b077aed3SPierre Pronchery
45*b077aed3SPierre Pronchery #endif /* S390X_EC_ASM */
46*b077aed3SPierre Pronchery
47*b077aed3SPierre Pronchery static OSSL_FUNC_signature_newctx_fn eddsa_newctx;
48*b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_sign_init_fn eddsa_digest_signverify_init;
49*b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_sign_fn ed25519_digest_sign;
50*b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_sign_fn ed448_digest_sign;
51*b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_verify_fn ed25519_digest_verify;
52*b077aed3SPierre Pronchery static OSSL_FUNC_signature_digest_verify_fn ed448_digest_verify;
53*b077aed3SPierre Pronchery static OSSL_FUNC_signature_freectx_fn eddsa_freectx;
54*b077aed3SPierre Pronchery static OSSL_FUNC_signature_dupctx_fn eddsa_dupctx;
55*b077aed3SPierre Pronchery static OSSL_FUNC_signature_get_ctx_params_fn eddsa_get_ctx_params;
56*b077aed3SPierre Pronchery static OSSL_FUNC_signature_gettable_ctx_params_fn eddsa_gettable_ctx_params;
57*b077aed3SPierre Pronchery
58*b077aed3SPierre Pronchery typedef struct {
59*b077aed3SPierre Pronchery OSSL_LIB_CTX *libctx;
60*b077aed3SPierre Pronchery ECX_KEY *key;
61*b077aed3SPierre Pronchery
62*b077aed3SPierre Pronchery /* The Algorithm Identifier of the signature algorithm */
63*b077aed3SPierre Pronchery unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE];
64*b077aed3SPierre Pronchery unsigned char *aid;
65*b077aed3SPierre Pronchery size_t aid_len;
66*b077aed3SPierre Pronchery } PROV_EDDSA_CTX;
67*b077aed3SPierre Pronchery
eddsa_newctx(void * provctx,const char * propq_unused)68*b077aed3SPierre Pronchery static void *eddsa_newctx(void *provctx, const char *propq_unused)
69*b077aed3SPierre Pronchery {
70*b077aed3SPierre Pronchery PROV_EDDSA_CTX *peddsactx;
71*b077aed3SPierre Pronchery
72*b077aed3SPierre Pronchery if (!ossl_prov_is_running())
73*b077aed3SPierre Pronchery return NULL;
74*b077aed3SPierre Pronchery
75*b077aed3SPierre Pronchery peddsactx = OPENSSL_zalloc(sizeof(PROV_EDDSA_CTX));
76*b077aed3SPierre Pronchery if (peddsactx == NULL) {
77*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
78*b077aed3SPierre Pronchery return NULL;
79*b077aed3SPierre Pronchery }
80*b077aed3SPierre Pronchery
81*b077aed3SPierre Pronchery peddsactx->libctx = PROV_LIBCTX_OF(provctx);
82*b077aed3SPierre Pronchery
83*b077aed3SPierre Pronchery return peddsactx;
84*b077aed3SPierre Pronchery }
85*b077aed3SPierre Pronchery
eddsa_digest_signverify_init(void * vpeddsactx,const char * mdname,void * vedkey,ossl_unused const OSSL_PARAM params[])86*b077aed3SPierre Pronchery static int eddsa_digest_signverify_init(void *vpeddsactx, const char *mdname,
87*b077aed3SPierre Pronchery void *vedkey,
88*b077aed3SPierre Pronchery ossl_unused const OSSL_PARAM params[])
89*b077aed3SPierre Pronchery {
90*b077aed3SPierre Pronchery PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
91*b077aed3SPierre Pronchery ECX_KEY *edkey = (ECX_KEY *)vedkey;
92*b077aed3SPierre Pronchery WPACKET pkt;
93*b077aed3SPierre Pronchery int ret;
94*b077aed3SPierre Pronchery
95*b077aed3SPierre Pronchery if (!ossl_prov_is_running())
96*b077aed3SPierre Pronchery return 0;
97*b077aed3SPierre Pronchery
98*b077aed3SPierre Pronchery if (mdname != NULL && mdname[0] != '\0') {
99*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST);
100*b077aed3SPierre Pronchery return 0;
101*b077aed3SPierre Pronchery }
102*b077aed3SPierre Pronchery
103*b077aed3SPierre Pronchery if (edkey == NULL) {
104*b077aed3SPierre Pronchery if (peddsactx->key != NULL)
105*b077aed3SPierre Pronchery /* there is nothing to do on reinit */
106*b077aed3SPierre Pronchery return 1;
107*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
108*b077aed3SPierre Pronchery return 0;
109*b077aed3SPierre Pronchery }
110*b077aed3SPierre Pronchery
111*b077aed3SPierre Pronchery if (!ossl_ecx_key_up_ref(edkey)) {
112*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
113*b077aed3SPierre Pronchery return 0;
114*b077aed3SPierre Pronchery }
115*b077aed3SPierre Pronchery
116*b077aed3SPierre Pronchery /*
117*b077aed3SPierre Pronchery * We do not care about DER writing errors.
118*b077aed3SPierre Pronchery * All it really means is that for some reason, there's no
119*b077aed3SPierre Pronchery * AlgorithmIdentifier to be had, but the operation itself is
120*b077aed3SPierre Pronchery * still valid, just as long as it's not used to construct
121*b077aed3SPierre Pronchery * anything that needs an AlgorithmIdentifier.
122*b077aed3SPierre Pronchery */
123*b077aed3SPierre Pronchery peddsactx->aid_len = 0;
124*b077aed3SPierre Pronchery ret = WPACKET_init_der(&pkt, peddsactx->aid_buf, sizeof(peddsactx->aid_buf));
125*b077aed3SPierre Pronchery switch (edkey->type) {
126*b077aed3SPierre Pronchery case ECX_KEY_TYPE_ED25519:
127*b077aed3SPierre Pronchery ret = ret && ossl_DER_w_algorithmIdentifier_ED25519(&pkt, -1, edkey);
128*b077aed3SPierre Pronchery break;
129*b077aed3SPierre Pronchery case ECX_KEY_TYPE_ED448:
130*b077aed3SPierre Pronchery ret = ret && ossl_DER_w_algorithmIdentifier_ED448(&pkt, -1, edkey);
131*b077aed3SPierre Pronchery break;
132*b077aed3SPierre Pronchery default:
133*b077aed3SPierre Pronchery /* Should never happen */
134*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
135*b077aed3SPierre Pronchery ossl_ecx_key_free(edkey);
136*b077aed3SPierre Pronchery return 0;
137*b077aed3SPierre Pronchery }
138*b077aed3SPierre Pronchery if (ret && WPACKET_finish(&pkt)) {
139*b077aed3SPierre Pronchery WPACKET_get_total_written(&pkt, &peddsactx->aid_len);
140*b077aed3SPierre Pronchery peddsactx->aid = WPACKET_get_curr(&pkt);
141*b077aed3SPierre Pronchery }
142*b077aed3SPierre Pronchery WPACKET_cleanup(&pkt);
143*b077aed3SPierre Pronchery
144*b077aed3SPierre Pronchery peddsactx->key = edkey;
145*b077aed3SPierre Pronchery
146*b077aed3SPierre Pronchery return 1;
147*b077aed3SPierre Pronchery }
148*b077aed3SPierre Pronchery
ed25519_digest_sign(void * vpeddsactx,unsigned char * sigret,size_t * siglen,size_t sigsize,const unsigned char * tbs,size_t tbslen)149*b077aed3SPierre Pronchery int ed25519_digest_sign(void *vpeddsactx, unsigned char *sigret,
150*b077aed3SPierre Pronchery size_t *siglen, size_t sigsize,
151*b077aed3SPierre Pronchery const unsigned char *tbs, size_t tbslen)
152*b077aed3SPierre Pronchery {
153*b077aed3SPierre Pronchery PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
154*b077aed3SPierre Pronchery const ECX_KEY *edkey = peddsactx->key;
155*b077aed3SPierre Pronchery
156*b077aed3SPierre Pronchery if (!ossl_prov_is_running())
157*b077aed3SPierre Pronchery return 0;
158*b077aed3SPierre Pronchery
159*b077aed3SPierre Pronchery if (sigret == NULL) {
160*b077aed3SPierre Pronchery *siglen = ED25519_SIGSIZE;
161*b077aed3SPierre Pronchery return 1;
162*b077aed3SPierre Pronchery }
163*b077aed3SPierre Pronchery if (sigsize < ED25519_SIGSIZE) {
164*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
165*b077aed3SPierre Pronchery return 0;
166*b077aed3SPierre Pronchery }
167*b077aed3SPierre Pronchery if (edkey->privkey == NULL) {
168*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
169*b077aed3SPierre Pronchery return 0;
170*b077aed3SPierre Pronchery }
171*b077aed3SPierre Pronchery #ifdef S390X_EC_ASM
172*b077aed3SPierre Pronchery if (S390X_CAN_SIGN(ED25519)) {
173*b077aed3SPierre Pronchery if (s390x_ed25519_digestsign(edkey, sigret, tbs, tbslen) == 0) {
174*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
175*b077aed3SPierre Pronchery return 0;
176*b077aed3SPierre Pronchery }
177*b077aed3SPierre Pronchery *siglen = ED25519_SIGSIZE;
178*b077aed3SPierre Pronchery return 1;
179*b077aed3SPierre Pronchery }
180*b077aed3SPierre Pronchery #endif /* S390X_EC_ASM */
181*b077aed3SPierre Pronchery if (ossl_ed25519_sign(sigret, tbs, tbslen, edkey->pubkey, edkey->privkey,
182*b077aed3SPierre Pronchery peddsactx->libctx, NULL) == 0) {
183*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
184*b077aed3SPierre Pronchery return 0;
185*b077aed3SPierre Pronchery }
186*b077aed3SPierre Pronchery *siglen = ED25519_SIGSIZE;
187*b077aed3SPierre Pronchery return 1;
188*b077aed3SPierre Pronchery }
189*b077aed3SPierre Pronchery
ed448_digest_sign(void * vpeddsactx,unsigned char * sigret,size_t * siglen,size_t sigsize,const unsigned char * tbs,size_t tbslen)190*b077aed3SPierre Pronchery int ed448_digest_sign(void *vpeddsactx, unsigned char *sigret,
191*b077aed3SPierre Pronchery size_t *siglen, size_t sigsize,
192*b077aed3SPierre Pronchery const unsigned char *tbs, size_t tbslen)
193*b077aed3SPierre Pronchery {
194*b077aed3SPierre Pronchery PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
195*b077aed3SPierre Pronchery const ECX_KEY *edkey = peddsactx->key;
196*b077aed3SPierre Pronchery
197*b077aed3SPierre Pronchery if (!ossl_prov_is_running())
198*b077aed3SPierre Pronchery return 0;
199*b077aed3SPierre Pronchery
200*b077aed3SPierre Pronchery if (sigret == NULL) {
201*b077aed3SPierre Pronchery *siglen = ED448_SIGSIZE;
202*b077aed3SPierre Pronchery return 1;
203*b077aed3SPierre Pronchery }
204*b077aed3SPierre Pronchery if (sigsize < ED448_SIGSIZE) {
205*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
206*b077aed3SPierre Pronchery return 0;
207*b077aed3SPierre Pronchery }
208*b077aed3SPierre Pronchery if (edkey->privkey == NULL) {
209*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
210*b077aed3SPierre Pronchery return 0;
211*b077aed3SPierre Pronchery }
212*b077aed3SPierre Pronchery #ifdef S390X_EC_ASM
213*b077aed3SPierre Pronchery if (S390X_CAN_SIGN(ED448)) {
214*b077aed3SPierre Pronchery if (s390x_ed448_digestsign(edkey, sigret, tbs, tbslen) == 0) {
215*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
216*b077aed3SPierre Pronchery return 0;
217*b077aed3SPierre Pronchery }
218*b077aed3SPierre Pronchery *siglen = ED448_SIGSIZE;
219*b077aed3SPierre Pronchery return 1;
220*b077aed3SPierre Pronchery }
221*b077aed3SPierre Pronchery #endif /* S390X_EC_ASM */
222*b077aed3SPierre Pronchery if (ossl_ed448_sign(peddsactx->libctx, sigret, tbs, tbslen, edkey->pubkey,
223*b077aed3SPierre Pronchery edkey->privkey, NULL, 0, edkey->propq) == 0) {
224*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
225*b077aed3SPierre Pronchery return 0;
226*b077aed3SPierre Pronchery }
227*b077aed3SPierre Pronchery *siglen = ED448_SIGSIZE;
228*b077aed3SPierre Pronchery return 1;
229*b077aed3SPierre Pronchery }
230*b077aed3SPierre Pronchery
ed25519_digest_verify(void * vpeddsactx,const unsigned char * sig,size_t siglen,const unsigned char * tbs,size_t tbslen)231*b077aed3SPierre Pronchery int ed25519_digest_verify(void *vpeddsactx, const unsigned char *sig,
232*b077aed3SPierre Pronchery size_t siglen, const unsigned char *tbs,
233*b077aed3SPierre Pronchery size_t tbslen)
234*b077aed3SPierre Pronchery {
235*b077aed3SPierre Pronchery PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
236*b077aed3SPierre Pronchery const ECX_KEY *edkey = peddsactx->key;
237*b077aed3SPierre Pronchery
238*b077aed3SPierre Pronchery if (!ossl_prov_is_running() || siglen != ED25519_SIGSIZE)
239*b077aed3SPierre Pronchery return 0;
240*b077aed3SPierre Pronchery
241*b077aed3SPierre Pronchery #ifdef S390X_EC_ASM
242*b077aed3SPierre Pronchery if (S390X_CAN_SIGN(ED25519))
243*b077aed3SPierre Pronchery return s390x_ed25519_digestverify(edkey, sig, tbs, tbslen);
244*b077aed3SPierre Pronchery #endif /* S390X_EC_ASM */
245*b077aed3SPierre Pronchery
246*b077aed3SPierre Pronchery return ossl_ed25519_verify(tbs, tbslen, sig, edkey->pubkey,
247*b077aed3SPierre Pronchery peddsactx->libctx, edkey->propq);
248*b077aed3SPierre Pronchery }
249*b077aed3SPierre Pronchery
ed448_digest_verify(void * vpeddsactx,const unsigned char * sig,size_t siglen,const unsigned char * tbs,size_t tbslen)250*b077aed3SPierre Pronchery int ed448_digest_verify(void *vpeddsactx, const unsigned char *sig,
251*b077aed3SPierre Pronchery size_t siglen, const unsigned char *tbs,
252*b077aed3SPierre Pronchery size_t tbslen)
253*b077aed3SPierre Pronchery {
254*b077aed3SPierre Pronchery PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
255*b077aed3SPierre Pronchery const ECX_KEY *edkey = peddsactx->key;
256*b077aed3SPierre Pronchery
257*b077aed3SPierre Pronchery if (!ossl_prov_is_running() || siglen != ED448_SIGSIZE)
258*b077aed3SPierre Pronchery return 0;
259*b077aed3SPierre Pronchery
260*b077aed3SPierre Pronchery #ifdef S390X_EC_ASM
261*b077aed3SPierre Pronchery if (S390X_CAN_SIGN(ED448))
262*b077aed3SPierre Pronchery return s390x_ed448_digestverify(edkey, sig, tbs, tbslen);
263*b077aed3SPierre Pronchery #endif /* S390X_EC_ASM */
264*b077aed3SPierre Pronchery
265*b077aed3SPierre Pronchery return ossl_ed448_verify(peddsactx->libctx, tbs, tbslen, sig, edkey->pubkey,
266*b077aed3SPierre Pronchery NULL, 0, edkey->propq);
267*b077aed3SPierre Pronchery }
268*b077aed3SPierre Pronchery
eddsa_freectx(void * vpeddsactx)269*b077aed3SPierre Pronchery static void eddsa_freectx(void *vpeddsactx)
270*b077aed3SPierre Pronchery {
271*b077aed3SPierre Pronchery PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
272*b077aed3SPierre Pronchery
273*b077aed3SPierre Pronchery ossl_ecx_key_free(peddsactx->key);
274*b077aed3SPierre Pronchery
275*b077aed3SPierre Pronchery OPENSSL_free(peddsactx);
276*b077aed3SPierre Pronchery }
277*b077aed3SPierre Pronchery
eddsa_dupctx(void * vpeddsactx)278*b077aed3SPierre Pronchery static void *eddsa_dupctx(void *vpeddsactx)
279*b077aed3SPierre Pronchery {
280*b077aed3SPierre Pronchery PROV_EDDSA_CTX *srcctx = (PROV_EDDSA_CTX *)vpeddsactx;
281*b077aed3SPierre Pronchery PROV_EDDSA_CTX *dstctx;
282*b077aed3SPierre Pronchery
283*b077aed3SPierre Pronchery if (!ossl_prov_is_running())
284*b077aed3SPierre Pronchery return NULL;
285*b077aed3SPierre Pronchery
286*b077aed3SPierre Pronchery dstctx = OPENSSL_zalloc(sizeof(*srcctx));
287*b077aed3SPierre Pronchery if (dstctx == NULL)
288*b077aed3SPierre Pronchery return NULL;
289*b077aed3SPierre Pronchery
290*b077aed3SPierre Pronchery *dstctx = *srcctx;
291*b077aed3SPierre Pronchery dstctx->key = NULL;
292*b077aed3SPierre Pronchery
293*b077aed3SPierre Pronchery if (srcctx->key != NULL && !ossl_ecx_key_up_ref(srcctx->key)) {
294*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
295*b077aed3SPierre Pronchery goto err;
296*b077aed3SPierre Pronchery }
297*b077aed3SPierre Pronchery dstctx->key = srcctx->key;
298*b077aed3SPierre Pronchery
299*b077aed3SPierre Pronchery return dstctx;
300*b077aed3SPierre Pronchery err:
301*b077aed3SPierre Pronchery eddsa_freectx(dstctx);
302*b077aed3SPierre Pronchery return NULL;
303*b077aed3SPierre Pronchery }
304*b077aed3SPierre Pronchery
eddsa_get_ctx_params(void * vpeddsactx,OSSL_PARAM * params)305*b077aed3SPierre Pronchery static int eddsa_get_ctx_params(void *vpeddsactx, OSSL_PARAM *params)
306*b077aed3SPierre Pronchery {
307*b077aed3SPierre Pronchery PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx;
308*b077aed3SPierre Pronchery OSSL_PARAM *p;
309*b077aed3SPierre Pronchery
310*b077aed3SPierre Pronchery if (peddsactx == NULL)
311*b077aed3SPierre Pronchery return 0;
312*b077aed3SPierre Pronchery
313*b077aed3SPierre Pronchery p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID);
314*b077aed3SPierre Pronchery if (p != NULL && !OSSL_PARAM_set_octet_string(p, peddsactx->aid,
315*b077aed3SPierre Pronchery peddsactx->aid_len))
316*b077aed3SPierre Pronchery return 0;
317*b077aed3SPierre Pronchery
318*b077aed3SPierre Pronchery return 1;
319*b077aed3SPierre Pronchery }
320*b077aed3SPierre Pronchery
321*b077aed3SPierre Pronchery static const OSSL_PARAM known_gettable_ctx_params[] = {
322*b077aed3SPierre Pronchery OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
323*b077aed3SPierre Pronchery OSSL_PARAM_END
324*b077aed3SPierre Pronchery };
325*b077aed3SPierre Pronchery
eddsa_gettable_ctx_params(ossl_unused void * vpeddsactx,ossl_unused void * provctx)326*b077aed3SPierre Pronchery static const OSSL_PARAM *eddsa_gettable_ctx_params(ossl_unused void *vpeddsactx,
327*b077aed3SPierre Pronchery ossl_unused void *provctx)
328*b077aed3SPierre Pronchery {
329*b077aed3SPierre Pronchery return known_gettable_ctx_params;
330*b077aed3SPierre Pronchery }
331*b077aed3SPierre Pronchery
332*b077aed3SPierre Pronchery const OSSL_DISPATCH ossl_ed25519_signature_functions[] = {
333*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx },
334*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
335*b077aed3SPierre Pronchery (void (*)(void))eddsa_digest_signverify_init },
336*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_SIGN,
337*b077aed3SPierre Pronchery (void (*)(void))ed25519_digest_sign },
338*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
339*b077aed3SPierre Pronchery (void (*)(void))eddsa_digest_signverify_init },
340*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY,
341*b077aed3SPierre Pronchery (void (*)(void))ed25519_digest_verify },
342*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx },
343*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx },
344*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))eddsa_get_ctx_params },
345*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
346*b077aed3SPierre Pronchery (void (*)(void))eddsa_gettable_ctx_params },
347*b077aed3SPierre Pronchery { 0, NULL }
348*b077aed3SPierre Pronchery };
349*b077aed3SPierre Pronchery
350*b077aed3SPierre Pronchery const OSSL_DISPATCH ossl_ed448_signature_functions[] = {
351*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx },
352*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
353*b077aed3SPierre Pronchery (void (*)(void))eddsa_digest_signverify_init },
354*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_SIGN,
355*b077aed3SPierre Pronchery (void (*)(void))ed448_digest_sign },
356*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
357*b077aed3SPierre Pronchery (void (*)(void))eddsa_digest_signverify_init },
358*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY,
359*b077aed3SPierre Pronchery (void (*)(void))ed448_digest_verify },
360*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx },
361*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx },
362*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))eddsa_get_ctx_params },
363*b077aed3SPierre Pronchery { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
364*b077aed3SPierre Pronchery (void (*)(void))eddsa_gettable_ctx_params },
365*b077aed3SPierre Pronchery { 0, NULL }
366*b077aed3SPierre Pronchery };
367*b077aed3SPierre Pronchery
368*b077aed3SPierre Pronchery #ifdef S390X_EC_ASM
369*b077aed3SPierre Pronchery
s390x_ed25519_digestsign(const ECX_KEY * edkey,unsigned char * sig,const unsigned char * tbs,size_t tbslen)370*b077aed3SPierre Pronchery static int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig,
371*b077aed3SPierre Pronchery const unsigned char *tbs, size_t tbslen)
372*b077aed3SPierre Pronchery {
373*b077aed3SPierre Pronchery int rc;
374*b077aed3SPierre Pronchery union {
375*b077aed3SPierre Pronchery struct {
376*b077aed3SPierre Pronchery unsigned char sig[64];
377*b077aed3SPierre Pronchery unsigned char priv[32];
378*b077aed3SPierre Pronchery } ed25519;
379*b077aed3SPierre Pronchery unsigned long long buff[512];
380*b077aed3SPierre Pronchery } param;
381*b077aed3SPierre Pronchery
382*b077aed3SPierre Pronchery memset(¶m, 0, sizeof(param));
383*b077aed3SPierre Pronchery memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
384*b077aed3SPierre Pronchery
385*b077aed3SPierre Pronchery rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
386*b077aed3SPierre Pronchery OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
387*b077aed3SPierre Pronchery if (rc != 0)
388*b077aed3SPierre Pronchery return 0;
389*b077aed3SPierre Pronchery
390*b077aed3SPierre Pronchery s390x_flip_endian32(sig, param.ed25519.sig);
391*b077aed3SPierre Pronchery s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
392*b077aed3SPierre Pronchery return 1;
393*b077aed3SPierre Pronchery }
394*b077aed3SPierre Pronchery
s390x_ed448_digestsign(const ECX_KEY * edkey,unsigned char * sig,const unsigned char * tbs,size_t tbslen)395*b077aed3SPierre Pronchery static int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig,
396*b077aed3SPierre Pronchery const unsigned char *tbs, size_t tbslen)
397*b077aed3SPierre Pronchery {
398*b077aed3SPierre Pronchery int rc;
399*b077aed3SPierre Pronchery union {
400*b077aed3SPierre Pronchery struct {
401*b077aed3SPierre Pronchery unsigned char sig[128];
402*b077aed3SPierre Pronchery unsigned char priv[64];
403*b077aed3SPierre Pronchery } ed448;
404*b077aed3SPierre Pronchery unsigned long long buff[512];
405*b077aed3SPierre Pronchery } param;
406*b077aed3SPierre Pronchery
407*b077aed3SPierre Pronchery memset(¶m, 0, sizeof(param));
408*b077aed3SPierre Pronchery memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
409*b077aed3SPierre Pronchery
410*b077aed3SPierre Pronchery rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
411*b077aed3SPierre Pronchery OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
412*b077aed3SPierre Pronchery if (rc != 0)
413*b077aed3SPierre Pronchery return 0;
414*b077aed3SPierre Pronchery
415*b077aed3SPierre Pronchery s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
416*b077aed3SPierre Pronchery s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
417*b077aed3SPierre Pronchery memcpy(sig, param.ed448.sig, 57);
418*b077aed3SPierre Pronchery memcpy(sig + 57, param.ed448.sig + 64, 57);
419*b077aed3SPierre Pronchery return 1;
420*b077aed3SPierre Pronchery }
421*b077aed3SPierre Pronchery
s390x_ed25519_digestverify(const ECX_KEY * edkey,const unsigned char * sig,const unsigned char * tbs,size_t tbslen)422*b077aed3SPierre Pronchery static int s390x_ed25519_digestverify(const ECX_KEY *edkey,
423*b077aed3SPierre Pronchery const unsigned char *sig,
424*b077aed3SPierre Pronchery const unsigned char *tbs, size_t tbslen)
425*b077aed3SPierre Pronchery {
426*b077aed3SPierre Pronchery union {
427*b077aed3SPierre Pronchery struct {
428*b077aed3SPierre Pronchery unsigned char sig[64];
429*b077aed3SPierre Pronchery unsigned char pub[32];
430*b077aed3SPierre Pronchery } ed25519;
431*b077aed3SPierre Pronchery unsigned long long buff[512];
432*b077aed3SPierre Pronchery } param;
433*b077aed3SPierre Pronchery
434*b077aed3SPierre Pronchery memset(¶m, 0, sizeof(param));
435*b077aed3SPierre Pronchery s390x_flip_endian32(param.ed25519.sig, sig);
436*b077aed3SPierre Pronchery s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
437*b077aed3SPierre Pronchery s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
438*b077aed3SPierre Pronchery
439*b077aed3SPierre Pronchery return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
440*b077aed3SPierre Pronchery ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
441*b077aed3SPierre Pronchery }
442*b077aed3SPierre Pronchery
s390x_ed448_digestverify(const ECX_KEY * edkey,const unsigned char * sig,const unsigned char * tbs,size_t tbslen)443*b077aed3SPierre Pronchery static int s390x_ed448_digestverify(const ECX_KEY *edkey,
444*b077aed3SPierre Pronchery const unsigned char *sig,
445*b077aed3SPierre Pronchery const unsigned char *tbs,
446*b077aed3SPierre Pronchery size_t tbslen)
447*b077aed3SPierre Pronchery {
448*b077aed3SPierre Pronchery union {
449*b077aed3SPierre Pronchery struct {
450*b077aed3SPierre Pronchery unsigned char sig[128];
451*b077aed3SPierre Pronchery unsigned char pub[64];
452*b077aed3SPierre Pronchery } ed448;
453*b077aed3SPierre Pronchery unsigned long long buff[512];
454*b077aed3SPierre Pronchery } param;
455*b077aed3SPierre Pronchery
456*b077aed3SPierre Pronchery memset(¶m, 0, sizeof(param));
457*b077aed3SPierre Pronchery memcpy(param.ed448.sig, sig, 57);
458*b077aed3SPierre Pronchery s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
459*b077aed3SPierre Pronchery memcpy(param.ed448.sig + 64, sig + 57, 57);
460*b077aed3SPierre Pronchery s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
461*b077aed3SPierre Pronchery memcpy(param.ed448.pub, edkey->pubkey, 57);
462*b077aed3SPierre Pronchery s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
463*b077aed3SPierre Pronchery
464*b077aed3SPierre Pronchery return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
465*b077aed3SPierre Pronchery ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
466*b077aed3SPierre Pronchery }
467*b077aed3SPierre Pronchery
468*b077aed3SPierre Pronchery #endif /* S390X_EC_ASM */
469