smp_act.cc revision 5ce55bd2e01e738e7558038c403bc87e035ba583
15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Copyright (C) 2003-2012 Broadcom Corporation
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the "License");
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  you may not use this file except in compliance with the License.
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  You may obtain a copy of the License at:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  http://www.apache.org/licenses/LICENSE-2.0
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  See the License for the specific language governing permissions and
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *  limitations under the License.
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
19444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji#include <string.h>
205a6b32562ab6a1bbca945e478d01e371bb49c40fPulkit Bhuwalka#include "btif_common.h"
217927f68bb2d9b963288261e1e858463b43c52a2dAndre Eisenbach#include "device/include/interop.h"
227927f68bb2d9b963288261e1e858463b43c52a2dAndre Eisenbach#include "include/bt_target.h"
237927f68bb2d9b963288261e1e858463b43c52a2dAndre Eisenbach#include "stack/btm/btm_int.h"
247927f68bb2d9b963288261e1e858463b43c52a2dAndre Eisenbach#include "stack/include/l2c_api.h"
257927f68bb2d9b963288261e1e858463b43c52a2dAndre Eisenbach#include "stack/smp/smp_int.h"
267927f68bb2d9b963288261e1e858463b43c52a2dAndre Eisenbach#include "utils/include/bt_utils.h"
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
28911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define SMP_KEY_DIST_TYPE_MAX 4
29fd102ca1610684631837278d74a2cfb6a50f7f69ravishankar srivatsa
30911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonconst tSMP_ACT smp_distribute_act[] = {smp_generate_ltk, smp_send_id_info,
31911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                       smp_generate_csrk,
32911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                       smp_set_derive_link_key};
330bd0c8fc88a7141691a7ca839b11cb711945ee33Nitin Arora
34a484a888196ddf8bcbf1ad3226d6451bc735a94bJakub Pawlowskistatic bool lmp_version_below(const RawAddress& bda, uint8_t version) {
35911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tACL_CONN* acl = btm_bda_to_acl(bda, BT_TRANSPORT_LE);
36911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (acl == NULL || acl->lmp_version == 0) {
37911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SMP_TRACE_WARNING("%s cannot retrieve LMP version...", __func__);
38911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return false;
39911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
40911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_WARNING("%s LMP version %d < %d", __func__, acl->lmp_version,
41911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                    version);
42911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return acl->lmp_version < version;
43911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson}
44911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
45911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic bool pts_test_send_authentication_complete_failure(tSMP_CB* p_cb) {
46fd102ca1610684631837278d74a2cfb6a50f7f69ravishankar srivatsa  uint8_t reason = p_cb->cert_failure;
47fd102ca1610684631837278d74a2cfb6a50f7f69ravishankar srivatsa  if (reason == SMP_PAIR_AUTH_FAIL || reason == SMP_PAIR_FAIL_UNKNOWN ||
48fd102ca1610684631837278d74a2cfb6a50f7f69ravishankar srivatsa      reason == SMP_PAIR_NOT_SUPPORT || reason == SMP_PASSKEY_ENTRY_FAIL ||
49fd102ca1610684631837278d74a2cfb6a50f7f69ravishankar srivatsa      reason == SMP_REPEATED_ATTEMPTS) {
505ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
515ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = reason;
525ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
53fd102ca1610684631837278d74a2cfb6a50f7f69ravishankar srivatsa    return true;
54911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
55fd102ca1610684631837278d74a2cfb6a50f7f69ravishankar srivatsa  return false;
560bd0c8fc88a7141691a7ca839b11cb711945ee33Nitin Arora}
570bd0c8fc88a7141691a7ca839b11cb711945ee33Nitin Arora
585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
59ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         smp_update_key_mask
60ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function updates the key mask for sending or receiving.
61ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
62911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void smp_update_key_mask(tSMP_CB* p_cb, uint8_t key_type, bool recv) {
63911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG(
64911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      "%s before update role=%d recv=%d local_i_key = %02x, local_r_key = %02x",
65911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      __func__, p_cb->role, recv, p_cb->local_i_key, p_cb->local_r_key);
66911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
67911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (((p_cb->le_secure_connections_mode_is_used) || (p_cb->smp_over_br)) &&
68911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      ((key_type == SMP_SEC_KEY_TYPE_ENC) ||
69911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson       (key_type == SMP_SEC_KEY_TYPE_LK))) {
70911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* in LE SC mode LTK, CSRK and BR/EDR LK are derived locally instead of
71911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ** being exchanged with the peer */
72911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cb->local_i_key &= ~key_type;
73911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cb->local_r_key &= ~key_type;
74911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else if (p_cb->role == HCI_ROLE_SLAVE) {
75911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (recv)
76911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->local_i_key &= ~key_type;
77444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji    else
78911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->local_r_key &= ~key_type;
79911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
80911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (recv)
81911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->local_r_key &= ~key_type;
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    else
83911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->local_i_key &= ~key_type;
84911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
86911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("updated local_i_key = %02x, local_r_key = %02x",
87911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                  p_cb->local_i_key, p_cb->local_r_key);
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
89444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
91ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_send_app_cback
929ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description  notifies application about the events the application is
939ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *              interested in
94ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
95911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_send_app_cback(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
96911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSMP_EVT_DATA cb_data;
97911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSMP_STATUS callback_rc;
98911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s p_cb->cb_evt=%d", __func__, p_cb->cb_evt);
99911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cb->p_callback && p_cb->cb_evt != 0) {
100911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    switch (p_cb->cb_evt) {
101911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      case SMP_IO_CAP_REQ_EVT:
102911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        cb_data.io_req.auth_req = p_cb->peer_auth_req;
103911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        cb_data.io_req.oob_data = SMP_OOB_NONE;
104911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        cb_data.io_req.io_cap = SMP_DEFAULT_IO_CAPS;
105911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        cb_data.io_req.max_key_size = SMP_MAX_ENC_KEY_SIZE;
106911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        cb_data.io_req.init_keys = p_cb->local_i_key;
107911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        cb_data.io_req.resp_keys = p_cb->local_r_key;
108911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        SMP_TRACE_WARNING("io_cap = %d", cb_data.io_req.io_cap);
109911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        break;
110911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
111911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      case SMP_NC_REQ_EVT:
112911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        cb_data.passkey = p_data->passkey;
113911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        break;
114911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      case SMP_SC_OOB_REQ_EVT:
115911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        cb_data.req_oob_type = p_data->req_oob_type;
116911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        break;
117911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      case SMP_SC_LOC_OOB_DATA_UP_EVT:
118911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        cb_data.loc_oob_data = p_cb->sc_oob_data.loc_oob_data;
119911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        break;
120911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
121911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      case SMP_BR_KEYS_REQ_EVT:
122911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        cb_data.io_req.auth_req = 0;
123911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        cb_data.io_req.oob_data = SMP_OOB_NONE;
124911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        cb_data.io_req.io_cap = 0;
125911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        cb_data.io_req.max_key_size = SMP_MAX_ENC_KEY_SIZE;
126911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        cb_data.io_req.init_keys = SMP_BR_SEC_DEFAULT_KEY;
127911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        cb_data.io_req.resp_keys = SMP_BR_SEC_DEFAULT_KEY;
128911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        break;
129911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
130911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      default:
131911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        break;
132911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
133911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
134911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    callback_rc =
135911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        (*p_cb->p_callback)(p_cb->cb_evt, p_cb->pairing_bda, &cb_data);
136911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
137911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SMP_TRACE_DEBUG("%s: callback_rc=%d  p_cb->cb_evt=%d", __func__,
138911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                    callback_rc, p_cb->cb_evt);
139911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
140911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (callback_rc == SMP_SUCCESS) {
141911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      switch (p_cb->cb_evt) {
142911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        case SMP_IO_CAP_REQ_EVT:
143911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_cb->loc_auth_req = cb_data.io_req.auth_req;
144911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_cb->local_io_capability = cb_data.io_req.io_cap;
145911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_cb->loc_oob_flag = cb_data.io_req.oob_data;
146911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_cb->loc_enc_size = cb_data.io_req.max_key_size;
147911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_cb->local_i_key = cb_data.io_req.init_keys;
148911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_cb->local_r_key = cb_data.io_req.resp_keys;
149911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
150911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          if (!(p_cb->loc_auth_req & SMP_AUTH_BOND)) {
151911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            SMP_TRACE_WARNING("Non bonding: No keys will be exchanged");
152911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            p_cb->local_i_key = 0;
153911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            p_cb->local_r_key = 0;
154911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          }
155911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
156911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          SMP_TRACE_WARNING(
157b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon              "rcvd auth_req: 0x%02x, io_cap: %d "
158b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon              "loc_oob_flag: %d loc_enc_size: %d, "
159911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              "local_i_key: 0x%02x, local_r_key: 0x%02x",
160911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              p_cb->loc_auth_req, p_cb->local_io_capability, p_cb->loc_oob_flag,
161911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              p_cb->loc_enc_size, p_cb->local_i_key, p_cb->local_r_key);
162911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
163911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_cb->secure_connections_only_mode_required =
164911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              (btm_cb.security_mode == BTM_SEC_MODE_SC) ? true : false;
165911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
166911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          if (p_cb->secure_connections_only_mode_required) {
167911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            p_cb->loc_auth_req |= SMP_SC_SUPPORT_BIT;
168911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          }
169911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
170911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          if (!(p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT) ||
171911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              lmp_version_below(p_cb->pairing_bda, HCI_PROTO_VERSION_4_2) ||
172911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              interop_match_addr(INTEROP_DISABLE_LE_SECURE_CONNECTIONS,
173a484a888196ddf8bcbf1ad3226d6451bc735a94bJakub Pawlowski                                 (const RawAddress*)&p_cb->pairing_bda)) {
174911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            p_cb->loc_auth_req &= ~SMP_KP_SUPPORT_BIT;
175911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK;
176911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
177911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          }
178911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
179911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          SMP_TRACE_WARNING(
180911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              "set auth_req: 0x%02x, local_i_key: 0x%02x, local_r_key: 0x%02x",
181911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              p_cb->loc_auth_req, p_cb->local_i_key, p_cb->local_r_key);
182911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
183911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          smp_sm_event(p_cb, SMP_IO_RSP_EVT, NULL);
184911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          break;
185911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
186911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        case SMP_BR_KEYS_REQ_EVT:
187911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_cb->loc_enc_size = cb_data.io_req.max_key_size;
188911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_cb->local_i_key = cb_data.io_req.init_keys;
189911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_cb->local_r_key = cb_data.io_req.resp_keys;
190e7f14a682d57811d9df0d64372f222bcc143ec86Jakub Pawlowski          p_cb->loc_auth_req |= SMP_H7_SUPPORT_BIT;
191911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
192911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK;
193911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
194911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
195911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          SMP_TRACE_WARNING(
196b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon              "for SMP over BR max_key_size: 0x%02x, local_i_key: 0x%02x, "
197b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon              "local_r_key: 0x%02x, p_cb->loc_auth_req: 0x%02x",
198e7f14a682d57811d9df0d64372f222bcc143ec86Jakub Pawlowski              p_cb->loc_enc_size, p_cb->local_i_key, p_cb->local_r_key,
199e7f14a682d57811d9df0d64372f222bcc143ec86Jakub Pawlowski              p_cb->loc_auth_req);
200444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
201911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          smp_br_state_machine_event(p_cb, SMP_BR_KEYS_RSP_EVT, NULL);
202911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          break;
203911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
205911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
207911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!p_cb->cb_evt && p_cb->discard_sec_req) {
208911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cb->discard_sec_req = false;
209911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_sm_event(p_cb, SMP_DISCARD_SEC_REQ_EVT, NULL);
210911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
211444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
212b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon  SMP_TRACE_DEBUG("%s: return", __func__);
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
214444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
216ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_send_pair_fail
217ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  pairing failure to peer device if needed.
218ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
219911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_send_pair_fail(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
2205ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  p_cb->status = p_data->status;
2215ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  p_cb->failure = p_data->status;
2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
223b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon  SMP_TRACE_DEBUG("%s: status=%d failure=%d ", __func__, p_cb->status,
224911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                  p_cb->failure);
2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
226911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cb->status <= SMP_MAX_FAIL_RSN_PER_SPEC &&
227911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->status != SMP_SUCCESS) {
228911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_send_cmd(SMP_OPCODE_PAIRING_FAILED, p_cb);
229911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cb->wait_for_authorization_complete = true;
230911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
234ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_send_pair_req
235ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  actions related to sending pairing request
236ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
237911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_send_pair_req(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
238911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(p_cb->pairing_bda);
239911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
2402d41fe1c5dbac701a074eec272545439168930a7Andre Eisenbach
241911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* erase all keys when master sends pairing req*/
242911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_dev_rec) btm_sec_clear_ble_keys(p_dev_rec);
243911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* do not manipulate the key, let app decide,
244911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson     leave out to BTM to mandate key distribution for bonding case */
245911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_send_cmd(SMP_OPCODE_PAIRING_REQ, p_cb);
2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
247444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
249ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_send_pair_rsp
250ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  actions related to sending pairing response
251ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
252911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_send_pair_rsp(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
253911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
2545cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
255911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->local_i_key &= p_cb->peer_i_key;
256911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->local_r_key &= p_cb->peer_r_key;
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
258911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (smp_send_cmd(SMP_OPCODE_PAIRING_RSP, p_cb)) {
259911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB)
260911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_use_oob_private_key(p_cb, NULL);
261911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    else
262911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_decide_association_model(p_cb, NULL);
263911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
267ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_send_confirm
268ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  send confirmation to the peer
269ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
270911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_send_confirm(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
271911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
272911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_send_cmd(SMP_OPCODE_CONFIRM, p_cb);
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
274444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
276ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_send_init
277ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process pairing initializer to slave device
278ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
279911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_send_init(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
280911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
281911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_send_cmd(SMP_OPCODE_INIT, p_cb);
282444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
283444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
284444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
285ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_send_rand
286ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  send pairing random to the peer
287ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
288911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_send_rand(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
289911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
290911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_send_cmd(SMP_OPCODE_RAND, p_cb);
291444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
2925cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
293444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
294ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_send_pair_public_key
295ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  send pairing public key command to the peer
296ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
297911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_send_pair_public_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
298911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
299911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_send_cmd(SMP_OPCODE_PAIR_PUBLIC_KEY, p_cb);
300444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
302444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
303ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     SMP_SEND_COMMITMENT
304ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description send commitment command to the peer
305ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
306911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_send_commitment(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
307911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
308911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_send_cmd(SMP_OPCODE_PAIR_COMMITM, p_cb);
309444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
311444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
312ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_send_dhkey_check
313ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description send DHKey Check command to the peer
314ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
315911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_send_dhkey_check(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
316911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
317911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_send_cmd(SMP_OPCODE_PAIR_DHKEY_CHECK, p_cb);
318444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
319444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
320444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
321ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_send_keypress_notification
322ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description send Keypress Notification command to the peer
323ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
324911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_send_keypress_notification(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
3255ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  p_cb->local_keypress_notification = p_data->status;
326911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_send_cmd(SMP_OPCODE_PAIR_KEYPR_NOTIF, p_cb);
3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
328444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
330ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_send_enc_info
331ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  send encryption information command.
332ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
333911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_send_enc_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
334911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBTM_LE_LENC_KEYS le_key;
3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
336b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon  SMP_TRACE_DEBUG("%s: p_cb->loc_enc_size = %d", __func__, p_cb->loc_enc_size);
337911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_ENC, false);
3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
339911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_send_cmd(SMP_OPCODE_ENCRYPT_INFO, p_cb);
340911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_send_cmd(SMP_OPCODE_MASTER_ID, p_cb);
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
342911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* save the DIV and key size information when acting as slave device */
343911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  memcpy(le_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
344911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  le_key.div = p_cb->div;
345911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  le_key.key_size = p_cb->loc_enc_size;
346911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  le_key.sec_level = p_cb->sec_level;
3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
348911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((p_cb->peer_auth_req & SMP_AUTH_BOND) &&
349911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (p_cb->loc_auth_req & SMP_AUTH_BOND))
350911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LENC,
351911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                        (tBTM_LE_KEY_VALUE*)&le_key, true);
352444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
353911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_WARNING("%s", __func__);
3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
355911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_key_distribution(p_cb, NULL);
3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
357444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
359ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_send_id_info
360ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  send ID information command.
361ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
362911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_send_id_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
363911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBTM_LE_KEY_VALUE le_key;
364911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
365911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_ID, false);
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
367911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_send_cmd(SMP_OPCODE_IDENTITY_INFO, p_cb);
368911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_send_cmd(SMP_OPCODE_ID_ADDR, p_cb);
3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
370911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((p_cb->peer_auth_req & SMP_AUTH_BOND) &&
371911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (p_cb->loc_auth_req & SMP_AUTH_BOND))
372911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LID, &le_key, true);
3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
374911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_WARNING("%s", __func__);
375911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_key_distribution_by_transport(p_cb, NULL);
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
377444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
379ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_send_csrk_info
380ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  send CSRK command.
381ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
382911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_send_csrk_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
383911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBTM_LE_LCSRK_KEYS key;
384911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
385911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_CSRK, false);
3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
387911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (smp_send_cmd(SMP_OPCODE_SIGN_INFO, p_cb)) {
388911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    key.div = p_cb->div;
389911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    key.sec_level = p_cb->sec_level;
390911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    key.counter = 0; /* initialize the local counter */
391911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy(key.csrk, p_cb->csrk, BT_OCTET16_LEN);
392911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LCSRK,
393911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                        (tBTM_LE_KEY_VALUE*)&key, true);
394911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
396911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_key_distribution_by_transport(p_cb, NULL);
3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
400ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_send_ltk_reply
401ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  send LTK reply
402ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
403911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_send_ltk_reply(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
404911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
405911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* send stk as LTK response */
406911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  btm_ble_ltk_request_reply(p_cb->pairing_bda, true, p_data->key.p_data);
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
408444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
410ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_proc_sec_req
411ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process security request.
412ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
413911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_proc_sec_req(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
414911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBTM_LE_AUTH_REQ auth_req = *(tBTM_LE_AUTH_REQ*)p_data;
415911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBTM_BLE_SEC_REQ_ACT sec_req_act;
4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
417b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon  SMP_TRACE_DEBUG("%s: auth_req=0x%x", __func__, auth_req);
4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
419911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->cb_evt = 0;
4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
421911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  btm_ble_link_sec_check(p_cb->pairing_bda, auth_req, &sec_req_act);
4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
423b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon  SMP_TRACE_DEBUG("%s: sec_req_act=0x%x", __func__, sec_req_act);
4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
425911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  switch (sec_req_act) {
426911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case BTM_BLE_SEC_REQ_ACT_ENCRYPT:
427b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon      SMP_TRACE_DEBUG("%s: BTM_BLE_SEC_REQ_ACT_ENCRYPT", __func__);
428911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_sm_event(p_cb, SMP_ENC_REQ_EVT, NULL);
429911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
430911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
431911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case BTM_BLE_SEC_REQ_ACT_PAIR:
432911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->secure_connections_only_mode_required =
433911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          (btm_cb.security_mode == BTM_SEC_MODE_SC) ? true : false;
434911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
435911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* respond to non SC pairing request as failure in SC only mode */
436911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_cb->secure_connections_only_mode_required &&
437911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          (auth_req & SMP_SC_SUPPORT_BIT) == 0) {
4385ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson        tSMP_INT_DATA smp_int_data;
4395ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson        smp_int_data.status = SMP_PAIR_AUTH_FAIL;
4405ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson        smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
441911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      } else {
442911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        /* initialize local i/r key to be default keys */
443911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_cb->peer_auth_req = auth_req;
444911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_cb->local_r_key = p_cb->local_i_key = SMP_SEC_DEFAULT_KEY;
445911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_cb->cb_evt = SMP_SEC_REQUEST_EVT;
446911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
447911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
448911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
449911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case BTM_BLE_SEC_REQ_ACT_DISCARD:
450911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->discard_sec_req = true;
451911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
452911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
453911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    default:
454911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* do nothing */
455911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
456911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
458444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
460ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_proc_sec_grant
461ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process security grant.
462ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
463911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_proc_sec_grant(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
4645ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  uint8_t res = p_data->status;
465911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
466911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (res != SMP_SUCCESS) {
467911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, p_data);
468911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else /*otherwise, start pairing */
469911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  {
470911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* send IO request callback */
471911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cb->cb_evt = SMP_IO_CAP_REQ_EVT;
472911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
474444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
476ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_proc_pair_fail
477ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process pairing failure from peer device
478ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
479911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_proc_pair_fail(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
480911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
4815ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  p_cb->status = p_data->status;
482373d928dbadbf0bbaa2e9b1128fedd48b4da41e8Jacky Cheung
483911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Cancel pending auth complete timer if set */
484911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  alarm_cancel(p_cb->delayed_auth_timer_ent);
4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
486444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
488ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_proc_pair_cmd
489ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  Process the SMP pairing request/response from peer device
490ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
491911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_proc_pair_cmd(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
4925ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  uint8_t* p = p_data->p_data;
493911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(p_cb->pairing_bda);
4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
495911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
496b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon  /* erase all keys if it is slave proc pairing req */
497911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_dev_rec && (p_cb->role == HCI_ROLE_SLAVE))
498911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    btm_sec_clear_ble_keys(p_dev_rec);
4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
500911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->flags |= SMP_PAIR_FLAG_ENC_AFTER_PAIR;
5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
502911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_UINT8(p_cb->peer_io_caps, p);
503911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_UINT8(p_cb->peer_oob_flag, p);
504911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_UINT8(p_cb->peer_auth_req, p);
505911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_UINT8(p_cb->peer_enc_size, p);
506911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_UINT8(p_cb->peer_i_key, p);
507911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_UINT8(p_cb->peer_r_key, p);
5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
509911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (smp_command_has_invalid_parameters(p_cb)) {
5105ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
5115ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = SMP_INVALID_PARAMETERS;
5125ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
513911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
514911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
515911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
516911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  // PTS Testing failure modes
517911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (pts_test_send_authentication_complete_failure(p_cb)) return;
518911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
519911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cb->role == HCI_ROLE_SLAVE) {
520911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (!(p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)) {
521911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* peer (master) started pairing sending Pairing Request */
522911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->local_i_key = p_cb->peer_i_key;
523911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->local_r_key = p_cb->peer_r_key;
524911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
525911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->cb_evt = SMP_SEC_REQUEST_EVT;
526911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else /* update local i/r key according to pairing request */
527911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    {
528911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* pairing started with this side (slave) sending Security Request */
529911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->local_i_key &= p_cb->peer_i_key;
530911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->local_r_key &= p_cb->peer_r_key;
531911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->selected_association_model = smp_select_association_model(p_cb);
532911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
533911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_cb->secure_connections_only_mode_required &&
534911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          (!(p_cb->le_secure_connections_mode_is_used) ||
535911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson           (p_cb->selected_association_model ==
536911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            SMP_MODEL_SEC_CONN_JUSTWORKS))) {
537911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        SMP_TRACE_ERROR(
538b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon            "%s: pairing failed - slave requires secure connection only mode",
539911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            __func__);
5405ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson        tSMP_INT_DATA smp_int_data;
5415ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson        smp_int_data.status = SMP_PAIR_AUTH_FAIL;
5425ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson        smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        return;
544911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
5450bd0c8fc88a7141691a7ca839b11cb711945ee33Nitin Arora
546911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) {
547911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        if (smp_request_oob_data(p_cb)) return;
548911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      } else {
549911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        smp_send_pair_rsp(p_cb, NULL);
550911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
551444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji    }
552911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else /* Master receives pairing response */
553911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  {
554911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cb->selected_association_model = smp_select_association_model(p_cb);
555444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
556911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_cb->secure_connections_only_mode_required &&
557911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        (!(p_cb->le_secure_connections_mode_is_used) ||
558911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson         (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS))) {
559911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      SMP_TRACE_ERROR(
560b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon          "Master requires secure connection only mode "
561b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon          "but it can't be provided -> Master fails pairing");
5625ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      tSMP_INT_DATA smp_int_data;
5635ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      smp_int_data.status = SMP_PAIR_AUTH_FAIL;
5645ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
565911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
566911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
568911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) {
569911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (smp_request_oob_data(p_cb)) return;
570911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else {
571911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_decide_association_model(p_cb, NULL);
5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
573911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
575444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
577ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_proc_confirm
578ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process pairing confirm from peer device
579ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
580911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_proc_confirm(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
5815ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  uint8_t* p = p_data->p_data;
582444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
583911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
584444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
585911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (smp_command_has_invalid_parameters(p_cb)) {
5865ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
5875ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = SMP_INVALID_PARAMETERS;
5885ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
589911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
590911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
5915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
592911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p != NULL) {
593911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* save the SConfirm for comparison later */
594911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    STREAM_TO_ARRAY(p_cb->rconfirm, p, BT_OCTET16_LEN);
595911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
5965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
597911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->flags |= SMP_PAIR_FLAGS_CMD_CONFIRM;
5985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
601ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_proc_init
602ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process pairing initializer from peer device
603ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
604911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_proc_init(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
6055ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  uint8_t* p = p_data->p_data;
606444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
607911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
608444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
609911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (smp_command_has_invalid_parameters(p_cb)) {
6105ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
6115ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = SMP_INVALID_PARAMETERS;
6125ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
613911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
614911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
615444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
616911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* save the SRand for comparison */
617911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_ARRAY(p_cb->rrand, p, BT_OCTET16_LEN);
6185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
619444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
621ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_proc_rand
622ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process pairing random (nonce) from peer device
623ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
624911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_proc_rand(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
6255ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  uint8_t* p = p_data->p_data;
6265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
627911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
629911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (smp_command_has_invalid_parameters(p_cb)) {
6305ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
6315ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = SMP_INVALID_PARAMETERS;
6325ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
633911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
634911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
635444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
636911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* save the SRand for comparison */
637911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_ARRAY(p_cb->rrand, p, BT_OCTET16_LEN);
6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
639444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
6405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
641ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_process_pairing_public_key
642ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process pairing public key command from the peer device
643ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *              - saves the peer public key;
644ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *              - sets the flag indicating that the peer public key is received;
645ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *              - calls smp_wait_for_both_public_keys(...).
646ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
647ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
648911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_process_pairing_public_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
6495ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  uint8_t* p = p_data->p_data;
6505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
651911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
6525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
653911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (smp_command_has_invalid_parameters(p_cb)) {
6545ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
6555ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = SMP_INVALID_PARAMETERS;
6565ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
657911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
658911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
660911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_ARRAY(p_cb->peer_publ_key.x, p, BT_OCTET32_LEN);
661911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_ARRAY(p_cb->peer_publ_key.y, p, BT_OCTET32_LEN);
662911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->flags |= SMP_PAIR_FLAG_HAVE_PEER_PUBL_KEY;
6635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
664911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_wait_for_both_public_keys(p_cb, NULL);
6655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
6665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
6675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
668ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_process_pairing_commitment
669ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process pairing commitment from peer device
670ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
671911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_process_pairing_commitment(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
6725ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  uint8_t* p = p_data->p_data;
6735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
674911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
6755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
676911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (smp_command_has_invalid_parameters(p_cb)) {
6775ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
6785ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = SMP_INVALID_PARAMETERS;
6795ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
680911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
681911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
6825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
683911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->flags |= SMP_PAIR_FLAG_HAVE_PEER_COMM;
6845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
685911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p != NULL) {
686911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    STREAM_TO_ARRAY(p_cb->remote_commitment, p, BT_OCTET16_LEN);
687911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
6885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
689444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
6905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
691ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_process_dhkey_check
692ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process DHKey Check from peer device
693ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
694911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_process_dhkey_check(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
6955ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  uint8_t* p = p_data->p_data;
6965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
697911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
6985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
699911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (smp_command_has_invalid_parameters(p_cb)) {
7005ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
7015ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = SMP_INVALID_PARAMETERS;
7025ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
703911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
704911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
7055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
706911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p != NULL) {
707911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    STREAM_TO_ARRAY(p_cb->remote_dhkey_check, p, BT_OCTET16_LEN);
708911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
709444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
710911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->flags |= SMP_PAIR_FLAG_HAVE_PEER_DHK_CHK;
7115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
7125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
7135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
714ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_process_keypress_notification
715ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process pairing keypress notification from peer device
716ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
717911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_process_keypress_notification(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
7185ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  uint8_t* p = p_data->p_data;
7195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
720911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
7215ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  p_cb->status = p_data->status;
7225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
723911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (smp_command_has_invalid_parameters(p_cb)) {
7245ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
7255ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = SMP_INVALID_PARAMETERS;
7265ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
727911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
728911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
7295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
730911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p != NULL) {
731911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    STREAM_TO_UINT8(p_cb->peer_keypress_notification, p);
732911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
733911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cb->peer_keypress_notification = BTM_SP_KEY_OUT_OF_RANGE;
734911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
735911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->cb_evt = SMP_PEER_KEYPR_NOT_EVT;
7365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
737444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
739ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_br_process_pairing_command
740ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  Process the SMP pairing request/response from peer device via
741ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *              BR/EDR transport.
742ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
743911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_br_process_pairing_command(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
7445ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  uint8_t* p = p_data->p_data;
745911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(p_cb->pairing_bda);
746911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
747911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
748911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* rejecting BR pairing request over non-SC BR link */
749911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!p_dev_rec->new_encryption_key_is_p256 && p_cb->role == HCI_ROLE_SLAVE) {
7505ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
7515ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = SMP_XTRANS_DERIVE_NOT_ALLOW;
7525ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &smp_int_data);
753911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
754911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
755911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
756911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* erase all keys if it is slave proc pairing req*/
757911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_dev_rec && (p_cb->role == HCI_ROLE_SLAVE))
758911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    btm_sec_clear_ble_keys(p_dev_rec);
759911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
760911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->flags |= SMP_PAIR_FLAG_ENC_AFTER_PAIR;
761911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
762911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_UINT8(p_cb->peer_io_caps, p);
763911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_UINT8(p_cb->peer_oob_flag, p);
764911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_UINT8(p_cb->peer_auth_req, p);
765911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_UINT8(p_cb->peer_enc_size, p);
766911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_UINT8(p_cb->peer_i_key, p);
767911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_UINT8(p_cb->peer_r_key, p);
768911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
769911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (smp_command_has_invalid_parameters(p_cb)) {
7705ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
7715ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = SMP_INVALID_PARAMETERS;
7725ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &smp_int_data);
773911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
774911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
775911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
776911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* peer (master) started pairing sending Pairing Request */
777911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* or being master device always use received i/r key as keys to distribute */
778911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->local_i_key = p_cb->peer_i_key;
779911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->local_r_key = p_cb->peer_r_key;
780911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
781911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cb->role == HCI_ROLE_SLAVE) {
782911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_dev_rec->new_encryption_key_is_p256 = false;
783911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* shortcut to skip Security Grant step */
784911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cb->cb_evt = SMP_BR_KEYS_REQ_EVT;
785b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon  } else {
786b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon    /* Master receives pairing response */
787911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SMP_TRACE_DEBUG(
788911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        "%s master rcvs valid PAIRING RESPONSE."
789911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        " Supposed to move to key distribution phase. ",
790911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        __func__);
791911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
792911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
793911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* auth_req received via BR/EDR SM channel is set to 0,
794911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson     but everything derived/exchanged has to be saved */
795911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->peer_auth_req |= SMP_AUTH_BOND;
796911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->loc_auth_req |= SMP_AUTH_BOND;
797444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
798444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
799444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
800ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_br_process_security_grant
801ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process security grant in case of pairing over BR/EDR transport.
802ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
803911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_br_process_security_grant(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
804911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
8055ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  if (p_data->status != SMP_SUCCESS) {
806911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, p_data);
807b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon  } else {
808b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon    /* otherwise, start pairing; send IO request callback */
809911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cb->cb_evt = SMP_BR_KEYS_REQ_EVT;
810911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
811444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
812444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
813444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
814ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_br_check_authorization_request
815ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  sets the SMP kes to be derived/distribute over BR/EDR transport
816ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *              before starting the distribution/derivation
817ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
818911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_br_check_authorization_request(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
819b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon  SMP_TRACE_DEBUG("%s rcvs i_keys=0x%x r_keys=0x%x (i-initiator r-responder)",
820b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon                  __func__, p_cb->local_i_key, p_cb->local_r_key);
821444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
822911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* In LE SC mode LK field is ignored when BR/EDR transport is used */
823911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK;
824911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
825444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
826911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* In LE SC mode only IRK, IAI, CSRK are exchanged with the peer.
827911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  ** Set local_r_key on master to expect only these keys. */
828911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cb->role == HCI_ROLE_MASTER) {
829911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cb->local_r_key &= (SMP_SEC_KEY_TYPE_ID | SMP_SEC_KEY_TYPE_CSRK);
830911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
831444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
832e7f14a682d57811d9df0d64372f222bcc143ec86Jakub Pawlowski  /* Check if H7 function needs to be used for key derivation*/
833e7f14a682d57811d9df0d64372f222bcc143ec86Jakub Pawlowski  if ((p_cb->loc_auth_req & SMP_H7_SUPPORT_BIT) &&
834e7f14a682d57811d9df0d64372f222bcc143ec86Jakub Pawlowski      (p_cb->peer_auth_req & SMP_H7_SUPPORT_BIT)) {
835e7f14a682d57811d9df0d64372f222bcc143ec86Jakub Pawlowski    p_cb->key_derivation_h7_used = TRUE;
836e7f14a682d57811d9df0d64372f222bcc143ec86Jakub Pawlowski  }
837e7f14a682d57811d9df0d64372f222bcc143ec86Jakub Pawlowski  SMP_TRACE_DEBUG("%s: use h7 = %d", __func__, p_cb->key_derivation_h7_used);
838e7f14a682d57811d9df0d64372f222bcc143ec86Jakub Pawlowski
839911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG(
840b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon      "%s rcvs upgrades: i_keys=0x%x r_keys=0x%x (i-initiator r-responder)",
841911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      __func__, p_cb->local_i_key, p_cb->local_r_key);
842444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
843911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (/*((p_cb->peer_auth_req & SMP_AUTH_BOND) ||
844911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          (p_cb->loc_auth_req & SMP_AUTH_BOND)) &&*/
845911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (p_cb->local_i_key || p_cb->local_r_key)) {
846911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_br_state_machine_event(p_cb, SMP_BR_BOND_REQ_EVT, NULL);
847444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
848911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* if no peer key is expected, start master key distribution */
849911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_cb->role == HCI_ROLE_MASTER && p_cb->local_r_key == 0)
850911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_key_distribution_by_transport(p_cb, NULL);
851911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
8525ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
8535ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = SMP_SUCCESS;
8545ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &smp_int_data);
855911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
856444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
8575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
858444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
859ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_br_select_next_key
860ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  selects the next key to derive/send when BR/EDR transport is
861ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *              used.
862ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
863911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_br_select_next_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
864911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s role=%d (0-master) r_keys=0x%x i_keys=0x%x", __func__,
865911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                  p_cb->role, p_cb->local_r_key, p_cb->local_i_key);
8665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
867911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cb->role == HCI_ROLE_SLAVE ||
868911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (!p_cb->local_r_key && p_cb->role == HCI_ROLE_MASTER)) {
869911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_key_pick_key(p_cb, p_data);
870911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
871444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
872911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!p_cb->local_i_key && !p_cb->local_r_key) {
873911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* state check to prevent re-entrance */
874911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (smp_get_br_state() == SMP_BR_STATE_BOND_PENDING) {
8755ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      if (p_cb->total_tx_unacked == 0) {
8765ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson        tSMP_INT_DATA smp_int_data;
8775ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson        smp_int_data.status = SMP_SUCCESS;
8785ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson        smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &smp_int_data);
8795ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      } else {
880911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_cb->wait_for_authorization_complete = true;
8815ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      }
882444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji    }
883911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
8845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
8865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
887ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_proc_enc_info
888ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process encryption information from peer device
889ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
890911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_proc_enc_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
8915ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  uint8_t* p = p_data->p_data;
8925cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
893911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
894911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_ARRAY(p_cb->ltk, p, BT_OCTET16_LEN);
895444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
896911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_key_distribution(p_cb, NULL);
8975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
8985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
899ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_proc_master_id
900ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process master ID from slave device
901ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
902911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_proc_master_id(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
9035ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  uint8_t* p = p_data->p_data;
904911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBTM_LE_PENC_KEYS le_key;
905444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
906911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
907911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_ENC, true);
908444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
909911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_UINT16(le_key.ediv, p);
910911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_ARRAY(le_key.rand, p, BT_OCTET8_LEN);
911444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
912911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* store the encryption keys from peer device */
913911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  memcpy(le_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
914911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  le_key.sec_level = p_cb->sec_level;
915911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  le_key.key_size = p_cb->loc_enc_size;
9165cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
917911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((p_cb->peer_auth_req & SMP_AUTH_BOND) &&
918911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (p_cb->loc_auth_req & SMP_AUTH_BOND))
919911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PENC,
920911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                        (tBTM_LE_KEY_VALUE*)&le_key, true);
921444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
922911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_key_distribution(p_cb, NULL);
9235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
9245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
9255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
926ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_proc_enc_info
927ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process identity information from peer device
928ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
929911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_proc_id_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
9305ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  uint8_t* p = p_data->p_data;
9315cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
932911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
933911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_ARRAY(p_cb->tk, p, BT_OCTET16_LEN); /* reuse TK for IRK */
934911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_key_distribution_by_transport(p_cb, NULL);
935444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
936444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
937444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
938ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_proc_id_addr
939ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process identity address from peer device
940ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
941911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_proc_id_addr(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
9425ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  uint8_t* p = p_data->p_data;
943911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBTM_LE_PID_KEYS pid_key;
944444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
945911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
946911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_ID, true);
947444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
948911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_UINT8(pid_key.addr_type, p);
949b8a477e9ac51898b05cb328eda897d95f1ef3d02Jakub Pawlowski  STREAM_TO_BDADDR(pid_key.static_addr, p);
950911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  memcpy(pid_key.irk, p_cb->tk, BT_OCTET16_LEN);
951444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
952911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* to use as BD_ADDR for lk derived from ltk */
953911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->id_addr_rcvd = true;
954911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->id_addr_type = pid_key.addr_type;
955c2276b06572ab6fc1f900fbb1f41087e77d47e2aJakub Pawlowski  p_cb->id_addr = pid_key.static_addr;
956e28055315f96c0d06e73a66a9bb06df85247b5a7Chaojing Sun
957911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* store the ID key from peer device */
958911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((p_cb->peer_auth_req & SMP_AUTH_BOND) &&
959911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (p_cb->loc_auth_req & SMP_AUTH_BOND))
960911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PID,
961911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                        (tBTM_LE_KEY_VALUE*)&pid_key, true);
962911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_key_distribution_by_transport(p_cb, NULL);
963444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
964444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
965444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
966ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_proc_srk_info
967ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process security information from peer device
968ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
969911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_proc_srk_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
970911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBTM_LE_PCSRK_KEYS le_key;
971444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
972911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
973911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_CSRK, true);
974444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
975911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* save CSRK to security record */
976911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  le_key.sec_level = p_cb->sec_level;
977b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon
978b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon  /* get peer CSRK */
9795ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  maybe_non_aligned_memcpy(le_key.csrk, p_data->p_data, BT_OCTET16_LEN);
980b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon
981b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon  /* initialize the peer counter */
982b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon  le_key.counter = 0;
983444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
984911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((p_cb->peer_auth_req & SMP_AUTH_BOND) &&
985911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (p_cb->loc_auth_req & SMP_AUTH_BOND))
986911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PCSRK,
987911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                        (tBTM_LE_KEY_VALUE*)&le_key, true);
988911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_key_distribution_by_transport(p_cb, NULL);
989444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
990444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
991444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
992ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_proc_compare
993ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process compare value
994ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
995911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_proc_compare(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
996911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
997911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!memcmp(p_cb->rconfirm, p_data->key.p_data, BT_OCTET16_LEN)) {
998911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* compare the max encryption key size, and save the smaller one for the
999911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson     * link */
1000911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_cb->peer_enc_size < p_cb->loc_enc_size)
1001911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->loc_enc_size = p_cb->peer_enc_size;
1002444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1003911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_cb->role == HCI_ROLE_SLAVE)
1004911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_sm_event(p_cb, SMP_RAND_EVT, NULL);
1005911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    else {
1006911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* master device always use received i/r key as keys to distribute */
1007911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->local_i_key = p_cb->peer_i_key;
1008911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->local_r_key = p_cb->peer_r_key;
1009911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1010911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_sm_event(p_cb, SMP_ENC_REQ_EVT, NULL);
1011444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji    }
1012911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1013911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
10145ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
10155ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = SMP_CONFIRM_VALUE_ERR;
10165ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    p_cb->failure = SMP_CONFIRM_VALUE_ERR;
10175ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
1018911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1019444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
1020444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1021444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1022ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_proc_sl_key
1023ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process key ready events.
1024ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1025911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_proc_sl_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1026911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t key_type = p_data->key.key_type;
1027444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1028911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
1029911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (key_type == SMP_KEY_TYPE_TK) {
1030911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_generate_srand_mrand_confirm(p_cb, NULL);
1031911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else if (key_type == SMP_KEY_TYPE_CFM) {
1032911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_set_state(SMP_STATE_WAIT_CONFIRM);
1033444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1034911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_cb->flags & SMP_PAIR_FLAGS_CMD_CONFIRM)
1035911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_sm_event(p_cb, SMP_CONFIRM_EVT, NULL);
1036911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1037444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
1038444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1039444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1040ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_start_enc
1041ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  start encryption
1042ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1043911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_start_enc(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1044911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBTM_STATUS cmd;
1045444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1046911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
1047911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_data != NULL)
1048911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    cmd = btm_ble_start_encrypt(p_cb->pairing_bda, true, p_data->key.p_data);
1049911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  else
1050911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    cmd = btm_ble_start_encrypt(p_cb->pairing_bda, false, NULL);
1051444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
10525ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  if (cmd != BTM_CMD_STARTED && cmd != BTM_BUSY) {
10535ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
10545ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = SMP_ENC_FAIL;
10555ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
10565ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  }
10575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1059444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1060ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_proc_discard
1061ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description   processing for discard security request
1062ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1063911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_proc_discard(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1064911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
1065911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!(p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD))
1066911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_reset_control_value(p_cb);
1067444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
10685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
10695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1070ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_enc_cmpl
1071ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description   encryption success
1072ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1073911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_enc_cmpl(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
10745ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  uint8_t enc_enable = p_data->status;
10755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1076911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
10775ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  tSMP_INT_DATA smp_int_data;
10785ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  smp_int_data.status = enc_enable ? SMP_SUCCESS : SMP_ENC_FAIL;
10795ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
10805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
10815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1082444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1083ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_check_auth_req
1084ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  check authentication request
1085ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1086911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_check_auth_req(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
10875ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  uint8_t enc_enable = p_data->status;
1088911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1089911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG(
1090b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon      "%s rcvs enc_enable=%d i_keys=0x%x r_keys=0x%x (i-initiator r-responder)",
1091911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      __func__, enc_enable, p_cb->local_i_key, p_cb->local_r_key);
1092911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (enc_enable == 1) {
1093911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_cb->le_secure_connections_mode_is_used) {
1094911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* In LE SC mode LTK is used instead of STK and has to be always saved */
1095911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->local_i_key |= SMP_SEC_KEY_TYPE_ENC;
1096911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->local_r_key |= SMP_SEC_KEY_TYPE_ENC;
1097911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1098911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* In LE SC mode LK is derived from LTK only if both sides request it */
1099911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (!(p_cb->local_i_key & SMP_SEC_KEY_TYPE_LK) ||
1100911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          !(p_cb->local_r_key & SMP_SEC_KEY_TYPE_LK)) {
1101911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK;
1102911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
1103911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
1104911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1105911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* In LE SC mode only IRK, IAI, CSRK are exchanged with the peer.
1106911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      ** Set local_r_key on master to expect only these keys.
1107911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      */
1108911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_cb->role == HCI_ROLE_MASTER) {
1109911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_cb->local_r_key &= (SMP_SEC_KEY_TYPE_ID | SMP_SEC_KEY_TYPE_CSRK);
1110911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
1111911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else {
1112911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* in legacy mode derivation of BR/EDR LK is not supported */
1113911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK;
1114911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
1115444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji    }
1116911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SMP_TRACE_DEBUG(
1117b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon        "%s rcvs upgrades: i_keys=0x%x r_keys=0x%x (i-initiator r-responder)",
1118911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        __func__, p_cb->local_i_key, p_cb->local_r_key);
1119911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1120911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (/*((p_cb->peer_auth_req & SMP_AUTH_BOND) ||
1121911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson         (p_cb->loc_auth_req & SMP_AUTH_BOND)) &&*/
1122911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        (p_cb->local_i_key || p_cb->local_r_key)) {
1123911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_sm_event(p_cb, SMP_BOND_REQ_EVT, NULL);
11245ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    } else {
11255ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      tSMP_INT_DATA smp_int_data;
11265ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      smp_int_data.status = enc_enable ? SMP_SUCCESS : SMP_ENC_FAIL;
11275ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
11285ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    }
1129911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else if (enc_enable == 0) {
11305ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
11315ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = enc_enable ? SMP_SUCCESS : SMP_ENC_FAIL;
1132911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* if failed for encryption after pairing, send callback */
1133911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_cb->flags & SMP_PAIR_FLAG_ENC_AFTER_PAIR)
11345ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
1135911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* if enc failed for old security information */
1136911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* if master device, clean up and abck to idle; slave device do nothing */
1137911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    else if (p_cb->role == HCI_ROLE_MASTER) {
11385ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
1139444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji    }
1140911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1141444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
1142444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1143444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1144ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_key_pick_key
1145ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  Pick a key distribution function based on the key mask.
1146ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1147911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_key_pick_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1148911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t key_to_dist =
1149911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (p_cb->role == HCI_ROLE_SLAVE) ? p_cb->local_r_key : p_cb->local_i_key;
1150911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t i = 0;
1151444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1152911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s key_to_dist=0x%x", __func__, key_to_dist);
1153911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  while (i < SMP_KEY_DIST_TYPE_MAX) {
1154911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SMP_TRACE_DEBUG("key to send = %02x, i = %d", key_to_dist, i);
1155444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1156911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (key_to_dist & (1 << i)) {
1157911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      SMP_TRACE_DEBUG("smp_distribute_act[%d]", i);
1158911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (*smp_distribute_act[i])(p_cb, p_data);
1159911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1160444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji    }
1161911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    i++;
1162911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1163444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
1164444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1165ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_key_distribution
1166ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  start key distribution if required.
1167ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1168911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_key_distribution(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1169911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s role=%d (0-master) r_keys=0x%x i_keys=0x%x", __func__,
1170911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                  p_cb->role, p_cb->local_r_key, p_cb->local_i_key);
1171911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1172911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cb->role == HCI_ROLE_SLAVE ||
1173911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (!p_cb->local_r_key && p_cb->role == HCI_ROLE_MASTER)) {
1174911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_key_pick_key(p_cb, p_data);
1175911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1176911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1177911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!p_cb->local_i_key && !p_cb->local_r_key) {
1178911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* state check to prevent re-entrant */
1179911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (smp_get_state() == SMP_STATE_BOND_PENDING) {
1180911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_cb->derive_lk) {
1181911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        smp_derive_link_key_from_long_term_key(p_cb, NULL);
1182911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_cb->derive_lk = false;
1183911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
1184911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1185911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_cb->total_tx_unacked == 0) {
1186911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        /*
1187911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson         * Instead of declaring authorization complete immediately,
1188911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson         * delay the event from being sent by SMP_DELAYED_AUTH_TIMEOUT_MS.
1189911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson         * This allows the slave to send over Pairing Failed if the
1190911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson         * last key is rejected.  During this waiting window, the
1191911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson         * state should remain in SMP_STATE_BOND_PENDING.
1192911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson         */
1193911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        if (!alarm_is_scheduled(p_cb->delayed_auth_timer_ent)) {
1194911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          SMP_TRACE_DEBUG("%s delaying auth complete.", __func__);
1195be8bbd7a83ec8bc900fac58a03010fbcb74956c9Jakub Pawlowski          alarm_set_on_mloop(p_cb->delayed_auth_timer_ent,
1196be8bbd7a83ec8bc900fac58a03010fbcb74956c9Jakub Pawlowski                             SMP_DELAYED_AUTH_TIMEOUT_MS,
1197be8bbd7a83ec8bc900fac58a03010fbcb74956c9Jakub Pawlowski                             smp_delayed_auth_complete_timeout, NULL);
1198444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji        }
1199911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      } else {
1200911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_cb->wait_for_authorization_complete = true;
1201911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
1202444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji    }
1203911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1204444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
1205444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1206444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1207ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         smp_decide_association_model
1208ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function is called to select assoc model to be used for
1209ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  STK generation and to start STK generation process.
1210ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1211ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1212911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_decide_association_model(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1213911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t int_evt = 0;
12145ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  tSMP_INT_DATA smp_int_data;
1215911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1216911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s Association Model = %d", __func__,
1217911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                  p_cb->selected_association_model);
1218911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1219911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  switch (p_cb->selected_association_model) {
1220911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_ENCRYPTION_ONLY: /* TK = 0, go calculate Confirm */
1221911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_cb->role == HCI_ROLE_MASTER &&
1222911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          ((p_cb->peer_auth_req & SMP_AUTH_YN_BIT) != 0) &&
1223911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          ((p_cb->loc_auth_req & SMP_AUTH_YN_BIT) == 0)) {
1224911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        SMP_TRACE_ERROR(
1225911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            "IO capability does not meet authentication requirement");
12265ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson        smp_int_data.status = SMP_PAIR_AUTH_FAIL;
1227911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        int_evt = SMP_AUTH_CMPL_EVT;
1228911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      } else {
1229911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_cb->sec_level = SMP_SEC_UNAUTHENTICATE;
1230911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        SMP_TRACE_EVENT("p_cb->sec_level =%d (SMP_SEC_UNAUTHENTICATE) ",
1231911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                        p_cb->sec_level);
1232911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
12335ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson        tSMP_KEY key;
1234911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        key.key_type = SMP_KEY_TYPE_TK;
1235911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        key.p_data = p_cb->tk;
12365ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson        smp_int_data.key = key;
1237911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1238911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        memset(p_cb->tk, 0, BT_OCTET16_LEN);
1239911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        /* TK, ready  */
1240911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        int_evt = SMP_KEY_READY_EVT;
1241911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
1242911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1243911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1244911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_PASSKEY:
1245911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->sec_level = SMP_SEC_AUTHENTICATED;
1246911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      SMP_TRACE_EVENT("p_cb->sec_level =%d (SMP_SEC_AUTHENTICATED) ",
1247911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                      p_cb->sec_level);
1248911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1249911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->cb_evt = SMP_PASSKEY_REQ_EVT;
1250911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      int_evt = SMP_TK_REQ_EVT;
1251911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1252911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1253911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_OOB:
1254911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      SMP_TRACE_ERROR("Association Model = SMP_MODEL_OOB");
1255911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->sec_level = SMP_SEC_AUTHENTICATED;
1256911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      SMP_TRACE_EVENT("p_cb->sec_level =%d (SMP_SEC_AUTHENTICATED) ",
1257911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                      p_cb->sec_level);
1258911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1259911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->cb_evt = SMP_OOB_REQ_EVT;
1260911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      int_evt = SMP_TK_REQ_EVT;
1261911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1262911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1263911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_KEY_NOTIF:
1264911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->sec_level = SMP_SEC_AUTHENTICATED;
1265911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      SMP_TRACE_DEBUG("Need to generate Passkey");
1266911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1267911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* generate passkey and notify application */
1268911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_generate_passkey(p_cb, NULL);
1269911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1270911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1271911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_JUSTWORKS:
1272911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_NUM_COMP:
1273911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_PASSKEY_ENT:
1274911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_PASSKEY_DISP:
1275911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_OOB:
1276911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      int_evt = SMP_PUBL_KEY_EXCH_REQ_EVT;
1277911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1278911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1279911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_OUT_OF_RANGE:
1280911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      SMP_TRACE_ERROR("Association Model = SMP_MODEL_OUT_OF_RANGE (failed)");
12815ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      smp_int_data.status = SMP_UNKNOWN_IO_CAP;
1282911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      int_evt = SMP_AUTH_CMPL_EVT;
1283911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1284911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1285911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    default:
1286911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      SMP_TRACE_ERROR(
1287911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          "Association Model = %d (SOMETHING IS WRONG WITH THE CODE)",
1288911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_cb->selected_association_model);
12895ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      smp_int_data.status = SMP_UNKNOWN_IO_CAP;
1290911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      int_evt = SMP_AUTH_CMPL_EVT;
1291911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1292911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1293911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_EVENT("sec_level=%d ", p_cb->sec_level);
12945ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson  if (int_evt) smp_sm_event(p_cb, int_evt, &smp_int_data);
1295444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
1296444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1297444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1298ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_process_io_response
1299ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process IO response for a slave device.
1300ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1301911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_process_io_response(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1302911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1303911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
1304911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD) {
1305911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* pairing started by local (slave) Security Request */
1306911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_set_state(SMP_STATE_SEC_REQ_PENDING);
1307911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_send_cmd(SMP_OPCODE_SEC_REQ, p_cb);
1308911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else /* plan to send pairing respond */
1309911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  {
1310911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* pairing started by peer (master) Pairing Request */
1311911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cb->selected_association_model = smp_select_association_model(p_cb);
1312911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1313911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_cb->secure_connections_only_mode_required &&
1314911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        (!(p_cb->le_secure_connections_mode_is_used) ||
1315911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson         (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS))) {
1316911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      SMP_TRACE_ERROR(
1317b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon          "Slave requires secure connection only mode "
1318b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon          "but it can't be provided -> Slave fails pairing");
13195ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      tSMP_INT_DATA smp_int_data;
13205ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      smp_int_data.status = SMP_PAIR_AUTH_FAIL;
13215ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
1322911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
1323911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
1324444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1325911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) {
1326911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (smp_request_oob_data(p_cb)) return;
1327911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
13280bd0c8fc88a7141691a7ca839b11cb711945ee33Nitin Arora
1329911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    // PTS Testing failure modes
1330911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (pts_test_send_authentication_complete_failure(p_cb)) return;
13310bd0c8fc88a7141691a7ca839b11cb711945ee33Nitin Arora
1332911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_send_pair_rsp(p_cb, NULL);
1333911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1334444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
1335444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1336444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1337ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_br_process_slave_keys_response
1338ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  process application keys response for a slave device
1339ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *              (BR/EDR transport).
1340ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1341911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_br_process_slave_keys_response(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1342911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_br_send_pair_response(p_cb, NULL);
1343444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
1344444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1345444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1346ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_br_send_pair_response
13479ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description  actions related to sending pairing response over BR/EDR
13489ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *              transport.
1349ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1350911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_br_send_pair_response(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1351911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
1352444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1353911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->local_i_key &= p_cb->peer_i_key;
1354911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->local_r_key &= p_cb->peer_r_key;
1355444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1356911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_send_cmd(SMP_OPCODE_PAIRING_RSP, p_cb);
1357444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
1358444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1359444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1360ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         smp_pairing_cmpl
13619ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description      This function is called to send the pairing complete
13629ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  callback and remove the connection if needed.
1363ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1364911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_pairing_cmpl(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1365911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cb->total_tx_unacked == 0) {
1366911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* process the pairing complete */
1367911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_proc_pairing_cmpl(p_cb);
1368911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1369444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
1370444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1371444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1372ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         smp_pair_terminate
13739ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description      This function is called to send the pairing complete
13749ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  callback and remove the connection if needed.
1375ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1376911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_pair_terminate(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1377911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
1378911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->status = SMP_CONN_TOUT;
1379911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_proc_pairing_cmpl(p_cb);
1380444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
1381444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1382444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1383ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         smp_idle_terminate
13849ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description      This function calledin idle state to determine to send
13859ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  authentication complete or not.
1386ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1387911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_idle_terminate(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1388911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD) {
1389911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SMP_TRACE_DEBUG("Pairing terminated at IDLE state.");
1390911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cb->status = SMP_FAIL;
1391911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_proc_pairing_cmpl(p_cb);
1392911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1393444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
1394444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1395444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1396ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_fast_conn_param
1397ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  apply default connection parameter for pairing process
1398ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1399911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_fast_conn_param(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1400911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Disable L2CAP connection parameter updates while bonding since
1401911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson     some peripherals are not able to revert to fast connection parameters
1402911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson     during the start of service discovery. Connection paramter updates
1403911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson     get enabled again once service discovery completes. */
1404911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, false);
1405444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
1406444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1407444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1408ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_both_have_public_keys
1409ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  The function is called when both local and peer public keys are
1410ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *              saved.
1411ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *              Actions:
1412ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *              - invokes DHKey computation;
1413ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *              - on slave side invokes sending local public key to the peer.
1414ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *              - invokes SC phase 1 process.
1415ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1416911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_both_have_public_keys(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1417911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
1418444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1419911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* invokes DHKey computation */
1420911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_compute_dhkey(p_cb);
1421444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1422911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* on slave side invokes sending local public key to the peer */
1423911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cb->role == HCI_ROLE_SLAVE) smp_send_pair_public_key(p_cb, NULL);
1424444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1425911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_sm_event(p_cb, SMP_SC_DHKEY_CMPLT_EVT, NULL);
1426444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
14275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
14285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1429ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_start_secure_connection_phase1
14309ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description  Start Secure Connection phase1 i.e. invokes initialization of
14319ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *              Secure Connection phase 1 parameters and starts building/sending
14329ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *              to the peer messages appropriate for the role and association
14339ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *              model.
1434ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1435911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_start_secure_connection_phase1(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1436911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
1437911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1438911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS) {
1439911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cb->sec_level = SMP_SEC_UNAUTHENTICATE;
1440911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SMP_TRACE_EVENT("p_cb->sec_level =%d (SMP_SEC_UNAUTHENTICATE) ",
1441911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                    p_cb->sec_level);
1442911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
1443911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cb->sec_level = SMP_SEC_AUTHENTICATED;
1444911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SMP_TRACE_EVENT("p_cb->sec_level =%d (SMP_SEC_AUTHENTICATED) ",
1445911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                    p_cb->sec_level);
1446911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1447911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1448911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  switch (p_cb->selected_association_model) {
1449911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_JUSTWORKS:
1450911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_NUM_COMP:
1451911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      memset(p_cb->local_random, 0, BT_OCTET16_LEN);
1452911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_start_nonce_generation(p_cb);
1453911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1454911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_PASSKEY_ENT:
1455911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* user has to provide passkey */
1456911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      p_cb->cb_evt = SMP_PASSKEY_REQ_EVT;
1457911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_sm_event(p_cb, SMP_TK_REQ_EVT, NULL);
1458911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1459911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_PASSKEY_DISP:
1460911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* passkey has to be provided to user */
1461911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      SMP_TRACE_DEBUG("Need to generate SC Passkey");
1462911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_generate_passkey(p_cb, NULL);
1463911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1464911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_OOB:
1465911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* use the available OOB information */
1466911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_process_secure_connection_oob_data(p_cb, NULL);
1467911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1468911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    default:
1469911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      SMP_TRACE_ERROR("Association Model = %d is not used in LE SC",
1470911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                      p_cb->selected_association_model);
1471911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1472911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
14735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1474444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
14755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1476ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_process_local_nonce
1477ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  The function processes new local nonce.
1478ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1479ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Note         It is supposed to be called in SC phase1.
1480ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1481911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_process_local_nonce(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1482911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
1483911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1484911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  switch (p_cb->selected_association_model) {
1485911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_JUSTWORKS:
1486911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_NUM_COMP:
1487911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_cb->role == HCI_ROLE_SLAVE) {
1488911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        /* slave calculates and sends local commitment */
1489911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        smp_calculate_local_commitment(p_cb);
1490911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        smp_send_commitment(p_cb, NULL);
1491911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        /* slave has to wait for peer nonce */
1492911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        smp_set_state(SMP_STATE_WAIT_NONCE);
1493911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      } else /* i.e. master */
1494911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      {
1495911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        if (p_cb->flags & SMP_PAIR_FLAG_HAVE_PEER_COMM) {
1496911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          /* slave commitment is already received, send local nonce, wait for
1497911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson           * remote nonce*/
1498911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          SMP_TRACE_DEBUG(
1499b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon              "master in assoc mode = %d "
1500b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon              "already rcvd slave commitment - race condition",
1501911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              p_cb->selected_association_model);
1502911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          p_cb->flags &= ~SMP_PAIR_FLAG_HAVE_PEER_COMM;
1503911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          smp_send_rand(p_cb, NULL);
1504911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          smp_set_state(SMP_STATE_WAIT_NONCE);
1505911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        }
1506911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
1507911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1508911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_PASSKEY_ENT:
1509911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_PASSKEY_DISP:
1510911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_calculate_local_commitment(p_cb);
1511911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1512911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_cb->role == HCI_ROLE_MASTER) {
1513911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        smp_send_commitment(p_cb, NULL);
1514911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      } else /* slave */
1515911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      {
1516911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        if (p_cb->flags & SMP_PAIR_FLAG_HAVE_PEER_COMM) {
1517911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          /* master commitment is already received */
1518911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          smp_send_commitment(p_cb, NULL);
1519911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          smp_set_state(SMP_STATE_WAIT_NONCE);
1520911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        }
1521911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
1522911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1523911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_OOB:
1524911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_cb->role == HCI_ROLE_MASTER) {
1525911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        smp_send_rand(p_cb, NULL);
1526911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
1527911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1528911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_set_state(SMP_STATE_WAIT_NONCE);
1529911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1530911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    default:
1531911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      SMP_TRACE_ERROR("Association Model = %d is not used in LE SC",
1532911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                      p_cb->selected_association_model);
1533911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1534911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
15355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1536444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
15375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1538ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_process_peer_nonce
15399ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description  The function processes newly received and saved in CB peer
15409ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *              nonce. The actions depend on the selected association model and
15419ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *              the role.
1542ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1543ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Note         It is supposed to be called in SC phase1.
1544ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1545911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_process_peer_nonce(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1546911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s start ", __func__);
15475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1548911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  // PTS Testing failure modes
1549fd102ca1610684631837278d74a2cfb6a50f7f69ravishankar srivatsa  if (p_cb->cert_failure == SMP_CONFIRM_VALUE_ERR) {
1550911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SMP_TRACE_ERROR("%s failure case = %d", __func__, p_cb->cert_failure);
15515ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
15525ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = SMP_CONFIRM_VALUE_ERR;
15535ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    p_cb->failure = SMP_CONFIRM_VALUE_ERR;
15545ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
1555911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
1556911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1557fd102ca1610684631837278d74a2cfb6a50f7f69ravishankar srivatsa  // PTS Testing failure modes (for LT)
1558fd102ca1610684631837278d74a2cfb6a50f7f69ravishankar srivatsa  if ((p_cb->cert_failure == SMP_NUMERIC_COMPAR_FAIL) &&
1559fd102ca1610684631837278d74a2cfb6a50f7f69ravishankar srivatsa      (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS) &&
1560fd102ca1610684631837278d74a2cfb6a50f7f69ravishankar srivatsa      (p_cb->role == HCI_ROLE_SLAVE)) {
1561fd102ca1610684631837278d74a2cfb6a50f7f69ravishankar srivatsa    SMP_TRACE_ERROR("%s failure case = %d", __func__, p_cb->cert_failure);
15625ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
15635ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = SMP_NUMERIC_COMPAR_FAIL;
15645ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    p_cb->failure = SMP_NUMERIC_COMPAR_FAIL;
15655ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
1566fd102ca1610684631837278d74a2cfb6a50f7f69ravishankar srivatsa    return;
1567fd102ca1610684631837278d74a2cfb6a50f7f69ravishankar srivatsa  }
1568911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1569911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  switch (p_cb->selected_association_model) {
1570911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_JUSTWORKS:
1571911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_NUM_COMP:
1572911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* in these models only master receives commitment */
1573911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_cb->role == HCI_ROLE_MASTER) {
1574911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        if (!smp_check_commitment(p_cb)) {
15755ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson          tSMP_INT_DATA smp_int_data;
15765ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson          smp_int_data.status = SMP_CONFIRM_VALUE_ERR;
15775ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson          p_cb->failure = SMP_CONFIRM_VALUE_ERR;
15785ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson          smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
1579911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          break;
1580911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        }
1581911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      } else {
1582911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        /* slave sends local nonce */
1583911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        smp_send_rand(p_cb, NULL);
1584911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
1585911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1586911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS) {
1587911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        /* go directly to phase 2 */
1588911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL);
1589911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      } else /* numeric comparison */
1590911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      {
1591911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        smp_set_state(SMP_STATE_WAIT_NONCE);
1592911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        smp_sm_event(p_cb, SMP_SC_CALC_NC_EVT, NULL);
1593911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
1594911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1595911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_PASSKEY_ENT:
1596911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_PASSKEY_DISP:
1597fd102ca1610684631837278d74a2cfb6a50f7f69ravishankar srivatsa      if (!smp_check_commitment(p_cb) &&
1598fd102ca1610684631837278d74a2cfb6a50f7f69ravishankar srivatsa          p_cb->cert_failure != SMP_NUMERIC_COMPAR_FAIL) {
15995ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson        tSMP_INT_DATA smp_int_data;
16005ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson        smp_int_data.status = SMP_CONFIRM_VALUE_ERR;
16015ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson        p_cb->failure = SMP_CONFIRM_VALUE_ERR;
16025ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson        smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
1603911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        break;
1604911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
16050bd0c8fc88a7141691a7ca839b11cb711945ee33Nitin Arora
1606911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_cb->role == HCI_ROLE_SLAVE) {
1607911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        smp_send_rand(p_cb, NULL);
1608911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
1609911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1610911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (++p_cb->round < 20) {
1611911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        smp_set_state(SMP_STATE_SEC_CONN_PHS1_START);
1612911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        p_cb->flags &= ~SMP_PAIR_FLAG_HAVE_PEER_COMM;
1613911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        smp_start_nonce_generation(p_cb);
1614911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        break;
1615911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
1616911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1617911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL);
1618911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1619911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    case SMP_MODEL_SEC_CONN_OOB:
1620911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (p_cb->role == HCI_ROLE_SLAVE) {
1621911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        smp_send_rand(p_cb, NULL);
1622911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
16235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1624911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL);
1625911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1626911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    default:
1627911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      SMP_TRACE_ERROR("Association Model = %d is not used in LE SC",
1628911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                      p_cb->selected_association_model);
1629911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
1630911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1631911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1632911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s end ", __func__);
1633444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
16345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1635444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1636ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_match_dhkey_checks
1637ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  checks if the calculated peer DHKey Check value is the same as
1638ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *              received from the peer DHKey check value.
1639ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1640911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_match_dhkey_checks(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
16415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1642911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
16435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1644911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (memcmp(p_data->key.p_data, p_cb->remote_dhkey_check, BT_OCTET16_LEN)) {
1645911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SMP_TRACE_WARNING("dhkey chcks do no match");
16465ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
16475ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = SMP_DHKEY_CHK_FAIL;
16485ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    p_cb->failure = SMP_DHKEY_CHK_FAIL;
16495ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
1650911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
1651911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
16525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1653911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_EVENT("dhkey chcks match");
16545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1655911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* compare the max encryption key size, and save the smaller one for the link
1656911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson   */
1657911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cb->peer_enc_size < p_cb->loc_enc_size)
1658911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cb->loc_enc_size = p_cb->peer_enc_size;
1659444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1660911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cb->role == HCI_ROLE_SLAVE) {
1661911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_sm_event(p_cb, SMP_PAIR_DHKEY_CHCK_EVT, NULL);
1662911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
1663911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* master device always use received i/r key as keys to distribute */
1664911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cb->local_i_key = p_cb->peer_i_key;
1665911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    p_cb->local_r_key = p_cb->peer_r_key;
1666911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_sm_event(p_cb, SMP_ENC_REQ_EVT, NULL);
1667911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1668444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
16695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1670444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1671ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_move_to_secure_connections_phase2
1672ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  Signal State Machine to start SC phase 2 initialization (to
1673ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *              compute local DHKey Check value).
1674ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1675ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Note         SM is supposed to be in the state SMP_STATE_SEC_CONN_PHS2_START.
1676ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1677911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_move_to_secure_connections_phase2(tSMP_CB* p_cb,
1678911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                           tSMP_INT_DATA* p_data) {
1679911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
1680911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL);
16815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
16825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
16835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1684ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_phase_2_dhkey_checks_are_present
16859ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description  generates event if dhkey check from the peer is already
16869ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *              received.
1687ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1688ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Note         It is supposed to be used on slave to prevent race condition.
16899ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *              It is supposed to be called after slave dhkey check is
16909ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *              calculated.
1691ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1692911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_phase_2_dhkey_checks_are_present(tSMP_CB* p_cb,
1693911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                          tSMP_INT_DATA* p_data) {
1694911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
16955cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
1696911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cb->flags & SMP_PAIR_FLAG_HAVE_PEER_DHK_CHK)
1697911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_sm_event(p_cb, SMP_SC_2_DHCK_CHKS_PRES_EVT, NULL);
16985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1699444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
17005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1701ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_wait_for_both_public_keys
17029ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description  generates SMP_BOTH_PUBL_KEYS_RCVD_EVT event when both local and
17039ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *              master public keys are available.
1704ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1705ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Note         on the slave it is used to prevent race condition.
1706ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1707ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1708911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_wait_for_both_public_keys(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1709911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
17105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1711911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((p_cb->flags & SMP_PAIR_FLAG_HAVE_PEER_PUBL_KEY) &&
1712911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (p_cb->flags & SMP_PAIR_FLAG_HAVE_LOCAL_PUBL_KEY)) {
1713911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if ((p_cb->role == HCI_ROLE_SLAVE) &&
1714911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        ((p_cb->req_oob_type == SMP_OOB_LOCAL) ||
1715911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson         (p_cb->req_oob_type == SMP_OOB_BOTH))) {
1716911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      smp_set_state(SMP_STATE_PUBLIC_KEY_EXCH);
17175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1718911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_sm_event(p_cb, SMP_BOTH_PUBL_KEYS_RCVD_EVT, NULL);
1719911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
17205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1721444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
17225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1723ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_start_passkey_verification
1724ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  Starts SC passkey entry verification.
1725ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1726911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_start_passkey_verification(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1727911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p = NULL;
17285cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen
1729911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
1730911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = p_cb->local_random;
1731911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT32_TO_STREAM(p, p_data->passkey);
1732ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
1733911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p = p_cb->peer_random;
1734911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT32_TO_STREAM(p, p_data->passkey);
17356975b4d711142b885af479721cada448952c6b41Andre Eisenbach
1736911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->round = 0;
1737911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_start_nonce_generation(p_cb);
17386975b4d711142b885af479721cada448952c6b41Andre Eisenbach}
17396975b4d711142b885af479721cada448952c6b41Andre Eisenbach
17406975b4d711142b885af479721cada448952c6b41Andre Eisenbach/*******************************************************************************
1741ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_process_secure_connection_oob_data
1742ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  Processes local/peer SC OOB data received from somewhere.
1743ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1744911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_process_secure_connection_oob_data(tSMP_CB* p_cb,
1745911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                            tSMP_INT_DATA* p_data) {
1746911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
17476975b4d711142b885af479721cada448952c6b41Andre Eisenbach
1748911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSMP_SC_OOB_DATA* p_sc_oob_data = &p_cb->sc_oob_data;
1749911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_sc_oob_data->loc_oob_data.present) {
1750911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy(p_cb->local_random, p_sc_oob_data->loc_oob_data.randomizer,
1751911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson           sizeof(p_cb->local_random));
1752911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
1753911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SMP_TRACE_EVENT("%s: local OOB randomizer is absent", __func__);
1754911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memset(p_cb->local_random, 0, sizeof(p_cb->local_random));
1755911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1756444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1757911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!p_sc_oob_data->peer_oob_data.present) {
1758911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SMP_TRACE_EVENT("%s: peer OOB data is absent", __func__);
1759911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memset(p_cb->peer_random, 0, sizeof(p_cb->peer_random));
1760911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
1761911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy(p_cb->peer_random, p_sc_oob_data->peer_oob_data.randomizer,
1762911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson           sizeof(p_cb->peer_random));
1763911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memcpy(p_cb->remote_commitment, p_sc_oob_data->peer_oob_data.commitment,
1764911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson           sizeof(p_cb->remote_commitment));
1765911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1766911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* check commitment */
1767911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (!smp_check_commitment(p_cb)) {
17685ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      tSMP_INT_DATA smp_int_data;
17695ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      smp_int_data.status = SMP_CONFIRM_VALUE_ERR;
17705ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      p_cb->failure = SMP_CONFIRM_VALUE_ERR;
17715ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson      smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
1772911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      return;
1773444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji    }
17746975b4d711142b885af479721cada448952c6b41Andre Eisenbach
1775911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_cb->peer_oob_flag != SMP_OOB_PRESENT) {
1776911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* the peer doesn't have local randomiser */
1777911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      SMP_TRACE_EVENT(
1778911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          "%s: peer didn't receive local OOB data, set local randomizer to 0",
1779911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          __func__);
1780911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      memset(p_cb->local_random, 0, sizeof(p_cb->local_random));
1781444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji    }
1782911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1783ead3cde4bac0c3e32cd31f149093f004eef8ceebGanesh Ganapathi Batta
1784911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  print128(p_cb->local_random, (const uint8_t*)"local OOB randomizer");
1785911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  print128(p_cb->peer_random, (const uint8_t*)"peer OOB randomizer");
1786911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_start_nonce_generation(p_cb);
17875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1788444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
17895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1790ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_set_local_oob_keys
17919ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description  Saves calculated private/public keys in
17929ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *              sc_oob_data.loc_oob_data, starts nonce generation
1793ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *              (to be saved in sc_oob_data.loc_oob_data.randomizer).
1794ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1795911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_set_local_oob_keys(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1796911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
1797444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1798911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  memcpy(p_cb->sc_oob_data.loc_oob_data.private_key_used, p_cb->private_key,
1799911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson         BT_OCTET32_LEN);
1800911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->sc_oob_data.loc_oob_data.publ_key_used = p_cb->loc_publ_key;
1801911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_start_nonce_generation(p_cb);
18025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
18038fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
18048fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta/*******************************************************************************
1805ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_set_local_oob_random_commitment
18069ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description  Saves calculated randomizer and commitment in
18079ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *              sc_oob_data.loc_oob_data, passes sc_oob_data.loc_oob_data up
18089ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *              for safekeeping.
1809ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1810911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_set_local_oob_random_commitment(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1811911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
1812911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  memcpy(p_cb->sc_oob_data.loc_oob_data.randomizer, p_cb->rand, BT_OCTET16_LEN);
1813444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1814911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_calculate_f4(p_cb->sc_oob_data.loc_oob_data.publ_key_used.x,
1815911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                   p_cb->sc_oob_data.loc_oob_data.publ_key_used.x,
1816911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                   p_cb->sc_oob_data.loc_oob_data.randomizer, 0,
1817911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                   p_cb->sc_oob_data.loc_oob_data.commitment);
1818444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1819d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen#if (SMP_DEBUG == TRUE)
1820911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t* p_print = NULL;
1821911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("local SC OOB data set:");
1822911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_print = (uint8_t*)&p_cb->sc_oob_data.loc_oob_data.addr_sent_to;
1823648d513fd66d28a10dab4def62ca2d27187ccc34Jack He  smp_debug_print_nbyte_little_endian(p_print, "addr_sent_to",
1824911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                      sizeof(tBLE_BD_ADDR));
1825911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_print = (uint8_t*)&p_cb->sc_oob_data.loc_oob_data.private_key_used;
1826648d513fd66d28a10dab4def62ca2d27187ccc34Jack He  smp_debug_print_nbyte_little_endian(p_print, "private_key_used",
1827648d513fd66d28a10dab4def62ca2d27187ccc34Jack He                                      BT_OCTET32_LEN);
1828911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_print = (uint8_t*)&p_cb->sc_oob_data.loc_oob_data.publ_key_used.x;
1829648d513fd66d28a10dab4def62ca2d27187ccc34Jack He  smp_debug_print_nbyte_little_endian(p_print, "publ_key_used.x",
1830648d513fd66d28a10dab4def62ca2d27187ccc34Jack He                                      BT_OCTET32_LEN);
1831911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_print = (uint8_t*)&p_cb->sc_oob_data.loc_oob_data.publ_key_used.y;
1832648d513fd66d28a10dab4def62ca2d27187ccc34Jack He  smp_debug_print_nbyte_little_endian(p_print, "publ_key_used.y",
1833648d513fd66d28a10dab4def62ca2d27187ccc34Jack He                                      BT_OCTET32_LEN);
1834911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_print = (uint8_t*)&p_cb->sc_oob_data.loc_oob_data.randomizer;
1835648d513fd66d28a10dab4def62ca2d27187ccc34Jack He  smp_debug_print_nbyte_little_endian(p_print, "randomizer", BT_OCTET16_LEN);
1836911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_print = (uint8_t*)&p_cb->sc_oob_data.loc_oob_data.commitment;
1837648d513fd66d28a10dab4def62ca2d27187ccc34Jack He  smp_debug_print_nbyte_little_endian(p_print, "commitment", BT_OCTET16_LEN);
1838911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("");
1839444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji#endif
18408fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
1841911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* pass created OOB data up */
1842911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->cb_evt = SMP_SC_LOC_OOB_DATA_UP_EVT;
1843911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_send_app_cback(p_cb, NULL);
1844444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1845911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_cb_cleanup(p_cb);
1846444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
18478fe58875ce67c6e1099e7ba2339dcd2b979491b0Ganesh Ganapathi Batta
18485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1849ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1850ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         smp_link_encrypted
1851ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
18529ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description      This function is called when link is encrypted and notified
18539ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  to the slave device. Proceed to to send LTK, DIV and ER to
18549ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  master if bonding the devices.
1855ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1856ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1857ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
1858ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1859ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1860a484a888196ddf8bcbf1ad3226d6451bc735a94bJakub Pawlowskivoid smp_link_encrypted(const RawAddress& bda, uint8_t encr_enable) {
1861911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSMP_CB* p_cb = &smp_cb;
18625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1863b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon  SMP_TRACE_DEBUG("%s: encr_enable=%d", __func__, encr_enable);
18645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1865c2276b06572ab6fc1f900fbb1f41087e77d47e2aJakub Pawlowski  if (smp_cb.pairing_bda == bda) {
1866b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon    /* encryption completed with STK, remember the key size now, could be
1867b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon     * overwritten when key exchange happens                                 */
1868911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (p_cb->loc_enc_size != 0 && encr_enable) {
1869911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* update the link encryption key size if a SMP pairing just performed */
1870911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      btm_ble_update_sec_key_size(bda, p_cb->loc_enc_size);
18715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1872911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
18735ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
18745ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = encr_enable;
18755ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_sm_event(&smp_cb, SMP_ENCRYPTED_EVT, &smp_int_data);
1876911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
18775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1878444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
18795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*******************************************************************************
1880ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1881ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         smp_proc_ltk_request
1882ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1883ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function is called when LTK request is received from
1884ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  controller.
1885ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1886ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
1887ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1888ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1889a484a888196ddf8bcbf1ad3226d6451bc735a94bJakub Pawlowskibool smp_proc_ltk_request(const RawAddress& bda) {
1890911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s state = %d", __func__, smp_cb.state);
1891911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bool match = false;
18921da48a3600c980fe4ba825d287ff0ac5038be3ffNitin Arora
1893c2276b06572ab6fc1f900fbb1f41087e77d47e2aJakub Pawlowski  if (bda == smp_cb.pairing_bda) {
1894911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    match = true;
1895911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
1896911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bda);
1897c2276b06572ab6fc1f900fbb1f41087e77d47e2aJakub Pawlowski    if (p_dev_rec != NULL && p_dev_rec->ble.pseudo_addr == smp_cb.pairing_bda &&
1898b707f447cbb916de2e0dfd2b4e9bf15818376e64Jakub Pawlowski        p_dev_rec->ble.pseudo_addr != RawAddress::kEmpty) {
1899911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      match = true;
19001da48a3600c980fe4ba825d287ff0ac5038be3ffNitin Arora    }
1901911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
19025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1903911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (match && smp_cb.state == SMP_STATE_ENCRYPTION_PENDING) {
1904911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_sm_event(&smp_cb, SMP_ENC_REQ_EVT, NULL);
1905911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return true;
1906911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
19075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1908911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return false;
19095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
1910444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1911444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1912ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1913ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         smp_process_secure_connection_long_term_key
1914ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1915ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function is called to process SC LTK.
1916ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  SC LTK is calculated and used instead of STK.
1917ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  Here SC LTK is saved in BLE DB.
1918ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1919ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
1920ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1921ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1922911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_process_secure_connection_long_term_key(void) {
1923911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSMP_CB* p_cb = &smp_cb;
1924444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1925911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
1926911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_save_secure_connections_long_term_key(p_cb);
1927444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1928911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_ENC, false);
1929911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_key_distribution(p_cb, NULL);
1930444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
1931444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1932444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1933ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1934ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         smp_set_derive_link_key
1935ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1936ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function is called to set flag that indicates that
1937ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  BR/EDR LK has to be derived from LTK after all keys are
1938ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  distributed.
1939ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1940ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
1941ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1942ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1943911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_set_derive_link_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1944911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
1945911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  p_cb->derive_lk = true;
1946911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_LK, false);
1947911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_key_distribution(p_cb, NULL);
1948e28055315f96c0d06e73a66a9bb06df85247b5a7Chaojing Sun}
1949e28055315f96c0d06e73a66a9bb06df85247b5a7Chaojing Sun
1950e28055315f96c0d06e73a66a9bb06df85247b5a7Chaojing Sun/*******************************************************************************
1951ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1952ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         smp_derive_link_key_from_long_term_key
1953ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1954ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function is called to derive BR/EDR LK from LTK.
1955ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1956ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
1957ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1958ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1959911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_derive_link_key_from_long_term_key(tSMP_CB* p_cb,
1960911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                            tSMP_INT_DATA* p_data) {
1961911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSMP_STATUS status = SMP_PAIR_FAIL_UNKNOWN;
1962444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1963911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
1964911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!smp_calculate_link_key_from_long_term_key(p_cb)) {
1965911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SMP_TRACE_ERROR("%s failed", __func__);
19665ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
19675ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = status;
19685ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
1969911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
1970911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1971444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
1972444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1973444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
1974ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1975ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         smp_br_process_link_key
1976ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1977ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function is called to process BR/EDR LK:
1978ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  - to derive SMP LTK from BR/EDR LK;
1979b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon *                  - to save SMP LTK.
1980ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1981ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Returns          void
1982ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
1983ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
1984911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_br_process_link_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
1985911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tSMP_STATUS status = SMP_PAIR_FAIL_UNKNOWN;
1986444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1987911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
1988911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (!smp_calculate_long_term_key_from_link_key(p_cb)) {
1989b2dadde6c163d59abe39ed9028efc8a986c268e4johnshamoon    SMP_TRACE_ERROR("%s: failed", __func__);
19905ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    tSMP_INT_DATA smp_int_data;
19915ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_int_data.status = status;
19925ce55bd2e01e738e7558038c403bc87e035ba583Myles Watson    smp_sm_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &smp_int_data);
1993911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
1994911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
1995444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
1996911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s: LTK derivation from LK successfully completed",
1997911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                  __func__);
1998911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_save_secure_connections_long_term_key(p_cb);
1999911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_ENC, false);
2000911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  smp_br_select_next_key(p_cb, NULL);
2001444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
2002444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
2003444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
2004ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function     smp_key_distribution_by_transport
2005ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description  depending on the transport used at the moment calls either
2006ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *              smp_key_distribution(...) or smp_br_key_distribution(...).
2007ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
2008911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_key_distribution_by_transport(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
2009911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
2010911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cb->smp_over_br) {
2011911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_br_select_next_key(p_cb, NULL);
2012911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
2013911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_key_distribution(p_cb, NULL);
2014911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
2015444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
2016444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji
2017444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji/*******************************************************************************
2018ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Function         smp_br_pairing_complete
20199ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Description      This function is called to send the pairing complete
20209ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  callback and remove the connection if needed.
2021ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
2022911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid smp_br_pairing_complete(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
2023911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  SMP_TRACE_DEBUG("%s", __func__);
2024d0aa8e53aa7ac1137a47570e08c2b963aaa49141Satya Calloji
2025911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (p_cb->total_tx_unacked == 0) {
2026911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* process the pairing complete */
2027911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    smp_proc_pairing_cmpl(p_cb);
2028911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
2029444a8da807abaf5f9e813ce70c56a79160495fb3Satya Calloji}
2030