Skip to content

Commit 1baec8b

Browse files
Address PR comments
Modify implementation of `PersistICDKey` not to depend on type of ICD key handle (AES, HMAC)
1 parent 85eae56 commit 1baec8b

File tree

6 files changed

+42
-84
lines changed

6 files changed

+42
-84
lines changed

src/crypto/CHIPCryptoPALPSA.h

+7-7
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ namespace Crypto {
7171
static_assert(PSA_KEY_ID_USER_MIN <= CHIP_CONFIG_CRYPTO_PSA_KEY_ID_BASE && CHIP_CONFIG_CRYPTO_PSA_KEY_ID_END <= PSA_KEY_ID_USER_MAX,
7272
"Matter specific PSA key range doesn't fit within PSA allowed range");
7373

74-
static constexpr uint32_t kMaxICDClientKeys = CHIP_CONFIG_ICD_MAX_CLIENTS;
74+
// Each ICD client requires storing two keys- AES and HMAC
75+
static constexpr uint32_t kMaxICDClientKeys = 2 * CHIP_CONFIG_CRYPTO_PSA_ICD_MAX_CLIENTS;
7576

7677
static_assert(kMaxICDClientKeys >= CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC * CHIP_CONFIG_MAX_FABRICS,
7778
"Number of allocated ICD key slots is lower than maximum number of supported ICD clients");
@@ -81,12 +82,11 @@ static_assert(kMaxICDClientKeys >= CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC
8182
*/
8283
enum class KeyIdBase : psa_key_id_t
8384
{
84-
Minimum = CHIP_CONFIG_CRYPTO_PSA_KEY_ID_BASE,
85-
Operational = Minimum, ///< Base of the PSA key ID range for Node Operational Certificate private keys
86-
DACPrivKey = Operational + kMaxValidFabricIndex + 1,
87-
ICDHmacKeyRangeStart = DACPrivKey + 1,
88-
ICDAesKeyRangeStart = ICDHmacKeyRangeStart + kMaxICDClientKeys,
89-
Maximum = ICDAesKeyRangeStart + kMaxICDClientKeys,
85+
Minimum = CHIP_CONFIG_CRYPTO_PSA_KEY_ID_BASE,
86+
Operational = Minimum, ///< Base of the PSA key ID range for Node Operational Certificate private keys
87+
DACPrivKey = Operational + kMaxValidFabricIndex + 1,
88+
ICDKeyRangeStart = DACPrivKey + 1,
89+
Maximum = ICDKeyRangeStart + kMaxICDClientKeys,
9090
};
9191

9292
static_assert(to_underlying(KeyIdBase::Minimum) >= CHIP_CONFIG_CRYPTO_PSA_KEY_ID_BASE &&

src/crypto/PSASessionKeystore.cpp

+22-60
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,6 @@ class KeyAttributesBase
3535
psa_set_key_bits(&mAttrs, bits);
3636
}
3737

38-
CHIP_ERROR SetKeyPersistence(psa_key_id_t keyId)
39-
{
40-
VerifyOrReturnError(to_underlying(KeyIdBase::Maximum) >= keyId && keyId >= to_underlying(KeyIdBase::Minimum),
41-
CHIP_ERROR_INVALID_ARGUMENT);
42-
43-
psa_set_key_lifetime(&mAttrs, PSA_KEY_LIFETIME_PERSISTENT);
44-
psa_set_key_id(&mAttrs, keyId);
45-
46-
return CHIP_NO_ERROR;
47-
}
48-
4938
~KeyAttributesBase() { psa_reset_key_attributes(&mAttrs); }
5039

5140
const psa_key_attributes_t & Get() { return mAttrs; }
@@ -79,6 +68,12 @@ class HkdfKeyAttributes : public KeyAttributesBase
7968
HkdfKeyAttributes() : KeyAttributesBase(PSA_KEY_TYPE_DERIVE, PSA_ALG_HKDF(PSA_ALG_SHA_256), PSA_KEY_USAGE_DERIVE, 0) {}
8069
};
8170

71+
void SetKeyId(Symmetric128BitsKeyHandle & key, psa_key_id_t newKeyId)
72+
{
73+
auto & KeyId = key.AsMutable<psa_key_id_t>();
74+
75+
KeyId = newKeyId;
76+
}
8277
} // namespace
8378

8479
CHIP_ERROR PSASessionKeystore::CreateKey(const Symmetric128BitsKeyByteArray & keyMaterial, Aes128KeyHandle & key)
@@ -190,66 +185,33 @@ void PSASessionKeystore::DestroyKey(HkdfKeyHandle & key)
190185
}
191186

192187
#if CHIP_CONFIG_ENABLE_ICD_CIP
193-
CHIP_ERROR PSASessionKeystore::PersistICDKey(Aes128KeyHandle & key)
188+
CHIP_ERROR PSASessionKeystore::PersistICDKey(Symmetric128BitsKeyHandle & key)
194189
{
195190
CHIP_ERROR err;
196-
AesKeyAttributes attrs;
197-
psa_key_id_t previousKeyId = key.As<psa_key_id_t>();
198-
psa_key_attributes_t previousKeyAttrs;
199-
200-
psa_get_key_attributes(previousKeyId, &previousKeyAttrs);
201-
// Exit early if key is already persistent
202-
if (psa_get_key_lifetime(&previousKeyAttrs) == PSA_KEY_LIFETIME_PERSISTENT)
203-
{
204-
ExitNow(err = CHIP_NO_ERROR);
205-
}
206-
207-
SuccessOrExit(err = Crypto::FindFreeKeySlotInRange(key.AsMutable<psa_key_id_t>(), to_underlying(KeyIdBase::ICDAesKeyRangeStart),
208-
kMaxICDClientKeys));
209-
210-
SuccessOrExit(err = attrs.SetKeyPersistence(key.As<psa_key_id_t>()));
211-
VerifyOrExit(psa_copy_key(previousKeyId, &attrs.Get(), &key.AsMutable<psa_key_id_t>()) == PSA_SUCCESS,
212-
err = CHIP_ERROR_INTERNAL);
191+
psa_key_id_t newKeyId = PSA_KEY_ID_NULL;
192+
psa_key_attributes_t attrs;
213193

214-
psa_destroy_key(previousKeyId);
194+
psa_get_key_attributes(key.As<psa_key_id_t>(), &attrs);
215195

216-
exit:
217-
if (err != CHIP_NO_ERROR)
218-
{
219-
psa_destroy_key(previousKeyId);
220-
psa_destroy_key(key.As<psa_key_id_t>());
221-
}
222-
223-
return err;
224-
}
225-
226-
CHIP_ERROR PSASessionKeystore::PersistICDKey(Hmac128KeyHandle & key)
227-
{
228-
CHIP_ERROR err;
229-
HmacKeyAttributes attrs;
230-
psa_key_id_t previousKeyId = key.As<psa_key_id_t>();
231-
psa_key_attributes_t previousKeyAttrs;
232-
233-
psa_get_key_attributes(previousKeyId, &previousKeyAttrs);
234196
// Exit early if key is already persistent
235-
if (psa_get_key_lifetime(&previousKeyAttrs) == PSA_KEY_LIFETIME_PERSISTENT)
197+
if (psa_get_key_lifetime(&attrs) == PSA_KEY_LIFETIME_PERSISTENT)
236198
{
237-
ExitNow(err = CHIP_NO_ERROR);
199+
psa_reset_key_attributes(&attrs);
200+
return CHIP_NO_ERROR;
238201
}
239202

240-
SuccessOrExit(err = Crypto::FindFreeKeySlotInRange(key.AsMutable<psa_key_id_t>(),
241-
to_underlying(KeyIdBase::ICDHmacKeyRangeStart), kMaxICDClientKeys));
242-
SuccessOrExit(err = attrs.SetKeyPersistence(key.As<psa_key_id_t>()));
243-
VerifyOrExit(psa_copy_key(previousKeyId, &attrs.Get(), &key.AsMutable<psa_key_id_t>()) == PSA_SUCCESS,
244-
err = CHIP_ERROR_INTERNAL);
245-
246-
psa_destroy_key(previousKeyId);
203+
SuccessOrExit(err = Crypto::FindFreeKeySlotInRange(newKeyId, to_underlying(KeyIdBase::ICDKeyRangeStart), kMaxICDClientKeys));
204+
psa_set_key_lifetime(&attrs, PSA_KEY_LIFETIME_PERSISTENT);
205+
psa_set_key_id(&attrs, newKeyId);
206+
VerifyOrExit(psa_copy_key(key.As<psa_key_id_t>(), &attrs, &newKeyId) == PSA_SUCCESS, err = CHIP_ERROR_INTERNAL);
247207

248208
exit:
249-
if (err != CHIP_NO_ERROR)
209+
DestroyKey(key);
210+
psa_reset_key_attributes(&attrs);
211+
212+
if (err == CHIP_NO_ERROR)
250213
{
251-
psa_destroy_key(previousKeyId);
252-
psa_destroy_key(key.As<psa_key_id_t>());
214+
SetKeyId(key, newKeyId);
253215
}
254216

255217
return err;

src/crypto/PSASessionKeystore.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
#pragma once
1919

20-
#include <app/icd/server/ICDServerConfig.h>
2120
#include <crypto/CHIPCryptoPALPSA.h>
2221
#include <crypto/SessionKeystore.h>
2322

@@ -40,8 +39,7 @@ class PSASessionKeystore : public SessionKeystore
4039
void DestroyKey(Symmetric128BitsKeyHandle & key) override;
4140
void DestroyKey(HkdfKeyHandle & key) override;
4241
#if CHIP_CONFIG_ENABLE_ICD_CIP
43-
CHIP_ERROR PersistICDKey(Aes128KeyHandle & key) override;
44-
CHIP_ERROR PersistICDKey(Hmac128KeyHandle & key) override;
42+
CHIP_ERROR PersistICDKey(Symmetric128BitsKeyHandle & key) override;
4543
#endif
4644

4745
private:

src/crypto/SessionKeystore.h

+7-9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#pragma once
1919

20+
#include <app/icd/server/ICDServerConfig.h>
2021
#include <crypto/CHIPCryptoPAL.h>
2122
#include <lib/support/Span.h>
2223

@@ -141,21 +142,18 @@ class SessionKeystore
141142
Aes128KeyHandle & i2rKey, Aes128KeyHandle & r2iKey,
142143
AttestationChallenge & attestationChallenge) = 0;
143144

145+
#if CHIP_CONFIG_ENABLE_ICD_CIP
144146
/**
145-
* @brief Store key in persistent PSA storage and return a key handle for an ICD Aes key.
147+
* @brief Persistently store an ICD key.
146148
*
147-
* If the method returns no error, the application is responsible for destroying the handle
148-
* using the DestroyKey() method when the key is no longer needed.
149-
*/
150-
virtual CHIP_ERROR PersistICDKey(Aes128KeyHandle & key) { return CHIP_NO_ERROR; }
151-
152-
/**
153-
* @brief Store key in persistent PSA storage and return a key handle for an ICD Hmac key.
149+
* If input is already a persistent key handle, the function is a no-op and the original handle is returned.
150+
* If input is a volatile key handle, key is persisted and the handle may be updated.
154151
*
155152
* If the method returns no error, the application is responsible for destroying the handle
156153
* using the DestroyKey() method when the key is no longer needed.
157154
*/
158-
virtual CHIP_ERROR PersistICDKey(Hmac128KeyHandle & key) { return CHIP_NO_ERROR; }
155+
virtual CHIP_ERROR PersistICDKey(Symmetric128BitsKeyHandle & key) { return CHIP_NO_ERROR; }
156+
#endif
159157
};
160158

161159
/**

src/lib/core/CHIPConfig.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -1668,7 +1668,7 @@ extern const char CHIP_NON_PRODUCTION_MARKER[];
16681668
#endif
16691669

16701670
/**
1671-
* @def CHIP_CONFIG_ICD_MAX_CLIENTS
1671+
* @def CHIP_CONFIG_CRYPTO_PSA_ICD_MAX_CLIENTS
16721672
*
16731673
* @brief
16741674
* Maximum number of ICD clients. Based on this number, platforms that utilize the
@@ -1679,8 +1679,8 @@ extern const char CHIP_NON_PRODUCTION_MARKER[];
16791679
* compute the number of PSA key slots. It should remain unchanged during the device's lifetime,
16801680
* as alterations may lead to issues with backwards compatibility.
16811681
*/
1682-
#ifndef CHIP_CONFIG_ICD_MAX_CLIENTS
1683-
#define CHIP_CONFIG_ICD_MAX_CLIENTS 256
1682+
#ifndef CHIP_CONFIG_CRYPTO_PSA_ICD_MAX_CLIENTS
1683+
#define CHIP_CONFIG_CRYPTO_PSA_ICD_MAX_CLIENTS 256
16841684
#endif
16851685

16861686
/**

src/platform/nrfconnect/CHIPPlatformConfig.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@
146146
#endif // CONFIG_CHIP_ICD_CLIENTS_PER_FABRIC
147147
#endif // CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC
148148

149-
#ifndef CHIP_CONFIG_ICD_MAX_CLIENTS
150-
#define CHIP_CONFIG_ICD_MAX_CLIENTS 256
149+
#ifndef CHIP_CONFIG_CRYPTO_PSA_ICD_MAX_CLIENTS
150+
#define CHIP_CONFIG_CRYPTO_PSA_ICD_MAX_CLIENTS 256
151151
#endif
152152

153153
#ifndef CHIP_CONFIG_ENABLE_BDX_LOG_TRANSFER

0 commit comments

Comments
 (0)