* [PATCH 1/3] Bluetooth: Pass only crypto context to SMP crypto functions
2014-10-25 19:15 [PATCH 0/3] Bluetooth: Add kernel-side SMP self-tests johan.hedberg
@ 2014-10-25 19:15 ` johan.hedberg
2014-10-25 19:15 ` [PATCH 2/3] Bluetooth: Add skeleton for SMP self-tests johan.hedberg
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: johan.hedberg @ 2014-10-25 19:15 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
In order to make unit testing possible we need to make the SMP crypto
functions only take the crypto context instead of the full SMP context
(the latter would require having hci_dev, hci_conn, l2cap_chan,
l2cap_conn, etc around). The drawback is that we no-longer get the
involved hdev in the debug logs, but this is really the only way to make
simple unit tests for the code.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
net/bluetooth/smp.c | 30 ++++++++++++------------------
1 file changed, 12 insertions(+), 18 deletions(-)
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index f09b6b65cf6b..fea3782989f4 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -191,16 +191,13 @@ int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa)
return 0;
}
-static int smp_c1(struct smp_chan *smp, 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])
+static int smp_c1(struct crypto_blkcipher *tfm_aes, 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])
{
- struct hci_dev *hdev = smp->conn->hcon->hdev;
u8 p1[16], p2[16];
int err;
- BT_DBG("%s", hdev->name);
-
memset(p1, 0, 16);
/* p1 = pres || preq || _rat || _iat */
@@ -218,7 +215,7 @@ static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7],
u128_xor((u128 *) res, (u128 *) r, (u128 *) p1);
/* res = e(k, res) */
- err = smp_e(smp->tfm_aes, k, res);
+ err = smp_e(tfm_aes, k, res);
if (err) {
BT_ERR("Encrypt data error");
return err;
@@ -228,26 +225,23 @@ static int smp_c1(struct smp_chan *smp, u8 k[16], u8 r[16], u8 preq[7],
u128_xor((u128 *) res, (u128 *) res, (u128 *) p2);
/* res = e(k, res) */
- err = smp_e(smp->tfm_aes, k, res);
+ err = smp_e(tfm_aes, k, res);
if (err)
BT_ERR("Encrypt data error");
return err;
}
-static int smp_s1(struct smp_chan *smp, u8 k[16], u8 r1[16], u8 r2[16],
- u8 _r[16])
+static int smp_s1(struct crypto_blkcipher *tfm_aes, u8 k[16], u8 r1[16],
+ u8 r2[16], u8 _r[16])
{
- struct hci_dev *hdev = smp->conn->hcon->hdev;
int err;
- BT_DBG("%s", hdev->name);
-
/* Just least significant octets from r1 and r2 are considered */
memcpy(_r, r2, 8);
memcpy(_r + 8, r1, 8);
- err = smp_e(smp->tfm_aes, k, _r);
+ err = smp_e(tfm_aes, k, _r);
if (err)
BT_ERR("Encrypt data error");
@@ -547,7 +541,7 @@ static u8 smp_confirm(struct smp_chan *smp)
BT_DBG("conn %p", conn);
- ret = smp_c1(smp, smp->tk, smp->prnd, smp->preq, smp->prsp,
+ ret = smp_c1(smp->tfm_aes, smp->tk, smp->prnd, smp->preq, smp->prsp,
conn->hcon->init_addr_type, &conn->hcon->init_addr,
conn->hcon->resp_addr_type, &conn->hcon->resp_addr,
cp.confirm_val);
@@ -578,7 +572,7 @@ static u8 smp_random(struct smp_chan *smp)
BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
- ret = smp_c1(smp, smp->tk, smp->rrnd, smp->preq, smp->prsp,
+ ret = smp_c1(smp->tfm_aes, smp->tk, smp->rrnd, smp->preq, smp->prsp,
hcon->init_addr_type, &hcon->init_addr,
hcon->resp_addr_type, &hcon->resp_addr, confirm);
if (ret)
@@ -594,7 +588,7 @@ static u8 smp_random(struct smp_chan *smp)
__le64 rand = 0;
__le16 ediv = 0;
- smp_s1(smp, smp->tk, smp->rrnd, smp->prnd, stk);
+ smp_s1(smp->tfm_aes, smp->tk, smp->rrnd, smp->prnd, stk);
memset(stk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
@@ -613,7 +607,7 @@ static u8 smp_random(struct smp_chan *smp)
smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
smp->prnd);
- smp_s1(smp, smp->tk, smp->prnd, smp->rrnd, stk);
+ smp_s1(smp->tfm_aes, smp->tk, smp->prnd, smp->rrnd, stk);
memset(stk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
--
1.9.3
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 2/3] Bluetooth: Add skeleton for SMP self-tests
2014-10-25 19:15 [PATCH 0/3] Bluetooth: Add kernel-side SMP self-tests johan.hedberg
2014-10-25 19:15 ` [PATCH 1/3] Bluetooth: Pass only crypto context to SMP crypto functions johan.hedberg
@ 2014-10-25 19:15 ` johan.hedberg
2014-10-25 19:15 ` [PATCH 3/3] Bluetooth: Add self-tests for SMP crypto functions johan.hedberg
2014-10-25 19:39 ` [PATCH 0/3] Bluetooth: Add kernel-side SMP self-tests Marcel Holtmann
3 siblings, 0 replies; 5+ messages in thread
From: johan.hedberg @ 2014-10-25 19:15 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
This patch adds a basic skeleton for SMP self-tests. The tests are put
behind a new configuration option since running them will slow down the
boot process. For now there are no actual tests defined but those will
come in a subsequent patch.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
net/bluetooth/Kconfig | 6 ++++++
net/bluetooth/smp.c | 33 +++++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 600fb29288f4..2675b4106b00 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -45,6 +45,12 @@ config BT_6LOWPAN
help
IPv6 compression over Bluetooth Low Energy.
+config BT_SELFTEST
+ bool "Run self-tests on boot"
+ depends on BT && DEBUG_KERNEL
+ help
+ Run self-tests during boot. Currently limited to SMP.
+
source "net/bluetooth/rfcomm/Kconfig"
source "net/bluetooth/bnep/Kconfig"
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index fea3782989f4..9821dc938e2c 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -1743,3 +1743,36 @@ void smp_unregister(struct hci_dev *hdev)
hdev->smp_data = NULL;
l2cap_chan_put(chan);
}
+
+#ifdef CONFIG_BT_SELFTEST
+
+static int __init run_selftests(struct crypto_blkcipher *tfm_aes)
+{
+ return 0;
+}
+
+static int __init test_smp(void)
+{
+ struct crypto_blkcipher *tfm_aes;
+ int err;
+
+ tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(tfm_aes)) {
+ BT_ERR("Unable to create ECB crypto context");
+ return PTR_ERR(tfm_aes);
+ }
+
+ err = run_selftests(tfm_aes);
+ if (err < 0)
+ BT_ERR("Self tests failed");
+ else
+ BT_INFO("Self-tests passed");
+
+ crypto_free_blkcipher(tfm_aes);
+
+ return err;
+}
+
+module_init(test_smp);
+
+#endif /* CONFIG_BT_SELFTEST */
--
1.9.3
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 3/3] Bluetooth: Add self-tests for SMP crypto functions
2014-10-25 19:15 [PATCH 0/3] Bluetooth: Add kernel-side SMP self-tests johan.hedberg
2014-10-25 19:15 ` [PATCH 1/3] Bluetooth: Pass only crypto context to SMP crypto functions johan.hedberg
2014-10-25 19:15 ` [PATCH 2/3] Bluetooth: Add skeleton for SMP self-tests johan.hedberg
@ 2014-10-25 19:15 ` johan.hedberg
2014-10-25 19:39 ` [PATCH 0/3] Bluetooth: Add kernel-side SMP self-tests Marcel Holtmann
3 siblings, 0 replies; 5+ messages in thread
From: johan.hedberg @ 2014-10-25 19:15 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
This patch adds self-tests for the c1 and s1 crypto functions used for
SMP pairing. The data used is the sample data from the core
specification.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
net/bluetooth/smp.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 87 insertions(+)
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 9821dc938e2c..983d1e0793f6 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -1746,8 +1746,95 @@ void smp_unregister(struct hci_dev *hdev)
#ifdef CONFIG_BT_SELFTEST
+static int __init test_ah(struct crypto_blkcipher *tfm_aes)
+{
+ u8 irk[16] = { 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34,
+ 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec };
+ u8 r[3] = { 0x94, 0x81, 0x70 };
+ u8 exp[3] = { 0xaa, 0xfb, 0x0d };
+ u8 res[3];
+ int err;
+
+ err = smp_ah(tfm_aes, irk, r, res);
+ if (err)
+ return err;
+
+ if (memcmp(res, exp, 3) != 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int __init test_c1(struct crypto_blkcipher *tfm_aes)
+{
+ u8 k[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ u8 r[16] = { 0xe0, 0x2e, 0x70, 0xc6, 0x4e, 0x27, 0x88, 0x63,
+ 0x0e, 0x6f, 0xad, 0x56, 0x21, 0xd5, 0x83, 0x57 };
+ u8 preq[7] = { 0x01, 0x01, 0x00, 0x00, 0x10, 0x07, 0x07 };
+ u8 pres[7] = { 0x02, 0x03, 0x00, 0x00, 0x08, 0x00, 0x05 };
+ u8 _iat = 0x01;
+ u8 _rat = 0x00;
+ bdaddr_t ra = { { 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1 } };
+ bdaddr_t ia = { { 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1 } };
+ u8 exp[16] = { 0x86, 0x3b, 0xf1, 0xbe, 0xc5, 0x4d, 0xa7, 0xd2,
+ 0xea, 0x88, 0x89, 0x87, 0xef, 0x3f, 0x1e, 0x1e };
+ u8 res[16];
+ int err;
+
+ err = smp_c1(tfm_aes, k, r, preq, pres, _iat, &ia, _rat, &ra, res);
+ if (err)
+ return err;
+
+ if (memcmp(res, exp, 16) != 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int __init test_s1(struct crypto_blkcipher *tfm_aes)
+{
+ u8 k[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ u8 r1[16] = { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 };
+ u8 r2[16] = { 0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99 };
+ u8 exp[16] = { 0x62, 0xa0, 0x6d, 0x79, 0xae, 0x16, 0x42, 0x5b,
+ 0x9b, 0xf4, 0xb0, 0xe8, 0xf0, 0xe1, 0x1f, 0x9a };
+ u8 res[16];
+ int err;
+
+ err = smp_s1(tfm_aes, k, r1, r2, res);
+ if (err)
+ return err;
+
+ if (memcmp(res, exp, 16) != 0)
+ return -EINVAL;
+
+ return 0;
+}
+
static int __init run_selftests(struct crypto_blkcipher *tfm_aes)
{
+ int err;
+
+ err = test_ah(tfm_aes);
+ if (err) {
+ BT_ERR("smp_ah test failed");
+ return err;
+ }
+
+ err = test_c1(tfm_aes);
+ if (err) {
+ BT_ERR("smp_c1 test failed");
+ return err;
+ }
+
+ err = test_s1(tfm_aes);
+ if (err) {
+ BT_ERR("smp_s1 test failed");
+ return err;
+ }
+
return 0;
}
--
1.9.3
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH 0/3] Bluetooth: Add kernel-side SMP self-tests
2014-10-25 19:15 [PATCH 0/3] Bluetooth: Add kernel-side SMP self-tests johan.hedberg
` (2 preceding siblings ...)
2014-10-25 19:15 ` [PATCH 3/3] Bluetooth: Add self-tests for SMP crypto functions johan.hedberg
@ 2014-10-25 19:39 ` Marcel Holtmann
3 siblings, 0 replies; 5+ messages in thread
From: Marcel Holtmann @ 2014-10-25 19:39 UTC (permalink / raw)
To: Johan Hedberg; +Cc: linux-bluetooth
Hi Johan,
> This patch set adds some simple self-tests for the SMP crypto functions.
> The tests are disabled by default and need to be enabled with a new
> config option in order to be compiled in.
>
> Johan
>
> ----------------------------------------------------------------
> Johan Hedberg (3):
> Bluetooth: Pass only crypto context to SMP crypto functions
> Bluetooth: Add skeleton for SMP self-tests
> Bluetooth: Add self-tests for SMP crypto functions
>
> net/bluetooth/Kconfig | 6 ++
> net/bluetooth/smp.c | 150 ++++++++++++++++++++++++++++++++++++++++------
> 2 files changed, 138 insertions(+), 18 deletions(-)
all 3 patches have been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply [flat|nested] 5+ messages in thread