1 /*
2  * Copyright 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "security_manager.h"
18 
19 #include "os/log.h"
20 
21 using std::vector;
22 
23 namespace test_vendor_lib {
24 
DeleteAllKeys()25 uint16_t SecurityManager::DeleteAllKeys() {
26   uint16_t size = key_store_.size();
27   key_store_.clear();
28   return size;
29 }
30 
DeleteKey(const Address & addr)31 uint16_t SecurityManager::DeleteKey(const Address& addr) {
32   uint16_t count = key_store_.count(addr.ToString());
33   if (count) {
34     key_store_.erase(addr.ToString());
35   }
36   return count;
37 }
38 
ReadAllKeys() const39 uint16_t SecurityManager::ReadAllKeys() const {
40   return key_store_.size();
41 }
42 
ReadKey(const Address & addr) const43 uint16_t SecurityManager::ReadKey(const Address& addr) const {
44   return key_store_.count(addr.ToString());
45 }
46 
WriteKey(const Address & addr,const std::array<uint8_t,16> & key)47 uint16_t SecurityManager::WriteKey(const Address& addr,
48                                    const std::array<uint8_t, 16>& key) {
49   if (key_store_.size() >= max_keys_) {
50     return 0;
51   }
52   key_store_[addr.ToString()] = key;
53   return 1;
54 }
55 
GetKey(const Address & addr) const56 const std::array<uint8_t, 16>& SecurityManager::GetKey(
57     const Address& addr) const {
58   ASSERT_LOG(ReadKey(addr), "No such key");
59   return key_store_.at(addr.ToString());
60 }
61 
AuthenticationRequest(const Address & addr,uint16_t handle)62 void SecurityManager::AuthenticationRequest(const Address& addr, uint16_t handle) {
63   authenticating_ = true;
64   current_handle_ = handle;
65   peer_address_ = addr;
66   peer_pin_requested_ = false;
67   peer_pin_received_ = false;
68   host_pin_received_ = false;
69 }
70 
AuthenticationRequestFinished()71 void SecurityManager::AuthenticationRequestFinished() {
72   authenticating_ = false;
73 }
74 
AuthenticationInProgress()75 bool SecurityManager::AuthenticationInProgress() {
76   return authenticating_;
77 }
78 
GetAuthenticationHandle()79 uint16_t SecurityManager::GetAuthenticationHandle() {
80   return current_handle_;
81 }
82 
GetAuthenticationAddress()83 Address SecurityManager::GetAuthenticationAddress() {
84   return peer_address_;
85 }
86 
SetPeerIoCapability(const Address & addr,uint8_t io_capability,uint8_t oob_present_flag,uint8_t authentication_requirements)87 void SecurityManager::SetPeerIoCapability(const Address& addr, uint8_t io_capability, uint8_t oob_present_flag,
88                                           uint8_t authentication_requirements) {
89   ASSERT(addr == peer_address_);
90   peer_capabilities_valid_ = true;
91   if (io_capability <= static_cast<uint8_t>(IoCapabilityType::NO_INPUT_NO_OUTPUT)) {
92     peer_io_capability_ = static_cast<IoCapabilityType>(io_capability);
93   } else {
94     peer_io_capability_ = IoCapabilityType::INVALID;
95     peer_capabilities_valid_ = false;
96   }
97   peer_oob_present_flag_ = oob_present_flag;
98   if (authentication_requirements <= static_cast<uint8_t>(AuthenticationType::GENERAL_BONDING_MITM)) {
99     peer_authentication_requirements_ = static_cast<AuthenticationType>(authentication_requirements);
100   } else {
101     peer_authentication_requirements_ = AuthenticationType::INVALID;
102     peer_capabilities_valid_ = false;
103   }
104 }
105 
SetLocalIoCapability(const Address & peer,uint8_t io_capability,uint8_t oob_present_flag,uint8_t authentication_requirements)106 void SecurityManager::SetLocalIoCapability(const Address& peer, uint8_t io_capability, uint8_t oob_present_flag,
107                                            uint8_t authentication_requirements) {
108   ASSERT(peer == peer_address_);
109   ASSERT_LOG(io_capability <= static_cast<uint8_t>(IoCapabilityType::NO_INPUT_NO_OUTPUT), "io_capability = %d",
110              static_cast<int>(io_capability));
111   ASSERT_LOG(oob_present_flag <= 3, "oob_present_flag = %hhx ",
112              oob_present_flag);
113   ASSERT_LOG(authentication_requirements <= static_cast<uint8_t>(AuthenticationType::GENERAL_BONDING_MITM),
114              "authentication_requirements = %d", static_cast<int>(authentication_requirements));
115   host_io_capability_ = static_cast<IoCapabilityType>(io_capability);
116   host_oob_present_flag_ = oob_present_flag;
117   host_authentication_requirements_ = static_cast<AuthenticationType>(authentication_requirements);
118   host_capabilities_valid_ = true;
119 }
120 
InvalidateIoCapabilities()121 void SecurityManager::InvalidateIoCapabilities() {
122   host_capabilities_valid_ = false;
123   peer_capabilities_valid_ = false;
124 }
125 
GetSimplePairingType()126 PairingType SecurityManager::GetSimplePairingType() {
127   if (!host_capabilities_valid_ || !peer_capabilities_valid_) {
128     return PairingType::INVALID;
129   }
130   bool host_requires_mitm = (host_authentication_requirements_ == AuthenticationType::NO_BONDING_MITM) ||
131                             (host_authentication_requirements_ == AuthenticationType::DEDICATED_BONDING_MITM) ||
132                             (host_authentication_requirements_ == AuthenticationType::GENERAL_BONDING_MITM);
133   bool peer_requires_mitm = (peer_authentication_requirements_ == AuthenticationType::NO_BONDING_MITM) ||
134                             (peer_authentication_requirements_ == AuthenticationType::DEDICATED_BONDING_MITM) ||
135                             (peer_authentication_requirements_ == AuthenticationType::GENERAL_BONDING_MITM);
136   if (peer_oob_present_flag_ != 0 || host_oob_present_flag_ != 0) {
137     if (host_oob_present_flag_ == 0) {
138       return PairingType::PEER_HAS_OUT_OF_BAND;
139     } else {
140       return PairingType::OUT_OF_BAND;
141     }
142   }
143   if (!(peer_requires_mitm || host_requires_mitm)) {
144     return PairingType::AUTO_CONFIRMATION;
145   }
146   LOG_INFO("%s: host does%s require peer does%s require MITM",
147            peer_address_.ToString().c_str(), host_requires_mitm ? "" : "n't",
148            peer_requires_mitm ? "" : "n't");
149   switch (peer_io_capability_) {
150     case IoCapabilityType::DISPLAY_ONLY:
151       switch (host_io_capability_) {
152         case IoCapabilityType::DISPLAY_ONLY:
153         case IoCapabilityType::DISPLAY_YES_NO:
154           return PairingType::AUTO_CONFIRMATION;
155         case IoCapabilityType::KEYBOARD_ONLY:
156           return PairingType::INPUT_PIN;
157         case IoCapabilityType::NO_INPUT_NO_OUTPUT:
158           return PairingType::AUTO_CONFIRMATION;
159         case IoCapabilityType::INVALID:
160           return PairingType::INVALID;
161       }
162     case IoCapabilityType::DISPLAY_YES_NO:
163       switch (host_io_capability_) {
164         case IoCapabilityType::DISPLAY_ONLY:
165           return PairingType::AUTO_CONFIRMATION;
166         case IoCapabilityType::DISPLAY_YES_NO:
167           return PairingType::DISPLAY_AND_CONFIRM;
168         case IoCapabilityType::KEYBOARD_ONLY:
169           return PairingType::INPUT_PIN;
170         case IoCapabilityType::NO_INPUT_NO_OUTPUT:
171           return PairingType::AUTO_CONFIRMATION;
172         case IoCapabilityType::INVALID:
173           return PairingType::INVALID;
174       }
175     case IoCapabilityType::KEYBOARD_ONLY:
176       switch (host_io_capability_) {
177         case IoCapabilityType::DISPLAY_ONLY:
178         case IoCapabilityType::DISPLAY_YES_NO:
179           return PairingType::DISPLAY_PIN;
180         case IoCapabilityType::KEYBOARD_ONLY:
181           return PairingType::INPUT_PIN;
182         case IoCapabilityType::NO_INPUT_NO_OUTPUT:
183           return PairingType::AUTO_CONFIRMATION;
184         case IoCapabilityType::INVALID:
185           return PairingType::INVALID;
186       }
187     case IoCapabilityType::NO_INPUT_NO_OUTPUT:
188       return PairingType::AUTO_CONFIRMATION;
189     case IoCapabilityType::INVALID:
190       return PairingType::INVALID;
191   }
192 }
193 
SetPinRequested(const Address & addr)194 void SecurityManager::SetPinRequested(const Address& addr) {
195   ASSERT(addr == peer_address_);
196   peer_pin_requested_ = true;
197 }
198 
GetPinRequested(const Address & addr)199 bool SecurityManager::GetPinRequested(const Address& addr) {
200   return peer_pin_requested_;
201 }
202 
SetLocalPin(const Address & peer,const std::vector<uint8_t> & pin)203 void SecurityManager::SetLocalPin(const Address& peer,
204                                   const std::vector<uint8_t>& pin) {
205   host_pin_received_ = true;
206   host_pin_ = pin;
207 }
208 
SetRemotePin(const Address & peer,const std::vector<uint8_t> & pin)209 void SecurityManager::SetRemotePin(const Address& peer,
210                                    const std::vector<uint8_t>& pin) {
211   peer_pin_received_ = true;
212   peer_pin_ = pin;
213 }
214 
GetLocalPinResponseReceived(const Address & peer)215 bool SecurityManager::GetLocalPinResponseReceived(const Address& peer) {
216   return host_pin_received_;
217 }
218 
GetRemotePinResponseReceived(const Address & peer)219 bool SecurityManager::GetRemotePinResponseReceived(const Address& peer) {
220   return peer_pin_received_;
221 }
222 
PinCompare()223 bool SecurityManager::PinCompare() {
224   return host_pin_received_ && peer_pin_received_ && peer_pin_ == host_pin_;
225 }
226 }  // namespace test_vendor_lib
227