12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102 |
- /******************************************************************************
- *
- * Copyright 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 <cutils/log.h>
- #include <log/log.h>
- #include <string.h>
- #include "btif_common.h"
- #include "btif_storage.h"
- #include "device/include/interop.h"
- #include "internal_include/bt_target.h"
- #include "stack/btm/btm_int.h"
- #include "stack/include/l2c_api.h"
- #include "stack/smp/p_256_ecc_pp.h"
- #include "stack/smp/smp_int.h"
- #include "utils/include/bt_utils.h"
- #define SMP_KEY_DIST_TYPE_MAX 4
- const tSMP_ACT smp_distribute_act[] = {
- smp_generate_ltk, /* SMP_SEC_KEY_TYPE_ENC - '1' bit index */
- smp_send_id_info, /* SMP_SEC_KEY_TYPE_ID - '1' bit index */
- smp_generate_csrk, /* SMP_SEC_KEY_TYPE_CSRK - '1' bit index */
- smp_set_derive_link_key /* SMP_SEC_KEY_TYPE_LK - '1' bit index */
- };
- static bool lmp_version_below(const RawAddress& 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_WARNING("%s LMP version %d < %d", __func__, acl->lmp_version,
- version);
- return acl->lmp_version < version;
- }
- static bool pts_test_send_authentication_complete_failure(tSMP_CB* p_cb) {
- uint8_t reason = p_cb->cert_failure;
- if (reason == SMP_PAIR_AUTH_FAIL || reason == SMP_PAIR_FAIL_UNKNOWN ||
- reason == SMP_PAIR_NOT_SUPPORT || reason == SMP_PASSKEY_ENTRY_FAIL ||
- reason == SMP_REPEATED_ATTEMPTS) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = reason;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return true;
- }
- return false;
- }
- /*******************************************************************************
- * 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_t key_type, bool recv) {
- SMP_TRACE_DEBUG(
- "%s before update role=%d recv=%d local_i_key = %02x, local_r_key = %02x",
- __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",
- 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", __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 = btif_storage_get_local_io_caps_ble();
- 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_WARNING("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("%s: callback_rc=%d p_cb->cb_evt=%d", __func__,
- 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_WARNING(
- "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",
- 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;
- /* just for PTS, force SC bit */
- if (p_cb->secure_connections_only_mode_required) {
- p_cb->loc_auth_req |= SMP_SC_SUPPORT_BIT;
- }
- if (!p_cb->secure_connections_only_mode_required &&
- (!(p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT) ||
- lmp_version_below(p_cb->pairing_bda, HCI_PROTO_VERSION_4_2) ||
- interop_match_addr(INTEROP_DISABLE_LE_SECURE_CONNECTIONS,
- (const RawAddress*)&p_cb->pairing_bda))) {
- p_cb->loc_auth_req &= ~SMP_SC_SUPPORT_BIT;
- 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;
- }
- if (lmp_version_below(p_cb->pairing_bda, HCI_PROTO_VERSION_5_0)) {
- p_cb->loc_auth_req &= ~SMP_H7_SUPPORT_BIT;
- }
- SMP_TRACE_WARNING(
- "set auth_req: 0x%02x, local_i_key: 0x%02x, local_r_key: 0x%02x",
- 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;
- 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->loc_auth_req |= SMP_H7_SUPPORT_BIT;
- 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, p_cb->loc_auth_req: 0x%02x",
- p_cb->loc_enc_size, p_cb->local_i_key, p_cb->local_r_key,
- p_cb->loc_auth_req);
- smp_br_state_machine_event(p_cb, SMP_BR_KEYS_RSP_EVT, NULL);
- break;
- }
- }
- }
- 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", __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 = p_data->status;
- p_cb->failure = p_data->status;
- 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) {
- tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(p_cb->pairing_bda);
- SMP_TRACE_DEBUG("%s", __func__);
- /* erase all keys when master sends pairing req*/
- if (p_dev_rec) btm_sec_clear_ble_keys(p_dev_rec);
- /* 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", __func__);
- 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);
- }
- }
- /*******************************************************************************
- * 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", __func__);
- smp_send_cmd(SMP_OPCODE_CONFIRM, p_cb);
- }
- /*******************************************************************************
- * 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", __func__);
- smp_send_cmd(SMP_OPCODE_INIT, p_cb);
- }
- /*******************************************************************************
- * 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", __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", __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 = p_data->status;
- 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_KEY_VALUE le_key;
- SMP_TRACE_DEBUG("%s: p_cb->loc_enc_size = %d", __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 */
- le_key.lenc_key.ltk = p_cb->ltk;
- le_key.lenc_key.div = p_cb->div;
- le_key.lenc_key.key_size = p_cb->loc_enc_size;
- le_key.lenc_key.sec_level = p_cb->sec_level;
- 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, &le_key, true);
- SMP_TRACE_WARNING("%s", __func__);
- smp_key_distribution(p_cb, NULL);
- }
- /*******************************************************************************
- * Function smp_send_id_info
- * Description send ID information command.
- ******************************************************************************/
- void smp_send_id_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
- tBTM_LE_KEY_VALUE le_key;
- SMP_TRACE_DEBUG("%s", __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 ((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);
- SMP_TRACE_WARNING("%s", __func__);
- smp_key_distribution_by_transport(p_cb, NULL);
- }
- /** send CSRK command. */
- void smp_send_csrk_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
- tBTM_LE_KEY_VALUE key;
- SMP_TRACE_DEBUG("%s", __func__);
- smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_CSRK, false);
- if (smp_send_cmd(SMP_OPCODE_SIGN_INFO, p_cb)) {
- key.lcsrk_key.div = p_cb->div;
- key.lcsrk_key.sec_level = p_cb->sec_level;
- key.lcsrk_key.counter = 0; /* initialize the local counter */
- key.lcsrk_key.csrk = p_cb->csrk;
- btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LCSRK, &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__);
- Octet16 stk;
- memcpy(stk.data(), p_data->key.p_data, stk.size());
- /* send stk as LTK response */
- btm_ble_ltk_request_reply(p_cb->pairing_bda, true, stk);
- }
- /*******************************************************************************
- * 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->p_data;
- tBTM_BLE_SEC_REQ_ACT sec_req_act;
- 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) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_PAIR_AUTH_FAIL;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- } 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;
- }
- }
- /*******************************************************************************
- * Function smp_proc_sec_grant
- * Description process security grant.
- ******************************************************************************/
- void smp_proc_sec_grant(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
- uint8_t res = p_data->status;
- 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__);
- if (p_cb->rcvd_cmd_len < 2) {
- android_errorWriteLog(0x534e4554, "111214739");
- SMP_TRACE_WARNING("%s: rcvd_cmd_len %d too short: must be at least 2",
- __func__, p_cb->rcvd_cmd_len);
- p_cb->status = SMP_INVALID_PARAMETERS;
- } else {
- p_cb->status = p_data->status;
- }
- /* Cancel pending auth complete timer if set */
- alarm_cancel(p_cb->delayed_auth_timer_ent);
- }
- /*******************************************************************************
- * 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_t* p = p_data->p_data;
- tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(p_cb->pairing_bda);
- SMP_TRACE_DEBUG("%s: pairing_bda=%s", __func__,
- p_cb->pairing_bda.ToString().c_str());
- /* 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;
- if (smp_command_has_invalid_length(p_cb)) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_INVALID_PARAMETERS;
- android_errorWriteLog(0x534e4554, "111850706");
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- 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)) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_INVALID_PARAMETERS;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- // PTS Testing failure modes
- if (pts_test_send_authentication_complete_failure(p_cb)) return;
- 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__);
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_PAIR_AUTH_FAIL;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) {
- 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");
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_PAIR_AUTH_FAIL;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) {
- if (smp_request_oob_data(p_cb)) return;
- } else {
- smp_decide_association_model(p_cb, NULL);
- }
- }
- }
- /** process pairing confirm from peer device */
- void smp_proc_confirm(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
- SMP_TRACE_DEBUG("%s", __func__);
- if (smp_command_has_invalid_parameters(p_cb)) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_INVALID_PARAMETERS;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- if (p_data) {
- uint8_t* p = p_data->p_data;
- if (p != NULL) {
- /* save the SConfirm for comparison later */
- STREAM_TO_ARRAY(p_cb->rconfirm.data(), p, OCTET16_LEN);
- }
- }
- p_cb->flags |= SMP_PAIR_FLAGS_CMD_CONFIRM;
- }
- /** process pairing initializer from peer device */
- void smp_proc_init(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
- uint8_t* p = p_data->p_data;
- SMP_TRACE_DEBUG("%s", __func__);
- if (smp_command_has_invalid_parameters(p_cb)) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_INVALID_PARAMETERS;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- /* save the SRand for comparison */
- STREAM_TO_ARRAY(p_cb->rrand.data(), p, OCTET16_LEN);
- }
- /*******************************************************************************
- * 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_t* p = p_data->p_data;
- SMP_TRACE_DEBUG("%s", __func__);
- if (smp_command_has_invalid_parameters(p_cb)) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_INVALID_PARAMETERS;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- /* save the SRand for comparison */
- STREAM_TO_ARRAY(p_cb->rrand.data(), p, 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_t* p = p_data->p_data;
- SMP_TRACE_DEBUG("%s", __func__);
- if (smp_command_has_invalid_parameters(p_cb)) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_INVALID_PARAMETERS;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- 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);
- Point pt;
- memcpy(pt.x, p_cb->peer_publ_key.x, BT_OCTET32_LEN);
- memcpy(pt.y, p_cb->peer_publ_key.y, BT_OCTET32_LEN);
- if (!ECC_ValidatePoint(pt)) {
- android_errorWriteLog(0x534e4554, "72377774");
- tSMP_INT_DATA smp;
- smp.status = SMP_PAIR_AUTH_FAIL;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp);
- return;
- }
- 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_t* p = p_data->p_data;
- SMP_TRACE_DEBUG("%s", __func__);
- if (smp_command_has_invalid_parameters(p_cb)) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_INVALID_PARAMETERS;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- p_cb->flags |= SMP_PAIR_FLAG_HAVE_PEER_COMM;
- if (p != NULL) {
- STREAM_TO_ARRAY(p_cb->remote_commitment.data(), p, 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_t* p = p_data->p_data;
- SMP_TRACE_DEBUG("%s", __func__);
- if (smp_command_has_invalid_parameters(p_cb)) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_INVALID_PARAMETERS;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- if (p != NULL) {
- STREAM_TO_ARRAY(p_cb->remote_dhkey_check.data(), p, 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_t* p = p_data->p_data;
- SMP_TRACE_DEBUG("%s", __func__);
- p_cb->status = p_data->status;
- if (smp_command_has_invalid_parameters(p_cb)) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_INVALID_PARAMETERS;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- 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;
- }
- /*******************************************************************************
- * 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_t* p = p_data->p_data;
- 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) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_XTRANS_DERIVE_NOT_ALLOW;
- smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- /* 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;
- if (smp_command_has_invalid_length(p_cb)) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_INVALID_PARAMETERS;
- android_errorWriteLog(0x534e4554, "111213909");
- smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- 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)) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_INVALID_PARAMETERS;
- smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &smp_int_data);
- 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) {
- SMP_TRACE_DEBUG("%s", __func__);
- if (p_data->status != 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) {
- SMP_TRACE_DEBUG("%s rcvs i_keys=0x%x r_keys=0x%x (i-initiator r-responder)",
- __func__, 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);
- }
- /* Check if H7 function needs to be used for key derivation*/
- if ((p_cb->loc_auth_req & SMP_H7_SUPPORT_BIT) &&
- (p_cb->peer_auth_req & SMP_H7_SUPPORT_BIT)) {
- p_cb->key_derivation_h7_used = TRUE;
- }
- SMP_TRACE_DEBUG("%s: use h7 = %d", __func__, p_cb->key_derivation_h7_used);
- SMP_TRACE_DEBUG(
- "%s rcvs upgrades: i_keys=0x%x r_keys=0x%x (i-initiator r-responder)",
- __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_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 {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_SUCCESS;
- smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &smp_int_data);
- }
- }
- /*******************************************************************************
- * 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) {
- 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) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_SUCCESS;
- smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &smp_int_data);
- } else {
- p_cb->wait_for_authorization_complete = true;
- }
- }
- }
- }
- /** process encryption information from peer device */
- void smp_proc_enc_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
- uint8_t* p = p_data->p_data;
- SMP_TRACE_DEBUG("%s", __func__);
- if (smp_command_has_invalid_parameters(p_cb)) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_INVALID_PARAMETERS;
- android_errorWriteLog(0x534e4554, "111937065");
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- STREAM_TO_ARRAY(p_cb->ltk.data(), p, OCTET16_LEN);
- smp_key_distribution(p_cb, NULL);
- }
- /** process master ID from slave device */
- void smp_proc_master_id(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
- uint8_t* p = p_data->p_data;
- tBTM_LE_KEY_VALUE le_key;
- SMP_TRACE_DEBUG("%s", __func__);
- if (p_cb->rcvd_cmd_len < 11) { // 1(Code) + 2(EDIV) + 8(Rand)
- android_errorWriteLog(0x534e4554, "111937027");
- SMP_TRACE_ERROR("%s: Invalid command length: %d, should be at least 11",
- __func__, p_cb->rcvd_cmd_len);
- return;
- }
- smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_ENC, true);
- STREAM_TO_UINT16(le_key.penc_key.ediv, p);
- STREAM_TO_ARRAY(le_key.penc_key.rand, p, BT_OCTET8_LEN);
- /* store the encryption keys from peer device */
- le_key.penc_key.ltk = p_cb->ltk;
- le_key.penc_key.sec_level = p_cb->sec_level;
- le_key.penc_key.key_size = p_cb->loc_enc_size;
- 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, &le_key, true);
- smp_key_distribution(p_cb, NULL);
- }
- /** process identity information from peer device */
- void smp_proc_id_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
- uint8_t* p = p_data->p_data;
- SMP_TRACE_DEBUG("%s", __func__);
- if (smp_command_has_invalid_parameters(p_cb)) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_INVALID_PARAMETERS;
- android_errorWriteLog(0x534e4554, "111937065");
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- STREAM_TO_ARRAY(p_cb->tk.data(), p, OCTET16_LEN); /* reuse TK for IRK */
- smp_key_distribution_by_transport(p_cb, NULL);
- }
- /** process identity address from peer device */
- void smp_proc_id_addr(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
- uint8_t* p = p_data->p_data;
- tBTM_LE_KEY_VALUE pid_key;
- SMP_TRACE_DEBUG("%s", __func__);
- if (smp_command_has_invalid_parameters(p_cb)) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_INVALID_PARAMETERS;
- android_errorWriteLog(0x534e4554, "111214770");
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_ID, true);
- STREAM_TO_UINT8(pid_key.pid_key.identity_addr_type, p);
- STREAM_TO_BDADDR(pid_key.pid_key.identity_addr, p);
- pid_key.pid_key.irk = p_cb->tk;
- /* to use as BD_ADDR for lk derived from ltk */
- p_cb->id_addr_rcvd = true;
- p_cb->id_addr_type = pid_key.pid_key.identity_addr_type;
- p_cb->id_addr = pid_key.pid_key.identity_addr;
- /* 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, &pid_key, true);
- smp_key_distribution_by_transport(p_cb, NULL);
- }
- /* process security information from peer device */
- void smp_proc_srk_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
- tBTM_LE_KEY_VALUE le_key;
- SMP_TRACE_DEBUG("%s", __func__);
- if (smp_command_has_invalid_parameters(p_cb)) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_INVALID_PARAMETERS;
- android_errorWriteLog(0x534e4554, "111214470");
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_CSRK, true);
- /* save CSRK to security record */
- le_key.pcsrk_key.sec_level = p_cb->sec_level;
- /* get peer CSRK */
- maybe_non_aligned_memcpy(le_key.pcsrk_key.csrk.data(), p_data->p_data,
- OCTET16_LEN);
- /* initialize the peer counter */
- le_key.pcsrk_key.counter = 0;
- 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, &le_key, 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) {
- SMP_TRACE_DEBUG("%s", __func__);
- if (!memcmp(p_cb->rconfirm.data(), p_data->key.p_data, 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 {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_CONFIRM_VALUE_ERR;
- p_cb->failure = SMP_CONFIRM_VALUE_ERR;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- }
- }
- /*******************************************************************************
- * 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_t key_type = p_data->key.key_type;
- SMP_TRACE_DEBUG("%s", __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;
- SMP_TRACE_DEBUG("%s", __func__);
- if (p_data != NULL) {
- cmd = btm_ble_start_encrypt(p_cb->pairing_bda, true,
- (Octet16*)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) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_ENC_FAIL;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- }
- }
- /*******************************************************************************
- * 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", __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_t enc_enable = p_data->status;
- SMP_TRACE_DEBUG("%s", __func__);
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = enc_enable ? SMP_SUCCESS : SMP_ENC_FAIL;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- }
- /*******************************************************************************
- * Function smp_check_auth_req
- * Description check authentication request
- ******************************************************************************/
- void smp_check_auth_req(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
- uint8_t enc_enable = p_data->status;
- SMP_TRACE_DEBUG(
- "%s rcvs enc_enable=%d i_keys=0x%x r_keys=0x%x (i-initiator r-responder)",
- __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)",
- __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 {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = enc_enable ? SMP_SUCCESS : SMP_ENC_FAIL;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- }
- } else if (enc_enable == 0) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = enc_enable ? SMP_SUCCESS : SMP_ENC_FAIL;
- /* 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, &smp_int_data);
- /* 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, &smp_int_data);
- }
- }
- }
- /*******************************************************************************
- * 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_t key_to_dist =
- (p_cb->role == HCI_ROLE_SLAVE) ? p_cb->local_r_key : p_cb->local_i_key;
- uint8_t i = 0;
- SMP_TRACE_DEBUG("%s key_to_dist=0x%x", __func__, key_to_dist);
- while (i < SMP_KEY_DIST_TYPE_MAX) {
- SMP_TRACE_DEBUG("key to send = %02x, i = %d", key_to_dist, i);
- if (key_to_dist & (1 << i)) {
- SMP_TRACE_DEBUG("smp_distribute_act[%d]", i);
- (*smp_distribute_act[i])(p_cb, p_data);
- break;
- }
- i++;
- }
- }
- /*******************************************************************************
- * Function smp_key_distribution
- * Description start key distribution if required.
- ******************************************************************************/
- void smp_key_distribution(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
- 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-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) {
- /*
- * Instead of declaring authorization complete immediately,
- * delay the event from being sent by SMP_DELAYED_AUTH_TIMEOUT_MS.
- * This allows the slave to send over Pairing Failed if the
- * last key is rejected. During this waiting window, the
- * state should remain in SMP_STATE_BOND_PENDING.
- */
- if (!alarm_is_scheduled(p_cb->delayed_auth_timer_ent)) {
- SMP_TRACE_DEBUG("%s delaying auth complete.", __func__);
- alarm_set_on_mloop(p_cb->delayed_auth_timer_ent,
- SMP_DELAYED_AUTH_TIMEOUT_MS,
- smp_delayed_auth_complete_timeout, NULL);
- }
- } 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_t int_evt = 0;
- tSMP_INT_DATA smp_int_data;
- SMP_TRACE_DEBUG("%s Association Model = %d", __func__,
- p_cb->selected_association_model);
- switch (p_cb->selected_association_model) {
- case SMP_MODEL_ENCRYPTION_ONLY: /* TK = 0, go calculate Confirm */
- if (p_cb->role == HCI_ROLE_MASTER &&
- ((p_cb->peer_auth_req & SMP_AUTH_YN_BIT) != 0) &&
- ((p_cb->loc_auth_req & SMP_AUTH_YN_BIT) == 0)) {
- SMP_TRACE_ERROR(
- "IO capability does not meet authentication requirement");
- smp_int_data.status = SMP_PAIR_AUTH_FAIL;
- int_evt = SMP_AUTH_CMPL_EVT;
- } else {
- p_cb->sec_level = SMP_SEC_UNAUTHENTICATE;
- SMP_TRACE_EVENT("p_cb->sec_level =%d (SMP_SEC_UNAUTHENTICATE) ",
- p_cb->sec_level);
- tSMP_KEY key;
- key.key_type = SMP_KEY_TYPE_TK;
- key.p_data = p_cb->tk.data();
- smp_int_data.key = key;
- p_cb->tk = {0};
- /* 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) ",
- 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");
- p_cb->sec_level = SMP_SEC_AUTHENTICATED;
- SMP_TRACE_EVENT("p_cb->sec_level =%d (SMP_SEC_AUTHENTICATED) ",
- 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");
- /* 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)");
- smp_int_data.status = SMP_UNKNOWN_IO_CAP;
- int_evt = SMP_AUTH_CMPL_EVT;
- break;
- default:
- SMP_TRACE_ERROR(
- "Association Model = %d (SOMETHING IS WRONG WITH THE CODE)",
- p_cb->selected_association_model);
- smp_int_data.status = SMP_UNKNOWN_IO_CAP;
- int_evt = SMP_AUTH_CMPL_EVT;
- }
- SMP_TRACE_EVENT("sec_level=%d ", p_cb->sec_level);
- if (int_evt) smp_sm_event(p_cb, int_evt, &smp_int_data);
- }
- /*******************************************************************************
- * 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) {
- SMP_TRACE_DEBUG("%s", __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");
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_PAIR_AUTH_FAIL;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) {
- if (smp_request_oob_data(p_cb)) return;
- }
- // PTS Testing failure modes
- if (pts_test_send_authentication_complete_failure(p_cb)) return;
- smp_send_pair_rsp(p_cb, NULL);
- }
- }
- /*******************************************************************************
- * 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", __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", __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.");
- p_cb->status = SMP_FAIL;
- smp_proc_pairing_cmpl(p_cb);
- }
- }
- /*******************************************************************************
- * 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", __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 Start 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", __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) ",
- p_cb->sec_level);
- } else {
- p_cb->sec_level = SMP_SEC_AUTHENTICATED;
- SMP_TRACE_EVENT("p_cb->sec_level =%d (SMP_SEC_AUTHENTICATED) ",
- p_cb->sec_level);
- }
- switch (p_cb->selected_association_model) {
- case SMP_MODEL_SEC_CONN_JUSTWORKS:
- case SMP_MODEL_SEC_CONN_NUM_COMP:
- p_cb->local_random = {0};
- 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");
- 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",
- 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", __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",
- 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",
- 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) {
- SMP_TRACE_DEBUG("%s start ", __func__);
- // PTS Testing failure modes
- if (p_cb->cert_failure == SMP_CONFIRM_VALUE_ERR) {
- SMP_TRACE_ERROR("%s failure case = %d", __func__, p_cb->cert_failure);
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_CONFIRM_VALUE_ERR;
- p_cb->failure = SMP_CONFIRM_VALUE_ERR;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- // PTS Testing failure modes (for LT)
- if ((p_cb->cert_failure == SMP_NUMERIC_COMPAR_FAIL) &&
- (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS) &&
- (p_cb->role == HCI_ROLE_SLAVE)) {
- SMP_TRACE_ERROR("%s failure case = %d", __func__, p_cb->cert_failure);
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_NUMERIC_COMPAR_FAIL;
- p_cb->failure = SMP_NUMERIC_COMPAR_FAIL;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- 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)) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_CONFIRM_VALUE_ERR;
- p_cb->failure = SMP_CONFIRM_VALUE_ERR;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- 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) &&
- p_cb->cert_failure != SMP_NUMERIC_COMPAR_FAIL) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_CONFIRM_VALUE_ERR;
- p_cb->failure = SMP_CONFIRM_VALUE_ERR;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- 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",
- p_cb->selected_association_model);
- break;
- }
- SMP_TRACE_DEBUG("%s end ", __func__);
- }
- /*******************************************************************************
- * 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) {
- SMP_TRACE_DEBUG("%s", __func__);
- if (memcmp(p_data->key.p_data, p_cb->remote_dhkey_check.data(),
- OCTET16_LEN)) {
- SMP_TRACE_WARNING("dhkey chcks do no match");
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_DHKEY_CHK_FAIL;
- p_cb->failure = SMP_DHKEY_CHK_FAIL;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- SMP_TRACE_EVENT("dhkey chcks match");
- /* 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", __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", __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", __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);
- }
- }
- /*******************************************************************************
- * 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_t* p = NULL;
- SMP_TRACE_DEBUG("%s", __func__);
- p = p_cb->local_random.data();
- UINT32_TO_STREAM(p, p_data->passkey);
- p = p_cb->peer_random.data();
- 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", __func__);
- tSMP_SC_OOB_DATA* p_sc_oob_data = &p_cb->sc_oob_data;
- if (p_sc_oob_data->loc_oob_data.present) {
- p_cb->local_random = p_sc_oob_data->loc_oob_data.randomizer;
- } else {
- SMP_TRACE_EVENT("%s: local OOB randomizer is absent", __func__);
- p_cb->local_random = {0};
- }
- if (!p_sc_oob_data->peer_oob_data.present) {
- SMP_TRACE_EVENT("%s: peer OOB data is absent", __func__);
- p_cb->peer_random = {0};
- } else {
- p_cb->peer_random = p_sc_oob_data->peer_oob_data.randomizer;
- p_cb->remote_commitment = p_sc_oob_data->peer_oob_data.commitment;
- /* check commitment */
- if (!smp_check_commitment(p_cb)) {
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = SMP_CONFIRM_VALUE_ERR;
- p_cb->failure = SMP_CONFIRM_VALUE_ERR;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- if (p_cb->peer_oob_flag != SMP_OOB_PRESENT) {
- /* the peer doesn't have local randomiser */
- SMP_TRACE_EVENT(
- "%s: peer didn't receive local OOB data, set local randomizer to 0",
- __func__);
- p_cb->local_random = {0};
- }
- }
- print128(p_cb->local_random, (const uint8_t*)"local OOB randomizer");
- print128(p_cb->peer_random, (const uint8_t*)"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", __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", __func__);
- p_cb->sc_oob_data.loc_oob_data.randomizer = p_cb->rand;
- p_cb->sc_oob_data.loc_oob_data.commitment =
- crypto_toolbox::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);
- #if (SMP_DEBUG == TRUE)
- uint8_t* p_print = NULL;
- SMP_TRACE_DEBUG("local SC OOB data set:");
- p_print = (uint8_t*)&p_cb->sc_oob_data.loc_oob_data.addr_sent_to;
- smp_debug_print_nbyte_little_endian(p_print, "addr_sent_to",
- sizeof(tBLE_BD_ADDR));
- p_print = (uint8_t*)&p_cb->sc_oob_data.loc_oob_data.private_key_used;
- smp_debug_print_nbyte_little_endian(p_print, "private_key_used",
- BT_OCTET32_LEN);
- p_print = (uint8_t*)&p_cb->sc_oob_data.loc_oob_data.publ_key_used.x;
- smp_debug_print_nbyte_little_endian(p_print, "publ_key_used.x",
- BT_OCTET32_LEN);
- p_print = (uint8_t*)&p_cb->sc_oob_data.loc_oob_data.publ_key_used.y;
- smp_debug_print_nbyte_little_endian(p_print, "publ_key_used.y",
- BT_OCTET32_LEN);
- p_print = (uint8_t*)&p_cb->sc_oob_data.loc_oob_data.randomizer;
- smp_debug_print_nbyte_little_endian(p_print, "randomizer", OCTET16_LEN);
- p_print = (uint8_t*)&p_cb->sc_oob_data.loc_oob_data.commitment;
- smp_debug_print_nbyte_little_endian(p_print, "commitment", 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);
- smp_cb_cleanup(p_cb);
- }
- /*******************************************************************************
- *
- * Function smp_link_encrypted
- *
- * Description This function is called when link is encrypted and notified
- * to the slave device. Proceed to to send LTK, DIV and ER to
- * master if bonding the devices.
- *
- *
- * Returns void
- *
- ******************************************************************************/
- void smp_link_encrypted(const RawAddress& bda, uint8_t encr_enable) {
- tSMP_CB* p_cb = &smp_cb;
- SMP_TRACE_DEBUG("%s: encr_enable=%d", __func__, encr_enable);
- if (smp_cb.pairing_bda == bda) {
- /* encryption completed with STK, remember the key size now, could be
- * overwritten 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);
- }
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = encr_enable;
- smp_sm_event(&smp_cb, SMP_ENCRYPTED_EVT, &smp_int_data);
- }
- }
- void smp_cancel_start_encryption_attempt() {
- SMP_TRACE_ERROR("%s: Encryption request cancelled", __func__);
- smp_sm_event(&smp_cb, SMP_DISCARD_SEC_REQ_EVT, NULL);
- }
- /*******************************************************************************
- *
- * Function smp_proc_ltk_request
- *
- * Description This function is called when LTK request is received from
- * controller.
- *
- * Returns void
- *
- ******************************************************************************/
- bool smp_proc_ltk_request(const RawAddress& bda) {
- SMP_TRACE_DEBUG("%s state = %d", __func__, smp_cb.state);
- bool match = false;
- if (bda == smp_cb.pairing_bda) {
- match = true;
- } else {
- tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bda);
- if (p_dev_rec != NULL && p_dev_rec->ble.pseudo_addr == smp_cb.pairing_bda &&
- p_dev_rec->ble.pseudo_addr != RawAddress::kEmpty) {
- 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", __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", __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", __func__);
- if (!smp_calculate_link_key_from_long_term_key(p_cb)) {
- SMP_TRACE_ERROR("%s failed", __func__);
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = status;
- smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- }
- /*******************************************************************************
- *
- * Function smp_br_process_link_key
- *
- * Description This function is called to process BR/EDR LK:
- * - to derive SMP LTK from BR/EDR LK;
- * - 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", __func__);
- if (!smp_calculate_long_term_key_from_link_key(p_cb)) {
- SMP_TRACE_ERROR("%s: failed", __func__);
- tSMP_INT_DATA smp_int_data;
- smp_int_data.status = status;
- smp_sm_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &smp_int_data);
- return;
- }
- tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(p_cb->pairing_bda);
- if (p_dev_rec) {
- SMP_TRACE_DEBUG("%s: dev_type = %d ", __func__, p_dev_rec->device_type);
- p_dev_rec->device_type |= BT_DEVICE_TYPE_BLE;
- } else {
- SMP_TRACE_ERROR("%s failed to find Security Record", __func__);
- }
- SMP_TRACE_DEBUG("%s: LTK derivation from LK successfully completed",
- __func__);
- 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);
- }
- /*******************************************************************************
- * 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", __func__);
- if (p_cb->smp_over_br) {
- smp_br_select_next_key(p_cb, NULL);
- } else {
- smp_key_distribution(p_cb, NULL);
- }
- }
- /*******************************************************************************
- * 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", __func__);
- if (p_cb->total_tx_unacked == 0) {
- /* process the pairing complete */
- smp_proc_pairing_cmpl(p_cb);
- }
- }
|