aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/smp.c
diff options
context:
space:
mode:
authorAnderson Briglia <anderson.briglia@openbossa.org>2011-06-09 17:50:44 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-06-13 14:48:23 -0400
commitd22ef0bc83c5a4e7ca9f2791e658dc8949d31ff4 (patch)
tree5c0e00d908550e1bda93160c4d865a46036a95c7 /net/bluetooth/smp.c
parent3a0259bb80cec7595a2d085a150412d23ba28c81 (diff)
Bluetooth: Add LE SMP Cryptoolbox functions
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@openbossa.org> Signed-off-by: Anderson Lizardo <anderson.lizardo@openbossa.org> Signed-off-by: Bruna Moreira <bruna.moreira@openbossa.org> Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/smp.c')
-rw-r--r--net/bluetooth/smp.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index aa20bee97501..57fc7d0cadf3 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -24,6 +24,123 @@
24#include <net/bluetooth/hci_core.h> 24#include <net/bluetooth/hci_core.h>
25#include <net/bluetooth/l2cap.h> 25#include <net/bluetooth/l2cap.h>
26#include <net/bluetooth/smp.h> 26#include <net/bluetooth/smp.h>
27#include <linux/crypto.h>
28#include <crypto/b128ops.h>
29
30static inline void swap128(u8 src[16], u8 dst[16])
31{
32 int i;
33 for (i = 0; i < 16; i++)
34 dst[15 - i] = src[i];
35}
36
37static inline void swap56(u8 src[7], u8 dst[7])
38{
39 int i;
40 for (i = 0; i < 7; i++)
41 dst[6 - i] = src[i];
42}
43
44static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
45{
46 struct blkcipher_desc desc;
47 struct scatterlist sg;
48 int err, iv_len;
49 unsigned char iv[128];
50
51 if (tfm == NULL) {
52 BT_ERR("tfm %p", tfm);
53 return -EINVAL;
54 }
55
56 desc.tfm = tfm;
57 desc.flags = 0;
58
59 err = crypto_blkcipher_setkey(tfm, k, 16);
60 if (err) {
61 BT_ERR("cipher setkey failed: %d", err);
62 return err;
63 }
64
65 sg_init_one(&sg, r, 16);
66
67 iv_len = crypto_blkcipher_ivsize(tfm);
68 if (iv_len) {
69 memset(&iv, 0xff, iv_len);
70 crypto_blkcipher_set_iv(tfm, iv, iv_len);
71 }
72
73 err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
74 if (err)
75 BT_ERR("Encrypt data error %d", err);
76
77 return err;
78}
79
80static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
81 u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
82 u8 _rat, bdaddr_t *ra, u8 res[16])
83{
84 u8 p1[16], p2[16];
85 int err;
86
87 memset(p1, 0, 16);
88
89 /* p1 = pres || preq || _rat || _iat */
90 swap56(pres, p1);
91 swap56(preq, p1 + 7);
92 p1[14] = _rat;
93 p1[15] = _iat;
94
95 memset(p2, 0, 16);
96
97 /* p2 = padding || ia || ra */
98 baswap((bdaddr_t *) (p2 + 4), ia);
99 baswap((bdaddr_t *) (p2 + 10), ra);
100
101 /* res = r XOR p1 */
102 u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
103
104 /* res = e(k, res) */
105 err = smp_e(tfm, k, res);
106 if (err) {
107 BT_ERR("Encrypt data error");
108 return err;
109 }
110
111 /* res = res XOR p2 */
112 u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
113
114 /* res = e(k, res) */
115 err = smp_e(tfm, k, res);
116 if (err)
117 BT_ERR("Encrypt data error");
118
119 return err;
120}
121
122static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16],
123 u8 r1[16], u8 r2[16], u8 _r[16])
124{
125 int err;
126
127 /* Just least significant octets from r1 and r2 are considered */
128 memcpy(_r, r1 + 8, 8);
129 memcpy(_r + 8, r2 + 8, 8);
130
131 err = smp_e(tfm, k, _r);
132 if (err)
133 BT_ERR("Encrypt data error");
134
135 return err;
136}
137
138static int smp_rand(u8 *buf)
139{
140 get_random_bytes(buf, 16);
141
142 return 0;
143}
27 144
28static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code, 145static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
29 u16 dlen, void *data) 146 u16 dlen, void *data)