Skip to content

Commit fe650a3

Browse files
[nrf toup] [Crypto] Fix the wrong handling PSA pending keypair.
The pending keypair was handled in a wrong way in the PSA PAL. This keypair should be saved to ITS as volatile persistence, then all operations should be done using this instance, and it must be saved to persistent storage in the CommitOpKeypairForFabric function. Previously, the same KeyId was used both to active and pending keypairs, and when a failsafe occurs, then this key has been removed and there is no key for the fabric anymore. Main changes: - PersistentP256Keypair::Generate generates a pending keypair as volatile with additional usage flag PSA_KEY_USAGE_COPY. - In the CommitOpKeypairForFabric function the pending keypair is copied to persistent location, and the keyId for fabric is replaced. Signed-off-by: Arkadiusz Balys <[email protected]>
1 parent 391a4ba commit fe650a3

File tree

1 file changed

+38
-10
lines changed

1 file changed

+38
-10
lines changed

src/crypto/PSAOperationalKeystore.cpp

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,13 @@ CHIP_ERROR PSAOperationalKeystore::PersistentP256Keypair::Generate()
6060
psa_status_t status = PSA_SUCCESS;
6161
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
6262
psa_key_id_t keyId = 0;
63-
size_t publicKeyLength;
64-
65-
Destroy();
63+
size_t publicKeyLength = 0;
6664

6765
// Type based on ECC with the elliptic curve SECP256r1 -> PSA_ECC_FAMILY_SECP_R1
6866
psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
6967
psa_set_key_bits(&attributes, kP256_PrivateKey_Length * 8);
7068
psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
71-
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
72-
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_PERSISTENT);
73-
psa_set_key_id(&attributes, GetKeyId());
74-
GetPSAKeyAllocator().UpdateKeyAttributes(attributes);
69+
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_COPY);
7570

7671
status = psa_generate_key(&attributes, &keyId);
7772
VerifyOrExit(status == PSA_SUCCESS, error = CHIP_ERROR_INTERNAL);
@@ -81,14 +76,19 @@ CHIP_ERROR PSAOperationalKeystore::PersistentP256Keypair::Generate()
8176
VerifyOrExit(publicKeyLength == kP256_PublicKey_Length, error = CHIP_ERROR_INTERNAL);
8277

8378
exit:
79+
// Save the volatile key id to the context
80+
ToPsaContext(mKeypair).key_id = keyId;
81+
8482
psa_reset_key_attributes(&attributes);
8583

8684
return error;
8785
}
8886

8987
CHIP_ERROR PSAOperationalKeystore::PersistentP256Keypair::Destroy()
9088
{
91-
psa_status_t status = psa_destroy_key(GetKeyId());
89+
psa_status_t status = PSA_SUCCESS;
90+
91+
status = psa_destroy_key(GetKeyId());
9292

9393
VerifyOrReturnError(status != PSA_ERROR_INVALID_HANDLE, CHIP_ERROR_INVALID_FABRIC_INDEX);
9494
VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL);
@@ -183,9 +183,37 @@ CHIP_ERROR PSAOperationalKeystore::CommitOpKeypairForFabric(FabricIndex fabricIn
183183
VerifyOrReturnError(IsValidFabricIndex(fabricIndex) && mPendingFabricIndex == fabricIndex, CHIP_ERROR_INVALID_FABRIC_INDEX);
184184
VerifyOrReturnError(mIsPendingKeypairActive, CHIP_ERROR_INCORRECT_STATE);
185185

186-
ReleasePendingKeypair();
186+
psa_status_t status = PSA_SUCCESS;
187+
CHIP_ERROR error = CHIP_NO_ERROR;
188+
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
189+
psa_key_id_t keyId = 0;
187190

188-
return CHIP_NO_ERROR;
191+
PersistentP256Keypair keyPairToCommit(fabricIndex);
192+
193+
status = psa_get_key_attributes(mPendingKeypair->GetKeyId(), &attributes);
194+
VerifyOrExit(status == PSA_SUCCESS, error = CHIP_ERROR_INTERNAL);
195+
196+
psa_destroy_key(keyPairToCommit.GetKeyId());
197+
198+
// Switch to the persistent key
199+
psa_set_key_id(&attributes, keyPairToCommit.GetKeyId());
200+
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_PERSISTENT);
201+
202+
// Update the key attributes if needed
203+
GetPSAKeyAllocator().UpdateKeyAttributes(attributes);
204+
205+
status = psa_copy_key(mPendingKeypair->GetKeyId(), &attributes, &keyId);
206+
VerifyOrExit(status == PSA_SUCCESS, error = CHIP_ERROR_INTERNAL);
207+
VerifyOrExit(keyId == keyPairToCommit.GetKeyId(), error = CHIP_ERROR_INTERNAL);
208+
209+
// Copied was done, so we can revert the pending keypair
210+
RevertPendingKeypair();
211+
212+
exit:
213+
LogPsaError(status);
214+
psa_reset_key_attributes(&attributes);
215+
216+
return error;
189217
}
190218

191219
CHIP_ERROR PSAOperationalKeystore::ExportOpKeypairForFabric(FabricIndex fabricIndex, Crypto::P256SerializedKeypair & outKeypair)

0 commit comments

Comments
 (0)