Bluetooth: Mesh: store rpl only if incoming data is accepted
Commit prevents updating replay protection list on any frame came from the network layer. Replay protection cache is updated only if - transport handles transport command without errors - access layer handles model message without errors - transport frame has correct length Signed-off-by: Aleksandr Khromykh <aleksandr.khromykh@nordicsemi.no>
This commit is contained in:
parent
7e39db9bce
commit
21eafe6b91
3 changed files with 36 additions and 32 deletions
|
@ -675,7 +675,7 @@ int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx,
|
|||
|
||||
err = send_friend_poll();
|
||||
if (err) {
|
||||
/* Will retry sending later */
|
||||
LOG_WRN("LPN didn't succeed poll sending (err %d)", err);
|
||||
for (int i = 0; i < ARRAY_SIZE(lpn->cred); i++) {
|
||||
if (lpn->sub->keys[i].valid) {
|
||||
bt_mesh_friend_cred_destroy(&lpn->cred[i]);
|
||||
|
@ -686,7 +686,6 @@ int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx,
|
|||
lpn->frnd = BT_MESH_ADDR_UNASSIGNED;
|
||||
lpn->recv_win = 0U;
|
||||
lpn->queue_size = 0U;
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -102,12 +102,12 @@ void bt_mesh_rpl_update(struct bt_mesh_rpl *rpl,
|
|||
}
|
||||
|
||||
/* Check the Replay Protection List for a replay attempt. If non-NULL match
|
||||
* parameter is given the RPL slot is returned but it is not immediately
|
||||
* updated (needed for segmented messages), whereas if a NULL match is given
|
||||
* the RPL is immediately updated (used for unsegmented messages).
|
||||
* parameter is given the RPL slot is returned, but it is not immediately
|
||||
* updated. This is used to prevent storing data in RPL that has been rejected
|
||||
* by upper logic (access, transport commands) and for receiving the segmented messages.
|
||||
* If a NULL match is given the RPL is immediately updated (used for proxy configuration).
|
||||
*/
|
||||
bool bt_mesh_rpl_check(struct bt_mesh_net_rx *rx,
|
||||
struct bt_mesh_rpl **match)
|
||||
bool bt_mesh_rpl_check(struct bt_mesh_net_rx *rx, struct bt_mesh_rpl **match)
|
||||
{
|
||||
struct bt_mesh_rpl *rpl;
|
||||
int i;
|
||||
|
|
|
@ -796,23 +796,22 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint8_t hdr, uint8_t aszmic,
|
|||
LOG_DBG("AKF %u AID 0x%02x", !ctx.crypto.dev_key, AID(&hdr));
|
||||
|
||||
if (!rx->local_match) {
|
||||
return 0;
|
||||
/* if friend_match was set the frame is for LPN which we are friends. */
|
||||
return rx->friend_match ? 0 : -ENXIO;
|
||||
}
|
||||
|
||||
rx->ctx.app_idx = bt_mesh_app_key_find(ctx.crypto.dev_key, AID(&hdr),
|
||||
rx, sdu_try_decrypt, &ctx);
|
||||
if (rx->ctx.app_idx == BT_MESH_KEY_UNUSED) {
|
||||
LOG_DBG("No matching AppKey");
|
||||
return 0;
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
rx->ctx.uuid = ctx.crypto.ad;
|
||||
|
||||
LOG_DBG("Decrypted (AppIdx: 0x%03x)", rx->ctx.app_idx);
|
||||
|
||||
(void)bt_mesh_model_recv(&rx->ctx, sdu);
|
||||
|
||||
return 0;
|
||||
return bt_mesh_access_recv(&rx->ctx, sdu);
|
||||
}
|
||||
|
||||
static struct seg_tx *seg_tx_lookup(uint16_t seq_zero, uint8_t obo, uint16_t addr)
|
||||
|
@ -1027,6 +1026,8 @@ static int trans_unseg(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx,
|
|||
{
|
||||
NET_BUF_SIMPLE_DEFINE_STATIC(sdu, BT_MESH_SDU_UNSEG_MAX);
|
||||
uint8_t hdr;
|
||||
struct bt_mesh_rpl *rpl = NULL;
|
||||
int err;
|
||||
|
||||
LOG_DBG("AFK %u AID 0x%02x", AKF(buf->data), AID(buf->data));
|
||||
|
||||
|
@ -1035,7 +1036,7 @@ static int trans_unseg(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx,
|
|||
return -EBADMSG;
|
||||
}
|
||||
|
||||
if (bt_mesh_rpl_check(rx, NULL)) {
|
||||
if (bt_mesh_rpl_check(rx, &rpl)) {
|
||||
LOG_WRN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", rx->ctx.addr, rx->ctx.recv_dst,
|
||||
rx->seq);
|
||||
return -EINVAL;
|
||||
|
@ -1044,18 +1045,22 @@ static int trans_unseg(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx,
|
|||
hdr = net_buf_simple_pull_u8(buf);
|
||||
|
||||
if (rx->ctl) {
|
||||
return ctl_recv(rx, hdr, buf, seq_auth);
|
||||
}
|
||||
|
||||
if (buf->len < 1 + APP_MIC_LEN(0)) {
|
||||
err = ctl_recv(rx, hdr, buf, seq_auth);
|
||||
} else if (buf->len < 1 + APP_MIC_LEN(0)) {
|
||||
LOG_ERR("Too short SDU + MIC");
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
} else {
|
||||
/* Adjust the length to not contain the MIC at the end */
|
||||
buf->len -= APP_MIC_LEN(0);
|
||||
err = sdu_recv(rx, hdr, 0, buf, &sdu, NULL);
|
||||
}
|
||||
|
||||
/* Adjust the length to not contain the MIC at the end */
|
||||
buf->len -= APP_MIC_LEN(0);
|
||||
/* Update rpl only if there is place and upper logic accepted incoming data. */
|
||||
if (err == 0 && rpl != NULL) {
|
||||
bt_mesh_rpl_update(rpl, rx);
|
||||
}
|
||||
|
||||
return sdu_recv(rx, hdr, 0, buf, &sdu, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, uint8_t ctl_op, void *data,
|
||||
|
@ -1558,17 +1563,6 @@ found_rx:
|
|||
}
|
||||
|
||||
LOG_DBG("Complete SDU");
|
||||
|
||||
if (rpl) {
|
||||
bt_mesh_rpl_update(rpl, net_rx);
|
||||
/* Update the seg, unless it has already been surpassed:
|
||||
* This needs to happen after rpl_update to ensure that the IV
|
||||
* update reset logic inside rpl_update doesn't overwrite the
|
||||
* change.
|
||||
*/
|
||||
rpl->seg = MAX(rpl->seg, auth_seqnum);
|
||||
}
|
||||
|
||||
*pdu_type = BT_MESH_FRIEND_PDU_COMPLETE;
|
||||
|
||||
/* If this fails, the work handler will either exit early because the
|
||||
|
@ -1602,6 +1596,17 @@ found_rx:
|
|||
err = sdu_recv(net_rx, *hdr, ASZMIC(hdr), &seg_buf, &sdu, rx);
|
||||
}
|
||||
|
||||
/* Update rpl only if there is place and upper logic accepted incoming data. */
|
||||
if (err == 0 && rpl != NULL) {
|
||||
bt_mesh_rpl_update(rpl, net_rx);
|
||||
/* Update the seg, unless it has already been surpassed:
|
||||
* This needs to happen after rpl_update to ensure that the IV
|
||||
* update reset logic inside rpl_update doesn't overwrite the
|
||||
* change.
|
||||
*/
|
||||
rpl->seg = MAX(rpl->seg, auth_seqnum);
|
||||
}
|
||||
|
||||
seg_rx_reset(rx, false);
|
||||
|
||||
return err;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue