return err;
 }
 
+static int smp_g2(struct crypto_hash *tfm_cmac, const u8 u[32], const u8 v[32],
+                 const u8 x[16], const u8 y[16], u32 *val)
+{
+       u8 m[80], tmp[16];
+       int err;
+
+       BT_DBG("u %32phN", u);
+       BT_DBG("v %32phN", v);
+       BT_DBG("x %16phN y %16phN", x, y);
+
+       memcpy(m, y, 16);
+       memcpy(m + 16, v, 32);
+       memcpy(m + 48, u, 32);
+
+       err = aes_cmac(tfm_cmac, x, m, sizeof(m), tmp);
+       if (err)
+               return err;
+
+       *val = get_unaligned_le32(tmp);
+       *val %= 1000000;
+
+       BT_DBG("val %06u", *val);
+
+       return 0;
+}
+
 static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
 {
        struct blkcipher_desc desc;
 {
        struct l2cap_chan *chan = conn->smp;
        struct smp_chan *smp = chan->data;
+       struct hci_conn *hcon = conn->hcon;
+       u8 *pkax, *pkbx, *na, *nb;
+       u32 passkey;
+       int err;
 
        BT_DBG("conn %p", conn);
 
        memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
        skb_pull(skb, sizeof(smp->rrnd));
 
-       return smp_random(smp);
+       if (!test_bit(SMP_FLAG_SC, &smp->flags))
+               return smp_random(smp);
+
+       if (hcon->out) {
+               u8 cfm[16];
+
+               err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
+                            smp->rrnd, 0, cfm);
+               if (err)
+                       return SMP_UNSPECIFIED;
+
+               if (memcmp(smp->pcnf, cfm, 16))
+                       return SMP_CONFIRM_FAILED;
+
+               pkax = smp->local_pk;
+               pkbx = smp->remote_pk;
+               na   = smp->prnd;
+               nb   = smp->rrnd;
+       } else {
+               smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
+                            smp->prnd);
+               SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
+
+               pkax = smp->remote_pk;
+               pkbx = smp->local_pk;
+               na   = smp->rrnd;
+               nb   = smp->prnd;
+       }
+
+       err = smp_g2(smp->tfm_cmac, pkax, pkbx, na, nb, &passkey);
+       if (err)
+               return SMP_UNSPECIFIED;
+
+       err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
+                                       hcon->type, hcon->dst_type,
+                                       passkey, 0);
+       if (err)
+               return SMP_UNSPECIFIED;
+
+       return 0;
 }
 
 static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level)