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 65 static 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) 88 static aes_key_t keys[CSMA_LLSEC_MAXKEYS];
92 csma_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)) 104 aead(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);
165 csma_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]);
220 csma_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();
231 csma_security_parse_frame(
void)
235 hdr_len = NETSTACK_FRAMER.parse();
240 if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) == 0) {
245 LOG_INFO(
"LLSEC-IN: ");
246 LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
248 LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
254 if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) != CSMA_LLSEC_SECURITY_LEVEL) {
255 LOG_INFO(
"received frame with wrong security level (%u) from ",
256 packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL));
257 LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
259 return FRAMER_FAILED;
262 if(LLSEC_KEY_MODE != CSMA_LLSEC_KEY_ID_MODE) {
263 LOG_INFO(
"received frame with wrong key id mode (%u) from ", LLSEC_KEY_MODE);
264 LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
266 return FRAMER_FAILED;
270 LOG_INFO(
"frame from ourselves\n");
271 return FRAMER_FAILED;
274 if(
packetbuf_datalen() <= MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07)) {
275 LOG_ERR(
"MIC error - too little data in frame!\n");
276 return FRAMER_FAILED;
280 if(!aead(hdr_len, 0)) {
281 LOG_INFO(
"received unauthentic frame %u from ",
283 LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
285 return FRAMER_FAILED;
295 csma_security_create_frame(
void)
297 packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
298 return NETSTACK_FRAMER.create();
301 csma_security_parse_frame(
void)
303 return NETSTACK_FRAMER.parse();
Interface to anti-replay mechanisms.
The 802.15.4 standard CSMA protocol (nonbeacon-enabled)
LLSEC802154 Security related configuration
Common functionality of 802.15.4-compliant llsec_drivers.
A MAC framer for IEEE 802.15.4
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
linkaddr_t linkaddr_node_addr
The link-layer address of the node.
uint16_t packetbuf_totlen(void)
Get the total length of the header and data in the packetbuf.
802.15.4 frame creation and parsing functions
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two link-layer addresses.
void * packetbuf_hdrptr(void)
Get a pointer to the header in the packetbuf, for outbound packets.
void anti_replay_set_counter(void)
Sets the frame counter packetbuf attributes.
Header file for the Packet buffer (packetbuf) management
Include file for the Contiki low-layer network stack (NETSTACK)
uint32_t anti_replay_get_counter(void)
Gets the frame counter from packetbuf.
Header file for the logging system
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.