Skip to content

Commit

Permalink
Bluetooth: Add selftest for ECDH key generation
Browse files Browse the repository at this point in the history
Since the ECDH key generation takes a different path, it needs to be
tested as well. For this generate the public debug key from the private
debug key and compare both.

This also moves the seeding of the private key into the SMP calling code
to allow for easier re-use of the ECDH key generation helper.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
  • Loading branch information
Marcel Holtmann authored and Johan Hedberg committed Apr 30, 2017
1 parent f958315 commit 71653eb
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
3 changes: 0 additions & 3 deletions net/bluetooth/ecdh_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
*/
#include "ecdh_helper.h"

#include <linux/random.h>
#include <linux/scatterlist.h>
#include <crypto/kpp.h>
#include <crypto/ecdh.h>
Expand Down Expand Up @@ -181,8 +180,6 @@ bool generate_ecdh_keys(u8 public_key[64], u8 private_key[32])
if (tries++ >= max_tries)
goto free_all;

get_random_bytes(private_key, 32);

/* Set private Key */
p.key = (char *)private_key;
crypto_ecdh_encode_key(buf, buf_len, &p);
Expand Down
38 changes: 38 additions & 0 deletions net/bluetooth/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,9 @@ int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16])
smp->debug_key = true;
} else {
while (true) {
/* Seed private key with random number */
get_random_bytes(smp->local_sk, 32);

/* Generate local key pair for Secure Connections */
if (!generate_ecdh_keys(smp->local_pk, smp->local_sk))
return -EIO;
Expand Down Expand Up @@ -1895,6 +1898,9 @@ static u8 sc_send_public_key(struct smp_chan *smp)
set_bit(SMP_FLAG_DEBUG_KEY, &smp->flags);
} else {
while (true) {
/* Seed private key with random number */
get_random_bytes(smp->local_sk, 32);

/* Generate local key pair for Secure Connections */
if (!generate_ecdh_keys(smp->local_pk, smp->local_sk))
return SMP_UNSPECIFIED;
Expand Down Expand Up @@ -3483,6 +3489,32 @@ void smp_unregister(struct hci_dev *hdev)

#if IS_ENABLED(CONFIG_BT_SELFTEST_SMP)

static inline void swap_digits(u64 *in, u64 *out, unsigned int ndigits)
{
int i;

for (i = 0; i < ndigits; i++)
out[i] = __swab64(in[ndigits - 1 - i]);
}

static int __init test_debug_key(void)
{
u8 pk[64], sk[32];

swap_digits((u64 *)debug_sk, (u64 *)sk, 4);

if (!generate_ecdh_keys(pk, sk))
return -EINVAL;

if (memcmp(sk, debug_sk, 32))
return -EINVAL;

if (memcmp(pk, debug_pk, 64))
return -EINVAL;

return 0;
}

static int __init test_ah(struct crypto_cipher *tfm_aes)
{
const u8 irk[16] = {
Expand Down Expand Up @@ -3738,6 +3770,12 @@ static int __init run_selftests(struct crypto_cipher *tfm_aes,

calltime = ktime_get();

err = test_debug_key();
if (err) {
BT_ERR("debug_key test failed");
goto done;
}

err = test_ah(tfm_aes);
if (err) {
BT_ERR("smp_ah test failed");
Expand Down

0 comments on commit 71653eb

Please sign in to comment.