Linux-Bluetooth Archive on lore.kernel.org
 help / color / Atom feed
From: Brian Gix <brian.gix@intel.com>
To: linux-bluetooth@vger.kernel.org
Cc: inga.stotland@intel.com, michal.lowas-rzechonek@silvair.com,
	brian.gix@intel.com
Subject: [PATCH BlueZ v2 8/9] mesh: Convert provisioning pkts to packed structs
Date: Thu, 11 Jul 2019 15:59:51 -0700
Message-ID: <20190711225952.1599-9-brian.gix@intel.com> (raw)
In-Reply-To: <20190711225952.1599-1-brian.gix@intel.com>

Provisioning packets are defined in the specification
as packed big endian structures. Instead of specifying
an octet array, we now use struct matching the spec.
---
 mesh/crypto.c         |   8 +--
 mesh/crypto.h         |   8 +--
 mesh/mesh.c           |   2 +-
 mesh/mesh.h           |   3 +-
 mesh/pb-adv.c         |  79 +++++++++++++++++--------
 mesh/prov-acceptor.c  | 156 +++++++++++++++++++++++++++-----------------------
 mesh/prov-initiator.c |  94 +++++++++++++++---------------
 mesh/prov.h           |  51 ++++++++++++++++-
 8 files changed, 247 insertions(+), 154 deletions(-)

diff --git a/mesh/crypto.c b/mesh/crypto.c
index 3fa0df246..a4679d88e 100644
--- a/mesh/crypto.c
+++ b/mesh/crypto.c
@@ -102,8 +102,8 @@ bool mesh_crypto_aes_cmac(const uint8_t key[16], const uint8_t *msg,
 
 bool mesh_crypto_aes_ccm_encrypt(const uint8_t nonce[13], const uint8_t key[16],
 					const uint8_t *aad, uint16_t aad_len,
-					const uint8_t *msg, uint16_t msg_len,
-					uint8_t *out_msg,
+					const void *msg, uint16_t msg_len,
+					void *out_msg,
 					void *out_mic, size_t mic_size)
 {
 	void *cipher;
@@ -128,8 +128,8 @@ bool mesh_crypto_aes_ccm_encrypt(const uint8_t nonce[13], const uint8_t key[16],
 
 bool mesh_crypto_aes_ccm_decrypt(const uint8_t nonce[13], const uint8_t key[16],
 				const uint8_t *aad, uint16_t aad_len,
-				const uint8_t *enc_msg, uint16_t enc_msg_len,
-				uint8_t *out_msg,
+				const void *enc_msg, uint16_t enc_msg_len,
+				void *out_msg,
 				void *out_mic, size_t mic_size)
 {
 	void *cipher;
diff --git a/mesh/crypto.h b/mesh/crypto.h
index ffd312231..3e6815a35 100644
--- a/mesh/crypto.h
+++ b/mesh/crypto.h
@@ -22,13 +22,13 @@
 
 bool mesh_crypto_aes_ccm_encrypt(const uint8_t nonce[13], const uint8_t key[16],
 					const uint8_t *aad, uint16_t aad_len,
-					const uint8_t *msg, uint16_t msg_len,
-					uint8_t *out_msg,
+					const void *msg, uint16_t msg_len,
+					void *out_msg,
 					void *out_mic, size_t mic_size);
 bool mesh_crypto_aes_ccm_decrypt(const uint8_t nonce[13], const uint8_t key[16],
 				const uint8_t *aad, uint16_t aad_len,
-				const uint8_t *enc_msg, uint16_t enc_msg_len,
-				uint8_t *out_msg,
+				const void *enc_msg, uint16_t enc_msg_len,
+				void *out_msg,
 				void *out_mic, size_t mic_size);
 bool mesh_aes_ecb_one(const uint8_t key[16],
 			const uint8_t plaintext[16], uint8_t encrypted[16]);
diff --git a/mesh/mesh.c b/mesh/mesh.c
index 62c80c0f3..b9e3162eb 100644
--- a/mesh/mesh.c
+++ b/mesh/mesh.c
@@ -86,7 +86,7 @@ static bool simple_match(const void *a, const void *b)
 /* Used for any outbound traffic that doesn't have Friendship Constraints */
 /* This includes Beacons, Provisioning and unrestricted Network Traffic */
 bool mesh_send_pkt(uint8_t count, uint16_t interval,
-					uint8_t *data, uint16_t len)
+					void *data, uint16_t len)
 {
 	struct mesh_io_send_info info = {
 		.type = MESH_IO_TIMING_TYPE_GENERAL,
diff --git a/mesh/mesh.h b/mesh/mesh.h
index 2ef77b57d..78d4d4926 100644
--- a/mesh/mesh.h
+++ b/mesh/mesh.h
@@ -37,8 +37,7 @@ void mesh_cleanup(void);
 bool mesh_dbus_init(struct l_dbus *dbus);
 
 const char *mesh_status_str(uint8_t err);
-bool mesh_send_pkt(uint8_t count, uint16_t interval, uint8_t *data,
-								uint16_t len);
+bool mesh_send_pkt(uint8_t count, uint16_t interval, void *data, uint16_t len);
 bool mesh_send_cancel(const uint8_t *filter, uint8_t len);
 bool mesh_reg_prov_rx(prov_rx_cb_t cb, void *user_data);
 void mesh_unreg_prov_rx(prov_rx_cb_t cb);
diff --git a/mesh/pb-adv.c b/mesh/pb-adv.c
index 4d85ee72e..6b4a70052 100644
--- a/mesh/pb-adv.c
+++ b/mesh/pb-adv.c
@@ -63,6 +63,36 @@ struct pb_adv_session {
 
 #define PB_ADV_MTU	24
 
+struct pb_ack {
+	uint8_t ad_type;
+	uint32_t link_id;
+	uint8_t trans_num;
+	uint8_t opcode;
+} __packed;
+
+struct pb_open_req{
+	uint8_t ad_type;
+	uint32_t link_id;
+	uint8_t trans_num;
+	uint8_t opcode;
+	uint8_t uuid[16];
+} __packed;
+
+struct pb_open_cfm{
+	uint8_t ad_type;
+	uint32_t link_id;
+	uint8_t trans_num;
+	uint8_t opcode;
+} __packed;
+
+struct pb_close_ind {
+	uint8_t ad_type;
+	uint32_t link_id;
+	uint8_t trans_num;
+	uint8_t opcode;
+	uint8_t reason;
+} __packed;
+
 static struct pb_adv_session *pb_session = NULL;
 
 static const uint8_t filter[1] = { MESH_AD_TYPE_PROVISION };
@@ -150,7 +180,7 @@ static void tx_timeout(struct l_timeout *timeout, void *user_data)
 	cb(user_data, 1);
 }
 
-static void pb_adv_tx(void *user_data, uint8_t *data, uint16_t len)
+static void pb_adv_tx(void *user_data, void *data, uint16_t len)
 {
 	struct pb_adv_session *session = user_data;
 
@@ -165,55 +195,56 @@ static void pb_adv_tx(void *user_data, uint8_t *data, uint16_t len)
 
 static void send_open_req(struct pb_adv_session *session)
 {
-	uint8_t open_req[23] = { MESH_AD_TYPE_PROVISION };
+	struct pb_open_req open_req = { MESH_AD_TYPE_PROVISION };
 
-	l_put_be32(session->link_id, open_req + 1);
-	open_req[1 + 4] = 0;
-	open_req[1 + 4 + 1] = PB_ADV_OPEN_REQ;
-	memcpy(open_req + 7, session->uuid, 16);
+	l_put_be32(session->link_id, &open_req.link_id);
+	open_req.trans_num = 0;
+	open_req.opcode = PB_ADV_OPEN_REQ;
+	memcpy(open_req.uuid, session->uuid, 16);
 
 	mesh_send_cancel(filter, sizeof(filter));
-	mesh_send_pkt(MESH_IO_TX_COUNT_UNLIMITED, 500, open_req,
-						sizeof(open_req));
+	mesh_send_pkt(MESH_IO_TX_COUNT_UNLIMITED, 500, &open_req,
+							sizeof(open_req));
 }
 
 static void send_open_cfm(struct pb_adv_session *session)
 {
-	uint8_t open_cfm[7] = { MESH_AD_TYPE_PROVISION };
+	struct pb_open_cfm open_cfm = { MESH_AD_TYPE_PROVISION };
 
-	l_put_be32(session->link_id, open_cfm + 1);
-	open_cfm[1 + 4] = 0;
-	open_cfm[1 + 4 + 1] = PB_ADV_OPEN_CFM; /* OPEN_CFM */
+	l_put_be32(session->link_id, &open_cfm.link_id);
+	open_cfm.trans_num = 0;
+	open_cfm.opcode = PB_ADV_OPEN_CFM;
 
 	mesh_send_cancel(filter, sizeof(filter));
-	mesh_send_pkt(5, 100, open_cfm, sizeof(open_cfm));
+	mesh_send_pkt(MESH_IO_TX_COUNT_UNLIMITED, 500, &open_cfm,
+							sizeof(open_cfm));
 }
 
 static void send_ack(struct pb_adv_session *session, uint8_t trans_num)
 {
-	uint8_t ack[7] = { MESH_AD_TYPE_PROVISION };
+	struct pb_ack ack = { MESH_AD_TYPE_PROVISION };
 
-	l_put_be32(session->link_id, ack + 1);
-	ack[1 + 4] = trans_num;
-	ack[1 + 4 + 1] = PB_ADV_ACK;
+	l_put_be32(session->link_id, &ack.link_id);
+	ack.trans_num = trans_num;
+	ack.opcode = PB_ADV_ACK;
 
-	mesh_send_pkt(1, 100, ack, sizeof(ack));
+	mesh_send_pkt(1, 100, &ack, sizeof(ack));
 }
 
 static void send_close_ind(struct pb_adv_session *session, uint8_t reason)
 {
-	uint8_t close_ind[8] = { MESH_AD_TYPE_PROVISION };
+	struct pb_close_ind close_ind = { MESH_AD_TYPE_PROVISION };
 
 	if (!pb_session || pb_session != session)
 		return;
 
-	l_put_be32(session->link_id, close_ind + 1);
-	close_ind[5] = 0;
-	close_ind[6] = PB_ADV_CLOSE;
-	close_ind[7] = reason;
+	l_put_be32(session->link_id, &close_ind.link_id);
+	close_ind.trans_num = 0;
+	close_ind.opcode = PB_ADV_CLOSE;
+	close_ind.reason = reason;
 
 	mesh_send_cancel(filter, sizeof(filter));
-	mesh_send_pkt(10, 100, close_ind, sizeof(close_ind));
+	mesh_send_pkt(10, 100, &close_ind, sizeof(close_ind));
 }
 
 static void pb_adv_packet(void *user_data, const uint8_t *pkt, uint16_t len)
diff --git a/mesh/prov-acceptor.c b/mesh/prov-acceptor.c
index 111340db3..57eb1e750 100644
--- a/mesh/prov-acceptor.c
+++ b/mesh/prov-acceptor.c
@@ -232,15 +232,15 @@ static uint32_t digit_mod(uint8_t power)
 static void number_cb(void *user_data, int err, uint32_t number)
 {
 	struct mesh_prov_acceptor *rx_prov = user_data;
-	uint8_t out[2];
+	struct prov_fail_msg msg;
 
 	if (prov != rx_prov)
 		return;
 
 	if (err) {
-		out[0] = PROV_FAILED;
-		out[1] = PROV_ERR_UNEXPECTED_ERR;
-		prov->trans_tx(prov->trans_data, out, 2);
+		msg.opcode = PROV_FAILED;
+		msg.reason = PROV_ERR_UNEXPECTED_ERR;
+		prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
 		return;
 	}
 
@@ -248,22 +248,22 @@ static void number_cb(void *user_data, int err, uint32_t number)
 	l_put_be32(number, prov->rand_auth_workspace + 28);
 	l_put_be32(number, prov->rand_auth_workspace + 44);
 	prov->material |= MAT_RAND_AUTH;
-	out[0] = PROV_INP_CMPLT;
-	prov->trans_tx(prov->trans_data, out, 1);
+	msg.opcode = PROV_INP_CMPLT;
+	prov->trans_tx(prov->trans_data, &msg.opcode, 1);
 }
 
 static void static_cb(void *user_data, int err, uint8_t *key, uint32_t len)
 {
 	struct mesh_prov_acceptor *rx_prov = user_data;
-	uint8_t out[2];
+	struct prov_fail_msg msg;
 
 	if (prov != rx_prov)
 		return;
 
 	if (err || !key || len != 16) {
-		out[0] = PROV_FAILED;
-		out[1] = PROV_ERR_UNEXPECTED_ERR;
-		prov->trans_tx(prov->trans_data, out, 2);
+		msg.opcode = PROV_FAILED;
+		msg.reason = PROV_ERR_UNEXPECTED_ERR;
+		prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
 		return;
 	}
 
@@ -276,15 +276,15 @@ static void static_cb(void *user_data, int err, uint8_t *key, uint32_t len)
 static void priv_key_cb(void *user_data, int err, uint8_t *key, uint32_t len)
 {
 	struct mesh_prov_acceptor *rx_prov = user_data;
-	uint8_t out[2];
+	struct prov_fail_msg msg;
 
 	if (prov != rx_prov)
 		return;
 
 	if (err || !key || len != 32) {
-		out[0] = PROV_FAILED;
-		out[1] = PROV_ERR_UNEXPECTED_ERR;
-		prov->trans_tx(prov->trans_data, out, 2);
+		msg.opcode = PROV_FAILED;
+		msg.reason = PROV_ERR_UNEXPECTED_ERR;
+		prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
 		return;
 	}
 
@@ -301,13 +301,53 @@ static void priv_key_cb(void *user_data, int err, uint8_t *key, uint32_t len)
 		acp_credentials(prov);
 }
 
+static void send_caps(struct mesh_prov_acceptor *prov)
+{
+	struct prov_caps_msg msg;
+
+	msg.opcode = PROV_CAPS;
+	memcpy(&msg.caps, &prov->conf_inputs.caps,
+			sizeof(prov->conf_inputs.caps));
+
+	prov->state = ACP_PROV_CAPS_SENT;
+	prov->expected = PROV_START;
+	prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
+}
+
+static void send_pub_key(struct mesh_prov_acceptor *prov)
+{
+	struct prov_pub_key_msg msg;
+
+	msg.opcode = PROV_PUB_KEY;
+	memcpy(msg.pub_key, prov->conf_inputs.dev_pub_key, sizeof(msg.pub_key));
+	prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
+}
+
+static void 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);
+	prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
+}
+
+static void send_rand(struct mesh_prov_acceptor *prov)
+{
+	struct prov_rand_msg msg;
+
+	msg.opcode = PROV_RANDOM;
+	memcpy(msg.rand, prov->rand_auth_workspace, sizeof(msg.rand));
+	prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
+}
+
 static void acp_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
 {
 	struct mesh_prov_acceptor *rx_prov = user_data;
 	struct mesh_prov_node_info *info;
-	uint8_t *out;
+	struct prov_fail_msg fail;
 	uint8_t type = *data++;
-	uint8_t fail_code[2];
 	uint32_t oob_key;
 	uint64_t decode_mic;
 	bool result;
@@ -323,7 +363,7 @@ static void acp_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
 		return;
 	} else if (type > prov->expected || type < prov->previous) {
 		l_error("Expected %2.2x, Got:%2.2x", prov->expected, type);
-		fail_code[1] = PROV_ERR_UNEXPECTED_PDU;
+		fail.reason = PROV_ERR_UNEXPECTED_PDU;
 		goto failure;
 	}
 
@@ -331,25 +371,14 @@ static void acp_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
 					len != expected_pdu_size[type]) {
 		l_error("Expected PDU size %d, Got %d (type: %2.2x)",
 			len, expected_pdu_size[type], type);
-		fail_code[1] = PROV_ERR_INVALID_FORMAT;
+		fail.reason = PROV_ERR_INVALID_FORMAT;
 		goto failure;
 	}
 
 	switch (type){
 	case PROV_INVITE: /* Prov Invite */
-		/* Prov Capabilities */
-		out = l_malloc(1 + sizeof(struct mesh_net_prov_caps));
-		out[0] = PROV_CAPS;
-		memcpy(out + 1, &prov->conf_inputs.caps,
-					sizeof(prov->conf_inputs.caps));
-
 		prov->conf_inputs.invite.attention = data[0];
-
-		prov->state = ACP_PROV_CAPS_SENT;
-		prov->expected = PROV_START;
-		prov->trans_tx(prov->trans_data,
-				out, sizeof(prov->conf_inputs.caps) + 1);
-		l_free(out);
+		send_caps(prov);
 		break;
 
 	case PROV_START: /* Prov Start */
@@ -359,7 +388,7 @@ static void acp_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
 		if (prov->conf_inputs.start.algorithm ||
 				prov->conf_inputs.start.pub_key > 1 ||
 				prov->conf_inputs.start.auth_method > 3) {
-			fail_code[1] = PROV_ERR_INVALID_FORMAT;
+			fail.reason = PROV_ERR_INVALID_FORMAT;
 			goto failure;
 		}
 
@@ -369,7 +398,7 @@ static void acp_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
 				mesh_agent_request_private_key(prov->agent,
 							priv_key_cb, prov);
 			} else {
-				fail_code[1] = PROV_ERR_INVALID_PDU;
+				fail.reason = PROV_ERR_INVALID_PDU;
 				goto failure;
 			}
 		} else {
@@ -395,13 +424,8 @@ static void acp_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
 
 		acp_credentials(prov);
 
-		if (!prov->conf_inputs.start.pub_key) {
-			out = l_malloc(65);
-			out[0] = PROV_PUB_KEY;
-			memcpy(out + 1, prov->conf_inputs.dev_pub_key, 64);
-			prov->trans_tx(prov->trans_data, out, 65);
-			l_free(out);
-		}
+		if (!prov->conf_inputs.start.pub_key)
+			send_pub_key(prov);
 
 		/* Start Step 3 */
 		switch (prov->conf_inputs.start.auth_method) {
@@ -413,10 +437,10 @@ static void acp_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
 		case 1:
 			/* Auth Type 3c - Static OOB */
 			/* Prompt Agent for Static OOB */
-			fail_code[1] = mesh_agent_request_static(prov->agent,
+			fail.reason = mesh_agent_request_static(prov->agent,
 					static_cb, prov);
 
-			if (fail_code[1])
+			if (fail.reason)
 				goto failure;
 
 			break;
@@ -434,17 +458,17 @@ static void acp_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
 			if (prov->conf_inputs.start.auth_action ==
 							PROV_ACTION_OUT_ALPHA) {
 				/* TODO: Construst NUL-term string to pass */
-				fail_code[1] = mesh_agent_display_string(
+				fail.reason = mesh_agent_display_string(
 					prov->agent, NULL, NULL, prov);
 			} else {
 				/* Ask Agent to Display U32 */
-				fail_code[1] = mesh_agent_display_number(
+				fail.reason = mesh_agent_display_number(
 					prov->agent, false,
 					prov->conf_inputs.start.auth_action,
 					oob_key, NULL, prov);
 			}
 
-			if (fail_code[1])
+			if (fail.reason)
 				goto failure;
 
 			break;
@@ -454,17 +478,17 @@ static void acp_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
 			/* Prompt Agent for Input OOB */
 			if (prov->conf_inputs.start.auth_action ==
 							PROV_ACTION_IN_ALPHA) {
-				fail_code[1] = mesh_agent_prompt_alpha(
+				fail.reason = mesh_agent_prompt_alpha(
 					prov->agent,
 					static_cb, prov);
 			} else {
-				fail_code[1] = mesh_agent_prompt_number(
+				fail.reason = mesh_agent_prompt_number(
 					prov->agent, false,
 					prov->conf_inputs.start.auth_action,
 					number_cb, prov);
 			}
 
-			if (fail_code[1])
+			if (fail.reason)
 				goto failure;
 
 			break;
@@ -474,22 +498,14 @@ static void acp_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
 		break;
 
 	case PROV_CONFIRM: /* Confirmation */
-		out = l_malloc(17);
-		out[0] = PROV_CONFIRM;
-
-		/* Calculate and Send our Confirmation */
-		mesh_crypto_aes_cmac(prov->calc_key, prov->rand_auth_workspace,
-								32, out + 1);
-		prov->trans_tx(prov->trans_data, out, 17);
-		l_free(out);
-
 		/* Save Provisioners confirmation for later compare */
 		memcpy(prov->confirm, data, 16);
 		prov->expected = PROV_RANDOM;
+
+		send_conf(prov);
 		break;
 
 	case PROV_RANDOM: /* Random Value */
-		out = l_malloc(17);
 		/* Calculate Session key (needed later) while data is fresh */
 		mesh_crypto_prov_prov_salt(prov->salt, data,
 						prov->rand_auth_workspace,
@@ -500,20 +516,17 @@ static void acp_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
 		/* Calculate expected Provisioner Confirm */
 		memcpy(prov->rand_auth_workspace + 16, data, 16);
 		mesh_crypto_aes_cmac(prov->calc_key,
-				prov->rand_auth_workspace + 16, 32, out);
+					prov->rand_auth_workspace + 16, 32,
+					prov->calc_key);
 
 		/* Compare our calculation with Provisioners */
-		if (memcmp(out, prov->confirm, 16)) {
-			fail_code[1] = PROV_ERR_CONFIRM_FAILED;
-			l_free(out);
+		if (memcmp(prov->calc_key, prov->confirm, 16)) {
+			fail.reason = PROV_ERR_CONFIRM_FAILED;
 			goto failure;
 		}
 
 		/* Send Random value we used */
-		out[0] = PROV_RANDOM;
-		memcpy(out + 1, prov->rand_auth_workspace, 16);
-		prov->trans_tx(prov->trans_data, out, 17);
-		l_free(out);
+		send_rand(prov);
 		prov->expected = PROV_DATA;
 		break;
 
@@ -533,7 +546,7 @@ static void acp_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
 		/* Validate that the data hasn't been messed with in transit */
 		if (l_get_be64(data + 25) != decode_mic) {
 			l_error("Provisioning Failed-MIC compare");
-			fail_code[1] = PROV_ERR_DECRYPT_FAILED;
+			fail.reason = PROV_ERR_DECRYPT_FAILED;
 			goto failure;
 		}
 
@@ -556,7 +569,7 @@ static void acp_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
 					prov->rand_auth_workspace, 1);
 			goto cleanup;
 		} else {
-			fail_code[1] = PROV_ERR_UNEXPECTED_ERR;
+			fail.reason = PROV_ERR_UNEXPECTED_ERR;
 			goto failure;
 		}
 		break;
@@ -570,14 +583,15 @@ static void acp_prov_rx(void *user_data, const uint8_t *data, uint16_t len)
 		goto cleanup;
 	}
 
-	prov->previous = type;
+	if (prov)
+		prov->previous = type;
 	return;
 
 failure:
-	fail_code[0] = PROV_FAILED;
-	prov->trans_tx(prov->trans_data, fail_code, 2);
+	fail.opcode = PROV_FAILED;
+	prov->trans_tx(prov->trans_data, &fail, sizeof(fail));
 	if (prov->cmplt)
-		prov->cmplt(prov->caller_data, fail_code[1], NULL);
+		prov->cmplt(prov->caller_data, fail.reason, NULL);
 	prov->cmplt = NULL;
 
 cleanup:
diff --git a/mesh/prov-initiator.c b/mesh/prov-initiator.c
index 208225f08..eb59f53f1 100644
--- a/mesh/prov-initiator.c
+++ b/mesh/prov-initiator.c
@@ -155,7 +155,7 @@ static void int_prov_open(void *user_data, prov_trans_tx_t trans_tx,
 				void *trans_data, uint8_t transport)
 {
 	struct mesh_prov_initiator *rx_prov = user_data;
-	uint8_t invite[] = { PROV_INVITE, 30 };
+	struct prov_invite_msg msg = { PROV_INVITE, { 30 }};
 
 	/* Only one provisioning session may be open at a time */
 	if (rx_prov != prov)
@@ -181,8 +181,8 @@ static void int_prov_open(void *user_data, prov_trans_tx_t trans_tx,
 	prov->state = INT_PROV_INVITE_SENT;
 	prov->expected = PROV_CAPS;
 
-	prov->conf_inputs.invite.attention = invite[1];
-	prov->trans_tx(prov->trans_data, invite, sizeof(invite));
+	prov->conf_inputs.invite.attention = msg.invite.attention;
+	prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
 	return;
 }
 
@@ -268,15 +268,15 @@ static void calc_local_material(const uint8_t *random)
 static void number_cb(void *user_data, int err, uint32_t number)
 {
 	struct mesh_prov_initiator *rx_prov = user_data;
-	uint8_t out[2];
+	struct prov_fail_msg msg;
 
 	if (prov != rx_prov)
 		return;
 
 	if (err) {
-		out[0] = PROV_FAILED;
-		out[1] = PROV_ERR_UNEXPECTED_ERR;
-		prov->trans_tx(prov->trans_data, out, 2);
+		msg.opcode = PROV_FAILED;
+		msg.reason = PROV_ERR_UNEXPECTED_ERR;
+		prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
 		return;
 	}
 
@@ -289,15 +289,15 @@ static void number_cb(void *user_data, int err, uint32_t number)
 static void static_cb(void *user_data, int err, uint8_t *key, uint32_t len)
 {
 	struct mesh_prov_initiator *rx_prov = user_data;
-	uint8_t out[2];
+	struct prov_fail_msg msg;
 
 	if (prov != rx_prov)
 		return;
 
 	if (err || !key || len != 16) {
-		out[0] = PROV_FAILED;
-		out[1] = PROV_ERR_UNEXPECTED_ERR;
-		prov->trans_tx(prov->trans_data, out, 2);
+		msg.opcode = PROV_FAILED;
+		msg.reason = PROV_ERR_UNEXPECTED_ERR;
+		prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
 		return;
 	}
 
@@ -309,15 +309,15 @@ static void static_cb(void *user_data, int err, uint8_t *key, uint32_t len)
 static void pub_key_cb(void *user_data, int err, uint8_t *key, uint32_t len)
 {
 	struct mesh_prov_initiator *rx_prov = user_data;
-	uint8_t out[2];
+	struct prov_fail_msg msg;
 
 	if (prov != rx_prov)
 		return;
 
 	if (err || !key || len != 64) {
-		out[0] = PROV_FAILED;
-		out[1] = PROV_ERR_UNEXPECTED_ERR;
-		prov->trans_tx(prov->trans_data, out, 2);
+		msg.opcode = PROV_FAILED;
+		msg.reason = PROV_ERR_UNEXPECTED_ERR;
+		prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
 		return;
 	}
 
@@ -330,45 +330,45 @@ static void pub_key_cb(void *user_data, int err, uint8_t *key, uint32_t len)
 
 static void send_pub_key(struct mesh_prov_initiator *prov)
 {
-	uint8_t out[65];
+	struct prov_pub_key_msg msg;
 
-	out[0] = PROV_PUB_KEY;
-	memcpy(out + 1, prov->conf_inputs.prv_pub_key, 64);
-	prov->trans_tx(prov->trans_data, out, 65);
+	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 send_confirm(struct mesh_prov_initiator *prov)
 {
-	uint8_t out[17];
+	struct prov_conf_msg msg;
 
-	out[0] = PROV_CONFIRM;
+	msg.opcode = PROV_CONFIRM;
 	mesh_crypto_aes_cmac(prov->calc_key, prov->rand_auth_workspace,
-			32, out + 1);
-	prov->trans_tx(prov->trans_data, out, 17);
+			32, msg.conf);
+	prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
 	prov->state = INT_PROV_CONF_SENT;
 	prov->expected = PROV_CONFIRM;
 }
 
 static void send_random(struct mesh_prov_initiator *prov)
 {
-	uint8_t out[17];
+	struct prov_rand_msg msg;
 
-	out[0] = PROV_RANDOM;
-	memcpy(out + 1, prov->rand_auth_workspace, 16);
-	prov->trans_tx(prov->trans_data, out, 17);
+	msg.opcode = PROV_RANDOM;
+	memcpy(msg.rand, prov->rand_auth_workspace, sizeof(msg.rand));
+	prov->trans_tx(prov->trans_data, &msg, sizeof(msg));
 	prov->state = INT_PROV_RAND_SENT;
 	prov->expected = PROV_RANDOM;
 }
 
 void initiator_prov_data(uint16_t net_idx, uint16_t primary, void *caller_data)
 {
+	struct prov_data_msg prov_data;
+	struct prov_fail_msg prov_fail;
 	struct keyring_net_key key;
 	struct mesh_net *net;
-	uint64_t mic;
 	uint32_t iv_index;
 	uint8_t snb_flags;
-	uint8_t out[34];
 
 	if (!prov || caller_data != prov->caller_data)
 		return;
@@ -388,7 +388,7 @@ void initiator_prov_data(uint16_t net_idx, uint16_t primary, void *caller_data)
 
 	/* Fill Prov Data Structure */
 	if (!keyring_get_net_key(prov->node, net_idx, &key)) {
-		out[1] = PROV_ERR_UNEXPECTED_ERR;
+		prov_fail.reason = PROV_ERR_UNEXPECTED_ERR;
 		goto failure;
 	}
 
@@ -396,36 +396,36 @@ void initiator_prov_data(uint16_t net_idx, uint16_t primary, void *caller_data)
 	prov->net_idx = net_idx;
 	mesh_net_get_snb_state(net, &snb_flags, &iv_index);
 
-	out[0] = PROV_DATA;
+	prov_data.opcode = PROV_DATA;
 
 	if (key.phase == KEY_REFRESH_PHASE_TWO) {
-		memcpy(out + 1, key.new_key, 16);
+		memcpy(&prov_data.data.net_key, key.new_key, 16);
 		snb_flags |= PROV_FLAG_KR;
 	} else
-		memcpy(out + 1, key.old_key, 16);
+		memcpy(&prov_data.data.net_key, key.old_key, 16);
 
-	l_put_be16(net_idx, out + 1 + 16);
-	l_put_u8(snb_flags, out + 1 + 16 + 2);
-	l_put_be32(iv_index, out + 1 + 16 + 2 + 1);
-	l_put_be16(primary, out + 1 + 16 + 2 + 1 + 4);
+	l_put_be16(net_idx, &prov_data.data.net_idx);
+	l_put_u8(snb_flags, &prov_data.data.flags);
+	l_put_be32(iv_index, &prov_data.data.iv_index);
+	l_put_be16(primary, &prov_data.data.primary);
 
-	print_packet("ProvData", out + 1, 25);
+	print_packet("ProvData", &prov_data.data, sizeof(prov_data.data));
 	/* Encrypt Prov Data */
 	mesh_crypto_aes_ccm_encrypt(prov->s_nonce, prov->s_key,
 			NULL, 0,
-			out + 1,
-			25,
-			out + 1,
-			&mic, sizeof(mic));
-	print_packet("EncData", out + 1, 25 + 8);
-	prov->trans_tx(prov->trans_data, out, 34);
+			&prov_data.data,
+			sizeof(prov_data.data),
+			&prov_data.data,
+			NULL, sizeof(prov_data.mic));
+	print_packet("EncdData", &prov_data.data, sizeof(prov_data) - 1);
+	prov->trans_tx(prov->trans_data, &prov_data, sizeof(prov_data));
 	prov->state = INT_PROV_DATA_SENT;
 	return;
 
 failure:
-	l_debug("Failing... %d", out[1]);
-	out[0] = PROV_FAILED;
-	prov->trans_tx(prov->trans_data, out, 2);
+	l_debug("Failing... %d", prov_fail.reason);
+	prov_fail.opcode = PROV_FAILED;
+	prov->trans_tx(prov->trans_data, &prov_fail, sizeof(prov_fail));
 	/* TODO: Call Complete Callback (Fail)*/
 }
 
diff --git a/mesh/prov.h b/mesh/prov.h
index 61ec08e10..11b20b31f 100644
--- a/mesh/prov.h
+++ b/mesh/prov.h
@@ -48,7 +48,7 @@ enum mesh_prov_mode {
 
 struct mesh_prov;
 
-typedef void (*prov_trans_tx_t)(void *trans_data, uint8_t *data, uint16_t len);
+typedef void (*prov_trans_tx_t)(void *trans_data, void *data, uint16_t len);
 typedef void (*mesh_prov_open_func_t)(void *user_data, prov_trans_tx_t trans_tx,
 					void *trans_data, uint8_t trans_type);
 
@@ -63,6 +63,11 @@ struct prov_invite {
 	uint8_t attention;
 } __packed;
 
+struct prov_invite_msg {
+	uint8_t opcode;
+	struct prov_invite invite;
+} __packed;
+
 struct prov_start {
 	uint8_t algorithm;
 	uint8_t pub_key;
@@ -71,6 +76,50 @@ struct prov_start {
 	uint8_t auth_size;
 } __packed;
 
+struct prov_caps_msg {
+	uint8_t opcode;
+	struct mesh_net_prov_caps caps;
+} __packed;
+
+struct prov_start_msg {
+	uint8_t opcode;
+	struct prov_start start;
+} __packed;
+
+struct prov_pub_key_msg {
+	uint8_t opcode;
+	uint8_t pub_key[64];
+} __packed;
+
+struct prov_conf_msg {
+	uint8_t opcode;
+	uint8_t conf[16];
+} __packed;
+
+struct prov_rand_msg {
+	uint8_t opcode;
+	uint8_t rand[16];
+} __packed;
+
+struct prov_data {
+	uint8_t net_key[16];
+	uint16_t net_idx;
+	uint8_t flags;
+	uint32_t iv_index;
+	uint16_t primary;
+} __packed;
+
+struct prov_data_msg {
+	uint8_t opcode;
+	struct prov_data data;
+	uint64_t mic;
+} __packed;
+
+struct prov_fail_msg {
+	uint8_t opcode;
+	uint8_t reason;
+} __packed;
+
 struct conf_input {
 	struct prov_invite		invite;
 	struct mesh_net_prov_caps	caps;
-- 
2.14.5


  parent reply index

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-11 22:59 [PATCH BlueZ v2 0/9] mesh: Provisioner Initiator added Brian Gix
2019-07-11 22:59 ` [PATCH BlueZ v2 1/9] doc: Cleanup API Provisioner1 interface Brian Gix
2019-07-11 22:59 ` [PATCH BlueZ v2 2/9] mesh: Fix support for Provisioner Initiator Brian Gix
2019-07-11 22:59 ` [PATCH BlueZ v2 3/9] mesh: Add special Beacon handler for Provisioning Brian Gix
2019-07-11 22:59 ` [PATCH BlueZ v2 4/9] mesh: Expose mapping function for D-Bus errors Brian Gix
2019-07-11 22:59 ` [PATCH BlueZ v2 5/9] mesh: Expose resources needed by Management1 interface Brian Gix
2019-07-11 22:59 ` [PATCH BlueZ v2 6/9] mesh: Fix implementation of Provisioner Initiator Brian Gix
2019-07-11 22:59 ` [PATCH BlueZ v2 7/9] mesh: Implement DBus Provisioning methods Brian Gix
2019-07-11 22:59 ` Brian Gix [this message]
2019-07-11 22:59 ` [PATCH BlueZ v2 9/9] test: This extends the mesh tool to exercise " Brian Gix
2019-07-12  8:39 ` [PATCH BlueZ v2 0/9] mesh: Provisioner Initiator added Michał Lowas-Rzechonek
2019-07-14 15:47 ` Gix, Brian

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190711225952.1599-9-brian.gix@intel.com \
    --to=brian.gix@intel.com \
    --cc=inga.stotland@intel.com \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=michal.lowas-rzechonek@silvair.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-Bluetooth Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-bluetooth/0 linux-bluetooth/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-bluetooth linux-bluetooth/ https://lore.kernel.org/linux-bluetooth \
		linux-bluetooth@vger.kernel.org
	public-inbox-index linux-bluetooth

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-bluetooth


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git