linux/net/bluetooth/smp.c

/*
   BlueZ - Bluetooth protocol stack for Linux
   Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2 as
   published by the Free Software Foundation;

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
   SOFTWARE IS DISCLAIMED.
*/

#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)

/* Low-level debug macros to be used for stuff that we don't want
 * accidentally in dmesg, i.e. the values of the various crypto keys
 * and the inputs & outputs of crypto functions.
 */
#ifdef DEBUG
#define SMP_DBG
#else
#define SMP_DBG(fmt, ...)
#endif

#define SMP_ALLOW_CMD(smp, code)

/* Keys which are not distributed with Secure Connections */
#define SMP_SC_NO_DIST

#define SMP_TIMEOUT

#define ID_ADDR_TIMEOUT

#define AUTH_REQ_MASK(dev)
#define KEY_DIST_MASK

/* Maximum message length that can be passed to aes_cmac */
#define CMAC_MSG_MAX

enum {};

struct smp_dev {};

struct smp_chan {};

/* These debug key values are defined in the SMP section of the core
 * specification. debug_pk is the public debug key and debug_sk the
 * private debug key.
 */
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)
{}

/* The following functions map to the LE SC SMP crypto functions
 * AES-CMAC, f4, f5, f6, g2 and h6.
 */

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])
{}

/* The following functions map to the legacy SMP crypto functions e, c1,
 * s1 and ah.
 */

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)
{}

/* Work-around for some implementations that incorrectly copy RFU bits
 * from our security request and thereby create the impression that
 * we're doing SC when in fact the remote doesn't support it.
 */
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