2016-05-18 02:24:46 +08:00
|
|
|
/*
|
2019-04-11 18:27:59 +08:00
|
|
|
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
2001-09-10 22:59:17 +08:00
|
|
|
*
|
2018-12-06 20:40:06 +08:00
|
|
|
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
2016-05-18 02:24:46 +08:00
|
|
|
* this file except in compliance with the License. You can obtain a copy
|
|
|
|
* in the file LICENSE in the source distribution or at
|
|
|
|
* https://www.openssl.org/source/license.html
|
2001-09-10 22:59:17 +08:00
|
|
|
*/
|
1998-12-21 18:52:47 +08:00
|
|
|
|
|
|
|
#include <stdio.h>
|
1999-04-24 06:13:45 +08:00
|
|
|
#include <openssl/objects.h>
|
|
|
|
#include <openssl/evp.h>
|
2016-03-19 02:30:20 +08:00
|
|
|
#include <openssl/engine.h>
|
2019-04-11 18:27:59 +08:00
|
|
|
#include <openssl/params.h>
|
|
|
|
#include <openssl/core_names.h>
|
|
|
|
#include "internal/cryptlib.h"
|
2019-09-28 06:45:33 +08:00
|
|
|
#include "crypto/evp.h"
|
2019-03-13 22:49:40 +08:00
|
|
|
#include "internal/provider.h"
|
2019-09-28 06:45:40 +08:00
|
|
|
#include "evp_local.h"
|
1998-12-21 18:52:47 +08:00
|
|
|
|
2015-12-01 08:38:35 +08:00
|
|
|
/* This call frees resources associated with the context */
|
2015-12-02 07:26:19 +08:00
|
|
|
int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
2015-12-01 08:38:35 +08:00
|
|
|
if (ctx == NULL)
|
|
|
|
return 1;
|
|
|
|
|
2019-09-24 17:23:41 +08:00
|
|
|
#ifndef FIPS_MODE
|
|
|
|
/* TODO(3.0): Temporarily no support for EVP_DigestSign* in FIPS module */
|
|
|
|
/*
|
|
|
|
* pctx should be freed by the user of EVP_MD_CTX
|
|
|
|
* if EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set
|
|
|
|
*/
|
|
|
|
if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX))
|
|
|
|
EVP_PKEY_CTX_free(ctx->pctx);
|
|
|
|
#endif
|
|
|
|
|
2019-09-26 21:55:00 +08:00
|
|
|
EVP_MD_free(ctx->fetched_digest);
|
|
|
|
ctx->fetched_digest = NULL;
|
|
|
|
ctx->reqdigest = NULL;
|
2019-03-14 00:17:17 +08:00
|
|
|
|
|
|
|
if (ctx->provctx != NULL) {
|
|
|
|
if (ctx->digest->freectx != NULL)
|
|
|
|
ctx->digest->freectx(ctx->provctx);
|
|
|
|
ctx->provctx = NULL;
|
|
|
|
EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO(3.0): Remove legacy code below */
|
|
|
|
|
2015-12-01 08:38:35 +08:00
|
|
|
/*
|
|
|
|
* Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
|
|
|
|
* sometimes only copies of the context are ever finalised.
|
|
|
|
*/
|
|
|
|
if (ctx->digest && ctx->digest->cleanup
|
|
|
|
&& !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
|
|
|
|
ctx->digest->cleanup(ctx);
|
|
|
|
if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
|
|
|
|
&& !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) {
|
|
|
|
OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
|
|
|
|
}
|
2019-05-13 13:41:06 +08:00
|
|
|
|
2019-09-24 17:23:41 +08:00
|
|
|
#if !defined(FIPS_MODE) && !defined(OPENSSL_NO_ENGINE)
|
2016-02-26 01:09:06 +08:00
|
|
|
ENGINE_finish(ctx->engine);
|
2015-12-01 08:38:35 +08:00
|
|
|
#endif
|
2019-09-26 21:55:00 +08:00
|
|
|
|
|
|
|
/* TODO(3.0): End of legacy code */
|
|
|
|
|
2016-06-25 06:37:27 +08:00
|
|
|
OPENSSL_cleanse(ctx, sizeof(*ctx));
|
2015-12-01 08:38:35 +08:00
|
|
|
|
|
|
|
return 1;
|
2015-01-22 11:40:55 +08:00
|
|
|
}
|
2001-07-31 07:57:25 +08:00
|
|
|
|
2015-12-02 07:26:19 +08:00
|
|
|
EVP_MD_CTX *EVP_MD_CTX_new(void)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
2015-12-01 08:38:35 +08:00
|
|
|
return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
|
|
|
|
}
|
2001-07-31 07:57:25 +08:00
|
|
|
|
2015-12-02 07:26:19 +08:00
|
|
|
void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
|
2015-12-01 08:38:35 +08:00
|
|
|
{
|
2019-03-14 00:17:17 +08:00
|
|
|
if (ctx == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
EVP_MD_CTX_reset(ctx);
|
|
|
|
|
|
|
|
OPENSSL_free(ctx);
|
|
|
|
return;
|
2015-01-22 11:40:55 +08:00
|
|
|
}
|
2001-07-31 07:57:25 +08:00
|
|
|
|
2001-03-08 22:04:22 +08:00
|
|
|
int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
2015-12-02 07:26:19 +08:00
|
|
|
EVP_MD_CTX_reset(ctx);
|
2015-01-22 11:40:55 +08:00
|
|
|
return EVP_DigestInit_ex(ctx, type, NULL);
|
|
|
|
}
|
2001-09-26 23:15:03 +08:00
|
|
|
|
2001-09-26 05:37:02 +08:00
|
|
|
int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
2019-05-13 13:41:06 +08:00
|
|
|
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
|
2019-03-14 00:17:17 +08:00
|
|
|
ENGINE *tmpimpl = NULL;
|
2019-05-13 13:41:06 +08:00
|
|
|
#endif
|
2019-03-14 00:17:17 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
|
2019-03-14 00:17:17 +08:00
|
|
|
|
2019-09-26 21:31:56 +08:00
|
|
|
if (ctx->provctx != NULL) {
|
|
|
|
if (!ossl_assert(ctx->digest != NULL)) {
|
|
|
|
EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (ctx->digest->freectx != NULL)
|
|
|
|
ctx->digest->freectx(ctx->provctx);
|
|
|
|
ctx->provctx = NULL;
|
|
|
|
}
|
|
|
|
|
2019-03-30 00:28:07 +08:00
|
|
|
if (type != NULL)
|
|
|
|
ctx->reqdigest = type;
|
|
|
|
|
2019-03-14 00:17:17 +08:00
|
|
|
/* TODO(3.0): Legacy work around code below. Remove this */
|
2019-05-13 13:41:06 +08:00
|
|
|
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
|
2015-01-22 11:40:55 +08:00
|
|
|
/*
|
|
|
|
* Whether it's nice or not, "Inits" can be used on "Final"'d contexts so
|
|
|
|
* this context may already have an ENGINE! Try to avoid releasing the
|
|
|
|
* previous handle, re-querying for an ENGINE, and having a
|
2016-02-06 04:23:54 +08:00
|
|
|
* reinitialisation, when it may all be unnecessary.
|
2015-01-22 11:40:55 +08:00
|
|
|
*/
|
2016-05-24 02:07:47 +08:00
|
|
|
if (ctx->engine && ctx->digest &&
|
|
|
|
(type == NULL || (type->type == ctx->digest->type)))
|
2015-01-22 11:40:55 +08:00
|
|
|
goto skip_to_init;
|
2019-03-14 00:17:17 +08:00
|
|
|
|
2019-06-04 22:15:46 +08:00
|
|
|
if (type != NULL) {
|
|
|
|
/*
|
|
|
|
* Ensure an ENGINE left lying around from last time is cleared (the
|
|
|
|
* previous check attempted to avoid this if the same ENGINE and
|
|
|
|
* EVP_MD could be used).
|
|
|
|
*/
|
|
|
|
ENGINE_finish(ctx->engine);
|
|
|
|
ctx->engine = NULL;
|
|
|
|
}
|
|
|
|
|
2019-03-14 00:17:17 +08:00
|
|
|
if (type != NULL && impl == NULL)
|
|
|
|
tmpimpl = ENGINE_get_digest_engine(type->type);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
2019-10-03 19:44:55 +08:00
|
|
|
* If there are engines involved or EVP_MD_CTX_FLAG_NO_INIT is set then we
|
|
|
|
* should use legacy handling for now.
|
2019-03-14 00:17:17 +08:00
|
|
|
*/
|
|
|
|
if (ctx->engine != NULL
|
|
|
|
|| impl != NULL
|
2019-05-13 13:41:06 +08:00
|
|
|
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
|
2019-03-14 00:17:17 +08:00
|
|
|
|| tmpimpl != NULL
|
2019-05-13 13:41:06 +08:00
|
|
|
#endif
|
2019-03-14 00:17:17 +08:00
|
|
|
|| (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0) {
|
|
|
|
if (ctx->digest == ctx->fetched_digest)
|
|
|
|
ctx->digest = NULL;
|
2019-09-03 23:47:13 +08:00
|
|
|
EVP_MD_free(ctx->fetched_digest);
|
2019-03-14 00:17:17 +08:00
|
|
|
ctx->fetched_digest = NULL;
|
|
|
|
goto legacy;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ctx->digest != NULL && ctx->digest->ctx_size > 0) {
|
|
|
|
OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
|
|
|
|
ctx->md_data = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO(3.0): Start of non-legacy code below */
|
|
|
|
|
|
|
|
if (type->prov == NULL) {
|
2019-05-13 13:41:06 +08:00
|
|
|
#ifdef FIPS_MODE
|
2019-12-01 07:18:47 +08:00
|
|
|
/* We only do explicit fetches inside the FIPS module */
|
2019-05-13 13:41:06 +08:00
|
|
|
EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
|
|
|
|
return 0;
|
|
|
|
#else
|
|
|
|
EVP_MD *provmd = EVP_MD_fetch(NULL, OBJ_nid2sn(type->type), "");
|
|
|
|
|
2019-03-14 00:17:17 +08:00
|
|
|
if (provmd == NULL) {
|
|
|
|
EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
type = provmd;
|
2019-09-03 23:47:13 +08:00
|
|
|
EVP_MD_free(ctx->fetched_digest);
|
2019-03-14 00:17:17 +08:00
|
|
|
ctx->fetched_digest = provmd;
|
2019-05-13 13:41:06 +08:00
|
|
|
#endif
|
2019-03-14 00:17:17 +08:00
|
|
|
}
|
|
|
|
|
2019-04-11 18:27:59 +08:00
|
|
|
if (ctx->provctx != NULL && ctx->digest != NULL && ctx->digest != type) {
|
|
|
|
if (ctx->digest->freectx != NULL)
|
|
|
|
ctx->digest->freectx(ctx->provctx);
|
|
|
|
ctx->provctx = NULL;
|
|
|
|
}
|
2019-03-14 00:17:17 +08:00
|
|
|
ctx->digest = type;
|
|
|
|
if (ctx->provctx == NULL) {
|
2019-04-30 19:41:51 +08:00
|
|
|
ctx->provctx = ctx->digest->newctx(ossl_provider_ctx(type->prov));
|
2019-03-14 00:17:17 +08:00
|
|
|
if (ctx->provctx == NULL) {
|
|
|
|
EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ctx->digest->dinit == NULL) {
|
|
|
|
EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ctx->digest->dinit(ctx->provctx);
|
|
|
|
|
|
|
|
/* TODO(3.0): Remove legacy code below */
|
|
|
|
legacy:
|
|
|
|
|
2019-05-13 13:41:06 +08:00
|
|
|
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
|
2015-01-22 11:40:55 +08:00
|
|
|
if (type) {
|
2016-02-26 01:09:06 +08:00
|
|
|
if (impl != NULL) {
|
2015-01-22 11:40:55 +08:00
|
|
|
if (!ENGINE_init(impl)) {
|
|
|
|
EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
|
|
|
|
return 0;
|
|
|
|
}
|
2016-02-26 01:09:06 +08:00
|
|
|
} else {
|
2015-01-22 11:40:55 +08:00
|
|
|
/* Ask if an ENGINE is reserved for this job */
|
2019-03-14 00:17:17 +08:00
|
|
|
impl = tmpimpl;
|
2016-02-26 01:09:06 +08:00
|
|
|
}
|
|
|
|
if (impl != NULL) {
|
2015-01-22 11:40:55 +08:00
|
|
|
/* There's an ENGINE for this job ... (apparently) */
|
|
|
|
const EVP_MD *d = ENGINE_get_digest(impl, type->type);
|
2016-02-26 01:09:06 +08:00
|
|
|
|
|
|
|
if (d == NULL) {
|
2015-01-22 11:40:55 +08:00
|
|
|
EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
|
|
|
|
ENGINE_finish(impl);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* We'll use the ENGINE's private digest definition */
|
|
|
|
type = d;
|
|
|
|
/*
|
|
|
|
* Store the ENGINE functional reference so we know 'type' came
|
|
|
|
* from an ENGINE and we need to release it when done.
|
|
|
|
*/
|
|
|
|
ctx->engine = impl;
|
|
|
|
} else
|
|
|
|
ctx->engine = NULL;
|
2015-03-11 23:41:52 +08:00
|
|
|
} else {
|
|
|
|
if (!ctx->digest) {
|
|
|
|
EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_NO_DIGEST_SET);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
type = ctx->digest;
|
2015-01-22 11:40:55 +08:00
|
|
|
}
|
2003-03-12 10:31:40 +08:00
|
|
|
#endif
|
2015-01-22 11:40:55 +08:00
|
|
|
if (ctx->digest != type) {
|
2016-03-15 01:06:19 +08:00
|
|
|
if (ctx->digest && ctx->digest->ctx_size) {
|
2016-05-24 02:07:47 +08:00
|
|
|
OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
|
2016-03-15 01:06:19 +08:00
|
|
|
ctx->md_data = NULL;
|
|
|
|
}
|
2015-01-22 11:40:55 +08:00
|
|
|
ctx->digest = type;
|
|
|
|
if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
|
|
|
|
ctx->update = type->update;
|
2016-01-22 03:53:18 +08:00
|
|
|
ctx->md_data = OPENSSL_zalloc(type->ctx_size);
|
2015-01-22 11:40:55 +08:00
|
|
|
if (ctx->md_data == NULL) {
|
|
|
|
EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-05-13 13:41:06 +08:00
|
|
|
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
|
2015-01-22 11:40:55 +08:00
|
|
|
skip_to_init:
|
2003-01-31 01:39:26 +08:00
|
|
|
#endif
|
2019-05-13 13:41:06 +08:00
|
|
|
#ifndef FIPS_MODE
|
2019-08-30 20:33:10 +08:00
|
|
|
/*
|
|
|
|
* TODO(3.0): Temporarily no support for EVP_DigestSign* inside FIPS module
|
|
|
|
* or when using providers.
|
|
|
|
*/
|
2019-09-05 06:13:25 +08:00
|
|
|
if (ctx->pctx != NULL
|
|
|
|
&& (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx)
|
|
|
|
|| ctx->pctx->op.sig.signature == NULL)) {
|
2015-01-22 11:40:55 +08:00
|
|
|
int r;
|
|
|
|
r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
|
|
|
|
EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
|
|
|
|
if (r <= 0 && (r != -2))
|
|
|
|
return 0;
|
|
|
|
}
|
2019-05-13 13:41:06 +08:00
|
|
|
#endif
|
2015-01-22 11:40:55 +08:00
|
|
|
if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
|
|
|
|
return 1;
|
|
|
|
return ctx->digest->init(ctx);
|
|
|
|
}
|
1998-12-21 18:52:47 +08:00
|
|
|
|
2008-11-04 20:06:09 +08:00
|
|
|
int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
2019-03-26 23:25:15 +08:00
|
|
|
if (count == 0)
|
|
|
|
return 1;
|
|
|
|
|
2019-10-08 00:47:04 +08:00
|
|
|
if (ctx->pctx != NULL
|
|
|
|
&& EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx)
|
|
|
|
&& ctx->pctx->op.sig.sigprovctx != NULL) {
|
|
|
|
/*
|
|
|
|
* Prior to OpenSSL 3.0 EVP_DigestSignUpdate() and
|
|
|
|
* EVP_DigestVerifyUpdate() were just macros for EVP_DigestUpdate().
|
|
|
|
* Some code calls EVP_DigestUpdate() directly even when initialised
|
|
|
|
* with EVP_DigestSignInit_ex() or EVP_DigestVerifyInit_ex(), so we
|
|
|
|
* detect that and redirect to the correct EVP_Digest*Update() function
|
|
|
|
*/
|
|
|
|
if (ctx->pctx->operation == EVP_PKEY_OP_SIGNCTX)
|
|
|
|
return EVP_DigestSignUpdate(ctx, data, count);
|
|
|
|
if (ctx->pctx->operation == EVP_PKEY_OP_VERIFYCTX)
|
|
|
|
return EVP_DigestVerifyUpdate(ctx, data, count);
|
|
|
|
EVPerr(EVP_F_EVP_DIGESTUPDATE, EVP_R_UPDATE_ERROR);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-03-14 00:17:17 +08:00
|
|
|
if (ctx->digest == NULL || ctx->digest->prov == NULL)
|
|
|
|
goto legacy;
|
|
|
|
|
|
|
|
if (ctx->digest->dupdate == NULL) {
|
|
|
|
EVPerr(EVP_F_EVP_DIGESTUPDATE, EVP_R_UPDATE_ERROR);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return ctx->digest->dupdate(ctx->provctx, data, count);
|
|
|
|
|
|
|
|
/* TODO(3.0): Remove legacy code below */
|
|
|
|
legacy:
|
2015-01-22 11:40:55 +08:00
|
|
|
return ctx->update(ctx, data, count);
|
|
|
|
}
|
1998-12-21 18:52:47 +08:00
|
|
|
|
2001-07-31 07:57:25 +08:00
|
|
|
/* The caller can assume that this removes any secret data from the context */
|
2001-03-08 22:04:22 +08:00
|
|
|
int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
ret = EVP_DigestFinal_ex(ctx, md, size);
|
2015-12-02 07:26:19 +08:00
|
|
|
EVP_MD_CTX_reset(ctx);
|
2015-01-22 11:40:55 +08:00
|
|
|
return ret;
|
|
|
|
}
|
2001-10-16 09:24:29 +08:00
|
|
|
|
|
|
|
/* The caller can assume that this removes any secret data from the context */
|
2019-03-14 00:17:17 +08:00
|
|
|
int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
|
|
|
int ret;
|
2019-03-14 00:17:17 +08:00
|
|
|
size_t size = 0;
|
2019-04-15 15:37:51 +08:00
|
|
|
size_t mdsize = EVP_MD_size(ctx->digest);
|
2019-03-14 00:17:17 +08:00
|
|
|
|
|
|
|
if (ctx->digest == NULL || ctx->digest->prov == NULL)
|
|
|
|
goto legacy;
|
2002-11-13 23:43:43 +08:00
|
|
|
|
2019-03-14 00:17:17 +08:00
|
|
|
if (ctx->digest->dfinal == NULL) {
|
|
|
|
EVPerr(EVP_F_EVP_DIGESTFINAL_EX, EVP_R_FINAL_ERROR);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-04-15 15:37:51 +08:00
|
|
|
ret = ctx->digest->dfinal(ctx->provctx, md, &size, mdsize);
|
2019-03-14 00:17:17 +08:00
|
|
|
|
|
|
|
if (isize != NULL) {
|
|
|
|
if (size <= UINT_MAX) {
|
|
|
|
*isize = (int)size;
|
|
|
|
} else {
|
|
|
|
EVPerr(EVP_F_EVP_DIGESTFINAL_EX, EVP_R_FINAL_ERROR);
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
/* TODO(3.0): Remove legacy code below */
|
|
|
|
legacy:
|
2019-04-15 15:37:51 +08:00
|
|
|
OPENSSL_assert(mdsize <= EVP_MAX_MD_SIZE);
|
2015-01-22 11:40:55 +08:00
|
|
|
ret = ctx->digest->final(ctx, md);
|
2019-03-14 00:17:17 +08:00
|
|
|
if (isize != NULL)
|
2019-04-15 15:37:51 +08:00
|
|
|
*isize = mdsize;
|
2015-01-22 11:40:55 +08:00
|
|
|
if (ctx->digest->cleanup) {
|
|
|
|
ctx->digest->cleanup(ctx);
|
|
|
|
EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
|
|
|
|
}
|
2016-06-25 06:37:27 +08:00
|
|
|
OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
|
2015-01-22 11:40:55 +08:00
|
|
|
return ret;
|
|
|
|
}
|
1999-01-31 20:14:39 +08:00
|
|
|
|
2017-08-11 04:39:40 +08:00
|
|
|
int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t size)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
2019-04-11 18:27:59 +08:00
|
|
|
OSSL_PARAM params[2];
|
|
|
|
size_t i = 0;
|
|
|
|
|
|
|
|
if (ctx->digest == NULL || ctx->digest->prov == NULL)
|
|
|
|
goto legacy;
|
2017-08-11 04:39:40 +08:00
|
|
|
|
2019-04-11 18:27:59 +08:00
|
|
|
if (ctx->digest->dfinal == NULL) {
|
|
|
|
EVPerr(EVP_F_EVP_DIGESTFINALXOF, EVP_R_FINAL_ERROR);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-06-24 12:43:55 +08:00
|
|
|
params[i++] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &size);
|
2019-04-11 18:27:59 +08:00
|
|
|
params[i++] = OSSL_PARAM_construct_end();
|
|
|
|
|
|
|
|
if (EVP_MD_CTX_set_params(ctx, params) > 0)
|
|
|
|
ret = ctx->digest->dfinal(ctx->provctx, md, &size, size);
|
|
|
|
EVP_MD_CTX_reset(ctx);
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
legacy:
|
2017-08-11 04:39:40 +08:00
|
|
|
if (ctx->digest->flags & EVP_MD_FLAG_XOF
|
|
|
|
&& size <= INT_MAX
|
|
|
|
&& ctx->digest->md_ctrl(ctx, EVP_MD_CTRL_XOF_LEN, (int)size, NULL)) {
|
|
|
|
ret = ctx->digest->final(ctx, md);
|
|
|
|
if (ctx->digest->cleanup != NULL) {
|
|
|
|
ctx->digest->cleanup(ctx);
|
|
|
|
EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
|
|
|
|
}
|
|
|
|
OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
|
|
|
|
} else {
|
|
|
|
EVPerr(EVP_F_EVP_DIGESTFINALXOF, EVP_R_NOT_XOF_OR_INVALID_LENGTH);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2001-07-31 07:57:25 +08:00
|
|
|
int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
2015-12-02 07:26:19 +08:00
|
|
|
EVP_MD_CTX_reset(out);
|
2015-01-22 11:40:55 +08:00
|
|
|
return EVP_MD_CTX_copy_ex(out, in);
|
|
|
|
}
|
2001-10-16 09:24:29 +08:00
|
|
|
|
|
|
|
int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
|
2015-01-22 11:40:55 +08:00
|
|
|
{
|
|
|
|
unsigned char *tmp_buf;
|
2019-03-14 00:17:17 +08:00
|
|
|
|
|
|
|
if (in == NULL || in->digest == NULL) {
|
2015-01-22 11:40:55 +08:00
|
|
|
EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_INPUT_NOT_INITIALIZED);
|
|
|
|
return 0;
|
|
|
|
}
|
2019-03-14 00:17:17 +08:00
|
|
|
|
|
|
|
if (in->digest->prov == NULL)
|
|
|
|
goto legacy;
|
|
|
|
|
|
|
|
if (in->digest->dupctx == NULL) {
|
|
|
|
EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_NOT_ABLE_TO_COPY_CTX);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
EVP_MD_CTX_reset(out);
|
|
|
|
if (out->fetched_digest != NULL)
|
2019-09-03 23:47:13 +08:00
|
|
|
EVP_MD_free(out->fetched_digest);
|
2019-03-14 00:17:17 +08:00
|
|
|
*out = *in;
|
|
|
|
/* NULL out pointers in case of error */
|
|
|
|
out->pctx = NULL;
|
|
|
|
out->provctx = NULL;
|
|
|
|
|
|
|
|
if (in->fetched_digest != NULL)
|
2019-06-25 00:38:01 +08:00
|
|
|
EVP_MD_up_ref(in->fetched_digest);
|
2019-03-14 00:17:17 +08:00
|
|
|
|
|
|
|
out->provctx = in->digest->dupctx(in->provctx);
|
|
|
|
if (out->provctx == NULL) {
|
|
|
|
EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_NOT_ABLE_TO_COPY_CTX);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* copied EVP_MD_CTX should free the copied EVP_PKEY_CTX */
|
|
|
|
EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
|
2019-05-13 13:41:06 +08:00
|
|
|
#ifndef FIPS_MODE
|
|
|
|
/* TODO(3.0): Temporarily no support for EVP_DigestSign* in FIPS module */
|
2019-03-14 00:17:17 +08:00
|
|
|
if (in->pctx != NULL) {
|
|
|
|
out->pctx = EVP_PKEY_CTX_dup(in->pctx);
|
|
|
|
if (out->pctx == NULL) {
|
|
|
|
EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_NOT_ABLE_TO_COPY_CTX);
|
|
|
|
EVP_MD_CTX_reset(out);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2019-05-13 13:41:06 +08:00
|
|
|
#endif
|
2019-03-14 00:17:17 +08:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
/* TODO(3.0): Remove legacy code below */
|
|
|
|
legacy:
|
2019-05-13 13:41:06 +08:00
|
|
|
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
|
2015-01-22 11:40:55 +08:00
|
|
|
/* Make sure it's safe to copy a digest context using an ENGINE */
|
|
|
|
if (in->engine && !ENGINE_init(in->engine)) {
|
|
|
|
EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_ENGINE_LIB);
|
|
|
|
return 0;
|
|
|
|
}
|
2003-01-31 01:39:26 +08:00
|
|
|
#endif
|
2001-09-03 04:05:27 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
if (out->digest == in->digest) {
|
|
|
|
tmp_buf = out->md_data;
|
|
|
|
EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE);
|
|
|
|
} else
|
|
|
|
tmp_buf = NULL;
|
2015-12-02 07:26:19 +08:00
|
|
|
EVP_MD_CTX_reset(out);
|
2015-05-02 11:10:31 +08:00
|
|
|
memcpy(out, in, sizeof(*out));
|
2015-01-22 11:40:55 +08:00
|
|
|
|
2018-09-04 17:21:10 +08:00
|
|
|
/* copied EVP_MD_CTX should free the copied EVP_PKEY_CTX */
|
|
|
|
EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
|
|
|
|
|
2015-12-18 20:03:45 +08:00
|
|
|
/* Null these variables, since they are getting fixed up
|
|
|
|
* properly below. Anything else may cause a memleak and/or
|
|
|
|
* double free if any of the memory allocations below fail
|
|
|
|
*/
|
|
|
|
out->md_data = NULL;
|
|
|
|
out->pctx = NULL;
|
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
if (in->md_data && out->digest->ctx_size) {
|
|
|
|
if (tmp_buf)
|
|
|
|
out->md_data = tmp_buf;
|
|
|
|
else {
|
|
|
|
out->md_data = OPENSSL_malloc(out->digest->ctx_size);
|
2015-10-30 19:12:26 +08:00
|
|
|
if (out->md_data == NULL) {
|
2015-01-22 11:40:55 +08:00
|
|
|
EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_MALLOC_FAILURE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
memcpy(out->md_data, in->md_data, out->digest->ctx_size);
|
|
|
|
}
|
2001-09-03 04:05:27 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
out->update = in->update;
|
2004-02-01 21:39:51 +08:00
|
|
|
|
2019-05-13 13:41:06 +08:00
|
|
|
#ifndef FIPS_MODE
|
|
|
|
/* TODO(3.0): Temporarily no support for EVP_DigestSign* in FIPS module */
|
2015-01-22 11:40:55 +08:00
|
|
|
if (in->pctx) {
|
|
|
|
out->pctx = EVP_PKEY_CTX_dup(in->pctx);
|
|
|
|
if (!out->pctx) {
|
2015-12-02 07:26:19 +08:00
|
|
|
EVP_MD_CTX_reset(out);
|
2015-01-22 11:40:55 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2019-05-13 13:41:06 +08:00
|
|
|
#endif
|
2007-04-12 21:02:31 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
if (out->digest->copy)
|
|
|
|
return out->digest->copy(out, in);
|
2006-05-25 08:55:00 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
return 1;
|
|
|
|
}
|
2001-02-02 08:45:54 +08:00
|
|
|
|
2004-05-15 19:29:55 +08:00
|
|
|
int EVP_Digest(const void *data, size_t count,
|
2015-01-22 11:40:55 +08:00
|
|
|
unsigned char *md, unsigned int *size, const EVP_MD *type,
|
|
|
|
ENGINE *impl)
|
|
|
|
{
|
2015-12-02 07:49:35 +08:00
|
|
|
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
|
2015-01-22 11:40:55 +08:00
|
|
|
int ret;
|
2001-07-31 07:57:25 +08:00
|
|
|
|
2015-12-01 08:38:35 +08:00
|
|
|
if (ctx == NULL)
|
|
|
|
return 0;
|
|
|
|
EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT);
|
|
|
|
ret = EVP_DigestInit_ex(ctx, type, impl)
|
|
|
|
&& EVP_DigestUpdate(ctx, data, count)
|
|
|
|
&& EVP_DigestFinal_ex(ctx, md, size);
|
2015-12-02 07:49:35 +08:00
|
|
|
EVP_MD_CTX_free(ctx);
|
2001-07-31 07:57:25 +08:00
|
|
|
|
2015-01-22 11:40:55 +08:00
|
|
|
return ret;
|
|
|
|
}
|
2001-07-31 07:57:25 +08:00
|
|
|
|
Add missing EVP param utility functions
These functions were missing for a completes API:
EVP_MD_get_params(), EVP_CIPHER_get_params(), EVP_CIPHER_CTX_set_params(),
and EVP_CIPHER_CTX_get_params
Additionally, we also add all the corresponding parameter descriptor
returning functions, along the correspoding provider dispatches:
EVP_MD_gettable_params(), EVP_MD_CTX_settable_params(),
EVP_MD_CTX_gettable_params(), EVP_CIPHER_gettable_params(),
EVP_CIPHER_CTX_settable_params(), and EVP_CIPHER_CTX_gettable_params()
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9576)
2019-08-12 20:56:18 +08:00
|
|
|
int EVP_MD_get_params(const EVP_MD *digest, OSSL_PARAM params[])
|
|
|
|
{
|
|
|
|
if (digest != NULL && digest->get_params != NULL)
|
|
|
|
return digest->get_params(params);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const OSSL_PARAM *EVP_MD_gettable_params(const EVP_MD *digest)
|
|
|
|
{
|
|
|
|
if (digest != NULL && digest->gettable_params != NULL)
|
|
|
|
return digest->gettable_params();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2019-04-11 18:27:59 +08:00
|
|
|
int EVP_MD_CTX_set_params(EVP_MD_CTX *ctx, const OSSL_PARAM params[])
|
|
|
|
{
|
2019-09-24 19:07:48 +08:00
|
|
|
EVP_PKEY_CTX *pctx = ctx->pctx;
|
|
|
|
|
2019-08-16 15:04:29 +08:00
|
|
|
if (ctx->digest != NULL && ctx->digest->set_ctx_params != NULL)
|
|
|
|
return ctx->digest->set_ctx_params(ctx->provctx, params);
|
2019-09-24 19:07:48 +08:00
|
|
|
|
|
|
|
if (pctx != NULL
|
|
|
|
&& (pctx->operation == EVP_PKEY_OP_VERIFYCTX
|
|
|
|
|| pctx->operation == EVP_PKEY_OP_SIGNCTX)
|
|
|
|
&& pctx->op.sig.sigprovctx != NULL
|
|
|
|
&& pctx->op.sig.signature->set_ctx_md_params != NULL)
|
|
|
|
return pctx->op.sig.signature->set_ctx_md_params(pctx->op.sig.sigprovctx,
|
|
|
|
params);
|
2019-04-11 18:27:59 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-09-24 22:17:15 +08:00
|
|
|
const OSSL_PARAM *EVP_MD_settable_ctx_params(const EVP_MD *md)
|
Add missing EVP param utility functions
These functions were missing for a completes API:
EVP_MD_get_params(), EVP_CIPHER_get_params(), EVP_CIPHER_CTX_set_params(),
and EVP_CIPHER_CTX_get_params
Additionally, we also add all the corresponding parameter descriptor
returning functions, along the correspoding provider dispatches:
EVP_MD_gettable_params(), EVP_MD_CTX_settable_params(),
EVP_MD_CTX_gettable_params(), EVP_CIPHER_gettable_params(),
EVP_CIPHER_CTX_settable_params(), and EVP_CIPHER_CTX_gettable_params()
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9576)
2019-08-12 20:56:18 +08:00
|
|
|
{
|
2019-09-24 22:17:15 +08:00
|
|
|
if (md != NULL && md->settable_ctx_params != NULL)
|
|
|
|
return md->settable_ctx_params();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const OSSL_PARAM *EVP_MD_CTX_settable_params(EVP_MD_CTX *ctx)
|
|
|
|
{
|
2019-09-24 19:07:48 +08:00
|
|
|
EVP_PKEY_CTX *pctx;
|
|
|
|
|
2019-09-24 22:17:15 +08:00
|
|
|
if (ctx != NULL
|
|
|
|
&& ctx->digest != NULL
|
|
|
|
&& ctx->digest->settable_ctx_params != NULL)
|
|
|
|
return ctx->digest->settable_ctx_params();
|
|
|
|
|
2019-09-24 19:07:48 +08:00
|
|
|
pctx = ctx->pctx;
|
|
|
|
if (pctx != NULL
|
|
|
|
&& (pctx->operation == EVP_PKEY_OP_VERIFYCTX
|
|
|
|
|| pctx->operation == EVP_PKEY_OP_SIGNCTX)
|
|
|
|
&& pctx->op.sig.sigprovctx != NULL
|
|
|
|
&& pctx->op.sig.signature->settable_ctx_md_params != NULL)
|
|
|
|
return pctx->op.sig.signature->settable_ctx_md_params(
|
|
|
|
pctx->op.sig.sigprovctx);
|
|
|
|
|
Add missing EVP param utility functions
These functions were missing for a completes API:
EVP_MD_get_params(), EVP_CIPHER_get_params(), EVP_CIPHER_CTX_set_params(),
and EVP_CIPHER_CTX_get_params
Additionally, we also add all the corresponding parameter descriptor
returning functions, along the correspoding provider dispatches:
EVP_MD_gettable_params(), EVP_MD_CTX_settable_params(),
EVP_MD_CTX_gettable_params(), EVP_CIPHER_gettable_params(),
EVP_CIPHER_CTX_settable_params(), and EVP_CIPHER_CTX_gettable_params()
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9576)
2019-08-12 20:56:18 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2019-06-24 12:43:55 +08:00
|
|
|
int EVP_MD_CTX_get_params(EVP_MD_CTX *ctx, OSSL_PARAM params[])
|
2019-04-11 18:27:59 +08:00
|
|
|
{
|
2019-09-24 19:07:48 +08:00
|
|
|
EVP_PKEY_CTX *pctx = ctx->pctx;
|
|
|
|
|
2019-04-11 18:27:59 +08:00
|
|
|
if (ctx->digest != NULL && ctx->digest->get_params != NULL)
|
2019-08-16 15:04:29 +08:00
|
|
|
return ctx->digest->get_ctx_params(ctx->provctx, params);
|
2019-09-24 19:07:48 +08:00
|
|
|
|
|
|
|
if (pctx != NULL
|
|
|
|
&& (pctx->operation == EVP_PKEY_OP_VERIFYCTX
|
|
|
|
|| pctx->operation == EVP_PKEY_OP_SIGNCTX)
|
|
|
|
&& pctx->op.sig.sigprovctx != NULL
|
|
|
|
&& pctx->op.sig.signature->get_ctx_md_params != NULL)
|
|
|
|
return pctx->op.sig.signature->get_ctx_md_params(pctx->op.sig.sigprovctx,
|
|
|
|
params);
|
|
|
|
|
2019-04-11 18:27:59 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-09-24 22:17:15 +08:00
|
|
|
const OSSL_PARAM *EVP_MD_gettable_ctx_params(const EVP_MD *md)
|
Add missing EVP param utility functions
These functions were missing for a completes API:
EVP_MD_get_params(), EVP_CIPHER_get_params(), EVP_CIPHER_CTX_set_params(),
and EVP_CIPHER_CTX_get_params
Additionally, we also add all the corresponding parameter descriptor
returning functions, along the correspoding provider dispatches:
EVP_MD_gettable_params(), EVP_MD_CTX_settable_params(),
EVP_MD_CTX_gettable_params(), EVP_CIPHER_gettable_params(),
EVP_CIPHER_CTX_settable_params(), and EVP_CIPHER_CTX_gettable_params()
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9576)
2019-08-12 20:56:18 +08:00
|
|
|
{
|
2019-09-24 22:17:15 +08:00
|
|
|
if (md != NULL && md->gettable_ctx_params != NULL)
|
|
|
|
return md->gettable_ctx_params();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const OSSL_PARAM *EVP_MD_CTX_gettable_params(EVP_MD_CTX *ctx)
|
|
|
|
{
|
2019-09-24 19:07:48 +08:00
|
|
|
EVP_PKEY_CTX *pctx;
|
|
|
|
|
2019-09-24 22:17:15 +08:00
|
|
|
if (ctx != NULL
|
|
|
|
&& ctx->digest != NULL
|
|
|
|
&& ctx->digest->gettable_ctx_params != NULL)
|
|
|
|
return ctx->digest->gettable_ctx_params();
|
|
|
|
|
2019-09-24 19:07:48 +08:00
|
|
|
pctx = ctx->pctx;
|
|
|
|
if (pctx != NULL
|
|
|
|
&& (pctx->operation == EVP_PKEY_OP_VERIFYCTX
|
|
|
|
|| pctx->operation == EVP_PKEY_OP_SIGNCTX)
|
|
|
|
&& pctx->op.sig.sigprovctx != NULL
|
|
|
|
&& pctx->op.sig.signature->gettable_ctx_md_params != NULL)
|
|
|
|
return pctx->op.sig.signature->gettable_ctx_md_params(
|
|
|
|
pctx->op.sig.sigprovctx);
|
|
|
|
|
Add missing EVP param utility functions
These functions were missing for a completes API:
EVP_MD_get_params(), EVP_CIPHER_get_params(), EVP_CIPHER_CTX_set_params(),
and EVP_CIPHER_CTX_get_params
Additionally, we also add all the corresponding parameter descriptor
returning functions, along the correspoding provider dispatches:
EVP_MD_gettable_params(), EVP_MD_CTX_settable_params(),
EVP_MD_CTX_gettable_params(), EVP_CIPHER_gettable_params(),
EVP_CIPHER_CTX_settable_params(), and EVP_CIPHER_CTX_gettable_params()
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9576)
2019-08-12 20:56:18 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2019-06-07 10:05:23 +08:00
|
|
|
/* TODO(3.0): Remove legacy code below - only used by engines & DigestSign */
|
2015-11-24 00:07:46 +08:00
|
|
|
int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
|
|
|
|
{
|
2019-07-16 12:03:12 +08:00
|
|
|
int ret = EVP_CTRL_RET_UNSUPPORTED;
|
|
|
|
int set_params = 1;
|
|
|
|
size_t sz;
|
|
|
|
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
|
|
|
|
|
|
|
if (ctx == NULL || ctx->digest == NULL) {
|
|
|
|
ERR_raise(ERR_LIB_EVP, EVP_R_MESSAGE_DIGEST_IS_NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-09-24 19:07:48 +08:00
|
|
|
if (ctx->digest->prov == NULL
|
|
|
|
&& (ctx->pctx == NULL
|
|
|
|
|| (ctx->pctx->operation != EVP_PKEY_OP_VERIFYCTX
|
|
|
|
&& ctx->pctx->operation != EVP_PKEY_OP_SIGNCTX)))
|
2019-07-16 12:03:12 +08:00
|
|
|
goto legacy;
|
|
|
|
|
|
|
|
switch (cmd) {
|
|
|
|
case EVP_MD_CTRL_XOF_LEN:
|
|
|
|
sz = (size_t)p1;
|
|
|
|
params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &sz);
|
|
|
|
break;
|
|
|
|
case EVP_MD_CTRL_MICALG:
|
|
|
|
set_params = 0;
|
|
|
|
params[0] = OSSL_PARAM_construct_utf8_string(OSSL_DIGEST_PARAM_MICALG,
|
2019-06-24 12:43:55 +08:00
|
|
|
p2, p1 ? p1 : 9999);
|
2019-07-16 12:03:12 +08:00
|
|
|
break;
|
2019-10-15 20:27:21 +08:00
|
|
|
case EVP_CTRL_SSL3_MASTER_SECRET:
|
|
|
|
params[0] = OSSL_PARAM_construct_octet_string(OSSL_DIGEST_PARAM_SSL3_MS,
|
|
|
|
p2, p1);
|
|
|
|
break;
|
2019-07-16 12:03:12 +08:00
|
|
|
default:
|
2019-10-13 19:00:46 +08:00
|
|
|
goto conclude;
|
2015-11-24 00:07:46 +08:00
|
|
|
}
|
2019-07-16 12:03:12 +08:00
|
|
|
|
|
|
|
if (set_params)
|
2019-09-24 19:07:48 +08:00
|
|
|
ret = EVP_MD_CTX_set_params(ctx, params);
|
2019-07-16 12:03:12 +08:00
|
|
|
else
|
2019-09-24 19:07:48 +08:00
|
|
|
ret = EVP_MD_CTX_get_params(ctx, params);
|
2019-10-06 16:45:17 +08:00
|
|
|
goto conclude;
|
2019-07-16 12:03:12 +08:00
|
|
|
|
|
|
|
|
|
|
|
/* TODO(3.0): Remove legacy code below */
|
|
|
|
legacy:
|
|
|
|
if (ctx->digest->md_ctrl == NULL) {
|
|
|
|
ERR_raise(ERR_LIB_EVP, EVP_R_CTRL_NOT_IMPLEMENTED);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = ctx->digest->md_ctrl(ctx, cmd, p1, p2);
|
2019-10-06 16:45:17 +08:00
|
|
|
conclude:
|
2019-07-16 12:03:12 +08:00
|
|
|
if (ret <= 0)
|
|
|
|
return 0;
|
|
|
|
return ret;
|
2015-11-24 00:07:46 +08:00
|
|
|
}
|
2019-03-13 22:49:40 +08:00
|
|
|
|
2019-09-03 23:47:13 +08:00
|
|
|
EVP_MD *evp_md_new(void)
|
|
|
|
{
|
|
|
|
EVP_MD *md = OPENSSL_zalloc(sizeof(*md));
|
|
|
|
|
|
|
|
if (md != NULL) {
|
|
|
|
md->lock = CRYPTO_THREAD_lock_new();
|
|
|
|
if (md->lock == NULL) {
|
|
|
|
OPENSSL_free(md);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
md->refcnt = 1;
|
|
|
|
}
|
|
|
|
return md;
|
|
|
|
}
|
|
|
|
|
2019-09-22 02:57:51 +08:00
|
|
|
/*
|
|
|
|
* FIPS module note: since internal fetches will be entirely
|
|
|
|
* provider based, we know that none of its code depends on legacy
|
|
|
|
* NIDs or any functionality that use them.
|
|
|
|
*/
|
|
|
|
#ifndef FIPS_MODE
|
|
|
|
/* TODO(3.x) get rid of the need for legacy NIDs */
|
|
|
|
static void set_legacy_nid(const char *name, void *vlegacy_nid)
|
|
|
|
{
|
|
|
|
int nid;
|
|
|
|
int *legacy_nid = vlegacy_nid;
|
2019-05-23 09:27:37 +08:00
|
|
|
/*
|
|
|
|
* We use lowest level function to get the associated method, because
|
|
|
|
* higher level functions such as EVP_get_digestbyname() have changed
|
|
|
|
* to look at providers too.
|
|
|
|
*/
|
|
|
|
const void *legacy_method = OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH);
|
2019-09-22 02:57:51 +08:00
|
|
|
|
|
|
|
if (*legacy_nid == -1) /* We found a clash already */
|
|
|
|
return;
|
2019-05-23 09:27:37 +08:00
|
|
|
|
|
|
|
if (legacy_method == NULL)
|
2019-09-22 02:57:51 +08:00
|
|
|
return;
|
2019-05-23 09:27:37 +08:00
|
|
|
nid = EVP_MD_nid(legacy_method);
|
2019-09-22 02:57:51 +08:00
|
|
|
if (*legacy_nid != NID_undef && *legacy_nid != nid) {
|
|
|
|
*legacy_nid = -1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
*legacy_nid = nid;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
In provider implemented methods, save the name number, not the name string
Multiple names per implementation is already supported in the namemap,
but hasn't been used yet. However, as soon as we have multiple names,
we will get an issue with what name should be saved in the method.
The solution is to not save the name itself, but rather the number
it's associated with. This number is supposed to be unique for each
set of names, and we assume that algorithm names are globally unique,
i.e. there can be no name overlap between different algorithm types.
Incidently, it was also found that the 'get' function used by
ossl_construct_method() doesn't need all the parameters it was given;
most of what it needs, it can now get through the data structure given
by the caller of ossl_construct_method(). As a consequence,
ossl_construct_method() itself doesn't need all the parameters it was
given either.
There are some added internal functions that are expected to disappear
as soon as legacy code is removed, such as evp_first_name() and
ossl_namemap_num2name().
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9897)
2019-09-14 22:22:19 +08:00
|
|
|
static void *evp_md_from_dispatch(int name_id,
|
|
|
|
const OSSL_DISPATCH *fns,
|
2019-10-31 19:10:01 +08:00
|
|
|
OSSL_PROVIDER *prov)
|
2019-03-13 22:49:40 +08:00
|
|
|
{
|
|
|
|
EVP_MD *md = NULL;
|
2019-03-14 00:17:17 +08:00
|
|
|
int fncnt = 0;
|
2019-03-13 22:49:40 +08:00
|
|
|
|
2019-05-08 20:00:31 +08:00
|
|
|
/* EVP_MD_fetch() will set the legacy NID if available */
|
In provider implemented methods, save the name number, not the name string
Multiple names per implementation is already supported in the namemap,
but hasn't been used yet. However, as soon as we have multiple names,
we will get an issue with what name should be saved in the method.
The solution is to not save the name itself, but rather the number
it's associated with. This number is supposed to be unique for each
set of names, and we assume that algorithm names are globally unique,
i.e. there can be no name overlap between different algorithm types.
Incidently, it was also found that the 'get' function used by
ossl_construct_method() doesn't need all the parameters it was given;
most of what it needs, it can now get through the data structure given
by the caller of ossl_construct_method(). As a consequence,
ossl_construct_method() itself doesn't need all the parameters it was
given either.
There are some added internal functions that are expected to disappear
as soon as legacy code is removed, such as evp_first_name() and
ossl_namemap_num2name().
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9897)
2019-09-14 22:22:19 +08:00
|
|
|
if ((md = evp_md_new()) == NULL) {
|
2019-07-11 04:22:16 +08:00
|
|
|
EVPerr(0, ERR_R_MALLOC_FAILURE);
|
2019-03-13 22:49:40 +08:00
|
|
|
return NULL;
|
2019-07-11 04:22:16 +08:00
|
|
|
}
|
2019-03-13 22:49:40 +08:00
|
|
|
|
2019-08-15 01:09:28 +08:00
|
|
|
#ifndef FIPS_MODE
|
2019-09-22 02:57:51 +08:00
|
|
|
/* TODO(3.x) get rid of the need for legacy NIDs */
|
|
|
|
md->type = NID_undef;
|
2019-09-23 16:56:13 +08:00
|
|
|
evp_names_do_all(prov, name_id, set_legacy_nid, &md->type);
|
2019-09-22 02:57:51 +08:00
|
|
|
if (md->type == -1) {
|
|
|
|
ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
|
|
|
|
EVP_MD_free(md);
|
|
|
|
return NULL;
|
In provider implemented methods, save the name number, not the name string
Multiple names per implementation is already supported in the namemap,
but hasn't been used yet. However, as soon as we have multiple names,
we will get an issue with what name should be saved in the method.
The solution is to not save the name itself, but rather the number
it's associated with. This number is supposed to be unique for each
set of names, and we assume that algorithm names are globally unique,
i.e. there can be no name overlap between different algorithm types.
Incidently, it was also found that the 'get' function used by
ossl_construct_method() doesn't need all the parameters it was given;
most of what it needs, it can now get through the data structure given
by the caller of ossl_construct_method(). As a consequence,
ossl_construct_method() itself doesn't need all the parameters it was
given either.
There are some added internal functions that are expected to disappear
as soon as legacy code is removed, such as evp_first_name() and
ossl_namemap_num2name().
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9897)
2019-09-14 22:22:19 +08:00
|
|
|
}
|
2019-08-15 01:09:28 +08:00
|
|
|
#endif
|
|
|
|
|
2019-09-22 02:57:51 +08:00
|
|
|
md->name_id = name_id;
|
|
|
|
|
2019-03-13 22:49:40 +08:00
|
|
|
for (; fns->function_id != 0; fns++) {
|
|
|
|
switch (fns->function_id) {
|
|
|
|
case OSSL_FUNC_DIGEST_NEWCTX:
|
2019-04-11 18:27:59 +08:00
|
|
|
if (md->newctx == NULL) {
|
|
|
|
md->newctx = OSSL_get_OP_digest_newctx(fns);
|
|
|
|
fncnt++;
|
|
|
|
}
|
2019-03-13 22:49:40 +08:00
|
|
|
break;
|
|
|
|
case OSSL_FUNC_DIGEST_INIT:
|
2019-04-11 18:27:59 +08:00
|
|
|
if (md->dinit == NULL) {
|
|
|
|
md->dinit = OSSL_get_OP_digest_init(fns);
|
|
|
|
fncnt++;
|
|
|
|
}
|
2019-03-13 22:49:40 +08:00
|
|
|
break;
|
2019-04-03 22:38:07 +08:00
|
|
|
case OSSL_FUNC_DIGEST_UPDATE:
|
2019-04-11 18:27:59 +08:00
|
|
|
if (md->dupdate == NULL) {
|
|
|
|
md->dupdate = OSSL_get_OP_digest_update(fns);
|
|
|
|
fncnt++;
|
|
|
|
}
|
2019-03-13 22:49:40 +08:00
|
|
|
break;
|
|
|
|
case OSSL_FUNC_DIGEST_FINAL:
|
2019-04-11 18:27:59 +08:00
|
|
|
if (md->dfinal == NULL) {
|
|
|
|
md->dfinal = OSSL_get_OP_digest_final(fns);
|
|
|
|
fncnt++;
|
|
|
|
}
|
2019-03-13 22:49:40 +08:00
|
|
|
break;
|
|
|
|
case OSSL_FUNC_DIGEST_DIGEST:
|
2019-04-11 18:27:59 +08:00
|
|
|
if (md->digest == NULL)
|
|
|
|
md->digest = OSSL_get_OP_digest_digest(fns);
|
2019-03-13 22:49:40 +08:00
|
|
|
/* We don't increment fnct for this as it is stand alone */
|
|
|
|
break;
|
|
|
|
case OSSL_FUNC_DIGEST_FREECTX:
|
2019-04-11 18:27:59 +08:00
|
|
|
if (md->freectx == NULL) {
|
|
|
|
md->freectx = OSSL_get_OP_digest_freectx(fns);
|
|
|
|
fncnt++;
|
|
|
|
}
|
2019-03-13 22:49:40 +08:00
|
|
|
break;
|
2019-03-14 00:17:17 +08:00
|
|
|
case OSSL_FUNC_DIGEST_DUPCTX:
|
2019-04-11 18:27:59 +08:00
|
|
|
if (md->dupctx == NULL)
|
|
|
|
md->dupctx = OSSL_get_OP_digest_dupctx(fns);
|
2019-03-14 00:17:17 +08:00
|
|
|
break;
|
2019-04-11 18:27:59 +08:00
|
|
|
case OSSL_FUNC_DIGEST_GET_PARAMS:
|
|
|
|
if (md->get_params == NULL)
|
|
|
|
md->get_params = OSSL_get_OP_digest_get_params(fns);
|
2019-03-29 01:22:20 +08:00
|
|
|
break;
|
2019-08-16 15:04:29 +08:00
|
|
|
case OSSL_FUNC_DIGEST_SET_CTX_PARAMS:
|
|
|
|
if (md->set_ctx_params == NULL)
|
|
|
|
md->set_ctx_params = OSSL_get_OP_digest_set_ctx_params(fns);
|
2019-07-16 12:03:12 +08:00
|
|
|
break;
|
2019-08-16 15:04:29 +08:00
|
|
|
case OSSL_FUNC_DIGEST_GET_CTX_PARAMS:
|
|
|
|
if (md->get_ctx_params == NULL)
|
|
|
|
md->get_ctx_params = OSSL_get_OP_digest_get_ctx_params(fns);
|
2019-07-16 12:03:12 +08:00
|
|
|
break;
|
Add missing EVP param utility functions
These functions were missing for a completes API:
EVP_MD_get_params(), EVP_CIPHER_get_params(), EVP_CIPHER_CTX_set_params(),
and EVP_CIPHER_CTX_get_params
Additionally, we also add all the corresponding parameter descriptor
returning functions, along the correspoding provider dispatches:
EVP_MD_gettable_params(), EVP_MD_CTX_settable_params(),
EVP_MD_CTX_gettable_params(), EVP_CIPHER_gettable_params(),
EVP_CIPHER_CTX_settable_params(), and EVP_CIPHER_CTX_gettable_params()
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9576)
2019-08-12 20:56:18 +08:00
|
|
|
case OSSL_FUNC_DIGEST_GETTABLE_PARAMS:
|
|
|
|
if (md->gettable_params == NULL)
|
|
|
|
md->gettable_params = OSSL_get_OP_digest_gettable_params(fns);
|
|
|
|
break;
|
|
|
|
case OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS:
|
|
|
|
if (md->settable_ctx_params == NULL)
|
|
|
|
md->settable_ctx_params =
|
|
|
|
OSSL_get_OP_digest_settable_ctx_params(fns);
|
|
|
|
break;
|
|
|
|
case OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS:
|
|
|
|
if (md->gettable_ctx_params == NULL)
|
|
|
|
md->gettable_ctx_params =
|
|
|
|
OSSL_get_OP_digest_gettable_ctx_params(fns);
|
|
|
|
break;
|
2019-03-13 22:49:40 +08:00
|
|
|
}
|
2019-03-14 00:17:17 +08:00
|
|
|
}
|
|
|
|
if ((fncnt != 0 && fncnt != 5)
|
2019-07-16 12:03:12 +08:00
|
|
|
|| (fncnt == 0 && md->digest == NULL)) {
|
2019-03-14 00:17:17 +08:00
|
|
|
/*
|
|
|
|
* In order to be a consistent set of functions we either need the
|
|
|
|
* whole set of init/update/final etc functions or none of them.
|
|
|
|
* The "digest" function can standalone. We at least need one way to
|
|
|
|
* generate digests.
|
|
|
|
*/
|
2019-09-03 23:47:13 +08:00
|
|
|
EVP_MD_free(md);
|
2019-07-16 12:03:12 +08:00
|
|
|
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
|
2019-03-14 00:17:17 +08:00
|
|
|
return NULL;
|
2019-03-13 22:49:40 +08:00
|
|
|
}
|
|
|
|
md->prov = prov;
|
|
|
|
if (prov != NULL)
|
2019-07-02 20:57:36 +08:00
|
|
|
ossl_provider_up_ref(prov);
|
2019-03-13 22:49:40 +08:00
|
|
|
|
|
|
|
return md;
|
|
|
|
}
|
|
|
|
|
2019-06-25 00:38:01 +08:00
|
|
|
static int evp_md_up_ref(void *md)
|
2019-03-13 22:49:40 +08:00
|
|
|
{
|
2019-06-25 00:38:01 +08:00
|
|
|
return EVP_MD_up_ref(md);
|
2019-03-13 22:49:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void evp_md_free(void *md)
|
|
|
|
{
|
2019-09-03 23:47:13 +08:00
|
|
|
EVP_MD_free(md);
|
2019-03-13 22:49:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
EVP_MD *EVP_MD_fetch(OPENSSL_CTX *ctx, const char *algorithm,
|
|
|
|
const char *properties)
|
|
|
|
{
|
2019-05-08 20:00:31 +08:00
|
|
|
EVP_MD *md =
|
|
|
|
evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties,
|
2019-10-31 19:10:01 +08:00
|
|
|
evp_md_from_dispatch, evp_md_up_ref, evp_md_free);
|
2019-05-08 20:00:31 +08:00
|
|
|
|
|
|
|
return md;
|
2019-03-13 22:49:40 +08:00
|
|
|
}
|
2019-07-13 13:02:54 +08:00
|
|
|
|
2019-09-03 23:47:13 +08:00
|
|
|
int EVP_MD_up_ref(EVP_MD *md)
|
|
|
|
{
|
|
|
|
int ref = 0;
|
|
|
|
|
|
|
|
CRYPTO_UP_REF(&md->refcnt, &ref, md->lock);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EVP_MD_free(EVP_MD *md)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (md == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
CRYPTO_DOWN_REF(&md->refcnt, &i, md->lock);
|
|
|
|
if (i > 0)
|
|
|
|
return;
|
|
|
|
ossl_provider_free(md->prov);
|
|
|
|
CRYPTO_THREAD_lock_free(md->lock);
|
|
|
|
OPENSSL_free(md);
|
|
|
|
}
|
|
|
|
|
EVP: add missing common functionality
This adds the missing functions that should be common for all
fetchable EVP sub-APIs:
EVP_KEYMGMT_is_a(), EVP_KEYMGMT_do_all_provided(), EVP_KEYEXCH_is_a(),
EVP_KEYEXCH_do_all_provided(), EVP_KDF_is_a(), EVP_MD_is_a(),
EVP_SIGNATURE_do_all_provided(), EVP_SIGNATURE_is_a().
This also renames EVP_MD_do_all_ex(), EVP_CIPHER_do_all_ex(),
EVP_KDF_do_all_ex(), EVP_MAC_do_all_ex() to change '_ex'
to '_provided'.
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/9979)
2019-09-23 16:33:26 +08:00
|
|
|
void EVP_MD_do_all_provided(OPENSSL_CTX *libctx,
|
|
|
|
void (*fn)(EVP_MD *mac, void *arg),
|
|
|
|
void *arg)
|
2019-07-13 13:02:54 +08:00
|
|
|
{
|
|
|
|
evp_generic_do_all(libctx, OSSL_OP_DIGEST,
|
|
|
|
(void (*)(void *, void *))fn, arg,
|
2019-10-31 19:10:01 +08:00
|
|
|
evp_md_from_dispatch, evp_md_free);
|
2019-07-13 13:02:54 +08:00
|
|
|
}
|