From 238994490b26b4eacf4ec92dbd6aca037ca5589b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arkadiusz=20Ba=C5=82ys?= Date: Thu, 14 Jul 2022 14:12:07 +0200 Subject: [PATCH] [nrfconnect] Added EnableKey parameter to factory data (#20557) Certification tests may make use of the TestEventTrigger command of GeneralDiagnostics cluster to trigger certain actions. The command uses authentication with the EnableKey parameter, that should be placed in the factory data set. - Added EnableKey to the JSON Schema - Added EnableKey to the factory data - Added EnableKey to the Cmake script - Added GetEnableKey to the FactoryDataProvider and FactoryDataParser --- config/nrfconnect/chip-module/Kconfig | 11 ++++++ .../chip-module/generate_factory_data.cmake | 5 +++ .../nrfconnect/main/AppTask.cpp | 18 +++++++--- .../nrfconnect/main/AppTask.cpp | 23 ++++++++++-- .../lighting-app/nrfconnect/main/AppTask.cpp | 35 ++++++++++++------- examples/lock-app/nrfconnect/main/AppTask.cpp | 18 +++++++--- examples/pump-app/nrfconnect/main/AppTask.cpp | 18 +++++++--- .../nrfconnect/main/AppTask.cpp | 18 +++++++--- .../window-app/nrfconnect/main/AppTask.cpp | 19 +++++++--- .../generate_nrfconnect_chip_factory_data.py | 9 +++-- .../nrfconnect/nrfconnect_factory_data.schema | 16 +++++++++ src/platform/nrfconnect/FactoryDataParser.c | 4 +++ src/platform/nrfconnect/FactoryDataParser.h | 1 + .../nrfconnect/FactoryDataProvider.cpp | 13 +++++++ src/platform/nrfconnect/FactoryDataProvider.h | 3 ++ 15 files changed, 169 insertions(+), 42 deletions(-) diff --git a/config/nrfconnect/chip-module/Kconfig b/config/nrfconnect/chip-module/Kconfig index 6550dca841b51e..962d7ca3322e27 100644 --- a/config/nrfconnect/chip-module/Kconfig +++ b/config/nrfconnect/chip-module/Kconfig @@ -254,6 +254,16 @@ config CHIP_DEVICE_ROTATING_DEVICE_UID A device rotating id unique id which will be generated if this config is not set in prj.conf file. +config CHIP_DEVICE_ENABLE_KEY + string "Enable Key for triggering test actions on device" + default "00112233445566778899AABBCCDDEEFF" + help + The Enable Key is a 128-bit value that triggers test action + while invoking the TestEventTrigger Command. + Pattern: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + This value is used during Certification Tests, + and should not be present on production devices. + config CHIP_CERTIFICATION_DECLARATION_STORAGE bool "Enable storing Certification Declaration" depends on CHIP_FACTORY_DATA @@ -274,4 +284,5 @@ config CHIP_CERTIFiCATION_DECLARATION_OTA_IMAGE_ID endif + endif diff --git a/config/nrfconnect/chip-module/generate_factory_data.cmake b/config/nrfconnect/chip-module/generate_factory_data.cmake index 02b6e6ce4c0ac0..71ad5d38c445f7 100644 --- a/config/nrfconnect/chip-module/generate_factory_data.cmake +++ b/config/nrfconnect/chip-module/generate_factory_data.cmake @@ -98,6 +98,11 @@ else() string(APPEND script_args "--spake2_verifier \"${CONFIG_CHIP_DEVICE_SPAKE2_TEST_VERIFIER}\"\n") endif() +if(CONFIG_CHIP_DEVICE_ENABLE_KEY) +# Add optional EnableKey that triggers user-specific action. +string(APPEND script_args "--enable_key \"${CONFIG_CHIP_DEVICE_ENABLE_KEY}\"\n") +endif() + # Set output JSON file and path to SCHEMA file to validate generated factory data string(APPEND script_args "-o \"${output_path}/${factory_data_target}.json\"\n") string(APPEND script_args "-s \"${schema_path}\"\n") diff --git a/examples/all-clusters-app/nrfconnect/main/AppTask.cpp b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp index 43b6043b73d256..be4a44dc8a2985 100644 --- a/examples/all-clusters-app/nrfconnect/main/AppTask.cpp +++ b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp @@ -59,10 +59,10 @@ K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), APP_EVENT_QUEUE_SIZE, alignof(Ap namespace { -// NOTE! This key is for test/certification only and should not be available in production devices. -// Ideally, it should be a part of the factory data set. -constexpr uint8_t kTestEventTriggerEnableKey[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; +// NOTE! This key is for test/certification only and should not be available in production devices! +// If CONFIG_CHIP_FACTORY_DATA is enabled, this value is read from the factory data. +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; LEDWidget sStatusLED; UnusedLedsWrapper<3> sUnusedLeds{ { DK_LED2, DK_LED3, DK_LED4 } }; @@ -191,12 +191,20 @@ CHIP_ERROR AppTask::Init() SetDeviceInstanceInfoProvider(&mFactoryDataProvider); SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); SetCommissionableDataProvider(&mFactoryDataProvider); + // Read EnableKey from the factory data. + MutableByteSpan enableKey(sTestEventTriggerEnableKey); + err = mFactoryDataProvider.GetEnableKey(enableKey); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger"); + memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); + } #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); #endif static CommonCaseDeviceServerInitParams initParams; - static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(kTestEventTriggerEnableKey) }; + static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; (void) initParams.InitializeStaticResourcesBeforeServerInit(); initParams.testEventTriggerDelegate = &testEventTriggerDelegate; ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); diff --git a/examples/light-switch-app/nrfconnect/main/AppTask.cpp b/examples/light-switch-app/nrfconnect/main/AppTask.cpp index b9c85caf6ff2b8..8ca5fac1429403 100644 --- a/examples/light-switch-app/nrfconnect/main/AppTask.cpp +++ b/examples/light-switch-app/nrfconnect/main/AppTask.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -65,6 +66,11 @@ K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppE Identify sIdentify = { kLightEndpointId, AppTask::IdentifyStartHandler, AppTask::IdentifyStopHandler, EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED }; +// NOTE! This key is for test/certification only and should not be available in production devices! +// If CONFIG_CHIP_FACTORY_DATA is enabled, this value is read from the factory data. +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + LEDWidget sStatusLED; LEDWidget sBleLED; LEDWidget sIdentifyLED; @@ -165,12 +171,23 @@ CHIP_ERROR AppTask::Init() SetDeviceInstanceInfoProvider(&mFactoryDataProvider); SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); SetCommissionableDataProvider(&mFactoryDataProvider); + // Read EnableKey from the factory data. + MutableByteSpan enableKey(sTestEventTriggerEnableKey); + err = mFactoryDataProvider.GetEnableKey(enableKey); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger"); + memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); + } #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); #endif - static chip::CommonCaseDeviceServerInitParams initParams; - ReturnErrorOnFailure(initParams.InitializeStaticResourcesBeforeServerInit()); - ReturnErrorOnFailure(Server::GetInstance().Init(initParams)); + + static CommonCaseDeviceServerInitParams initParams; + static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + initParams.testEventTriggerDelegate = &testEventTriggerDelegate; + ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); diff --git a/examples/lighting-app/nrfconnect/main/AppTask.cpp b/examples/lighting-app/nrfconnect/main/AppTask.cpp index 0b7436a70bdb2c..a2cb35de24fadb 100644 --- a/examples/lighting-app/nrfconnect/main/AppTask.cpp +++ b/examples/lighting-app/nrfconnect/main/AppTask.cpp @@ -58,17 +58,20 @@ using namespace ::chip::DeviceLayer; namespace { -constexpr int kFactoryResetTriggerTimeout = 3000; -constexpr int kFactoryResetCancelWindowTimeout = 3000; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; -constexpr EndpointId kLightEndpointId = 1; -constexpr uint32_t kIdentifyBlinkRateMs = 500; -constexpr uint8_t kDefaultMinLevel = 0; -constexpr uint8_t kDefaultMaxLevel = 254; -constexpr uint8_t kTestEventTriggerEnableKey[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; +constexpr int kFactoryResetTriggerTimeout = 3000; +constexpr int kFactoryResetCancelWindowTimeout = 3000; +constexpr int kAppEventQueueSize = 10; +constexpr uint8_t kButtonPushEvent = 1; +constexpr uint8_t kButtonReleaseEvent = 0; +constexpr EndpointId kLightEndpointId = 1; +constexpr uint32_t kIdentifyBlinkRateMs = 500; +constexpr uint8_t kDefaultMinLevel = 0; +constexpr uint8_t kDefaultMaxLevel = 254; + +// NOTE! This key is for test/certification only and should not be available in production devices! +// If CONFIG_CHIP_FACTORY_DATA is enabled, this value is read from the factory data. +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); k_timer sFunctionTimer; @@ -173,12 +176,20 @@ CHIP_ERROR AppTask::Init() SetDeviceInstanceInfoProvider(&mFactoryDataProvider); SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); SetCommissionableDataProvider(&mFactoryDataProvider); + // Read EnableKey from the factory data. + MutableByteSpan enableKey(sTestEventTriggerEnableKey); + err = mFactoryDataProvider.GetEnableKey(enableKey); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger"); + memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); + } #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); #endif static CommonCaseDeviceServerInitParams initParams; - static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(kTestEventTriggerEnableKey) }; + static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; (void) initParams.InitializeStaticResourcesBeforeServerInit(); initParams.testEventTriggerDelegate = &testEventTriggerDelegate; ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); diff --git a/examples/lock-app/nrfconnect/main/AppTask.cpp b/examples/lock-app/nrfconnect/main/AppTask.cpp index 19e8c3c7873ce5..ff6cb1f6a7850d 100644 --- a/examples/lock-app/nrfconnect/main/AppTask.cpp +++ b/examples/lock-app/nrfconnect/main/AppTask.cpp @@ -61,10 +61,10 @@ using namespace ::chip::DeviceLayer; namespace { constexpr EndpointId kLockEndpointId = 1; -// NOTE! This key is for test/certification only and should not be available in production devices. -// Ideally, it should be a part of the factory data set. -constexpr uint8_t kTestEventTriggerEnableKey[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; +// NOTE! This key is for test/certification only and should not be available in production devices! +// If CONFIG_CHIP_FACTORY_DATA is enabled, this value is read from the factory data. +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; LOG_MODULE_DECLARE(app, CONFIG_MATTER_LOG_LEVEL); K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), APP_EVENT_QUEUE_SIZE, alignof(AppEvent)); @@ -161,12 +161,20 @@ CHIP_ERROR AppTask::Init() SetDeviceInstanceInfoProvider(&mFactoryDataProvider); SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); SetCommissionableDataProvider(&mFactoryDataProvider); + // Read EnableKey from the factory data. + MutableByteSpan enableKey(sTestEventTriggerEnableKey); + err = mFactoryDataProvider.GetEnableKey(enableKey); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger"); + memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); + } #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); #endif static CommonCaseDeviceServerInitParams initParams; - static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(kTestEventTriggerEnableKey) }; + static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; (void) initParams.InitializeStaticResourcesBeforeServerInit(); initParams.testEventTriggerDelegate = &testEventTriggerDelegate; ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); diff --git a/examples/pump-app/nrfconnect/main/AppTask.cpp b/examples/pump-app/nrfconnect/main/AppTask.cpp index 35de7711981720..887c0a16931188 100644 --- a/examples/pump-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-app/nrfconnect/main/AppTask.cpp @@ -62,10 +62,10 @@ using namespace ::chip::DeviceLayer; namespace { -// NOTE! This key is for test/certification only and should not be available in production devices. -// Ideally, it should be a part of the factory data set. -constexpr uint8_t kTestEventTriggerEnableKey[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; +// NOTE! This key is for test/certification only and should not be available in production devices! +// If CONFIG_CHIP_FACTORY_DATA is enabled, this value is read from the factory data. +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; LOG_MODULE_DECLARE(app, CONFIG_MATTER_LOG_LEVEL); K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), APP_EVENT_QUEUE_SIZE, alignof(AppEvent)); @@ -159,12 +159,20 @@ CHIP_ERROR AppTask::Init() SetDeviceInstanceInfoProvider(&mFactoryDataProvider); SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); SetCommissionableDataProvider(&mFactoryDataProvider); + // Read EnableKey from the factory data. + MutableByteSpan enableKey(sTestEventTriggerEnableKey); + err = mFactoryDataProvider.GetEnableKey(enableKey); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger"); + memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); + } #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); #endif static CommonCaseDeviceServerInitParams initParams; - static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(kTestEventTriggerEnableKey) }; + static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; (void) initParams.InitializeStaticResourcesBeforeServerInit(); initParams.testEventTriggerDelegate = &testEventTriggerDelegate; ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); diff --git a/examples/pump-controller-app/nrfconnect/main/AppTask.cpp b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp index 79b0a43adf42df..898ffcc0892a1b 100644 --- a/examples/pump-controller-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp @@ -59,10 +59,10 @@ using namespace ::chip::DeviceLayer; namespace { -// NOTE! This key is for test/certification only and should not be available in production devices. -// Ideally, it should be a part of the factory data set. -constexpr uint8_t kTestEventTriggerEnableKey[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; +// NOTE! This key is for test/certification only and should not be available in production devices! +// If CONFIG_CHIP_FACTORY_DATA is enabled, this value is read from the factory data. +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; LOG_MODULE_DECLARE(app, CONFIG_MATTER_LOG_LEVEL); K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), APP_EVENT_QUEUE_SIZE, alignof(AppEvent)); @@ -156,12 +156,20 @@ CHIP_ERROR AppTask::Init() SetDeviceInstanceInfoProvider(&mFactoryDataProvider); SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); SetCommissionableDataProvider(&mFactoryDataProvider); + // Read EnableKey from the factory data. + MutableByteSpan enableKey(sTestEventTriggerEnableKey); + err = mFactoryDataProvider.GetEnableKey(enableKey); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger"); + memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); + } #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); #endif static CommonCaseDeviceServerInitParams initParams; - static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(kTestEventTriggerEnableKey) }; + static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; (void) initParams.InitializeStaticResourcesBeforeServerInit(); initParams.testEventTriggerDelegate = &testEventTriggerDelegate; ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); diff --git a/examples/window-app/nrfconnect/main/AppTask.cpp b/examples/window-app/nrfconnect/main/AppTask.cpp index 0c80759cb4f25f..330fb4862e6529 100644 --- a/examples/window-app/nrfconnect/main/AppTask.cpp +++ b/examples/window-app/nrfconnect/main/AppTask.cpp @@ -55,10 +55,10 @@ K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), APP_EVENT_QUEUE_SIZE, alignof(Ap namespace { -// NOTE! This key is for test/certification only and should not be available in production devices. -// Ideally, it should be a part of the factory data set. -constexpr uint8_t kTestEventTriggerEnableKey[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; +// NOTE! This key is for test/certification only and should not be available in production devices! +// If CONFIG_CHIP_FACTORY_DATA is enabled, this value is read from the factory data. +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; LEDWidget sStatusLED; UnusedLedsWrapper<1> sUnusedLeds{ { DK_LED4 } }; @@ -159,12 +159,21 @@ CHIP_ERROR AppTask::Init() SetDeviceInstanceInfoProvider(&mFactoryDataProvider); SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); SetCommissionableDataProvider(&mFactoryDataProvider); + // Read EnableKey from the factory data. + MutableByteSpan enableKey(sTestEventTriggerEnableKey); + err = mFactoryDataProvider.GetEnableKey(enableKey); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger"); + memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); + } #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); + #endif static CommonCaseDeviceServerInitParams initParams; - static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(kTestEventTriggerEnableKey) }; + static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; (void) initParams.InitializeStaticResourcesBeforeServerInit(); initParams.testEventTriggerDelegate = &testEventTriggerDelegate; ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); diff --git a/scripts/tools/nrfconnect/generate_nrfconnect_chip_factory_data.py b/scripts/tools/nrfconnect/generate_nrfconnect_chip_factory_data.py index 62e9fa303e051b..04256488340729 100644 --- a/scripts/tools/nrfconnect/generate_nrfconnect_chip_factory_data.py +++ b/scripts/tools/nrfconnect/generate_nrfconnect_chip_factory_data.py @@ -144,7 +144,8 @@ def generate_json(self): # rotating device ID unique ID was not provided, so do not store it in factory data. rd_uid = None else: - rd_uid = self._args.rd_uid + rd_uid = HEX_PREFIX + self._args.rd_uid + if not self._args.spake2_verifier: spake_2_verifier = base64.b64decode(self._generate_spake2_verifier()) else: @@ -186,6 +187,7 @@ def generate_json(self): self._add_entry("discriminator", self._args.discriminator) if rd_uid: self._add_entry("rd_uid", rd_uid) + self._add_entry("enable_key", HEX_PREFIX + self._args.enable_key) # add user-specific data self._add_entry("user", self._args.user) @@ -320,13 +322,16 @@ def allow_any_int(i): return int(i, 0) optional_arguments.add_argument("--pai_cert", type=str, help="[.der] Provide the path to .der file containing PAI certificate.") optional_arguments.add_argument("--rd_uid", type=str, - help="[hex string] Provide the rotating device unique ID. If this argument is not provided a new rotating device id unique id will be generated.") + help="[hex string] [128-bit hex-encoded] Provide the rotating device unique ID. If this argument is not provided a new rotating device id unique id will be generated.") optional_arguments.add_argument("--passcode", type=allow_any_int, help="[int | hex] Default PASE session passcode. (This is mandatory to generate Spake2 Verifier).") optional_arguments.add_argument("--spake2p_path", type=str, help="[string] Provide a path to spake2p. By default You can find spake2p in connectedhomeip/src/tools/spake2p directory and build it there.") optional_arguments.add_argument("--spake2_verifier", type=str, help="[ascii string] Provide Spake2 Verifier without generating it.") + optional_arguments.add_argument("--enable_key", type=str, + help="[hex string] [128-bit hex-encoded] The Enable Key is a 128-bit value that triggers manufacturer-specific action while invoking the TestEventTrigger Command." + "This value is used during Certification Tests, and should not be present on production devices.") optional_arguments.add_argument("--user", type=str, help="[string] Provide additional user-specific keys in Json format: {'name_1': 'value_1', 'name_2': 'value_2', ... 'name_n', 'value_n'}.") args = parser.parse_args() diff --git a/scripts/tools/nrfconnect/nrfconnect_factory_data.schema b/scripts/tools/nrfconnect/nrfconnect_factory_data.schema index 621e20fc6c4074..fa2e9a2679d6cc 100644 --- a/scripts/tools/nrfconnect/nrfconnect_factory_data.schema +++ b/scripts/tools/nrfconnect/nrfconnect_factory_data.schema @@ -75,23 +75,30 @@ "rd_uid": { "description": "A randomly-generated 128-bit or longer octet string. Length has been expanded with 'hex:' prefix", "type": "string", + "pattern:": "^hex:{1}", "minLength": 20, + "minLength": 5, "maxLength": 36 }, "dac_cert": { "description": "DAC certificate in hex-string format", "type": "string", + "pattern:": "^hex:{1}([0-9A-Fa-f]){2,}", + "minLength": 5, "maxLength": 1204 }, "dac_key": { "description": "DAC Private Key in hex-string format", "type": "string", + "pattern:": "^hex:{1}([0-9A-Fa-f]){2,}", "minLength": 68, "maxLength": 68 }, "pai_cert": { "description": "PAI certificate in hex-string format", "type": "string", + "pattern:": "^hex:{1}([0-9A-Fa-f]){2,}", + "minLength": 5, "maxLength": 1204 }, "passcode": { @@ -109,12 +116,14 @@ "spake2_salt": { "description": "A key-derivation function for the Symmetric Password-Authenticated Key Exchange.", "type": "string", + "pattern:": "^hex:{1}([0-9A-Fa-f]){2,}", "minLength": 36, "maxLength": 68 }, "spake2_verifier": { "description": "A verifier for the Symmetric Password-Authenticated Key Exchange", "type": "string", + "pattern:": "^hex:{1}([0-9A-Fa-f]){2,}", "minLength": 97 }, "discriminator": { @@ -123,6 +132,13 @@ "minimum": 0, "maximum": 4095 }, + "enable_key": { + "description": "The Enable Key is a 128-bit value that triggers manufacturer-specific action while invoking the TestEventTrigger Command", + "type": "string", + "pattern": "^hex:{1}([0-9A-Fa-f]){32}", + "minLength": 36, + "maxLength": 36 + }, "user": { "description": "A user-specific additional data which should be added to factory data. This should be a Json format.", "type": "object" diff --git a/src/platform/nrfconnect/FactoryDataParser.c b/src/platform/nrfconnect/FactoryDataParser.c index c297a8d29008b7..3036fb57f58363 100644 --- a/src/platform/nrfconnect/FactoryDataParser.c +++ b/src/platform/nrfconnect/FactoryDataParser.c @@ -149,6 +149,10 @@ bool ParseFactoryData(uint8_t * buffer, uint16_t bufferSize, struct FactoryData { res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->product_name); } + else if (strncmp("enable_key", (const char *) currentString.value, currentString.len) == 0) + { + res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->enable_key); + } else if (strncmp("user", (const char *) currentString.value, currentString.len) == 0) { res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->user); diff --git a/src/platform/nrfconnect/FactoryDataParser.h b/src/platform/nrfconnect/FactoryDataParser.h index 53b78a816ae142..156010ab66c527 100644 --- a/src/platform/nrfconnect/FactoryDataParser.h +++ b/src/platform/nrfconnect/FactoryDataParser.h @@ -53,6 +53,7 @@ struct FactoryData struct FactoryDataString spake2_verifier; uint16_t discriminator; uint32_t passcode; + struct FactoryDataString enable_key; struct FactoryDataString user; bool vendorIdPresent; diff --git a/src/platform/nrfconnect/FactoryDataProvider.cpp b/src/platform/nrfconnect/FactoryDataProvider.cpp index aba9d4543028ec..967226cfc107a4 100644 --- a/src/platform/nrfconnect/FactoryDataProvider.cpp +++ b/src/platform/nrfconnect/FactoryDataProvider.cpp @@ -320,6 +320,19 @@ CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(Mu return CHIP_NO_ERROR; } +template +CHIP_ERROR FactoryDataProvider::GetEnableKey(MutableByteSpan & enableKey) +{ + ReturnErrorCodeIf(!mFactoryData.enable_key.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + ReturnErrorCodeIf(enableKey.size() < mFactoryData.enable_key.len, CHIP_ERROR_BUFFER_TOO_SMALL); + + memcpy(enableKey.data(), mFactoryData.enable_key.data, mFactoryData.enable_key.len); + + enableKey.reduce_size(mFactoryData.enable_key.len); + + return CHIP_NO_ERROR; +} + // Fully instantiate the template class in whatever compilation unit includes this file. template class FactoryDataProvider; template class FactoryDataProvider; diff --git a/src/platform/nrfconnect/FactoryDataProvider.h b/src/platform/nrfconnect/FactoryDataProvider.h index 202058aa99e7e3..0818c3f506694d 100644 --- a/src/platform/nrfconnect/FactoryDataProvider.h +++ b/src/platform/nrfconnect/FactoryDataProvider.h @@ -105,6 +105,9 @@ class FactoryDataProvider : public chip::Credentials::DeviceAttestationCredentia CHIP_ERROR GetHardwareVersionString(char * buf, size_t bufSize) override; CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) override; + // ===== Members functions that are platform-specific + CHIP_ERROR GetEnableKey(MutableByteSpan & enableKey); + private: static constexpr uint16_t kFactoryDataPartitionSize = PM_FACTORY_DATA_SIZE; static constexpr uint32_t kFactoryDataPartitionAddress = PM_FACTORY_DATA_ADDRESS;