[bluetooth-next 05/15] Bluetooth: LE SMP Cryptoolbox functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Anderson Briglia <anderson.briglia@xxxxxxxxxxxxx>

This patch implements SMP crypto functions called ah, c1, s1 and e.
It also implements auxiliary functions. All These functions are needed
for SMP keys generation.

Signed-off-by: Anderson Briglia <anderson.briglia@xxxxxxxxxxxxx>
Signed-off-by: Anderson Lizardo <anderson.lizardo@xxxxxxxxxxxxx>
Signed-off-by: Bruna Moreira <bruna.moreira@xxxxxxxxxxxxx>
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@xxxxxxxxxxxxx>
---
 net/bluetooth/smp.c |  122 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 122 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 7f275bf..740f579 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -24,6 +24,128 @@
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/l2cap.h>
 #include <net/bluetooth/smp.h>
+#include <linux/crypto.h>
+#include <crypto/b128ops.h>
+
+static inline void swap128(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])
+{
+	int i;
+	for (i = 0; i < 7; i++)
+		dst[6 - i] = src[i];
+}
+
+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];
+
+	if (tfm == NULL) {
+		BT_ERR("tfm %p", tfm);
+		return -EINVAL;
+	}
+
+	desc.tfm = tfm;
+	desc.flags = 0;
+
+	err = crypto_blkcipher_setkey(tfm, k, 16);
+	if (err) {
+		BT_ERR("cipher setkey failed: %d", err);
+		return err;
+	}
+
+	sg_init_one(&sg, r, 16);
+
+	iv_len = crypto_blkcipher_ivsize(tfm);
+	if (iv_len) {
+		memset(&iv, 0xff, iv_len);
+		crypto_blkcipher_set_iv(tfm, iv, iv_len);
+	}
+
+	err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
+	if (err)
+		BT_ERR("Encrypt data error %d", err);
+
+	return err;
+}
+
+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 p1[16], p2[16], pair[7];
+	bdaddr_t addr;
+	int err;
+
+	/* p1 = pres || preq || _rat || _iat */
+	memset(p1, 0, 16);
+	swap56(pres, pair);
+
+	memcpy(p1, pair, 7);
+	swap56(preq, pair);
+
+	memcpy(p1 + 7, pair, 7);
+	*(p1 + 14) = _rat;
+	*(p1 + 15) = _iat;
+
+	/* p2 = padding || ia || ra */
+	memset(p2, 0, 16);
+	baswap(&addr, ia);
+	memcpy(p2 + 4, &addr, 6);
+	baswap(&addr, ra);
+	memcpy(p2 + 10, &addr, 6);
+
+	/* res = r XOR p1 */
+	u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
+
+	/* res = e(k, res) */
+	err = smp_e(tfm, k, res);
+	if (err) {
+		BT_ERR("Encrypt data error");
+		return err;
+	}
+
+	/* res = res XOR p2 */
+	u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
+
+	/* res = e(k, res) */
+	err = smp_e(tfm, k, res);
+	if (err)
+		BT_ERR("Encrypt data error");
+
+	return err;
+}
+
+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);
+
+	err = smp_e(tfm, k, _r);
+	if (err)
+		BT_ERR("Encrypt data error");
+
+	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)
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux