Applied with minor changes On Tue, 2020-01-21 at 14:44 +0530, Prathyusha Nelluri wrote: > From: Prathyusha N <prathyusha.n@xxxxxxxxxxx> > > In Public Key OOB case, when provisioner receives public key via > OOB, provisioner has to send it's public key to remote node and > and then proceed for authentication. > > Handle invalid keys case. > --- > mesh/prov-initiator.c | 231 +++++++++++++++++++++++++----------------- > 1 file changed, 136 insertions(+), 95 deletions(-) > > diff --git a/mesh/prov-initiator.c b/mesh/prov-initiator.c > index 7efd5b349..21f686264 100644 > --- a/mesh/prov-initiator.c > +++ b/mesh/prov-initiator.c > @@ -186,7 +186,7 @@ static void int_prov_open(void *user_data, prov_trans_tx_t trans_tx, > return; > } > > -static void prov_calc_secret(const uint8_t *pub, const uint8_t *priv, > +static bool prov_calc_secret(const uint8_t *pub, const uint8_t *priv, > uint8_t *secret) > { > uint8_t tmp[64]; > @@ -196,22 +196,27 @@ static void prov_calc_secret(const uint8_t *pub, const uint8_t *priv, > swap_u256_bytes(tmp); > swap_u256_bytes(tmp + 32); > > - ecdh_shared_secret(tmp, priv, secret); > + if (!ecdh_shared_secret(tmp, priv, secret)) > + return false; > > /* Convert to Mesh byte order */ > swap_u256_bytes(secret); > + return true; > } > > -static void int_credentials(struct mesh_prov_initiator *prov) > +static bool int_credentials(struct mesh_prov_initiator *prov) > { > - prov_calc_secret(prov->conf_inputs.dev_pub_key, > - prov->private_key, prov->secret); > + if (!prov_calc_secret(prov->conf_inputs.dev_pub_key, > + prov->private_key, prov->secret)) > + goto failure; > > - mesh_crypto_s1(&prov->conf_inputs, > - sizeof(prov->conf_inputs), prov->salt); > + if (!mesh_crypto_s1(&prov->conf_inputs, > + sizeof(prov->conf_inputs), prov->salt)) > + goto failure; > > - mesh_crypto_prov_conf_key(prov->secret, prov->salt, > - prov->calc_key); > + if (!mesh_crypto_prov_conf_key(prov->secret, prov->salt, > + prov->calc_key)) > + goto failure; > > l_getrandom(prov->rand_auth_workspace, 16); > > @@ -224,6 +229,11 @@ static void int_credentials(struct mesh_prov_initiator *prov) > print_packet("LocalRandom", prov->rand_auth_workspace, 16); > print_packet("ConfirmationSalt", prov->salt, 16); > print_packet("ConfirmationKey", prov->calc_key, 16); > + > + return true; > + > +failure: > + return false; > } > > static uint8_t u16_high_bit(uint16_t mask) > @@ -320,10 +330,21 @@ static void static_cb(void *user_data, int err, uint8_t *key, uint32_t len) > send_confirm(prov); > } > > +static void send_pub_key(struct mesh_prov_initiator *prov) > +{ > + struct prov_pub_key_msg msg; > + > + msg.opcode = PROV_PUB_KEY; > + memcpy(msg.pub_key, prov->conf_inputs.prv_pub_key, 64); > + prov->trans_tx(prov->trans_data, &msg, sizeof(msg)); > + prov->state = INT_PROV_KEY_SENT; > +} > + > static void pub_key_cb(void *user_data, int err, uint8_t *key, uint32_t len) > { > struct mesh_prov_initiator *rx_prov = user_data; > struct prov_fail_msg msg; > + uint8_t fail_code[2]; > > if (prov != rx_prov) > return; > @@ -338,20 +359,17 @@ static void pub_key_cb(void *user_data, int err, uint8_t *key, uint32_t len) > memcpy(prov->conf_inputs.dev_pub_key, key, 64); > prov->material |= MAT_REMOTE_PUBLIC; > > - if ((prov->material & MAT_SECRET) == MAT_SECRET) > - int_credentials(prov); > - > - send_confirm(prov); > -} > - > -static void send_pub_key(struct mesh_prov_initiator *prov) > -{ > - struct prov_pub_key_msg msg; > + if ((prov->material & MAT_SECRET) == MAT_SECRET) { > + if (!int_credentials(prov)) { > + fail_code[0] = PROV_FAILED; > + fail_code[1] = PROV_ERR_UNEXPECTED_ERR; > + prov->trans_tx(prov->trans_data, fail_code, 2); > + int_prov_close(prov, fail_code[1]); > + return; > + } > + } > > - msg.opcode = PROV_PUB_KEY; > - memcpy(msg.pub_key, prov->conf_inputs.prv_pub_key, 64); > - prov->trans_tx(prov->trans_data, &msg, sizeof(msg)); > - prov->state = INT_PROV_KEY_SENT; > + send_pub_key(prov); > } > > static void send_random(struct mesh_prov_initiator *prov) > @@ -482,13 +500,99 @@ static void get_random_key(struct mesh_prov_initiator *prov, uint8_t action, > l_put_be32(oob_key, prov->rand_auth_workspace + 44); > } > > +static void int_prov_auth(void) > +{ > + uint8_t fail_code[2]; > + uint32_t oob_key; > + > + prov->state = INT_PROV_KEY_ACKED; > + > + l_debug("auth_method: %d", prov->conf_inputs.start.auth_method); > + memset(prov->rand_auth_workspace + 16, 0, 32); > + > + switch (prov->conf_inputs.start.auth_method) { > + default: > + case 0: > + /* Auth Type 3c - No OOB */ > + prov->material |= MAT_RAND_AUTH; > + break; > + case 1: > + /* Auth Type 3c - Static OOB */ > + /* Prompt Agent for Static OOB */ > + fail_code[1] = mesh_agent_request_static(prov->agent, > + static_cb, prov); > + > + if (fail_code[1]) > + goto failure; > + > + break; > + case 2: > + /* Auth Type 3a - Output OOB */ > + /* Prompt Agent for Output OOB */ > + if (prov->conf_inputs.start.auth_action == > + PROV_ACTION_OUT_ALPHA) { > + fail_code[1] = mesh_agent_prompt_alpha( > + prov->agent, true, > + static_cb, prov); > + } else { > + fail_code[1] = mesh_agent_prompt_number( > + prov->agent, true, > + prov->conf_inputs.start.auth_action, > + number_cb, prov); > + } > + > + if (fail_code[1]) > + goto failure; > + > + break; > + > + case 3: > + /* Auth Type 3b - input OOB */ > + get_random_key(prov, > + prov->conf_inputs.start.auth_action, > + prov->conf_inputs.start.auth_size); > + oob_key = l_get_be32(prov->rand_auth_workspace + 28); > + > + /* Ask Agent to Display random key */ > + if (prov->conf_inputs.start.auth_action == > + PROV_ACTION_IN_ALPHA) { > + > + fail_code[1] = mesh_agent_display_string( > + prov->agent, > + (char *) prov->rand_auth_workspace + 16, > + NULL, prov); > + } else { > + fail_code[1] = mesh_agent_display_number( > + prov->agent, true, > + prov->conf_inputs.start.auth_action, > + oob_key, NULL, prov); > + } > + > + if (fail_code[1]) > + goto failure; > + > + break; > + > + } > + > + if (prov->material & MAT_RAND_AUTH) > + send_confirm(prov); > + > + return; > + > +failure: > + l_debug("Failing... %d", fail_code[1]); > + fail_code[0] = PROV_FAILED; > + prov->trans_tx(prov->trans_data, fail_code, 2); > + int_prov_close(prov, fail_code[1]); > +} > + > static void int_prov_rx(void *user_data, const uint8_t *data, uint16_t len) > { > struct mesh_prov_initiator *rx_prov = user_data; > uint8_t *out; > uint8_t type = *data++; > uint8_t fail_code[2]; > - uint32_t oob_key; > > if (rx_prov != prov || !prov->trans_tx) > return; > @@ -596,79 +700,12 @@ static void int_prov_rx(void *user_data, const uint8_t *data, uint16_t len) > if ((prov->material & MAT_SECRET) != MAT_SECRET) > return; > > - int_credentials(prov); > - prov->state = INT_PROV_KEY_ACKED; > - > - l_debug("auth_method: %d", prov->conf_inputs.start.auth_method); > - memset(prov->rand_auth_workspace + 16, 0, 32); > - switch (prov->conf_inputs.start.auth_method) { > - default: > - case 0: > - /* Auth Type 3c - No OOB */ > - prov->material |= MAT_RAND_AUTH; > - break; > - case 1: > - /* Auth Type 3c - Static OOB */ > - /* Prompt Agent for Static OOB */ > - fail_code[1] = mesh_agent_request_static(prov->agent, > - static_cb, prov); > - > - if (fail_code[1]) > - goto failure; > - > - break; > - case 2: > - /* Auth Type 3a - Output OOB */ > - /* Prompt Agent for Output OOB */ > - if (prov->conf_inputs.start.auth_action == > - PROV_ACTION_OUT_ALPHA) { > - fail_code[1] = mesh_agent_prompt_alpha( > - prov->agent, true, > - static_cb, prov); > - } else { > - fail_code[1] = mesh_agent_prompt_number( > - prov->agent, true, > - prov->conf_inputs.start.auth_action, > - number_cb, prov); > - } > - > - if (fail_code[1]) > - goto failure; > - > - break; > - > - case 3: > - /* Auth Type 3b - input OOB */ > - get_random_key(prov, > - prov->conf_inputs.start.auth_action, > - prov->conf_inputs.start.auth_size); > - oob_key = l_get_be32(prov->rand_auth_workspace + 28); > - > - /* Ask Agent to Display random key */ > - if (prov->conf_inputs.start.auth_action == > - PROV_ACTION_IN_ALPHA) { > - > - fail_code[1] = mesh_agent_display_string( > - prov->agent, > - (char *) prov->rand_auth_workspace + 16, > - NULL, prov); > - } else { > - fail_code[1] = mesh_agent_display_number( > - prov->agent, true, > - prov->conf_inputs.start.auth_action, > - oob_key, NULL, prov); > - } > - > - if (fail_code[1]) > - goto failure; > - > - break; > - > + if (!int_credentials(prov)) { > + fail_code[1] = PROV_ERR_UNEXPECTED_ERR; > + goto failure; > } > > - if (prov->material & MAT_RAND_AUTH) > - send_confirm(prov); > - > + int_prov_auth(); > break; > > case PROV_INP_CMPLT: /* Provisioning Input Complete */ > @@ -760,11 +797,15 @@ static void int_prov_ack(void *user_data, uint8_t msg_num) > prov->state = INT_PROV_DATA_ACKED; > break; > > + case INT_PROV_KEY_SENT: > + if (prov->conf_inputs.caps.pub_type == 1) > + int_prov_auth(); > + break; > + > case INT_PROV_IDLE: > case INT_PROV_INVITE_SENT: > case INT_PROV_INVITE_ACKED: > case INT_PROV_START_ACKED: > - case INT_PROV_KEY_SENT: > case INT_PROV_KEY_ACKED: > case INT_PROV_CONF_SENT: > case INT_PROV_CONF_ACKED: