Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7ed58647 authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

Add IsRpa and IsRpaThatMatchesIrk into AddressWithType

Test: added unittests
Bug: 142341141
Change-Id: I0fc939317cf83793d2496780fab5ebdc05b76ba3
parent d2e1ed53
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <string>
#include <utility>

#include "crypto_toolbox/crypto_toolbox.h"
#include "hci/address.h"
#include "hci/hci_packets.h"

@@ -42,6 +43,34 @@ class AddressWithType final {
    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 {
    return address_ < rhs.address_ && address_type_ < rhs.address_type_;
  }
+33 −0
Original line number Diff line number Diff line
@@ -64,5 +64,38 @@ TEST(AddressWithTypeTest, HashDifferentSameAddressDiffType) {
  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 bluetooth
 No newline at end of file