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