summaryrefslogtreecommitdiffstats
path: root/stack/smp/smp_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'stack/smp/smp_api.c')
-rw-r--r--stack/smp/smp_api.c299
1 files changed, 283 insertions, 16 deletions
diff --git a/stack/smp/smp_api.c b/stack/smp/smp_api.c
index 2ebf9538a..4d7b16df9 100644
--- a/stack/smp/smp_api.c
+++ b/stack/smp/smp_api.c
@@ -35,7 +35,7 @@
#include "hcimsgs.h"
#include "btu.h"
-
+ #include "p_256_ecc_pp.h"
/*******************************************************************************
**
@@ -48,8 +48,6 @@
*******************************************************************************/
void SMP_Init(void)
{
-
- SMP_TRACE_EVENT ("SMP_Init");
memset(&smp_cb, 0, sizeof(tSMP_CB));
#if defined(SMP_INITIAL_TRACE_LEVEL)
@@ -57,8 +55,11 @@ void SMP_Init(void)
#else
smp_cb.trace_level = BT_TRACE_LEVEL_NONE; /* No traces */
#endif
+ SMP_TRACE_EVENT ("%s", __FUNCTION__);
smp_l2cap_if_init();
+ /* initialization of P-256 parameters */
+ p_256_init_curve(KEY_LENGTH_DWORDS_P256);
}
@@ -131,8 +132,10 @@ tSMP_STATUS SMP_Pair (BD_ADDR bd_addr)
tSMP_CB *p_cb = &smp_cb;
UINT8 status = SMP_PAIR_INTERNAL_ERR;
- BTM_TRACE_EVENT ("SMP_Pair state=%d flag=0x%x ", p_cb->state, p_cb->flags);
- if (p_cb->state != SMP_ST_IDLE || p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)
+ SMP_TRACE_EVENT ("%s state=%d br_state=%d flag=0x%x ",
+ __FUNCTION__, p_cb->state, p_cb->br_state, p_cb->flags);
+ if (p_cb->state != SMP_STATE_IDLE || p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD ||
+ p_cb->smp_over_br)
{
/* pending security on going, reject this one */
return SMP_BUSY;
@@ -145,7 +148,7 @@ tSMP_STATUS SMP_Pair (BD_ADDR bd_addr)
if (!L2CA_ConnectFixedChnl (L2CAP_SMP_CID, bd_addr))
{
- SMP_TRACE_ERROR("SMP_Pair: L2C connect fixed channel failed.");
+ SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.", __FUNCTION__);
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
return status;
}
@@ -154,6 +157,49 @@ tSMP_STATUS SMP_Pair (BD_ADDR bd_addr)
}
}
+/*******************************************************************************
+**
+** Function SMP_BR_PairWith
+**
+** Description This function is called to start a SMP pairing over BR/EDR.
+** Device support one SMP pairing at one time.
+**
+** Parameters bd_addr - peer device bd address.
+**
+** Returns SMP_STARTED if pairing started, otherwise reason for failure.
+**
+*******************************************************************************/
+tSMP_STATUS SMP_BR_PairWith (BD_ADDR bd_addr)
+{
+ tSMP_CB *p_cb = &smp_cb;
+ UINT8 status = SMP_PAIR_INTERNAL_ERR;
+
+ SMP_TRACE_EVENT ("%s state=%d br_state=%d flag=0x%x ",
+ __func__, p_cb->state, p_cb->br_state, p_cb->flags);
+
+ if (p_cb->state != SMP_STATE_IDLE ||
+ p_cb->smp_over_br ||
+ p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)
+ {
+ /* pending security on going, reject this one */
+ return SMP_BUSY;
+ }
+
+ p_cb->role = HCI_ROLE_MASTER;
+ p_cb->flags = SMP_PAIR_FLAGS_WE_STARTED_DD;
+ p_cb->smp_over_br = TRUE;
+
+ memcpy (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN);
+
+ if (!L2CA_ConnectFixedChnl (L2CAP_SMP_BR_CID, bd_addr))
+ {
+ SMP_TRACE_ERROR("%s: L2C connect fixed channel failed.",__FUNCTION__);
+ smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &status);
+ return status;
+ }
+
+ return SMP_STARTED;
+}
/*******************************************************************************
**
@@ -173,7 +219,7 @@ BOOLEAN SMP_PairCancel (BD_ADDR bd_addr)
BOOLEAN status = FALSE;
BTM_TRACE_EVENT ("SMP_CancelPair state=%d flag=0x%x ", p_cb->state, p_cb->flags);
- if ( (p_cb->state != SMP_ST_IDLE) &&
+ if ( (p_cb->state != SMP_STATE_IDLE) &&
(!memcmp (p_cb->pairing_bda, bd_addr, BD_ADDR_LEN)) )
{
p_cb->is_pair_cancel = TRUE;
@@ -200,11 +246,27 @@ BOOLEAN SMP_PairCancel (BD_ADDR bd_addr)
void SMP_SecurityGrant(BD_ADDR bd_addr, UINT8 res)
{
SMP_TRACE_EVENT ("SMP_SecurityGrant ");
- if (smp_cb.state != SMP_ST_WAIT_APP_RSP ||
+
+ if (smp_cb.smp_over_br)
+ {
+ if (smp_cb.br_state != SMP_BR_STATE_WAIT_APP_RSP ||
+ smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
+ memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN))
+ {
+ return;
+ }
+
+ /* clear the SMP_SEC_REQUEST_EVT event after get grant */
+ /* avoid generating duplicate pair request */
+ smp_cb.cb_evt = 0;
+ smp_br_state_machine_event(&smp_cb, SMP_BR_API_SEC_GRANT_EVT, &res);
+ return;
+ }
+
+ if (smp_cb.state != SMP_STATE_WAIT_APP_RSP ||
smp_cb.cb_evt != SMP_SEC_REQUEST_EVT ||
memcmp (smp_cb.pairing_bda, bd_addr, BD_ADDR_LEN))
return;
-
/* clear the SMP_SEC_REQUEST_EVT event after get grant */
/* avoid generate duplicate pair request */
smp_cb.cb_evt = 0;
@@ -228,7 +290,6 @@ void SMP_PasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey)
{
tSMP_CB *p_cb = & smp_cb;
UINT8 failure = SMP_PASSKEY_ENTRY_FAIL;
- tBTM_SEC_DEV_REC *p_dev_rec;
SMP_TRACE_EVENT ("SMP_PasskeyReply: Key: %d Result:%d",
passkey, res);
@@ -246,13 +307,12 @@ void SMP_PasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey)
return;
}
- if ((p_dev_rec = btm_find_dev (bd_addr)) == NULL)
+ if (btm_find_dev (bd_addr) == NULL)
{
SMP_TRACE_ERROR ("SMP_PasskeyReply() - no dev CB");
return;
}
-
if (passkey > BTM_MAX_PASSKEY_VAL || res != SMP_SUCCESS)
{
SMP_TRACE_WARNING ("SMP_PasskeyReply() - Wrong key len: %d or passkey entry fail", passkey);
@@ -260,6 +320,10 @@ void SMP_PasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey)
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
}
+ else if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_PASSKEY_ENT)
+ {
+ smp_sm_event(&smp_cb, SMP_SC_KEY_READY_EVT, &passkey);
+ }
else
{
smp_convert_string_to_tk(p_cb->tk, passkey);
@@ -270,6 +334,56 @@ void SMP_PasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey)
/*******************************************************************************
**
+** Function SMP_ConfirmReply
+**
+** Description This function is called after Security Manager submitted
+** numeric comparison request to the application.
+**
+** Parameters: bd_addr - Address of the device with which numeric
+** comparison was requested
+** res - comparison result SMP_SUCCESS if success
+**
+*******************************************************************************/
+void SMP_ConfirmReply (BD_ADDR bd_addr, UINT8 res)
+{
+ tSMP_CB *p_cb = & smp_cb;
+ UINT8 failure = SMP_NUMERIC_COMPAR_FAIL;
+
+ SMP_TRACE_EVENT ("%s: Result:%d", __FUNCTION__, res);
+
+ /* If timeout already expired or has been canceled, ignore the reply */
+ if (p_cb->cb_evt != SMP_NC_REQ_EVT)
+ {
+ SMP_TRACE_WARNING ("%s() - Wrong State: %d", __FUNCTION__,p_cb->state);
+ return;
+ }
+
+ if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0)
+ {
+ SMP_TRACE_ERROR ("%s() - Wrong BD Addr",__FUNCTION__);
+ return;
+ }
+
+ if (btm_find_dev (bd_addr) == NULL)
+ {
+ SMP_TRACE_ERROR ("%s() - no dev CB",__FUNCTION__);
+ return;
+ }
+
+ if (res != SMP_SUCCESS)
+ {
+ SMP_TRACE_WARNING ("%s() - Numeric Comparison fails",__FUNCTION__);
+ /* send pairing failure */
+ smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
+ }
+ else
+ {
+ smp_sm_event(p_cb, SMP_SC_NC_OK_EVT, NULL);
+ }
+}
+
+/*******************************************************************************
+**
** Function SMP_OobDataReply
**
** Description This function is called to provide the OOB data for
@@ -285,13 +399,11 @@ void SMP_OobDataReply(BD_ADDR bd_addr, tSMP_STATUS res, UINT8 len, UINT8 *p_data
tSMP_CB *p_cb = & smp_cb;
UINT8 failure = SMP_OOB_FAIL;
tSMP_KEY key;
- UNUSED(bd_addr);
- SMP_TRACE_EVENT ("SMP_OobDataReply State: %d res:%d",
- smp_cb.state, res);
+ SMP_TRACE_EVENT ("%s State: %d res:%d", __FUNCTION__, smp_cb.state, res);
/* If timeout already expired or has been canceled, ignore the reply */
- if (p_cb->state != SMP_ST_WAIT_APP_RSP || p_cb->cb_evt != SMP_OOB_REQ_EVT)
+ if (p_cb->state != SMP_STATE_WAIT_APP_RSP || p_cb->cb_evt != SMP_OOB_REQ_EVT)
return;
if (res != SMP_SUCCESS || len == 0 || !p_data)
@@ -314,6 +426,69 @@ void SMP_OobDataReply(BD_ADDR bd_addr, tSMP_STATUS res, UINT8 len, UINT8 *p_data
/*******************************************************************************
**
+** Function SMP_SecureConnectionOobDataReply
+**
+** Description This function is called to provide the SC OOB data for
+** SMP in response to SMP_SC_OOB_REQ_EVT
+**
+** Parameters: p_data - pointer to the data
+**
+*******************************************************************************/
+void SMP_SecureConnectionOobDataReply(UINT8 *p_data)
+{
+ tSMP_CB *p_cb = &smp_cb;
+
+ UINT8 failure = SMP_OOB_FAIL;
+ tSMP_SC_OOB_DATA *p_oob = (tSMP_SC_OOB_DATA *) p_data;
+ if (!p_oob)
+ {
+ SMP_TRACE_ERROR("%s received no data",__FUNCTION__);
+ smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
+ return;
+ }
+
+ SMP_TRACE_EVENT ("%s req_oob_type: %d, loc_oob_data.present: %d, "
+ "peer_oob_data.present: %d",
+ __FUNCTION__, p_cb->req_oob_type, p_oob->loc_oob_data.present,
+ p_oob->peer_oob_data.present);
+
+ if (p_cb->state != SMP_STATE_WAIT_APP_RSP || p_cb->cb_evt != SMP_SC_OOB_REQ_EVT)
+ return;
+
+ BOOLEAN data_missing = FALSE;
+ switch (p_cb->req_oob_type)
+ {
+ case SMP_OOB_PEER:
+ if (!p_oob->peer_oob_data.present)
+ data_missing = TRUE;
+ break;
+ case SMP_OOB_LOCAL:
+ if (!p_oob->loc_oob_data.present)
+ data_missing = TRUE;
+ break;
+ case SMP_OOB_BOTH:
+ if (!p_oob->loc_oob_data.present || !p_oob->peer_oob_data.present)
+ data_missing = TRUE;
+ break;
+ default:
+ SMP_TRACE_EVENT ("Unexpected OOB data type requested. Fail OOB");
+ data_missing = TRUE;
+ break;
+ }
+
+ if (data_missing)
+ {
+ smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure);
+ return;
+ }
+
+ p_cb->sc_oob_data = *p_oob;
+
+ smp_sm_event(&smp_cb, SMP_SC_OOB_DATA_EVT, p_data);
+}
+
+/*******************************************************************************
+**
** Function SMP_Encrypt
**
** Description This function is called to encrypt the data with the specified
@@ -337,4 +512,96 @@ BOOLEAN SMP_Encrypt (UINT8 *key, UINT8 key_len,
status = smp_encrypt_data(key, key_len, plain_text, pt_len, p_out);
return status;
}
+
+/*******************************************************************************
+**
+** Function SMP_KeypressNotification
+**
+** Description This function is called to notify Security Manager about Keypress Notification.
+**
+** Parameters: bd_addr Address of the device to send keypress notification to
+** value Keypress notification parameter value
+**
+*******************************************************************************/
+void SMP_KeypressNotification (BD_ADDR bd_addr, UINT8 value)
+{
+ tSMP_CB *p_cb = &smp_cb;
+
+ SMP_TRACE_EVENT ("%s: Value: %d", __FUNCTION__,value);
+
+ if (memcmp (bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) != 0)
+ {
+ SMP_TRACE_ERROR ("%s() - Wrong BD Addr",__FUNCTION__);
+ return;
+ }
+
+ if (btm_find_dev (bd_addr) == NULL)
+ {
+ SMP_TRACE_ERROR ("%s() - no dev CB",__FUNCTION__);
+ return;
+ }
+
+ /* Keypress Notification is used by a device with KeyboardOnly IO capabilities */
+ /* during the passkey entry protocol */
+ if (p_cb->local_io_capability != SMP_IO_CAP_IN)
+ {
+ SMP_TRACE_ERROR ("%s() - wrong local IO capabilities %d",
+ __FUNCTION__, p_cb->local_io_capability);
+ return;
+ }
+
+ if (p_cb->selected_association_model != SMP_MODEL_SEC_CONN_PASSKEY_ENT)
+ {
+ SMP_TRACE_ERROR ("%s() - wrong protocol %d", __FUNCTION__,
+ p_cb->selected_association_model);
+ return;
+ }
+
+ smp_sm_event(p_cb, SMP_KEYPRESS_NOTIFICATION_EVENT, &value);
+}
+
+/*******************************************************************************
+**
+** Function SMP_CreateLocalSecureConnectionsOobData
+**
+** Description This function is called to start creation of local SC OOB
+** data set (tSMP_LOC_OOB_DATA).
+**
+** Parameters: bd_addr - Address of the device to send OOB data block to
+**
+** Returns Boolean - TRUE: creation of local SC OOB data set started.
+*******************************************************************************/
+BOOLEAN SMP_CreateLocalSecureConnectionsOobData (tBLE_BD_ADDR *addr_to_send_to)
+{
+ tSMP_CB *p_cb = &smp_cb;
+ UINT8 *bd_addr;
+
+ if (addr_to_send_to == NULL)
+ {
+ SMP_TRACE_ERROR ("%s addr_to_send_to is not provided",__FUNCTION__);
+ return FALSE;
+ }
+
+ bd_addr = addr_to_send_to->bda;
+
+ SMP_TRACE_EVENT ("%s addr type: %u, BDA: %08x%04x, state: %u, br_state: %u",
+ __FUNCTION__, addr_to_send_to->type,
+ (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8) + bd_addr[3],
+ (bd_addr[4]<<8)+bd_addr[5],
+ p_cb->state,
+ p_cb->br_state);
+
+ if ((p_cb->state != SMP_STATE_IDLE) || (p_cb->smp_over_br))
+ {
+ SMP_TRACE_WARNING ("%s creation of local OOB data set "\
+ "starts only in IDLE state",__FUNCTION__);
+ return FALSE;
+ }
+
+ p_cb->sc_oob_data.loc_oob_data.addr_sent_to = *addr_to_send_to;
+ smp_sm_event(p_cb, SMP_CR_LOC_SC_OOB_DATA_EVT, NULL);
+
+ return TRUE;
+}
+
#endif /* SMP_INCLUDED */