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 "log.h"
20
21 using std::vector;
22
23 namespace rootcanal {
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 { return key_store_.size(); }
40
ReadKey(const Address & addr) const41 uint16_t SecurityManager::ReadKey(const Address& addr) const {
42 return key_store_.count(addr.ToString());
43 }
44
WriteKey(const Address & addr,const std::array<uint8_t,16> & key)45 uint16_t SecurityManager::WriteKey(const Address& addr,
46 const std::array<uint8_t, 16>& key) {
47 if (key_store_.size() >= max_keys_) {
48 return 0;
49 }
50 key_store_[addr.ToString()] = key;
51 return 1;
52 }
53
GetKey(const Address & addr) const54 const std::array<uint8_t, 16>& SecurityManager::GetKey(
55 const Address& addr) const {
56 ASSERT_LOG(ReadKey(addr), "No such key");
57 return key_store_.at(addr.ToString());
58 }
59
AuthenticationRequest(const Address & addr,uint16_t handle,bool initiator)60 void SecurityManager::AuthenticationRequest(const Address& addr,
61 uint16_t handle, bool initiator) {
62 authenticating_ = true;
63 current_handle_ = handle;
64 peer_address_ = addr;
65 initiator_ = initiator;
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() { return authenticating_; }
76
IsInitiator()77 bool SecurityManager::IsInitiator() { return initiator_; }
78
GetAuthenticationHandle()79 uint16_t SecurityManager::GetAuthenticationHandle() { return current_handle_; }
80
GetAuthenticationAddress()81 Address SecurityManager::GetAuthenticationAddress() { return peer_address_; }
82
SetPeerIoCapability(const Address & addr,uint8_t io_capability,uint8_t oob_present_flag,uint8_t authentication_requirements)83 void SecurityManager::SetPeerIoCapability(const Address& addr,
84 uint8_t io_capability,
85 uint8_t oob_present_flag,
86 uint8_t authentication_requirements) {
87 ASSERT(addr == peer_address_);
88 peer_capabilities_valid_ = true;
89 if (io_capability <=
90 static_cast<uint8_t>(IoCapabilityType::NO_INPUT_NO_OUTPUT)) {
91 peer_io_capability_ = static_cast<IoCapabilityType>(io_capability);
92 } else {
93 peer_io_capability_ = IoCapabilityType::INVALID;
94 peer_capabilities_valid_ = false;
95 }
96 peer_oob_present_flag_ = oob_present_flag;
97 if (authentication_requirements <=
98 static_cast<uint8_t>(AuthenticationType::GENERAL_BONDING_MITM)) {
99 peer_authentication_requirements_ =
100 static_cast<AuthenticationType>(authentication_requirements);
101 } else {
102 peer_authentication_requirements_ = AuthenticationType::INVALID;
103 peer_capabilities_valid_ = false;
104 }
105 }
106
SetLocalIoCapability(const Address & peer,uint8_t io_capability,uint8_t oob_present_flag,uint8_t authentication_requirements)107 void SecurityManager::SetLocalIoCapability(
108 const Address& peer, uint8_t io_capability, uint8_t oob_present_flag,
109 uint8_t authentication_requirements) {
110 ASSERT(peer == peer_address_);
111 ASSERT_LOG(io_capability <=
112 static_cast<uint8_t>(IoCapabilityType::NO_INPUT_NO_OUTPUT),
113 "io_capability = %d", static_cast<int>(io_capability));
114 ASSERT_LOG(oob_present_flag <= 3, "oob_present_flag = %hhx ",
115 oob_present_flag);
116 ASSERT_LOG(authentication_requirements <=
117 static_cast<uint8_t>(AuthenticationType::GENERAL_BONDING_MITM),
118 "authentication_requirements = %d",
119 static_cast<int>(authentication_requirements));
120 host_io_capability_ = static_cast<IoCapabilityType>(io_capability);
121 host_oob_present_flag_ = oob_present_flag;
122 host_authentication_requirements_ =
123 static_cast<AuthenticationType>(authentication_requirements);
124 host_capabilities_valid_ = true;
125 }
126
InvalidateIoCapabilities()127 void SecurityManager::InvalidateIoCapabilities() {
128 host_capabilities_valid_ = false;
129 peer_capabilities_valid_ = false;
130 }
131
GetSimplePairingType()132 PairingType SecurityManager::GetSimplePairingType() {
133 if (!host_capabilities_valid_ || !peer_capabilities_valid_) {
134 return PairingType::INVALID;
135 }
136 bool host_requires_mitm = (host_authentication_requirements_ ==
137 AuthenticationType::NO_BONDING_MITM) ||
138 (host_authentication_requirements_ ==
139 AuthenticationType::DEDICATED_BONDING_MITM) ||
140 (host_authentication_requirements_ ==
141 AuthenticationType::GENERAL_BONDING_MITM);
142 bool peer_requires_mitm = (peer_authentication_requirements_ ==
143 AuthenticationType::NO_BONDING_MITM) ||
144 (peer_authentication_requirements_ ==
145 AuthenticationType::DEDICATED_BONDING_MITM) ||
146 (peer_authentication_requirements_ ==
147 AuthenticationType::GENERAL_BONDING_MITM);
148 if (peer_oob_present_flag_ != 0 || host_oob_present_flag_ != 0) {
149 if (host_oob_present_flag_ == 0) {
150 return PairingType::PEER_HAS_OUT_OF_BAND;
151 } else {
152 return PairingType::OUT_OF_BAND;
153 }
154 }
155 if (!(peer_requires_mitm || host_requires_mitm)) {
156 return PairingType::AUTO_CONFIRMATION;
157 }
158 LOG_INFO("%s: host does%s require peer does%s require MITM",
159 peer_address_.ToString().c_str(), host_requires_mitm ? "" : "n't",
160 peer_requires_mitm ? "" : "n't");
161 switch (peer_io_capability_) {
162 case IoCapabilityType::DISPLAY_ONLY:
163 switch (host_io_capability_) {
164 case IoCapabilityType::DISPLAY_ONLY:
165 case IoCapabilityType::DISPLAY_YES_NO:
166 return PairingType::AUTO_CONFIRMATION;
167 case IoCapabilityType::KEYBOARD_ONLY:
168 return PairingType::INPUT_PIN;
169 case IoCapabilityType::NO_INPUT_NO_OUTPUT:
170 return PairingType::AUTO_CONFIRMATION;
171 case IoCapabilityType::INVALID:
172 return PairingType::INVALID;
173 }
174 case IoCapabilityType::DISPLAY_YES_NO:
175 switch (host_io_capability_) {
176 case IoCapabilityType::DISPLAY_ONLY:
177 return PairingType::AUTO_CONFIRMATION;
178 case IoCapabilityType::DISPLAY_YES_NO:
179 return PairingType::DISPLAY_AND_CONFIRM;
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::KEYBOARD_ONLY:
188 switch (host_io_capability_) {
189 case IoCapabilityType::DISPLAY_ONLY:
190 case IoCapabilityType::DISPLAY_YES_NO:
191 return PairingType::DISPLAY_PIN;
192 case IoCapabilityType::KEYBOARD_ONLY:
193 return PairingType::INPUT_PIN;
194 case IoCapabilityType::NO_INPUT_NO_OUTPUT:
195 return PairingType::AUTO_CONFIRMATION;
196 case IoCapabilityType::INVALID:
197 return PairingType::INVALID;
198 }
199 case IoCapabilityType::NO_INPUT_NO_OUTPUT:
200 return PairingType::AUTO_CONFIRMATION;
201 case IoCapabilityType::INVALID:
202 return PairingType::INVALID;
203 }
204 }
205
SetPinRequested(const Address & addr)206 void SecurityManager::SetPinRequested(const Address& addr) {
207 ASSERT(addr == peer_address_);
208 peer_pin_requested_ = true;
209 }
210
GetPinRequested(const Address & addr)211 bool SecurityManager::GetPinRequested(const Address& addr) {
212 ASSERT(addr == peer_address_);
213 return peer_pin_requested_;
214 }
215
SetLocalPin(const Address & peer,const std::vector<uint8_t> & pin)216 void SecurityManager::SetLocalPin(const Address& peer,
217 const std::vector<uint8_t>& pin) {
218 ASSERT(peer == peer_address_);
219 host_pin_received_ = true;
220 host_pin_ = pin;
221 }
222
SetRemotePin(const Address & peer,const std::vector<uint8_t> & pin)223 void SecurityManager::SetRemotePin(const Address& peer,
224 const std::vector<uint8_t>& pin) {
225 ASSERT(peer == peer_address_);
226 peer_pin_received_ = true;
227 peer_pin_ = pin;
228 }
229
GetLocalPinResponseReceived(const Address & peer)230 bool SecurityManager::GetLocalPinResponseReceived(const Address& peer) {
231 ASSERT(peer == peer_address_);
232 return host_pin_received_;
233 }
234
GetRemotePinResponseReceived(const Address & peer)235 bool SecurityManager::GetRemotePinResponseReceived(const Address& peer) {
236 ASSERT(peer == peer_address_);
237 return peer_pin_received_;
238 }
239
PinCompare()240 bool SecurityManager::PinCompare() {
241 return host_pin_received_ && peer_pin_received_ && peer_pin_ == host_pin_;
242 }
243 } // namespace rootcanal
244