fast_pair_decryption.cc 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/services/quick_pair/fast_pair_decryption.h"
  5. #include "ash/services/quick_pair/public/cpp/decrypted_passkey.h"
  6. #include "ash/services/quick_pair/public/cpp/decrypted_response.h"
  7. #include "base/check.h"
  8. #include "third_party/abseil-cpp/absl/types/optional.h"
  9. #include "third_party/boringssl/src/include/openssl/aes.h"
  10. namespace ash {
  11. namespace quick_pair {
  12. namespace fast_pair_decryption {
  13. constexpr int kMessageTypeIndex = 0;
  14. constexpr int kResponseAddressStartIndex = 1;
  15. constexpr int kResponseSaltStartIndex = 7;
  16. constexpr uint8_t kKeybasedPairingResponseType = 0x01;
  17. constexpr uint8_t kSeekerPasskeyType = 0x02;
  18. constexpr uint8_t kProviderPasskeyType = 0x03;
  19. constexpr int kPasskeySaltStartIndex = 4;
  20. std::array<uint8_t, kBlockByteSize> DecryptBytes(
  21. const std::array<uint8_t, kBlockByteSize>& aes_key_bytes,
  22. const std::array<uint8_t, kBlockByteSize>& encrypted_bytes) {
  23. AES_KEY aes_key;
  24. int aes_key_was_set = AES_set_decrypt_key(aes_key_bytes.data(),
  25. aes_key_bytes.size() * 8, &aes_key);
  26. DCHECK(aes_key_was_set == 0); // Invalid AES key size.;
  27. std::array<uint8_t, kBlockByteSize> decrypted_bytes;
  28. AES_decrypt(encrypted_bytes.data(), decrypted_bytes.data(), &aes_key);
  29. return decrypted_bytes;
  30. }
  31. // Decrypts the encrypted response
  32. // (https://developers.google.com/nearby/fast-pair/spec#table1.4) and returns
  33. // the parsed decrypted response
  34. // (https://developers.google.com/nearby/fast-pair/spec#table1.3)
  35. absl::optional<DecryptedResponse> ParseDecryptedResponse(
  36. const std::array<uint8_t, kBlockByteSize>& aes_key_bytes,
  37. const std::array<uint8_t, kBlockByteSize>& encrypted_response_bytes) {
  38. std::array<uint8_t, kBlockByteSize> decrypted_response_bytes =
  39. DecryptBytes(aes_key_bytes, encrypted_response_bytes);
  40. uint8_t message_type = decrypted_response_bytes[kMessageTypeIndex];
  41. // If the message type index is not the expected fast pair message type, then
  42. // this is not a valid fast pair response.
  43. if (message_type != kKeybasedPairingResponseType) {
  44. return absl::nullopt;
  45. }
  46. std::array<uint8_t, kDecryptedResponseAddressByteSize> address_bytes;
  47. std::copy(decrypted_response_bytes.begin() + kResponseAddressStartIndex,
  48. decrypted_response_bytes.begin() + kResponseSaltStartIndex,
  49. address_bytes.begin());
  50. std::array<uint8_t, kDecryptedResponseSaltByteSize> salt;
  51. std::copy(decrypted_response_bytes.begin() + kResponseSaltStartIndex,
  52. decrypted_response_bytes.end(), salt.begin());
  53. return DecryptedResponse(FastPairMessageType::kKeyBasedPairingResponse,
  54. address_bytes, salt);
  55. }
  56. // Decrypts the encrypted passkey
  57. // (https://developers.google.com/nearby/fast-pair/spec#table2.1) and returns
  58. // the parsed decrypted passkey
  59. // (https://developers.google.com/nearby/fast-pair/spec#table2.2)
  60. absl::optional<DecryptedPasskey> ParseDecryptedPasskey(
  61. const std::array<uint8_t, kBlockByteSize>& aes_key_bytes,
  62. const std::array<uint8_t, kBlockByteSize>& encrypted_passkey_bytes) {
  63. std::array<uint8_t, kBlockByteSize> decrypted_passkey_bytes =
  64. DecryptBytes(aes_key_bytes, encrypted_passkey_bytes);
  65. FastPairMessageType message_type;
  66. if (decrypted_passkey_bytes[kMessageTypeIndex] == kSeekerPasskeyType) {
  67. message_type = FastPairMessageType::kSeekersPasskey;
  68. } else if (decrypted_passkey_bytes[kMessageTypeIndex] ==
  69. kProviderPasskeyType) {
  70. message_type = FastPairMessageType::kProvidersPasskey;
  71. } else {
  72. return absl::nullopt;
  73. }
  74. uint32_t passkey = decrypted_passkey_bytes[3];
  75. passkey += decrypted_passkey_bytes[2] << 8;
  76. passkey += decrypted_passkey_bytes[1] << 16;
  77. std::array<uint8_t, kDecryptedPasskeySaltByteSize> salt;
  78. std::copy(decrypted_passkey_bytes.begin() + kPasskeySaltStartIndex,
  79. decrypted_passkey_bytes.end(), salt.begin());
  80. return DecryptedPasskey(message_type, passkey, salt);
  81. }
  82. } // namespace fast_pair_decryption
  83. } // namespace quick_pair
  84. } // namespace ash