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