Create fast pair data encryptor with Accountkey

PiperOrigin-RevId: 534908947
This commit is contained in:
Qin Wang
2023-05-24 11:04:41 -07:00
committed by Copybara-Service
parent ecca9c1d19
commit 1d5abfcc0f
3 changed files with 127 additions and 25 deletions
@@ -26,6 +26,8 @@
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "fastpair/common/account_key.h"
#include "fastpair/common/constant.h"
#include "fastpair/common/protocol.h"
#include "fastpair/crypto/decrypted_passkey.h"
@@ -78,9 +80,7 @@ void FastPairDataEncryptorImpl::Factory::CreateAsync(
device.GetProtocol() == Protocol::kFastPairRetroactivePairing) {
CreateAsyncWithKeyExchange(device, std::move(on_get_instance_callback));
} else {
NEARBY_LOGS(INFO) << __func__
<< ": Can't create FP encryptor. Invalid protocol.";
on_get_instance_callback(nullptr);
CreateAsyncWithAccountKey(device, std::move(on_get_instance_callback));
}
}
@@ -104,19 +104,36 @@ void FastPairDataEncryptorImpl::Factory::DeviceMetadataRetrieved(
absl::AnyInvocable<void(std::unique_ptr<FastPairDataEncryptor>)>
on_get_instance_callback,
DeviceMetadata& device_metadata) {
NEARBY_LOGS(INFO) << __func__;
DCHECK(&device_metadata);
std::optional<KeyPair> key_pair =
FastPairEncryption::GenerateKeysWithEcdhKeyAgreement(
device_metadata.GetDetails().anti_spoofing_key_pair().public_key());
if (!key_pair.has_value()) {
NEARBY_LOGS(INFO) << "Fail to generate key pair";
on_get_instance_callback(nullptr);
std::move(on_get_instance_callback)(nullptr);
return;
}
std::unique_ptr<FastPairDataEncryptor> data_encryptor =
auto data_encryptor =
std::make_unique<FastPairDataEncryptorImpl>(key_pair.value());
on_get_instance_callback(std::move(data_encryptor));
std::move(on_get_instance_callback)(std::move(data_encryptor));
}
void FastPairDataEncryptorImpl::Factory::CreateAsyncWithAccountKey(
const FastPairDevice& device,
absl::AnyInvocable<void(std::unique_ptr<FastPairDataEncryptor>)>
on_get_instance_callback) {
NEARBY_LOGS(INFO) << __func__;
absl::string_view account_key = device.GetAccountKey().GetAsBytes();
CHECK_EQ(account_key.size(), static_cast<size_t>(kSharedSecretKeyByteSize));
std::array<uint8_t, kSharedSecretKeyByteSize> shared_secret_key;
std::copy_n(account_key.begin(), kSharedSecretKeyByteSize,
shared_secret_key.begin());
std::move(on_get_instance_callback)(
std::make_unique<FastPairDataEncryptorImpl>(
std::move(shared_secret_key)));
}
// FastPairDataEncryptorImpl
@@ -64,6 +64,11 @@ class FastPairDataEncryptorImpl : public FastPairDataEncryptor {
absl::AnyInvocable<void(std::unique_ptr<FastPairDataEncryptor>)>
on_get_instance_callback,
DeviceMetadata& device_metadata);
static void CreateAsyncWithAccountKey(
const FastPairDevice& device,
absl::AnyInvocable<void(std::unique_ptr<FastPairDataEncryptor>)>
on_get_instance_callback);
};
std::array<uint8_t, kAesBlockByteSize> EncryptBytes(
@@ -24,9 +24,12 @@
#include "gtest/gtest.h"
#include "absl/functional/bind_front.h"
#include "absl/strings/escaping.h"
#include "fastpair/common/account_key.h"
#include "fastpair/common/constant.h"
#include "fastpair/common/protocol.h"
#include "fastpair/crypto/fast_pair_encryption.h"
#include "fastpair/dataparser/fast_pair_data_parser.h"
#include "fastpair/handshake/fast_pair_data_encryptor.h"
#include "fastpair/server_access/fake_fast_pair_repository.h"
#include "internal/platform/count_down_latch.h"
@@ -54,7 +57,7 @@ class FastPairDataEncryptorImplTest : public testing::Test {
public:
void TearDown() override { data_encryptor_.reset(); }
void FailedSetUpNoMetadata() {
void FailedSetUpRepositoryWithNoDeviceMetadata() {
CountDownLatch latch(1);
repository_ = std::make_unique<FakeFastPairRepository>();
FastPairDevice device(kValidModelId, kTestAddress,
@@ -66,7 +69,7 @@ class FastPairDataEncryptorImplTest : public testing::Test {
EXPECT_FALSE(latch.Await(kWaitTimeout).GetResult());
}
void FailedSetUpNoKeyPair() {
void FailedSetUpRepositoryWithNoPublicKey() {
repository_ = std::make_unique<FakeFastPairRepository>();
proto::Device metadata;
std::string decoded_key;
@@ -83,7 +86,7 @@ class FastPairDataEncryptorImplTest : public testing::Test {
latch.Await();
}
void SuccessfulSetUp() {
void SuccessCreateFastPairDataEncryptorWithKeyExchange() {
repository_ = std::make_unique<FakeFastPairRepository>();
proto::Device metadata;
std::string decoded_key;
@@ -100,6 +103,22 @@ class FastPairDataEncryptorImplTest : public testing::Test {
latch.Await();
}
void SuccessCreateFastPairDataEncryptorWithAccountKey() {
FastPairDevice device(kValidModelId, kTestAddress,
Protocol::kFastPairSubsequentPairing);
const std::vector<uint8_t> kAccountKey{0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
0x77, 0x88, 0x99, 0x00, 0xAA, 0xBB,
0xCC, 0xDD, 0xEE, 0xFF};
device.SetAccountKey(
AccountKey(std::string(kAccountKey.begin(), kAccountKey.end())));
CountDownLatch latch(1);
FastPairDataEncryptorImpl::Factory::CreateAsync(
device, absl::bind_front(
&FastPairDataEncryptorImplTest::OnDataEncryptorCreateAsync,
this, latch));
latch.Await();
}
void OnDataEncryptorCreateAsync(
CountDownLatch latch,
std::unique_ptr<FastPairDataEncryptor> fast_pair_data_encryptor) {
@@ -153,6 +172,21 @@ class FastPairDataEncryptorImplTest : public testing::Test {
latch.Await();
}
void ParseDecryptedPasskeyWithAccountKey() {
const std::array<uint8_t, kSharedSecretKeyByteSize> kAccountKey{
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
0x99, 0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
auto bytes = FastPairEncryption::EncryptBytes(kAccountKey, kPasskeyBytes);
CountDownLatch latch(1);
data_encryptor_->ParseDecryptPasskey(
std::vector<uint8_t>(bytes.begin(), bytes.end()),
absl::bind_front(
&FastPairDataEncryptorImplTest::ParseDecryptPasskeyCallback, this,
latch));
latch.Await();
}
void ParseDecryptedPasskeyInvalidBytes() {
const std::array<uint8_t, kAesBlockByteSize> bytes =
data_encryptor_->EncryptBytes(kPasskeyBytes);
@@ -189,36 +223,55 @@ class FastPairDataEncryptorImplTest : public testing::Test {
TEST_F(FastPairDataEncryptorImplTest, FailedSetUpNoMetadata) {
EXPECT_FALSE(data_encryptor_);
FailedSetUpNoMetadata();
FailedSetUpRepositoryWithNoDeviceMetadata();
EXPECT_FALSE(data_encryptor_);
}
TEST_F(FastPairDataEncryptorImplTest, NoKeyPair) {
FailedSetUpNoKeyPair();
FailedSetUpRepositoryWithNoPublicKey();
EXPECT_FALSE(data_encryptor_);
}
TEST_F(FastPairDataEncryptorImplTest, SuccessfulSetUp) {
TEST_F(FastPairDataEncryptorImplTest,
SuccessCreateFastPairDataEncryptorWithKeyExchange) {
EXPECT_FALSE(data_encryptor_);
SuccessfulSetUp();
SuccessCreateFastPairDataEncryptorWithKeyExchange();
EXPECT_TRUE(data_encryptor_);
}
TEST_F(FastPairDataEncryptorImplTest,
SuccessCreateFastPairDataEncryptorWithAccountKey) {
EXPECT_FALSE(data_encryptor_);
SuccessCreateFastPairDataEncryptorWithAccountKey();
EXPECT_TRUE(data_encryptor_);
}
TEST_F(FastPairDataEncryptorImplTest, GetPublicKey) {
SuccessfulSetUp();
SuccessCreateFastPairDataEncryptorWithKeyExchange();
EXPECT_TRUE(data_encryptor_);
ParseDecryptedPasskey();
EXPECT_NE(data_encryptor_->GetPublicKey(), std::nullopt);
}
TEST_F(FastPairDataEncryptorImplTest, EncryptBytes) {
SuccessfulSetUp();
TEST_F(FastPairDataEncryptorImplTest, GetNoPublicKey) {
SuccessCreateFastPairDataEncryptorWithAccountKey();
EXPECT_TRUE(data_encryptor_);
EXPECT_EQ(data_encryptor_->GetPublicKey(), std::nullopt);
}
TEST_F(FastPairDataEncryptorImplTest, EncryptBytesWithKeyExchange) {
SuccessCreateFastPairDataEncryptorWithKeyExchange();
EXPECT_TRUE(data_encryptor_);
EXPECT_FALSE(EncryptBytes().empty());
}
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedResponse) {
SuccessfulSetUp();
TEST_F(FastPairDataEncryptorImplTest, EncryptBytesWithAccountKey) {
SuccessCreateFastPairDataEncryptorWithAccountKey();
EXPECT_TRUE(data_encryptor_);
EXPECT_FALSE(EncryptBytes().empty());
}
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedResponseWithKeyExchange) {
SuccessCreateFastPairDataEncryptorWithKeyExchange();
EXPECT_TRUE(data_encryptor_);
ParseDecryptedResponse();
EXPECT_TRUE(response_);
@@ -229,15 +282,27 @@ TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedResponse) {
FastPairMessageType::kKeyBasedPairingResponse);
}
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedResponse_InvalidInputSize) {
SuccessfulSetUp();
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedResponseWithAccountKey) {
SuccessCreateFastPairDataEncryptorWithAccountKey();
EXPECT_TRUE(data_encryptor_);
ParseDecryptedResponse();
EXPECT_TRUE(response_);
const std::array<uint8_t, kDecryptedResponseAddressByteSize> kAddressBytes = {
0x5E, 0x3F, 0x45, 0x61, 0xC3, 0x32};
EXPECT_EQ(response_->address_bytes, kAddressBytes);
EXPECT_EQ(response_->message_type,
FastPairMessageType::kKeyBasedPairingResponse);
}
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedResponseInvalidInputSize) {
SuccessCreateFastPairDataEncryptorWithKeyExchange();
EXPECT_TRUE(data_encryptor_);
ParseDecryptedResponseInvalidBytes();
EXPECT_FALSE(response_);
}
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedPasskey) {
SuccessfulSetUp();
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedPasskeyWithKeyExchange) {
SuccessCreateFastPairDataEncryptorWithKeyExchange();
EXPECT_TRUE(data_encryptor_);
ParseDecryptedPasskey();
EXPECT_TRUE(passkey_);
@@ -251,8 +316,23 @@ TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedPasskey) {
EXPECT_EQ(passkey_->message_type, FastPairMessageType::kSeekersPasskey);
}
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedPasskey_InvalidInputSize) {
SuccessfulSetUp();
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedPasskeyWithAccountKey) {
SuccessCreateFastPairDataEncryptorWithAccountKey();
EXPECT_TRUE(data_encryptor_);
ParseDecryptedPasskeyWithAccountKey();
EXPECT_TRUE(passkey_);
// Passkey bytes.
std::array<uint8_t, 3> passkey_bytes = {0x5E, 0x3F, 0x45};
uint32_t passkey = passkey_bytes[2];
passkey += passkey_bytes[1] << 8;
passkey += passkey_bytes[0] << 16;
EXPECT_EQ(passkey_->passkey, passkey);
EXPECT_EQ(passkey_->message_type, FastPairMessageType::kSeekersPasskey);
}
TEST_F(FastPairDataEncryptorImplTest, ParseDecryptedPasskeyInvalidInputSize) {
SuccessCreateFastPairDataEncryptorWithKeyExchange();
EXPECT_TRUE(data_encryptor_);
ParseDecryptedPasskeyInvalidBytes();
EXPECT_FALSE(passkey_);