From 2954929f8a8a5b69f38d028aa666aca187eab6f5 Mon Sep 17 00:00:00 2001 From: wyhong <30567533+wy-hh@users.noreply.github.com> Date: Wed, 12 Apr 2023 02:26:23 +0800 Subject: [PATCH] [Bouffalolab] Add factory data provider support for BL602 (#26026) * add factory data provider support * update project config for bl602 * Fix restyled --- .../bouffalolab/bl602/CHIPProjectConfig.h | 12 +- .../bl602/flash_config/factory_data.dts | 361 +++++++++ .../bouffalolab/bl602/ldscripts/flash_rom.ld | 5 + .../bouffalolab/common/plat/platform.cpp | 26 +- src/platform/bouffalolab/BL602/BUILD.gn | 7 + .../common/FactoryDataProvider.cpp | 711 ++++++++++++++++++ .../bouffalolab/common/FactoryDataProvider.h | 76 ++ third_party/bouffalolab/bl602/bl_iot_sdk.gni | 17 + third_party/bouffalolab/bl702/bl_iot_sdk.gni | 1 + third_party/bouffalolab/repo | 2 +- 10 files changed, 1209 insertions(+), 9 deletions(-) create mode 100644 examples/platform/bouffalolab/bl602/flash_config/factory_data.dts create mode 100644 src/platform/bouffalolab/common/FactoryDataProvider.cpp create mode 100644 src/platform/bouffalolab/common/FactoryDataProvider.h diff --git a/examples/lighting-app/bouffalolab/bl602/CHIPProjectConfig.h b/examples/lighting-app/bouffalolab/bl602/CHIPProjectConfig.h index 16439282d46ad9..18b7923935696a 100644 --- a/examples/lighting-app/bouffalolab/bl602/CHIPProjectConfig.h +++ b/examples/lighting-app/bouffalolab/bl602/CHIPProjectConfig.h @@ -57,19 +57,13 @@ /** * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID * - * 0x235A: Chip's Vendor Id. - * 0xFFF1: Test vendor */ -//#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0x130D #define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0xFFF1 /** * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID * - * 0x534B: BL602 lock-app - * TODO: 3R */ -//#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0xF001 #define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8005 /** @@ -140,3 +134,9 @@ #define CHIP_SYSTEM_CRYPTO_HEADER_RESERVE_SIZE 128 #define CHIP_BLE_DEVICE_NAME "MatterLight" + +/** Please contact Bouffalo Lab for how to use factory data provider */ +// #define CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE 1 +// uncomment out the following macro to use factory test data +// when CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE sets to 1 +// #define CONFIG_BOUFFALOLAB_FACTORY_DATA_TEST diff --git a/examples/platform/bouffalolab/bl602/flash_config/factory_data.dts b/examples/platform/bouffalolab/bl602/flash_config/factory_data.dts new file mode 100644 index 00000000000000..77eca2a07ad56d --- /dev/null +++ b/examples/platform/bouffalolab/bl602/flash_config/factory_data.dts @@ -0,0 +1,361 @@ +/dts-v1/; +/include/ "bl602_base.dtsi"; +// version: 17 +// last_comp_version: 16 +// boot_cpuid_phys: 0x0 + +/ { + model = "bl bl602 IOT board"; + compatible = "bl,bl602-sample", "bl,bl602-common"; + #address-cells = <0x1>; + #size-cells = <0x1>; + gpio { + #address-cells = <1>; + #size-cells = <1>; + max_num = <40>; + gpio0 { + status = "okay"; + pin = <5>; + feature = "led"; + active = "Hi"; //Hi or Lo + mode = "blink"; //blink or hearbeat + time = <100>; //duration for this mode + }; + gpio1 { + status = "disable"; + pin = <6>; + feature = "led"; + active = "Hi"; //Hi or Lo + mode = "blink"; //blink or hearbeat + time = <100>; //duration for this mode + }; + gpio2 { + status = "okay"; + pin = <2>; + feature = "button"; + active = "Hi"; + mode = "multipress"; + button { + debounce = <10>; + short_press_ms { + start = <100>; + end = <3000>; + kevent = <2>; + }; + long_press_ms { + start = <6000>; + end = <10000>; + kevent = <3>; + }; + longlong_press_ms { + start = <15000>; + kevent = <4>; + }; + trig_level = "Hi"; + }; + hbn_use = "disable"; + }; + }; + i2s { + #address-cells = <1>; + #size-cells = <1>; + i2s@40017000 { + status = "okay"; + compatible = "bl602_i2s"; + reg = <0x40017000 0x100>; + mclk_only = "okay"; + pin { + mclk = <11>; + }; + }; + i2s@40017100 { + status = "okay"; + compatible = "bl602_i2s"; + reg = <0x40017100 0x100>; + mclk_only = "disable"; + pin { + bclk = <12>; + fs = <29>; + do = <30>; + di = <31>; + }; + }; + }; + i2c { + #address-cells = <1>; + #size-cells = <1>; + i2c@40011000 { + status = "okay"; + compatible = "bl602_i2c"; + reg = <0x40011000 0x100>; + pin { + scl = <32>; + sda = <13>; + }; + devices { + list_addr = <0x18 0x21>; + list_driver = "i2c_es8311", "i2c_gc0308>"; + }; + }; + i2c@40011100 { + status = "disable"; + compatible = "bl602_i2c"; + reg = <0x40011100 0x100>; + pin { + /*empty here*/ + }; + }; + }; + timer { + #address-cells = <1>; + #size-cells = <1>; + timer@40014000 { + status = "disable"; + compatible = "bl602_timer"; + reg = <0x40014000 0x100>; + }; + timer@40014100 { + status = "disable"; + compatible = "bl602_timer"; + reg = <0x40014100 0x100>; + }; + }; + pwm { + #address-cells = <1>; + #size-cells = <1>; + pwm@4000A420 { + status = "okay"; + compatible = "bl602_pwm"; + reg = <0x4000A420 0x20>; + path = "/dev/pwm0"; + id = <0>; + pin = <0>; + freq = <800000>; + duty = <50>; + }; + pwm@4000A440 { + status = "disable"; + reg = <0x4000A440 0x20>; + path = "/dev/pwm1"; + id = <1>; + pin = <1>; + freq = <5000>; + duty = <50>; + }; + pwm@4000A460 { + status = "disable"; + reg = <0x4000A460 0x20>; + path = "/dev/pwm2"; + id = <2>; + pin = <2>; + freq = <5000>; + duty = <50>; + }; + pwm@4000A480 { + status = "disable"; + reg = <0x4000A480 0x20>; + path = "/dev/pwm3"; + id = <3>; + pin = <3>; + freq = <5000>; + duty = <50>; + }; + pwm@4000A4A0 { + status = "disable"; + reg = <0x4000A4A0 0x20>; + path = "/dev/pwm4"; + id = <4>; + pin = <4>; + freq = <5000>; + duty = <50>; + }; + }; + ir { + #address-cells = <1>; + #size-cells = <1>; + ctrltype = <0>; + tx { + status = "disable"; + pin = <11>; // only support 11 + mode = "NEC"; // NEC,ExtenedNEC,RC5,SWM + interval = <100>; // ms + active_mode = "Hi"; //Hi,Lo + }; + rx { + status = "okay"; + pin = <12>; // only support 12 13 + mode = "NEC"; // NEC,ExtenedNEC,RC5,SWM + active_mode = "Hi"; //Hi,Lo + data_check = <2>; //bit 0:check cmd, bit 1:check addr + }; + }; + uart { + #address-cells = <1>; + #size-cells = <1>; + uart@4000A000 { + status = "okay"; + id = <0>; + compatible = "bl602_uart"; + path = "/dev/ttyS0"; + baudrate = <2000000>; + pin { + rx = <7>; + tx = <16>; + }; + buf_size { + rx_size = <512>; + tx_size = <512>; + }; + feature { + tx = "okay"; + rx = "okay"; + cts = "disable"; + rts = "disable"; + }; + }; + uart@4000A100 { + status = "okay"; + id = <1>; + compatible = "bl602_uart"; + path = "/dev/ttyS1"; + baudrate = <115200>; + pin { + rx = <3>; + tx = <4>; + }; + buf_size { + rx_size = <512>; + tx_size = <512>; + }; + feature { + tx = "okay"; + rx = "okay"; + cts = "disable"; + rts = "disable"; + }; + }; + }; + spi { + #address-cells = <1>; + #size-cells = <1>; + spi@4000F000 { + status = "okay"; /* okay disable */ + mode = "master"; + reg = <0x4000F000 0x100>; /* 4KB */ + path = "/dev/spi0"; + port = <0>; + polar_phase = <1>; /* 0,1,2,3 */ + freq = <6000000>; + pin { + clk = <3>; + cs = <2>; + mosi = <1>; + miso = <0>; + }; + dma_cfg { + tx_dma_ch = <2>; + rx_dma_ch = <3>; + }; + }; + }; + gpip { + #address-cells = <1>; + #size-cells = <1>; + adc_key { + status = "disable"; + pin = <9>; + interrupt = <3>; + key_vol = <0 100 400 300 500>; + key_pcb = "SW1", "SW2", "SW3", "SW4","SW5"; + key_event = "Usr1", "Usr2", "Start", "Up", "Down"; + key_raw = <1 2 3 4 5>; + }; + }; + qspi { + #address-cells = <1>; + #size-cells = <1>; + qspi@4000A000 { + status = "disable"; + reg = <0x4000A000 0x1000>;/* 4KB */ + }; + }; + wifi { + #address-cells = <1>; + #size-cells = <1>; + region { + country_code = <86>; + }; + mac { + mode = "MBF"; + sta_mac_addr = [C8 43 57 82 73 40]; + ap_mac_addr = [C8 43 57 82 73 02]; + }; + sta { + ssid = "yourssid"; + pwd = "yourapssword"; + auto_connect_enable = <0>; + }; + ap { + ssid = "bl_test_005"; + pwd = "12345678"; + ap_channel = <11>; + auto_chan_detect = "disable"; + }; + brd_rf { + xtal_mode = "MF"; + xtal = <36 36 0 60 60>; + /* + pwr_table = < 4 3 3 186 + 4 3 4 176 + 4 3 5 167 + 3 3 0 159 + 3 3 1 149 + 3 3 2 140 + 3 3 3 129 + 3 3 4 119 + 3 3 5 110 + 2 3 0 101 + 2 3 1 91 + 2 3 2 82 + 2 3 3 72 + 2 3 4 62 + 2 3 5 52 + 1 3 3 10>; + */ + pwr_mode = "bf";//B: only use power offset in EFUSE; b: use power offset in EFUSE with incremental mode; F: only use power offset in Flash; f: use power offset in Flash with incremental mode + pwr_table_11b = <20 20 20 18>;//1Mbps 2Mbps 5.5Mbps 11Mbps + pwr_table_11g = <18 18 18 18 18 18 14 14>; //6Mbps 9Mbps 12Mbps 18MBps 24Mbps 36Mbps 48Mbps 54Mbps + pwr_table_11n = <18 18 18 18 18 16 14 14>; //MCS0 MCS1 MCS2 MCS3 MCS4 MCS5 MCS6 MCS7 + pwr_offset = <10 10 10 10 10 10 10 10 10 10 10 10 10 10>;//due to the limit of current DTC, negative value is used. So we work around by adding all the poweroffset with 10. so 8 represents -2; 10 represents 0; 13 represents 3 + }; + rf_temp { + en_tcal = <0>; + linear_or_follow = <1>; + Tchannels = <2412 2427 2442 2457 2472>; + Tchannel_os = <180 168 163 160 157>; + Tchannel_os_low = <199 186 170 165 160>; + Troom_os = <255>; + //negative value is NOT supported. So we use '256' for 0, '255' for -1, '257' for 1,'511' for 256 + }; + }; + bluetooth { + #address-cells = <1>; + #size-cells = <1>; + brd_rf { + pwr_table_ble = <13>; //range:0~15dbm + }; + }; + MFD { + vendor_name = "Bouffalo Lab"; + vendor_id = [0x0d 0x13]; + product_name = "Test Device"; + product_id = [0x01 0xf0]; + product_part_number = "Test Part Number"; + product_url = "Test Product URL"; + product_label = "Test Product Label"; + manufactoring_date = <2023 02 26>; + hardware_version = [0x01 0x00]; + hardware_version_string = "ver_0.1"; + }; +}; +}; diff --git a/examples/platform/bouffalolab/bl602/ldscripts/flash_rom.ld b/examples/platform/bouffalolab/bl602/ldscripts/flash_rom.ld index 5ad35f1b9832b8..37c93f2e58d4a5 100644 --- a/examples/platform/bouffalolab/bl602/ldscripts/flash_rom.ld +++ b/examples/platform/bouffalolab/bl602/ldscripts/flash_rom.ld @@ -14,6 +14,9 @@ __RAM_END = 0x4200C000 + 256K - __EM_SIZE; /* leave 8K left for BLE */ __RAM_TCM_LEN = (16K + 16K + 48K + 64K + 64K - 16K - 16K); __RAM_WIFI_LEN = (__RAM_END - __RAM_START - __RAM_TCM_LEN); +__OCRAM_START_ADDRESS = 0x42030000 + 0x8000; +__OCRAM_SIZE = 112K; + MEMORY { rom (rxai!w) : ORIGIN = 0x21015000, LENGTH = 44K @@ -255,6 +258,8 @@ SECTIONS PROVIDE( _ld_ram_size2 = LENGTH(ram_wifi) ); PROVIDE( _ld_ram_addr2 = ORIGIN(ram_wifi) ); + PROVIDE(__ocram_start_addr = __OCRAM_START_ADDRESS); + PROVIDE(__ocram_size = __OCRAM_SIZE); /*BOOT2 sections*/ PROVIDE ( __boot2_pt_addr_src = BOOT2_PT_ADDR ); diff --git a/examples/platform/bouffalolab/common/plat/platform.cpp b/examples/platform/bouffalolab/common/plat/platform.cpp index 692b469eeb2c3b..50ed0de9c19a4d 100644 --- a/examples/platform/bouffalolab/common/plat/platform.cpp +++ b/examples/platform/bouffalolab/common/plat/platform.cpp @@ -59,6 +59,9 @@ #endif #include +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE || defined(CONFIG_BOUFFALOLAB_FACTORY_DATA_TEST) +#include +#endif #if CONFIG_ENABLE_CHIP_SHELL || PW_RPC_ENABLED #include "uart.h" @@ -81,6 +84,12 @@ chip::app::Clusters::NetworkCommissioning::Instance static chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE || defined(CONFIG_BOUFFALOLAB_FACTORY_DATA_TEST) +namespace { +FactoryDataProvider sFactoryDataProvider; +} +#endif + void ChipEventHandler(const ChipDeviceEvent * event, intptr_t arg) { switch (event->Type) @@ -196,10 +205,23 @@ CHIP_ERROR PlatformManagerImpl::PlatformInit(void) ReturnLogErrorOnFailure(sWiFiNetworkCommissioningInstance.Init()); #endif - chip::DeviceLayer::PlatformMgr().LockChipStack(); - // Initialize device attestation config +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE || defined(CONFIG_BOUFFALOLAB_FACTORY_DATA_TEST) + if (CHIP_NO_ERROR == sFactoryDataProvider.Init()) + { + SetDeviceInstanceInfoProvider(&sFactoryDataProvider); + SetDeviceAttestationCredentialsProvider(&sFactoryDataProvider); + SetCommissionableDataProvider(&sFactoryDataProvider); + } + else + { + ChipLogError(NotSpecified, "sFactoryDataProvider.Init() failed"); + } +#else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif + + chip::DeviceLayer::PlatformMgr().LockChipStack(); #if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY chip::app::DnssdServer::Instance().SetExtendedDiscoveryTimeoutSecs(EXT_DISCOVERY_TIMEOUT_SECS); diff --git a/src/platform/bouffalolab/BL602/BUILD.gn b/src/platform/bouffalolab/BL602/BUILD.gn index be0dd88d664852..64846e02898547 100644 --- a/src/platform/bouffalolab/BL602/BUILD.gn +++ b/src/platform/bouffalolab/BL602/BUILD.gn @@ -60,4 +60,11 @@ static_library("BL602") { "KeyValueStoreManagerImpl.cpp", "KeyValueStoreManagerImpl.h", ] + + sources += [ + "${chip_root}/src/credentials/CHIPCert.h", + "${chip_root}/src/credentials/DeviceAttestationCredsProvider.h", + "../common/FactoryDataProvider.cpp", + "../common/FactoryDataProvider.h", + ] } diff --git a/src/platform/bouffalolab/common/FactoryDataProvider.cpp b/src/platform/bouffalolab/common/FactoryDataProvider.cpp new file mode 100644 index 00000000000000..d659afc6257d1e --- /dev/null +++ b/src/platform/bouffalolab/common/FactoryDataProvider.cpp @@ -0,0 +1,711 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * 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 "FactoryDataProvider.h" +#include "CHIPDevicePlatformConfig.h" +#include +#include + +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE +#include +#else +#include +extern "C" { +#include +} +#endif +#include +extern "C" { +#include +} +#include + +namespace chip { +namespace DeviceLayer { + +CHIP_ERROR LoadKeypairFromRaw(ByteSpan privateKey, ByteSpan publicKey, Crypto::P256Keypair & keypair) +{ + Crypto::P256SerializedKeypair serializedKeypair; + ReturnErrorOnFailure(serializedKeypair.SetLength(privateKey.size() + publicKey.size())); + memcpy(serializedKeypair.Bytes(), publicKey.data(), publicKey.size()); + memcpy(serializedKeypair.Bytes() + publicKey.size(), privateKey.data(), privateKey.size()); + return keypair.Deserialize(serializedKeypair); +} + +CHIP_ERROR FactoryDataProvider::Init() +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + if (false == mfd_init()) + { + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + } +#endif + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetCertificationDeclaration(MutableByteSpan & outBuffer) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getCd(outBuffer.data(), outBuffer.size()); + if (len > 0) + { + outBuffer.reduce_size(len); + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + + static const unsigned char Chip_Test_CD_130D_f001_der[539] = { + 0x30, 0x81, 0xe9, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x81, 0xdb, 0x30, 0x81, 0xd8, + 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x45, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x38, 0x04, 0x36, 0x15, 0x24, 0x00, 0x01, 0x25, + 0x01, 0x0d, 0x13, 0x36, 0x02, 0x05, 0x01, 0xf0, 0x18, 0x25, 0x03, 0x34, 0x12, 0x2c, 0x04, 0x13, 0x5a, 0x49, 0x47, 0x32, + 0x30, 0x31, 0x34, 0x31, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x31, 0x2d, 0x32, 0x34, 0x24, 0x05, 0x00, 0x24, 0x06, + 0x00, 0x25, 0x07, 0x76, 0x98, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, 0x01, 0x03, 0x80, 0x14, 0x62, 0xfa, + 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, 0xf5, 0x04, 0xf3, 0x71, 0x60, 0x30, 0x0b, + 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, + 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x21, 0x00, 0xd9, 0x91, 0xc9, 0xce, 0xaf, 0x8e, 0x81, 0x56, 0x10, 0x63, + 0x1d, 0x1d, 0x69, 0x3d, 0x0c, 0xbb, 0xb6, 0x17, 0x6e, 0x0b, 0x91, 0xba, 0x7b, 0x23, 0x57, 0xdc, 0x50, 0x80, 0x23, 0xc9, + 0x8e, 0xd0, 0x02, 0x20, 0x34, 0x5d, 0xeb, 0xd7, 0x38, 0xca, 0x8f, 0xfb, 0xa8, 0x4e, 0x8b, 0xe9, 0x5b, 0x66, 0x8b, 0x15, + 0xb9, 0x0a, 0x9a, 0xf2, 0x11, 0x82, 0x0a, 0x7a, 0xf2, 0x9f, 0x3b, 0xdd, 0xd8, 0x15, 0x51, 0x07 + }; + + ReturnErrorOnFailure(CopySpanToMutableSpan(ByteSpan(Chip_Test_CD_130D_f001_der), outBuffer)); + + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) +{ + out_firmware_info_buffer.reduce_size(0); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & outBuffer) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getDacCert(outBuffer.data(), outBuffer.size()); + if (len > 0) + { + outBuffer.reduce_size(len); + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + static const uint8_t Dac_Cert_Array[] = { + 0x30, 0x82, 0x01, 0xd0, 0x30, 0x82, 0x01, 0x76, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x68, 0xa3, 0xb6, 0x6e, 0x27, + 0x6b, 0x5b, 0x29, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x30, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, + 0x50, 0x41, 0x49, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x01, 0x0c, + 0x04, 0x31, 0x33, 0x30, 0x44, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x36, 0x32, 0x38, 0x31, 0x34, 0x32, 0x33, 0x34, + 0x33, 0x5a, 0x18, 0x0f, 0x39, 0x39, 0x39, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, + 0x48, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x54, + 0x65, 0x73, 0x74, 0x20, 0x44, 0x41, 0x43, 0x20, 0x30, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, + 0x82, 0xa2, 0x7c, 0x02, 0x01, 0x0c, 0x04, 0x31, 0x33, 0x30, 0x44, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, + 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x02, 0x0c, 0x04, 0x46, 0x30, 0x30, 0x31, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, + 0xd8, 0x19, 0x93, 0xac, 0xf1, 0xc8, 0x63, 0xbb, 0x04, 0x2b, 0x8c, 0x2e, 0x4d, 0xe4, 0x08, 0x39, 0x4f, 0xf9, 0x3e, 0xa3, + 0x89, 0x19, 0x96, 0x8c, 0x22, 0xa1, 0x0f, 0xeb, 0x4c, 0x20, 0x2a, 0x8a, 0x12, 0xff, 0xe4, 0xe6, 0x09, 0x4f, 0x13, 0x4b, + 0xa8, 0x35, 0x53, 0x2f, 0xa4, 0x9d, 0x8e, 0x79, 0x8c, 0x07, 0x01, 0x5c, 0x73, 0xff, 0x0d, 0x1c, 0x34, 0xfe, 0x14, 0x7f, + 0xbe, 0xc6, 0x70, 0xf8, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, + 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x1d, + 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x63, 0x9f, 0xbd, 0x91, 0x8c, 0x90, 0xed, 0x7a, 0xbf, 0x64, 0xcd, + 0xe8, 0x2e, 0x13, 0x10, 0x8e, 0xee, 0x5d, 0x6f, 0x8e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0x3a, 0xb2, 0xfa, 0x06, 0x27, 0xcc, 0x4a, 0xdc, 0x84, 0xac, 0x9c, 0x95, 0x1e, 0x8c, 0x8f, 0xdc, 0x4c, 0x0d, + 0xec, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, + 0x21, 0x00, 0xd6, 0xc3, 0xab, 0x6d, 0xbd, 0xd0, 0xa2, 0x45, 0xbc, 0xcf, 0xb7, 0x2d, 0x6f, 0x5e, 0xd1, 0xbe, 0xd7, 0xd4, + 0xea, 0xca, 0x9e, 0xf2, 0xa1, 0x09, 0x77, 0xc3, 0x43, 0xa2, 0x29, 0x67, 0x63, 0x3d, 0x02, 0x20, 0x2b, 0xb8, 0x39, 0xf8, + 0x31, 0xeb, 0x83, 0x31, 0xe2, 0x31, 0xeb, 0xd2, 0x5c, 0x82, 0xe4, 0xb7, 0x14, 0xfd, 0x62, 0x97, 0x1f, 0x64, 0xff, 0x51, + 0x43, 0x83, 0xb4, 0xa9, 0x19, 0x6f, 0x96, 0xcf + }; + + ReturnErrorOnFailure(CopySpanToMutableSpan(ByteSpan(Dac_Cert_Array), outBuffer)); + + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getPaiCert(outBuffer.data(), outBuffer.size()); + if (len > 0) + { + outBuffer.reduce_size(len); + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + static const uint8_t Pai_Cert_Array[] = { + 0x30, 0x82, 0x01, 0xa7, 0x30, 0x82, 0x01, 0x4e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x01, 0x0f, 0x96, 0xa1, 0x42, + 0x5c, 0xe7, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x1a, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, + 0x50, 0x41, 0x41, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x36, 0x32, 0x38, 0x31, 0x34, 0x32, 0x33, 0x34, 0x33, 0x5a, + 0x18, 0x0f, 0x39, 0x39, 0x39, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x30, 0x31, + 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, + 0x74, 0x20, 0x50, 0x41, 0x49, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, + 0x01, 0x0c, 0x04, 0x31, 0x33, 0x30, 0x44, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xdb, 0xbe, 0xac, 0xd5, 0xf3, 0xd6, + 0x32, 0x36, 0x04, 0x00, 0xe0, 0xa1, 0x16, 0x8d, 0xbf, 0x0c, 0x74, 0x8f, 0xdb, 0xd7, 0x03, 0x7f, 0x8c, 0x4e, 0x65, 0x58, + 0x27, 0x2f, 0xfa, 0x2d, 0x64, 0x61, 0x4e, 0xe5, 0x72, 0xb8, 0xa5, 0x87, 0x8c, 0x15, 0xc7, 0x25, 0x55, 0x47, 0xc4, 0xc9, + 0x62, 0xda, 0xd7, 0x02, 0x64, 0xd2, 0x84, 0x2d, 0xe8, 0x2d, 0xf1, 0x69, 0xcb, 0x56, 0x42, 0x86, 0xf8, 0x55, 0xa3, 0x66, + 0x30, 0x64, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, + 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, + 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3a, 0xb2, 0xfa, 0x06, 0x27, 0xcc, 0x4a, 0xdc, 0x84, 0xac, 0x9c, + 0x95, 0x1e, 0x8c, 0x8f, 0xdc, 0x4c, 0x0d, 0xec, 0x01, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0x78, 0x5c, 0xe7, 0x05, 0xb8, 0x6b, 0x8f, 0x4e, 0x6f, 0xc7, 0x93, 0xaa, 0x60, 0xcb, 0x43, 0xea, 0x69, 0x68, + 0x82, 0xd5, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, + 0x20, 0x0f, 0x12, 0x2f, 0x8c, 0x83, 0xab, 0xdd, 0x35, 0x53, 0xbc, 0xcd, 0xe5, 0xec, 0x2d, 0x84, 0x99, 0x24, 0xb5, 0xe0, + 0x1a, 0x54, 0x45, 0x37, 0x78, 0xba, 0x88, 0xa8, 0x51, 0x18, 0xf8, 0x0e, 0x05, 0x02, 0x20, 0x59, 0x84, 0x16, 0xe1, 0xd1, + 0xee, 0x5e, 0xc6, 0x50, 0xcd, 0x5d, 0x58, 0x47, 0xb8, 0x10, 0x82, 0xa9, 0xa2, 0x2f, 0x4f, 0x31, 0x7e, 0xc7, 0x5d, 0xb6, + 0x6c, 0xc9, 0xc5, 0x70, 0xb8, 0x1e, 0xd8 + }; + + ReturnErrorOnFailure(CopySpanToMutableSpan(ByteSpan(Pai_Cert_Array), outBuffer)); + + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) +{ + Crypto::P256ECDSASignature signature; + Crypto::P256Keypair keypair; + chip::Crypto::P256PublicKey dacPublicKey; + + if (outSignBuffer.size() < signature.Capacity()) + { + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + + uint32_t dacCertSize = 0, dacPrivateKeySize = 0; + uint8_t * pDacCertPtr = mfd_getDacCertPtr(&dacCertSize); + uint8_t * pDacPrivateKeyPtr = mfd_getDacPrivateKeyPtr(&dacPrivateKeySize); + + if (NULL == pDacCertPtr || 0 == dacCertSize || NULL == pDacPrivateKeyPtr || 0 == dacPrivateKeySize) + { + outSignBuffer.reduce_size(0); + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + ByteSpan dacCert(pDacCertPtr, dacCertSize); + ByteSpan dacPrivateKey(pDacPrivateKeyPtr, dacPrivateKeySize); + +#else + static const uint8_t Dac_PrivateKey_Array[] = { 0x65, 0x11, 0x78, 0x2e, 0xf7, 0xcd, 0x30, 0x59, 0xbd, 0x3a, 0xdd, + 0x44, 0x6f, 0xc5, 0xdd, 0x92, 0xe5, 0xd8, 0x3c, 0x56, 0x9d, 0x67, + 0x7a, 0x29, 0xc7, 0xe9, 0xa7, 0x8f, 0x67, 0xc5, 0x5f, 0xf2 }; + + uint8_t dac_cert_array[Credentials::kMaxDERCertLength]; + uint8_t dac_cert_private_key_array[sizeof(Dac_PrivateKey_Array)]; + MutableByteSpan dacCert(dac_cert_array, Credentials::kMaxDERCertLength), + dacPrivateKey(dac_cert_private_key_array, sizeof(dac_cert_private_key_array)); + + ReturnErrorOnFailure(CopySpanToMutableSpan(ByteSpan(Dac_PrivateKey_Array), dacPrivateKey)); + ReturnErrorOnFailure(GetDeviceAttestationCert(dacCert)); + +#endif + + ReturnErrorOnFailure(chip::Crypto::ExtractPubkeyFromX509Cert(dacCert, dacPublicKey)); + + ReturnErrorOnFailure(LoadKeypairFromRaw(dacPrivateKey, ByteSpan(dacPublicKey.Bytes(), dacPublicKey.Length()), keypair)); + ReturnErrorOnFailure(keypair.ECDSA_sign_msg(messageToSign.data(), messageToSign.size(), signature)); + + ReturnErrorOnFailure(CopySpanToMutableSpan(ByteSpan(signature.Bytes(), signature.Length()), outSignBuffer)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetSetupDiscriminator(uint16_t & setupDiscriminator) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getDiscriminator((uint8_t *) &setupDiscriminator, sizeof(setupDiscriminator)); + if (len > 0) + { + setupDiscriminator = 0xfff & setupDiscriminator; + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + setupDiscriminator = 3840; + + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR FactoryDataProvider::SetSetupDiscriminator(uint16_t setupDiscriminator) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR FactoryDataProvider::GetSpake2pIterationCount(uint32_t & iterationCount) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getSapke2It((uint8_t *) &iterationCount, sizeof(iterationCount)); + if (len > 0) + { + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + iterationCount = 1000; + + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getSapke2Salt(saltBuf.data(), saltBuf.size()); + if (len > 0) + { + saltBuf.reduce_size(len); + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + static const char spake2pSalt[] = "U1BBS0UyUCBLZXkgU2FsdA=="; + uint32_t aSpake2pSaltLen; + + if (!utils_base64decode((const uint8_t *) spake2pSalt, sizeof(spake2pSalt) - 1, saltBuf.size(), saltBuf.data(), + &aSpake2pSaltLen)) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + saltBuf = MutableByteSpan(saltBuf.data(), aSpake2pSaltLen); + + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getSapke2Verifier(verifierBuf.data(), verifierBuf.size()); + if (len > 0) + { + verifierLen = len; + verifierBuf.reduce_size(len); + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + static const char spake2pVerifier[] = "jdf0KbjmAwujViR8WckvvklJzE0UL+uIOiIjTtb3a5kE/" + "WdbVWhmDFSSjLqFhiiCILxXQ4NVO3YBWTdkERnTlXbFmx+T/32FMRpZLPz8yqFXyALytJW7ZJfArBz0/CP9hA=="; + uint32_t aSpake2pVerifierLen; + + if (!utils_base64decode((const uint8_t *) spake2pVerifier, sizeof(spake2pVerifier) - 1, verifierBuf.size(), verifierBuf.data(), + &aSpake2pVerifierLen)) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + verifierBuf = MutableByteSpan(verifierBuf.data(), aSpake2pVerifierLen); + verifierLen = aSpake2pVerifierLen; + + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetSetupPasscode(uint32_t & setupPasscode) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getPasscode((uint8_t *) &setupPasscode, sizeof(setupPasscode)); + if (len > 0) + { + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + setupPasscode = 49808401; + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR FactoryDataProvider::SetSetupPasscode(uint32_t setupPasscode) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR FactoryDataProvider::GetVendorName(char * buf, size_t bufSize) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getVendorName(buf, bufSize); + if (len > 0) + { + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + static const char vendorName[] = "Bouffalo Lab"; + strncpy(buf, vendorName, bufSize); + + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetVendorId(uint16_t & vendorId) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getVendorId((uint8_t *) &vendorId, sizeof(vendorId)); + if (len > 0) + { + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + vendorId = 0x130D; + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetProductName(char * buf, size_t bufSize) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getProductName(buf, bufSize); + if (len > 0) + { + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + strncpy(buf, CHIP_BLE_DEVICE_NAME, bufSize); + + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetProductId(uint16_t & productId) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getProductId((uint8_t *) &productId, sizeof(productId)); + if (len > 0) + { + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + productId = 0xf001; + + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetPartNumber(char * buf, size_t bufSize) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getPartNumber(buf, bufSize); + if (len > 0) + { + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetProductURL(char * buf, size_t bufSize) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getProductUrl(buf, bufSize); + if (len > 0) + { + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetProductLabel(char * buf, size_t bufSize) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getProductLabel(buf, bufSize); + if (len > 0) + { + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetSerialNumber(char * buf, size_t bufSize) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getSerialNumber(buf, bufSize); + if (len > 0) + { + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + strncpy(buf, CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER, bufSize); + + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) +{ +#define OS_YEAR \ + ((((int) (__DATE__[7] - '0') * 10 + (int) (__DATE__[8] - '0')) * 10 + (int) (__DATE__[9] - '0')) * 10 + \ + (int) (__DATE__[10] - '0')) + +#define OS_MONTH \ + (__DATE__[2] == 'n' ? (__DATE__[1] == 'a' ? 1 : 6) \ + : __DATE__[2] == 'b' ? 2 \ + : __DATE__[2] == 'r' ? (__DATE__[0] == 'M' ? 3 : 4) \ + : __DATE__[2] == 'y' ? 5 \ + : __DATE__[2] == 'l' \ + ? 7 \ + : __DATE__[2] == 'g' ? 8 \ + : __DATE__[2] == 'p' ? 9 : __DATE__[2] == 't' ? 10 : __DATE__[2] == 'v' ? 11 : 12) + +#define OS_DAY ((__DATE__[4] == ' ' ? 0 : __DATE__[4] - '0') * 10 + (__DATE__[5] - '0')) + +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + if (mfd_getManufacturingDate(&year, &month, &day)) + { + return CHIP_NO_ERROR; + } +#endif + + year = (uint16_t) OS_YEAR; + month = (uint8_t) OS_MONTH; + day = (uint8_t) OS_DAY; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProvider::GetHardwareVersion(uint16_t & hardwareVersion) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getHardwareVersion((uint8_t *) &hardwareVersion, sizeof(hardwareVersion)); + if (len > 0) + { + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + hardwareVersion = CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION; + + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetHardwareVersionString(char * buf, size_t bufSize) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getHardwareVersionString(buf, bufSize); + if (len > 0) + { + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + strncpy(buf, CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING, bufSize); + + return CHIP_NO_ERROR; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) +{ +#if CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + int len = 0; + + len = mfd_getRotatingDeviceIdUniqueId(uniqueIdSpan.data(), uniqueIdSpan.size()); + if (len > 0) + { + return CHIP_NO_ERROR; + } + else if (0 == len) + { + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return CHIP_ERROR_BUFFER_TOO_SMALL; +#else + constexpr uint8_t uniqueId[] = CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID; + + uniqueIdSpan = MutableByteSpan((uint8_t *) uniqueId, sizeof(uniqueId)); + + return CHIP_NO_ERROR; +#endif +} + +extern "C" bool spake2pUtils_test(uint32_t aIt, uint8_t * aSalt, uint32_t aSaltLen, uint8_t * aSaltVerifier, + uint32_t * pSaltVerifierLen, uint32_t pincode) +{ + chip::Crypto::Spake2pVerifier verifier; + ByteSpan salt(aSalt, aSaltLen); + chip::MutableByteSpan serializedVerifierSpan(aSaltVerifier, *pSaltVerifierLen); + + VerifyOrReturnValue(aIt >= chip::Crypto::kSpake2p_Min_PBKDF_Iterations && aIt <= chip::Crypto::kSpake2p_Max_PBKDF_Iterations, + false); + VerifyOrReturnValue(aSalt && aSaltLen >= chip::Crypto::kSpake2p_Min_PBKDF_Salt_Length && + aSaltLen <= chip::Crypto::kSpake2p_Max_PBKDF_Salt_Length, + false); + VerifyOrReturnValue(aSaltVerifier && *pSaltVerifierLen >= chip::Crypto::kSpake2p_VerifierSerialized_Length, false); + + VerifyOrReturnValue(CHIP_NO_ERROR == verifier.Generate(aIt, salt, pincode), false); + + VerifyOrReturnValue(CHIP_NO_ERROR == verifier.Serialize(serializedVerifierSpan), false); + + *pSaltVerifierLen = serializedVerifierSpan.size(); + + return true; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/common/FactoryDataProvider.h b/src/platform/bouffalolab/common/FactoryDataProvider.h new file mode 100644 index 00000000000000..58ea373cd935ed --- /dev/null +++ b/src/platform/bouffalolab/common/FactoryDataProvider.h @@ -0,0 +1,76 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * 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 +#include +#include + +#include + +namespace chip { +namespace DeviceLayer { + +class FactoryDataProvider : public chip::Credentials::DeviceAttestationCredentialsProvider, + public CommissionableDataProvider, + public DeviceInstanceInfoProvider +{ +public: + CHIP_ERROR Init(); + + // ===== Members functions that implement the DeviceAttestationCredentialsProvider + CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & outBuffer) override; + CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override; + CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & outBuffer) override; + CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) override; + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override; + + // ===== Members functions that implement the CommissionableDataProvider + CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator) override; + CHIP_ERROR SetSetupDiscriminator(uint16_t setupDiscriminator) override; + CHIP_ERROR GetSpake2pIterationCount(uint32_t & iterationCount) override; + CHIP_ERROR GetSpake2pSalt(MutableByteSpan & saltBuf) override; + CHIP_ERROR GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) override; + CHIP_ERROR GetSetupPasscode(uint32_t & setupPasscode) override; + CHIP_ERROR SetSetupPasscode(uint32_t setupPasscode) override; + + // ===== Members functions that implement the DeviceInstanceInfoProvider + CHIP_ERROR GetVendorName(char * buf, size_t bufSize) override; + CHIP_ERROR GetVendorId(uint16_t & vendorId) override; + CHIP_ERROR GetProductName(char * buf, size_t bufSize) override; + CHIP_ERROR GetProductId(uint16_t & productId) override; + CHIP_ERROR GetPartNumber(char * buf, size_t bufSize) override; + CHIP_ERROR GetProductURL(char * buf, size_t bufSize) override; + CHIP_ERROR GetProductLabel(char * buf, size_t bufSize) override; + CHIP_ERROR GetSerialNumber(char * buf, size_t bufSize) override; + CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) override; + CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override; + CHIP_ERROR GetHardwareVersionString(char * buf, size_t bufSize) override; + CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) override; + +private: +#if !CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE + uint8_t mSpake2pSalt[32]; + uint32_t mSpake2pSaltLen; + uint8_t mSpake2pVerifier[100]; + uint32_t mSpake2pVerifierLen; +#endif +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/third_party/bouffalolab/bl602/bl_iot_sdk.gni b/third_party/bouffalolab/bl602/bl_iot_sdk.gni index 85cf926562b4fa..ea44002bccf38d 100644 --- a/third_party/bouffalolab/bl602/bl_iot_sdk.gni +++ b/third_party/bouffalolab/bl602/bl_iot_sdk.gni @@ -475,6 +475,7 @@ template("bl_iot_sdk") { "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/aes.c", "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/asn1parse.c", "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/asn1write.c", + "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/base64.c", "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/bignum.c", "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/ccm.c", "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/cipher.c", @@ -491,6 +492,7 @@ template("bl_iot_sdk") { "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/hmac_drbg.c", "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/md.c", "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/oid.c", + "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/pem.c", "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/pk.c", "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/pk_wrap.c", "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/pkcs5.c", @@ -499,7 +501,9 @@ template("bl_iot_sdk") { "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/platform_util.c", "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/sha256.c", "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/sha512.c", + "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/x509.c", "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/x509_create.c", + "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/x509_crt.c", "${bl_iot_sdk_root}/components/security/mbedtls_lts/mbedtls/library/x509write_csr.c", ] @@ -607,6 +611,7 @@ template("bl_iot_sdk") { ] public_configs = [ ":${sdk_target_name}_config", + ":${sdk_target_name}_config_hosal", ":${sdk_target_name}_ble_config", ] @@ -932,12 +937,24 @@ template("bl_iot_sdk") { ] } + config("${sdk_target_name}_config_factory_data") { + include_dirs = [ "${bl_iot_sdk_root}/components/network/matter/matter_factory_data/include" ] + } + + source_set("${sdk_target_name}_factory_data") { + libs = [ "${bl_iot_sdk_root}/components/network/matter/matter_factory_data/lib/libmatter_factory_data.a" ] + + configs += [ ":${sdk_target_name}_config" ] + public_configs = [ ":${sdk_target_name}_config_factory_data" ] + } + group(sdk_target_name) { public_deps = [ ":${sdk_target_name}_BSP_Driver", ":${sdk_target_name}_bl602_freertos", ":${sdk_target_name}_blcrypto_suite", ":${sdk_target_name}_ble", + ":${sdk_target_name}_factory_data", ":${sdk_target_name}_fs", ":${sdk_target_name}_hosal", ":${sdk_target_name}_libc", diff --git a/third_party/bouffalolab/bl702/bl_iot_sdk.gni b/third_party/bouffalolab/bl702/bl_iot_sdk.gni index 9c7d8ea64ea339..9783d77e6a732b 100644 --- a/third_party/bouffalolab/bl702/bl_iot_sdk.gni +++ b/third_party/bouffalolab/bl702/bl_iot_sdk.gni @@ -643,6 +643,7 @@ template("bl_iot_sdk") { configs += [ ":${sdk_target_name}_config_BSP_Driver", + ":${sdk_target_name}_config_hosal", ":${sdk_target_name}_config_freertos", ":${sdk_target_name}_config_utils", ] diff --git a/third_party/bouffalolab/repo b/third_party/bouffalolab/repo index 890577da8b6b1d..7ca85fd77663ab 160000 --- a/third_party/bouffalolab/repo +++ b/third_party/bouffalolab/repo @@ -1 +1 @@ -Subproject commit 890577da8b6b1d7f1078382e4e320a1e60cc5f60 +Subproject commit 7ca85fd77663ab6e13ce8481593474ea38ad4bb2