19#include <winpr/config.h>
22#include <winpr/assert.h>
23#include <winpr/crypto.h>
26#include <openssl/md4.h>
27#include <openssl/md5.h>
28#include <openssl/sha.h>
29#include <openssl/evp.h>
30#include <openssl/hmac.h>
31#if OPENSSL_VERSION_NUMBER >= 0x30000000L
32#include <openssl/core_names.h>
38#include <mbedtls/md5.h>
40#include <mbedtls/sha1.h>
41#include <mbedtls/md.h>
42#if MBEDTLS_VERSION_MAJOR < 3
43#define mbedtls_md_info_from_ctx(_ctx) (_ctx->md_info)
47#if defined(WITH_INTERNAL_MD4)
51#if defined(WITH_INTERNAL_MD5)
57#define TAG WINPR_TAG("crypto.hash")
64extern const EVP_MD* winpr_openssl_get_evp_md(WINPR_MD_TYPE md);
68const EVP_MD* winpr_openssl_get_evp_md(WINPR_MD_TYPE md)
70 const char* name = winpr_md_type_to_string(md);
73 return EVP_get_digestbyname(name);
78mbedtls_md_type_t winpr_mbedtls_get_md_type(
int md)
80 mbedtls_md_type_t type = MBEDTLS_MD_NONE;
85 type = MBEDTLS_MD_MD5;
89 type = MBEDTLS_MD_SHA1;
93 type = MBEDTLS_MD_SHA224;
97 type = MBEDTLS_MD_SHA256;
100 case WINPR_MD_SHA384:
101 type = MBEDTLS_MD_SHA384;
104 case WINPR_MD_SHA512:
105 type = MBEDTLS_MD_SHA512;
118static const struct hash_map hashes[] = {
119 {
"md2", WINPR_MD_MD2 }, {
"md4", WINPR_MD_MD4 },
120 {
"md5", WINPR_MD_MD5 }, {
"sha1", WINPR_MD_SHA1 },
121 {
"sha224", WINPR_MD_SHA224 }, {
"sha256", WINPR_MD_SHA256 },
122 {
"sha384", WINPR_MD_SHA384 }, {
"sha512", WINPR_MD_SHA512 },
123 {
"sha3_224", WINPR_MD_SHA3_224 }, {
"sha3_256", WINPR_MD_SHA3_256 },
124 {
"sha3_384", WINPR_MD_SHA3_384 }, {
"sha3_512", WINPR_MD_SHA3_512 },
125 {
"shake128", WINPR_MD_SHAKE128 }, {
"shake256", WINPR_MD_SHAKE256 },
126 {
nullptr, WINPR_MD_NONE }
129WINPR_MD_TYPE winpr_md_type_from_string(
const char* name)
131 const struct hash_map* cur = hashes;
134 if (_stricmp(cur->name, name) == 0)
138 return WINPR_MD_NONE;
141const char* winpr_md_type_to_string(WINPR_MD_TYPE md)
143 const struct hash_map* cur = hashes;
153struct winpr_hmac_ctx_private_st
157#if defined(WITH_INTERNAL_MD5)
160#if defined(WITH_OPENSSL)
161#if OPENSSL_VERSION_NUMBER >= 0x30000000L
167#if defined(WITH_MBEDTLS)
168 mbedtls_md_context_t hmac;
172WINPR_HMAC_CTX* winpr_HMAC_New(
void)
174 WINPR_HMAC_CTX* ctx = (WINPR_HMAC_CTX*)calloc(1,
sizeof(WINPR_HMAC_CTX));
177#if defined(WITH_OPENSSL)
178#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
179 (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
181 if (!(ctx->hmac = (HMAC_CTX*)calloc(1,
sizeof(HMAC_CTX))))
184 HMAC_CTX_init(ctx->hmac);
185#elif OPENSSL_VERSION_NUMBER < 0x30000000L
186 if (!(ctx->hmac = HMAC_CTX_new()))
189 EVP_MAC* emac = EVP_MAC_fetch(
nullptr,
"HMAC",
nullptr);
192 ctx->xhmac = EVP_MAC_CTX_new(emac);
197#elif defined(WITH_MBEDTLS)
198 mbedtls_md_init(&ctx->hmac);
203 WINPR_PRAGMA_DIAG_PUSH
204 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
205 winpr_HMAC_Free(ctx);
206 WINPR_PRAGMA_DIAG_POP
210BOOL winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, WINPR_MD_TYPE md,
const void* key,
size_t keylen)
217#if defined(WITH_INTERNAL_MD5)
219 hmac_md5_init(&ctx->hmac_md5, key, keylen);
226#if defined(WITH_OPENSSL)
227#if OPENSSL_VERSION_NUMBER >= 0x30000000L
228 char* hash = WINPR_CAST_CONST_PTR_AWAY(winpr_md_type_to_string(md),
char*);
233 const char* param_name = OSSL_MAC_PARAM_DIGEST;
234 const OSSL_PARAM param[] = { OSSL_PARAM_construct_utf8_string(param_name, hash, 0),
235 OSSL_PARAM_construct_end() };
237 return EVP_MAC_init(ctx->xhmac, key, keylen, param) == 1;
239 HMAC_CTX* hmac = ctx->hmac;
240 const EVP_MD* evp = winpr_openssl_get_evp_md(md);
245 if (keylen > INT_MAX)
247#if (OPENSSL_VERSION_NUMBER < 0x10000000L) || \
248 (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
249 HMAC_Init_ex(hmac, key, (
int)keylen, evp,
nullptr);
253 if (HMAC_Init_ex(hmac, key, (
int)keylen, evp,
nullptr) == 1)
258#elif defined(WITH_MBEDTLS)
259 mbedtls_md_context_t* hmac = &ctx->hmac;
260 mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
261 const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type);
263 if (!md_info || !hmac)
266 if (mbedtls_md_info_from_ctx(hmac) != md_info)
268 mbedtls_md_free(hmac);
270 if (mbedtls_md_setup(hmac, md_info, 1) != 0)
274 if (mbedtls_md_hmac_starts(hmac, key, keylen) == 0)
281BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx,
const void* input,
size_t ilen)
287#if defined(WITH_INTERNAL_MD5)
289 hmac_md5_update(&ctx->hmac_md5, input, ilen);
296#if defined(WITH_OPENSSL)
297#if OPENSSL_VERSION_NUMBER >= 0x30000000L
298 return EVP_MAC_update(ctx->xhmac, input, ilen) == 1;
300 HMAC_CTX* hmac = ctx->hmac;
301#if (OPENSSL_VERSION_NUMBER < 0x10000000L) || \
302 (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
303 HMAC_Update(hmac, input, ilen);
307 if (HMAC_Update(hmac, input, ilen) == 1)
311#elif defined(WITH_MBEDTLS)
312 mbedtls_md_context_t* mdctx = &ctx->hmac;
314 if (mbedtls_md_hmac_update(mdctx, input, ilen) == 0)
321BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx,
void* output,
size_t olen)
327#if defined(WITH_INTERNAL_MD5)
329 if (olen < WINPR_MD5_DIGEST_LENGTH)
331 hmac_md5_finalize(&ctx->hmac_md5, output);
338#if defined(WITH_OPENSSL)
339#if OPENSSL_VERSION_NUMBER >= 0x30000000L
340 const int rc = EVP_MAC_final(ctx->xhmac, output,
nullptr, olen);
343 HMAC_CTX* hmac = ctx->hmac;
344#if (OPENSSL_VERSION_NUMBER < 0x10000000L) || \
345 (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
346 HMAC_Final(hmac, output,
nullptr);
350 if (HMAC_Final(hmac, output,
nullptr) == 1)
355#elif defined(WITH_MBEDTLS)
356 mbedtls_md_context_t* mdctx = &ctx->hmac;
358 if (mbedtls_md_hmac_finish(mdctx, output) == 0)
365void winpr_HMAC_Free(WINPR_HMAC_CTX* ctx)
370#if defined(WITH_OPENSSL)
371#if OPENSSL_VERSION_NUMBER >= 0x30000000L
372 EVP_MAC_CTX_free(ctx->xhmac);
374 HMAC_CTX* hmac = ctx->hmac;
378#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
379 (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
380 HMAC_CTX_cleanup(hmac);
387#elif defined(WITH_MBEDTLS)
388 mbedtls_md_context_t* hmac = &ctx->hmac;
391 mbedtls_md_free(hmac);
398BOOL winpr_HMAC(WINPR_MD_TYPE md,
const void* key,
size_t keylen,
const void* input,
size_t ilen,
399 void* output,
size_t olen)
402 WINPR_HMAC_CTX* ctx = winpr_HMAC_New();
407 if (!winpr_HMAC_Init(ctx, md, key, keylen))
410 if (!winpr_HMAC_Update(ctx, input, ilen))
413 if (!winpr_HMAC_Final(ctx, output, olen))
418 winpr_HMAC_Free(ctx);
426struct winpr_digest_ctx_private_st
430#if defined(WITH_INTERNAL_MD4)
433#if defined(WITH_INTERNAL_MD5)
436#if defined(WITH_OPENSSL)
439#if defined(WITH_MBEDTLS)
440 mbedtls_md_context_t* mdctx;
444WINPR_DIGEST_CTX* winpr_Digest_New(
void)
446 WINPR_DIGEST_CTX* ctx = calloc(1,
sizeof(WINPR_DIGEST_CTX));
450#if defined(WITH_OPENSSL)
451#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
452 (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
453 ctx->mdctx = EVP_MD_CTX_create();
455 ctx->mdctx = EVP_MD_CTX_new();
460#elif defined(WITH_MBEDTLS)
461 ctx->mdctx = (mbedtls_md_context_t*)calloc(1,
sizeof(mbedtls_md_context_t));
466 mbedtls_md_init(ctx->mdctx);
471 WINPR_PRAGMA_DIAG_PUSH
472 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
473 winpr_Digest_Free(ctx);
474 WINPR_PRAGMA_DIAG_POP
478#if defined(WITH_OPENSSL)
479static BOOL winpr_Digest_Init_Internal(WINPR_DIGEST_CTX* ctx,
const EVP_MD* evp)
482 EVP_MD_CTX* mdctx = ctx->mdctx;
487 if (EVP_DigestInit_ex(mdctx, evp,
nullptr) != 1)
489 WLog_ERR(TAG,
"Failed to initialize digest %s", winpr_md_type_to_string(ctx->md));
496#elif defined(WITH_MBEDTLS)
497static BOOL winpr_Digest_Init_Internal(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
500 mbedtls_md_context_t* mdctx = ctx->mdctx;
501 mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
502 const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type);
507 if (mbedtls_md_info_from_ctx(mdctx) != md_info)
509 mbedtls_md_free(mdctx);
511 if (mbedtls_md_setup(mdctx, md_info, 0) != 0)
515 if (mbedtls_md_starts(mdctx) != 0)
522BOOL winpr_Digest_Init_Allow_FIPS(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
531#if defined(WITH_INTERNAL_MD5)
532 winpr_MD5_Init(&ctx->md5);
534#elif defined(WITH_OPENSSL)
535#if OPENSSL_VERSION_NUMBER >= 0x30000000L
536#if !defined(WITH_INTERNAL_MD5)
537 if (md == WINPR_MD_MD5)
539 EVP_MD* md5 = EVP_MD_fetch(
nullptr,
"MD5",
"fips=no");
540 BOOL rc = winpr_Digest_Init_Internal(ctx, md5);
546 const EVP_MD* evp = winpr_openssl_get_evp_md(md);
547 EVP_MD_CTX_set_flags(ctx->mdctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
548 return winpr_Digest_Init_Internal(ctx, evp);
549#elif defined(WITH_MBEDTLS)
550 return winpr_Digest_Init_Internal(ctx, md);
554 WLog_ERR(TAG,
"Invalid FIPS digest %s requested", winpr_md_type_to_string(md));
559BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
566#if defined(WITH_INTERNAL_MD4)
568 winpr_MD4_Init(&ctx->md4);
571#if defined(WITH_INTERNAL_MD5)
573 winpr_MD5_Init(&ctx->md5);
580#if defined(WITH_OPENSSL)
581 const EVP_MD* evp = winpr_openssl_get_evp_md(md);
582 return winpr_Digest_Init_Internal(ctx, evp);
584 return winpr_Digest_Init_Internal(ctx, md);
588BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx,
const void* input,
size_t ilen)
594#if defined(WITH_INTERNAL_MD4)
596 winpr_MD4_Update(&ctx->md4, input, ilen);
599#if defined(WITH_INTERNAL_MD5)
601 winpr_MD5_Update(&ctx->md5, input, ilen);
608#if defined(WITH_OPENSSL)
609 EVP_MD_CTX* mdctx = ctx->mdctx;
611 return EVP_DigestUpdate(mdctx, input, ilen) == 1;
613#elif defined(WITH_MBEDTLS)
614 mbedtls_md_context_t* mdctx = ctx->mdctx;
616 if (mbedtls_md_update(mdctx, input, ilen) != 0)
623BOOL winpr_Digest_Final(WINPR_DIGEST_CTX* ctx,
void* output, WINPR_ATTR_UNUSED
size_t olen)
629#if defined(WITH_INTERNAL_MD4)
631 if (olen < WINPR_MD4_DIGEST_LENGTH)
633 winpr_MD4_Final(output, &ctx->md4);
636#if defined(WITH_INTERNAL_MD5)
638 if (olen < WINPR_MD5_DIGEST_LENGTH)
640 winpr_MD5_Final(output, &ctx->md5);
648#if defined(WITH_OPENSSL)
649 EVP_MD_CTX* mdctx = ctx->mdctx;
651 return EVP_DigestFinal_ex(mdctx, output,
nullptr) == 1;
653#elif defined(WITH_MBEDTLS)
654 mbedtls_md_context_t* mdctx = ctx->mdctx;
656 if (mbedtls_md_finish(mdctx, output) == 0)
663BOOL winpr_DigestSign_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md,
void* key)
667#if defined(WITH_OPENSSL)
668 const EVP_MD* evp = winpr_openssl_get_evp_md(md);
672 const int rdsi = EVP_DigestSignInit(ctx->mdctx,
nullptr, evp,
nullptr, key);
679BOOL winpr_DigestSign_Update(WINPR_DIGEST_CTX* ctx,
const void* input,
size_t ilen)
683#if defined(WITH_OPENSSL)
684 EVP_MD_CTX* mdctx = ctx->mdctx;
686 return (EVP_DigestSignUpdate(mdctx, input, ilen) == 1);
692BOOL winpr_DigestSign_Final(WINPR_DIGEST_CTX* ctx,
void* output,
size_t* piolen)
696#if defined(WITH_OPENSSL)
697 EVP_MD_CTX* mdctx = ctx->mdctx;
699 return EVP_DigestSignFinal(mdctx, output, piolen) == 1;
705void winpr_Digest_Free(WINPR_DIGEST_CTX* ctx)
709#if defined(WITH_OPENSSL)
712#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
713 (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
714 EVP_MD_CTX_destroy(ctx->mdctx);
716 EVP_MD_CTX_free(ctx->mdctx);
720#elif defined(WITH_MBEDTLS)
723 mbedtls_md_free(ctx->mdctx);
731BOOL winpr_Digest_Allow_FIPS(WINPR_MD_TYPE md,
const void* input,
size_t ilen,
void* output,
735 WINPR_DIGEST_CTX* ctx = winpr_Digest_New();
740 if (!winpr_Digest_Init_Allow_FIPS(ctx, md))
743 if (!winpr_Digest_Update(ctx, input, ilen))
746 if (!winpr_Digest_Final(ctx, output, olen))
751 winpr_Digest_Free(ctx);
755BOOL winpr_Digest(WINPR_MD_TYPE md,
const void* input,
size_t ilen,
void* output,
size_t olen)
758 WINPR_DIGEST_CTX* ctx = winpr_Digest_New();
763 if (!winpr_Digest_Init(ctx, md))
766 if (!winpr_Digest_Update(ctx, input, ilen))
769 if (!winpr_Digest_Final(ctx, output, olen))
774 winpr_Digest_Free(ctx);