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