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