|
28 | 28 | #define BLE_GATTS_INCLUDE_SZ 6
|
29 | 29 | #define BLE_GATTS_CHR_MAX_SZ 19
|
30 | 30 |
|
| 31 | +#if NIMBLE_BLE_SM |
| 32 | +#include "tinycrypt/aes.h" |
| 33 | +#include "tinycrypt/constants.h" |
| 34 | +#include "tinycrypt/utils.h" |
| 35 | + |
| 36 | +#if MYNEWT_VAL(BLE_SM_SC) |
| 37 | +#include "tinycrypt/cmac_mode.h" |
| 38 | +#include "tinycrypt/ecc_dh.h" |
| 39 | +#endif |
| 40 | +#endif |
| 41 | + |
31 | 42 | static const ble_uuid_t *uuid_pri =
|
32 | 43 | BLE_UUID16_DECLARE(BLE_ATT_UUID_PRIMARY_SERVICE);
|
33 | 44 | static const ble_uuid_t *uuid_sec =
|
@@ -1719,6 +1730,8 @@ ble_gatts_bonding_restored(uint16_t conn_handle)
|
1719 | 1730 | {
|
1720 | 1731 | struct ble_store_value_cccd cccd_value;
|
1721 | 1732 | struct ble_store_key_cccd cccd_key;
|
| 1733 | + struct ble_store_value_hash hash_value; |
| 1734 | + struct ble_store_key_hash hash_key; |
1722 | 1735 | struct ble_gatts_clt_cfg *clt_cfg;
|
1723 | 1736 | struct ble_hs_conn *conn;
|
1724 | 1737 | uint8_t att_op;
|
@@ -1799,6 +1812,13 @@ ble_gatts_bonding_restored(uint16_t conn_handle)
|
1799 | 1812 |
|
1800 | 1813 | cccd_key.idx++;
|
1801 | 1814 | }
|
| 1815 | + |
| 1816 | + hash_key.peer_addr = conn->bhc_peer_addr; |
| 1817 | + hash_key.peer_addr.type = |
| 1818 | + ble_hs_misc_peer_addr_type_to_id(conn->bhc_peer_addr.type); |
| 1819 | + hash_key.idx = 0; |
| 1820 | + |
| 1821 | + rc = ble_store_read_hash(conn_handle, &hash_key, &hash_value); // read peer hash, read the database hash characteristic and compare, if rc != 0 => ble_svc_conn_gatt_changed(0, 0xffff) |
1802 | 1822 | }
|
1803 | 1823 |
|
1804 | 1824 | static struct ble_gatts_svc_entry *
|
@@ -2182,3 +2202,107 @@ ble_gatts_init(void)
|
2182 | 2202 | return 0;
|
2183 | 2203 |
|
2184 | 2204 | }
|
| 2205 | + |
| 2206 | +static void ble_db_hash_message_append_u16(uint16_t val, uint8_t *buf, uint8_t *len) { |
| 2207 | + val = htole16(val); |
| 2208 | + memcpy(buf + *len, &val, sizeof(uint16_t)); |
| 2209 | + *len += sizeof(uint16_t); |
| 2210 | +} |
| 2211 | + |
| 2212 | +static void ble_db_hash_message_append_u32(uint32_t val, uint8_t *buf, uint8_t *len) { |
| 2213 | + val = htole32(val); |
| 2214 | + memcpy(buf + *len, &val, sizeof(uint32_t)); |
| 2215 | + *len += sizeof(uint32_t); |
| 2216 | +} |
| 2217 | + |
| 2218 | +static void ble_db_hash_message_append_uuid(const ble_uuid_t *uuid, uint8_t *buf, uint8_t *len) { |
| 2219 | + switch (uuid->type) { |
| 2220 | + case BLE_UUID_TYPE_16: { |
| 2221 | + ble_db_hash_message_append_u16( BLE_UUID16(uuid)->value, buf, len); |
| 2222 | + break; |
| 2223 | + } |
| 2224 | + case BLE_UUID_TYPE_32: { |
| 2225 | + ble_db_hash_message_append_u32(BLE_UUID32(uuid)->value, buf, len); |
| 2226 | + break; |
| 2227 | + } |
| 2228 | + case BLE_UUID_TYPE_128: { |
| 2229 | + memcpy(buf + *len, BLE_UUID128(uuid)->value, 16); |
| 2230 | + *len += 16; |
| 2231 | + break; |
| 2232 | + } |
| 2233 | + default: |
| 2234 | + break; |
| 2235 | + } |
| 2236 | +} |
| 2237 | + |
| 2238 | +/** |
| 2239 | + * Called when the database cmac hash needs to be computed using the information |
| 2240 | + * from registered services, characteristics and descriptors. This |
| 2241 | + * function: |
| 2242 | + * o Sets up the cmac generator with a key of 0s |
| 2243 | + * o Parse services, characteristics and descriptors and adds information |
| 2244 | + * to the message to code. |
| 2245 | + * o Computes the cmac coded message. |
| 2246 | + */ |
| 2247 | +int ble_compute_db_hash(uint8_t db_hash[16]) |
| 2248 | +{ |
| 2249 | + uint8_t buf[24]; |
| 2250 | + uint8_t buf_len; |
| 2251 | + |
| 2252 | + struct tc_aes_key_sched_struct sched; |
| 2253 | + struct tc_cmac_struct state; |
| 2254 | + const uint8_t key[16] = {0}; |
| 2255 | + |
| 2256 | + if (tc_cmac_setup(&state, key, &sched) == TC_CRYPTO_FAIL) { |
| 2257 | + return BLE_HS_EUNKNOWN; |
| 2258 | + } |
| 2259 | + |
| 2260 | + for (int i = 0; i < ble_gatts_num_svc_entries; i++) { |
| 2261 | + struct ble_gatts_svc_entry *entry = &ble_gatts_svc_entries[i]; |
| 2262 | + buf_len = 0; |
| 2263 | + ble_db_hash_message_append_u16(entry->handle, buf, &buf_len); |
| 2264 | + ble_db_hash_message_append_u16(BLE_ATT_UUID_PRIMARY_SERVICE, buf, &buf_len); |
| 2265 | + ble_db_hash_message_append_uuid(entry->svc->uuid, buf, &buf_len); |
| 2266 | + |
| 2267 | + if (tc_cmac_update(&state, buf, buf_len) == TC_CRYPTO_FAIL) { |
| 2268 | + return BLE_HS_EUNKNOWN; |
| 2269 | + } |
| 2270 | + buf_len = 0; |
| 2271 | + |
| 2272 | + if (entry->svc->characteristics != NULL) { |
| 2273 | + for (const struct ble_gatt_chr_def *chr = entry->svc->characteristics; chr && chr->uuid; chr++) { |
| 2274 | + if (chr->val_handle == NULL) { |
| 2275 | + continue; |
| 2276 | + } |
| 2277 | + ble_db_hash_message_append_u16(*chr->val_handle - 1, buf, &buf_len); |
| 2278 | + ble_db_hash_message_append_u16(BLE_ATT_UUID_CHARACTERISTIC, buf, &buf_len); |
| 2279 | + ble_db_hash_message_append_u16(chr->flags, buf, &buf_len); |
| 2280 | + ble_db_hash_message_append_u16(*chr->val_handle, buf, &buf_len); |
| 2281 | + ble_db_hash_message_append_uuid(chr->uuid, buf, &buf_len); |
| 2282 | + |
| 2283 | + if (tc_cmac_update(&state, buf, buf_len) == TC_CRYPTO_FAIL) { |
| 2284 | + return BLE_HS_EUNKNOWN; |
| 2285 | + } |
| 2286 | + buf_len = 0; |
| 2287 | + |
| 2288 | + if (chr->descriptors != NULL) { |
| 2289 | + for (struct ble_gatt_dsc_def *dsc = chr->descriptors; dsc && dsc->uuid; dsc++) { |
| 2290 | + ble_db_hash_message_append_u16(*chr->val_handle + 1, buf, &buf_len); |
| 2291 | + ble_db_hash_message_append_u16(BLE_ATT_UUID_DESCRIPTOR, buf, &buf_len); |
| 2292 | + |
| 2293 | + if (tc_cmac_update(&state, buf, buf_len) == TC_CRYPTO_FAIL) { |
| 2294 | + return BLE_HS_EUNKNOWN; |
| 2295 | + } |
| 2296 | + buf_len = 0; |
| 2297 | + } |
| 2298 | + } |
| 2299 | + } |
| 2300 | + } |
| 2301 | + } |
| 2302 | + |
| 2303 | + if (tc_cmac_final(db_hash, &state) == TC_CRYPTO_FAIL) { |
| 2304 | + return BLE_HS_EUNKNOWN; |
| 2305 | + } |
| 2306 | + |
| 2307 | + return 0; |
| 2308 | +} |
0 commit comments