]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
a28d06f3 | 2 | * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. |
91c9e621 | 3 | * |
4a8b0c55 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
62867571 RS |
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 | |
91c9e621 DSH |
8 | */ |
9 | ||
10 | #include <stdio.h> | |
b39fc560 | 11 | #include "internal/cryptlib.h" |
91c9e621 DSH |
12 | #include <openssl/evp.h> |
13 | #include <openssl/objects.h> | |
25f2138b | 14 | #include "crypto/evp.h" |
d8c98d79 | 15 | #include "internal/provider.h" |
d2f53212 | 16 | #include "internal/numbers.h" /* includes SIZE_MAX */ |
706457b7 | 17 | #include "evp_local.h" |
91c9e621 | 18 | |
f844f9eb | 19 | #ifndef FIPS_MODULE |
72df8f88 | 20 | |
f723c98e DSH |
21 | static int update(EVP_MD_CTX *ctx, const void *data, size_t datalen) |
22 | { | |
9311d0c4 | 23 | ERR_raise(ERR_LIB_EVP, EVP_R_ONLY_ONESHOT_SUPPORTED); |
f723c98e DSH |
24 | return 0; |
25 | } | |
26 | ||
eea1e780 MC |
27 | /* |
28 | * If we get the "NULL" md then the name comes back as "UNDEF". We want to use | |
29 | * NULL for this. | |
30 | */ | |
31 | static const char *canon_mdname(const char *mdname) | |
32 | { | |
33 | if (mdname != NULL && strcmp(mdname, "UNDEF") == 0) | |
34 | return NULL; | |
35 | ||
36 | return mdname; | |
37 | } | |
38 | ||
777c47ac | 39 | static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, |
d8c98d79 | 40 | const EVP_MD *type, const char *mdname, |
b4250010 | 41 | OSSL_LIB_CTX *libctx, const char *props, |
4b58d9b4 P |
42 | ENGINE *e, EVP_PKEY *pkey, int ver, |
43 | OSSL_PARAM params[]) | |
0f113f3e | 44 | { |
d8c98d79 | 45 | EVP_PKEY_CTX *locpctx = NULL; |
0e521004 | 46 | EVP_SIGNATURE *signature = NULL; |
f6aa5774 RL |
47 | EVP_KEYMGMT *tmp_keymgmt = NULL; |
48 | const char *supported_sig = NULL; | |
ead0d234 | 49 | char locmdname[80] = ""; /* 80 chars should be enough */ |
d8c98d79 MC |
50 | void *provkey = NULL; |
51 | int ret; | |
52 | ||
7c14d0c1 | 53 | if (ctx->algctx != NULL) { |
15de965f MC |
54 | if (!ossl_assert(ctx->digest != NULL)) { |
55 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); | |
56 | return 0; | |
57 | } | |
58 | if (ctx->digest->freectx != NULL) | |
7c14d0c1 SL |
59 | ctx->digest->freectx(ctx->algctx); |
60 | ctx->algctx = NULL; | |
15de965f MC |
61 | } |
62 | ||
a45694a3 | 63 | if (ctx->pctx == NULL) { |
5b888e93 | 64 | if (e == NULL) |
a45694a3 MC |
65 | ctx->pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, props); |
66 | else | |
67 | ctx->pctx = EVP_PKEY_CTX_new(pkey, e); | |
68 | } | |
0e521004 RL |
69 | if (ctx->pctx == NULL) |
70 | return 0; | |
71 | ||
d8c98d79 MC |
72 | locpctx = ctx->pctx; |
73 | evp_pkey_ctx_free_old_ops(locpctx); | |
d8c98d79 | 74 | |
2c6094ba RL |
75 | if (props == NULL) |
76 | props = locpctx->propquery; | |
77 | ||
0b9dd384 RL |
78 | ERR_set_mark(); |
79 | ||
f21c9c64 | 80 | if (evp_pkey_ctx_is_legacy(locpctx)) |
d8c98d79 MC |
81 | goto legacy; |
82 | ||
3c6ed955 RL |
83 | /* |
84 | * Ensure that the key is provided, either natively, or as a cached export. | |
3c6ed955 | 85 | */ |
f6aa5774 | 86 | tmp_keymgmt = locpctx->keymgmt; |
3c6ed955 RL |
87 | provkey = evp_pkey_export_to_provider(locpctx->pkey, locpctx->libctx, |
88 | &tmp_keymgmt, locpctx->propquery); | |
b8ea8d39 | 89 | if (provkey == NULL) { |
b8ea8d39 MC |
90 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); |
91 | goto err; | |
92 | } | |
f6aa5774 | 93 | if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) { |
0b9dd384 | 94 | ERR_clear_last_mark(); |
f6aa5774 RL |
95 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); |
96 | goto err; | |
d8c98d79 | 97 | } |
f6aa5774 RL |
98 | EVP_KEYMGMT_free(locpctx->keymgmt); |
99 | locpctx->keymgmt = tmp_keymgmt; | |
100 | ||
101 | if (locpctx->keymgmt->query_operation_name != NULL) | |
102 | supported_sig = | |
103 | locpctx->keymgmt->query_operation_name(OSSL_OP_SIGNATURE); | |
104 | ||
105 | /* | |
106 | * If we didn't get a supported sig, assume there is one with the | |
107 | * same name as the key type. | |
108 | */ | |
109 | if (supported_sig == NULL) | |
110 | supported_sig = locpctx->keytype; | |
111 | ||
112 | /* | |
113 | * Because we cleared out old ops, we shouldn't need to worry about | |
114 | * checking if signature is already there. | |
115 | */ | |
116 | signature = EVP_SIGNATURE_fetch(locpctx->libctx, supported_sig, | |
117 | locpctx->propquery); | |
118 | ||
119 | if (signature == NULL | |
ed576acd TM |
120 | || (EVP_KEYMGMT_get0_provider(locpctx->keymgmt) |
121 | != EVP_SIGNATURE_get0_provider(signature))) { | |
0e521004 | 122 | /* |
0b9dd384 RL |
123 | * We don't need to free ctx->keymgmt here, as it's not necessarily |
124 | * tied to this operation. It will be freed by EVP_PKEY_CTX_free(). | |
0e521004 RL |
125 | */ |
126 | EVP_SIGNATURE_free(signature); | |
127 | goto legacy; | |
128 | } | |
129 | ||
0b9dd384 | 130 | /* |
0b9dd384 RL |
131 | * If we don't have the full support we need with provided methods, |
132 | * let's go see if legacy does. | |
133 | */ | |
134 | ERR_pop_to_mark(); | |
135 | ||
0e521004 | 136 | /* No more legacy from here down to legacy: */ |
d8c98d79 | 137 | |
ead0d234 RL |
138 | if (pctx != NULL) |
139 | *pctx = locpctx; | |
140 | ||
d8c98d79 | 141 | locpctx->op.sig.signature = signature; |
0e521004 RL |
142 | locpctx->operation = ver ? EVP_PKEY_OP_VERIFYCTX |
143 | : EVP_PKEY_OP_SIGNCTX; | |
7c14d0c1 | 144 | locpctx->op.sig.algctx |
2c6094ba | 145 | = signature->newctx(ossl_provider_ctx(signature->prov), props); |
7c14d0c1 | 146 | if (locpctx->op.sig.algctx == NULL) { |
d8c98d79 MC |
147 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); |
148 | goto err; | |
149 | } | |
0e521004 | 150 | if (type != NULL) { |
d8c98d79 | 151 | ctx->reqdigest = type; |
ead0d234 | 152 | if (mdname == NULL) |
ed576acd | 153 | mdname = canon_mdname(EVP_MD_get0_name(type)); |
d8c98d79 | 154 | } else { |
4c627d86 RL |
155 | if (mdname == NULL) { |
156 | if (evp_keymgmt_util_get_deflt_digest_name(tmp_keymgmt, provkey, | |
157 | locmdname, | |
158 | sizeof(locmdname)) > 0) { | |
159 | mdname = canon_mdname(locmdname); | |
4c627d86 RL |
160 | } |
161 | } | |
ead0d234 RL |
162 | |
163 | if (mdname != NULL) { | |
3101ab60 MC |
164 | /* |
165 | * We're about to get a new digest so clear anything associated with | |
166 | * an old digest. | |
167 | */ | |
168 | evp_md_ctx_clear_digest(ctx, 1); | |
169 | ||
f80d0d2f DB |
170 | /* legacy code support for engines */ |
171 | ERR_set_mark(); | |
ead0d234 | 172 | /* |
f6c95e46 | 173 | * This might be requested by a later call to EVP_MD_CTX_get0_md(). |
ead0d234 RL |
174 | * In that case the "explicit fetch" rules apply for that |
175 | * function (as per man pages), i.e. the ref count is not updated | |
176 | * so the EVP_MD should not be used beyound the lifetime of the | |
177 | * EVP_MD_CTX. | |
178 | */ | |
f80d0d2f DB |
179 | ctx->fetched_digest = EVP_MD_fetch(locpctx->libctx, mdname, props); |
180 | if (ctx->fetched_digest != NULL) { | |
181 | ctx->digest = ctx->reqdigest = ctx->fetched_digest; | |
182 | } else { | |
183 | /* legacy engine support : remove the mark when this is deleted */ | |
184 | ctx->reqdigest = ctx->digest = EVP_get_digestbyname(mdname); | |
185 | if (ctx->digest == NULL) { | |
186 | (void)ERR_clear_last_mark(); | |
187 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); | |
188 | goto err; | |
189 | } | |
3101ab60 | 190 | } |
f80d0d2f | 191 | (void)ERR_pop_to_mark(); |
ead0d234 | 192 | } |
d8c98d79 MC |
193 | } |
194 | ||
195 | if (ver) { | |
196 | if (signature->digest_verify_init == NULL) { | |
197 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); | |
198 | goto err; | |
199 | } | |
7c14d0c1 | 200 | ret = signature->digest_verify_init(locpctx->op.sig.algctx, |
4b58d9b4 | 201 | mdname, provkey, params); |
d8c98d79 MC |
202 | } else { |
203 | if (signature->digest_sign_init == NULL) { | |
204 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); | |
205 | goto err; | |
206 | } | |
7c14d0c1 | 207 | ret = signature->digest_sign_init(locpctx->op.sig.algctx, |
4b58d9b4 | 208 | mdname, provkey, params); |
d8c98d79 MC |
209 | } |
210 | ||
86df26b3 RL |
211 | goto end; |
212 | ||
d8c98d79 MC |
213 | err: |
214 | evp_pkey_ctx_free_old_ops(locpctx); | |
215 | locpctx->operation = EVP_PKEY_OP_UNDEFINED; | |
216 | return 0; | |
e69adea5 | 217 | |
d8c98d79 | 218 | legacy: |
0b9dd384 | 219 | /* |
0b9dd384 RL |
220 | * If we don't have the full support we need with provided methods, |
221 | * let's go see if legacy does. | |
222 | */ | |
223 | ERR_pop_to_mark(); | |
224 | ||
55ca8125 MC |
225 | if (type == NULL && mdname != NULL) |
226 | type = evp_get_digestbyname_ex(locpctx->libctx, mdname); | |
227 | ||
e0d8523e | 228 | if (ctx->pctx->pmeth == NULL) { |
9311d0c4 | 229 | ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
76123661 | 230 | return 0; |
e0d8523e RL |
231 | } |
232 | ||
0f113f3e | 233 | if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) { |
e69adea5 | 234 | |
0f113f3e MC |
235 | if (type == NULL) { |
236 | int def_nid; | |
237 | if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0) | |
238 | type = EVP_get_digestbynid(def_nid); | |
239 | } | |
c8ef656d | 240 | |
0f113f3e | 241 | if (type == NULL) { |
9311d0c4 | 242 | ERR_raise(ERR_LIB_EVP, EVP_R_NO_DEFAULT_DIGEST); |
0f113f3e MC |
243 | return 0; |
244 | } | |
245 | } | |
e69adea5 | 246 | |
0f113f3e MC |
247 | if (ver) { |
248 | if (ctx->pctx->pmeth->verifyctx_init) { | |
249 | if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <= 0) | |
250 | return 0; | |
251 | ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX; | |
f723c98e DSH |
252 | } else if (ctx->pctx->pmeth->digestverify != 0) { |
253 | ctx->pctx->operation = EVP_PKEY_OP_VERIFY; | |
254 | ctx->update = update; | |
255 | } else if (EVP_PKEY_verify_init(ctx->pctx) <= 0) { | |
0f113f3e | 256 | return 0; |
f723c98e | 257 | } |
0f113f3e MC |
258 | } else { |
259 | if (ctx->pctx->pmeth->signctx_init) { | |
260 | if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0) | |
261 | return 0; | |
262 | ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX; | |
f723c98e DSH |
263 | } else if (ctx->pctx->pmeth->digestsign != 0) { |
264 | ctx->pctx->operation = EVP_PKEY_OP_SIGN; | |
265 | ctx->update = update; | |
266 | } else if (EVP_PKEY_sign_init(ctx->pctx) <= 0) { | |
0f113f3e | 267 | return 0; |
f723c98e | 268 | } |
0f113f3e MC |
269 | } |
270 | if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0) | |
271 | return 0; | |
272 | if (pctx) | |
273 | *pctx = ctx->pctx; | |
274 | if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) | |
275 | return 1; | |
276 | if (!EVP_DigestInit_ex(ctx, type, e)) | |
277 | return 0; | |
4803717f PY |
278 | /* |
279 | * This indicates the current algorithm requires | |
280 | * special treatment before hashing the tbs-message. | |
281 | */ | |
a5ce329e | 282 | ctx->pctx->flag_call_digest_custom = 0; |
675f4cee | 283 | if (ctx->pctx->pmeth->digest_custom != NULL) |
a5ce329e | 284 | ctx->pctx->flag_call_digest_custom = 1; |
4803717f | 285 | |
86df26b3 RL |
286 | ret = 1; |
287 | ||
288 | end: | |
289 | #ifndef FIPS_MODULE | |
290 | if (ret > 0) | |
291 | ret = evp_pkey_ctx_use_cached_data(locpctx); | |
292 | #endif | |
293 | ||
294 | return ret > 0 ? 1 : 0; | |
0f113f3e | 295 | } |
91c9e621 | 296 | |
d8652be0 | 297 | int EVP_DigestSignInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, |
b4250010 | 298 | const char *mdname, OSSL_LIB_CTX *libctx, |
4b58d9b4 P |
299 | const char *props, EVP_PKEY *pkey, |
300 | OSSL_PARAM params[]) | |
d8c98d79 | 301 | { |
4b58d9b4 P |
302 | return do_sigver_init(ctx, pctx, NULL, mdname, libctx, props, NULL, pkey, 0, |
303 | params); | |
d8c98d79 MC |
304 | } |
305 | ||
91c9e621 | 306 | int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, |
0f113f3e MC |
307 | const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) |
308 | { | |
4b58d9b4 P |
309 | return do_sigver_init(ctx, pctx, type, NULL, NULL, NULL, e, pkey, 0, |
310 | NULL); | |
d8c98d79 MC |
311 | } |
312 | ||
d8652be0 | 313 | int EVP_DigestVerifyInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, |
b4250010 | 314 | const char *mdname, OSSL_LIB_CTX *libctx, |
4b58d9b4 P |
315 | const char *props, EVP_PKEY *pkey, |
316 | OSSL_PARAM params[]) | |
d8c98d79 | 317 | { |
4b58d9b4 P |
318 | return do_sigver_init(ctx, pctx, NULL, mdname, libctx, props, NULL, pkey, 1, |
319 | params); | |
0f113f3e | 320 | } |
91c9e621 DSH |
321 | |
322 | int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, | |
0f113f3e MC |
323 | const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) |
324 | { | |
4b58d9b4 P |
325 | return do_sigver_init(ctx, pctx, type, NULL, NULL, NULL, e, pkey, 1, |
326 | NULL); | |
d8c98d79 | 327 | } |
72df8f88 | 328 | #endif /* FIPS_MDOE */ |
d8c98d79 MC |
329 | |
330 | int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize) | |
331 | { | |
332 | EVP_PKEY_CTX *pctx = ctx->pctx; | |
333 | ||
334 | if (pctx == NULL | |
335 | || pctx->operation != EVP_PKEY_OP_SIGNCTX | |
7c14d0c1 | 336 | || pctx->op.sig.algctx == NULL |
d8c98d79 MC |
337 | || pctx->op.sig.signature == NULL) |
338 | goto legacy; | |
339 | ||
eea1e780 MC |
340 | if (pctx->op.sig.signature->digest_sign_update == NULL) { |
341 | ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | |
342 | return 0; | |
343 | } | |
344 | ||
7c14d0c1 | 345 | return pctx->op.sig.signature->digest_sign_update(pctx->op.sig.algctx, |
d8c98d79 MC |
346 | data, dsize); |
347 | ||
348 | legacy: | |
72133070 P |
349 | if (pctx != NULL) { |
350 | /* do_sigver_init() checked that |digest_custom| is non-NULL */ | |
351 | if (pctx->flag_call_digest_custom | |
352 | && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx)) | |
353 | return 0; | |
354 | pctx->flag_call_digest_custom = 0; | |
355 | } | |
a5ce329e | 356 | |
d8c98d79 | 357 | return EVP_DigestUpdate(ctx, data, dsize); |
0f113f3e | 358 | } |
91c9e621 | 359 | |
d8c98d79 MC |
360 | int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize) |
361 | { | |
362 | EVP_PKEY_CTX *pctx = ctx->pctx; | |
363 | ||
364 | if (pctx == NULL | |
365 | || pctx->operation != EVP_PKEY_OP_VERIFYCTX | |
7c14d0c1 | 366 | || pctx->op.sig.algctx == NULL |
d8c98d79 MC |
367 | || pctx->op.sig.signature == NULL) |
368 | goto legacy; | |
369 | ||
eea1e780 MC |
370 | if (pctx->op.sig.signature->digest_verify_update == NULL) { |
371 | ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | |
372 | return 0; | |
373 | } | |
374 | ||
7c14d0c1 | 375 | return pctx->op.sig.signature->digest_verify_update(pctx->op.sig.algctx, |
d8c98d79 MC |
376 | data, dsize); |
377 | ||
378 | legacy: | |
089c2928 P |
379 | if (pctx != NULL) { |
380 | /* do_sigver_init() checked that |digest_custom| is non-NULL */ | |
381 | if (pctx->flag_call_digest_custom | |
382 | && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx)) | |
383 | return 0; | |
384 | pctx->flag_call_digest_custom = 0; | |
385 | } | |
a5ce329e | 386 | |
d8c98d79 MC |
387 | return EVP_DigestUpdate(ctx, data, dsize); |
388 | } | |
389 | ||
f844f9eb | 390 | #ifndef FIPS_MODULE |
0f113f3e MC |
391 | int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, |
392 | size_t *siglen) | |
393 | { | |
4c9b0a03 | 394 | int sctx = 0, r = 0; |
0f113f3e | 395 | EVP_PKEY_CTX *pctx = ctx->pctx; |
d8c98d79 MC |
396 | |
397 | if (pctx == NULL | |
398 | || pctx->operation != EVP_PKEY_OP_SIGNCTX | |
7c14d0c1 | 399 | || pctx->op.sig.algctx == NULL |
d8c98d79 MC |
400 | || pctx->op.sig.signature == NULL) |
401 | goto legacy; | |
402 | ||
7c14d0c1 | 403 | return pctx->op.sig.signature->digest_sign_final(pctx->op.sig.algctx, |
d8c98d79 MC |
404 | sigret, siglen, SIZE_MAX); |
405 | ||
406 | legacy: | |
8f020c3d RL |
407 | if (pctx == NULL || pctx->pmeth == NULL) { |
408 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); | |
409 | return 0; | |
410 | } | |
411 | ||
a5ce329e RL |
412 | /* do_sigver_init() checked that |digest_custom| is non-NULL */ |
413 | if (pctx->flag_call_digest_custom | |
414 | && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx)) | |
415 | return 0; | |
416 | pctx->flag_call_digest_custom = 0; | |
417 | ||
0f113f3e | 418 | if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) { |
8f020c3d | 419 | if (sigret == NULL) |
0f113f3e MC |
420 | return pctx->pmeth->signctx(pctx, sigret, siglen, ctx); |
421 | if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) | |
422 | r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx); | |
423 | else { | |
8f020c3d RL |
424 | EVP_PKEY_CTX *dctx = EVP_PKEY_CTX_dup(pctx); |
425 | ||
426 | if (dctx == NULL) | |
0f113f3e MC |
427 | return 0; |
428 | r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx); | |
429 | EVP_PKEY_CTX_free(dctx); | |
430 | } | |
431 | return r; | |
432 | } | |
8f020c3d | 433 | if (pctx->pmeth->signctx != NULL) |
0f113f3e MC |
434 | sctx = 1; |
435 | else | |
436 | sctx = 0; | |
8f020c3d | 437 | if (sigret != NULL) { |
0f113f3e | 438 | unsigned char md[EVP_MAX_MD_SIZE]; |
4c9b0a03 | 439 | unsigned int mdlen = 0; |
8f020c3d | 440 | |
0f113f3e MC |
441 | if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) { |
442 | if (sctx) | |
8f020c3d | 443 | r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx); |
0f113f3e MC |
444 | else |
445 | r = EVP_DigestFinal_ex(ctx, md, &mdlen); | |
446 | } else { | |
bfb0641f | 447 | EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new(); |
8f020c3d | 448 | |
19546246 | 449 | if (tmp_ctx == NULL) |
0f113f3e | 450 | return 0; |
19546246 BE |
451 | if (!EVP_MD_CTX_copy_ex(tmp_ctx, ctx)) { |
452 | EVP_MD_CTX_free(tmp_ctx); | |
453 | return 0; | |
454 | } | |
0f113f3e | 455 | if (sctx) |
77a01145 RL |
456 | r = tmp_ctx->pctx->pmeth->signctx(tmp_ctx->pctx, |
457 | sigret, siglen, tmp_ctx); | |
0f113f3e | 458 | else |
77a01145 | 459 | r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen); |
bfb0641f | 460 | EVP_MD_CTX_free(tmp_ctx); |
0f113f3e MC |
461 | } |
462 | if (sctx || !r) | |
463 | return r; | |
8f020c3d | 464 | if (EVP_PKEY_sign(pctx, sigret, siglen, md, mdlen) <= 0) |
0f113f3e MC |
465 | return 0; |
466 | } else { | |
467 | if (sctx) { | |
468 | if (pctx->pmeth->signctx(pctx, sigret, siglen, ctx) <= 0) | |
469 | return 0; | |
470 | } else { | |
ed576acd | 471 | int s = EVP_MD_get_size(ctx->digest); |
8f020c3d | 472 | |
0f113f3e MC |
473 | if (s < 0 || EVP_PKEY_sign(pctx, sigret, siglen, NULL, s) <= 0) |
474 | return 0; | |
475 | } | |
476 | } | |
477 | return 1; | |
478 | } | |
91c9e621 | 479 | |
75394189 DSH |
480 | int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen, |
481 | const unsigned char *tbs, size_t tbslen) | |
482 | { | |
eea1e780 MC |
483 | EVP_PKEY_CTX *pctx = ctx->pctx; |
484 | ||
485 | if (pctx != NULL | |
486 | && pctx->operation == EVP_PKEY_OP_SIGNCTX | |
7c14d0c1 | 487 | && pctx->op.sig.algctx != NULL |
eea1e780 MC |
488 | && pctx->op.sig.signature != NULL) { |
489 | if (pctx->op.sig.signature->digest_sign != NULL) | |
7c14d0c1 | 490 | return pctx->op.sig.signature->digest_sign(pctx->op.sig.algctx, |
eea1e780 MC |
491 | sigret, siglen, SIZE_MAX, |
492 | tbs, tbslen); | |
493 | } else { | |
494 | /* legacy */ | |
495 | if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestsign != NULL) | |
496 | return ctx->pctx->pmeth->digestsign(ctx, sigret, siglen, tbs, tbslen); | |
497 | } | |
498 | ||
75394189 DSH |
499 | if (sigret != NULL && EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0) |
500 | return 0; | |
501 | return EVP_DigestSignFinal(ctx, sigret, siglen); | |
502 | } | |
503 | ||
0f7fa1b1 | 504 | int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, |
0f113f3e MC |
505 | size_t siglen) |
506 | { | |
507 | unsigned char md[EVP_MAX_MD_SIZE]; | |
4c9b0a03 GK |
508 | int r = 0; |
509 | unsigned int mdlen = 0; | |
510 | int vctx = 0; | |
d8c98d79 MC |
511 | EVP_PKEY_CTX *pctx = ctx->pctx; |
512 | ||
513 | if (pctx == NULL | |
514 | || pctx->operation != EVP_PKEY_OP_VERIFYCTX | |
7c14d0c1 | 515 | || pctx->op.sig.algctx == NULL |
d8c98d79 MC |
516 | || pctx->op.sig.signature == NULL) |
517 | goto legacy; | |
518 | ||
7c14d0c1 | 519 | return pctx->op.sig.signature->digest_verify_final(pctx->op.sig.algctx, |
d8c98d79 | 520 | sig, siglen); |
0eab41fb | 521 | |
d8c98d79 | 522 | legacy: |
8f020c3d RL |
523 | if (pctx == NULL || pctx->pmeth == NULL) { |
524 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); | |
525 | return 0; | |
526 | } | |
527 | ||
a5ce329e RL |
528 | /* do_sigver_init() checked that |digest_custom| is non-NULL */ |
529 | if (pctx->flag_call_digest_custom | |
530 | && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx)) | |
531 | return 0; | |
532 | pctx->flag_call_digest_custom = 0; | |
533 | ||
8f020c3d | 534 | if (pctx->pmeth->verifyctx != NULL) |
0f113f3e MC |
535 | vctx = 1; |
536 | else | |
537 | vctx = 0; | |
538 | if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) { | |
4803717f | 539 | if (vctx) |
8f020c3d | 540 | r = pctx->pmeth->verifyctx(pctx, sig, siglen, ctx); |
4803717f | 541 | else |
0f113f3e MC |
542 | r = EVP_DigestFinal_ex(ctx, md, &mdlen); |
543 | } else { | |
bfb0641f | 544 | EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new(); |
19546246 BE |
545 | if (tmp_ctx == NULL) |
546 | return -1; | |
547 | if (!EVP_MD_CTX_copy_ex(tmp_ctx, ctx)) { | |
548 | EVP_MD_CTX_free(tmp_ctx); | |
0f113f3e | 549 | return -1; |
19546246 | 550 | } |
4803717f | 551 | if (vctx) |
77a01145 RL |
552 | r = tmp_ctx->pctx->pmeth->verifyctx(tmp_ctx->pctx, |
553 | sig, siglen, tmp_ctx); | |
4803717f | 554 | else |
77a01145 | 555 | r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen); |
bfb0641f | 556 | EVP_MD_CTX_free(tmp_ctx); |
0f113f3e MC |
557 | } |
558 | if (vctx || !r) | |
559 | return r; | |
8f020c3d | 560 | return EVP_PKEY_verify(pctx, sig, siglen, md, mdlen); |
0f113f3e | 561 | } |
75394189 DSH |
562 | |
563 | int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, | |
564 | size_t siglen, const unsigned char *tbs, size_t tbslen) | |
565 | { | |
eea1e780 MC |
566 | EVP_PKEY_CTX *pctx = ctx->pctx; |
567 | ||
568 | if (pctx != NULL | |
569 | && pctx->operation == EVP_PKEY_OP_VERIFYCTX | |
7c14d0c1 | 570 | && pctx->op.sig.algctx != NULL |
eea1e780 MC |
571 | && pctx->op.sig.signature != NULL) { |
572 | if (pctx->op.sig.signature->digest_verify != NULL) | |
7c14d0c1 | 573 | return pctx->op.sig.signature->digest_verify(pctx->op.sig.algctx, |
eea1e780 MC |
574 | sigret, siglen, |
575 | tbs, tbslen); | |
576 | } else { | |
577 | /* legacy */ | |
578 | if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestverify != NULL) | |
579 | return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen, tbs, tbslen); | |
580 | } | |
581 | ||
75394189 DSH |
582 | if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0) |
583 | return -1; | |
584 | return EVP_DigestVerifyFinal(ctx, sigret, siglen); | |
585 | } | |
f844f9eb | 586 | #endif /* FIPS_MODULE */ |