1 /****************************************************************************** 2 * 3 * Copyright (C) 2008-2012 Broadcom Corporation 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 19 /****************************************************************************** 20 * 21 * This file contains the implementation of the SMP interface used by 22 * applications that can run over an SMP. 23 * 24 ******************************************************************************/ 25 #include <base/logging.h> 26 #include <string.h> 27 28 #include "bt_target.h" 29 #include "bt_utils.h" 30 #include "stack_config.h" 31 32 #include "btm_int.h" 33 #include "hcimsgs.h" 34 #include "l2c_int.h" 35 #include "l2cdefs.h" 36 #include "smp_api.h" 37 #include "smp_int.h" 38 39 #include "btu.h" 40 #include "p_256_ecc_pp.h" 41 42 /******************************************************************************* 43 * 44 * Function SMP_Init 45 * 46 * Description This function initializes the SMP unit. 47 * 48 * Returns void 49 * 50 ******************************************************************************/ 51 void SMP_Init(void) { 52 memset(&smp_cb, 0, sizeof(tSMP_CB)); 53 smp_cb.smp_rsp_timer_ent = alarm_new("smp.smp_rsp_timer_ent"); 54 smp_cb.delayed_auth_timer_ent = alarm_new("smp.delayed_auth_timer_ent"); 55 56 #if defined(SMP_INITIAL_TRACE_LEVEL) 57 smp_cb.trace_level = SMP_INITIAL_TRACE_LEVEL; 58 #else 59 smp_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */ 60 #endif 61 SMP_TRACE_EVENT("%s", __func__); 62 63 smp_l2cap_if_init(); 64 /* initialization of P-256 parameters */ 65 p_256_init_curve(KEY_LENGTH_DWORDS_P256); 66 67 /* Initialize failure case for certification */ 68 smp_cb.cert_failure = 69 stack_config_get_interface()->get_pts_smp_failure_case(); 70 if (smp_cb.cert_failure) 71 SMP_TRACE_ERROR("%s PTS FAILURE MODE IN EFFECT (CASE %d)", __func__, 72 smp_cb.cert_failure); 73 } 74 75 /******************************************************************************* 76 * 77 * Function SMP_SetTraceLevel 78 * 79 * Description This function sets the trace level for SMP. If called with 80 * a value of 0xFF, it simply returns the current trace level. 81 * 82 * Input Parameters: 83 * level: The level to set the GATT tracing to: 84 * 0xff-returns the current setting. 85 * 0-turns off tracing. 86 * >= 1-Errors. 87 * >= 2-Warnings. 88 * >= 3-APIs. 89 * >= 4-Events. 90 * >= 5-Debug. 91 * 92 * Returns The new or current trace level 93 * 94 ******************************************************************************/ 95 extern uint8_t SMP_SetTraceLevel(uint8_t new_level) { 96 if (new_level != 0xFF) smp_cb.trace_level = new_level; 97 98 return (smp_cb.trace_level); 99 } 100 101 /******************************************************************************* 102 * 103 * Function SMP_Register 104 * 105 * Description This function register for the SMP services callback. 106 * 107 * Returns void 108 * 109 ******************************************************************************/ 110 bool SMP_Register(tSMP_CALLBACK* p_cback) { 111 SMP_TRACE_EVENT("SMP_Register state=%d", smp_cb.state); 112 113 if (smp_cb.p_callback != NULL) { 114 SMP_TRACE_ERROR("SMP_Register: duplicate registration, overwrite it"); 115 } 116 smp_cb.p_callback = p_cback; 117 118 return (true); 119 } 120 121 /******************************************************************************* 122 * 123 * Function SMP_Pair 124 * 125 * Description This function call to perform a SMP pairing with peer 126 * device. Device support one SMP pairing at one time. 127 * 128 * Parameters bd_addr - peer device bd address. 129 * 130 * Returns None 131 * 132 ******************************************************************************/ 133 tSMP_STATUS SMP_Pair(const RawAddress& bd_addr) { 134 tSMP_CB* p_cb = &smp_cb; 135 uint8_t status = SMP_PAIR_INTERNAL_ERR; 136 137 SMP_TRACE_EVENT("%s state=%d br_state=%d flag=0x%x ", __func__, p_cb->state, 138 p_cb->br_state, p_cb->flags); 139 if (p_cb->state != SMP_STATE_IDLE || 140 p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD || p_cb->smp_over_br) { 141 /* pending security on going, reject this one */ 142 return SMP_BUSY; 143 } else { 144 p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD; 145 p_cb->pairing_bda = bd_addr; 146 147 if (!L2CA_ConnectFixedChnl(L2CAP_SMP_CID, bd_addr)) { 148 SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.", __func__); 149 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status); 150 return status; 151 } 152 153 return SMP_STARTED; 154 } 155 } 156 157 /******************************************************************************* 158 * 159 * Function SMP_BR_PairWith 160 * 161 * Description This function is called to start a SMP pairing over BR/EDR. 162 * Device support one SMP pairing at one time. 163 * 164 * Parameters bd_addr - peer device bd address. 165 * 166 * Returns SMP_STARTED if pairing started, otherwise the reason for 167 * failure. 168 * 169 ******************************************************************************/ 170 tSMP_STATUS SMP_BR_PairWith(const RawAddress& bd_addr) { 171 tSMP_CB* p_cb = &smp_cb; 172 uint8_t status = SMP_PAIR_INTERNAL_ERR; 173 174 SMP_TRACE_EVENT("%s state=%d br_state=%d flag=0x%x ", __func__, p_cb->state, 175 p_cb->br_state, p_cb->flags); 176 177 if (p_cb->state != SMP_STATE_IDLE || p_cb->smp_over_br || 178 p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD) { 179 /* pending security on going, reject this one */ 180 return SMP_BUSY; 181 } 182 183 p_cb->role = HCI_ROLE_MASTER; 184 p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD; 185 p_cb->smp_over_br = true; 186 p_cb->pairing_bda = bd_addr; 187 188 if (!L2CA_ConnectFixedChnl(L2CAP_SMP_BR_CID, bd_addr)) { 189 SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.", __func__); 190 smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &status); 191 return status; 192 } 193 194 return SMP_STARTED; 195 } 196 197 /******************************************************************************* 198 * 199 * Function SMP_PairCancel 200 * 201 * Description This function call to cancel a SMP pairing with peer device. 202 * 203 * Parameters bd_addr - peer device bd address. 204 * 205 * Returns true - Pairining is cancelled 206 * 207 ******************************************************************************/ 208 bool SMP_PairCancel(const RawAddress& bd_addr) { 209 tSMP_CB* p_cb = &smp_cb; 210 uint8_t err_code = SMP_PAIR_FAIL_UNKNOWN; 211 bool status = false; 212 213 // PTS SMP failure test cases 214 if (p_cb->cert_failure == SMP_PASSKEY_ENTRY_FAIL || 215 p_cb->cert_failure == SMP_NUMERIC_COMPAR_FAIL) 216 err_code = p_cb->cert_failure; 217 218 BTM_TRACE_EVENT("SMP_CancelPair state=%d flag=0x%x ", p_cb->state, 219 p_cb->flags); 220 if (p_cb->state != SMP_STATE_IDLE && p_cb->pairing_bda == bd_addr) { 221 p_cb->is_pair_cancel = true; 222 SMP_TRACE_DEBUG("Cancel Pairing: set fail reason Unknown"); 223 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &err_code); 224 status = true; 225 } 226 227 return status; 228 } 229 /******************************************************************************* 230 * 231 * Function SMP_SecurityGrant 232 * 233 * Description This function is called to grant security process. 234 * 235 * Parameters bd_addr - peer device bd address. 236 * res - result of the operation SMP_SUCCESS if success. 237 * Otherwise, SMP_REPEATED_ATTEMPTS if too many 238 * attempts. 239 * 240 * Returns None 241 * 242 ******************************************************************************/ 243 void SMP_SecurityGrant(const RawAddress& bd_addr, uint8_t res) { 244 SMP_TRACE_EVENT("SMP_SecurityGrant "); 245 246 if (smp_cb.smp_over_br) { 247 if (smp_cb.br_state != SMP_BR_STATE_WAIT_APP_RSP || 248 smp_cb.cb_evt != SMP_SEC_REQUEST_EVT || smp_cb.pairing_bda != bd_addr) { 249 return; 250 } 251 252 /* clear the SMP_SEC_REQUEST_EVT event after get grant */ 253 /* avoid generating duplicate pair request */ 254 smp_cb.cb_evt = 0; 255 smp_br_state_machine_event(&smp_cb, SMP_BR_API_SEC_GRANT_EVT, &res); 256 return; 257 } 258 259 if (smp_cb.state != SMP_STATE_WAIT_APP_RSP || 260 smp_cb.cb_evt != SMP_SEC_REQUEST_EVT || smp_cb.pairing_bda != bd_addr) 261 return; 262 /* clear the SMP_SEC_REQUEST_EVT event after get grant */ 263 /* avoid generate duplicate pair request */ 264 smp_cb.cb_evt = 0; 265 smp_sm_event(&smp_cb, SMP_API_SEC_GRANT_EVT, &res); 266 } 267 268 /******************************************************************************* 269 * 270 * Function SMP_PasskeyReply 271 * 272 * Description This function is called after Security Manager submitted 273 * passkey request to the application. 274 * 275 * Parameters: bd_addr - Address of the device for which passkey was 276 * requested 277 * res - result of the operation SMP_SUCCESS if success 278 * passkey - numeric value in the range of 279 * BTM_MIN_PASSKEY_VAL(0) - 280 * BTM_MAX_PASSKEY_VAL(999999(0xF423F)). 281 * 282 ******************************************************************************/ 283 void SMP_PasskeyReply(const RawAddress& bd_addr, uint8_t res, 284 uint32_t passkey) { 285 tSMP_CB* p_cb = &smp_cb; 286 uint8_t failure = SMP_PASSKEY_ENTRY_FAIL; 287 288 SMP_TRACE_EVENT("SMP_PasskeyReply: Key: %d Result:%d", passkey, res); 289 290 /* If timeout already expired or has been canceled, ignore the reply */ 291 if (p_cb->cb_evt != SMP_PASSKEY_REQ_EVT) { 292 SMP_TRACE_WARNING("SMP_PasskeyReply() - Wrong State: %d", p_cb->state); 293 return; 294 } 295 296 if (bd_addr != p_cb->pairing_bda) { 297 SMP_TRACE_ERROR("SMP_PasskeyReply() - Wrong BD Addr"); 298 return; 299 } 300 301 if (btm_find_dev(bd_addr) == NULL) { 302 SMP_TRACE_ERROR("SMP_PasskeyReply() - no dev CB"); 303 return; 304 } 305 306 if (passkey > BTM_MAX_PASSKEY_VAL || res != SMP_SUCCESS) { 307 SMP_TRACE_WARNING( 308 "SMP_PasskeyReply() - Wrong key len: %d or passkey entry fail", 309 passkey); 310 /* send pairing failure */ 311 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure); 312 313 } else if (p_cb->selected_association_model == 314 SMP_MODEL_SEC_CONN_PASSKEY_ENT) { 315 smp_sm_event(&smp_cb, SMP_SC_KEY_READY_EVT, &passkey); 316 } else { 317 smp_convert_string_to_tk(p_cb->tk, passkey); 318 } 319 320 return; 321 } 322 323 /******************************************************************************* 324 * 325 * Function SMP_ConfirmReply 326 * 327 * Description This function is called after Security Manager submitted 328 * numeric comparison request to the application. 329 * 330 * Parameters: bd_addr - Address of the device with which numeric 331 * comparison was requested 332 * res - comparison result SMP_SUCCESS if success 333 * 334 ******************************************************************************/ 335 void SMP_ConfirmReply(const RawAddress& bd_addr, uint8_t res) { 336 tSMP_CB* p_cb = &smp_cb; 337 uint8_t failure = SMP_NUMERIC_COMPAR_FAIL; 338 339 SMP_TRACE_EVENT("%s: Result:%d", __func__, res); 340 341 /* If timeout already expired or has been canceled, ignore the reply */ 342 if (p_cb->cb_evt != SMP_NC_REQ_EVT) { 343 SMP_TRACE_WARNING("%s() - Wrong State: %d", __func__, p_cb->state); 344 return; 345 } 346 347 if (bd_addr != p_cb->pairing_bda) { 348 SMP_TRACE_ERROR("%s() - Wrong BD Addr", __func__); 349 return; 350 } 351 352 if (btm_find_dev(bd_addr) == NULL) { 353 SMP_TRACE_ERROR("%s() - no dev CB", __func__); 354 return; 355 } 356 357 if (res != SMP_SUCCESS) { 358 SMP_TRACE_WARNING("%s() - Numeric Comparison fails", __func__); 359 /* send pairing failure */ 360 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure); 361 } else { 362 smp_sm_event(p_cb, SMP_SC_NC_OK_EVT, NULL); 363 } 364 } 365 366 /******************************************************************************* 367 * 368 * Function SMP_OobDataReply 369 * 370 * Description This function is called to provide the OOB data for 371 * SMP in response to SMP_OOB_REQ_EVT 372 * 373 * Parameters: bd_addr - Address of the peer device 374 * res - result of the operation SMP_SUCCESS if success 375 * p_data - simple pairing Randomizer C. 376 * 377 ******************************************************************************/ 378 void SMP_OobDataReply(const RawAddress& bd_addr, tSMP_STATUS res, uint8_t len, 379 uint8_t* p_data) { 380 tSMP_CB* p_cb = &smp_cb; 381 uint8_t failure = SMP_OOB_FAIL; 382 tSMP_KEY key; 383 384 SMP_TRACE_EVENT("%s State: %d res:%d", __func__, smp_cb.state, res); 385 386 /* If timeout already expired or has been canceled, ignore the reply */ 387 if (p_cb->state != SMP_STATE_WAIT_APP_RSP || p_cb->cb_evt != SMP_OOB_REQ_EVT) 388 return; 389 390 if (res != SMP_SUCCESS || len == 0 || !p_data) { 391 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure); 392 } else { 393 if (len > BT_OCTET16_LEN) len = BT_OCTET16_LEN; 394 395 memcpy(p_cb->tk, p_data, len); 396 397 key.key_type = SMP_KEY_TYPE_TK; 398 key.p_data = p_cb->tk; 399 400 smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &key); 401 } 402 } 403 404 /******************************************************************************* 405 * 406 * Function SMP_SecureConnectionOobDataReply 407 * 408 * Description This function is called to provide the SC OOB data for 409 * SMP in response to SMP_SC_OOB_REQ_EVT 410 * 411 * Parameters: p_data - pointer to the data 412 * 413 ******************************************************************************/ 414 void SMP_SecureConnectionOobDataReply(uint8_t* p_data) { 415 tSMP_CB* p_cb = &smp_cb; 416 417 uint8_t failure = SMP_OOB_FAIL; 418 tSMP_SC_OOB_DATA* p_oob = (tSMP_SC_OOB_DATA*)p_data; 419 if (!p_oob) { 420 SMP_TRACE_ERROR("%s received no data", __func__); 421 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure); 422 return; 423 } 424 425 SMP_TRACE_EVENT( 426 "%s req_oob_type: %d, loc_oob_data.present: %d, " 427 "peer_oob_data.present: %d", 428 __func__, p_cb->req_oob_type, p_oob->loc_oob_data.present, 429 p_oob->peer_oob_data.present); 430 431 if (p_cb->state != SMP_STATE_WAIT_APP_RSP || 432 p_cb->cb_evt != SMP_SC_OOB_REQ_EVT) 433 return; 434 435 bool data_missing = false; 436 switch (p_cb->req_oob_type) { 437 case SMP_OOB_PEER: 438 if (!p_oob->peer_oob_data.present) data_missing = true; 439 break; 440 case SMP_OOB_LOCAL: 441 if (!p_oob->loc_oob_data.present) data_missing = true; 442 break; 443 case SMP_OOB_BOTH: 444 if (!p_oob->loc_oob_data.present || !p_oob->peer_oob_data.present) 445 data_missing = true; 446 break; 447 default: 448 SMP_TRACE_EVENT("Unexpected OOB data type requested. Fail OOB"); 449 data_missing = true; 450 break; 451 } 452 453 if (data_missing) { 454 smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure); 455 return; 456 } 457 458 p_cb->sc_oob_data = *p_oob; 459 460 smp_sm_event(&smp_cb, SMP_SC_OOB_DATA_EVT, p_data); 461 } 462 463 /******************************************************************************* 464 * 465 * Function SMP_Encrypt 466 * 467 * Description This function is called to encrypt the data with the 468 * specified key 469 * 470 * Parameters: key - Pointer to key key[0] conatins the MSB 471 * key_len - key length 472 * plain_text - Pointer to data to be encrypted 473 * plain_text[0] conatins the MSB 474 * pt_len - plain text length 475 * p_out - output of the encrypted texts 476 * 477 * Returns Boolean - request is successful 478 ******************************************************************************/ 479 bool SMP_Encrypt(uint8_t* key, uint8_t key_len, uint8_t* plain_text, 480 uint8_t pt_len, tSMP_ENC* p_out) 481 482 { 483 bool status = false; 484 status = smp_encrypt_data(key, key_len, plain_text, pt_len, p_out); 485 return status; 486 } 487 488 /******************************************************************************* 489 * 490 * Function SMP_KeypressNotification 491 * 492 * Description This function is called to notify Security Manager about 493 * Keypress Notification. 494 * 495 * Parameters: bd_addr Address of the device to send keypress 496 * notification to 497 * value Keypress notification parameter value 498 * 499 ******************************************************************************/ 500 void SMP_KeypressNotification(const RawAddress& bd_addr, uint8_t value) { 501 tSMP_CB* p_cb = &smp_cb; 502 503 SMP_TRACE_EVENT("%s: Value: %d", __func__, value); 504 505 if (bd_addr != p_cb->pairing_bda) { 506 SMP_TRACE_ERROR("%s() - Wrong BD Addr", __func__); 507 return; 508 } 509 510 if (btm_find_dev(bd_addr) == NULL) { 511 SMP_TRACE_ERROR("%s() - no dev CB", __func__); 512 return; 513 } 514 515 /* Keypress Notification is used by a device with KeyboardOnly IO capabilities 516 * during the passkey entry protocol */ 517 if (p_cb->local_io_capability != SMP_IO_CAP_IN) { 518 SMP_TRACE_ERROR("%s() - wrong local IO capabilities %d", __func__, 519 p_cb->local_io_capability); 520 return; 521 } 522 523 if (p_cb->selected_association_model != SMP_MODEL_SEC_CONN_PASSKEY_ENT) { 524 SMP_TRACE_ERROR("%s() - wrong protocol %d", __func__, 525 p_cb->selected_association_model); 526 return; 527 } 528 529 smp_sm_event(p_cb, SMP_KEYPRESS_NOTIFICATION_EVENT, &value); 530 } 531 532 /******************************************************************************* 533 * 534 * Function SMP_CreateLocalSecureConnectionsOobData 535 * 536 * Description This function is called to start creation of local SC OOB 537 * data set (tSMP_LOC_OOB_DATA). 538 * 539 * Parameters: bd_addr - Address of the device to send OOB data block to 540 * 541 * Returns Boolean - true: creation of local SC OOB data set started. 542 ******************************************************************************/ 543 bool SMP_CreateLocalSecureConnectionsOobData(tBLE_BD_ADDR* addr_to_send_to) { 544 tSMP_CB* p_cb = &smp_cb; 545 546 if (addr_to_send_to == NULL) { 547 SMP_TRACE_ERROR("%s addr_to_send_to is not provided", __func__); 548 return false; 549 } 550 551 VLOG(2) << __func__ << " addr type:" << +addr_to_send_to->type 552 << ", BDA:" << addr_to_send_to->bda << ", state:" << p_cb->state 553 << ", br_state: " << p_cb->br_state; 554 555 if ((p_cb->state != SMP_STATE_IDLE) || (p_cb->smp_over_br)) { 556 SMP_TRACE_WARNING( 557 "%s creation of local OOB data set " 558 "starts only in IDLE state", 559 __func__); 560 return false; 561 } 562 563 p_cb->sc_oob_data.loc_oob_data.addr_sent_to = *addr_to_send_to; 564 smp_sm_event(p_cb, SMP_CR_LOC_SC_OOB_DATA_EVT, NULL); 565 566 return true; 567 } 568