Bluetooth: Mesh: Provisioning PDU length defines

Adds length defines for all provisioning PDUs and uses them to split
prov_link.conf_inputs into separate fields.

Signed-off-by: Trond Einar Snekvik <Trond.Einar.Snekvik@nordicsemi.no>
This commit is contained in:
Trond Einar Snekvik 2021-06-16 15:12:57 +02:00 committed by Carles Cufí
commit abcbfed6c3
4 changed files with 80 additions and 55 deletions

View file

@ -34,6 +34,10 @@
struct bt_mesh_prov_link bt_mesh_prov_link; struct bt_mesh_prov_link bt_mesh_prov_link;
const struct bt_mesh_prov *bt_mesh_prov; const struct bt_mesh_prov *bt_mesh_prov;
/* Verify specification defined length: */
BUILD_ASSERT(sizeof(bt_mesh_prov_link.conf_inputs) == 145,
"Confirmation inputs shall be 145 bytes");
static void pub_key_ready(const uint8_t *pkey) static void pub_key_ready(const uint8_t *pkey)
{ {
if (!pkey) { if (!pkey) {
@ -53,7 +57,7 @@ int bt_mesh_prov_reset_state(void (*func)(const uint8_t key[64]))
pub_key_cb.func = func ? func : pub_key_ready; pub_key_cb.func = func ? func : pub_key_ready;
/* Disable Attention Timer if it was set */ /* Disable Attention Timer if it was set */
if (bt_mesh_prov_link.conf_inputs[0]) { if (bt_mesh_prov_link.conf_inputs.invite[0]) {
bt_mesh_attention(NULL, 0); bt_mesh_attention(NULL, 0);
} }
@ -260,16 +264,16 @@ static void prov_recv(const struct prov_bearer *bearer, void *cb_data,
struct net_buf_simple *buf) struct net_buf_simple *buf)
{ {
static const uint8_t op_len[10] = { static const uint8_t op_len[10] = {
[PROV_INVITE] = 1, [PROV_INVITE] = PDU_LEN_INVITE,
[PROV_CAPABILITIES] = 11, [PROV_CAPABILITIES] = PDU_LEN_CAPABILITIES,
[PROV_START] = 5, [PROV_START] = PDU_LEN_START,
[PROV_PUB_KEY] = 64, [PROV_PUB_KEY] = PDU_LEN_PUB_KEY,
[PROV_INPUT_COMPLETE] = 0, [PROV_INPUT_COMPLETE] = PDU_LEN_INPUT_COMPLETE,
[PROV_CONFIRM] = 16, [PROV_CONFIRM] = PDU_LEN_CONFIRM,
[PROV_RANDOM] = 16, [PROV_RANDOM] = PDU_LEN_RANDOM,
[PROV_DATA] = 33, [PROV_DATA] = PDU_LEN_DATA,
[PROV_COMPLETE] = 0, [PROV_COMPLETE] = PDU_LEN_COMPLETE,
[PROV_FAILED] = 1, [PROV_FAILED] = PDU_LEN_FAILED,
}; };
uint8_t type = buf->data[0]; uint8_t type = buf->data[0];

View file

@ -52,10 +52,23 @@
#define PROV_NO_PDU 0xff #define PROV_NO_PDU 0xff
#define PDU_LEN_INVITE 1
#define PDU_LEN_CAPABILITIES 11
#define PDU_LEN_START 5
#define PDU_LEN_PUB_KEY 64
#define PDU_LEN_INPUT_COMPLETE 0
#define PDU_LEN_CONFIRM 16
#define PDU_LEN_RANDOM 16
#define PDU_LEN_DATA 33
#define PDU_LEN_COMPLETE 0
#define PDU_LEN_FAILED 1
#define PDU_OP_LEN 1
#define PROV_ALG_P256 0x00 #define PROV_ALG_P256 0x00
#define PROV_BUF(name, len) \ #define PROV_BUF(name, len) \
NET_BUF_SIMPLE_DEFINE(name, PROV_BEARER_BUF_HEADROOM + len) NET_BUF_SIMPLE_DEFINE(name, PROV_BEARER_BUF_HEADROOM + PDU_OP_LEN + len)
enum { enum {
WAIT_PUB_KEY, /* Waiting for local PubKey to be generated */ WAIT_PUB_KEY, /* Waiting for local PubKey to be generated */
@ -108,7 +121,14 @@ struct bt_mesh_prov_link {
uint8_t conf_salt[16]; /* ConfirmationSalt */ uint8_t conf_salt[16]; /* ConfirmationSalt */
uint8_t conf_key[16]; /* ConfirmationKey */ uint8_t conf_key[16]; /* ConfirmationKey */
uint8_t conf_inputs[145]; /* ConfirmationInputs */ /* ConfirmationInput fields: */
struct {
uint8_t invite[PDU_LEN_INVITE];
uint8_t capabilities[PDU_LEN_CAPABILITIES];
uint8_t start[PDU_LEN_START];
uint8_t pub_key_provisioner[PDU_LEN_PUB_KEY]; /* big-endian */
uint8_t pub_key_device[PDU_LEN_PUB_KEY]; /* big-endian */
} conf_inputs;
uint8_t prov_salt[16]; /* Provisioning Salt */ uint8_t prov_salt[16]; /* Provisioning Salt */
}; };

View file

@ -50,7 +50,7 @@ static int reset_state(void)
static void prov_send_fail_msg(uint8_t err) static void prov_send_fail_msg(uint8_t err)
{ {
PROV_BUF(buf, 2); PROV_BUF(buf, PDU_LEN_FAILED);
BT_DBG("%u", err); BT_DBG("%u", err);
@ -76,7 +76,7 @@ static void prov_fail(uint8_t reason)
static void prov_invite(const uint8_t *data) static void prov_invite(const uint8_t *data)
{ {
PROV_BUF(buf, 12); PROV_BUF(buf, PDU_LEN_CAPABILITIES);
BT_DBG("Attention Duration: %u seconds", data[0]); BT_DBG("Attention Duration: %u seconds", data[0]);
@ -84,7 +84,7 @@ static void prov_invite(const uint8_t *data)
bt_mesh_attention(NULL, data[0]); bt_mesh_attention(NULL, data[0]);
} }
bt_mesh_prov_link.conf_inputs[0] = data[0]; memcpy(bt_mesh_prov_link.conf_inputs.invite, data, PDU_LEN_INVITE);
bt_mesh_prov_buf_init(&buf, PROV_CAPABILITIES); bt_mesh_prov_buf_init(&buf, PROV_CAPABILITIES);
@ -113,7 +113,7 @@ static void prov_invite(const uint8_t *data)
/* Input OOB Action */ /* Input OOB Action */
net_buf_simple_add_be16(&buf, bt_mesh_prov->input_actions); net_buf_simple_add_be16(&buf, bt_mesh_prov->input_actions);
memcpy(&bt_mesh_prov_link.conf_inputs[1], &buf.data[1], 11); memcpy(bt_mesh_prov_link.conf_inputs.capabilities, &buf.data[1], PDU_LEN_CAPABILITIES);
if (bt_mesh_prov_send(&buf, NULL)) { if (bt_mesh_prov_send(&buf, NULL)) {
BT_ERR("Failed to send capabilities"); BT_ERR("Failed to send capabilities");
@ -147,7 +147,7 @@ static void prov_start(const uint8_t *data)
atomic_set_bit_to(bt_mesh_prov_link.flags, OOB_PUB_KEY, data[1] == PUB_KEY_OOB); atomic_set_bit_to(bt_mesh_prov_link.flags, OOB_PUB_KEY, data[1] == PUB_KEY_OOB);
memcpy(&bt_mesh_prov_link.conf_inputs[12], data, 5); memcpy(bt_mesh_prov_link.conf_inputs.start, data, PDU_LEN_START);
bt_mesh_prov_link.expect = PROV_PUB_KEY; bt_mesh_prov_link.expect = PROV_PUB_KEY;
@ -168,14 +168,14 @@ static void prov_start(const uint8_t *data)
static void send_confirm(void) static void send_confirm(void)
{ {
PROV_BUF(cfm, 17); PROV_BUF(cfm, PDU_LEN_CONFIRM);
uint8_t *inputs = (uint8_t *)&bt_mesh_prov_link.conf_inputs;
BT_DBG("ConfInputs[0] %s", bt_hex(bt_mesh_prov_link.conf_inputs, 64)); BT_DBG("ConfInputs[0] %s", bt_hex(inputs, 64));
BT_DBG("ConfInputs[64] %s", bt_hex(&bt_mesh_prov_link.conf_inputs[64], 64)); BT_DBG("ConfInputs[64] %s", bt_hex(&inputs[64], 64));
BT_DBG("ConfInputs[128] %s", bt_hex(&bt_mesh_prov_link.conf_inputs[128], 17)); BT_DBG("ConfInputs[128] %s", bt_hex(&inputs[128], 17));
if (bt_mesh_prov_conf_salt(bt_mesh_prov_link.conf_inputs, if (bt_mesh_prov_conf_salt(inputs, bt_mesh_prov_link.conf_salt)) {
bt_mesh_prov_link.conf_salt)) {
BT_ERR("Unable to generate confirmation salt"); BT_ERR("Unable to generate confirmation salt");
prov_fail(PROV_ERR_UNEXP_ERR); prov_fail(PROV_ERR_UNEXP_ERR);
return; return;
@ -220,7 +220,7 @@ static void send_confirm(void)
static void send_input_complete(void) static void send_input_complete(void)
{ {
PROV_BUF(buf, 1); PROV_BUF(buf, PDU_LEN_INPUT_COMPLETE);
bt_mesh_prov_buf_init(&buf, PROV_INPUT_COMPLETE); bt_mesh_prov_buf_init(&buf, PROV_INPUT_COMPLETE);
if (bt_mesh_prov_send(&buf, NULL)) { if (bt_mesh_prov_send(&buf, NULL)) {
@ -251,7 +251,7 @@ static void start_auth(void)
static void send_pub_key(void) static void send_pub_key(void)
{ {
PROV_BUF(buf, 65); PROV_BUF(buf, PDU_LEN_PUB_KEY);
const uint8_t *key; const uint8_t *key;
key = bt_pub_key_get(); key = bt_pub_key_get();
@ -269,8 +269,8 @@ static void send_pub_key(void)
sys_memcpy_swap(net_buf_simple_add(&buf, 32), key, 32); sys_memcpy_swap(net_buf_simple_add(&buf, 32), key, 32);
sys_memcpy_swap(net_buf_simple_add(&buf, 32), &key[32], 32); sys_memcpy_swap(net_buf_simple_add(&buf, 32), &key[32], 32);
/* PublicKeyRemote */ /* PublicKeyDevice */
memcpy(&bt_mesh_prov_link.conf_inputs[81], &buf.data[1], 64); memcpy(bt_mesh_prov_link.conf_inputs.pub_key_device, &buf.data[1], PDU_LEN_PUB_KEY);
if (bt_mesh_prov_send(&buf, public_key_sent)) { if (bt_mesh_prov_send(&buf, public_key_sent)) {
BT_ERR("Failed to send Public Key"); BT_ERR("Failed to send Public Key");
@ -312,7 +312,7 @@ static void prov_dh_key_gen(void)
const uint8_t *remote_pk; const uint8_t *remote_pk;
uint8_t remote_pk_le[64]; uint8_t remote_pk_le[64];
remote_pk = &bt_mesh_prov_link.conf_inputs[17]; remote_pk = bt_mesh_prov_link.conf_inputs.pub_key_provisioner;
if (IS_ENABLED(CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY) && if (IS_ENABLED(CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY) &&
atomic_test_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY)) { atomic_test_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY)) {
@ -349,7 +349,7 @@ static void prov_pub_key(const uint8_t *data)
BT_DBG("Remote Public Key: %s", bt_hex(data, 64)); BT_DBG("Remote Public Key: %s", bt_hex(data, 64));
/* PublicKeyProvisioner */ /* PublicKeyProvisioner */
memcpy(&bt_mesh_prov_link.conf_inputs[17], data, 64); memcpy(bt_mesh_prov_link.conf_inputs.pub_key_provisioner, data, PDU_LEN_PUB_KEY);
if (IS_ENABLED(CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY) && if (IS_ENABLED(CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY) &&
atomic_test_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY)) { atomic_test_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY)) {
@ -360,7 +360,8 @@ static void prov_pub_key(const uint8_t *data)
} }
/* No swap needed since user provides public key in big-endian */ /* No swap needed since user provides public key in big-endian */
memcpy(&bt_mesh_prov_link.conf_inputs[81], bt_mesh_prov->public_key_be, 64); memcpy(bt_mesh_prov_link.conf_inputs.pub_key_device, bt_mesh_prov->public_key_be,
PDU_LEN_PUB_KEY);
atomic_set_bit(bt_mesh_prov_link.flags, WAIT_DH_KEY); atomic_set_bit(bt_mesh_prov_link.flags, WAIT_DH_KEY);
@ -401,7 +402,7 @@ static void notify_input_complete(void)
static void send_random(void) static void send_random(void)
{ {
PROV_BUF(rnd, 17); PROV_BUF(rnd, PDU_LEN_RANDOM);
bt_mesh_prov_buf_init(&rnd, PROV_RANDOM); bt_mesh_prov_buf_init(&rnd, PROV_RANDOM);
net_buf_simple_add_mem(&rnd, bt_mesh_prov_link.rand, 16); net_buf_simple_add_mem(&rnd, bt_mesh_prov_link.rand, 16);
@ -473,7 +474,7 @@ static inline bool is_pb_gatt(void)
static void prov_data(const uint8_t *data) static void prov_data(const uint8_t *data)
{ {
PROV_BUF(msg, 1); PROV_BUF(msg, PDU_LEN_COMPLETE);
uint8_t session_key[16]; uint8_t session_key[16];
uint8_t nonce[13]; uint8_t nonce[13];
uint8_t dev_key[16]; uint8_t dev_key[16];

View file

@ -77,14 +77,15 @@ static void prov_fail(uint8_t reason)
static void send_invite(void) static void send_invite(void)
{ {
PROV_BUF(inv, 2); PROV_BUF(inv, PDU_LEN_INVITE);
BT_DBG(""); BT_DBG("");
bt_mesh_prov_buf_init(&inv, PROV_INVITE); bt_mesh_prov_buf_init(&inv, PROV_INVITE);
net_buf_simple_add_u8(&inv, prov_device.attention_duration); net_buf_simple_add_u8(&inv, prov_device.attention_duration);
bt_mesh_prov_link.conf_inputs[0] = prov_device.attention_duration; memcpy(bt_mesh_prov_link.conf_inputs.invite, &prov_device.attention_duration,
PDU_LEN_INVITE);
if (bt_mesh_prov_send(&inv, NULL)) { if (bt_mesh_prov_send(&inv, NULL)) {
BT_ERR("Failed to send invite"); BT_ERR("Failed to send invite");
@ -109,15 +110,14 @@ static void send_start(void)
BT_DBG(""); BT_DBG("");
uint8_t method, action; uint8_t method, action;
PROV_BUF(start, 6); PROV_BUF(start, PDU_LEN_START);
const uint8_t *data = &bt_mesh_prov_link.conf_inputs[1 + 3]; bool oob_pub_key = bt_mesh_prov_link.conf_inputs.capabilities[3] == PUB_KEY_OOB;
bt_mesh_prov_buf_init(&start, PROV_START); bt_mesh_prov_buf_init(&start, PROV_START);
net_buf_simple_add_u8(&start, PROV_ALG_P256); net_buf_simple_add_u8(&start, PROV_ALG_P256);
if (atomic_test_bit(bt_mesh_prov_link.flags, REMOTE_PUB_KEY) && if (atomic_test_bit(bt_mesh_prov_link.flags, REMOTE_PUB_KEY) && oob_pub_key) {
*data == PUB_KEY_OOB) {
net_buf_simple_add_u8(&start, PUB_KEY_OOB); net_buf_simple_add_u8(&start, PUB_KEY_OOB);
atomic_set_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY); atomic_set_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY);
} else { } else {
@ -150,7 +150,7 @@ static void send_start(void)
net_buf_simple_add_u8(&start, bt_mesh_prov_link.oob_size); net_buf_simple_add_u8(&start, bt_mesh_prov_link.oob_size);
memcpy(&bt_mesh_prov_link.conf_inputs[12], &start.data[1], 5); memcpy(bt_mesh_prov_link.conf_inputs.invite, &start.data[1], PDU_LEN_INVITE);
if (bt_mesh_prov_auth(method, action, bt_mesh_prov_link.oob_size) < 0) { if (bt_mesh_prov_auth(method, action, bt_mesh_prov_link.oob_size) < 0) {
BT_ERR("Invalid authentication method: 0x%02x; " BT_ERR("Invalid authentication method: 0x%02x; "
@ -264,7 +264,7 @@ static void prov_capabilities(const uint8_t *data)
return; return;
} }
memcpy(&bt_mesh_prov_link.conf_inputs[1], data, 11); memcpy(bt_mesh_prov_link.conf_inputs.capabilities, data, PDU_LEN_CAPABILITIES);
if (bt_mesh_prov->capabilities) { if (bt_mesh_prov->capabilities) {
bt_mesh_prov->capabilities(&caps); bt_mesh_prov->capabilities(&caps);
@ -280,14 +280,14 @@ static void prov_capabilities(const uint8_t *data)
static void send_confirm(void) static void send_confirm(void)
{ {
PROV_BUF(cfm, 17); PROV_BUF(cfm, PDU_LEN_CONFIRM);
uint8_t *inputs = (uint8_t *)&bt_mesh_prov_link.conf_inputs;
BT_DBG("ConfInputs[0] %s", bt_hex(bt_mesh_prov_link.conf_inputs, 64)); BT_DBG("ConfInputs[0] %s", bt_hex(inputs, 64));
BT_DBG("ConfInputs[64] %s", bt_hex(&bt_mesh_prov_link.conf_inputs[64], 64)); BT_DBG("ConfInputs[64] %s", bt_hex(&inputs[64], 64));
BT_DBG("ConfInputs[128] %s", bt_hex(&bt_mesh_prov_link.conf_inputs[128], 17)); BT_DBG("ConfInputs[128] %s", bt_hex(&inputs[128], 17));
if (bt_mesh_prov_conf_salt(bt_mesh_prov_link.conf_inputs, if (bt_mesh_prov_conf_salt(inputs, bt_mesh_prov_link.conf_salt)) {
bt_mesh_prov_link.conf_salt)) {
BT_ERR("Unable to generate confirmation salt"); BT_ERR("Unable to generate confirmation salt");
prov_fail(PROV_ERR_UNEXP_ERR); prov_fail(PROV_ERR_UNEXP_ERR);
return; return;
@ -343,7 +343,7 @@ static void public_key_sent(int err, void *cb_data)
static void send_pub_key(void) static void send_pub_key(void)
{ {
PROV_BUF(buf, 65); PROV_BUF(buf, PDU_LEN_PUB_KEY);
const uint8_t *key; const uint8_t *key;
key = bt_pub_key_get(); key = bt_pub_key_get();
@ -362,7 +362,7 @@ static void send_pub_key(void)
sys_memcpy_swap(net_buf_simple_add(&buf, 32), &key[32], 32); sys_memcpy_swap(net_buf_simple_add(&buf, 32), &key[32], 32);
/* PublicKeyProvisioner */ /* PublicKeyProvisioner */
memcpy(&bt_mesh_prov_link.conf_inputs[17], &buf.data[1], 64); memcpy(bt_mesh_prov_link.conf_inputs.pub_key_provisioner, &buf.data[1], PDU_LEN_PUB_KEY);
if (bt_mesh_prov_send(&buf, public_key_sent)) { if (bt_mesh_prov_send(&buf, public_key_sent)) {
BT_ERR("Failed to send Public Key"); BT_ERR("Failed to send Public Key");
@ -402,8 +402,8 @@ static void prov_dh_key_gen(void)
const uint8_t *remote_pk; const uint8_t *remote_pk;
const uint8_t *local_pk; const uint8_t *local_pk;
local_pk = &bt_mesh_prov_link.conf_inputs[17]; local_pk = bt_mesh_prov_link.conf_inputs.pub_key_provisioner;
remote_pk = &bt_mesh_prov_link.conf_inputs[81]; remote_pk = bt_mesh_prov_link.conf_inputs.pub_key_device;
/* Copy remote key in little-endian for bt_dh_key_gen(). /* Copy remote key in little-endian for bt_dh_key_gen().
* X and Y halves are swapped independently. The bt_dh_key_gen() * X and Y halves are swapped independently. The bt_dh_key_gen()
@ -435,7 +435,7 @@ static void prov_pub_key(const uint8_t *data)
atomic_set_bit(bt_mesh_prov_link.flags, REMOTE_PUB_KEY); atomic_set_bit(bt_mesh_prov_link.flags, REMOTE_PUB_KEY);
/* PublicKeyDevice */ /* PublicKeyDevice */
memcpy(&bt_mesh_prov_link.conf_inputs[81], data, 64); memcpy(bt_mesh_prov_link.conf_inputs.pub_key_device, data, 64);
bt_mesh_prov_link.bearer->clear_tx(); bt_mesh_prov_link.bearer->clear_tx();
prov_dh_key_gen(); prov_dh_key_gen();
@ -477,7 +477,7 @@ static void prov_input_complete(const uint8_t *data)
static void send_prov_data(void) static void send_prov_data(void)
{ {
PROV_BUF(pdu, 34); PROV_BUF(pdu, PDU_LEN_DATA);
struct bt_mesh_cdb_subnet *sub; struct bt_mesh_cdb_subnet *sub;
uint8_t session_key[16]; uint8_t session_key[16];
uint8_t nonce[13]; uint8_t nonce[13];
@ -572,7 +572,7 @@ static void prov_complete(const uint8_t *data)
static void send_random(void) static void send_random(void)
{ {
PROV_BUF(rnd, 17); PROV_BUF(rnd, PDU_LEN_RANDOM);
bt_mesh_prov_buf_init(&rnd, PROV_RANDOM); bt_mesh_prov_buf_init(&rnd, PROV_RANDOM);
net_buf_simple_add_mem(&rnd, bt_mesh_prov_link.rand, 16); net_buf_simple_add_mem(&rnd, bt_mesh_prov_link.rand, 16);
@ -730,7 +730,7 @@ int bt_mesh_prov_remote_pub_key_set(const uint8_t public_key[64])
return -EALREADY; return -EALREADY;
} }
memcpy(&bt_mesh_prov_link.conf_inputs[81], public_key, 64); memcpy(bt_mesh_prov_link.conf_inputs.pub_key_device, public_key, PDU_LEN_PUB_KEY);
return 0; return 0;
} }