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 }
67 
AuthenticationRequestFinished()68 void SecurityManager::AuthenticationRequestFinished() {
69   authenticating_ = false;
70 }
71 
AuthenticationInProgress()72 bool SecurityManager::AuthenticationInProgress() {
73   return authenticating_;
74 }
75 
GetAuthenticationHandle()76 uint16_t SecurityManager::GetAuthenticationHandle() {
77   return current_handle_;
78 }
79 
GetAuthenticationAddress()80 Address SecurityManager::GetAuthenticationAddress() {
81   return peer_address_;
82 }
83 
SetPeerIoCapability(const Address & addr,uint8_t io_capability,uint8_t oob_present_flag,uint8_t authentication_requirements)84 void SecurityManager::SetPeerIoCapability(const Address& addr, uint8_t io_capability, uint8_t oob_present_flag,
85                                           uint8_t authentication_requirements) {
86   ASSERT(addr == peer_address_);
87   peer_capabilities_valid_ = true;
88   if (io_capability <= static_cast<uint8_t>(IoCapabilityType::NO_INPUT_NO_OUTPUT)) {
89     peer_io_capability_ = static_cast<IoCapabilityType>(io_capability);
90   } else {
91     peer_io_capability_ = IoCapabilityType::INVALID;
92     peer_capabilities_valid_ = false;
93   }
94   peer_oob_present_flag_ = (oob_present_flag == 1);
95   if (authentication_requirements <= static_cast<uint8_t>(AuthenticationType::GENERAL_BONDING_MITM)) {
96     peer_authentication_requirements_ = static_cast<AuthenticationType>(authentication_requirements);
97   } else {
98     peer_authentication_requirements_ = AuthenticationType::INVALID;
99     peer_capabilities_valid_ = false;
100   }
101 }
102 
SetLocalIoCapability(const Address & peer,uint8_t io_capability,uint8_t oob_present_flag,uint8_t authentication_requirements)103 void SecurityManager::SetLocalIoCapability(const Address& peer, uint8_t io_capability, uint8_t oob_present_flag,
104                                            uint8_t authentication_requirements) {
105   ASSERT(peer == peer_address_);
106   ASSERT_LOG(io_capability <= static_cast<uint8_t>(IoCapabilityType::NO_INPUT_NO_OUTPUT), "io_capability = %d",
107              static_cast<int>(io_capability));
108   ASSERT_LOG(oob_present_flag <= 1, "oob_present_flag = %hhx ", oob_present_flag);
109   ASSERT_LOG(authentication_requirements <= static_cast<uint8_t>(AuthenticationType::GENERAL_BONDING_MITM),
110              "authentication_requirements = %d", static_cast<int>(authentication_requirements));
111   host_io_capability_ = static_cast<IoCapabilityType>(io_capability);
112   host_oob_present_flag_ = (oob_present_flag == 1);
113   host_authentication_requirements_ = static_cast<AuthenticationType>(authentication_requirements);
114   host_capabilities_valid_ = true;
115 }
116 
InvalidateIoCapabilities()117 void SecurityManager::InvalidateIoCapabilities() {
118   host_capabilities_valid_ = false;
119   peer_capabilities_valid_ = false;
120 }
121 
GetSimplePairingType()122 PairingType SecurityManager::GetSimplePairingType() {
123   if (!host_capabilities_valid_ || !peer_capabilities_valid_) {
124     return PairingType::INVALID;
125   }
126   bool host_requires_mitm = (host_authentication_requirements_ == AuthenticationType::NO_BONDING_MITM) ||
127                             (host_authentication_requirements_ == AuthenticationType::DEDICATED_BONDING_MITM) ||
128                             (host_authentication_requirements_ == AuthenticationType::GENERAL_BONDING_MITM);
129   bool peer_requires_mitm = (peer_authentication_requirements_ == AuthenticationType::NO_BONDING_MITM) ||
130                             (peer_authentication_requirements_ == AuthenticationType::DEDICATED_BONDING_MITM) ||
131                             (peer_authentication_requirements_ == AuthenticationType::GENERAL_BONDING_MITM);
132   if (!(peer_requires_mitm || host_requires_mitm)) {
133     return PairingType::AUTO_CONFIRMATION;
134   }
135   LOG_INFO("%s: host does%s require peer does%s require MITM",
136            peer_address_.ToString().c_str(), host_requires_mitm ? "" : "n't",
137            peer_requires_mitm ? "" : "n't");
138   switch (peer_io_capability_) {
139     case IoCapabilityType::DISPLAY_ONLY:
140       switch (host_io_capability_) {
141         case IoCapabilityType::DISPLAY_ONLY:
142         case IoCapabilityType::DISPLAY_YES_NO:
143           return PairingType::AUTO_CONFIRMATION;
144         case IoCapabilityType::KEYBOARD_ONLY:
145           return PairingType::INPUT_PIN;
146         case IoCapabilityType::NO_INPUT_NO_OUTPUT:
147           return PairingType::AUTO_CONFIRMATION;
148         default:
149           return PairingType::INVALID;
150       }
151     case IoCapabilityType::DISPLAY_YES_NO:
152       switch (host_io_capability_) {
153         case IoCapabilityType::DISPLAY_ONLY:
154           return PairingType::AUTO_CONFIRMATION;
155         case IoCapabilityType::DISPLAY_YES_NO:
156           return PairingType::DISPLAY_AND_CONFIRM;
157         case IoCapabilityType::KEYBOARD_ONLY:
158           return PairingType::DISPLAY_PIN;
159         case IoCapabilityType::NO_INPUT_NO_OUTPUT:
160           return PairingType::AUTO_CONFIRMATION;
161         default:
162           return PairingType::INVALID;
163       }
164     case IoCapabilityType::KEYBOARD_ONLY:
165       switch (host_io_capability_) {
166         case IoCapabilityType::DISPLAY_ONLY:
167           return PairingType::DISPLAY_PIN;
168         case IoCapabilityType::DISPLAY_YES_NO:
169           return PairingType::DISPLAY_PIN;
170         case IoCapabilityType::KEYBOARD_ONLY:
171           return PairingType::INPUT_PIN;
172         case IoCapabilityType::NO_INPUT_NO_OUTPUT:
173           return PairingType::AUTO_CONFIRMATION;
174         default:
175           return PairingType::INVALID;
176       }
177     case IoCapabilityType::NO_INPUT_NO_OUTPUT:
178       return PairingType::AUTO_CONFIRMATION;
179     default:
180       return PairingType::INVALID;
181   }
182 }
183 
184 }  // namespace test_vendor_lib
185