| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194 |
- /******************************************************************************
- *
- * Copyright (C) 2003-2012 Broadcom Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************************/
- #include <string.h>
- #include "device/interop.h"
- #include "common/bt_target.h"
- #include "btm_int.h"
- #include "stack/l2c_api.h"
- #include "smp_int.h"
- #include "p_256_ecc_pp.h"
- //#include "utils/include/bt_utils.h"
- #if SMP_INCLUDED == TRUE
- const UINT8 smp_association_table[2][SMP_IO_CAP_MAX][SMP_IO_CAP_MAX] = {
- /* initiator */
- { {SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY}, /* Display Only */
- {SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY}, /* SMP_CAP_IO = 1 */
- {SMP_MODEL_KEY_NOTIF, SMP_MODEL_KEY_NOTIF, SMP_MODEL_PASSKEY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF}, /* keyboard only */
- {SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY},/* No Input No Output */
- {SMP_MODEL_KEY_NOTIF, SMP_MODEL_KEY_NOTIF, SMP_MODEL_PASSKEY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF}
- }, /* keyboard display */
- /* responder */
- { {SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF}, /* Display Only */
- {SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_KEY_NOTIF}, /* SMP_CAP_IO = 1 */
- {SMP_MODEL_PASSKEY, SMP_MODEL_PASSKEY, SMP_MODEL_PASSKEY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY}, /* keyboard only */
- {SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_ENCRYPTION_ONLY},/* No Input No Output */
- {SMP_MODEL_PASSKEY, SMP_MODEL_PASSKEY, SMP_MODEL_KEY_NOTIF, SMP_MODEL_ENCRYPTION_ONLY, SMP_MODEL_PASSKEY}
- } /* keyboard display */
- /* display only */ /*SMP_CAP_IO = 1 */ /* keyboard only */ /* No InputOutput */ /* keyboard display */
- };
- #define SMP_KEY_DIST_TYPE_MAX 4
- const tSMP_ACT smp_distribute_act [] = {
- #if (BLE_INCLUDED == TRUE)
- smp_generate_ltk,
- smp_send_id_info,
- smp_generate_csrk,
- smp_set_derive_link_key
- #else
- NULL,
- NULL,
- NULL,
- NULL
- #endif ///BLE_INCLUDED == TRUE
- };
- extern UINT8 bta_dm_co_ble_get_accept_auth_enable(void);
- extern UINT8 bta_dm_co_ble_get_auth_req(void);
- static bool lmp_version_below(BD_ADDR bda, uint8_t version)
- {
- tACL_CONN *acl = btm_bda_to_acl(bda, BT_TRANSPORT_LE);
- if (acl == NULL || acl->lmp_version == 0) {
- SMP_TRACE_WARNING("%s cannot retrieve LMP version...", __func__);
- return false;
- }
- SMP_TRACE_DEBUG("%s LMP version %d < %d", __func__, acl->lmp_version, version);
- return acl->lmp_version < version;
- }
- /*******************************************************************************
- ** Function smp_update_key_mask
- ** Description This function updates the key mask for sending or receiving.
- *******************************************************************************/
- static void smp_update_key_mask (tSMP_CB *p_cb, UINT8 key_type, BOOLEAN recv)
- {
- SMP_TRACE_DEBUG("%s before update role=%d recv=%d local_i_key = %02x, local_r_key = %02x\n",
- __func__, p_cb->role, recv, p_cb->local_i_key, p_cb->local_r_key);
- if (((p_cb->le_secure_connections_mode_is_used) ||
- (p_cb->smp_over_br)) &&
- ((key_type == SMP_SEC_KEY_TYPE_ENC) || (key_type == SMP_SEC_KEY_TYPE_LK))) {
- /* in LE SC mode LTK, CSRK and BR/EDR LK are derived locally instead of
- ** being exchanged with the peer */
- p_cb->local_i_key &= ~key_type;
- p_cb->local_r_key &= ~key_type;
- } else if (p_cb->role == HCI_ROLE_SLAVE) {
- if (recv) {
- p_cb->local_i_key &= ~key_type;
- } else {
- p_cb->local_r_key &= ~key_type;
- }
- } else {
- if (recv) {
- p_cb->local_r_key &= ~key_type;
- } else {
- p_cb->local_i_key &= ~key_type;
- }
- }
- SMP_TRACE_DEBUG("updated local_i_key = %02x, local_r_key = %02x\n", p_cb->local_i_key,
- p_cb->local_r_key);
- }
- /*******************************************************************************
- ** Function smp_send_app_cback
- ** Description notifies application about the events the application is interested in
- *******************************************************************************/
- void smp_send_app_cback(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- tSMP_EVT_DATA cb_data;
- tSMP_STATUS callback_rc;
- SMP_TRACE_DEBUG("%s p_cb->cb_evt=%d\n", __func__, p_cb->cb_evt);
- if (p_cb->p_callback && p_cb->cb_evt != 0) {
- switch (p_cb->cb_evt) {
- case SMP_IO_CAP_REQ_EVT:
- cb_data.io_req.auth_req = p_cb->peer_auth_req;
- cb_data.io_req.oob_data = SMP_OOB_NONE;
- cb_data.io_req.io_cap = SMP_DEFAULT_IO_CAPS;
- cb_data.io_req.max_key_size = SMP_MAX_ENC_KEY_SIZE;
- cb_data.io_req.init_keys = p_cb->local_i_key ;
- cb_data.io_req.resp_keys = p_cb->local_r_key ;
- SMP_TRACE_DEBUG ( "io_cap = %d", cb_data.io_req.io_cap);
- break;
- case SMP_NC_REQ_EVT:
- cb_data.passkey = p_data->passkey;
- break;
- case SMP_SC_OOB_REQ_EVT:
- cb_data.req_oob_type = p_data->req_oob_type;
- break;
- case SMP_SC_LOC_OOB_DATA_UP_EVT:
- cb_data.loc_oob_data = p_cb->sc_oob_data.loc_oob_data;
- break;
- case SMP_BR_KEYS_REQ_EVT:
- cb_data.io_req.auth_req = 0;
- cb_data.io_req.oob_data = SMP_OOB_NONE;
- cb_data.io_req.io_cap = 0;
- cb_data.io_req.max_key_size = SMP_MAX_ENC_KEY_SIZE;
- cb_data.io_req.init_keys = SMP_BR_SEC_DEFAULT_KEY;
- cb_data.io_req.resp_keys = SMP_BR_SEC_DEFAULT_KEY;
- break;
- default:
- break;
- }
- callback_rc = (*p_cb->p_callback)(p_cb->cb_evt, p_cb->pairing_bda, &cb_data);
- SMP_TRACE_DEBUG("callback_rc=%d p_cb->cb_evt=%d\n", callback_rc, p_cb->cb_evt );
- if (callback_rc == SMP_SUCCESS) {
- switch (p_cb->cb_evt) {
- case SMP_IO_CAP_REQ_EVT:
- p_cb->loc_auth_req = cb_data.io_req.auth_req;
- p_cb->local_io_capability = cb_data.io_req.io_cap;
- p_cb->loc_oob_flag = cb_data.io_req.oob_data;
- p_cb->loc_enc_size = cb_data.io_req.max_key_size;
- p_cb->local_i_key = cb_data.io_req.init_keys;
- p_cb->local_r_key = cb_data.io_req.resp_keys;
- if (!(p_cb->loc_auth_req & SMP_AUTH_BOND)) {
- SMP_TRACE_WARNING ("Non bonding: No keys will be exchanged");
- p_cb->local_i_key = 0;
- p_cb->local_r_key = 0;
- }
- SMP_TRACE_DEBUG ("rcvd auth_req: 0x%02x, io_cap: %d \
- loc_oob_flag: %d loc_enc_size: %d,"
- "local_i_key: 0x%02x, local_r_key: 0x%02x\n",
- p_cb->loc_auth_req, p_cb->local_io_capability, p_cb->loc_oob_flag,
- p_cb->loc_enc_size, p_cb->local_i_key, p_cb->local_r_key);
- p_cb->secure_connections_only_mode_required =
- (btm_cb.security_mode == BTM_SEC_MODE_SC) ? TRUE : FALSE;
- if (p_cb->secure_connections_only_mode_required) {
- p_cb->loc_auth_req |= SMP_SC_SUPPORT_BIT;
- }
- if (!(p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT)
- || lmp_version_below(p_cb->pairing_bda, HCI_PROTO_VERSION_4_2)
- || interop_match(INTEROP_DISABLE_LE_SECURE_CONNECTIONS,
- (const bt_bdaddr_t *)&p_cb->pairing_bda)) {
- p_cb->loc_auth_req &= ~SMP_KP_SUPPORT_BIT;
- p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK;
- p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
- }
- SMP_TRACE_DEBUG("set auth_req: 0x%02x, local_i_key: 0x%02x, local_r_key: 0x%02x\n",
- p_cb->loc_auth_req, p_cb->local_i_key, p_cb->local_r_key);
- smp_sm_event(p_cb, SMP_IO_RSP_EVT, NULL);
- break;
- #if (CLASSIC_BT_INCLUDED == TRUE)
- case SMP_BR_KEYS_REQ_EVT:
- p_cb->loc_enc_size = cb_data.io_req.max_key_size;
- p_cb->local_i_key = cb_data.io_req.init_keys;
- p_cb->local_r_key = cb_data.io_req.resp_keys;
- p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK;
- p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
- SMP_TRACE_WARNING ( "for SMP over BR max_key_size: 0x%02x,\
- local_i_key: 0x%02x, local_r_key: 0x%02x\n",
- p_cb->loc_enc_size, p_cb->local_i_key, p_cb->local_r_key);
- smp_br_state_machine_event(p_cb, SMP_BR_KEYS_RSP_EVT, NULL);
- break;
- #endif ///CLASSIC_BT_INCLUDED == TRUE
- }
- }
- }
- if (!p_cb->cb_evt && p_cb->discard_sec_req) {
- p_cb->discard_sec_req = FALSE;
- smp_sm_event(p_cb, SMP_DISCARD_SEC_REQ_EVT, NULL);
- }
- SMP_TRACE_DEBUG("%s return\n", __func__);
- }
- /*******************************************************************************
- ** Function smp_send_pair_fail
- ** Description pairing failure to peer device if needed.
- *******************************************************************************/
- void smp_send_pair_fail(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- p_cb->status = *(UINT8 *)p_data;
- p_cb->failure = *(UINT8 *)p_data;
- SMP_TRACE_DEBUG("%s status=%d failure=%d ", __func__, p_cb->status, p_cb->failure);
- if (p_cb->status <= SMP_MAX_FAIL_RSN_PER_SPEC && p_cb->status != SMP_SUCCESS) {
- smp_send_cmd(SMP_OPCODE_PAIRING_FAILED, p_cb);
- p_cb->wait_for_authorization_complete = TRUE;
- }
- }
- /*******************************************************************************
- ** Function smp_send_pair_req
- ** Description actions related to sending pairing request
- *******************************************************************************/
- void smp_send_pair_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- #if (BLE_INCLUDED == TRUE)
- tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (p_cb->pairing_bda);
- /* erase all keys when master sends pairing req*/
- if (p_dev_rec) {
- btm_sec_clear_ble_keys(p_dev_rec);
- }
- #endif ///BLE_INCLUDED == TRUE
- /* do not manipulate the key, let app decide,
- leave out to BTM to mandate key distribution for bonding case */
- smp_send_cmd(SMP_OPCODE_PAIRING_REQ, p_cb);
- }
- /*******************************************************************************
- ** Function smp_send_pair_rsp
- ** Description actions related to sending pairing response
- *******************************************************************************/
- void smp_send_pair_rsp(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- #if (BLE_INCLUDED == TRUE)
- p_cb->local_i_key &= p_cb->peer_i_key;
- p_cb->local_r_key &= p_cb->peer_r_key;
- if (smp_send_cmd (SMP_OPCODE_PAIRING_RSP, p_cb)) {
- if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) {
- smp_use_oob_private_key(p_cb, NULL);
- } else {
- smp_decide_association_model(p_cb, NULL);
- }
- }
- #endif ///BLE_INCLUDED == TRUE
- }
- /*******************************************************************************
- ** Function smp_send_confirm
- ** Description send confirmation to the peer
- *******************************************************************************/
- void smp_send_confirm(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- smp_send_cmd(SMP_OPCODE_CONFIRM, p_cb);
- }
- #if 0 //Unused
- /*******************************************************************************
- ** Function smp_send_init
- ** Description process pairing initializer to slave device
- *******************************************************************************/
- void smp_send_init(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- smp_send_cmd(SMP_OPCODE_INIT, p_cb);
- }
- #endif
- /*******************************************************************************
- ** Function smp_send_rand
- ** Description send pairing random to the peer
- *******************************************************************************/
- void smp_send_rand(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- smp_send_cmd(SMP_OPCODE_RAND, p_cb);
- }
- /*******************************************************************************
- ** Function smp_send_pair_public_key
- ** Description send pairing public key command to the peer
- *******************************************************************************/
- void smp_send_pair_public_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- smp_send_cmd(SMP_OPCODE_PAIR_PUBLIC_KEY, p_cb);
- }
- /*******************************************************************************
- ** Function SMP_SEND_COMMITMENT
- ** Description send commitment command to the peer
- *******************************************************************************/
- void smp_send_commitment(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s", __func__);
- smp_send_cmd(SMP_OPCODE_PAIR_COMMITM, p_cb);
- }
- /*******************************************************************************
- ** Function smp_send_dhkey_check
- ** Description send DHKey Check command to the peer
- *******************************************************************************/
- void smp_send_dhkey_check(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s", __func__);
- smp_send_cmd(SMP_OPCODE_PAIR_DHKEY_CHECK, p_cb);
- }
- /*******************************************************************************
- ** Function smp_send_keypress_notification
- ** Description send Keypress Notification command to the peer
- *******************************************************************************/
- void smp_send_keypress_notification(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- p_cb->local_keypress_notification = *(UINT8 *) p_data;
- smp_send_cmd(SMP_OPCODE_PAIR_KEYPR_NOTIF, p_cb);
- }
- /*******************************************************************************
- ** Function smp_send_enc_info
- ** Description send encryption information command.
- *******************************************************************************/
- void smp_send_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- tBTM_LE_LENC_KEYS le_key;
- SMP_TRACE_DEBUG("%s p_cb->loc_enc_size = %d\n", __func__, p_cb->loc_enc_size);
- smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ENC, FALSE);
- smp_send_cmd(SMP_OPCODE_ENCRYPT_INFO, p_cb);
- smp_send_cmd(SMP_OPCODE_MASTER_ID, p_cb);
- /* save the DIV and key size information when acting as slave device */
- memcpy(le_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
- le_key.div = p_cb->div;
- le_key.key_size = p_cb->loc_enc_size;
- le_key.sec_level = p_cb->sec_level;
- #if (BLE_INCLUDED == TRUE)
- if ((p_cb->peer_auth_req & SMP_AUTH_BOND) && (p_cb->loc_auth_req & SMP_AUTH_BOND)) {
- btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LENC,
- (tBTM_LE_KEY_VALUE *)&le_key, TRUE);
- }
- SMP_TRACE_DEBUG ("%s\n", __func__);
- smp_key_distribution(p_cb, NULL);
- #endif ///BLE_INCLUDED == TRUE
- }
- /*******************************************************************************
- ** Function smp_send_id_info
- ** Description send ID information command.
- *******************************************************************************/
- void smp_send_id_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ID, FALSE);
- smp_send_cmd(SMP_OPCODE_IDENTITY_INFO, p_cb);
- smp_send_cmd(SMP_OPCODE_ID_ADDR, p_cb);
- #if (BLE_INCLUDED == TRUE)
- tBTM_LE_KEY_VALUE le_key;
- if ((p_cb->peer_auth_req & SMP_AUTH_BOND) && (p_cb->loc_auth_req & SMP_AUTH_BOND)) {
- btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LID,
- &le_key, TRUE);
- }
- #endif ///BLE_INCLUDED == TRUE
- smp_key_distribution_by_transport(p_cb, NULL);
- }
- #if (BLE_INCLUDED == TRUE)
- /*******************************************************************************
- ** Function smp_send_csrk_info
- ** Description send CSRK command.
- *******************************************************************************/
- void smp_send_csrk_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- tBTM_LE_LCSRK_KEYS key;
- SMP_TRACE_DEBUG("%s\n", __func__);
- smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_CSRK, FALSE);
- if (smp_send_cmd(SMP_OPCODE_SIGN_INFO, p_cb)) {
- key.div = p_cb->div;
- key.sec_level = p_cb->sec_level;
- key.counter = 0; /* initialize the local counter */
- memcpy (key.csrk, p_cb->csrk, BT_OCTET16_LEN);
- btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LCSRK, (tBTM_LE_KEY_VALUE *)&key, TRUE);
- }
- smp_key_distribution_by_transport(p_cb, NULL);
- }
- /*******************************************************************************
- ** Function smp_send_ltk_reply
- ** Description send LTK reply
- *******************************************************************************/
- void smp_send_ltk_reply(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s", __func__);
- /* send stk as LTK response */
- btm_ble_ltk_request_reply(p_cb->pairing_bda, TRUE, p_data->key.p_data);
- }
- /*******************************************************************************
- ** Function smp_proc_sec_req
- ** Description process security request.
- *******************************************************************************/
- void smp_proc_sec_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- tBTM_LE_AUTH_REQ auth_req = *(tBTM_LE_AUTH_REQ *)p_data;
- tBTM_BLE_SEC_REQ_ACT sec_req_act;
- UINT8 reason;
- SMP_TRACE_DEBUG("%s auth_req=0x%x", __func__, auth_req);
- p_cb->cb_evt = 0;
- btm_ble_link_sec_check(p_cb->pairing_bda, auth_req, &sec_req_act);
- SMP_TRACE_DEBUG("%s sec_req_act=0x%x", __func__, sec_req_act);
- switch (sec_req_act) {
- case BTM_BLE_SEC_REQ_ACT_ENCRYPT:
- SMP_TRACE_DEBUG("%s BTM_BLE_SEC_REQ_ACT_ENCRYPT", __func__);
- smp_sm_event(p_cb, SMP_ENC_REQ_EVT, NULL);
- break;
- case BTM_BLE_SEC_REQ_ACT_PAIR:
- p_cb->secure_connections_only_mode_required =
- (btm_cb.security_mode == BTM_SEC_MODE_SC) ? TRUE : FALSE;
- /* respond to non SC pairing request as failure in SC only mode */
- if (p_cb->secure_connections_only_mode_required &&
- (auth_req & SMP_SC_SUPPORT_BIT) == 0) {
- reason = SMP_PAIR_AUTH_FAIL;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- } else {
- /* initialize local i/r key to be default keys */
- p_cb->peer_auth_req = auth_req;
- p_cb->local_r_key = p_cb->local_i_key = SMP_SEC_DEFAULT_KEY ;
- p_cb->cb_evt = SMP_SEC_REQUEST_EVT;
- }
- break;
- case BTM_BLE_SEC_REQ_ACT_DISCARD:
- p_cb->discard_sec_req = TRUE;
- break;
- default:
- /* do nothing */
- break;
- }
- }
- #endif ///BLE_INCLUDED == TRUE
- /*******************************************************************************
- ** Function smp_proc_sec_grant
- ** Description process security grant.
- *******************************************************************************/
- void smp_proc_sec_grant(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 res = *(UINT8 *)p_data;
- SMP_TRACE_DEBUG("%s", __func__);
- if (res != SMP_SUCCESS) {
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, p_data);
- } else { /*otherwise, start pairing */
- /* send IO request callback */
- p_cb->cb_evt = SMP_IO_CAP_REQ_EVT;
- }
- }
- /*******************************************************************************
- ** Function smp_proc_pair_fail
- ** Description process pairing failure from peer device
- *******************************************************************************/
- void smp_proc_pair_fail(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s", __func__);
- p_cb->status = *(UINT8 *)p_data;
- }
- /*******************************************************************************
- ** Function smp_get_auth_mode
- ** Description Get the SMP pairing auth mode
- *******************************************************************************/
- uint16_t smp_get_auth_mode (tSMP_ASSO_MODEL model)
- {
- SMP_TRACE_DEBUG("%s model %d", __func__, model);
- uint16_t auth = 0;
- if (model == SMP_MODEL_ENCRYPTION_ONLY || model == SMP_MODEL_SEC_CONN_JUSTWORKS) {
- //No MITM
- if(model == SMP_MODEL_SEC_CONN_JUSTWORKS) {
- //SC SMP_SC_SUPPORT_BIT
- auth |= SMP_SC_SUPPORT_BIT;
- }
- } else if (model <= SMP_MODEL_KEY_NOTIF) {
- //NO SC, MITM
- auth |= SMP_AUTH_YN_BIT;
- } else if (model <= SMP_MODEL_SEC_CONN_OOB) {
- //SC, MITM
- auth |= SMP_SC_SUPPORT_BIT;
- auth |= SMP_AUTH_YN_BIT;
- } else {
- auth = 0;
- }
- return auth;
- }
- #if (BLE_INCLUDED == TRUE)
- /*******************************************************************************
- ** Function smp_proc_pair_cmd
- ** Description Process the SMP pairing request/response from peer device
- *******************************************************************************/
- void smp_proc_pair_cmd(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 *p = (UINT8 *)p_data;
- UINT8 reason = SMP_ENC_KEY_SIZE;
- tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (p_cb->pairing_bda);
- SMP_TRACE_DEBUG("%s\n", __func__);
- /* erase all keys if it is slave proc pairing req*/
- if (p_dev_rec && (p_cb->role == HCI_ROLE_SLAVE)) {
- btm_sec_clear_ble_keys(p_dev_rec);
- }
- p_cb->flags |= SMP_PAIR_FLAG_ENC_AFTER_PAIR;
- STREAM_TO_UINT8(p_cb->peer_io_caps, p);
- STREAM_TO_UINT8(p_cb->peer_oob_flag, p);
- STREAM_TO_UINT8(p_cb->peer_auth_req, p);
- STREAM_TO_UINT8(p_cb->peer_enc_size, p);
- STREAM_TO_UINT8(p_cb->peer_i_key, p);
- STREAM_TO_UINT8(p_cb->peer_r_key, p);
- if (smp_command_has_invalid_parameters(p_cb)) {
- reason = SMP_INVALID_PARAMETERS;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- return;
- }
- p_cb->accept_specified_sec_auth = bta_dm_co_ble_get_accept_auth_enable();
- p_cb->origin_loc_auth_req = bta_dm_co_ble_get_auth_req();
- if (p_cb->role == HCI_ROLE_SLAVE) {
- if (!(p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)) {
- /* peer (master) started pairing sending Pairing Request */
- p_cb->local_i_key = p_cb->peer_i_key;
- p_cb->local_r_key = p_cb->peer_r_key;
- p_cb->cb_evt = SMP_SEC_REQUEST_EVT;
- } else { /* update local i/r key according to pairing request */
- /* pairing started with this side (slave) sending Security Request */
- p_cb->local_i_key &= p_cb->peer_i_key;
- p_cb->local_r_key &= p_cb->peer_r_key;
- p_cb->selected_association_model = smp_select_association_model(p_cb);
- if (p_cb->secure_connections_only_mode_required &&
- (!(p_cb->le_secure_connections_mode_is_used) ||
- (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS))) {
- SMP_TRACE_ERROR("%s pairing failed - slave requires secure connection only mode",
- __func__);
- reason = SMP_PAIR_AUTH_FAIL;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- return;
- }
- uint16_t auth = smp_get_auth_mode(p_cb->selected_association_model);
- if(p_cb->peer_auth_req & p_cb->loc_auth_req & SMP_AUTH_GEN_BOND) {
- auth |= SMP_AUTH_GEN_BOND;
- }
- p_cb->auth_mode = auth;
- if (p_cb->accept_specified_sec_auth) {
- if ((auth & p_cb->origin_loc_auth_req) != p_cb->origin_loc_auth_req ) {
- SMP_TRACE_ERROR("%s pairing failed - slave requires auth is 0x%x but peer auth is 0x%x local auth is 0x%x",
- __func__, p_cb->origin_loc_auth_req, p_cb->peer_auth_req, p_cb->loc_auth_req);
- if (BTM_IsAclConnectionUp(p_cb->pairing_bda, BT_TRANSPORT_LE)) {
- btm_remove_acl (p_cb->pairing_bda, BT_TRANSPORT_LE);
- }
- reason = SMP_PAIR_AUTH_FAIL;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- return;
- }
- }
- if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB && p_cb->loc_oob_flag == SMP_OOB_PRESENT) {
- if (smp_request_oob_data(p_cb)) {
- return;
- }
- } else {
- smp_send_pair_rsp(p_cb, NULL);
- }
- }
- } else { /* Master receives pairing response */
- p_cb->selected_association_model = smp_select_association_model(p_cb);
- if (p_cb->secure_connections_only_mode_required &&
- (!(p_cb->le_secure_connections_mode_is_used) ||
- (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS))) {
- SMP_TRACE_ERROR ("Master requires secure connection only mode \
- but it can't be provided -> Master fails pairing");
- reason = SMP_PAIR_AUTH_FAIL;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- return;
- }
- uint16_t auth = smp_get_auth_mode(p_cb->selected_association_model);
- if(p_cb->peer_auth_req & p_cb->loc_auth_req & SMP_AUTH_GEN_BOND) {
- auth |= SMP_AUTH_GEN_BOND;
- }
- p_cb->auth_mode = auth;
- if (p_cb->accept_specified_sec_auth) {
- if ((auth & p_cb->origin_loc_auth_req) != p_cb->origin_loc_auth_req ) {
- SMP_TRACE_ERROR("%s pairing failed - master requires auth is 0x%x but peer auth is 0x%x local auth is 0x%x",
- __func__, p_cb->origin_loc_auth_req, p_cb->peer_auth_req, p_cb->loc_auth_req);
- if (BTM_IsAclConnectionUp(p_cb->pairing_bda, BT_TRANSPORT_LE)) {
- btm_remove_acl (p_cb->pairing_bda, BT_TRANSPORT_LE);
- }
- reason = SMP_PAIR_AUTH_FAIL;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- return;
- }
- }
- /* Only if peer oob data present, then should request peer oob data */
- if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB && p_cb->loc_oob_flag == SMP_OOB_PRESENT) {
- if (smp_request_oob_data(p_cb)) {
- return;
- }
- } else {
- smp_decide_association_model(p_cb, NULL);
- }
- }
- }
- #endif ///BLE_INCLUDED == TRUE
- /*******************************************************************************
- ** Function smp_proc_confirm
- ** Description process pairing confirm from peer device
- *******************************************************************************/
- void smp_proc_confirm(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 *p = (UINT8 *)p_data;
- UINT8 reason = SMP_INVALID_PARAMETERS;
- SMP_TRACE_DEBUG("%s\n", __func__);
- if (smp_command_has_invalid_parameters(p_cb)) {
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- return;
- }
- if (p != NULL) {
- /* save the SConfirm for comparison later */
- STREAM_TO_ARRAY(p_cb->rconfirm, p, BT_OCTET16_LEN);
- }
- p_cb->flags |= SMP_PAIR_FLAGS_CMD_CONFIRM;
- }
- #if 0 //Unused
- /*******************************************************************************
- ** Function smp_proc_init
- ** Description process pairing initializer from peer device
- *******************************************************************************/
- void smp_proc_init(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 *p = (UINT8 *)p_data;
- UINT8 reason = SMP_INVALID_PARAMETERS;
- SMP_TRACE_DEBUG("%s", __func__);
- if (smp_command_has_invalid_parameters(p_cb)) {
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- return;
- }
- /* save the SRand for comparison */
- STREAM_TO_ARRAY(p_cb->rrand, p, BT_OCTET16_LEN);
- }
- #endif
- /*******************************************************************************
- ** Function smp_proc_rand
- ** Description process pairing random (nonce) from peer device
- *******************************************************************************/
- void smp_proc_rand(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 *p = (UINT8 *)p_data;
- UINT8 reason = SMP_INVALID_PARAMETERS;
- SMP_TRACE_DEBUG("%s\n", __func__);
- if (smp_command_has_invalid_parameters(p_cb)) {
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- return;
- }
- /* save the SRand for comparison */
- STREAM_TO_ARRAY(p_cb->rrand, p, BT_OCTET16_LEN);
- }
- /*******************************************************************************
- ** Function smp_process_pairing_public_key
- ** Description process pairing public key command from the peer device
- ** - saves the peer public key;
- ** - sets the flag indicating that the peer public key is received;
- ** - calls smp_wait_for_both_public_keys(...).
- **
- *******************************************************************************/
- void smp_process_pairing_public_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 *p = (UINT8 *)p_data;
- UINT8 reason = SMP_INVALID_PARAMETERS;
- SMP_TRACE_DEBUG("%s", __func__);
- if (smp_command_has_invalid_parameters(p_cb)) {
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- return;
- }
- STREAM_TO_ARRAY(p_cb->peer_publ_key.x, p, BT_OCTET32_LEN);
- STREAM_TO_ARRAY(p_cb->peer_publ_key.y, p, BT_OCTET32_LEN);
- /* Check if the peer device's and own public key are not same. If they are same then
- * return pairing fail. This check is needed to avoid 'Impersonation in Passkey entry
- * protocol' vulnerability (CVE-2020-26558).*/
- if ((memcmp(p_cb->loc_publ_key.x, p_cb->peer_publ_key.x, sizeof(BT_OCTET32)) == 0)) {
- p_cb->status = SMP_PAIR_AUTH_FAIL;
- p_cb->failure = SMP_PAIR_AUTH_FAIL;
- reason = SMP_PAIR_AUTH_FAIL;
- SMP_TRACE_ERROR("%s, Peer and own device cannot have same public key.", __func__);
- smp_sm_event(p_cb, SMP_PAIRING_FAILED_EVT, &reason);
- return ;
- }
- /* In order to prevent the x and y coordinates of the public key from being modified,
- we need to check whether the x and y coordinates are on the given elliptic curve. */
- if (!ECC_CheckPointIsInElliCur_P256((Point *)&p_cb->peer_publ_key)) {
- SMP_TRACE_ERROR("%s, Invalid Public key.", __func__);
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- }
- p_cb->flags |= SMP_PAIR_FLAG_HAVE_PEER_PUBL_KEY;
- smp_wait_for_both_public_keys(p_cb, NULL);
- }
- /*******************************************************************************
- ** Function smp_process_pairing_commitment
- ** Description process pairing commitment from peer device
- *******************************************************************************/
- void smp_process_pairing_commitment(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 *p = (UINT8 *)p_data;
- UINT8 reason = SMP_INVALID_PARAMETERS;
- SMP_TRACE_DEBUG("%s", __func__);
- if (smp_command_has_invalid_parameters(p_cb)) {
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- return;
- }
- p_cb->flags |= SMP_PAIR_FLAG_HAVE_PEER_COMM;
- if (p != NULL) {
- STREAM_TO_ARRAY(p_cb->remote_commitment, p, BT_OCTET16_LEN);
- }
- }
- /*******************************************************************************
- ** Function smp_process_dhkey_check
- ** Description process DHKey Check from peer device
- *******************************************************************************/
- void smp_process_dhkey_check(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 *p = (UINT8 *)p_data;
- UINT8 reason = SMP_INVALID_PARAMETERS;
- SMP_TRACE_DEBUG("%s", __func__);
- if (smp_command_has_invalid_parameters(p_cb)) {
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- return;
- }
- if (p != NULL) {
- STREAM_TO_ARRAY(p_cb->remote_dhkey_check, p, BT_OCTET16_LEN);
- }
- p_cb->flags |= SMP_PAIR_FLAG_HAVE_PEER_DHK_CHK;
- }
- /*******************************************************************************
- ** Function smp_process_keypress_notification
- ** Description process pairing keypress notification from peer device
- *******************************************************************************/
- void smp_process_keypress_notification(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 *p = (UINT8 *)p_data;
- UINT8 reason = SMP_INVALID_PARAMETERS;
- SMP_TRACE_DEBUG("%s", __func__);
- p_cb->status = *(UINT8 *)p_data;
- if (smp_command_has_invalid_parameters(p_cb)) {
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- return;
- }
- if (p != NULL) {
- STREAM_TO_UINT8(p_cb->peer_keypress_notification, p);
- } else {
- p_cb->peer_keypress_notification = BTM_SP_KEY_OUT_OF_RANGE;
- }
- p_cb->cb_evt = SMP_PEER_KEYPR_NOT_EVT;
- }
- #if (CLASSIC_BT_INCLUDED == TRUE)
- /*******************************************************************************
- ** Function smp_br_process_pairing_command
- ** Description Process the SMP pairing request/response from peer device via
- ** BR/EDR transport.
- *******************************************************************************/
- void smp_br_process_pairing_command(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 *p = (UINT8 *)p_data;
- UINT8 reason = SMP_ENC_KEY_SIZE;
- tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (p_cb->pairing_bda);
- SMP_TRACE_DEBUG("%s", __func__);
- /* rejecting BR pairing request over non-SC BR link */
- if (!p_dev_rec->new_encryption_key_is_p256 && p_cb->role == HCI_ROLE_SLAVE) {
- reason = SMP_XTRANS_DERIVE_NOT_ALLOW;
- smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &reason);
- return;
- }
- #if (BLE_INCLUDED == TRUE)
- /* erase all keys if it is slave proc pairing req*/
- if (p_dev_rec && (p_cb->role == HCI_ROLE_SLAVE)) {
- btm_sec_clear_ble_keys(p_dev_rec);
- }
- #endif ///BLE_INCLUDED == TRUE
- p_cb->flags |= SMP_PAIR_FLAG_ENC_AFTER_PAIR;
- STREAM_TO_UINT8(p_cb->peer_io_caps, p);
- STREAM_TO_UINT8(p_cb->peer_oob_flag, p);
- STREAM_TO_UINT8(p_cb->peer_auth_req, p);
- STREAM_TO_UINT8(p_cb->peer_enc_size, p);
- STREAM_TO_UINT8(p_cb->peer_i_key, p);
- STREAM_TO_UINT8(p_cb->peer_r_key, p);
- if (smp_command_has_invalid_parameters(p_cb)) {
- reason = SMP_INVALID_PARAMETERS;
- smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &reason);
- return;
- }
- /* peer (master) started pairing sending Pairing Request */
- /* or being master device always use received i/r key as keys to distribute */
- p_cb->local_i_key = p_cb->peer_i_key;
- p_cb->local_r_key = p_cb->peer_r_key;
- if (p_cb->role == HCI_ROLE_SLAVE) {
- p_dev_rec->new_encryption_key_is_p256 = FALSE;
- /* shortcut to skip Security Grant step */
- p_cb->cb_evt = SMP_BR_KEYS_REQ_EVT;
- } else { /* Master receives pairing response */
- SMP_TRACE_DEBUG("%s master rcvs valid PAIRING RESPONSE."
- " Supposed to move to key distribution phase. ", __func__);
- }
- /* auth_req received via BR/EDR SM channel is set to 0,
- but everything derived/exchanged has to be saved */
- p_cb->peer_auth_req |= SMP_AUTH_BOND;
- p_cb->loc_auth_req |= SMP_AUTH_BOND;
- }
- /*******************************************************************************
- ** Function smp_br_process_security_grant
- ** Description process security grant in case of pairing over BR/EDR transport.
- *******************************************************************************/
- void smp_br_process_security_grant(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 res = *(UINT8 *)p_data;
- SMP_TRACE_DEBUG("%s", __func__);
- if (res != SMP_SUCCESS) {
- smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, p_data);
- } else { /*otherwise, start pairing */
- /* send IO request callback */
- p_cb->cb_evt = SMP_BR_KEYS_REQ_EVT;
- }
- }
- /*******************************************************************************
- ** Function smp_br_check_authorization_request
- ** Description sets the SMP kes to be derived/distribute over BR/EDR transport
- ** before starting the distribution/derivation
- *******************************************************************************/
- void smp_br_check_authorization_request(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 reason = SMP_SUCCESS;
- SMP_TRACE_DEBUG("%s rcvs i_keys=0x%x r_keys=0x%x "
- "(i-initiator r-responder)", __FUNCTION__, p_cb->local_i_key,
- p_cb->local_r_key);
- /* In LE SC mode LK field is ignored when BR/EDR transport is used */
- p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK;
- p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
- /* In LE SC mode only IRK, IAI, CSRK are exchanged with the peer.
- ** Set local_r_key on master to expect only these keys. */
- if (p_cb->role == HCI_ROLE_MASTER) {
- p_cb->local_r_key &= (SMP_SEC_KEY_TYPE_ID | SMP_SEC_KEY_TYPE_CSRK);
- }
- SMP_TRACE_DEBUG("%s rcvs upgrades: i_keys=0x%x r_keys=0x%x "
- "(i-initiator r-responder)", __FUNCTION__, p_cb->local_i_key,
- p_cb->local_r_key);
- if (/*((p_cb->peer_auth_req & SMP_AUTH_BOND) ||
- (p_cb->loc_auth_req & SMP_AUTH_BOND)) &&*/
- (p_cb->local_i_key || p_cb->local_r_key)) {
- smp_br_state_machine_event(p_cb, SMP_BR_BOND_REQ_EVT, NULL);
- /* if no peer key is expected, start master key distribution */
- if (p_cb->role == HCI_ROLE_MASTER && p_cb->local_r_key == 0) {
- smp_key_distribution_by_transport(p_cb, NULL);
- }
- } else {
- smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &reason);
- }
- }
- /*******************************************************************************
- ** Function smp_br_select_next_key
- ** Description selects the next key to derive/send when BR/EDR transport is
- ** used.
- *******************************************************************************/
- void smp_br_select_next_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 reason = SMP_SUCCESS;
- SMP_TRACE_DEBUG("%s role=%d (0-master) r_keys=0x%x i_keys=0x%x",
- __func__, p_cb->role, p_cb->local_r_key, p_cb->local_i_key);
- if (p_cb->role == HCI_ROLE_SLAVE ||
- (!p_cb->local_r_key && p_cb->role == HCI_ROLE_MASTER)) {
- smp_key_pick_key(p_cb, p_data);
- }
- if (!p_cb->local_i_key && !p_cb->local_r_key) {
- /* state check to prevent re-entrance */
- if (smp_get_br_state() == SMP_BR_STATE_BOND_PENDING) {
- if (p_cb->total_tx_unacked == 0) {
- smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &reason);
- } else {
- p_cb->wait_for_authorization_complete = TRUE;
- }
- }
- }
- }
- #endif ///CLASSIC_BT_INCLUDED == TRUE
- #if (BLE_INCLUDED == TRUE)
- /*******************************************************************************
- ** Function smp_proc_enc_info
- ** Description process encryption information from peer device
- *******************************************************************************/
- void smp_proc_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 *p = (UINT8 *)p_data;
- SMP_TRACE_DEBUG("%s\n", __func__);
- STREAM_TO_ARRAY(p_cb->ltk, p, BT_OCTET16_LEN);
- smp_key_distribution(p_cb, NULL);
- }
- #endif ///BLE_INCLUDED == TRUE
- /*******************************************************************************
- ** Function smp_proc_master_id
- ** Description process master ID from slave device
- *******************************************************************************/
- void smp_proc_master_id(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 *p = (UINT8 *)p_data;
- tBTM_LE_PENC_KEYS le_key;
- SMP_TRACE_DEBUG("%s\np_cb->peer_auth_req = %d,p_cb->loc_auth_req= %d\n", __func__,
- p_cb->peer_auth_req, p_cb->loc_auth_req);
- smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ENC, TRUE);
- STREAM_TO_UINT16(le_key.ediv, p);
- STREAM_TO_ARRAY(le_key.rand, p, BT_OCTET8_LEN );
- /* store the encryption keys from peer device */
- memcpy(le_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
- le_key.sec_level = p_cb->sec_level;
- le_key.key_size = p_cb->loc_enc_size;
- #if (BLE_INCLUDED == TRUE)
- if ((p_cb->peer_auth_req & SMP_AUTH_BOND) && (p_cb->loc_auth_req & SMP_AUTH_BOND)) {
- btm_sec_save_le_key(p_cb->pairing_bda,
- BTM_LE_KEY_PENC,
- (tBTM_LE_KEY_VALUE *)&le_key, TRUE);
- }
- smp_key_distribution(p_cb, NULL);
- #endif ///BLE_INCLUDED == TRUE
- }
- /*******************************************************************************
- ** Function smp_proc_enc_info
- ** Description process identity information from peer device
- *******************************************************************************/
- void smp_proc_id_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 *p = (UINT8 *)p_data;
- SMP_TRACE_DEBUG("%s", __func__);
- STREAM_TO_ARRAY (p_cb->tk, p, BT_OCTET16_LEN); /* reuse TK for IRK */
- smp_key_distribution_by_transport(p_cb, NULL);
- }
- /*******************************************************************************
- ** Function smp_proc_id_addr
- ** Description process identity address from peer device
- *******************************************************************************/
- void smp_proc_id_addr(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 *p = (UINT8 *)p_data;
- tBTM_LE_PID_KEYS pid_key;
- SMP_TRACE_DEBUG("%s", __func__);
- smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ID, TRUE);
- STREAM_TO_UINT8(pid_key.addr_type, p);
- STREAM_TO_BDADDR(pid_key.static_addr, p);
- memcpy(pid_key.irk, p_cb->tk, BT_OCTET16_LEN);
- /* to use as BD_ADDR for lk derived from ltk */
- p_cb->id_addr_rcvd = TRUE;
- p_cb->id_addr_type = pid_key.addr_type;
- memcpy(p_cb->id_addr, pid_key.static_addr, BD_ADDR_LEN);
- #if (BLE_INCLUDED == TRUE)
- /* store the ID key from peer device */
- if ((p_cb->peer_auth_req & SMP_AUTH_BOND) && (p_cb->loc_auth_req & SMP_AUTH_BOND)) {
- btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PID,
- (tBTM_LE_KEY_VALUE *)&pid_key, TRUE);
- }
- #endif ///BLE_INCLUDED == TRUE
- smp_key_distribution_by_transport(p_cb, NULL);
- }
- /*******************************************************************************
- ** Function smp_proc_srk_info
- ** Description process security information from peer device
- *******************************************************************************/
- void smp_proc_srk_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- #if (BLE_INCLUDED == TRUE)
- tBTM_LE_PCSRK_KEYS le_key;
- SMP_TRACE_DEBUG("%s", __func__);
- smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_CSRK, TRUE);
- /* save CSRK to security record */
- le_key.sec_level = p_cb->sec_level;
- memcpy (le_key.csrk, p_data, BT_OCTET16_LEN); /* get peer CSRK */
- le_key.counter = 0; /* initialize the peer counter */
- if ((p_cb->peer_auth_req & SMP_AUTH_BOND) && (p_cb->loc_auth_req & SMP_AUTH_BOND)) {
- btm_sec_save_le_key(p_cb->pairing_bda,
- BTM_LE_KEY_PCSRK,
- (tBTM_LE_KEY_VALUE *)&le_key, TRUE);
- }
- #endif ///BLE_INCLUDED == TRUE
- smp_key_distribution_by_transport(p_cb, NULL);
- }
- /*******************************************************************************
- ** Function smp_proc_compare
- ** Description process compare value
- *******************************************************************************/
- void smp_proc_compare(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 reason;
- SMP_TRACE_DEBUG("%s\n", __func__);
- if (!memcmp(p_cb->rconfirm, p_data->key.p_data, BT_OCTET16_LEN)) {
- /* compare the max encryption key size, and save the smaller one for the link */
- if ( p_cb->peer_enc_size < p_cb->loc_enc_size) {
- p_cb->loc_enc_size = p_cb->peer_enc_size;
- }
- if (p_cb->role == HCI_ROLE_SLAVE) {
- smp_sm_event(p_cb, SMP_RAND_EVT, NULL);
- } else {
- /* master device always use received i/r key as keys to distribute */
- p_cb->local_i_key = p_cb->peer_i_key;
- p_cb->local_r_key = p_cb->peer_r_key;
- smp_sm_event(p_cb, SMP_ENC_REQ_EVT, NULL);
- }
- } else {
- reason = p_cb->failure = SMP_CONFIRM_VALUE_ERR;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- }
- }
- #if (BLE_INCLUDED == TRUE)
- /*******************************************************************************
- ** Function smp_proc_sl_key
- ** Description process key ready events.
- *******************************************************************************/
- void smp_proc_sl_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 key_type = p_data->key.key_type;
- SMP_TRACE_DEBUG("%s\n", __func__);
- if (key_type == SMP_KEY_TYPE_TK) {
- smp_generate_srand_mrand_confirm(p_cb, NULL);
- } else if (key_type == SMP_KEY_TYPE_CFM) {
- smp_set_state(SMP_STATE_WAIT_CONFIRM);
- if (p_cb->flags & SMP_PAIR_FLAGS_CMD_CONFIRM) {
- smp_sm_event(p_cb, SMP_CONFIRM_EVT, NULL);
- }
- }
- }
- /*******************************************************************************
- ** Function smp_start_enc
- ** Description start encryption
- *******************************************************************************/
- void smp_start_enc(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- tBTM_STATUS cmd;
- UINT8 reason = SMP_ENC_FAIL;
- SMP_TRACE_DEBUG("%s\n", __func__);
- if (p_data != NULL) {
- cmd = btm_ble_start_encrypt(p_cb->pairing_bda, TRUE, p_data->key.p_data);
- } else {
- cmd = btm_ble_start_encrypt(p_cb->pairing_bda, FALSE, NULL);
- }
- if (cmd != BTM_CMD_STARTED && cmd != BTM_BUSY) {
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- }
- }
- #endif ///BLE_INCLUDED == TRUE
- /*******************************************************************************
- ** Function smp_proc_discard
- ** Description processing for discard security request
- *******************************************************************************/
- void smp_proc_discard(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- if (!(p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)) {
- smp_reset_control_value(p_cb);
- }
- }
- /*******************************************************************************
- ** Function smp_enc_cmpl
- ** Description encryption success
- *******************************************************************************/
- void smp_enc_cmpl(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 enc_enable = *(UINT8 *)p_data;
- UINT8 reason = enc_enable ? SMP_SUCCESS : SMP_ENC_FAIL;
- SMP_TRACE_DEBUG("%s\n", __func__);
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- }
- /*******************************************************************************
- ** Function smp_check_auth_req
- ** Description check authentication request
- *******************************************************************************/
- void smp_check_auth_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 enc_enable = *(UINT8 *)p_data;
- UINT8 reason = enc_enable ? SMP_SUCCESS : SMP_ENC_FAIL;
- SMP_TRACE_DEBUG("%s rcvs enc_enable=%d i_keys=0x%x r_keys=0x%x "
- "(i-initiator r-responder)\n",
- __func__, enc_enable, p_cb->local_i_key, p_cb->local_r_key);
- if (enc_enable == 1) {
- if (p_cb->le_secure_connections_mode_is_used) {
- /* In LE SC mode LTK is used instead of STK and has to be always saved */
- p_cb->local_i_key |= SMP_SEC_KEY_TYPE_ENC;
- p_cb->local_r_key |= SMP_SEC_KEY_TYPE_ENC;
- /* In LE SC mode LK is derived from LTK only if both sides request it */
- if (!(p_cb->local_i_key & SMP_SEC_KEY_TYPE_LK) ||
- !(p_cb->local_r_key & SMP_SEC_KEY_TYPE_LK)) {
- p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK;
- p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
- }
- /* In LE SC mode only IRK, IAI, CSRK are exchanged with the peer.
- ** Set local_r_key on master to expect only these keys.
- */
- if (p_cb->role == HCI_ROLE_MASTER) {
- p_cb->local_r_key &= (SMP_SEC_KEY_TYPE_ID | SMP_SEC_KEY_TYPE_CSRK);
- }
- } else {
- /* in legacy mode derivation of BR/EDR LK is not supported */
- p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK;
- p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
- }
- SMP_TRACE_DEBUG("%s rcvs upgrades: i_keys=0x%x r_keys=0x%x "
- "(i-initiator r-responder)\n",
- __func__, p_cb->local_i_key, p_cb->local_r_key);
- if (/*((p_cb->peer_auth_req & SMP_AUTH_BOND) ||
- (p_cb->loc_auth_req & SMP_AUTH_BOND)) &&*/
- (p_cb->local_i_key || p_cb->local_r_key)) {
- smp_sm_event(p_cb, SMP_BOND_REQ_EVT, NULL);
- } else {
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- }
- } else if (enc_enable == 0) {
- /* if failed for encryption after pairing, send callback */
- if (p_cb->flags & SMP_PAIR_FLAG_ENC_AFTER_PAIR) {
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- }
- /* if enc failed for old security information */
- /* if master device, clean up and abck to idle; slave device do nothing */
- else if (p_cb->role == HCI_ROLE_MASTER) {
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- }
- }
- }
- /*******************************************************************************
- ** Function smp_key_pick_key
- ** Description Pick a key distribution function based on the key mask.
- *******************************************************************************/
- void smp_key_pick_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 key_to_dist = (p_cb->role == HCI_ROLE_SLAVE) ? p_cb->local_r_key : p_cb->local_i_key;
- UINT8 i = 0;
- SMP_TRACE_DEBUG("%s key_to_dist=0x%x\n", __func__, key_to_dist);
- while (i < SMP_KEY_DIST_TYPE_MAX) {
- SMP_TRACE_DEBUG("key to send = %02x, i = %d\n", key_to_dist, i);
- if (key_to_dist & (1 << i) && smp_distribute_act[i] != NULL) {
- SMP_TRACE_DEBUG("smp_distribute_act[%d]\n", i);
- (* smp_distribute_act[i])(p_cb, p_data);
- break;
- }
- i ++;
- }
- }
- #if (BLE_INCLUDED == TRUE)
- /*******************************************************************************
- ** Function smp_key_distribution
- ** Description start key distribution if required.
- *******************************************************************************/
- void smp_key_distribution(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 reason = SMP_SUCCESS;
- SMP_TRACE_DEBUG("\n%s role=%d (0-master) r_keys=0x%x i_keys=0x%x\n",
- __func__, p_cb->role, p_cb->local_r_key, p_cb->local_i_key);
- if (p_cb->role == HCI_ROLE_SLAVE ||
- (!p_cb->local_r_key && p_cb->role == HCI_ROLE_MASTER)) {
- smp_key_pick_key(p_cb, p_data);
- }
- if (!p_cb->local_i_key && !p_cb->local_r_key) {
- /* state check to prevent re-entrant */
- if (smp_get_state() == SMP_STATE_BOND_PENDING) {
- if (p_cb->derive_lk) {
- smp_derive_link_key_from_long_term_key(p_cb, NULL);
- p_cb->derive_lk = FALSE;
- }
- if (p_cb->total_tx_unacked == 0) {
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- } else {
- p_cb->wait_for_authorization_complete = TRUE;
- }
- }
- }
- }
- /*******************************************************************************
- ** Function smp_decide_association_model
- ** Description This function is called to select assoc model to be used for
- ** STK generation and to start STK generation process.
- **
- *******************************************************************************/
- void smp_decide_association_model(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 failure = SMP_UNKNOWN_IO_CAP;
- UINT8 int_evt = 0;
- tSMP_KEY key;
- tSMP_INT_DATA *p = NULL;
- SMP_TRACE_DEBUG("%s Association Model = %d\n", __func__, p_cb->selected_association_model);
- switch (p_cb->selected_association_model) {
- case SMP_MODEL_ENCRYPTION_ONLY: /* TK = 0, go calculate Confirm */
- p_cb->sec_level = SMP_SEC_UNAUTHENTICATE;
- SMP_TRACE_EVENT ("p_cb->sec_level =%d (SMP_SEC_UNAUTHENTICATE) \n", p_cb->sec_level );
- key.key_type = SMP_KEY_TYPE_TK;
- key.p_data = p_cb->tk;
- p = (tSMP_INT_DATA *)&key;
- memset(p_cb->tk, 0, BT_OCTET16_LEN);
- /* TK, ready */
- int_evt = SMP_KEY_READY_EVT;
- break;
- case SMP_MODEL_PASSKEY:
- p_cb->sec_level = SMP_SEC_AUTHENTICATED;
- SMP_TRACE_EVENT ("p_cb->sec_level =%d (SMP_SEC_AUTHENTICATED) \n", p_cb->sec_level );
- p_cb->cb_evt = SMP_PASSKEY_REQ_EVT;
- int_evt = SMP_TK_REQ_EVT;
- break;
- case SMP_MODEL_OOB:
- SMP_TRACE_ERROR ("Association Model = SMP_MODEL_OOB\n");
- p_cb->sec_level = SMP_SEC_AUTHENTICATED;
- SMP_TRACE_EVENT ("p_cb->sec_level =%d (SMP_SEC_AUTHENTICATED) \n", p_cb->sec_level );
- p_cb->cb_evt = SMP_OOB_REQ_EVT;
- int_evt = SMP_TK_REQ_EVT;
- break;
- case SMP_MODEL_KEY_NOTIF:
- p_cb->sec_level = SMP_SEC_AUTHENTICATED;
- SMP_TRACE_DEBUG("Need to generate Passkey\n");
- /* generate passkey and notify application */
- smp_generate_passkey(p_cb, NULL);
- break;
- case SMP_MODEL_SEC_CONN_JUSTWORKS:
- case SMP_MODEL_SEC_CONN_NUM_COMP:
- case SMP_MODEL_SEC_CONN_PASSKEY_ENT:
- case SMP_MODEL_SEC_CONN_PASSKEY_DISP:
- case SMP_MODEL_SEC_CONN_OOB:
- int_evt = SMP_PUBL_KEY_EXCH_REQ_EVT;
- break;
- case SMP_MODEL_OUT_OF_RANGE:
- SMP_TRACE_ERROR("Association Model = SMP_MODEL_OUT_OF_RANGE (failed)\n");
- p = (tSMP_INT_DATA *)&failure;
- int_evt = SMP_AUTH_CMPL_EVT;
- break;
- default:
- SMP_TRACE_ERROR("Association Model = %d (SOMETHING IS WRONG WITH THE CODE)\n",
- p_cb->selected_association_model);
- p = (tSMP_INT_DATA *)&failure;
- int_evt = SMP_AUTH_CMPL_EVT;
- }
- SMP_TRACE_EVENT ("sec_level=%d \n", p_cb->sec_level );
- if (int_evt) {
- smp_sm_event(p_cb, int_evt, p);
- }
- }
- /*******************************************************************************
- ** Function smp_process_io_response
- ** Description process IO response for a slave device.
- *******************************************************************************/
- void smp_process_io_response(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- uint8_t reason = SMP_PAIR_AUTH_FAIL;
- SMP_TRACE_DEBUG("%s\n", __func__);
- if (p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD) {
- /* pairing started by local (slave) Security Request */
- smp_set_state(SMP_STATE_SEC_REQ_PENDING);
- smp_send_cmd(SMP_OPCODE_SEC_REQ, p_cb);
- } else { /* plan to send pairing respond */
- /* pairing started by peer (master) Pairing Request */
- p_cb->selected_association_model = smp_select_association_model(p_cb);
- if (p_cb->secure_connections_only_mode_required &&
- (!(p_cb->le_secure_connections_mode_is_used) ||
- (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS))) {
- SMP_TRACE_ERROR ("Slave requires secure connection only mode \
- but it can't be provided -> Slave fails pairing\n");
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- return;
- }
- uint16_t auth = smp_get_auth_mode(p_cb->selected_association_model);
- if(p_cb->peer_auth_req & p_cb->loc_auth_req & SMP_AUTH_GEN_BOND) {
- auth |= SMP_AUTH_GEN_BOND;
- }
- p_cb->auth_mode = auth;
- if (p_cb->accept_specified_sec_auth) {
- if ((auth & p_cb->origin_loc_auth_req) != p_cb->origin_loc_auth_req ) {
- SMP_TRACE_ERROR("pairing failed - slave requires auth is 0x%x but peer auth is 0x%x local auth is 0x%x",
- p_cb->origin_loc_auth_req, p_cb->peer_auth_req, p_cb->loc_auth_req);
- if (BTM_IsAclConnectionUp(p_cb->pairing_bda, BT_TRANSPORT_LE)) {
- btm_remove_acl (p_cb->pairing_bda, BT_TRANSPORT_LE);
- }
- reason = SMP_PAIR_AUTH_FAIL;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- return;
- }
- }
- if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB && p_cb->loc_oob_flag == SMP_OOB_PRESENT) {
- if (smp_request_oob_data(p_cb)) {
- return;
- }
- }
- smp_send_pair_rsp(p_cb, NULL);
- }
- }
- #endif ///BLE_INCLUDED == TRUE
- /*******************************************************************************
- ** Function smp_br_process_slave_keys_response
- ** Description process application keys response for a slave device
- ** (BR/EDR transport).
- *******************************************************************************/
- void smp_br_process_slave_keys_response(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- smp_br_send_pair_response(p_cb, NULL);
- }
- /*******************************************************************************
- ** Function smp_br_send_pair_response
- ** Description actions related to sending pairing response over BR/EDR transport.
- *******************************************************************************/
- void smp_br_send_pair_response(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- p_cb->local_i_key &= p_cb->peer_i_key;
- p_cb->local_r_key &= p_cb->peer_r_key;
- smp_send_cmd (SMP_OPCODE_PAIRING_RSP, p_cb);
- }
- /*******************************************************************************
- ** Function smp_pairing_cmpl
- ** Description This function is called to send the pairing complete callback
- ** and remove the connection if needed.
- *******************************************************************************/
- void smp_pairing_cmpl(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- if (p_cb->total_tx_unacked == 0) {
- /* process the pairing complete */
- smp_proc_pairing_cmpl(p_cb);
- }
- }
- /*******************************************************************************
- ** Function smp_pair_terminate
- ** Description This function is called to send the pairing complete callback
- ** and remove the connection if needed.
- *******************************************************************************/
- void smp_pair_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- p_cb->status = SMP_CONN_TOUT;
- smp_proc_pairing_cmpl(p_cb);
- }
- /*******************************************************************************
- ** Function smp_idle_terminate
- ** Description This function calledin idle state to determine to send authentication
- ** complete or not.
- *******************************************************************************/
- void smp_idle_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- if (p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD) {
- SMP_TRACE_DEBUG("Pairing terminated at IDLE state.\n");
- p_cb->status = SMP_FAIL;
- smp_proc_pairing_cmpl(p_cb);
- }
- }
- #if (BLE_INCLUDED == TRUE)
- /*******************************************************************************
- ** Function smp_fast_conn_param
- ** Description apply default connection parameter for pairing process
- *******************************************************************************/
- void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- if(p_cb->role == BTM_ROLE_MASTER) {
- #if (BT_MULTI_CONNECTION_ENBALE == FALSE)
- L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE);
- #endif
- } else {
- #if (SMP_SLAVE_CON_PARAMS_UPD_ENABLE == TRUE)
- tBTM_SEC_DEV_REC *p_rec = btm_find_dev (p_cb->pairing_bda);
- if(p_rec && p_rec->ble.skip_update_conn_param) {
- //do nothing
- return;
- }
- /* Disable L2CAP connection parameter updates while bonding since
- some peripherals are not able to revert to fast connection parameters
- during the start of service discovery. Connection paramter updates
- get enabled again once service discovery completes. */
- #if (BT_MULTI_CONNECTION_ENBALE == FALSE)
- L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE);
- #endif
- #endif
- }
- }
- /*******************************************************************************
- ** Function smp_both_have_public_keys
- ** Description The function is called when both local and peer public keys are
- ** saved.
- ** Actions:
- ** - invokes DHKey computation;
- ** - on slave side invokes sending local public key to the peer.
- ** - invokes SC phase 1 process.
- *******************************************************************************/
- void smp_both_have_public_keys(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- /* invokes DHKey computation */
- smp_compute_dhkey(p_cb);
- /* on slave side invokes sending local public key to the peer */
- if (p_cb->role == HCI_ROLE_SLAVE) {
- smp_send_pair_public_key(p_cb, NULL);
- }
- smp_sm_event(p_cb, SMP_SC_DHKEY_CMPLT_EVT, NULL);
- }
- /*******************************************************************************
- ** Function smp_start_secure_connection_phase1
- ** Description The function starts Secure Connection phase1 i.e. invokes initialization of Secure Connection
- ** phase 1 parameters and starts building/sending to the peer
- ** messages appropriate for the role and association model.
- *******************************************************************************/
- void smp_start_secure_connection_phase1(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS) {
- p_cb->sec_level = SMP_SEC_UNAUTHENTICATE;
- SMP_TRACE_EVENT ("p_cb->sec_level =%d (SMP_SEC_UNAUTHENTICATE)\n ", p_cb->sec_level );
- } else {
- p_cb->sec_level = SMP_SEC_AUTHENTICATED;
- SMP_TRACE_EVENT ("p_cb->sec_level =%d (SMP_SEC_AUTHENTICATED)\n ", p_cb->sec_level );
- }
- switch (p_cb->selected_association_model) {
- case SMP_MODEL_SEC_CONN_JUSTWORKS:
- case SMP_MODEL_SEC_CONN_NUM_COMP:
- memset(p_cb->local_random, 0, BT_OCTET16_LEN);
- smp_start_nonce_generation(p_cb);
- break;
- case SMP_MODEL_SEC_CONN_PASSKEY_ENT:
- /* user has to provide passkey */
- p_cb->cb_evt = SMP_PASSKEY_REQ_EVT;
- smp_sm_event(p_cb, SMP_TK_REQ_EVT, NULL);
- break;
- case SMP_MODEL_SEC_CONN_PASSKEY_DISP:
- /* passkey has to be provided to user */
- SMP_TRACE_DEBUG("Need to generate SC Passkey\n");
- smp_generate_passkey(p_cb, NULL);
- break;
- case SMP_MODEL_SEC_CONN_OOB:
- /* use the available OOB information */
- smp_process_secure_connection_oob_data(p_cb, NULL);
- break;
- default:
- SMP_TRACE_ERROR ("Association Model = %d is not used in LE SC\n",
- p_cb->selected_association_model);
- break;
- }
- }
- /*******************************************************************************
- ** Function smp_process_local_nonce
- ** Description The function processes new local nonce.
- **
- ** Note It is supposed to be called in SC phase1.
- *******************************************************************************/
- void smp_process_local_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- switch (p_cb->selected_association_model) {
- case SMP_MODEL_SEC_CONN_JUSTWORKS:
- case SMP_MODEL_SEC_CONN_NUM_COMP:
- if (p_cb->role == HCI_ROLE_SLAVE) {
- /* slave calculates and sends local commitment */
- smp_calculate_local_commitment(p_cb);
- smp_send_commitment(p_cb, NULL);
- /* slave has to wait for peer nonce */
- smp_set_state(SMP_STATE_WAIT_NONCE);
- } else { /* i.e. master */
- if (p_cb->flags & SMP_PAIR_FLAG_HAVE_PEER_COMM) {
- /* slave commitment is already received, send local nonce, wait for remote nonce*/
- SMP_TRACE_DEBUG("master in assoc mode = %d \
- already rcvd slave commitment - race condition\n",
- p_cb->selected_association_model);
- p_cb->flags &= ~SMP_PAIR_FLAG_HAVE_PEER_COMM;
- smp_send_rand(p_cb, NULL);
- smp_set_state(SMP_STATE_WAIT_NONCE);
- }
- }
- break;
- case SMP_MODEL_SEC_CONN_PASSKEY_ENT:
- case SMP_MODEL_SEC_CONN_PASSKEY_DISP:
- smp_calculate_local_commitment(p_cb);
- if (p_cb->role == HCI_ROLE_MASTER) {
- smp_send_commitment(p_cb, NULL);
- } else { /* slave */
- if (p_cb->flags & SMP_PAIR_FLAG_HAVE_PEER_COMM) {
- /* master commitment is already received */
- smp_send_commitment(p_cb, NULL);
- smp_set_state(SMP_STATE_WAIT_NONCE);
- }
- }
- break;
- case SMP_MODEL_SEC_CONN_OOB:
- if (p_cb->role == HCI_ROLE_MASTER) {
- smp_send_rand(p_cb, NULL);
- }
- smp_set_state(SMP_STATE_WAIT_NONCE);
- break;
- default:
- SMP_TRACE_ERROR ("Association Model = %d is not used in LE SC\n",
- p_cb->selected_association_model);
- break;
- }
- }
- /*******************************************************************************
- ** Function smp_process_peer_nonce
- ** Description The function processes newly received and saved in CB peer nonce.
- ** The actions depend on the selected association model and the role.
- **
- ** Note It is supposed to be called in SC phase1.
- *******************************************************************************/
- void smp_process_peer_nonce(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 reason;
- SMP_TRACE_DEBUG("%s start \n", __func__);
- switch (p_cb->selected_association_model) {
- case SMP_MODEL_SEC_CONN_JUSTWORKS:
- case SMP_MODEL_SEC_CONN_NUM_COMP:
- /* in these models only master receives commitment */
- if (p_cb->role == HCI_ROLE_MASTER) {
- if (!smp_check_commitment(p_cb)) {
- reason = p_cb->failure = SMP_CONFIRM_VALUE_ERR;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- break;
- }
- } else {
- /* slave sends local nonce */
- smp_send_rand(p_cb, NULL);
- }
- if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS) {
- /* go directly to phase 2 */
- smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL);
- } else { /* numeric comparison */
- smp_set_state(SMP_STATE_WAIT_NONCE);
- smp_sm_event(p_cb, SMP_SC_CALC_NC_EVT, NULL);
- }
- break;
- case SMP_MODEL_SEC_CONN_PASSKEY_ENT:
- case SMP_MODEL_SEC_CONN_PASSKEY_DISP:
- if (!smp_check_commitment(p_cb)) {
- reason = p_cb->failure = SMP_CONFIRM_VALUE_ERR;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- break;
- }
- if (p_cb->role == HCI_ROLE_SLAVE) {
- smp_send_rand(p_cb, NULL);
- }
- if (++p_cb->round < 20) {
- smp_set_state(SMP_STATE_SEC_CONN_PHS1_START);
- p_cb->flags &= ~SMP_PAIR_FLAG_HAVE_PEER_COMM;
- smp_start_nonce_generation(p_cb);
- break;
- }
- smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL);
- break;
- case SMP_MODEL_SEC_CONN_OOB:
- if (p_cb->role == HCI_ROLE_SLAVE) {
- smp_send_rand(p_cb, NULL);
- }
- smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL);
- break;
- default:
- SMP_TRACE_ERROR ("Association Model = %d is not used in LE SC\n",
- p_cb->selected_association_model);
- break;
- }
- SMP_TRACE_DEBUG("%s end\n ", __FUNCTION__);
- }
- #endif ///BLE_INCLUDED == TRUE
- /*******************************************************************************
- ** Function smp_match_dhkey_checks
- ** Description checks if the calculated peer DHKey Check value is the same as
- ** received from the peer DHKey check value.
- *******************************************************************************/
- void smp_match_dhkey_checks(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 reason = SMP_DHKEY_CHK_FAIL;
- SMP_TRACE_DEBUG("%s\n", __func__);
- if (memcmp(p_data->key.p_data, p_cb->remote_dhkey_check, BT_OCTET16_LEN)) {
- SMP_TRACE_WARNING ("dhkey checks do no match\n");
- p_cb->failure = reason;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- return;
- }
- SMP_TRACE_EVENT ("dhkey checks match\n");
- /* compare the max encryption key size, and save the smaller one for the link */
- if (p_cb->peer_enc_size < p_cb->loc_enc_size) {
- p_cb->loc_enc_size = p_cb->peer_enc_size;
- }
- if (p_cb->role == HCI_ROLE_SLAVE) {
- smp_sm_event(p_cb, SMP_PAIR_DHKEY_CHCK_EVT, NULL);
- } else {
- /* master device always use received i/r key as keys to distribute */
- p_cb->local_i_key = p_cb->peer_i_key;
- p_cb->local_r_key = p_cb->peer_r_key;
- smp_sm_event(p_cb, SMP_ENC_REQ_EVT, NULL);
- }
- }
- /*******************************************************************************
- ** Function smp_move_to_secure_connections_phase2
- ** Description Signal State Machine to start SC phase 2 initialization (to
- ** compute local DHKey Check value).
- **
- ** Note SM is supposed to be in the state SMP_STATE_SEC_CONN_PHS2_START.
- *******************************************************************************/
- void smp_move_to_secure_connections_phase2(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL);
- }
- /*******************************************************************************
- ** Function smp_phase_2_dhkey_checks_are_present
- ** Description generates event if dhkey check from the peer is already received.
- **
- ** Note It is supposed to be used on slave to prevent race condition.
- ** It is supposed to be called after slave dhkey check is calculated.
- *******************************************************************************/
- void smp_phase_2_dhkey_checks_are_present(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- if (p_cb->flags & SMP_PAIR_FLAG_HAVE_PEER_DHK_CHK) {
- smp_sm_event(p_cb, SMP_SC_2_DHCK_CHKS_PRES_EVT, NULL);
- }
- }
- /*******************************************************************************
- ** Function smp_wait_for_both_public_keys
- ** Description generates SMP_BOTH_PUBL_KEYS_RCVD_EVT event when both local and master
- ** public keys are available.
- **
- ** Note on the slave it is used to prevent race condition.
- **
- *******************************************************************************/
- void smp_wait_for_both_public_keys(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- if ((p_cb->flags & SMP_PAIR_FLAG_HAVE_PEER_PUBL_KEY) &&
- (p_cb->flags & SMP_PAIR_FLAG_HAVE_LOCAL_PUBL_KEY)) {
- if ((p_cb->role == HCI_ROLE_SLAVE) &&
- ((p_cb->req_oob_type == SMP_OOB_LOCAL) || (p_cb->req_oob_type == SMP_OOB_BOTH))) {
- smp_set_state(SMP_STATE_PUBLIC_KEY_EXCH);
- }
- smp_sm_event(p_cb, SMP_BOTH_PUBL_KEYS_RCVD_EVT, NULL);
- }
- }
- #if (BLE_INCLUDED == TRUE)
- /*******************************************************************************
- ** Function smp_start_passkey_verification
- ** Description Starts SC passkey entry verification.
- *******************************************************************************/
- void smp_start_passkey_verification(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- UINT8 *p = NULL;
- SMP_TRACE_DEBUG("%s\n", __func__);
- p = p_cb->local_random;
- UINT32_TO_STREAM(p, p_data->passkey);
- p = p_cb->peer_random;
- UINT32_TO_STREAM(p, p_data->passkey);
- p_cb->round = 0;
- smp_start_nonce_generation(p_cb);
- }
- /*******************************************************************************
- ** Function smp_process_secure_connection_oob_data
- ** Description Processes local/peer SC OOB data received from somewhere.
- *******************************************************************************/
- void smp_process_secure_connection_oob_data(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- tSMP_SC_OOB_DATA *p_sc_oob_data = &p_cb->sc_oob_data;
- if (p_sc_oob_data->loc_oob_data.present) {
- memcpy(p_cb->local_random, p_sc_oob_data->loc_oob_data.randomizer,
- sizeof(p_cb->local_random));
- } else {
- SMP_TRACE_EVENT ("local OOB randomizer is absent\n");
- memset(p_cb->local_random, 0, sizeof (p_cb->local_random));
- }
- if (!p_sc_oob_data->peer_oob_data.present) {
- SMP_TRACE_EVENT ("peer OOB data is absent\n");
- memset(p_cb->peer_random, 0, sizeof (p_cb->peer_random));
- } else {
- memcpy(p_cb->peer_random, p_sc_oob_data->peer_oob_data.randomizer,
- sizeof(p_cb->peer_random));
- memcpy(p_cb->remote_commitment, p_sc_oob_data->peer_oob_data.commitment,
- sizeof(p_cb->remote_commitment));
- UINT8 reason = SMP_CONFIRM_VALUE_ERR;
- /* check commitment */
- if (!smp_check_commitment(p_cb)) {
- p_cb->failure = reason;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
- return;
- }
- if (p_cb->peer_oob_flag != SMP_OOB_PRESENT) {
- /* the peer doesn't have local randomiser */
- SMP_TRACE_EVENT ("peer didn't receive local OOB data, set local randomizer to 0\n");
- memset(p_cb->local_random, 0, sizeof (p_cb->local_random));
- }
- }
- print128(p_cb->local_random, (const UINT8 *)"local OOB randomizer");
- print128(p_cb->peer_random, (const UINT8 *)"peer OOB randomizer");
- smp_start_nonce_generation(p_cb);
- }
- /*******************************************************************************
- ** Function smp_set_local_oob_keys
- ** Description Saves calculated private/public keys in sc_oob_data.loc_oob_data,
- ** starts nonce generation
- ** (to be saved in sc_oob_data.loc_oob_data.randomizer).
- *******************************************************************************/
- void smp_set_local_oob_keys(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- memcpy(p_cb->sc_oob_data.loc_oob_data.private_key_used, p_cb->private_key,
- BT_OCTET32_LEN);
- p_cb->sc_oob_data.loc_oob_data.publ_key_used = p_cb->loc_publ_key;
- smp_start_nonce_generation(p_cb);
- }
- /*******************************************************************************
- ** Function smp_set_local_oob_random_commitment
- ** Description Saves calculated randomizer and commitment in sc_oob_data.loc_oob_data,
- ** passes sc_oob_data.loc_oob_data up for safekeeping.
- *******************************************************************************/
- void smp_set_local_oob_random_commitment(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- memcpy(p_cb->sc_oob_data.loc_oob_data.randomizer, p_cb->rand,
- BT_OCTET16_LEN);
- smp_calculate_f4(p_cb->sc_oob_data.loc_oob_data.publ_key_used.x,
- p_cb->sc_oob_data.loc_oob_data.publ_key_used.x,
- p_cb->sc_oob_data.loc_oob_data.randomizer, 0,
- p_cb->sc_oob_data.loc_oob_data.commitment);
- p_cb->sc_oob_data.loc_oob_data.present = true;
- #if SMP_DEBUG == TRUE
- UINT8 *p_print = NULL;
- SMP_TRACE_DEBUG("local SC OOB data set:\n");
- p_print = (UINT8 *) &p_cb->sc_oob_data.loc_oob_data.addr_sent_to;
- smp_debug_print_nbyte_little_endian (p_print, (const UINT8 *)"addr_sent_to",
- sizeof(tBLE_BD_ADDR));
- p_print = (UINT8 *) &p_cb->sc_oob_data.loc_oob_data.private_key_used;
- smp_debug_print_nbyte_little_endian (p_print, (const UINT8 *)"private_key_used",
- BT_OCTET32_LEN);
- p_print = (UINT8 *) &p_cb->sc_oob_data.loc_oob_data.publ_key_used.x;
- smp_debug_print_nbyte_little_endian (p_print, (const UINT8 *)"publ_key_used.x",
- BT_OCTET32_LEN);
- p_print = (UINT8 *) &p_cb->sc_oob_data.loc_oob_data.publ_key_used.y;
- smp_debug_print_nbyte_little_endian (p_print, (const UINT8 *)"publ_key_used.y",
- BT_OCTET32_LEN);
- p_print = (UINT8 *) &p_cb->sc_oob_data.loc_oob_data.randomizer;
- smp_debug_print_nbyte_little_endian (p_print, (const UINT8 *)"randomizer",
- BT_OCTET16_LEN);
- p_print = (UINT8 *) &p_cb->sc_oob_data.loc_oob_data.commitment;
- smp_debug_print_nbyte_little_endian (p_print, (const UINT8 *) "commitment",
- BT_OCTET16_LEN);
- SMP_TRACE_DEBUG("");
- #endif
- /* pass created OOB data up */
- p_cb->cb_evt = SMP_SC_LOC_OOB_DATA_UP_EVT;
- smp_send_app_cback(p_cb, NULL);
- // Store the data for later use when we are paired with
- smp_save_local_oob_data(p_cb);
- smp_cb_cleanup(p_cb);
- }
- /*******************************************************************************
- **
- ** Function smp_link_encrypted
- **
- ** Description This function is called when link is encrypted and notified to
- ** slave device. Proceed to to send LTK, DIV and ER to master if
- ** bonding the devices.
- **
- **
- ** Returns void
- **
- *******************************************************************************/
- void smp_link_encrypted(BD_ADDR bda, UINT8 encr_enable)
- {
- tSMP_CB *p_cb = &smp_cb;
- tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bda);
- SMP_TRACE_DEBUG("%s encr_enable=%d\n", __func__, encr_enable);
- if (memcmp(&smp_cb.pairing_bda[0], bda, BD_ADDR_LEN) == 0) {
- /* encryption completed with STK, remmeber the key size now, could be overwite
- * when key exchange happens */
- if (p_cb->loc_enc_size != 0 && encr_enable) {
- /* update the link encryption key size if a SMP pairing just performed */
- btm_ble_update_sec_key_size(bda, p_cb->loc_enc_size);
- }
- smp_sm_event(&smp_cb, SMP_ENCRYPTED_EVT, &encr_enable);
- } else if (p_dev_rec && !p_dev_rec->role_master && !p_dev_rec->enc_init_by_we ){
- /*
- if enc_init_by_we is false, it means that client initiates encryption before slave calls esp_ble_set_encryption()
- we need initiate pairing_bda and p_cb->role then encryption, for example iPhones
- */
- memcpy(&smp_cb.pairing_bda[0], bda, BD_ADDR_LEN);
- p_cb->state = SMP_STATE_ENCRYPTION_PENDING;
- p_cb->role = HCI_ROLE_SLAVE;
- p_dev_rec->enc_init_by_we = FALSE;
- smp_sm_event(&smp_cb, SMP_ENCRYPTED_EVT, &encr_enable);
- } else if (p_dev_rec && p_dev_rec->role_master && p_dev_rec->enc_init_by_we){
- memcpy(&smp_cb.pairing_bda[0], bda, BD_ADDR_LEN);
- p_cb->state = SMP_STATE_ENCRYPTION_PENDING;
- p_cb->role = HCI_ROLE_MASTER;
- p_dev_rec->enc_init_by_we = FALSE;
- smp_sm_event(&smp_cb, SMP_ENCRYPTED_EVT, &encr_enable);
- }
- }
- /*******************************************************************************
- **
- ** Function smp_proc_ltk_request
- **
- ** Description This function is called when LTK request is received from
- ** controller.
- **
- ** Returns void
- **
- *******************************************************************************/
- BOOLEAN smp_proc_ltk_request(BD_ADDR bda)
- {
- SMP_TRACE_DEBUG("%s state = %d\n", __func__, smp_cb.state);
- BOOLEAN match = FALSE;
- if (!memcmp(bda, smp_cb.pairing_bda, BD_ADDR_LEN)) {
- match = TRUE;
- } else {
- BD_ADDR dummy_bda = {0};
- tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(bda);
- if (p_dev_rec != NULL &&
- 0 == memcmp(p_dev_rec->ble.pseudo_addr, smp_cb.pairing_bda, BD_ADDR_LEN) &&
- 0 != memcmp(p_dev_rec->ble.pseudo_addr, dummy_bda, BD_ADDR_LEN)) {
- match = TRUE;
- }
- }
- if (match && smp_cb.state == SMP_STATE_ENCRYPTION_PENDING) {
- smp_sm_event(&smp_cb, SMP_ENC_REQ_EVT, NULL);
- return TRUE;
- }
- return FALSE;
- }
- /*******************************************************************************
- **
- ** Function smp_process_secure_connection_long_term_key
- **
- ** Description This function is called to process SC LTK.
- ** SC LTK is calculated and used instead of STK.
- ** Here SC LTK is saved in BLE DB.
- **
- ** Returns void
- **
- *******************************************************************************/
- void smp_process_secure_connection_long_term_key(void)
- {
- tSMP_CB *p_cb = &smp_cb;
- SMP_TRACE_DEBUG("%s\n", __func__);
- smp_save_secure_connections_long_term_key(p_cb);
- smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ENC, FALSE);
- smp_key_distribution(p_cb, NULL);
- }
- /*******************************************************************************
- **
- ** Function smp_set_derive_link_key
- **
- ** Description This function is called to set flag that indicates that
- ** BR/EDR LK has to be derived from LTK after all keys are
- ** distributed.
- **
- ** Returns void
- **
- *******************************************************************************/
- void smp_set_derive_link_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG ("%s\n", __func__);
- p_cb->derive_lk = TRUE;
- smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_LK, FALSE);
- smp_key_distribution(p_cb, NULL);
- }
- /*******************************************************************************
- **
- ** Function smp_derive_link_key_from_long_term_key
- **
- ** Description This function is called to derive BR/EDR LK from LTK.
- **
- ** Returns void
- **
- *******************************************************************************/
- void smp_derive_link_key_from_long_term_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- tSMP_STATUS status = SMP_PAIR_FAIL_UNKNOWN;
- SMP_TRACE_DEBUG("%s\n", __func__);
- if (!smp_calculate_link_key_from_long_term_key(p_cb)) {
- SMP_TRACE_ERROR("%s failed\n", __FUNCTION__);
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
- return;
- }
- }
- #endif ///BLE_INCLUDED == TRUE
- #if (CLASSIC_BT_INCLUDED == TRUE)
- /*******************************************************************************
- **
- ** Function smp_br_process_link_key
- **
- ** Description This function is called to process BR/EDR LK:
- ** - to derive SMP LTK from BR/EDR LK;
- *8 - to save SMP LTK.
- **
- ** Returns void
- **
- *******************************************************************************/
- void smp_br_process_link_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- tSMP_STATUS status = SMP_PAIR_FAIL_UNKNOWN;
- SMP_TRACE_DEBUG("%s\n", __func__);
- if (!smp_calculate_long_term_key_from_link_key(p_cb)) {
- SMP_TRACE_ERROR ("%s failed\n", __FUNCTION__);
- smp_sm_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &status);
- return;
- }
- SMP_TRACE_DEBUG("%s: LTK derivation from LK successfully completed\n", __FUNCTION__);
- smp_save_secure_connections_long_term_key(p_cb);
- smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ENC, FALSE);
- smp_br_select_next_key(p_cb, NULL);
- }
- #endif ///CLASSIC_BT_INCLUDED == TRUE
- /*******************************************************************************
- ** Function smp_key_distribution_by_transport
- ** Description depending on the transport used at the moment calls either
- ** smp_key_distribution(...) or smp_br_key_distribution(...).
- *******************************************************************************/
- void smp_key_distribution_by_transport(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- if (p_cb->smp_over_br) {
- #if (CLASSIC_BT_INCLUDED == TRUE)
- smp_br_select_next_key(p_cb, NULL);
- #endif ///CLASSIC_BT_INCLUDED == TRUE
- } else {
- #if (BLE_INCLUDED == TRUE)
- smp_key_distribution(p_cb, NULL);
- #endif ///BLE_INCLUDED == TRUE
- }
- }
- /*******************************************************************************
- ** Function smp_br_pairing_complete
- ** Description This function is called to send the pairing complete callback
- ** and remove the connection if needed.
- *******************************************************************************/
- void smp_br_pairing_complete(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
- {
- SMP_TRACE_DEBUG("%s\n", __func__);
- if (p_cb->total_tx_unacked == 0) {
- /* process the pairing complete */
- smp_proc_pairing_cmpl(p_cb);
- }
- }
- #endif
|