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 !defined(WITH_INTERNAL_MD5)
552  if (md == WINPR_MD_MD5)
553  {
554  EVP_MD* md5 = EVP_MD_fetch(NULL, "MD5", "fips=no");
555  BOOL rc = winpr_Digest_Init_Internal(ctx, md5);
556  EVP_MD_free(md5);
557  return rc;
558  }
559 #endif
560 #endif
561  const EVP_MD* evp = winpr_openssl_get_evp_md(md);
562  EVP_MD_CTX_set_flags(ctx->mdctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
563  return winpr_Digest_Init_Internal(ctx, evp);
564 #elif defined(WITH_MBEDTLS)
565  return winpr_Digest_Init_Internal(ctx, md);
566 #endif
567 }
568 
569 BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md)
570 {
571  WINPR_ASSERT(ctx);
572 
573  ctx->md = md;
574  switch (md)
575  {
576 #if defined(WITH_INTERNAL_MD4)
577  case WINPR_MD_MD4:
578  winpr_MD4_Init(&ctx->md4);
579  return TRUE;
580 #endif
581 #if defined(WITH_INTERNAL_MD5)
582  case WINPR_MD_MD5:
583  winpr_MD5_Init(&ctx->md5);
584  return TRUE;
585 #endif
586  default:
587  break;
588  }
589 
590 #if defined(WITH_OPENSSL)
591  const EVP_MD* evp = winpr_openssl_get_evp_md(md);
592  return winpr_Digest_Init_Internal(ctx, evp);
593 #else
594  return winpr_Digest_Init_Internal(ctx, md);
595 #endif
596 }
597 
598 BOOL winpr_Digest_Update(WINPR_DIGEST_CTX* ctx, const void* input, size_t ilen)
599 {
600  WINPR_ASSERT(ctx);
601 
602  switch (ctx->md)
603  {
604 #if defined(WITH_INTERNAL_MD4)
605  case WINPR_MD_MD4:
606  winpr_MD4_Update(&ctx->md4, input, ilen);
607  return TRUE;
608 #endif
609 #if defined(WITH_INTERNAL_MD5)
610  case WINPR_MD_MD5:
611  winpr_MD5_Update(&ctx->md5, input, ilen);
612  return TRUE;
613 #endif
614  default:
615  break;
616  }
617 
618 #if defined(WITH_OPENSSL)
619  EVP_MD_CTX* mdctx = ctx->mdctx;
620 
621  if (EVP_DigestUpdate(mdctx, input, ilen) != 1)
622  return FALSE;
623 
624 #elif defined(WITH_MBEDTLS)
625  mbedtls_md_context_t* mdctx = ctx->mdctx;
626 
627  if (mbedtls_md_update(mdctx, input, ilen) != 0)
628  return FALSE;
629 
630 #endif
631  return TRUE;
632 }
633 
634 BOOL winpr_Digest_Final(WINPR_DIGEST_CTX* ctx, void* output, size_t olen)
635 {
636  WINPR_ASSERT(ctx);
637 
638  switch (ctx->md)
639  {
640 #if defined(WITH_INTERNAL_MD4)
641  case WINPR_MD_MD4:
642  if (olen < WINPR_MD4_DIGEST_LENGTH)
643  return FALSE;
644  winpr_MD4_Final(output, &ctx->md4);
645  return TRUE;
646 #endif
647 #if defined(WITH_INTERNAL_MD5)
648  case WINPR_MD_MD5:
649  if (olen < WINPR_MD5_DIGEST_LENGTH)
650  return FALSE;
651  winpr_MD5_Final(output, &ctx->md5);
652  return TRUE;
653 #endif
654 
655  default:
656  break;
657  }
658 
659 #if defined(WITH_OPENSSL)
660  EVP_MD_CTX* mdctx = ctx->mdctx;
661 
662  if (EVP_DigestFinal_ex(mdctx, output, NULL) == 1)
663  return TRUE;
664 
665 #elif defined(WITH_MBEDTLS)
666  mbedtls_md_context_t* mdctx = ctx->mdctx;
667 
668  if (mbedtls_md_finish(mdctx, output) == 0)
669  return TRUE;
670 
671 #endif
672  return FALSE;
673 }
674 
675 BOOL winpr_DigestSign_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE digest, void* key)
676 {
677  WINPR_ASSERT(ctx);
678 
679 #if defined(WITH_OPENSSL)
680  const EVP_MD* evp = winpr_openssl_get_evp_md(digest);
681  if (!evp)
682  return FALSE;
683 
684  const int rdsi = EVP_DigestSignInit(ctx->mdctx, NULL, evp, NULL, key);
685  if (rdsi <= 0)
686  return FALSE;
687  return TRUE;
688 #else
689  return FALSE;
690 #endif
691 }
692 
693 BOOL winpr_DigestSign_Update(WINPR_DIGEST_CTX* ctx, const void* input, size_t ilen)
694 {
695  WINPR_ASSERT(ctx);
696 
697 #if defined(WITH_OPENSSL)
698  EVP_MD_CTX* mdctx = ctx->mdctx;
699 
700  if (EVP_DigestSignUpdate(mdctx, input, ilen) != 1)
701  return FALSE;
702  return TRUE;
703 #else
704  return FALSE;
705 #endif
706 }
707 
708 BOOL winpr_DigestSign_Final(WINPR_DIGEST_CTX* ctx, void* output, size_t* piolen)
709 {
710  WINPR_ASSERT(ctx);
711 
712 #if defined(WITH_OPENSSL)
713  EVP_MD_CTX* mdctx = ctx->mdctx;
714 
715  return EVP_DigestSignFinal(mdctx, output, piolen) == 1;
716 #else
717  return FALSE;
718 #endif
719 }
720 
721 void winpr_Digest_Free(WINPR_DIGEST_CTX* ctx)
722 {
723  if (!ctx)
724  return;
725 #if defined(WITH_OPENSSL)
726  if (ctx->mdctx)
727  {
728 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
729  (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
730  EVP_MD_CTX_destroy(ctx->mdctx);
731 #else
732  EVP_MD_CTX_free(ctx->mdctx);
733 #endif
734  }
735 
736 #elif defined(WITH_MBEDTLS)
737  if (ctx->mdctx)
738  {
739  mbedtls_md_free(ctx->mdctx);
740  free(ctx->mdctx);
741  }
742 
743 #endif
744  free(ctx);
745 }
746 
747 BOOL winpr_Digest_Allow_FIPS(WINPR_MD_TYPE md, const void* input, size_t ilen, void* output,
748  size_t olen)
749 {
750  BOOL result = FALSE;
751  WINPR_DIGEST_CTX* ctx = winpr_Digest_New();
752 
753  if (!ctx)
754  return FALSE;
755 
756  if (!winpr_Digest_Init_Allow_FIPS(ctx, md))
757  goto out;
758 
759  if (!winpr_Digest_Update(ctx, input, ilen))
760  goto out;
761 
762  if (!winpr_Digest_Final(ctx, output, olen))
763  goto out;
764 
765  result = TRUE;
766 out:
767  winpr_Digest_Free(ctx);
768  return result;
769 }
770 
771 BOOL winpr_Digest(WINPR_MD_TYPE md, const void* input, size_t ilen, void* output, size_t olen)
772 {
773  BOOL result = FALSE;
774  WINPR_DIGEST_CTX* ctx = winpr_Digest_New();
775 
776  if (!ctx)
777  return FALSE;
778 
779  if (!winpr_Digest_Init(ctx, md))
780  goto out;
781 
782  if (!winpr_Digest_Update(ctx, input, ilen))
783  goto out;
784 
785  if (!winpr_Digest_Final(ctx, output, olen))
786  goto out;
787 
788  result = TRUE;
789 out:
790  winpr_Digest_Free(ctx);
791  return result;
792 }