mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-08-12 21:17:57 +00:00
feat(nimble): signed write support
This commit is contained in:
committed by
Abhinav Kudnar
parent
5668e0c2f2
commit
4712c3c890
@@ -207,6 +207,7 @@ struct os_mbuf;
|
||||
|
||||
/** Write Command. */
|
||||
#define BLE_ATT_OP_WRITE_CMD 0x52
|
||||
#define BLE_ATT_OP_SIGNED_WRITE_CMD 0xD2
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
@@ -522,6 +522,21 @@ int ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle,
|
||||
int ble_gattc_write_no_rsp_flat(uint16_t conn_handle, uint16_t attr_handle,
|
||||
const void *data, uint16_t data_len);
|
||||
|
||||
/**
|
||||
* Initiates GATT procedure: Signed Write. This function consumes the
|
||||
* supplied mbuf regardless of the outcome.
|
||||
*
|
||||
* @param conn_handle The connection over which to execute the
|
||||
* procedure.
|
||||
* @param attr_handle The handle of the characteristic value to write
|
||||
* to.
|
||||
* @param txom The value to write to the characteristic.
|
||||
*
|
||||
* @return 0 on success; nonzero on failure.
|
||||
*/
|
||||
int ble_gattc_signed_write(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct os_mbuf * txom);
|
||||
|
||||
/**
|
||||
* Initiates GATT procedure: Write Characteristic Value. This function
|
||||
* consumes the supplied mbuf regardless of the outcome.
|
||||
|
||||
@@ -81,6 +81,7 @@ struct ble_store_value_sec {
|
||||
|
||||
uint8_t csrk[16];
|
||||
uint8_t csrk_present:1;
|
||||
uint32_t sign_counter;
|
||||
|
||||
unsigned authenticated:1;
|
||||
uint8_t sc:1;
|
||||
|
||||
@@ -71,6 +71,7 @@ static const struct ble_att_rx_dispatch_entry ble_att_rx_dispatch[] = {
|
||||
{ BLE_ATT_OP_INDICATE_RSP, ble_att_clt_rx_indicate },
|
||||
{ BLE_ATT_OP_READ_MULT_VAR_REQ, ble_att_svr_rx_read_mult_var },
|
||||
{ BLE_ATT_OP_WRITE_CMD, ble_att_svr_rx_write_no_rsp },
|
||||
{ BLE_ATT_OP_SIGNED_WRITE_CMD, ble_att_svr_rx_signed_write },
|
||||
};
|
||||
|
||||
#define BLE_ATT_RX_DISPATCH_SZ \
|
||||
|
||||
@@ -25,6 +25,11 @@
|
||||
#include "nimble/ble.h"
|
||||
#include "host/ble_uuid.h"
|
||||
#include "ble_hs_priv.h"
|
||||
#include "esp_nimble_mem.h"
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#if NIMBLE_BLE_CONNECT
|
||||
/*****************************************************************************
|
||||
@@ -748,6 +753,90 @@ ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_att_clt_tx_signed_write_cmd(uint16_t conn_handle, uint16_t handle, uint8_t *csrk,
|
||||
uint32_t counter, struct os_mbuf *txom)
|
||||
{
|
||||
#if !NIMBLE_BLE_ATT_CLT_SIGNED_WRITE
|
||||
return BLE_HS_ENOTSUP;
|
||||
#endif
|
||||
|
||||
struct ble_att_signed_write_cmd *cmd;
|
||||
struct os_mbuf *txom2;
|
||||
uint8_t cmac[16];
|
||||
uint8_t *message = NULL;
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
BLE_HS_LOG(DEBUG, "ble_att_clt_tx_signed_write_cmd(): ");
|
||||
for (i = 0; i < OS_MBUF_PKTLEN(txom); i++) {
|
||||
BLE_HS_LOG(DEBUG, "0x%02x", (OS_MBUF_DATA(txom, uint8_t *))[i]);
|
||||
}
|
||||
|
||||
cmd = ble_att_cmd_get(BLE_ATT_OP_SIGNED_WRITE_CMD,
|
||||
sizeof(*cmd), &txom2);
|
||||
if (cmd == NULL) {
|
||||
rc = BLE_HS_ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
cmd->handle = htole16(handle);
|
||||
|
||||
/* Message to be signed is message||sign_counter,
|
||||
* where || represents concatenation
|
||||
*/
|
||||
message = nimble_platform_mem_malloc(OS_MBUF_PKTLEN(txom) + sizeof(counter));
|
||||
rc = os_mbuf_copydata(txom, 0, OS_MBUF_PKTLEN(txom), message);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
memcpy(&message[OS_MBUF_PKTLEN(txom)], &counter, sizeof(counter));
|
||||
|
||||
/* ble_sm_alg_aes_cmac takes data in little-endian format,
|
||||
* so converting it to LE.
|
||||
*/
|
||||
swap_in_place(message, OS_MBUF_PKTLEN(txom) + sizeof(counter));
|
||||
|
||||
/* Getting the CMAC (Cipher-based Message Authentication Code)
|
||||
* for the message using our CSRK for this connection.
|
||||
*/
|
||||
memset(cmac, 0, sizeof cmac);
|
||||
rc = ble_sm_alg_aes_cmac(csrk, message,
|
||||
OS_MBUF_PKTLEN(txom) + sizeof(counter), cmac);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* After using the csrk to sign data,
|
||||
* the sign counter needs to be updated.
|
||||
*/
|
||||
rc = ble_sm_incr_our_sign_counter(conn_handle);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Converting cmac to little-endian */
|
||||
swap_in_place(cmac, sizeof(cmac));
|
||||
|
||||
/* Creating final signed message */
|
||||
rc = os_mbuf_append(txom, (void *)&counter, sizeof(counter));
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
rc = os_mbuf_copyinto(txom, OS_MBUF_PKTLEN(txom),
|
||||
cmac + (sizeof(cmac)/2), sizeof(cmac)/2);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if(message != NULL) nimble_platform_mem_free(message);
|
||||
os_mbuf_concat(txom2, txom);
|
||||
return ble_att_tx(conn_handle, txom2);
|
||||
err:
|
||||
if(message != NULL) nimble_platform_mem_free(message);
|
||||
os_mbuf_free_chain(txom2);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* $prepare write request *
|
||||
*****************************************************************************/
|
||||
|
||||
@@ -353,6 +353,20 @@ struct ble_att_write_cmd {
|
||||
uint8_t value[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/**
|
||||
* | Parameter | Size (octets) |
|
||||
* +------------------------------------+-------------------+
|
||||
* | Attribute Opcode | 1 |
|
||||
* | Attribute Handle | 2 |
|
||||
* | Attribute Value | 0 to (ATT_MTU-15) |
|
||||
* | Authentication Signature | 12 |
|
||||
*/
|
||||
#define BLE_ATT_SIGNED_WRITE_CMD_BASE_SZ 15
|
||||
#define BLE_ATT_SIGNED_WRITE_DATA_OFFSET 3
|
||||
struct ble_att_signed_write_cmd {
|
||||
uint16_t handle;
|
||||
} __attribute__((packed));
|
||||
|
||||
void ble_att_error_rsp_parse(const void *payload, int len,
|
||||
struct ble_att_error_rsp *rsp);
|
||||
void ble_att_error_rsp_write(void *payload, int len,
|
||||
|
||||
@@ -212,6 +212,7 @@ int ble_att_svr_rx_read_mult(uint16_t conn_handle,
|
||||
int ble_att_svr_rx_write(uint16_t conn_handle,
|
||||
struct os_mbuf **rxom);
|
||||
int ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom);
|
||||
int ble_att_svr_rx_signed_write(uint16_t conn_handle, struct os_mbuf **rxom);
|
||||
int ble_att_svr_rx_prep_write(uint16_t conn_handle,
|
||||
struct os_mbuf **rxom);
|
||||
int ble_att_svr_rx_exec_write(uint16_t conn_handle,
|
||||
@@ -298,6 +299,9 @@ int ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t handle,
|
||||
uint16_t offset, struct os_mbuf *txom);
|
||||
int ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom);
|
||||
int ble_att_clt_tx_exec_write(uint16_t conn_handle, uint8_t flags);
|
||||
int ble_att_clt_tx_signed_write_cmd(uint16_t conn_handle, uint16_t handle,
|
||||
uint8_t * csrk, uint32_t counter,
|
||||
struct os_mbuf * txom);
|
||||
int ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom);
|
||||
int ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom);
|
||||
int ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle,
|
||||
|
||||
@@ -2348,6 +2348,111 @@ ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom)
|
||||
return ble_att_svr_write_handle(conn_handle, handle, 0, rxom, &att_err);
|
||||
}
|
||||
|
||||
int
|
||||
ble_att_svr_rx_signed_write(uint16_t conn_handle, struct os_mbuf **rxom)
|
||||
{
|
||||
#if !MYNEWT_VAL(BLE_ATT_SVR_SIGNED_WRITE)
|
||||
return BLE_HS_ENOTSUP;
|
||||
#endif
|
||||
|
||||
struct ble_att_signed_write_cmd *req;
|
||||
struct ble_store_value_sec value_sec;
|
||||
struct ble_store_key_sec key_sec;
|
||||
struct ble_gap_conn_desc desc;
|
||||
uint8_t att_err;
|
||||
uint16_t handle;
|
||||
uint8_t sign[12];
|
||||
uint8_t cmac[16];
|
||||
uint8_t *message = NULL;
|
||||
int rc;
|
||||
|
||||
rc = ble_gap_conn_find(conn_handle, &desc);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
memset(&key_sec, 0, sizeof key_sec);
|
||||
key_sec.peer_addr = desc.peer_id_addr;
|
||||
|
||||
/* Getting the CSRK for authentication */
|
||||
rc = ble_store_read_peer_sec(&key_sec, &value_sec);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
if (value_sec.csrk_present != 1) {
|
||||
rc = BLE_HS_EAUTHEN;
|
||||
goto err;
|
||||
}
|
||||
|
||||
rc = ble_att_svr_pullup_req_base(rxom, sizeof(*req), &att_err);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
req = (struct ble_att_signed_write_cmd *)(*rxom)->om_data;
|
||||
|
||||
handle = le16toh(req->handle);
|
||||
|
||||
/* Strip the request base from the front of the mbuf. */
|
||||
os_mbuf_adj(*rxom, sizeof(*req));
|
||||
|
||||
os_mbuf_copydata(*rxom,
|
||||
OS_MBUF_PKTLEN(*rxom) - (BLE_ATT_SIGNED_WRITE_CMD_BASE_SZ - BLE_ATT_SIGNED_WRITE_DATA_OFFSET),
|
||||
BLE_ATT_SIGNED_WRITE_CMD_BASE_SZ - BLE_ATT_SIGNED_WRITE_DATA_OFFSET,
|
||||
sign);
|
||||
|
||||
/* Strip the signature from the end of the mbuf. */
|
||||
os_mbuf_adj(*rxom, -(BLE_ATT_SIGNED_WRITE_CMD_BASE_SZ - BLE_ATT_SIGNED_WRITE_DATA_OFFSET));
|
||||
|
||||
/* Authentication procedure */
|
||||
message = nimble_platform_mem_malloc(OS_MBUF_PKTLEN(*rxom) + sizeof(value_sec.sign_counter));
|
||||
os_mbuf_copydata(*rxom, 0, OS_MBUF_PKTLEN(*rxom), message);
|
||||
memcpy(&message[OS_MBUF_PKTLEN(*rxom)], &value_sec.sign_counter, sizeof(value_sec.sign_counter));
|
||||
|
||||
/* Converting message into little endian format */
|
||||
swap_in_place(message, OS_MBUF_PKTLEN(*rxom) + sizeof(value_sec.sign_counter));
|
||||
|
||||
/* Using AES-CMAC to get the CMAC from the message and CSRK of this device */
|
||||
memset(cmac, 0, sizeof cmac);
|
||||
rc = ble_sm_alg_aes_cmac(value_sec.csrk, message, OS_MBUF_PKTLEN(*rxom) + sizeof(value_sec.sign_counter), cmac);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Converting cmac to little endian */
|
||||
swap_in_place(cmac, sizeof cmac);
|
||||
|
||||
/* Comparing sign counter */
|
||||
if(memcmp(sign, &value_sec.sign_counter, sizeof(value_sec.sign_counter)) != 0) {
|
||||
rc = BLE_HS_EAUTHEN;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Comparing signature */
|
||||
if(memcmp(&sign[sizeof(value_sec.sign_counter)], &cmac[sizeof(cmac) / 2], sizeof(cmac) / 2) != 0) {
|
||||
rc = BLE_HS_EAUTHEN;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Signature matches, increment sign counter and pass the data to the upper layer */
|
||||
rc = ble_sm_incr_peer_sign_counter(conn_handle);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
rc = ble_att_svr_write_handle(conn_handle, handle, 0, rxom, &att_err);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if(message != NULL) nimble_platform_mem_free(message);
|
||||
return 0;
|
||||
err:
|
||||
if(message != NULL) nimble_platform_mem_free(message);
|
||||
ble_gap_terminate(conn_handle, BLE_ERR_AUTH_FAIL);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ble_att_svr_write_local(uint16_t attr_handle, struct os_mbuf *om)
|
||||
{
|
||||
@@ -3026,7 +3131,7 @@ ble_att_svr_reset(void)
|
||||
}
|
||||
|
||||
ble_att_svr_id = 0;
|
||||
|
||||
|
||||
/* Note: prep entries do not get freed here because it is assumed there are
|
||||
* no established connections.
|
||||
*/
|
||||
|
||||
@@ -56,6 +56,8 @@ STATS_SECT_START(ble_gattc_stats)
|
||||
STATS_SECT_ENTRY(read_long_fail)
|
||||
STATS_SECT_ENTRY(read_mult)
|
||||
STATS_SECT_ENTRY(read_mult_fail)
|
||||
STATS_SECT_ENTRY(signed_write)
|
||||
STATS_SECT_ENTRY(signed_write_fail)
|
||||
STATS_SECT_ENTRY(write_no_rsp)
|
||||
STATS_SECT_ENTRY(write_no_rsp_fail)
|
||||
STATS_SECT_ENTRY(write)
|
||||
|
||||
@@ -457,6 +457,8 @@ STATS_NAME_START(ble_gattc_stats)
|
||||
STATS_NAME(ble_gattc_stats, read_long_fail)
|
||||
STATS_NAME(ble_gattc_stats, read_mult)
|
||||
STATS_NAME(ble_gattc_stats, read_mult_fail)
|
||||
STATS_NAME(ble_gattc_stats, signed_write)
|
||||
STATS_NAME(ble_gattc_stats, signed_write_fail)
|
||||
STATS_NAME(ble_gattc_stats, write_no_rsp)
|
||||
STATS_NAME(ble_gattc_stats, write_no_rsp_fail)
|
||||
STATS_NAME(ble_gattc_stats, write)
|
||||
@@ -611,6 +613,13 @@ ble_gattc_log_write(uint16_t att_handle, uint16_t len, int expecting_rsp)
|
||||
BLE_HS_LOG(INFO, "att_handle=%d len=%d\n", att_handle, len);
|
||||
}
|
||||
|
||||
static void
|
||||
ble_gattc_log_signed_write(uint16_t att_handle, uint16_t len)
|
||||
{
|
||||
ble_gattc_log_proc_init("signed write; ");
|
||||
BLE_HS_LOG(INFO, "att_handle=%d len=%d\n", att_handle, len);
|
||||
}
|
||||
|
||||
static void
|
||||
ble_gattc_log_write_long(struct ble_gattc_proc *proc)
|
||||
{
|
||||
@@ -3495,6 +3504,62 @@ ble_gattc_write_no_rsp_flat(uint16_t conn_handle, uint16_t attr_handle,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* $signed write *
|
||||
****************************************************************************/
|
||||
|
||||
int
|
||||
ble_gattc_signed_write(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct os_mbuf *txom)
|
||||
{
|
||||
#if !MYNEWT_VAL(BLE_GATT_SIGNED_WRITE)
|
||||
return BLE_HS_ENOTSUP;
|
||||
#endif
|
||||
|
||||
int rc;
|
||||
struct ble_store_value_sec value_sec;
|
||||
struct ble_store_key_sec key_sec;
|
||||
struct ble_gap_conn_desc desc;
|
||||
|
||||
STATS_INC(ble_gattc_stats, signed_write);
|
||||
|
||||
ble_gattc_log_signed_write(attr_handle, OS_MBUF_PKTLEN(txom));
|
||||
|
||||
rc = ble_gap_conn_find(conn_handle, &desc);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
if (desc.sec_state.encrypted == 1) {
|
||||
rc = BLE_HS_EENCRYPT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
memset(&key_sec, 0, sizeof key_sec);
|
||||
key_sec.peer_addr = desc.peer_id_addr;
|
||||
|
||||
/* Getting the CSRK for signing */
|
||||
rc = ble_store_read_our_sec(&key_sec, &value_sec);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
if (value_sec.csrk_present != 1) {
|
||||
rc = BLE_HS_EAUTHEN;
|
||||
goto err;
|
||||
}
|
||||
|
||||
rc = ble_att_clt_tx_signed_write_cmd(conn_handle, attr_handle,
|
||||
value_sec.csrk, value_sec.sign_counter, txom);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
STATS_INC(ble_gattc_stats, signed_write_fail);
|
||||
os_mbuf_free_chain(txom);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* $write *
|
||||
*****************************************************************************/
|
||||
|
||||
@@ -492,6 +492,7 @@ ble_sm_fill_store_value(const ble_addr_t *peer_addr,
|
||||
|
||||
if (keys->csrk_valid) {
|
||||
memcpy(value_sec->csrk, keys->csrk, sizeof value_sec->csrk);
|
||||
value_sec->sign_counter = keys->sign_counter;
|
||||
value_sec->csrk_present = 1;
|
||||
}
|
||||
}
|
||||
@@ -2331,6 +2332,8 @@ ble_sm_key_exch_exec(struct ble_sm_proc *proc, struct ble_sm_result *res,
|
||||
memcpy(sign_info->sig_key, proc->our_keys.csrk, 16);
|
||||
}
|
||||
proc->our_keys.csrk_valid = 1;
|
||||
proc->our_keys.sign_counter = 0;
|
||||
memcpy(proc->our_keys.csrk, sign_info->sig_key, 16);
|
||||
|
||||
rc = ble_sm_tx(proc->conn_handle, txom);
|
||||
if (rc != 0) {
|
||||
@@ -2532,6 +2535,7 @@ ble_sm_sign_info_rx(uint16_t conn_handle, struct os_mbuf **om,
|
||||
|
||||
memcpy(proc->peer_keys.csrk, cmd->sig_key, 16);
|
||||
proc->peer_keys.csrk_valid = 1;
|
||||
proc->peer_keys.sign_counter = 0;
|
||||
|
||||
ble_sm_key_rxed(proc, res);
|
||||
}
|
||||
@@ -2564,6 +2568,106 @@ ble_sm_fail_rx(uint16_t conn_handle, struct os_mbuf **om,
|
||||
* $api *
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* API to be used to increment the sign-counter whenever the CSRK is used
|
||||
* to sign a message.
|
||||
*
|
||||
* @param conn_handle The connection_handle of the peer to whom
|
||||
* the signed message is sent, and with
|
||||
* whom the CSRK was shared that was used
|
||||
* to sign the message.
|
||||
*/
|
||||
int
|
||||
ble_sm_incr_our_sign_counter(uint16_t conn_handle)
|
||||
{
|
||||
struct ble_store_key_sec key_sec;
|
||||
struct ble_store_value_sec value_sec;
|
||||
struct ble_gap_conn_desc desc;
|
||||
int rc;
|
||||
|
||||
rc = ble_gap_conn_find(conn_handle, &desc);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
memset(&key_sec, 0, sizeof key_sec);
|
||||
key_sec.peer_addr = desc.peer_id_addr;
|
||||
|
||||
rc = ble_store_read_our_sec(&key_sec, &value_sec);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
if (value_sec.csrk_present != 1) {
|
||||
return BLE_HS_ENOENT;
|
||||
}
|
||||
if (value_sec.sign_counter == (uint32_t)0xffffffff) {
|
||||
return BLE_HS_ENOMEM;
|
||||
}
|
||||
|
||||
rc = ble_store_delete_our_sec(&key_sec);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
value_sec.sign_counter += 1;
|
||||
rc = ble_store_write_our_sec(&value_sec);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* API to be used to increment the sign-counter whenever the CSRK is used
|
||||
* to authenticate a received signed message.
|
||||
*
|
||||
* @param conn_handle The connection_handle of the peer from whom
|
||||
* the signed message is received, and with
|
||||
* whom the CSRK was shared that was used
|
||||
* to authenticate the signed message.
|
||||
*/
|
||||
int
|
||||
ble_sm_incr_peer_sign_counter(uint16_t conn_handle)
|
||||
{
|
||||
struct ble_store_key_sec key_sec;
|
||||
struct ble_store_value_sec value_sec;
|
||||
struct ble_gap_conn_desc desc;
|
||||
int rc;
|
||||
|
||||
rc = ble_gap_conn_find(conn_handle, &desc);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
memset(&key_sec, 0, sizeof key_sec);
|
||||
key_sec.peer_addr = desc.peer_id_addr;
|
||||
|
||||
rc = ble_store_read_peer_sec(&key_sec, &value_sec);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
if (value_sec.csrk_present != 1) {
|
||||
return BLE_HS_ENOENT;
|
||||
}
|
||||
if (value_sec.sign_counter == (uint32_t)0xffffffff) {
|
||||
return BLE_HS_ENOMEM;
|
||||
}
|
||||
|
||||
rc = ble_store_delete_peer_sec(&key_sec);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
value_sec.sign_counter += 1;
|
||||
rc = ble_store_write_peer_sec(&value_sec);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Times out expired SM procedures.
|
||||
*
|
||||
|
||||
@@ -234,6 +234,7 @@ struct ble_sm_keys {
|
||||
unsigned irk_valid:1;
|
||||
unsigned csrk_valid:1;
|
||||
unsigned addr_valid:1;
|
||||
uint32_t sign_counter;
|
||||
uint16_t ediv;
|
||||
uint64_t rand_val;
|
||||
uint8_t addr_type;
|
||||
@@ -391,6 +392,10 @@ void ble_sm_ia_ra(struct ble_sm_proc *proc,
|
||||
uint8_t *out_iat, uint8_t *out_ia,
|
||||
uint8_t *out_rat, uint8_t *out_ra);
|
||||
|
||||
int ble_sm_incr_our_sign_counter(uint16_t conn_handle);
|
||||
int ble_sm_incr_peer_sign_counter(uint16_t conn_handle);
|
||||
int ble_sm_alg_aes_cmac(const uint8_t *key, const uint8_t *in, size_t len,
|
||||
uint8_t *out);
|
||||
int32_t ble_sm_timer(void);
|
||||
void ble_sm_connection_broken(uint16_t conn_handle);
|
||||
int ble_sm_pair_initiate(uint16_t conn_handle);
|
||||
@@ -403,6 +408,9 @@ int ble_sm_alg_encrypt(const uint8_t *key, const uint8_t *plaintext,
|
||||
int ble_sm_init(void);
|
||||
#else
|
||||
|
||||
#define ble_sm_incr_our_sign_counter(conn_handle) BLE_HS_ENOTSUP
|
||||
#define ble_sm_incr_peer_sign_counter(conn_handle) BLE_HS_ENOTSUP
|
||||
#define ble_sm_alg_aes_cmac(key, in, len, out) BLE_HS_ENOTSUP
|
||||
#define ble_sm_enc_change_rx(evt) ((void)(evt))
|
||||
#define ble_sm_ltk_req_rx(evt) ((void)(evt))
|
||||
#define ble_sm_enc_key_refresh_rx(evt) ((void)(evt))
|
||||
|
||||
@@ -84,7 +84,7 @@ ble_store_config_print_value_sec(const struct ble_store_value_sec *sec)
|
||||
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, " sign_counter = %u", sec->sign_counter);
|
||||
}
|
||||
|
||||
BLE_HS_LOG(DEBUG, "\n");
|
||||
|
||||
@@ -81,6 +81,10 @@ extern "C" {
|
||||
#define NIMBLE_BLE_ATT_CLT_READ_GROUP_TYPE \
|
||||
(MYNEWT_VAL(BLE_GATT_DISC_ALL_SVCS))
|
||||
|
||||
#undef NIMBLE_BLE_ATT_CLT_SIGNED_WRITE
|
||||
#define NIMBLE_BLE_ATT_CLT_SIGNED_WRITE \
|
||||
(MYNEWT_VAL(BLE_GATT_SIGNED_WRITE))
|
||||
|
||||
#undef NIMBLE_BLE_ATT_CLT_WRITE
|
||||
#define NIMBLE_BLE_ATT_CLT_WRITE \
|
||||
(MYNEWT_VAL(BLE_GATT_WRITE))
|
||||
|
||||
Reference in New Issue
Block a user