123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ash/quick_pair/fast_pair_handshake/fast_pair_data_encryptor_impl.h"
- #include <array>
- #include <cstdint>
- #include "ash/quick_pair/common/fast_pair/fast_pair_metrics.h"
- #include "ash/quick_pair/common/logging.h"
- #include "ash/quick_pair/common/protocol.h"
- #include "ash/quick_pair/fast_pair_handshake/fast_pair_encryption.h"
- #include "ash/quick_pair/proto/fastpair.pb.h"
- #include "ash/quick_pair/repository/fast_pair/device_metadata.h"
- #include "ash/quick_pair/repository/fast_pair_repository.h"
- #include "ash/services/quick_pair/quick_pair_process.h"
- #include "base/check.h"
- #include "base/memory/ptr_util.h"
- #include "base/notreached.h"
- namespace ash {
- namespace quick_pair {
- namespace {
- // static
- FastPairDataEncryptorImpl::Factory* g_test_factory_ = nullptr;
- bool ValidateInputSize(const std::vector<uint8_t>& encrypted_bytes) {
- if (encrypted_bytes.size() != kBlockSizeBytes) {
- QP_LOG(WARNING) << __func__ << ": Encrypted bytes should have size = "
- << kBlockSizeBytes
- << ", actual = " << encrypted_bytes.size();
- return false;
- }
- return true;
- }
- } // namespace
- // static
- void FastPairDataEncryptorImpl::Factory::SetFactoryForTesting(
- Factory* g_test_factory) {
- g_test_factory_ = g_test_factory;
- }
- FastPairDataEncryptorImpl::Factory::~Factory() = default;
- // static
- void FastPairDataEncryptorImpl::Factory::CreateAsync(
- scoped_refptr<Device> device,
- base::OnceCallback<void(std::unique_ptr<FastPairDataEncryptor>)>
- on_get_instance_callback) {
- if (g_test_factory_) {
- g_test_factory_->CreateInstance(std::move(device),
- std::move(on_get_instance_callback));
- return;
- }
- if (device->protocol == Protocol::kFastPairInitial ||
- device->protocol == Protocol::kFastPairRetroactive) {
- CreateAsyncWithKeyExchange(std::move(device),
- std::move(on_get_instance_callback));
- } else if (device->protocol == Protocol::kFastPairSubsequent) {
- CreateAsyncWithAccountKey(std::move(device),
- std::move(on_get_instance_callback));
- } else {
- // This object doesn't handle any other protocols, calling with another
- // is a bug.
- NOTREACHED();
- }
- }
- // static
- void FastPairDataEncryptorImpl::Factory::CreateAsyncWithKeyExchange(
- scoped_refptr<Device> device,
- base::OnceCallback<void(std::unique_ptr<FastPairDataEncryptor>)>
- on_get_instance_callback) {
- QP_LOG(INFO) << __func__;
- // We first have to get the metadata in order to get the public key to use
- // to generate the new secret key pair.
- auto metadata_id = device->metadata_id;
- FastPairRepository::Get()->GetDeviceMetadata(
- metadata_id,
- base::BindOnce(
- &FastPairDataEncryptorImpl::Factory::DeviceMetadataRetrieved,
- std::move(device), std::move(on_get_instance_callback)));
- }
- // static
- void FastPairDataEncryptorImpl::Factory::CreateAsyncWithAccountKey(
- scoped_refptr<Device> device,
- base::OnceCallback<void(std::unique_ptr<FastPairDataEncryptor>)>
- on_get_instance_callback) {
- QP_LOG(INFO) << __func__;
- absl::optional<std::vector<uint8_t>> account_key =
- device->GetAdditionalData(Device::AdditionalDataType::kAccountKey);
- DCHECK(account_key);
- DCHECK_EQ(account_key->size(), static_cast<size_t>(kPrivateKeyByteSize));
- std::array<uint8_t, kPrivateKeyByteSize> private_key;
- std::copy_n(account_key->begin(), kPrivateKeyByteSize, private_key.begin());
- std::unique_ptr<FastPairDataEncryptorImpl> data_encryptor =
- base::WrapUnique(new FastPairDataEncryptorImpl(std::move(private_key)));
- std::move(on_get_instance_callback).Run(std::move(data_encryptor));
- }
- // static
- void FastPairDataEncryptorImpl::Factory::DeviceMetadataRetrieved(
- scoped_refptr<Device> device,
- base::OnceCallback<void(std::unique_ptr<FastPairDataEncryptor>)>
- on_get_instance_callback,
- DeviceMetadata* device_metadata,
- bool has_retryable_error) {
- if (!device_metadata) {
- QP_LOG(WARNING) << __func__ << ": No device metadata retrieved.";
- std::move(on_get_instance_callback).Run(nullptr);
- return;
- }
- const std::string& public_anti_spoofing_key =
- device_metadata->GetDetails().anti_spoofing_key_pair().public_key();
- absl::optional<fast_pair_encryption::KeyPair> key_pair =
- fast_pair_encryption::GenerateKeysWithEcdhKeyAgreement(
- public_anti_spoofing_key);
- RecordKeyPairGenerationResult(/*success=*/key_pair.has_value());
- if (key_pair) {
- std::unique_ptr<FastPairDataEncryptorImpl> data_encryptor =
- base::WrapUnique(new FastPairDataEncryptorImpl(key_pair.value()));
- std::move(on_get_instance_callback).Run(std::move(data_encryptor));
- } else {
- QP_LOG(WARNING) << __func__ << ": Failed to get key pair for device";
- std::move(on_get_instance_callback).Run(nullptr);
- }
- }
- FastPairDataEncryptorImpl::FastPairDataEncryptorImpl(
- const fast_pair_encryption::KeyPair& key_pair)
- : secret_key_(key_pair.private_key), public_key_(key_pair.public_key) {}
- FastPairDataEncryptorImpl::FastPairDataEncryptorImpl(
- const std::array<uint8_t, kPrivateKeyByteSize>& secret_key)
- : secret_key_(secret_key) {}
- FastPairDataEncryptorImpl::~FastPairDataEncryptorImpl() = default;
- const std::array<uint8_t, kBlockSizeBytes>
- FastPairDataEncryptorImpl::EncryptBytes(
- const std::array<uint8_t, kBlockSizeBytes>& bytes_to_encrypt) {
- return fast_pair_encryption::EncryptBytes(secret_key_, bytes_to_encrypt);
- }
- const absl::optional<std::array<uint8_t, kPublicKeyByteSize>>&
- FastPairDataEncryptorImpl::GetPublicKey() {
- return public_key_;
- }
- void FastPairDataEncryptorImpl::ParseDecryptedResponse(
- const std::vector<uint8_t>& encrypted_response_bytes,
- base::OnceCallback<void(const absl::optional<DecryptedResponse>&)>
- callback) {
- if (!ValidateInputSize(encrypted_response_bytes)) {
- std::move(callback).Run(absl::nullopt);
- return;
- }
- quick_pair_process::ParseDecryptedResponse(
- std::vector<uint8_t>(secret_key_.begin(), secret_key_.end()),
- encrypted_response_bytes, std::move(callback),
- base::BindOnce(
- &FastPairDataEncryptorImpl::QuickPairProcessStoppedOnResponse,
- weak_ptr_factory_.GetWeakPtr()));
- }
- void FastPairDataEncryptorImpl::ParseDecryptedPasskey(
- const std::vector<uint8_t>& encrypted_passkey_bytes,
- base::OnceCallback<void(const absl::optional<DecryptedPasskey>&)>
- callback) {
- if (!ValidateInputSize(encrypted_passkey_bytes)) {
- std::move(callback).Run(absl::nullopt);
- return;
- }
- quick_pair_process::ParseDecryptedPasskey(
- std::vector<uint8_t>(secret_key_.begin(), secret_key_.end()),
- encrypted_passkey_bytes, std::move(callback),
- base::BindOnce(
- &FastPairDataEncryptorImpl::QuickPairProcessStoppedOnPasskey,
- weak_ptr_factory_.GetWeakPtr()));
- }
- void FastPairDataEncryptorImpl::QuickPairProcessStoppedOnResponse(
- QuickPairProcessManager::ShutdownReason shutdown_reason) {
- QP_LOG(WARNING)
- << ": Quick Pair process stopped while decrypting response due to error: "
- << shutdown_reason;
- }
- void FastPairDataEncryptorImpl::QuickPairProcessStoppedOnPasskey(
- QuickPairProcessManager::ShutdownReason shutdown_reason) {
- QP_LOG(WARNING)
- << ": Quick Pair process stopped while decrypting passkey due to error: "
- << shutdown_reason;
- }
- } // namespace quick_pair
- } // namespace ash
|