Skip to content

Commit 546f646

Browse files
rosahay-silabssenthilkurestyled-commitsbrosahay
authored
[SILABS] Adds support for encryption in Multi-OTA using mbedTLS (#38920)
* Rename to OtaTlvEncryptionKeyPSA implementation for AES key management and decryption * Refactor OTA encryption files with general cleanup * Implement OTA encryption key storage for Tinycrypt and PSA Crypto * Add missing includes and namespace usage in OTATlvProcessor * added MbedTLS code for OTA encryption/decryption * Restyled by clang-format * resolve build error * Refactor OTA encryption key handling for Tinycrypt and MbedTLS * Enhance OTA encryption handling by refining conditional compilation and improving key management across multiple files * Adds build changes * undo change * align ifdef declarations * Added LICENSE for the new and updating old files * Adds fix for build * Update submodule * Remove unnecessary SilabsConfig include from OtaTlvEncryptionKeyPSA.cpp * Format OtaTlvEncryptionKeyMbed.cpp source inclusion for better readability * Add padding removal for the last block in OTA processing * Add encryption key handling and decryption tests in SilabsTestDelegate * Refactor test cases for SilabsTestEventTriggerDelegate to improve clarity and maintainability * Remove redundant tests and update encryption key handling in SilabsTestEventTriggerDelegate --------- Co-authored-by: senthil kumar E K <[email protected]> Co-authored-by: Restyled.io <[email protected]> Co-authored-by: brosahay <[email protected]>
1 parent 7cc92a0 commit 546f646

File tree

10 files changed

+265
-33
lines changed

10 files changed

+265
-33
lines changed

examples/platform/silabs/provision/ProvisionStorageDefault.cpp

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@
2929
#include <platform/silabs/platformAbstraction/SilabsPlatform.h>
3030
#include <silabs_creds.h>
3131
#ifndef NDEBUG
32-
#if defined(SL_MATTER_TEST_EVENT_TRIGGER_ENABLED) && (SL_MATTER_GN_BUILD == 0)
32+
#if defined(SL_MATTER_TEST_EVENT_TRIGGER_ENABLED) && SL_MATTER_TEST_EVENT_TRIGGER_ENABLED && (SL_MATTER_GN_BUILD == 0)
3333
#include <sl_matter_test_event_trigger_config.h>
3434
#endif // defined(SL_MATTER_TEST_EVENT_TRIGGER_ENABLED) && (SL_MATTER_GN_BUILD == 0)
3535
#endif // NDEBUG
36-
#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION
36+
#if defined(SL_MATTER_ENABLE_OTA_ENCRYPTION) && SL_MATTER_ENABLE_OTA_ENCRYPTION
3737
#include <platform/silabs/multi-ota/OtaTlvEncryptionKey.h>
3838
#endif // SL_MATTER_ENABLE_OTA_ENCRYPTION
3939
#ifndef SLI_SI91X_MCU_INTERFACE
@@ -616,7 +616,7 @@ CHIP_ERROR Storage::SignWithDeviceAttestationKey(const ByteSpan & message, Mutab
616616
// ChipLogByteSpan(DeviceLayer, ByteSpan(signature.data(), signature.size() < kDebugLength ? signature.size() : kDebugLength));
617617
return err;
618618
}
619-
#endif // SLI_SI91X_MCU_INTERFACE
619+
#endif // SLI_SI91X_MCU_INTERFACE && SL_MBEDTLS_USE_TINYCRYPT
620620

621621
//
622622
// Other
@@ -662,12 +662,62 @@ CHIP_ERROR Storage::GetProvisionRequest(bool & value)
662662
return SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_Provision_Request, value);
663663
}
664664

665-
#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION
665+
#if defined(SL_MATTER_ENABLE_OTA_ENCRYPTION) && SL_MATTER_ENABLE_OTA_ENCRYPTION
666666
CHIP_ERROR Storage::SetOtaTlvEncryptionKey(const ByteSpan & value)
667667
{
668-
chip::DeviceLayer::Silabs::OtaTlvEncryptionKey::OtaTlvEncryptionKey key;
668+
#if defined(SL_MBEDTLS_USE_TINYCRYPT)
669+
// Tinycrypt doesn't support the key ID, so we need to store the key as a binary blob
670+
return SilabsConfig::WriteConfigValueBin(SilabsConfig::kOtaTlvEncryption_KeyId, value.data(), value.size());
671+
#else // MBEDTLS_USE_PSA_CRYPTO
672+
Silabs::OtaTlvEncryptionKey key;
669673
ReturnErrorOnFailure(key.Import(value.data(), value.size()));
670674
return SilabsConfig::WriteConfigValue(SilabsConfig::kOtaTlvEncryption_KeyId, key.GetId());
675+
#endif // SL_MBEDTLS_USE_TINYCRYPT
676+
}
677+
678+
CHIP_ERROR Storage::GetOtaTlvEncryptionKeyId(uint32_t & keyId)
679+
{
680+
#if defined(SL_MBEDTLS_USE_TINYCRYPT)
681+
// Tinycrypt doesn't support the key ID
682+
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
683+
#else // MBEDTLS_USE_PSA_CRYPTO
684+
// Read the key ID from the config
685+
return SilabsConfig::ReadConfigValue(SilabsConfig::kOtaTlvEncryption_KeyId, keyId);
686+
#endif // SL_MBEDTLS_USE_TINYCRYPT
687+
}
688+
689+
CHIP_ERROR Storage::DecryptUsingOtaTlvEncryptionKey(MutableByteSpan & block, uint32_t & ivOffset)
690+
{
691+
#if defined(SL_MBEDTLS_USE_TINYCRYPT)
692+
uint8_t keyBuffer[kOTAEncryptionKeyLength] = { 0 };
693+
size_t keyLen = 0;
694+
695+
// Read the key from the provisioning storage
696+
MutableByteSpan keySpan = MutableByteSpan(keyBuffer);
697+
698+
SilabsConfig::ReadConfigValueBin(SilabsConfig::kOtaTlvEncryption_KeyId, keySpan.data(), keySpan.size());
699+
VerifyOrReturnError(keySpan.size() == kOTAEncryptionKeyLength, CHIP_ERROR_INVALID_ARGUMENT);
700+
701+
Silabs::OtaTlvEncryptionKey::Decrypt((const ByteSpan) keySpan, block, ivOffset);
702+
return CHIP_NO_ERROR;
703+
#else // MBEDTLS_USE_PSA_CRYPTO
704+
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
705+
#endif // SL_MBEDTLS_USE_TINYCRYPT
706+
}
707+
#else
708+
CHIP_ERROR Storage::SetOtaTlvEncryptionKey(const ByteSpan & value)
709+
{
710+
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
711+
}
712+
713+
CHIP_ERROR Storage::GetOtaTlvEncryptionKeyId(uint32_t & keyId)
714+
{
715+
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
716+
}
717+
718+
CHIP_ERROR Storage::DecryptUsingOtaTlvEncryptionKey(MutableByteSpan & block, uint32_t & ivOffset)
719+
{
720+
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
671721
}
672722
#endif // SL_MATTER_ENABLE_OTA_ENCRYPTION
673723

examples/platform/silabs/provision/ProvisionStorageFlash.cpp

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#include <sl_matter_test_event_trigger_config.h>
3232
#endif // defined(SL_MATTER_TEST_EVENT_TRIGGER_ENABLED) && (SL_MATTER_GN_BUILD == 0)
3333
#endif // NDEBUG
34-
#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION
34+
#if defined(SL_MATTER_ENABLE_OTA_ENCRYPTION) && SL_MATTER_ENABLE_OTA_ENCRYPTION
3535
#include <platform/silabs/multi-ota/OtaTlvEncryptionKey.h>
3636
#endif // SL_MATTER_ENABLE_OTA_ENCRYPTION
3737

@@ -731,10 +731,64 @@ CHIP_ERROR Storage::GetProvisionRequest(bool & value)
731731
// return Flash::Set(Parameters::ID::kProvisionRequest, value);
732732
return CHIP_ERROR_NOT_IMPLEMENTED;
733733
}
734-
#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION
734+
735+
#if defined(SL_MATTER_ENABLE_OTA_ENCRYPTION) && SL_MATTER_ENABLE_OTA_ENCRYPTION
735736
CHIP_ERROR Storage::SetOtaTlvEncryptionKey(const ByteSpan & value)
736737
{
738+
#if defined(SL_MBEDTLS_USE_TINYCRYPT)
739+
// Tinycrypt doesn't support the key ID, so we need to store the key as a binary blob
740+
return Flash::Set(Parameters::ID::kOtaTlvEncryptionKey, value.data(), value.size());
741+
#else // MBEDTLS_USE_PSA_CRYPTO
742+
Silabs::OtaTlvEncryptionKey key;
743+
ReturnErrorOnFailure(key.Import(value.data(), value.size()));
744+
return Flash::Set(Parameters::ID::kOtaTlvEncryptionKey, key.GetId());
745+
#endif // SL_MBEDTLS_USE_TINYCRYPT
746+
}
747+
748+
CHIP_ERROR Storage::GetOtaTlvEncryptionKeyId(uint32_t & keyId)
749+
{
750+
#if defined(SL_MBEDTLS_USE_TINYCRYPT)
751+
// Tinycrypt doesn't support the key ID
752+
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
753+
#else // MBEDTLS_USE_PSA_CRYPTO
754+
return Flash::Get(Parameters::ID::kOtaTlvEncryptionKey, keyId);
755+
#endif // SL_MBEDTLS_USE_TINYCRYPT
756+
}
757+
758+
CHIP_ERROR Storage::DecryptUsingOtaTlvEncryptionKey(MutableByteSpan & block, uint32_t & ivOffset)
759+
{
760+
#if defined(SL_MBEDTLS_USE_TINYCRYPT)
761+
uint8_t keyBuffer[Silabs::OtaTlvEncryptionKey::kOTAEncryptionKeyLength] = { 0 };
762+
size_t keyLen = 0;
763+
764+
// Read the key from the provisioning storage
765+
MutableByteSpan keySpan = MutableByteSpan(keyBuffer);
766+
767+
ReturnErrorOnFailure(Flash::Get(Parameters::ID::kOtaTlvEncryptionKey, keySpan.data(), keySpan.size(), keyLen));
768+
keySpan.reduce_size(keyLen);
769+
770+
VerifyOrReturnError(keySpan.size() == Silabs::OtaTlvEncryptionKey::kOTAEncryptionKeyLength, CHIP_ERROR_INVALID_ARGUMENT);
771+
772+
Silabs::OtaTlvEncryptionKey::Decrypt((const ByteSpan) keySpan, block, ivOffset);
773+
return CHIP_NO_ERROR;
774+
#else // MBEDTLS_USE_PSA_CRYPTO
737775
return CHIP_ERROR_NOT_IMPLEMENTED;
776+
#endif // SL_MBEDTLS_USE_TINYCRYPT
777+
}
778+
#else
779+
CHIP_ERROR Storage::SetOtaTlvEncryptionKey(const ByteSpan & value)
780+
{
781+
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
782+
}
783+
784+
CHIP_ERROR Storage::GetOtaTlvEncryptionKeyId(uint32_t & keyId)
785+
{
786+
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
787+
}
788+
789+
CHIP_ERROR Storage::DecryptUsingOtaTlvEncryptionKey(MutableByteSpan & block, uint32_t & ivOffset)
790+
{
791+
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
738792
}
739793
#endif // SL_MATTER_ENABLE_OTA_ENCRYPTION
740794

examples/platform/silabs/tests/TestSilabsTestEventTrigger.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,17 @@ class ProviderStub : public ProvisionedDataProvider
5656

5757
void SetForceError(bool value) { forceError = value; }
5858

59+
CHIP_ERROR GetOtaTlvEncryptionKeyId(uint32_t & value) override
60+
{
61+
value = 0;
62+
return CHIP_NO_ERROR;
63+
}
64+
65+
CHIP_ERROR DecryptUsingOtaTlvEncryptionKey(MutableByteSpan & block, uint32_t & ivOffset) override
66+
{
67+
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
68+
}
69+
5970
private:
6071
uint8_t mEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0 };
6172
bool forceError = false;

src/platform/silabs/multi-ota/BUILD.gn

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ source_set("multi-ota-efr32") {
7676
}
7777

7878
if (chip_enable_multi_ota_encryption) {
79-
sources += [ "${silabs_platform_dir}/multi-ota/OtaTlvEncryptionKey.cpp" ]
79+
sources += [ "${silabs_platform_dir}/multi-ota/OtaTlvEncryptionKeyPSA.cpp" ]
8080
}
8181
}
8282

@@ -88,7 +88,8 @@ source_set("multi-ota-siwx") {
8888
"${silabs_platform_dir}/wifi:wifi-platform",
8989
]
9090
if (chip_enable_multi_ota_encryption) {
91-
sources += [ "${silabs_platform_dir}/multi-ota/OtaTlvEncryptionKey.cpp" ]
91+
sources +=
92+
[ "${silabs_platform_dir}/multi-ota/OtaTlvEncryptionKeyMbed.cpp" ]
9293
}
9394
public_configs = [ ":multi-ota-siwx-config" ]
9495
}

src/platform/silabs/multi-ota/OTATlvProcessor.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
*
3-
* Copyright (c) 2023 Project CHIP Authors
3+
* Copyright (c) 2023-2025 Project CHIP Authors
44
* All rights reserved.
55
*
66
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,25 +20,24 @@
2020
#include <lib/support/BufferReader.h>
2121
#include <lib/support/TypeTraits.h>
2222

23+
#include <headers/ProvisionManager.h>
24+
#include <headers/ProvisionStorage.h>
2325
#include <platform/silabs/multi-ota/OTAMultiImageProcessorImpl.h>
2426
#include <platform/silabs/multi-ota/OTATlvProcessor.h>
25-
#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION
27+
#if SL_MATTER_ENABLE_OTA_ENCRYPTION
2628
#include <platform/silabs/multi-ota/OtaTlvEncryptionKey.h>
2729
#endif
2830

2931
using namespace ::chip::DeviceLayer::Internal;
32+
using namespace ::chip::DeviceLayer::Silabs;
3033

3134
namespace chip {
3235

33-
#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION
34-
constexpr uint8_t au8Iv[] = { 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x00, 0x00, 0x00 };
35-
#endif
36-
3736
CHIP_ERROR OTATlvProcessor::Init()
3837
{
3938
VerifyOrReturnError(mCallbackProcessDescriptor != nullptr, CHIP_OTA_PROCESSOR_CB_NOT_REGISTERED);
4039
mAccumulator.Init(GetAccumulatorLength());
41-
#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION
40+
#if defined(SL_MATTER_ENABLE_OTA_ENCRYPTION) && SL_MATTER_ENABLE_OTA_ENCRYPTION
4241
mUnalignmentNum = 0;
4342
#endif
4443
return CHIP_NO_ERROR;
@@ -49,7 +48,7 @@ CHIP_ERROR OTATlvProcessor::Clear()
4948
OTATlvProcessor::ClearInternal();
5049
mAccumulator.Clear();
5150
mDescriptorProcessed = false;
52-
#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION
51+
#if defined(SL_MATTER_ENABLE_OTA_ENCRYPTION) && SL_MATTER_ENABLE_OTA_ENCRYPTION
5352
mUnalignmentNum = 0;
5453
#endif
5554
return CHIP_NO_ERROR;
@@ -89,7 +88,7 @@ void OTATlvProcessor::ClearInternal()
8988
mLength = 0;
9089
mProcessedLength = 0;
9190
mWasSelected = false;
92-
#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION
91+
#if defined(SL_MATTER_ENABLE_OTA_ENCRYPTION) && SL_MATTER_ENABLE_OTA_ENCRYPTION
9392
mIVOffset = 0;
9493
mLastBlock = false;
9594
#endif // SL_MATTER_ENABLE_OTA_ENCRYPTION
@@ -137,13 +136,18 @@ CHIP_ERROR OTADataAccumulator::Accumulate(ByteSpan & block)
137136
return CHIP_NO_ERROR;
138137
}
139138

140-
#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION
139+
#if defined(SL_MATTER_ENABLE_OTA_ENCRYPTION) && SL_MATTER_ENABLE_OTA_ENCRYPTION
141140
CHIP_ERROR OTATlvProcessor::vOtaProcessInternalEncryption(MutableByteSpan & block)
142141
{
142+
#if defined(SL_MBEDTLS_USE_TINYCRYPT)
143+
Provision::Manager::GetInstance().GetStorage().DecryptUsingOtaTlvEncryptionKey(block, mIVOffset);
144+
#else // MBEDTLS_USE_PSA_CRYPTO
143145
uint32_t keyId;
144-
SilabsConfig::ReadConfigValue(SilabsConfig::kOtaTlvEncryption_KeyId, keyId);
145-
chip::DeviceLayer::Silabs::OtaTlvEncryptionKey::OtaTlvEncryptionKey key(keyId);
146+
Provision::Manager::GetInstance().GetStorage().GetOtaTlvEncryptionKeyId(keyId);
147+
chip::DeviceLayer::Silabs::OtaTlvEncryptionKey key(keyId);
148+
146149
key.Decrypt(block, mIVOffset);
150+
#endif // SL_MBEDTLS_USE_TINYCRYPT
147151

148152
return CHIP_NO_ERROR;
149153
}
Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
/*
2+
*
3+
* Copyright (c) 2023-2025 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
119
#pragma once
220

321
#include <lib/core/CHIPError.h>
@@ -7,27 +25,32 @@
725
#include <stddef.h>
826
#include <stdint.h>
927

28+
#define AU8IV_INIT_VALUE 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x00, 0x00, 0x00
29+
1030
namespace chip {
1131
namespace DeviceLayer {
1232
namespace Silabs {
13-
namespace OtaTlvEncryptionKey {
14-
15-
static constexpr uint32_t kAES_KeyId_Default = (PSA_KEY_ID_USER_MIN + 2);
1633
class OtaTlvEncryptionKey
1734
{
1835
public:
36+
static constexpr uint32_t kAES_KeyId_Default = (PSA_KEY_ID_USER_MIN + 2);
37+
static constexpr size_t kOTAEncryptionKeyLength = 128u / 8u; // 128 bits KeyLength expressed in bytes.
38+
1939
OtaTlvEncryptionKey(uint32_t id = 0) { mId = (id > 0) ? id : kAES_KeyId_Default; }
2040
~OtaTlvEncryptionKey() = default;
2141

42+
#if defined(SL_MBEDTLS_USE_TINYCRYPT)
43+
static CHIP_ERROR Decrypt(const ByteSpan & key, MutableByteSpan & block, uint32_t & mIVOffset);
44+
#else // SL_MBEDTLS_USE_PSA_CRYPTO
2245
uint32_t GetId() { return mId; }
2346
CHIP_ERROR Import(const uint8_t * key, size_t key_len);
2447
CHIP_ERROR Decrypt(MutableByteSpan & block, uint32_t & mIVOffset);
48+
#endif // SL_MBEDTLS_USE_TINYCRYPT
2549

2650
protected:
2751
uint32_t mId = 0;
2852
};
2953

30-
} // namespace OtaTlvEncryptionKey
3154
} // namespace Silabs
3255
} // namespace DeviceLayer
3356
} // namespace chip

0 commit comments

Comments
 (0)