From 3ffa474c1fb404031fbb07b2a84a8e4f8674d797 Mon Sep 17 00:00:00 2001 From: Sumeet Singh Date: Wed, 31 Jan 2024 15:10:45 +0530 Subject: [PATCH] fix(nimble): message to be signed is corrected in signed write --- nimble/host/src/ble_att_clt.c | 25 ++++++++++++++++++------- nimble/host/src/ble_att_svr.c | 24 ++++++++++++++++-------- nimble/host/src/ble_gattc.c | 6 +++++- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/nimble/host/src/ble_att_clt.c b/nimble/host/src/ble_att_clt.c index 340d62f7c..d83137768 100644 --- a/nimble/host/src/ble_att_clt.c +++ b/nimble/host/src/ble_att_clt.c @@ -765,6 +765,7 @@ ble_att_clt_tx_signed_write_cmd(uint16_t conn_handle, uint16_t handle, uint8_t * struct os_mbuf *txom2; uint8_t cmac[16]; uint8_t *message = NULL; + uint8_t len; int rc; int i; @@ -781,27 +782,37 @@ ble_att_clt_tx_signed_write_cmd(uint16_t conn_handle, uint16_t handle, uint8_t * } cmd->handle = htole16(handle); - /* Message to be signed is message||sign_counter, + /* Message to be signed is opcode||handle||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); + len = BLE_ATT_SIGNED_WRITE_DATA_OFFSET + OS_MBUF_PKTLEN(txom) + sizeof(counter); + message = nimble_platform_mem_malloc(len); + + /** Copying opcode and handle */ + rc = os_mbuf_copydata(txom2, 0, BLE_ATT_SIGNED_WRITE_DATA_OFFSET, message); if (rc != 0) { goto err; } - memcpy(&message[OS_MBUF_PKTLEN(txom)], &counter, sizeof(counter)); + /** Copying message */ + rc = os_mbuf_copydata(txom, 0, OS_MBUF_PKTLEN(txom), &message[BLE_ATT_SIGNED_WRITE_DATA_OFFSET]); + if (rc != 0) { + goto err; + } + + /** Copying sign counter */ + memcpy(&message[BLE_ATT_SIGNED_WRITE_DATA_OFFSET + 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)); + swap_in_place(message, len); /* 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); + rc = ble_sm_alg_aes_cmac(csrk, message, len, cmac); if (rc != 0) { goto err; } diff --git a/nimble/host/src/ble_att_svr.c b/nimble/host/src/ble_att_svr.c index 65e9f0948..7ff3b5569 100644 --- a/nimble/host/src/ble_att_svr.c +++ b/nimble/host/src/ble_att_svr.c @@ -2366,7 +2366,9 @@ ble_att_svr_rx_signed_write(uint16_t conn_handle, struct os_mbuf **rxom) uint16_t handle; uint8_t sign[12]; uint8_t cmac[16]; + uint8_t csrk[16]; uint8_t *message = NULL; + uint16_t len; int rc; rc = ble_gap_conn_find(conn_handle, &desc); @@ -2396,9 +2398,6 @@ ble_att_svr_rx_signed_write(uint16_t conn_handle, struct os_mbuf **rxom) 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, @@ -2408,16 +2407,22 @@ ble_att_svr_rx_signed_write(uint16_t conn_handle, struct os_mbuf **rxom) 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)); + len = OS_MBUF_PKTLEN(*rxom) + sizeof(value_sec.sign_counter) + 1; + message = nimble_platform_mem_malloc(len); + + message[0] = BLE_ATT_OP_SIGNED_WRITE_CMD; + os_mbuf_copydata(*rxom, 0, OS_MBUF_PKTLEN(*rxom), &message[1]); + memcpy(&message[1 + 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)); + swap_in_place(message, len); + + /* Converting CSRK into little endian format */ + swap_buf(csrk, value_sec.csrk, 16); /* 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); + rc = ble_sm_alg_aes_cmac(csrk, message, len, cmac); if (rc != 0) { goto err; } @@ -2443,6 +2448,9 @@ ble_att_svr_rx_signed_write(uint16_t conn_handle, struct os_mbuf **rxom) goto err; } + /* Strip the request base from the front of the mbuf. */ + os_mbuf_adj(*rxom, sizeof(*req)); + rc = ble_att_svr_write_handle(conn_handle, handle, 0, rxom, &att_err); if (rc != 0) { goto err; diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index acac6b72d..6b157b969 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -3520,6 +3520,7 @@ ble_gattc_signed_write(uint16_t conn_handle, uint16_t attr_handle, struct ble_store_value_sec value_sec; struct ble_store_key_sec key_sec; struct ble_gap_conn_desc desc; + uint8_t csrk[16]; STATS_INC(ble_gattc_stats, signed_write); @@ -3547,8 +3548,11 @@ ble_gattc_signed_write(uint16_t conn_handle, uint16_t attr_handle, goto err; } + /* Converting the csrk to little endian */ + swap_buf(csrk, value_sec.csrk, 16); + rc = ble_att_clt_tx_signed_write_cmd(conn_handle, attr_handle, - value_sec.csrk, value_sec.sign_counter, txom); + csrk, value_sec.sign_counter, txom); if (rc != 0) { goto err; }