llsec: Permit dynamic security levels
This commit is contained in:
parent
0379af3624
commit
10d8b05bc6
22 changed files with 137 additions and 122 deletions
|
@ -128,8 +128,10 @@ To configure TSCH, see the macros in `.h` files under `core/net/mac/tsch/` and r
|
|||
To include TSCH standard-compliant security, set the following:
|
||||
```
|
||||
/* Enable security */
|
||||
#undef LLSEC802154_CONF_SECURITY_LEVEL
|
||||
#define LLSEC802154_CONF_SECURITY_LEVEL 1
|
||||
#undef LLSEC802154_CONF_ENABLED
|
||||
#define LLSEC802154_CONF_ENABLED 1
|
||||
#undef TSCH_SECURITY_CONF_LEVEL
|
||||
#define TSCH_SECURITY_CONF_LEVEL 1
|
||||
/* TSCH uses explicit keys to identify k1 and k2 */
|
||||
#undef LLSEC802154_CONF_USES_EXPLICIT_KEYS
|
||||
#define LLSEC802154_CONF_USES_EXPLICIT_KEYS 1
|
||||
|
|
|
@ -94,7 +94,7 @@ tsch_packet_create_eack(uint8_t *buf, int buf_size,
|
|||
p.src_pid = IEEE802154_PANID;
|
||||
linkaddr_copy((linkaddr_t *)&p.src_addr, &linkaddr_node_addr);
|
||||
#endif
|
||||
#if TSCH_SECURITY_ENABLED
|
||||
#if LLSEC802154_ENABLED
|
||||
if(tsch_is_pan_secured) {
|
||||
p.fcf.security_enabled = 1;
|
||||
p.aux_hdr.security_control.security_level = TSCH_SECURITY_KEY_SEC_LEVEL_ACK;
|
||||
|
@ -103,7 +103,7 @@ tsch_packet_create_eack(uint8_t *buf, int buf_size,
|
|||
p.aux_hdr.security_control.frame_counter_size = 1;
|
||||
p.aux_hdr.key_index = TSCH_SECURITY_KEY_INDEX_ACK;
|
||||
}
|
||||
#endif /* TSCH_SECURITY_ENABLED */
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
|
||||
if((curr_len = frame802154_create(&p, buf)) == 0) {
|
||||
return 0;
|
||||
|
@ -166,13 +166,13 @@ tsch_packet_parse_eack(const uint8_t *buf, int buf_size,
|
|||
|
||||
if(frame->fcf.ie_list_present) {
|
||||
int mic_len = 0;
|
||||
#if TSCH_SECURITY_ENABLED
|
||||
#if LLSEC802154_ENABLED
|
||||
/* Check if there is space for the security MIC (if any) */
|
||||
mic_len = tsch_security_mic_len(frame);
|
||||
if(buf_size < curr_len + mic_len) {
|
||||
return 0;
|
||||
}
|
||||
#endif /* TSCH_SECURITY_ENABLED */
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
/* Parse information elements. We need to substract the MIC length, as the exact payload len is needed while parsing */
|
||||
if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) {
|
||||
return 0;
|
||||
|
@ -222,7 +222,7 @@ tsch_packet_create_eb(uint8_t *buf, int buf_size, uint8_t seqno,
|
|||
p.dest_addr[0] = 0xff;
|
||||
p.dest_addr[1] = 0xff;
|
||||
|
||||
#if TSCH_SECURITY_ENABLED
|
||||
#if LLSEC802154_ENABLED
|
||||
if(tsch_is_pan_secured) {
|
||||
p.fcf.security_enabled = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0;
|
||||
p.aux_hdr.security_control.security_level = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL);
|
||||
|
@ -231,7 +231,7 @@ tsch_packet_create_eb(uint8_t *buf, int buf_size, uint8_t seqno,
|
|||
p.aux_hdr.security_control.frame_counter_size = 1;
|
||||
p.aux_hdr.key_index = packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX);
|
||||
}
|
||||
#endif /* TSCH_SECURITY_ENABLED */
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
|
||||
if((curr_len = frame802154_create(&p, buf)) == 0) {
|
||||
return 0;
|
||||
|
@ -387,14 +387,14 @@ tsch_packet_parse_eb(const uint8_t *buf, int buf_size,
|
|||
if(frame->fcf.ie_list_present) {
|
||||
/* Calculate space needed for the security MIC, if any, before attempting to parse IEs */
|
||||
int mic_len = 0;
|
||||
#if TSCH_SECURITY_ENABLED
|
||||
#if LLSEC802154_ENABLED
|
||||
if(!frame_without_mic) {
|
||||
mic_len = tsch_security_mic_len(frame);
|
||||
if(buf_size < curr_len + mic_len) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* TSCH_SECURITY_ENABLED */
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
|
||||
/* Parse information elements. We need to substract the MIC length, as the exact payload len is needed while parsing */
|
||||
if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) {
|
||||
|
|
|
@ -39,22 +39,36 @@
|
|||
#include "net/mac/tsch/tsch-asn.h"
|
||||
#include "net/mac/tsch/tsch-private.h"
|
||||
#include "net/mac/frame802154.h"
|
||||
#include "net/llsec/llsec802154.h"
|
||||
#include "net/mac/frame802154e-ie.h"
|
||||
|
||||
/******** Configuration *******/
|
||||
|
||||
/* To enable TSCH security:
|
||||
* - set LLSEC802154_CONF_SECURITY_LEVEL
|
||||
* - set LLSEC802154_CONF_ENABLED
|
||||
* - set TSCH_SECURITY_CONF_LEVEL
|
||||
* - set LLSEC802154_CONF_USES_EXPLICIT_KEYS
|
||||
* - unset LLSEC802154_CONF_USES_FRAME_COUNTER
|
||||
* */
|
||||
#define TSCH_SECURITY_ENABLED (LLSEC802154_CONF_SECURITY_LEVEL != 0)
|
||||
#if TSCH_SECURITY_ENABLED && !LLSEC802154_CONF_USES_EXPLICIT_KEYS
|
||||
#error TSCH_SECURITY_ENABLED set but LLSEC802154_CONF_USES_EXPLICIT_KEYS unset
|
||||
#endif /* TSCH_SECURITY_ENABLED */
|
||||
#if TSCH_SECURITY_ENABLED && LLSEC802154_CONF_USES_FRAME_COUNTER
|
||||
#error TSCH_SECURITY_ENABLED set but LLSEC802154_CONF_USES_FRAME_COUNTER set
|
||||
#endif /* TSCH_SECURITY_ENABLED */
|
||||
|
||||
#ifdef TSCH_SECURITY_CONF_LEVEL
|
||||
#define TSCH_SECURITY_LEVEL TSCH_SECURITY_CONF_LEVEL
|
||||
#else /* TSCH_SECURITY_CONF_LEVEL */
|
||||
#define TSCH_SECURITY_LEVEL FRAME802154_SECURITY_LEVEL_NONE
|
||||
#endif /* TSCH_SECURITY_CONF_LEVEL */
|
||||
|
||||
#if LLSEC802154_ENABLED && !TSCH_SECURITY_LEVEL
|
||||
#error LLSEC802154_ENABLED set but TSCH_SECURITY_LEVEL unset
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
#if !LLSEC802154_ENABLED && TSCH_SECURITY_LEVEL
|
||||
#error TSCH_SECURITY_LEVEL set but LLSEC802154_ENABLED unset
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
#if LLSEC802154_ENABLED && !LLSEC802154_USES_EXPLICIT_KEYS
|
||||
#error LLSEC802154_ENABLED set but LLSEC802154_USES_EXPLICIT_KEYS unset
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
#if LLSEC802154_ENABLED && LLSEC802154_USES_FRAME_COUNTER
|
||||
#error LLSEC802154_ENABLED set but LLSEC802154_USES_FRAME_COUNTER set
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
|
||||
/* K1, defined in 6TiSCH minimal, is well-known (offers no security) and used for EBs only */
|
||||
#ifdef TSCH_SECURITY_CONF_K1
|
||||
|
|
|
@ -404,10 +404,10 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
|
|||
} else {
|
||||
/* packet payload */
|
||||
static void *packet;
|
||||
#if TSCH_SECURITY_ENABLED
|
||||
#if LLSEC802154_ENABLED
|
||||
/* encrypted payload */
|
||||
static uint8_t encrypted_packet[TSCH_PACKET_MAX_LEN];
|
||||
#endif /* TSCH_SECURITY_ENABLED */
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
/* packet payload length */
|
||||
static uint8_t packet_len;
|
||||
/* packet seqno */
|
||||
|
@ -434,7 +434,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
|
|||
packet_ready = 1;
|
||||
}
|
||||
|
||||
#if TSCH_SECURITY_ENABLED
|
||||
#if LLSEC802154_ENABLED
|
||||
if(tsch_is_pan_secured) {
|
||||
/* If we are going to encrypt, we need to generate the output in a separate buffer and keep
|
||||
* the original untouched. This is to allow for future retransmissions. */
|
||||
|
@ -445,7 +445,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
|
|||
packet = encrypted_packet;
|
||||
}
|
||||
}
|
||||
#endif /* TSCH_SECURITY_ENABLED */
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
|
||||
/* prepare packet to send: copy to radio buffer */
|
||||
if(packet_ready && NETSTACK_RADIO.prepare(packet, packet_len) == 0) { /* 0 means success */
|
||||
|
@ -530,7 +530,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
|
|||
ack_len = 0;
|
||||
}
|
||||
|
||||
#if TSCH_SECURITY_ENABLED
|
||||
#if LLSEC802154_ENABLED
|
||||
if(ack_len != 0) {
|
||||
if(!tsch_security_parse_frame(ackbuf, ack_hdrlen, ack_len - ack_hdrlen - tsch_security_mic_len(&frame),
|
||||
&frame, ¤t_neighbor->addr, ¤t_asn)) {
|
||||
|
@ -544,7 +544,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
|
|||
snprintf(log->message, sizeof(log->message),
|
||||
"!failed to parse ACK"));
|
||||
}
|
||||
#endif /* TSCH_SECURITY_ENABLED */
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
}
|
||||
|
||||
if(ack_len != 0) {
|
||||
|
@ -604,11 +604,11 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
|
|||
log->tx.drift = drift_correction;
|
||||
log->tx.drift_used = is_drift_correction_used;
|
||||
log->tx.is_data = ((((uint8_t *)(queuebuf_dataptr(current_packet->qb)))[0]) & 7) == FRAME802154_DATAFRAME;
|
||||
#if TSCH_SECURITY_ENABLED
|
||||
#if LLSEC802154_ENABLED
|
||||
log->tx.sec_level = queuebuf_attr(current_packet->qb, PACKETBUF_ATTR_SECURITY_LEVEL);
|
||||
#else /* TSCH_SECURITY_ENABLED */
|
||||
#else /* LLSEC802154_ENABLED */
|
||||
log->tx.sec_level = 0;
|
||||
#endif /* TSCH_SECURITY_ENABLED */
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
log->tx.dest = TSCH_LOG_ID_FROM_LINKADDR(queuebuf_addr(current_packet->qb, PACKETBUF_ADDR_RECEIVER));
|
||||
);
|
||||
|
||||
|
@ -712,7 +712,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t))
|
|||
|
||||
packet_duration = TSCH_PACKET_DURATION(current_input->len);
|
||||
|
||||
#if TSCH_SECURITY_ENABLED
|
||||
#if LLSEC802154_ENABLED
|
||||
/* Decrypt and verify incoming frame */
|
||||
if(frame_valid) {
|
||||
if(tsch_security_parse_frame(
|
||||
|
@ -731,7 +731,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t))
|
|||
"!failed to parse frame %u %u", header_len, current_input->len));
|
||||
frame_valid = 0;
|
||||
}
|
||||
#endif /* TSCH_SECURITY_ENABLED */
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
|
||||
if(frame_valid) {
|
||||
if(linkaddr_cmp(&destination_address, &linkaddr_node_addr)
|
||||
|
@ -765,12 +765,12 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t))
|
|||
ack_len = tsch_packet_create_eack(ack_buf, sizeof(ack_buf),
|
||||
&source_address, frame.seq, (int16_t)RTIMERTICKS_TO_US(estimated_drift), do_nack);
|
||||
|
||||
#if TSCH_SECURITY_ENABLED
|
||||
#if LLSEC802154_ENABLED
|
||||
if(tsch_is_pan_secured) {
|
||||
/* Secure ACK frame. There is only header and header IEs, therefore data len == 0. */
|
||||
ack_len += tsch_security_secure_frame(ack_buf, ack_buf, ack_len, 0, ¤t_asn);
|
||||
}
|
||||
#endif /* TSCH_SECURITY_ENABLED */
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
|
||||
/* Copy to radio buffer */
|
||||
NETSTACK_RADIO.prepare((const void *)ack_buf, ack_len);
|
||||
|
|
|
@ -141,7 +141,7 @@ int tsch_is_coordinator = 0;
|
|||
/* Are we associated to a TSCH network? */
|
||||
int tsch_is_associated = 0;
|
||||
/* Is the PAN running link-layer security? */
|
||||
int tsch_is_pan_secured = TSCH_SECURITY_ENABLED;
|
||||
int tsch_is_pan_secured = LLSEC802154_ENABLED;
|
||||
/* The current Absolute Slot Number (ASN) */
|
||||
struct asn_t current_asn;
|
||||
/* Device rank or join priority:
|
||||
|
@ -177,7 +177,7 @@ tsch_set_coordinator(int enable)
|
|||
void
|
||||
tsch_set_pan_secured(int enable)
|
||||
{
|
||||
tsch_is_pan_secured = TSCH_SECURITY_ENABLED && enable;
|
||||
tsch_is_pan_secured = LLSEC802154_ENABLED && enable;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -455,21 +455,21 @@ tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp)
|
|||
}
|
||||
#endif /* TSCH_JOIN_SECURED_ONLY */
|
||||
|
||||
#if TSCH_SECURITY_ENABLED
|
||||
#if LLSEC802154_ENABLED
|
||||
if(!tsch_security_parse_frame(input_eb->payload, hdrlen,
|
||||
input_eb->len - hdrlen - tsch_security_mic_len(&frame),
|
||||
&frame, (linkaddr_t*)&frame.src_addr, ¤t_asn)) {
|
||||
PRINTF("TSCH:! parse_eb: failed to authenticate\n");
|
||||
return 0;
|
||||
}
|
||||
#endif /* TSCH_SECURITY_ENABLED */
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
|
||||
#if !TSCH_SECURITY_ENABLED
|
||||
#if !LLSEC802154_ENABLED
|
||||
if(frame.fcf.security_enabled == 1) {
|
||||
PRINTF("TSCH:! parse_eb: we do not support security, but EB is secured\n");
|
||||
return 0;
|
||||
}
|
||||
#endif /* !TSCH_SECURITY_ENABLED */
|
||||
#endif /* !LLSEC802154_ENABLED */
|
||||
|
||||
#if TSCH_JOIN_MY_PANID_ONLY
|
||||
/* Check if the EB comes from the PAN ID we expect */
|
||||
|
@ -746,14 +746,14 @@ PROCESS_THREAD(tsch_send_eb_process, ev, data)
|
|||
}
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_BEACONFRAME);
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, tsch_packet_seqno);
|
||||
#if TSCH_SECURITY_ENABLED
|
||||
#if LLSEC802154_ENABLED
|
||||
if(tsch_is_pan_secured) {
|
||||
/* Set security level, key id and index */
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, TSCH_SECURITY_KEY_SEC_LEVEL_EB);
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, FRAME802154_1_BYTE_KEY_ID_MODE); /* Use 1-byte key index */
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, TSCH_SECURITY_KEY_INDEX_EB);
|
||||
}
|
||||
#endif /* TSCH_SECURITY_ENABLED */
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
eb_len = tsch_packet_create_eb(packetbuf_dataptr(), PACKETBUF_SIZE,
|
||||
tsch_packet_seqno, &hdr_len, &tsch_sync_ie_offset);
|
||||
if(eb_len != 0) {
|
||||
|
@ -907,14 +907,14 @@ send_packet(mac_callback_t sent, void *ptr)
|
|||
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, tsch_packet_seqno);
|
||||
|
||||
#if TSCH_SECURITY_ENABLED
|
||||
#if LLSEC802154_ENABLED
|
||||
if(tsch_is_pan_secured) {
|
||||
/* Set security level, key id and index */
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, TSCH_SECURITY_KEY_SEC_LEVEL_OTHER);
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, FRAME802154_1_BYTE_KEY_ID_MODE); /* Use 1-byte key index */
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, TSCH_SECURITY_KEY_INDEX_OTHER);
|
||||
}
|
||||
#endif /* TSCH_SECURITY_ENABLED */
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
|
||||
packet_count_before = tsch_queue_packet_count(addr);
|
||||
|
||||
|
|
|
@ -84,8 +84,8 @@
|
|||
#ifdef TSCH_CONF_JOIN_SECURED_ONLY
|
||||
#define TSCH_JOIN_SECURED_ONLY TSCH_CONF_JOIN_SECURED_ONLY
|
||||
#else
|
||||
/* By default, set if TSCH_SECURITY_ENABLED is also non-zero */
|
||||
#define TSCH_JOIN_SECURED_ONLY TSCH_SECURITY_ENABLED
|
||||
/* By default, set if LLSEC802154_ENABLED is also non-zero */
|
||||
#define TSCH_JOIN_SECURED_ONLY LLSEC802154_ENABLED
|
||||
#endif
|
||||
|
||||
/* By default, join any PAN ID. Otherwise, wait for an EB from IEEE802154_PANID */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue