Skip to content

Commit 2d63f5e

Browse files
Johan Hedbergjhedberg
authored andcommitted
Bluetooth: Mesh: Fix & clean up Friendship Credential handling
Pass the subnet to some friend_cred_* APIs since it contains all necessary information for choosing the right keys to generate them from. Also shorten the API names to avoid awkward line splitting - these are internal APIs so it's an acceptable compromise. One bug that this fixes as part of the cleanup is using the right NetKey Index when clearing Friendship: previously the code was always using the index of the first subnet, regardless of which subnet the Friendship was based on. Signed-off-by: Johan Hedberg <[email protected]>
1 parent e719906 commit 2d63f5e

File tree

5 files changed

+73
-86
lines changed

5 files changed

+73
-86
lines changed

subsys/bluetooth/host/mesh/cfg_srv.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1999,7 +1999,7 @@ static void net_key_update(struct bt_mesh_model *model,
19991999
err = bt_mesh_net_keys_create(&sub->keys[1], buf->data);
20002000
if (!err && (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) ||
20012001
IS_ENABLED(CONFIG_BT_MESH_FRIEND))) {
2002-
err = bt_mesh_friend_cred_update(ctx->net_idx, 1, buf->data);
2002+
err = friend_cred_update(sub);
20032003
}
20042004

20052005
if (err) {
@@ -2608,7 +2608,7 @@ static void krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
26082608
bt_mesh_net_revoke_keys(sub);
26092609
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) ||
26102610
IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
2611-
bt_mesh_friend_cred_refresh(ctx->net_idx);
2611+
friend_cred_refresh(ctx->net_idx);
26122612
}
26132613
sub->kr_phase = BT_MESH_KR_NORMAL;
26142614
sub->kr_flag = 0;

subsys/bluetooth/host/mesh/friend.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ static void friend_clear(struct bt_mesh_friend *frnd)
160160

161161
k_delayed_work_cancel(&frnd->timer);
162162

163-
bt_mesh_friend_cred_del(bt_mesh.sub[0].net_idx, frnd->lpn);
163+
friend_cred_del(frnd->net_idx, frnd->lpn);
164164

165165
if (frnd->last) {
166166
net_buf_unref(frnd->last);
@@ -325,9 +325,8 @@ static struct net_buf *create_friend_pdu(struct bt_mesh_friend *frnd,
325325
priv = sub->keys[sub->kr_flag].privacy;
326326
nid = sub->keys[sub->kr_flag].nid;
327327
} else {
328-
if (bt_mesh_friend_cred_get(sub, frnd->lpn, &nid, &enc,
329-
&priv)) {
330-
BT_ERR("bt_mesh_friend_cred_get failed");
328+
if (friend_cred_get(sub, frnd->lpn, &nid, &enc, &priv)) {
329+
BT_ERR("friend_cred_get failed");
331330
goto failed;
332331
}
333332
}
@@ -861,8 +860,7 @@ int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
861860
k_delayed_work_submit(&frnd->timer,
862861
offer_delay(frnd, rx->rssi, msg->criteria));
863862

864-
bt_mesh_friend_cred_add(sub->net_idx, sub->keys[0].net, 0,
865-
frnd->lpn, frnd->lpn_counter, frnd->counter);
863+
friend_cred_create(sub, frnd->lpn, frnd->lpn_counter, frnd->counter);
866864

867865
enqueue_offer(frnd, rx->rssi);
868866

subsys/bluetooth/host/mesh/lpn.c

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ static void clear_friendship(bool force, bool disable)
213213

214214
k_delayed_work_cancel(&lpn->timer);
215215

216-
bt_mesh_friend_cred_del(bt_mesh.sub[0].net_idx, lpn->frnd);
216+
friend_cred_del(bt_mesh.sub[0].net_idx, lpn->frnd);
217217

218218
if (lpn->clear_success) {
219219
lpn->old_friend = BT_MESH_ADDR_UNASSIGNED;
@@ -482,7 +482,7 @@ int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx,
482482
struct bt_mesh_ctl_friend_offer *msg = (void *)buf->data;
483483
struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
484484
struct bt_mesh_subnet *sub = rx->sub;
485-
struct bt_mesh_friend_cred *cred;
485+
struct friend_cred *cred;
486486
u16_t frnd_counter;
487487
int err;
488488

@@ -509,22 +509,12 @@ int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx,
509509

510510
lpn->frnd = rx->ctx.addr;
511511

512-
cred = bt_mesh_friend_cred_add(sub->net_idx, sub->keys[0].net, 0,
513-
lpn->frnd, lpn->counter, frnd_counter);
512+
cred = friend_cred_create(sub, lpn->frnd, lpn->counter, frnd_counter);
514513
if (!cred) {
515514
lpn->frnd = BT_MESH_ADDR_UNASSIGNED;
516515
return -ENOMEM;
517516
}
518517

519-
if (sub->kr_flag) {
520-
err = bt_mesh_friend_cred_set(cred, 1, sub->keys[1].net);
521-
if (err) {
522-
bt_mesh_friend_cred_clear(cred);
523-
lpn->frnd = BT_MESH_ADDR_UNASSIGNED;
524-
return err;
525-
}
526-
}
527-
528518
/* TODO: Add offer acceptance criteria check */
529519

530520
k_delayed_work_cancel(&lpn->timer);
@@ -534,7 +524,7 @@ int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx,
534524

535525
err = send_friend_poll();
536526
if (err) {
537-
bt_mesh_friend_cred_clear(cred);
527+
friend_cred_clear(cred);
538528
lpn->frnd = BT_MESH_ADDR_UNASSIGNED;
539529
lpn->recv_win = 0;
540530
lpn->queue_size = 0;

subsys/bluetooth/host/mesh/net.c

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
#endif
6565

6666
#if FRIEND_CRED_COUNT > 0
67-
static struct bt_mesh_friend_cred friend_cred[FRIEND_CRED_COUNT];
67+
static struct friend_cred friend_cred[FRIEND_CRED_COUNT];
6868
#endif
6969

7070
static u64_t msg_cache[CONFIG_BT_MESH_MSG_CACHE_SIZE];
@@ -208,8 +208,7 @@ int bt_mesh_net_keys_create(struct bt_mesh_subnet_keys *keys,
208208

209209
#if (defined(CONFIG_BT_MESH_LOW_POWER) || \
210210
defined(CONFIG_BT_MESH_FRIEND))
211-
int bt_mesh_friend_cred_set(struct bt_mesh_friend_cred *cred, u8_t idx,
212-
const u8_t net_key[16])
211+
int friend_cred_set(struct friend_cred *cred, u8_t idx, const u8_t net_key[16])
213212
{
214213
u16_t lpn_addr, frnd_addr;
215214
int err;
@@ -252,12 +251,12 @@ int bt_mesh_friend_cred_set(struct bt_mesh_friend_cred *cred, u8_t idx,
252251
return 0;
253252
}
254253

255-
void bt_mesh_friend_cred_refresh(u16_t net_idx)
254+
void friend_cred_refresh(u16_t net_idx)
256255
{
257256
int i;
258257

259258
for (i = 0; i < ARRAY_SIZE(friend_cred); i++) {
260-
struct bt_mesh_friend_cred *cred = &friend_cred[i];
259+
struct friend_cred *cred = &friend_cred[i];
261260

262261
if (cred->addr != BT_MESH_ADDR_UNASSIGNED &&
263262
cred->net_idx == net_idx) {
@@ -267,21 +266,21 @@ void bt_mesh_friend_cred_refresh(u16_t net_idx)
267266
}
268267
}
269268

270-
int bt_mesh_friend_cred_update(u16_t net_idx, u8_t idx, const u8_t net_key[16])
269+
int friend_cred_update(struct bt_mesh_subnet *sub)
271270
{
272271
int err, i;
273272

274-
BT_DBG("net_idx 0x%04x idx %u", net_idx, idx);
273+
BT_DBG("net_idx 0x%04x", sub->net_idx);
275274

276275
for (i = 0; i < ARRAY_SIZE(friend_cred); i++) {
277-
struct bt_mesh_friend_cred *cred = &friend_cred[i];
276+
struct friend_cred *cred = &friend_cred[i];
278277

279278
if (cred->addr == BT_MESH_ADDR_UNASSIGNED ||
280-
cred->net_idx != net_idx) {
279+
cred->net_idx != sub->net_idx) {
281280
continue;
282281
}
283282

284-
err = bt_mesh_friend_cred_set(cred, idx, net_key);
283+
err = friend_cred_set(cred, 1, sub->keys[1].net);
285284
if (err) {
286285
return err;
287286
}
@@ -290,21 +289,18 @@ int bt_mesh_friend_cred_update(u16_t net_idx, u8_t idx, const u8_t net_key[16])
290289
return 0;
291290
}
292291

293-
struct bt_mesh_friend_cred *bt_mesh_friend_cred_add(u16_t net_idx,
294-
const u8_t net_key[16],
295-
u8_t idx, u16_t addr,
296-
u16_t lpn_counter,
297-
u16_t frnd_counter)
292+
struct friend_cred *friend_cred_create(struct bt_mesh_subnet *sub, u16_t addr,
293+
u16_t lpn_counter, u16_t frnd_counter)
298294
{
299-
struct bt_mesh_friend_cred *cred;
295+
struct friend_cred *cred;
300296
int i, err;
301297

302-
BT_DBG("net_idx 0x%04x addr 0x%04x idx %u", net_idx, addr, idx);
298+
BT_DBG("net_idx 0x%04x addr 0x%04x", sub->net_idx, addr);
303299

304300
for (cred = NULL, i = 0; i < ARRAY_SIZE(friend_cred); i++) {
305301
if ((friend_cred[i].addr == BT_MESH_ADDR_UNASSIGNED) ||
306302
(friend_cred[i].addr == addr &&
307-
friend_cred[i].net_idx == net_idx)) {
303+
friend_cred[i].net_idx == sub->net_idx)) {
308304
cred = &friend_cred[i];
309305
break;
310306
}
@@ -315,21 +311,29 @@ struct bt_mesh_friend_cred *bt_mesh_friend_cred_add(u16_t net_idx,
315311
return NULL;
316312
}
317313

318-
cred->net_idx = net_idx;
314+
cred->net_idx = sub->net_idx;
319315
cred->addr = addr;
320316
cred->lpn_counter = lpn_counter;
321317
cred->frnd_counter = frnd_counter;
322318

323-
err = bt_mesh_friend_cred_set(cred, idx, net_key);
319+
err = friend_cred_set(cred, 0, sub->keys[0].net);
324320
if (err) {
325-
bt_mesh_friend_cred_clear(cred);
321+
friend_cred_clear(cred);
326322
return NULL;
327323
}
328324

325+
if (sub->kr_flag) {
326+
err = friend_cred_set(cred, 1, sub->keys[1].net);
327+
if (err) {
328+
friend_cred_clear(cred);
329+
return NULL;
330+
}
331+
}
332+
329333
return cred;
330334
}
331335

332-
void bt_mesh_friend_cred_clear(struct bt_mesh_friend_cred *cred)
336+
void friend_cred_clear(struct friend_cred *cred)
333337
{
334338
cred->net_idx = BT_MESH_KEY_UNUSED;
335339
cred->addr = BT_MESH_ADDR_UNASSIGNED;
@@ -338,31 +342,31 @@ void bt_mesh_friend_cred_clear(struct bt_mesh_friend_cred *cred)
338342
memset(cred->cred, 0, sizeof(cred->cred));
339343
}
340344

341-
int bt_mesh_friend_cred_del(u16_t net_idx, u16_t addr)
345+
int friend_cred_del(u16_t net_idx, u16_t addr)
342346
{
343347
int i;
344348

345349
for (i = 0; i < ARRAY_SIZE(friend_cred); i++) {
346-
struct bt_mesh_friend_cred *cred = &friend_cred[i];
350+
struct friend_cred *cred = &friend_cred[i];
347351

348352
if (cred->addr == addr && cred->net_idx == net_idx) {
349-
bt_mesh_friend_cred_clear(cred);
353+
friend_cred_clear(cred);
350354
return 0;
351355
}
352356
}
353357

354358
return -ENOENT;
355359
}
356360

357-
int bt_mesh_friend_cred_get(struct bt_mesh_subnet *sub, u16_t addr, u8_t *nid,
358-
const u8_t **enc, const u8_t **priv)
361+
int friend_cred_get(struct bt_mesh_subnet *sub, u16_t addr, u8_t *nid,
362+
const u8_t **enc, const u8_t **priv)
359363
{
360364
int i;
361365

362366
BT_DBG("net_idx 0x%04x addr 0x%04x", sub->net_idx, addr);
363367

364368
for (i = 0; i < ARRAY_SIZE(friend_cred); i++) {
365-
struct bt_mesh_friend_cred *cred = &friend_cred[i];
369+
struct friend_cred *cred = &friend_cred[i];
366370

367371
if (cred->net_idx != sub->net_idx) {
368372
continue;
@@ -390,8 +394,8 @@ int bt_mesh_friend_cred_get(struct bt_mesh_subnet *sub, u16_t addr, u8_t *nid,
390394
return -ENOENT;
391395
}
392396
#else
393-
int bt_mesh_friend_cred_get(struct bt_mesh_subnet *sub, u16_t addr, u8_t *nid,
394-
const u8_t **enc, const u8_t **priv)
397+
int friend_cred_get(struct bt_mesh_subnet *sub, u16_t addr, u8_t *nid,
398+
const u8_t **enc, const u8_t **priv)
395399
{
396400
return -ENOENT;
397401
}
@@ -541,7 +545,7 @@ bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, u8_t new_kr, bool new_key)
541545
bt_mesh_net_revoke_keys(sub);
542546
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) ||
543547
IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
544-
bt_mesh_friend_cred_refresh(sub->net_idx);
548+
friend_cred_refresh(sub->net_idx);
545549
}
546550
sub->kr_phase = BT_MESH_KR_NORMAL;
547551
return true;
@@ -801,8 +805,8 @@ int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct net_buf_simple *buf,
801805
}
802806

803807
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) && tx->friend_cred) {
804-
if (bt_mesh_friend_cred_get(tx->sub, BT_MESH_ADDR_UNASSIGNED,
805-
&nid, &enc, &priv)) {
808+
if (friend_cred_get(tx->sub, BT_MESH_ADDR_UNASSIGNED,
809+
&nid, &enc, &priv)) {
806810
BT_WARN("Falling back to master credentials");
807811

808812
tx->friend_cred = 0;
@@ -993,7 +997,7 @@ static int friend_decrypt(struct bt_mesh_subnet *sub, const u8_t *data,
993997
BT_DBG("NID 0x%02x net_idx 0x%04x", NID(data), sub->net_idx);
994998

995999
for (i = 0; i < ARRAY_SIZE(friend_cred); i++) {
996-
struct bt_mesh_friend_cred *cred = &friend_cred[i];
1000+
struct friend_cred *cred = &friend_cred[i];
9971001

9981002
if (cred->net_idx != sub->net_idx) {
9991003
continue;

subsys/bluetooth/host/mesh/net.h

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,6 @@ struct bt_mesh_app_key {
2727
} keys[2];
2828
};
2929

30-
/* Friendship Credentials */
31-
struct bt_mesh_friend_cred {
32-
u16_t net_idx;
33-
u16_t addr;
34-
35-
u16_t lpn_counter;
36-
u16_t frnd_counter;
37-
38-
struct {
39-
u8_t nid; /* NID */
40-
u8_t enc[16]; /* EncKey */
41-
u8_t privacy[16]; /* PrivacyKey */
42-
} cred[2];
43-
};
44-
4530
struct bt_mesh_subnet {
4631
u32_t beacon_sent; /* Timestamp of last sent beacon */
4732
u8_t beacons_last; /* Number of beacons during last
@@ -279,21 +264,6 @@ int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16],
279264

280265
u8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub);
281266

282-
int bt_mesh_friend_cred_get(struct bt_mesh_subnet *sub, u16_t addr, u8_t *nid,
283-
const u8_t **enc, const u8_t **priv);
284-
int bt_mesh_friend_cred_set(struct bt_mesh_friend_cred *cred, u8_t idx,
285-
const u8_t net_key[16]);
286-
void bt_mesh_friend_cred_refresh(u16_t net_idx);
287-
int bt_mesh_friend_cred_update(u16_t net_idx, u8_t idx,
288-
const u8_t net_key[16]);
289-
struct bt_mesh_friend_cred *bt_mesh_friend_cred_add(u16_t net_idx,
290-
const u8_t net_key[16],
291-
u8_t idx, u16_t addr,
292-
u16_t lpn_counter,
293-
u16_t frnd_counter);
294-
void bt_mesh_friend_cred_clear(struct bt_mesh_friend_cred *cred);
295-
int bt_mesh_friend_cred_del(u16_t net_idx, u16_t addr);
296-
297267
bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, u8_t new_kr, bool new_key);
298268

299269
void bt_mesh_net_revoke_keys(struct bt_mesh_subnet *sub);
@@ -327,3 +297,28 @@ void bt_mesh_net_recv(struct net_buf_simple *data, s8_t rssi,
327297
enum bt_mesh_net_if net_if);
328298

329299
void bt_mesh_net_init(void);
300+
301+
/* Friendship Credential Management */
302+
struct friend_cred {
303+
u16_t net_idx;
304+
u16_t addr;
305+
306+
u16_t lpn_counter;
307+
u16_t frnd_counter;
308+
309+
struct {
310+
u8_t nid; /* NID */
311+
u8_t enc[16]; /* EncKey */
312+
u8_t privacy[16]; /* PrivacyKey */
313+
} cred[2];
314+
};
315+
316+
int friend_cred_get(struct bt_mesh_subnet *sub, u16_t addr, u8_t *nid,
317+
const u8_t **enc, const u8_t **priv);
318+
int friend_cred_set(struct friend_cred *cred, u8_t idx, const u8_t net_key[16]);
319+
void friend_cred_refresh(u16_t net_idx);
320+
int friend_cred_update(struct bt_mesh_subnet *sub);
321+
struct friend_cred *friend_cred_create(struct bt_mesh_subnet *sub, u16_t addr,
322+
u16_t lpn_counter, u16_t frnd_counter);
323+
void friend_cred_clear(struct friend_cred *cred);
324+
int friend_cred_del(u16_t net_idx, u16_t addr);

0 commit comments

Comments
 (0)