Skip to content

Commit

Permalink
riscv: telink: load DAC key/cert from flash zone.
Browse files Browse the repository at this point in the history
Signed-off-by: Zhenghuan Zhang <[email protected]>
  • Loading branch information
Zhenghuan Zhang committed Jan 9, 2025
1 parent 6132400 commit 9f99531
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 0 deletions.
5 changes: 5 additions & 0 deletions config/telink/chip-module/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,8 @@ config CHIP_USE_MARS_SENSOR
bool "Use Mars board sensor"
depends on SOC_SERIES_RISCV_TELINK_B9X && (BOARD_TLSR9518ADK80D || BOARD_TLSR9518ADK80D_RETENTION)
default n

config SECURE_PROGRAMMING
bool "Enable reading DAC and keys from the DAC partition"
depends on CHIP_FACTORY_DATA
default n
3 changes: 3 additions & 0 deletions config/telink/chip-module/Kconfig.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ config DYNAMIC_INTERRUPTS
config CHIP_OTA_REQUESTOR
default y

config SECURE_PROGRAMMING
default n

config MCUBOOT_SIGNATURE_KEY_FILE
default "bootloader/mcuboot/root-ec-p256.pem" if BOARD_TLSR9118BDK40D
depends on BOOTLOADER_MCUBOOT
Expand Down
6 changes: 6 additions & 0 deletions src/platform/telink/CHIPDevicePlatformConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@
#define CHIP_DEVICE_EXPOSE_CHIPID_VIA_BLE 0
#endif

#ifdef CONFIG_SECURE_PROGRAMMING
#define CHIP_DEVICE_SECURE_PROGRAMMING CONFIG_SECURE_PROGRAMMING
#else
#define CHIP_DEVICE_SECURE_PROGRAMMING 0
#endif

// ========== Platform-specific Configuration =========

// These are configuration options that are unique to Zephyr platforms.
Expand Down
70 changes: 70 additions & 0 deletions src/platform/telink/FactoryDataParser.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@

LOG_MODULE_DECLARE(app, CONFIG_MATTER_LOG_LEVEL);

#if CHIP_DEVICE_SECURE_PROGRAMMING
static uint8_t dac_key_decrypt[32] = { 0 };
#endif

static inline bool uint16_decode(zcbor_state_t * states, uint16_t * value)
{
uint32_t u32;
Expand Down Expand Up @@ -121,6 +125,7 @@ bool ParseFactoryData(uint8_t * buffer, uint16_t bufferSize, struct FactoryData
{
res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->rd_uid);
}
#if !CHIP_DEVICE_SECURE_PROGRAMMING
else if (strncmp("dac_cert", (const char *) currentString.value, currentString.len) == 0)
{
res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->dac_cert);
Expand All @@ -129,6 +134,7 @@ bool ParseFactoryData(uint8_t * buffer, uint16_t bufferSize, struct FactoryData
{
res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->dac_priv_key);
}
#endif
else if (strncmp("pai_cert", (const char *) currentString.value, currentString.len) == 0)
{
res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->pai_cert);
Expand Down Expand Up @@ -181,3 +187,67 @@ bool ParseFactoryData(uint8_t * buffer, uint16_t bufferSize, struct FactoryData

return res && zcbor_list_map_end_force_decode(states);
}

#if CHIP_DEVICE_SECURE_PROGRAMMING

#if defined(CONFIG_SOC_RISCV_TELINK_B92)
#include "aes.h"
#endif

#if defined(CONFIG_SOC_RISCV_TELINK_TL321X)
#include <ske.h>
#include <ske_portable.h>
#endif

bool LoadDACCertAndKey(uint8_t * buffer, struct FactoryData * factoryData)
{
size_t dac_priv_key_len;
uint8_t chip_id[16] = { 0 };
dac_priv_key_len = buffer[0];
dac_priv_key_len |= (uint16_t) buffer[1] << 8;
factoryData->dac_priv_key.len = dac_priv_key_len;
if (!factoryData->dac_priv_key.len)
{
return false;
}

#if defined(CONFIG_SOC_RISCV_TELINK_B92)
if (efuse_get_chip_id(chip_id))
#endif
#if defined(CONFIG_SOC_RISCV_TELINK_TL321X)
if (efuse_get_chip_id(chip_id) == DRV_API_SUCCESS)
#endif
{
#if defined(CONFIG_SOC_RISCV_TELINK_B92)
aes_decrypt(chip_id, buffer + 2, dac_key_decrypt);
aes_decrypt(chip_id, buffer + 18, dac_key_decrypt + 16);
#endif
#if defined(CONFIG_SOC_RISCV_TELINK_TL321X)
ske_dig_en();
uint32_t r = core_interrupt_disable();
ske_lp_crypto(SKE_ALG_AES_128, SKE_MODE_ECB, SKE_CRYPTO_DECRYPT, chip_id, 0, NULL, buffer + 2, dac_key_decrypt, 16);
ske_lp_crypto(SKE_ALG_AES_128, SKE_MODE_ECB, SKE_CRYPTO_DECRYPT, chip_id, 0, NULL, buffer + 18, dac_key_decrypt + 16,
16);
core_restore_interrupt(r);
#endif
factoryData->dac_priv_key.data = dac_key_decrypt;
}
else
{
LOG_ERR("Private key decryption failed.");
return false;
}

size_t dac_cert_len;
dac_cert_len = buffer[100];
dac_cert_len |= (uint16_t) buffer[101] << 8;
factoryData->dac_cert.len = dac_cert_len;
if (!factoryData->dac_cert.len)
{
return false;
}
factoryData->dac_cert.data = buffer + 102;

return true;
}
#endif
14 changes: 14 additions & 0 deletions src/platform/telink/FactoryDataParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <stddef.h>
#include <stdint.h>

#include "CHIPDevicePlatformConfig.h"

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -77,6 +79,18 @@ struct FactoryData
*/
bool ParseFactoryData(uint8_t * buffer, uint16_t bufferSize, struct FactoryData * factoryData);

#if CHIP_DEVICE_SECURE_PROGRAMMING
/**
* @brief Inject dac cert and dac private key into the factory data structure.
*
* @param[in] buffer Buffer containing dac data.
* @param[out] factoryData address of object to be filled with parsed factory data.
*
* @returns true on success, false otherwise.
*/
bool LoadDACCertAndKey(uint8_t * buffer, struct FactoryData * factoryData);
#endif

#ifdef __cplusplus
}
#endif
22 changes: 22 additions & 0 deletions src/platform/telink/FactoryDataProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ CHIP_ERROR FactoryDataProvider<FlashFactoryData>::Init()
{
uint8_t * factoryData = nullptr;
size_t factoryDataSize;
#if CHIP_DEVICE_SECURE_PROGRAMMING
uint8_t * dacData = nullptr;
size_t dacDataSize;
#endif

CHIP_ERROR error = mFlashFactoryData.ProtectFactoryDataPartitionAgainstWrite();

Expand All @@ -81,12 +85,30 @@ CHIP_ERROR FactoryDataProvider<FlashFactoryData>::Init()
return error;
}

#if CHIP_DEVICE_SECURE_PROGRAMMING
error = mFlashFactoryData.GetDACDataPartition(dacData, dacDataSize);

if (error != CHIP_NO_ERROR)
{
ChipLogError(DeviceLayer, "Failed to read DAC data partition");
return error;
}
#endif

if (!ParseFactoryData(factoryData + kFactoryDataOffset, factoryDataSize - kFactoryDataOffset, &mFactoryData))
{
ChipLogError(DeviceLayer, "Failed to parse factory data");
return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
}

#if CHIP_DEVICE_SECURE_PROGRAMMING
if (!LoadDACCertAndKey(dacData, &mFactoryData))
{
ChipLogError(DeviceLayer, "Failed to inject dac data");
return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
}
#endif

// Check if factory data version is correct
if (mFactoryData.version != CONFIG_CHIP_FACTORY_DATA_VERSION)
{
Expand Down
21 changes: 21 additions & 0 deletions src/platform/telink/FactoryDataProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ namespace chip {
namespace DeviceLayer {

__attribute__((section(".bss"))) static uint8_t mFactoryDataBuffer[FIXED_PARTITION_SIZE(factory_partition)];
#if CHIP_DEVICE_SECURE_PROGRAMMING
__attribute__((section(".bss"))) static uint8_t mDACDataBuffer[FIXED_PARTITION_SIZE(dac_keypair_partition)];
#endif

struct InternalFlashFactoryData
{
Expand Down Expand Up @@ -62,6 +65,24 @@ struct ExternalFlashFactoryData
return CHIP_NO_ERROR;
}

#if CHIP_DEVICE_SECURE_PROGRAMMING
CHIP_ERROR GetDACDataPartition(uint8_t *& data, size_t & dataSize)
{
int ret = flash_read(mFlashDevice, FIXED_PARTITION_OFFSET(dac_keypair_partition), mDACDataBuffer,
FIXED_PARTITION_SIZE(dac_keypair_partition));

if (ret != 0)
{
return CHIP_ERROR_READ_FAILED;
}

data = mDACDataBuffer;
dataSize = FIXED_PARTITION_SIZE(dac_keypair_partition);

return CHIP_NO_ERROR;
}
#endif

CHIP_ERROR ProtectFactoryDataPartitionAgainstWrite() { return CHIP_ERROR_NOT_IMPLEMENTED; }

const struct device * mFlashDevice = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller));
Expand Down

0 comments on commit 9f99531

Please sign in to comment.