Esempio n. 1
0
static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
{
	struct hci_conn *hcon = conn->hcon;
	int ret;

	BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");

	memcpy(hcon->pcnf, skb->data, sizeof(hcon->pcnf));
	skb_pull(skb, sizeof(hcon->pcnf));

	if (conn->hcon->out) {
		u8 random[16];

		swap128(hcon->prnd, random);
		smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random),
								random);
	} else if (hcon->tk_valid) {
		ret = send_pairing_confirm(conn);

		if (ret)
			return SMP_CONFIRM_FAILED;
	} else
		hcon->cfm_pending = TRUE;


	mod_timer(&hcon->smp_timer, jiffies + msecs_to_jiffies(SMP_TIMEOUT));

	return 0;
}
Esempio n. 2
0
int le_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, void *cp)
{
	struct mgmt_cp_user_passkey_reply *psk_reply = cp;
	struct l2cap_conn *conn = hcon->smp_conn;
	u8 key[16];
	u8 reason = 0;
	int ret = 0;

	BT_DBG("");

	hcon->tk_valid = TRUE;

	switch (mgmt_op) {
	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
		reason = SMP_CONFIRM_FAILED;
		break;
	case MGMT_OP_USER_CONFIRM_REPLY:
		break;
	case MGMT_OP_USER_PASSKEY_REPLY:
		memset(key, 0, sizeof(key));
		BT_DBG("PassKey: %d", psk_reply->passkey);
		put_unaligned_le32(psk_reply->passkey, key);
		swap128(key, hcon->tk);
		break;
	default:
		reason = SMP_CONFIRM_FAILED;
		ret = -EOPNOTSUPP;
		break;
	}

	if (reason) {
		BT_DBG("smp_send_cmd: SMP_CMD_PAIRING_FAIL");
		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
								&reason);
		del_timer(&hcon->smp_timer);
		clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
#ifdef BLUETOOTH_CUSTOMIZE
		clear_bit(HCI_CONN_LE_CONN_UPDATE_PEND, &hcon->pend);
#endif /* BLUETOOTH_CUSTOMIZE */
		mgmt_auth_failed(hcon->hdev->id, conn->dst, reason);
		hci_conn_put(hcon);
	} else if (hcon->cfm_pending) {
		BT_DBG("send_pairing_confirm");
		ret = send_pairing_confirm(conn);
	}

	return ret;
}
Esempio n. 3
0
static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
{
	struct hci_conn *hcon = conn->hcon;
	struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
	u8 key_size, auth = SMP_AUTH_NONE;
	int ret;

	BT_DBG("conn %p", conn);

	skb_pull(skb, sizeof(*rsp));

	req = (void *) &hcon->preq[1];

	key_size = min(req->max_key_size, rsp->max_key_size);
	if (check_enc_key_size(conn, key_size))
		return SMP_ENC_KEY_SIZE;

	hcon->prsp[0] = SMP_CMD_PAIRING_RSP;
	memcpy(&hcon->prsp[1], rsp, sizeof(*rsp));

	ret = smp_rand(hcon->prnd);
	if (ret)
		return SMP_UNSPECIFIED;

	if ((req->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;

	ret = tk_request(conn, req->oob_flag, auth, rsp->io_capability,
							req->io_capability);
	if (ret)
		return SMP_UNSPECIFIED;

	hcon->cfm_pending = TRUE;

	
	if (!hcon->tk_valid)
		return 0;

	ret = send_pairing_confirm(conn);
	if (ret)
		return SMP_CONFIRM_FAILED;

	return 0;
}