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