Blame winpr/libwinpr/crypto/hash.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * WinPR: Windows Portable Runtime
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2015 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/crt.h>
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/crypto.h>
Packit 1fb8d4
Packit 1fb8d4
#ifdef WITH_OPENSSL
Packit 1fb8d4
#include <openssl/md4.h>
Packit 1fb8d4
#include <openssl/md5.h>
Packit 1fb8d4
#include <openssl/sha.h>
Packit 1fb8d4
#include <openssl/evp.h>
Packit 1fb8d4
#include <openssl/hmac.h>
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#ifdef WITH_MBEDTLS
Packit 1fb8d4
#include <mbedtls/md4.h>
Packit 1fb8d4
#include <mbedtls/md5.h>
Packit 1fb8d4
#include <mbedtls/sha1.h>
Packit 1fb8d4
#include <mbedtls/md.h>
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * HMAC
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef WITH_OPENSSL
Packit Service 5a9772
const EVP_MD* winpr_openssl_get_evp_md(WINPR_MD_TYPE md)
Packit 1fb8d4
{
Packit Service 5a9772
	const char* name = winpr_md_type_to_string(md);
Packit Service 5a9772
	if (!name)
Packit Service 5a9772
		return NULL;
Packit Service 5a9772
	return EVP_get_digestbyname(name);
Packit 1fb8d4
}
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#ifdef WITH_MBEDTLS
Packit 1fb8d4
mbedtls_md_type_t winpr_mbedtls_get_md_type(int md)
Packit 1fb8d4
{
Packit 1fb8d4
	mbedtls_md_type_t type = MBEDTLS_MD_NONE;
Packit 1fb8d4
Packit 1fb8d4
	switch (md)
Packit 1fb8d4
	{
Packit 1fb8d4
		case WINPR_MD_MD2:
Packit 1fb8d4
			type = MBEDTLS_MD_MD2;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case WINPR_MD_MD4:
Packit 1fb8d4
			type = MBEDTLS_MD_MD4;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case WINPR_MD_MD5:
Packit 1fb8d4
			type = MBEDTLS_MD_MD5;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case WINPR_MD_SHA1:
Packit 1fb8d4
			type = MBEDTLS_MD_SHA1;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case WINPR_MD_SHA224:
Packit 1fb8d4
			type = MBEDTLS_MD_SHA224;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case WINPR_MD_SHA256:
Packit 1fb8d4
			type = MBEDTLS_MD_SHA256;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case WINPR_MD_SHA384:
Packit 1fb8d4
			type = MBEDTLS_MD_SHA384;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case WINPR_MD_SHA512:
Packit 1fb8d4
			type = MBEDTLS_MD_SHA512;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case WINPR_MD_RIPEMD160:
Packit 1fb8d4
			type = MBEDTLS_MD_RIPEMD160;
Packit 1fb8d4
			break;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return type;
Packit 1fb8d4
}
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit Service 5a9772
struct hash_map
Packit Service 5a9772
{
Packit Service 5a9772
	const char* name;
Packit Service 5a9772
	WINPR_MD_TYPE md;
Packit Service 5a9772
};
Packit Service 5a9772
static const struct hash_map hashes[] = { { "md2", WINPR_MD_MD2 },
Packit Service 5a9772
	                                      { "md4", WINPR_MD_MD4 },
Packit Service 5a9772
	                                      { "md5", WINPR_MD_MD5 },
Packit Service 5a9772
	                                      { "sha1", WINPR_MD_SHA1 },
Packit Service 5a9772
	                                      { "sha224", WINPR_MD_SHA224 },
Packit Service 5a9772
	                                      { "sha256", WINPR_MD_SHA256 },
Packit Service 5a9772
	                                      { "sha384", WINPR_MD_SHA384 },
Packit Service 5a9772
	                                      { "sha512", WINPR_MD_SHA512 },
Packit Service 5a9772
	                                      { "sha3_224", WINPR_MD_SHA3_224 },
Packit Service 5a9772
	                                      { "sha3_256", WINPR_MD_SHA3_256 },
Packit Service 5a9772
	                                      { "sha3_384", WINPR_MD_SHA3_384 },
Packit Service 5a9772
	                                      { "sha3_512", WINPR_MD_SHA3_512 },
Packit Service 5a9772
	                                      { "shake128", WINPR_MD_SHAKE128 },
Packit Service 5a9772
	                                      { "shake256", WINPR_MD_SHAKE256 },
Packit Service 5a9772
	                                      { NULL, WINPR_MD_NONE } };
Packit Service 5a9772
Packit Service 5a9772
WINPR_MD_TYPE winpr_md_type_from_string(const char* name)
Packit Service 5a9772
{
Packit Service 5a9772
	const struct hash_map* cur = hashes;
Packit Service 5a9772
	while (cur->name)
Packit Service 5a9772
	{
Packit Service 5a9772
		if (_stricmp(cur->name, name) == 0)
Packit Service 5a9772
			return cur->md;
Packit Service 5a9772
		cur++;
Packit Service 5a9772
	}
Packit Service 5a9772
	return WINPR_MD_NONE;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
const char* winpr_md_type_to_string(WINPR_MD_TYPE md)
Packit Service 5a9772
{
Packit Service 5a9772
	const struct hash_map* cur = hashes;
Packit Service 5a9772
	while (cur->name)
Packit Service 5a9772
	{
Packit Service 5a9772
		if (cur->md == md)
Packit Service 5a9772
			return cur->name;
Packit Service 5a9772
		cur++;
Packit Service 5a9772
	}
Packit Service 5a9772
	return NULL;
Packit Service 5a9772
}
Packit Service 5a9772
Packit 1fb8d4
WINPR_HMAC_CTX* winpr_HMAC_New(void)
Packit 1fb8d4
{
Packit 1fb8d4
	WINPR_HMAC_CTX* ctx = NULL;
Packit 1fb8d4
#if defined(WITH_OPENSSL)
Packit 1fb8d4
	HMAC_CTX* hmac = NULL;
Packit 1fb8d4
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
Packit 1fb8d4
Packit Service 5a9772
	if (!(hmac = (HMAC_CTX*)calloc(1, sizeof(HMAC_CTX))))
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	HMAC_CTX_init(hmac);
Packit 1fb8d4
#else
Packit 1fb8d4
Packit 1fb8d4
	if (!(hmac = HMAC_CTX_new()))
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit Service 5a9772
	ctx = (WINPR_HMAC_CTX*)hmac;
Packit 1fb8d4
#elif defined(WITH_MBEDTLS)
Packit 1fb8d4
	mbedtls_md_context_t* hmac;
Packit 1fb8d4
Packit Service 5a9772
	if (!(hmac = (mbedtls_md_context_t*)calloc(1, sizeof(mbedtls_md_context_t))))
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	mbedtls_md_init(hmac);
Packit Service 5a9772
	ctx = (WINPR_HMAC_CTX*)hmac;
Packit 1fb8d4
#endif
Packit 1fb8d4
	return ctx;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, WINPR_MD_TYPE md, const BYTE* key, size_t keylen)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(WITH_OPENSSL)
Packit Service 5a9772
	HMAC_CTX* hmac = (HMAC_CTX*)ctx;
Packit 1fb8d4
	const EVP_MD* evp = winpr_openssl_get_evp_md(md);
Packit 1fb8d4
Packit 1fb8d4
	if (!evp || !hmac)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
#if (OPENSSL_VERSION_NUMBER < 0x10000000L) || defined(LIBRESSL_VERSION_NUMBER)
Packit 1fb8d4
	HMAC_Init_ex(hmac, key, keylen, evp, NULL); /* no return value on OpenSSL 0.9.x */
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
#else
Packit 1fb8d4
Packit 1fb8d4
	if (HMAC_Init_ex(hmac, key, keylen, evp, NULL) == 1)
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
#elif defined(WITH_MBEDTLS)
Packit Service 5a9772
	mbedtls_md_context_t* hmac = (mbedtls_md_context_t*)ctx;
Packit 1fb8d4
	mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
Packit 1fb8d4
	const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type);
Packit 1fb8d4
Packit 1fb8d4
	if (!md_info || !hmac)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (hmac->md_info != md_info)
Packit 1fb8d4
	{
Packit 1fb8d4
		mbedtls_md_free(hmac); /* can be called at any time after mbedtls_md_init */
Packit 1fb8d4
Packit 1fb8d4
		if (mbedtls_md_setup(hmac, md_info, 1) != 0)
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (mbedtls_md_hmac_starts(hmac, key, keylen) == 0)
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const BYTE* input, size_t ilen)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(WITH_OPENSSL)
Packit Service 5a9772
	HMAC_CTX* hmac = (HMAC_CTX*)ctx;
Packit 1fb8d4
#if (OPENSSL_VERSION_NUMBER < 0x10000000L) || defined(LIBRESSL_VERSION_NUMBER)
Packit 1fb8d4
	HMAC_Update(hmac, input, ilen); /* no return value on OpenSSL 0.9.x */
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
#else
Packit 1fb8d4
Packit 1fb8d4
	if (HMAC_Update(hmac, input, ilen) == 1)
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
#elif defined(WITH_MBEDTLS)
Packit Service 5a9772
	mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*)ctx;
Packit 1fb8d4
Packit 1fb8d4
	if (mbedtls_md_hmac_update(mdctx, input, ilen) == 0)
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, BYTE* output, size_t olen)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(WITH_OPENSSL)
Packit 1fb8d4
	HMAC_CTX* hmac;
Packit 1fb8d4
#elif defined(WITH_MBEDTLS)
Packit 1fb8d4
	mbedtls_md_context_t* mdctx;
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
	if (!ctx)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
#if defined(WITH_OPENSSL)
Packit Service 5a9772
	hmac = (HMAC_CTX*)ctx;
Packit 1fb8d4
#if (OPENSSL_VERSION_NUMBER < 0x10000000L) || defined(LIBRESSL_VERSION_NUMBER)
Packit 1fb8d4
	HMAC_Final(hmac, output, NULL); /* no return value on OpenSSL 0.9.x */
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
#else
Packit 1fb8d4
Packit 1fb8d4
	if (HMAC_Final(hmac, output, NULL) == 1)
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
#elif defined(WITH_MBEDTLS)
Packit Service 5a9772
	mdctx = (mbedtls_md_context_t*)ctx;
Packit 1fb8d4
Packit 1fb8d4
	if (mbedtls_md_hmac_finish(mdctx, output) == 0)
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void winpr_HMAC_Free(WINPR_HMAC_CTX* ctx)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(WITH_OPENSSL)
Packit Service 5a9772
	HMAC_CTX* hmac = (HMAC_CTX*)ctx;
Packit 1fb8d4
Packit 1fb8d4
	if (hmac)
Packit 1fb8d4
	{
Packit 1fb8d4
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
Packit 1fb8d4
		HMAC_CTX_cleanup(hmac);
Packit 1fb8d4
		free(hmac);
Packit 1fb8d4
#else
Packit 1fb8d4
		HMAC_CTX_free(hmac);
Packit 1fb8d4
#endif
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
#elif defined(WITH_MBEDTLS)
Packit Service 5a9772
	mbedtls_md_context_t* hmac = (mbedtls_md_context_t*)ctx;
Packit 1fb8d4
Packit 1fb8d4
	if (hmac)
Packit 1fb8d4
	{
Packit 1fb8d4
		mbedtls_md_free(hmac);
Packit 1fb8d4
		free(hmac);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
BOOL winpr_HMAC(WINPR_MD_TYPE md, const BYTE* key, size_t keylen, const BYTE* input, size_t ilen,
Packit Service 5a9772
                BYTE* output, size_t olen)
Packit 1fb8d4
{
Packit 1fb8d4
	BOOL result = FALSE;
Packit 1fb8d4
	WINPR_HMAC_CTX* ctx = winpr_HMAC_New();
Packit 1fb8d4
Packit 1fb8d4
	if (!ctx)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (!winpr_HMAC_Init(ctx, md, key, keylen))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!winpr_HMAC_Update(ctx, input, ilen))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!winpr_HMAC_Final(ctx, output, olen))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	result = TRUE;
Packit 1fb8d4
out:
Packit 1fb8d4
	winpr_HMAC_Free(ctx);
Packit 1fb8d4
	return result;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Generic Digest API
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
WINPR_DIGEST_CTX* winpr_Digest_New(void)
Packit 1fb8d4
{
Packit 1fb8d4
	WINPR_DIGEST_CTX* ctx = NULL;
Packit 1fb8d4
#if defined(WITH_OPENSSL)
Packit 1fb8d4
	EVP_MD_CTX* mdctx;
Packit 1fb8d4
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
Packit 1fb8d4
	mdctx = EVP_MD_CTX_create();
Packit 1fb8d4
#else
Packit 1fb8d4
	mdctx = EVP_MD_CTX_new();
Packit 1fb8d4
#endif
Packit Service 5a9772
	ctx = (WINPR_DIGEST_CTX*)mdctx;
Packit 1fb8d4
#elif defined(WITH_MBEDTLS)
Packit 1fb8d4
	mbedtls_md_context_t* mdctx;
Packit Service 5a9772
	mdctx = (mbedtls_md_context_t*)calloc(1, sizeof(mbedtls_md_context_t));
Packit 1fb8d4
Packit 1fb8d4
	if (mdctx)
Packit 1fb8d4
		mbedtls_md_init(mdctx);
Packit 1fb8d4
Packit Service 5a9772
	ctx = (WINPR_DIGEST_CTX*)mdctx;
Packit 1fb8d4
#endif
Packit 1fb8d4
	return ctx;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#if defined(WITH_OPENSSL)
Packit 1fb8d4
static BOOL winpr_Digest_Init_Internal(WINPR_DIGEST_CTX* ctx, const EVP_MD* evp)
Packit 1fb8d4
{
Packit Service 5a9772
	EVP_MD_CTX* mdctx = (EVP_MD_CTX*)ctx;
Packit 1fb8d4
Packit 1fb8d4
	if (!mdctx || !evp)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (EVP_DigestInit_ex(mdctx, evp, NULL) != 1)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#elif defined(WITH_MBEDTLS)
Packit 1fb8d4
static BOOL winpr_Digest_Init_Internal(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
Packit 1fb8d4
{
Packit Service 5a9772
	mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*)ctx;
Packit 1fb8d4
	mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
Packit 1fb8d4
	const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type);
Packit 1fb8d4
Packit 1fb8d4
	if (!md_info)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (mdctx->md_info != md_info)
Packit 1fb8d4
	{
Packit 1fb8d4
		mbedtls_md_free(mdctx); /* can be called at any time after mbedtls_md_init */
Packit 1fb8d4
Packit 1fb8d4
		if (mbedtls_md_setup(mdctx, md_info, 0) != 0)
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (mbedtls_md_starts(mdctx) != 0)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
BOOL winpr_Digest_Init_Allow_FIPS(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(WITH_OPENSSL)
Packit Service 5a9772
	EVP_MD_CTX* mdctx = (EVP_MD_CTX*)ctx;
Packit 1fb8d4
	const EVP_MD* evp = winpr_openssl_get_evp_md(md);
Packit 1fb8d4
Packit 1fb8d4
	/* Only MD5 is supported for FIPS allow override */
Packit 1fb8d4
	if (md != WINPR_MD_MD5)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	EVP_MD_CTX_set_flags(mdctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
Packit 1fb8d4
	return winpr_Digest_Init_Internal(ctx, evp);
Packit 1fb8d4
#elif defined(WITH_MBEDTLS)
Packit 1fb8d4
Packit 1fb8d4
	/* Only MD5 is supported for FIPS allow override */
Packit 1fb8d4
	if (md != WINPR_MD_MD5)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	return winpr_Digest_Init_Internal(ctx, md);
Packit 1fb8d4
#endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(WITH_OPENSSL)
Packit 1fb8d4
	const EVP_MD* evp = winpr_openssl_get_evp_md(md);
Packit 1fb8d4
	return winpr_Digest_Init_Internal(ctx, evp);
Packit 1fb8d4
#else
Packit 1fb8d4
	return winpr_Digest_Init_Internal(ctx, md);
Packit 1fb8d4
#endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const BYTE* input, size_t ilen)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(WITH_OPENSSL)
Packit Service 5a9772
	EVP_MD_CTX* mdctx = (EVP_MD_CTX*)ctx;
Packit 1fb8d4
Packit 1fb8d4
	if (EVP_DigestUpdate(mdctx, input, ilen) != 1)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
#elif defined(WITH_MBEDTLS)
Packit Service 5a9772
	mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*)ctx;
Packit 1fb8d4
Packit 1fb8d4
	if (mbedtls_md_update(mdctx, input, ilen) != 0)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL winpr_Digest_Final(WINPR_DIGEST_CTX* ctx, BYTE* output, size_t olen)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(WITH_OPENSSL)
Packit Service 5a9772
	EVP_MD_CTX* mdctx = (EVP_MD_CTX*)ctx;
Packit 1fb8d4
Packit 1fb8d4
	if (EVP_DigestFinal_ex(mdctx, output, NULL) == 1)
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
Packit 1fb8d4
#elif defined(WITH_MBEDTLS)
Packit Service 5a9772
	mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*)ctx;
Packit 1fb8d4
Packit 1fb8d4
	if (mbedtls_md_finish(mdctx, output) == 0)
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void winpr_Digest_Free(WINPR_DIGEST_CTX* ctx)
Packit 1fb8d4
{
Packit 1fb8d4
#if defined(WITH_OPENSSL)
Packit Service 5a9772
	EVP_MD_CTX* mdctx = (EVP_MD_CTX*)ctx;
Packit 1fb8d4
Packit 1fb8d4
	if (mdctx)
Packit 1fb8d4
	{
Packit 1fb8d4
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
Packit 1fb8d4
		EVP_MD_CTX_destroy(mdctx);
Packit 1fb8d4
#else
Packit 1fb8d4
		EVP_MD_CTX_free(mdctx);
Packit 1fb8d4
#endif
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
#elif defined(WITH_MBEDTLS)
Packit Service 5a9772
	mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*)ctx;
Packit 1fb8d4
Packit 1fb8d4
	if (mdctx)
Packit 1fb8d4
	{
Packit 1fb8d4
		mbedtls_md_free(mdctx);
Packit 1fb8d4
		free(mdctx);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
BOOL winpr_Digest_Allow_FIPS(WINPR_MD_TYPE md, const BYTE* input, size_t ilen, BYTE* output,
Packit Service 5a9772
                             size_t olen)
Packit 1fb8d4
{
Packit 1fb8d4
	BOOL result = FALSE;
Packit 1fb8d4
	WINPR_DIGEST_CTX* ctx = winpr_Digest_New();
Packit 1fb8d4
Packit 1fb8d4
	if (!ctx)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (!winpr_Digest_Init_Allow_FIPS(ctx, md))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!winpr_Digest_Update(ctx, input, ilen))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!winpr_Digest_Final(ctx, output, olen))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	result = TRUE;
Packit 1fb8d4
out:
Packit 1fb8d4
	winpr_Digest_Free(ctx);
Packit 1fb8d4
	return result;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL winpr_Digest(WINPR_MD_TYPE md, const BYTE* input, size_t ilen, BYTE* output, size_t olen)
Packit 1fb8d4
{
Packit 1fb8d4
	BOOL result = FALSE;
Packit 1fb8d4
	WINPR_DIGEST_CTX* ctx = winpr_Digest_New();
Packit 1fb8d4
Packit 1fb8d4
	if (!ctx)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (!winpr_Digest_Init(ctx, md))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!winpr_Digest_Update(ctx, input, ilen))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	if (!winpr_Digest_Final(ctx, output, olen))
Packit 1fb8d4
		goto out;
Packit 1fb8d4
Packit 1fb8d4
	result = TRUE;
Packit 1fb8d4
out:
Packit 1fb8d4
	winpr_Digest_Free(ctx);
Packit 1fb8d4
	return result;
Packit 1fb8d4
}