diff options
Diffstat (limited to 'net/bluetooth/smp.c')
| -rw-r--r-- | net/bluetooth/smp.c | 861 | 
1 files changed, 621 insertions, 240 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index b5562abdd6e..e33a982161c 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -28,20 +28,48 @@  #include <net/bluetooth/hci_core.h>  #include <net/bluetooth/l2cap.h>  #include <net/bluetooth/mgmt.h> -#include <net/bluetooth/smp.h> + +#include "smp.h"  #define SMP_TIMEOUT	msecs_to_jiffies(30000)  #define AUTH_REQ_MASK   0x07 -static inline void swap128(u8 src[16], u8 dst[16]) +#define SMP_FLAG_TK_VALID	1 +#define SMP_FLAG_CFM_PENDING	2 +#define SMP_FLAG_MITM_AUTH	3 +#define SMP_FLAG_COMPLETE	4 +#define SMP_FLAG_INITIATOR	5 + +struct smp_chan { +	struct l2cap_conn *conn; +	u8		preq[7]; /* SMP Pairing Request */ +	u8		prsp[7]; /* SMP Pairing Response */ +	u8		prnd[16]; /* SMP Pairing Random (local) */ +	u8		rrnd[16]; /* SMP Pairing Random (remote) */ +	u8		pcnf[16]; /* SMP Pairing Confirm */ +	u8		tk[16]; /* SMP Temporary Key */ +	u8		enc_key_size; +	u8		remote_key_dist; +	bdaddr_t	id_addr; +	u8		id_addr_type; +	u8		irk[16]; +	struct smp_csrk	*csrk; +	struct smp_csrk	*slave_csrk; +	struct smp_ltk	*ltk; +	struct smp_ltk	*slave_ltk; +	struct smp_irk	*remote_irk; +	unsigned long	flags; +}; + +static inline void swap128(const u8 src[16], u8 dst[16])  {  	int i;  	for (i = 0; i < 16; i++)  		dst[15 - i] = src[i];  } -static inline void swap56(u8 src[7], u8 dst[7]) +static inline void swap56(const u8 src[7], u8 dst[7])  {  	int i;  	for (i = 0; i < 7; i++) @@ -52,8 +80,8 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)  {  	struct blkcipher_desc desc;  	struct scatterlist sg; -	int err, iv_len; -	unsigned char iv[128]; +	uint8_t tmp[16], data[16]; +	int err;  	if (tfm == NULL) {  		BT_ERR("tfm %p", tfm); @@ -63,30 +91,92 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)  	desc.tfm = tfm;  	desc.flags = 0; -	err = crypto_blkcipher_setkey(tfm, k, 16); +	/* The most significant octet of key corresponds to k[0] */ +	swap128(k, tmp); + +	err = crypto_blkcipher_setkey(tfm, tmp, 16);  	if (err) {  		BT_ERR("cipher setkey failed: %d", err);  		return err;  	} -	sg_init_one(&sg, r, 16); +	/* Most significant octet of plaintextData corresponds to data[0] */ +	swap128(r, data); -	iv_len = crypto_blkcipher_ivsize(tfm); -	if (iv_len) { -		memset(&iv, 0xff, iv_len); -		crypto_blkcipher_set_iv(tfm, iv, iv_len); -	} +	sg_init_one(&sg, data, 16);  	err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);  	if (err)  		BT_ERR("Encrypt data error %d", err); +	/* Most significant octet of encryptedData corresponds to data[0] */ +	swap128(data, r); +  	return err;  } +static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3]) +{ +	u8 _res[16]; +	int err; + +	/* r' = padding || r */ +	memcpy(_res, r, 3); +	memset(_res + 3, 0, 13); + +	err = smp_e(tfm, irk, _res); +	if (err) { +		BT_ERR("Encrypt error"); +		return err; +	} + +	/* The output of the random address function ah is: +	 *	ah(h, r) = e(k, r') mod 2^24 +	 * The output of the security function e is then truncated to 24 bits +	 * by taking the least significant 24 bits of the output of e as the +	 * result of ah. +	 */ +	memcpy(res, _res, 3); + +	return 0; +} + +bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16], +		     bdaddr_t *bdaddr) +{ +	u8 hash[3]; +	int err; + +	BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk); + +	err = smp_ah(tfm, irk, &bdaddr->b[3], hash); +	if (err) +		return false; + +	return !memcmp(bdaddr->b, hash, 3); +} + +int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa) +{ +	int err; + +	get_random_bytes(&rpa->b[3], 3); + +	rpa->b[5] &= 0x3f;	/* Clear two most significant bits */ +	rpa->b[5] |= 0x40;	/* Set second most significant bit */ + +	err = smp_ah(tfm, irk, &rpa->b[3], rpa->b); +	if (err < 0) +		return err; + +	BT_DBG("RPA %pMR", rpa); + +	return 0; +} +  static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16], -		u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia, -		u8 _rat, bdaddr_t *ra, u8 res[16]) +		  u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia, +		  u8 _rat, bdaddr_t *ra, u8 res[16])  {  	u8 p1[16], p2[16];  	int err; @@ -94,16 +184,15 @@ static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],  	memset(p1, 0, 16);  	/* p1 = pres || preq || _rat || _iat */ -	swap56(pres, p1); -	swap56(preq, p1 + 7); -	p1[14] = _rat; -	p1[15] = _iat; - -	memset(p2, 0, 16); +	p1[0] = _iat; +	p1[1] = _rat; +	memcpy(p1 + 2, preq, 7); +	memcpy(p1 + 9, pres, 7);  	/* p2 = padding || ia || ra */ -	baswap((bdaddr_t *) (p2 + 4), ia); -	baswap((bdaddr_t *) (p2 + 10), ra); +	memcpy(p2, ra, 6); +	memcpy(p2 + 6, ia, 6); +	memset(p2 + 12, 0, 4);  	/* res = r XOR p1 */  	u128_xor((u128 *) res, (u128 *) r, (u128 *) p1); @@ -126,14 +215,14 @@ static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],  	return err;  } -static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], -			u8 r1[16], u8 r2[16], u8 _r[16]) +static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16], +		  u8 r2[16], u8 _r[16])  {  	int err;  	/* Just least significant octets from r1 and r2 are considered */ -	memcpy(_r, r1 + 8, 8); -	memcpy(_r + 8, r2 + 8, 8); +	memcpy(_r, r2, 8); +	memcpy(_r + 8, r1, 8);  	err = smp_e(tfm, k, _r);  	if (err) @@ -142,15 +231,8 @@ static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16],  	return err;  } -static int smp_rand(u8 *buf) -{ -	get_random_bytes(buf, 16); - -	return 0; -} -  static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code, -						u16 dlen, void *data) +				     u16 dlen, void *data)  {  	struct sk_buff *skb;  	struct l2cap_hdr *lh; @@ -167,7 +249,7 @@ static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,  	lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);  	lh->len = cpu_to_le16(sizeof(code) + dlen); -	lh->cid = __constant_cpu_to_le16(L2CAP_CID_SMP); +	lh->cid = cpu_to_le16(L2CAP_CID_SMP);  	memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code)); @@ -213,35 +295,48 @@ 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) +			      struct smp_cmd_pairing *req, +			      struct smp_cmd_pairing *rsp, __u8 authreq)  { -	u8 dist_keys = 0; +	struct smp_chan *smp = conn->smp_chan; +	struct hci_conn *hcon = conn->hcon; +	struct hci_dev *hdev = hcon->hdev; +	u8 local_dist = 0, remote_dist = 0;  	if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->dev_flags)) { -		dist_keys = SMP_DIST_ENC_KEY; +		local_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN; +		remote_dist = SMP_DIST_ENC_KEY | SMP_DIST_SIGN;  		authreq |= SMP_AUTH_BONDING;  	} else {  		authreq &= ~SMP_AUTH_BONDING;  	} +	if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags)) +		remote_dist |= SMP_DIST_ID_KEY; + +	if (test_bit(HCI_PRIVACY, &hdev->dev_flags)) +		local_dist |= SMP_DIST_ID_KEY; +  	if (rsp == NULL) {  		req->io_capability = conn->hcon->io_capability;  		req->oob_flag = SMP_OOB_NOT_PRESENT;  		req->max_key_size = SMP_MAX_ENC_KEY_SIZE; -		req->init_key_dist = 0; -		req->resp_key_dist = dist_keys; +		req->init_key_dist = local_dist; +		req->resp_key_dist = remote_dist;  		req->auth_req = (authreq & AUTH_REQ_MASK); + +		smp->remote_key_dist = remote_dist;  		return;  	}  	rsp->io_capability = conn->hcon->io_capability;  	rsp->oob_flag = SMP_OOB_NOT_PRESENT;  	rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE; -	rsp->init_key_dist = 0; -	rsp->resp_key_dist = req->resp_key_dist & dist_keys; +	rsp->init_key_dist = req->init_key_dist & remote_dist; +	rsp->resp_key_dist = req->resp_key_dist & local_dist;  	rsp->auth_req = (authreq & AUTH_REQ_MASK); + +	smp->remote_key_dist = rsp->init_key_dist;  }  static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) @@ -249,7 +344,7 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)  	struct smp_chan *smp = conn->smp_chan;  	if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) || -			(max_key_size < SMP_MIN_ENC_KEY_SIZE)) +	    (max_key_size < SMP_MIN_ENC_KEY_SIZE))  		return SMP_ENC_KEY_SIZE;  	smp->enc_key_size = max_key_size; @@ -257,21 +352,21 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)  	return 0;  } -static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send) +static void smp_failure(struct l2cap_conn *conn, u8 reason)  {  	struct hci_conn *hcon = conn->hcon; -	if (send) +	if (reason)  		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), -								&reason); +			     &reason); -	clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->flags); -	mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type, -			 hcon->dst_type, HCI_ERROR_AUTH_FAILURE); +	clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags); +	mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type, +			 HCI_ERROR_AUTH_FAILURE);  	cancel_delayed_work_sync(&conn->security_timer); -	if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) +	if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))  		smp_chan_destroy(conn);  } @@ -290,6 +385,16 @@ static const u8 gen_method[5][5] = {  	{ CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP     },  }; +static u8 get_auth_method(struct smp_chan *smp, u8 local_io, u8 remote_io) +{ +	/* If either side has unknown io_caps, use JUST WORKS */ +	if (local_io > SMP_IO_KEYBOARD_DISPLAY || +	    remote_io > SMP_IO_KEYBOARD_DISPLAY) +		return JUST_WORKS; + +	return gen_method[remote_io][local_io]; +} +  static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,  						u8 local_io, u8 remote_io)  { @@ -301,33 +406,34 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,  	/* Initialize key for JUST WORKS */  	memset(smp->tk, 0, sizeof(smp->tk)); -	clear_bit(SMP_FLAG_TK_VALID, &smp->smp_flags); +	clear_bit(SMP_FLAG_TK_VALID, &smp->flags);  	BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);  	/* If neither side wants MITM, use JUST WORKS */ -	/* If either side has unknown io_caps, use JUST WORKS */  	/* Otherwise, look up method from the table */ -	if (!(auth & SMP_AUTH_MITM) || -			local_io > SMP_IO_KEYBOARD_DISPLAY || -			remote_io > SMP_IO_KEYBOARD_DISPLAY) +	if (!(auth & SMP_AUTH_MITM))  		method = JUST_WORKS;  	else -		method = gen_method[remote_io][local_io]; +		method = get_auth_method(smp, local_io, remote_io);  	/* If not bonding, don't ask user to confirm a Zero TK */  	if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM)  		method = JUST_WORKS; +	/* Don't confirm locally initiated pairing attempts */ +	if (method == JUST_CFM && test_bit(SMP_FLAG_INITIATOR, &smp->flags)) +		method = JUST_WORKS; +  	/* If Just Works, Continue with Zero TK */  	if (method == JUST_WORKS) { -		set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags); +		set_bit(SMP_FLAG_TK_VALID, &smp->flags);  		return 0;  	}  	/* Not Just Works/Confirm results in MITM Authentication */  	if (method != JUST_CFM) -		set_bit(SMP_FLAG_MITM_AUTH, &smp->smp_flags); +		set_bit(SMP_FLAG_MITM_AUTH, &smp->flags);  	/* If both devices have Keyoard-Display I/O, the master  	 * Confirms and the slave Enters the passkey. @@ -339,168 +445,145 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,  			method = REQ_PASSKEY;  	} -	/* Generate random passkey. Not valid until confirmed. */ +	/* Generate random passkey. */  	if (method == CFM_PASSKEY) { -		u8 key[16]; - -		memset(key, 0, sizeof(key)); +		memset(smp->tk, 0, sizeof(smp->tk));  		get_random_bytes(&passkey, sizeof(passkey));  		passkey %= 1000000; -		put_unaligned_le32(passkey, key); -		swap128(key, smp->tk); +		put_unaligned_le32(passkey, smp->tk);  		BT_DBG("PassKey: %d", passkey); +		set_bit(SMP_FLAG_TK_VALID, &smp->flags);  	}  	hci_dev_lock(hcon->hdev);  	if (method == REQ_PASSKEY) -		ret = mgmt_user_passkey_request(hcon->hdev, conn->dst, +		ret = mgmt_user_passkey_request(hcon->hdev, &hcon->dst,  						hcon->type, hcon->dst_type); +	else if (method == JUST_CFM) +		ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, +						hcon->type, hcon->dst_type, +						passkey, 1);  	else -		ret = mgmt_user_confirm_request(hcon->hdev, conn->dst, +		ret = mgmt_user_passkey_notify(hcon->hdev, &hcon->dst,  						hcon->type, hcon->dst_type, -						cpu_to_le32(passkey), 0); +						passkey, 0);  	hci_dev_unlock(hcon->hdev);  	return ret;  } -static void confirm_work(struct work_struct *work) +static u8 smp_confirm(struct smp_chan *smp)  { -	struct smp_chan *smp = container_of(work, struct smp_chan, confirm);  	struct l2cap_conn *conn = smp->conn; -	struct crypto_blkcipher *tfm; +	struct hci_dev *hdev = conn->hcon->hdev; +	struct crypto_blkcipher *tfm = hdev->tfm_aes;  	struct smp_cmd_pairing_confirm cp;  	int ret; -	u8 res[16], reason;  	BT_DBG("conn %p", conn); -	tfm = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); -	if (IS_ERR(tfm)) { -		reason = SMP_UNSPECIFIED; -		goto error; -	} +	/* Prevent mutual access to hdev->tfm_aes */ +	hci_dev_lock(hdev); -	smp->tfm = tfm; +	ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp, +		     conn->hcon->init_addr_type, &conn->hcon->init_addr, +		     conn->hcon->resp_addr_type, &conn->hcon->resp_addr, +		     cp.confirm_val); -	if (conn->hcon->out) -		ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp, 0, -			     conn->src, conn->hcon->dst_type, conn->dst, res); -	else -		ret = smp_c1(tfm, smp->tk, smp->prnd, smp->preq, smp->prsp, -			     conn->hcon->dst_type, conn->dst, 0, conn->src, -			     res); -	if (ret) { -		reason = SMP_UNSPECIFIED; -		goto error; -	} +	hci_dev_unlock(hdev); -	clear_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags); +	if (ret) +		return SMP_UNSPECIFIED; -	swap128(res, cp.confirm_val); -	smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); +	clear_bit(SMP_FLAG_CFM_PENDING, &smp->flags); -	return; +	smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); -error: -	smp_failure(conn, reason, 1); +	return 0;  } -static void random_work(struct work_struct *work) +static u8 smp_random(struct smp_chan *smp)  { -	struct smp_chan *smp = container_of(work, struct smp_chan, random);  	struct l2cap_conn *conn = smp->conn;  	struct hci_conn *hcon = conn->hcon; -	struct crypto_blkcipher *tfm = smp->tfm; -	u8 reason, confirm[16], res[16], key[16]; +	struct hci_dev *hdev = hcon->hdev; +	struct crypto_blkcipher *tfm = hdev->tfm_aes; +	u8 confirm[16];  	int ret; -	if (IS_ERR_OR_NULL(tfm)) { -		reason = SMP_UNSPECIFIED; -		goto error; -	} +	if (IS_ERR_OR_NULL(tfm)) +		return SMP_UNSPECIFIED;  	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); -	if (hcon->out) -		ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp, 0, -			     conn->src, hcon->dst_type, conn->dst, res); -	else -		ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp, -			     hcon->dst_type, conn->dst, 0, conn->src, res); -	if (ret) { -		reason = SMP_UNSPECIFIED; -		goto error; -	} +	/* Prevent mutual access to hdev->tfm_aes */ +	hci_dev_lock(hdev); + +	ret = smp_c1(tfm, smp->tk, smp->rrnd, smp->preq, smp->prsp, +		     hcon->init_addr_type, &hcon->init_addr, +		     hcon->resp_addr_type, &hcon->resp_addr, confirm); -	swap128(res, confirm); +	hci_dev_unlock(hdev); + +	if (ret) +		return SMP_UNSPECIFIED;  	if (memcmp(smp->pcnf, confirm, sizeof(smp->pcnf)) != 0) {  		BT_ERR("Pairing failed (confirmation values mismatch)"); -		reason = SMP_CONFIRM_FAILED; -		goto error; +		return SMP_CONFIRM_FAILED;  	}  	if (hcon->out) { -		u8 stk[16], rand[8]; -		__le16 ediv; - -		memset(rand, 0, sizeof(rand)); -		ediv = 0; +		u8 stk[16]; +		__le64 rand = 0; +		__le16 ediv = 0; -		smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, key); -		swap128(key, stk); +		smp_s1(tfm, smp->tk, smp->rrnd, smp->prnd, stk);  		memset(stk + smp->enc_key_size, 0,  		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); -		if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) { -			reason = SMP_UNSPECIFIED; -			goto error; -		} +		if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) +			return SMP_UNSPECIFIED;  		hci_le_start_enc(hcon, ediv, rand, stk);  		hcon->enc_key_size = smp->enc_key_size;  	} else { -		u8 stk[16], r[16], rand[8]; -		__le16 ediv; +		u8 stk[16], auth; +		__le64 rand = 0; +		__le16 ediv = 0; -		memset(rand, 0, sizeof(rand)); -		ediv = 0; +		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), +			     smp->prnd); -		swap128(smp->prnd, r); -		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(r), r); - -		smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, key); -		swap128(key, stk); +		smp_s1(tfm, smp->tk, smp->prnd, smp->rrnd, stk);  		memset(stk + smp->enc_key_size, 0, -				SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); +		       SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); + +		if (hcon->pending_sec_level == BT_SECURITY_HIGH) +			auth = 1; +		else +			auth = 0; -		hci_add_ltk(hcon->hdev, conn->dst, hcon->dst_type, -			    HCI_SMP_STK_SLAVE, 0, 0, stk, smp->enc_key_size, +		hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, +			    HCI_SMP_STK_SLAVE, auth, stk, smp->enc_key_size,  			    ediv, rand);  	} -	return; - -error: -	smp_failure(conn, reason, 1); +	return 0;  }  static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)  {  	struct smp_chan *smp; -	smp = kzalloc(sizeof(struct smp_chan), GFP_ATOMIC); +	smp = kzalloc(sizeof(*smp), GFP_ATOMIC);  	if (!smp)  		return NULL; -	INIT_WORK(&smp->confirm, confirm_work); -	INIT_WORK(&smp->random, random_work); -  	smp->conn = conn;  	conn->smp_chan = smp;  	conn->hcon->smp_conn = conn; @@ -513,11 +596,33 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)  void smp_chan_destroy(struct l2cap_conn *conn)  {  	struct smp_chan *smp = conn->smp_chan; +	bool complete;  	BUG_ON(!smp); -	if (smp->tfm) -		crypto_free_blkcipher(smp->tfm); +	complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); +	mgmt_smp_complete(conn->hcon, complete); + +	kfree(smp->csrk); +	kfree(smp->slave_csrk); + +	/* If pairing failed clean up any keys we might have */ +	if (!complete) { +		if (smp->ltk) { +			list_del(&smp->ltk->list); +			kfree(smp->ltk); +		} + +		if (smp->slave_ltk) { +			list_del(&smp->slave_ltk->list); +			kfree(smp->slave_ltk); +		} + +		if (smp->remote_irk) { +			list_del(&smp->remote_irk->list); +			kfree(smp->remote_irk); +		} +	}  	kfree(smp);  	conn->smp_chan = NULL; @@ -530,7 +635,6 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)  	struct l2cap_conn *conn = hcon->smp_conn;  	struct smp_chan *smp;  	u32 value; -	u8 key[16];  	BT_DBG(""); @@ -542,26 +646,28 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)  	switch (mgmt_op) {  	case MGMT_OP_USER_PASSKEY_REPLY:  		value = le32_to_cpu(passkey); -		memset(key, 0, sizeof(key)); +		memset(smp->tk, 0, sizeof(smp->tk));  		BT_DBG("PassKey: %d", value); -		put_unaligned_le32(value, key); -		swap128(key, smp->tk); +		put_unaligned_le32(value, smp->tk);  		/* Fall Through */  	case MGMT_OP_USER_CONFIRM_REPLY: -		set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags); +		set_bit(SMP_FLAG_TK_VALID, &smp->flags);  		break;  	case MGMT_OP_USER_PASSKEY_NEG_REPLY:  	case MGMT_OP_USER_CONFIRM_NEG_REPLY: -		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED, 1); +		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);  		return 0;  	default: -		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED, 1); +		smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);  		return -EOPNOTSUPP;  	}  	/* If it is our turn to send Pairing Confirm, do so now */ -	if (test_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags)) -		queue_work(hcon->hdev->workqueue, &smp->confirm); +	if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) { +		u8 rsp = smp_confirm(smp); +		if (rsp) +			smp_failure(conn, rsp); +	}  	return 0;  } @@ -570,12 +676,14 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)  {  	struct smp_cmd_pairing rsp, *req = (void *) skb->data;  	struct smp_chan *smp; -	u8 key_size; -	u8 auth = SMP_AUTH_NONE; +	u8 key_size, auth, sec_level;  	int ret;  	BT_DBG("conn %p", conn); +	if (skb->len < sizeof(*req)) +		return SMP_INVALID_PARAMS; +  	if (conn->hcon->link_mode & HCI_LM_MASTER)  		return SMP_CMD_NOTSUPP; @@ -592,10 +700,21 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)  	skb_pull(skb, sizeof(*req));  	/* We didn't start the pairing, so match remote */ -	if (req->auth_req & SMP_AUTH_BONDING) -		auth = req->auth_req; +	auth = req->auth_req; -	conn->hcon->pending_sec_level = authreq_to_seclevel(auth); +	sec_level = authreq_to_seclevel(auth); +	if (sec_level > conn->hcon->pending_sec_level) +		conn->hcon->pending_sec_level = sec_level; + +	/* If we need MITM check that it can be acheived */ +	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { +		u8 method; + +		method = get_auth_method(smp, conn->hcon->io_capability, +					 req->io_capability); +		if (method == JUST_WORKS || method == JUST_CFM) +			return SMP_AUTH_REQUIREMENTS; +	}  	build_pairing_cmd(conn, req, &rsp, auth); @@ -603,9 +722,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)  	if (check_enc_key_size(conn, key_size))  		return SMP_ENC_KEY_SIZE; -	ret = smp_rand(smp->prnd); -	if (ret) -		return SMP_UNSPECIFIED; +	get_random_bytes(smp->prnd, sizeof(smp->prnd));  	smp->prsp[0] = SMP_CMD_PAIRING_RSP;  	memcpy(&smp->prsp[1], &rsp, sizeof(rsp)); @@ -617,6 +734,8 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)  	if (ret)  		return SMP_UNSPECIFIED; +	clear_bit(SMP_FLAG_INITIATOR, &smp->flags); +  	return 0;  } @@ -624,12 +743,14 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)  {  	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;  	struct smp_chan *smp = conn->smp_chan; -	struct hci_dev *hdev = conn->hcon->hdev;  	u8 key_size, auth = SMP_AUTH_NONE;  	int ret;  	BT_DBG("conn %p", conn); +	if (skb->len < sizeof(*rsp)) +		return SMP_INVALID_PARAMS; +  	if (!(conn->hcon->link_mode & HCI_LM_MASTER))  		return SMP_CMD_NOTSUPP; @@ -641,15 +762,28 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)  	if (check_enc_key_size(conn, key_size))  		return SMP_ENC_KEY_SIZE; -	ret = smp_rand(smp->prnd); -	if (ret) -		return SMP_UNSPECIFIED; +	/* If we need MITM check that it can be acheived */ +	if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { +		u8 method; + +		method = get_auth_method(smp, req->io_capability, +					 rsp->io_capability); +		if (method == JUST_WORKS || method == JUST_CFM) +			return SMP_AUTH_REQUIREMENTS; +	} + +	get_random_bytes(smp->prnd, sizeof(smp->prnd));  	smp->prsp[0] = SMP_CMD_PAIRING_RSP;  	memcpy(&smp->prsp[1], rsp, sizeof(*rsp)); +	/* Update remote key distribution in case the remote cleared +	 * some bits that we had enabled in our request. +	 */ +	smp->remote_key_dist &= rsp->resp_key_dist; +  	if ((req->auth_req & SMP_AUTH_BONDING) && -			(rsp->auth_req & SMP_AUTH_BONDING)) +	    (rsp->auth_req & SMP_AUTH_BONDING))  		auth = SMP_AUTH_BONDING;  	auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM; @@ -658,13 +792,11 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)  	if (ret)  		return SMP_UNSPECIFIED; -	set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags); +	set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);  	/* Can't compose response until we have been confirmed */ -	if (!test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) -		return 0; - -	queue_work(hdev->workqueue, &smp->confirm); +	if (test_bit(SMP_FLAG_TK_VALID, &smp->flags)) +		return smp_confirm(smp);  	return 0;  } @@ -672,24 +804,22 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)  static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)  {  	struct smp_chan *smp = conn->smp_chan; -	struct hci_dev *hdev = conn->hcon->hdev;  	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); +	if (skb->len < sizeof(smp->pcnf)) +		return SMP_INVALID_PARAMS; +  	memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));  	skb_pull(skb, sizeof(smp->pcnf)); -	if (conn->hcon->out) { -		u8 random[16]; - -		swap128(smp->prnd, random); -		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random), -								random); -	} else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) { -		queue_work(hdev->workqueue, &smp->confirm); -	} else { -		set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags); -	} +	if (conn->hcon->out) +		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), +			     smp->prnd); +	else if (test_bit(SMP_FLAG_TK_VALID, &smp->flags)) +		return smp_confirm(smp); +	else +		set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);  	return 0;  } @@ -697,16 +827,16 @@ 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)  {  	struct smp_chan *smp = conn->smp_chan; -	struct hci_dev *hdev = conn->hcon->hdev;  	BT_DBG("conn %p", conn); -	swap128(skb->data, smp->rrnd); -	skb_pull(skb, sizeof(smp->rrnd)); +	if (skb->len < sizeof(smp->rrnd)) +		return SMP_INVALID_PARAMS; -	queue_work(hdev->workqueue, &smp->random); +	memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd)); +	skb_pull(skb, sizeof(smp->rrnd)); -	return 0; +	return smp_random(smp);  }  static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) @@ -714,7 +844,8 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)  	struct smp_ltk *key;  	struct hci_conn *hcon = conn->hcon; -	key = hci_find_ltk_by_addr(hcon->hdev, conn->dst, hcon->dst_type); +	key = hci_find_ltk_by_addr(hcon->hdev, &hcon->dst, hcon->dst_type, +				   hcon->out);  	if (!key)  		return 0; @@ -728,18 +859,27 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)  	hcon->enc_key_size = key->enc_size;  	return 1; -  } +  static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)  {  	struct smp_cmd_security_req *rp = (void *) skb->data;  	struct smp_cmd_pairing cp;  	struct hci_conn *hcon = conn->hcon;  	struct smp_chan *smp; +	u8 sec_level;  	BT_DBG("conn %p", conn); -	hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req); +	if (skb->len < sizeof(*rp)) +		return SMP_INVALID_PARAMS; + +	if (!(conn->hcon->link_mode & HCI_LM_MASTER)) +		return SMP_CMD_NOTSUPP; + +	sec_level = authreq_to_seclevel(rp->auth_req); +	if (sec_level > hcon->pending_sec_level) +		hcon->pending_sec_level = sec_level;  	if (smp_ltk_encrypt(conn, hcon->pending_sec_level))  		return 0; @@ -759,29 +899,46 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)  	smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); +	clear_bit(SMP_FLAG_INITIATOR, &smp->flags); +  	return 0;  } +bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level) +{ +	if (sec_level == BT_SECURITY_LOW) +		return true; + +	if (hcon->sec_level >= sec_level) +		return true; + +	return false; +} +  int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)  {  	struct l2cap_conn *conn = hcon->l2cap_data; -	struct smp_chan *smp = conn->smp_chan; +	struct smp_chan *smp;  	__u8 authreq;  	BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); -	if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) +	/* This may be NULL if there's an unexpected disconnection */ +	if (!conn)  		return 1; -	if (sec_level == BT_SECURITY_LOW) +	if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))  		return 1; -	if (hcon->sec_level >= sec_level) +	if (smp_sufficient_security(hcon, sec_level))  		return 1; +	if (sec_level > hcon->pending_sec_level) +		hcon->pending_sec_level = sec_level; +  	if (hcon->link_mode & HCI_LM_MASTER) -		if (smp_ltk_encrypt(conn, sec_level)) -			goto done; +		if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) +			return 0;  	if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))  		return 0; @@ -792,6 +949,13 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)  	authreq = seclevel_to_authreq(sec_level); +	/* Require MITM if IO Capability allows or the security level +	 * requires it. +	 */ +	if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT || +	    hcon->pending_sec_level > BT_SECURITY_MEDIUM) +		authreq |= SMP_AUTH_MITM; +  	if (hcon->link_mode & HCI_LM_MASTER) {  		struct smp_cmd_pairing cp; @@ -806,8 +970,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)  		smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);  	} -done: -	hcon->pending_sec_level = sec_level; +	set_bit(SMP_FLAG_INITIATOR, &smp->flags);  	return 0;  } @@ -817,6 +980,15 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)  	struct smp_cmd_encrypt_info *rp = (void *) skb->data;  	struct smp_chan *smp = conn->smp_chan; +	BT_DBG("conn %p", conn); + +	if (skb->len < sizeof(*rp)) +		return SMP_INVALID_PARAMS; + +	/* Ignore this PDU if it wasn't requested */ +	if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY)) +		return 0; +  	skb_pull(skb, sizeof(*rp));  	memcpy(smp->tk, rp->ltk, sizeof(smp->tk)); @@ -830,16 +1002,138 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)  	struct smp_chan *smp = conn->smp_chan;  	struct hci_dev *hdev = conn->hcon->hdev;  	struct hci_conn *hcon = conn->hcon; +	struct smp_ltk *ltk;  	u8 authenticated; +	BT_DBG("conn %p", conn); + +	if (skb->len < sizeof(*rp)) +		return SMP_INVALID_PARAMS; + +	/* Ignore this PDU if it wasn't requested */ +	if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY)) +		return 0; + +	/* Mark the information as received */ +	smp->remote_key_dist &= ~SMP_DIST_ENC_KEY; + +	skb_pull(skb, sizeof(*rp)); + +	hci_dev_lock(hdev); +	authenticated = (hcon->sec_level == BT_SECURITY_HIGH); +	ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK, +			  authenticated, smp->tk, smp->enc_key_size, +			  rp->ediv, rp->rand); +	smp->ltk = ltk; +	if (!(smp->remote_key_dist & SMP_DIST_ID_KEY)) +		smp_distribute_keys(conn); +	hci_dev_unlock(hdev); + +	return 0; +} + +static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb) +{ +	struct smp_cmd_ident_info *info = (void *) skb->data; +	struct smp_chan *smp = conn->smp_chan; + +	BT_DBG(""); + +	if (skb->len < sizeof(*info)) +		return SMP_INVALID_PARAMS; + +	/* Ignore this PDU if it wasn't requested */ +	if (!(smp->remote_key_dist & SMP_DIST_ID_KEY)) +		return 0; + +	skb_pull(skb, sizeof(*info)); + +	memcpy(smp->irk, info->irk, 16); + +	return 0; +} + +static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, +				   struct sk_buff *skb) +{ +	struct smp_cmd_ident_addr_info *info = (void *) skb->data; +	struct smp_chan *smp = conn->smp_chan; +	struct hci_conn *hcon = conn->hcon; +	bdaddr_t rpa; + +	BT_DBG(""); + +	if (skb->len < sizeof(*info)) +		return SMP_INVALID_PARAMS; + +	/* Ignore this PDU if it wasn't requested */ +	if (!(smp->remote_key_dist & SMP_DIST_ID_KEY)) +		return 0; + +	/* Mark the information as received */ +	smp->remote_key_dist &= ~SMP_DIST_ID_KEY; + +	skb_pull(skb, sizeof(*info)); + +	/* Strictly speaking the Core Specification (4.1) allows sending +	 * an empty address which would force us to rely on just the IRK +	 * as "identity information". However, since such +	 * implementations are not known of and in order to not over +	 * complicate our implementation, simply pretend that we never +	 * received an IRK for such a device. +	 */ +	if (!bacmp(&info->bdaddr, BDADDR_ANY)) { +		BT_ERR("Ignoring IRK with no identity address"); +		smp_distribute_keys(conn); +		return 0; +	} + +	bacpy(&smp->id_addr, &info->bdaddr); +	smp->id_addr_type = info->addr_type; + +	if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type)) +		bacpy(&rpa, &hcon->dst); +	else +		bacpy(&rpa, BDADDR_ANY); + +	smp->remote_irk = hci_add_irk(conn->hcon->hdev, &smp->id_addr, +				      smp->id_addr_type, smp->irk, &rpa); + +	smp_distribute_keys(conn); + +	return 0; +} + +static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) +{ +	struct smp_cmd_sign_info *rp = (void *) skb->data; +	struct smp_chan *smp = conn->smp_chan; +	struct hci_dev *hdev = conn->hcon->hdev; +	struct smp_csrk *csrk; + +	BT_DBG("conn %p", conn); + +	if (skb->len < sizeof(*rp)) +		return SMP_INVALID_PARAMS; + +	/* Ignore this PDU if it wasn't requested */ +	if (!(smp->remote_key_dist & SMP_DIST_SIGN)) +		return 0; + +	/* Mark the information as received */ +	smp->remote_key_dist &= ~SMP_DIST_SIGN; +  	skb_pull(skb, sizeof(*rp));  	hci_dev_lock(hdev); -	authenticated = (conn->hcon->sec_level == BT_SECURITY_HIGH); -	hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type, -		    HCI_SMP_LTK, 1, authenticated, smp->tk, smp->enc_key_size, -		    rp->ediv, rp->rand); -	smp_distribute_keys(conn, 1); +	csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); +	if (csrk) { +		csrk->master = 0x01; +		memcpy(csrk->val, rp->csrk, sizeof(csrk->val)); +	} +	smp->csrk = csrk; +	if (!(smp->remote_key_dist & SMP_DIST_SIGN)) +		smp_distribute_keys(conn);  	hci_dev_unlock(hdev);  	return 0; @@ -847,16 +1141,27 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)  int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)  { -	__u8 code = skb->data[0]; -	__u8 reason; +	struct hci_conn *hcon = conn->hcon; +	__u8 code, reason;  	int err = 0; -	if (!test_bit(HCI_LE_ENABLED, &conn->hcon->hdev->dev_flags)) { +	if (hcon->type != LE_LINK) { +		kfree_skb(skb); +		return 0; +	} + +	if (skb->len < 1) { +		kfree_skb(skb); +		return -EILSEQ; +	} + +	if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) {  		err = -ENOTSUPP;  		reason = SMP_PAIRING_NOTSUPP;  		goto done;  	} +	code = skb->data[0];  	skb_pull(skb, sizeof(code));  	/* @@ -878,7 +1183,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)  		break;  	case SMP_CMD_PAIRING_FAIL: -		smp_failure(conn, skb->data[0], 0); +		smp_failure(conn, 0);  		reason = 0;  		err = -EPERM;  		break; @@ -908,10 +1213,15 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)  		break;  	case SMP_CMD_IDENT_INFO: +		reason = smp_cmd_ident_info(conn, skb); +		break; +  	case SMP_CMD_IDENT_ADDR_INFO: +		reason = smp_cmd_ident_addr_info(conn, skb); +		break; +  	case SMP_CMD_SIGN_INFO: -		/* Just ignored */ -		reason = 0; +		reason = smp_cmd_sign_info(conn, skb);  		break;  	default: @@ -924,32 +1234,84 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)  done:  	if (reason) -		smp_failure(conn, reason, 1); +		smp_failure(conn, reason);  	kfree_skb(skb);  	return err;  } -int smp_distribute_keys(struct l2cap_conn *conn, __u8 force) +static void smp_notify_keys(struct l2cap_conn *conn) +{ +	struct smp_chan *smp = conn->smp_chan; +	struct hci_conn *hcon = conn->hcon; +	struct hci_dev *hdev = hcon->hdev; +	struct smp_cmd_pairing *req = (void *) &smp->preq[1]; +	struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1]; +	bool persistent; + +	if (smp->remote_irk) { +		mgmt_new_irk(hdev, smp->remote_irk); +		/* Now that user space can be considered to know the +		 * identity address track the connection based on it +		 * from now on. +		 */ +		bacpy(&hcon->dst, &smp->remote_irk->bdaddr); +		hcon->dst_type = smp->remote_irk->addr_type; +		l2cap_conn_update_id_addr(hcon); +	} + +	/* The LTKs and CSRKs should be persistent only if both sides +	 * had the bonding bit set in their authentication requests. +	 */ +	persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING); + +	if (smp->csrk) { +		smp->csrk->bdaddr_type = hcon->dst_type; +		bacpy(&smp->csrk->bdaddr, &hcon->dst); +		mgmt_new_csrk(hdev, smp->csrk, persistent); +	} + +	if (smp->slave_csrk) { +		smp->slave_csrk->bdaddr_type = hcon->dst_type; +		bacpy(&smp->slave_csrk->bdaddr, &hcon->dst); +		mgmt_new_csrk(hdev, smp->slave_csrk, persistent); +	} + +	if (smp->ltk) { +		smp->ltk->bdaddr_type = hcon->dst_type; +		bacpy(&smp->ltk->bdaddr, &hcon->dst); +		mgmt_new_ltk(hdev, smp->ltk, persistent); +	} + +	if (smp->slave_ltk) { +		smp->slave_ltk->bdaddr_type = hcon->dst_type; +		bacpy(&smp->slave_ltk->bdaddr, &hcon->dst); +		mgmt_new_ltk(hdev, smp->slave_ltk, persistent); +	} +} + +int smp_distribute_keys(struct l2cap_conn *conn)  {  	struct smp_cmd_pairing *req, *rsp;  	struct smp_chan *smp = conn->smp_chan; +	struct hci_conn *hcon = conn->hcon; +	struct hci_dev *hdev = hcon->hdev;  	__u8 *keydist; -	BT_DBG("conn %p force %d", conn, force); +	BT_DBG("conn %p", conn); -	if (!test_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) +	if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))  		return 0;  	rsp = (void *) &smp->prsp[1];  	/* The responder sends its keys first */ -	if (!force && conn->hcon->out && (rsp->resp_key_dist & 0x07)) +	if (hcon->out && (smp->remote_key_dist & 0x07))  		return 0;  	req = (void *) &smp->preq[1]; -	if (conn->hcon->out) { +	if (hcon->out) {  		keydist = &rsp->init_key_dist;  		*keydist &= req->init_key_dist;  	} else { @@ -957,28 +1319,30 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)  		*keydist &= req->resp_key_dist;  	} -  	BT_DBG("keydist 0x%x", *keydist);  	if (*keydist & SMP_DIST_ENC_KEY) {  		struct smp_cmd_encrypt_info enc;  		struct smp_cmd_master_ident ident; -		struct hci_conn *hcon = conn->hcon; +		struct smp_ltk *ltk;  		u8 authenticated;  		__le16 ediv; +		__le64 rand;  		get_random_bytes(enc.ltk, sizeof(enc.ltk));  		get_random_bytes(&ediv, sizeof(ediv)); -		get_random_bytes(ident.rand, sizeof(ident.rand)); +		get_random_bytes(&rand, sizeof(rand));  		smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc);  		authenticated = hcon->sec_level == BT_SECURITY_HIGH; -		hci_add_ltk(conn->hcon->hdev, conn->dst, hcon->dst_type, -			    HCI_SMP_LTK_SLAVE, 1, authenticated, -			    enc.ltk, smp->enc_key_size, ediv, ident.rand); +		ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, +				  HCI_SMP_LTK_SLAVE, authenticated, enc.ltk, +				  smp->enc_key_size, ediv, rand); +		smp->slave_ltk = ltk;  		ident.ediv = ediv; +		ident.rand = rand;  		smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident); @@ -989,37 +1353,54 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)  		struct smp_cmd_ident_addr_info addrinfo;  		struct smp_cmd_ident_info idinfo; -		/* Send a dummy key */ -		get_random_bytes(idinfo.irk, sizeof(idinfo.irk)); +		memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk));  		smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo); -		/* Just public address */ -		memset(&addrinfo, 0, sizeof(addrinfo)); -		bacpy(&addrinfo.bdaddr, conn->src); +		/* The hci_conn contains the local identity address +		 * after the connection has been established. +		 * +		 * This is true even when the connection has been +		 * established using a resolvable random address. +		 */ +		bacpy(&addrinfo.bdaddr, &hcon->src); +		addrinfo.addr_type = hcon->src_type;  		smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo), -								&addrinfo); +			     &addrinfo);  		*keydist &= ~SMP_DIST_ID_KEY;  	}  	if (*keydist & SMP_DIST_SIGN) {  		struct smp_cmd_sign_info sign; +		struct smp_csrk *csrk; -		/* Send a dummy key */ +		/* Generate a new random key */  		get_random_bytes(sign.csrk, sizeof(sign.csrk)); +		csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); +		if (csrk) { +			csrk->master = 0x00; +			memcpy(csrk->val, sign.csrk, sizeof(csrk->val)); +		} +		smp->slave_csrk = csrk; +  		smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign);  		*keydist &= ~SMP_DIST_SIGN;  	} -	if (conn->hcon->out || force) { -		clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags); -		cancel_delayed_work_sync(&conn->security_timer); -		smp_chan_destroy(conn); -	} +	/* If there are still keys to be received wait for them */ +	if ((smp->remote_key_dist & 0x07)) +		return 0; + +	clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags); +	cancel_delayed_work_sync(&conn->security_timer); +	set_bit(SMP_FLAG_COMPLETE, &smp->flags); +	smp_notify_keys(conn); + +	smp_chan_destroy(conn);  	return 0;  }  | 
