xref: /openssl/crypto/evp/m_sigver.c (revision 7ed6de99)
1 /*
2  * Copyright 2006-2024 The OpenSSL Project Authors. All Rights Reserved.
3  *
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
8  */
9 
10 #include <stdio.h>
11 #include "internal/cryptlib.h"
12 #include <openssl/evp.h>
13 #include <openssl/objects.h>
14 #include "crypto/evp.h"
15 #include "internal/provider.h"
16 #include "internal/numbers.h"   /* includes SIZE_MAX */
17 #include "evp_local.h"
18 
19 #ifndef FIPS_MODULE
update(EVP_MD_CTX * ctx,const void * data,size_t datalen)20 static int update(EVP_MD_CTX *ctx, const void *data, size_t datalen)
21 {
22     ERR_raise(ERR_LIB_EVP, EVP_R_ONLY_ONESHOT_SUPPORTED);
23     return 0;
24 }
25 #endif
26 
27 /*
28  * If we get the "NULL" md then the name comes back as "UNDEF". We want to use
29  * NULL for this.
30  */
canon_mdname(const char * mdname)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 
do_sigver_init(EVP_MD_CTX * ctx,EVP_PKEY_CTX ** pctx,const EVP_MD * type,const char * mdname,OSSL_LIB_CTX * libctx,const char * props,ENGINE * e,EVP_PKEY * pkey,int ver,const OSSL_PARAM params[])39 static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
40                           const EVP_MD *type, const char *mdname,
41                           OSSL_LIB_CTX *libctx, const char *props,
42                           ENGINE *e, EVP_PKEY *pkey, int ver,
43                           const OSSL_PARAM params[])
44 {
45     EVP_PKEY_CTX *locpctx = NULL;
46     EVP_SIGNATURE *signature = NULL;
47     EVP_KEYMGMT *tmp_keymgmt = NULL;
48     const OSSL_PROVIDER *tmp_prov = NULL;
49     const char *supported_sig = NULL;
50     char locmdname[80] = "";     /* 80 chars should be enough */
51     void *provkey = NULL;
52     int ret, iter, reinit = 1;
53 
54     if (!evp_md_ctx_free_algctx(ctx))
55         return 0;
56 
57     if (ctx->pctx == NULL) {
58         reinit = 0;
59         if (e == NULL)
60             ctx->pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, props);
61 #ifndef FIPS_MODULE
62         else
63             ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
64 #endif
65     }
66     if (ctx->pctx == NULL)
67         return 0;
68 
69     EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_FINALISED);
70 
71     locpctx = ctx->pctx;
72     ERR_set_mark();
73 
74     if (evp_pkey_ctx_is_legacy(locpctx))
75         goto legacy;
76 
77     /* do not reinitialize if pkey is set or operation is different */
78     if (reinit
79         && (pkey != NULL
80             || locpctx->operation != (ver ? EVP_PKEY_OP_VERIFYCTX
81                                           : EVP_PKEY_OP_SIGNCTX)
82             || (signature = locpctx->op.sig.signature) == NULL
83             || locpctx->op.sig.algctx == NULL))
84         reinit = 0;
85 
86     if (props == NULL)
87         props = locpctx->propquery;
88 
89     if (locpctx->pkey == NULL) {
90         ERR_clear_last_mark();
91         ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET);
92         goto err;
93     }
94 
95     if (!reinit) {
96         evp_pkey_ctx_free_old_ops(locpctx);
97     } else {
98         if (mdname == NULL && type == NULL)
99             mdname = canon_mdname(EVP_MD_get0_name(ctx->reqdigest));
100         goto reinitialize;
101     }
102 
103     /*
104      * Try to derive the supported signature from |locpctx->keymgmt|.
105      */
106     if (!ossl_assert(locpctx->pkey->keymgmt == NULL
107                      || locpctx->pkey->keymgmt == locpctx->keymgmt)) {
108         ERR_clear_last_mark();
109         ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
110         goto err;
111     }
112     supported_sig = evp_keymgmt_util_query_operation_name(locpctx->keymgmt,
113                                                           OSSL_OP_SIGNATURE);
114     if (supported_sig == NULL) {
115         ERR_clear_last_mark();
116         ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
117         goto err;
118     }
119 
120     /*
121      * We perform two iterations:
122      *
123      * 1.  Do the normal signature fetch, using the fetching data given by
124      *     the EVP_PKEY_CTX.
125      * 2.  Do the provider specific signature fetch, from the same provider
126      *     as |ctx->keymgmt|
127      *
128      * We then try to fetch the keymgmt from the same provider as the
129      * signature, and try to export |ctx->pkey| to that keymgmt (when
130      * this keymgmt happens to be the same as |ctx->keymgmt|, the export
131      * is a no-op, but we call it anyway to not complicate the code even
132      * more).
133      * If the export call succeeds (returns a non-NULL provider key pointer),
134      * we're done and can perform the operation itself.  If not, we perform
135      * the second iteration, or jump to legacy.
136      */
137     for (iter = 1, provkey = NULL; iter < 3 && provkey == NULL; iter++) {
138         EVP_KEYMGMT *tmp_keymgmt_tofree = NULL;
139 
140         /*
141          * If we're on the second iteration, free the results from the first.
142          * They are NULL on the first iteration, so no need to check what
143          * iteration we're on.
144          */
145         EVP_SIGNATURE_free(signature);
146         EVP_KEYMGMT_free(tmp_keymgmt);
147 
148         switch (iter) {
149         case 1:
150             signature = EVP_SIGNATURE_fetch(locpctx->libctx, supported_sig,
151                                             locpctx->propquery);
152             if (signature != NULL)
153                 tmp_prov = EVP_SIGNATURE_get0_provider(signature);
154             break;
155         case 2:
156             tmp_prov = EVP_KEYMGMT_get0_provider(locpctx->keymgmt);
157             signature =
158                 evp_signature_fetch_from_prov((OSSL_PROVIDER *)tmp_prov,
159                                               supported_sig, locpctx->propquery);
160             if (signature == NULL)
161                 goto legacy;
162             break;
163         }
164         if (signature == NULL)
165             continue;
166 
167         /*
168          * Ensure that the key is provided, either natively, or as a cached
169          * export.  We start by fetching the keymgmt with the same name as
170          * |locpctx->pkey|, but from the provider of the signature method, using
171          * the same property query as when fetching the signature method.
172          * With the keymgmt we found (if we did), we try to export |locpctx->pkey|
173          * to it (evp_pkey_export_to_provider() is smart enough to only actually
174 
175          * export it if |tmp_keymgmt| is different from |locpctx->pkey|'s keymgmt)
176          */
177         tmp_keymgmt_tofree = tmp_keymgmt =
178             evp_keymgmt_fetch_from_prov((OSSL_PROVIDER *)tmp_prov,
179                                         EVP_KEYMGMT_get0_name(locpctx->keymgmt),
180                                         locpctx->propquery);
181         if (tmp_keymgmt != NULL)
182             provkey = evp_pkey_export_to_provider(locpctx->pkey, locpctx->libctx,
183                                                   &tmp_keymgmt, locpctx->propquery);
184         if (tmp_keymgmt == NULL)
185             EVP_KEYMGMT_free(tmp_keymgmt_tofree);
186     }
187 
188     if (provkey == NULL) {
189         EVP_SIGNATURE_free(signature);
190         ERR_clear_last_mark();
191         ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
192         goto err;
193     }
194 
195     ERR_pop_to_mark();
196 
197     /* No more legacy from here down to legacy: */
198 
199     locpctx->op.sig.signature = signature;
200     locpctx->operation = ver ? EVP_PKEY_OP_VERIFYCTX
201                              : EVP_PKEY_OP_SIGNCTX;
202     locpctx->op.sig.algctx
203         = signature->newctx(ossl_provider_ctx(signature->prov), props);
204     if (locpctx->op.sig.algctx == NULL) {
205         ERR_raise(ERR_LIB_EVP,  EVP_R_INITIALIZATION_ERROR);
206         goto err;
207     }
208 
209  reinitialize:
210     if (pctx != NULL)
211         *pctx = locpctx;
212 
213     if (type != NULL) {
214         ctx->reqdigest = type;
215         if (mdname == NULL)
216             mdname = canon_mdname(EVP_MD_get0_name(type));
217     } else {
218         if (mdname == NULL && !reinit) {
219             if (evp_keymgmt_util_get_deflt_digest_name(tmp_keymgmt, provkey,
220                                                        locmdname,
221                                                        sizeof(locmdname)) > 0) {
222                 mdname = canon_mdname(locmdname);
223             }
224         }
225 
226         if (mdname != NULL) {
227             /*
228              * We're about to get a new digest so clear anything associated with
229              * an old digest.
230              */
231             evp_md_ctx_clear_digest(ctx, 1, 0);
232 
233             /* legacy code support for engines */
234             ERR_set_mark();
235             /*
236              * This might be requested by a later call to EVP_MD_CTX_get0_md().
237              * In that case the "explicit fetch" rules apply for that
238              * function (as per man pages), i.e. the ref count is not updated
239              * so the EVP_MD should not be used beyond the lifetime of the
240              * EVP_MD_CTX.
241              */
242             ctx->fetched_digest = EVP_MD_fetch(locpctx->libctx, mdname, props);
243             if (ctx->fetched_digest != NULL) {
244                 ctx->digest = ctx->reqdigest = ctx->fetched_digest;
245             } else {
246 #ifdef FIPS_MODULE
247                 (void)ERR_clear_last_mark();
248                 ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
249                 goto err;
250 #else
251                 /* legacy engine support : remove the mark when this is deleted */
252                 ctx->reqdigest = ctx->digest = EVP_get_digestbyname(mdname);
253                 if (ctx->digest == NULL) {
254                     (void)ERR_clear_last_mark();
255                     ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
256                     goto err;
257                 }
258 #endif
259             }
260             (void)ERR_pop_to_mark();
261         }
262     }
263 
264     if (ver) {
265         if (signature->digest_verify_init == NULL) {
266             ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
267             goto err;
268         }
269         ret = signature->digest_verify_init(locpctx->op.sig.algctx,
270                                             mdname, provkey, params);
271     } else {
272         if (signature->digest_sign_init == NULL) {
273             ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
274             goto err;
275         }
276         ret = signature->digest_sign_init(locpctx->op.sig.algctx,
277                                           mdname, provkey, params);
278     }
279 
280     /*
281      * If the operation was not a success and no digest was found, an error
282      * needs to be raised.
283      */
284     if (ret > 0 || mdname != NULL)
285         goto end;
286     if (type == NULL)   /* This check is redundant but clarifies matters */
287         ERR_raise(ERR_LIB_EVP, EVP_R_NO_DEFAULT_DIGEST);
288 
289  err:
290     evp_pkey_ctx_free_old_ops(locpctx);
291     locpctx->operation = EVP_PKEY_OP_UNDEFINED;
292     EVP_KEYMGMT_free(tmp_keymgmt);
293     return 0;
294 
295  legacy:
296     /*
297      * If we don't have the full support we need with provided methods,
298      * let's go see if legacy does.
299      */
300     ERR_pop_to_mark();
301     EVP_KEYMGMT_free(tmp_keymgmt);
302     tmp_keymgmt = NULL;
303 
304 #ifdef FIPS_MODULE
305     return 0;
306 #else
307     if (type == NULL && mdname != NULL)
308         type = evp_get_digestbyname_ex(locpctx->libctx, mdname);
309 
310     if (ctx->pctx->pmeth == NULL) {
311         ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
312         return 0;
313     }
314 
315     if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) {
316 
317         if (type == NULL) {
318             int def_nid;
319             if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
320                 type = EVP_get_digestbynid(def_nid);
321         }
322 
323         if (type == NULL) {
324             ERR_raise(ERR_LIB_EVP, EVP_R_NO_DEFAULT_DIGEST);
325             return 0;
326         }
327     }
328 
329     if (ver) {
330         if (ctx->pctx->pmeth->verifyctx_init) {
331             if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <= 0)
332                 return 0;
333             ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
334         } else if (ctx->pctx->pmeth->digestverify != 0) {
335             ctx->pctx->operation = EVP_PKEY_OP_VERIFY;
336             ctx->update = update;
337         } else if (EVP_PKEY_verify_init(ctx->pctx) <= 0) {
338             return 0;
339         }
340     } else {
341         if (ctx->pctx->pmeth->signctx_init) {
342             if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0)
343                 return 0;
344             ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
345         } else if (ctx->pctx->pmeth->digestsign != 0) {
346             ctx->pctx->operation = EVP_PKEY_OP_SIGN;
347             ctx->update = update;
348         } else if (EVP_PKEY_sign_init(ctx->pctx) <= 0) {
349             return 0;
350         }
351     }
352     if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
353         return 0;
354     if (pctx)
355         *pctx = ctx->pctx;
356     if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)
357         return 1;
358     if (!EVP_DigestInit_ex(ctx, type, e))
359         return 0;
360     /*
361      * This indicates the current algorithm requires
362      * special treatment before hashing the tbs-message.
363      */
364     ctx->pctx->flag_call_digest_custom = 0;
365     if (ctx->pctx->pmeth->digest_custom != NULL)
366         ctx->pctx->flag_call_digest_custom = 1;
367 
368     ret = 1;
369 #endif
370  end:
371 #ifndef FIPS_MODULE
372     if (ret > 0)
373         ret = evp_pkey_ctx_use_cached_data(locpctx);
374 #endif
375 
376     EVP_KEYMGMT_free(tmp_keymgmt);
377     return ret > 0 ? 1 : 0;
378 }
379 
EVP_DigestSignInit_ex(EVP_MD_CTX * ctx,EVP_PKEY_CTX ** pctx,const char * mdname,OSSL_LIB_CTX * libctx,const char * props,EVP_PKEY * pkey,const OSSL_PARAM params[])380 int EVP_DigestSignInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
381                           const char *mdname, OSSL_LIB_CTX *libctx,
382                           const char *props, EVP_PKEY *pkey,
383                           const OSSL_PARAM params[])
384 {
385     return do_sigver_init(ctx, pctx, NULL, mdname, libctx, props, NULL, pkey, 0,
386                           params);
387 }
388 
389 #ifndef FIPS_MODULE
EVP_DigestSignInit(EVP_MD_CTX * ctx,EVP_PKEY_CTX ** pctx,const EVP_MD * type,ENGINE * e,EVP_PKEY * pkey)390 int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
391                        const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
392 {
393     return do_sigver_init(ctx, pctx, type, NULL, NULL, NULL, e, pkey, 0,
394                           NULL);
395 }
396 #endif
397 
EVP_DigestVerifyInit_ex(EVP_MD_CTX * ctx,EVP_PKEY_CTX ** pctx,const char * mdname,OSSL_LIB_CTX * libctx,const char * props,EVP_PKEY * pkey,const OSSL_PARAM params[])398 int EVP_DigestVerifyInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
399                             const char *mdname, OSSL_LIB_CTX *libctx,
400                             const char *props, EVP_PKEY *pkey,
401                             const OSSL_PARAM params[])
402 {
403     return do_sigver_init(ctx, pctx, NULL, mdname, libctx, props, NULL, pkey, 1,
404                           params);
405 }
406 
407 #ifndef FIPS_MODULE
EVP_DigestVerifyInit(EVP_MD_CTX * ctx,EVP_PKEY_CTX ** pctx,const EVP_MD * type,ENGINE * e,EVP_PKEY * pkey)408 int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
409                          const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
410 {
411     return do_sigver_init(ctx, pctx, type, NULL, NULL, NULL, e, pkey, 1,
412                           NULL);
413 }
414 #endif /* FIPS_MODULE */
415 
EVP_DigestSignUpdate(EVP_MD_CTX * ctx,const void * data,size_t dsize)416 int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
417 {
418     EVP_PKEY_CTX *pctx = ctx->pctx;
419 
420     if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
421         ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
422         return 0;
423     }
424 
425     if (pctx == NULL
426             || pctx->operation != EVP_PKEY_OP_SIGNCTX
427             || pctx->op.sig.algctx == NULL
428             || pctx->op.sig.signature == NULL)
429         goto legacy;
430 
431     if (pctx->op.sig.signature->digest_sign_update == NULL) {
432         ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
433         return 0;
434     }
435 
436     return pctx->op.sig.signature->digest_sign_update(pctx->op.sig.algctx,
437                                                       data, dsize);
438 
439  legacy:
440 #ifdef FIPS_MODULE
441     ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
442     return 0;
443 #else
444     if (pctx != NULL) {
445         /* do_sigver_init() checked that |digest_custom| is non-NULL */
446         if (pctx->flag_call_digest_custom
447             && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx))
448             return 0;
449         pctx->flag_call_digest_custom = 0;
450     }
451 
452     return EVP_DigestUpdate(ctx, data, dsize);
453 #endif
454 }
455 
EVP_DigestVerifyUpdate(EVP_MD_CTX * ctx,const void * data,size_t dsize)456 int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
457 {
458     EVP_PKEY_CTX *pctx = ctx->pctx;
459 
460     if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
461         ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
462         return 0;
463     }
464 
465     if (pctx == NULL
466             || pctx->operation != EVP_PKEY_OP_VERIFYCTX
467             || pctx->op.sig.algctx == NULL
468             || pctx->op.sig.signature == NULL)
469         goto legacy;
470 
471     if (pctx->op.sig.signature->digest_verify_update == NULL) {
472         ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
473         return 0;
474     }
475 
476     return pctx->op.sig.signature->digest_verify_update(pctx->op.sig.algctx,
477                                                         data, dsize);
478 
479  legacy:
480 #ifdef FIPS_MODULE
481     ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
482     return 0;
483 #else
484     if (pctx != NULL) {
485         /* do_sigver_init() checked that |digest_custom| is non-NULL */
486         if (pctx->flag_call_digest_custom
487             && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx))
488             return 0;
489         pctx->flag_call_digest_custom = 0;
490     }
491 
492     return EVP_DigestUpdate(ctx, data, dsize);
493 #endif
494 }
495 
EVP_DigestSignFinal(EVP_MD_CTX * ctx,unsigned char * sigret,size_t * siglen)496 int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
497                         size_t *siglen)
498 {
499 #ifndef FIPS_MODULE
500     int sctx = 0;
501 #endif
502     int r = 0;
503     EVP_PKEY_CTX *dctx = NULL, *pctx = ctx->pctx;
504 
505     if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
506         ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
507         return 0;
508     }
509 
510     if (pctx == NULL
511             || pctx->operation != EVP_PKEY_OP_SIGNCTX
512             || pctx->op.sig.algctx == NULL
513             || pctx->op.sig.signature == NULL)
514         goto legacy;
515 
516 #ifndef FIPS_MODULE
517     if (sigret != NULL && (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) == 0) {
518         /* try dup */
519         dctx = EVP_PKEY_CTX_dup(pctx);
520         if (dctx != NULL)
521             pctx = dctx;
522     }
523 #endif
524     r = pctx->op.sig.signature->digest_sign_final(pctx->op.sig.algctx,
525                                                   sigret, siglen,
526                                                   sigret == NULL ? 0 : *siglen);
527     if (dctx == NULL && sigret != NULL)
528         ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
529     else
530         EVP_PKEY_CTX_free(dctx);
531     return r;
532 
533  legacy:
534 #ifdef FIPS_MODULE
535     ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
536     return 0;
537 #else
538     if (pctx == NULL || pctx->pmeth == NULL) {
539         ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
540         return 0;
541     }
542 
543     /* do_sigver_init() checked that |digest_custom| is non-NULL */
544     if (pctx->flag_call_digest_custom
545         && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx))
546         return 0;
547     pctx->flag_call_digest_custom = 0;
548 
549     if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) {
550         if (sigret == NULL)
551             return pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
552         if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0) {
553             r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
554             ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
555         } else {
556             dctx = EVP_PKEY_CTX_dup(pctx);
557             if (dctx == NULL)
558                 return 0;
559             r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx);
560             EVP_PKEY_CTX_free(dctx);
561         }
562         return r;
563     }
564     if (pctx->pmeth->signctx != NULL)
565         sctx = 1;
566     else
567         sctx = 0;
568     if (sigret != NULL) {
569         unsigned char md[EVP_MAX_MD_SIZE];
570         unsigned int mdlen = 0;
571 
572         if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
573             if (sctx)
574                 r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
575             else
576                 r = EVP_DigestFinal_ex(ctx, md, &mdlen);
577         } else {
578             EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
579 
580             if (tmp_ctx == NULL)
581                 return 0;
582             if (!EVP_MD_CTX_copy_ex(tmp_ctx, ctx)) {
583                 EVP_MD_CTX_free(tmp_ctx);
584                 return 0;
585             }
586             if (sctx)
587                 r = tmp_ctx->pctx->pmeth->signctx(tmp_ctx->pctx,
588                                                   sigret, siglen, tmp_ctx);
589             else
590                 r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen);
591             EVP_MD_CTX_free(tmp_ctx);
592         }
593         if (sctx || !r)
594             return r;
595         if (EVP_PKEY_sign(pctx, sigret, siglen, md, mdlen) <= 0)
596             return 0;
597     } else {
598         if (sctx) {
599             if (pctx->pmeth->signctx(pctx, sigret, siglen, ctx) <= 0)
600                 return 0;
601         } else {
602             int s = EVP_MD_get_size(ctx->digest);
603 
604             if (s <= 0 || EVP_PKEY_sign(pctx, sigret, siglen, NULL, s) <= 0)
605                 return 0;
606         }
607     }
608     return 1;
609 #endif
610 }
611 
EVP_DigestSign(EVP_MD_CTX * ctx,unsigned char * sigret,size_t * siglen,const unsigned char * tbs,size_t tbslen)612 int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
613                    const unsigned char *tbs, size_t tbslen)
614 {
615     EVP_PKEY_CTX *pctx = ctx->pctx;
616 
617     if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
618         ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
619         return 0;
620     }
621 
622     if (pctx != NULL
623             && pctx->operation == EVP_PKEY_OP_SIGNCTX
624             && pctx->op.sig.algctx != NULL
625             && pctx->op.sig.signature != NULL) {
626         if (pctx->op.sig.signature->digest_sign != NULL) {
627             if (sigret != NULL)
628                 ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
629             return pctx->op.sig.signature->digest_sign(pctx->op.sig.algctx,
630                                                        sigret, siglen,
631                                                        sigret == NULL ? 0 : *siglen,
632                                                        tbs, tbslen);
633         }
634 #ifdef FIPS_MODULE
635     }
636     ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
637     return 0;
638 #else
639     } else {
640         /* legacy */
641         if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestsign != NULL)
642             return ctx->pctx->pmeth->digestsign(ctx, sigret, siglen, tbs, tbslen);
643     }
644 
645     if (sigret != NULL && EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0)
646         return 0;
647     return EVP_DigestSignFinal(ctx, sigret, siglen);
648 #endif
649 }
650 
EVP_DigestVerifyFinal(EVP_MD_CTX * ctx,const unsigned char * sig,size_t siglen)651 int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
652                           size_t siglen)
653 {
654 #ifndef FIPS_MODULE
655     int vctx = 0;
656     unsigned int mdlen = 0;
657     unsigned char md[EVP_MAX_MD_SIZE];
658 #endif
659     int r = 0;
660     EVP_PKEY_CTX *dctx = NULL, *pctx = ctx->pctx;
661 
662     if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
663         ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
664         return 0;
665     }
666 
667     if (pctx == NULL
668             || pctx->operation != EVP_PKEY_OP_VERIFYCTX
669             || pctx->op.sig.algctx == NULL
670             || pctx->op.sig.signature == NULL)
671         goto legacy;
672 
673 #ifndef FIPS_MODULE
674     if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISE) == 0) {
675         /* try dup */
676         dctx = EVP_PKEY_CTX_dup(pctx);
677         if (dctx != NULL)
678             pctx = dctx;
679     }
680 #endif
681     r = pctx->op.sig.signature->digest_verify_final(pctx->op.sig.algctx,
682                                                     sig, siglen);
683     if (dctx == NULL)
684         ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
685     else
686         EVP_PKEY_CTX_free(dctx);
687     return r;
688 
689  legacy:
690 #ifdef FIPS_MODULE
691     ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
692     return 0;
693 #else
694     if (pctx == NULL || pctx->pmeth == NULL) {
695         ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
696         return 0;
697     }
698 
699     /* do_sigver_init() checked that |digest_custom| is non-NULL */
700     if (pctx->flag_call_digest_custom
701         && !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx))
702         return 0;
703     pctx->flag_call_digest_custom = 0;
704 
705     if (pctx->pmeth->verifyctx != NULL)
706         vctx = 1;
707     else
708         vctx = 0;
709     if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
710         if (vctx) {
711             r = pctx->pmeth->verifyctx(pctx, sig, siglen, ctx);
712             ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
713         } else
714             r = EVP_DigestFinal_ex(ctx, md, &mdlen);
715     } else {
716         EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
717         if (tmp_ctx == NULL)
718             return -1;
719         if (!EVP_MD_CTX_copy_ex(tmp_ctx, ctx)) {
720             EVP_MD_CTX_free(tmp_ctx);
721             return -1;
722         }
723         if (vctx)
724             r = tmp_ctx->pctx->pmeth->verifyctx(tmp_ctx->pctx,
725                                                 sig, siglen, tmp_ctx);
726         else
727             r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen);
728         EVP_MD_CTX_free(tmp_ctx);
729     }
730     if (vctx || !r)
731         return r;
732     return EVP_PKEY_verify(pctx, sig, siglen, md, mdlen);
733 #endif
734 }
735 
EVP_DigestVerify(EVP_MD_CTX * ctx,const unsigned char * sigret,size_t siglen,const unsigned char * tbs,size_t tbslen)736 int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
737                      size_t siglen, const unsigned char *tbs, size_t tbslen)
738 {
739     EVP_PKEY_CTX *pctx = ctx->pctx;
740 
741     if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
742         ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
743         return 0;
744     }
745 
746     if (pctx != NULL
747             && pctx->operation == EVP_PKEY_OP_VERIFYCTX
748             && pctx->op.sig.algctx != NULL
749             && pctx->op.sig.signature != NULL) {
750         if (pctx->op.sig.signature->digest_verify != NULL) {
751             ctx->flags |= EVP_MD_CTX_FLAG_FINALISED;
752             return pctx->op.sig.signature->digest_verify(pctx->op.sig.algctx,
753                                                          sigret, siglen,
754                                                          tbs, tbslen);
755         }
756 #ifdef FIPS_MODULE
757     }
758     ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
759     return 0;
760 #else
761     } else {
762         /* legacy */
763         if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestverify != NULL)
764             return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen, tbs, tbslen);
765     }
766     if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0)
767         return -1;
768     return EVP_DigestVerifyFinal(ctx, sigret, siglen);
769 #endif
770 }
771