From efdae04affa42dc81d51f6473fc0e148115e90b3 Mon Sep 17 00:00:00 2001 From: Arkadiusz Balys Date: Fri, 23 Feb 2024 16:40:10 +0100 Subject: [PATCH] [nrf noup] Spake2+ alignments regarding the newest Oberon version Aligned Spake2+ algorithm to the Oberon PSA core v1.2.1.1 --- .../nrfconnect/chip-module/Kconfig.defaults | 7 +- src/crypto/CHIPCryptoPALPSA.cpp | 49 +++------ src/crypto/CHIPCryptoPALPSA.h | 18 +--- src/crypto/PSASessionKeystore.cpp | 14 +-- src/crypto/PSASpake2p.cpp | 102 ++++++++---------- src/platform/nrfconnect/CHIPPlatformConfig.h | 3 +- 6 files changed, 68 insertions(+), 125 deletions(-) diff --git a/config/nrfconnect/chip-module/Kconfig.defaults b/config/nrfconnect/chip-module/Kconfig.defaults index 568a5dde8b..341d0647b6 100644 --- a/config/nrfconnect/chip-module/Kconfig.defaults +++ b/config/nrfconnect/chip-module/Kconfig.defaults @@ -297,9 +297,7 @@ config MBEDTLS_HEAP_SIZE config CHIP_CRYPTO_PSA default y if !CHIP_WIFI - imply PSA_WANT_ALG_SPAKE2P - # Set SPAKE2P to version 4 to be compatible with Matter specification. - imply PSA_CRYPTO_SPAKE2P_USE_VERSION_04 + imply PSA_WANT_ALG_SPAKE2P_MATTER if CHIP_CRYPTO_PSA @@ -309,9 +307,6 @@ config PSA_CRYPTO_DRIVER_CC3XX config PSA_WANT_ALG_SHA_224 default n -config PSA_WANT_ALG_SPAKE2P - default y - # Extend the maximum number of PSA key slots to fit Matter requirements config MBEDTLS_PSA_KEY_SLOT_COUNT default 64 diff --git a/src/crypto/CHIPCryptoPALPSA.cpp b/src/crypto/CHIPCryptoPALPSA.cpp index fe47747398..1e021b2249 100644 --- a/src/crypto/CHIPCryptoPALPSA.cpp +++ b/src/crypto/CHIPCryptoPALPSA.cpp @@ -284,58 +284,37 @@ CHIP_ERROR PsaKdf::Init(const ByteSpan & secret, const ByteSpan & salt, const By psa_reset_key_attributes(&attrs); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - PsaHkdfKeyHandle hkdfKeyHandle = { .mKeyId = mSecretKeyId, .mIsKeyId = true }; - - return InitOperation(hkdfKeyHandle, salt, info); + return InitOperation(mSecretKeyId, salt, info); } CHIP_ERROR PsaKdf::Init(const HkdfKeyHandle & hkdfKey, const ByteSpan & salt, const ByteSpan & info) { - return InitOperation(hkdfKey.As(), salt, info); + return InitOperation(hkdfKey.As(), salt, info); } -CHIP_ERROR PsaKdf::InitOperation(PsaHkdfKeyHandle hkdfKey, const ByteSpan & salt, const ByteSpan & info) +CHIP_ERROR PsaKdf::InitOperation(psa_key_id_t hkdfKey, const ByteSpan & salt, const ByteSpan & info) { - psa_status_t status; - if (hkdfKey.mIsKeyId) - { - status = psa_key_derivation_setup(&mOperation, PSA_ALG_HKDF(PSA_ALG_SHA_256)); - VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - - if (salt.size() > 0) - { - status = psa_key_derivation_input_bytes(&mOperation, PSA_KEY_DERIVATION_INPUT_SALT, salt.data(), salt.size()); - VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - } - - status = psa_key_derivation_input_key(&mOperation, PSA_KEY_DERIVATION_INPUT_SECRET, hkdfKey.mKeyId); - VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + psa_status_t status = psa_key_derivation_setup(&mOperation, PSA_ALG_HKDF(PSA_ALG_SHA_256)); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - status = psa_key_derivation_input_bytes(&mOperation, PSA_KEY_DERIVATION_INPUT_INFO, info.data(), info.size()); + if (salt.size() > 0) + { + status = psa_key_derivation_input_bytes(&mOperation, PSA_KEY_DERIVATION_INPUT_SALT, salt.data(), salt.size()); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - - mDerivationOperation = &mOperation; } - else - { - mDerivationOperation = hkdfKey.mKeyDerivationOp; - if (salt.size() > 0) - { - status = psa_key_derivation_input_bytes(mDerivationOperation, PSA_KEY_DERIVATION_INPUT_SALT, salt.data(), salt.size()); - VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - } + status = psa_key_derivation_input_key(&mOperation, PSA_KEY_DERIVATION_INPUT_SECRET, hkdfKey); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - status = psa_key_derivation_input_bytes(mDerivationOperation, PSA_KEY_DERIVATION_INPUT_INFO, info.data(), info.size()); - VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - } + status = psa_key_derivation_input_bytes(&mOperation, PSA_KEY_DERIVATION_INPUT_INFO, info.data(), info.size()); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); return CHIP_NO_ERROR; } CHIP_ERROR PsaKdf::DeriveBytes(const MutableByteSpan & output) { - psa_status_t status = psa_key_derivation_output_bytes(mDerivationOperation, output.data(), output.size()); + psa_status_t status = psa_key_derivation_output_bytes(&mOperation, output.data(), output.size()); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); @@ -344,7 +323,7 @@ CHIP_ERROR PsaKdf::DeriveBytes(const MutableByteSpan & output) CHIP_ERROR PsaKdf::DeriveKey(const psa_key_attributes_t & attributes, psa_key_id_t & keyId) { - psa_status_t status = psa_key_derivation_output_key(&attributes, mDerivationOperation, &keyId); + psa_status_t status = psa_key_derivation_output_key(&attributes, &mOperation, &keyId); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); diff --git a/src/crypto/CHIPCryptoPALPSA.h b/src/crypto/CHIPCryptoPALPSA.h index 134966adc3..bd48c1441f 100644 --- a/src/crypto/CHIPCryptoPALPSA.h +++ b/src/crypto/CHIPCryptoPALPSA.h @@ -95,17 +95,6 @@ inline const PsaP256KeypairContext & ToConstPsaContext(const P256KeypairContext return *SafePointerCast(&context); } -struct PsaHkdfKeyHandle -{ - union - { - psa_key_id_t mKeyId; - psa_key_derivation_operation_t * mKeyDerivationOp; - }; - - bool mIsKeyId = true; -}; - /** * @brief Wrapper for PSA key derivation API. */ @@ -156,11 +145,10 @@ class PsaKdf CHIP_ERROR DeriveKey(const psa_key_attributes_t & attributes, psa_key_id_t & keyId); private: - CHIP_ERROR InitOperation(PsaHkdfKeyHandle hkdfKey, const ByteSpan & salt, const ByteSpan & info); + CHIP_ERROR InitOperation(psa_key_id_t hkdfKey, const ByteSpan & salt, const ByteSpan & info); - psa_key_id_t mSecretKeyId = PSA_KEY_ID_NULL; - psa_key_derivation_operation_t mOperation = PSA_KEY_DERIVATION_OPERATION_INIT; - psa_key_derivation_operation_t * mDerivationOperation = nullptr; + psa_key_id_t mSecretKeyId = PSA_KEY_ID_NULL; + psa_key_derivation_operation_t mOperation = PSA_KEY_DERIVATION_OPERATION_INIT; }; } // namespace Crypto } // namespace chip diff --git a/src/crypto/PSASessionKeystore.cpp b/src/crypto/PSASessionKeystore.cpp index c66544ee8d..797dcdeb65 100644 --- a/src/crypto/PSASessionKeystore.cpp +++ b/src/crypto/PSASessionKeystore.cpp @@ -186,18 +186,10 @@ void PSASessionKeystore::DestroyKey(Symmetric128BitsKeyHandle & key) void PSASessionKeystore::DestroyKey(HkdfKeyHandle & key) { - auto & keyHandle = key.AsMutable(); + auto & keyId = key.AsMutable(); - if (keyHandle.mIsKeyId) - { - psa_destroy_key(keyHandle.mKeyId); - keyHandle.mKeyId = 0; - } - else - { - Platform::Delete(keyHandle.mKeyDerivationOp); - keyHandle.mKeyDerivationOp = nullptr; - } + psa_destroy_key(keyId); + keyId = PSA_KEY_ID_NULL; } } // namespace Crypto diff --git a/src/crypto/PSASpake2p.cpp b/src/crypto/PSASpake2p.cpp index 2f2d34b613..ad52cf4d5c 100644 --- a/src/crypto/PSASpake2p.cpp +++ b/src/crypto/PSASpake2p.cpp @@ -33,14 +33,6 @@ CHIP_ERROR PSASpake2p_P256_SHA256_HKDF_HMAC::Init(const uint8_t * context, size_ VerifyOrReturnError(context_len <= sizeof(mContext), CHIP_ERROR_BUFFER_TOO_SMALL); - psa_pake_cipher_suite_t cs = PSA_PAKE_CIPHER_SUITE_INIT; - psa_pake_cs_set_algorithm(&cs, PSA_ALG_SPAKE2P); - psa_pake_cs_set_primitive(&cs, PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256)); - psa_pake_cs_set_hash(&cs, PSA_ALG_SHA_256); - - psa_status_t status = psa_pake_setup(&mOperation, &cs); - VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - memcpy(mContext, context, context_len); mContextLen = context_len; @@ -64,33 +56,38 @@ CHIP_ERROR PSASpake2p_P256_SHA256_HKDF_HMAC::BeginVerifier(const uint8_t * my_id VerifyOrReturnError(w0in_len <= kSpake2p_WS_Length, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(Lin_len == kP256_Point_Length, CHIP_ERROR_INVALID_ARGUMENT); - mRole = PSA_PAKE_ROLE_SERVER; - psa_status_t status = psa_pake_set_role(&mOperation, PSA_PAKE_ROLE_SERVER); - VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - - status = psa_pake_set_peer(&mOperation, peer_identity, peer_identity_len); - VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - - status = psa_pake_set_user(&mOperation, my_identity, my_identity_len); - VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - uint8_t password[kSpake2p_WS_Length + kP256_Point_Length]; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_pake_cipher_suite_t cp = PSA_PAKE_CIPHER_SUITE_INIT; + + psa_pake_cs_set_algorithm(&cp, PSA_ALG_SPAKE2P_MATTER); + psa_pake_cs_set_primitive(&cp, PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256)); memcpy(password + 0, w0in, w0in_len); memcpy(password + w0in_len, Lin, Lin_len); psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE); - psa_set_key_algorithm(&attributes, PSA_ALG_SPAKE2P); - psa_set_key_type(&attributes, PSA_KEY_TYPE_PASSWORD); + psa_set_key_algorithm(&attributes, PSA_ALG_SPAKE2P_MATTER); + psa_set_key_type(&attributes, PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1)); + + psa_status_t status = psa_import_key(&attributes, password, w0in_len + Lin_len, &mKey); - status = psa_import_key(&attributes, password, w0in_len + Lin_len, &mKey); psa_reset_key_attributes(&attributes); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - status = psa_pake_set_password_key(&mOperation, mKey); + status = psa_pake_setup(&mOperation, mKey, &cp); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + + mRole = PSA_PAKE_ROLE_SERVER; + status = psa_pake_set_role(&mOperation, PSA_PAKE_ROLE_SERVER); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - status = psa_pake_input(&mOperation, PSA_PAKE_STEP_CONTEXT, mContext, mContextLen); + status = psa_pake_set_peer(&mOperation, peer_identity, peer_identity_len); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + + status = psa_pake_set_user(&mOperation, my_identity, my_identity_len); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + + status = psa_pake_set_context(&mOperation, mContext, mContextLen); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); return CHIP_NO_ERROR; @@ -104,33 +101,38 @@ CHIP_ERROR PSASpake2p_P256_SHA256_HKDF_HMAC::BeginProver(const uint8_t * my_iden VerifyOrReturnError(w0in_len <= kSpake2p_WS_Length, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(w1in_len <= kSpake2p_WS_Length, CHIP_ERROR_INVALID_ARGUMENT); - mRole = PSA_PAKE_ROLE_CLIENT; - psa_status_t status = psa_pake_set_role(&mOperation, PSA_PAKE_ROLE_CLIENT); - VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - - status = psa_pake_set_user(&mOperation, my_identity, my_identity_len); - VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - - status = psa_pake_set_peer(&mOperation, peer_identity, peer_identity_len); - VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - uint8_t password[kSpake2p_WS_Length * 2]; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_pake_cipher_suite_t cp = PSA_PAKE_CIPHER_SUITE_INIT; + + psa_pake_cs_set_algorithm(&cp, PSA_ALG_SPAKE2P_MATTER); + psa_pake_cs_set_primitive(&cp, PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256)); memcpy(password + 0, w0in, w0in_len); memcpy(password + w0in_len, w1in, w1in_len); psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE); - psa_set_key_algorithm(&attributes, PSA_ALG_SPAKE2P); - psa_set_key_type(&attributes, PSA_KEY_TYPE_PASSWORD); + psa_set_key_algorithm(&attributes, PSA_ALG_SPAKE2P_MATTER); + psa_set_key_type(&attributes, PSA_KEY_TYPE_SPAKE2P_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + + psa_status_t status = psa_import_key(&attributes, password, w0in_len + w1in_len, &mKey); - status = psa_import_key(&attributes, password, w0in_len + w1in_len, &mKey); psa_reset_key_attributes(&attributes); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - status = psa_pake_set_password_key(&mOperation, mKey); + status = psa_pake_setup(&mOperation, mKey, &cp); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + + mRole = PSA_PAKE_ROLE_CLIENT; + status = psa_pake_set_role(&mOperation, PSA_PAKE_ROLE_CLIENT); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - status = psa_pake_input(&mOperation, PSA_PAKE_STEP_CONTEXT, mContext, mContextLen); + status = psa_pake_set_user(&mOperation, my_identity, my_identity_len); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + + status = psa_pake_set_peer(&mOperation, peer_identity, peer_identity_len); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + + status = psa_pake_set_context(&mOperation, mContext, mContextLen); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); return CHIP_NO_ERROR; @@ -182,29 +184,17 @@ CHIP_ERROR PSASpake2p_P256_SHA256_HKDF_HMAC::KeyConfirm(const uint8_t * in, size CHIP_ERROR PSASpake2p_P256_SHA256_HKDF_HMAC::GetKeys(SessionKeystore & keystore, HkdfKeyHandle & key) { - /* - * TODO: use psa_pake_shared_secret() proposed in https://github.com/ARM-software/psa-api/issues/86 - */ - - psa_key_derivation_operation_t * kdf = Platform::New(); - Platform::UniquePtr kdfPtr(kdf); - - VerifyOrReturnError(kdfPtr, CHIP_ERROR_NO_MEMORY); + auto & keyId = key.AsMutable(); - *kdfPtr = PSA_KEY_DERIVATION_OPERATION_INIT; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_status_t status = psa_key_derivation_setup(kdfPtr.get(), PSA_ALG_HKDF(PSA_ALG_SHA_256)); - VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + psa_set_key_type(&attributes, PSA_KEY_TYPE_DERIVE); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE); + psa_set_key_algorithm(&attributes, PSA_ALG_HKDF(PSA_ALG_SHA_256)); - status = psa_pake_get_implicit_key(&mOperation, kdfPtr.get()); + psa_status_t status = psa_pake_get_shared_key(&mOperation, &attributes, &keyId); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - auto & hkdfKeyHandle = key.AsMutable(); - hkdfKeyHandle.mKeyDerivationOp = kdfPtr.get(); - hkdfKeyHandle.mIsKeyId = false; - - kdfPtr.release(); - return CHIP_NO_ERROR; } diff --git a/src/platform/nrfconnect/CHIPPlatformConfig.h b/src/platform/nrfconnect/CHIPPlatformConfig.h index db5e3aab8c..3ece933d37 100644 --- a/src/platform/nrfconnect/CHIPPlatformConfig.h +++ b/src/platform/nrfconnect/CHIPPlatformConfig.h @@ -40,8 +40,7 @@ #ifdef CONFIG_CHIP_CRYPTO_PSA #define CHIP_CONFIG_SHA256_CONTEXT_SIZE sizeof(psa_hash_operation_t) -// Alignment to sizeof(PsaHkdfKeyHandle) from crypto/CHIPCryptoPALPSA.h. -#define CHIP_CONFIG_HKDF_KEY_HANDLE_CONTEXT_SIZE (sizeof(psa_key_id_t) + sizeof(bool)) +#define CHIP_CONFIG_HKDF_KEY_HANDLE_CONTEXT_SIZE sizeof(psa_key_id_t) #elif defined(CONFIG_CC3XX_BACKEND) // Size of the statically allocated context for SHA256 operations in CryptoPAL // determined empirically.