Home | History | Annotate | Download | only in smp
      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