From 96434985827ddcd5e174f79172ecc6d721284171 Mon Sep 17 00:00:00 2001 From: sujaygkulkarni-nxp <77627602+sujaygkulkarni-nxp@users.noreply.github.com> Date: Tue, 16 Aug 2022 03:02:40 +0530 Subject: [PATCH] HSM key store to handle AddNOC / UpdateNOC (#21667) * draft code for hsm integration in key store * updated crypto build file * updated keystore hsm file * updated keystore file * code cleanup * code cleanup * restyler * using hsm util file * bug fixes * removed hsm key store. Will be moved to application specific code. * reseting pending slot * restyler * review comments - update * draft code for hsm integration in key store * updated crypto build file * updated keystore hsm file * updated keystore file * code cleanup * code cleanup * restyler * using hsm util file * bug fixes * removed hsm key store. Will be moved to application specific code. * reseting pending slot * restyler * review comments - update * review comments - updated * declaring variable where it is used --- src/credentials/FabricTable.cpp | 7 - src/credentials/FabricTable.h | 9 +- src/crypto/BUILD.gn | 2 + src/crypto/hsm/CHIPCryptoPALHsm.h | 2 - src/crypto/hsm/CHIPCryptoPALHsm_config.h | 4 +- .../hsm/nxp/CHIPCryptoPALHsm_SE05X_P256.cpp | 13 - .../nxp/CHIPCryptoPALHsm_SE05X_Spake2p.cpp | 20 +- .../hsm/nxp/CHIPCryptoPALHsm_SE05X_utils.h | 4 +- ...ersistentStorageOperationalKeystoreHSM.cpp | 274 ++++++++++++++++++ .../PersistentStorageOperationalKeystoreHSM.h | 99 +++++++ 10 files changed, 390 insertions(+), 44 deletions(-) create mode 100644 src/crypto/hsm/nxp/PersistentStorageOperationalKeystoreHSM.cpp create mode 100644 src/crypto/hsm/nxp/PersistentStorageOperationalKeystoreHSM.h diff --git a/src/credentials/FabricTable.cpp b/src/credentials/FabricTable.cpp index 5814f9158bc669..1bb3b8b0139ef2 100644 --- a/src/credentials/FabricTable.cpp +++ b/src/credentials/FabricTable.cpp @@ -28,9 +28,6 @@ #include #include #include -#if CHIP_CRYPTO_HSM -#include -#endif namespace chip { using namespace Credentials; @@ -257,11 +254,7 @@ CHIP_ERROR FabricInfo::SetOperationalKeypair(const P256Keypair * keyPair) if (mOperationalKey == nullptr) { -#ifdef ENABLE_HSM_CASE_OPS_KEY - mOperationalKey = chip::Platform::New(); -#else mOperationalKey = chip::Platform::New(); -#endif } VerifyOrReturnError(mOperationalKey != nullptr, CHIP_ERROR_NO_MEMORY); return mOperationalKey->Deserialize(serialized); diff --git a/src/credentials/FabricTable.h b/src/credentials/FabricTable.h index d5c3a39fab3d77..7dbc84cc849e73 100644 --- a/src/credentials/FabricTable.h +++ b/src/credentials/FabricTable.h @@ -230,13 +230,8 @@ class DLL_EXPORT FabricInfo VendorId mVendorId = VendorId::NotSpecified; char mFabricLabel[kFabricLabelMaxLengthInBytes + 1] = { '\0' }; - -#ifdef ENABLE_HSM_CASE_OPS_KEY - mutable Crypto::P256KeypairHSM * mOperationalKey = nullptr; -#else - mutable Crypto::P256Keypair * mOperationalKey = nullptr; -#endif - bool mHasExternallyOwnedOperationalKey = false; + mutable Crypto::P256Keypair * mOperationalKey = nullptr; + bool mHasExternallyOwnedOperationalKey = false; CHIP_ERROR CommitToStorage(PersistentStorageDelegate * storage) const; CHIP_ERROR LoadFromStorage(PersistentStorageDelegate * storage, FabricIndex newFabricIndex, const ByteSpan & rcac, diff --git a/src/crypto/BUILD.gn b/src/crypto/BUILD.gn index 61672d3a3224b1..e06ab28cb988ef 100644 --- a/src/crypto/BUILD.gn +++ b/src/crypto/BUILD.gn @@ -167,6 +167,8 @@ static_library("crypto") { "hsm/nxp/CHIPCryptoPALHsm_SE05X_PBKDF.cpp", "hsm/nxp/CHIPCryptoPALHsm_SE05X_Spake2p.cpp", "hsm/nxp/CHIPCryptoPALHsm_SE05X_utils.cpp", + "hsm/nxp/PersistentStorageOperationalKeystoreHSM.cpp", + "hsm/nxp/PersistentStorageOperationalKeystoreHSM.h", ] public_deps += [ "${chip_root}/third_party/simw-top-mini:se05x" ] public_configs += [ "${chip_root}/third_party/simw-top-mini:se05x_config" ] diff --git a/src/crypto/hsm/CHIPCryptoPALHsm.h b/src/crypto/hsm/CHIPCryptoPALHsm.h index 0b1c0a93f9d12a..a1212dac4a245b 100644 --- a/src/crypto/hsm/CHIPCryptoPALHsm.h +++ b/src/crypto/hsm/CHIPCryptoPALHsm.h @@ -145,8 +145,6 @@ class P256KeypairHSM : public P256Keypair uint32_t GetKeyId(void) { return keyid; } - CHIP_ERROR CreateOperationalKey(FabricIndex fabricIdx); - private: uint32_t keyid; P256PublicKeyHSM mPublicKeyHSM; diff --git a/src/crypto/hsm/CHIPCryptoPALHsm_config.h b/src/crypto/hsm/CHIPCryptoPALHsm_config.h index 7a4bd41cfd413a..1c3b611be8c581 100644 --- a/src/crypto/hsm/CHIPCryptoPALHsm_config.h +++ b/src/crypto/hsm/CHIPCryptoPALHsm_config.h @@ -25,7 +25,7 @@ /* * Enable HSM for SPAKE VERIFIER */ -#define ENABLE_HSM_SPAKE_VERIFIER 0 +#define ENABLE_HSM_SPAKE_VERIFIER 1 /* * Enable HSM for SPAKE PROVER @@ -58,8 +58,6 @@ #if ((CHIP_CRYPTO_HSM) && (ENABLE_HSM_GENERATE_EC_KEY)) #define ENABLE_HSM_EC_KEY -#define ENABLE_HSM_CASE_EPHEMERAL_KEY -//#define ENABLE_HSM_CASE_OPS_KEY //#define ENABLE_HSM_ECDSA_VERIFY #endif diff --git a/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_P256.cpp b/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_P256.cpp index 1007ba2c395973..0d27c5a2428f40 100644 --- a/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_P256.cpp +++ b/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_P256.cpp @@ -693,19 +693,6 @@ CHIP_ERROR P256KeypairHSM::NewCertificateSigningRequest(uint8_t * csr, size_t & return error; } -CHIP_ERROR P256KeypairHSM::CreateOperationalKey(FabricIndex fabricIdx) -{ - (void) fabricIdx; - // TBD - Map fabric index to operational keys - SetKeyId(kKeyId_operational_key_keyid); - if (Initialize() == CHIP_NO_ERROR) - { - provisioned_key = true; - return CHIP_NO_ERROR; - } - return CHIP_ERROR_INTERNAL; -} - } // namespace Crypto } // namespace chip diff --git a/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_Spake2p.cpp b/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_Spake2p.cpp index f62691d1342765..346ff8342641ce 100644 --- a/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_Spake2p.cpp +++ b/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_Spake2p.cpp @@ -27,13 +27,13 @@ #if ((ENABLE_HSM_SPAKE_VERIFIER) || (ENABLE_HSM_SPAKE_PROVER)) #if ENABLE_HSM_SPAKE_VERIFIER -const uint32_t w0in_id_v = 0x2347; -const uint32_t Lin_id_v = 0x2348; +const uint32_t w0in_id_v = 0x7D200001; +const uint32_t Lin_id_v = 0x7D200002; #endif #if ENABLE_HSM_SPAKE_PROVER -const uint32_t w0in_id_p = 0x2349; -const uint32_t w1in_id_p = 0x2350; +const uint32_t w0in_id_p = 0x7D200003; +const uint32_t w1in_id_p = 0x7D200004; #endif void Spake2p_Finish_HSM(hsm_pake_context_t * phsm_pake_context) @@ -71,7 +71,7 @@ CHIP_ERROR create_init_crypto_obj(chip::Crypto::CHIP_SPAKE2P_ROLE role, hsm_pake uint8_t create_crypto_obj = 1; #endif - ChipLogProgress(Crypto, "Using Object Id --> %d \n", spakeObjectId); + ChipLogProgress(Crypto, "SE05x: Using Object Id --> %d", spakeObjectId); if (spakeObjectId != 0) { @@ -124,7 +124,7 @@ CHIP_ERROR Spake2p_ComputeRoundOne_HSM(hsm_pake_context_t * phsm_pake_context, c { SE05x_CryptoObjectID_t spakeObjectId = phsm_pake_context->spake_objId; - ChipLogProgress(Crypto, "Using HSM for spake2p ComputeRoundOne \n"); + ChipLogProgress(Crypto, "SE05x: Using HSM for spake2p ComputeRoundOne"); VerifyOrReturnError(out != nullptr, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(out_len != nullptr, CHIP_ERROR_INVALID_ARGUMENT); @@ -156,7 +156,7 @@ CHIP_ERROR Spake2p_ComputeRoundTwo_HSM(hsm_pake_context_t * phsm_pake_context, c VerifyOrReturnError(pKeyKe != nullptr, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(pkeyKeLen != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - ChipLogProgress(Crypto, "Using HSM for spake2p ComputeRoundTwo \n"); + ChipLogProgress(Crypto, "SE05x: Using HSM for spake2p ComputeRoundTwo"); const uint8_t * const pab = (role == chip::Crypto::CHIP_SPAKE2P_ROLE::VERIFIER) ? NULL : in; const size_t pab_len = (role == chip::Crypto::CHIP_SPAKE2P_ROLE::VERIFIER) ? 0 : in_len; @@ -178,7 +178,7 @@ CHIP_ERROR Spake2p_KeyConfirm_HSM(hsm_pake_context_t * phsm_pake_context, chip:: VerifyOrReturnError(in != nullptr, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(gex_sss_chip_ctx.ks.session != NULL, CHIP_ERROR_INTERNAL); - ChipLogProgress(Crypto, "Using HSM for spake2p KeyConfirm \n"); + ChipLogProgress(Crypto, "SE05x: Using HSM for spake2p KeyConfirm"); uint8_t presult = 0; const SE05x_CryptoObjectID_t spakeObjectId = phsm_pake_context->spake_objId; @@ -251,7 +251,7 @@ CHIP_ERROR Spake2pHSM_P256_SHA256_HKDF_HMAC::BeginVerifier(const uint8_t * my_id VerifyOrReturnError(peer_identity != nullptr, CHIP_ERROR_INVALID_ARGUMENT); } - ChipLogProgress(Crypto, "HSM - BeginVerifier \n"); + ChipLogProgress(Crypto, "SE05x: HSM - BeginVerifier"); ReturnErrorOnFailure(FELoad(w0in, w0in_len, w0)); ReturnErrorOnFailure(FEWrite(w0, w0in_mod, w0in_mod_len)); @@ -309,7 +309,7 @@ CHIP_ERROR Spake2pHSM_P256_SHA256_HKDF_HMAC::BeginProver(const uint8_t * my_iden VerifyOrReturnError(state == CHIP_SPAKE2P_STATE::INIT, CHIP_ERROR_INTERNAL); - ChipLogProgress(Crypto, "HSM - BeginProver \n"); + ChipLogProgress(Crypto, "SE05x: HSM - BeginProver"); ReturnErrorOnFailure(FELoad(w0in, w0in_len, w0)); ReturnErrorOnFailure(FEWrite(w0, w0in_mod, w0in_mod_len)); diff --git a/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_utils.h b/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_utils.h index 2169ffd8bc9978..e5e3bb12ce9ba7 100644 --- a/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_utils.h +++ b/src/crypto/hsm/nxp/CHIPCryptoPALHsm_SE05X_utils.h @@ -42,11 +42,11 @@ extern ex_sss_boot_ctx_t gex_sss_chip_ctx; enum keyid_values { kKeyId_NotInitialized = 0, - kKeyId_pbkdf2_sha256_hmac_keyid = 0xBCBCBCBC, + kKeyId_pbkdf2_sha256_hmac_keyid = 0x7D000000, kKeyId_hkdf_sha256_hmac_keyid, kKeyId_hmac_sha256_keyid, kKeyId_sha256_ecc_pub_keyid, - kKeyId_operational_key_keyid, + kKeyId_case_ephemeral_keyid, }; // Enable the below macro to make spake HSM imlementation reentrant. diff --git a/src/crypto/hsm/nxp/PersistentStorageOperationalKeystoreHSM.cpp b/src/crypto/hsm/nxp/PersistentStorageOperationalKeystoreHSM.cpp new file mode 100644 index 00000000000000..abe0f8e4b35e6a --- /dev/null +++ b/src/crypto/hsm/nxp/PersistentStorageOperationalKeystoreHSM.cpp @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PersistentStorageOperationalKeystoreHSM.h" +#include "CHIPCryptoPALHsm_SE05X_utils.h" +#include + +#if ENABLE_HSM_GENERATE_EC_KEY + +namespace chip { + +using namespace chip::Crypto; + +#define MAX_KEYID_SLOTS_FOR_FABRICS 32 +#define FABRIC_SE05X_KEYID_START 0x7D100000 + +/** + * Known issues: + * 1. The current HSM keystore implementation is tested only with one fabric. To be tested with multiple fabrics. + * 2. Logic to read the HSM and create the fabricTable from the persistent keys after reboot is missing . + */ + +struct keyidFabIdMapping_t +{ + uint32_t keyId; + FabricIndex fabricIndex; + bool isPending; + Crypto::P256KeypairHSM * pkeyPair; +} keyidFabIdMapping[MAX_KEYID_SLOTS_FOR_FABRICS] = { + 0, +}; + +uint8_t getEmpytSlotId() +{ + uint8_t i = 0; + for (auto & mapping : keyidFabIdMapping) + { + if (mapping.keyId == kKeyId_NotInitialized && mapping.isPending == false) + { + break; + } + i++; + } + return i; +} + +void PersistentStorageOperationalKeystoreHSM::ResetPendingSlot() +{ + uint32_t slotId = mPendingKeypair->GetKeyId() - FABRIC_SE05X_KEYID_START; + if (slotId < MAX_KEYID_SLOTS_FOR_FABRICS) + { + keyidFabIdMapping[slotId].keyId = kKeyId_NotInitialized; + keyidFabIdMapping[slotId].fabricIndex = kUndefinedFabricIndex; + keyidFabIdMapping[slotId].isPending = false; + } +} + +bool PersistentStorageOperationalKeystoreHSM::HasOpKeypairForFabric(FabricIndex fabricIndex) const +{ + VerifyOrReturnError(IsValidFabricIndex(fabricIndex), false); + + // If there was a pending keypair, then there's really a usable key + if (mIsPendingKeypairActive && (fabricIndex == mPendingFabricIndex) && (mPendingKeypair != nullptr)) + { + ChipLogProgress(Crypto, "SE05x: HasOpKeypairForFabric ==> mPendingKeypair found"); + return true; + } + + for (auto & mapping : keyidFabIdMapping) + { + if (mapping.fabricIndex == fabricIndex) + { + ChipLogProgress(Crypto, "SE05x: HasOpKeypairForFabric ==> stored keyPair found"); + return true; + } + } + + ChipLogProgress(Crypto, "SE05x: HasOpKeypairForFabric ==> No key found"); + return false; +} + +CHIP_ERROR PersistentStorageOperationalKeystoreHSM::NewOpKeypairForFabric(FabricIndex fabricIndex, + MutableByteSpan & outCertificateSigningRequest) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrReturnError(IsValidFabricIndex(fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX); + + ChipLogProgress(Crypto, "SE05x: New Op Keypair for Fabric %02x", fabricIndex); + + // Replace previous pending keypair, if any was previously allocated + ResetPendingKey(); + + uint8_t slotId = getEmpytSlotId(); + VerifyOrReturnError(slotId < MAX_KEYID_SLOTS_FOR_FABRICS, CHIP_ERROR_NO_MEMORY); + + mPendingKeypair = Platform::New(); + VerifyOrReturnError(mPendingKeypair != nullptr, CHIP_ERROR_NO_MEMORY); + + // Key id is created as slotid + start offset of ops key id + mPendingKeypair->SetKeyId(FABRIC_SE05X_KEYID_START + slotId); + + err = mPendingKeypair->Initialize(); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_NO_MEMORY); + + mPendingFabricIndex = fabricIndex; + + keyidFabIdMapping[slotId].isPending = true; + + size_t csrLength = outCertificateSigningRequest.size(); + err = mPendingKeypair->NewCertificateSigningRequest(outCertificateSigningRequest.data(), csrLength); + if (err != CHIP_NO_ERROR) + { + ResetPendingKey(); + return err; + } + outCertificateSigningRequest.reduce_size(csrLength); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR PersistentStorageOperationalKeystoreHSM::ActivateOpKeypairForFabric(FabricIndex fabricIndex, + const Crypto::P256PublicKey & nocPublicKey) +{ + ChipLogProgress(Crypto, "SE05x: ActivateOpKeypair for Fabric %02x", fabricIndex); + + VerifyOrReturnError(mPendingKeypair != nullptr, CHIP_ERROR_INVALID_FABRIC_INDEX); + VerifyOrReturnError(IsValidFabricIndex(fabricIndex) && (fabricIndex == mPendingFabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX); + + // Validate public key being activated matches last generated pending keypair + VerifyOrReturnError(mPendingKeypair->Pubkey().Matches(nocPublicKey), CHIP_ERROR_INVALID_PUBLIC_KEY); + + mIsPendingKeypairActive = true; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR PersistentStorageOperationalKeystoreHSM::CommitOpKeypairForFabric(FabricIndex fabricIndex) +{ + VerifyOrReturnError(mPendingKeypair != nullptr, CHIP_ERROR_INVALID_FABRIC_INDEX); + VerifyOrReturnError(IsValidFabricIndex(fabricIndex) && (fabricIndex == mPendingFabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX); + VerifyOrReturnError(mIsPendingKeypairActive == true, CHIP_ERROR_INCORRECT_STATE); + + uint32_t slotId = mPendingKeypair->GetKeyId() - FABRIC_SE05X_KEYID_START; + + VerifyOrReturnError(slotId < MAX_KEYID_SLOTS_FOR_FABRICS, CHIP_ERROR_NO_MEMORY); + + ChipLogProgress(Crypto, "SE05x: CommitOpKeypair for Fabric %02x", fabricIndex); + + for (auto & mapping : keyidFabIdMapping) + { + if (mapping.fabricIndex == fabricIndex) + { + // Delete the previous keyPair associated with the fabric + mapping.isPending = false; + Platform::Delete(mapping.pkeyPair); + mapping.pkeyPair = NULL; + mapping.keyId = kKeyId_NotInitialized; + mapping.fabricIndex = kUndefinedFabricIndex; + } + } + + keyidFabIdMapping[slotId].pkeyPair = mPendingKeypair; + keyidFabIdMapping[slotId].keyId = mPendingKeypair->GetKeyId(); + keyidFabIdMapping[slotId].fabricIndex = mPendingFabricIndex; + keyidFabIdMapping[slotId].isPending = false; + + // If we got here, we succeeded and can reset the pending key: next `SignWithOpKeypair` will use the stored key. + mPendingKeypair = nullptr; + mIsPendingKeypairActive = false; + mPendingFabricIndex = kUndefinedFabricIndex; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR PersistentStorageOperationalKeystoreHSM::RemoveOpKeypairForFabric(FabricIndex fabricIndex) +{ + VerifyOrReturnError(IsValidFabricIndex(fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX); + + ChipLogProgress(Crypto, "SE05x: RemoveOpKeypair for Fabric %02x", fabricIndex); + + // Remove pending state if matching + if ((mPendingKeypair != nullptr) && (fabricIndex == mPendingFabricIndex)) + { + RevertPendingKeypair(); + } + + for (auto & mapping : keyidFabIdMapping) + { + if (mapping.fabricIndex == fabricIndex) + { + // Delete the keyPair associated with the fabric + mapping.isPending = false; + Platform::Delete(mapping.pkeyPair); + mapping.pkeyPair = NULL; + mapping.keyId = kKeyId_NotInitialized; + mapping.fabricIndex = kUndefinedFabricIndex; + } + } + + return CHIP_NO_ERROR; +} + +void PersistentStorageOperationalKeystoreHSM::RevertPendingKeypair() +{ + ChipLogProgress(Crypto, "SE05x: RevertPendingKeypair"); + // Just reset the pending key, we never stored anything + ResetPendingKey(); +} + +CHIP_ERROR PersistentStorageOperationalKeystoreHSM::SignWithOpKeypair(FabricIndex fabricIndex, const ByteSpan & message, + Crypto::P256ECDSASignature & outSignature) const +{ + ChipLogProgress(Crypto, "SE05x: SignWithOpKeypair"); + + if (mIsPendingKeypairActive && (fabricIndex == mPendingFabricIndex)) + { + VerifyOrReturnError(mPendingKeypair != nullptr, CHIP_ERROR_INTERNAL); + // We have an override key: sign with it! + ChipLogProgress(Crypto, "SE05x: SignWithOpKeypair ==> using mPendingKeypair"); + return mPendingKeypair->ECDSA_sign_msg(message.data(), message.size(), outSignature); + } + else + { + for (auto & mapping : keyidFabIdMapping) + { + if ((mapping.fabricIndex == fabricIndex) && (mapping.isPending == false)) + { + ChipLogProgress(Crypto, "SE05x: SignWithOpKeypair ==> using stored keyPair"); + return mapping.pkeyPair->ECDSA_sign_msg(message.data(), message.size(), outSignature); + } + } + } + + ChipLogProgress(Crypto, "SE05x: SignWithOpKeypair ==> No keyPair found"); + return CHIP_ERROR_INVALID_FABRIC_INDEX; +} + +Crypto::P256Keypair * PersistentStorageOperationalKeystoreHSM::AllocateEphemeralKeypairForCASE() +{ + ChipLogProgress(Crypto, "SE05x: AllocateEphemeralKeypairForCASE using se05x"); + Crypto::P256KeypairHSM * pkeyPair = Platform::New(); + + if (pkeyPair != nullptr) + { + pkeyPair->SetKeyId(kKeyId_case_ephemeral_keyid); + } + + return pkeyPair; +} + +void PersistentStorageOperationalKeystoreHSM::ReleaseEphemeralKeypair(Crypto::P256Keypair * keypair) +{ + ChipLogProgress(Crypto, "SE05x: ReleaseEphemeralKeypair using se05x"); + Platform::Delete(static_cast(keypair)); +} + +} // namespace chip + +#endif //#if ENABLE_HSM_GENERATE_EC_KEY diff --git a/src/crypto/hsm/nxp/PersistentStorageOperationalKeystoreHSM.h b/src/crypto/hsm/nxp/PersistentStorageOperationalKeystoreHSM.h new file mode 100644 index 00000000000000..bc00feaa8bb8d0 --- /dev/null +++ b/src/crypto/hsm/nxp/PersistentStorageOperationalKeystoreHSM.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "CHIPCryptoPALHsm_SE05X_utils.h" +#include +#include +#include +#include +#include +#include + +#if ENABLE_HSM_GENERATE_EC_KEY + +namespace chip { + +class PersistentStorageOperationalKeystoreHSM : public Crypto::OperationalKeystore +{ +public: + PersistentStorageOperationalKeystoreHSM() = default; + virtual ~PersistentStorageOperationalKeystoreHSM() { Finish(); } + + // Non-copyable + PersistentStorageOperationalKeystoreHSM(PersistentStorageOperationalKeystoreHSM const &) = delete; + void operator=(PersistentStorageOperationalKeystoreHSM const &) = delete; + + /** + * @brief Initialize the Operational Keystore for HSM. + * + * @param storage Pointer to persistent storage delegate to use. Must outlive this instance. + * @retval CHIP_NO_ERROR on success + * @retval CHIP_ERROR_INCORRECT_STATE if already initialized + */ + CHIP_ERROR Init(PersistentStorageDelegate * storage) + { + IgnoreUnusedVariable(storage); + mPendingFabricIndex = kUndefinedFabricIndex; + mPendingKeypair = nullptr; + mIsPendingKeypairActive = false; + return CHIP_NO_ERROR; + } + + /** + * @brief Finalize the keystore, so that subsequent operations fail + */ + void Finish() { ResetPendingKey(); } + + bool HasPendingOpKeypair() const override { return (mPendingKeypair != nullptr); } + + bool HasOpKeypairForFabric(FabricIndex fabricIndex) const override; + CHIP_ERROR NewOpKeypairForFabric(FabricIndex fabricIndex, MutableByteSpan & outCertificateSigningRequest) override; + CHIP_ERROR ActivateOpKeypairForFabric(FabricIndex fabricIndex, const Crypto::P256PublicKey & nocPublicKey) override; + CHIP_ERROR CommitOpKeypairForFabric(FabricIndex fabricIndex) override; + CHIP_ERROR RemoveOpKeypairForFabric(FabricIndex fabricIndex) override; + void RevertPendingKeypair() override; + CHIP_ERROR SignWithOpKeypair(FabricIndex fabricIndex, const ByteSpan & message, + Crypto::P256ECDSASignature & outSignature) const override; + Crypto::P256Keypair * AllocateEphemeralKeypairForCASE() override; + void ReleaseEphemeralKeypair(Crypto::P256Keypair * keypair) override; + +protected: + void ResetPendingSlot(); + + void ResetPendingKey() + { + if (mPendingKeypair != nullptr) + { + ResetPendingSlot(); + Platform::Delete(mPendingKeypair); + } + mPendingKeypair = nullptr; + mIsPendingKeypairActive = false; + mPendingFabricIndex = kUndefinedFabricIndex; + } + + // This pending fabric index is `kUndefinedFabricIndex` if there isn't a pending keypair override for a given fabric. + FabricIndex mPendingFabricIndex = kUndefinedFabricIndex; + Crypto::P256KeypairHSM * mPendingKeypair = nullptr; + bool mIsPendingKeypairActive = false; +}; + +} // namespace chip + +#endif //#if ENABLE_HSM_GENERATE_EC_KEY