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

Commit ca5c7679 authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by Gerrit Code Review
Browse files

Merge "LE Pairing Handler"

parents a64a660a e29e0f18
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -310,10 +310,12 @@ genrule {
    srcs: [
        "hci/hci_packets.pdl",
        "l2cap/l2cap_packets.pdl",
        "smp/smp_packets.pdl",
    ],
    out: [
        "hci/hci_packets.h",
        "l2cap/l2cap_packets.h",
        "smp/smp_packets.h",
    ],
}

+97 −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 <memory>

#include "common/bidi_queue.h"
#include "os/handler.h"
#include "packet/base_packet_builder.h"
#include "packet/bit_inserter.h"
#include "packet/packet_view.h"

namespace bluetooth {
namespace common {
namespace testing {

/* This class is a pair of BiDiQueues, that have down ends "wired" together. It can be used i.e. to mock L2cap
 * interface, and provide two queues, where each sends packets of type A, and receives packets of type B */
template <class A, class B, std::unique_ptr<B> (*A_TO_B)(std::unique_ptr<A>)>
class WiredPairOfBiDiQueues {
  void dequeue_callback_a() {
    auto down_thing = queue_a_.GetDownEnd()->TryDequeue();
    if (!down_thing) LOG_ERROR("Received dequeue, but no data ready...");

    down_buffer_b_.Enqueue(A_TO_B(std::move(down_thing)), handler_);
  }

  void dequeue_callback_b() {
    auto down_thing = queue_b_.GetDownEnd()->TryDequeue();
    if (!down_thing) LOG_ERROR("Received dequeue, but no data ready...");

    down_buffer_a_.Enqueue(A_TO_B(std::move(down_thing)), handler_);
  }

  os::Handler* handler_;
  common::BidiQueue<B, A> queue_a_{10};
  common::BidiQueue<B, A> queue_b_{10};
  os::EnqueueBuffer<B> down_buffer_a_{queue_a_.GetDownEnd()};
  os::EnqueueBuffer<B> down_buffer_b_{queue_b_.GetDownEnd()};

 public:
  WiredPairOfBiDiQueues(os::Handler* handler) : handler_(handler) {
    queue_a_.GetDownEnd()->RegisterDequeue(
        handler_, common::Bind(&WiredPairOfBiDiQueues::dequeue_callback_a, common::Unretained(this)));
    queue_b_.GetDownEnd()->RegisterDequeue(
        handler_, common::Bind(&WiredPairOfBiDiQueues::dequeue_callback_b, common::Unretained(this)));
  }

  ~WiredPairOfBiDiQueues() {
    queue_a_.GetDownEnd()->UnregisterDequeue();
    queue_b_.GetDownEnd()->UnregisterDequeue();
  }

  /* This methd returns the UpEnd of queue A */
  common::BidiQueueEnd<A, B>* GetQueueAUpEnd() {
    return queue_a_.GetUpEnd();
  }

  /* This methd returns the UpEnd of queue B */
  common::BidiQueueEnd<A, B>* GetQueueBUpEnd() {
    return queue_b_.GetUpEnd();
  }
};

namespace {
std::unique_ptr<packet::PacketView<packet::kLittleEndian>> BuilderToView(
    std::unique_ptr<packet::BasePacketBuilder> up_thing) {
  auto bytes = std::make_shared<std::vector<uint8_t>>();
  bluetooth::packet::BitInserter i(*bytes);
  bytes->reserve(up_thing->size());
  up_thing->Serialize(i);
  return std::make_unique<packet::PacketView<packet::kLittleEndian>>(bytes);
}
}  // namespace

using WiredPairOfL2capQueues =
    WiredPairOfBiDiQueues<packet::BasePacketBuilder, packet::PacketView<packet::kLittleEndian>, BuilderToView>;

}  // namespace testing
}  // namespace common
}  // namespace bluetooth
+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include "common/callback.h"
#include "hci/hci_packets.h"
#include "os/handler.h"
#include "os/utils.h"

namespace bluetooth {
+7 −0
Original line number Diff line number Diff line
@@ -3,6 +3,10 @@ filegroup {
    srcs: [
        "ecc/multprecision.cc",
        "ecc/p_256_ecc_pp.cc",
        "ecdh_keys.cc",
        "pairing_handler_le.cc",
        "pairing_handler_le_legacy.cc",
        "pairing_handler_le_secure_connections.cc",
    ]
}

@@ -10,5 +14,8 @@ filegroup {
    name: "BluetoothSmpTestSources",
    srcs: [
        "ecc/multipoint_test.cc",
        "pairing_handler_le_unittest.cc",
        "test/fake_l2cap_test.cc",
        "test/pairing_handler_le_pair_test.cc",
    ]
}
 No newline at end of file
+82 −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.
 *
 ******************************************************************************/

#include "smp/ecdh_keys.h"

/**********************************************************************************************************************
 TODO: We should have random number management in separate file, and we
       should honour all the random number requirements from the spec!!
**********************************************************************************************************************/
#include <chrono>
#include <cstdlib>

#include "smp/ecc/p_256_ecc_pp.h"

namespace {
template <size_t SIZE>
static std::array<uint8_t, SIZE> GenerateRandom() {
  // TODO:  We need a proper  random number generator here.
  // use current time as seed for random generator
  std::srand(std::time(nullptr));
  std::array<uint8_t, SIZE> r;
  for (size_t i = 0; i < SIZE; i++) r[i] = std::rand();
  return r;
}
}  // namespace
/*********************************************************************************************************************/

namespace bluetooth {
namespace smp {

std::pair<std::array<uint8_t, 32>, EcdhPublicKey> GenerateECDHKeyPair() {
  std::array<uint8_t, 32> private_key = GenerateRandom<32>();
  ecc::Point public_key;

  ECC_PointMult(&public_key, &(ecc::curve_p256.G), (uint32_t*)private_key.data());

  EcdhPublicKey pk;
  memcpy(pk.x.data(), public_key.x, 32);
  memcpy(pk.y.data(), public_key.y, 32);

  /* private_key, public key pair */
  return std::make_pair<std::array<uint8_t, 32>, EcdhPublicKey>(std::move(private_key), std::move(pk));
}

bool ValidateECDHPoint(EcdhPublicKey pk) {
  ecc::Point public_key;
  memcpy(public_key.x, pk.x.data(), 32);
  memcpy(public_key.y, pk.y.data(), 32);
  memset(public_key.z, 0, 32);
  return ECC_ValidatePoint(public_key);
}

std::array<uint8_t, 32> ComputeDHKey(std::array<uint8_t, 32> my_private_key, EcdhPublicKey remote_public_key) {
  ecc::Point peer_publ_key, new_publ_key;
  uint32_t private_key[8];
  memcpy(private_key, my_private_key.data(), 32);
  memcpy(peer_publ_key.x, remote_public_key.x.data(), 32);
  memcpy(peer_publ_key.y, remote_public_key.y.data(), 32);
  ECC_PointMult(&new_publ_key, &peer_publ_key, (uint32_t*)private_key);

  std::array<uint8_t, 32> dhkey;
  memcpy(dhkey.data(), new_publ_key.x, 32);
  return dhkey;
}

}  // namespace smp
}  // namespace bluetooth
Loading