{
        cmd->io_capability = conn->hcon->io_capability;
        cmd->oob_flag = SMP_OOB_NOT_PRESENT;
-       cmd->max_key_size = 16;
+       cmd->max_key_size = SMP_MAX_ENC_KEY_SIZE;
        cmd->init_key_dist = 0x00;
        cmd->resp_key_dist = 0x00;
        cmd->auth_req = authreq;
 }
 
+static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
+{
+       if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) ||
+                       (max_key_size < SMP_MIN_ENC_KEY_SIZE))
+               return SMP_ENC_KEY_SIZE;
+
+       conn->smp_key_size = max_key_size;
+
+       return 0;
+}
+
 static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
 {
-       struct smp_cmd_pairing *rp = (void *) skb->data;
+       struct smp_cmd_pairing rsp, *req = (void *) skb->data;
+       u8 key_size;
 
        BT_DBG("conn %p", conn);
 
        conn->preq[0] = SMP_CMD_PAIRING_REQ;
-       memcpy(&conn->preq[1], rp, sizeof(*rp));
-       skb_pull(skb, sizeof(*rp));
+       memcpy(&conn->preq[1], req, sizeof(*req));
+       skb_pull(skb, sizeof(*req));
 
-       if (rp->oob_flag)
+       if (req->oob_flag)
                return SMP_OOB_NOT_AVAIL;
 
        /* We didn't start the pairing, so no requirements */
-       build_pairing_cmd(conn, rp, SMP_AUTH_NONE);
+       build_pairing_cmd(conn, &rsp, SMP_AUTH_NONE);
+
+       key_size = min(req->max_key_size, rsp.max_key_size);
+       if (check_enc_key_size(conn, key_size))
+               return SMP_ENC_KEY_SIZE;
 
        /* Just works */
        memset(conn->tk, 0, sizeof(conn->tk));
 
        conn->prsp[0] = SMP_CMD_PAIRING_RSP;
-       memcpy(&conn->prsp[1], rp, sizeof(*rp));
+       memcpy(&conn->prsp[1], &rsp, sizeof(rsp));
 
-       smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(*rp), rp);
+       smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
 
        mod_timer(&conn->security_timer, jiffies +
                                        msecs_to_jiffies(SMP_TIMEOUT));
 
 static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
 {
-       struct smp_cmd_pairing *rp = (void *) skb->data;
+       struct smp_cmd_pairing *req, *rsp = (void *) skb->data;
        struct smp_cmd_pairing_confirm cp;
        struct crypto_blkcipher *tfm = conn->hcon->hdev->tfm;
        int ret;
-       u8 res[16];
+       u8 res[16], key_size;
 
        BT_DBG("conn %p", conn);
 
-       skb_pull(skb, sizeof(*rp));
+       skb_pull(skb, sizeof(*rsp));
+
+       req = (void *) &conn->preq[1];
 
-       if (rp->oob_flag)
+       key_size = min(req->max_key_size, rsp->max_key_size);
+       if (check_enc_key_size(conn, key_size))
+               return SMP_ENC_KEY_SIZE;
+
+       if (rsp->oob_flag)
                return SMP_OOB_NOT_AVAIL;
 
        /* Just works */
        memset(conn->tk, 0, sizeof(conn->tk));
 
        conn->prsp[0] = SMP_CMD_PAIRING_RSP;
-       memcpy(&conn->prsp[1], rp, sizeof(*rp));
+       memcpy(&conn->prsp[1], rsp, sizeof(*rsp));
 
        ret = smp_rand(conn->prnd);
        if (ret)
                smp_s1(tfm, conn->tk, random, conn->prnd, key);
                swap128(key, hcon->ltk);
 
+               memset(hcon->ltk + conn->smp_key_size, 0,
+                               SMP_MAX_ENC_KEY_SIZE - conn->smp_key_size);
+
                memset(rand, 0, sizeof(rand));
                ediv = 0;
                hci_le_start_enc(hcon, ediv, rand, hcon->ltk);
 
                smp_s1(tfm, conn->tk, conn->prnd, random, key);
                swap128(key, hcon->ltk);
+
+               memset(hcon->ltk + conn->smp_key_size, 0,
+                               SMP_MAX_ENC_KEY_SIZE - conn->smp_key_size);
        }
 
        return 0;