2 * Copyright 2020 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/err.h>
17 #include "internal/nelem.h"
18 #include "internal/sizes.h"
19 #include "prov/providercommon.h"
20 #include "prov/implementations.h"
21 #include "prov/providercommonerr.h"
22 #include "prov/provider_ctx.h"
23 #include "prov/der_ecx.h"
24 #include "crypto/ecx.h"
26 static OSSL_FUNC_signature_newctx_fn eddsa_newctx
;
27 static OSSL_FUNC_signature_digest_sign_init_fn eddsa_digest_signverify_init
;
28 static OSSL_FUNC_signature_digest_sign_fn ed25519_digest_sign
;
29 static OSSL_FUNC_signature_digest_sign_fn ed448_digest_sign
;
30 static OSSL_FUNC_signature_digest_verify_fn ed25519_digest_verify
;
31 static OSSL_FUNC_signature_digest_verify_fn ed448_digest_verify
;
32 static OSSL_FUNC_signature_freectx_fn eddsa_freectx
;
33 static OSSL_FUNC_signature_dupctx_fn eddsa_dupctx
;
34 static OSSL_FUNC_signature_get_ctx_params_fn eddsa_get_ctx_params
;
35 static OSSL_FUNC_signature_gettable_ctx_params_fn eddsa_gettable_ctx_params
;
41 /* The Algorithm Identifier of the signature algorithm */
42 unsigned char aid_buf
[OSSL_MAX_ALGORITHM_ID_SIZE
];
47 static void *eddsa_newctx(void *provctx
, const char *propq_unused
)
49 PROV_EDDSA_CTX
*peddsactx
;
51 if (!ossl_prov_is_running())
54 peddsactx
= OPENSSL_zalloc(sizeof(PROV_EDDSA_CTX
));
55 if (peddsactx
== NULL
) {
56 PROVerr(0, ERR_R_MALLOC_FAILURE
);
60 peddsactx
->libctx
= PROV_LIBRARY_CONTEXT_OF(provctx
);
65 static int eddsa_digest_signverify_init(void *vpeddsactx
, const char *mdname
,
68 PROV_EDDSA_CTX
*peddsactx
= (PROV_EDDSA_CTX
*)vpeddsactx
;
69 ECX_KEY
*edkey
= (ECX_KEY
*)vedkey
;
73 if (!ossl_prov_is_running())
76 if (mdname
!= NULL
&& mdname
[0] != '\0') {
77 PROVerr(0, PROV_R_INVALID_DIGEST
);
81 if (!ecx_key_up_ref(edkey
)) {
82 PROVerr(0, ERR_R_INTERNAL_ERROR
);
87 * TODO(3.0) Should we care about DER writing errors?
88 * All it really means is that for some reason, there's no
89 * AlgorithmIdentifier to be had, but the operation itself is
90 * still valid, just as long as it's not used to construct
91 * anything that needs an AlgorithmIdentifier.
93 peddsactx
->aid_len
= 0;
94 ret
= WPACKET_init_der(&pkt
, peddsactx
->aid_buf
, sizeof(peddsactx
->aid_buf
));
95 switch (edkey
->type
) {
96 case ECX_KEY_TYPE_ED25519
:
97 ret
= ret
&& DER_w_algorithmIdentifier_ED25519(&pkt
, -1, edkey
);
99 case ECX_KEY_TYPE_ED448
:
100 ret
= ret
&& DER_w_algorithmIdentifier_ED448(&pkt
, -1, edkey
);
103 /* Should never happen */
104 PROVerr(0, ERR_R_INTERNAL_ERROR
);
107 if (ret
&& WPACKET_finish(&pkt
)) {
108 WPACKET_get_total_written(&pkt
, &peddsactx
->aid_len
);
109 peddsactx
->aid
= WPACKET_get_curr(&pkt
);
111 WPACKET_cleanup(&pkt
);
113 peddsactx
->key
= edkey
;
118 int ed25519_digest_sign(void *vpeddsactx
, unsigned char *sigret
,
119 size_t *siglen
, size_t sigsize
,
120 const unsigned char *tbs
, size_t tbslen
)
122 PROV_EDDSA_CTX
*peddsactx
= (PROV_EDDSA_CTX
*)vpeddsactx
;
123 const ECX_KEY
*edkey
= peddsactx
->key
;
125 if (!ossl_prov_is_running())
128 if (sigret
== NULL
) {
129 *siglen
= ED25519_SIGSIZE
;
132 if (sigsize
< ED25519_SIGSIZE
) {
133 PROVerr(0, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
137 if (ED25519_sign(sigret
, tbs
, tbslen
, edkey
->pubkey
, edkey
->privkey
,
138 peddsactx
->libctx
, NULL
) == 0) {
139 PROVerr(0, PROV_R_FAILED_TO_SIGN
);
142 *siglen
= ED25519_SIGSIZE
;
146 int ed448_digest_sign(void *vpeddsactx
, unsigned char *sigret
,
147 size_t *siglen
, size_t sigsize
,
148 const unsigned char *tbs
, size_t tbslen
)
150 PROV_EDDSA_CTX
*peddsactx
= (PROV_EDDSA_CTX
*)vpeddsactx
;
151 const ECX_KEY
*edkey
= peddsactx
->key
;
153 if (!ossl_prov_is_running())
156 if (sigret
== NULL
) {
157 *siglen
= ED448_SIGSIZE
;
160 if (sigsize
< ED448_SIGSIZE
) {
161 PROVerr(0, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
165 if (ED448_sign(peddsactx
->libctx
, sigret
, tbs
, tbslen
, edkey
->pubkey
,
166 edkey
->privkey
, NULL
, 0) == 0) {
167 PROVerr(0, PROV_R_FAILED_TO_SIGN
);
170 *siglen
= ED448_SIGSIZE
;
174 int ed25519_digest_verify(void *vpeddsactx
, const unsigned char *sig
,
175 size_t siglen
, const unsigned char *tbs
,
178 PROV_EDDSA_CTX
*peddsactx
= (PROV_EDDSA_CTX
*)vpeddsactx
;
179 const ECX_KEY
*edkey
= peddsactx
->key
;
181 if (!ossl_prov_is_running() || siglen
!= ED25519_SIGSIZE
)
184 return ED25519_verify(tbs
, tbslen
, sig
, edkey
->pubkey
, peddsactx
->libctx
,
188 int ed448_digest_verify(void *vpeddsactx
, const unsigned char *sig
,
189 size_t siglen
, const unsigned char *tbs
,
192 PROV_EDDSA_CTX
*peddsactx
= (PROV_EDDSA_CTX
*)vpeddsactx
;
193 const ECX_KEY
*edkey
= peddsactx
->key
;
195 if (!ossl_prov_is_running() || siglen
!= ED448_SIGSIZE
)
198 return ED448_verify(peddsactx
->libctx
, tbs
, tbslen
, sig
, edkey
->pubkey
,
202 static void eddsa_freectx(void *vpeddsactx
)
204 PROV_EDDSA_CTX
*peddsactx
= (PROV_EDDSA_CTX
*)vpeddsactx
;
206 ecx_key_free(peddsactx
->key
);
208 OPENSSL_free(peddsactx
);
211 static void *eddsa_dupctx(void *vpeddsactx
)
213 PROV_EDDSA_CTX
*srcctx
= (PROV_EDDSA_CTX
*)vpeddsactx
;
214 PROV_EDDSA_CTX
*dstctx
;
216 if (!ossl_prov_is_running())
219 dstctx
= OPENSSL_zalloc(sizeof(*srcctx
));
226 if (srcctx
->key
!= NULL
&& !ecx_key_up_ref(srcctx
->key
)) {
227 PROVerr(0, ERR_R_INTERNAL_ERROR
);
230 dstctx
->key
= srcctx
->key
;
234 eddsa_freectx(dstctx
);
238 static int eddsa_get_ctx_params(void *vpeddsactx
, OSSL_PARAM
*params
)
240 PROV_EDDSA_CTX
*peddsactx
= (PROV_EDDSA_CTX
*)vpeddsactx
;
243 if (peddsactx
== NULL
|| params
== NULL
)
246 p
= OSSL_PARAM_locate(params
, OSSL_SIGNATURE_PARAM_ALGORITHM_ID
);
247 if (p
!= NULL
&& !OSSL_PARAM_set_octet_string(p
, peddsactx
->aid
,
254 static const OSSL_PARAM known_gettable_ctx_params
[] = {
255 OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID
, NULL
, 0),
259 static const OSSL_PARAM
*eddsa_gettable_ctx_params(ossl_unused
void *provctx
)
261 return known_gettable_ctx_params
;
264 const OSSL_DISPATCH ed25519_signature_functions
[] = {
265 { OSSL_FUNC_SIGNATURE_NEWCTX
, (void (*)(void))eddsa_newctx
},
266 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT
,
267 (void (*)(void))eddsa_digest_signverify_init
},
268 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN
,
269 (void (*)(void))ed25519_digest_sign
},
270 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT
,
271 (void (*)(void))eddsa_digest_signverify_init
},
272 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY
,
273 (void (*)(void))ed25519_digest_verify
},
274 { OSSL_FUNC_SIGNATURE_FREECTX
, (void (*)(void))eddsa_freectx
},
275 { OSSL_FUNC_SIGNATURE_DUPCTX
, (void (*)(void))eddsa_dupctx
},
276 { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS
, (void (*)(void))eddsa_get_ctx_params
},
277 { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS
,
278 (void (*)(void))eddsa_gettable_ctx_params
},
282 const OSSL_DISPATCH ed448_signature_functions
[] = {
283 { OSSL_FUNC_SIGNATURE_NEWCTX
, (void (*)(void))eddsa_newctx
},
284 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT
,
285 (void (*)(void))eddsa_digest_signverify_init
},
286 { OSSL_FUNC_SIGNATURE_DIGEST_SIGN
,
287 (void (*)(void))ed448_digest_sign
},
288 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT
,
289 (void (*)(void))eddsa_digest_signverify_init
},
290 { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY
,
291 (void (*)(void))ed448_digest_verify
},
292 { OSSL_FUNC_SIGNATURE_FREECTX
, (void (*)(void))eddsa_freectx
},
293 { OSSL_FUNC_SIGNATURE_DUPCTX
, (void (*)(void))eddsa_dupctx
},
294 { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS
, (void (*)(void))eddsa_get_ctx_params
},
295 { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS
,
296 (void (*)(void))eddsa_gettable_ctx_params
},