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