mesh: use replay protection list

This commit is contained in:
Matthias Ringwald 2019-03-29 19:12:01 +01:00
parent 16753ea2f9
commit 2a0ab8c231
2 changed files with 54 additions and 26 deletions

View File

@ -490,6 +490,7 @@ static void show_usage(void){
printf("2 - Send Segmented Access Message - Unicast\n");
printf("3 - Send Segmented Access Message - Group D000\n");
printf("4 - Send Segmented Access Message - Virtual 9779\n");
printf("6 - Clear Replay Protection List\n");
printf("7 - Load PTS App key\n");
printf("\n");
}
@ -523,6 +524,10 @@ static void stdin_process(char cmd){
case '4':
send_pts_segmented_access_messsage_virtual();
break;
case '6':
printf("Clearing Replay Protection List\n");
mesh_seq_auth_reset();
break;
case '7':
load_pts_app_key();
break;

View File

@ -195,53 +195,76 @@ static uint8_t mesh_network_send(uint16_t netkey_index, uint8_t ctl, uint8_t ttl
// mesh seq auth validation
// TODO: support multiple devices
#define MESH_ADDRESS_UNSASSIGNED 0xfffb
static uint16_t mesh_seq_auth_single_src = MESH_ADDRESS_UNSASSIGNED;
static uint32_t mesh_seq_auth_single_seq;
static uint16_t mesh_seq_auth_single_zero;
typedef struct {
// primary element address
uint16_t address;
// next expected seq number
uint32_t seq;
// seq_zero
uint16_t seq_zero;
} mesh_peer_t;
#define MESH_NUM_PEERS 5
static mesh_peer_t mesh_peers[MESH_NUM_PEERS];
static mesh_peer_t * mesh_peer_for_addr(uint16_t address){
int i;
for (i=0;i<MESH_NUM_PEERS;i++){
if (mesh_peers[i].address == address){
return &mesh_peers[i];
}
}
for (i=0;i<MESH_NUM_PEERS;i++){
// TODO: use MESH_ADDRESS_UNASSIGNED (after setting it to 0)
if (mesh_peers[i].address== 0){
memset(&mesh_peers[i], 0, sizeof(mesh_peer_t));
mesh_peers[i].address = address;
return &mesh_peers[i];
}
}
return NULL;
}
void mesh_seq_auth_reset(void){
mesh_seq_auth_single_src = MESH_ADDRESS_UNSASSIGNED;
int i;
for(i=0;i<MESH_NUM_PEERS;i++){
memset(&mesh_peers[i], 0, sizeof(mesh_peer_t));
}
}
// 0: valid
// 1: different node / cache full
// 2: older message
static int mesh_seq_auth_validate(uint16_t src, uint32_t seq){
if (mesh_seq_auth_single_src == MESH_ADDRESS_UNSASSIGNED){
mesh_seq_auth_single_src = src;
mesh_seq_auth_single_seq = seq;
mesh_peer_t * peer = mesh_peer_for_addr(src);
if (peer == NULL) return 1;
if (peer->seq >= seq) return 2;
peer->seq = seq;
return 0;
}
if (mesh_seq_auth_single_src != src){
return 1;
}
if (mesh_seq_auth_single_seq >= seq){
return 2;
}
mesh_seq_auth_single_seq = seq;
return 0;
}
// return:
// - 0 = new seq_zero
// - 1 = different src
// - 1 = different src / cache full
// - 2 = current src + seq_zer0
// - 3 = older
static int mesh_seq_zero_validate(uint16_t src, uint16_t seq_zero){
printf("mesh_seq_zero_validate(%x, %x) -- last (%x, %x)\n", src, seq_zero, mesh_seq_auth_single_src, mesh_seq_auth_single_zero);
mesh_peer_t * peer = mesh_peer_for_addr(src);
if (peer == 0) return 1;
printf("mesh_seq_zero_validate(%x, %x) -- last (%x, %x)\n", src, seq_zero, peer->address, peer->seq_zero);
// assume mesh_seq_auth_validate was already called
if (mesh_seq_auth_single_src == MESH_ADDRESS_UNSASSIGNED) return 0;
if (mesh_seq_auth_single_src != src) return 1;
if (mesh_seq_auth_single_zero == seq_zero) return 2;
if (mesh_seq_auth_single_zero > seq_zero) return 3;
if (peer->seq_zero == seq_zero) return 2;
if (peer->seq_zero > seq_zero) return 3;
return 0;
}
static void mesh_seq_zero_commit(uint16_t src, uint16_t seq_zero){
printf("mesh_seq_zero_commit(%x, %x) -- last (%x, %x)\n", src, seq_zero, mesh_seq_auth_single_src, mesh_seq_auth_single_zero);
mesh_seq_auth_single_src = src;
mesh_seq_auth_single_zero = seq_zero;
mesh_peer_t * peer = mesh_peer_for_addr(src);
if (peer == 0) return;
printf("mesh_seq_zero_commit(%x, %x) -- last (%x, %x)\n", src, seq_zero, peer->address, peer->seq_zero);
peer->seq_zero = seq_zero;
}
// stub lower transport