58#include "ccm-star-packetbuf.h"
61#define LOG_MODULE "CSMA"
62#define LOG_LEVEL LOG_LEVEL_MAC
64#if LOG_LEVEL == LOG_LEVEL_DBG
65static const char * HEX =
"0123456789ABCDEF";
68#if LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER
70#define MIC_LEN(level) LLSEC802154_MIC_LEN(level)
72#if LLSEC802154_USES_EXPLICIT_KEYS
73#define LLSEC_KEY_INDEX (FRAME802154_IMPLICIT_KEY == packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE) \
75 : packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX))
76#define LLSEC_KEY_MODE (packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE))
78#define LLSEC_KEY_INDEX (0)
79#define LLSEC_KEY_MODE (FRAME802154_IMPLICIT_KEY)
88static aes_key_t keys[CSMA_LLSEC_MAXKEYS];
92csma_security_set_key(uint8_t index,
const uint8_t *key)
94 if(key != NULL && index < CSMA_LLSEC_MAXKEYS) {
95 memcpy(keys[index].u8, key, 16);
101#define N_KEYS (sizeof(keys) / sizeof(aes_key))
104aead(uint8_t hdrlen,
int forward)
107 uint8_t nonce[CCM_STAR_NONCE_LENGTH];
114 uint8_t generated_mic[MIC_LEN(7)];
118 uint8_t with_encryption;
120 key_index = LLSEC_KEY_INDEX;
121 if(key_index >= CSMA_LLSEC_MAXKEYS) {
122 LOG_ERR(
"Key not available: %u\n", key_index);
126 key = &keys[key_index];
128 ccm_star_packetbuf_set_nonce(nonce, forward);
133 (packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x4) ? 1 : 0;
135 if(with_encryption) {
138 m_len = totlen - hdrlen;
146 result = forward ? mic : generated_mic;
148 CCM_STAR.set_key(key->u8);
152 result, MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07),
159 return (memcmp(generated_mic, mic, MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07)) == 0);
165csma_security_create_frame(
void)
169 packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
170 if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0 &&
171 LLSEC_KEY_INDEX != 0xffff) {
175 hdr_len = NETSTACK_FRAMER.create();
180 if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0) {
181#if LOG_LEVEL == LOG_LEVEL_DBG
187 LOG_DBG_(
"%c%c", HEX[(p[i] >> 4) & 0x0f], HEX[p[i] & 0x0f]);
192 if(!aead(hdr_len, 1)) {
193 LOG_ERR(
"failed to encrypt packet to ");
194 LOG_ERR_LLADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
196 return FRAMER_FAILED;
198 LOG_INFO(
"LLSEC-OUT:");
199 LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
201 LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
203 packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL), LLSEC_KEY_INDEX);
205#if LOG_LEVEL == LOG_LEVEL_DBG
209 LOG_DBG_(
"%c%c", HEX[(p[i] >> 4) & 0x0f], HEX[p[i] & 0x0f]);
220csma_security_frame_len(
void)
222 if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0 &&
223 LLSEC_KEY_INDEX != 0xffff) {
224 return NETSTACK_FRAMER.length() +
225 MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07);
227 return NETSTACK_FRAMER.length();
231csma_security_parse_frame(
void)
235 hdr_len = NETSTACK_FRAMER.parse();
240 if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) == 0) {
243 #ifdef LLSEC802154_REJECT_INSECURE
244 return FRAMER_FAILED;
251 LOG_INFO(
"LLSEC-IN: ");
252 LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
254 LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
260 if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) != CSMA_LLSEC_SECURITY_LEVEL) {
261 LOG_INFO(
"received frame with wrong security level (%u) from ",
262 packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL));
263 LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
265 return FRAMER_FAILED;
268 if(LLSEC_KEY_MODE != CSMA_LLSEC_KEY_ID_MODE) {
269 LOG_INFO(
"received frame with wrong key id mode (%u) from ", LLSEC_KEY_MODE);
270 LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
272 return FRAMER_FAILED;
276 LOG_INFO(
"frame from ourselves\n");
277 return FRAMER_FAILED;
280 if(
packetbuf_datalen() <= MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07)) {
281 LOG_ERR(
"MIC error - too little data in frame!\n");
282 return FRAMER_FAILED;
286 if(!aead(hdr_len, 0)) {
287 LOG_INFO(
"received unauthentic frame %u from ",
289 LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
291 return FRAMER_FAILED;
301csma_security_create_frame(
void)
303 packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
304 return NETSTACK_FRAMER.create();
307csma_security_parse_frame(
void)
309 return NETSTACK_FRAMER.parse();
Interface to anti-replay mechanisms.
LLSEC802154 Security related configuration.
The 802.15.4 standard CSMA protocol (nonbeacon-enabled)
802.15.4 frame creation and parsing functions
A MAC framer for IEEE 802.15.4.
linkaddr_t linkaddr_node_addr
The link-layer address of the node.
bool linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two link-layer addresses.
uint32_t anti_replay_get_counter(void)
Gets the frame counter from packetbuf.
void anti_replay_set_counter(void)
Sets the frame counter packetbuf attributes.
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
uint16_t packetbuf_totlen(void)
Get the total length of the header and data in the packetbuf.
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
void * packetbuf_hdrptr(void)
Get a pointer to the header in the packetbuf, for outbound packets.
Common functionality of 802.15.4-compliant llsec_drivers.
Header file for the logging system.
Include file for the Contiki low-layer network stack (NETSTACK)
Header file for the Packet buffer (packetbuf) management.