1 /*
2  *
3  *  Copyright 2019 The Android Open Source Project
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  */
18 
19 #pragma once
20 
21 #include <memory>
22 #include <utility>
23 
24 #include "crypto_toolbox/crypto_toolbox.h"
25 #include "hci/address_with_type.h"
26 
27 namespace bluetooth {
28 namespace security {
29 namespace record {
30 
31 class SecurityRecord {
32  public:
SecurityRecord(hci::AddressWithType address)33   explicit SecurityRecord(hci::AddressWithType address) : pseudo_address_(address) {}
34 
35   SecurityRecord& operator=(const SecurityRecord& other) = default;
36 
37   /**
38    * Returns true if a device is currently pairing to another device
39    */
IsPairing()40   bool IsPairing() const {
41     return pairing_;
42   }
43 
44   /* Link key has been exchanged, but not stored */
IsPaired()45   bool IsPaired() const {
46     return IsClassicLinkKeyValid();
47   }
48 
49   /**
50    * Returns true if Link Keys are stored persistently
51    */
IsBonded()52   bool IsBonded() const {
53     return IsPaired() && persisted_;
54   }
55 
56   /**
57    * Called by storage manager once record has persisted
58    */
SetPersisted(bool persisted)59   void SetPersisted(bool persisted) {
60     persisted_ = persisted;
61   }
62 
SetLinkKey(std::array<uint8_t,16> link_key,hci::KeyType key_type)63   void SetLinkKey(std::array<uint8_t, 16> link_key, hci::KeyType key_type) {
64     link_key_ = link_key;
65     key_type_ = key_type;
66     CancelPairing();
67   }
68 
CancelPairing()69   void CancelPairing() {
70     pairing_ = false;
71   }
72 
GetLinkKey()73   std::array<uint8_t, 16> GetLinkKey() {
74     ASSERT(IsClassicLinkKeyValid());
75     return link_key_;
76   }
77 
GetKeyType()78   hci::KeyType GetKeyType() {
79     ASSERT(IsClassicLinkKeyValid());
80     return key_type_;
81   }
82 
GetPseudoAddress()83   hci::AddressWithType GetPseudoAddress() {
84     return pseudo_address_;
85   }
86 
SetAuthenticated(bool is_authenticated)87   void SetAuthenticated(bool is_authenticated) {
88     this->is_authenticated_ = is_authenticated;
89   }
90 
IsAuthenticated()91   bool IsAuthenticated() {
92     return this->is_authenticated_;
93   }
94 
SetRequiresMitmProtection(bool requires_mitm_protection)95   void SetRequiresMitmProtection(bool requires_mitm_protection) {
96     this->requires_mitm_protection_ = requires_mitm_protection;
97   }
98 
RequiresMitmProtection()99   bool RequiresMitmProtection() {
100     return this->requires_mitm_protection_;
101   }
102 
SetIsEncryptionRequired(bool is_encryption_required)103   void SetIsEncryptionRequired(bool is_encryption_required) {
104     this->is_encryption_required_ = is_encryption_required;
105   }
106 
IsEncryptionRequired()107   bool IsEncryptionRequired() {
108     return this->is_encryption_required_;
109   }
110 
111  private:
112   /* First address we have ever seen this device with, that we used to create bond */
113   hci::AddressWithType pseudo_address_;
114 
115   std::array<uint8_t, 16> link_key_ = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
116   hci::KeyType key_type_ = hci::KeyType::DEBUG_COMBINATION;
117 
IsClassicLinkKeyValid()118   bool IsClassicLinkKeyValid() const {
119     return !std::all_of(link_key_.begin(), link_key_.end(), [](uint8_t b) { return b == 0; });
120   }
121   bool persisted_ = false;
122   bool pairing_ = false;
123   bool is_authenticated_ = false;
124   bool requires_mitm_protection_ = false;
125   bool is_encryption_required_ = false;
126 
127  public:
128   /* Identity Address */
129   std::optional<hci::AddressWithType> identity_address_;
130 
131   std::optional<crypto_toolbox::Octet16> ltk;
132   std::optional<uint16_t> ediv;
133   std::optional<std::array<uint8_t, 8>> rand;
134   std::optional<crypto_toolbox::Octet16> irk;
135   std::optional<crypto_toolbox::Octet16> signature_key;
136 };
137 
138 }  // namespace record
139 }  // namespace security
140 }  // namespace bluetooth
141