Skip to content

Commit

Permalink
[Crypto] replacing OpenSSL-specific flag by new public API
Browse files Browse the repository at this point in the history
This is a follow_up to #36386 based on a post-merge comment,
- an OpenSSL-specific mInitialized flag was added to HASH_SHA256 to check if digest computation was initialised, which isn't used for other Crypto Backends
- Fix: replace by a Public API `IsInitialized`, with its implementation for OpenSSL/BoringSSL
  • Loading branch information
Alami-Amine committed Nov 22, 2024
1 parent 093aff8 commit 758706d
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 14 deletions.
10 changes: 7 additions & 3 deletions src/crypto/CHIPCryptoPAL.h
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,13 @@ class Hash_SHA256_stream
*/
CHIP_ERROR Begin();

/**
* @brief check if the digest computation has been initialized.
*
* @return True if the context is correctly initialized; otherwise, false.
*/
bool IsInitialized();

/**
* @brief Add some data to the digest computation, updating internal state.
*
Expand Down Expand Up @@ -942,9 +949,6 @@ class Hash_SHA256_stream

private:
HashSHA256OpaqueContext mContext;
#if CHIP_CRYPTO_BORINGSSL || CHIP_CRYPTO_OPENSSL
bool mInitialized = false;
#endif
};

class HKDF_sha
Expand Down
34 changes: 23 additions & 11 deletions src/crypto/CHIPCryptoPALOpenSSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ CHIP_ERROR AES_CCM_encrypt(const uint8_t * plaintext, size_t plaintext_length, c
VerifyOrExit(tag_length == CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES, error = CHIP_ERROR_INVALID_ARGUMENT);
#else
VerifyOrExit(tag_length == 8 || tag_length == 12 || tag_length == CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES,
error = CHIP_ERROR_INVALID_ARGUMENT);
error = CHIP_ERROR_INVALID_ARGUMENT);
#endif // CHIP_CRYPTO_BORINGSSL

#if CHIP_CRYPTO_BORINGSSL
Expand Down Expand Up @@ -251,7 +251,7 @@ CHIP_ERROR AES_CCM_encrypt(const uint8_t * plaintext, size_t plaintext_length, c
// Encrypt
VerifyOrExit(CanCastTo<int>(plaintext_length), error = CHIP_ERROR_INVALID_ARGUMENT);
result = EVP_EncryptUpdate(context, Uint8::to_uchar(ciphertext), &bytesWritten, Uint8::to_const_uchar(plaintext),
static_cast<int>(plaintext_length));
static_cast<int>(plaintext_length));
VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);
VerifyOrExit((ciphertext_was_null && bytesWritten == 0) || (bytesWritten >= 0), error = CHIP_ERROR_INTERNAL);
ciphertext_length = static_cast<unsigned int>(bytesWritten);
Expand Down Expand Up @@ -328,7 +328,7 @@ CHIP_ERROR AES_CCM_decrypt(const uint8_t * ciphertext, size_t ciphertext_length,
VerifyOrExit(tag_length == CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES, error = CHIP_ERROR_INVALID_ARGUMENT);
#else
VerifyOrExit(tag_length == 8 || tag_length == 12 || tag_length == CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES,
error = CHIP_ERROR_INVALID_ARGUMENT);
error = CHIP_ERROR_INVALID_ARGUMENT);
#endif // CHIP_CRYPTO_BORINGSSL
VerifyOrExit(nonce != nullptr, error = CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrExit(nonce_length > 0, error = CHIP_ERROR_INVALID_ARGUMENT);
Expand Down Expand Up @@ -362,7 +362,7 @@ CHIP_ERROR AES_CCM_decrypt(const uint8_t * ciphertext, size_t ciphertext_length,
// we're writing the tag, not reading.
VerifyOrExit(CanCastTo<int>(tag_length), error = CHIP_ERROR_INVALID_ARGUMENT);
result = EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_CCM_SET_TAG, static_cast<int>(tag_length),
const_cast<void *>(static_cast<const void *>(tag)));
const_cast<void *>(static_cast<const void *>(tag)));
VerifyOrExit(result == 1, error = CHIP_ERROR_INTERNAL);

// Pass in key + nonce
Expand All @@ -388,7 +388,7 @@ CHIP_ERROR AES_CCM_decrypt(const uint8_t * ciphertext, size_t ciphertext_length,
// Pass in ciphertext. We wont get anything if validation fails.
VerifyOrExit(CanCastTo<int>(ciphertext_length), error = CHIP_ERROR_INVALID_ARGUMENT);
result = EVP_DecryptUpdate(context, Uint8::to_uchar(plaintext), &bytesOutput, Uint8::to_const_uchar(ciphertext),
static_cast<int>(ciphertext_length));
static_cast<int>(ciphertext_length));
if (plaintext_was_null)
{
VerifyOrExit(bytesOutput <= static_cast<int>(sizeof(placeholder_plaintext)), error = CHIP_ERROR_INTERNAL);
Expand Down Expand Up @@ -449,7 +449,7 @@ static inline EVP_MD_CTX * to_inner_hash_evp_md_ctx(HashSHA256OpaqueContext * co
return *SafePointerCast<EVP_MD_CTX **>(context);
}

Hash_SHA256_stream::Hash_SHA256_stream() : mInitialized(false)
Hash_SHA256_stream::Hash_SHA256_stream()
{
set_inner_hash_evp_md_ctx(&mContext, nullptr);
}
Expand All @@ -470,14 +470,27 @@ CHIP_ERROR Hash_SHA256_stream::Begin()
const int result = EVP_DigestInit_ex(mdctx, _digestForType(DigestType::SHA256), nullptr);

VerifyOrReturnError(result == 1, CHIP_ERROR_INTERNAL);
mInitialized = true;

return CHIP_NO_ERROR;
}

bool Hash_SHA256_stream::IsInitialized()
{
EVP_MD_CTX * mdctx = to_inner_hash_evp_md_ctx(&mContext);
VerifyOrReturnValue(mdctx != nullptr, false);

// Verify that the EVP_MD_CTX is initialized to SHA256 (ensures that EVP_DigestInit_ex was called)
#if CHIP_CRYPTO_BORINGSSL
return EVP_MD_CTX_md(mdctx) == _digestForType(DigestType::SHA256);
#else
// EVP_MD_CTX_md() was Deprecated in OPENSSL 3.0; However, BoringSSL does not support EVP_MD_CTX_get0_md() yet
return EVP_MD_CTX_get0_md(mdctx) == _digestForType(DigestType::SHA256);
#endif
}

CHIP_ERROR Hash_SHA256_stream::AddData(const ByteSpan data)
{
VerifyOrReturnError(mInitialized, CHIP_ERROR_UNINITIALIZED);
VerifyOrReturnError(IsInitialized(), CHIP_ERROR_UNINITIALIZED, Clear());

EVP_MD_CTX * mdctx = to_inner_hash_evp_md_ctx(&mContext);
VerifyOrReturnError(mdctx != nullptr, CHIP_ERROR_INTERNAL);
Expand All @@ -492,7 +505,7 @@ CHIP_ERROR Hash_SHA256_stream::AddData(const ByteSpan data)
CHIP_ERROR Hash_SHA256_stream::GetDigest(MutableByteSpan & out_buffer)
{

VerifyOrReturnError(mInitialized, CHIP_ERROR_UNINITIALIZED);
VerifyOrReturnError(IsInitialized(), CHIP_ERROR_UNINITIALIZED, Clear());

EVP_MD_CTX * mdctx = to_inner_hash_evp_md_ctx(&mContext);

Expand All @@ -519,7 +532,7 @@ CHIP_ERROR Hash_SHA256_stream::Finish(MutableByteSpan & out_buffer)
unsigned int size;

VerifyOrReturnError(out_buffer.size() >= kSHA256_Hash_Length, CHIP_ERROR_BUFFER_TOO_SMALL);
VerifyOrReturnError(mInitialized, CHIP_ERROR_UNINITIALIZED);
VerifyOrReturnError(IsInitialized(), CHIP_ERROR_UNINITIALIZED, Clear());

EVP_MD_CTX * mdctx = to_inner_hash_evp_md_ctx(&mContext);

Expand All @@ -541,7 +554,6 @@ void Hash_SHA256_stream::Clear()
EVP_MD_CTX_free(mdctx);
set_inner_hash_evp_md_ctx(&mContext, nullptr);

mInitialized = false;
OPENSSL_cleanse(this, sizeof(*this));
}

Expand Down

0 comments on commit 758706d

Please sign in to comment.