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 #include "security/record/security_record_storage.h"
19 
20 #include "storage/mutation.h"
21 
22 namespace bluetooth {
23 namespace security {
24 namespace record {
25 
26 namespace {
SetClassicData(storage::Mutation & mutation,std::shared_ptr<record::SecurityRecord> record,storage::Device & device)27 void SetClassicData(
28     storage::Mutation& mutation, std::shared_ptr<record::SecurityRecord> record, storage::Device& device) {
29   if (*device.GetDeviceType() == hci::DeviceType::LE) {
30     return;
31   }
32   if (record->IsClassicLinkKeyValid()) {
33     LOG_WARN("Type: %d", static_cast<int>(*device.GetDeviceType()));
34     mutation.Add(device.Classic().SetLinkKey(record->GetLinkKey()));
35     mutation.Add(device.Classic().SetLinkKeyType(record->GetKeyType()));
36   }
37 }
38 
SetLeData(storage::Mutation & mutation,std::shared_ptr<record::SecurityRecord> record,storage::Device & device)39 void SetLeData(storage::Mutation& mutation, std::shared_ptr<record::SecurityRecord> record, storage::Device& device) {
40   if (*device.GetDeviceType() == hci::DeviceType::BR_EDR) {
41     return;
42   }
43 
44   auto le_device = device.Le();
45 
46   if (record->identity_address_) {
47     mutation.Add(le_device.SetAddressType(record->identity_address_->GetAddressType()));
48   }
49 
50   if (record->remote_irk) {
51     std::array<uint8_t, 23> peerid;
52     std::copy_n(record->remote_irk->data(), record->remote_irk->size(), peerid.data());
53     peerid[16] = static_cast<uint8_t>(record->identity_address_->GetAddressType());
54     std::copy_n(record->identity_address_->GetAddress().data(), 6, peerid.data() + 17);
55 
56     common::ByteArray<23> byte_array(peerid);
57     mutation.Add(le_device.SetPeerId(byte_array.ToString()));
58   }
59 
60   if (record->pseudo_address_) {
61     mutation.Add(le_device.SetLegacyPseudoAddress(record->pseudo_address_->GetAddress()));
62   }
63 
64   if (record->remote_ltk) {
65     std::array<uint8_t, 28> penc_keys;
66 
67     std::copy_n(record->remote_ltk->data(), record->remote_ltk->size(), penc_keys.data());
68     std::copy_n(record->remote_rand->data(), record->remote_rand->size(), penc_keys.data() + 16);
69     uint16_t* ediv_location = (uint16_t*)(penc_keys.data() + 24);
70     *ediv_location = *record->remote_ediv;
71     penc_keys[26] = record->security_level;
72     penc_keys[27] = record->key_size;
73 
74     common::ByteArray<28> byte_array(penc_keys);
75     mutation.Add(le_device.SetPeerEncryptionKeys(byte_array.ToString()));
76   }
77 
78   if (record->remote_signature_key) {
79     std::array<uint8_t, 21> psrk_keys;
80 
81     // four bytes counter, all zeros
82     *psrk_keys.data() = 0;
83     *(psrk_keys.data() + 1) = 0;
84     *(psrk_keys.data() + 2) = 0;
85     *(psrk_keys.data() + 3) = 0;
86     std::copy_n(record->remote_signature_key->data(), record->remote_signature_key->size(), psrk_keys.data() + 4);
87     *(psrk_keys.data() + 20) = record->security_level;
88 
89     common::ByteArray<21> byte_array(psrk_keys);
90     mutation.Add(le_device.SetPeerSignatureResolvingKeys(byte_array.ToString()));
91   }
92 }
93 
SetAuthenticationData(storage::Mutation & mutation,std::shared_ptr<record::SecurityRecord> record,storage::Device & device)94 void SetAuthenticationData(storage::Mutation& mutation, std::shared_ptr<record::SecurityRecord> record, storage::Device& device) {
95   device.SetIsAuthenticated((record->IsAuthenticated() ? 1 : 0));
96   device.SetIsEncryptionRequired((record->IsEncryptionRequired() ? 1 : 0));
97   device.SetRequiresMitmProtection(record->RequiresMitmProtection() ? 1 : 0);
98 }
99 }  // namespace
100 
SecurityRecordStorage(storage::StorageModule * storage_module,os::Handler * handler)101 SecurityRecordStorage::SecurityRecordStorage(storage::StorageModule* storage_module, os::Handler* handler)
102     : storage_module_(storage_module), handler_(handler) {}
103 
SaveSecurityRecords(std::set<std::shared_ptr<record::SecurityRecord>> * records)104 void SecurityRecordStorage::SaveSecurityRecords(std::set<std::shared_ptr<record::SecurityRecord>>* records) {
105   for (auto record : *records) {
106     if (record->IsTemporary()) continue;
107     storage::Device device = storage_module_->GetDeviceByClassicMacAddress(record->GetPseudoAddress()->GetAddress());
108     auto mutation = storage_module_->Modify();
109 
110     if (record->IsClassicLinkKeyValid() && !record->identity_address_) {
111       mutation.Add(device.SetDeviceType(hci::DeviceType::BR_EDR));
112     } else if (record->IsClassicLinkKeyValid() && record->remote_ltk) {
113       mutation.Add(device.SetDeviceType(hci::DeviceType::DUAL));
114     } else if (!record->IsClassicLinkKeyValid() && record->remote_ltk) {
115       mutation.Add(device.SetDeviceType(hci::DeviceType::LE));
116     } else {
117       LOG_ERROR(
118           "Cannot determine device type from security record for '%s'; dropping!",
119           record->GetPseudoAddress()->ToString().c_str());
120       continue;
121     }
122     mutation.Commit();
123     SetClassicData(mutation, record, device);
124     SetLeData(mutation, record, device);
125     SetAuthenticationData(mutation, record, device);
126     mutation.Commit();
127   }
128 }
129 
LoadSecurityRecords(std::set<std::shared_ptr<record::SecurityRecord>> * records)130 void SecurityRecordStorage::LoadSecurityRecords(std::set<std::shared_ptr<record::SecurityRecord>>* records) {
131   for (auto device : storage_module_->GetBondedDevices()) {
132     auto address_type = (device.GetDeviceType() == hci::DeviceType::BR_EDR) ? hci::AddressType::PUBLIC_DEVICE_ADDRESS
133                                                                             : device.Le().GetAddressType();
134     auto address_with_type = hci::AddressWithType(device.GetAddress(), *address_type);
135 
136     auto record = std::make_shared<record::SecurityRecord>(address_with_type);
137     if (device.GetDeviceType() != hci::DeviceType::LE) {
138       record->SetLinkKey(device.Classic().GetLinkKey()->bytes, *device.Classic().GetLinkKeyType());
139     }
140     if (device.GetDeviceType() != hci::DeviceType::BR_EDR) {
141       record->pseudo_address_ = std::make_optional<hci::AddressWithType>(
142           *device.Le().GetLegacyPseudoAddress(), *device.Le().GetAddressType());
143 
144       if (device.Le().GetPeerId()) {
145         auto peerid = common::ByteArray<23>::FromString(*device.Le().GetPeerId());
146         record->remote_irk = std::make_optional<std::array<uint8_t, 16>>();
147         std::copy_n(peerid->data(), record->remote_irk->size(), record->remote_irk->data());
148 
149         uint8_t idaddress_type;
150         hci::Address idaddress;
151         std::copy_n(peerid->data() + 16, 1, &idaddress_type);
152         std::copy_n(peerid->data() + 17, 6, idaddress.data());
153         record->identity_address_ =
154             std::make_optional<hci::AddressWithType>(idaddress, static_cast<hci::AddressType>(idaddress_type));
155       }
156 
157       if (device.Le().GetPeerEncryptionKeys()) {
158         auto peer_encryption_keys = common::ByteArray<28>::FromString(*device.Le().GetPeerEncryptionKeys());
159         record->remote_ltk = std::make_optional<std::array<uint8_t, 16>>();
160         record->remote_rand = std::make_optional<std::array<uint8_t, 8>>();
161         record->remote_ediv = std::make_optional(0);
162 
163         std::copy_n(peer_encryption_keys->data(), 16, record->remote_ltk->data());
164         std::copy_n(peer_encryption_keys->data() + 16, 8, record->remote_rand->data());
165         std::copy_n(peer_encryption_keys->data() + 24, 2, &(*record->remote_ediv));
166         record->security_level = peer_encryption_keys->data()[26];
167         record->key_size = peer_encryption_keys->data()[27];
168       }
169 
170       if (device.Le().GetPeerSignatureResolvingKeys()) {
171         auto peer_signature_resolving_keys =
172             common::ByteArray<21>::FromString(*device.Le().GetPeerSignatureResolvingKeys());
173         record->remote_signature_key = std::make_optional<std::array<uint8_t, 16>>();
174 
175         std::copy_n(peer_signature_resolving_keys->data() + 4, 16, record->remote_signature_key->data());
176         record->security_level = peer_signature_resolving_keys->data()[20];
177       }
178     }
179     record->SetIsEncryptionRequired(device.GetIsEncryptionRequired() == 1 ? true : false);
180     record->SetAuthenticated(device.GetIsAuthenticated() == 1 ? true : false);
181     record->SetRequiresMitmProtection(device.GetRequiresMitmProtection() == 1 ? true : false);
182     records->insert(record);
183   }
184 }
185 
RemoveDevice(hci::AddressWithType address)186 void SecurityRecordStorage::RemoveDevice(hci::AddressWithType address) {
187   storage::Device device = storage_module_->GetDeviceByClassicMacAddress(address.GetAddress());
188   auto mutation = storage_module_->Modify();
189   mutation.Add(device.RemoveFromConfig());
190   mutation.Commit();
191 }
192 
193 }  // namespace record
194 }  // namespace security
195 }  // namespace bluetooth
196