diff --git a/docs/platforms/nxp/nxp_manufacturing_flow.md b/docs/platforms/nxp/nxp_manufacturing_flow.md index 28618b276a5e01..0f30d0612b1f81 100644 --- a/docs/platforms/nxp/nxp_manufacturing_flow.md +++ b/docs/platforms/nxp/nxp_manufacturing_flow.md @@ -103,8 +103,6 @@ Here is the interpretation of the **required** parameters: --hw_version -> Hardware Version as number --hw_version_str -> Hardware Version as string --cert_declaration -> path to the Certification Declaration (der format) location ---dac_cert -> path to the DAC (der format) location ---dac_key -> path to the DAC key (der format) location --pai_cert -> path to the PAI (der format) location --spake2p_path -> path to the spake2p tool --out -> name of the binary that will be used for storing all the generated data @@ -113,6 +111,11 @@ Here is the interpretation of the **required** parameters: Here is the interpretation of the **optional** parameters: ```shell +--dac_cert -> path to the DAC certificate (der format) location +--dac_key -> path to the DAC key (der format) location +--EL2GO_bin -> path to the EdgeLock 2Go binary (bin format) location +--EL2GO_DAC_KEY_ID -> DAC key ID configured into EdgeLock 2Go as hex value +--EL2GO_DAC_CERT_ID -> DAC certificate ID configured into EdgeLock 2Go as hex value --dac_key_password -> Password to decode DAC key --dac_key_use_sss_blob -> Used when --dac_key contains a path to an encrypted blob, instead of the actual DAC private key. The blob metadata size is 24, so the total length @@ -182,17 +185,56 @@ Also, demo **DAC**, **PAI** and **PAA** certificates needed in case ## 6. Increased security for DAC private key -### 6.1 SSS-based platforms +### 6.1 SSS-based with EdgeLock2go support + +EdgeLock2go services could be used to securely provisioned DAC key/cert during +manufacturing. + +Prior to the generation of the factory data binary. `EL2GO` data needs to be +generated following `EL2GO` process. + +For the factory data generation following option need to be added: + +`--EL2GO_bin ~/secure_objects.bin` containing `EL2GO` information including +encrypted DAC private key and certificate. `--EL2GO_DAC_KEY_ID 1234` containing +corresponding to the ID of the DAC key chosen during `EL2GO` key generation. +`--EL2GO_DAC_CERT_ID 4321` containing corresponding to the ID of the DAC +certification chosen during `EL2GO` key generation. + +Reference factory data generation command: + +```shell +python3 ./scripts/tools/nxp/factory_data_generator/generate.py -i 10000 -s UXKLzwHdN3DZZLBaL2iVGhQi/OoQwIwJRQV4rpEalbA= -p ${passcode} -d ${discriminator} --vid "0x$VID" --pid "0x$PID" --vendor_name "NXP Semiconductors" --product_name "Thermostat" --serial_num "12345678" --date "$DATE" --hw_version 1 --hw_version_str "1.0" --cert_declaration $FACTORY_DATA_DEST/Chip-Test-CD-$VID-$PID.der --EL2GO_bin ~/secure_objects.bin --EL2GO_DAC_KEY_ID 1234 --EL2GO_DAC_CERT_ID 4321 --pai_cert $FACTORY_DATA_DEST/Chip-PAI-NXP-$VID-$PID-Cert.der --spake2p_path ./out/spake2p --unique_id "00112233445566778899aabbccddeeff" --out $FACTORY_DATA_DEST/factory_data.bin +``` + +Supported platforms: + +- `rw61x` + +In addition to the GN flag `nxp_use_factory_data=true`, a Matter application +needs to be built with `nxp_enable_secure_EL2GO_factory_data=true` to allow +loading of EdgeLock2go data to the secure element. + +In this mode EdgeLock2go keys will always remain encrypted and only usable by +the `SSS`. In this case, all operations that requires DAC private access will be +transferred to the `SSS`. + +### 6.2 SSS-based without EdgeLock2go support for DAC private key secure storage Supported platforms: - `k32w1` - `mcxw71` +- `rw61x` For platforms that have a secure subsystem (`SSS`), the DAC private key can be converted to an encrypted blob. This blob will overwrite the DAC private key in -factory data and will be imported in the `SSS` at initialization, by the factory -data provider instance. +factory data and will be imported in the `SSS` by the factory data provider +instance. + +In this architecture, outside of the manufacturing flow, the DAC private will +always remain usable only by the `SSS`. In this case, all operations that +requires DAC private access will be transferred to the `SSS`. The application will check at initialization whether the DAC private key has been converted or not and convert it if needed. However, the conversion process @@ -226,64 +268,5 @@ Please note that `--dac_key` now points to a binary file that contains the encrypted blob. The user can use the DAC private in plain text instead of using the `SSS` by -adding the following gn argument `chip_use_plain_dac_key=true`. - -### 6.2 RW61X - -Supported platforms: - -- RW61X - -there are three implementations for factory data protection - -- whole factory data protection with AES encryption ( - nxp_use_factory_data=true nxp_enable_secure_whole_factory_data=true ) - `examples/platform/nxp/rt/rw61x/factory_data/source/AppFactoryDataExample.cpp`\ - `src/platform/nxp/rt/rw61x/FactoryDataProviderEncImpl.cpp` - -- only dac private key protection ( nxp_use_factory_data=true - nxp_enable_secure_dac_private_key_storage=true ) - `examples/platform/nxp/rt/rw61x/factory_data/source/AppFactoryDataExample.cpp` - \ - `src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.cpp` - -- whole factory data protection with hard-coded AES key ( - nxp_use_factory_data=true ) - `examples/platform/nxp/common/factory_data/source/AppFactoryDataDefaultImpl.cpp` - \ - `src/platform/nxp/common/factory_data/FactoryDataProviderFwkImpl.cpp` - -for the first one, the whole factory data is encrypted by an AES-256 key, the -AES key can be passed through serial link when in factory production mode, and -will be provisioned into Edge Lock, and the returned AES Key blob (wrapped key) -can be stored in the end of factory data region in TLV format. for the -decryption process, the blob is retrieved and provisioned into Edge Lock and the -whole factory data can be decrypted using the returned key index in Edge Lock. -Compared with only dac private key protection solution, this solution can avoid -tampering with the original factory data. - -the factory data should be encrypted by an AES-256 key using "--aes256_key" -option in "generate.py" script file. - -it will check whether there is AES key blob in factory data region when in each -initialization, if not, the default AES key is converted and the result is -stored into flash, it run only once. - -for the second one, it only protect the dac private key inside the factory data, -the dac private key is retrieved and provisioned into Edge Lock, the returned -key blob replace the previous dac private key, and also update the overall size -and hash, and re-write the factory data. when device is doing matter -commissioning, the blob is retrieved and provisioned into Edge Lock and the -signing can be done using the returned key index in Edge Lock. - -the factory data should be plain text for the first programming. it will check -whether there is dac private key blob (base on the size of blob, should be 48) -in factory data when in each initialization, if not, the dac private key is -converted and the result is stored into flash, it run only once. - -for the third one, it is a little similar to the first one, the whole factory -data is encrypted by an AES key, but there are two differences: - -- the AES key is hard-coded and not provisioned into Edge Lock -- the factory data should be encrypted by AES-128 key using "--aes128_key" - option in "generate.py" script file. +adding the following gn argument `chip_use_plain_dac_key=true` (not supported on +rw61x). diff --git a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn index 73f21538380b0e..5b73da4bc92080 100644 --- a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn +++ b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn @@ -1,5 +1,5 @@ # Copyright (c) 2021 Project CHIP Authors -# Copyright 2023 NXP +# Copyright 2023-2024 NXP # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -55,15 +55,6 @@ app_common_folder = "all-clusters-app/all-clusters-common" rt_sdk("sdk") { defines = [] - # To be moved, temporary mbedtls config fix to build app with factory data - if (nxp_enable_secure_dac_private_key_storage || - nxp_enable_secure_whole_factory_data) { - defines += [ - "MBEDTLS_NIST_KW_C", - "MBEDTLS_PSA_CRYPTO_CLIENT", - ] - } - cflags = [] public_deps = [] public_configs = [] @@ -141,8 +132,8 @@ rt_executable("all_cluster_app") { "../../common/main/main.cpp", ] - if (nxp_enable_secure_dac_private_key_storage || - nxp_enable_secure_whole_factory_data) { + if (nxp_enable_secure_whole_factory_data || + nxp_enable_secure_EL2GO_factory_data) { sources += [ "${chip_root}/examples/platform/nxp/${nxp_platform}/factory_data/source/AppFactoryDataExample.cpp" ] if (nxp_enable_secure_whole_factory_data) { defines += [ "ENABLE_SECURE_WHOLE_FACTORY_DATA" ] diff --git a/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn b/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn index 936f1de4a7d262..063cf49b81a2b5 100644 --- a/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn +++ b/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn @@ -56,15 +56,6 @@ app_common_folder = "laundry-washer-app/nxp/zap" rt_sdk("sdk") { defines = [] - # To be moved, temporary mbedtls config fix to build app with factory data - if (nxp_enable_secure_dac_private_key_storage || - nxp_enable_secure_whole_factory_data) { - defines += [ - "MBEDTLS_NIST_KW_C", - "MBEDTLS_PSA_CRYPTO_CLIENT", - ] - } - cflags = [] public_deps = [] public_configs = [] @@ -142,8 +133,8 @@ rt_executable("laundry-washer") { "../../common/main/main.cpp", ] - if (nxp_enable_secure_dac_private_key_storage || - nxp_enable_secure_whole_factory_data) { + if (nxp_enable_secure_whole_factory_data || + nxp_enable_secure_EL2GO_factory_data) { sources += [ "${chip_root}/examples/platform/nxp/${nxp_platform}/factory_data/source/AppFactoryDataExample.cpp" ] if (nxp_enable_secure_whole_factory_data) { defines += [ "ENABLE_SECURE_WHOLE_FACTORY_DATA" ] diff --git a/examples/thermostat/nxp/rt/rw61x/BUILD.gn b/examples/thermostat/nxp/rt/rw61x/BUILD.gn index ec0a6d4f0ec379..07a58e947756c6 100644 --- a/examples/thermostat/nxp/rt/rw61x/BUILD.gn +++ b/examples/thermostat/nxp/rt/rw61x/BUILD.gn @@ -1,5 +1,5 @@ # Copyright (c) 2021 Project CHIP Authors -# Copyright 2023 NXP +# Copyright 2023-2024 NXP # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -58,15 +58,6 @@ app_common_folder = "thermostat/nxp/zap" rt_sdk("sdk") { defines = [] - # To be moved, temporary mbedtls config fix to build app with factory data - if (nxp_enable_secure_dac_private_key_storage || - nxp_enable_secure_whole_factory_data) { - defines += [ - "MBEDTLS_NIST_KW_C", - "MBEDTLS_PSA_CRYPTO_CLIENT", - ] - } - cflags = [] public_deps = [] public_configs = [] @@ -165,8 +156,8 @@ rt_executable("thermostat") { ] } - if (nxp_enable_secure_dac_private_key_storage || - nxp_enable_secure_whole_factory_data) { + if (nxp_enable_secure_whole_factory_data || + nxp_enable_secure_EL2GO_factory_data) { sources += [ "${chip_root}/examples/platform/nxp/${nxp_platform}/factory_data/source/AppFactoryDataExample.cpp" ] if (nxp_enable_secure_whole_factory_data) { defines += [ "ENABLE_SECURE_WHOLE_FACTORY_DATA" ] diff --git a/scripts/tools/nxp/factory_data_generator/custom.py b/scripts/tools/nxp/factory_data_generator/custom.py index 179f990c3052bc..87d3b7dca3c4b7 100644 --- a/scripts/tools/nxp/factory_data_generator/custom.py +++ b/scripts/tools/nxp/factory_data_generator/custom.py @@ -337,3 +337,30 @@ def encode(self): def max_length(self): return 64 + + +class El2GoObject(FileArgument): + + def __init__(self, arg): + super().__init__(arg) + + def key(self): + return 24 + + +class El2GoDacKeyID(IntArgument): + + def __init__(self, arg): + super().__init__(arg) + + def key(self): + return 25 + + +class El2GoDacCertID(IntArgument): + + def __init__(self, arg): + super().__init__(arg) + + def key(self): + return 26 diff --git a/scripts/tools/nxp/factory_data_generator/generate.py b/scripts/tools/nxp/factory_data_generator/generate.py index 945f8bde641749..a36f0153fb8f35 100755 --- a/scripts/tools/nxp/factory_data_generator/generate.py +++ b/scripts/tools/nxp/factory_data_generator/generate.py @@ -23,10 +23,10 @@ import sys from crc import Calculator, Crc16 -from custom import (CertDeclaration, DacCert, DacPKey, Discriminator, HardwareVersion, HardwareVersionStr, IterationCount, - ManufacturingDate, PaiCert, PartNumber, ProductFinish, ProductId, ProductLabel, ProductName, - ProductPrimaryColor, ProductURL, Salt, SerialNum, SetupPasscode, StrArgument, UniqueId, VendorId, VendorName, - Verifier) +from custom import (CertDeclaration, DacCert, DacPKey, Discriminator, El2GoDacCertID, El2GoDacKeyID, El2GoObject, HardwareVersion, + HardwareVersionStr, IterationCount, ManufacturingDate, PaiCert, PartNumber, ProductFinish, ProductId, + ProductLabel, ProductName, ProductPrimaryColor, ProductURL, Salt, SerialNum, SetupPasscode, StrArgument, + UniqueId, VendorId, VendorName, Verifier) from default import InputArgument # Global variable for hash ID @@ -75,13 +75,24 @@ def __init__(self, args): self.spake2p = Spake2p() if self.args.spake2p_verifier is None: self.spake2p.generate(self.args) - self.args.dac_key.generate_private_key(self.args.dac_key_password, self.args.dac_key_use_sss_blob) + if self.args.dac_key: + self.args.dac_key.generate_private_key(self.args.dac_key_password, self.args.dac_key_use_sss_blob) def _validate_args(self): - if self.args.dac_key_password is None: + if self.args.dac_key_password is None and self.args.EL2GO_bin is None: logging.warning( "DAC Key password not provided. It means DAC Key is not protected." ) + if self.args.dac_key and self.args.EL2GO_bin: + logging.error("Could not provide two DAC Key provisionning method at the same time") + + if (not self.args.dac_key or not self.args.dac_cert) and not self.args.EL2GO_bin: + logging.error("Need to provide a DAC provisionner") + raise Exception("Could not generate factory data") + + if self.args.EL2GO_bin and (not self.args.EL2GO_DAC_CERT_ID or not self.args.EL2GO_DAC_KEY_ID): + logging.error("Need to provide EdgeLock 2Go DAC IDs") + raise Exception("Could not generate factory data") str_args = [obj for key, obj in vars(self.args).items() if isinstance(obj, StrArgument)] for str_arg in str_args: @@ -210,10 +221,6 @@ def main(): help="[str] Hardware version as string") required.add_argument("--cert_declaration", required=True, type=CertDeclaration, help="[path] Path to Certification Declaration in DER format") - required.add_argument("--dac_cert", required=True, type=DacCert, - help="[path] Path to DAC certificate in DER format") - required.add_argument("--dac_key", required=True, type=DacPKey, - help="[path] Path to DAC key in DER format") required.add_argument("--pai_cert", required=True, type=PaiCert, help="[path] Path to PAI certificate in DER format") required.add_argument("--spake2p_path", required=True, type=str, @@ -221,6 +228,16 @@ def main(): required.add_argument("--out", required=True, type=str, help="[path] Path to output binary") + optional.add_argument("--dac_cert", type=DacCert, + help="[path] Path to DAC certificate in DER format") + optional.add_argument("--dac_key", type=DacPKey, + help="[path] Path to DAC key in DER format") + optional.add_argument("--EL2GO_bin", type=El2GoObject, + help="[path] Path to EL2GO secure objects binary") + optional.add_argument("--EL2GO_DAC_KEY_ID", type=El2GoDacKeyID, + help="[hex] EL2GO DAC key ID") + optional.add_argument("--EL2GO_DAC_CERT_ID", type=El2GoDacCertID, + help="[hex] EL2GO DAC certificate ID") optional.add_argument("--dac_key_password", type=str, help="[path] Password to decode DAC Key if available") optional.add_argument("--dac_key_use_sss_blob", action='store_true', diff --git a/src/platform/nxp/common/factory_data/FactoryDataProvider.h b/src/platform/nxp/common/factory_data/FactoryDataProvider.h index b06089270a7355..58ad20d7b977fb 100644 --- a/src/platform/nxp/common/factory_data/FactoryDataProvider.h +++ b/src/platform/nxp/common/factory_data/FactoryDataProvider.h @@ -1,7 +1,7 @@ /* * * Copyright (c) 2023 Project CHIP Authors - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,21 @@ namespace chip { namespace DeviceLayer { +#define CHIP_FACTORY_DATA_ERROR(e) \ + ChipError(ChipError::Range::kLastRange, ((uint8_t) ChipError::Range::kLastRange << 2) | e, __FILE__, __LINE__) + +#define CHIP_FACTORY_DATA_SHA_CHECK CHIP_FACTORY_DATA_ERROR(0x01) +#define CHIP_FACTORY_DATA_HEADER_READ CHIP_FACTORY_DATA_ERROR(0x02) +#define CHIP_FACTORY_DATA_HASH_ID CHIP_FACTORY_DATA_ERROR(0x03) +#define CHIP_FACTORY_DATA_PDM_RESTORE CHIP_FACTORY_DATA_ERROR(0x04) +#define CHIP_FACTORY_DATA_NULL CHIP_FACTORY_DATA_ERROR(0x05) +#define CHIP_FACTORY_DATA_FLASH_ERASE CHIP_FACTORY_DATA_ERROR(0x06) +#define CHIP_FACTORY_DATA_FLASH_PROGRAM CHIP_FACTORY_DATA_ERROR(0x07) +#define CHIP_FACTORY_DATA_INTERNAL_FLASH_READ CHIP_FACTORY_DATA_ERROR(0x08) +#define CHIP_FACTORY_DATA_PDM_SAVE_RECORD CHIP_FACTORY_DATA_ERROR(0x09) +#define CHIP_FACTORY_DATA_PDM_READ_RECORD CHIP_FACTORY_DATA_ERROR(0x0A) +#define CHIP_FACTORY_DATA_RESTORE_MECHANISM CHIP_FACTORY_DATA_ERROR(0x0B) + class FactoryDataProviderImpl; /** @@ -72,6 +87,10 @@ class FactoryDataProvider : public chip::Credentials::DeviceAttestationCredentia kProductLabel, kProductFinish, kProductPrimaryColor, + kEl2GoBlob, + kEl2GoDacKeyId, + kEl2GoDacCertId, + kMaxId }; diff --git a/src/platform/nxp/rt/rw61x/BUILD.gn b/src/platform/nxp/rt/rw61x/BUILD.gn index 13c2b3c2ffc591..684faf3a7f575c 100644 --- a/src/platform/nxp/rt/rw61x/BUILD.gn +++ b/src/platform/nxp/rt/rw61x/BUILD.gn @@ -1,5 +1,5 @@ # Copyright (c) 2021 Project CHIP Authors -# Copyright 2023 NXP +# Copyright 2023-2024 NXP # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -52,18 +52,18 @@ config("nxp_platform_config") { "CONFIG_CHIP_ENCRYPTED_FACTORY_DATA=1", ] - if (nxp_enable_secure_dac_private_key_storage) { - assert(nxp_enable_secure_dac_private_key_storage && - !nxp_enable_secure_whole_factory_data, - "please select only one protection solution") - defines += [ "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/rt/rw61x/FactoryDataProviderImpl.h\"" ] - } else if (nxp_enable_secure_whole_factory_data) { + if (nxp_enable_secure_whole_factory_data) { assert(nxp_enable_secure_whole_factory_data && - !nxp_enable_secure_dac_private_key_storage, + !nxp_enable_secure_EL2GO_factory_data, "please select only one protection solution") defines += [ "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/rt/rw61x/FactoryDataProviderEncImpl.h\"" ] + } else if (nxp_enable_secure_EL2GO_factory_data) { + assert(!nxp_enable_secure_whole_factory_data && + nxp_enable_secure_EL2GO_factory_data, + "please select only one protection solution") + defines += [ "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/rt/rw61x/FactoryDataProviderEl2GoImpl.h\"" ] } else { - defines += [ "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/common/factory_data/FactoryDataProviderFwkImpl.h\"" ] + defines += [ "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/rt/rw61x/FactoryDataProviderImpl.h\"" ] } } @@ -201,20 +201,20 @@ static_library("nxp_platform") { "../../common/factory_data/FactoryDataProvider.cpp", "../../common/factory_data/FactoryDataProvider.h", ] - if (nxp_enable_secure_dac_private_key_storage) { - sources += [ - "FactoryDataProviderImpl.cpp", - "FactoryDataProviderImpl.h", - ] - } else if (nxp_enable_secure_whole_factory_data) { + if (nxp_enable_secure_whole_factory_data) { sources += [ "FactoryDataProviderEncImpl.cpp", "FactoryDataProviderEncImpl.h", ] + } else if (nxp_enable_secure_EL2GO_factory_data) { + sources += [ + "FactoryDataProviderEl2GoImpl.cpp", + "FactoryDataProviderEl2GoImpl.h", + ] } else { sources += [ - "../../common/factory_data/FactoryDataProviderFwkImpl.cpp", - "../../common/factory_data/FactoryDataProviderFwkImpl.h", + "FactoryDataProviderImpl.cpp", + "FactoryDataProviderImpl.h", ] } diff --git a/src/platform/nxp/rt/rw61x/FactoryDataProviderEl2GoImpl.cpp b/src/platform/nxp/rt/rw61x/FactoryDataProviderEl2GoImpl.cpp new file mode 100644 index 00000000000000..d7919201af7ca4 --- /dev/null +++ b/src/platform/nxp/rt/rw61x/FactoryDataProviderEl2GoImpl.cpp @@ -0,0 +1,283 @@ +/* + * + * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright 2024 NXP + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "FactoryDataProviderEl2GoImpl.h" + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +#include "ELSFactoryData.h" +#include "mflash_drv.h" + +#if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_ALT) +#include "els_pkc_mbedtls.h" +#endif /* defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_ALT) */ + +#include "fsl_adapter_flash.h" + +/* mbedtls */ +#include "mbedtls/aes.h" +#include "mbedtls/sha256.h" + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +#ifndef FACTORY_DATA_PROVIDER_LOG +#define FACTORY_DATA_PROVIDER_LOG 0 +#endif + +#if FACTORY_DATA_PROVIDER_LOG +#include "fsl_debug_console.h" +#define FACTORY_DATA_PROVIDER_PRINTF(...) \ + PRINTF("[%s] ", __FUNCTION__); \ + PRINTF(__VA_ARGS__); \ + PRINTF("\n\r"); +#else +#define FACTORY_DATA_PROVIDER_PRINTF(...) +#endif + +/* Grab symbol for the base address from the linker file. */ +extern uint32_t __FACTORY_DATA_START_OFFSET[]; +extern uint32_t __FACTORY_DATA_SIZE[]; + +using namespace ::chip::Credentials; +using namespace ::chip::Crypto; + +namespace chip { +namespace DeviceLayer { + +FactoryDataProviderImpl FactoryDataProviderImpl::sInstance; + +CHIP_ERROR FactoryDataProviderImpl::SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, + uint32_t * contentAddr) +{ + CHIP_ERROR err = CHIP_ERROR_NOT_FOUND; + uint8_t type = 0; + uint32_t index = 0; + uint8_t * addrContent = NULL; + uint8_t * factoryDataAddress = &factoryDataRamBuffer[0]; + uint32_t factoryDataSize = sizeof(factoryDataRamBuffer); + uint16_t currentLen = 0; + + while (index < factoryDataSize) + { + /* Read the type */ + memcpy((uint8_t *) &type, factoryDataAddress + index, sizeof(type)); + index += sizeof(type); + + /* Read the len */ + memcpy((uint8_t *) ¤tLen, factoryDataAddress + index, sizeof(currentLen)); + index += sizeof(currentLen); + + /* Check if the type gotten is the expected one */ + if (searchedType == type) + { + FACTORY_DATA_PROVIDER_PRINTF("type = %d, currentLen = %d, bufLength =%d", type, currentLen, bufLength); + /* If pBuf is null it means that we only want to know if the Type has been found */ + if (pBuf != NULL) + { + /* If the buffer given is too small, fill only the available space */ + if (bufLength < currentLen) + { + currentLen = bufLength; + } + memcpy((uint8_t *) pBuf, factoryDataAddress + index, currentLen); + } + length = currentLen; + if (contentAddr != NULL) + { + *contentAddr = (uint32_t) factoryDataAddress + index; + } + err = CHIP_NO_ERROR; + break; + } + else if (type == 0) + { + /* No more type available , break the loop */ + break; + } + else + { + /* Jump to next data */ + index += currentLen; + } + } + + return err; +} + +CHIP_ERROR FactoryDataProviderImpl::GetDeviceAttestationCert(MutableByteSpan & outBuffer) +{ + status_t status = STATUS_SUCCESS; + uint8_t el2go_blob[EL2GO_MAX_BLOB_SIZE] = { 0U }; + size_t el2go_blob_size = 0U; + size_t outBufferSize = 0U; + uint16_t CertificateIdSize = 0; + uint16_t BlobSize = 0; + uint32_t Addr; + uint32_t el2go_dac_cert_id = 0; + + /* Search key ID FactoryDataId::kEl2GoBlob address */ + ReturnErrorOnFailure(SearchForId(FactoryDataId::kEl2GoBlob, NULL, 0, BlobSize, &Addr)); + ReturnErrorOnFailure( + SearchForId(FactoryDataId::kEl2GoDacCertId, (uint8_t *) &el2go_dac_cert_id, sizeof(el2go_dac_cert_id), CertificateIdSize)); + + /* Read DAC certificate from EL2GO data */ + status = + read_el2go_blob((uint8_t *) Addr, (size_t) BlobSize, el2go_dac_cert_id, el2go_blob, EL2GO_MAX_BLOB_SIZE, &el2go_blob_size); + + STATUS_SUCCESS_OR_EXIT_MSG("DAC Private key not found: 0x%08x", status); + + // Import EL2GO blobs in ELS + status = decrypt_el2go_cert_blob(el2go_blob, el2go_blob_size, outBuffer.data(), outBuffer.size(), &outBufferSize); + outBuffer.reduce_size(outBufferSize); + STATUS_SUCCESS_OR_EXIT_MSG("decrypt_el2go_cert_blob failed: 0x%08x", status); + + return CHIP_NO_ERROR; + +exit: + return CHIP_ERROR_INTERNAL; +} + +CHIP_ERROR FactoryDataProviderImpl::ReadAndCheckFactoryDataInFlash(void) +{ + status_t status; + uint32_t factoryDataAddress = (uint32_t) __FACTORY_DATA_START_OFFSET; + uint32_t factoryDataSize = (uint32_t) __FACTORY_DATA_SIZE; + uint32_t hashId; + uint8_t calculatedHash[SHA256_OUTPUT_SIZE]; + CHIP_ERROR res; + + /* Init mflash */ + status = mflash_drv_init(); + + if (status != kStatus_Success || factoryDataSize > sizeof(factoryDataRamBuffer)) + return CHIP_ERROR_INTERNAL; + + /* Load the factory data into RAM buffer */ + if (mflash_drv_read(factoryDataAddress, (uint32_t *) &factoryDataRamBuffer[0], factoryDataSize) != kStatus_Success) + { + return CHIP_ERROR_INTERNAL; + } + memcpy(&mHeader, factoryDataRamBuffer, sizeof(mHeader)); + if (mHeader.hashId != HASH_ID) + { + return CHIP_FACTORY_DATA_HASH_ID; + } + /* remove the header section */ + memmove(&factoryDataRamBuffer[0], &factoryDataRamBuffer[sizeof(mHeader)], mHeader.size); + + /* Calculate SHA256 value over the factory data and compare with stored value */ + res = Hash_SHA256(&factoryDataRamBuffer[0], mHeader.size, &calculatedHash[0]); + + if (res != CHIP_NO_ERROR) + return res; + + if (memcmp(&calculatedHash[0], &mHeader.hash[0], HASH_LEN) != 0) + { + return CHIP_FACTORY_DATA_HASH_ID; + } + + ChipLogProgress(DeviceLayer, "factory data hash check is successful!"); + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & digestToSign, MutableByteSpan & outSignBuffer) +{ + CHIP_ERROR res = CHIP_NO_ERROR; + status_t status = STATUS_SUCCESS; + uint8_t el2go_blob[EL2GO_MAX_BLOB_SIZE] = { 0U }; + size_t el2go_blob_size = 0U; + mcuxClEls_EccSignOption_t sign_options = { 0 }; + uint8_t public_key[MCUXCLELS_ECC_PUBLICKEY_SIZE] = { 0 }; + size_t public_key_size = sizeof(public_key); + uint8_t hash[MCUXCLHASH_OUTPUT_SIZE_SHA_256] = { 0 }; + mcuxClEls_KeyIndex_t key_index = MCUXCLELS_KEY_SLOTS; + mcuxClEls_EccByte_t ecc_signature[MCUXCLELS_ECC_SIGNATURE_SIZE]; + uint8_t digest[kSHA256_Hash_Length]; + uint16_t BlobSize = 0; + uint16_t KeyIdSize = 0; + uint32_t Addr; + uint32_t el2go_dac_key_id = 0; + + /* Search key ID FactoryDataId::kEl2GoBlob */ + ReturnErrorOnFailure(SearchForId(FactoryDataId::kEl2GoBlob, NULL, 0, BlobSize, &Addr)); + ReturnErrorOnFailure( + SearchForId(FactoryDataId::kEl2GoDacKeyId, (uint8_t *) &el2go_dac_key_id, sizeof(el2go_dac_key_id), KeyIdSize)); + + /* Calculate message HASH to sign */ + memset(&digest[0], 0, sizeof(digest)); + res = Hash_SHA256(digestToSign.data(), digestToSign.size(), &digest[0]); + if (res != CHIP_NO_ERROR) + { + return res; + } + +#if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_ALT) + (void) mcux_els_mutex_lock(); +#endif + + /* Read DAC key from EL2GO data*/ + status = + read_el2go_blob((uint8_t *) Addr, (size_t) BlobSize, el2go_dac_key_id, el2go_blob, EL2GO_MAX_BLOB_SIZE, &el2go_blob_size); + STATUS_SUCCESS_OR_EXIT_MSG("DAC Provate key not found: 0x%08x", status); + + // Import EL2GO blobs in ELS + status = import_el2go_key_in_els(el2go_blob, el2go_blob_size, &key_index); + + // Generate key in ELS + status = els_keygen(key_index, public_key, &public_key_size); + STATUS_SUCCESS_OR_EXIT_MSG("els_keygen failed: 0x%08x", status); + + // Compute signature + status = ELS_sign_hash(hash, ecc_signature, &sign_options, key_index); + CopySpanToMutableSpan(ByteSpan{ ecc_signature, MCUXCLELS_ECC_SIGNATURE_SIZE }, outSignBuffer); + STATUS_SUCCESS_OR_EXIT_MSG("ELS_sign_hash failed: 0x%08x", status); + + status = els_delete_key(key_index); + STATUS_SUCCESS_OR_EXIT_MSG("Deletion of el2goimport_auth failed", status); + +#if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_ALT) + (void) mcux_els_mutex_unlock(); +#endif + return CHIP_NO_ERROR; +exit: +#if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_ALT) + (void) mcux_els_mutex_unlock(); +#endif + return CHIP_ERROR_INTERNAL; +} + +CHIP_ERROR FactoryDataProviderImpl::Init(void) +{ + uint16_t len; + uint8_t type; + uint16_t keySize = 0; + status_t status = STATUS_SUCCESS; + + ReturnLogErrorOnFailure(ReadAndCheckFactoryDataInFlash()); + + els_enable(); + + return CHIP_NO_ERROR; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/rt/rw61x/FactoryDataProviderEl2GoImpl.h b/src/platform/nxp/rt/rw61x/FactoryDataProviderEl2GoImpl.h new file mode 100644 index 00000000000000..fdf3aa9b80a540 --- /dev/null +++ b/src/platform/nxp/rt/rw61x/FactoryDataProviderEl2GoImpl.h @@ -0,0 +1,77 @@ +/* + * + * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright 2024 NXP + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#define FACTORY_DATA_MAX_SIZE 4096 + +#define EL2GO_MAX_BLOB_SIZE 3072U +#define EL2GO_MAX_CERT_SIZE 2048U +#define PUBLIC_KEY_SIZE 64U + +namespace chip { +namespace DeviceLayer { + +/** + * @brief This class provides Commissionable data and Device Attestation Credentials. + * + * This implementation allows to use the ELS hardware module to load the Matter factory + * dataset in RAM at the boot. + * + * + */ + +class FactoryDataProviderImpl : public FactoryDataProvider +{ +public: + static FactoryDataProviderImpl sInstance; + + CHIP_ERROR Init(void); + CHIP_ERROR SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, + uint32_t * contentAddr = NULL); + CHIP_ERROR SignWithDacKey(const ByteSpan & digestToSign, MutableByteSpan & outSignBuffer); + ; + CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & outBuffer) override; + +private: + struct Header + { + uint32_t hashId; + uint32_t size; + uint8_t hash[4]; + }; + uint8_t factoryDataRamBuffer[FACTORY_DATA_MAX_SIZE]; + Header mHeader; + + CHIP_ERROR ReadAndCheckFactoryDataInFlash(void); +}; + +inline FactoryDataProvider & FactoryDataPrvd() +{ + return FactoryDataProviderImpl::sInstance; +} + +inline FactoryDataProviderImpl & FactoryDataPrvdImpl() +{ + return FactoryDataProviderImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.cpp b/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.cpp index 73155af65eb48c..4fcd61c02d1ecf 100644 --- a/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.cpp +++ b/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.cpp @@ -1,7 +1,7 @@ /* * * Copyright (c) 2020-2022 Project CHIP Authors - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,10 @@ extern "C" { #include "ELSFactoryData.h" #include "mflash_drv.h" +#if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_ALT) +#include "els_pkc_mbedtls.h" +#endif /* defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_ALT) */ + #include "fsl_adapter_flash.h" /* mbedtls */ @@ -63,6 +67,23 @@ FactoryDataProviderImpl FactoryDataProviderImpl::sInstance; static constexpr size_t kPrivateKeyBlobLength = Crypto::kP256_PrivateKey_Length + ELS_BLOB_METADATA_SIZE + ELS_WRAP_OVERHEAD; +CHIP_ERROR FactoryDataProviderImpl::DecryptAes128Ecb(uint8_t * dest, uint8_t * source, const uint8_t * aes128Key) +{ + uint8_t res = 0; + mbedtls_aes_context aesCtx; + + mbedtls_aes_init(&aesCtx); + res = mbedtls_aes_setkey_dec(&aesCtx, aes128Key, 128U); + VerifyOrReturnError(res == 0, CHIP_ERROR_INTERNAL); + + res = mbedtls_aes_crypt_ecb(&aesCtx, MBEDTLS_AES_DECRYPT, source, dest); + VerifyOrReturnError(res == 0, CHIP_ERROR_INTERNAL); + + mbedtls_aes_free(&aesCtx); + + return CHIP_NO_ERROR; +} + CHIP_ERROR FactoryDataProviderImpl::SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, uint32_t * contentAddr) { @@ -123,6 +144,7 @@ CHIP_ERROR FactoryDataProviderImpl::SearchForId(uint8_t searchedType, uint8_t * CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & digestToSign, MutableByteSpan & outSignBuffer) { + CHIP_ERROR res = CHIP_NO_ERROR; uint8_t els_key_blob[kPrivateKeyBlobLength]; size_t els_key_blob_size = sizeof(els_key_blob); uint16_t keySize = 0; @@ -146,6 +168,19 @@ CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & digestToSign PLOG_DEBUG_BUFFER("els_key_blob", els_key_blob, els_key_blob_size); + /* Calculate message HASH to sign */ + memset(&digest[0], 0, sizeof(digest)); + res = Hash_SHA256(digestToSign.data(), digestToSign.size(), &digest[0]); + if (res != CHIP_NO_ERROR) + { + return res; + } + + PLOG_DEBUG_BUFFER("digestToSign", digestToSign.data(), digestToSign.size()); + +#if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_ALT) + (void) mcux_els_mutex_lock(); +#endif /* Import blob DAC key into SE50 (reserved key slot) */ status = import_die_int_wrapped_key_into_els(els_key_blob, els_key_blob_size, plain_key_properties, &key_index); STATUS_SUCCESS_OR_EXIT_MSG("import_die_int_wrapped_key_into_els failed: 0x%08x", status); @@ -160,12 +195,6 @@ CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & digestToSign /* The key is usable for signing. */ PLOG_DEBUG_BUFFER("public_key", public_key, public_key_size); - /* Calculate message HASH to sign */ - memset(&digest[0], 0, sizeof(digest)); - ReturnErrorOnFailure(Hash_SHA256(digestToSign.data(), digestToSign.size(), &digest[0])); - - PLOG_DEBUG_BUFFER("digestToSign", digestToSign.data(), digestToSign.size()); - /* ECC sign message hash with the key index slot reserved during the blob importation */ ELS_sign_hash(digest, ecc_signature, &sign_options, key_index); @@ -173,10 +202,16 @@ CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & digestToSign els_delete_key(key_index); /* Generate MutableByteSpan with ECC signature and ECC signature size */ +#if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_ALT) + (void) mcux_els_mutex_unlock(); +#endif return CopySpanToMutableSpan(ByteSpan{ ecc_signature, MCUXCLELS_ECC_SIGNATURE_SIZE }, outSignBuffer); exit: els_delete_key(key_index); +#if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_ALT) + (void) mcux_els_mutex_unlock(); +#endif return CHIP_ERROR_INVALID_SIGNATURE; } @@ -188,6 +223,7 @@ CHIP_ERROR FactoryDataProviderImpl::ReadAndCheckFactoryDataInFlash(void) uint32_t hashId; uint8_t calculatedHash[SHA256_OUTPUT_SIZE]; CHIP_ERROR res; + uint8_t currentBlock[16]; /* Init mflash */ status = mflash_drv_init(); @@ -216,13 +252,64 @@ CHIP_ERROR FactoryDataProviderImpl::ReadAndCheckFactoryDataInFlash(void) if (memcmp(&calculatedHash[0], &mHeader.hash[0], HASH_LEN) != 0) { - return CHIP_ERROR_NOT_FOUND; + /* HASH value didn't match, test if factory data are encrypted */ + + /* try to decrypt factory data, reset factory data buffer content*/ + memset(factoryDataRamBuffer, 0, sizeof(factoryDataRamBuffer)); + memset(calculatedHash, 0, sizeof(calculatedHash)); + + factoryDataAddress += sizeof(Header); + + /* Load the buffer into RAM by reading each 16 bytes blocks */ + for (int i = 0; i < (mHeader.size / 16); i++) + { + if (mflash_drv_read(factoryDataAddress + i * 16, (uint32_t *) ¤tBlock[0], sizeof(currentBlock)) != + kStatus_Success) + { + return CHIP_ERROR_INTERNAL; + } + ReturnErrorOnFailure(DecryptAes128Ecb(&factoryDataRamBuffer[i * 16], ¤tBlock[0], pAesKey)); + } + + /* Calculate SHA256 value over the factory data and compare with stored value */ + res = Hash_SHA256(&factoryDataRamBuffer[0], mHeader.size, &calculatedHash[0]); + if (memcmp(&calculatedHash[0], &mHeader.hash[0], HASH_LEN) != 0) + { + return CHIP_ERROR_NOT_FOUND; + } } ChipLogProgress(DeviceLayer, "factory data hash check is successful!"); return CHIP_NO_ERROR; } +CHIP_ERROR FactoryDataProviderImpl::SetAes128Key(const uint8_t * keyAes128) +{ + CHIP_ERROR error = CHIP_ERROR_INVALID_ARGUMENT; + if (keyAes128 != nullptr) + { + pAesKey = keyAes128; + error = CHIP_NO_ERROR; + } + return error; +} + +CHIP_ERROR FactoryDataProviderImpl::SetEncryptionMode(EncryptionMode mode) +{ + CHIP_ERROR error = CHIP_ERROR_INVALID_ARGUMENT; + + /* + * Currently the fwk_factory_data_provider module supports only ecb mode. + * Therefore return an error if encrypt mode is not ecb + */ + if (mode == encrypt_ecb) + { + encryptMode = mode; + error = CHIP_NO_ERROR; + } + return error; +} + CHIP_ERROR FactoryDataProviderImpl::Init(void) { uint16_t len; @@ -250,11 +337,6 @@ CHIP_ERROR FactoryDataProviderImpl::Init(void) ChipLogProgress(DeviceLayer, "SSS: convert DAC private key to blob"); ReturnLogErrorOnFailure(ELS_ConvertDacKey()); ChipLogProgress(DeviceLayer, "System restarting"); - // Restart the system. - NVIC_SystemReset(); - while (1) - { - } } return CHIP_NO_ERROR; @@ -278,8 +360,8 @@ CHIP_ERROR FactoryDataProviderImpl::ELS_ConvertDacKey() PLOG_DEBUG_BUFFER("blob", blob, blobSize); /* Read all factory data */ - hal_flash_status_t status = - HAL_FlashRead(factoryDataAddress + MFLASH_BASE_ADDRESS, newSize - (ELS_BLOB_METADATA_SIZE + ELS_WRAP_OVERHEAD), data); + hal_flash_status_t status = HAL_FlashRead(factoryDataAddress + MFLASH_BASE_ADDRESS, sizeof(Header), data); + memcpy(data + sizeof(Header), factoryDataRamBuffer, mHeader.size); VerifyOrReturnError(status == kStatus_HAL_Flash_Success, CHIP_ERROR_INTERNAL); ChipLogError(DeviceLayer, "SSS: cached factory data in RAM"); @@ -296,6 +378,13 @@ CHIP_ERROR FactoryDataProviderImpl::ELS_ConvertDacKey() VerifyOrReturnError(status == kStatus_HAL_Flash_Success, CHIP_ERROR_INTERNAL); ChipLogError(DeviceLayer, "SSS: updated factory data"); + /* remove the header section as it will no longer be used */ + memmove(&data[0], &data[sizeof(mHeader)], newSize); + memset(factoryDataRamBuffer, 0, sizeof(factoryDataRamBuffer)); + memcpy(factoryDataRamBuffer, data, newSize); + /* Actualisation of the factory data payload size */ + mHeader.size = newSize; + chip::Platform::MemoryFree(data); return CHIP_NO_ERROR; } diff --git a/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.h b/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.h index 4fc4785328aaf4..4e72fcd9539d65 100644 --- a/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.h +++ b/src/platform/nxp/rt/rw61x/FactoryDataProviderImpl.h @@ -1,7 +1,7 @@ /* * * Copyright (c) 2020-2022 Project CHIP Authors - * Copyright 2023 NXP + * Copyright 2023-2024 NXP * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,6 +44,9 @@ class FactoryDataProviderImpl : public FactoryDataProvider uint32_t * contentAddr = NULL); CHIP_ERROR SignWithDacKey(const ByteSpan & digestToSign, MutableByteSpan & outSignBuffer); + CHIP_ERROR SetAes128Key(const uint8_t * keyAes128); + CHIP_ERROR SetEncryptionMode(EncryptionMode mode); + private: struct Header { @@ -54,6 +57,9 @@ class FactoryDataProviderImpl : public FactoryDataProvider uint8_t factoryDataRamBuffer[FACTORY_DATA_MAX_SIZE]; Header mHeader; + const uint8_t * pAesKey = nullptr; + EncryptionMode encryptMode = encrypt_ecb; + /* TLV offset */ static constexpr uint32_t kLengthOffset = 1; static constexpr uint32_t kValueOffset = 3; @@ -61,6 +67,7 @@ class FactoryDataProviderImpl : public FactoryDataProvider CHIP_ERROR ReplaceWithBlob(uint8_t * data, uint8_t * blob, size_t blobLen, uint32_t offset); CHIP_ERROR ELS_ExportBlob(uint8_t * data, size_t * dataLen, uint32_t & offset); CHIP_ERROR ELS_ConvertDacKey(); + CHIP_ERROR DecryptAes128Ecb(uint8_t * dest, uint8_t * source, const uint8_t * aes128Key); CHIP_ERROR ReadAndCheckFactoryDataInFlash(void); }; diff --git a/third_party/nxp/nxp_matter_support b/third_party/nxp/nxp_matter_support index 69f40517ca5f27..7323d61dfc746a 160000 --- a/third_party/nxp/nxp_matter_support +++ b/third_party/nxp/nxp_matter_support @@ -1 +1 @@ -Subproject commit 69f40517ca5f27fdf3026f695c0d0607b604dc0e +Subproject commit 7323d61dfc746aff677cb40c17cfed9d43dd9c1d