FreeRDP
libwinpr/crypto/hash.c
1 
19 #include <winpr/config.h>
20 
21 #include <winpr/crt.h>
22 #include <winpr/assert.h>
23 #include <winpr/crypto.h>
24 
25 #ifdef WITH_OPENSSL
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>
33 #endif
34 #endif
35 
36 #ifdef WITH_MBEDTLS
37 #ifdef MBEDTLS_MD5_C
38 #include <mbedtls/md5.h>
39 #endif
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)
44 #endif
45 #endif
46 
47 #if defined(WITH_INTERNAL_MD4)
48 #include "md4.h"
49 #endif
50 
51 #if defined(WITH_INTERNAL_MD5)
52 #include "md5.h"
53 #include "hmac_md5.h"
54 #endif
55 
56 #include "../log.h"
57 #define TAG WINPR_TAG("crypto.hash")
58 
63 #ifdef WITH_OPENSSL
64 extern const EVP_MD* winpr_openssl_get_evp_md(WINPR_MD_TYPE md);
65 #endif
66 
67 #ifdef WITH_OPENSSL
68 const EVP_MD* winpr_openssl_get_evp_md(WINPR_MD_TYPE md)
69 {
70  const char* name = winpr_md_type_to_string(md);
71  if (!name)
72  return NULL;
73  return EVP_get_digestbyname(name);
74 }
75 #endif
76 
77 #ifdef WITH_MBEDTLS
78 mbedtls_md_type_t winpr_mbedtls_get_md_type(int md)
79 {
80  mbedtls_md_type_t type = MBEDTLS_MD_NONE;
81 
82  switch (md)
83  {
84  case WINPR_MD_MD5:
85  type = MBEDTLS_MD_MD5;
86  break;
87 
88  case WINPR_MD_SHA1:
89  type = MBEDTLS_MD_SHA1;
90  break;
91 
92  case WINPR_MD_SHA224:
93  type = MBEDTLS_MD_SHA224;
94  break;
95 
96  case WINPR_MD_SHA256:
97  type = MBEDTLS_MD_SHA256;
98  break;
99 
100  case WINPR_MD_SHA384:
101  type = MBEDTLS_MD_SHA384;
102  break;
103 
104  case WINPR_MD_SHA512:
105  type = MBEDTLS_MD_SHA512;
106  break;
107  }
108 
109  return type;
110 }
111 #endif
112 
113 struct hash_map
114 {
115  const char* name;
116  WINPR_MD_TYPE md;
117 };
118 static const struct hash_map hashes[] = { { "md2", WINPR_MD_MD2 },
119  { "md4", WINPR_MD_MD4 },
120  { "md5", WINPR_MD_MD5 },
121  { "sha1", WINPR_MD_SHA1 },
122  { "sha224", WINPR_MD_SHA224 },
123  { "sha256", WINPR_MD_SHA256 },
124  { "sha384", WINPR_MD_SHA384 },
125  { "sha512", WINPR_MD_SHA512 },
126  { "sha3_224", WINPR_MD_SHA3_224 },
127  { "sha3_256", WINPR_MD_SHA3_256 },
128  { "sha3_384", WINPR_MD_SHA3_384 },
129  { "sha3_512", WINPR_MD_SHA3_512 },
130  { "shake128", WINPR_MD_SHAKE128 },
131  { "shake256", WINPR_MD_SHAKE256 },
132  { NULL, WINPR_MD_NONE } };
133 
134 WINPR_MD_TYPE winpr_md_type_from_string(const char* name)
135 {
136  const struct hash_map* cur = hashes;
137  while (cur->name)
138  {
139  if (_stricmp(cur->name, name) == 0)
140  return cur->md;
141  cur++;
142  }
143  return WINPR_MD_NONE;
144 }
145 
146 const char* winpr_md_type_to_string(WINPR_MD_TYPE md)
147 {
148  const struct hash_map* cur = hashes;
149  while (cur->name)
150  {
151  if (cur->md == md)
152  return cur->name;
153  cur++;
154  }
155  return NULL;
156 }
157 
158 struct winpr_hmac_ctx_private_st
159 {
160  WINPR_MD_TYPE md;
161 
162 #if defined(WITH_INTERNAL_MD5)
163  WINPR_HMAC_MD5_CTX hmac_md5;
164 #endif
165 #if defined(WITH_OPENSSL)
166 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
167  EVP_MAC_CTX* xhmac;
168 #else
169  HMAC_CTX* hmac;
170 #endif
171 #endif
172 #if defined(WITH_MBEDTLS)
173  mbedtls_md_context_t hmac;
174 #endif
175 };
176 
177 WINPR_HMAC_CTX* winpr_HMAC_New(void)
178 {
179  WINPR_HMAC_CTX* ctx = (WINPR_HMAC_CTX*)calloc(1, sizeof(WINPR_HMAC_CTX));
180  if (!ctx)
181  return NULL;
182 #if defined(WITH_OPENSSL)
183 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
184  (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
185 
186  if (!(ctx->hmac = (HMAC_CTX*)calloc(1, sizeof(HMAC_CTX))))
187  goto fail;
188 
189  HMAC_CTX_init(ctx->hmac);
190 #elif OPENSSL_VERSION_NUMBER < 0x30000000L
191  if (!(ctx->hmac = HMAC_CTX_new()))
192  goto fail;
193 #else
194  EVP_MAC* emac = EVP_MAC_fetch(NULL, "HMAC", NULL);
195  if (!emac)
196  goto fail;
197  ctx->xhmac = EVP_MAC_CTX_new(emac);
198  EVP_MAC_free(emac);
199  if (!ctx->xhmac)
200  goto fail;
201 #endif
202 #elif defined(WITH_MBEDTLS)
203  mbedtls_md_init(&ctx->hmac);
204 #endif
205  return ctx;
206 
207 fail:
208  WINPR_PRAGMA_DIAG_PUSH
209  WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
210  winpr_HMAC_Free(ctx);
211  WINPR_PRAGMA_DIAG_POP
212  return NULL;
213 }
214 
215 BOOL winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, WINPR_MD_TYPE md, const void* key, size_t keylen)
216 {
217  WINPR_ASSERT(ctx);
218 
219  ctx->md = md;
220  switch (ctx->md)
221  {
222 #if defined(WITH_INTERNAL_MD5)
223  case WINPR_MD_MD5:
224  hmac_md5_init(&ctx->hmac_md5, key, keylen);
225  return TRUE;
226 #endif
227  default:
228  break;
229  }
230 
231 #if defined(WITH_OPENSSL)
232 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
233  char* hash = WINPR_CAST_CONST_PTR_AWAY(winpr_md_type_to_string(md), char*);
234 
235  if (!ctx->xhmac)
236  return FALSE;
237 
238  const char* param_name = OSSL_MAC_PARAM_DIGEST;
239  const OSSL_PARAM param[] = { OSSL_PARAM_construct_utf8_string(param_name, hash, 0),
240  OSSL_PARAM_construct_end() };
241 
242  if (EVP_MAC_init(ctx->xhmac, key, keylen, param) == 1)
243  return TRUE;
244 #else
245  HMAC_CTX* hmac = ctx->hmac;
246  const EVP_MD* evp = winpr_openssl_get_evp_md(md);
247 
248  if (!evp || !hmac)
249  return FALSE;
250 
251  if (keylen > INT_MAX)
252  return FALSE;
253 #if (OPENSSL_VERSION_NUMBER < 0x10000000L) || \
254  (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
255  HMAC_Init_ex(hmac, key, (int)keylen, evp, NULL); /* no return value on OpenSSL 0.9.x */
256  return TRUE;
257 #else
258 
259  if (HMAC_Init_ex(hmac, key, (int)keylen, evp, NULL) == 1)
260  return TRUE;
261 
262 #endif
263 #endif
264 #elif defined(WITH_MBEDTLS)
265  mbedtls_md_context_t* hmac = &ctx->hmac;
266  mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
267  const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type);
268 
269  if (!md_info || !hmac)
270  return FALSE;
271 
272  if (mbedtls_md_info_from_ctx(hmac) != md_info)
273  {
274  mbedtls_md_free(hmac); /* can be called at any time after mbedtls_md_init */
275 
276  if (mbedtls_md_setup(hmac, md_info, 1) != 0)
277  return FALSE;
278  }
279 
280  if (mbedtls_md_hmac_starts(hmac, key, keylen) == 0)
281  return TRUE;
282 
283 #endif
284  return FALSE;
285 }
286 
287 BOOL winpr_HMAC_Update(WINPR_HMAC_CTX* ctx, const void* input, size_t ilen)
288 {
289  WINPR_ASSERT(ctx);
290 
291  switch (ctx->md)
292  {
293 #if defined(WITH_INTERNAL_MD5)
294  case WINPR_MD_MD5:
295  hmac_md5_update(&ctx->hmac_md5, input, ilen);
296  return TRUE;
297 #endif
298  default:
299  break;
300  }
301 
302 #if defined(WITH_OPENSSL)
303 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
304  if (EVP_MAC_update(ctx->xhmac, input, ilen) == 1)
305  return TRUE;
306 #else
307  HMAC_CTX* hmac = ctx->hmac;
308 #if (OPENSSL_VERSION_NUMBER < 0x10000000L) || \
309  (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
310  HMAC_Update(hmac, input, ilen); /* no return value on OpenSSL 0.9.x */
311  return TRUE;
312 #else
313 
314  if (HMAC_Update(hmac, input, ilen) == 1)
315  return TRUE;
316 #endif
317 #endif
318 #elif defined(WITH_MBEDTLS)
319  mbedtls_md_context_t* mdctx = &ctx->hmac;
320 
321  if (mbedtls_md_hmac_update(mdctx, input, ilen) == 0)
322  return TRUE;
323 
324 #endif
325  return FALSE;
326 }
327 
328 BOOL winpr_HMAC_Final(WINPR_HMAC_CTX* ctx, void* output, size_t olen)
329 {
330  WINPR_ASSERT(ctx);
331 
332  switch (ctx->md)
333  {
334 #if defined(WITH_INTERNAL_MD5)
335  case WINPR_MD_MD5:
336  if (olen < WINPR_MD5_DIGEST_LENGTH)
337  return FALSE;
338  hmac_md5_finalize(&ctx->hmac_md5, output);
339  return TRUE;
340 #endif
341  default:
342  break;
343  }
344 
345 #if defined(WITH_OPENSSL)
346 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
347  const int rc = EVP_MAC_final(ctx->xhmac, output, NULL, olen);
348  if (rc == 1)
349  return TRUE;
350 #else
351  HMAC_CTX* hmac = ctx->hmac;
352 #if (OPENSSL_VERSION_NUMBER < 0x10000000L) || \
353  (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
354  HMAC_Final(hmac, output, NULL); /* no return value on OpenSSL 0.9.x */
355  return TRUE;
356 #else
357 
358  if (HMAC_Final(hmac, output, NULL) == 1)
359  return TRUE;
360 
361 #endif
362 #endif
363 #elif defined(WITH_MBEDTLS)
364  mbedtls_md_context_t* mdctx = &ctx->hmac;
365 
366  if (mbedtls_md_hmac_finish(mdctx, output) == 0)
367  return TRUE;
368 
369 #endif
370  return FALSE;
371 }
372 
373 void winpr_HMAC_Free(WINPR_HMAC_CTX* ctx)
374 {
375  if (!ctx)
376  return;
377 
378 #if defined(WITH_OPENSSL)
379 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
380  EVP_MAC_CTX_free(ctx->xhmac);
381 #else
382  HMAC_CTX* hmac = ctx->hmac;
383 
384  if (hmac)
385  {
386 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
387  (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
388  HMAC_CTX_cleanup(hmac);
389  free(hmac);
390 #else
391  HMAC_CTX_free(hmac);
392 #endif
393  }
394 #endif
395 #elif defined(WITH_MBEDTLS)
396  mbedtls_md_context_t* hmac = &ctx->hmac;
397 
398  if (hmac)
399  mbedtls_md_free(hmac);
400 
401 #endif
402 
403  free(ctx);
404 }
405 
406 BOOL winpr_HMAC(WINPR_MD_TYPE md, const void* key, size_t keylen, const void* input, size_t ilen,
407  void* output, size_t olen)
408 {
409  BOOL result = FALSE;
410  WINPR_HMAC_CTX* ctx = winpr_HMAC_New();
411 
412  if (!ctx)
413  return FALSE;
414 
415  if (!winpr_HMAC_Init(ctx, md, key, keylen))
416  goto out;
417 
418  if (!winpr_HMAC_Update(ctx, input, ilen))
419  goto out;
420 
421  if (!winpr_HMAC_Final(ctx, output, olen))
422  goto out;
423 
424  result = TRUE;
425 out:
426  winpr_HMAC_Free(ctx);
427  return result;
428 }
429 
434 struct winpr_digest_ctx_private_st
435 {
436  WINPR_MD_TYPE md;
437 
438 #if defined(WITH_INTERNAL_MD4)
439  WINPR_MD4_CTX md4;
440 #endif
441 #if defined(WITH_INTERNAL_MD5)
442  WINPR_MD5_CTX md5;
443 #endif
444 #if defined(WITH_OPENSSL)
445  EVP_MD_CTX* mdctx;
446 #endif
447 #if defined(WITH_MBEDTLS)
448  mbedtls_md_context_t* mdctx;
449 #endif
450 };
451 
452 WINPR_DIGEST_CTX* winpr_Digest_New(void)
453 {
454  WINPR_DIGEST_CTX* ctx = calloc(1, sizeof(WINPR_DIGEST_CTX));
455  if (!ctx)
456  return NULL;
457 
458 #if defined(WITH_OPENSSL)
459 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
460  (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
461  ctx->mdctx = EVP_MD_CTX_create();
462 #else
463  ctx->mdctx = EVP_MD_CTX_new();
464 #endif
465  if (!ctx->mdctx)
466  goto fail;
467 
468 #elif defined(WITH_MBEDTLS)
469  ctx->mdctx = (mbedtls_md_context_t*)calloc(1, sizeof(mbedtls_md_context_t));
470 
471  if (!ctx->mdctx)
472  goto fail;
473 
474  mbedtls_md_init(ctx->mdctx);
475 #endif
476  return ctx;
477 
478 fail:
479  WINPR_PRAGMA_DIAG_PUSH
480  WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
481  winpr_Digest_Free(ctx);
482  WINPR_PRAGMA_DIAG_POP
483  return NULL;
484 }
485 
486 #if defined(WITH_OPENSSL)
487 static BOOL winpr_Digest_Init_Internal(WINPR_DIGEST_CTX* ctx, const EVP_MD* evp)
488 {
489  WINPR_ASSERT(ctx);
490  EVP_MD_CTX* mdctx = ctx->mdctx;
491 
492  if (!mdctx || !evp)
493  return FALSE;
494 
495  if (EVP_DigestInit_ex(mdctx, evp, NULL) != 1)
496  {
497  WLog_ERR(TAG, "Failed to initialize digest %s", winpr_md_type_to_string(ctx->md));
498  return FALSE;
499  }
500 
501  return TRUE;
502 }
503 
504 #elif defined(WITH_MBEDTLS)
505 static BOOL winpr_Digest_Init_Internal(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
506 {
507  WINPR_ASSERT(ctx);
508  mbedtls_md_context_t* mdctx = ctx->mdctx;
509  mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md);
510  const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type);
511 
512  if (!md_info)
513  return FALSE;
514 
515  if (mbedtls_md_info_from_ctx(mdctx) != md_info)
516  {
517  mbedtls_md_free(mdctx); /* can be called at any time after mbedtls_md_init */
518 
519  if (mbedtls_md_setup(mdctx, md_info, 0) != 0)
520  return FALSE;
521  }
522 
523  if (mbedtls_md_starts(mdctx) != 0)
524  return FALSE;
525 
526  return TRUE;
527 }
528 #endif
529 
530 BOOL winpr_Digest_Init_Allow_FIPS(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
531 {
532  WINPR_ASSERT(ctx);
533 
534  ctx->md = md;
535  switch (md)
536  {
537  case WINPR_MD_MD5:
538 #if defined(WITH_INTERNAL_MD5)
539  winpr_MD5_Init(&ctx->md5);
540  return TRUE;
541 #else
542  break;
543 #endif
544  default:
545  WLog_ERR(TAG, "Invalid FIPS digest %s requested", winpr_md_type_to_string(md));
546  return FALSE;
547  }
548 
549 #if defined(WITH_OPENSSL)
550 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
551  if (md == WINPR_MD_MD5)
552  {
553  EVP_MD* md5 = EVP_MD_fetch(NULL, "MD5", "fips=no");
554  BOOL rc = winpr_Digest_Init_Internal(ctx, md5);
555  EVP_MD_free(md5);
556  return rc;
557  }
558 #endif
559  const EVP_MD* evp = winpr_openssl_get_evp_md(md);
560  EVP_MD_CTX_set_flags(ctx->mdctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
561  return winpr_Digest_Init_Internal(ctx, evp);
562 #elif defined(WITH_MBEDTLS)
563  return winpr_Digest_Init_Internal(ctx, md);
564 #endif
565 }
566 
567 BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
568 {
569  WINPR_ASSERT(ctx);
570 
571  ctx->md = md;
572  switch (md)
573  {
574 #if defined(WITH_INTERNAL_MD4)
575  case WINPR_MD_MD4:
576  winpr_MD4_Init(&ctx->md4);
577  return TRUE;
578 #endif
579 #if defined(WITH_INTERNAL_MD5)
580  case WINPR_MD_MD5:
581  winpr_MD5_Init(&ctx->md5);
582  return TRUE;
583 #endif
584  default:
585  break;
586  }
587 
588 #if defined(WITH_OPENSSL)
589  const EVP_MD* evp = winpr_openssl_get_evp_md(md);
590  return winpr_Digest_Init_Internal(ctx, evp);
591 #else
592  return winpr_Digest_Init_Internal(ctx, md);
593 #endif
594 }
595 
596 BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const void* input, size_t ilen)
597 {
598  WINPR_ASSERT(ctx);
599 
600  switch (ctx->md)
601  {
602 #if defined(WITH_INTERNAL_MD4)
603  case WINPR_MD_MD4:
604  winpr_MD4_Update(&ctx->md4, input, ilen);
605  return TRUE;
606 #endif
607 #if defined(WITH_INTERNAL_MD5)
608  case WINPR_MD_MD5:
609  winpr_MD5_Update(&ctx->md5, input, ilen);
610  return TRUE;
611 #endif
612  default:
613  break;
614  }
615 
616 #if defined(WITH_OPENSSL)
617  EVP_MD_CTX* mdctx = ctx->mdctx;
618 
619  if (EVP_DigestUpdate(mdctx, input, ilen) != 1)
620  return FALSE;
621 
622 #elif defined(WITH_MBEDTLS)
623  mbedtls_md_context_t* mdctx = ctx->mdctx;
624 
625  if (mbedtls_md_update(mdctx, input, ilen) != 0)
626  return FALSE;
627 
628 #endif
629  return TRUE;
630 }
631 
632 BOOL winpr_Digest_Final(WINPR_DIGEST_CTX* ctx, void* output, size_t olen)
633 {
634  WINPR_ASSERT(ctx);
635 
636  switch (ctx->md)
637  {
638 #if defined(WITH_INTERNAL_MD4)
639  case WINPR_MD_MD4:
640  if (olen < WINPR_MD4_DIGEST_LENGTH)
641  return FALSE;
642  winpr_MD4_Final(output, &ctx->md4);
643  return TRUE;
644 #endif
645 #if defined(WITH_INTERNAL_MD5)
646  case WINPR_MD_MD5:
647  if (olen < WINPR_MD5_DIGEST_LENGTH)
648  return FALSE;
649  winpr_MD5_Final(output, &ctx->md5);
650  return TRUE;
651 #endif
652 
653  default:
654  break;
655  }
656 
657 #if defined(WITH_OPENSSL)
658  EVP_MD_CTX* mdctx = ctx->mdctx;
659 
660  if (EVP_DigestFinal_ex(mdctx, output, NULL) == 1)
661  return TRUE;
662 
663 #elif defined(WITH_MBEDTLS)
664  mbedtls_md_context_t* mdctx = ctx->mdctx;
665 
666  if (mbedtls_md_finish(mdctx, output) == 0)
667  return TRUE;
668 
669 #endif
670  return FALSE;
671 }
672 
673 BOOL winpr_DigestSign_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE digest, void* key)
674 {
675  WINPR_ASSERT(ctx);
676 
677 #if defined(WITH_OPENSSL)
678  const EVP_MD* evp = winpr_openssl_get_evp_md(digest);
679  if (!evp)
680  return FALSE;
681 
682  const int rdsi = EVP_DigestSignInit(ctx->mdctx, NULL, evp, NULL, key);
683  if (rdsi <= 0)
684  return FALSE;
685  return TRUE;
686 #else
687  return FALSE;
688 #endif
689 }
690 
691 BOOL winpr_DigestSign_Update(WINPR_DIGEST_CTX* ctx, const void* input, size_t ilen)
692 {
693  WINPR_ASSERT(ctx);
694 
695 #if defined(WITH_OPENSSL)
696  EVP_MD_CTX* mdctx = ctx->mdctx;
697 
698  if (EVP_DigestSignUpdate(mdctx, input, ilen) != 1)
699  return FALSE;
700  return TRUE;
701 #else
702  return FALSE;
703 #endif
704 }
705 
706 BOOL winpr_DigestSign_Final(WINPR_DIGEST_CTX* ctx, void* output, size_t* piolen)
707 {
708  WINPR_ASSERT(ctx);
709 
710 #if defined(WITH_OPENSSL)
711  EVP_MD_CTX* mdctx = ctx->mdctx;
712 
713  return EVP_DigestSignFinal(mdctx, output, piolen) == 1;
714 #else
715  return FALSE;
716 #endif
717 }
718 
719 void winpr_Digest_Free(WINPR_DIGEST_CTX* ctx)
720 {
721  if (!ctx)
722  return;
723 #if defined(WITH_OPENSSL)
724  if (ctx->mdctx)
725  {
726 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
727  (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
728  EVP_MD_CTX_destroy(ctx->mdctx);
729 #else
730  EVP_MD_CTX_free(ctx->mdctx);
731 #endif
732  }
733 
734 #elif defined(WITH_MBEDTLS)
735  if (ctx->mdctx)
736  {
737  mbedtls_md_free(ctx->mdctx);
738  free(ctx->mdctx);
739  }
740 
741 #endif
742  free(ctx);
743 }
744 
745 BOOL winpr_Digest_Allow_FIPS(WINPR_MD_TYPE md, const void* input, size_t ilen, void* output,
746  size_t olen)
747 {
748  BOOL result = FALSE;
749  WINPR_DIGEST_CTX* ctx = winpr_Digest_New();
750 
751  if (!ctx)
752  return FALSE;
753 
754  if (!winpr_Digest_Init_Allow_FIPS(ctx, md))
755  goto out;
756 
757  if (!winpr_Digest_Update(ctx, input, ilen))
758  goto out;
759 
760  if (!winpr_Digest_Final(ctx, output, olen))
761  goto out;
762 
763  result = TRUE;
764 out:
765  winpr_Digest_Free(ctx);
766  return result;
767 }
768 
769 BOOL winpr_Digest(WINPR_MD_TYPE md, const void* input, size_t ilen, void* output, size_t olen)
770 {
771  BOOL result = FALSE;
772  WINPR_DIGEST_CTX* ctx = winpr_Digest_New();
773 
774  if (!ctx)
775  return FALSE;
776 
777  if (!winpr_Digest_Init(ctx, md))
778  goto out;
779 
780  if (!winpr_Digest_Update(ctx, input, ilen))
781  goto out;
782 
783  if (!winpr_Digest_Final(ctx, output, olen))
784  goto out;
785 
786  result = TRUE;
787 out:
788  winpr_Digest_Free(ctx);
789  return result;
790 }