]>
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, |
0ab18e79 SL |
41 | OPENSSL_CTX *libctx, const char *props, |
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 | ||
df13defd | 83 | if (locpctx->engine != NULL || locpctx->keytype == NULL) |
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); | |
175 | } else { | |
176 | EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST); | |
177 | return 0; | |
178 | } | |
179 | } | |
ead0d234 RL |
180 | |
181 | if (mdname != NULL) { | |
182 | /* | |
183 | * This might be requested by a later call to EVP_MD_CTX_md(). | |
184 | * In that case the "explicit fetch" rules apply for that | |
185 | * function (as per man pages), i.e. the ref count is not updated | |
186 | * so the EVP_MD should not be used beyound the lifetime of the | |
187 | * EVP_MD_CTX. | |
188 | */ | |
ada0670b | 189 | ctx->digest = ctx->reqdigest = ctx->fetched_digest = |
ead0d234 RL |
190 | EVP_MD_fetch(locpctx->libctx, mdname, props); |
191 | } | |
d8c98d79 MC |
192 | } |
193 | ||
194 | if (ver) { | |
195 | if (signature->digest_verify_init == NULL) { | |
196 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); | |
197 | goto err; | |
198 | } | |
0e521004 | 199 | ret = signature->digest_verify_init(locpctx->op.sig.sigprovctx, |
2c6094ba | 200 | mdname, provkey); |
d8c98d79 MC |
201 | } else { |
202 | if (signature->digest_sign_init == NULL) { | |
203 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); | |
204 | goto err; | |
205 | } | |
0e521004 | 206 | ret = signature->digest_sign_init(locpctx->op.sig.sigprovctx, |
2c6094ba | 207 | mdname, provkey); |
d8c98d79 MC |
208 | } |
209 | ||
210 | return ret ? 1 : 0; | |
211 | err: | |
212 | evp_pkey_ctx_free_old_ops(locpctx); | |
213 | locpctx->operation = EVP_PKEY_OP_UNDEFINED; | |
214 | return 0; | |
e69adea5 | 215 | |
d8c98d79 | 216 | legacy: |
0b9dd384 RL |
217 | /* |
218 | * TODO remove this when legacy is gone | |
219 | * If we don't have the full support we need with provided methods, | |
220 | * let's go see if legacy does. | |
221 | */ | |
222 | ERR_pop_to_mark(); | |
223 | ||
55ca8125 MC |
224 | if (type == NULL && mdname != NULL) |
225 | type = evp_get_digestbyname_ex(locpctx->libctx, mdname); | |
226 | ||
e0d8523e RL |
227 | if (ctx->pctx->pmeth == NULL) { |
228 | EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); | |
76123661 | 229 | return 0; |
e0d8523e RL |
230 | } |
231 | ||
0f113f3e | 232 | if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) { |
e69adea5 | 233 | |
0f113f3e MC |
234 | if (type == NULL) { |
235 | int def_nid; | |
236 | if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0) | |
237 | type = EVP_get_digestbynid(def_nid); | |
238 | } | |
c8ef656d | 239 | |
0f113f3e MC |
240 | if (type == NULL) { |
241 | EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST); | |
242 | return 0; | |
243 | } | |
244 | } | |
e69adea5 | 245 | |
0f113f3e MC |
246 | if (ver) { |
247 | if (ctx->pctx->pmeth->verifyctx_init) { | |
248 | if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <= 0) | |
249 | return 0; | |
250 | ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX; | |
f723c98e DSH |
251 | } else if (ctx->pctx->pmeth->digestverify != 0) { |
252 | ctx->pctx->operation = EVP_PKEY_OP_VERIFY; | |
253 | ctx->update = update; | |
254 | } else if (EVP_PKEY_verify_init(ctx->pctx) <= 0) { | |
0f113f3e | 255 | return 0; |
f723c98e | 256 | } |
0f113f3e MC |
257 | } else { |
258 | if (ctx->pctx->pmeth->signctx_init) { | |
259 | if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0) | |
260 | return 0; | |
261 | ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX; | |
f723c98e DSH |
262 | } else if (ctx->pctx->pmeth->digestsign != 0) { |
263 | ctx->pctx->operation = EVP_PKEY_OP_SIGN; | |
264 | ctx->update = update; | |
265 | } else if (EVP_PKEY_sign_init(ctx->pctx) <= 0) { | |
0f113f3e | 266 | return 0; |
f723c98e | 267 | } |
0f113f3e MC |
268 | } |
269 | if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0) | |
270 | return 0; | |
271 | if (pctx) | |
272 | *pctx = ctx->pctx; | |
273 | if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) | |
274 | return 1; | |
275 | if (!EVP_DigestInit_ex(ctx, type, e)) | |
276 | return 0; | |
4803717f PY |
277 | /* |
278 | * This indicates the current algorithm requires | |
279 | * special treatment before hashing the tbs-message. | |
280 | */ | |
a5ce329e | 281 | ctx->pctx->flag_call_digest_custom = 0; |
675f4cee | 282 | if (ctx->pctx->pmeth->digest_custom != NULL) |
a5ce329e | 283 | ctx->pctx->flag_call_digest_custom = 1; |
4803717f | 284 | |
0f113f3e MC |
285 | return 1; |
286 | } | |
91c9e621 | 287 | |
0ab18e79 SL |
288 | int EVP_DigestSignInit_with_libctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, |
289 | const char *mdname, | |
290 | OPENSSL_CTX *libctx, const char *props, | |
291 | EVP_PKEY *pkey) | |
d8c98d79 | 292 | { |
0ab18e79 | 293 | return do_sigver_init(ctx, pctx, NULL, mdname, libctx, props, NULL, pkey, 0); |
d8c98d79 MC |
294 | } |
295 | ||
91c9e621 | 296 | int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, |
0f113f3e MC |
297 | const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) |
298 | { | |
0ab18e79 | 299 | return do_sigver_init(ctx, pctx, type, NULL, NULL, NULL, e, pkey, 0); |
d8c98d79 MC |
300 | } |
301 | ||
0ab18e79 SL |
302 | int EVP_DigestVerifyInit_with_libctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, |
303 | const char *mdname, | |
304 | OPENSSL_CTX *libctx, const char *props, | |
305 | EVP_PKEY *pkey) | |
d8c98d79 | 306 | { |
0ab18e79 | 307 | return do_sigver_init(ctx, pctx, NULL, mdname, libctx, props, NULL, pkey, 1); |
0f113f3e | 308 | } |
91c9e621 DSH |
309 | |
310 | int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, | |
0f113f3e MC |
311 | const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) |
312 | { | |
0ab18e79 | 313 | return do_sigver_init(ctx, pctx, type, NULL, NULL, NULL, e, pkey, 1); |
d8c98d79 | 314 | } |
72df8f88 | 315 | #endif /* FIPS_MDOE */ |
d8c98d79 MC |
316 | |
317 | int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize) | |
318 | { | |
319 | EVP_PKEY_CTX *pctx = ctx->pctx; | |
320 | ||
321 | if (pctx == NULL | |
322 | || pctx->operation != EVP_PKEY_OP_SIGNCTX | |
323 | || pctx->op.sig.sigprovctx == NULL | |
324 | || pctx->op.sig.signature == NULL) | |
325 | goto legacy; | |
326 | ||
eea1e780 MC |
327 | if (pctx->op.sig.signature->digest_sign_update == NULL) { |
328 | ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | |
329 | return 0; | |
330 | } | |
331 | ||
d8c98d79 MC |
332 | return pctx->op.sig.signature->digest_sign_update(pctx->op.sig.sigprovctx, |
333 | data, dsize); | |
334 | ||
335 | legacy: | |
72133070 P |
336 | if (pctx != NULL) { |
337 | /* do_sigver_init() checked that |digest_custom| is non-NULL */ | |
338 | if (pctx->flag_call_digest_custom | |
339 | && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx)) | |
340 | return 0; | |
341 | pctx->flag_call_digest_custom = 0; | |
342 | } | |
a5ce329e | 343 | |
d8c98d79 | 344 | return EVP_DigestUpdate(ctx, data, dsize); |
0f113f3e | 345 | } |
91c9e621 | 346 | |
d8c98d79 MC |
347 | int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize) |
348 | { | |
349 | EVP_PKEY_CTX *pctx = ctx->pctx; | |
350 | ||
351 | if (pctx == NULL | |
352 | || pctx->operation != EVP_PKEY_OP_VERIFYCTX | |
353 | || pctx->op.sig.sigprovctx == NULL | |
354 | || pctx->op.sig.signature == NULL) | |
355 | goto legacy; | |
356 | ||
eea1e780 MC |
357 | if (pctx->op.sig.signature->digest_verify_update == NULL) { |
358 | ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | |
359 | return 0; | |
360 | } | |
361 | ||
d8c98d79 MC |
362 | return pctx->op.sig.signature->digest_verify_update(pctx->op.sig.sigprovctx, |
363 | data, dsize); | |
364 | ||
365 | legacy: | |
089c2928 P |
366 | if (pctx != NULL) { |
367 | /* do_sigver_init() checked that |digest_custom| is non-NULL */ | |
368 | if (pctx->flag_call_digest_custom | |
369 | && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx)) | |
370 | return 0; | |
371 | pctx->flag_call_digest_custom = 0; | |
372 | } | |
a5ce329e | 373 | |
d8c98d79 MC |
374 | return EVP_DigestUpdate(ctx, data, dsize); |
375 | } | |
376 | ||
f844f9eb | 377 | #ifndef FIPS_MODULE |
0f113f3e MC |
378 | int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, |
379 | size_t *siglen) | |
380 | { | |
4c9b0a03 | 381 | int sctx = 0, r = 0; |
0f113f3e | 382 | EVP_PKEY_CTX *pctx = ctx->pctx; |
d8c98d79 MC |
383 | |
384 | if (pctx == NULL | |
385 | || pctx->operation != EVP_PKEY_OP_SIGNCTX | |
386 | || pctx->op.sig.sigprovctx == NULL | |
387 | || pctx->op.sig.signature == NULL) | |
388 | goto legacy; | |
389 | ||
390 | return pctx->op.sig.signature->digest_sign_final(pctx->op.sig.sigprovctx, | |
391 | sigret, siglen, SIZE_MAX); | |
392 | ||
393 | legacy: | |
8f020c3d RL |
394 | if (pctx == NULL || pctx->pmeth == NULL) { |
395 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); | |
396 | return 0; | |
397 | } | |
398 | ||
a5ce329e RL |
399 | /* do_sigver_init() checked that |digest_custom| is non-NULL */ |
400 | if (pctx->flag_call_digest_custom | |
401 | && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx)) | |
402 | return 0; | |
403 | pctx->flag_call_digest_custom = 0; | |
404 | ||
0f113f3e | 405 | if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) { |
8f020c3d | 406 | if (sigret == NULL) |
0f113f3e MC |
407 | return pctx->pmeth->signctx(pctx, sigret, siglen, ctx); |
408 | if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) | |
409 | r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx); | |
410 | else { | |
8f020c3d RL |
411 | EVP_PKEY_CTX *dctx = EVP_PKEY_CTX_dup(pctx); |
412 | ||
413 | if (dctx == NULL) | |
0f113f3e MC |
414 | return 0; |
415 | r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx); | |
416 | EVP_PKEY_CTX_free(dctx); | |
417 | } | |
418 | return r; | |
419 | } | |
8f020c3d | 420 | if (pctx->pmeth->signctx != NULL) |
0f113f3e MC |
421 | sctx = 1; |
422 | else | |
423 | sctx = 0; | |
8f020c3d | 424 | if (sigret != NULL) { |
0f113f3e | 425 | unsigned char md[EVP_MAX_MD_SIZE]; |
4c9b0a03 | 426 | unsigned int mdlen = 0; |
8f020c3d | 427 | |
0f113f3e MC |
428 | if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) { |
429 | if (sctx) | |
8f020c3d | 430 | r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx); |
0f113f3e MC |
431 | else |
432 | r = EVP_DigestFinal_ex(ctx, md, &mdlen); | |
433 | } else { | |
bfb0641f | 434 | EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new(); |
8f020c3d | 435 | |
19546246 | 436 | if (tmp_ctx == NULL) |
0f113f3e | 437 | return 0; |
19546246 BE |
438 | if (!EVP_MD_CTX_copy_ex(tmp_ctx, ctx)) { |
439 | EVP_MD_CTX_free(tmp_ctx); | |
440 | return 0; | |
441 | } | |
0f113f3e | 442 | if (sctx) |
77a01145 RL |
443 | r = tmp_ctx->pctx->pmeth->signctx(tmp_ctx->pctx, |
444 | sigret, siglen, tmp_ctx); | |
0f113f3e | 445 | else |
77a01145 | 446 | r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen); |
bfb0641f | 447 | EVP_MD_CTX_free(tmp_ctx); |
0f113f3e MC |
448 | } |
449 | if (sctx || !r) | |
450 | return r; | |
8f020c3d | 451 | if (EVP_PKEY_sign(pctx, sigret, siglen, md, mdlen) <= 0) |
0f113f3e MC |
452 | return 0; |
453 | } else { | |
454 | if (sctx) { | |
455 | if (pctx->pmeth->signctx(pctx, sigret, siglen, ctx) <= 0) | |
456 | return 0; | |
457 | } else { | |
458 | int s = EVP_MD_size(ctx->digest); | |
8f020c3d | 459 | |
0f113f3e MC |
460 | if (s < 0 || EVP_PKEY_sign(pctx, sigret, siglen, NULL, s) <= 0) |
461 | return 0; | |
462 | } | |
463 | } | |
464 | return 1; | |
465 | } | |
91c9e621 | 466 | |
75394189 DSH |
467 | int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen, |
468 | const unsigned char *tbs, size_t tbslen) | |
469 | { | |
eea1e780 MC |
470 | EVP_PKEY_CTX *pctx = ctx->pctx; |
471 | ||
472 | if (pctx != NULL | |
473 | && pctx->operation == EVP_PKEY_OP_SIGNCTX | |
474 | && pctx->op.sig.sigprovctx != NULL | |
475 | && pctx->op.sig.signature != NULL) { | |
476 | if (pctx->op.sig.signature->digest_sign != NULL) | |
477 | return pctx->op.sig.signature->digest_sign(pctx->op.sig.sigprovctx, | |
478 | sigret, siglen, SIZE_MAX, | |
479 | tbs, tbslen); | |
480 | } else { | |
481 | /* legacy */ | |
482 | if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestsign != NULL) | |
483 | return ctx->pctx->pmeth->digestsign(ctx, sigret, siglen, tbs, tbslen); | |
484 | } | |
485 | ||
75394189 DSH |
486 | if (sigret != NULL && EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0) |
487 | return 0; | |
488 | return EVP_DigestSignFinal(ctx, sigret, siglen); | |
489 | } | |
490 | ||
0f7fa1b1 | 491 | int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, |
0f113f3e MC |
492 | size_t siglen) |
493 | { | |
494 | unsigned char md[EVP_MAX_MD_SIZE]; | |
4c9b0a03 GK |
495 | int r = 0; |
496 | unsigned int mdlen = 0; | |
497 | int vctx = 0; | |
d8c98d79 MC |
498 | EVP_PKEY_CTX *pctx = ctx->pctx; |
499 | ||
500 | if (pctx == NULL | |
501 | || pctx->operation != EVP_PKEY_OP_VERIFYCTX | |
502 | || pctx->op.sig.sigprovctx == NULL | |
503 | || pctx->op.sig.signature == NULL) | |
504 | goto legacy; | |
505 | ||
506 | return pctx->op.sig.signature->digest_verify_final(pctx->op.sig.sigprovctx, | |
507 | sig, siglen); | |
0eab41fb | 508 | |
d8c98d79 | 509 | legacy: |
8f020c3d RL |
510 | if (pctx == NULL || pctx->pmeth == NULL) { |
511 | ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); | |
512 | return 0; | |
513 | } | |
514 | ||
a5ce329e RL |
515 | /* do_sigver_init() checked that |digest_custom| is non-NULL */ |
516 | if (pctx->flag_call_digest_custom | |
517 | && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx)) | |
518 | return 0; | |
519 | pctx->flag_call_digest_custom = 0; | |
520 | ||
8f020c3d | 521 | if (pctx->pmeth->verifyctx != NULL) |
0f113f3e MC |
522 | vctx = 1; |
523 | else | |
524 | vctx = 0; | |
525 | if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) { | |
4803717f | 526 | if (vctx) |
8f020c3d | 527 | r = pctx->pmeth->verifyctx(pctx, sig, siglen, ctx); |
4803717f | 528 | else |
0f113f3e MC |
529 | r = EVP_DigestFinal_ex(ctx, md, &mdlen); |
530 | } else { | |
bfb0641f | 531 | EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new(); |
19546246 BE |
532 | if (tmp_ctx == NULL) |
533 | return -1; | |
534 | if (!EVP_MD_CTX_copy_ex(tmp_ctx, ctx)) { | |
535 | EVP_MD_CTX_free(tmp_ctx); | |
0f113f3e | 536 | return -1; |
19546246 | 537 | } |
4803717f | 538 | if (vctx) |
77a01145 RL |
539 | r = tmp_ctx->pctx->pmeth->verifyctx(tmp_ctx->pctx, |
540 | sig, siglen, tmp_ctx); | |
4803717f | 541 | else |
77a01145 | 542 | r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen); |
bfb0641f | 543 | EVP_MD_CTX_free(tmp_ctx); |
0f113f3e MC |
544 | } |
545 | if (vctx || !r) | |
546 | return r; | |
8f020c3d | 547 | return EVP_PKEY_verify(pctx, sig, siglen, md, mdlen); |
0f113f3e | 548 | } |
75394189 DSH |
549 | |
550 | int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, | |
551 | size_t siglen, const unsigned char *tbs, size_t tbslen) | |
552 | { | |
eea1e780 MC |
553 | EVP_PKEY_CTX *pctx = ctx->pctx; |
554 | ||
555 | if (pctx != NULL | |
556 | && pctx->operation == EVP_PKEY_OP_VERIFYCTX | |
557 | && pctx->op.sig.sigprovctx != NULL | |
558 | && pctx->op.sig.signature != NULL) { | |
559 | if (pctx->op.sig.signature->digest_verify != NULL) | |
560 | return pctx->op.sig.signature->digest_verify(pctx->op.sig.sigprovctx, | |
561 | sigret, siglen, | |
562 | tbs, tbslen); | |
563 | } else { | |
564 | /* legacy */ | |
565 | if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestverify != NULL) | |
566 | return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen, tbs, tbslen); | |
567 | } | |
568 | ||
75394189 DSH |
569 | if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0) |
570 | return -1; | |
571 | return EVP_DigestVerifyFinal(ctx, sigret, siglen); | |
572 | } | |
f844f9eb | 573 | #endif /* FIPS_MODULE */ |