Skip to content

Commit 83fd7f1

Browse files
authored
Fix issue using non-FIPS algorithsm in some FIPS environments (#1589)
Despite using "-fips" for `EVP_MD_fetch()` with OpenSSL 3, we are seeing this error in some FIPS-enabled environments: LibClamAV Error: cli_scan_fmap: Error initializing md5 hash context The fix seems to be to create a new OpenSSL context rather than passing NULL for the default context. See: https://docs.openssl.org/3.0/man7/fips_module/#programmatically-loading-the-fips-module-nondefault-library-context Special thanks to Tom Judge for identifying this fix. CLAM-2879
1 parent c26a818 commit 83fd7f1

File tree

1 file changed

+79
-12
lines changed

1 file changed

+79
-12
lines changed

libclamav/crypto.c

Lines changed: 79 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,8 @@ extern cl_error_t cl_hash_data_ex(
196196
EVP_MD_CTX *ctx = NULL;
197197

198198
#if OPENSSL_VERSION_MAJOR >= 3
199-
EVP_MD *md = NULL;
199+
OSSL_LIB_CTX *ossl_ctx = NULL;
200+
EVP_MD *md = NULL;
200201
#else
201202
const EVP_MD *md = NULL;
202203
#endif
@@ -219,7 +220,14 @@ extern cl_error_t cl_hash_data_ex(
219220
#if OPENSSL_VERSION_MAJOR >= 3
220221
if (flags & CL_HASH_FLAG_FIPS_BYPASS) {
221222
/* Bypass FIPS restrictions the OpenSSL 3.0 way */
222-
md = EVP_MD_fetch(NULL, to_openssl_alg(alg), "-fips");
223+
ossl_ctx = OSSL_LIB_CTX_new();
224+
if (NULL == ossl_ctx) {
225+
cli_errmsg("cl_hash_data_ex: Failed to create new OpenSSL library context\n");
226+
status = CL_EMEM;
227+
goto done;
228+
}
229+
230+
md = EVP_MD_fetch(ossl_ctx, to_openssl_alg(alg), "-fips");
223231
} else {
224232
/* Use FIPS compliant algorithms */
225233
md = EVP_MD_fetch(NULL, to_openssl_alg(alg), NULL);
@@ -322,6 +330,9 @@ extern cl_error_t cl_hash_data_ex(
322330
if (NULL != md) {
323331
EVP_MD_free(md);
324332
}
333+
if (NULL != ossl_ctx) {
334+
OSSL_LIB_CTX_free(ossl_ctx);
335+
}
325336
#endif
326337
return status;
327338
}
@@ -345,7 +356,8 @@ extern cl_error_t cl_hash_init_ex(
345356
EVP_MD_CTX *ctx = NULL;
346357

347358
#if OPENSSL_VERSION_MAJOR >= 3
348-
EVP_MD *md = NULL;
359+
OSSL_LIB_CTX *ossl_ctx = NULL;
360+
EVP_MD *md = NULL;
349361
#else
350362
const EVP_MD *md = NULL;
351363
#endif
@@ -359,7 +371,14 @@ extern cl_error_t cl_hash_init_ex(
359371
#if OPENSSL_VERSION_MAJOR >= 3
360372
if (flags & CL_HASH_FLAG_FIPS_BYPASS) {
361373
/* Bypass FIPS restrictions the OpenSSL 3.0 way */
362-
md = EVP_MD_fetch(NULL, to_openssl_alg(alg), "-fips");
374+
ossl_ctx = OSSL_LIB_CTX_new();
375+
if (NULL == ossl_ctx) {
376+
cli_errmsg("cl_hash_data_ex: Failed to create new OpenSSL library context\n");
377+
status = CL_EMEM;
378+
goto done;
379+
}
380+
381+
md = EVP_MD_fetch(ossl_ctx, to_openssl_alg(alg), "-fips");
363382
} else {
364383
/* Use FIPS compliant algorithms */
365384
md = EVP_MD_fetch(NULL, to_openssl_alg(alg), NULL);
@@ -406,6 +425,9 @@ extern cl_error_t cl_hash_init_ex(
406425
if (NULL != md) {
407426
EVP_MD_free(md);
408427
}
428+
if (NULL != ossl_ctx) {
429+
OSSL_LIB_CTX_free(ossl_ctx);
430+
}
409431
#endif
410432
return status;
411433
}
@@ -570,7 +592,8 @@ extern cl_error_t cl_hash_file_fd_ex(
570592
EVP_MD_CTX *ctx = NULL;
571593

572594
#if OPENSSL_VERSION_MAJOR >= 3
573-
EVP_MD *md = NULL;
595+
OSSL_LIB_CTX *ossl_ctx = NULL;
596+
EVP_MD *md = NULL;
574597
#else
575598
const EVP_MD *md = NULL;
576599
#endif
@@ -620,7 +643,14 @@ extern cl_error_t cl_hash_file_fd_ex(
620643
#if OPENSSL_VERSION_MAJOR >= 3
621644
if (flags & CL_HASH_FLAG_FIPS_BYPASS) {
622645
/* Bypass FIPS restrictions the OpenSSL 3.0 way */
623-
md = EVP_MD_fetch(NULL, to_openssl_alg(alg), "-fips");
646+
ossl_ctx = OSSL_LIB_CTX_new();
647+
if (NULL == ossl_ctx) {
648+
cli_errmsg("cl_hash_data_ex: Failed to create new OpenSSL library context\n");
649+
status = CL_EMEM;
650+
goto done;
651+
}
652+
653+
md = EVP_MD_fetch(ossl_ctx, to_openssl_alg(alg), "-fips");
624654
} else {
625655
/* Use FIPS compliant algorithms */
626656
md = EVP_MD_fetch(NULL, to_openssl_alg(alg), NULL);
@@ -750,6 +780,9 @@ extern cl_error_t cl_hash_file_fd_ex(
750780
if (NULL != md) {
751781
EVP_MD_free(md);
752782
}
783+
if (NULL != ossl_ctx) {
784+
OSSL_LIB_CTX_free(ossl_ctx);
785+
}
753786
#endif
754787
return status;
755788
}
@@ -761,7 +794,8 @@ unsigned char *cl_hash_data(const char *alg, const void *buf, size_t len, unsign
761794
size_t mdsz;
762795

763796
#if OPENSSL_VERSION_MAJOR >= 3
764-
EVP_MD *md = NULL;
797+
OSSL_LIB_CTX *ossl_ctx = NULL;
798+
EVP_MD *md = NULL;
765799
#else
766800
const EVP_MD *md = NULL;
767801
#endif
@@ -774,7 +808,13 @@ unsigned char *cl_hash_data(const char *alg, const void *buf, size_t len, unsign
774808

775809
#if OPENSSL_VERSION_MAJOR >= 3
776810
/* Bypass FIPS restrictions the OpenSSL 3.0 way */
777-
md = EVP_MD_fetch(NULL, to_openssl_alg(alg), "-fips");
811+
ossl_ctx = OSSL_LIB_CTX_new();
812+
if (NULL == ossl_ctx) {
813+
cli_errmsg("cl_hash_data_ex: Failed to create new OpenSSL library context\n");
814+
return NULL;
815+
}
816+
817+
md = EVP_MD_fetch(ossl_ctx, to_openssl_alg(alg), "-fips");
778818
#else
779819
md = EVP_get_digestbyname(to_openssl_alg(alg));
780820
#endif
@@ -787,6 +827,7 @@ unsigned char *cl_hash_data(const char *alg, const void *buf, size_t len, unsign
787827
if (!(ret)) {
788828
#if OPENSSL_VERSION_MAJOR >= 3
789829
EVP_MD_free(md);
830+
OSSL_LIB_CTX_free(ossl_ctx);
790831
#endif
791832
return NULL;
792833
}
@@ -798,6 +839,7 @@ unsigned char *cl_hash_data(const char *alg, const void *buf, size_t len, unsign
798839

799840
#if OPENSSL_VERSION_MAJOR >= 3
800841
EVP_MD_free(md);
842+
OSSL_LIB_CTX_free(ossl_ctx);
801843
#endif
802844
return NULL;
803845
}
@@ -818,6 +860,7 @@ unsigned char *cl_hash_data(const char *alg, const void *buf, size_t len, unsign
818860

819861
#if OPENSSL_VERSION_MAJOR >= 3
820862
EVP_MD_free(md);
863+
OSSL_LIB_CTX_free(ossl_ctx);
821864
#endif
822865
EVP_MD_CTX_destroy(ctx);
823866
return NULL;
@@ -837,6 +880,7 @@ unsigned char *cl_hash_data(const char *alg, const void *buf, size_t len, unsign
837880

838881
#if OPENSSL_VERSION_MAJOR >= 3
839882
EVP_MD_free(md);
883+
OSSL_LIB_CTX_free(ossl_ctx);
840884
#endif
841885
EVP_MD_CTX_destroy(ctx);
842886
return NULL;
@@ -853,6 +897,7 @@ unsigned char *cl_hash_data(const char *alg, const void *buf, size_t len, unsign
853897

854898
#if OPENSSL_VERSION_MAJOR >= 3
855899
EVP_MD_free(md);
900+
OSSL_LIB_CTX_free(ossl_ctx);
856901
#endif
857902
EVP_MD_CTX_destroy(ctx);
858903
return NULL;
@@ -871,13 +916,15 @@ unsigned char *cl_hash_data(const char *alg, const void *buf, size_t len, unsign
871916

872917
#if OPENSSL_VERSION_MAJOR >= 3
873918
EVP_MD_free(md);
919+
OSSL_LIB_CTX_free(ossl_ctx);
874920
#endif
875921
EVP_MD_CTX_destroy(ctx);
876922
return NULL;
877923
}
878924

879925
#if OPENSSL_VERSION_MAJOR >= 3
880926
EVP_MD_free(md);
927+
OSSL_LIB_CTX_free(ossl_ctx);
881928
#endif
882929
EVP_MD_CTX_destroy(ctx);
883930

@@ -892,7 +939,8 @@ unsigned char *cl_hash_file_fd(int fd, const char *alg, unsigned int *olen)
892939
EVP_MD_CTX *ctx;
893940

894941
#if OPENSSL_VERSION_MAJOR >= 3
895-
EVP_MD *md = NULL;
942+
OSSL_LIB_CTX *ossl_ctx = NULL;
943+
EVP_MD *md = NULL;
896944
#else
897945
const EVP_MD *md = NULL;
898946
#endif
@@ -901,7 +949,13 @@ unsigned char *cl_hash_file_fd(int fd, const char *alg, unsigned int *olen)
901949

902950
#if OPENSSL_VERSION_MAJOR >= 3
903951
/* Bypass FIPS restrictions the OpenSSL 3.0 way */
904-
md = EVP_MD_fetch(NULL, to_openssl_alg(alg), "-fips");
952+
ossl_ctx = OSSL_LIB_CTX_new();
953+
if (NULL == ossl_ctx) {
954+
cli_errmsg("cl_hash_data_ex: Failed to create new OpenSSL library context\n");
955+
return NULL;
956+
}
957+
958+
md = EVP_MD_fetch(ossl_ctx, to_openssl_alg(alg), "-fips");
905959
#else
906960
md = EVP_get_digestbyname(to_openssl_alg(alg));
907961
#endif
@@ -912,6 +966,7 @@ unsigned char *cl_hash_file_fd(int fd, const char *alg, unsigned int *olen)
912966
if (!(ctx)) {
913967
#if OPENSSL_VERSION_MAJOR >= 3
914968
EVP_MD_free(md);
969+
OSSL_LIB_CTX_free(ossl_ctx);
915970
#endif
916971
return NULL;
917972
}
@@ -926,6 +981,7 @@ unsigned char *cl_hash_file_fd(int fd, const char *alg, unsigned int *olen)
926981
if (!EVP_DigestInit_ex(ctx, md, NULL)) {
927982
#if OPENSSL_VERSION_MAJOR >= 3
928983
EVP_MD_free(md);
984+
OSSL_LIB_CTX_free(ossl_ctx);
929985
#endif
930986
EVP_MD_CTX_free(ctx);
931987
return NULL;
@@ -934,6 +990,7 @@ unsigned char *cl_hash_file_fd(int fd, const char *alg, unsigned int *olen)
934990
res = cl_hash_file_fd_ctx(ctx, fd, olen);
935991
#if OPENSSL_VERSION_MAJOR >= 3
936992
EVP_MD_free(md);
993+
OSSL_LIB_CTX_free(ossl_ctx);
937994
#endif
938995
EVP_MD_CTX_free(ctx);
939996

@@ -1788,14 +1845,21 @@ void *cl_hash_init(const char *alg)
17881845
EVP_MD_CTX *ctx;
17891846

17901847
#if OPENSSL_VERSION_MAJOR >= 3
1791-
EVP_MD *md = NULL;
1848+
OSSL_LIB_CTX *ossl_ctx = NULL;
1849+
EVP_MD *md = NULL;
17921850
#else
17931851
const EVP_MD *md = NULL;
17941852
#endif
17951853

17961854
#if OPENSSL_VERSION_MAJOR >= 3
17971855
/* Bypass FIPS restrictions the OpenSSL 3.0 way */
1798-
md = EVP_MD_fetch(NULL, to_openssl_alg(alg), "-fips");
1856+
ossl_ctx = OSSL_LIB_CTX_new();
1857+
if (NULL == ossl_ctx) {
1858+
cli_errmsg("cl_hash_data_ex: Failed to create new OpenSSL library context\n");
1859+
return NULL;
1860+
}
1861+
1862+
md = EVP_MD_fetch(ossl_ctx, to_openssl_alg(alg), "-fips");
17991863
#else
18001864
md = EVP_get_digestbyname(to_openssl_alg(alg));
18011865
#endif
@@ -1806,6 +1870,7 @@ void *cl_hash_init(const char *alg)
18061870
if (!(ctx)) {
18071871
#if OPENSSL_VERSION_MAJOR >= 3
18081872
EVP_MD_free(md);
1873+
OSSL_LIB_CTX_free(ossl_ctx);
18091874
#endif
18101875
return NULL;
18111876
}
@@ -1820,13 +1885,15 @@ void *cl_hash_init(const char *alg)
18201885
if (!EVP_DigestInit_ex(ctx, md, NULL)) {
18211886
#if OPENSSL_VERSION_MAJOR >= 3
18221887
EVP_MD_free(md);
1888+
OSSL_LIB_CTX_free(ossl_ctx);
18231889
#endif
18241890
EVP_MD_CTX_free(ctx);
18251891
return NULL;
18261892
}
18271893

18281894
#if OPENSSL_VERSION_MAJOR >= 3
18291895
EVP_MD_free(md);
1896+
OSSL_LIB_CTX_free(ossl_ctx);
18301897
#endif
18311898
return (void *)ctx;
18321899
}

0 commit comments

Comments
 (0)