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