|
25 | 25 | #include "host/ble_uuid.h" |
26 | 26 | #include "host/ble_store.h" |
27 | 27 | #include "ble_hs_priv.h" |
| 28 | +#include "tinycrypt/aes.h" |
| 29 | +#include "tinycrypt/cmac_mode.h" |
| 30 | +#include "tinycrypt/constants.h" |
28 | 31 |
|
29 | 32 | #define BLE_GATTS_INCLUDE_SZ 6 |
30 | 33 | #define BLE_GATTS_CHR_MAX_SZ 19 |
@@ -65,6 +68,10 @@ struct ble_gatts_clt_cfg { |
65 | 68 | static struct ble_gatts_clt_cfg *ble_gatts_clt_cfgs; |
66 | 69 | static int ble_gatts_num_cfgable_chrs; |
67 | 70 |
|
| 71 | +#if MYNEWT_VAL(BLE_ATT_SVR_ROBUST_CACHE) |
| 72 | +uint8_t db_hash[16]; |
| 73 | +#endif |
| 74 | + |
68 | 75 | STATS_SECT_DECL(ble_gatts_stats) ble_gatts_stats; |
69 | 76 | STATS_NAME_START(ble_gatts_stats) |
70 | 77 | STATS_NAME(ble_gatts_stats, svcs) |
@@ -1061,6 +1068,8 @@ ble_gatts_register_svcs(const struct ble_gatt_svc_def *svcs, |
1061 | 1068 | int rc; |
1062 | 1069 | int i; |
1063 | 1070 |
|
| 1071 | + num_svcs = 0; |
| 1072 | + |
1064 | 1073 | for (i = 0; svcs[i].type != BLE_GATT_SVC_TYPE_END; i++) { |
1065 | 1074 | idx = ble_gatts_num_svc_entries + i; |
1066 | 1075 | if (idx >= ble_hs_max_services) { |
@@ -1227,6 +1236,13 @@ ble_gatts_start(void) |
1227 | 1236 | } |
1228 | 1237 | ble_gatts_free_svc_defs(); |
1229 | 1238 |
|
| 1239 | +#if MYNEWT_VAL(BLE_ATT_SVR_ROBUST_CACHE) |
| 1240 | + rc = ble_gatts_calculate_db_hash(db_hash); |
| 1241 | + if (rc != 0) { |
| 1242 | + goto done; |
| 1243 | + } |
| 1244 | +#endif |
| 1245 | + |
1230 | 1246 | if (ble_gatts_num_cfgable_chrs == 0) { |
1231 | 1247 | rc = 0; |
1232 | 1248 | goto done; |
@@ -2226,6 +2242,87 @@ ble_gatts_lcl_svc_foreach(ble_gatt_svc_foreach_fn cb, void *arg) |
2226 | 2242 | } |
2227 | 2243 | } |
2228 | 2244 |
|
| 2245 | +/* Helpers to append data to buf */ |
| 2246 | +#define BUF_PUT_LE16(buf, buf_len, val) \ |
| 2247 | + do { \ |
| 2248 | + put_le16((buf) + (buf_len), (val)); \ |
| 2249 | + (buf_len) += 2; \ |
| 2250 | + } while (0) |
| 2251 | + |
| 2252 | +int ble_gatt_foreach_hash_append(struct ble_att_svr_entry *entry, void *arg) |
| 2253 | +{ |
| 2254 | + uint16_t uuid; |
| 2255 | + struct os_mbuf *om; |
| 2256 | + uint8_t buf[24]; |
| 2257 | + uint16_t buf_len; |
| 2258 | + int rc; |
| 2259 | + |
| 2260 | + uuid = ble_uuid_u16(entry->ha_uuid); |
| 2261 | + buf_len = 0; |
| 2262 | + switch (uuid) { |
| 2263 | + case BLE_ATT_UUID_PRIMARY_SERVICE: |
| 2264 | + case BLE_ATT_UUID_SECONDARY_SERVICE: |
| 2265 | + case BLE_ATT_UUID_INCLUDE: |
| 2266 | + case BLE_ATT_UUID_CHARACTERISTIC: |
| 2267 | + case BLE_GATT_DSC_EXT_PROP_UUID16: |
| 2268 | + /* attr handle */ |
| 2269 | + BUF_PUT_LE16(buf, buf_len, entry->ha_handle_id); |
| 2270 | + /* attr type */ |
| 2271 | + BUF_PUT_LE16(buf, buf_len, uuid); |
| 2272 | + rc = ble_att_svr_read_local(entry->ha_handle_id, &om); |
| 2273 | + if (rc != 0) { |
| 2274 | + return rc; |
| 2275 | + } |
| 2276 | + os_mbuf_copydata(om, 0, os_mbuf_len(om), buf + buf_len); |
| 2277 | + buf_len += os_mbuf_len(om); |
| 2278 | + break; |
| 2279 | + |
| 2280 | + case BLE_GATT_DSC_CLT_CFG_UUID16: |
| 2281 | + BUF_PUT_LE16(buf, buf_len, entry->ha_handle_id); |
| 2282 | + BUF_PUT_LE16(buf, buf_len, uuid); |
| 2283 | + break; |
| 2284 | + default: |
| 2285 | + return 0; |
| 2286 | + } |
| 2287 | + if (tc_cmac_update(arg, buf, buf_len) == TC_CRYPTO_FAIL) { |
| 2288 | + return BLE_HS_EUNKNOWN; |
| 2289 | + } |
| 2290 | + |
| 2291 | + return 0; |
| 2292 | +} |
| 2293 | + |
| 2294 | +/** |
| 2295 | + * Calculate db_hash |
| 2296 | + * @param hash |
| 2297 | + * @return |
| 2298 | + */ |
| 2299 | + |
| 2300 | +int ble_gatts_calculate_db_hash(uint8_t *hash) |
| 2301 | +{ |
| 2302 | +#if !MYNEWT_VAL(BLE_ATT_SVR_ROBUST_CACHE) |
| 2303 | + return BLE_HS_ENOTSUP; |
| 2304 | +#endif |
| 2305 | + struct tc_aes_key_sched_struct sched; |
| 2306 | + struct tc_cmac_struct state; |
| 2307 | + |
| 2308 | + /* k is the 128-bit key, which shall be all zero (7.3.1 Core spec) */ |
| 2309 | + const uint8_t key[16] = {0}; |
| 2310 | + |
| 2311 | + if (tc_cmac_setup(&state, key, &sched) == TC_CRYPTO_FAIL) { |
| 2312 | + return BLE_HS_EUNKNOWN; |
| 2313 | + } |
| 2314 | + |
| 2315 | + ble_att_svr_foreach(0x0001, 0xFFFF, ble_gatt_foreach_hash_append, &state); |
| 2316 | + |
| 2317 | + if (tc_cmac_final(hash, &state) == TC_CRYPTO_FAIL) { |
| 2318 | + return BLE_HS_EUNKNOWN; |
| 2319 | + } |
| 2320 | + |
| 2321 | + swap_in_place(hash, 16); |
| 2322 | + |
| 2323 | + return 0; |
| 2324 | +} |
| 2325 | + |
2229 | 2326 | int |
2230 | 2327 | ble_gatts_reset(void) |
2231 | 2328 | { |
|
0 commit comments