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í
parent eb0eb67481
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;
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)
{
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;
/* 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);
}
@ -260,16 +264,16 @@ static void prov_recv(const struct prov_bearer *bearer, void *cb_data,
struct net_buf_simple *buf)
{
static const uint8_t op_len[10] = {
[PROV_INVITE] = 1,
[PROV_CAPABILITIES] = 11,
[PROV_START] = 5,
[PROV_PUB_KEY] = 64,
[PROV_INPUT_COMPLETE] = 0,
[PROV_CONFIRM] = 16,
[PROV_RANDOM] = 16,
[PROV_DATA] = 33,
[PROV_COMPLETE] = 0,
[PROV_FAILED] = 1,
[PROV_INVITE] = PDU_LEN_INVITE,
[PROV_CAPABILITIES] = PDU_LEN_CAPABILITIES,
[PROV_START] = PDU_LEN_START,
[PROV_PUB_KEY] = PDU_LEN_PUB_KEY,
[PROV_INPUT_COMPLETE] = PDU_LEN_INPUT_COMPLETE,
[PROV_CONFIRM] = PDU_LEN_CONFIRM,
[PROV_RANDOM] = PDU_LEN_RANDOM,
[PROV_DATA] = PDU_LEN_DATA,
[PROV_COMPLETE] = PDU_LEN_COMPLETE,
[PROV_FAILED] = PDU_LEN_FAILED,
};
uint8_t type = buf->data[0];

View file

@ -52,10 +52,23 @@
#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_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 {
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_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 */
};

View file

@ -50,7 +50,7 @@ static int reset_state(void)
static void prov_send_fail_msg(uint8_t err)
{
PROV_BUF(buf, 2);
PROV_BUF(buf, PDU_LEN_FAILED);
BT_DBG("%u", err);
@ -76,7 +76,7 @@ static void prov_fail(uint8_t reason)
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]);
@ -84,7 +84,7 @@ static void prov_invite(const uint8_t *data)
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);
@ -113,7 +113,7 @@ static void prov_invite(const uint8_t *data)
/* Input OOB Action */
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)) {
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);
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;
@ -168,14 +168,14 @@ static void prov_start(const uint8_t *data)
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[64] %s", bt_hex(&bt_mesh_prov_link.conf_inputs[64], 64));
BT_DBG("ConfInputs[128] %s", bt_hex(&bt_mesh_prov_link.conf_inputs[128], 17));
BT_DBG("ConfInputs[0] %s", bt_hex(inputs, 64));
BT_DBG("ConfInputs[64] %s", bt_hex(&inputs[64], 64));
BT_DBG("ConfInputs[128] %s", bt_hex(&inputs[128], 17));
if (bt_mesh_prov_conf_salt(bt_mesh_prov_link.conf_inputs,
bt_mesh_prov_link.conf_salt)) {
if (bt_mesh_prov_conf_salt(inputs, bt_mesh_prov_link.conf_salt)) {
BT_ERR("Unable to generate confirmation salt");
prov_fail(PROV_ERR_UNEXP_ERR);
return;
@ -220,7 +220,7 @@ static void send_confirm(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);
if (bt_mesh_prov_send(&buf, NULL)) {
@ -251,7 +251,7 @@ static void start_auth(void)
static void send_pub_key(void)
{
PROV_BUF(buf, 65);
PROV_BUF(buf, PDU_LEN_PUB_KEY);
const uint8_t *key;
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], 32);
/* PublicKeyRemote */
memcpy(&bt_mesh_prov_link.conf_inputs[81], &buf.data[1], 64);
/* PublicKeyDevice */
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)) {
BT_ERR("Failed to send Public Key");
@ -312,7 +312,7 @@ static void prov_dh_key_gen(void)
const uint8_t *remote_pk;
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) &&
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));
/* 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) &&
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 */
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);
@ -401,7 +402,7 @@ static void notify_input_complete(void)
static void send_random(void)
{
PROV_BUF(rnd, 17);
PROV_BUF(rnd, PDU_LEN_RANDOM);
bt_mesh_prov_buf_init(&rnd, PROV_RANDOM);
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)
{
PROV_BUF(msg, 1);
PROV_BUF(msg, PDU_LEN_COMPLETE);
uint8_t session_key[16];
uint8_t nonce[13];
uint8_t dev_key[16];

View file

@ -77,14 +77,15 @@ static void prov_fail(uint8_t reason)
static void send_invite(void)
{
PROV_BUF(inv, 2);
PROV_BUF(inv, PDU_LEN_INVITE);
BT_DBG("");
bt_mesh_prov_buf_init(&inv, PROV_INVITE);
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)) {
BT_ERR("Failed to send invite");
@ -109,15 +110,14 @@ static void send_start(void)
BT_DBG("");
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);
net_buf_simple_add_u8(&start, PROV_ALG_P256);
if (atomic_test_bit(bt_mesh_prov_link.flags, REMOTE_PUB_KEY) &&
*data == PUB_KEY_OOB) {
if (atomic_test_bit(bt_mesh_prov_link.flags, REMOTE_PUB_KEY) && oob_pub_key) {
net_buf_simple_add_u8(&start, PUB_KEY_OOB);
atomic_set_bit(bt_mesh_prov_link.flags, OOB_PUB_KEY);
} else {
@ -150,7 +150,7 @@ static void send_start(void)
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) {
BT_ERR("Invalid authentication method: 0x%02x; "
@ -264,7 +264,7 @@ static void prov_capabilities(const uint8_t *data)
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) {
bt_mesh_prov->capabilities(&caps);
@ -280,14 +280,14 @@ static void prov_capabilities(const uint8_t *data)
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[64] %s", bt_hex(&bt_mesh_prov_link.conf_inputs[64], 64));
BT_DBG("ConfInputs[128] %s", bt_hex(&bt_mesh_prov_link.conf_inputs[128], 17));
BT_DBG("ConfInputs[0] %s", bt_hex(inputs, 64));
BT_DBG("ConfInputs[64] %s", bt_hex(&inputs[64], 64));
BT_DBG("ConfInputs[128] %s", bt_hex(&inputs[128], 17));
if (bt_mesh_prov_conf_salt(bt_mesh_prov_link.conf_inputs,
bt_mesh_prov_link.conf_salt)) {
if (bt_mesh_prov_conf_salt(inputs, bt_mesh_prov_link.conf_salt)) {
BT_ERR("Unable to generate confirmation salt");
prov_fail(PROV_ERR_UNEXP_ERR);
return;
@ -343,7 +343,7 @@ static void public_key_sent(int err, void *cb_data)
static void send_pub_key(void)
{
PROV_BUF(buf, 65);
PROV_BUF(buf, PDU_LEN_PUB_KEY);
const uint8_t *key;
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);
/* 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)) {
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 *local_pk;
local_pk = &bt_mesh_prov_link.conf_inputs[17];
remote_pk = &bt_mesh_prov_link.conf_inputs[81];
local_pk = bt_mesh_prov_link.conf_inputs.pub_key_provisioner;
remote_pk = bt_mesh_prov_link.conf_inputs.pub_key_device;
/* Copy remote key in little-endian for 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);
/* 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();
prov_dh_key_gen();
@ -477,7 +477,7 @@ static void prov_input_complete(const uint8_t *data)
static void send_prov_data(void)
{
PROV_BUF(pdu, 34);
PROV_BUF(pdu, PDU_LEN_DATA);
struct bt_mesh_cdb_subnet *sub;
uint8_t session_key[16];
uint8_t nonce[13];
@ -572,7 +572,7 @@ static void prov_complete(const uint8_t *data)
static void send_random(void)
{
PROV_BUF(rnd, 17);
PROV_BUF(rnd, PDU_LEN_RANDOM);
bt_mesh_prov_buf_init(&rnd, PROV_RANDOM);
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;
}
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;
}