| /* |
| * 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_SM_PRIV_ |
| #define H_BLE_SM_PRIV_ |
| |
| #include <inttypes.h> |
| #include "syscfg/syscfg.h" |
| #include "os/queue.h" |
| #include "nimble/nimble_opt.h" |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| struct ble_gap_sec_state; |
| struct hci_le_lt_key_req; |
| struct hci_encrypt_change; |
| |
| #define BLE_SM_MTU 65 |
| |
| #define BLE_SM_OP_PAIR_REQ 0x01 |
| #define BLE_SM_OP_PAIR_RSP 0x02 |
| #define BLE_SM_OP_PAIR_CONFIRM 0x03 |
| #define BLE_SM_OP_PAIR_RANDOM 0x04 |
| #define BLE_SM_OP_PAIR_FAIL 0x05 |
| #define BLE_SM_OP_ENC_INFO 0x06 |
| #define BLE_SM_OP_MASTER_ID 0x07 |
| #define BLE_SM_OP_IDENTITY_INFO 0x08 |
| #define BLE_SM_OP_IDENTITY_ADDR_INFO 0x09 |
| #define BLE_SM_OP_SIGN_INFO 0x0a |
| #define BLE_SM_OP_SEC_REQ 0x0b |
| #define BLE_SM_OP_PAIR_PUBLIC_KEY 0x0c |
| #define BLE_SM_OP_PAIR_DHKEY_CHECK 0x0d |
| #define BLE_SM_OP_PAIR_KEYPRESS_NOTIFY 0x0e |
| |
| struct ble_sm_hdr { |
| uint8_t opcode; |
| uint8_t data[0]; |
| } __attribute__((packed)); |
| |
| /** |
| * | Parameter | Size (octets) | |
| * +------------------------------------+-------------------+ |
| * | (Code=0x01/0x02 [req/rsp]) | 1 | |
| * | IO Capability | 1 | |
| * | OOB data flag | 1 | |
| * | AuthReq | 1 | |
| * | Maximum Encryption Key Size | 1 | |
| * | Initiator Key Distribution | 1 | |
| * | Responder Key Distribution | 1 | |
| */ |
| |
| struct ble_sm_pair_cmd { |
| uint8_t io_cap; |
| uint8_t oob_data_flag; |
| uint8_t authreq; |
| uint8_t max_enc_key_size; |
| uint8_t init_key_dist; |
| uint8_t resp_key_dist; |
| } __attribute__((packed)); |
| |
| /** |
| * | Parameter | Size (octets) | |
| * +------------------------------------+-------------------+ |
| * | (Code=0x03) | 1 | |
| * | Confirm Value | 16 | |
| */ |
| |
| struct ble_sm_pair_confirm { |
| uint8_t value[16]; |
| } __attribute__((packed)); |
| |
| /** |
| * | Parameter | Size (octets) | |
| * +------------------------------------+-------------------+ |
| * | (Code=0x04) | 1 | |
| * | Random Value | 16 | |
| */ |
| struct ble_sm_pair_random { |
| uint8_t value[16]; |
| } __attribute__((packed)); |
| |
| /** |
| * | Parameter | Size (octets) | |
| * +------------------------------------+-------------------+ |
| * | (Code=0x05) | 1 | |
| * | Reason | 1 | |
| */ |
| struct ble_sm_pair_fail { |
| uint8_t reason; |
| } __attribute__((packed)); |
| |
| /** |
| * | Parameter | Size (octets) | |
| * +------------------------------------+-------------------+ |
| * | (Code=0x06) | 1 | |
| * | ltk | 16 | |
| */ |
| struct ble_sm_enc_info { |
| uint8_t ltk[16]; |
| } __attribute__((packed)); |
| |
| /** |
| * | Parameter | Size (octets) | |
| * +------------------------------------+-------------------+ |
| * | (Code=0x07) | 1 | |
| * | EDIV | 2 | |
| * | RAND | 8 | |
| */ |
| struct ble_sm_master_id { |
| uint16_t ediv; |
| uint64_t rand_val; |
| } __attribute__((packed)); |
| |
| /** |
| * | Parameter | Size (octets) | |
| * +------------------------------------+-------------------+ |
| * | (Code=0x08) | 1 | |
| * | irk | 16 | |
| */ |
| struct ble_sm_id_info { |
| uint8_t irk[16]; |
| } __attribute__((packed)); |
| |
| /** |
| * | Parameter | Size (octets) | |
| * +------------------------------------+-------------------+ |
| * | (Code=0x09) | 1 | |
| * | addr_type | 1 | |
| * | address | 6 | |
| */ |
| struct ble_sm_id_addr_info { |
| uint8_t addr_type; |
| uint8_t bd_addr[6]; |
| } __attribute__((packed)); |
| |
| /** |
| * | Parameter | Size (octets) | |
| * +------------------------------------+-------------------+ |
| * | (Code=0x0A) | 1 | |
| * | csrk | 16 | |
| */ |
| struct ble_sm_sign_info { |
| uint8_t sig_key[16]; |
| } __attribute__((packed)); |
| |
| /** |
| * | Parameter | Size (octets) | |
| * +------------------------------------+-------------------+ |
| * | (Code=0x0B) | 1 | |
| * | authreq | 1 | |
| */ |
| struct ble_sm_sec_req { |
| uint8_t authreq; |
| } __attribute__((packed)); |
| |
| /** |
| * | Parameter | Size (octets) | |
| * +------------------------------------+-------------------+ |
| * | (Code=0x0c) | 1 | |
| * | Public Key X | 32 | |
| * | Public Key Y | 32 | |
| */ |
| struct ble_sm_public_key { |
| uint8_t x[32]; |
| uint8_t y[32]; |
| } __attribute__((packed)); |
| |
| /** |
| * | Parameter | Size (octets) | |
| * +------------------------------------+-------------------+ |
| * | (Code=0x0d) | 1 | |
| * | DHKey Check | 16 | |
| */ |
| struct ble_sm_dhkey_check { |
| uint8_t value[16]; |
| } __attribute__((packed)); |
| |
| #if NIMBLE_BLE_SM |
| |
| #define BLE_SM_PROC_STATE_NONE ((uint8_t)-1) |
| |
| #define BLE_SM_PROC_STATE_PAIR 0 |
| #define BLE_SM_PROC_STATE_CONFIRM 1 |
| #define BLE_SM_PROC_STATE_RANDOM 2 |
| #define BLE_SM_PROC_STATE_LTK_START 3 |
| #define BLE_SM_PROC_STATE_LTK_RESTORE 4 |
| #define BLE_SM_PROC_STATE_ENC_START 5 |
| #define BLE_SM_PROC_STATE_ENC_RESTORE 6 |
| #define BLE_SM_PROC_STATE_KEY_EXCH 7 |
| #define BLE_SM_PROC_STATE_SEC_REQ 8 |
| #define BLE_SM_PROC_STATE_PUBLIC_KEY 9 |
| #define BLE_SM_PROC_STATE_DHKEY_CHECK 10 |
| #define BLE_SM_PROC_STATE_CNT 11 |
| |
| #define BLE_SM_PROC_F_INITIATOR 0x01 |
| #define BLE_SM_PROC_F_IO_INJECTED 0x02 |
| #define BLE_SM_PROC_F_ADVANCE_ON_IO 0x04 |
| #define BLE_SM_PROC_F_AUTHENTICATED 0x08 |
| #define BLE_SM_PROC_F_SC 0x10 |
| #define BLE_SM_PROC_F_BONDING 0x20 |
| |
| #define BLE_SM_KE_F_ENC_INFO 0x01 |
| #define BLE_SM_KE_F_MASTER_ID 0x02 |
| #define BLE_SM_KE_F_ID_INFO 0x04 |
| #define BLE_SM_KE_F_ADDR_INFO 0x08 |
| #define BLE_SM_KE_F_SIGN_INFO 0x10 |
| |
| typedef uint8_t ble_sm_proc_flags; |
| |
| struct ble_sm_keys { |
| unsigned ltk_valid:1; |
| unsigned ediv_rand_valid:1; |
| unsigned irk_valid:1; |
| unsigned csrk_valid:1; |
| unsigned addr_valid:1; |
| uint16_t ediv; |
| uint64_t rand_val; |
| uint8_t addr_type; |
| uint8_t key_size; |
| uint8_t ltk[16]; /* Little endian. */ |
| uint8_t irk[16]; /* Little endian. */ |
| uint8_t csrk[16]; /* Little endian. */ |
| uint8_t addr[6]; /* Little endian. */ |
| }; |
| |
| struct ble_sm_proc { |
| STAILQ_ENTRY(ble_sm_proc) next; |
| |
| ble_npl_time_t exp_os_ticks; |
| ble_sm_proc_flags flags; |
| uint16_t conn_handle; |
| uint8_t pair_alg; |
| uint8_t state; |
| uint8_t rx_key_flags; |
| uint8_t key_size; |
| |
| uint8_t pair_req[sizeof(struct ble_sm_hdr) + sizeof(struct ble_sm_pair_cmd)]; |
| uint8_t pair_rsp[sizeof(struct ble_sm_hdr) + sizeof(struct ble_sm_pair_cmd)]; |
| uint8_t tk[16]; |
| uint8_t confirm_peer[16]; |
| uint8_t randm[16]; |
| uint8_t rands[16]; |
| uint8_t ltk[16]; /* Little endian. */ |
| struct ble_sm_keys our_keys; |
| struct ble_sm_keys peer_keys; |
| |
| #if MYNEWT_VAL(BLE_SM_SC) |
| /* Secure connections. */ |
| uint8_t passkey_bits_exchanged; |
| uint8_t ri; |
| struct ble_sm_public_key pub_key_peer; |
| uint8_t mackey[16]; |
| uint8_t dhkey[32]; |
| const struct ble_sm_sc_oob_data *oob_data_local; |
| const struct ble_sm_sc_oob_data *oob_data_remote; |
| #endif |
| }; |
| |
| struct ble_sm_result { |
| int app_status; |
| uint8_t sm_err; |
| struct ble_gap_passkey_params passkey_params; |
| void *state_arg; |
| unsigned execute : 1; |
| unsigned enc_cb : 1; |
| unsigned bonded : 1; |
| unsigned restore : 1; |
| }; |
| |
| #if MYNEWT_VAL(BLE_HS_DEBUG) |
| void ble_sm_dbg_set_next_pair_rand(uint8_t *next_pair_rand); |
| void ble_sm_dbg_set_next_ediv(uint16_t next_ediv); |
| void ble_sm_dbg_set_next_master_id_rand(uint64_t next_master_id_rand); |
| void ble_sm_dbg_set_next_ltk(uint8_t *next_ltk); |
| void ble_sm_dbg_set_next_csrk(uint8_t *next_csrk); |
| void ble_sm_dbg_set_sc_keys(uint8_t *pubkey, uint8_t *privkey); |
| #endif |
| |
| int ble_sm_num_procs(void); |
| |
| int ble_sm_alg_s1(const uint8_t *k, const uint8_t *r1, const uint8_t *r2, |
| uint8_t *out); |
| int ble_sm_alg_c1(const uint8_t *k, const uint8_t *r, |
| const uint8_t *preq, const uint8_t *pres, |
| uint8_t iat, uint8_t rat, |
| const uint8_t *ia, const uint8_t *ra, |
| uint8_t *out_enc_data); |
| int ble_sm_alg_f4(const uint8_t *u, const uint8_t *v, const uint8_t *x, |
| uint8_t z, uint8_t *out_enc_data); |
| int ble_sm_alg_g2(const uint8_t *u, const uint8_t *v, const uint8_t *x, |
| const uint8_t *y, uint32_t *passkey); |
| int ble_sm_alg_f5(const uint8_t *w, const uint8_t *n1, const uint8_t *n2, |
| uint8_t a1t, const uint8_t *a1, uint8_t a2t, |
| const uint8_t *a2, uint8_t *mackey, uint8_t *ltk); |
| int ble_sm_alg_f6(const uint8_t *w, const uint8_t *n1, const uint8_t *n2, |
| const uint8_t *r, const uint8_t *iocap, uint8_t a1t, |
| const uint8_t *a1, uint8_t a2t, const uint8_t *a2, |
| uint8_t *check); |
| int ble_sm_alg_csis_k1(const uint8_t *n, size_t n_len, const uint8_t *salt, |
| const uint8_t *p, size_t p_len, uint8_t *out); |
| int ble_sm_alg_csis_s1(const uint8_t *m, size_t m_len, uint8_t *out); |
| int ble_sm_alg_csis_sef(const uint8_t *k, const uint8_t *plaintext_sirk, |
| uint8_t *out); |
| int ble_sm_alg_csis_sdf(const uint8_t *k, const uint8_t *enc_sirk, |
| uint8_t *out); |
| int ble_sm_alg_csis_sih(const uint8_t *k, const uint8_t *r, uint8_t *out); |
| int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, |
| const uint8_t *peer_pub_key_y, |
| const uint8_t *our_priv_key, uint8_t *out_dhkey); |
| int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv); |
| void ble_sm_alg_ecc_init(void); |
| |
| int ble_sm_csis_generate_rsi(const uint8_t *sirk, uint8_t *out); |
| int ble_sm_csis_encrypt_sirk(const uint8_t *ltk, const uint8_t *plaintext_sirk, |
| uint8_t *out); |
| int ble_sm_csis_decrypt_sirk(const uint8_t *ltk, const uint8_t *enc_sirk, uint8_t *out); |
| |
| void ble_sm_enc_change_rx(const struct ble_hci_ev_enrypt_chg *ev); |
| void ble_sm_enc_key_refresh_rx(const struct ble_hci_ev_enc_key_refresh *ev); |
| int ble_sm_ltk_req_rx(const struct ble_hci_ev_le_subev_lt_key_req *ev); |
| |
| #if MYNEWT_VAL(BLE_SM_LEGACY) |
| int ble_sm_lgcy_io_action(struct ble_sm_proc *proc, uint8_t *action); |
| void ble_sm_lgcy_confirm_exec(struct ble_sm_proc *proc, |
| struct ble_sm_result *res); |
| void ble_sm_lgcy_random_exec(struct ble_sm_proc *proc, |
| struct ble_sm_result *res); |
| void ble_sm_lgcy_random_rx(struct ble_sm_proc *proc, |
| struct ble_sm_result *res); |
| #else |
| #define ble_sm_lgcy_io_action(proc, action) (BLE_HS_ENOTSUP) |
| #define ble_sm_lgcy_confirm_exec(proc, res) |
| #define ble_sm_lgcy_random_exec(proc, res) |
| #define ble_sm_lgcy_random_rx(proc, res) |
| #endif |
| |
| #if MYNEWT_VAL(BLE_SM_SC) |
| int ble_sm_sc_io_action(struct ble_sm_proc *proc, uint8_t *action); |
| void ble_sm_sc_confirm_exec(struct ble_sm_proc *proc, |
| struct ble_sm_result *res); |
| void ble_sm_sc_random_exec(struct ble_sm_proc *proc, |
| struct ble_sm_result *res); |
| void ble_sm_sc_random_rx(struct ble_sm_proc *proc, struct ble_sm_result *res); |
| void ble_sm_sc_public_key_exec(struct ble_sm_proc *proc, |
| struct ble_sm_result *res, |
| void *arg); |
| void ble_sm_sc_public_key_rx(uint16_t conn_handle, struct os_mbuf **rxom, |
| struct ble_sm_result *res); |
| void ble_sm_sc_dhkey_check_exec(struct ble_sm_proc *proc, |
| struct ble_sm_result *res, void *arg); |
| void ble_sm_sc_dhkey_check_rx(uint16_t conn_handle, struct os_mbuf **rxom, |
| struct ble_sm_result *res); |
| bool ble_sm_sc_oob_data_check(struct ble_sm_proc *proc, |
| bool oob_data_local_present, |
| bool oob_data_remote_present); |
| void ble_sm_sc_oob_confirm(struct ble_sm_proc *proc, struct ble_sm_result *res); |
| void ble_sm_sc_init(void); |
| #else |
| #define ble_sm_sc_io_action(proc, action) (BLE_HS_ENOTSUP) |
| #define ble_sm_sc_confirm_exec(proc, res) |
| #define ble_sm_sc_random_exec(proc, res) |
| #define ble_sm_sc_random_rx(proc, res) |
| #define ble_sm_sc_public_key_exec(proc, res, arg) |
| #define ble_sm_sc_public_key_rx(conn_handle, op, om, res) |
| #define ble_sm_sc_dhkey_check_exec(proc, res, arg) |
| #define ble_sm_sc_dhkey_check_rx(conn_handle, op, om, res) |
| #define ble_sm_sc_init() |
| |
| #endif |
| |
| struct ble_sm_proc *ble_sm_proc_find(uint16_t conn_handle, uint8_t state, |
| int is_initiator, |
| struct ble_sm_proc **out_prev); |
| int ble_sm_gen_pair_rand(uint8_t *pair_rand); |
| uint8_t *ble_sm_our_pair_rand(struct ble_sm_proc *proc); |
| uint8_t *ble_sm_peer_pair_rand(struct ble_sm_proc *proc); |
| int ble_sm_ioact_state(uint8_t action); |
| int ble_sm_proc_can_advance(struct ble_sm_proc *proc); |
| void ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res, |
| bool tx_fail); |
| void ble_sm_confirm_advance(struct ble_sm_proc *proc); |
| void ble_sm_ia_ra(struct ble_sm_proc *proc, |
| uint8_t *out_iat, uint8_t *out_ia, |
| uint8_t *out_rat, uint8_t *out_ra); |
| |
| int32_t ble_sm_timer(void); |
| void ble_sm_connection_broken(uint16_t conn_handle); |
| int ble_sm_pair_initiate(uint16_t conn_handle); |
| int ble_sm_slave_initiate(uint16_t conn_handle); |
| int ble_sm_enc_initiate(uint16_t conn_handle, uint8_t key_size, |
| const uint8_t *ltk, uint16_t ediv, |
| uint64_t rand_val, int auth); |
| int ble_sm_init(void); |
| #else |
| |
| #define ble_sm_enc_change_rx(evt) ((void)(evt)) |
| #define ble_sm_ltk_req_rx(evt) ((void)(evt)) |
| #define ble_sm_enc_key_refresh_rx(evt) ((void)(evt)) |
| |
| #define ble_sm_timer() BLE_HS_FOREVER |
| #define ble_sm_connection_broken(conn_handle) |
| #define ble_sm_pair_initiate(conn_handle) BLE_HS_ENOTSUP |
| #define ble_sm_slave_initiate(conn_handle) BLE_HS_ENOTSUP |
| #define ble_sm_enc_initiate(conn_handle, keysize, ltk, ediv, rand_val, auth) \ |
| BLE_HS_ENOTSUP |
| |
| #define ble_sm_init() 0 |
| |
| #endif |
| |
| struct ble_l2cap_chan *ble_sm_create_chan(uint16_t handle); |
| void *ble_sm_cmd_get(uint8_t opcode, size_t len, struct os_mbuf **txom); |
| int ble_sm_tx(uint16_t conn_handle, struct os_mbuf *txom); |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif |