bleprph - 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/5585ad20 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/5585ad20 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/5585ad20 Branch: refs/heads/develop Commit: 5585ad20227c32a9c1049268b8b1b2877c7b372e Parents: f3a009f Author: Christopher Collins <[email protected]> Authored: Tue May 24 17:43:30 2016 -0700 Committer: Christopher Collins <[email protected]> Committed: Wed May 25 12:16:46 2016 -0700 ---------------------------------------------------------------------- apps/bleprph/src/bleprph.h | 13 ++- apps/bleprph/src/keystore.c | 102 ------------------- apps/bleprph/src/main.c | 97 +----------------- apps/bleprph/src/misc.c | 33 ++++++ apps/bleprph/src/store.c | 141 ++++++++++++++++++++++++++ net/nimble/host/include/host/ble_store.h | 2 + net/nimble/host/src/ble_store.c | 8 ++ 7 files changed, 197 insertions(+), 199 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5585ad20/apps/bleprph/src/bleprph.h ---------------------------------------------------------------------- diff --git a/apps/bleprph/src/bleprph.h b/apps/bleprph/src/bleprph.h index 873d35b..742319f 100644 --- a/apps/bleprph/src/bleprph.h +++ b/apps/bleprph/src/bleprph.h @@ -21,6 +21,8 @@ #define H_BLEPRPH_ #include "log/log.h" +union ble_store_value; +union ble_store_key; extern struct log bleprph_log; @@ -51,9 +53,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/5585ad20/apps/bleprph/src/keystore.c ---------------------------------------------------------------------- diff --git a/apps/bleprph/src/keystore.c b/apps/bleprph/src/keystore.c deleted file mode 100644 index efa17ea..0000000 --- a/apps/bleprph/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/5585ad20/apps/bleprph/src/main.c ---------------------------------------------------------------------- diff --git a/apps/bleprph/src/main.c b/apps/bleprph/src/main.c index 96db35b..51bd7d7 100755 --- a/apps/bleprph/src/main.c +++ b/apps/bleprph/src/main.c @@ -16,6 +16,7 @@ * specific language governing permissions and limitations * under the License. */ + #include <assert.h> #include <string.h> #include <stdio.h> @@ -88,19 +89,6 @@ static int bleprph_gap_event(int event, struct ble_gap_conn_ctxt *ctxt, void *arg); /** - * Utility function to log an array of bytes. - */ -static void -bleprph_print_bytes(uint8_t *bytes, int len) -{ - int i; - - for (i = 0; i < len; i++) { - BLEPRPH_LOG(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); - } -} - -/** * Logs information about a connection to the console. */ static void @@ -109,7 +97,7 @@ bleprph_print_conn_desc(struct ble_gap_conn_desc *desc) BLEPRPH_LOG(INFO, "handle=%d peer_addr_type=%d peer_addr=", desc->conn_handle, desc->peer_addr_type); - bleprph_print_bytes(desc->peer_addr, 6); + print_bytes(desc->peer_addr, 6); BLEPRPH_LOG(INFO, " conn_itvl=%d conn_latency=%d supervision_timeout=%d " "encrypted=%d authenticated=%d", desc->conn_itvl, @@ -226,83 +214,6 @@ bleprph_gap_event(int event, struct ble_gap_conn_ctxt *ctxt, void *arg) return 0; } -static int -bleprph_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. - */ - BLEPRPH_LOG(INFO, "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; - BLEPRPH_LOG(INFO, "ltk="); - bleprph_print_bytes(dst->ltk.key, sizeof dst->ltk.key); - BLEPRPH_LOG(INFO, " authenticated=%d\n", authenticated); - } else { - BLEPRPH_LOG(INFO, "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 void -bleprph_print_key_exchange_parms(struct ble_store_value_ltk *ltk) -{ - BLEPRPH_LOG(INFO, "ediv=%u rand=%llu authenticated=%d ", ltk->ediv, - ltk->rand_num, ltk->authenticated); - BLEPRPH_LOG(INFO, "ltk="); - bleprph_print_bytes(ltk->key, 16); - BLEPRPH_LOG(INFO, "\n"); -} - -static int -bleprph_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 - * bleprph isn't restarted!). - */ - BLEPRPH_LOG(INFO, "persisting our ltk; "); - bleprph_print_key_exchange_parms(&val->ltk); - rc = keystore_add(&val->ltk); - if (rc != 0) { - BLEPRPH_LOG(INFO, "error persisting LTK; status=%d\n", rc); - } - return rc; - - default: - return BLE_HS_ENOTSUP; - } -} - /** * Event loop for the main bleprph task. */ @@ -407,8 +318,8 @@ main(void) cfg.sm_bonding = 1; cfg.sm_our_key_dist = BLE_L2CAP_SM_PAIR_KEY_DIST_ENC; cfg.sm_their_key_dist = BLE_L2CAP_SM_PAIR_KEY_DIST_ENC; - cfg.store_read_cb = bleprph_store_read; - cfg.store_write_cb = bleprph_store_write; + cfg.store_read_cb = store_read; + cfg.store_write_cb = store_write; /* Initialize eventq */ os_eventq_init(&bleprph_evq); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5585ad20/apps/bleprph/src/misc.c ---------------------------------------------------------------------- diff --git a/apps/bleprph/src/misc.c b/apps/bleprph/src/misc.c new file mode 100644 index 0000000..64dfeed --- /dev/null +++ b/apps/bleprph/src/misc.c @@ -0,0 +1,33 @@ +/** + * 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 "bleprph.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++) { + BLEPRPH_LOG(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); + } +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5585ad20/apps/bleprph/src/store.c ---------------------------------------------------------------------- diff --git a/apps/bleprph/src/store.c b/apps/bleprph/src/store.c new file mode 100644 index 0000000..0439ee6 --- /dev/null +++ b/apps/bleprph/src/store.c @@ -0,0 +1,141 @@ +/** + * 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" + +#include "bleprph.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) +{ + BLEPRPH_LOG(INFO, "ediv=%u rand=%llu authenticated=%d ", ltk->ediv, + ltk->rand_num, ltk->authenticated); + BLEPRPH_LOG(INFO, "ltk="); + print_bytes(ltk->key, 16); + BLEPRPH_LOG(INFO, "\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. + */ + BLEPRPH_LOG(INFO, "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: + BLEPRPH_LOG(INFO, "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) { + BLEPRPH_LOG(INFO, "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; + } +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5585ad20/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 8edbb01..5d54ce9 100644 --- a/net/nimble/host/include/host/ble_store.h +++ b/net/nimble/host/include/host/ble_store.h @@ -93,6 +93,8 @@ int ble_store_read_cccd(struct ble_store_key_cccd *key, int ble_store_write_cccd(struct ble_store_value_cccd *value); int ble_store_delete_cccd(struct ble_store_key_cccd *key); +void ble_store_key_from_value_ltk(struct ble_store_key_ltk *out_key, + struct ble_store_value_ltk *value); void ble_store_key_from_value_cccd(struct ble_store_key_cccd *out_key, struct ble_store_value_cccd *value); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5585ad20/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 24480c1..267e8d3 100644 --- a/net/nimble/host/src/ble_store.c +++ b/net/nimble/host/src/ble_store.c @@ -110,3 +110,11 @@ ble_store_key_from_value_cccd(struct ble_store_key_cccd *out_key, out_key->chr_val_handle = value->chr_val_handle; out_key->idx = 0; } + +void +ble_store_key_from_value_ltk(struct ble_store_key_ltk *out_key, + struct ble_store_value_ltk *value) +{ + out_key->ediv = value->ediv; + out_key->rand_num = value->rand_num; +}
