bletiny - Use new BLE host persist store.
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/355103a3 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/355103a3 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/355103a3 Branch: refs/heads/develop Commit: 355103a391333740f870819a62914f2ae2ead7e4 Parents: 5585ad2 Author: Christopher Collins <[email protected]> Authored: Tue May 24 18:39:56 2016 -0700 Committer: Christopher Collins <[email protected]> Committed: Wed May 25 12:16:46 2016 -0700 ---------------------------------------------------------------------- apps/bletiny/src/bletiny_priv.h | 15 ++-- apps/bletiny/src/keystore.c | 102 ------------------------- apps/bletiny/src/main.c | 120 +++++------------------------ apps/bletiny/src/misc.c | 34 +++++++++ apps/bletiny/src/store.c | 142 +++++++++++++++++++++++++++++++++++ 5 files changed, 202 insertions(+), 211 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/355103a3/apps/bletiny/src/bletiny_priv.h ---------------------------------------------------------------------- diff --git a/apps/bletiny/src/bletiny_priv.h b/apps/bletiny/src/bletiny_priv.h index df18890..d3be8eb 100644 --- a/apps/bletiny/src/bletiny_priv.h +++ b/apps/bletiny/src/bletiny_priv.h @@ -33,8 +33,8 @@ struct ble_gap_crt_params; struct hci_adv_params; struct ble_l2cap_sig_update_req; struct ble_l2cap_sig_update_params; -struct ble_store_key_ltk; -struct ble_store_value_ltk; +union ble_store_value; +union ble_store_key; typedef int cmd_fn(int argc, char **argv); struct cmd_entry { @@ -187,9 +187,12 @@ extern const uint8_t gatt_svr_chr_bleprph_write[16]; void gatt_svr_init(void); -/** Keystore. */ -int keystore_lookup(struct ble_store_key_ltk *store_key, uint8_t *out_ltk, - int *out_authenticated); -int keystore_add(struct ble_store_value_ltk *store_value); +/** Store. */ +int store_read(int obj_type, union ble_store_key *key, + union ble_store_value *dst); +int store_write(int obj_type, union ble_store_value *val); + +/** Misc. */ +void print_bytes(uint8_t *bytes, int len); #endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/355103a3/apps/bletiny/src/keystore.c ---------------------------------------------------------------------- diff --git a/apps/bletiny/src/keystore.c b/apps/bletiny/src/keystore.c deleted file mode 100644 index efa17ea..0000000 --- a/apps/bletiny/src/keystore.c +++ /dev/null @@ -1,102 +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. - */ - -/** - * This file implements a simple in-RAM key database for long-term keys. A key - * is inserted into the database immediately after a successful pairing - * procedure. A key is retrieved from the database when the central performs - * the encryption procedure (bonding). - * - * As this database is only stored in RAM, its contents are lost if bleprph is - * restarted. - */ - -#include <inttypes.h> -#include <string.h> - -#include "host/ble_hs.h" - -#define KEYSTORE_MAX_ENTRIES 4 - -struct keystore_entry { - uint64_t rand_num; - uint16_t ediv; - uint8_t ltk[16]; - - unsigned authenticated:1; - - /* XXX: authreq. */ -}; - -static struct keystore_entry keystore_entries[KEYSTORE_MAX_ENTRIES]; -static int keystore_num_entries; - -/** - * Searches the database for a long-term key matching the specified criteria. - * - * @return 0 if a key was found; else BLE_HS_ENOENT. - */ -int -keystore_lookup(struct ble_store_key_ltk *store_key, uint8_t *out_ltk, - int *out_authenticated) -{ - struct keystore_entry *entry; - int i; - - for (i = 0; i < keystore_num_entries; i++) { - entry = keystore_entries + i; - - if (entry->ediv == store_key->ediv && - entry->rand_num == store_key->rand_num) { - - memcpy(out_ltk, entry->ltk, sizeof entry->ltk); - *out_authenticated = entry->authenticated; - - return 0; - } - } - - return BLE_HS_ENOENT; -} - -/** - * Adds the specified key to the database. - * - * @return 0 on success; BLE_HS_ENOMEM if the database is - * full. - */ -int -keystore_add(struct ble_store_value_ltk *store_value) -{ - struct keystore_entry *entry; - - if (keystore_num_entries >= KEYSTORE_MAX_ENTRIES) { - return BLE_HS_ENOMEM; - } - - entry = keystore_entries + keystore_num_entries; - keystore_num_entries++; - - entry->ediv = store_value->ediv; - entry->rand_num = store_value->rand_num; - memcpy(entry->ltk, store_value->key, sizeof entry->ltk); - entry->authenticated = store_value->authenticated; - - return 0; -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/355103a3/apps/bletiny/src/main.c ---------------------------------------------------------------------- diff --git a/apps/bletiny/src/main.c b/apps/bletiny/src/main.c index 7a5b073..6797b53 100755 --- a/apps/bletiny/src/main.c +++ b/apps/bletiny/src/main.c @@ -145,21 +145,11 @@ bletiny_print_error(char *msg, uint16_t conn_handle, } static void -bletiny_print_bytes(uint8_t *bytes, int len) -{ - int i; - - for (i = 0; i < len; i++) { - console_printf("%s0x%02x", i != 0 ? ":" : "", bytes[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); - bletiny_print_bytes(desc->peer_addr, 6); + print_bytes(desc->peer_addr, 6); 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, @@ -170,16 +160,6 @@ bletiny_print_conn_desc(struct ble_gap_conn_desc *desc) } static void -bletiny_print_key_exchange_parms(struct ble_store_value_ltk *ltk) -{ - console_printf("ediv=%u rand=%llu authenticated=%d ", ltk->ediv, - ltk->rand_num, ltk->authenticated); - console_printf("ltk="); - bletiny_print_bytes(ltk->key, 16); - console_printf("\n"); -} - -static void bletiny_print_adv_fields(struct ble_hs_adv_fields *fields) { uint32_t u32; @@ -237,21 +217,21 @@ bletiny_print_adv_fields(struct ble_hs_adv_fields *fields) if (fields->device_class != NULL) { console_printf(" device_class="); - bletiny_print_bytes(fields->device_class, + print_bytes(fields->device_class, BLE_HS_ADV_DEVICE_CLASS_LEN); console_printf("\n"); } if (fields->slave_itvl_range != NULL) { console_printf(" slave_itvl_range="); - bletiny_print_bytes(fields->slave_itvl_range, + print_bytes(fields->slave_itvl_range, BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN); console_printf("\n"); } if (fields->svc_data_uuid16 != NULL) { console_printf(" svc_data_uuid16="); - bletiny_print_bytes(fields->svc_data_uuid16, + print_bytes(fields->svc_data_uuid16, fields->svc_data_uuid16_len); console_printf("\n"); } @@ -276,7 +256,7 @@ bletiny_print_adv_fields(struct ble_hs_adv_fields *fields) if (fields->le_addr != NULL) { console_printf(" le_addr="); - bletiny_print_bytes(fields->le_addr, BLE_HS_ADV_LE_ADDR_LEN); + print_bytes(fields->le_addr, BLE_HS_ADV_LE_ADDR_LEN); console_printf("\n"); } @@ -286,27 +266,27 @@ bletiny_print_adv_fields(struct ble_hs_adv_fields *fields) if (fields->svc_data_uuid32 != NULL) { console_printf(" svc_data_uuid32="); - bletiny_print_bytes(fields->svc_data_uuid32, + print_bytes(fields->svc_data_uuid32, fields->svc_data_uuid32_len); console_printf("\n"); } if (fields->svc_data_uuid128 != NULL) { console_printf(" svc_data_uuid128="); - bletiny_print_bytes(fields->svc_data_uuid128, + print_bytes(fields->svc_data_uuid128, fields->svc_data_uuid128_len); console_printf("\n"); } if (fields->uri != NULL) { console_printf(" uri="); - bletiny_print_bytes(fields->uri, fields->uri_len); + print_bytes(fields->uri, fields->uri_len); console_printf("\n"); } if (fields->mfg_data != NULL) { console_printf(" mfg_data="); - bletiny_print_bytes(fields->mfg_data, fields->mfg_data_len); + print_bytes(fields->mfg_data, fields->mfg_data_len); console_printf("\n"); } } @@ -745,7 +725,7 @@ bletiny_on_read(uint16_t conn_handle, struct ble_gatt_error *error, console_printf("characteristic read; conn_handle=%d " "attr_handle=%d len=%d value=", conn_handle, attr->handle, attr->value_len); - bletiny_print_bytes(attr->value, attr->value_len); + print_bytes(attr->value, attr->value_len); console_printf("\n"); } else { console_printf("characteristic read complete\n"); @@ -764,7 +744,7 @@ bletiny_on_write(uint16_t conn_handle, struct ble_gatt_error *error, console_printf("characteristic write complete; conn_handle=%d " "attr_handle=%d len=%d value=", conn_handle, attr->handle, attr->value_len); - bletiny_print_bytes(attr->value, attr->value_len); + print_bytes(attr->value, attr->value_len); console_printf("\n"); } @@ -787,7 +767,7 @@ bletiny_on_write_reliable(uint16_t conn_handle, struct ble_gatt_error *error, for (i = 0; i < num_attrs; i++) { console_printf(" attr_handle=%d len=%d value=", attrs[i].handle, attrs[i].value_len); - bletiny_print_bytes(attrs[i].value, attrs[i].value_len); + print_bytes(attrs[i].value, attrs[i].value_len); } console_printf("\n"); } @@ -859,7 +839,7 @@ bletiny_gap_event(int event, struct ble_gap_conn_ctxt *ctxt, void *arg) ctxt->notify.attr_handle, ctxt->notify.indication, ctxt->notify.attr_len); - bletiny_print_bytes(ctxt->notify.attr_data, ctxt->notify.attr_len); + print_bytes(ctxt->notify.attr_data, ctxt->notify.attr_len); console_printf("\n"); return 0; @@ -868,72 +848,6 @@ bletiny_gap_event(int event, struct ble_gap_conn_ctxt *ctxt, void *arg) } } -static int -bletiny_store_read(int obj_type, union ble_store_key *key, - union ble_store_value *dst) -{ - int authenticated; - int rc; - - switch (obj_type) { - case BLE_STORE_OBJ_TYPE_OUR_LTK: - /* An encryption procedure (bonding) is being attempted. The nimble - * stack is asking us to look in our key database for a long-term key - * corresponding to the specified ediv and random number. - */ - console_printf("looking up ltk with ediv=0x%02x rand=0x%llx\n", - key->ltk.ediv, key->ltk.rand_num); - - /* Perform a key lookup and populate the context object with the - * result. The nimble stack will use this key if this function returns - * success. - */ - rc = keystore_lookup(&key->ltk, dst->ltk.key, &authenticated); - if (rc == 0) { - dst->ltk.authenticated = authenticated; - console_printf("ltk="); - bletiny_print_bytes(dst->ltk.key, sizeof dst->ltk.key); - console_printf(" authenticated=%d\n", authenticated); - } else { - console_printf("no matching ltk\n"); - } - - /* Indicate whether we were able to find an appropriate key. */ - if (rc != 0) { - return rc; - } - - return 0; - - default: - return BLE_HS_ENOTSUP; - } -} - -static int -bletiny_store_write(int obj_type, union ble_store_value *val) -{ - int rc; - - switch (obj_type) { - case BLE_STORE_OBJ_TYPE_OUR_LTK: - /* The central is sending us key information. Save the long-term key - * in the in-RAM database. This permits bonding to occur on subsequent - * connections with this peer (as long as bletiny isn't restarted!). - */ - console_printf("persisting our ltk; "); - bletiny_print_key_exchange_parms(&val->ltk); - rc = keystore_add(&val->ltk); - if (rc != 0) { - console_printf("error persisting ltk; status=%d\n", rc); - } - return rc; - - default: - return BLE_HS_ENOTSUP; - } -} - static void bletiny_on_l2cap_update(int status, void *arg) { @@ -948,10 +862,10 @@ 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); - bletiny_print_bytes(desc->addr, 6); + print_bytes(desc->addr, 6); console_printf(" length_data=%d rssi=%d data=", desc->length_data, desc->rssi); - bletiny_print_bytes(desc->data, desc->length_data); + print_bytes(desc->data, desc->length_data); console_printf(" fields:\n"); bletiny_print_adv_fields(desc->fields); console_printf("\n"); @@ -1403,8 +1317,8 @@ main(void) cfg.max_gattc_procs = 2; cfg.max_l2cap_chans = NIMBLE_OPT(MAX_CONNECTIONS) * 3; cfg.max_l2cap_sig_procs = 2; - cfg.store_read_cb = bletiny_store_read; - cfg.store_write_cb = bletiny_store_write; + cfg.store_read_cb = store_read; + cfg.store_write_cb = store_write; rc = ble_hs_init(&bletiny_evq, &cfg); assert(rc == 0); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/355103a3/apps/bletiny/src/misc.c ---------------------------------------------------------------------- diff --git a/apps/bletiny/src/misc.c b/apps/bletiny/src/misc.c new file mode 100644 index 0000000..702c6cb --- /dev/null +++ b/apps/bletiny/src/misc.c @@ -0,0 +1,34 @@ +/** + * 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 "console/console.h" +#include "bletiny_priv.h" + +/** + * Utility function to log an array of bytes. + */ +void +print_bytes(uint8_t *bytes, int len) +{ + int i; + + for (i = 0; i < len; i++) { + console_printf("%s0x%02x", i != 0 ? ":" : "", bytes[i]); + } +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/355103a3/apps/bletiny/src/store.c ---------------------------------------------------------------------- diff --git a/apps/bletiny/src/store.c b/apps/bletiny/src/store.c new file mode 100644 index 0000000..b714d2d --- /dev/null +++ b/apps/bletiny/src/store.c @@ -0,0 +1,142 @@ +/** + * 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. + */ + +/** + * This file implements a simple in-RAM key database for long-term keys. A key + * is inserted into the database immediately after a successful pairing + * procedure. A key is retrieved from the database when the central performs + * the encryption procedure (bonding). + * + * As this database is only stored in RAM, its contents are lost if bleprph is + * restarted. + */ + +#include <inttypes.h> +#include <string.h> + +#include "console/console.h" +#include "host/ble_hs.h" + +#include "bletiny_priv.h" + +#define STORE_MAX_OUR_LTKS 4 + +static struct ble_store_value_ltk store_our_ltks[STORE_MAX_OUR_LTKS]; +static int store_num_our_ltks; + +static int +store_find_our_ltk(struct ble_store_key_ltk *key_ltk) +{ + struct ble_store_value_ltk *cur; + int i; + + for (i = 0; i < store_num_our_ltks; i++) { + cur = store_our_ltks + i; + + if (cur->ediv == key_ltk->ediv && + cur->rand_num == key_ltk->rand_num) { + + return i; + } + } + + return -1; +} + +static void +store_print_ltk(struct ble_store_value_ltk *ltk) +{ + console_printf("ediv=%u rand=%llu authenticated=%d ", ltk->ediv, + ltk->rand_num, ltk->authenticated); + console_printf("ltk="); + print_bytes(ltk->key, 16); + console_printf("\n"); +} + +/** + * Searches the database for a long-term key matching the specified criteria. + * + * @return 0 if a key was found; else BLE_HS_ENOENT. + */ +int +store_read(int obj_type, union ble_store_key *key, union ble_store_value *dst) +{ + int idx; + + switch (obj_type) { + case BLE_STORE_OBJ_TYPE_OUR_LTK: + /* An encryption procedure (bonding) is being attempted. The nimble + * stack is asking us to look in our key database for a long-term key + * corresponding to the specified ediv and random number. + */ + console_printf("looking up ltk with ediv=0x%02x rand=0x%llx\n", + key->ltk.ediv, key->ltk.rand_num); + + /* Perform a key lookup and populate the context object with the + * result. The nimble stack will use this key if this function returns + * success. + */ + idx = store_find_our_ltk(&key->ltk); + if (idx == -1) { + return BLE_HS_ENOENT; + } + dst->ltk = store_our_ltks[idx]; + return 0; + + default: + return BLE_HS_ENOTSUP; + } +} + +/** + * Adds the specified key to the database. + * + * @return 0 on success; BLE_HS_ENOMEM if the database is + * full. + */ +int +store_write(int obj_type, union ble_store_value *val) +{ + struct ble_store_key_ltk key_ltk; + int idx; + + switch (obj_type) { + case BLE_STORE_OBJ_TYPE_OUR_LTK: + console_printf("persisting our ltk; "); + store_print_ltk(&val->ltk); + + ble_store_key_from_value_ltk(&key_ltk, &val->ltk); + idx = store_find_our_ltk(&key_ltk); + if (idx == -1) { + if (store_num_our_ltks >= STORE_MAX_OUR_LTKS) { + console_printf("error persisting LTK; too many entries\n"); + return BLE_HS_ENOMEM; + } + + idx = store_num_our_ltks; + store_num_our_ltks++; + } + + store_our_ltks[idx] = val->ltk; + return 0; + + default: + return BLE_HS_ENOTSUP; + } +}
