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

Commit 671bae7f authored by Henri Chataing's avatar Henri Chataing Committed by Automerger Merge Worker
Browse files

Merge "RootCanal: Internalize the crypto toolbox and bluetooth hci...

Merge "RootCanal: Internalize the crypto toolbox and bluetooth hci dependencies" am: 055f7284 am: be501936

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Bluetooth/+/2299357



Change-Id: I253d25a1fffc3fe9298205bd3e2490a52c6d49c9
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents bb2b1758 be501936
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ cc_binary {
        "liblog",
        "libutils",
        "libprotobuf-cpp-lite",
        "libcrypto",
    ],
    cflags: [
        "-fvisibility=hidden",
@@ -68,7 +69,6 @@ cc_binary {
    ],
    include_dirs: [
        "packages/modules/Bluetooth/system",
        "packages/modules/Bluetooth/system/gd",
        "packages/modules/Bluetooth/system/internal_include",
        "packages/modules/Bluetooth/system/stack/include",
    ],
@@ -119,7 +119,6 @@ cc_library_shared {
    ],
    include_dirs: [
        "packages/modules/Bluetooth/system",
        "packages/modules/Bluetooth/system/gd",
        "packages/modules/Bluetooth/system/internal_include",
        "packages/modules/Bluetooth/system/stack/include",
    ],
+15 −10
Original line number Diff line number Diff line
@@ -28,9 +28,6 @@ cc_defaults {
    local_include_dirs: [
        "include",
    ],
    include_dirs: [
        "packages/modules/Bluetooth/system/gd",
    ],
    header_libs: [
        "libbase_headers",
    ],
@@ -41,6 +38,15 @@ cc_defaults {
    ],
}

filegroup {
    name: "lib_sources",
    srcs: [
        "lib/crypto/crypto.cc",
        "lib/hci/address.cc",
        "lib/hci/class_of_device.cc",
    ],
}

// This library should be added as `whole_static_libs`
// as it uses static registration and all object
// files needs to be linked
@@ -82,9 +88,8 @@ cc_library_static {
        "net/posix/posix_async_socket.cc",
        "net/posix/posix_async_socket_connector.cc",
        "net/posix/posix_async_socket_server.cc",
        ":lib_sources",
        ":BluetoothPacketSources",
        ":BluetoothHciClassSources",
        ":BluetoothCryptoToolboxSources",
    ],
    export_include_dirs: [
        "include",
@@ -98,6 +103,7 @@ cc_library_static {
    ],
    shared_libs: [
        "libbase",
        "libcrypto",
    ],
    static_libs: [
        "libjsoncpp",
@@ -126,9 +132,8 @@ cc_library_host_shared {
        "model/controller/security_manager.cc",
        "model/devices/device.cc",
        "model/setup/async_manager.cc",
        ":lib_sources",
        ":BluetoothPacketSources",
        ":BluetoothHciClassSources",
        ":BluetoothCryptoToolboxSources",
    ],
    export_include_dirs: [
        "include",
@@ -136,6 +141,7 @@ cc_library_host_shared {
    ],
    stl: "libc++_static",
    static_libs: [
        "libcrypto",
        "libjsoncpp",
    ],
    whole_static_libs: [
@@ -233,6 +239,7 @@ cc_test_host {
    ],
    shared_libs: [
        "libbase",
        "libcrypto",
    ],
    static_libs: [
        "libbt-rootcanal",
@@ -291,9 +298,6 @@ cc_test_host {
    local_include_dirs: [
        "include",
    ],
    include_dirs: [
        "packages/modules/Bluetooth/system/gd",
    ],
    shared_libs: [
        "libbase",
    ],
@@ -331,6 +335,7 @@ cc_binary_host {
    ],
    static_libs: [
        "libc++fs",
        "libcrypto",
        "libjsoncpp",
        "libprotobuf-cpp-lite",
        "libscriptedbeaconpayload-protos-lite",
+40 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * 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 <algorithm>
#include <array>
#include <cstdint>

namespace rootcanal::crypto {

constexpr int kOctet16Length = 16;
using Octet16 = std::array<uint8_t, kOctet16Length>;

Octet16 aes_128(const Octet16& key, const Octet16& message);

/* This function computes AES_128(key, message). |key| must be 128bit.
 * |message| can be at most 16 bytes long, its length in bytes is given in
 * |length| */
inline Octet16 aes_128(const Octet16& key, const uint8_t* message,
                       const uint8_t length) {
  Octet16 padded_message{0};
  std::copy(message, message + length, padded_message.begin());
  return aes_128(key, padded_message);
}

}  // namespace rootcanal::crypto
+96 −0
Original line number Diff line number Diff line
/******************************************************************************
 *
 *  Copyright 2019 The Android Open Source Project
 *
 *  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 <array>
#include <cstring>
#include <initializer_list>
#include <optional>
#include <ostream>
#include <string>

#include "packet/custom_field_fixed_size_interface.h"

namespace bluetooth {
namespace hci {

class Address final : public packet::CustomFieldFixedSizeInterface<Address> {
 public:
  static constexpr size_t kLength = 6;

  std::array<uint8_t, kLength> address = {};

  constexpr Address() = default;
  constexpr Address(std::array<uint8_t, kLength> const& address);
  Address(const uint8_t (&address)[kLength]);
  Address(std::initializer_list<uint8_t> l);

  // CustomFieldFixedSizeInterface methods
  inline uint8_t* data() override { return address.data(); }
  inline const uint8_t* data() const override { return address.data(); }

  // storage::Serializable methods
  std::string ToString() const;
  static std::optional<Address> FromString(const std::string& from);

  bool operator<(const Address& rhs) const { return address < rhs.address; }
  bool operator==(const Address& rhs) const { return address == rhs.address; }
  bool operator>(const Address& rhs) const { return (rhs < *this); }
  bool operator<=(const Address& rhs) const { return !(*this > rhs); }
  bool operator>=(const Address& rhs) const { return !(*this < rhs); }
  bool operator!=(const Address& rhs) const { return !(*this == rhs); }

  bool IsEmpty() const { return *this == kEmpty; }

  // Converts |string| to Address and places it in |to|. If |from| does
  // not represent a Bluetooth address, |to| is not modified and this function
  // returns false. Otherwise, it returns true.
  static bool FromString(const std::string& from, Address& to);

  // Copies |from| raw Bluetooth address octets to the local object.
  // Returns the number of copied octets - should be always Address::kLength
  size_t FromOctets(const uint8_t* from);

  static bool IsValidAddress(const std::string& address);

  static const Address kEmpty;  // 00:00:00:00:00:00
  static const Address kAny;    // FF:FF:FF:FF:FF:FF
};

inline std::ostream& operator<<(std::ostream& os, const Address& a) {
  os << a.ToString();
  return os;
}

}  // namespace hci
}  // namespace bluetooth

namespace std {
template <>
struct hash<bluetooth::hci::Address> {
  std::size_t operator()(const bluetooth::hci::Address& address) const {
    uint64_t address_int = 0;
    for (auto b : address.address) {
      address_int <<= 8;
      address_int |= b;
    }
    return std::hash<uint64_t>{}(address_int);
  }
};
}  // namespace std
+141 −0
Original line number Diff line number Diff line
/******************************************************************************
 *
 *  Copyright 2019 The Android Open Source Project
 *
 *  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 <sstream>
#include <string>
#include <utility>

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

namespace bluetooth {
namespace hci {

class AddressWithType final {
 public:
  AddressWithType(Address address, AddressType address_type)
      : address_(std::move(address)), address_type_(address_type) {}

  explicit AddressWithType()
      : address_(Address::kEmpty),
        address_type_(AddressType::PUBLIC_DEVICE_ADDRESS) {}

  inline Address GetAddress() const { return address_; }

  inline AddressType GetAddressType() const { return address_type_; }

  /* Is this an Resolvable Private Address ? */
  inline bool IsRpa() const {
    return address_type_ == hci::AddressType::RANDOM_DEVICE_ADDRESS &&
           ((address_.data())[0] & 0xc0) == 0x40;
  }

  /* Is this an Resolvable Private Address, that was generated from given irk ?
   */
  bool IsRpaThatMatchesIrk(const rootcanal::crypto::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 */
    rootcanal::crypto::Octet16 computed_hash =
        rootcanal::crypto::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_ < rhs.address_
                                      : address_type_ < rhs.address_type_;
  }
  bool operator==(const AddressWithType& rhs) const {
    return address_ == rhs.address_ && address_type_ == rhs.address_type_;
  }
  bool operator>(const AddressWithType& rhs) const { return (rhs < *this); }
  bool operator<=(const AddressWithType& rhs) const { return !(*this > rhs); }
  bool operator>=(const AddressWithType& rhs) const { return !(*this < rhs); }
  bool operator!=(const AddressWithType& rhs) const { return !(*this == rhs); }

  FilterAcceptListAddressType ToFilterAcceptListAddressType() const {
    switch (address_type_) {
      case AddressType::PUBLIC_DEVICE_ADDRESS:
      case AddressType::PUBLIC_IDENTITY_ADDRESS:
        return FilterAcceptListAddressType::PUBLIC;
      case AddressType::RANDOM_DEVICE_ADDRESS:
      case AddressType::RANDOM_IDENTITY_ADDRESS:
        return FilterAcceptListAddressType::RANDOM;
    }
  }

  PeerAddressType ToPeerAddressType() const {
    switch (address_type_) {
      case AddressType::PUBLIC_DEVICE_ADDRESS:
      case AddressType::PUBLIC_IDENTITY_ADDRESS:
        return PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS;
      case AddressType::RANDOM_DEVICE_ADDRESS:
      case AddressType::RANDOM_IDENTITY_ADDRESS:
        return PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS;
    }
  }

  std::string ToString() const {
    std::stringstream ss;
    ss << address_ << "[" << AddressTypeText(address_type_) << "]";
    return ss.str();
  }

 private:
  Address address_;
  AddressType address_type_;
};

inline std::ostream& operator<<(std::ostream& os, const AddressWithType& a) {
  os << a.ToString();
  return os;
}

}  // namespace hci
}  // namespace bluetooth

namespace std {
template <>
struct hash<bluetooth::hci::AddressWithType> {
  std::size_t operator()(const bluetooth::hci::AddressWithType& address) const {
    uint64_t address_int = static_cast<uint64_t>(address.GetAddressType());
    for (auto b : address.GetAddress().address) {
      address_int <<= 8;
      address_int |= b;
    }
    return std::hash<uint64_t>{}(address_int);
  }
};
}  // namespace std
Loading