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 [thread overview]
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
next prev parent reply other threads:[~2019-07-11 23:00 UTC|newest]
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 publicly 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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.