Bluetooth: Mesh: Fix rejecting invalid remote public key
The code was already rejecting the key, however that rejection happened only after we had already sent our public key as response, which got interpreted as acceptance by the tester (PTS). This fixes issue that d4fd267086a56c270a793114e7575afae9a9befa supposed to fix. The problem is bt_dh_key_gen is async. Local public key cannot be sent from the same context the bt_dh_key_gen is called because we don't know yet if remote key is valid. Fixes MESH/NODE/PROV/BI-13-C. Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
This commit is contained in:
parent
ade6cc633c
commit
83b50f6bee
1 changed files with 35 additions and 49 deletions
|
@ -108,7 +108,6 @@
|
|||
enum {
|
||||
REMOTE_PUB_KEY, /* Remote key has been received */
|
||||
LINK_ACTIVE, /* Link has been opened */
|
||||
HAVE_DHKEY, /* DHKey has been calculated */
|
||||
SEND_CONFIRM, /* Waiting to send Confirm value */
|
||||
WAIT_NUMBER, /* Waiting for number input from user */
|
||||
WAIT_STRING, /* Waiting for string input from user */
|
||||
|
@ -838,10 +837,6 @@ int bt_mesh_input_number(u32_t num)
|
|||
|
||||
send_input_complete();
|
||||
|
||||
if (!atomic_test_bit(link.flags, HAVE_DHKEY)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) {
|
||||
send_confirm();
|
||||
}
|
||||
|
@ -861,10 +856,6 @@ int bt_mesh_input_string(const char *str)
|
|||
|
||||
send_input_complete();
|
||||
|
||||
if (!atomic_test_bit(link.flags, HAVE_DHKEY)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) {
|
||||
send_confirm();
|
||||
}
|
||||
|
@ -872,37 +863,23 @@ int bt_mesh_input_string(const char *str)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void prov_dh_key_cb(const u8_t key[32])
|
||||
static void send_pub_key(const u8_t dhkey[32])
|
||||
{
|
||||
BT_DBG("%p", key);
|
||||
PROV_BUF(buf, 65);
|
||||
const u8_t *key;
|
||||
|
||||
if (!key) {
|
||||
BT_DBG("%p", dhkey);
|
||||
|
||||
if (!dhkey) {
|
||||
BT_ERR("DHKey generation failed");
|
||||
prov_send_fail_msg(PROV_ERR_UNEXP_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
sys_memcpy_swap(link.dhkey, key, 32);
|
||||
sys_memcpy_swap(link.dhkey, dhkey, 32);
|
||||
|
||||
BT_DBG("DHkey: %s", bt_hex(link.dhkey, 32));
|
||||
|
||||
atomic_set_bit(link.flags, HAVE_DHKEY);
|
||||
|
||||
if (atomic_test_bit(link.flags, WAIT_NUMBER) ||
|
||||
atomic_test_bit(link.flags, WAIT_STRING)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) {
|
||||
send_confirm();
|
||||
}
|
||||
}
|
||||
|
||||
static void send_pub_key(void)
|
||||
{
|
||||
PROV_BUF(buf, 65);
|
||||
const u8_t *key;
|
||||
|
||||
key = bt_pub_key_get();
|
||||
if (!key) {
|
||||
BT_ERR("No public key available");
|
||||
|
@ -912,20 +889,6 @@ static void send_pub_key(void)
|
|||
|
||||
BT_DBG("Local Public Key: %s", bt_hex(key, 64));
|
||||
|
||||
/* Copy remote key in little-endian for bt_dh_key_gen().
|
||||
* X and Y halves are swapped independently. Use response
|
||||
* buffer as a temporary storage location. The bt_dh_key_gen()
|
||||
* will also take care of validating the remote public key.
|
||||
*/
|
||||
sys_memcpy_swap(buf.data, &link.conf_inputs[17], 32);
|
||||
sys_memcpy_swap(&buf.data[32], &link.conf_inputs[49], 32);
|
||||
|
||||
if (bt_dh_key_gen(buf.data, prov_dh_key_cb)) {
|
||||
BT_ERR("Failed to generate DHKey");
|
||||
prov_send_fail_msg(PROV_ERR_UNEXP_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
prov_buf_init(&buf, PROV_PUB_KEY);
|
||||
|
||||
/* Swap X and Y halves independently to big-endian */
|
||||
|
@ -939,9 +902,28 @@ static void send_pub_key(void)
|
|||
return;
|
||||
}
|
||||
|
||||
atomic_set_bit(link.flags, SEND_CONFIRM);
|
||||
link.expect = PROV_CONFIRM;
|
||||
}
|
||||
|
||||
static void prov_dh_key_gen(void)
|
||||
{
|
||||
u8_t remote_pk[64];
|
||||
|
||||
/* Copy remote key in little-endian for bt_dh_key_gen().
|
||||
* X and Y halves are swapped independently. Use response
|
||||
* buffer as a temporary storage location. The bt_dh_key_gen()
|
||||
* will also take care of validating the remote public key.
|
||||
*/
|
||||
sys_memcpy_swap(remote_pk, &link.conf_inputs[17], 32);
|
||||
sys_memcpy_swap(&remote_pk[32], &link.conf_inputs[49], 32);
|
||||
|
||||
if (bt_dh_key_gen(remote_pk, send_pub_key)) {
|
||||
BT_ERR("Failed to generate DHKey");
|
||||
prov_send_fail_msg(PROV_ERR_UNEXP_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
static void prov_pub_key(const u8_t *data)
|
||||
{
|
||||
BT_DBG("Remote Public Key: %s", bt_hex(data, 64));
|
||||
|
@ -958,7 +940,7 @@ static void prov_pub_key(const u8_t *data)
|
|||
return;
|
||||
}
|
||||
|
||||
send_pub_key();
|
||||
prov_dh_key_gen();
|
||||
}
|
||||
|
||||
static void pub_key_ready(const u8_t *pkey)
|
||||
|
@ -971,7 +953,7 @@ static void pub_key_ready(const u8_t *pkey)
|
|||
BT_DBG("Local public key ready");
|
||||
|
||||
if (atomic_test_and_clear_bit(link.flags, REMOTE_PUB_KEY)) {
|
||||
send_pub_key();
|
||||
prov_dh_key_gen();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -986,12 +968,16 @@ static void prov_confirm(const u8_t *data)
|
|||
|
||||
memcpy(link.conf, data, 16);
|
||||
|
||||
if (!atomic_test_bit(link.flags, HAVE_DHKEY)) {
|
||||
if (atomic_test_bit(link.flags, WAIT_NUMBER) ||
|
||||
atomic_test_bit(link.flags, WAIT_STRING)) {
|
||||
/* Clear retransmit timer */
|
||||
#if defined(CONFIG_BT_MESH_PB_ADV)
|
||||
prov_clear_tx();
|
||||
#endif
|
||||
atomic_set_bit(link.flags, SEND_CONFIRM);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) {
|
||||
send_confirm();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue