void ble_sm_lgcy_random_rx(struct ble_sm_proc *proc, struct ble_sm_result *res) { uint8_t preq[BLE_SM_HDR_SZ + BLE_SM_PAIR_CMD_SZ]; uint8_t pres[BLE_SM_HDR_SZ + BLE_SM_PAIR_CMD_SZ]; uint8_t confirm_val[16]; uint8_t k[16]; uint8_t ia[6]; uint8_t ra[6]; uint8_t iat; uint8_t rat; int rc; rc = ble_sm_lgcy_confirm_prepare_args(proc, k, preq, pres, &iat, &rat, ia, ra); if (rc != 0) { res->app_status = rc; res->sm_err = BLE_SM_ERR_UNSPECIFIED; res->enc_cb = 1; return; } rc = ble_sm_alg_c1(k, ble_sm_peer_pair_rand(proc), preq, pres, iat, rat, ia, ra, confirm_val); if (rc != 0) { res->app_status = rc; res->sm_err = BLE_SM_ERR_UNSPECIFIED; res->enc_cb = 1; return; } if (memcmp(proc->confirm_peer, confirm_val, 16) != 0) { /* Random number mismatch. */ res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_CONFIRM_MISMATCH); res->sm_err = BLE_SM_ERR_CONFIRM_MISMATCH; res->enc_cb = 1; return; } /* Generate the key. */ rc = ble_sm_gen_stk(proc); if (rc != 0) { res->app_status = rc; res->sm_err = BLE_SM_ERR_UNSPECIFIED; res->enc_cb = 1; return; } if (proc->flags & BLE_SM_PROC_F_INITIATOR) { /* Send the start-encrypt HCI command to the controller. For * short-term key generation, we always set ediv and rand to 0. * (Vol. 3, part H, 2.4.4.1). */ proc->state = BLE_SM_PROC_STATE_ENC_START; } res->execute = 1; }
static void ble_sm_dhkey_check_process(struct ble_sm_proc *proc, struct ble_sm_dhkey_check *cmd, struct ble_sm_result *res) { uint8_t exp_value[16]; const uint8_t *peer_ota_addr; const uint8_t *our_ota_addr; uint8_t peer_id_addr_type; uint8_t our_id_addr_type; uint8_t iocap[3]; uint8_t ioact; if (proc->flags & BLE_SM_PROC_F_INITIATOR) { ble_sm_sc_dhkey_check_iocap(&proc->pair_rsp, iocap); } else { ble_sm_sc_dhkey_check_iocap(&proc->pair_req, iocap); } ble_sm_sc_dhkey_addrs(proc, &our_id_addr_type, &our_ota_addr, &peer_id_addr_type, &peer_ota_addr); BLE_HS_LOG(DEBUG, "tk="); ble_hs_log_flat_buf(proc->tk, 32); BLE_HS_LOG(DEBUG, "\n"); res->app_status = ble_sm_alg_f6(proc->mackey, ble_sm_peer_pair_rand(proc), ble_sm_our_pair_rand(proc), proc->tk, iocap, peer_id_addr_type, peer_ota_addr, our_id_addr_type, our_ota_addr, exp_value); if (res->app_status != 0) { res->sm_err = BLE_SM_ERR_UNSPECIFIED; res->enc_cb = 1; return; } if (memcmp(cmd->value, exp_value, 16) != 0) { /* Random number mismatch. */ res->sm_err = BLE_SM_ERR_DHKEY; res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_DHKEY); res->enc_cb = 1; return; } ioact = ble_sm_sc_io_action(proc); if (ble_sm_ioact_state(ioact) == proc->state) { proc->flags |= BLE_SM_PROC_F_ADVANCE_ON_IO; } if (ble_sm_proc_can_advance(proc)) { if (proc->flags & BLE_SM_PROC_F_INITIATOR) { proc->state = BLE_SM_PROC_STATE_ENC_START; } res->execute = 1; } }
void ble_sm_sc_public_key_rx(uint16_t conn_handle, uint8_t op, struct os_mbuf **om, struct ble_sm_result *res) { struct ble_sm_public_key cmd; struct ble_sm_proc *proc; struct ble_sm_proc *prev; uint8_t ioact; int rc; res->app_status = ble_hs_mbuf_pullup_base(om, BLE_SM_PUBLIC_KEY_SZ); if (res->app_status != 0) { res->enc_cb = 1; return; } res->app_status = ble_sm_sc_ensure_keys_generated(); if (res->app_status != 0) { res->enc_cb = 1; res->sm_err = BLE_SM_ERR_UNSPECIFIED; return; } ble_sm_public_key_parse((*om)->om_data, (*om)->om_len, &cmd); BLE_SM_LOG_CMD(0, "public key", conn_handle, ble_sm_public_key_log, &cmd); ble_hs_lock(); proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_PUBLIC_KEY, -1, &prev); if (proc == NULL) { res->app_status = BLE_HS_ENOENT; res->sm_err = BLE_SM_ERR_UNSPECIFIED; } else { proc->pub_key_peer = cmd; rc = ble_sm_alg_gen_dhkey(proc->pub_key_peer.x, proc->pub_key_peer.y, ble_sm_sc_priv_key.u32, proc->dhkey); if (rc != 0) { res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_DHKEY); res->sm_err = BLE_SM_ERR_DHKEY; res->enc_cb = 1; } else { if (proc->flags & BLE_SM_PROC_F_INITIATOR) { proc->state = BLE_SM_PROC_STATE_CONFIRM; ioact = ble_sm_sc_io_action(proc); if (ble_sm_ioact_state(ioact) == proc->state) { res->passkey_params.action = ioact; } if (ble_sm_proc_can_advance(proc) && ble_sm_sc_initiator_txes_confirm(proc)) { res->execute = 1; } } else { res->execute = 1; } } } ble_hs_unlock(); }
void ble_sm_sc_random_rx(struct ble_sm_proc *proc, struct ble_sm_result *res) { uint8_t confirm_val[16]; uint8_t ia[6]; uint8_t ra[6]; uint8_t ioact; uint8_t iat; uint8_t rat; int rc; if (proc->flags & BLE_SM_PROC_F_INITIATOR || ble_sm_sc_responder_verifies_random(proc)) { BLE_HS_LOG(DEBUG, "tk="); ble_hs_log_flat_buf(proc->tk, 32); BLE_HS_LOG(DEBUG, "\n"); rc = ble_sm_alg_f4(proc->pub_key_peer.x, ble_sm_sc_pub_key.u8, ble_sm_peer_pair_rand(proc), proc->ri, confirm_val); if (rc != 0) { res->app_status = rc; res->sm_err = BLE_SM_ERR_UNSPECIFIED; res->enc_cb = 1; return; } if (memcmp(proc->confirm_peer, confirm_val, 16) != 0) { /* Random number mismatch. */ res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_CONFIRM_MISMATCH); res->sm_err = BLE_SM_ERR_CONFIRM_MISMATCH; res->enc_cb = 1; return; } } /* Calculate the mac key and ltk. */ ble_sm_ia_ra(proc, &iat, ia, &rat, ra); rc = ble_sm_alg_f5(proc->dhkey, proc->randm, proc->rands, iat, ia, rat, ra, proc->mackey, proc->ltk); if (rc != 0) { res->app_status = rc; res->sm_err = BLE_SM_ERR_UNSPECIFIED; res->enc_cb = 1; return; } /* Ensure the ltk gets persisted when the pairing procedure succeeds. */ memcpy(proc->our_keys.ltk, proc->ltk, sizeof proc->our_keys.ltk); proc->our_keys.ltk_valid = 1; proc->our_keys.ediv = 0; proc->our_keys.rand_val = 0; proc->our_keys.ediv_rand_valid = 1; memcpy(proc->peer_keys.ltk, proc->ltk, sizeof proc->peer_keys.ltk); proc->peer_keys.ltk_valid = 1; proc->peer_keys.ediv = 0; proc->peer_keys.rand_val = 0; proc->peer_keys.ediv_rand_valid = 1; if (proc->flags & BLE_SM_PROC_F_INITIATOR) { ble_sm_sc_random_advance(proc); ioact = ble_sm_sc_io_action(proc); if (ble_sm_ioact_state(ioact) == proc->state && !(proc->flags & BLE_SM_PROC_F_IO_INJECTED)) { res->passkey_params.action = ioact; BLE_HS_DBG_ASSERT(ioact == BLE_SM_IOACT_NUMCMP); ble_sm_sc_gen_numcmp(proc, res); } else { res->execute = 1; } } else { res->execute = 1; } }