#include <linux/debugfs.h>
#include <linux/scatterlist.h>
#include <crypto/aes.h>
#include <crypto/hash.h>
#include <crypto/kpp.h>
#include <crypto/utils.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/mgmt.h>
#include "ecdh_helper.h"
#include "smp.h"
#define SMP_DEV(hdev) …
#ifdef DEBUG
#define SMP_DBG …
#else
#define SMP_DBG(fmt, ...) …
#endif
#define SMP_ALLOW_CMD(smp, code) …
#define SMP_SC_NO_DIST …
#define SMP_TIMEOUT …
#define ID_ADDR_TIMEOUT …
#define AUTH_REQ_MASK(dev) …
#define KEY_DIST_MASK …
#define CMAC_MSG_MAX …
enum { … };
struct smp_dev { … };
struct smp_chan { … };
static const u8 debug_pk[64] = …;
static const u8 debug_sk[32] = …;
static inline void swap_buf(const u8 *src, u8 *dst, size_t len)
{ … }
static int aes_cmac(struct crypto_shash *tfm, const u8 k[16], const u8 *m,
size_t len, u8 mac[16])
{ … }
static int smp_f4(struct crypto_shash *tfm_cmac, const u8 u[32],
const u8 v[32], const u8 x[16], u8 z, u8 res[16])
{ … }
static int smp_f5(struct crypto_shash *tfm_cmac, const u8 w[32],
const u8 n1[16], const u8 n2[16], const u8 a1[7],
const u8 a2[7], u8 mackey[16], u8 ltk[16])
{ … }
static int smp_f6(struct crypto_shash *tfm_cmac, const u8 w[16],
const u8 n1[16], const u8 n2[16], const u8 r[16],
const u8 io_cap[3], const u8 a1[7], const u8 a2[7],
u8 res[16])
{ … }
static int smp_g2(struct crypto_shash *tfm_cmac, const u8 u[32], const u8 v[32],
const u8 x[16], const u8 y[16], u32 *val)
{ … }
static int smp_h6(struct crypto_shash *tfm_cmac, const u8 w[16],
const u8 key_id[4], u8 res[16])
{ … }
static int smp_h7(struct crypto_shash *tfm_cmac, const u8 w[16],
const u8 salt[16], u8 res[16])
{ … }
static int smp_e(const u8 *k, u8 *r)
{ … }
static int smp_c1(const u8 k[16],
const u8 r[16], const u8 preq[7], const u8 pres[7], u8 _iat,
const bdaddr_t *ia, u8 _rat, const bdaddr_t *ra, u8 res[16])
{ … }
static int smp_s1(const u8 k[16],
const u8 r1[16], const u8 r2[16], u8 _r[16])
{ … }
static int smp_ah(const u8 irk[16], const u8 r[3], u8 res[3])
{ … }
bool smp_irk_matches(struct hci_dev *hdev, const u8 irk[16],
const bdaddr_t *bdaddr)
{ … }
int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa)
{ … }
int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16])
{ … }
static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
{ … }
static u8 authreq_to_seclevel(u8 authreq)
{ … }
static __u8 seclevel_to_authreq(__u8 sec_level)
{ … }
static void build_pairing_cmd(struct l2cap_conn *conn,
struct smp_cmd_pairing *req,
struct smp_cmd_pairing *rsp, __u8 authreq)
{ … }
static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
{ … }
static void smp_chan_destroy(struct l2cap_conn *conn)
{ … }
static void smp_failure(struct l2cap_conn *conn, u8 reason)
{ … }
#define JUST_WORKS …
#define JUST_CFM …
#define REQ_PASSKEY …
#define CFM_PASSKEY …
#define REQ_OOB …
#define DSP_PASSKEY …
#define OVERLAP …
static const u8 gen_method[5][5] = …;
static const u8 sc_method[5][5] = …;
static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io)
{ … }
static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
u8 local_io, u8 remote_io)
{ … }
static u8 smp_confirm(struct smp_chan *smp)
{ … }
static u8 smp_random(struct smp_chan *smp)
{ … }
static void smp_notify_keys(struct l2cap_conn *conn)
{ … }
static void sc_add_ltk(struct smp_chan *smp)
{ … }
static void sc_generate_link_key(struct smp_chan *smp)
{ … }
static void smp_allow_key_dist(struct smp_chan *smp)
{ … }
static void sc_generate_ltk(struct smp_chan *smp)
{ … }
static void smp_distribute_keys(struct smp_chan *smp)
{ … }
static void smp_timeout(struct work_struct *work)
{ … }
static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
{ … }
static int sc_mackey_and_ltk(struct smp_chan *smp, u8 mackey[16], u8 ltk[16])
{ … }
static void sc_dhkey_check(struct smp_chan *smp)
{ … }
static u8 sc_passkey_send_confirm(struct smp_chan *smp)
{ … }
static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op)
{ … }
static int sc_user_reply(struct smp_chan *smp, u16 mgmt_op, __le32 passkey)
{ … }
int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
{ … }
static void build_bredr_pairing_cmd(struct smp_chan *smp,
struct smp_cmd_pairing *req,
struct smp_cmd_pairing *rsp)
{ … }
static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
{ … }
static u8 sc_send_public_key(struct smp_chan *smp)
{ … }
static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
{ … }
static u8 sc_check_confirm(struct smp_chan *smp)
{ … }
static int fixup_sc_false_positive(struct smp_chan *smp)
{ … }
static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
{ … }
static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
{ … }
static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)
{ … }
bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level,
enum smp_key_pref key_pref)
{ … }
static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
{ … }
int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
{ … }
int smp_cancel_and_remove_pairing(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 addr_type)
{ … }
static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
{ … }
static int smp_cmd_initiator_ident(struct l2cap_conn *conn, struct sk_buff *skb)
{ … }
static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
{ … }
static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
struct sk_buff *skb)
{ … }
static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
{ … }
static u8 sc_select_method(struct smp_chan *smp)
{ … }
static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)
{ … }
static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb)
{ … }
static int smp_cmd_keypress_notify(struct l2cap_conn *conn,
struct sk_buff *skb)
{ … }
static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
{ … }
static void smp_teardown_cb(struct l2cap_chan *chan, int err)
{ … }
static void bredr_pairing(struct l2cap_chan *chan)
{ … }
static void smp_resume_cb(struct l2cap_chan *chan)
{ … }
static void smp_ready_cb(struct l2cap_chan *chan)
{ … }
static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
{ … }
static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan,
unsigned long hdr_len,
unsigned long len, int nb)
{ … }
static const struct l2cap_ops smp_chan_ops = …;
static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
{ … }
static const struct l2cap_ops smp_root_chan_ops = …;
static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
{ … }
static void smp_del_chan(struct l2cap_chan *chan)
{ … }
int smp_force_bredr(struct hci_dev *hdev, bool enable)
{ … }
int smp_register(struct hci_dev *hdev)
{ … }
void smp_unregister(struct hci_dev *hdev)
{ … }
#if IS_ENABLED(CONFIG_BT_SELFTEST_SMP)
static int __init test_debug_key(struct crypto_kpp *tfm_ecdh)
{ … }
static int __init test_ah(void)
{ … }
static int __init test_c1(void)
{ … }
static int __init test_s1(void)
{ … }
static int __init test_f4(struct crypto_shash *tfm_cmac)
{ … }
static int __init test_f5(struct crypto_shash *tfm_cmac)
{ … }
static int __init test_f6(struct crypto_shash *tfm_cmac)
{ … }
static int __init test_g2(struct crypto_shash *tfm_cmac)
{ … }
static int __init test_h6(struct crypto_shash *tfm_cmac)
{ … }
static char test_smp_buffer[32];
static ssize_t test_smp_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static const struct file_operations test_smp_fops = …;
static int __init run_selftests(struct crypto_shash *tfm_cmac,
struct crypto_kpp *tfm_ecdh)
{ … }
int __init bt_selftest_smp(void)
{ … }
#endif