summaryrefslogtreecommitdiff
path: root/src/libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c
diff options
context:
space:
mode:
authorJF <jf@codingfield.com>2020-04-26 10:25:59 +0200
committerJF <jf@codingfield.com>2020-04-26 10:25:59 +0200
commitbdc10744fb338ae197692713a0b48a7ccc36f566 (patch)
treeaf7a8f2f16ddd2e5483758effec15c7683f6c453 /src/libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c
parent032fad094c6411ad3ff4321ad61ceed95d7dc4ff (diff)
Add Nimble in libs directory
Diffstat (limited to 'src/libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c')
-rw-r--r--src/libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c254
1 files changed, 254 insertions, 0 deletions
diff --git a/src/libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c b/src/libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c
new file mode 100644
index 00000000..bb2d66d5
--- /dev/null
+++ b/src/libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c
@@ -0,0 +1,254 @@
+/*
+ * 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 <string.h>
+#include <errno.h>
+#include "nimble/ble.h"
+#include "nimble/nimble_opt.h"
+#include "host/ble_sm.h"
+#include "ble_hs_priv.h"
+
+#if MYNEWT_VAL(BLE_SM_LEGACY)
+
+/**
+ * Create some shortened names for the passkey actions so that the table is
+ * easier to read.
+ */
+#define IOACT_NONE BLE_SM_IOACT_NONE
+#define IOACT_OOB BLE_SM_IOACT_OOB
+#define IOACT_INPUT BLE_SM_IOACT_INPUT
+#define IOACT_DISP BLE_SM_IOACT_DISP
+
+/* This is the initiator passkey action action dpeneding on the io
+ * capabilties of both parties
+ */
+static const uint8_t ble_sm_lgcy_init_ioa[5 /*resp*/ ][5 /*init*/ ] =
+{
+ {IOACT_NONE, IOACT_NONE, IOACT_INPUT, IOACT_NONE, IOACT_INPUT},
+ {IOACT_NONE, IOACT_NONE, IOACT_INPUT, IOACT_NONE, IOACT_INPUT},
+ {IOACT_DISP, IOACT_DISP, IOACT_INPUT, IOACT_NONE, IOACT_DISP},
+ {IOACT_NONE, IOACT_NONE, IOACT_NONE, IOACT_NONE, IOACT_NONE},
+ {IOACT_DISP, IOACT_DISP, IOACT_INPUT, IOACT_NONE, IOACT_DISP},
+};
+
+/* This is the responder passkey action action depending on the io
+ * capabilities of both parties
+ */
+static const uint8_t ble_sm_lgcy_resp_ioa[5 /*resp*/ ][5 /*init*/ ] =
+{
+ {IOACT_NONE, IOACT_NONE, IOACT_DISP, IOACT_NONE, IOACT_DISP},
+ {IOACT_NONE, IOACT_NONE, IOACT_DISP, IOACT_NONE, IOACT_DISP},
+ {IOACT_INPUT, IOACT_INPUT, IOACT_INPUT, IOACT_NONE, IOACT_INPUT},
+ {IOACT_NONE, IOACT_NONE, IOACT_NONE, IOACT_NONE, IOACT_NONE},
+ {IOACT_INPUT, IOACT_INPUT, IOACT_DISP, IOACT_NONE, IOACT_INPUT},
+};
+
+int
+ble_sm_lgcy_io_action(struct ble_sm_proc *proc, uint8_t *action)
+{
+ struct ble_sm_pair_cmd *pair_req, *pair_rsp;
+
+ pair_req = (struct ble_sm_pair_cmd *) &proc->pair_req[1];
+ pair_rsp = (struct ble_sm_pair_cmd *) &proc->pair_rsp[1];
+
+ if (pair_req->oob_data_flag == BLE_SM_PAIR_OOB_YES &&
+ pair_rsp->oob_data_flag == BLE_SM_PAIR_OOB_YES) {
+ *action = BLE_SM_IOACT_OOB;
+ } else if (!(pair_req->authreq & BLE_SM_PAIR_AUTHREQ_MITM) &&
+ !(pair_rsp->authreq & BLE_SM_PAIR_AUTHREQ_MITM)) {
+
+ *action = BLE_SM_IOACT_NONE;
+ } else if (pair_req->io_cap >= BLE_SM_IO_CAP_RESERVED ||
+ pair_rsp->io_cap >= BLE_SM_IO_CAP_RESERVED) {
+ *action = BLE_SM_IOACT_NONE;
+ } else if (proc->flags & BLE_SM_PROC_F_INITIATOR) {
+ *action = ble_sm_lgcy_init_ioa[pair_rsp->io_cap][pair_req->io_cap];
+ } else {
+ *action = ble_sm_lgcy_resp_ioa[pair_rsp->io_cap][pair_req->io_cap];
+ }
+
+ switch (*action) {
+ case BLE_SM_IOACT_NONE:
+ proc->pair_alg = BLE_SM_PAIR_ALG_JW;
+ break;
+
+ case BLE_SM_IOACT_OOB:
+ proc->pair_alg = BLE_SM_PAIR_ALG_OOB;
+ proc->flags |= BLE_SM_PROC_F_AUTHENTICATED;
+ break;
+
+ case BLE_SM_IOACT_INPUT:
+ case BLE_SM_IOACT_DISP:
+ proc->pair_alg = BLE_SM_PAIR_ALG_PASSKEY;
+ proc->flags |= BLE_SM_PROC_F_AUTHENTICATED;
+ break;
+
+ default:
+ BLE_HS_DBG_ASSERT(0);
+ return BLE_HS_EINVAL;
+ }
+
+ return 0;
+}
+
+void
+ble_sm_lgcy_confirm_exec(struct ble_sm_proc *proc, struct ble_sm_result *res)
+{
+ struct ble_sm_pair_confirm *cmd;
+ struct os_mbuf *txom;
+ uint8_t ia[6];
+ uint8_t ra[6];
+ uint8_t iat;
+ uint8_t rat;
+ int rc;
+
+ cmd = ble_sm_cmd_get(BLE_SM_OP_PAIR_CONFIRM, sizeof(*cmd), &txom);
+ if (cmd == NULL) {
+ rc = BLE_HS_ENOMEM;
+ goto err;
+ }
+
+ ble_sm_ia_ra(proc, &iat, ia, &rat, ra);
+
+ rc = ble_sm_alg_c1(proc->tk, ble_sm_our_pair_rand(proc), proc->pair_req,
+ proc->pair_rsp, iat, rat, ia, ra, cmd->value);
+ if (rc != 0) {
+ goto err;
+ }
+
+ rc = ble_sm_tx(proc->conn_handle, txom);
+ if (rc != 0) {
+ goto err;
+ }
+
+ if (!(proc->flags & BLE_SM_PROC_F_INITIATOR)) {
+ proc->state = BLE_SM_PROC_STATE_RANDOM;
+ }
+
+ return;
+
+err:
+ if (txom) {
+ os_mbuf_free_chain(txom);
+ }
+
+ res->app_status = rc;
+ res->enc_cb = 1;
+ res->sm_err = BLE_SM_ERR_UNSPECIFIED;
+}
+
+static int
+ble_sm_gen_stk(struct ble_sm_proc *proc)
+{
+ uint8_t key[16];
+ int rc;
+
+ rc = ble_sm_alg_s1(proc->tk, proc->rands, proc->randm, key);
+ if (rc != 0) {
+ return rc;
+ }
+
+ memcpy(proc->ltk, key, proc->key_size);
+
+ /* Ensure proper key size */
+ memset(proc->ltk + proc->key_size, 0, sizeof key - proc->key_size);
+
+ return 0;
+}
+
+void
+ble_sm_lgcy_random_exec(struct ble_sm_proc *proc, struct ble_sm_result *res)
+{
+ struct ble_sm_pair_random *cmd;
+ struct os_mbuf *txom;
+ int rc;
+
+ cmd = ble_sm_cmd_get(BLE_SM_OP_PAIR_RANDOM, sizeof(*cmd), &txom);
+ if (cmd == NULL) {
+ res->app_status = BLE_HS_ENOMEM;
+ res->enc_cb = 1;
+ res->sm_err = BLE_SM_ERR_UNSPECIFIED;
+ return;
+ }
+
+ memcpy(cmd->value, ble_sm_our_pair_rand(proc), 16);
+
+ rc = ble_sm_tx(proc->conn_handle, txom);
+ if (rc != 0) {
+ res->app_status = rc;
+ res->enc_cb = 1;
+ res->sm_err = BLE_SM_ERR_UNSPECIFIED;
+ return;
+ }
+
+ if (!(proc->flags & BLE_SM_PROC_F_INITIATOR)) {
+ proc->state = BLE_SM_PROC_STATE_LTK_START;
+ }
+}
+
+void
+ble_sm_lgcy_random_rx(struct ble_sm_proc *proc, struct ble_sm_result *res)
+{
+ uint8_t confirm_val[16];
+ uint8_t ia[6];
+ uint8_t ra[6];
+ uint8_t iat;
+ uint8_t rat;
+ int rc;
+
+ ble_sm_ia_ra(proc, &iat, ia, &rat, ra);
+
+ rc = ble_sm_alg_c1(proc->tk, ble_sm_peer_pair_rand(proc), proc->pair_req,
+ proc->pair_rsp, iat, rat, ia, ra, confirm_val);
+ if (rc != 0) {
+ res->app_status = rc;
+ res->sm_err = BLE_SM_ERR_UNSPECIFIED;
+ res->enc_cb = 1;
+ return;
+ }
+
+ if (memcmp(proc->confirm_peer, confirm_val, 16) != 0) {
+ /* Random number mismatch. */
+ res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_CONFIRM_MISMATCH);
+ res->sm_err = BLE_SM_ERR_CONFIRM_MISMATCH;
+ res->enc_cb = 1;
+ return;
+ }
+
+ /* Generate the key. */
+ rc = ble_sm_gen_stk(proc);
+ if (rc != 0) {
+ res->app_status = rc;
+ res->sm_err = BLE_SM_ERR_UNSPECIFIED;
+ res->enc_cb = 1;
+ return;
+ }
+
+ if (proc->flags & BLE_SM_PROC_F_INITIATOR) {
+ /* Send the start-encrypt HCI command to the controller. For
+ * short-term key generation, we always set ediv and rand to 0.
+ * (Vol. 3, part H, 2.4.4.1).
+ */
+ proc->state = BLE_SM_PROC_STATE_ENC_START;
+ }
+
+ res->execute = 1;
+}
+
+#endif