second cut at host privacy
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/34e4509a Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/34e4509a Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/34e4509a Branch: refs/heads/develop Commit: 34e4509af1f497c6b85cf16f1f43755a998f8e4b Parents: a8c1718 Author: Paul Dietrich <paulfdietr...@yahoo.com> Authored: Wed May 18 14:25:17 2016 -0700 Committer: Paul Dietrich <paulfdietr...@yahoo.com> Committed: Thu Jun 2 14:12:05 2016 -0700 ---------------------------------------------------------------------- apps/bletiny/pkg.yml | 2 +- apps/bletiny/src/bletiny.h | 2 + apps/bletiny/src/cmd.c | 306 ++++++++++++++++++++--- apps/bletiny/src/main.c | 92 ++----- apps/bletiny/src/parse.c | 24 +- net/nimble/controller/src/ble_ll_hci.c | 4 +- net/nimble/controller/src/ble_ll_rand.c | 2 +- net/nimble/host/include/host/ble_gap.h | 7 + net/nimble/host/include/host/ble_keycache.h | 75 ------ net/nimble/host/include/host/ble_store.h | 7 + net/nimble/host/src/ble_gap.c | 61 +++-- net/nimble/host/src/ble_hs_priv.c | 161 +++++++++--- net/nimble/host/src/ble_hs_priv.h | 5 +- net/nimble/host/src/ble_hs_startup.c | 5 +- net/nimble/host/src/ble_keycache.c | 205 --------------- net/nimble/host/src/ble_l2cap_sm.c | 11 +- net/nimble/host/src/ble_store.c | 72 ++++++ net/nimble/host/src/host_hci.c | 30 ++- net/nimble/host/src/host_hci_cmd.c | 4 +- net/nimble/host/src/test/ble_hs_test_util.c | 20 +- net/nimble/include/nimble/hci_common.h | 2 + 21 files changed, 631 insertions(+), 466 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/apps/bletiny/pkg.yml ---------------------------------------------------------------------- diff --git a/apps/bletiny/pkg.yml b/apps/bletiny/pkg.yml index 614f76f..90e2286 100644 --- a/apps/bletiny/pkg.yml +++ b/apps/bletiny/pkg.yml @@ -33,4 +33,4 @@ pkg.deps: pkg.cflags: # Reduce the log level from DEBUG to INFO. This is necessary to fit # bletiny on the nRF51dk. - - "-DLOG_LEVEL=1" + - "-DLOG_LEVEL=0" http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/apps/bletiny/src/bletiny.h ---------------------------------------------------------------------- diff --git a/apps/bletiny/src/bletiny.h b/apps/bletiny/src/bletiny.h index f793550..0e3cae6 100644 --- a/apps/bletiny/src/bletiny.h +++ b/apps/bletiny/src/bletiny.h @@ -96,6 +96,7 @@ extern struct log bletiny_log; void print_addr(void *addr); void print_uuid(void *uuid128); +void print_bytes(uint8_t *bytes, int len); const struct cmd_entry *parse_cmd_find(const struct cmd_entry *cmds, char *name); struct kv_pair *parse_kv_find(struct kv_pair *kvs, char *name); @@ -111,6 +112,7 @@ uint16_t parse_arg_uint16_dflt(char *name, uint16_t dflt, int *out_status); uint32_t parse_arg_uint32(char *name, int *out_status); uint64_t parse_arg_uint64(char *name, int *out_status); int parse_arg_kv(char *name, struct kv_pair *kvs); +int parse_arg_kv_default(char *name, struct kv_pair *kvs, int def_val); int parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len); int parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len); int parse_arg_mac(char *name, uint8_t *dst); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/apps/bletiny/src/cmd.c ---------------------------------------------------------------------- diff --git a/apps/bletiny/src/cmd.c b/apps/bletiny/src/cmd.c index f44c6dd..e0a361b 100644 --- a/apps/bletiny/src/cmd.c +++ b/apps/bletiny/src/cmd.c @@ -285,19 +285,20 @@ cmd_adv(int argc, char **argv) } conn = parse_arg_kv("conn", cmd_adv_conn_modes); - if (conn == -1) { + if (conn < 0) { console_printf("invalid 'conn' parameter\n"); return -1; } disc = parse_arg_kv("disc", cmd_adv_disc_modes); - if (disc == -1) { + if (conn < 0) { console_printf("missing 'disc' parameter\n"); return -1; } if (conn == BLE_GAP_CONN_MODE_DIR) { - addr_type = parse_arg_kv("peer_addr_type", cmd_adv_addr_types); + addr_type = parse_arg_kv_default + ("peer_addr_type", cmd_adv_addr_types, BLE_ADDR_TYPE_PUBLIC); if (addr_type == -1) { return -1; } @@ -313,13 +314,13 @@ cmd_adv(int argc, char **argv) peer_addr_type = addr_type; - addr_type = parse_arg_kv("own_addr_type", cmd_adv_addr_types); - if (addr_type == -1) { - return -1; - } else { - addr_type = BLE_ADDR_TYPE_PUBLIC; + rc = parse_arg_kv_default + ("own_addr_type", cmd_adv_addr_types, BLE_ADDR_TYPE_PUBLIC); + if (rc == -1) { + return rc; } - params.own_addr_type = addr_type; + + params.own_addr_type = rc; u8 = parse_arg_long_bounds("chan_map", 0, 0xff, &rc); if (rc == 0) { @@ -348,7 +349,7 @@ cmd_adv(int argc, char **argv) * $connect * *****************************************************************************/ -static struct kv_pair cmd_conn_addr_types[] = { +static struct kv_pair cmd_conn_peer_addr_types[] = { { "public", BLE_HCI_CONN_PEER_ADDR_PUBLIC }, { "random", BLE_HCI_CONN_PEER_ADDR_RANDOM }, { "public_ident", BLE_HCI_CONN_PEER_ADDR_PUBLIC_IDENT }, @@ -357,6 +358,14 @@ static struct kv_pair cmd_conn_addr_types[] = { { NULL } }; +static struct kv_pair cmd_conn_own_addr_types[] = { + { "public", BLE_ADDR_TYPE_PUBLIC }, + { "random", BLE_ADDR_TYPE_RANDOM }, + { "rpa_pub", BLE_ADDR_TYPE_RPA_PUB_DEFAULT }, + { "rpa_rnd", BLE_ADDR_TYPE_RPA_RND_DEFAULT }, + { NULL } +}; + static int cmd_conn(int argc, char **argv) { @@ -375,7 +384,7 @@ cmd_conn(int argc, char **argv) return 0; } - addr_type = parse_arg_kv("peer_addr_type", cmd_conn_addr_types); + addr_type = parse_arg_kv("peer_addr_type", cmd_conn_peer_addr_types); if (addr_type == -1) { return -1; } @@ -389,10 +398,12 @@ cmd_conn(int argc, char **argv) memset(peer_addr, 0, sizeof peer_addr); } - params.our_addr_type = parse_arg_kv("our_addr_type", cmd_conn_addr_types); - if (rc != 0) { + rc = parse_arg_kv_default("own_addr_type", + cmd_conn_own_addr_types, BLE_ADDR_TYPE_PUBLIC); + if (rc < 0) { return rc; } + params.our_addr_type = rc; params.scan_itvl = parse_arg_uint16_dflt("scan_itvl", 0x0010, &rc); if (rc != 0) { @@ -843,22 +854,23 @@ cmd_scan(int argc, char **argv) } disc = parse_arg_kv("disc", cmd_scan_disc_modes); - if (disc == -1) { + if (disc < 0) { return EINVAL; } type = parse_arg_kv("type", cmd_scan_types); - if (type == -1) { + if (type < 0) { return EINVAL; } filt = parse_arg_kv("filt", cmd_scan_filt_policies); - if (disc == -1) { + if (filt < 0) { return EINVAL; } - addr_mode = parse_arg_kv("addr_mode", cmd_scan_addr_types); - if (disc == -1) { + addr_mode = parse_arg_kv_default("addr_mode", + cmd_scan_addr_types, BLE_ADDR_TYPE_PUBLIC); + if (addr_mode == -1) { return EINVAL; } @@ -1012,25 +1024,9 @@ cmd_sec_restart(int argc, char **argv) return 0; } -static int -cmd_sec_ltk(int argc, char **argv) -{ - /* TODO */ - return -1; -} - -static int -cmd_sec_request(int argc, char **argv) -{ - /* TODO */ - return -1; -} - static struct cmd_entry cmd_sec_entries[] = { { "start", cmd_sec_start }, { "restart", cmd_sec_restart }, - { "ltk", cmd_sec_ltk }, - { "request", cmd_sec_request } }; static int @@ -1399,6 +1395,7 @@ cmd_set(int argc, char **argv) { uint16_t mtu; uint8_t addr[6]; + uint8_t irk[16]; int good; int rc; @@ -1436,6 +1433,14 @@ cmd_set(int argc, char **argv) return rc; } + rc = parse_arg_byte_stream_exact_length("irk", irk, 16); + if (rc == 0) { + good = 1; + ble_hs_priv_update_irk(irk); + } else if (rc != ENOENT) { + return rc; + } + if (!good) { console_printf("Error: no valid settings specified\n"); return -1; @@ -1676,6 +1681,238 @@ cmd_write(int argc, char **argv) return 0; } +/***************************************************************************** + * store * + *****************************************************************************/ +#define BLETINY_CMD_KEYSTORE_ENTRY_TYPE_MST_SEC 0 +#define BLETINY_CMD_KEYSTORE_ENTRY_TYPE_SLV_SEC 1 +#define BLETINY_CMD_KEYSTORE_ENTRY_TYPE_CCCD_SEC 2 + +static struct kv_pair cmd_keystore_entry_type[] = { + { "msec", BLE_STORE_OBJ_TYPE_MST_SEC }, + { "ssec", BLE_STORE_OBJ_TYPE_SLV_SEC }, + { "cccd", BLE_STORE_OBJ_TYPE_CCCD }, + { NULL } +}; + +static struct kv_pair cmd_keystore_addr_type[] = { + { "public", BLE_ADDR_TYPE_PUBLIC }, + { "random", BLE_ADDR_TYPE_RANDOM }, + { NULL } +}; + +static int +cmd_keystore_parse_keydata(int argc, char **argv, union ble_store_key *out, + int *obj_type) +{ + int type; + int rc; + + memset(out, 0, sizeof(*out)); + type = parse_arg_kv("type", cmd_keystore_entry_type); + *obj_type = type; + + switch (type) { + case BLE_STORE_OBJ_TYPE_MST_SEC: + case BLE_STORE_OBJ_TYPE_SLV_SEC: + /* try to parse by address and type */ + out->sec.peer_addr_type = + parse_arg_kv("addr_type", cmd_keystore_addr_type); + rc = parse_arg_mac("addr", out->sec.peer_addr); + + if (rc || out->sec.peer_addr_type < 0) { + + out->sec.peer_addr_type = BLE_STORE_ADDR_TYPE_NONE; + + out->sec.ediv = parse_arg_uint16("ediv", &rc); + if (rc != 0) { + return rc; + } + + out->sec.rand_num = parse_arg_uint64("rand", &rc); + if (rc != 0) { + return rc; + } + } + + break; + default: + return -1; + } + return 0; +} + +static int +cmd_keystore_parse_valuedata(int argc, char **argv, + int obj_type, + union ble_store_key *key, + union ble_store_value *out) +{ + int rc; + int valcnt = 0; + memset(out, 0, sizeof(*out)); + + switch (obj_type) { + case BLE_STORE_OBJ_TYPE_MST_SEC: + case BLE_STORE_OBJ_TYPE_SLV_SEC: + rc = parse_arg_byte_stream_exact_length("ltk", out->sec.ltk, 16); + if (rc == 0) { + out->sec.ltk_present = 1; + valcnt++; + } else if (rc != ENOENT) { + return rc; + } + rc = parse_arg_byte_stream_exact_length("irk", out->sec.irk, 16); + if (rc == 0) { + out->sec.irk_present = 1; + valcnt++; + } else if (rc != ENOENT) { + return rc; + } + rc = parse_arg_byte_stream_exact_length("csrk", out->sec.csrk, 16); + if (rc == 0) { + out->sec.csrk_present = 1; + valcnt++; + } else if (rc != ENOENT) { + return rc; + } + out->sec.peer_addr_type = key->sec.peer_addr_type; + memcpy(out->sec.peer_addr, key->sec.peer_addr, 6); + out->sec.ediv = key->sec.ediv; + out->sec.rand_num = key->sec.rand_num; + break; + } + + if (valcnt) { + return 0; + } + return -1; +} + +static int +cmd_keystore_add(int argc, char **argv) +{ + union ble_store_key key; + union ble_store_value value; + int obj_type; + int rc; + + rc = cmd_keystore_parse_keydata(argc, argv, &key, &obj_type); + + if (rc) { + return rc; + } + + rc = cmd_keystore_parse_valuedata(argc, argv, obj_type, &key, &value); + + if (rc) { + return rc; + } + + switch(obj_type) { + case BLE_STORE_OBJ_TYPE_MST_SEC: + rc = ble_store_write_mst_sec(&value.sec); + break; + case BLE_STORE_OBJ_TYPE_SLV_SEC: + rc = ble_store_write_slv_sec(&value.sec); + break; + case BLE_STORE_OBJ_TYPE_CCCD: + rc = ble_store_write_cccd(&value.cccd); + break; + default: + rc = ble_store_write(obj_type, &value); + } + return rc; +} + +static int +cmd_keystore_del(int argc, char **argv) +{ + union ble_store_key key; + int obj_type; + int rc; + + rc = cmd_keystore_parse_keydata(argc, argv, &key, &obj_type); + + if (rc) { + return rc; + } + rc = ble_store_delete(obj_type, &key); + return rc; +} + +static int +cmd_keystore_iterator(int obj_type, + union ble_store_value *val, + void *cookie) { + + switch (obj_type) { + case BLE_STORE_OBJ_TYPE_MST_SEC: + case BLE_STORE_OBJ_TYPE_SLV_SEC: + console_printf("Key: "); + if (val->sec.peer_addr_type == BLE_STORE_ADDR_TYPE_NONE) { + console_printf("ediv=%u ", val->sec.ediv); + console_printf("ediv=%llu ", val->sec.rand_num); + } else { + console_printf("addr_type=%u ", val->sec.peer_addr_type); + print_addr(val->sec.peer_addr); + } + console_printf("\n"); + + if (val->sec.ltk_present) { + console_printf(" LTK: "); + print_bytes(val->sec.ltk, 16); + console_printf("\n"); + } + if (val->sec.irk_present) { + console_printf(" IRK: "); + print_bytes(val->sec.irk, 16); + console_printf("\n"); + } + if (val->sec.csrk_present) { + console_printf(" CSRK: "); + print_bytes(val->sec.csrk, 16); + console_printf("\n"); + } + break; + } + return 0; +} + +static int +cmd_keystore_show(int argc, char **argv) +{ + int type; + + type = parse_arg_kv("type", cmd_keystore_entry_type); + + if (type < 0) { + return type; + } + + ble_store_iterate(type, &cmd_keystore_iterator, NULL); + return 0; +} + +static struct cmd_entry cmd_keystore_entries[] = { + { "add", cmd_keystore_add }, + { "del", cmd_keystore_del }, + { "show", cmd_keystore_show }, + { NULL, NULL } +}; + +static int +cmd_keystore(int argc, char **argv) +{ + int rc; + + rc = cmd_exec(cmd_keystore_entries, argc, argv); + if (rc != 0) { + return rc; + } + + return 0; +} /***************************************************************************** * $passkey * @@ -1750,6 +1987,7 @@ static struct cmd_entry cmd_b_entries[] = { { "show", cmd_show }, { "sec", cmd_sec }, { "set", cmd_set }, + { "store", cmd_keystore }, { "term", cmd_term }, { "update", cmd_update }, { "wl", cmd_wl }, http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/apps/bletiny/src/main.c ---------------------------------------------------------------------- diff --git a/apps/bletiny/src/main.c b/apps/bletiny/src/main.c index 837ddf2..47394b3 100755 --- a/apps/bletiny/src/main.c +++ b/apps/bletiny/src/main.c @@ -42,7 +42,6 @@ #include "host/ble_gap.h" #include "host/ble_gatt.h" #include "host/ble_store.h" -#include "host/ble_keycache.h" #include "controller/ble_ll.h" /* XXX: An app should not include private headers from a library. The bletiny @@ -146,11 +145,19 @@ bletiny_print_error(char *msg, uint16_t conn_handle, } static void +bletiny_print_mac(uint8_t *mac) { + int i; + for (i = 5; i >= 0; i--) { + console_printf("%s0x%02x", i != 5 ? ":" : "", mac[i]); + } +} + +static void bletiny_print_conn_desc(struct ble_gap_conn_desc *desc) { console_printf("handle=%d peer_addr_type=%d peer_addr=", desc->conn_handle, desc->peer_addr_type); - print_bytes(desc->peer_addr, 6); + bletiny_print_mac(desc->peer_addr); console_printf(" conn_itvl=%d conn_latency=%d supervision_timeout=%d " "pair_alg=%d enc_enabled=%d authenticated=%d", desc->conn_itvl, desc->conn_latency, @@ -161,6 +168,15 @@ bletiny_print_conn_desc(struct ble_gap_conn_desc *desc) } static void +bletiny_print_enh_conn_info(struct ble_gap_enhanced_conn *penh) +{ + console_printf(" local_rpa "); + bletiny_print_mac(penh->local_rpa); + console_printf(" peer_rpa "); + bletiny_print_mac(penh->peer_rpa); +} + +static void bletiny_print_adv_fields(struct ble_hs_adv_fields *fields) { uint32_t u32; @@ -257,7 +273,7 @@ bletiny_print_adv_fields(struct ble_hs_adv_fields *fields) if (fields->le_addr != NULL) { console_printf(" le_addr="); - print_bytes(fields->le_addr, BLE_HS_ADV_LE_ADDR_LEN); + bletiny_print_mac(fields->le_addr); console_printf("\n"); } @@ -652,31 +668,6 @@ bletiny_dsc_add(uint16_t conn_handle, uint16_t chr_def_handle, return dsc; } -static void -bletiny_start_auto_advertise(void) -{ - struct ble_hs_adv_fields fields; - int rc; - - if (BLETINY_AUTO_DEVICE_NAME[0] != '\0') { - memset(&fields, 0, sizeof fields); - - fields.name = (uint8_t *)BLETINY_AUTO_DEVICE_NAME; - fields.name_len = strlen(BLETINY_AUTO_DEVICE_NAME); - fields.name_is_complete = 1; - rc = bletiny_set_adv_data(&fields); - if (rc != 0) { - return; - } - - rc = bletiny_adv_start(BLE_GAP_DISC_MODE_GEN, BLE_GAP_CONN_MODE_UND, - 0, 0, NULL); - if (rc != 0) { - return; - } - } -} - static int bletiny_on_mtu(uint16_t conn_handle, struct ble_gatt_error *error, uint16_t mtu, void *arg) @@ -812,6 +803,10 @@ bletiny_gap_event(int event, struct ble_gap_conn_ctxt *ctxt, void *arg) ctxt->connect.status == 0 ? "established" : "failed", ctxt->connect.status); bletiny_print_conn_desc(ctxt->desc); + + if (ctxt->connect.status == 0) { + bletiny_print_enh_conn_info(ctxt->connect.enhanced_conn); + } console_printf("\n"); if (ctxt->connect.status == 0) { @@ -868,37 +863,6 @@ bletiny_gap_event(int event, struct ble_gap_conn_ctxt *ctxt, void *arg) print_bytes(ctxt->notify.attr_data, ctxt->notify.attr_len); console_printf("\n"); return 0; - case BLE_GAP_EVENT_LTK_REQUEST: - { - struct ble_gap_key_parms kp; - console_printf("looking up ltk with ediv=0x%02x rand=0x%llx\n", - ctxt->ltk_params->ediv, ctxt->ltk_params->rand_num); - if ((ble_keycache_find(ctxt->desc->peer_addr_type, - ctxt->desc->peer_addr, &kp) == 0) && - (kp.ltk_valid) && (kp.ediv_rand_valid)) { - console_printf("ltk="); - bletiny_print_bytes(kp.ltk, sizeof(kp.ltk)); - console_printf("\n"); - } else { - console_printf("no matching ltk\n"); - } - return 0; - } - case BLE_GAP_EVENT_KEY_EXCHANGE: - rc = 0; - console_printf("key exchange event; status=%d ", status); - bletiny_print_key_exchange_parms(ctxt->key_params); - - if(ctxt->key_params->addr_valid) - { - rc = ble_keycache_add(ctxt->key_params->addr_type, - ctxt->key_params->addr, - ctxt->key_params); - if (rc != 0) { - console_printf("error persisting keys; status=%d\n", rc); - } - } - return rc; default: return 0; } @@ -918,7 +882,7 @@ bletiny_on_scan(int event, int status, struct ble_gap_disc_desc *desc, case BLE_GAP_EVENT_DISC_SUCCESS: console_printf("received advertisement; event_type=%d addr_type=%d " "addr=", desc->event_type, desc->addr_type); - print_bytes(desc->addr, 6); + bletiny_print_mac(desc->addr); console_printf(" length_data=%d rssi=%d data=", desc->length_data, desc->rssi); print_bytes(desc->data, desc->length_data); @@ -1130,8 +1094,8 @@ bletiny_conn_initiate(int addr_type, uint8_t *peer_addr, { int rc; - rc = ble_gap_conn_initiate(addr_type, peer_addr, NULL, bletiny_gap_event, - params); + rc = ble_gap_conn_initiate(addr_type, peer_addr, params, bletiny_gap_event, + NULL); return rc; } @@ -1384,10 +1348,6 @@ main(void) rc = ble_ll_init(BLE_LL_TASK_PRI, MBUF_NUM_MBUFS, BLE_MBUF_PAYLOAD_SIZE); assert(rc == 0); - /* initialize the keycache to store private keys */ - rc = ble_keycache_init(4); - assert(rc == 0); - rc = cmd_init(); assert(rc == 0); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/apps/bletiny/src/parse.c ---------------------------------------------------------------------- diff --git a/apps/bletiny/src/parse.c b/apps/bletiny/src/parse.c index 457cb7c..a739d3d 100644 --- a/apps/bletiny/src/parse.c +++ b/apps/bletiny/src/parse.c @@ -214,17 +214,37 @@ parse_arg_kv(char *name, struct kv_pair *kvs) sval = parse_arg_find(name); if (sval == NULL) { - return ENOENT; + return -1; } kv = parse_kv_find(kvs, sval); if (kv == NULL) { - return EINVAL; + return -2; } return kv->val; } +int +parse_arg_kv_default(char *name, struct kv_pair *kvs, int def_val) +{ + struct kv_pair *kv; + char *sval; + + sval = parse_arg_find(name); + if (sval == NULL) { + return def_val; + } + + kv = parse_kv_find(kvs, sval); + if (kv == NULL) { + return -1; + } + + return kv->val; +} + + static int parse_arg_byte_stream_delim(char *sval, char *delims, int max_len, uint8_t *dst, int *out_len) http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/controller/src/ble_ll_hci.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_hci.c b/net/nimble/controller/src/ble_ll_hci.c index 3cbec48..ec26019 100644 --- a/net/nimble/controller/src/ble_ll_hci.c +++ b/net/nimble/controller/src/ble_ll_hci.c @@ -642,10 +642,10 @@ ble_ll_hci_le_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen) #endif #if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1) case BLE_HCI_OCF_LE_ADD_RESOLV_LIST : - ble_ll_resolv_list_add(cmdbuf); + rc = ble_ll_resolv_list_add(cmdbuf); break; case BLE_HCI_OCF_LE_RMV_RESOLV_LIST: - ble_ll_resolv_list_rmv(cmdbuf); + rc = ble_ll_resolv_list_rmv(cmdbuf); break; case BLE_HCI_OCF_LE_CLR_RESOLV_LIST: rc = ble_ll_resolv_list_clr(); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/controller/src/ble_ll_rand.c ---------------------------------------------------------------------- diff --git a/net/nimble/controller/src/ble_ll_rand.c b/net/nimble/controller/src/ble_ll_rand.c index 4da599f..c5201f9 100644 --- a/net/nimble/controller/src/ble_ll_rand.c +++ b/net/nimble/controller/src/ble_ll_rand.c @@ -31,7 +31,7 @@ struct ble_ll_rnum_data { uint8_t *rnd_in; uint8_t *rnd_out; - uint8_t rnd_size; + volatile uint8_t rnd_size; }; struct ble_ll_rnum_data g_ble_ll_rnum_data; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/host/include/host/ble_gap.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/include/host/ble_gap.h b/net/nimble/host/include/host/ble_gap.h index 7cca333..65b1a11 100644 --- a/net/nimble/host/include/host/ble_gap.h +++ b/net/nimble/host/include/host/ble_gap.h @@ -171,12 +171,18 @@ struct ble_gap_passkey_action { uint8_t action; }; +struct ble_gap_enhanced_conn { + uint8_t peer_rpa[6]; + uint8_t local_rpa[6]; +}; + struct ble_gap_conn_ctxt { struct ble_gap_conn_desc *desc; union { struct { int status; + struct ble_gap_enhanced_conn *enhanced_conn; } connect; struct { @@ -274,5 +280,6 @@ int ble_gap_security_initiate(uint16_t conn_handle); int ble_gap_encryption_initiate(uint16_t conn_handle, uint8_t *ltk, uint16_t ediv, uint64_t rand_val, int auth); +int ble_gap_provide_ltk(uint16_t conn_handle, uint8_t *ltk); void ble_gap_init_identity_addr(uint8_t *addr); #endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/host/include/host/ble_keycache.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/include/host/ble_keycache.h b/net/nimble/host/include/host/ble_keycache.h deleted file mode 100644 index c97aeac..0000000 --- a/net/nimble/host/include/host/ble_keycache.h +++ /dev/null @@ -1,75 +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. - */ -#ifndef H_BLE_KEYCACHE_ -#define H_BLE_KEYCACHE_ - -struct ble_gap_key_parms; - -/* - * This is a helper library to help the application store and access - * keys for devices. The keys are passed from the stack as a single - * blob in ble_gap_key_parms. When this is written to the cache, it - * will overwrite any previous data for that address, So, if you - * want to preserved any information from a previous write for this - * address, you had better read the value out first and then - * preserve what you want. - * - * A note on address types. This cache will store any address type. - * Its up to the application to filter the address and determine - * whether its worth storing in the keycache or not - * - * A note on multi-tasking. This library is written to be access from a single - * task. If you intend to use this from multiple tasks (e.g. a UI task to - * delete bonding data and the host task to add bondind data) its up to your - * application to provide mutual exclusion - */ - -/** - * Adds an entry to the LTK keycache. - * Returns an error (negative) if the LTK key cache is full . - * Within the key params struct, addr must be valid as this is - * the lookup for key cache entries. - */ -int -ble_keycache_add(uint8_t addr_type, uint8_t *key_addr, struct ble_gap_key_parms *pltk); - -/* - * reads values for the given addr from the keycache. If no entry - * is found, a negative value is returned and pout_entry is undefined. - */ -int -ble_keycache_find(uint8_t addr_type, uint8_t *key_addr, struct ble_gap_key_parms *pout_entry); - -/* - * Deletes an entry from the keycache for the give address. - * Returns 0 if the entry is successfully deleted. NOTE: if there is - * no entry for the given address the function will return 0. Returns - * negative on error - * @Param addr -- a 6 octet mac address of the device - */ - int - ble_keycache_delete(uint8_t addr_type, uint8_t *key_addr); - -/* Initialize a key-cache. - */ - -int -ble_keycache_init(int max_entries); - -#endif /* H_BLE_KEYCACHE_ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/host/include/host/ble_store.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/include/host/ble_store.h b/net/nimble/host/include/host/ble_store.h index 7a75703..72b177e 100644 --- a/net/nimble/host/include/host/ble_store.h +++ b/net/nimble/host/include/host/ble_store.h @@ -136,4 +136,11 @@ void ble_store_key_from_value_sec(struct ble_store_key_sec *out_key, void ble_store_key_from_value_cccd(struct ble_store_key_cccd *out_key, struct ble_store_value_cccd *value); +typedef int ble_store_iterator_fn(int obj_type, + union ble_store_value *val, + void *cookie); + +void ble_store_iterate(int obj_type, + ble_store_iterator_fn *callback, + void *cookie); #endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/host/src/ble_gap.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_gap.c b/net/nimble/host/src/ble_gap.c index dcaa493..4ec25d4 100644 --- a/net/nimble/host/src/ble_gap.c +++ b/net/nimble/host/src/ble_gap.c @@ -25,7 +25,6 @@ #include "nimble/nimble_opt.h" #include "host/host_hci.h" #include "ble_hs_priv.h" -#include "host/ble_keycache.h" /** * GAP - Generic Access Profile. @@ -824,6 +823,7 @@ ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt) struct ble_gap_conn_ctxt ctxt; struct ble_gap_snapshot snap; struct ble_hs_conn *conn; + struct ble_gap_enhanced_conn enhanced_conn; int rc; STATS_INC(ble_gap_stats, rx_conn_complete); @@ -916,6 +916,9 @@ ble_gap_rx_conn_complete(struct hci_le_conn_complete *evt) memset(&ctxt, 0, sizeof ctxt); ctxt.desc = &snap.desc; + memcpy(enhanced_conn.local_rpa, evt->local_rpa,6); + memcpy(enhanced_conn.peer_rpa, evt->peer_rpa,6); + ctxt.connect.enhanced_conn = &enhanced_conn; ctxt.connect.status = 0; ble_gap_call_event_cb(BLE_GAP_EVENT_CONNECT, &ctxt, snap.cb, snap.cb_arg); @@ -1273,7 +1276,7 @@ ble_gap_adv_data_tx(void) } static int -ble_gap_adv_params_tx(const struct ble_gap_adv_params *adv_params, +ble_gap_adv_params_tx(const struct ble_gap_adv_params *adv_params, uint8_t *peer_addr, uint8_t peer_addr_type) { struct hci_adv_params hci_adv_params; @@ -1286,16 +1289,19 @@ ble_gap_adv_params_tx(const struct ble_gap_adv_params *adv_params, } else { memset(peer, 0, 6); } - + hci_adv_params.adv_channel_map = adv_params->adv_channel_map; hci_adv_params.own_addr_type = adv_params->own_addr_type; hci_adv_params.adv_filter_policy = adv_params->adv_filter_policy; hci_adv_params.adv_itvl_min = adv_params->adv_itvl_min; hci_adv_params.adv_itvl_max = adv_params->adv_itvl_max; + hci_adv_params.peer_addr_type = peer_addr_type; + hci_adv_params.adv_type = adv_params->adv_type; - if (ble_gap_slave.conn_mode == BLE_GAP_CONN_MODE_DIR) { - hci_adv_params.peer_addr_type = peer_addr_type; - memcpy(hci_adv_params.peer_addr,peer, + if ((ble_gap_slave.conn_mode == BLE_GAP_CONN_MODE_DIR) || + (adv_params->own_addr_type == BLE_ADDR_TYPE_RPA_PUB_DEFAULT) || + (adv_params->own_addr_type == BLE_ADDR_TYPE_RPA_RND_DEFAULT)) { + memcpy(hci_adv_params.peer_addr,peer, sizeof(hci_adv_params.peer_addr)); } @@ -1303,24 +1309,6 @@ ble_gap_adv_params_tx(const struct ble_gap_adv_params *adv_params, ble_gap_log_adv(adv_params, peer, peer_addr_type); BLE_HS_LOG(INFO, "\n"); - switch (ble_gap_slave.conn_mode) { - case BLE_GAP_CONN_MODE_NON: - hci_adv_params.adv_type = BLE_HCI_ADV_TYPE_ADV_NONCONN_IND; - break; - - case BLE_GAP_CONN_MODE_DIR: - hci_adv_params.adv_type = BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD; - break; - - case BLE_GAP_CONN_MODE_UND: - hci_adv_params.adv_type = BLE_HCI_ADV_TYPE_ADV_IND; - break; - - default: - BLE_HS_DBG_ASSERT(0); - break; - } - rc = host_hci_cmd_build_le_set_adv_params(&hci_adv_params, buf, sizeof buf); if (rc != 0) { return rc; @@ -1423,7 +1411,7 @@ ble_gap_adv_start(uint8_t discoverable_mode, uint8_t connectable_mode, rc = BLE_HS_EINVAL; goto done; } - + BLE_HS_LOG(INFO, "GAP procedure initiated: advertise; "); ble_gap_log_adv(&gap_adv_params, peer_addr, peer_addr_type); BLE_HS_LOG(INFO, "\n"); @@ -1442,6 +1430,24 @@ ble_gap_adv_start(uint8_t discoverable_mode, uint8_t connectable_mode, ble_hs_priv_set_nrpa(); } + switch (connectable_mode) { + case BLE_GAP_CONN_MODE_NON: + gap_adv_params.adv_type = BLE_HCI_ADV_TYPE_ADV_NONCONN_IND; + break; + + case BLE_GAP_CONN_MODE_DIR: + gap_adv_params.adv_type = BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD; + break; + + case BLE_GAP_CONN_MODE_UND: + gap_adv_params.adv_type = BLE_HCI_ADV_TYPE_ADV_IND; + break; + + default: + BLE_HS_DBG_ASSERT(0); + break; + } + rc = ble_gap_adv_params_tx(&gap_adv_params, peer_addr, peer_addr_type); if (rc != 0) { goto done; @@ -1779,12 +1785,13 @@ ble_gap_conn_initiate(int addr_type, uint8_t *addr, if (addr_type != BLE_HCI_CONN_PEER_ADDR_PUBLIC && addr_type != BLE_HCI_CONN_PEER_ADDR_RANDOM && + addr_type != BLE_HCI_CONN_PEER_ADDR_PUB_ID && + addr_type != BLE_HCI_CONN_PEER_ADDR_RAND_ID && addr_type != BLE_GAP_ADDR_TYPE_WL) { rc = BLE_HS_EINVAL; goto done; } - if (params == NULL) { params = (void *)&ble_gap_params_dflt; @@ -2226,7 +2233,7 @@ ble_gap_notify_event(uint16_t conn_handle, uint16_t attr_handle, void ble_gap_init_identity_addr(uint8_t *addr) { - ble_hs_priv_init_identity(addr); + ble_hs_priv_update_identity(addr); } /***************************************************************************** http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/host/src/ble_hs_priv.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hs_priv.c b/net/nimble/host/src/ble_hs_priv.c index 574c459..75d210b 100644 --- a/net/nimble/host/src/ble_hs_priv.c +++ b/net/nimble/host/src/ble_hs_priv.c @@ -17,7 +17,6 @@ * under the License. */ #include <inttypes.h> -#include <host/ble_keycache.h> #include <stdio.h> #include <string.h> #include "ble_hs_priv.h" @@ -25,10 +24,11 @@ int identity_initalized; static uint8_t identity_addr[6]; static uint8_t identity_addr_type; -static uint8_t irk[16]; -/* use this as a default IRK if there is none stored in the - * keycache. */ +uint8_t g_irk[16]; + + +/* use this as a default IRK if there is none stored in the ble_store */ const uint8_t default_irk[16] = { 0xef, 0x8d, 0xe2, 0x16, 0x4f, 0xec, 0x43, 0x0d, 0xbf, 0x5b, 0xdd, 0x34, 0xc0, 0x53, 0x1e, 0xb8, @@ -70,66 +70,159 @@ ble_hs_priv_set_addr_to(uint16_t timeout) { return rc; } +static int +ble_keycache_set_status(int enable) +{ + uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_ADDR_RESOL_ENA_LEN]; + int rc; + rc = host_hci_cmd_set_addr_resolution_enable(enable, buf, sizeof(buf)); + + if (0 == rc) { + rc = ble_hci_cmd_tx(buf, NULL, 0, NULL); + } + + return rc; +} + +int +ble_keycache_remove_irk_entry(uint8_t addr_type, uint8_t *addr) +{ + uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_RMV_FROM_RESOLV_LIST_LEN]; + int rc; + + /* build the message data */ + rc = host_hci_cmd_remove_device_from_resolving_list(addr_type, addr, + buf, sizeof(buf)); + + if (0 == rc) { + rc = ble_hci_cmd_tx(buf, NULL, 0, NULL); + } + + return rc; +} + + +static int +ble_keycache_clear_irk_enties(void) +{ + uint8_t buf[BLE_HCI_CMD_HDR_LEN ]; + int rc; + + /* build the message data */ + rc = host_hci_cmd_clear_resolving_list(buf, sizeof(buf)); + + if (0 == rc) { + rc = ble_hci_cmd_tx(buf, NULL, 0, NULL); + } + + return rc; +} + + +int +ble_keycache_write_irk_entry(uint8_t *addr, uint8_t addr_type, uint8_t *irk) +{ + struct hci_add_dev_to_resolving_list add; + uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_ADD_TO_RESOLV_LIST_LEN]; + int rc; + + /* build the message data */ + add.addr_type = addr_type; + memcpy(add.addr, addr, 6); + memcpy(add.local_irk, ble_hs_priv_get_local_irk(), 16); + memcpy(add.peer_irk, irk, 16); + + rc = host_hci_cmd_add_device_to_resolving_list(&add, buf, sizeof(buf)); + + if (0 == rc) { + rc = ble_hci_cmd_tx(buf, NULL, 0, NULL); + } + + return rc; +} + void -ble_hs_priv_init_identity(uint8_t *addr) { +ble_hs_priv_update_identity(uint8_t *addr) { - struct ble_gap_key_parms parms; int rc; uint8_t random_addr[6]; + int first_init = (identity_initalized == 0); - ble_hs_generate_static_random_addr(random_addr); - rc = ble_hs_util_set_random_addr(random_addr); - assert(rc == 0); - - if(identity_initalized) { - return; + /* only do this stuff once */ + if(first_init) { + /* set up the periodic change of our NRA */ + rc = ble_hs_priv_set_addr_to(ble_hs_cfg.privacy_resolvable_addr_timeout); + assert(rc == 0); } - /* did we get passed an address at initialization */ + /* did we get passed an address */ if(addr) { memcpy(identity_addr, addr, 6); identity_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC; - } else if (0 ) + } else if (0) { /* if that fails, try to get a static random address from nvram */ /* TODO */ } else { + /* generate a new static random address and store to memory */ + ble_hs_generate_static_random_addr(random_addr); + rc = ble_hs_util_set_random_addr(random_addr); + assert(rc == 0); + identity_addr_type = BLE_HCI_ADV_OWN_ADDR_RANDOM; memcpy(identity_addr, random_addr, 6); /* TODO store it */ } + identity_initalized = 1; +} + +void +ble_hs_priv_update_irk(uint8_t *irk) +{ + uint8_t tmp_addr[6]; + int irk_changed; + uint8_t new_irk[16]; + + memset(new_irk, 0, sizeof(new_irk)); + /* now try to get an IRK from internal nvram */ - if(0) { - /* TODO */ + if (irk) { + memcpy(new_irk, irk, 16); + } else if(0) { + /* TODO call to application internal nvram */ } else { /* if that fails, use the default IRK */ - memcpy(irk, default_irk, 16); + memcpy(new_irk, default_irk, 16); } - identity_initalized = 1; - - /* write a zero peer addr and addr type */ - memset(parms.irk, 0, 16); - parms.irk_valid = 1; - memset(parms.addr, 0, 6); - parms.addr_valid = 1; - parms.addr_type = 0; - rc = ble_keycache_add(identity_addr_type, identity_addr, &parms); - assert(rc == 0); - - /* set up the periodic change of our NRA */ - rc = ble_hs_priv_set_addr_to(ble_hs_cfg.privacy_resolvable_addr_timeout); - assert(rc == 0); + irk_changed = memcmp(g_irk, new_irk, 16); + + /* if we are changing our IRK, we need to clear this. Also, for + * first time, clear this */ + if (irk_changed) { + memcpy(g_irk, new_irk, 16); + + /* we need to clear this cache since all the other entries used + * our IRK */ + ble_keycache_set_status(0); + ble_keycache_clear_irk_enties(); + ble_keycache_set_status(1); + /* push our identity to the controller as a keycache entry.with a zero + * MAC address. The controller uses this entry to generate a RPA when + * we do advertising with own addr type = rpa */ + memset(tmp_addr, 0, 6); + ble_keycache_write_irk_entry(tmp_addr, 0 ,g_irk); + } } uint8_t * bls_hs_priv_get_local_identity_addr(uint8_t *type) { if(!identity_initalized) { - ble_hs_priv_init_identity(NULL); + ble_hs_priv_update_identity(NULL); } if (type) { @@ -148,7 +241,7 @@ uint8_t * ble_hs_priv_get_local_irk(void) { if(!identity_initalized) { - ble_hs_priv_init_identity(NULL); + ble_hs_priv_update_identity(NULL); } - return irk; + return g_irk; } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/host/src/ble_hs_priv.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hs_priv.h b/net/nimble/host/src/ble_hs_priv.h index 956a355..fd9247a 100644 --- a/net/nimble/host/src/ble_hs_priv.h +++ b/net/nimble/host/src/ble_hs_priv.h @@ -104,9 +104,12 @@ int ble_hci_cmd_tx_empty_ack(void *cmd); void ble_hci_cmd_rx_ack(uint8_t *ack_ev); void ble_hci_cmd_init(void); int ble_hs_priv_set_nrpa(void); -void ble_hs_priv_init_identity(uint8_t *addr); +void ble_hs_priv_update_identity(uint8_t *addr); +void ble_hs_priv_update_irk(uint8_t *irk); void bls_hs_priv_copy_local_identity_addr(uint8_t *pdst, uint8_t* addr_type); uint8_t *ble_hs_priv_get_local_irk(void); +int ble_keycache_remove_irk_entry(uint8_t addr_type, uint8_t *addr); +int ble_keycache_write_irk_entry(uint8_t *addr, uint8_t addrtype, uint8_t *irk); #if PHONY_HCI_ACKS typedef int ble_hci_cmd_phony_ack_fn(uint8_t *ack, int ack_buf_len); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/host/src/ble_hs_startup.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hs_startup.c b/net/nimble/host/src/ble_hs_startup.c index f26eeba..d0f96a2 100644 --- a/net/nimble/host/src/ble_hs_startup.c +++ b/net/nimble/host/src/ble_hs_startup.c @@ -84,7 +84,7 @@ ble_hs_startup_le_set_evmask_tx(void) int rc; /* [ Default event set ]. */ - host_hci_cmd_build_le_set_event_mask(0x000000000000001f, buf, sizeof buf); + host_hci_cmd_build_le_set_event_mask(0x000000000000021f, buf, sizeof buf); rc = ble_hci_cmd_tx_empty_ack(buf); if (rc != 0) { return rc; @@ -164,7 +164,8 @@ ble_hs_startup_go(void) } /* XXX: Read BD_ADDR. */ - ble_hs_priv_init_identity(g_dev_addr); + ble_hs_priv_update_identity(g_dev_addr); + ble_hs_priv_update_irk(NULL); return rc; } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/host/src/ble_keycache.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_keycache.c b/net/nimble/host/src/ble_keycache.c deleted file mode 100644 index e474785..0000000 --- a/net/nimble/host/src/ble_keycache.c +++ /dev/null @@ -1,205 +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. - */ - -#include <inttypes.h> -#include <stdio.h> -#include <string.h> -#include <host/ble_gap.h> -#include <host/ble_keycache.h> -#include "ble_hs_priv.h" - -#define MAC_ADDR_LEN 6 -#define KEYDATA_SIZE_BYTES (sizeof(struct ble_gap_key_parms)) - -/* FOR NOW we implement this as a simple RAM cache for testing. - * The config module is still being invented and I don't want - * to duplicate that work */ - -struct keycache_entry { - uint8_t valid; - uint8_t key[MAC_ADDR_LEN + 1]; - uint8_t data[KEYDATA_SIZE_BYTES]; -}; - -/* a global key cache */ -static struct keycache_entry *p_keycache; -static int keycache_entries; - -int -ble_keycache_find(uint8_t addr_type, uint8_t *key_addr, struct ble_gap_key_parms *pout_entry) -{ - int i; - for(i = 0; i < keycache_entries; i++) { - if (p_keycache[i].valid) { - if ((memcmp(key_addr, p_keycache[i].key, MAC_ADDR_LEN) == 0) && - ( p_keycache[i].key[6] == addr_type)) { - if (pout_entry) { - memcpy(pout_entry, p_keycache[i].data, KEYDATA_SIZE_BYTES); - } - return 0; - } - } - } - - return -1; -} - -static int -ble_keycache_write_irk_entry(struct ble_gap_key_parms *pkeys) -{ - struct hci_add_dev_to_resolving_list add; - uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_ADD_TO_RESOLV_LIST_LEN]; - int rc; - - if(!pkeys->irk_valid) { - return -1; - } - - /* build the message data */ - memcpy(add.addr, pkeys->addr, 6); - memcpy(add.local_irk, ble_hs_priv_get_local_irk(), 16); - memcpy(add.peer_irk, pkeys->irk, 16); - - rc = host_hci_cmd_add_device_to_resolving_list(&add, buf, sizeof(buf)); - - if (0 == rc) { - rc = ble_hci_cmd_tx(buf, NULL, 0, NULL); - } - - return rc; -} - -int -ble_keycache_add(uint8_t addr_type, uint8_t *key_addr, struct ble_gap_key_parms *pkeys) -{ - int i; - int entry = -1; - /* loop through once to find the entry. Pick the first empty one - * or overwrite the old one */ - for(i = 0; i < keycache_entries; i++) { - if ((!p_keycache[i].valid) && (entry == -1)) { - entry = i; - } else if ((memcmp(key_addr, p_keycache[i].key, MAC_ADDR_LEN) == 0) && - ( p_keycache[i].key[6] == addr_type)) { - entry = i; - } - } - - if(entry >= 0 ) { - int rc; - memcpy(p_keycache[i].data, pkeys, KEYDATA_SIZE_BYTES); - memcpy(p_keycache[i].key, key_addr, MAC_ADDR_LEN); - p_keycache[i].key[6] = addr_type; - p_keycache[i].valid = 1; - /* plumb this down to the HW. If it fails, return error, - * and remove from this keycache .*/ - rc = ble_keycache_write_irk_entry(pkeys); - - if(rc) { - p_keycache[i].valid = 0; - } - return rc; - } - return -1; -} - -static int -ble_keycache_remove_irk_entry(uint8_t addr_type, uint8_t *addr) -{ - uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_RMV_FROM_RESOLV_LIST_LEN]; - int rc; - - /* build the message data */ - rc = host_hci_cmd_remove_device_from_resolving_list(addr_type, addr, - buf, sizeof(buf)); - - if (0 == rc) { - rc = ble_hci_cmd_tx(buf, NULL, 0, NULL); - } - - return rc; -} - - int - ble_keycache_delete(uint8_t addr_type, uint8_t *key_addr) -{ - int i; - for(i = 0; i < keycache_entries; i++) { - if (p_keycache[i].valid) { - if ((memcmp(key_addr, p_keycache[i].key, MAC_ADDR_LEN) == 0) && - ( p_keycache[i].key[6] == addr_type)) { - p_keycache[i].valid = 0; - ble_keycache_remove_irk_entry(addr_type, key_addr); - } - } - } - return 0; -} - -static int -ble_keycache_clear_irk_enties(void) -{ - uint8_t buf[BLE_HCI_CMD_HDR_LEN ]; - int rc; - - /* build the message data */ - rc = host_hci_cmd_clear_resolving_list(buf, sizeof(buf)); - - if (0 == rc) { - rc = ble_hci_cmd_tx(buf, NULL, 0, NULL); - } - - return rc; -} - -static int -ble_keycache_set_status(int enable) -{ - uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_ADDR_RESOL_ENA_LEN]; - int rc; - rc = host_hci_cmd_set_addr_resolution_enable(enable, buf, sizeof(buf)); - - if (0 == rc) { - rc = ble_hci_cmd_tx(buf, NULL, 0, NULL); - } - - return rc; -} - -int -ble_keycache_init(int max_entries) -{ - if (p_keycache) { - return -1; - } - - /* TODO this should really be a flash based implementation */ - p_keycache = calloc(max_entries, sizeof(struct keycache_entry)); - - if (NULL == p_keycache) { - return -2; - } - keycache_entries = max_entries; - - /* clear entries in the hardware */ - ble_keycache_set_status(0); - ble_keycache_clear_irk_enties(); - ble_keycache_set_status(1); - return 0; -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/host/src/ble_l2cap_sm.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_l2cap_sm.c b/net/nimble/host/src/ble_l2cap_sm.c index 0e9a4dc..fb89877 100644 --- a/net/nimble/host/src/ble_l2cap_sm.c +++ b/net/nimble/host/src/ble_l2cap_sm.c @@ -972,13 +972,11 @@ ble_l2cap_sm_confirm_prepare_args(struct ble_l2cap_sm_proc *proc, conn = ble_hs_conn_find(proc->conn_handle); if (conn != NULL) { if (proc->flags & BLE_L2CAP_SM_PROC_F_INITIATOR) { - *iat = BLE_ADDR_TYPE_PUBLIC; - bls_hs_priv_copy_local_identity_addr(ra, rat); + bls_hs_priv_copy_local_identity_addr(ia, iat); *rat = conn->bhc_addr_type; memcpy(ra, conn->bhc_addr, 6); } else { - *rat = BLE_ADDR_TYPE_PUBLIC; - bls_hs_priv_copy_local_identity_addr(ia, iat); + bls_hs_priv_copy_local_identity_addr(ra, rat); *iat = conn->bhc_addr_type; memcpy(ia, conn->bhc_addr, 6); } @@ -1381,7 +1379,6 @@ ble_l2cap_sm_key_exchange_go(struct ble_l2cap_sm_proc *proc, } /* copy data to pass to application */ - proc->our_keys.is_ours = 1; proc->our_keys.irk_valid = 1; proc->our_keys.addr_valid = 1; memcpy(proc->our_keys.irk, irk,16); @@ -1795,7 +1792,7 @@ ble_l2cap_sm_lt_key_req_ltk_handle(struct hci_le_lt_key_req *evt) int store_rc; int rc; - /* Tell applicaiton to look up LTK by ediv/rand pair. */ + /* Tell application to look up LTK by ediv/rand pair. */ /* XXX: Also filter by peer address? */ memset(&key_sec, 0, sizeof key_sec); key_sec.peer_addr_type = BLE_STORE_ADDR_TYPE_NONE; @@ -2004,7 +2001,7 @@ ble_l2cap_sm_rx_sec_req(uint16_t conn_handle, uint8_t op, struct os_mbuf **om) ble_hs_unlock(); if (rc == 0) { - /* Query database for an LTK corresonding to the sender. We are the + /* Query database for an LTK corresponding to the sender. We are the * master, so retrieve a master key. */ rc = ble_store_read_mst_sec(&key_sec, &value_sec); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/host/src/ble_store.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_store.c b/net/nimble/host/src/ble_store.c index a49d6b1..f03f671 100644 --- a/net/nimble/host/src/ble_store.c +++ b/net/nimble/host/src/ble_store.c @@ -101,6 +101,11 @@ ble_store_read_mst_sec(struct ble_store_key_sec *key_sec, store_key = (void *)key_sec; store_value = (void *)value_sec; rc = ble_store_read(BLE_STORE_OBJ_TYPE_MST_SEC, store_key, store_value); + + if (rc) { + return rc; + } + return rc; } @@ -112,6 +117,35 @@ ble_store_write_mst_sec(struct ble_store_value_sec *value_sec) store_value = (void *)value_sec; rc = ble_store_write(BLE_STORE_OBJ_TYPE_MST_SEC, store_value); + + if ((value_sec->peer_addr_type != BLE_STORE_ADDR_TYPE_NONE) && + (value_sec->irk_present)) { + /* Write the peer IRK to the controller keycache + * There is not much to do here if it fails */ + rc = ble_keycache_write_irk_entry(value_sec->peer_addr, + value_sec->peer_addr_type, + value_sec->irk); + } + + return rc; +} + +int +ble_store_delete_mst_sec(struct ble_store_key_sec *key_sec) +{ + union ble_store_key *store_key; + int rc; + + store_key = (void *)key_sec; + rc = ble_store_delete(BLE_STORE_OBJ_TYPE_MST_SEC, store_key); + + if(key_sec->peer_addr_type == BLE_STORE_ADDR_TYPE_NONE) { + /* don't error check this since we don't know without looking up + * the value whether it had a valid IRK */ + ble_keycache_remove_irk_entry(key_sec->peer_addr_type, + key_sec->peer_addr); + } + return rc; } @@ -173,3 +207,41 @@ ble_store_key_from_value_sec(struct ble_store_key_sec *out_key, out_key->ediv_rand_present = 1; out_key->idx = 0; } + +void ble_store_iterate(int obj_type, + ble_store_iterator_fn *callback, + void *cookie) +{ + union ble_store_key key; + union ble_store_value value; + int idx = 0; + uint8_t *pidx; + + /* a magic value to retrieve anything */ + memset(&key, 0, sizeof(key)); + switch(obj_type) { + case BLE_STORE_OBJ_TYPE_MST_SEC: + case BLE_STORE_OBJ_TYPE_SLV_SEC: + key.sec.peer_addr_type = BLE_STORE_ADDR_TYPE_NONE; + pidx = &key.sec.idx; + break; + case BLE_STORE_OBJ_TYPE_CCCD: + key.cccd.peer_addr_type = BLE_STORE_ADDR_TYPE_NONE; + pidx = &key.cccd.idx; + default: + return; + } + + while (1) { + int rc; + *pidx = idx; + rc = ble_store_read(obj_type, &key, &value); + if (rc != 0) { + /* read error or no more entries */ + break; + } else if (callback) { + callback(obj_type, &value, cookie); + } + idx++; + } +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/host/src/host_hci.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/host_hci.c b/net/nimble/host/src/host_hci.c index a030c89..2bbdd8f 100644 --- a/net/nimble/host/src/host_hci.c +++ b/net/nimble/host/src/host_hci.c @@ -87,6 +87,7 @@ static const struct host_hci_le_event_dispatch_entry { BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE, host_hci_rx_le_conn_upd_complete }, { BLE_HCI_LE_SUBEV_LT_KEY_REQ, host_hci_rx_le_lt_key_req }, { BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ, host_hci_rx_le_conn_parm_req }, + { BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE, host_hci_rx_le_conn_complete }, }; #define HOST_HCI_LE_EVENT_DISPATCH_SZ \ @@ -132,7 +133,7 @@ host_hci_le_dispatch_entry_find(uint8_t event_code) const struct host_hci_le_event_dispatch_entry *entry; int i; - for (i = 0; i < HOST_HCI_EVENT_DISPATCH_SZ; i++) { + for (i = 0; i < HOST_HCI_LE_EVENT_DISPATCH_SZ; i++) { entry = host_hci_le_event_dispatch + i; if (entry->hmd_subevent == event_code) { return entry; @@ -240,22 +241,41 @@ static int host_hci_rx_le_conn_complete(uint8_t subevent, uint8_t *data, int len) { struct hci_le_conn_complete evt; + int extended_offset = 0; int rc; if (len < BLE_HCI_LE_CONN_COMPLETE_LEN) { return BLE_HS_EMSGSIZE; } + /* this code processes two different events that are really similar */ + if ((subevent == BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE) && + ( len < BLE_HCI_LE_ENH_CONN_COMPLETE_LEN)) { + return BLE_HS_EMSGSIZE; + } + evt.subevent_code = data[0]; evt.status = data[1]; evt.connection_handle = le16toh(data + 2); evt.role = data[4]; evt.peer_addr_type = data[5]; memcpy(evt.peer_addr, data + 6, BLE_DEV_ADDR_LEN); - evt.conn_itvl = le16toh(data + 12); - evt.conn_latency = le16toh(data + 14); - evt.supervision_timeout = le16toh(data + 16); - evt.master_clk_acc = data[18]; + + /* enhanced connection event has the same information with these + * extra fields stuffed into the middle */ + if (subevent == BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE) { + memcpy(evt.local_rpa, data + 12, BLE_DEV_ADDR_LEN); + memcpy(evt.peer_rpa, data + 18, BLE_DEV_ADDR_LEN); + extended_offset = 12; + } else { + memset(evt.local_rpa, 0, BLE_DEV_ADDR_LEN); + memset(evt.peer_rpa, 0, BLE_DEV_ADDR_LEN); + } + + evt.conn_itvl = le16toh(data + 12 + extended_offset); + evt.conn_latency = le16toh(data + 14 + extended_offset); + evt.supervision_timeout = le16toh(data + 16 + extended_offset); + evt.master_clk_acc = data[18 + extended_offset]; if (evt.status == 0) { if (evt.role != BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER && http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/host/src/host_hci_cmd.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/host_hci_cmd.c b/net/nimble/host/src/host_hci_cmd.c index 9763974..16b6d0a 100644 --- a/net/nimble/host/src/host_hci_cmd.c +++ b/net/nimble/host/src/host_hci_cmd.c @@ -985,7 +985,7 @@ host_hci_cmd_body_add_device_to_resolving_list(uint8_t addr_type, dst[0] = addr_type; memcpy(dst + 1, addr, BLE_DEV_ADDR_LEN); memcpy(dst + 1 + 6, peer_irk , 16); - memcpy(dst + 1 + 6 + 16, peer_irk , 16); + memcpy(dst + 1 + 6 + 16, local_irk , 16); /* 16 + 16 + 6 + 1 == 39 */ return 0; } @@ -1203,7 +1203,7 @@ host_hci_cmd_set_resolvable_private_address_timeout(uint16_t timeout, int rc; BLE_HS_DBG_ASSERT( - dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_RESPRIV_ADDR_TO_LEN); + dst_len >= BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_RESOLV_PRIV_ADDR_TO_LEN); host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_RPA_TMO, BLE_HCI_SET_RESOLV_PRIV_ADDR_TO_LEN, dst); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/host/src/test/ble_hs_test_util.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/test/ble_hs_test_util.c b/net/nimble/host/src/test/ble_hs_test_util.c index 3aa6fcf..0de8842 100644 --- a/net/nimble/host/src/test/ble_hs_test_util.c +++ b/net/nimble/host/src/test/ble_hs_test_util.c @@ -425,6 +425,7 @@ int ble_hs_test_util_adv_start(uint8_t discoverable_mode, uint8_t connectable_mode, uint8_t *peer_addr, uint8_t peer_addr_type, + struct ble_gap_adv_params *adv_params, ble_gap_event_fn *cb, void *cb_arg, int fail_idx, uint8_t fail_status) { @@ -673,7 +674,22 @@ ble_hs_test_util_set_startup_acks(void) .evt_params = { 0 }, .evt_params_len = 8, }, - + { + .opcode = host_hci_opcode_join(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_SET_ADDR_RES_EN), + }, + { + .opcode = host_hci_opcode_join(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_CLR_RESOLV_LIST), + }, + { + .opcode = host_hci_opcode_join(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_SET_ADDR_RES_EN), + }, + { + .opcode = host_hci_opcode_join(BLE_HCI_OGF_LE, + BLE_HCI_OCF_LE_ADD_RESOLV_LIST), + }, { 0 } })); } @@ -757,7 +773,7 @@ ble_hs_test_util_tx_all(void) void ble_hs_test_util_set_public_addr(uint8_t *addr) { - ble_hs_priv_init_identity(addr); + ble_hs_priv_update_identity(addr); } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/34e4509a/net/nimble/include/nimble/hci_common.h ---------------------------------------------------------------------- diff --git a/net/nimble/include/nimble/hci_common.h b/net/nimble/include/nimble/hci_common.h index 67fe6e8..be72f5b 100644 --- a/net/nimble/include/nimble/hci_common.h +++ b/net/nimble/include/nimble/hci_common.h @@ -653,6 +653,8 @@ struct hci_le_conn_complete uint16_t conn_latency; uint16_t supervision_timeout; uint8_t master_clk_acc; + uint8_t local_rpa[BLE_DEV_ADDR_LEN]; + uint8_t peer_rpa[BLE_DEV_ADDR_LEN]; }; /* Connection update complete LE meta subevent */