diff --git a/core/lib/ccm-star.c b/core/lib/ccm-star.c index f916c4633..fdbbd5363 100644 --- a/core/lib/ccm-star.c +++ b/core/lib/ccm-star.c @@ -146,9 +146,32 @@ set_key(const uint8_t *key) AES_128.set_key(key); } /*---------------------------------------------------------------------------*/ +void +aead(const uint8_t* nonce, + uint8_t* m, uint8_t m_len, + const uint8_t* a, uint8_t a_len, + uint8_t *result, uint8_t mic_len, + int forward) +{ + if(!forward) { + /* decrypt */ + ctr(nonce, m, m_len); + } + + mic(nonce, + m, m_len, + a, a_len, + result, + mic_len); + + if(forward) { + /* encrypt */ + ctr(nonce, m, m_len); + } +} +/*---------------------------------------------------------------------------*/ const struct ccm_star_driver ccm_star_driver = { - mic, - ctr, - set_key + set_key, + aead }; /*---------------------------------------------------------------------------*/ diff --git a/core/lib/ccm-star.h b/core/lib/ccm-star.h index ad4e49798..06296fb44 100644 --- a/core/lib/ccm-star.h +++ b/core/lib/ccm-star.h @@ -54,34 +54,27 @@ * Structure of CCM* drivers. */ struct ccm_star_driver { - - /** - * \brief Generates a MIC over the data supplied. - * \param nonce The nonce to use. CCM_STAR_NONCE_LENGTH bytes long. - * \param m Message to authenticate and encrypt - * \param a Additional authenticated data - * \param result The generated MIC will be put here - * \param mic_len The size of the MIC to be generated. <= 16. - */ - void (* mic)(const uint8_t* nonce, - const uint8_t* m, uint8_t m_len, - const uint8_t* a, uint8_t a_len, - uint8_t *result, - uint8_t mic_len); - - /** - * \brief XORs m with the key stream. - * \param nonce The nonce to use. CCM_STAR_NONCE_LENGTH bytes long. - * \param m Message to authenticate and encrypt - */ - void (* ctr)(const uint8_t* nonce, - uint8_t* m, uint8_t m_len); /** * \brief Sets the key in use. Default implementation calls AES_128.set_key(). * \param key The key to use. */ void (* set_key)(const uint8_t* key); + + /** + * \brief Combines authentication and encryption. + * \param nonce The nonce to use. CCM_STAR_NONCE_LENGTH bytes long. + * \param m message to encrypt or decrypt + * \param a Additional authenticated data + * \param result The generated MIC will be put here + * \param mic_len The size of the MIC to be generated. <= 16. + * \param forward != 0 if used in forward direction. + */ + void (* aead)(const uint8_t* nonce, + uint8_t* m, uint8_t m_len, + const uint8_t* a, uint8_t a_len, + uint8_t *result, uint8_t mic_len, + int forward); }; extern const struct ccm_star_driver CCM_STAR; diff --git a/core/net/llsec/ccm-star-packetbuf.c b/core/net/llsec/ccm-star-packetbuf.c index 91740f547..61e681b1c 100644 --- a/core/net/llsec/ccm-star-packetbuf.c +++ b/core/net/llsec/ccm-star-packetbuf.c @@ -39,7 +39,7 @@ */ #include "llsec/ccm-star-packetbuf.h" -#include "lib/ccm-star.h" +#include "net/linkaddr.h" #include "net/packetbuf.h" #include @@ -62,10 +62,12 @@ get_extended_address(const linkaddr_t *addr) } #endif /* LINKADDR_SIZE == 2 */ /*---------------------------------------------------------------------------*/ -/* Inits the 13-byte CCM* nonce as of 802.15.4-2011. */ -static void -set_nonce(uint8_t *nonce, const linkaddr_t *source_addr) +void +ccm_star_packetbuf_set_nonce(uint8_t *nonce, int forward) { + const linkaddr_t *source_addr; + + source_addr = forward ? &linkaddr_node_addr : packetbuf_addr(PACKETBUF_ADDR_SENDER); memcpy(nonce, get_extended_address(source_addr), 8); nonce[8] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 8; nonce[9] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) & 0xff; @@ -74,43 +76,3 @@ set_nonce(uint8_t *nonce, const linkaddr_t *source_addr) nonce[12] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL); } /*---------------------------------------------------------------------------*/ -void -ccm_star_packetbuf_mic(const linkaddr_t *source_addr, - uint8_t *result, - uint8_t mic_len) -{ - uint8_t nonce[CCM_STAR_NONCE_LENGTH]; - uint8_t *m; - uint8_t m_len; - uint8_t *a; - uint8_t a_len; - - set_nonce(nonce, source_addr); - - a = packetbuf_hdrptr(); - if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & (1 << 2)) { - m = packetbuf_dataptr(); - m_len = packetbuf_datalen(); - a_len = packetbuf_hdrlen(); - } else { - m = NULL; - m_len = 0; - a_len = packetbuf_totlen(); - } - - CCM_STAR.mic(nonce, - m, m_len, - a, a_len, - result, - mic_len); -} -/*---------------------------------------------------------------------------*/ -void -ccm_star_packetbuf_ctr(const linkaddr_t *source_addr) -{ - uint8_t nonce[CCM_STAR_NONCE_LENGTH]; - - set_nonce(nonce, source_addr); - CCM_STAR.ctr(nonce, packetbuf_dataptr(), packetbuf_datalen()); -} -/*---------------------------------------------------------------------------*/ diff --git a/core/net/llsec/ccm-star-packetbuf.h b/core/net/llsec/ccm-star-packetbuf.h index d93ff1160..dcbe6c4db 100644 --- a/core/net/llsec/ccm-star-packetbuf.h +++ b/core/net/llsec/ccm-star-packetbuf.h @@ -41,18 +41,8 @@ #ifndef CCM_STAR_PACKETBUF_H_ #define CCM_STAR_PACKETBUF_H_ -#include "net/linkaddr.h" +#include "lib/ccm-star.h" -/** - * \brief Calls CCM_STAR.mic with parameters appropriate for LLSEC. - */ -void ccm_star_packetbuf_mic(const linkaddr_t *source_addr, - uint8_t *result, - uint8_t mic_len); - -/** - * \brief Calls CCM_STAR.ctr with parameters appropriate for LLSEC. - */ -void ccm_star_packetbuf_ctr(const linkaddr_t *source_addr); +void ccm_star_packetbuf_set_nonce(uint8_t *nonce, int forward); #endif /* CCM_STAR_PACKETBUF_H_ */ diff --git a/core/net/llsec/noncoresec/noncoresec.c b/core/net/llsec/noncoresec/noncoresec.c index ca6e5f3ee..ee26a5ba0 100644 --- a/core/net/llsec/noncoresec/noncoresec.c +++ b/core/net/llsec/noncoresec/noncoresec.c @@ -80,6 +80,45 @@ static uint8_t key[16] = NONCORESEC_KEY; NBR_TABLE(struct anti_replay_info, anti_replay_table); +/*---------------------------------------------------------------------------*/ +static int +aead(int forward) +{ + uint8_t nonce[CCM_STAR_NONCE_LENGTH]; + uint8_t *m; + uint8_t m_len; + uint8_t *a; + uint8_t a_len; + uint8_t *result; + uint8_t generated_mic[LLSEC802154_MIC_LENGTH]; + uint8_t *mic; + + ccm_star_packetbuf_set_nonce(nonce, forward); + a = packetbuf_hdrptr(); + m = packetbuf_dataptr(); +#if WITH_ENCRYPTION + a_len = packetbuf_hdrlen(); + m_len = packetbuf_datalen(); +#else /* WITH_ENCRYPTION */ + a_len = packetbuf_totlen(); + m_len = 0; +#endif /* WITH_ENCRYPTION */ + mic = a + a_len + m_len; + result = forward ? mic : generated_mic; + + CCM_STAR.aead(nonce, + m, m_len, + a, a_len, + result, LLSEC802154_MIC_LENGTH, + forward); + + if(forward) { + packetbuf_set_datalen(packetbuf_datalen() + LLSEC802154_MIC_LENGTH); + return 1; + } else { + return (memcmp(generated_mic, mic, LLSEC802154_MIC_LENGTH) == 0); + } +} /*---------------------------------------------------------------------------*/ static void send(mac_callback_t sent, void *ptr) @@ -94,22 +133,13 @@ static int create(void) { int result; - uint8_t *dataptr; - uint8_t datalen; result = framer_802154.create(); if(result == FRAMER_FAILED) { return result; } - - dataptr = packetbuf_dataptr(); - datalen = packetbuf_datalen(); - ccm_star_packetbuf_mic(&linkaddr_node_addr, dataptr + datalen, LLSEC802154_MIC_LENGTH); -#if WITH_ENCRYPTION - ccm_star_packetbuf_ctr(&linkaddr_node_addr); -#endif /* WITH_ENCRYPTION */ - packetbuf_set_datalen(datalen + LLSEC802154_MIC_LENGTH); + aead(1); return result; } @@ -123,8 +153,6 @@ parse(void) static void input(void) { - uint8_t generated_mic[LLSEC802154_MIC_LENGTH]; - uint8_t *received_mic; const linkaddr_t *sender; struct anti_replay_info* info; @@ -140,14 +168,8 @@ input(void) packetbuf_set_datalen(packetbuf_datalen() - LLSEC802154_MIC_LENGTH); -#if WITH_ENCRYPTION - ccm_star_packetbuf_ctr(sender); -#endif /* WITH_ENCRYPTION */ - ccm_star_packetbuf_mic(sender, generated_mic, LLSEC802154_MIC_LENGTH); - - received_mic = ((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen(); - if(memcmp(generated_mic, received_mic, LLSEC802154_MIC_LENGTH) != 0) { - PRINTF("noncoresec: received nonauthentic frame %"PRIu32"\n", + if(!aead(0)) { + PRINTF("noncoresec: received unauthentic frame %"PRIu32"\n", anti_replay_get_counter()); return; } diff --git a/examples/llsec/ccm-star-tests/encryption/tests.c b/examples/llsec/ccm-star-tests/encryption/tests.c index 0c454157c..b5c296799 100644 --- a/examples/llsec/ccm-star-tests/encryption/tests.c +++ b/examples/llsec/ccm-star-tests/encryption/tests.c @@ -72,11 +72,12 @@ test_sec_lvl_6() 0x01 , 0xCE }; uint8_t oracle[LLSEC802154_MIC_LENGTH] = { 0x4F , 0xDE , 0x52 , 0x90 , 0x61 , 0xF9 , 0xC6 , 0xF1 }; + uint8_t nonce[13]; frame802154_frame_counter_t counter; - uint8_t mic[LLSEC802154_MIC_LENGTH]; printf("Testing verification ... "); + linkaddr_copy(&linkaddr_node_addr, &source_address); packetbuf_clear(); packetbuf_set_datalen(30); memcpy(packetbuf_hdrptr(), data, 30); @@ -87,9 +88,14 @@ test_sec_lvl_6() packetbuf_hdrreduce(29); CCM_STAR.set_key(key); - ccm_star_packetbuf_mic(&source_address, mic, LLSEC802154_MIC_LENGTH); + ccm_star_packetbuf_set_nonce(nonce, 1); + CCM_STAR.aead(nonce, + packetbuf_dataptr(), packetbuf_datalen(), + packetbuf_hdrptr(), packetbuf_hdrlen(), + ((uint8_t *) packetbuf_hdrptr()) + 30, LLSEC802154_MIC_LENGTH, + 1); - if(memcmp(mic, oracle, LLSEC802154_MIC_LENGTH) == 0) { + if(memcmp(((uint8_t *) packetbuf_hdrptr()) + 30, oracle, LLSEC802154_MIC_LENGTH) == 0) { printf("Success\n"); } else { printf("Failure\n"); @@ -97,7 +103,6 @@ test_sec_lvl_6() printf("Testing encryption ... "); - ccm_star_packetbuf_ctr(&source_address); if(((uint8_t *) packetbuf_hdrptr())[29] == 0xD8) { printf("Success\n"); } else { @@ -105,7 +110,13 @@ test_sec_lvl_6() } printf("Testing decryption ... "); - ccm_star_packetbuf_ctr(&source_address); + packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &source_address); + ccm_star_packetbuf_set_nonce(nonce, 0); + CCM_STAR.aead(nonce, + packetbuf_dataptr(), packetbuf_datalen(), + packetbuf_hdrptr(), packetbuf_hdrlen(), + ((uint8_t *) packetbuf_hdrptr()) + 30, LLSEC802154_MIC_LENGTH, + 0); if(((uint8_t *) packetbuf_hdrptr())[29] == 0xCE) { printf("Success\n"); } else { diff --git a/examples/llsec/ccm-star-tests/verification/tests.c b/examples/llsec/ccm-star-tests/verification/tests.c index 61490a0c5..4de463fee 100644 --- a/examples/llsec/ccm-star-tests/verification/tests.c +++ b/examples/llsec/ccm-star-tests/verification/tests.c @@ -101,9 +101,11 @@ test_sec_lvl_2() 0x84 , 0x1A , 0xB5 , 0x53 }; frame802154_frame_counter_t counter; uint8_t mic[LLSEC802154_MIC_LENGTH]; + uint8_t nonce[13]; printf("Testing verification ... "); + linkaddr_copy(&linkaddr_node_addr, &source_address); packetbuf_clear(); packetbuf_set_datalen(26); memcpy(packetbuf_hdrptr(), data, 26); @@ -114,9 +116,14 @@ test_sec_lvl_2() packetbuf_hdrreduce(18); CCM_STAR.set_key(key); - ccm_star_packetbuf_mic(&source_address, mic, LLSEC802154_MIC_LENGTH); + ccm_star_packetbuf_set_nonce(nonce, 1); + CCM_STAR.aead(nonce, + NULL, 0, + packetbuf_hdrptr(), packetbuf_totlen(), + ((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen(), LLSEC802154_MIC_LENGTH, + 1); - if(memcmp(mic, oracle, LLSEC802154_MIC_LENGTH) == 0) { + if(memcmp(((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen(), oracle, LLSEC802154_MIC_LENGTH) == 0) { printf("Success\n"); } else { printf("Failure\n");