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

Commit 589ec9a4 authored by Henri Chataing's avatar Henri Chataing Committed by Gerrit Code Review
Browse files

Merge "RootCanal: Implement the command LE Read Local P-256 Public Key" into main

parents d1fddbc7 b10bac90
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -305,6 +305,7 @@ python_test_host {
        ":llcp_packets_python3_gen",
        "py/bluetooth.py",
        "py/controller.py",
        "test/HCI/AEN/*.py",
        "test/LL/*.py",
        "test/LL/CIS/CEN/*.py",
        "test/LL/CIS/PER/*.py",
+1 −1
Original line number Diff line number Diff line
@@ -285,7 +285,7 @@ static std::array<uint8_t, 64> SupportedCommands() {
          // OpCodeIndex::LE_SET_DATA_LENGTH,
          OpCodeIndex::LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH,
          OpCodeIndex::LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH,
          // OpCodeIndex::LE_READ_LOCAL_P_256_PUBLIC_KEY,
          OpCodeIndex::LE_READ_LOCAL_P_256_PUBLIC_KEY,
          // OpCodeIndex::LE_GENERATE_DHKEY_V1,
          OpCodeIndex::LE_ADD_DEVICE_TO_RESOLVING_LIST,
          OpCodeIndex::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST, OpCodeIndex::LE_CLEAR_RESOLVING_LIST,
+61 −2
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@

#include "model/controller/dual_mode_controller.h"

#include <openssl/ec.h>
#include <openssl/ec_key.h>
#include <openssl/mem.h>
#include <openssl/nid.h>
#include <packet_runtime.h>

#include <algorithm>
@@ -2210,6 +2214,61 @@ void DualModeController::LeWriteSuggestedDefaultDataLength(CommandView command)
          kNumCommandPackets, status));
}

static ErrorCode generateP256Key(std::array<uint8_t, 32>& key_x_coordinate,
                                 std::array<uint8_t, 32>& key_y_coordinate) {
  auto ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
  if (!ec_key) {
    WARNING("EC_KEY_new_by_curve_name(NID_X9_62_prime256v1) failed");
    return ErrorCode::UNSPECIFIED_ERROR;
  }

  if (!EC_KEY_generate_key(ec_key)) {
    WARNING("EC_KEY_generate_key failed");
    EC_KEY_free(ec_key);
    return ErrorCode::UNSPECIFIED_ERROR;
  }

  uint8_t* out_buf = nullptr;
  auto size = EC_KEY_key2buf(ec_key, POINT_CONVERSION_UNCOMPRESSED, &out_buf, nullptr);
  if (!out_buf) {
    WARNING("EC_KEY_key2buf failed");
    EC_KEY_free(ec_key);
    return ErrorCode::UNSPECIFIED_ERROR;
  }

  const size_t expected_size = key_x_coordinate.size() + key_y_coordinate.size() + 1;
  if (size != expected_size) {
    WARNING("unexpected size {}", size);
    OPENSSL_free(out_buf);
    EC_KEY_free(ec_key);
    return ErrorCode::UNSPECIFIED_ERROR;
  }

  memcpy(key_x_coordinate.data(), out_buf + 1, key_x_coordinate.size());
  memcpy(key_y_coordinate.data(), out_buf + 1 + key_x_coordinate.size(), key_y_coordinate.size());

  // OPENSSL_free(out_buf); // <-- this call fails with error invalid pointer
  EC_KEY_free(ec_key);
  return ErrorCode::SUCCESS;
}

void DualModeController::LeReadLocalP256PublicKey(CommandView command) {
  auto command_view = bluetooth::hci::LeReadLocalP256PublicKeyView::Create(command);
  CHECK_PACKET_VIEW(command_view);

  DEBUG(id_, "<< LE Read Local P-256 Public Key");

  send_event_(bluetooth::hci::LeReadLocalP256PublicKeyStatusBuilder::Create(ErrorCode::SUCCESS,
                                                                            kNumCommandPackets));

  std::array<uint8_t, 32> key_x_coordinate = {};
  std::array<uint8_t, 32> key_y_coordinate = {};
  ErrorCode status = generateP256Key(key_x_coordinate, key_y_coordinate);

  send_event_(bluetooth::hci::LeReadLocalP256PublicKeyCompleteBuilder::Create(
          status, key_x_coordinate, key_y_coordinate));
}

void DualModeController::LeAddDeviceToResolvingList(CommandView command) {
  auto command_view = bluetooth::hci::LeAddDeviceToResolvingListView::Create(command);
  CHECK_PACKET_VIEW(command_view);
@@ -3959,8 +4018,8 @@ const std::unordered_map<OpCode, DualModeController::CommandHandler>
                 &DualModeController::LeReadSuggestedDefaultDataLength},
                {OpCode::LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH,
                 &DualModeController::LeWriteSuggestedDefaultDataLength},
                //{OpCode::LE_READ_LOCAL_P_256_PUBLIC_KEY,
                //&DualModeController::LeReadLocalP256PublicKey},
                {OpCode::LE_READ_LOCAL_P_256_PUBLIC_KEY,
                 &DualModeController::LeReadLocalP256PublicKey},
                //{OpCode::LE_GENERATE_DHKEY_V1,
                //&DualModeController::LeGenerateDhkeyV1},
                {OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST,
+3 −0
Original line number Diff line number Diff line
@@ -450,6 +450,9 @@ public:
  void LeReadSuggestedDefaultDataLength(CommandView command);
  void LeWriteSuggestedDefaultDataLength(CommandView command);

  // 7.8.36
  void LeReadLocalP256PublicKey(CommandView command);

  // 7.8.38 - 7.8.41
  void LeAddDeviceToResolvingList(CommandView command);
  void LeRemoveDeviceFromResolvingList(CommandView command);
+8 −7
Original line number Diff line number Diff line
@@ -3536,17 +3536,17 @@ packet LeWriteSuggestedDefaultDataLengthComplete : CommandComplete (command_op_c
  status : ErrorCode,
}

packet LeReadLocalP256PublicKeyCommand : Command (op_code = LE_READ_LOCAL_P_256_PUBLIC_KEY) {
packet LeReadLocalP256PublicKey : Command (op_code = LE_READ_LOCAL_P_256_PUBLIC_KEY) {
}

packet LeReadLocalP256PublicKeyCommandStatus : CommandStatus (command_op_code = LE_READ_LOCAL_P_256_PUBLIC_KEY) {
packet LeReadLocalP256PublicKeyStatus : CommandStatus (command_op_code = LE_READ_LOCAL_P_256_PUBLIC_KEY) {
}

packet LeGenerateDhkeyV1Command : Command (op_code = LE_GENERATE_DHKEY_V1) {
packet LeGenerateDhkeyV1 : Command (op_code = LE_GENERATE_DHKEY_V1) {
  remote_p_256_public_key : 8[64],
}

packet LeGenerateDhkeyV1CommandStatus : CommandStatus (command_op_code = LE_GENERATE_DHKEY_V1) {
packet LeGenerateDhkeyV1Status : CommandStatus (command_op_code = LE_GENERATE_DHKEY_V1) {
}

packet LeAddDeviceToResolvingList : Command (op_code = LE_ADD_DEVICE_TO_RESOLVING_LIST) {
@@ -5211,12 +5211,13 @@ packet LeDataLengthChange : LeMetaEvent (subevent_code = DATA_LENGTH_CHANGE) {
  max_rx_time : 16, // 0x0148 - 0x4290
}

packet ReadLocalP256PublicKeyComplete : LeMetaEvent (subevent_code = READ_LOCAL_P256_PUBLIC_KEY_COMPLETE) {
packet LeReadLocalP256PublicKeyComplete : LeMetaEvent (subevent_code = READ_LOCAL_P256_PUBLIC_KEY_COMPLETE) {
  status : ErrorCode,
  local_p_256_public_key : 8[64],
  key_x_coordinate : 8[32],
  key_y_coordinate : 8[32],
}

packet GenerateDhKeyComplete : LeMetaEvent (subevent_code = GENERATE_DHKEY_COMPLETE) {
packet LeGenerateDhKeyComplete : LeMetaEvent (subevent_code = GENERATE_DHKEY_COMPLETE) {
  status : ErrorCode,
  dh_key : 8[32],
}
Loading