IMPALA-14385: Fix crashes using sha2() in FIPS CentOS 7

This commit fixes a crash in the sha2() function that occurs when
Impala is run on a FIPS enabled OS, particularly CentOS 7. Running
sha2() with 384 or 512-bit lengths would cause the impalad
to crash with an OpenSSL assertion failure:
"Low level API call to digest SHA384 forbidden in FIPS mode!"

The root cause was the direct use of low-level OpenSSL API calls
like SHA384(), SHA512(). OpenSSL 1.0 (used in RHEL/CentOS 7) is
particularly strict and forbids these calls in FIPS mode, causing
the module to terminate the process.

This patch changes to use the high-level, FIPS compliant EVP_Digest
API to perform the hash in sha2() function implementation.

Tests:
Ran sha2() in FIPS enabled CentOs 7 after the change and succeeded.
Passed exhaustive tests.

Change-Id: I694532350285534fd935c92b7a78bed91ded3cb5
Reviewed-on: http://gerrit.cloudera.org:8080/23373
Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
This commit is contained in:
Yida Wu
2025-09-02 13:06:47 -07:00
committed by Impala Public Jenkins
parent c78f7a7290
commit e486f3e3c3

View File

@@ -287,28 +287,25 @@ StringVal UtilityFunctions::Sha2(FunctionContext* ctx, const StringVal& input_st
return StringVal::null();
}
StringVal sha_hash;
const EVP_MD* md_alg = nullptr;
int digest_length = 0;
switch(bit_len.val) {
case 224:
sha_hash = StringVal(ctx, SHA224_DIGEST_LENGTH);
if (UNLIKELY(sha_hash.is_null)) return StringVal::null();
SHA224(input_str.ptr, input_str.len, sha_hash.ptr);
md_alg = EVP_sha224();
digest_length = SHA224_DIGEST_LENGTH;
break;
case 256:
sha_hash = StringVal(ctx, SHA256_DIGEST_LENGTH);
if (UNLIKELY(sha_hash.is_null)) return StringVal::null();
SHA256(input_str.ptr, input_str.len, sha_hash.ptr);
md_alg = EVP_sha256();
digest_length = SHA256_DIGEST_LENGTH;
break;
case 384:
sha_hash = StringVal(ctx, SHA384_DIGEST_LENGTH);
if (UNLIKELY(sha_hash.is_null)) return StringVal::null();
SHA384(input_str.ptr, input_str.len, sha_hash.ptr);
md_alg = EVP_sha384();
digest_length = SHA384_DIGEST_LENGTH;
break;
case 512:
sha_hash = StringVal(ctx, SHA512_DIGEST_LENGTH);
if (UNLIKELY(sha_hash.is_null)) return StringVal::null();
SHA512(input_str.ptr, input_str.len, sha_hash.ptr);
md_alg = EVP_sha512();
digest_length = SHA512_DIGEST_LENGTH;
break;
default:
// Unsupported bit length.
@@ -316,6 +313,14 @@ StringVal UtilityFunctions::Sha2(FunctionContext* ctx, const StringVal& input_st
return StringVal::null();
}
StringVal sha_hash(ctx, digest_length);
if (UNLIKELY(sha_hash.is_null)) return StringVal::null();
// Do not use low-level calls like SHA384(), which can be forbidden in FIPS mode.
// This is the fips-compliant hashing implementation, which uses the high-level
// EVP_Digest function.
EVP_Digest(input_str.ptr, input_str.len, sha_hash.ptr, nullptr, md_alg, nullptr);
return StringFunctions::Lower(ctx, MathFunctions::HexString(ctx, sha_hash));
}