diff options
author | JF <jf@codingfield.com> | 2020-04-26 10:25:59 +0200 |
---|---|---|
committer | JF <jf@codingfield.com> | 2020-04-26 10:25:59 +0200 |
commit | bdc10744fb338ae197692713a0b48a7ccc36f566 (patch) | |
tree | af7a8f2f16ddd2e5483758effec15c7683f6c453 /src/libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c | |
parent | 032fad094c6411ad3ff4321ad61ceed95d7dc4ff (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.c | 254 |
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 |