1 /*
2 * Copyright 2023 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_event_parser.h"
18
19 #include <bluetooth/log.h>
20
21 #include <optional>
22 #include <string>
23
24 #include "btm_sec.h"
25 #include "common/metrics.h"
26 #include "hci/hci_packets.h"
27 #include "main/shim/helpers.h"
28 #include "stack/include/btm_sec_api_types.h"
29 #include "stack/include/hci_error_code.h"
30 #include "stack/include/sec_hci_link_interface.h"
31 #include "stack/include/stack_metrics_logging.h"
32 #include "types/raw_address.h"
33
34 using namespace bluetooth;
35 using namespace bluetooth::hci;
36 using android::bluetooth::hci::CMD_UNKNOWN;
37 using android::bluetooth::hci::STATUS_UNKNOWN;
38 using bluetooth::common::kUnknownConnectionHandle;
39
40 namespace bluetooth::stack::btm {
41 namespace {
log_address_and_status(const Address & bda,EventCode event_code,ErrorCode event_status)42 static void log_address_and_status(const Address& bda, EventCode event_code,
43 ErrorCode event_status) {
44 uint32_t cmd = android::bluetooth::hci::CMD_UNKNOWN;
45 uint16_t status = static_cast<uint16_t>(event_status);
46 uint16_t reason = android::bluetooth::hci::STATUS_UNKNOWN;
47 uint16_t handle = bluetooth::common::kUnknownConnectionHandle;
48 int64_t value = 0;
49 log_classic_pairing_event(ToRawAddress(bda), handle, cmd, static_cast<uint16_t>(event_code),
50 status, reason, value);
51 }
log_address(const Address & bda,EventCode event_code)52 static void log_address(const Address& bda, EventCode event_code) {
53 uint32_t cmd = android::bluetooth::hci::CMD_UNKNOWN;
54 uint16_t status = android::bluetooth::hci::STATUS_UNKNOWN;
55 uint16_t reason = android::bluetooth::hci::STATUS_UNKNOWN;
56 uint16_t handle = bluetooth::common::kUnknownConnectionHandle;
57 int64_t value = 0;
58 log_classic_pairing_event(ToRawAddress(bda), handle, cmd, static_cast<uint16_t>(event_code),
59 status, reason, value);
60 }
parse_encryption_change(const EventView event)61 static void parse_encryption_change(const EventView event) {
62 auto change_opt = EncryptionChangeView::CreateOptional(event);
63 log::assert_that(change_opt.has_value(), "assert failed: change_opt.has_value()");
64 auto change = change_opt.value();
65
66 ErrorCode status = change.GetStatus();
67 uint16_t handle = change.GetConnectionHandle();
68 EncryptionEnabled encr_enable = change.GetEncryptionEnabled();
69
70 btm_sec_encryption_change_evt(handle, static_cast<tHCI_STATUS>(status),
71 static_cast<uint8_t>(encr_enable), 0);
72 log_classic_pairing_event(
73 ToRawAddress(Address::kEmpty), handle, android::bluetooth::hci::CMD_UNKNOWN,
74 static_cast<uint32_t>(change.GetEventCode()), static_cast<uint16_t>(status),
75 android::bluetooth::hci::STATUS_UNKNOWN, 0);
76 }
parse_encryption_change_v2(const EventView event)77 static void parse_encryption_change_v2(const EventView event) {
78 auto change_opt = EncryptionChangeV2View::CreateOptional(event);
79 log::assert_that(change_opt.has_value(), "assert failed: change_opt.has_value()");
80 auto change = change_opt.value();
81
82 ErrorCode status = change.GetStatus();
83 uint16_t handle = change.GetConnectionHandle();
84 EncryptionEnabled encr_enable = change.GetEncryptionEnabled();
85 uint8_t key_size = change.GetKeySize();
86
87 btm_sec_encryption_change_evt(handle, static_cast<tHCI_STATUS>(status),
88 static_cast<uint8_t>(encr_enable), key_size);
89 log_classic_pairing_event(
90 ToRawAddress(Address::kEmpty), handle, android::bluetooth::hci::CMD_UNKNOWN,
91 static_cast<uint32_t>(change.GetEventCode()), static_cast<uint16_t>(status),
92 android::bluetooth::hci::STATUS_UNKNOWN, 0);
93 }
parse_change_connection_link_key_complete(const EventView event)94 static void parse_change_connection_link_key_complete(const EventView event) {
95 auto complete_opt = ChangeConnectionLinkKeyCompleteView::CreateOptional(event);
96 log::assert_that(complete_opt.has_value(), "assert failed: complete_opt.has_value()");
97 auto complete = complete_opt.value();
98
99 log_classic_pairing_event(
100 ToRawAddress(Address::kEmpty), complete.GetConnectionHandle(),
101 android::bluetooth::hci::CMD_UNKNOWN, static_cast<uint32_t>(complete.GetEventCode()),
102 static_cast<uint16_t>(complete.GetStatus()), android::bluetooth::hci::STATUS_UNKNOWN, 0);
103 }
parse_central_link_key_complete(const EventView event)104 static void parse_central_link_key_complete(const EventView event) {
105 auto event_opt = CentralLinkKeyCompleteView::CreateOptional(event);
106 log::assert_that(event_opt.has_value(), "assert failed: event_opt.has_value()");
107 auto complete = event_opt.value();
108
109 log::info("Unhandled event: {}", EventCodeText(event.GetEventCode()));
110 }
parse_return_link_keys(const EventView event)111 static void parse_return_link_keys(const EventView event) {
112 auto event_opt = ReturnLinkKeysView::CreateOptional(event);
113 log::assert_that(event_opt.has_value(), "assert failed: event_opt.has_value()");
114 auto view = event_opt.value();
115
116 log::info("Unhandled event: {}", EventCodeText(event.GetEventCode()));
117 }
parse_pin_code_request(const EventView event)118 static void parse_pin_code_request(const EventView event) {
119 auto event_opt = PinCodeRequestView::CreateOptional(event);
120 log::assert_that(event_opt.has_value(), "assert failed: event_opt.has_value()");
121 auto request = event_opt.value();
122 btm_sec_pin_code_request(ToRawAddress(request.GetBdAddr()));
123 }
parse_link_key_request(const EventView event)124 static void parse_link_key_request(const EventView event) {
125 auto event_opt = LinkKeyRequestView::CreateOptional(event);
126 log::assert_that(event_opt.has_value(), "assert failed: event_opt.has_value()");
127 auto request = event_opt.value();
128
129 btm_sec_link_key_request(ToRawAddress(request.GetBdAddr()));
130 log_address(request.GetBdAddr(), event.GetEventCode());
131 }
parse_link_key_notification(const EventView event)132 static void parse_link_key_notification(const EventView event) {
133 auto event_opt = LinkKeyNotificationView::CreateOptional(event);
134 log::assert_that(event_opt.has_value(), "assert failed: event_opt.has_value()");
135 auto notification = event_opt.value();
136
137 btm_sec_link_key_notification(ToRawAddress(notification.GetBdAddr()), notification.GetLinkKey(),
138 static_cast<uint8_t>(notification.GetKeyType()));
139 log_address(notification.GetBdAddr(), event.GetEventCode());
140 }
parse_encryption_key_refresh_complete(const EventView event)141 static void parse_encryption_key_refresh_complete(const EventView event) {
142 auto event_opt = EncryptionKeyRefreshCompleteView::CreateOptional(event);
143 log::assert_that(event_opt.has_value(), "assert failed: event_opt.has_value()");
144 auto refresh = event_opt.value();
145
146 btm_sec_encryption_key_refresh_complete(refresh.GetConnectionHandle(),
147 static_cast<tHCI_STATUS>(refresh.GetStatus()));
148 }
parse_io_capabilities_req(const EventView event)149 static void parse_io_capabilities_req(const EventView event) {
150 auto event_opt = IoCapabilityRequestView::CreateOptional(event);
151 log::assert_that(event_opt.has_value(), "assert failed: event_opt.has_value()");
152 auto request = event_opt.value();
153
154 RawAddress peer = ToRawAddress(request.GetBdAddr());
155
156 btm_io_capabilities_req(peer);
157 log_address(request.GetBdAddr(), event.GetEventCode());
158 }
parse_io_capabilities_rsp(const EventView event)159 static void parse_io_capabilities_rsp(const EventView event) {
160 auto response_opt = IoCapabilityResponseView::CreateOptional(event);
161 log::assert_that(response_opt.has_value(), "assert failed: response_opt.has_value()");
162 auto response = response_opt.value();
163
164 tBTM_SP_IO_RSP evt_data{
165 .bd_addr = ToRawAddress(response.GetBdAddr()),
166 .io_cap = static_cast<tBTM_IO_CAP>(response.GetIoCapability()),
167 .oob_data = static_cast<tBTM_OOB_DATA>(response.GetOobDataPresent()),
168 .auth_req = static_cast<tBTM_AUTH_REQ>(response.GetAuthenticationRequirements()),
169 };
170
171 btm_io_capabilities_rsp(evt_data);
172 log_address(response.GetBdAddr(), event.GetEventCode());
173 }
parse_remote_oob_data_request(const EventView event)174 static void parse_remote_oob_data_request(const EventView event) {
175 auto event_opt = RemoteOobDataRequestView::CreateOptional(event);
176 log::assert_that(event_opt.has_value(), "assert failed: event_opt.has_value()");
177 auto request = event_opt.value();
178
179 btm_rem_oob_req(ToRawAddress(request.GetBdAddr()));
180 log_address(request.GetBdAddr(), event.GetEventCode());
181 }
parse_simple_pairing_complete(const EventView event)182 static void parse_simple_pairing_complete(const EventView event) {
183 auto event_opt = SimplePairingCompleteView::CreateOptional(event);
184 log::assert_that(event_opt.has_value(), "assert failed: event_opt.has_value()");
185 auto complete = event_opt.value();
186
187 btm_simple_pair_complete(ToRawAddress(complete.GetBdAddr()),
188 static_cast<uint8_t>(complete.GetStatus()));
189 log_address_and_status(complete.GetBdAddr(), event.GetEventCode(), complete.GetStatus());
190 }
parse_user_passkey_notification(const EventView event)191 static void parse_user_passkey_notification(const EventView event) {
192 auto event_opt = UserPasskeyNotificationView::CreateOptional(event);
193 log::assert_that(event_opt.has_value(), "assert failed: event_opt.has_value()");
194 auto notification = event_opt.value();
195
196 btm_proc_sp_req_evt(BTM_SP_KEY_NOTIF_EVT, ToRawAddress(notification.GetBdAddr()),
197 notification.GetPasskey());
198 log_address(notification.GetBdAddr(), event.GetEventCode());
199 }
parse_keypress_notification(const EventView event)200 static void parse_keypress_notification(const EventView event) {
201 auto event_opt = KeypressNotificationView::CreateOptional(event);
202 log::assert_that(event_opt.has_value(), "assert failed: event_opt.has_value()");
203 auto notification = event_opt.value();
204
205 log::info("Unhandled event: {}", EventCodeText(event.GetEventCode()));
206 log_address(notification.GetBdAddr(), event.GetEventCode());
207 }
parse_user_confirmation_request(const EventView event)208 static void parse_user_confirmation_request(const EventView event) {
209 auto event_opt = UserConfirmationRequestView::CreateOptional(event);
210 log::assert_that(event_opt.has_value(), "assert failed: event_opt.has_value()");
211 auto request = event_opt.value();
212
213 btm_proc_sp_req_evt(BTM_SP_CFM_REQ_EVT, ToRawAddress(request.GetBdAddr()),
214 request.GetNumericValue());
215 log_address(request.GetBdAddr(), event.GetEventCode());
216 }
parse_user_passkey_request(const EventView event)217 static void parse_user_passkey_request(const EventView event) {
218 auto event_opt = UserPasskeyRequestView::CreateOptional(event);
219 log::assert_that(event_opt.has_value(), "assert failed: event_opt.has_value()");
220 auto request = event_opt.value();
221
222 btm_proc_sp_req_evt(BTM_SP_KEY_REQ_EVT, ToRawAddress(request.GetBdAddr()),
223 0 /* No value needed */);
224 log_address(request.GetBdAddr(), event.GetEventCode());
225 }
226 } // namespace
227 } // namespace bluetooth::stack::btm
228
229 namespace bluetooth::stack::btm {
230
OnSecurityEvent(bluetooth::hci::EventView event)231 void SecurityEventParser::OnSecurityEvent(bluetooth::hci::EventView event) {
232 switch (event.GetEventCode()) {
233 case EventCode::ENCRYPTION_CHANGE:
234 parse_encryption_change(event);
235 break;
236 case EventCode::CHANGE_CONNECTION_LINK_KEY_COMPLETE:
237 parse_change_connection_link_key_complete(event);
238 break;
239 case EventCode::CENTRAL_LINK_KEY_COMPLETE:
240 parse_central_link_key_complete(event);
241 break;
242 case EventCode::RETURN_LINK_KEYS:
243 parse_return_link_keys(event);
244 break;
245 case EventCode::PIN_CODE_REQUEST:
246 parse_pin_code_request(event);
247 break;
248 case EventCode::LINK_KEY_REQUEST:
249 parse_link_key_request(event);
250 break;
251 case EventCode::LINK_KEY_NOTIFICATION:
252 parse_link_key_notification(event);
253 break;
254 case EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE:
255 parse_encryption_key_refresh_complete(event);
256 break;
257 case EventCode::IO_CAPABILITY_REQUEST:
258 parse_io_capabilities_req(event);
259 break;
260 case EventCode::IO_CAPABILITY_RESPONSE:
261 parse_io_capabilities_rsp(event);
262 break;
263 case EventCode::REMOTE_OOB_DATA_REQUEST:
264 parse_remote_oob_data_request(event);
265 break;
266 case EventCode::SIMPLE_PAIRING_COMPLETE:
267 parse_simple_pairing_complete(event);
268 break;
269 case EventCode::USER_PASSKEY_NOTIFICATION:
270 parse_user_passkey_notification(event);
271 break;
272 case EventCode::KEYPRESS_NOTIFICATION:
273 parse_keypress_notification(event);
274 break;
275 case EventCode::USER_CONFIRMATION_REQUEST:
276 parse_user_confirmation_request(event);
277 break;
278 case EventCode::USER_PASSKEY_REQUEST:
279 parse_user_passkey_request(event);
280 break;
281 case EventCode::ENCRYPTION_CHANGE_V2:
282 parse_encryption_change_v2(event);
283 break;
284 default:
285 log::error("Unhandled event {}", EventCodeText(event.GetEventCode()));
286 }
287 }
288 } // namespace bluetooth::stack::btm
289