Loading system/gd/hci/address_with_type.h +29 −0 Original line number Original line Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <string> #include <string> #include <utility> #include <utility> #include "crypto_toolbox/crypto_toolbox.h" #include "hci/address.h" #include "hci/address.h" #include "hci/hci_packets.h" #include "hci/hci_packets.h" Loading @@ -42,6 +43,34 @@ class AddressWithType final { return address_type_; return address_type_; } } /* Is this an Resolvable Private Address ? */ inline bool IsRpa() const { return address_type_ == hci::AddressType::RANDOM_DEVICE_ADDRESS && ((address_.address)[0] & 0xc0) == 0x40; } /* Is this an Resolvable Private Address, that was generated from given irk ? */ bool IsRpaThatMatchesIrk(const crypto_toolbox::Octet16& irk) const { if (!IsRpa()) return false; /* use the 3 MSB of bd address as prand */ uint8_t prand[3]; prand[0] = address_.address[2]; prand[1] = address_.address[1]; prand[2] = address_.address[0]; /* generate X = E irk(R0, R1, R2) and R is random address 3 LSO */ crypto_toolbox::Octet16 computed_hash = crypto_toolbox::aes_128(irk, &prand[0], 3); uint8_t hash[3]; hash[0] = address_.address[5]; hash[1] = address_.address[4]; hash[2] = address_.address[3]; if (memcmp(computed_hash.data(), &hash[0], 3) == 0) { // match return true; } // not a match return false; } bool operator<(const AddressWithType& rhs) const { bool operator<(const AddressWithType& rhs) const { return address_ < rhs.address_ && address_type_ < rhs.address_type_; return address_ < rhs.address_ && address_type_ < rhs.address_type_; } } Loading system/gd/hci/address_with_type_test.cc +33 −0 Original line number Original line Diff line number Diff line Loading @@ -64,5 +64,38 @@ TEST(AddressWithTypeTest, HashDifferentSameAddressDiffType) { EXPECT_NE(hasher(address_with_type_1), hasher(address_with_type_2)); EXPECT_NE(hasher(address_with_type_1), hasher(address_with_type_2)); } } TEST(AddressWithTypeTest, IsRpa) { // Public address can't be RPA EXPECT_FALSE( AddressWithType(Address{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}, AddressType::PUBLIC_IDENTITY_ADDRESS).IsRpa()); // Must have proper Most Significant Bit configuration EXPECT_FALSE( AddressWithType(Address{{0x30, 0x02, 0x03, 0x04, 0x05, 0x06}}, AddressType::RANDOM_DEVICE_ADDRESS).IsRpa()); EXPECT_TRUE( AddressWithType(Address{{0x40, 0x02, 0x03, 0x04, 0x05, 0x03}}, AddressType::RANDOM_DEVICE_ADDRESS).IsRpa()); EXPECT_TRUE( AddressWithType(Address{{0x50, 0x02, 0x03, 0x04, 0x05, 0x06}}, AddressType::RANDOM_DEVICE_ADDRESS).IsRpa()); EXPECT_TRUE( AddressWithType(Address{{0x60, 0x02, 0x03, 0x04, 0x05, 0x06}}, AddressType::RANDOM_DEVICE_ADDRESS).IsRpa()); EXPECT_TRUE( AddressWithType(Address{{0x70, 0x02, 0x03, 0x04, 0x05, 0x06}}, AddressType::RANDOM_DEVICE_ADDRESS).IsRpa()); EXPECT_FALSE( AddressWithType(Address{{0x80, 0x02, 0x03, 0x04, 0x05, 0x06}}, AddressType::RANDOM_DEVICE_ADDRESS).IsRpa()); } TEST(AddressWithTypeTest, IsRpaThatMatchesIrk) { // Public address can't be RPA AddressWithType address_1 = AddressWithType(Address{{0x50, 0x02, 0x03, 0xC9, 0x12, 0xDE}}, AddressType::RANDOM_DEVICE_ADDRESS); AddressWithType address_2 = AddressWithType(Address{{0x50, 0x02, 0x03, 0xC9, 0x12, 0xDD}}, AddressType::RANDOM_DEVICE_ADDRESS); crypto_toolbox::Octet16 irk_1{0x90, 0x5e, 0x60, 0x59, 0xc9, 0x11, 0x43, 0x7b, 0x04, 0x09, 0x6a, 0x53, 0x28, 0xe6, 0x59, 0x6d}; EXPECT_TRUE(address_1.IsRpaThatMatchesIrk(irk_1)); EXPECT_FALSE(address_2.IsRpaThatMatchesIrk(irk_1)); } } // namespace hci } // namespace hci } // namespace bluetooth } // namespace bluetooth No newline at end of file Loading
system/gd/hci/address_with_type.h +29 −0 Original line number Original line Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <string> #include <string> #include <utility> #include <utility> #include "crypto_toolbox/crypto_toolbox.h" #include "hci/address.h" #include "hci/address.h" #include "hci/hci_packets.h" #include "hci/hci_packets.h" Loading @@ -42,6 +43,34 @@ class AddressWithType final { return address_type_; return address_type_; } } /* Is this an Resolvable Private Address ? */ inline bool IsRpa() const { return address_type_ == hci::AddressType::RANDOM_DEVICE_ADDRESS && ((address_.address)[0] & 0xc0) == 0x40; } /* Is this an Resolvable Private Address, that was generated from given irk ? */ bool IsRpaThatMatchesIrk(const crypto_toolbox::Octet16& irk) const { if (!IsRpa()) return false; /* use the 3 MSB of bd address as prand */ uint8_t prand[3]; prand[0] = address_.address[2]; prand[1] = address_.address[1]; prand[2] = address_.address[0]; /* generate X = E irk(R0, R1, R2) and R is random address 3 LSO */ crypto_toolbox::Octet16 computed_hash = crypto_toolbox::aes_128(irk, &prand[0], 3); uint8_t hash[3]; hash[0] = address_.address[5]; hash[1] = address_.address[4]; hash[2] = address_.address[3]; if (memcmp(computed_hash.data(), &hash[0], 3) == 0) { // match return true; } // not a match return false; } bool operator<(const AddressWithType& rhs) const { bool operator<(const AddressWithType& rhs) const { return address_ < rhs.address_ && address_type_ < rhs.address_type_; return address_ < rhs.address_ && address_type_ < rhs.address_type_; } } Loading
system/gd/hci/address_with_type_test.cc +33 −0 Original line number Original line Diff line number Diff line Loading @@ -64,5 +64,38 @@ TEST(AddressWithTypeTest, HashDifferentSameAddressDiffType) { EXPECT_NE(hasher(address_with_type_1), hasher(address_with_type_2)); EXPECT_NE(hasher(address_with_type_1), hasher(address_with_type_2)); } } TEST(AddressWithTypeTest, IsRpa) { // Public address can't be RPA EXPECT_FALSE( AddressWithType(Address{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}, AddressType::PUBLIC_IDENTITY_ADDRESS).IsRpa()); // Must have proper Most Significant Bit configuration EXPECT_FALSE( AddressWithType(Address{{0x30, 0x02, 0x03, 0x04, 0x05, 0x06}}, AddressType::RANDOM_DEVICE_ADDRESS).IsRpa()); EXPECT_TRUE( AddressWithType(Address{{0x40, 0x02, 0x03, 0x04, 0x05, 0x03}}, AddressType::RANDOM_DEVICE_ADDRESS).IsRpa()); EXPECT_TRUE( AddressWithType(Address{{0x50, 0x02, 0x03, 0x04, 0x05, 0x06}}, AddressType::RANDOM_DEVICE_ADDRESS).IsRpa()); EXPECT_TRUE( AddressWithType(Address{{0x60, 0x02, 0x03, 0x04, 0x05, 0x06}}, AddressType::RANDOM_DEVICE_ADDRESS).IsRpa()); EXPECT_TRUE( AddressWithType(Address{{0x70, 0x02, 0x03, 0x04, 0x05, 0x06}}, AddressType::RANDOM_DEVICE_ADDRESS).IsRpa()); EXPECT_FALSE( AddressWithType(Address{{0x80, 0x02, 0x03, 0x04, 0x05, 0x06}}, AddressType::RANDOM_DEVICE_ADDRESS).IsRpa()); } TEST(AddressWithTypeTest, IsRpaThatMatchesIrk) { // Public address can't be RPA AddressWithType address_1 = AddressWithType(Address{{0x50, 0x02, 0x03, 0xC9, 0x12, 0xDE}}, AddressType::RANDOM_DEVICE_ADDRESS); AddressWithType address_2 = AddressWithType(Address{{0x50, 0x02, 0x03, 0xC9, 0x12, 0xDD}}, AddressType::RANDOM_DEVICE_ADDRESS); crypto_toolbox::Octet16 irk_1{0x90, 0x5e, 0x60, 0x59, 0xc9, 0x11, 0x43, 0x7b, 0x04, 0x09, 0x6a, 0x53, 0x28, 0xe6, 0x59, 0x6d}; EXPECT_TRUE(address_1.IsRpaThatMatchesIrk(irk_1)); EXPECT_FALSE(address_2.IsRpaThatMatchesIrk(irk_1)); } } // namespace hci } // namespace hci } // namespace bluetooth } // namespace bluetooth No newline at end of file