From 170a5b8d6733edce25b11f38c5c6a53932916f04 Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Thu, 5 Dec 2024 16:55:29 -0500 Subject: [PATCH] add PSA_KEY_SLOTS for matter psa crypto --- .../silabs/efr32/CHIPCryptoPALPsaEfr32.cpp | 64 ++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/src/platform/silabs/efr32/CHIPCryptoPALPsaEfr32.cpp b/src/platform/silabs/efr32/CHIPCryptoPALPsaEfr32.cpp index cef956681a..9ec4a93b48 100644 --- a/src/platform/silabs/efr32/CHIPCryptoPALPsaEfr32.cpp +++ b/src/platform/silabs/efr32/CHIPCryptoPALPsaEfr32.cpp @@ -417,7 +417,10 @@ CHIP_ERROR HMAC_sha::HMAC_SHA256(const Hmac128KeyHandle & key, const uint8_t * m CHIP_ERROR PBKDF2_sha256::pbkdf2_sha256(const uint8_t * pass, size_t pass_length, const uint8_t * salt, size_t salt_length, unsigned int iteration_count, uint32_t key_length, uint8_t * key) { - VerifyOrReturnError(IsBufferNonEmpty(pass, pass_length), CHIP_ERROR_INVALID_ARGUMENT); + /* + TODO: Switch to the following implementation once mbedTLS gets support for PBKDF2 + + VerifyOrReturnError(isBufferNonEmpty(pass, pass_length), CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(key != nullptr, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(salt_length >= kSpake2p_Min_PBKDF_Salt_Length && salt_length <= kSpake2p_Max_PBKDF_Salt_Length, CHIP_ERROR_INVALID_ARGUMENT); @@ -445,6 +448,65 @@ CHIP_ERROR PBKDF2_sha256::pbkdf2_sha256(const uint8_t * pass, size_t pass_length psa_key_derivation_abort(&operation); return error; + */ + + VerifyOrReturnError(IsBufferNonEmpty(pass, pass_length), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(salt != nullptr && salt_length >= kSpake2p_Min_PBKDF_Salt_Length && + salt_length <= kSpake2p_Max_PBKDF_Salt_Length, + CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsBufferNonEmpty(key, key_length), CHIP_ERROR_INVALID_ARGUMENT); + + constexpr size_t kMacLength = PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, pass_length * 8, PSA_ALG_HMAC(PSA_ALG_SHA_256)); + const psa_algorithm_t algorithm = PSA_ALG_HMAC(PSA_ALG_SHA_256); + CHIP_ERROR error = CHIP_NO_ERROR; + psa_status_t status = PSA_SUCCESS; + psa_key_attributes_t attrs = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t keyId = 0; + + psa_set_key_type(&attrs, PSA_KEY_TYPE_HMAC); + psa_set_key_algorithm(&attrs, algorithm); + psa_set_key_usage_flags(&attrs, PSA_KEY_USAGE_SIGN_HASH); + + status = psa_import_key(&attrs, pass, pass_length, &keyId); + VerifyOrExit(status == PSA_SUCCESS, error = CHIP_ERROR_INTERNAL); + + for (uint32_t blockNo = 1; key_length != 0; ++blockNo) + { + uint8_t in[chip::max(kMacLength, kSpake2p_Max_PBKDF_Salt_Length + 4)]; + size_t inLength = salt_length + 4; + uint8_t out[kMacLength]; + size_t outLength; + uint8_t result[kMacLength] = {}; + + memcpy(in, salt, salt_length); + Encoding::BigEndian::Put32(&in[salt_length], blockNo); + + for (size_t iteration = 0; iteration < iteration_count; ++iteration) + { + status = psa_mac_compute(keyId, algorithm, in, inLength, out, sizeof(out), &outLength); + VerifyOrExit(status == PSA_SUCCESS && outLength == kMacLength, error = CHIP_ERROR_INTERNAL); + + for (size_t byteNo = 0; byteNo < kMacLength; ++byteNo) + { + result[byteNo] ^= out[byteNo]; + in[byteNo] = out[byteNo]; + } + + inLength = outLength; + } + + const size_t usedKeyLength = chip::min(key_length, kMacLength); + memcpy(key, result, usedKeyLength); + key += usedKeyLength; + key_length -= usedKeyLength; + } + +exit: + LogPsaError(status); + psa_destroy_key(keyId); + psa_reset_key_attributes(&attrs); + + return CHIP_NO_ERROR; } CHIP_ERROR add_entropy_source(entropy_source /* fn_source */, void * /* p_source */, size_t /* threshold */)