Skip to content

Commit 15a7070

Browse files
[NXP][k32w1] Remove the need for extra DAC private key conversion binary (project-chip#32699)
* [NXP][k32w1] Add SSS DAC private key conversion at init / Use plain-text DAC key * Do SSS DAC private key conversion at initialization if needed. * Do not use extra SSS conversion binary anymore. * Add option to use DAC private key in plain text. Signed-off-by: Andrei Menzopol <andrei.menzopol@nxp.com> * [NXP][k32w1] Update manufacturing flow to not use chip_convert_dac_private_key * Using chip_convert_dac_private_key option is not needed anymore. * Use chip_use_plain_dac_key=true for plain-text DAC private key. Signed-off-by: Andrei Menzopol <andrei.menzopol@nxp.com> * [NXP][k32w1] Remove example_convert_dac_private_key.jlink * Using chip_convert_dac_private_key option is not needed anymore, making the jlink script obsolete. Signed-off-by: Andrei Menzopol <andrei.menzopol@nxp.com> * Restyled by prettier-markdown * Restyled by prettier-markdown * Check SSS_ExportBlob return status Signed-off-by: Andrei Menzopol <andrei.menzopol@nxp.com> --------- Signed-off-by: Andrei Menzopol <andrei.menzopol@nxp.com> Co-authored-by: Restyled.io <commits@restyled.io>
1 parent dfb8bb9 commit 15a7070

File tree

6 files changed

+96
-71
lines changed

6 files changed

+96
-71
lines changed

docs/guides/nxp_manufacturing_flow.md

+10-18
Original file line numberDiff line numberDiff line change
@@ -215,26 +215,15 @@ converted to an encrypted blob. This blob will overwrite the DAC private key in
215215
factory data and will be imported in the `SSS` at initialization, by the factory
216216
data provider instance.
217217

218-
The conversion process shall happen at manufacturing time and should be run one
219-
time only:
220-
221-
- Write factory data binary.
222-
- Build the application with
223-
`chip_with_factory_data=1 chip_convert_dac_private_key=1` set.
224-
- Write the application to the board and let it run.
225-
226-
After the conversion process:
218+
The application will check at initialization whether the DAC private key has
219+
been converted or not and convert it if needed. However, the conversion process
220+
should be done at manufacturing time for security reasons.
227221

228-
- Make sure the application is built with `chip_with_factory_data=1`, but
229-
without `chip_convert_dac_private_key` arg, since conversion already
230-
happened.
231-
- Write the application to the board.
232-
233-
If you are using Jlink, you can see a conversion script example in:
222+
There is no need for an extra binary.
234223

235-
```shell
236-
./scripts/tools/nxp/factory_data_generator/k32w1/example_convert_dac_private_key.jlink
237-
```
224+
- Write factory data binary.
225+
- Build the application with `chip_with_factory_data=1` set.
226+
- Write the application to the board and use it as usual.
238227

239228
Factory data should now contain a corresponding encrypted blob instead of the
240229
DAC private key.
@@ -251,6 +240,9 @@ python3 ./scripts/tools/nxp/factory_data_generator/generate.py -i 10000 -s UXKLz
251240
Please note that `--dac_key` now points to a binary file that contains the
252241
encrypted blob.
253242

243+
The user can use the DAC private in plain text instead of using the `SSS` by
244+
adding the following gn argument `chip_use_plain_dac_key=true`.
245+
254246
### 6.2 RW61X
255247

256248
Supported platforms:

scripts/tools/nxp/factory_data_generator/k32w1/example_convert_dac_private_key.jlink

-16
This file was deleted.

src/platform/nxp/k32w/k32w1/BUILD.gn

+6-4
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ static_library("nxp_platform") {
6161
"ram_storage.h",
6262
]
6363

64+
if (chip_use_plain_dac_key) {
65+
defines += [ "CHIP_USE_PLAIN_DAC_KEY=1" ]
66+
} else {
67+
defines += [ "CHIP_USE_PLAIN_DAC_KEY=0" ]
68+
}
69+
6470
public = [
6571
"${chip_root}/src/credentials/DeviceAttestationCredsProvider.h",
6672
"${chip_root}/src/credentials/examples/DeviceAttestationCredsExample.h",
@@ -107,10 +113,6 @@ static_library("nxp_platform") {
107113
"${chip_root}/src/credentials/CHIPCert.h",
108114
"${chip_root}/src/credentials/CertificationDeclaration.h",
109115
]
110-
111-
if (chip_convert_dac_private_key == 1) {
112-
defines += [ "CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY=1" ]
113-
}
114116
}
115117

116118
public_deps += [ "${mbedtls_root}:mbedtls" ]

src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.cpp

+70-13
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,30 @@
1515
* limitations under the License.
1616
*/
1717

18-
#include <platform/nxp/k32w/k32w1/FactoryDataProviderImpl.h>
19-
20-
#if CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY
2118
#include "fsl_adapter_flash.h"
22-
#endif
19+
#include <platform/nxp/k32w/k32w1/FactoryDataProviderImpl.h>
2320

2421
namespace chip {
2522
namespace DeviceLayer {
2623

24+
#if !CHIP_USE_PLAIN_DAC_KEY
2725
// SSS adds 24 bytes of metadata when creating the blob
2826
static constexpr size_t kSssBlobMetadataLength = 24;
2927
static constexpr size_t kPrivateKeyBlobLength = Crypto::kP256_PrivateKey_Length + kSssBlobMetadataLength;
28+
#endif
3029

3130
FactoryDataProviderImpl::~FactoryDataProviderImpl()
3231
{
32+
#if !CHIP_USE_PLAIN_DAC_KEY
3333
SSS_KEY_OBJ_FREE(&mContext);
34+
#endif
3435
}
3536

3637
CHIP_ERROR FactoryDataProviderImpl::Init()
3738
{
3839
CHIP_ERROR error = CHIP_NO_ERROR;
3940

40-
#if CHIP_DEVICE_CONFIG_ENABLE_SSS_API_TEST
41+
#if CHIP_DEVICE_CONFIG_ENABLE_SSS_API_TEST && !CHIP_USE_PLAIN_DAC_KEY
4142
SSS_RunApiTest();
4243
#endif
4344

@@ -47,16 +48,56 @@ CHIP_ERROR FactoryDataProviderImpl::Init()
4748
ChipLogError(DeviceLayer, "Factory data init failed with: %s", ErrorStr(error));
4849
}
4950

51+
#if !CHIP_USE_PLAIN_DAC_KEY
5052
ReturnErrorOnFailure(SSS_InitContext());
51-
#if CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY
5253
ReturnErrorOnFailure(SSS_ConvertDacKey());
53-
ReturnErrorOnFailure(Validate());
54-
#endif
5554
ReturnErrorOnFailure(SSS_ImportPrivateKeyBlob());
55+
#endif
5656

5757
return error;
5858
}
5959

60+
#if CHIP_USE_PLAIN_DAC_KEY
61+
CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer)
62+
{
63+
CHIP_ERROR error = CHIP_NO_ERROR;
64+
Crypto::P256ECDSASignature signature;
65+
Crypto::P256Keypair keypair;
66+
Crypto::P256SerializedKeypair serializedKeypair;
67+
uint8_t keyBuf[Crypto::kP256_PrivateKey_Length];
68+
MutableByteSpan dacPrivateKeySpan(keyBuf);
69+
uint16_t keySize = 0;
70+
71+
VerifyOrExit(!outSignBuffer.empty(), error = CHIP_ERROR_INVALID_ARGUMENT);
72+
VerifyOrExit(!messageToSign.empty(), error = CHIP_ERROR_INVALID_ARGUMENT);
73+
VerifyOrExit(outSignBuffer.size() >= signature.Capacity(), error = CHIP_ERROR_BUFFER_TOO_SMALL);
74+
75+
/* Get private key of DAC certificate from reserved section */
76+
error = SearchForId(FactoryDataId::kDacPrivateKeyId, dacPrivateKeySpan.data(), dacPrivateKeySpan.size(), keySize);
77+
SuccessOrExit(error);
78+
dacPrivateKeySpan.reduce_size(keySize);
79+
VerifyOrExit(keySize == Crypto::kP256_PrivateKey_Length, error = CHIP_ERROR_WRONG_KEY_TYPE);
80+
81+
/* Only the private key is used when signing */
82+
error = serializedKeypair.SetLength(Crypto::kP256_PublicKey_Length + dacPrivateKeySpan.size());
83+
SuccessOrExit(error);
84+
memcpy(serializedKeypair.Bytes() + Crypto::kP256_PublicKey_Length, dacPrivateKeySpan.data(), dacPrivateKeySpan.size());
85+
86+
error = keypair.Deserialize(serializedKeypair);
87+
SuccessOrExit(error);
88+
89+
error = keypair.ECDSA_sign_msg(messageToSign.data(), messageToSign.size(), signature);
90+
SuccessOrExit(error);
91+
92+
error = CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer);
93+
94+
exit:
95+
/* Sanitize temporary buffer */
96+
memset(keyBuf, 0, Crypto::kP256_PrivateKey_Length);
97+
return error;
98+
}
99+
100+
#else
60101
CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer)
61102
{
62103
Crypto::P256ECDSASignature signature;
@@ -118,18 +159,25 @@ CHIP_ERROR FactoryDataProviderImpl::SSS_Sign(uint8_t * digest, Crypto::P256ECDSA
118159
return error;
119160
}
120161

121-
#if CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY
122162
CHIP_ERROR FactoryDataProviderImpl::SSS_ConvertDacKey()
123163
{
124164
size_t blobSize = kPrivateKeyBlobLength;
125165
size_t newSize = sizeof(FactoryDataProvider::Header) + mHeader.size + kSssBlobMetadataLength;
126166
uint8_t blob[kPrivateKeyBlobLength] = { 0 };
127167
uint8_t * data = static_cast<uint8_t *>(chip::Platform::MemoryAlloc(newSize));
128168
uint32_t offset = 0;
169+
bool convNeeded = true;
129170

130171
VerifyOrReturnError(data != nullptr, CHIP_ERROR_INTERNAL);
131172

132-
ReturnErrorOnFailure(SSS_ExportBlob(blob, &blobSize, offset));
173+
ReturnErrorOnFailure(SSS_ExportBlob(blob, &blobSize, offset, convNeeded));
174+
if (!convNeeded)
175+
{
176+
ChipLogError(DeviceLayer, "SSS: DAC private key already converted to blob");
177+
chip::Platform::MemoryFree(data);
178+
return CHIP_NO_ERROR;
179+
}
180+
133181
ChipLogError(DeviceLayer, "SSS: extracted blob from DAC private key");
134182

135183
hal_flash_status_t status = HAL_FlashRead(kFactoryDataStart, newSize - kSssBlobMetadataLength, data);
@@ -149,22 +197,31 @@ CHIP_ERROR FactoryDataProviderImpl::SSS_ConvertDacKey()
149197
chip::Platform::MemoryFree(data);
150198
ChipLogError(DeviceLayer, "SSS: sanitized RAM cache");
151199

200+
ReturnErrorOnFailure(Validate());
201+
152202
return CHIP_NO_ERROR;
153203
}
154204

155-
CHIP_ERROR FactoryDataProviderImpl::SSS_ExportBlob(uint8_t * data, size_t * dataLen, uint32_t & offset)
205+
CHIP_ERROR FactoryDataProviderImpl::SSS_ExportBlob(uint8_t * data, size_t * dataLen, uint32_t & offset, bool & isNeeded)
156206
{
157207
CHIP_ERROR error = CHIP_NO_ERROR;
158208
auto res = kStatus_SSS_Success;
159209

160-
uint8_t keyBuf[Crypto::kP256_PrivateKey_Length];
210+
uint8_t keyBuf[kPrivateKeyBlobLength];
161211
MutableByteSpan dacPrivateKeySpan(keyBuf);
162212
uint16_t keySize = 0;
213+
isNeeded = true;
163214

164215
error = SearchForId(FactoryDataId::kDacPrivateKeyId, dacPrivateKeySpan.data(), dacPrivateKeySpan.size(), keySize, &offset);
165216
SuccessOrExit(error);
166217
dacPrivateKeySpan.reduce_size(keySize);
167218

219+
if (keySize == kPrivateKeyBlobLength)
220+
{
221+
isNeeded = false;
222+
return CHIP_NO_ERROR;
223+
}
224+
168225
res = SSS_KEY_STORE_SET_KEY(&mContext, dacPrivateKeySpan.data(), Crypto::kP256_PrivateKey_Length, keySize * 8,
169226
kSSS_KeyPart_Private);
170227
VerifyOrExit(res == kStatus_SSS_Success, error = CHIP_ERROR_INTERNAL);
@@ -197,7 +254,6 @@ CHIP_ERROR FactoryDataProviderImpl::ReplaceWithBlob(uint8_t * data, uint8_t * bl
197254

198255
return CHIP_NO_ERROR;
199256
}
200-
#endif // CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY
201257

202258
#if CHIP_DEVICE_CONFIG_ENABLE_SSS_API_TEST
203259

@@ -298,6 +354,7 @@ void FactoryDataProviderImpl::SSS_RunApiTest()
298354
SSS_KEY_OBJ_FREE(&mContext);
299355
}
300356
#endif // CHIP_DEVICE_CONFIG_ENABLE_SSS_API_TEST
357+
#endif // CHIP_USE_PLAIN_DAC_KEY
301358

302359
} // namespace DeviceLayer
303360
} // namespace chip

src/platform/nxp/k32w/k32w1/FactoryDataProviderImpl.h

+9-19
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,8 @@
1919
#include <crypto/CHIPCryptoPAL.h>
2020
#include <platform/nxp/k32w/common/FactoryDataProvider.h>
2121

22+
#if !CHIP_USE_PLAIN_DAC_KEY
2223
#include "sss_crypto.h"
23-
24-
/* This flag should be defined when the factory data contains
25-
* the DAC private key in plain text. It usually occurs in
26-
* manufacturing.
27-
*
28-
* The init phase will use S200 to export an encrypted blob,
29-
* then overwrite the private key section from internal flash.
30-
*
31-
* Should be used one time only for securing the private key.
32-
* The manufacturer will then flash the real image, which shall
33-
* not define this flag.
34-
*/
35-
#ifndef CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY
36-
#define CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY 0
3724
#endif
3825

3926
/* This flag should be defined to run SSS_RunApiTest tests.
@@ -59,12 +46,13 @@ class FactoryDataProviderImpl : public FactoryDataProvider
5946
CHIP_ERROR SignWithDacKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override;
6047

6148
private:
49+
#if !CHIP_USE_PLAIN_DAC_KEY
50+
6251
CHIP_ERROR SSS_InitContext();
6352
CHIP_ERROR SSS_ImportPrivateKeyBlob();
6453
CHIP_ERROR SSS_Sign(uint8_t * digest, Crypto::P256ECDSASignature & signature);
65-
#if CHIP_DEVICE_CONFIG_SECURE_DAC_PRIVATE_KEY
6654
/*!
67-
* \brief Convert DAC private key to an SSS encrypted blob and update factory data
55+
* \brief Convert DAC private key to an SSS encrypted blob and update factory data if not already done
6856
*
6957
* @note This API should be called in manufacturing process context to replace
7058
* DAC private key with an SSS encrypted blob. The conversion will be a
@@ -74,15 +62,16 @@ class FactoryDataProviderImpl : public FactoryDataProvider
7462
CHIP_ERROR SSS_ConvertDacKey();
7563

7664
/*!
77-
* \brief Export an SSS encrypted blob from the DAC private key found in factory data
65+
* \brief Check and export an SSS encrypted blob from the DAC private key found in factory data if needed
7866
*
7967
* @param data Pointer to an allocated buffer
8068
* @param dataLen Pointer to a variable that will store the blob length
8169
* @param offset Offset of private key from the start of factory data payload address (after header)
70+
* @param isNeeded Will be set to true if conversion is needed
8271
*
8372
* @retval #CHIP_NO_ERROR if conversion to blob was successful.
8473
*/
85-
CHIP_ERROR SSS_ExportBlob(uint8_t * data, size_t * dataLen, uint32_t & offset);
74+
CHIP_ERROR SSS_ExportBlob(uint8_t * data, size_t * dataLen, uint32_t & offset, bool & isNeeded);
8675

8776
/*!
8877
* \brief Replace DAC private key with the specified SSS encrypted blob
@@ -97,12 +86,13 @@ class FactoryDataProviderImpl : public FactoryDataProvider
9786
* @retval #CHIP_NO_ERROR if conversion to blob was successful.
9887
*/
9988
CHIP_ERROR ReplaceWithBlob(uint8_t * data, uint8_t * blob, size_t blobLen, uint32_t offset);
100-
#endif
89+
10190
#if CHIP_DEVICE_CONFIG_ENABLE_SSS_API_TEST
10291
void SSS_RunApiTest();
10392
#endif
10493

10594
sss_sscp_object_t mContext;
95+
#endif // CHIP_USE_PLAIN_DAC_KEY
10696
};
10797

10898
} // namespace DeviceLayer

src/platform/nxp/k32w/k32w1/args.gni

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import("//build_overrides/openthread.gni")
1919
declare_args() {
2020
chip_with_ot_cli = 0
2121
chip_with_low_power = 0
22-
chip_convert_dac_private_key = 0
2322
sdk_release = 1
23+
chip_use_plain_dac_key = false
2424
}
2525

2626
nxp_platform = "k32w/k32w1"

0 commit comments

Comments
 (0)