mesh: Add Provisioning Confirmation validity check
authorBrian Gix <brian.gix@intel.com>
Thu, 8 Apr 2021 19:01:34 +0000 (12:01 -0700)
committerAyush Garg <ayush.garg@samsung.com>
Fri, 11 Mar 2022 13:38:35 +0000 (19:08 +0530)
Validate generated and received confirmation data is unique during
provisioning.

Signed-off-by: Anuj Jain <anuj01.jain@samsung.com>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
mesh/prov-acceptor.c
mesh/prov-initiator.c

index 4ec6ea3..e806b12 100644 (file)
@@ -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 */
index 4f492a4..ae9c646 100644 (file)
@@ -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);