summaryrefslogtreecommitdiff
path: root/tools/smp-tester.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-03-17 19:01:35 +0200
committerJohan Hedberg <johan.hedberg@intel.com>2014-03-17 19:01:35 +0200
commit7942c48b4ca773f9f70ae6a456830dc4350cad14 (patch)
tree2ad9cef638e9c38bb0fabf23692fdcbb84e644d3 /tools/smp-tester.c
parent5579308c0d2baa6dbf3205ff1876fb9396cf1dfe (diff)
downloadbluez-7942c48b4ca773f9f70ae6a456830dc4350cad14.tar.gz
tools/smp-tester: Convert to using shared/crypto.c
Diffstat (limited to 'tools/smp-tester.c')
-rw-r--r--tools/smp-tester.c255
1 files changed, 24 insertions, 231 deletions
diff --git a/tools/smp-tester.c b/tools/smp-tester.c
index d81266394..8e5ed8544 100644
--- a/tools/smp-tester.c
+++ b/tools/smp-tester.c
@@ -40,44 +40,11 @@
#include "monitor/bt.h"
#include "emulator/bthost.h"
+#include "src/shared/crypto.h"
#include "src/shared/tester.h"
#include "src/shared/mgmt.h"
#include "src/shared/hciemu.h"
-#ifndef SOL_ALG
-#define SOL_ALG 279
-#endif
-
-#ifndef AF_ALG
-#define AF_ALG 38
-#define PF_ALG AF_ALG
-
-#include <linux/types.h>
-
-struct sockaddr_alg {
- __u16 salg_family;
- __u8 salg_type[14];
- __u32 salg_feat;
- __u32 salg_mask;
- __u8 salg_name[64];
-};
-
-struct af_alg_iv {
- __u32 ivlen;
- __u8 iv[0];
-};
-
-#define ALG_SET_KEY 1
-#define ALG_SET_IV 2
-#define ALG_SET_OP 3
-
-#define ALG_OP_DECRYPT 0
-#define ALG_OP_ENCRYPT 1
-
-#else
-#include <linux/if_alg.h>
-#endif
-
#define SMP_CID 0x0006
struct test_data {
@@ -94,7 +61,7 @@ struct test_data {
bool out;
uint16_t handle;
size_t counter;
- int alg_sk;
+ struct bt_crypto *crypto;
uint8_t smp_tk[16];
uint8_t smp_prnd[16];
uint8_t smp_rrnd[16];
@@ -116,180 +83,6 @@ struct smp_data {
size_t req_count;
};
-static int alg_setup(void)
-{
- struct sockaddr_alg salg;
- int sk;
-
- sk = socket(PF_ALG, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
- if (sk < 0) {
- tester_warn("socket(AF_ALG): %s", strerror(errno));
- return -1;
- }
-
- memset(&salg, 0, sizeof(salg));
- salg.salg_family = AF_ALG;
- strcpy((char *) salg.salg_type, "skcipher");
- strcpy((char *) salg.salg_name, "ecb(aes)");
-
- if (bind(sk, (struct sockaddr *) &salg, sizeof(salg)) < 0) {
- tester_warn("bind(AF_ALG): %s", strerror(errno));
- close(sk);
- return -1;
- }
-
- return sk;
-}
-
-static int alg_new(int alg_sk, const uint8_t *key)
-{
- int sk;
-
- if (setsockopt(alg_sk, SOL_ALG, ALG_SET_KEY, key, 16) < 0) {
- tester_warn("setsockopt(ALG_SET_KEY): %s", strerror(errno));
- return -1;
- }
-
- sk = accept4(alg_sk, NULL, 0, SOCK_CLOEXEC);
- if (sk < 0) {
- tester_warn("accept4(AF_ALG): %s", strerror(errno));
- return -1;
- }
-
- return sk;
-}
-
-static int alg_encrypt(int sk, uint8_t in[16], uint8_t out[16])
-{
- __u32 alg_op = ALG_OP_ENCRYPT;
- char cbuf[CMSG_SPACE(sizeof(alg_op))];
- struct cmsghdr *cmsg;
- struct msghdr msg;
- struct iovec iov;
- int ret;
-
- memset(cbuf, 0, sizeof(cbuf));
- memset(&msg, 0, sizeof(msg));
-
- msg.msg_control = cbuf;
- msg.msg_controllen = sizeof(cbuf);
-
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_level = SOL_ALG;
- cmsg->cmsg_type = ALG_SET_OP;
- cmsg->cmsg_len = CMSG_LEN(sizeof(alg_op));
- memcpy(CMSG_DATA(cmsg), &alg_op, sizeof(alg_op));
-
- iov.iov_base = in;
- iov.iov_len = 16;
-
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
-
- ret = sendmsg(sk, &msg, 0);
- if (ret < 0) {
- tester_warn("sendmsg(AF_ALG): %s", strerror(errno));
- return ret;
- }
-
- ret = read(sk, out, 16);
- if (ret < 0)
- tester_warn("read(AF_ALG): %s", strerror(errno));
-
- return 0;
-}
-
-static int smp_e(uint8_t key[16], uint8_t in[16], uint8_t out[16])
-{
- struct test_data *data = tester_get_data();
- int sk, err;
-
- sk = alg_new(data->alg_sk, key);
- if (sk < 0)
- return sk;
-
- err = alg_encrypt(sk, in, out);
-
- close(sk);
-
- return err;
-}
-
-static inline void swap128(const uint8_t src[16], uint8_t dst[16])
-{
- int i;
- for (i = 0; i < 16; i++)
- dst[15 - i] = src[i];
-}
-
-static inline void swap56(const uint8_t src[7], uint8_t dst[7])
-{
- int i;
- for (i = 0; i < 7; i++)
- dst[6 - i] = src[i];
-}
-
-typedef struct {
- uint64_t a, b;
-} u128;
-
-static inline void u128_xor(void *r, const void *p, const void *q)
-{
- const u128 pp = bt_get_unaligned((const u128 *) p);
- const u128 qq = bt_get_unaligned((const u128 *) q);
- u128 rr;
-
- rr.a = pp.a ^ qq.a;
- rr.b = pp.b ^ qq.b;
-
- bt_put_unaligned(rr, (u128 *) r);
-}
-
-static int smp_c1(uint8_t r[16], uint8_t res[16])
-{
- struct test_data *data = tester_get_data();
- uint8_t p1[16], p2[16];
- int err;
-
- memset(p1, 0, 16);
-
- /* p1 = pres || preq || _rat || _iat */
- swap56(data->smp_prsp, p1);
- swap56(data->smp_preq, p1 + 7);
- p1[14] = data->ra_type;
- p1[15] = data->ia_type;
-
- memset(p2, 0, 16);
-
- /* p2 = padding || ia || ra */
- baswap((bdaddr_t *) (p2 + 4), (bdaddr_t *) data->ia);
- baswap((bdaddr_t *) (p2 + 10), (bdaddr_t *) data->ra);
-
- /* res = r XOR p1 */
- u128_xor(res, r, p1);
-
- /* res = e(k, res) */
- err = smp_e(data->smp_tk, res, res);
- if (err)
- return err;
-
- /* res = res XOR p2 */
- u128_xor(res, res, p2);
-
- /* res = e(k, res) */
- return smp_e(data->smp_tk, res, res);
-}
-
-static int smp_s1(uint8_t r1[16], uint8_t r2[16], uint8_t res[16])
-{
- struct test_data *data = tester_get_data();
-
- memcpy(res, r1 + 8, 8);
- memcpy(res + 8, r2 + 8, 8);
-
- return smp_e(data->smp_tk, res, res);
-}
-
static void mgmt_debug(const char *str, void *user_data)
{
const char *prefix = user_data;
@@ -402,9 +195,9 @@ static void test_pre_setup(const void *test_data)
{
struct test_data *data = tester_get_data();
- data->alg_sk = alg_setup();
- if (data->alg_sk < 0) {
- tester_warn("Failed to setup AF_ALG socket");
+ data->crypto = bt_crypto_new();
+ if (!data->crypto) {
+ tester_warn("Failed to setup crypto");
tester_pre_setup_failed();
return;
}
@@ -412,6 +205,7 @@ static void test_pre_setup(const void *test_data)
data->mgmt = mgmt_new_default();
if (!data->mgmt) {
tester_warn("Failed to setup management interface");
+ bt_crypto_unref(data->crypto);
tester_pre_setup_failed();
return;
}
@@ -432,9 +226,9 @@ static void test_post_teardown(const void *test_data)
data->io_id = 0;
}
- if (data->alg_sk >= 0) {
- close(data->alg_sk);
- data->alg_sk = -1;
+ if (data->crypto) {
+ bt_crypto_unref(data->crypto);
+ data->crypto = NULL;
}
hciemu_unref(data->hciemu);
@@ -455,7 +249,6 @@ static void test_data_free(void *test_data)
if (!user) \
break; \
user->hciemu_type = HCIEMU_TYPE_LE; \
- user->alg_sk = -1; \
user->test_data = data; \
tester_add_full(name, data, \
test_pre_setup, setup, func, NULL, \
@@ -616,7 +409,6 @@ static const void *get_pdu(const uint8_t *data)
struct test_data *test_data = tester_get_data();
uint8_t opcode = data[0];
static uint8_t buf[17];
- uint8_t res[16];
switch (opcode) {
case 0x01: /* Pairing Request */
@@ -627,12 +419,15 @@ static const void *get_pdu(const uint8_t *data)
break;
case 0x03: /* Pairing Confirm */
buf[0] = data[0];
- smp_c1(test_data->smp_prnd, res);
- swap128(res, &buf[1]);
+ bt_crypto_c1(test_data->crypto, test_data->smp_tk,
+ test_data->smp_prnd, test_data->smp_prsp,
+ test_data->smp_preq, test_data->ia_type,
+ test_data->ia, test_data->ra_type,
+ test_data->ra, &buf[1]);
return buf;
case 0x04: /* Pairing Random */
buf[0] = data[0];
- swap128(test_data->smp_prnd, &buf[1]);
+ memcpy(&buf[1], test_data->smp_prnd, 16);
return buf;
default:
break;
@@ -644,15 +439,13 @@ static const void *get_pdu(const uint8_t *data)
static bool verify_random(const uint8_t rnd[16])
{
struct test_data *data = tester_get_data();
- uint8_t confirm[16], res[16], key[16];
- int err;
+ uint8_t confirm[16];
- err = smp_c1(data->smp_rrnd, res);
- if (err < 0)
+ if (!bt_crypto_c1(data->crypto, data->smp_tk, data->smp_rrnd,
+ data->smp_prsp, data->smp_preq, data->ia_type,
+ data->ia, data->ra_type, data->ra, confirm))
return false;
- swap128(res, confirm);
-
if (memcmp(data->smp_pcnf, confirm, sizeof(data->smp_pcnf) != 0)) {
tester_warn("Confirmation values don't match");
return false;
@@ -660,12 +453,12 @@ static bool verify_random(const uint8_t rnd[16])
if (data->out) {
struct bthost *bthost = hciemu_client_get_host(data->hciemu);
- smp_s1(data->smp_rrnd, data->smp_prnd, key);
- swap128(key, data->smp_ltk);
+ bt_crypto_s1(data->crypto, data->smp_tk, data->smp_rrnd,
+ data->smp_prnd, data->smp_ltk);
bthost_le_start_encrypt(bthost, data->handle, data->smp_ltk);
} else {
- smp_s1(data->smp_prnd, data->smp_rrnd, key);
- swap128(key, data->smp_ltk);
+ bt_crypto_s1(data->crypto, data->smp_tk, data->smp_prnd,
+ data->smp_rrnd, data->smp_ltk);
}
return true;
@@ -715,7 +508,7 @@ static void smp_server(const void *data, uint16_t len, void *user_data)
memcpy(test_data->smp_pcnf, data + 1, 16);
goto next;
case 0x04: /* Pairing Random */
- swap128(data + 1, test_data->smp_rrnd);
+ memcpy(test_data->smp_rrnd, data + 1, 16);
if (!verify_random(data + 1))
goto failed;
goto next;