All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 1/1] mesh: Handle publickey exchange phase for initiator
       [not found] <CGME20200121091512epcas5p3fd399b595da13bbd57edcac6c97ad8be@epcas5p3.samsung.com>
@ 2020-01-21  9:14 ` Prathyusha Nelluri
  2020-01-23 16:13   ` Gix, Brian
  2020-01-25 16:27   ` Gix, Brian
  0 siblings, 2 replies; 3+ messages in thread
From: Prathyusha Nelluri @ 2020-01-21  9:14 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Prathyusha N

From: Prathyusha N <prathyusha.n@samsung.com>

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:
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v1 1/1] mesh: Handle publickey exchange phase for initiator
  2020-01-21  9:14 ` [PATCH v1 1/1] mesh: Handle publickey exchange phase for initiator Prathyusha Nelluri
@ 2020-01-23 16:13   ` Gix, Brian
  2020-01-25 16:27   ` Gix, Brian
  1 sibling, 0 replies; 3+ messages in thread
From: Gix, Brian @ 2020-01-23 16:13 UTC (permalink / raw)
  To: prathyusha.n, linux-bluetooth

Hi Prathyusha,

A few minor changes, please.

On Tue, 2020-01-21 at 14:44 +0530, Prathyusha Nelluri wrote:
> From: Prathyusha N <prathyusha.n@samsung.com>
> 
> 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;

return false;

>  
> -	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;

return false;

>  
> -	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;

return false;

>  
>  	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;

Please only use failure label goto's when there is some extra action or clean-up that needs to be done. 
Otherwise just return the fail value as needed, instead of goto.

>  }
>  
>  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]);

This failure label is fine, because clean actions are taken

> +}
> +
>  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:

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v1 1/1] mesh: Handle publickey exchange phase for initiator
  2020-01-21  9:14 ` [PATCH v1 1/1] mesh: Handle publickey exchange phase for initiator Prathyusha Nelluri
  2020-01-23 16:13   ` Gix, Brian
@ 2020-01-25 16:27   ` Gix, Brian
  1 sibling, 0 replies; 3+ messages in thread
From: Gix, Brian @ 2020-01-25 16:27 UTC (permalink / raw)
  To: prathyusha.n, linux-bluetooth

Applied with minor changes

On Tue, 2020-01-21 at 14:44 +0530, Prathyusha Nelluri wrote:
> From: Prathyusha N <prathyusha.n@samsung.com>
> 
> 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:

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-01-25 16:27 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20200121091512epcas5p3fd399b595da13bbd57edcac6c97ad8be@epcas5p3.samsung.com>
2020-01-21  9:14 ` [PATCH v1 1/1] mesh: Handle publickey exchange phase for initiator Prathyusha Nelluri
2020-01-23 16:13   ` Gix, Brian
2020-01-25 16:27   ` Gix, Brian

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.