diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c index c1ee15967a..3ac99bde93 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c @@ -156,6 +156,7 @@ struct prov_link { uint8_t *rand; /* Local Random */ uint8_t *conf; /* Remote Confirmation */ + uint8_t *local_conf; /* Local Confirmation */ uint8_t *prov_salt; /* Provisioning Salt */ @@ -1253,6 +1254,7 @@ static void prov_memory_free(const uint8_t idx) PROV_FREE_MEM(idx, auth); PROV_FREE_MEM(idx, rand); PROV_FREE_MEM(idx, conf); + PROV_FREE_MEM(idx, local_conf); PROV_FREE_MEM(idx, conf_salt); PROV_FREE_MEM(idx, conf_key); PROV_FREE_MEM(idx, conf_inputs); @@ -1980,6 +1982,7 @@ static int prov_auth(const uint8_t idx, uint8_t method, uint8_t action, uint8_t static void send_confirm(const uint8_t idx) { PROV_BUF(buf, 17); + uint8_t *conf = NULL; BT_DBG("ConfInputs[0] %s", bt_hex(link[idx].conf_inputs, 64)); BT_DBG("ConfInputs[64] %s", bt_hex(link[idx].conf_inputs + 64, 64)); @@ -2026,12 +2029,22 @@ static void send_confirm(const uint8_t idx) prov_buf_init(&buf, PROV_CONFIRM); - if (bt_mesh_prov_conf(link[idx].conf_key, link[idx].rand, link[idx].auth, - net_buf_simple_add(&buf, 16))) { + conf = net_buf_simple_add(&buf, 16); + + if (bt_mesh_prov_conf(link[idx].conf_key, link[idx].rand, + link[idx].auth, conf)) { BT_ERR("Failed to generate confirmation value"); goto fail; } + link[idx].local_conf = bt_mesh_calloc(PROV_CONFIRM_SIZE); + if (!link[idx].local_conf) { + BT_ERR("%s, Out of memory", __func__); + goto fail; + } + + memcpy(link[idx].local_conf, conf, PROV_CONFIRM_SIZE); + if (prov_send(idx, &buf)) { BT_ERR("Failed to send Provisioning Confirm"); goto fail; @@ -2299,6 +2312,12 @@ static void prov_confirm(const uint8_t idx, const uint8_t *data) BT_DBG("Remote Confirm: %s", bt_hex(data, 16)); + if (!memcmp(data, link[idx].local_conf, 16)) { + BT_ERR("Confirmation value is identical to ours, rejecting."); + close_link(idx, CLOSE_REASON_FAILED); + return; + } + /* Make sure received pdu is ok and cancel the timeout timer */ if (bt_mesh_atomic_test_and_clear_bit(link[idx].flags, TIMEOUT_START)) { k_delayed_work_cancel(&link[idx].timeout); @@ -2509,6 +2528,11 @@ static void prov_random(const uint8_t idx, const uint8_t *data) BT_DBG("Remote Random: %s", bt_hex(data, 16)); + if (!memcmp(data, link[idx].rand, 16)) { + BT_ERR("Random value is identical to ours, rejecting."); + goto fail; + } + if (bt_mesh_prov_conf(link[idx].conf_key, data, link[idx].auth, conf_verify)) { BT_ERR("Failed to calculate confirmation verification"); goto fail;