16
16
*/
17
17
18
18
#include " PSAOperationalKeystore.h"
19
+ #include " PersistentStorageOperationalKeystore.h"
19
20
20
21
#include < lib/support/CHIPMem.h>
21
22
@@ -135,6 +136,35 @@ CHIP_ERROR PSAOperationalKeystore::NewOpKeypairForFabric(FabricIndex fabricIndex
135
136
return CHIP_NO_ERROR;
136
137
}
137
138
139
+ CHIP_ERROR PSAOperationalKeystore::PersistentP256Keypair::Deserialize (P256SerializedKeypair & input)
140
+ {
141
+ CHIP_ERROR error = CHIP_NO_ERROR;
142
+ psa_status_t status = PSA_SUCCESS;
143
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
144
+ psa_key_id_t keyId = 0 ;
145
+ VerifyOrReturnError (input.Length () == mPublicKey .Length () + kP256_PrivateKey_Length , CHIP_ERROR_INVALID_ARGUMENT);
146
+
147
+ Destroy ();
148
+
149
+ // Type based on ECC with the elliptic curve SECP256r1 -> PSA_ECC_FAMILY_SECP_R1
150
+ psa_set_key_type (&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR (PSA_ECC_FAMILY_SECP_R1));
151
+ psa_set_key_bits (&attributes, kP256_PrivateKey_Length * 8 );
152
+ psa_set_key_algorithm (&attributes, PSA_ALG_ECDSA (PSA_ALG_SHA_256));
153
+ psa_set_key_usage_flags (&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
154
+ psa_set_key_lifetime (&attributes, PSA_KEY_LIFETIME_PERSISTENT);
155
+ psa_set_key_id (&attributes, GetKeyId ());
156
+
157
+ status = psa_import_key (&attributes, input.ConstBytes () + mPublicKey .Length (), kP256_PrivateKey_Length , &keyId);
158
+ VerifyOrExit (status == PSA_SUCCESS, error = CHIP_ERROR_INTERNAL);
159
+
160
+ memcpy (mPublicKey .Bytes (), input.ConstBytes (), mPublicKey .Length ());
161
+
162
+ exit :
163
+ psa_reset_key_attributes (&attributes);
164
+
165
+ return error;
166
+ }
167
+
138
168
CHIP_ERROR PSAOperationalKeystore::ActivateOpKeypairForFabric (FabricIndex fabricIndex, const Crypto::P256PublicKey & nocPublicKey)
139
169
{
140
170
VerifyOrReturnError (IsValidFabricIndex (fabricIndex) && mPendingFabricIndex == fabricIndex, CHIP_ERROR_INVALID_FABRIC_INDEX);
@@ -154,6 +184,40 @@ CHIP_ERROR PSAOperationalKeystore::CommitOpKeypairForFabric(FabricIndex fabricIn
154
184
return CHIP_NO_ERROR;
155
185
}
156
186
187
+ CHIP_ERROR PSAOperationalKeystore::ExportOpKeypairForFabric (FabricIndex fabricIndex, Crypto::P256SerializedKeypair & outKeypair)
188
+ {
189
+ // Currently exporting the key is forbidden in PSAOperationalKeystore because the PSA_KEY_USAGE_EXPORT usage flag is not set, so
190
+ // there is no need to compile the code for the device, but there should be an implementation for test purposes to verify if
191
+ // the psa_export_key returns an error.
192
+ #if CHIP_CONFIG_TEST
193
+ VerifyOrReturnError (IsValidFabricIndex (fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX);
194
+ VerifyOrReturnError (HasOpKeypairForFabric (fabricIndex), CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND);
195
+
196
+ size_t outSize = 0 ;
197
+ psa_status_t status =
198
+ psa_export_key (PersistentP256Keypair (fabricIndex).GetKeyId (), outKeypair.Bytes (), outKeypair.Capacity (), &outSize);
199
+
200
+ if (status == PSA_ERROR_BUFFER_TOO_SMALL)
201
+ {
202
+ return CHIP_ERROR_BUFFER_TOO_SMALL;
203
+ }
204
+ else if (status == PSA_ERROR_NOT_PERMITTED)
205
+ {
206
+ return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
207
+ }
208
+ else if (status != PSA_SUCCESS)
209
+ {
210
+ return CHIP_ERROR_INTERNAL;
211
+ }
212
+
213
+ outKeypair.SetLength (outSize);
214
+
215
+ return CHIP_NO_ERROR;
216
+ #else
217
+ return CHIP_ERROR_NOT_IMPLEMENTED;
218
+ #endif
219
+ }
220
+
157
221
CHIP_ERROR PSAOperationalKeystore::RemoveOpKeypairForFabric (FabricIndex fabricIndex)
158
222
{
159
223
VerifyOrReturnError (IsValidFabricIndex (fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX);
@@ -209,5 +273,31 @@ void PSAOperationalKeystore::ReleasePendingKeypair()
209
273
mIsPendingKeypairActive = false ;
210
274
}
211
275
276
+ CHIP_ERROR PSAOperationalKeystore::MigrateOpKeypairForFabric (FabricIndex fabricIndex,
277
+ OperationalKeystore & operationalKeystore) const
278
+ {
279
+ VerifyOrReturnError (IsValidFabricIndex (fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX);
280
+
281
+ P256SerializedKeypair serializedKeypair;
282
+
283
+ // Do not allow overwriting the existing key and just remove it from the previous Operational Keystore if needed.
284
+ if (!HasOpKeypairForFabric (fabricIndex))
285
+ {
286
+ ReturnErrorOnFailure (operationalKeystore.ExportOpKeypairForFabric (fabricIndex, serializedKeypair));
287
+
288
+ PersistentP256Keypair keypair (fabricIndex);
289
+ ReturnErrorOnFailure (keypair.Deserialize (serializedKeypair));
290
+
291
+ // Migrated key is not useful anymore, remove it from the previous keystore.
292
+ ReturnErrorOnFailure (operationalKeystore.RemoveOpKeypairForFabric (fabricIndex));
293
+ }
294
+ else if (operationalKeystore.HasOpKeypairForFabric (fabricIndex))
295
+ {
296
+ ReturnErrorOnFailure (operationalKeystore.RemoveOpKeypairForFabric (fabricIndex));
297
+ }
298
+
299
+ return CHIP_NO_ERROR;
300
+ }
301
+
212
302
} // namespace Crypto
213
303
} // namespace chip
0 commit comments