Validate generated and received confirmation data is unique during provisioning. --- mesh/prov-acceptor.c | 13 +++++++++++-- mesh/prov-initiator.c | 8 ++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/mesh/prov-acceptor.c b/mesh/prov-acceptor.c index 4ec6ea34a..e806b12ef 100644 --- a/mesh/prov-acceptor.c +++ b/mesh/prov-acceptor.c @@ -347,14 +347,20 @@ static void send_pub_key(struct mesh_prov_acceptor *prov) prov->trans_tx(prov->trans_data, &msg, sizeof(msg)); } -static void send_conf(struct mesh_prov_acceptor *prov) +static bool send_conf(struct mesh_prov_acceptor *prov) { struct prov_conf_msg msg; msg.opcode = PROV_CONFIRM; mesh_crypto_aes_cmac(prov->calc_key, prov->rand_auth_workspace, 32, msg.conf); + + /* Fail if confirmations match */ + if (!memcmp(msg.conf, prov->confirm, sizeof(msg.conf))) + return false; + prov->trans_tx(prov->trans_data, &msg, sizeof(msg)); + return true; } static void send_rand(struct mesh_prov_acceptor *prov) @@ -529,7 +535,10 @@ static void acp_prov_rx(void *user_data, const uint8_t *data, uint16_t len) memcpy(prov->confirm, data, 16); prov->expected = PROV_RANDOM; - send_conf(prov); + if (!send_conf(prov)) { + fail.reason = PROV_ERR_INVALID_PDU; + goto failure; + } break; case PROV_RANDOM: /* Random Value */ diff --git a/mesh/prov-initiator.c b/mesh/prov-initiator.c index 4f492a49c..ae9c646de 100644 --- a/mesh/prov-initiator.c +++ b/mesh/prov-initiator.c @@ -279,6 +279,7 @@ static void send_confirm(struct mesh_prov_initiator *prov) msg.opcode = PROV_CONFIRM; mesh_crypto_aes_cmac(prov->calc_key, prov->rand_auth_workspace, 32, msg.conf); + memcpy(prov->confirm, msg.conf, sizeof(prov->confirm)); prov->trans_tx(prov->trans_data, &msg, sizeof(msg)); prov->state = INT_PROV_CONF_SENT; prov->expected = PROV_CONFIRM; @@ -732,6 +733,13 @@ static void int_prov_rx(void *user_data, const uint8_t *data, uint16_t len) case PROV_CONFIRM: /* Confirmation */ prov->state = INT_PROV_CONF_ACKED; /* RXed Device Confirmation */ + + /* Disallow echoed values */ + if (!memcmp(prov->confirm, data, 16)) { + fail_code[1] = PROV_ERR_INVALID_PDU; + goto failure; + } + memcpy(prov->confirm, data, 16); print_packet("ConfirmationDevice", prov->confirm, 16); send_random(prov); -- 2.25.4