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