From d741f41d213f131f594c6a9e2c2cb6e37c10c373 Mon Sep 17 00:00:00 2001 From: h2zero Date: Wed, 14 Oct 2026 14:40:02 -0600 Subject: [PATCH] Update nimble core to 1.10 --- src/NimBLEUtils.cpp | 4 +- src/nimble/NOTICE | 2 +- src/nimble/README.md | 10 +- src/nimble/RELEASE_NOTES.md | 8 +- src/nimble/nimble/controller/src/ble_ll.c | 5 +- src/nimble/nimble/controller/src/ble_ll_adv.c | 11 +- .../nimble/controller/src/ble_ll_conn.c | 2 +- .../nimble/controller/src/ble_ll_crypto.c | 13 + .../nimble/controller/src/ble_ll_cs_drbg.c | 2 +- .../nimble/controller/src/ble_ll_ctrl.c | 63 +- .../nimble/controller/src/ble_ll_resolv.c | 14 +- .../nimble/controller/src/ble_ll_scan.c | 6 +- .../nimble/controller/src/ble_ll_scan_aux.c | 4 +- .../nimble/controller/src/ble_ll_sched.c | 4 +- src/nimble/nimble/drivers/nrf5x/src/ble_phy.c | 2 +- src/nimble/nimble/host/include/host/ble_gap.h | 4 - .../nimble/host/include/host/ble_gatt.h | 48 -- src/nimble/nimble/host/src/ble_aes_ccm.c | 3 +- src/nimble/nimble/host/src/ble_att_svr.c | 112 +++- src/nimble/nimble/host/src/ble_ead.c | 2 +- src/nimble/nimble/host/src/ble_gap.c | 17 +- src/nimble/nimble/host/src/ble_gattc.c | 116 ++-- src/nimble/nimble/host/src/ble_gatts.c | 25 +- src/nimble/nimble/host/src/ble_hs.c | 4 + src/nimble/nimble/host/src/ble_hs_conn.c | 5 +- src/nimble/nimble/host/src/ble_hs_hci.c | 15 +- src/nimble/nimble/host/src/ble_hs_hci_evt.c | 2 +- src/nimble/nimble/host/src/ble_hs_stop.c | 13 +- src/nimble/nimble/host/src/ble_sm.c | 26 +- src/nimble/nimble/host/src/ble_sm_alg.c | 606 ++++++++++++------ src/nimble/nimble/host/src/ble_sm_lgcy.c | 12 + .../host/store/config/src/ble_store_nvs.c | 168 +++-- .../ram/include/store/ram/ble_store_ram.h | 44 -- .../nimble/host/store/ram/src/ble_store_ram.c | 542 ---------------- src/nimble/nimble/include/nimble/hci_common.h | 14 +- src/nimble/porting/nimble/src/nimble_port.c | 1 + src/nimconfig.h | 5 - src/syscfg/syscfg.h | 2 +- 38 files changed, 823 insertions(+), 1113 deletions(-) delete mode 100644 src/nimble/nimble/host/store/ram/include/store/ram/ble_store_ram.h delete mode 100644 src/nimble/nimble/host/store/ram/src/ble_store_ram.c diff --git a/src/NimBLEUtils.cpp b/src/NimBLEUtils.cpp index ce2c5b9bd..830e0a7be 100644 --- a/src/NimBLEUtils.cpp +++ b/src/NimBLEUtils.cpp @@ -533,8 +533,8 @@ const char* NimBLEUtils::gapEventToString(uint8_t eventType) { return "BLE_GAP_EVENT_PATHLOSS_THRESHOLD"; case BLE_GAP_EVENT_TRANSMIT_POWER: // 26 return "BLE_GAP_EVENT_TRANSMIT_POWER"; - case BLE_GAP_EVENT_PARING_COMPLETE: // 27 - return "BLE_GAP_EVENT_PARING_COMPLETE"; + case BLE_GAP_EVENT_PAIRING_COMPLETE: // 27 + return "BLE_GAP_EVENT_PAIRING_COMPLETE"; case BLE_GAP_EVENT_SUBRATE_CHANGE: // 28 return "BLE_GAP_EVENT_SUBRATE_CHANGE"; # ifdef BLE_GAP_EVENT_VS_HCI diff --git a/src/nimble/NOTICE b/src/nimble/NOTICE index 8f970cbce..398da75ae 100644 --- a/src/nimble/NOTICE +++ b/src/nimble/NOTICE @@ -1,5 +1,5 @@ Apache Mynewt NimBLE -Copyright 2015-2025 The Apache Software Foundation +Copyright 2015-2026 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). diff --git a/src/nimble/README.md b/src/nimble/README.md index 00cb27c63..e88acd799 100644 --- a/src/nimble/README.md +++ b/src/nimble/README.md @@ -29,14 +29,22 @@ + + + + - + + + + +

Apache NimBLE is an open-source Bluetooth 5.4 stack (both Host & Controller) diff --git a/src/nimble/RELEASE_NOTES.md b/src/nimble/RELEASE_NOTES.md index 141f8944f..2ff4b5eee 100644 --- a/src/nimble/RELEASE_NOTES.md +++ b/src/nimble/RELEASE_NOTES.md @@ -1,6 +1,6 @@ # RELEASE NOTES -15 December 2025 - Apache NimBLE v1.9.0 +10 July 2026 - Apache NimBLE v1.10.0 For full release notes, please visit the [Apache Mynewt Wiki](https://cwiki.apache.org/confluence/display/MYNEWT/Release+Notes). @@ -8,10 +8,10 @@ For full release notes, please visit the Apache NimBLE is an open-source Bluetooth 5.4 stack (both Host & Controller) that completely replaces the proprietary SoftDevice on Nordic chipsets. -New features in this version of NimBLE include: +Major changes in this version of NimBLE include: -* Characteristic Extended Properties descriptor in GATT server -* Framed PDUs in ISO Adaptation Layer +* Removal of Tinycrypt support +* Removal of deprecated code If working on next-generation RTOS and Bluetooth protocol stack sounds exciting to you, get in touch, by sending a mail to the Apache Mynewt diff --git a/src/nimble/nimble/controller/src/ble_ll.c b/src/nimble/nimble/controller/src/ble_ll.c index e0624cbc0..7bada47dc 100644 --- a/src/nimble/nimble/controller/src/ble_ll.c +++ b/src/nimble/nimble/controller/src/ble_ll.c @@ -1191,6 +1191,9 @@ ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr) ble_ll_trace_u32x3(BLE_LL_TRACE_ID_RX_END, pdu_type, len, rxhdr->rxinfo.flags); + /* Update RSSI */ + rxhdr->rxinfo.rssi -= ble_ll_rx_gain(); + #if MYNEWT_VAL(BLE_LL_EXT) if (BLE_MBUF_HDR_RX_STATE(rxhdr) == BLE_LL_STATE_EXTERNAL) { rc = ble_ll_ext_rx_isr_end(rxbuf, rxhdr); @@ -1812,8 +1815,6 @@ ble_ll_init(void) g_dev_addr[i] = pub_dev_addr & 0xff; pub_dev_addr >>= 8; } -#else - memcpy(g_dev_addr, MYNEWT_VAL(BLE_PUBLIC_DEV_ADDR), BLE_DEV_ADDR_LEN); #endif if (ble_ll_is_addr_empty(g_dev_addr)) { rc = ble_hw_get_public_addr(&addr); diff --git a/src/nimble/nimble/controller/src/ble_ll_adv.c b/src/nimble/nimble/controller/src/ble_ll_adv.c index 6e952d3b1..1691d14e5 100644 --- a/src/nimble/nimble/controller/src/ble_ll_adv.c +++ b/src/nimble/nimble/controller/src/ble_ll_adv.c @@ -1131,7 +1131,7 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch) uint8_t end_trans; uint32_t txstart; struct ble_ll_adv_sm *advsm; -#if MYNEWT_VAL(BLE_LL_PHY) && MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) +#if MYNEWT_VAL(BLE_LL_PHY) uint8_t phy_mode __attribute__((unused)); #endif @@ -1161,13 +1161,12 @@ ble_ll_adv_tx_start_cb(struct ble_ll_sched_item *sch) phy_mode = ble_ll_phy_to_phy_mode(advsm->pri_phy, BLE_HCI_LE_PHY_CODED_ANY); #endif if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) { - ble_phy_mode_set(BLE_PHY_MODE_1M, BLE_PHY_MODE_1M); - } else { - ble_phy_mode_set(phy_mode, phy_mode); + phy_mode = BLE_PHY_MODE_1M; } #else - ble_phy_mode_set(BLE_PHY_MODE_1M, BLE_PHY_MODE_1M); + phy_mode = BLE_PHY_MODE_1M; #endif + ble_phy_mode_set(phy_mode, phy_mode); #endif /* Set the power */ @@ -2322,7 +2321,7 @@ ble_ll_adv_sync_tx_start_cb(struct ble_ll_sched_item *sch) #if MYNEWT_VAL(BLE_LL_PHY) /* Set phy mode */ - ble_phy_mode_set(advsm->sec_phy, advsm->sec_phy); + ble_phy_mode_set(advsm->sec_phy, advsm->sec_phy); #endif /* Set the power */ diff --git a/src/nimble/nimble/controller/src/ble_ll_conn.c b/src/nimble/nimble/controller/src/ble_ll_conn.c index 3be7a3f1e..b7ba1d7bb 100644 --- a/src/nimble/nimble/controller/src/ble_ll_conn.c +++ b/src/nimble/nimble/controller/src/ble_ll_conn.c @@ -3582,7 +3582,7 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr) #endif /* Update RSSI */ - connsm->conn_rssi = hdr->rxinfo.rssi - ble_ll_rx_gain(); + connsm->conn_rssi = hdr->rxinfo.rssi; /* * If we are a peripheral, we can only start to use peripheral latency diff --git a/src/nimble/nimble/controller/src/ble_ll_crypto.c b/src/nimble/nimble/controller/src/ble_ll_crypto.c index 0406705af..22b738b05 100644 --- a/src/nimble/nimble/controller/src/ble_ll_crypto.c +++ b/src/nimble/nimble/controller/src/ble_ll_crypto.c @@ -23,13 +23,25 @@ #include "nimble/nimble/include/nimble/ble.h" #include "nimble/nimble/controller/include/controller/ble_ll_crypto.h" #include "nimble/nimble/controller/include/controller/ble_hw.h" +#if MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) +#include +#else #include "nimble/ext/tinycrypt/include/tinycrypt/constants.h" #include "nimble/ext/tinycrypt/include/tinycrypt/cmac_mode.h" +#endif int ble_ll_crypto_cmac(const uint8_t *key, const uint8_t *in, int len, uint8_t *out) { +#if MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) + if (mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB), + key, 128, in, len, out)) { + return -1; + } + + return 0; +#else struct tc_aes_key_sched_struct sched; struct tc_cmac_struct state; @@ -46,6 +58,7 @@ ble_ll_crypto_cmac(const uint8_t *key, const uint8_t *in, int len, } return 0; +#endif } int diff --git a/src/nimble/nimble/controller/src/ble_ll_cs_drbg.c b/src/nimble/nimble/controller/src/ble_ll_cs_drbg.c index 7e43358c3..224aa8783 100644 --- a/src/nimble/nimble/controller/src/ble_ll_cs_drbg.c +++ b/src/nimble/nimble/controller/src/ble_ll_cs_drbg.c @@ -25,7 +25,7 @@ #include #include "nimble/porting/nimble/include/os/endian.h" #include "nimble/nimble/include/nimble/ble.h" -#include "nimble/ext/tinycrypt/include/tinycrypt/aes.h" +#include "mbedtls/aes.h" #include "ble_ll_cs_drbg_priv.h" #if !(BABBLESIM || MYNEWT_VAL(SELFTEST)) #include "nimble/nimble/controller/include/controller/ble_hw.h" diff --git a/src/nimble/nimble/controller/src/ble_ll_ctrl.c b/src/nimble/nimble/controller/src/ble_ll_ctrl.c index b836c6819..5b06450cc 100644 --- a/src/nimble/nimble/controller/src/ble_ll_ctrl.c +++ b/src/nimble/nimble/controller/src/ble_ll_ctrl.c @@ -2098,6 +2098,47 @@ ble_ll_ctrl_rx_reject_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr, return rsp_opcode; } +static bool +ble_ll_conn_chk_conn_update_req(const struct ble_ll_conn_upd_req *req) +{ + uint32_t timeout_usecs; + uint32_t min_timeout_usecs; + + if ((req->interval < BLE_HCI_CONN_ITVL_MIN) || + (req->interval > BLE_HCI_CONN_ITVL_MAX) || + (req->latency > BLE_HCI_CONN_LATENCY_MAX) || + (req->timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN) || + (req->timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX)) { + return false; + } + + /* Supervision timeout (in msecs) must be more than: + * (1 + connLatency) * connIntervalMax * 1.25 msecs * 2. + */ + timeout_usecs = req->timeout; + timeout_usecs *= (BLE_HCI_CONN_SPVN_TMO_UNITS * 1000); + min_timeout_usecs = (uint32_t)req->interval * 2 * BLE_LL_CONN_ITVL_USECS; + min_timeout_usecs *= (1 + req->latency); + if (timeout_usecs <= min_timeout_usecs) { + return false; + } + + /* The transmitWindowOffset shall be a multiple of 1.25 ms in the range + * 0 ms to connInterval. + */ + if (req->winoffset > req->interval) { + return false; + } + + /* The transmitWindowSize shall be a multiple of 1.25 ms in the range + * 1.25 ms to the lesser of 10 ms and (connInterval - 1.25 ms). + */ + if ((req->winsize < 1) || (req->winsize > MIN(8, req->interval - 1))) { + return false; + } + + return true; +} /** * Called when we receive a connection update event * @@ -2109,7 +2150,6 @@ ble_ll_ctrl_rx_reject_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr, static int ble_ll_ctrl_rx_conn_update(struct ble_ll_conn_sm *connsm, uint8_t *dptr) { - uint8_t rsp_opcode; uint16_t conn_events; struct ble_ll_conn_upd_req *reqdata; @@ -2129,9 +2169,11 @@ ble_ll_ctrl_rx_conn_update(struct ble_ll_conn_sm *connsm, uint8_t *dptr) reqdata->timeout = get_le16(dptr + 7); reqdata->instant = get_le16(dptr + 9); - /* XXX: validate them at some point. If they dont check out, we - return the unknown response */ - rsp_opcode = BLE_ERR_MAX; + /* Check if parameters are valid */ + if (!ble_ll_conn_chk_conn_update_req(reqdata)) { + ble_ll_conn_timeout(connsm, BLE_ERR_INV_LMP_LL_PARM); + return BLE_ERR_MAX; + } /* If instant is in the past, we have to end the connection */ conn_events = (reqdata->instant - connsm->event_cntr) & 0xFFFF; @@ -2156,7 +2198,7 @@ ble_ll_ctrl_rx_conn_update(struct ble_ll_conn_sm *connsm, uint8_t *dptr) } } - return rsp_opcode; + return BLE_ERR_MAX; } void @@ -2485,6 +2527,17 @@ ble_ll_ctrl_rx_chanmap_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr) } #endif + /* Minimum number of channels is 2. + * If invalid map was provided we have to end the connection. + */ + if (ble_ll_utils_chan_map_used_get(dptr) < 2) { + ble_ll_conn_timeout(connsm, BLE_ERR_INV_LMP_LL_PARM); + return BLE_ERR_MAX; + } + + /* The bits in positions 37, 38 and 39 are reserved for future use */ + dptr[4] &= 0x1f; + /* If instant is in the past, we have to end the connection */ instant = get_le16(dptr + BLE_LL_CHAN_MAP_LEN); conn_events = (instant - connsm->event_cntr) & 0xFFFF; diff --git a/src/nimble/nimble/controller/src/ble_ll_resolv.c b/src/nimble/nimble/controller/src/ble_ll_resolv.c index 9b71efeb4..adc7739c1 100644 --- a/src/nimble/nimble/controller/src/ble_ll_resolv.c +++ b/src/nimble/nimble/controller/src/ble_ll_resolv.c @@ -140,25 +140,23 @@ static void ble_ll_resolv_rpa_timer_cb(struct ble_npl_event *ev) { int i; - os_sr_t sr; + uint8_t rpa[6]; struct ble_ll_resolv_entry *rl; #if MYNEWT_VAL(BLE_LL_HCI_VS_LOCAL_IRK) struct local_irk_data *irk_data; - uint8_t rpa[6]; + os_sr_t sr; #endif rl = &g_ble_ll_resolv_list[0]; for (i = 0; i < g_ble_ll_resolv_data.rl_cnt; ++i) { if (rl->rl_has_local) { - OS_ENTER_CRITICAL(sr); - ble_ll_resolv_gen_priv_addr(rl, 1); - OS_EXIT_CRITICAL(sr); + generate_rpa(rl->rl_local_irk, rpa); + ble_ll_resolv_set_local_rpa(i, rpa); } if (rl->rl_has_peer) { - OS_ENTER_CRITICAL(sr); - ble_ll_resolv_gen_priv_addr(rl, 0); - OS_EXIT_CRITICAL(sr); + generate_rpa(rl->rl_peer_irk, rpa); + ble_ll_resolv_set_peer_rpa(i, rpa); } ++rl; } diff --git a/src/nimble/nimble/controller/src/ble_ll_scan.c b/src/nimble/nimble/controller/src/ble_ll_scan.c index d74cf672e..70ee3c199 100644 --- a/src/nimble/nimble/controller/src/ble_ll_scan.c +++ b/src/nimble/nimble/controller/src/ble_ll_scan.c @@ -720,7 +720,7 @@ ble_ll_scan_send_adv_report(uint8_t pdu_type, if (scansm->ext_scanning) { rc = ble_ll_hci_send_legacy_ext_adv_report(evtype, adva, adva_type, - hdr->rxinfo.rssi - ble_ll_rx_gain(), + hdr->rxinfo.rssi, adv_data_len, om, inita, inita_type); goto done; @@ -729,12 +729,12 @@ goto done; if (subev == BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT) { rc = ble_ll_hci_send_dir_adv_report(adva, adva_type, inita, inita_type, - hdr->rxinfo.rssi - ble_ll_rx_gain()); + hdr->rxinfo.rssi); goto done; } rc = ble_ll_hci_send_adv_report(evtype, adva, adva_type, - hdr->rxinfo.rssi - ble_ll_rx_gain(), + hdr->rxinfo.rssi, adv_data_len, om); done: if (!rc && scansm->scan_filt_dups) { diff --git a/src/nimble/nimble/controller/src/ble_ll_scan_aux.c b/src/nimble/nimble/controller/src/ble_ll_scan_aux.c index 729dac08a..e96675974 100644 --- a/src/nimble/nimble/controller/src/ble_ll_scan_aux.c +++ b/src/nimble/nimble/controller/src/ble_ll_scan_aux.c @@ -437,7 +437,7 @@ ble_ll_hci_ev_update_ext_adv_report_from_ext(struct ble_hci_ev *hci_ev, report->pri_phy = rxinfo->phy; report->sec_phy = 0; report->sid = 0xff; - report->rssi = rxhdr->rxinfo.rssi - ble_ll_rx_gain(); + report->rssi = rxhdr->rxinfo.rssi; report->periodic_itvl = 0; report->data_len = 0; @@ -566,7 +566,7 @@ ble_ll_hci_ev_send_ext_adv_report(struct os_mbuf *rxpdu, hci_subev = (void *)(*hci_ev)->data; report = hci_subev->reports; - report->rssi = rxinfo->rssi - ble_ll_rx_gain(); + report->rssi = rxinfo->rssi; report->data_len = MIN(max_data_len, data_len - offset); os_mbuf_copydata(rxpdu, offset, report->data_len, report->data); diff --git a/src/nimble/nimble/controller/src/ble_ll_sched.c b/src/nimble/nimble/controller/src/ble_ll_sched.c index 73ca0d14b..d95642f1f 100644 --- a/src/nimble/nimble/controller/src/ble_ll_sched.c +++ b/src/nimble/nimble/controller/src/ble_ll_sched.c @@ -529,7 +529,9 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm, OS_ENTER_CRITICAL(sr); if (!g_ble_ll_conn_css_ref) { - css->period_anchor_ticks = earliest_start; + css->period_anchor_ticks = earliest_start + + MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET) * + BLE_LL_SCHED_USECS_PER_SLOT; css->period_anchor_rem_us = 0; css->period_anchor_idx = 0; css->period_anchor_slot_idx = connsm->css_slot_idx; diff --git a/src/nimble/nimble/drivers/nrf5x/src/ble_phy.c b/src/nimble/nimble/drivers/nrf5x/src/ble_phy.c index b06faa2fb..68800648e 100644 --- a/src/nimble/nimble/drivers/nrf5x/src/ble_phy.c +++ b/src/nimble/nimble/drivers/nrf5x/src/ble_phy.c @@ -1665,7 +1665,7 @@ ble_phy_init(void) #if PHY_USE_HEADERMASK_WORKAROUND NVIC_SetVector(CCM_AAR_IRQn, (uint32_t)ble_phy_ccm_isr); NVIC_EnableIRQ(CCM_AAR_IRQn); - NRF_CCM->INTENCLR = CCM_INTENCLR_ENDKSGEN_Msk;; + NRF_CCM->INTENCLR = CCM_INTENCLR_ENDKSGEN_Msk; #endif #endif diff --git a/src/nimble/nimble/host/include/host/ble_gap.h b/src/nimble/nimble/host/include/host/ble_gap.h index aac89c87f..a68d8b865 100644 --- a/src/nimble/nimble/host/include/host/ble_gap.h +++ b/src/nimble/nimble/host/include/host/ble_gap.h @@ -249,9 +249,6 @@ struct hci_conn_update; /** GAP event: Pairing complete */ #define BLE_GAP_EVENT_PAIRING_COMPLETE 27 -/** GAP event: Pairing complete (deprecated) */ -#define BLE_GAP_EVENT_PARING_COMPLETE BLE_GAP_EVENT_PAIRING_COMPLETE - /** GAP event: Subrate change */ #define BLE_GAP_EVENT_SUBRATE_CHANGE 28 @@ -1249,7 +1246,6 @@ struct ble_gap_event { * * Valid for the following event types: * o BLE_GAP_EVENT_PAIRING_COMPLETE - * o BLE_GAP_EVENT_PARING_COMPLETE (deprecated) */ struct { /** diff --git a/src/nimble/nimble/host/include/host/ble_gatt.h b/src/nimble/nimble/host/include/host/ble_gatt.h index a96fcc4c2..de59e5cea 100644 --- a/src/nimble/nimble/host/include/host/ble_gatt.h +++ b/src/nimble/nimble/host/include/host/ble_gatt.h @@ -710,20 +710,6 @@ int ble_gatts_notify_multiple_custom(uint16_t conn_handle, size_t chr_count, struct ble_gatt_notif *tuples); -/** - * @deprecated Should not be used. Use ble_gatts_notify_custom instead. - * - * @param conn_handle The connection over which to execute the - * procedure. - * @param att_handle The attribute handle to indicate in the - * outgoing notification. - * @param om The value to write to the characteristic. - * - * @return 0 on success; nonzero on failure. - */ -int ble_gattc_notify_custom(uint16_t conn_handle, uint16_t att_handle, - struct os_mbuf *om); - /** * Sends a characteristic notification. The content of the message is read * from the specified characteristic. @@ -738,19 +724,6 @@ int ble_gattc_notify_custom(uint16_t conn_handle, uint16_t att_handle, */ int ble_gatts_notify(uint16_t conn_handle, uint16_t chr_val_handle); -/** - * @deprecated Should not be used. Use ble_gatts_notify instead. - * - * @param conn_handle The connection over which to execute the - * procedure. - * @param chr_val_handle The value attribute handle of the - * characteristic to include in the outgoing - * notification. - * - * @return 0 on success; nonzero on failure. - */ -int ble_gattc_notify(uint16_t conn_handle, uint16_t chr_val_handle); - /** * Sends a multiple handle variable length characteristic notification. The * content of the message is read from the specified characteristics. @@ -794,21 +767,6 @@ int ble_gatts_notify_multiple(uint16_t conn_handle, int ble_gatts_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, struct os_mbuf *txom); -/** - * @deprecated Should not be used. Use ble_gatts_indicate_custom instead. - * - * @param conn_handle The connection over which to execute the - * procedure. - * @param chr_val_handle The value attribute handle of the - * characteristic to include in the outgoing - * indication. - * @param txom The data to include in the indication. - * - * @return 0 on success; nonzero on failure. - */ -int ble_gattc_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, - struct os_mbuf *txom); - /** * Sends a characteristic indication. The content of the message is read from * the specified characteristic. @@ -823,12 +781,6 @@ int ble_gattc_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, */ int ble_gatts_indicate(uint16_t conn_handle, uint16_t chr_val_handle); -/** - * @deprecated Should not be used. Use ble_gatts_indicate instead. - * @copydoc ble_gatts_indicate - */ -int ble_gattc_indicate(uint16_t conn_handle, uint16_t chr_val_handle); - /** * Initialize the BLE GATT client * diff --git a/src/nimble/nimble/host/src/ble_aes_ccm.c b/src/nimble/nimble/host/src/ble_aes_ccm.c index 2d0ad440b..aef718869 100644 --- a/src/nimble/nimble/host/src/ble_aes_ccm.c +++ b/src/nimble/nimble/host/src/ble_aes_ccm.c @@ -13,10 +13,11 @@ #if CONFIG_MBEDTLS_VER_4_X_SUPPORT #include "psa/crypto.h" #else -#include "nimble/ext/tinycrypt/include/tinycrypt/aes.h" +#include "mbedtls/aes.h" #endif // CONFIG_MBEDTLS_VER_4_X_SUPPORT #else #include "nimble/ext/tinycrypt/include/tinycrypt/constants.h" +#include "nimble/ext/tinycrypt/include/tinycrypt/aes.h" #endif #if MYNEWT_VAL(ENC_ADV_DATA) diff --git a/src/nimble/nimble/host/src/ble_att_svr.c b/src/nimble/nimble/host/src/ble_att_svr.c index 2ffddcf33..3868eedc7 100644 --- a/src/nimble/nimble/host/src/ble_att_svr.c +++ b/src/nimble/nimble/host/src/ble_att_svr.c @@ -1089,8 +1089,9 @@ ble_att_svr_fill_type_value(uint16_t conn_handle, uint16_t mtu, uint8_t *out_att_err) { struct ble_att_svr_entry *ha; - uint8_t buf[16]; + struct os_mbuf *attr_om; uint16_t attr_len; + uint16_t req_val_len; uint16_t first; uint16_t prev; int any_entries; @@ -1099,6 +1100,11 @@ ble_att_svr_fill_type_value(uint16_t conn_handle, first = 0; prev = 0; rc = 0; + attr_om = NULL; + + /* Length of the attribute value in the request. */ + req_val_len = OS_MBUF_PKTLEN(rxom) - + sizeof(struct ble_att_find_type_value_req); /* Iterate through the attribute list, keeping track of the current * matching group. For each attribute entry, determine if data needs to be @@ -1141,15 +1147,31 @@ ble_att_svr_fill_type_value(uint16_t conn_handle, * determine if this attribute matches. */ if (ble_uuid_cmp(ha->ha_uuid, &attr_type.u) == 0) { - rc = ble_att_svr_read_flat(conn_handle, ha, 0, sizeof buf, buf, - &attr_len, out_att_err); + /* Lazily allocate a temporary mbuf for reading attribute values. */ + if (attr_om == NULL) { + attr_om = ble_hs_mbuf_l2cap_pkt(); + if (attr_om == NULL) { + *out_att_err = BLE_ATT_ERR_INSUFFICIENT_RES; + rc = BLE_HS_ENOMEM; + goto done; + } + } else { + os_mbuf_adj(attr_om, OS_MBUF_PKTLEN(attr_om)); + } + + /* Read attribute value into temporary mbuf. */ + rc = ble_att_svr_read(conn_handle, ha, 0, attr_om, out_att_err); if (rc != 0) { goto done; } - /* value is at the end of req */ - rc = os_mbuf_cmpf(rxom, sizeof(struct ble_att_find_type_value_req), - buf, attr_len); - if (rc == 0) { + + attr_len = OS_MBUF_PKTLEN(attr_om); + + /* Compare attribute value with the value from the request. */ + if (attr_len == req_val_len && + os_mbuf_cmpm(rxom, + sizeof(struct ble_att_find_type_value_req), + attr_om, 0, attr_len) == 0) { first = ha->ha_handle_id; prev = ha->ha_handle_id; } @@ -1170,6 +1192,8 @@ ble_att_svr_fill_type_value(uint16_t conn_handle, } done: + os_mbuf_free_chain(attr_om); + any_entries = OS_MBUF_PKTHDR(txom)->omp_len > BLE_ATT_FIND_TYPE_VALUE_RSP_BASE_SZ; if (rc == 0 && !any_entries) { @@ -1293,9 +1317,10 @@ ble_att_svr_build_read_type_rsp(uint16_t conn_handle, uint16_t cid, struct ble_att_read_type_rsp *rsp; struct ble_att_svr_entry *entry; struct os_mbuf *txom; + struct os_mbuf *attr_om; uint16_t attr_len; + uint16_t max_attr_len; uint16_t mtu; - uint8_t buf[19]; int entry_written; int txomlen; int prev_attr_len; @@ -1306,6 +1331,7 @@ ble_att_svr_build_read_type_rsp(uint16_t conn_handle, uint16_t cid, *err_handle = start_handle; entry_written = 0; prev_attr_len = 0; + attr_om = NULL; /* Just reuse the request buffer for the response. */ txom = *rxom; @@ -1326,6 +1352,12 @@ ble_att_svr_build_read_type_rsp(uint16_t conn_handle, uint16_t cid, mtu = ble_att_mtu_by_cid(conn_handle, cid); + /* Per Core Spec: max attribute value length is min(ATT_MTU - 4, 253). */ + max_attr_len = mtu - 4; + if (max_attr_len > 253) { + max_attr_len = 253; + } + /* Find all matching attributes, writing a record for each. */ entry = NULL; while (1) { @@ -1336,15 +1368,29 @@ ble_att_svr_build_read_type_rsp(uint16_t conn_handle, uint16_t cid, } if (entry->ha_handle_id >= start_handle) { - rc = ble_att_svr_read_flat(conn_handle, entry, 0, sizeof buf, buf, - &attr_len, att_err); + /* Lazily allocate a temporary mbuf for reading attribute values. */ + if (attr_om == NULL) { + attr_om = ble_hs_mbuf_l2cap_pkt(); + if (attr_om == NULL) { + *att_err = BLE_ATT_ERR_INSUFFICIENT_RES; + *err_handle = entry->ha_handle_id; + rc = BLE_HS_ENOMEM; + goto done; + } + } else { + os_mbuf_adj(attr_om, OS_MBUF_PKTLEN(attr_om)); + } + + /* Read attribute value into temporary mbuf. */ + rc = ble_att_svr_read(conn_handle, entry, 0, attr_om, att_err); if (rc != 0) { *err_handle = entry->ha_handle_id; goto done; } - if (attr_len > mtu - 4) { - attr_len = mtu - 4; + attr_len = OS_MBUF_PKTLEN(attr_om); + if (attr_len > max_attr_len) { + attr_len = max_attr_len; } if (prev_attr_len == 0) { @@ -1367,12 +1413,14 @@ ble_att_svr_build_read_type_rsp(uint16_t conn_handle, uint16_t cid, } data->handle = htole16(entry->ha_handle_id); - memcpy(data->value, buf, attr_len); + os_mbuf_copydata(attr_om, 0, attr_len, data->value); entry_written = 1; } } done: + os_mbuf_free_chain(attr_om); + if (!entry_written) { /* No matching attributes. */ if (*att_err == 0) { @@ -1682,10 +1730,9 @@ ble_att_svr_build_read_mult_rsp_var(uint16_t conn_handle, uint16_t cid, tmp = os_msys_get_pkthdr(2, 0); /* Iterate through requested handles, reading the corresponding attribute - * for each. Stop when there are no more handles to process, or the - * response is full. + * for each. Stop when there are no more handles to process. */ - while (OS_MBUF_PKTLEN(*rxom) >= 2 && OS_MBUF_PKTLEN(txom) < mtu) { + while (OS_MBUF_PKTLEN(*rxom) >= 2) { /* Ensure the full 16-bit handle is contiguous at the start of the * mbuf. */ @@ -1707,27 +1754,42 @@ ble_att_svr_build_read_mult_rsp_var(uint16_t conn_handle, uint16_t cid, goto done; } tuple_len = OS_MBUF_PKTLEN(tmp); - rc = os_mbuf_append(txom, &tuple_len, sizeof(tuple_len)); - if (rc != 0) { - *err_handle = handle; - goto done; - } - if (tuple_len != 0) { - rc = os_mbuf_appendfrom(txom, tmp, 0, tuple_len); + + if (OS_MBUF_PKTLEN(txom) < mtu) { + rc = os_mbuf_append(txom, &tuple_len, sizeof(tuple_len)); if (rc != 0) { *err_handle = handle; goto done; } + if (tuple_len != 0) { + rc = os_mbuf_appendfrom(txom, tmp, 0, tuple_len); + if (rc != 0) { + *err_handle = handle; + goto done; + } + } + } + + if (tuple_len != 0) { os_mbuf_adj(tmp, tuple_len); } } rc = 0; done: - if (tmp) { os_mbuf_free_chain(tmp); } + + /* If an execution error occurred, immediately release the bloated success + * buffer back to the memory pool so the error handler has room to generate + * an error Response. + */ + if (rc != 0 && txom != NULL) { + os_mbuf_free_chain(txom); + txom = NULL; + } + *out_txom = txom; return rc; } @@ -1773,7 +1835,7 @@ ble_att_svr_service_uuid(struct ble_att_svr_entry *entry, ble_uuid_any_t *uuid, uint8_t *out_att_err) { uint8_t val[16]; - uint16_t attr_len; + uint16_t attr_len = 0; int rc; rc = ble_att_svr_read_flat(BLE_HS_CONN_HANDLE_NONE, entry, 0, sizeof(val), val, diff --git a/src/nimble/nimble/host/src/ble_ead.c b/src/nimble/nimble/host/src/ble_ead.c index efef51659..69dfdb27e 100644 --- a/src/nimble/nimble/host/src/ble_ead.c +++ b/src/nimble/nimble/host/src/ble_ead.c @@ -19,7 +19,7 @@ static uint8_t ble_ead_aad[] = {0xEA}; static int ble_ead_rand(void *buf, size_t len) { int rc; - rc = ble_hs_hci_util_rand(buf, len); + rc = ble_hs_hci_rand(buf, len); if (rc != 0) { return -1; } diff --git a/src/nimble/nimble/host/src/ble_gap.c b/src/nimble/nimble/host/src/ble_gap.c index b65a5fae4..9c0bd7c07 100644 --- a/src/nimble/nimble/host/src/ble_gap.c +++ b/src/nimble/nimble/host/src/ble_gap.c @@ -1218,6 +1218,9 @@ static void ble_gap_master_failed(int status) { switch (ble_gap_master.op) { + case BLE_GAP_OP_NULL: + break; + #if NIMBLE_BLE_CONNECT case BLE_GAP_OP_M_CONN: STATS_INC(ble_gap_stats, initiate_fail); @@ -1296,7 +1299,7 @@ ble_gap_conn_broken(uint16_t conn_handle, int reason) ble_sm_connection_broken(conn_handle); ble_gatts_connection_broken(conn_handle); ble_gattc_connection_broken(conn_handle); - ble_hs_flow_connection_broken(conn_handle);; + ble_hs_flow_connection_broken(conn_handle); ble_hs_atomic_conn_delete(conn_handle); @@ -6402,6 +6405,18 @@ ble_gap_update_params(uint16_t conn_handle, rc = 0; } else { rc = ble_gap_update_tx(conn_handle, params); + + /* + * If the controller rejects the LL update with "Unsupported Remote + * Feature" and we are the slave, fall back to L2CAP signaling. This + * happens when the local controller supports the Connection Parameters + * Request procedure but the peer's controller does not. + */ + if (rc == BLE_HS_HCI_ERR(BLE_ERR_UNSUPP_REM_FEATURE) && + !(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) { + l2cap_update = 1; + rc = 0; + } } done: diff --git a/src/nimble/nimble/host/src/ble_gattc.c b/src/nimble/nimble/host/src/ble_gattc.c index dd1a25674..6d42c82a9 100644 --- a/src/nimble/nimble/host/src/ble_gattc.c +++ b/src/nimble/nimble/host/src/ble_gattc.c @@ -3361,49 +3361,62 @@ ble_gattc_read_mult_cb_var(struct ble_gattc_proc *proc, int status, for (i = 0; i < proc->read_mult.num_handles; i++) { attr[i].handle = proc->read_mult.handles[i]; attr[i].offset = 0; - if (om == NULL || OS_MBUF_PKTLEN(*om) == 0) { - continue; - } + } - *om = os_mbuf_pullup(*om, 2); - assert(*om); + if (status == 0) { + for (i = 0; i < proc->read_mult.num_handles; i++) { + if (OS_MBUF_PKTLEN(*om) < 2) { + break; + } - attr_len = get_le16((*om)->om_data); + *om = os_mbuf_pullup(*om, 2); + if (*om == NULL) { + break; + } - os_mbuf_adj(*om, 2); + attr_len = get_le16((*om)->om_data); + os_mbuf_adj(*om, 2); - if (attr_len > BLE_ATT_ATTR_MAX_LEN) { - /*TODO Figure out what to do here */ - break; - } + if (attr_len > BLE_ATT_ATTR_MAX_LEN) { + break; + } - attr[i].om = os_msys_get_pkthdr(attr_len, 0); - if (!attr[i].om) { - /*TODO Figure out what to do here */ - break; - } + attr[i].om = os_msys_get_pkthdr(attr_len, 0); + if (!attr[i].om) { + /* this is OOM condition*/ + status = BLE_HS_ENOMEM; + break; + } - rc = os_mbuf_appendfrom(attr[i].om, *om, 0, attr_len); - if (rc) { - /*TODO Figure out what to do here */ - break; + rc = os_mbuf_appendfrom(attr[i].om, *om, 0, attr_len); + if (rc) { + break; + } + + os_mbuf_adj(*om, attr_len); } - os_mbuf_adj(*om, attr_len); - } + /* failed to correctly parse response, + * cleanup any partial data and set status if not set already + */ + if (i < proc->read_mult.num_handles || OS_MBUF_PKTLEN(*om) != 0) { + for (i = 0; i < proc->read_mult.num_handles; i++) { + os_mbuf_free_chain(attr[i].om); + attr[i].om = NULL; + } - /*FIXME Testing assert */ - assert(i == proc->read_mult.num_handles); + if (status == 0) { + status = BLE_HS_EBADDATA; + } + } + } proc->read_mult.cb_mult(proc->conn_handle, - ble_gattc_error(status, att_handle), &attr[0], - i, - proc->read_mult.cb_arg); + ble_gattc_error(status, att_handle), &attr[0], + proc->read_mult.num_handles, proc->read_mult.cb_arg); for (i = 0; i < proc->read_mult.num_handles; i++) { - if (attr[i].om != NULL) { - os_mbuf_free_chain(attr[i].om); - } + os_mbuf_free_chain(attr[i].om); } return 0; @@ -4400,16 +4413,6 @@ ble_gatts_notify_custom(uint16_t conn_handle, uint16_t chr_val_handle, return rc; } -/** - * Deprecated. Should not be used. Use ble_gatts_notify_custom instead. - */ -int -ble_gattc_notify_custom(uint16_t conn_handle, uint16_t chr_val_handle, - struct os_mbuf *txom) -{ - return ble_gatts_notify_custom(conn_handle, chr_val_handle, txom); -} - int ble_gatts_notify(uint16_t conn_handle, uint16_t chr_val_handle) { @@ -4434,7 +4437,7 @@ ble_gatts_notify_multiple_custom(uint16_t conn_handle, #endif int rc; - int i = 0; + size_t i = 0; uint16_t cur_chr_cnt = 0; /* mtu = MTU - 1 octet (OP code) */ uint16_t mtu = ble_att_mtu(conn_handle) - 1; @@ -4524,7 +4527,8 @@ ble_gatts_notify_multiple(uint16_t conn_handle, #if !MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE) return BLE_HS_ENOTSUP; #endif - int rc, i; + int rc; + size_t i; struct ble_gatt_notif tuples[num_handles]; struct ble_hs_conn *conn; @@ -4557,15 +4561,6 @@ ble_gatts_notify_multiple(uint16_t conn_handle, return rc; } -/** - * Deprecated. Should not be used. Use ble_gatts_notify instead. - */ -int -ble_gattc_notify(uint16_t conn_handle, uint16_t chr_val_handle) -{ - return ble_gatts_notify(conn_handle, chr_val_handle); -} - /***************************************************************************** * $indicate * *****************************************************************************/ @@ -4718,31 +4713,12 @@ ble_gatts_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, return rc; } -/** - * Deprecated. Should not be used. Use ble_gatts_indicate_custom instead. - */ -int -ble_gattc_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, - struct os_mbuf *txom) -{ - return ble_gatts_indicate_custom(conn_handle, chr_val_handle, txom); -} - int ble_gatts_indicate(uint16_t conn_handle, uint16_t chr_val_handle) { return ble_gatts_indicate_custom(conn_handle, chr_val_handle, NULL); } -/** - * Deprecated. Should not be used. Use ble_gatts_indicate instead. - */ -int -ble_gattc_indicate(uint16_t conn_handle, uint16_t chr_val_handle) -{ - return ble_gatts_indicate(conn_handle, chr_val_handle); -} - /***************************************************************************** * $rx * *****************************************************************************/ diff --git a/src/nimble/nimble/host/src/ble_gatts.c b/src/nimble/nimble/host/src/ble_gatts.c index 7977ae4ed..8aecb1215 100644 --- a/src/nimble/nimble/host/src/ble_gatts.c +++ b/src/nimble/nimble/host/src/ble_gatts.c @@ -20,6 +20,7 @@ #include #include #include +#include "nimble/porting/nimble/include/os/util.h" #include "nimble/nimble/include/nimble/ble.h" #include "nimble/nimble/host/include/host/ble_gatt.h" #include "nimble/nimble/host/include/host/ble_uuid.h" @@ -830,11 +831,29 @@ ble_gatts_clt_cfg_access(uint16_t conn_handle, uint16_t attr_handle, } static int -ble_gatts_register_clt_cfg_dsc(uint16_t *att_handle) +ble_gatts_register_clt_cfg_dsc(const struct ble_gatt_chr_def *chr, uint16_t *att_handle) { + uint8_t chr_att_flags; + uint8_t att_flags; int rc; - rc = ble_att_svr_register(uuid_ccc, BLE_ATT_F_READ | BLE_ATT_F_WRITE, 0, + /* Writing the CCCD enables notifications/indications of the + * characteristic value, so require the same encryption/authentication + * level as the characteristic itself. Authorization is not inherited: + * the stack cannot enforce it on the internal CCCD access callback, + * and its flag alone would wrongly activate the key-size check. + */ + chr_att_flags = ble_gatts_att_flags_from_chr_flags(chr->flags); + + att_flags = BLE_ATT_F_READ | BLE_ATT_F_WRITE; + if (chr_att_flags & (BLE_ATT_F_READ_ENC | BLE_ATT_F_WRITE_ENC)) { + att_flags |= BLE_ATT_F_WRITE_ENC; + } + if (chr_att_flags & (BLE_ATT_F_READ_AUTHEN | BLE_ATT_F_WRITE_AUTHEN)) { + att_flags |= BLE_ATT_F_WRITE_AUTHEN; + } + + rc = ble_att_svr_register(uuid_ccc, att_flags, chr->min_key_size, att_handle, ble_gatts_clt_cfg_access, NULL); if (rc != 0) { return rc; @@ -958,7 +977,7 @@ ble_gatts_register_chr(const struct ble_gatt_svc_def *svc, } if (ble_gatts_chr_clt_cfg_allowed(chr) != 0) { - rc = ble_gatts_register_clt_cfg_dsc(&dsc_handle); + rc = ble_gatts_register_clt_cfg_dsc(chr, &dsc_handle); if (rc != 0) { return rc; } diff --git a/src/nimble/nimble/host/src/ble_hs.c b/src/nimble/nimble/host/src/ble_hs.c index b32bf1eb4..a67f83b41 100644 --- a/src/nimble/nimble/host/src/ble_hs.c +++ b/src/nimble/nimble/host/src/ble_hs.c @@ -385,6 +385,9 @@ ble_hs_reset(void) /* Clear configured addresses. */ ble_hs_id_reset(); + /* Drop cached privacy state so sync re-runs the full setup. */ + ble_hs_pvcy_reset(); + if (ble_hs_cfg.reset_cb != NULL && ble_hs_reset_reason != 0) { ble_hs_cfg.reset_cb(ble_hs_reset_reason); } @@ -444,6 +447,7 @@ ble_hs_timer_reset(uint32_t ticks) if (!ble_hs_is_enabled()) { ble_npl_callout_stop(&ble_hs_timer); + ble_npl_callout_deinit(&ble_hs_timer); } else { rc = ble_npl_callout_reset(&ble_hs_timer, ticks); BLE_HS_DBG_ASSERT_EVAL(rc == 0); diff --git a/src/nimble/nimble/host/src/ble_hs_conn.c b/src/nimble/nimble/host/src/ble_hs_conn.c index 34e53c078..a6b05089c 100644 --- a/src/nimble/nimble/host/src/ble_hs_conn.c +++ b/src/nimble/nimble/host/src/ble_hs_conn.c @@ -509,11 +509,14 @@ ble_hs_conn_timer(void) #endif struct ble_hs_conn *conn; - ble_npl_time_t now = ble_npl_time_get(); int32_t next_exp_in = BLE_HS_FOREVER; int32_t next_exp_in_new; bool next_exp_in_updated; + +#if BLE_HS_ATT_SVR_QUEUED_WRITE_TMO || MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT) != 0 + ble_npl_time_t now = ble_npl_time_get(); int32_t time_diff; +#endif ble_hs_lock(); diff --git a/src/nimble/nimble/host/src/ble_hs_hci.c b/src/nimble/nimble/host/src/ble_hs_hci.c index 5be396929..bf84e4827 100644 --- a/src/nimble/nimble/host/src/ble_hs_hci.c +++ b/src/nimble/nimble/host/src/ble_hs_hci.c @@ -335,8 +335,8 @@ ble_hs_hci_cmd_tx(uint16_t opcode, const void *cmd, uint8_t cmd_len, struct ble_hs_hci_ack ack; int rc; - BLE_HS_DBG_ASSERT(ble_hs_hci_ack == NULL); ble_hs_hci_lock(); + BLE_HS_DBG_ASSERT(ble_hs_hci_ack == NULL); rc = ble_hs_hci_cmd_send_buf(opcode, cmd, cmd_len); if (rc != 0) { @@ -586,8 +586,17 @@ ble_hs_hci_acl_tx_now(struct ble_hs_conn *conn, struct os_mbuf **om) BLE_HS_LOG(DEBUG, "\n"); #endif + /* Account for the controller buf that will hold the txed fragment. + * Do this before ble_hs_tx_data() to avoid a race with the Number of + * Completed Packets event that may arrive before tx returns. + */ + conn->bhc_outstanding_pkts++; + ble_hs_hci_avail_pkts--; + rc = ble_hs_tx_data(frag); if (rc != 0) { + conn->bhc_outstanding_pkts--; + ble_hs_hci_avail_pkts++; goto err; } @@ -596,10 +605,6 @@ ble_hs_hci_acl_tx_now(struct ble_hs_conn *conn, struct os_mbuf **om) */ conn->bhc_flags |= BLE_HS_CONN_F_TX_FRAG; pb = BLE_HCI_PB_MIDDLE; - - /* Account for the controller buf that will hold the txed fragment. */ - conn->bhc_outstanding_pkts++; - ble_hs_hci_avail_pkts--; } if (txom != NULL) { diff --git a/src/nimble/nimble/host/src/ble_hs_hci_evt.c b/src/nimble/nimble/host/src/ble_hs_hci_evt.c index 7dbac752e..57fc23353 100644 --- a/src/nimble/nimble/host/src/ble_hs_hci_evt.c +++ b/src/nimble/nimble/host/src/ble_hs_hci_evt.c @@ -552,7 +552,7 @@ ble_hs_hci_evt_le_adv_rpt(uint8_t subevent, const void *data, unsigned int len) for (i = 0; i < ev->num_reports; i++) { rpt = data; - data += sizeof(rpt) + rpt->data_len + 1; + data += sizeof(*rpt) + rpt->data_len + 1; desc.event_type = rpt->type; desc.addr.type = rpt->addr_type; diff --git a/src/nimble/nimble/host/src/ble_hs_stop.c b/src/nimble/nimble/host/src/ble_hs_stop.c index 18ac09e28..6cc79e385 100644 --- a/src/nimble/nimble/host/src/ble_hs_stop.c +++ b/src/nimble/nimble/host/src/ble_hs_stop.c @@ -67,11 +67,16 @@ ble_hs_stop_done(int status) slist = ble_hs_stop_listeners; SLIST_INIT(&ble_hs_stop_listeners); - ble_hs_stop_hci_reset(); - ble_hs_enabled_state = BLE_HS_ENABLED_STATE_OFF; - /* Clear advertising, scanning and connection states. */ + ble_hs_unlock(); + + ble_hs_stop_hci_reset(); + + /* Clear advertising, scanning and connection states. + * Called outside the lock because ble_gap_reset_state() acquires + * it internally (via ble_gap_conn_broken, ble_hs_atomic_*, etc). + */ ble_gap_reset_state(0); /* After LL reset the controller loses its random address */ @@ -79,8 +84,6 @@ ble_hs_stop_done(int status) ble_hs_pvcy_reset(); - ble_hs_unlock(); - SLIST_FOREACH(listener, &slist, link) { listener->fn(status, listener->arg); } diff --git a/src/nimble/nimble/host/src/ble_sm.c b/src/nimble/nimble/host/src/ble_sm.c index 198c6fc87..dbc2ec090 100644 --- a/src/nimble/nimble/host/src/ble_sm.c +++ b/src/nimble/nimble/host/src/ble_sm.c @@ -972,6 +972,16 @@ ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res, ble_hs_unlock(); + /* Persist keys if bonding has successfully completed. + * This must happen before firing the pairing complete callback + * so that applications can read the persisted keys from the store. + */ + if (res->app_status == 0 && rm && proc != NULL && + proc->flags & BLE_SM_PROC_F_BONDING) { + + ble_sm_persist_keys(proc); + } + if (res->enc_cb && res->app_status != BLE_HS_ENOTCONN) { /* Do not send this event on broken connection */ @@ -993,14 +1003,6 @@ ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res, ble_gap_passkey_event(conn_handle, &res->passkey_params); } - /* Persist keys if bonding has successfully completed. */ - if (res->app_status == 0 && - rm && - proc->flags & BLE_SM_PROC_F_BONDING) { - - ble_sm_persist_keys(proc); - } - if (rm) { ble_sm_proc_free(proc); break; @@ -1393,6 +1395,13 @@ ble_sm_ltk_req_rx(const struct ble_hci_ev_le_subev_lt_key_req *ev) memset(&res, 0, sizeof res); ble_hs_lock(); + + conn = ble_hs_conn_find_assert(conn_handle); + if (conn == NULL) { + ble_hs_unlock(); + return BLE_HS_ENOENT; + } + proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_NONE, 0, NULL); if (proc == NULL) { /* The peer is attempting to restore a encrypted connection via the @@ -1432,7 +1441,6 @@ ble_sm_ltk_req_rx(const struct ble_hci_ev_le_subev_lt_key_req *ev) } if (restore) { - conn = ble_hs_conn_find_assert(conn_handle); ble_hs_conn_addrs(conn, &addrs); memcpy(peer_id_addr, addrs.peer_id_addr.val, 6); } diff --git a/src/nimble/nimble/host/src/ble_sm_alg.c b/src/nimble/nimble/host/src/ble_sm_alg.c index 2373d7db7..93209f73d 100644 --- a/src/nimble/nimble/host/src/ble_sm_alg.c +++ b/src/nimble/nimble/host/src/ble_sm_alg.c @@ -30,18 +30,17 @@ #include "ble_hs_priv.h" #if MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) -#include "nimble/ext/tinycrypt/include/tinycrypt/aes.h" - -#if MYNEWT_VAL(BLE_SM_SC) -#include "mbedtls/cipher.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/cmac.h" -#include "mbedtls/ecdh.h" -#include "mbedtls/ecp.h" -#endif - +#if CONFIG_MBEDTLS_VER_4_X_SUPPORT +#include #else +#include +#if MYNEWT_VAL(BLE_SM_SC) +#include +#include +#include +#endif // MYNEWT_VAL(BLE_SM_SC) +#endif // CONFIG_MBEDTLS_VER_4_X_SUPPORT +#else // !MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) #include "nimble/ext/tinycrypt/include/tinycrypt/aes.h" #include "nimble/ext/tinycrypt/include/tinycrypt/constants.h" #include "nimble/ext/tinycrypt/include/tinycrypt/utils.h" @@ -49,36 +48,37 @@ #if MYNEWT_VAL(BLE_SM_SC) #include "nimble/ext/tinycrypt/include/tinycrypt/cmac_mode.h" #include "nimble/ext/tinycrypt/include/tinycrypt/ecc_dh.h" +#endif +#endif // MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) + +#if !CONFIG_MBEDTLS_VER_4_X_SUPPORT #if MYNEWT_VAL(TRNG) #include "trng/trng.h" #endif -#endif +#if MYNEWT_VAL(BLE_SM_SC) && MYNEWT_VAL(TRNG) +static struct trng_dev *g_trng; #endif +#endif // !CONFIG_MBEDTLS_VER_4_X_SUPPORT +// Helper to prevent optimization when zeroing memory +static inline void ble_sm_alg_secure_zero(void *v, size_t n) { #if MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) -#if MYNEWT_VAL(BLE_SM_SC) -static mbedtls_ecp_keypair keypair; -#endif + mbedtls_platform_zeroize(v, n); #else -#if MYNEWT_VAL(BLE_SM_SC) && MYNEWT_VAL(TRNG) -static struct trng_dev *g_trng; -#endif -#endif + if (v == NULL || n == 0) { + return; + } -/** - * Keep forward-compatibility with Mbed TLS 3.x. - * - * Direct access to fields of structures declared in public headers is no longer - * supported. In Mbed TLS 3, the layout of structures is not considered part of - * the stable API, and minor versions (3.1, 3.2, etc.) may add, remove, rename, - * reorder or change the type of structure fields. - */ -#if (MBEDTLS_VERSION_NUMBER < 0x03000000) -#ifndef MBEDTLS_PRIVATE -#define MBEDTLS_PRIVATE(member) member -#endif + volatile unsigned char *p = (volatile unsigned char *)v; + while (n--) { + *p++ = 0; + } + + // Compiler memory barrier + __asm__ __volatile__("" : : "r"(v) : "memory"); #endif +} static void ble_sm_alg_xor_128(const uint8_t *p, const uint8_t *q, uint8_t *r) @@ -94,43 +94,85 @@ int ble_sm_alg_encrypt(const uint8_t *key, const uint8_t *plaintext, uint8_t *enc_data) { + int ret = 0; uint8_t tmp[16]; swap_buf(tmp, key, 16); + #if MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) +#if CONFIG_MBEDTLS_VER_4_X_SUPPORT + psa_status_t status; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECB_NO_PADDING); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&key_attributes, 128); + + status = psa_import_key(&key_attributes, tmp, 16, &key_id); + if (status != PSA_SUCCESS) { + ret = BLE_HS_EUNKNOWN; + goto done; + } + + psa_reset_key_attributes(&key_attributes); + swap_buf(tmp, plaintext, 16); + size_t output_len = 0; + status = psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING, tmp, + 16, enc_data, 16, &output_len); + if (status != PSA_SUCCESS || output_len != 16) { + psa_destroy_key(key_id); + ret = BLE_HS_EUNKNOWN; + goto done; + } + + psa_destroy_key(key_id); + +#else mbedtls_aes_context s = {0}; mbedtls_aes_init(&s); if (mbedtls_aes_setkey_enc(&s, tmp, 128) != 0) { mbedtls_aes_free(&s); - return BLE_HS_EUNKNOWN; + ret = BLE_HS_EUNKNOWN; + goto done; } swap_buf(tmp, plaintext, 16); if (mbedtls_aes_crypt_ecb(&s, MBEDTLS_AES_ENCRYPT, tmp, enc_data) != 0) { mbedtls_aes_free(&s); - return BLE_HS_EUNKNOWN; + ret = BLE_HS_EUNKNOWN; + goto done; } mbedtls_aes_free(&s); -#else +#endif /* CONFIG_MBEDTLS_VER_4_X_SUPPORT */ +#else /* !MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) */ struct tc_aes_key_sched_struct s; if (tc_aes128_set_encrypt_key(&s, tmp) == TC_CRYPTO_FAIL) { - return BLE_HS_EUNKNOWN; + ble_sm_alg_secure_zero(&s, sizeof(s)); + ret = BLE_HS_EUNKNOWN; + goto done; } swap_buf(tmp, plaintext, 16); if (tc_aes_encrypt(enc_data, tmp, &s) == TC_CRYPTO_FAIL) { - return BLE_HS_EUNKNOWN; + ble_sm_alg_secure_zero(&s, sizeof(s)); + ret = BLE_HS_EUNKNOWN; + goto done; } + ble_sm_alg_secure_zero(&s, sizeof(s)); #endif + swap_in_place(enc_data, 16); - return 0; +done: + ble_sm_alg_secure_zero(tmp, sizeof(tmp)); + return ret; } int @@ -257,77 +299,73 @@ ble_sm_alg_log_buf(const char *name, const uint8_t *buf, int len) * @param len Length of the message in octets. * @param out Output; message authentication code. */ - -#if MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) int ble_sm_alg_aes_cmac(const uint8_t *key, const uint8_t *in, size_t len, uint8_t *out) { - int rc = BLE_HS_EUNKNOWN; - mbedtls_cipher_context_t ctx = {0}; - const mbedtls_cipher_info_t *cipher_info; - - mbedtls_cipher_init(&ctx); - - cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB); - - if (cipher_info == NULL) { - goto exit; +#if MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) +#if CONFIG_MBEDTLS_VER_4_X_SUPPORT + psa_status_t status; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + psa_algorithm_t alg = PSA_ALG_CMAC; + size_t output_len = 0; + + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_MESSAGE); + psa_set_key_algorithm(&key_attributes, PSA_ALG_CMAC); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&key_attributes, 128); + + status = psa_import_key(&key_attributes, key, 16, &key_id); + if (status != PSA_SUCCESS) { + return BLE_HS_EUNKNOWN; } - if (mbedtls_cipher_setup(&ctx, cipher_info) != 0) { - goto exit; - } + psa_reset_key_attributes(&key_attributes); - rc = mbedtls_cipher_cmac_starts(&ctx, key, 128); - if (rc != 0) { - goto exit; + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + status = psa_mac_sign_setup(&operation, key_id, alg); + if (status != PSA_SUCCESS) { + psa_destroy_key(key_id); + return BLE_HS_EUNKNOWN; } - rc = mbedtls_cipher_cmac_update(&ctx, in, len); - if (rc != 0) { - goto exit; + status = psa_mac_update(&operation, in, len); + if (status == PSA_SUCCESS) { + status = psa_mac_sign_finish(&operation, out, 16, &output_len); } - rc = mbedtls_cipher_cmac_finish(&ctx, out); - -exit: - mbedtls_cipher_free(&ctx); - return rc; -} - + psa_mac_abort(&operation); + psa_destroy_key(key_id); + return (status == PSA_SUCCESS && output_len == 16) ? 0 : BLE_HS_EUNKNOWN; #else + if (mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB), + key, 128, in, len, out)) { + return BLE_HS_EUNKNOWN; + } -/** - * Cypher based Message Authentication Code (CMAC) with AES 128 bit - * - * @param key 128-bit key. - * @param in Message to be authenticated. - * @param len Length of the message in octets. - * @param out Output; message authentication code. - */ -static int -ble_sm_alg_aes_cmac(const uint8_t *key, const uint8_t *in, size_t len, - uint8_t *out) -{ + return 0; +#endif // CONFIG_MBEDTLS_VER_4_X_SUPPORT +#else + int rc = 0; struct tc_aes_key_sched_struct sched; struct tc_cmac_struct state; - if (tc_cmac_setup(&state, key, &sched) == TC_CRYPTO_FAIL) { - return BLE_HS_EUNKNOWN; - } + rc = (tc_cmac_setup(&state, key, &sched) == TC_CRYPTO_FAIL) ? BLE_HS_EUNKNOWN : 0; - if (tc_cmac_update(&state, in, len) == TC_CRYPTO_FAIL) { - return BLE_HS_EUNKNOWN; + if (rc == 0) { + rc = (tc_cmac_update(&state, in, len) == TC_CRYPTO_FAIL) ? BLE_HS_EUNKNOWN : 0; } - if (tc_cmac_final(out, &state) == TC_CRYPTO_FAIL) { - return BLE_HS_EUNKNOWN; + if (rc == 0) { + rc = (tc_cmac_final(out, &state) == TC_CRYPTO_FAIL) ? BLE_HS_EUNKNOWN : 0; } - return 0; + ble_sm_alg_secure_zero(&sched, sizeof(sched)); + ble_sm_alg_secure_zero(&state, sizeof(state)); + return rc; +#endif // MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) } -#endif int ble_sm_alg_f4(const uint8_t *u, const uint8_t *v, const uint8_t *x, @@ -656,102 +694,165 @@ ble_sm_alg_csis_sih(const uint8_t *k, const uint8_t *r, uint8_t *out) return 0; } +int +ble_sm_alg_rng(void *arg, unsigned char *buf, size_t size) +{ + (void)arg; + +#if MYNEWT_VAL(SELFTEST) + while (size--) { + buf[size] = 9; + } + + return 0; +#elif MYNEWT_VAL(TRNG) + size_t num; + + if (!g_trng) { + g_trng = (struct trng_dev *)os_dev_open("trng", OS_WAIT_FOREVER, NULL); + assert(g_trng); + } + + while (size) { + num = trng_read(g_trng, buf, size); + buf += num; + size -= num; + } + + return 0; +#else + return ble_hs_hci_rand(buf, size); +#endif +} + int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey) { + int err = 0; +#if MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) +#if CONFIG_MBEDTLS_VER_4_X_SUPPORT + // PSA/mbedTLS expects 65 bytes: 0x04 prefix + X (32 bytes) + Y (32 bytes) + uint8_t pk[65]; uint8_t dh[32]; - uint8_t pk[64]; uint8_t priv[32]; - int rc = BLE_HS_EUNKNOWN; - swap_buf(pk, peer_pub_key_x, 32); - swap_buf(&pk[32], peer_pub_key_y, 32); + psa_key_id_t key_id = 0; + psa_status_t status; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + size_t output_len = 0; + swap_buf(priv, our_priv_key, 32); -#if MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) - struct mbedtls_ecp_point pt = {0}, Q = {0}; - mbedtls_mpi z = {0}, d = {0}; - mbedtls_ctr_drbg_context ctr_drbg = {0}; - mbedtls_entropy_context entropy = {0}; - - uint8_t pub[65] = {0}; - /* Hardcoded first byte of pub key for MBEDTLS_ECP_PF_UNCOMPRESSED */ - pub[0] = 0x04; - memcpy(&pub[1], pk, 64); - - /* Initialize the required structures here */ - mbedtls_ecp_point_init(&pt); - mbedtls_ecp_point_init(&Q); - mbedtls_ctr_drbg_init(&ctr_drbg); - mbedtls_entropy_init(&entropy); - mbedtls_mpi_init(&d); - mbedtls_mpi_init(&z); + pk[0] = 0x04; // Uncompressed format for public key + swap_buf(&pk[1], peer_pub_key_x, 32); + swap_buf(&pk[33], peer_pub_key_y, 32); + + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&key_attributes, 256); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); - /* Below 3 steps are to validate public key on curve secp256r1 */ - if (mbedtls_ecp_group_load(&keypair.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1) != 0) { - goto exit; + status = psa_import_key(&key_attributes, priv, 32, &key_id); + if (status == PSA_SUCCESS) { + psa_reset_key_attributes(&key_attributes); + status = psa_raw_key_agreement(PSA_ALG_ECDH, key_id, pk, 65, dh, sizeof(dh), &output_len); } - if (mbedtls_ecp_point_read_binary(&keypair.MBEDTLS_PRIVATE(grp), &pt, pub, 65) != 0) { - goto exit; + if (status != PSA_SUCCESS || output_len != 32) { + err = BLE_HS_EUNKNOWN; + } else { + swap_buf(out_dhkey, dh, 32); } - if (mbedtls_ecp_check_pubkey(&keypair.MBEDTLS_PRIVATE(grp), &pt) != 0) { - goto exit; + if (key_id != 0) { + psa_destroy_key(key_id); } - /* Set PRNG */ - if ( ( rc = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, - NULL, 0) ) != 0) { - goto exit; + ble_sm_alg_secure_zero(priv, sizeof(priv)); + ble_sm_alg_secure_zero(dh, sizeof(dh)); + ble_sm_alg_secure_zero(pk, sizeof(pk)); + + return err; +#else + mbedtls_mpi priv; + mbedtls_mpi shared; + mbedtls_ecp_group group; + mbedtls_ecp_point point; + uint8_t pub_key[65]; + + mbedtls_mpi_init(&priv); + mbedtls_mpi_init(&shared); + mbedtls_ecp_point_init(&point); + mbedtls_ecp_group_init(&group); + + pub_key[0] = 0x04; /* Uncompressed point identifier */ + swap_buf(&pub_key[1], peer_pub_key_x, 32); + swap_buf(&pub_key[33], peer_pub_key_y, 32); + + err = mbedtls_ecp_group_load(&group, MBEDTLS_ECP_DP_SECP256R1); + + if (err == 0) { + err = mbedtls_ecp_point_read_binary(&group, &point, pub_key, sizeof(pub_key)); } - /* Prepare point Q from pub key */ - if (mbedtls_ecp_point_read_binary(&keypair.MBEDTLS_PRIVATE(grp), &Q, pub, 65) != 0) { - goto exit; + if (err == 0) { + err = mbedtls_ecp_check_pubkey(&group, &point); } - if (mbedtls_mpi_read_binary(&d, priv, 32) != 0) { - goto exit; + if (err == 0) { + err = mbedtls_mpi_read_binary_le(&priv, our_priv_key, 32); } - rc = mbedtls_ecdh_compute_shared(&keypair.MBEDTLS_PRIVATE(grp), &z, &Q, &d, - mbedtls_ctr_drbg_random, &ctr_drbg); - if (rc != 0) { - goto exit; + if (err == 0) { + err = mbedtls_ecdh_compute_shared(&group, &shared, &point, &priv, + ble_sm_alg_rng, NULL); } - rc = mbedtls_mpi_write_binary(&z, dh, 32); - if (rc != 0) { - goto exit; + if (err == 0) { + err = mbedtls_mpi_write_binary_le(&shared, out_dhkey, 32); } -exit: - mbedtls_ecp_point_free(&pt); - mbedtls_mpi_free(&z); - mbedtls_mpi_free(&d); - mbedtls_ecp_point_free(&Q); - mbedtls_entropy_free(&entropy); - mbedtls_ctr_drbg_free(&ctr_drbg); - if (rc != 0) { + mbedtls_ecp_group_free(&group); + mbedtls_ecp_point_free(&point); + mbedtls_mpi_free(&priv); + mbedtls_mpi_free(&shared); + ble_sm_alg_secure_zero(pub_key, sizeof(pub_key)); + if (err) { return BLE_HS_EUNKNOWN; } + return 0; +#endif #else + uint8_t dh[32]; + uint8_t pk[64]; + uint8_t priv[32]; + + swap_buf(pk, peer_pub_key_x, 32); + swap_buf(&pk[32], peer_pub_key_y, 32); + swap_buf(priv, our_priv_key, 32); + if (uECC_valid_public_key(pk, &curve_secp256r1) < 0) { - return BLE_HS_EUNKNOWN; + err = BLE_HS_EUNKNOWN; + goto done; } - rc = uECC_shared_secret(pk, priv, dh, &curve_secp256r1); - if (rc == TC_CRYPTO_FAIL) { - return BLE_HS_EUNKNOWN; + err = uECC_shared_secret(pk, priv, dh, &curve_secp256r1); + if (err == TC_CRYPTO_FAIL) { + err = BLE_HS_EUNKNOWN; + goto done; } -#endif + err = 0; swap_buf(out_dhkey, dh, 32); - return 0; +done: + ble_sm_alg_secure_zero(priv, sizeof(priv)); + ble_sm_alg_secure_zero(dh, sizeof(dh)); + ble_sm_alg_secure_zero(pk, sizeof(pk)); + return err; +#endif } /* based on Core Specification 4.2 Vol 3. Part H 2.3.5.6.1 */ @@ -774,97 +875,172 @@ static const uint8_t ble_sm_alg_dbg_pub_key[64] = { }; #endif -#if MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) -static int -mbedtls_gen_keypair(uint8_t *public_key, uint8_t *private_key) +/** + * pub: 64 bytes + * priv: 32 bytes + */ +int +ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) { - int rc = BLE_HS_EUNKNOWN; - mbedtls_entropy_context entropy = {0}; - mbedtls_ctr_drbg_context ctr_drbg = {0}; +#if MYNEWT_VAL(BLE_SM_SC_DEBUG_KEYS) + swap_buf(pub, ble_sm_alg_dbg_pub_key, 32); + swap_buf(&pub[32], &ble_sm_alg_dbg_pub_key[32], 32); + swap_buf(priv, ble_sm_alg_dbg_priv_key, 32); + return 0; +#else +#if MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) +#if CONFIG_MBEDTLS_VER_4_X_SUPPORT + int ret = 0; - mbedtls_entropy_init(&entropy); - mbedtls_ctr_drbg_init(&ctr_drbg); + psa_status_t status; + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_id_t key_id = 0; + size_t olen = 0; - /* Free the previously allocate keypair */ - mbedtls_ecp_keypair_free(&keypair); + // Temporary flat arrays to hold raw Big-Endian values from PSA + uint8_t tmp_priv[32]; + uint8_t tmp_pub[65]; // 0x04 uncompressed prefix + 32-byte X + 32-byte Y - mbedtls_ecp_keypair_init(&keypair); + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_bits(&key_attributes, 256); + psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_EXPORT); - if (( rc = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, - NULL, 0)) != 0) { - goto exit; - } + do { + status = psa_generate_key(&key_attributes, &key_id); + if (status != PSA_SUCCESS) { + ret = BLE_HS_EUNKNOWN; + goto psa_exit; + } + + status = psa_export_key(key_id, tmp_priv, sizeof(tmp_priv), &olen); + if (status != PSA_SUCCESS || olen != 32) { + ret = BLE_HS_EUNKNOWN; + goto psa_exit; + } - if ((rc = mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1, &keypair, - mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) { - goto exit; + // Convert Big-Endian to Little-Endian to evaluate against the debug key rule + swap_buf(priv, tmp_priv, 32); + + if (memcmp(priv, ble_sm_alg_dbg_priv_key, 32) == 0) { + psa_destroy_key(key_id); + key_id = 0; + continue; // Regenerate keypair + } + break; + } while (1); + + psa_reset_key_attributes(&key_attributes); + + status = psa_export_public_key(key_id, tmp_pub, sizeof(tmp_pub), &olen); + if (status != PSA_SUCCESS || olen != 65 || tmp_pub[0] != 0x04) { + ret = BLE_HS_EUNKNOWN; + goto psa_exit; } - if (( rc = mbedtls_mpi_write_binary(&keypair.MBEDTLS_PRIVATE(d), private_key, 32)) != 0) { - goto exit; + // Unpack Big-Endian coordinates and transform them to NimBLE's Little-Endian requirement + swap_buf(pub, &tmp_pub[1], 32); // Extract X + swap_buf(pub + 32, &tmp_pub[33], 32); // Extract Y + +psa_exit: + if (key_id != 0) { + psa_destroy_key(key_id); } + ble_sm_alg_secure_zero(tmp_priv, sizeof(tmp_priv)); + ble_sm_alg_secure_zero(tmp_pub, sizeof(tmp_pub)); + return ret; + +#else // Legacy MbedTLS Fallback Block + uint8_t pub_buf[65]; + size_t pub_len = 0; + mbedtls_ecp_keypair keypair; + mbedtls_ecp_group group; + mbedtls_ecp_point point; + mbedtls_mpi d; + int err; - size_t olen = 0; - uint8_t pub[65] = {0}; + mbedtls_ecp_keypair_init(&keypair); + mbedtls_ecp_group_init(&group); + mbedtls_ecp_point_init(&point); + mbedtls_mpi_init(&d); + + do { + err = mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1, &keypair, + ble_sm_alg_rng, NULL); + if (err) { + break; + } + + err = mbedtls_ecp_export(&keypair, &group, &d, &point); + if (err) { + break; + } + + err = mbedtls_mpi_write_binary_le(&d, priv, 32); + if (err) { + break; + } + /* Make sure generated key isn't debug key. */ + } while (memcmp(priv, ble_sm_alg_dbg_priv_key, 32) == 0); - if ((rc = mbedtls_ecp_point_write_binary(&keypair.MBEDTLS_PRIVATE(grp), &keypair.MBEDTLS_PRIVATE(Q), MBEDTLS_ECP_PF_UNCOMPRESSED, - &olen, pub, 65)) != 0) { - goto exit; + if (err == 0) { + err = mbedtls_ecp_point_write_binary(&group, &point, MBEDTLS_ECP_PF_UNCOMPRESSED, + &pub_len, pub_buf, sizeof(pub_buf)); } - memcpy(public_key, &pub[1], 64); + if (err == 0) { + if (pub_len == sizeof(pub_buf)) { + swap_buf(pub, &pub_buf[1], 32); + swap_buf(pub + 32, &pub_buf[33], 32); + } else { + err = BLE_HS_EUNKNOWN; + } + } -exit: - mbedtls_ctr_drbg_free( &ctr_drbg ); - mbedtls_entropy_free( &entropy ); - if (rc != 0) { - mbedtls_ecp_keypair_free(&keypair); + mbedtls_ecp_keypair_free(&keypair); + mbedtls_ecp_group_free(&group); + mbedtls_ecp_point_free(&point); + mbedtls_mpi_free(&d); + + if (err) { return BLE_HS_EUNKNOWN; } return 0; -} +#endif // CONFIG_MBEDTLS_VER_4_X_SUPPORT -void mbedtls_free_keypair(void) -{ - mbedtls_ecp_keypair_free(&keypair); -} -#endif - -/** - * pub: 64 bytes - * priv: 32 bytes - */ -int -ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) -{ -#if MYNEWT_VAL(BLE_SM_SC_DEBUG_KEYS) - swap_buf(pub, ble_sm_alg_dbg_pub_key, 32); - swap_buf(&pub[32], &ble_sm_alg_dbg_pub_key[32], 32); - swap_buf(priv, ble_sm_alg_dbg_priv_key, 32); -#else - uint8_t pk[64]; +#else // TinyCrypt / uECC Block + int ret = 0; + uint8_t tmp_priv[32]; + uint8_t tmp_pub[64]; // uECC uses native 64 bytes (omits the 0x04 uncompressed prefix) do { -#if MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) - if (mbedtls_gen_keypair(pk, priv) != 0) { - return BLE_HS_EUNKNOWN; - } -#else - if (uECC_make_key(pk, priv, &curve_secp256r1) != TC_CRYPTO_SUCCESS) { - return BLE_HS_EUNKNOWN; + // uECC uses Big-Endian mapping internally + if (uECC_make_key(tmp_pub, tmp_priv, &curve_secp256r1) != 1) { + ret = BLE_HS_EUNKNOWN; + goto tc_exit; } -#endif - /* Make sure generated key isn't debug key. */ - } while (memcmp(priv, ble_sm_alg_dbg_priv_key, 32) == 0); - swap_buf(pub, pk, 32); - swap_buf(&pub[32], &pk[32], 32); - swap_in_place(priv, 32); -#endif + // Swap to Little-Endian for validation + swap_buf(priv, tmp_priv, 32); - return 0; + if (memcmp(priv, ble_sm_alg_dbg_priv_key, 32) == 0) { + continue; + } + break; + } while (1); + + // Unpack Big-Endian coordinates to NimBLE's Little-Endian public array destination + swap_buf(pub, tmp_pub, 32); + swap_buf(pub + 32, &tmp_pub[32], 32); + +tc_exit: + ble_sm_alg_secure_zero(tmp_priv, sizeof(tmp_priv)); + ble_sm_alg_secure_zero(tmp_pub, sizeof(tmp_pub)); + return ret; +#endif // MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) +#endif // MYNEWT_VAL(BLE_SM_SC_DEBUG_KEYS) } #if MYNEWT_VAL(SELFTEST) @@ -889,6 +1065,10 @@ ble_sm_alg_rand(uint8_t *dst, unsigned int size) size -= num; } #else + if (!ble_hs_is_enabled()) { + return 0; + } + if (ble_hs_hci_rand(dst, size)) { return 0; } @@ -899,11 +1079,11 @@ ble_sm_alg_rand(uint8_t *dst, unsigned int size) #endif void -ble_sm_alg_ecc_init(void) -{ +ble_sm_alg_ecc_init(void) { #if (!MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS)) uECC_set_rng(ble_sm_alg_rand); #endif + return; } #endif diff --git a/src/nimble/nimble/host/src/ble_sm_lgcy.c b/src/nimble/nimble/host/src/ble_sm_lgcy.c index 1a53aa821..0c64ef1c7 100644 --- a/src/nimble/nimble/host/src/ble_sm_lgcy.c +++ b/src/nimble/nimble/host/src/ble_sm_lgcy.c @@ -215,6 +215,18 @@ ble_sm_lgcy_random_rx(struct ble_sm_proc *proc, struct ble_sm_result *res) ble_sm_ia_ra(proc, &iat, ia, &rat, ra); + /* If the peer echoed our own random back (Srand == Mrand), the c1 check + * would trivially pass because the peer also mirrored Mconfirm. + * Reject this immediately with Confirm Value Failed. + */ + if ((proc->flags & BLE_SM_PROC_F_INITIATOR) && + memcmp(ble_sm_peer_pair_rand(proc), ble_sm_our_pair_rand(proc), 16) == 0) { + 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; + } + rc = ble_sm_alg_c1(proc->tk, ble_sm_peer_pair_rand(proc), proc->pair_req, proc->pair_rsp, iat, rat, ia, ra, confirm_val); if (rc != 0) { diff --git a/src/nimble/nimble/host/store/config/src/ble_store_nvs.c b/src/nimble/nimble/host/store/config/src/ble_store_nvs.c index 85a733a82..21645f5c8 100644 --- a/src/nimble/nimble/host/store/config/src/ble_store_nvs.c +++ b/src/nimble/nimble/host/store/config/src/ble_store_nvs.c @@ -42,7 +42,7 @@ #define NIMBLE_NVS_CCCD_SEC_KEY "cccd_sec" #define NIMBLE_NVS_CSFC_SEC_KEY "csfc_sec" #define NIMBLE_NVS_PEER_RECORDS_KEY "p_dev_rec" -#define NIMBLE_NVS_DEFAULT_NAMESPACE "nimble_bond" +#define NIMBLE_NVS_NAMESPACE "nimble_bond" #if MYNEWT_VAL(ENC_ADV_DATA) #define NIMBLE_NVS_EAD_SEC_KEY "ead_sec" @@ -51,32 +51,12 @@ #define NIMBLE_NVS_LOCAL_IRK_KEY "local_irk" #define NIMBLE_NVS_RPA_RECORDS_KEY "rpa_rec" -static const char *LOG_TAG = "NIMBLE_NVS"; -static char nimble_nvs_namespace_buf[NIMBLE_NVS_STR_NAME_MAX_LEN]; -static const char *NIMBLE_NVS_NAMESPACE = NIMBLE_NVS_DEFAULT_NAMESPACE; +static const char *TAG = "NIMBLE_NVS"; /***************************************************************************** * $ MISC * *****************************************************************************/ -void -set_nimble_nvs_namespace(const char *ns) -{ - if (ns == NULL) { - NIMBLE_NVS_NAMESPACE = NIMBLE_NVS_DEFAULT_NAMESPACE; - return; - } - - if (strlen(ns) < NIMBLE_NVS_STR_NAME_MAX_LEN) { - strncpy(nimble_nvs_namespace_buf, ns, NIMBLE_NVS_STR_NAME_MAX_LEN - 1); - nimble_nvs_namespace_buf[NIMBLE_NVS_STR_NAME_MAX_LEN - 1] = '\0'; - NIMBLE_NVS_NAMESPACE = nimble_nvs_namespace_buf; - } else { - ESP_LOGE(LOG_TAG, "Namespace string is too long, using default namespace"); - NIMBLE_NVS_NAMESPACE = NIMBLE_NVS_DEFAULT_NAMESPACE; - } -} - static void get_nvs_key_string(int obj_type, int index, char *key_string) { @@ -159,7 +139,7 @@ get_nvs_peer_record(char *key_string, struct ble_hs_dev_records *p_dev_rec) err = nvs_open(NIMBLE_NVS_NAMESPACE, NVS_READWRITE, &nimble_handle); if (err != ESP_OK) { - ESP_LOGE(LOG_TAG, "NVS open operation failed"); + ESP_LOGE(TAG, "NVS open operation failed"); return BLE_HS_ESTORE_FAIL; } @@ -188,7 +168,7 @@ get_nvs_db_value(int obj_type, char *key_string, union ble_store_value *val) err = nvs_open(NIMBLE_NVS_NAMESPACE, NVS_READWRITE, &nimble_handle); if (err != ESP_OK) { - ESP_LOGE(LOG_TAG, "NVS open operation failed"); + ESP_LOGE(TAG, "NVS open operation failed"); return BLE_HS_ESTORE_FAIL; } @@ -264,7 +244,7 @@ get_nvs_db_attribute(int obj_type, bool empty, void *value, int num_value) /* Check if the user is searching for empty index to write to */ if (err == ESP_ERR_NVS_NOT_FOUND) { if (empty) { - ESP_LOGD(LOG_TAG, "Empty NVS index found = %d for obj_type = %d", i, obj_type); + ESP_LOGD(TAG, "Empty NVS index found = %d for obj_type = %d", i, obj_type); return i; } } else if (err == ESP_OK) { @@ -311,7 +291,7 @@ get_nvs_db_attribute(int obj_type, bool empty, void *value, int num_value) } } } else { - ESP_LOGE(LOG_TAG, "NVS read operation failed while fetching size !!"); + ESP_LOGE(TAG, "NVS read operation failed while fetching size !!"); return -1; } } @@ -335,13 +315,13 @@ ble_nvs_delete_value(int obj_type, int8_t index) char key_string[NIMBLE_NVS_STR_NAME_MAX_LEN]; if (index > get_nvs_max_obj_value(obj_type)) { - ESP_LOGE(LOG_TAG, "Invalid index provided to delete"); + ESP_LOGE(TAG, "Invalid index provided to delete"); return BLE_HS_EUNKNOWN; } err = nvs_open(NIMBLE_NVS_NAMESPACE, NVS_READWRITE, &nimble_handle); if (err != ESP_OK) { - ESP_LOGE(LOG_TAG, "NVS open operation failed !!"); + ESP_LOGE(TAG, "NVS open operation failed !!"); return BLE_HS_ESTORE_FAIL; } @@ -372,20 +352,20 @@ ble_nvs_write_key_value(char *key, const void *value, size_t required_size) err = nvs_open(NIMBLE_NVS_NAMESPACE, NVS_READWRITE, &nimble_handle); if (err != ESP_OK) { - ESP_LOGE(LOG_TAG, "NVS open operation failed !!"); + ESP_LOGE(TAG, "NVS open operation failed !!"); return BLE_HS_ESTORE_FAIL; } err = nvs_set_blob(nimble_handle, key, value, required_size); if (err != ESP_OK) { - ESP_LOGE(LOG_TAG, "NVS write operation failed !!"); + ESP_LOGE(TAG, "NVS write operation failed !!"); goto error; } /* NVS commit and close */ err = nvs_commit(nimble_handle); if (err != ESP_OK) { - ESP_LOGE(LOG_TAG, "NVS commit operation failed !!"); + ESP_LOGE(TAG, "NVS commit operation failed !!"); goto error; } @@ -409,13 +389,13 @@ ble_store_nvs_write(int obj_type, const union ble_store_value *val) write_key_index = get_nvs_db_attribute(obj_type, 1, NULL, 0); if (write_key_index == -1) { - ESP_LOGE(LOG_TAG, "NVS operation failed !!"); + ESP_LOGE(TAG, "NVS operation failed !!"); return BLE_HS_ESTORE_FAIL; } else if (write_key_index > get_nvs_max_obj_value(obj_type)) { /* bare-bone config code will take care of capacity overflow event, * however another check added for consistency */ - ESP_LOGD(LOG_TAG, "NVS size overflow."); + ESP_LOGD(TAG, "NVS size overflow."); return BLE_HS_ESTORE_CAP; } @@ -456,13 +436,13 @@ ble_store_nvs_peer_records(int obj_type, const struct ble_hs_dev_records *p_dev_ write_key_index = get_nvs_db_attribute(obj_type, 1, NULL, 0); if (write_key_index == -1) { - ESP_LOGE(LOG_TAG, "NVS operation failed !!"); + ESP_LOGE(TAG, "NVS operation failed !!"); return BLE_HS_ESTORE_FAIL; } else if (write_key_index > get_nvs_max_obj_value(obj_type)) { /* bare-bone config code will take care of capacity overflow event, * however another check added for consistency */ - ESP_LOGD(LOG_TAG, "NVS size overflow."); + ESP_LOGD(TAG, "NVS size overflow."); return BLE_HS_ESTORE_CAP; } @@ -496,7 +476,7 @@ populate_db_from_nvs(int obj_type, void *dst, int *db_num) if (err == ESP_ERR_NVS_NOT_FOUND) { continue; } else if (err != ESP_OK) { - ESP_LOGE(LOG_TAG, "NVS read operation failed !!"); + ESP_LOGE(TAG, "NVS read operation failed !!"); return -1; } #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) @@ -505,14 +485,14 @@ populate_db_from_nvs(int obj_type, void *dst, int *db_num) if (err == ESP_ERR_NVS_NOT_FOUND) { continue; } else if (err != ESP_OK) { - ESP_LOGE(LOG_TAG, "NVS read operation failed !!"); + ESP_LOGE(TAG, "NVS read operation failed !!"); return -1; } } /* NVS index has data, fill up the ram db with it */ if (obj_type == BLE_STORE_OBJ_TYPE_PEER_DEV_REC) { - ESP_LOGD(LOG_TAG, "Peer dev records filled from NVS index = %d", i); + ESP_LOGD(TAG, "Peer dev records filled from NVS index = %d", i); memcpy(db_item, &p_dev_rec, sizeof(struct ble_hs_dev_records)); db_item += sizeof(struct ble_hs_dev_records); (*db_num)++; @@ -520,35 +500,35 @@ populate_db_from_nvs(int obj_type, void *dst, int *db_num) #endif { if (obj_type == BLE_STORE_OBJ_TYPE_CCCD) { - ESP_LOGD(LOG_TAG, "CCCD in RAM is filled up from NVS index = %d", i); + ESP_LOGD(TAG, "CCCD in RAM is filled up from NVS index = %d", i); memcpy(db_item, &cur.cccd, sizeof(struct ble_store_value_cccd)); db_item += sizeof(struct ble_store_value_cccd); (*db_num)++; } else if (obj_type == BLE_STORE_OBJ_TYPE_CSFC) { - ESP_LOGD(LOG_TAG, "CSFC in RAM is filled up from NVS index = %d", i); + ESP_LOGD(TAG, "CSFC in RAM is filled up from NVS index = %d", i); memcpy(db_item, &cur.csfc, sizeof(struct ble_store_value_csfc)); db_item += sizeof(struct ble_store_value_csfc); (*db_num)++; #if MYNEWT_VAL(ENC_ADV_DATA) } else if (obj_type == BLE_STORE_OBJ_TYPE_ENC_ADV_DATA) { - ESP_LOGD(LOG_TAG, "EAD in RAM is filled up from NVS index = %d", i); + ESP_LOGD(TAG, "EAD in RAM is filled up from NVS index = %d", i); memcpy(db_item, &cur.ead, sizeof(struct ble_store_value_ead)); db_item += sizeof(struct ble_store_value_ead); (*db_num)++; #endif } else if(obj_type == BLE_STORE_OBJ_TYPE_LOCAL_IRK) { - ESP_LOGD(LOG_TAG, "Local IRK in RAM is filled up from NVS index = %d", i); + ESP_LOGD(TAG, "Local IRK in RAM is filled up from NVS index = %d", i); memcpy(db_item, &cur.local_irk, sizeof(struct ble_store_value_local_irk)); db_item += sizeof(struct ble_store_value_local_irk); (*db_num)++; } else if(obj_type == BLE_STORE_OBJ_TYPE_PEER_ADDR) { - ESP_LOGD(LOG_TAG, "RPA_REC in RAM is filled up from NVS index = %d", i); + ESP_LOGD(TAG, "RPA_REC in RAM is filled up from NVS index = %d", i); memcpy(db_item, &cur.rpa_rec, sizeof(struct ble_store_value_rpa_rec)); db_item += sizeof(struct ble_store_value_rpa_rec); (*db_num)++; } else { - ESP_LOGD(LOG_TAG, "KEY in RAM is filled up from NVS index = %d", i); + ESP_LOGD(TAG, "KEY in RAM is filled up from NVS index = %d", i); memcpy(db_item, &cur.sec, sizeof(struct ble_store_value_sec)); db_item += sizeof(struct ble_store_value_sec); (*db_num)++; @@ -574,15 +554,15 @@ ble_nvs_restore_sec_keys(void) err = populate_db_from_nvs(BLE_STORE_OBJ_TYPE_OUR_SEC, ble_store_config_our_secs, &ble_store_config_num_our_secs); if (err != ESP_OK) { - ESP_LOGE(LOG_TAG, "NVS operation failed for 'our sec'"); + ESP_LOGE(TAG, "NVS operation failed for 'our sec'"); return err; } - ESP_LOGD(LOG_TAG, "ble_store_config_our_secs restored %d bonds", ble_store_config_num_our_secs); + ESP_LOGD(TAG, "ble_store_config_our_secs restored %d bonds", ble_store_config_num_our_secs); err = populate_db_from_nvs(BLE_STORE_OBJ_TYPE_PEER_SEC, ble_store_config_peer_secs, &ble_store_config_num_peer_secs); if (err != ESP_OK) { - ESP_LOGE(LOG_TAG, "NVS operation failed for 'peer sec'"); + ESP_LOGE(TAG, "NVS operation failed for 'peer sec'"); return err; } @@ -606,7 +586,7 @@ ble_nvs_restore_sec_keys(void) ble_store_config_our_bond_count = ble_store_config_our_secs[ble_store_config_num_our_secs - 1].bond_count; ble_store_config_peer_bond_count = ble_store_config_peer_secs[ble_store_config_num_peer_secs - 1].bond_count; - ESP_LOGD(LOG_TAG, "ble_store_config_peer_secs restored %d bonds", + ESP_LOGD(TAG, "ble_store_config_peer_secs restored %d bonds", ble_store_config_num_peer_secs); #endif @@ -614,10 +594,10 @@ ble_nvs_restore_sec_keys(void) err = populate_db_from_nvs(BLE_STORE_OBJ_TYPE_CCCD, ble_store_config_cccds, &ble_store_config_num_cccds); if (err != ESP_OK) { - ESP_LOGE(LOG_TAG, "NVS operation failed for 'CCCD'"); + ESP_LOGE(TAG, "NVS operation failed for 'CCCD'"); return err; } - ESP_LOGD(LOG_TAG, "ble_store_config_cccds restored %d bonds", + ESP_LOGD(TAG, "ble_store_config_cccds restored %d bonds", ble_store_config_num_cccds); #endif @@ -625,10 +605,10 @@ ble_nvs_restore_sec_keys(void) err = populate_db_from_nvs(BLE_STORE_OBJ_TYPE_CSFC, ble_store_config_csfcs, &ble_store_config_num_csfcs); if (err != ESP_OK) { - ESP_LOGE(LOG_TAG, "NVS operation failed for 'CSFC'"); + ESP_LOGE(TAG, "NVS operation failed for 'CSFC'"); return err; } - ESP_LOGD(LOG_TAG, "ble_store_config_csfcs restored %d bonds", + ESP_LOGD(TAG, "ble_store_config_csfcs restored %d bonds", ble_store_config_num_csfcs); #endif @@ -636,28 +616,28 @@ ble_nvs_restore_sec_keys(void) err = populate_db_from_nvs(BLE_STORE_OBJ_TYPE_ENC_ADV_DATA, ble_store_config_eads, &ble_store_config_num_eads); if (err != ESP_OK) { - ESP_LOGE(LOG_TAG, "NVS operation failed for 'EAD'"); + ESP_LOGE(TAG, "NVS operation failed for 'EAD'"); return err; } - ESP_LOGD(LOG_TAG, "ble_store_config_eads restored %d bonds", + ESP_LOGD(TAG, "ble_store_config_eads restored %d bonds", ble_store_config_num_eads); #endif err = populate_db_from_nvs(BLE_STORE_OBJ_TYPE_LOCAL_IRK, ble_store_config_local_irks, &ble_store_config_num_local_irks); if (err != ESP_OK) { - ESP_LOGE(LOG_TAG, "NVS operation failed for 'Local IRK'"); + ESP_LOGE(TAG, "NVS operation failed for 'Local IRK'"); return err; } - ESP_LOGD(LOG_TAG, "ble_store_config_local_irks restored %d irks", + ESP_LOGD(TAG, "ble_store_config_local_irks restored %d irks", ble_store_config_num_local_irks); err = populate_db_from_nvs(BLE_STORE_OBJ_TYPE_PEER_ADDR, ble_store_config_rpa_recs, &ble_store_config_num_rpa_recs); if (err != ESP_OK) { - ESP_LOGE(LOG_TAG, "NVS operation failed for 'RPA_REC'"); + ESP_LOGE(TAG, "NVS operation failed for 'RPA_REC'"); return err; } - ESP_LOGD(LOG_TAG, "ble_store_config_rpa_recs restored %d bonds", + ESP_LOGD(TAG, "ble_store_config_rpa_recs restored %d bonds", ble_store_config_num_rpa_recs); return 0; @@ -674,12 +654,12 @@ ble_nvs_restore_peer_records(void) err = populate_db_from_nvs(BLE_STORE_OBJ_TYPE_PEER_DEV_REC, peer_dev_rec, &ble_store_num_peer_dev_rec); if (err != ESP_OK) { - ESP_LOGE(LOG_TAG, "NVS operation failed fetching 'Peer Dev Records'"); + ESP_LOGE(TAG, "NVS operation failed fetching 'Peer Dev Records'"); return err; } ble_rpa_set_num_peer_dev_records(ble_store_num_peer_dev_rec); - ESP_LOGD(LOG_TAG, "peer_dev_rec restored %d records", ble_store_num_peer_dev_rec); + ESP_LOGD(TAG, "peer_dev_rec restored %d records", ble_store_num_peer_dev_rec); return 0; } @@ -693,14 +673,14 @@ int ble_store_config_persist_cccds(void) nvs_count = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_CCCD, 0, NULL, 0); if (nvs_count == -1) { - ESP_LOGE(LOG_TAG, "NVS operation failed while persisting CCCD"); + ESP_LOGE(TAG, "NVS operation failed while persisting CCCD"); return BLE_HS_ESTORE_FAIL; } if (nvs_count < ble_store_config_num_cccds) { /* NVS db count less than RAM count, write operation */ - ESP_LOGD(LOG_TAG, "Persisting CCCD value in NVS..."); + ESP_LOGD(TAG, "Persisting CCCD value in NVS..."); val.cccd = ble_store_config_cccds[ble_store_config_num_cccds - 1]; return ble_store_nvs_write(BLE_STORE_OBJ_TYPE_CCCD, &val); } else if (nvs_count > ble_store_config_num_cccds) { @@ -708,10 +688,10 @@ int ble_store_config_persist_cccds(void) nvs_idx = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_CCCD, 0, ble_store_config_cccds, ble_store_config_num_cccds); if (nvs_idx == -1) { - ESP_LOGE(LOG_TAG, "NVS delete operation failed for CCCD"); + ESP_LOGE(TAG, "NVS delete operation failed for CCCD"); return BLE_HS_ESTORE_FAIL; } - ESP_LOGD(LOG_TAG, "Deleting CCCD, nvs idx = %d", nvs_idx); + ESP_LOGD(TAG, "Deleting CCCD, nvs idx = %d", nvs_idx); return ble_nvs_delete_value(BLE_STORE_OBJ_TYPE_CCCD, nvs_idx); } return 0; @@ -726,13 +706,13 @@ int ble_store_config_persist_csfcs(void) nvs_count = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_CSFC, 0, NULL, 0); if (nvs_count == -1) { - ESP_LOGE(LOG_TAG, "NVS operation failed while persisting CSFC"); + ESP_LOGE(TAG, "NVS operation failed while persisting CSFC"); return BLE_HS_ESTORE_FAIL; } if (nvs_count < ble_store_config_num_csfcs) { /* NVS db count less than RAM count, write operation */ - ESP_LOGD(LOG_TAG, "Persisting CSFC value in NVS..."); + ESP_LOGD(TAG, "Persisting CSFC value in NVS..."); val.csfc = ble_store_config_csfcs[ble_store_config_num_csfcs - 1]; return ble_store_nvs_write(BLE_STORE_OBJ_TYPE_CSFC, &val); } else if (nvs_count > ble_store_config_num_csfcs) { @@ -740,10 +720,10 @@ int ble_store_config_persist_csfcs(void) nvs_idx = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_CSFC, 0, ble_store_config_csfcs, ble_store_config_num_csfcs); if (nvs_idx == -1) { - ESP_LOGE(LOG_TAG, "NVS delete operation failed for CSFC"); + ESP_LOGE(TAG, "NVS delete operation failed for CSFC"); return BLE_HS_ESTORE_FAIL; } - ESP_LOGD(LOG_TAG, "Deleting CSFC, nvs idx = %d", nvs_idx); + ESP_LOGD(TAG, "Deleting CSFC, nvs idx = %d", nvs_idx); return ble_nvs_delete_value(BLE_STORE_OBJ_TYPE_CSFC, nvs_idx); } return 0; @@ -758,13 +738,13 @@ int ble_store_config_persist_eads(void) nvs_count = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_ENC_ADV_DATA, 0, NULL, 0); if (nvs_count == -1) { - ESP_LOGE(LOG_TAG, "NVS operation failed while persisting EAD"); + ESP_LOGE(TAG, "NVS operation failed while persisting EAD"); return BLE_HS_ESTORE_FAIL; } if (nvs_count < ble_store_config_num_eads) { /* NVS db count less than RAM count, write operation */ - ESP_LOGD(LOG_TAG, "Persisting EAD value in NVS..."); + ESP_LOGD(TAG, "Persisting EAD value in NVS..."); val.ead = ble_store_config_eads[ble_store_config_num_eads - 1]; return ble_store_nvs_write(BLE_STORE_OBJ_TYPE_ENC_ADV_DATA, &val); } else if (nvs_count > ble_store_config_num_eads) { @@ -772,10 +752,10 @@ int ble_store_config_persist_eads(void) nvs_idx = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_ENC_ADV_DATA, 0, ble_store_config_eads, ble_store_config_num_eads); if (nvs_idx == -1) { - ESP_LOGE(LOG_TAG, "NVS delete operation failed for EAD"); + ESP_LOGE(TAG, "NVS delete operation failed for EAD"); return BLE_HS_ESTORE_FAIL; } - ESP_LOGD(LOG_TAG, "Deleting EAD, nvs idx = %d", nvs_idx); + ESP_LOGD(TAG, "Deleting EAD, nvs idx = %d", nvs_idx); return ble_nvs_delete_value(BLE_STORE_OBJ_TYPE_ENC_ADV_DATA, nvs_idx); } return 0; @@ -788,13 +768,13 @@ int ble_store_config_persist_local_irk(void) nvs_count = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_LOCAL_IRK, 0, NULL, 0); if (nvs_count == -1) { - ESP_LOGE(LOG_TAG, "NVS operation failed while persisting EAD"); + ESP_LOGE(TAG, "NVS operation failed while persisting EAD"); return BLE_HS_ESTORE_FAIL; } if (nvs_count < ble_store_config_num_local_irks) { /* NVS db count less than RAM count, write operation */ - ESP_LOGD(LOG_TAG, "Persisting Local IRK value in NVS..."); + ESP_LOGD(TAG, "Persisting Local IRK value in NVS..."); val.local_irk = ble_store_config_local_irks[ble_store_config_num_local_irks-1]; return ble_store_nvs_write(BLE_STORE_OBJ_TYPE_LOCAL_IRK, &val); } else if (nvs_count > ble_store_config_num_local_irks) { @@ -802,10 +782,10 @@ int ble_store_config_persist_local_irk(void) nvs_idx = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_LOCAL_IRK, 0, ble_store_config_local_irks, ble_store_config_num_local_irks); if (nvs_idx == -1) { - ESP_LOGE(LOG_TAG, "NVS delete operation failed for Local IRK"); + ESP_LOGE(TAG, "NVS delete operation failed for Local IRK"); return BLE_HS_ESTORE_FAIL; } - ESP_LOGD(LOG_TAG, "Deleting Local IRK, nvs idx = %d", nvs_idx); + ESP_LOGD(TAG, "Deleting Local IRK, nvs idx = %d", nvs_idx); return ble_nvs_delete_value(BLE_STORE_OBJ_TYPE_LOCAL_IRK, nvs_idx); } return 0; @@ -817,12 +797,12 @@ int ble_store_config_persist_rpa_recs(void) union ble_store_value val; nvs_count = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_PEER_ADDR, 0, NULL, 0); if (nvs_count == -1) { - ESP_LOGE(LOG_TAG, "NVS operation failed while persisting RPA_RECS"); + ESP_LOGE(TAG, "NVS operation failed while persisting RPA_RECS"); return BLE_HS_ESTORE_FAIL; } if (nvs_count < ble_store_config_num_rpa_recs) { /* NVS db count less than RAM count, write operation */ - ESP_LOGD(LOG_TAG, "Persisting RPA_RECS value in NVS..."); + ESP_LOGD(TAG, "Persisting RPA_RECS value in NVS..."); val.rpa_rec = ble_store_config_rpa_recs[ble_store_config_num_rpa_recs - 1]; return ble_store_nvs_write(BLE_STORE_OBJ_TYPE_PEER_ADDR, &val); } else if (nvs_count > ble_store_config_num_rpa_recs) { @@ -830,10 +810,10 @@ int ble_store_config_persist_rpa_recs(void) nvs_idx = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_PEER_ADDR, 0, ble_store_config_rpa_recs, ble_store_config_num_rpa_recs); if (nvs_idx == -1) { - ESP_LOGE(LOG_TAG, "NVS delete operation failed for RPA_REC"); + ESP_LOGE(TAG, "NVS delete operation failed for RPA_REC"); return BLE_HS_ESTORE_FAIL; } - ESP_LOGD(LOG_TAG, "Deleting RPA_REC, nvs idx = %d", nvs_idx); + ESP_LOGD(TAG, "Deleting RPA_REC, nvs idx = %d", nvs_idx); return ble_nvs_delete_value(BLE_STORE_OBJ_TYPE_PEER_ADDR, nvs_idx); } return 0; @@ -847,14 +827,14 @@ int ble_store_config_persist_peer_secs(void) nvs_count = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_PEER_SEC, 0, NULL, 0); if (nvs_count == -1) { - ESP_LOGE(LOG_TAG, "NVS operation failed while persisting peer sec"); + ESP_LOGE(TAG, "NVS operation failed while persisting peer sec"); return BLE_HS_ESTORE_FAIL; } if (nvs_count < ble_store_config_num_peer_secs) { /* NVS db count less than RAM count, write operation */ - ESP_LOGD(LOG_TAG, "Persisting peer sec value in NVS..."); + ESP_LOGD(TAG, "Persisting peer sec value in NVS..."); val.sec = ble_store_config_peer_secs[ble_store_config_num_peer_secs - 1]; return ble_store_nvs_write(BLE_STORE_OBJ_TYPE_PEER_SEC, &val); } else if (nvs_count > ble_store_config_num_peer_secs) { @@ -862,10 +842,10 @@ int ble_store_config_persist_peer_secs(void) nvs_idx = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_PEER_SEC, 0, ble_store_config_peer_secs, ble_store_config_num_peer_secs); if (nvs_idx == -1) { - ESP_LOGE(LOG_TAG, "NVS delete operation failed for peer sec"); + ESP_LOGE(TAG, "NVS delete operation failed for peer sec"); return BLE_HS_ESTORE_FAIL; } - ESP_LOGD(LOG_TAG, "Deleting peer sec, nvs idx = %d", nvs_idx); + ESP_LOGD(TAG, "Deleting peer sec, nvs idx = %d", nvs_idx); return ble_nvs_delete_value(BLE_STORE_OBJ_TYPE_PEER_SEC, nvs_idx); } return 0; @@ -878,14 +858,14 @@ int ble_store_config_persist_our_secs(void) nvs_count = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_OUR_SEC, 0, NULL, 0); if (nvs_count == -1) { - ESP_LOGE(LOG_TAG, "NVS operation failed while persisting our sec"); + ESP_LOGE(TAG, "NVS operation failed while persisting our sec"); return BLE_HS_ESTORE_FAIL; } if (nvs_count < ble_store_config_num_our_secs) { /* NVS db count less than RAM count, write operation */ - ESP_LOGD(LOG_TAG, "Persisting our sec value to NVS..."); + ESP_LOGD(TAG, "Persisting our sec value to NVS..."); val.sec = ble_store_config_our_secs[ble_store_config_num_our_secs - 1]; return ble_store_nvs_write(BLE_STORE_OBJ_TYPE_OUR_SEC, &val); } else if (nvs_count > ble_store_config_num_our_secs) { @@ -893,10 +873,10 @@ int ble_store_config_persist_our_secs(void) nvs_idx = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_OUR_SEC, 0, ble_store_config_our_secs, ble_store_config_num_our_secs); if (nvs_idx == -1) { - ESP_LOGE(LOG_TAG, "NVS delete operation failed for our sec"); + ESP_LOGE(TAG, "NVS delete operation failed for our sec"); return BLE_HS_ESTORE_FAIL; } - ESP_LOGD(LOG_TAG, "Deleting our sec, nvs idx = %d", nvs_idx); + ESP_LOGD(TAG, "Deleting our sec, nvs idx = %d", nvs_idx); return ble_nvs_delete_value(BLE_STORE_OBJ_TYPE_OUR_SEC, nvs_idx); } return 0; @@ -912,14 +892,14 @@ int ble_store_persist_peer_records(void) nvs_count = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_PEER_DEV_REC, 0, NULL, 0); if (nvs_count == -1) { - ESP_LOGE(LOG_TAG, "NVS operation failed while persisting peer_dev_rec"); + ESP_LOGE(TAG, "NVS operation failed while persisting peer_dev_rec"); return BLE_HS_ESTORE_FAIL; } if (nvs_count < ble_store_num_peer_dev_rec) { /* NVS db count less than RAM count, write operation */ - ESP_LOGD(LOG_TAG, "Persisting peer dev record to NVS..."); + ESP_LOGD(TAG, "Persisting peer dev record to NVS..."); peer_rec = peer_dev_rec[ble_store_num_peer_dev_rec - 1]; return ble_store_nvs_peer_records(BLE_STORE_OBJ_TYPE_PEER_DEV_REC, &peer_rec); } else if (nvs_count > ble_store_num_peer_dev_rec) { @@ -928,10 +908,10 @@ int ble_store_persist_peer_records(void) peer_dev_rec, ble_store_num_peer_dev_rec); if (nvs_idx == -1) { - ESP_LOGE(LOG_TAG, "NVS delete operation failed for peer records"); + ESP_LOGE(TAG, "NVS delete operation failed for peer records"); return BLE_HS_ESTORE_FAIL; } - ESP_LOGD(LOG_TAG, "Deleting peer record, nvs idx = %d", nvs_idx); + ESP_LOGD(TAG, "Deleting peer record, nvs idx = %d", nvs_idx); return ble_nvs_delete_value(BLE_STORE_OBJ_TYPE_PEER_DEV_REC, nvs_idx); } return 0; @@ -944,12 +924,12 @@ void ble_store_config_conf_init(void) err = ble_nvs_restore_sec_keys(); if (err != 0) { - ESP_LOGE(LOG_TAG, "NVS operation failed, can't retrieve the bonding info"); + ESP_LOGE(TAG, "NVS operation failed, can't retrieve the bonding info"); } #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) err = ble_nvs_restore_peer_records(); if (err != 0) { - ESP_LOGE(LOG_TAG, "NVS operation failed, can't retrieve the peer records"); + ESP_LOGE(TAG, "NVS operation failed, can't retrieve the peer records"); } #endif } diff --git a/src/nimble/nimble/host/store/ram/include/store/ram/ble_store_ram.h b/src/nimble/nimble/host/store/ram/include/store/ram/ble_store_ram.h deleted file mode 100644 index 19372f171..000000000 --- a/src/nimble/nimble/host/store/ram/include/store/ram/ble_store_ram.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - -/* This package has been deprecated and you should - * use the store/config package. For a RAM-only BLE store, - * use store/config and set BLE_STORE_CONFIG_PERSIST to 0. - */ - -#ifndef H_BLE_STORE_RAM_ -#define H_BLE_STORE_RAM_ - -#ifdef __cplusplus -extern "C" { -#endif - -union ble_store_key; -union ble_store_value; - -int ble_store_ram_read(int obj_type, const union ble_store_key *key, - union ble_store_value *value); -int ble_store_ram_write(int obj_type, const union ble_store_value *val); -int ble_store_ram_delete(int obj_type, const union ble_store_key *key); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/nimble/nimble/host/store/ram/src/ble_store_ram.c b/src/nimble/nimble/host/store/ram/src/ble_store_ram.c deleted file mode 100644 index 56aed73c3..000000000 --- a/src/nimble/nimble/host/store/ram/src/ble_store_ram.c +++ /dev/null @@ -1,542 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - -/** - * This file implements a simple in-RAM key database for BLE host security - * material and CCCDs. As this database is only ble_store_ramd in RAM, its - * contents are lost when the application terminates. - */ - -/* This package has been deprecated and you should - * use the store/config package. For a RAM-only BLE store, - * use store/config and set BLE_STORE_CONFIG_PERSIST to 0. - */ - -#include -#include - -#include "nimble/porting/nimble/include/sysinit/sysinit.h" -#include "syscfg/syscfg.h" -#include "nimble/nimble/host/include/host/ble_hs.h" -#include "nimble/nimble/host/store/ram/include/store/ram/ble_store_ram.h" - -#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) -static struct ble_store_value_sec - ble_store_ram_our_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; -#endif - -static int ble_store_ram_num_our_secs; - -#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) -static struct ble_store_value_sec - ble_store_ram_peer_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; -#endif - -static int ble_store_ram_num_peer_secs; - -#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) -static struct ble_store_value_cccd - ble_store_ram_cccds[MYNEWT_VAL(BLE_STORE_MAX_CCCDS)]; -#endif - -static int ble_store_ram_num_cccds; - -/***************************************************************************** - * $sec * - *****************************************************************************/ - -#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) -static void -ble_store_ram_print_value_sec(const struct ble_store_value_sec *sec) -{ - if (sec->ltk_present) { - BLE_HS_LOG(DEBUG, "ediv=%u rand=%llu authenticated=%d ltk=", - sec->ediv, sec->rand_num, sec->authenticated); - ble_hs_log_flat_buf(sec->ltk, 16); - BLE_HS_LOG(DEBUG, " "); - } - if (sec->irk_present) { - BLE_HS_LOG(DEBUG, "irk="); - ble_hs_log_flat_buf(sec->irk, 16); - BLE_HS_LOG(DEBUG, " "); - } - if (sec->csrk_present) { - BLE_HS_LOG(DEBUG, "csrk="); - ble_hs_log_flat_buf(sec->csrk, 16); - BLE_HS_LOG(DEBUG, " "); - } - - BLE_HS_LOG(DEBUG, "\n"); -} -#endif - -static void -ble_store_ram_print_key_sec(const struct ble_store_key_sec *key_sec) -{ - if (ble_addr_cmp(&key_sec->peer_addr, BLE_ADDR_ANY)) { - BLE_HS_LOG(DEBUG, "peer_addr_type=%d peer_addr=", - key_sec->peer_addr.type); - ble_hs_log_flat_buf(key_sec->peer_addr.val, 6); - BLE_HS_LOG(DEBUG, " "); - } -} - -#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) -static int -ble_store_ram_find_sec(const struct ble_store_key_sec *key_sec, - const struct ble_store_value_sec *value_secs, - int num_value_secs) -{ - const struct ble_store_value_sec *cur; - int i; - - if (!ble_addr_cmp(&key_sec->peer_addr, BLE_ADDR_ANY)) { - if (key_sec->idx < num_value_secs) { - return key_sec->idx; - } - } else if (key_sec->idx == 0) { - for (i = 0; i < num_value_secs; i++) { - cur = &value_secs[i]; - - if (!ble_addr_cmp(&cur->peer_addr, &key_sec->peer_addr)) { - return i; - } - } - } - - return -1; -} -#endif - -static int -ble_store_ram_read_our_sec(const struct ble_store_key_sec *key_sec, - struct ble_store_value_sec *value_sec) -{ -#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) - int idx; - - idx = ble_store_ram_find_sec(key_sec, ble_store_ram_our_secs, - ble_store_ram_num_our_secs); - if (idx == -1) { - return BLE_HS_ENOENT; - } - - *value_sec = ble_store_ram_our_secs[idx]; - return 0; -#else - return BLE_HS_ENOENT; -#endif - -} - -static int -ble_store_ram_write_our_sec(const struct ble_store_value_sec *value_sec) -{ -#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) - struct ble_store_key_sec key_sec; - int idx; - - BLE_HS_LOG(DEBUG, "persisting our sec; "); - ble_store_ram_print_value_sec(value_sec); - - ble_store_key_from_value_sec(&key_sec, value_sec); - idx = ble_store_ram_find_sec(&key_sec, ble_store_ram_our_secs, - ble_store_ram_num_our_secs); - if (idx == -1) { - if (ble_store_ram_num_our_secs >= MYNEWT_VAL(BLE_STORE_MAX_BONDS)) { - BLE_HS_LOG(DEBUG, "error persisting our sec; too many entries " - "(%d)\n", ble_store_ram_num_our_secs); - return BLE_HS_ESTORE_CAP; - } - - idx = ble_store_ram_num_our_secs; - ble_store_ram_num_our_secs++; - } - - ble_store_ram_our_secs[idx] = *value_sec; - - return 0; -#else - return BLE_HS_ENOENT; -#endif - -} - -#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) -static int -ble_store_ram_delete_obj(void *values, int value_size, int idx, - int *num_values) -{ - uint8_t *dst; - uint8_t *src; - int move_count; - - (*num_values)--; - if (idx < *num_values) { - dst = values; - dst += idx * value_size; - src = dst + value_size; - - move_count = *num_values - idx; - memmove(dst, src, move_count); - } - - return 0; -} - -static int -ble_store_ram_delete_sec(const struct ble_store_key_sec *key_sec, - struct ble_store_value_sec *value_secs, - int *num_value_secs) -{ - int idx; - int rc; - - idx = ble_store_ram_find_sec(key_sec, value_secs, *num_value_secs); - if (idx == -1) { - return BLE_HS_ENOENT; - } - - rc = ble_store_ram_delete_obj(value_secs, sizeof *value_secs, idx, - num_value_secs); - if (rc != 0) { - return rc; - } - - return 0; -} -#endif - -static int -ble_store_ram_delete_our_sec(const struct ble_store_key_sec *key_sec) -{ -#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) - int rc; - - rc = ble_store_ram_delete_sec(key_sec, ble_store_ram_our_secs, - &ble_store_ram_num_our_secs); - if (rc != 0) { - return rc; - } - return 0; -#else - return BLE_HS_ENOENT; -#endif - -} - -static int -ble_store_ram_delete_peer_sec(const struct ble_store_key_sec *key_sec) -{ -#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) - int rc; - - rc = ble_store_ram_delete_sec(key_sec, ble_store_ram_peer_secs, - &ble_store_ram_num_peer_secs); - if (rc != 0) { - return rc; - } - return 0; -#else - return BLE_HS_ENOENT; -#endif - -} - -static int -ble_store_ram_read_peer_sec(const struct ble_store_key_sec *key_sec, - struct ble_store_value_sec *value_sec) -{ -#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) - int idx; - - idx = ble_store_ram_find_sec(key_sec, ble_store_ram_peer_secs, - ble_store_ram_num_peer_secs); - if (idx == -1) { - return BLE_HS_ENOENT; - } - - *value_sec = ble_store_ram_peer_secs[idx]; - return 0; -#else - return BLE_HS_ENOENT; -#endif - -} - -static int -ble_store_ram_write_peer_sec(const struct ble_store_value_sec *value_sec) -{ -#if MYNEWT_VAL(BLE_STORE_MAX_BONDS) - struct ble_store_key_sec key_sec; - int idx; - - BLE_HS_LOG(DEBUG, "persisting peer sec; "); - ble_store_ram_print_value_sec(value_sec); - - ble_store_key_from_value_sec(&key_sec, value_sec); - idx = ble_store_ram_find_sec(&key_sec, ble_store_ram_peer_secs, - ble_store_ram_num_peer_secs); - if (idx == -1) { - if (ble_store_ram_num_peer_secs >= MYNEWT_VAL(BLE_STORE_MAX_BONDS)) { - BLE_HS_LOG(DEBUG, "error persisting peer sec; too many entries " - "(%d)\n", ble_store_ram_num_peer_secs); - return BLE_HS_ESTORE_CAP; - } - - idx = ble_store_ram_num_peer_secs; - ble_store_ram_num_peer_secs++; - } - - ble_store_ram_peer_secs[idx] = *value_sec; - return 0; -#else - return BLE_HS_ENOENT; -#endif - -} - -/***************************************************************************** - * $cccd * - *****************************************************************************/ - -#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) -static int -ble_store_ram_find_cccd(const struct ble_store_key_cccd *key) -{ - struct ble_store_value_cccd *cccd; - int skipped; - int i; - - skipped = 0; - for (i = 0; i < ble_store_ram_num_cccds; i++) { - cccd = ble_store_ram_cccds + i; - - if (ble_addr_cmp(&key->peer_addr, BLE_ADDR_ANY)) { - if (ble_addr_cmp(&cccd->peer_addr, &key->peer_addr)) { - continue; - } - } - - if (key->chr_val_handle != 0) { - if (cccd->chr_val_handle != key->chr_val_handle) { - continue; - } - } - - if (key->idx > skipped) { - skipped++; - continue; - } - - return i; - } - - return -1; -} -#endif - -static int -ble_store_ram_delete_cccd(const struct ble_store_key_cccd *key_cccd) -{ -#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) - int idx; - int rc; - - idx = ble_store_ram_find_cccd(key_cccd); - if (idx == -1) { - return BLE_HS_ENOENT; - } - - rc = ble_store_ram_delete_obj(ble_store_ram_cccds, - sizeof *ble_store_ram_cccds, - idx, - &ble_store_ram_num_cccds); - if (rc != 0) { - return rc; - } - return 0; -#else - return BLE_HS_ENOENT; -#endif - -} - -static int -ble_store_ram_read_cccd(const struct ble_store_key_cccd *key_cccd, - struct ble_store_value_cccd *value_cccd) -{ -#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) - int idx; - - idx = ble_store_ram_find_cccd(key_cccd); - if (idx == -1) { - return BLE_HS_ENOENT; - } - - *value_cccd = ble_store_ram_cccds[idx]; - - return 0; -#else - return BLE_HS_ENOENT; -#endif -} - -static int -ble_store_ram_write_cccd(const struct ble_store_value_cccd *value_cccd) -{ -#if MYNEWT_VAL(BLE_STORE_MAX_CCCDS) - struct ble_store_key_cccd key_cccd; - int idx; - - ble_store_key_from_value_cccd(&key_cccd, value_cccd); - idx = ble_store_ram_find_cccd(&key_cccd); - if (idx == -1) { - if (ble_store_ram_num_cccds >= MYNEWT_VAL(BLE_STORE_MAX_CCCDS)) { - BLE_HS_LOG(DEBUG, "error persisting cccd; too many entries (%d)\n", - ble_store_ram_num_cccds); - return BLE_HS_ESTORE_CAP; - } - - idx = ble_store_ram_num_cccds; - ble_store_ram_num_cccds++; - } - - ble_store_ram_cccds[idx] = *value_cccd; - return 0; -#else - return BLE_HS_ENOENT; -#endif - -} - -/***************************************************************************** - * $api * - *****************************************************************************/ - -/** - * Searches the database for an object matching the specified criteria. - * - * @return 0 if a key was found; else BLE_HS_ENOENT. - */ -int -ble_store_ram_read(int obj_type, const union ble_store_key *key, - union ble_store_value *value) -{ - int rc; - - switch (obj_type) { - case BLE_STORE_OBJ_TYPE_PEER_SEC: - /* An encryption procedure (bonding) is being attempted. The nimble - * stack is asking us to look in our key database for a long-term key - * corresponding to the specified ediv and random number. - * - * Perform a key lookup and populate the context object with the - * result. The nimble stack will use this key if this function returns - * success. - */ - BLE_HS_LOG(DEBUG, "looking up peer sec; "); - ble_store_ram_print_key_sec(&key->sec); - BLE_HS_LOG(DEBUG, "\n"); - rc = ble_store_ram_read_peer_sec(&key->sec, &value->sec); - return rc; - - case BLE_STORE_OBJ_TYPE_OUR_SEC: - BLE_HS_LOG(DEBUG, "looking up our sec; "); - ble_store_ram_print_key_sec(&key->sec); - BLE_HS_LOG(DEBUG, "\n"); - rc = ble_store_ram_read_our_sec(&key->sec, &value->sec); - return rc; - - case BLE_STORE_OBJ_TYPE_CCCD: - rc = ble_store_ram_read_cccd(&key->cccd, &value->cccd); - return rc; - - default: - return BLE_HS_ENOTSUP; - } -} - -/** - * Adds the specified object to the database. - * - * @return 0 on success; BLE_HS_ESTORE_CAP if the database - * is full. - */ -int -ble_store_ram_write(int obj_type, const union ble_store_value *val) -{ - int rc; - - switch (obj_type) { - case BLE_STORE_OBJ_TYPE_PEER_SEC: - rc = ble_store_ram_write_peer_sec(&val->sec); - return rc; - - case BLE_STORE_OBJ_TYPE_OUR_SEC: - rc = ble_store_ram_write_our_sec(&val->sec); - return rc; - - case BLE_STORE_OBJ_TYPE_CCCD: - rc = ble_store_ram_write_cccd(&val->cccd); - return rc; - - default: - return BLE_HS_ENOTSUP; - } -} - -int -ble_store_ram_delete(int obj_type, const union ble_store_key *key) -{ - int rc; - - switch (obj_type) { - case BLE_STORE_OBJ_TYPE_PEER_SEC: - rc = ble_store_ram_delete_peer_sec(&key->sec); - return rc; - - case BLE_STORE_OBJ_TYPE_OUR_SEC: - rc = ble_store_ram_delete_our_sec(&key->sec); - return rc; - - case BLE_STORE_OBJ_TYPE_CCCD: - rc = ble_store_ram_delete_cccd(&key->cccd); - return rc; - - default: - return BLE_HS_ENOTSUP; - } -} - -void -ble_store_ram_init(void) -{ - /* Ensure this function only gets called by sysinit. */ - SYSINIT_ASSERT_ACTIVE(); - - ble_hs_cfg.store_read_cb = ble_store_ram_read; - ble_hs_cfg.store_write_cb = ble_store_ram_write; - ble_hs_cfg.store_delete_cb = ble_store_ram_delete; - - /* Re-initialize BSS values in case of unit tests. */ - ble_store_ram_num_our_secs = 0; - ble_store_ram_num_peer_secs = 0; - ble_store_ram_num_cccds = 0; -} diff --git a/src/nimble/nimble/include/nimble/hci_common.h b/src/nimble/nimble/include/nimble/hci_common.h index be7f9b942..e06585f9f 100644 --- a/src/nimble/nimble/include/nimble/hci_common.h +++ b/src/nimble/nimble/include/nimble/hci_common.h @@ -1724,7 +1724,7 @@ struct ble_hci_ev_hw_error { struct comp_pkt { uint16_t handle; uint16_t packets; -} __attribute__((packed));; +} __attribute__((packed)); struct ble_hci_ev_num_comp_pkts { uint8_t count; struct comp_pkt completed[0]; @@ -2380,6 +2380,8 @@ struct ble_hci_ev_le_subev_cs_test_end_complete { #define BLE_HCI_VER_BCS_5_4 (13) #define BLE_HCI_VER_BCS_6_0 (14) #define BLE_HCI_VER_BCS_6_1 (15) +#define BLE_HCI_VER_BCS_6_2 (16) +#define BLE_HCI_VER_BCS_6_3 (17) #define BLE_LMP_VER_BCS_1_0b (0) #define BLE_LMP_VER_BCS_1_1 (1) @@ -2397,6 +2399,8 @@ struct ble_hci_ev_le_subev_cs_test_end_complete { #define BLE_LMP_VER_BCS_5_4 (13) #define BLE_LMP_VER_BCS_6_0 (14) #define BLE_LMP_VER_BCS_6_1 (15) +#define BLE_LMP_VER_BCS_6_2 (16) +#define BLE_LMP_VER_BCS_6_3 (17) /* selected HCI and LMP version */ #if MYNEWT_VAL(BLE_VERSION) == 50 @@ -2420,6 +2424,12 @@ struct ble_hci_ev_le_subev_cs_test_end_complete { #elif MYNEWT_VAL(BLE_VERSION) == 61 #define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_6_1 #define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_6_1 +#elif MYNEWT_VAL(BLE_VERSION) == 62 +#define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_6_2 +#define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_6_2 +#elif MYNEWT_VAL(BLE_VERSION) == 63 +#define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_6_3 +#define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_6_3 #else #error Unsupported BLE_VERSION selected #endif @@ -2463,7 +2473,7 @@ struct hci_data_hdr #define BLE_HCI_ISO_PKT_STATUS_VALID 0x00 #define BLE_HCI_ISO_PKT_STATUS_INVALID 0x01 -#define BLE_HCI_ISO_PKT_STATUS_LOST 0x10 +#define BLE_HCI_ISO_PKT_STATUS_LOST 0x02 #define BLE_HCI_ISO_BIG_HANDLE_MIN 0x00 #define BLE_HCI_ISO_BIG_HANDLE_MAX 0xEF diff --git a/src/nimble/porting/nimble/src/nimble_port.c b/src/nimble/porting/nimble/src/nimble_port.c index 516ff0bda..3f0701dfc 100644 --- a/src/nimble/porting/nimble/src/nimble_port.c +++ b/src/nimble/porting/nimble/src/nimble_port.c @@ -316,6 +316,7 @@ nimble_port_init(void) os_msys_init(); #if NIMBLE_CFG_CONTROLLER + extern void ble_ll_init(void); ble_ll_init(); #endif diff --git a/src/nimconfig.h b/src/nimconfig.h index 387896a7c..79a6079f2 100644 --- a/src/nimconfig.h +++ b/src/nimconfig.h @@ -181,11 +181,6 @@ # define MYNEWT_VAL_BLE_USE_ESP_TIMER (CONFIG_BT_NIMBLE_USE_ESP_TIMER) -# ifdef CONFIG_BT_NIMBLE_EXT_ADV // Workaround for PlatformIO build flags causing redefinition warnings -# undef MYNEWT_VAL_BLE_EXT_ADV -# define MYNEWT_VAL_BLE_EXT_ADV (CONFIG_BT_NIMBLE_EXT_ADV) -# endif - # if CONFIG_IDF_TARGET_ESP32 && (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)) # define MYNEWT_VAL_BLE_HCI_VS (0) # endif diff --git a/src/syscfg/syscfg.h b/src/syscfg/syscfg.h index e5a511fea..8cabef923 100644 --- a/src/syscfg/syscfg.h +++ b/src/syscfg/syscfg.h @@ -1872,7 +1872,7 @@ #define MYNEWT_VAL_BLE_PHY_EXTENDED_TIFS (2) #endif -#define MYNEWT_VAL_BLE_LL_PHY MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_2M_PHY || MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CODED_PHY +#define MYNEWT_VAL_BLE_LL_PHY (MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_2M_PHY || MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CODED_PHY) /*espressif added configs*/