From 1166732dd60e275cf9e34b4cad1545cab8798ac2 Mon Sep 17 00:00:00 2001 From: Kamil Kasperczyk <66371704+kkasperczyk-no@users.noreply.github.com> Date: Wed, 12 Jan 2022 23:07:33 +0100 Subject: [PATCH] zephyr: Added support for rotating device ID (#13411) * zephyr: Added support for rotating device ID Zephyr platform doesn't support advertising over Bluetooth LE rotating device ID. * Added kconfig option to enable CHIP_ROTATING_DEVICE_ID support * Changed IncrementLifetimeCounter method scope to be implemented by the ConfigurationManager and not in the local Generic manager scope. * Added setting additional data flag in BLE device identification info if additional data advertising is enabled * Added BLE GATT C3 characteristic and support for reading its attribute * Added generating rotating device ID for BLE GATT C3 characteristic * Extracted additional data payload files from the setup payload * Disabled rotating device ID support by default --- config/nrfconnect/chip-module/CMakeLists.txt | 5 ++ config/zephyr/Kconfig | 6 ++ src/include/platform/ConfigurationManager.h | 1 + .../GenericConfigurationManagerImpl.cpp | 8 +- .../GenericConfigurationManagerImpl.h | 2 +- src/platform/Zephyr/BLEManagerImpl.cpp | 74 ++++++++++++++++++- src/platform/Zephyr/BLEManagerImpl.h | 10 +++ src/platform/fake/ConfigurationManagerImpl.h | 1 + src/platform/nrfconnect/BUILD.gn | 2 +- src/platform/telink/BUILD.gn | 5 +- src/setup_payload/BUILD.gn | 18 ++++- 11 files changed, 123 insertions(+), 9 deletions(-) diff --git a/config/nrfconnect/chip-module/CMakeLists.txt b/config/nrfconnect/chip-module/CMakeLists.txt index 9a9ed9529afb41..857bf65ed0e21f 100644 --- a/config/nrfconnect/chip-module/CMakeLists.txt +++ b/config/nrfconnect/chip-module/CMakeLists.txt @@ -195,6 +195,11 @@ chip_gn_arg_bool ("chip_monolithic_tests" CONFIG_CHIP_BUILD_TE chip_gn_arg_bool ("chip_inet_config_enable_tcp_endpoint" CONFIG_CHIP_BUILD_TESTS) chip_gn_arg_bool ("chip_build_libshell" CONFIG_CHIP_LIB_SHELL) +if (CONFIG_CHIP_ROTATING_DEVICE_ID) + chip_gn_arg_bool ("chip_enable_rotating_device_id" "true") + chip_gn_arg_bool ("chip_enable_additional_data_advertising" "true") +endif() + if (CONFIG_CHIP_ENABLE_DNSSD_SRP) chip_gn_arg_string("chip_mdns" "platform") endif() diff --git a/config/zephyr/Kconfig b/config/zephyr/Kconfig index a390f78b429527..e3c7bdfd0a6810 100644 --- a/config/zephyr/Kconfig +++ b/config/zephyr/Kconfig @@ -108,6 +108,12 @@ config CHIP_OTA_REQUESTOR Device Firmware Upgrade by quering and downloading a new firmware image from an external OTA Provider node. +config CHIP_ROTATING_DEVICE_ID + bool "Enable rotating device ID support" + help + Enables rotating device identifier that provides a non-trackable identifier + which is unique per device and rotates at pre-defined moments. + config CHIP_OPERATIONAL_TIME_SAVE_INTERVAL int "Interval of saving node operation time to flash in hours unit" default 10 diff --git a/src/include/platform/ConfigurationManager.h b/src/include/platform/ConfigurationManager.h index 88a2c857cb4b1f..40fa50f2fa6c05 100644 --- a/src/include/platform/ConfigurationManager.h +++ b/src/include/platform/ConfigurationManager.h @@ -98,6 +98,7 @@ class ConfigurationManager virtual CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator) = 0; // Lifetime counter is monotonic counter that is incremented only in the case of a factory reset virtual CHIP_ERROR GetLifetimeCounter(uint16_t & lifetimeCounter) = 0; + virtual CHIP_ERROR IncrementLifetimeCounter() = 0; virtual CHIP_ERROR GetRegulatoryLocation(uint8_t & location) = 0; virtual CHIP_ERROR GetCountryCode(char * buf, size_t bufSize, size_t & codeLen) = 0; virtual CHIP_ERROR GetActiveLocale(char * buf, size_t bufSize, size_t & codeLen) = 0; diff --git a/src/include/platform/internal/GenericConfigurationManagerImpl.cpp b/src/include/platform/internal/GenericConfigurationManagerImpl.cpp index 9108081aceabdf..11ac8979aad52d 100644 --- a/src/include/platform/internal/GenericConfigurationManagerImpl.cpp +++ b/src/include/platform/internal/GenericConfigurationManagerImpl.cpp @@ -250,7 +250,7 @@ template void GenericConfigurationManagerImpl::InitiateFactoryReset() { #if CHIP_ENABLE_ROTATING_DEVICE_ID - _IncrementLifetimeCounter(); + IncrementLifetimeCounter(); #endif // Inheriting classes should call this method so the lifetime counter is updated if necessary. } @@ -499,7 +499,7 @@ CHIP_ERROR GenericConfigurationManagerImpl::GetLifetimeCounter(uint } template -CHIP_ERROR GenericConfigurationManagerImpl::_IncrementLifetimeCounter() +CHIP_ERROR GenericConfigurationManagerImpl::IncrementLifetimeCounter() { #if CHIP_ENABLE_ROTATING_DEVICE_ID return mLifetimePersistedCounter.Advance(); @@ -542,6 +542,10 @@ GenericConfigurationManagerImpl::GetBLEDeviceIdentificationInfo(Ble SuccessOrExit(err); deviceIdInfo.SetDeviceDiscriminator(discriminator); +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + deviceIdInfo.SetAdditionalDataFlag(true); +#endif + exit: return err; } diff --git a/src/include/platform/internal/GenericConfigurationManagerImpl.h b/src/include/platform/internal/GenericConfigurationManagerImpl.h index 8311dd3365e140..d29a0ed2a38240 100644 --- a/src/include/platform/internal/GenericConfigurationManagerImpl.h +++ b/src/include/platform/internal/GenericConfigurationManagerImpl.h @@ -76,7 +76,7 @@ class GenericConfigurationManagerImpl : public ConfigurationManager CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator) override; CHIP_ERROR StoreSetupDiscriminator(uint16_t setupDiscriminator) override; CHIP_ERROR GetLifetimeCounter(uint16_t & lifetimeCounter) override; - CHIP_ERROR _IncrementLifetimeCounter(); + CHIP_ERROR IncrementLifetimeCounter() override; CHIP_ERROR GetFailSafeArmed(bool & val) override; CHIP_ERROR SetFailSafeArmed(bool val) override; CHIP_ERROR GetBLEDeviceIdentificationInfo(Ble::ChipBLEDeviceIdentificationInfo & deviceIdInfo) override; diff --git a/src/platform/Zephyr/BLEManagerImpl.cpp b/src/platform/Zephyr/BLEManagerImpl.cpp index 072e1c0d6903a6..f6f392ee1ceca7 100644 --- a/src/platform/Zephyr/BLEManagerImpl.cpp +++ b/src/platform/Zephyr/BLEManagerImpl.cpp @@ -31,6 +31,9 @@ #include #include #include +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +#include +#endif #include #include @@ -55,6 +58,11 @@ const bt_uuid_128 UUID128_CHIPoBLEChar_RX = BT_UUID_INIT_128(0x11, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18); const bt_uuid_128 UUID128_CHIPoBLEChar_TX = BT_UUID_INIT_128(0x12, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18); +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +const bt_uuid_128 UUID128_CHIPoBLEChar_C3 = + BT_UUID_INIT_128(0x04, 0x8F, 0x21, 0x83, 0x8A, 0x74, 0x7D, 0xB8, 0xF2, 0x45, 0x72, 0x87, 0x38, 0x02, 0x63, 0x64); +#endif + bt_uuid_16 UUID16_CHIPoBLEService = BT_UUID_INIT_16(0xFFF6); const ChipBleUUID chipUUID_CHIPoBLEChar_RX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, @@ -76,7 +84,14 @@ struct bt_gatt_attr sChipoBleAttributes[] = { BT_GATT_PRIMARY_SERVICE(&UUID16 BT_GATT_CHRC_NOTIFY, BT_GATT_PERM_NONE, nullptr, nullptr, nullptr), - BT_GATT_CCC_MANAGED(&CHIPoBLEChar_TX_CCC, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE)}; + BT_GATT_CCC_MANAGED(&CHIPoBLEChar_TX_CCC, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE), +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + BT_GATT_CHARACTERISTIC(&UUID128_CHIPoBLEChar_C3.uuid, + BT_GATT_CHRC_READ, + BT_GATT_PERM_READ, + BLEManagerImpl::HandleC3Read, nullptr, nullptr), +#endif +}; struct bt_gatt_service sChipoBleService = BT_GATT_SERVICE(sChipoBleAttributes); @@ -273,6 +288,10 @@ CHIP_ERROR BLEManagerImpl::StartAdvertising(void) chip::Encoding::LittleEndian::Put16(serviceData.uuid, UUID16_CHIPoBLEService.val); ReturnErrorOnFailure(ConfigurationMgr().GetBLEDeviceIdentificationInfo(serviceData.deviceIdInfo)); +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + ReturnErrorOnFailure(PrepareC3CharData()); +#endif + if (!isAdvertisingRerun) { #if CONFIG_BT_PRIVACY @@ -340,6 +359,11 @@ CHIP_ERROR BLEManagerImpl::StopAdvertising(void) ChipLogProgress(DeviceLayer, "CHIPoBLE advertising stopped"); +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + // Increment life time counter to protect against long-term tracking of rotating device ID. + ReturnErrorOnFailure(ConfigurationMgr().IncrementLifetimeCounter()); +#endif + // Post a CHIPoBLEAdvertisingChange(Stopped) event. { ChipDeviceEvent advChange; @@ -563,6 +587,37 @@ CHIP_ERROR BLEManagerImpl::HandleTXCharComplete(const ChipDeviceEvent * event) return CHIP_NO_ERROR; } +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +CHIP_ERROR BLEManagerImpl::PrepareC3CharData() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + char serialNumber[ConfigurationManager::kMaxSerialNumberLength + 1] = {}; + uint16_t lifetimeCounter = 0; + BitFlags additionalDataFields; + +#if CHIP_ENABLE_ROTATING_DEVICE_ID + err = ConfigurationMgr().GetSerialNumber(serialNumber, sizeof(serialNumber)); + SuccessOrExit(err); + err = ConfigurationMgr().GetLifetimeCounter(lifetimeCounter); + SuccessOrExit(err); + + additionalDataFields.Set(AdditionalDataFields::RotatingDeviceId); +#endif + + err = AdditionalDataPayloadGenerator().generateAdditionalDataPayload(lifetimeCounter, serialNumber, strlen(serialNumber), + c3CharDataBufferHandle, additionalDataFields); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to generate TLV encoded Additional Data (%s)", __func__); + } + + return err; +} +#endif + void BLEManagerImpl::HandleBLEAdvertisementTimeout(System::Layer * layer, void * param) { BLEMgr().SetAdvertisingEnabled(false); @@ -855,6 +910,23 @@ void BLEManagerImpl::HandleDisconnect(struct bt_conn * conId, uint8_t reason) exit: PlatformMgr().UnlockChipStack(); } + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING +ssize_t BLEManagerImpl::HandleC3Read(struct bt_conn * conId, const struct bt_gatt_attr * attr, void * buf, uint16_t len, + uint16_t offset) +{ + ChipLogDetail(DeviceLayer, "Read request received for CHIPoBLE C3 (ConnId 0x%02" PRIx16 ")", bt_conn_index(conId)); + + if (sInstance.c3CharDataBufferHandle.IsNull()) + { + return 0; + } + + return bt_gatt_attr_read(conId, attr, buf, len, offset, sInstance.c3CharDataBufferHandle->Start(), + sInstance.c3CharDataBufferHandle->DataLength()); +} +#endif + } // namespace Internal } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/Zephyr/BLEManagerImpl.h b/src/platform/Zephyr/BLEManagerImpl.h index f564b305f8a8aa..5c2146f8580706 100644 --- a/src/platform/Zephyr/BLEManagerImpl.h +++ b/src/platform/Zephyr/BLEManagerImpl.h @@ -103,6 +103,9 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla bool mSubscribedConns[CONFIG_BT_MAX_CONN]; bt_gatt_notify_params mNotifyParams[CONFIG_BT_MAX_CONN]; bt_conn_cb mConnCallbacks; +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + PacketBufferHandle c3CharDataBufferHandle; +#endif void DriveBLEState(void); CHIP_ERROR ConfigureAdvertising(void); @@ -113,6 +116,9 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla CHIP_ERROR HandleRXCharWrite(const ChipDeviceEvent * event); CHIP_ERROR HandleTXCharCCCDWrite(const ChipDeviceEvent * event); CHIP_ERROR HandleTXCharComplete(const ChipDeviceEvent * event); +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + CHIP_ERROR PrepareC3CharData(); +#endif bool IsSubscribed(bt_conn * conn); bool SetSubscribed(bt_conn * conn); bool UnsetSubscribed(bt_conn * conn); @@ -139,6 +145,10 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla static ssize_t HandleRXWrite(bt_conn * conn, const bt_gatt_attr * attr, const void * buf, uint16_t len, uint16_t offset, uint8_t flags); static ssize_t HandleTXCCCWrite(bt_conn * conn, const bt_gatt_attr * attr, uint16_t value); + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + static ssize_t HandleC3Read(struct bt_conn * conn, const struct bt_gatt_attr * attr, void * buf, uint16_t len, uint16_t offset); +#endif }; /** diff --git a/src/platform/fake/ConfigurationManagerImpl.h b/src/platform/fake/ConfigurationManagerImpl.h index 43faeb31e199c0..fd9b571ee7bb9e 100644 --- a/src/platform/fake/ConfigurationManagerImpl.h +++ b/src/platform/fake/ConfigurationManagerImpl.h @@ -61,6 +61,7 @@ class ConfigurationManagerImpl : public ConfigurationManager CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator) override { return CHIP_ERROR_NOT_IMPLEMENTED; } CHIP_ERROR StoreSetupDiscriminator(uint16_t setupDiscriminator) override { return CHIP_ERROR_NOT_IMPLEMENTED; } CHIP_ERROR GetLifetimeCounter(uint16_t & lifetimeCounter) override { return CHIP_ERROR_NOT_IMPLEMENTED; } + CHIP_ERROR IncrementLifetimeCounter() override { return CHIP_ERROR_NOT_IMPLEMENTED; } CHIP_ERROR GetFailSafeArmed(bool & val) override { return CHIP_ERROR_NOT_IMPLEMENTED; } CHIP_ERROR SetFailSafeArmed(bool val) override { return CHIP_ERROR_NOT_IMPLEMENTED; } CHIP_ERROR GetBLEDeviceIdentificationInfo(Ble::ChipBLEDeviceIdentificationInfo & deviceIdInfo) override diff --git a/src/platform/nrfconnect/BUILD.gn b/src/platform/nrfconnect/BUILD.gn index 0bf154e0ded158..30893e96fb4cf6 100644 --- a/src/platform/nrfconnect/BUILD.gn +++ b/src/platform/nrfconnect/BUILD.gn @@ -47,7 +47,7 @@ static_library("nrfconnect") { "SystemPlatformConfig.h", ] - deps = [] + deps = [ "${chip_root}/src/setup_payload:additional_data_payload" ] public_deps = [ "${chip_root}/src/platform:platform_base" ] diff --git a/src/platform/telink/BUILD.gn b/src/platform/telink/BUILD.gn index b4c5c22962ac3e..f439b27323b416 100644 --- a/src/platform/telink/BUILD.gn +++ b/src/platform/telink/BUILD.gn @@ -62,5 +62,8 @@ static_library("telink") { } } - public_deps += [ "${chip_root}/src/crypto" ] + public_deps += [ + "${chip_root}/src/crypto", + "${chip_root}/src/setup_payload:additional_data_payload", + ] } diff --git a/src/setup_payload/BUILD.gn b/src/setup_payload/BUILD.gn index 2e6dcd2141a48c..0fb90417d81428 100644 --- a/src/setup_payload/BUILD.gn +++ b/src/setup_payload/BUILD.gn @@ -14,15 +14,26 @@ import("//build_overrides/chip.gni") -static_library("setup_payload") { - output_name = "libSetupPayload" - +source_set("additional_data_payload") { sources = [ "AdditionalDataPayload.h", "AdditionalDataPayloadGenerator.cpp", "AdditionalDataPayloadGenerator.h", "AdditionalDataPayloadParser.cpp", "AdditionalDataPayloadParser.h", + ] + + public_deps = [ + "${chip_root}/src/crypto", + "${chip_root}/src/lib/core", + "${chip_root}/src/lib/support", + ] +} + +static_library("setup_payload") { + output_name = "libSetupPayload" + + sources = [ "Base38.h", "Base38Decode.cpp", "Base38Decode.h", @@ -45,6 +56,7 @@ static_library("setup_payload") { cflags = [ "-Wconversion" ] public_deps = [ + ":additional_data_payload", "${chip_root}/src/crypto", "${chip_root}/src/lib/core", "${chip_root}/src/lib/support",