llsec: Added AEAD mode to CCM*

This commit is contained in:
Konrad Krentz 2015-07-15 06:11:42 -07:00 committed by kkrentz
parent c656a4d1c5
commit 0a6b1cb646
7 changed files with 116 additions and 108 deletions

View file

@ -146,9 +146,32 @@ set_key(const uint8_t *key)
AES_128.set_key(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 = { const struct ccm_star_driver ccm_star_driver = {
mic, set_key,
ctr, aead
set_key
}; };
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View file

@ -54,34 +54,27 @@
* Structure of CCM* drivers. * Structure of CCM* drivers.
*/ */
struct ccm_star_driver { 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(). * \brief Sets the key in use. Default implementation calls AES_128.set_key().
* \param key The key to use. * \param key The key to use.
*/ */
void (* set_key)(const uint8_t* key); 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; extern const struct ccm_star_driver CCM_STAR;

View file

@ -39,7 +39,7 @@
*/ */
#include "llsec/ccm-star-packetbuf.h" #include "llsec/ccm-star-packetbuf.h"
#include "lib/ccm-star.h" #include "net/linkaddr.h"
#include "net/packetbuf.h" #include "net/packetbuf.h"
#include <string.h> #include <string.h>
@ -62,10 +62,12 @@ get_extended_address(const linkaddr_t *addr)
} }
#endif /* LINKADDR_SIZE == 2 */ #endif /* LINKADDR_SIZE == 2 */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Inits the 13-byte CCM* nonce as of 802.15.4-2011. */ void
static void ccm_star_packetbuf_set_nonce(uint8_t *nonce, int forward)
set_nonce(uint8_t *nonce, const linkaddr_t *source_addr)
{ {
const linkaddr_t *source_addr;
source_addr = forward ? &linkaddr_node_addr : packetbuf_addr(PACKETBUF_ADDR_SENDER);
memcpy(nonce, get_extended_address(source_addr), 8); memcpy(nonce, get_extended_address(source_addr), 8);
nonce[8] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 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; 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); 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());
}
/*---------------------------------------------------------------------------*/

View file

@ -41,18 +41,8 @@
#ifndef CCM_STAR_PACKETBUF_H_ #ifndef CCM_STAR_PACKETBUF_H_
#define CCM_STAR_PACKETBUF_H_ #define CCM_STAR_PACKETBUF_H_
#include "net/linkaddr.h" #include "lib/ccm-star.h"
/** void ccm_star_packetbuf_set_nonce(uint8_t *nonce, int forward);
* \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);
#endif /* CCM_STAR_PACKETBUF_H_ */ #endif /* CCM_STAR_PACKETBUF_H_ */

View file

@ -80,6 +80,45 @@
static uint8_t key[16] = NONCORESEC_KEY; static uint8_t key[16] = NONCORESEC_KEY;
NBR_TABLE(struct anti_replay_info, anti_replay_table); 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 static void
send(mac_callback_t sent, void *ptr) send(mac_callback_t sent, void *ptr)
@ -94,22 +133,13 @@ static int
create(void) create(void)
{ {
int result; int result;
uint8_t *dataptr;
uint8_t datalen;
result = framer_802154.create(); result = framer_802154.create();
if(result == FRAMER_FAILED) { if(result == FRAMER_FAILED) {
return result; return result;
} }
dataptr = packetbuf_dataptr();
datalen = packetbuf_datalen();
ccm_star_packetbuf_mic(&linkaddr_node_addr, dataptr + datalen, LLSEC802154_MIC_LENGTH); aead(1);
#if WITH_ENCRYPTION
ccm_star_packetbuf_ctr(&linkaddr_node_addr);
#endif /* WITH_ENCRYPTION */
packetbuf_set_datalen(datalen + LLSEC802154_MIC_LENGTH);
return result; return result;
} }
@ -123,8 +153,6 @@ parse(void)
static void static void
input(void) input(void)
{ {
uint8_t generated_mic[LLSEC802154_MIC_LENGTH];
uint8_t *received_mic;
const linkaddr_t *sender; const linkaddr_t *sender;
struct anti_replay_info* info; struct anti_replay_info* info;
@ -140,14 +168,8 @@ input(void)
packetbuf_set_datalen(packetbuf_datalen() - LLSEC802154_MIC_LENGTH); packetbuf_set_datalen(packetbuf_datalen() - LLSEC802154_MIC_LENGTH);
#if WITH_ENCRYPTION if(!aead(0)) {
ccm_star_packetbuf_ctr(sender); PRINTF("noncoresec: received unauthentic frame %"PRIu32"\n",
#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",
anti_replay_get_counter()); anti_replay_get_counter());
return; return;
} }

View file

@ -72,11 +72,12 @@ test_sec_lvl_6()
0x01 , 0xCE }; 0x01 , 0xCE };
uint8_t oracle[LLSEC802154_MIC_LENGTH] = { 0x4F , 0xDE , 0x52 , 0x90 , uint8_t oracle[LLSEC802154_MIC_LENGTH] = { 0x4F , 0xDE , 0x52 , 0x90 ,
0x61 , 0xF9 , 0xC6 , 0xF1 }; 0x61 , 0xF9 , 0xC6 , 0xF1 };
uint8_t nonce[13];
frame802154_frame_counter_t counter; frame802154_frame_counter_t counter;
uint8_t mic[LLSEC802154_MIC_LENGTH];
printf("Testing verification ... "); printf("Testing verification ... ");
linkaddr_copy(&linkaddr_node_addr, &source_address);
packetbuf_clear(); packetbuf_clear();
packetbuf_set_datalen(30); packetbuf_set_datalen(30);
memcpy(packetbuf_hdrptr(), data, 30); memcpy(packetbuf_hdrptr(), data, 30);
@ -87,9 +88,14 @@ test_sec_lvl_6()
packetbuf_hdrreduce(29); packetbuf_hdrreduce(29);
CCM_STAR.set_key(key); 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"); printf("Success\n");
} else { } else {
printf("Failure\n"); printf("Failure\n");
@ -97,7 +103,6 @@ test_sec_lvl_6()
printf("Testing encryption ... "); printf("Testing encryption ... ");
ccm_star_packetbuf_ctr(&source_address);
if(((uint8_t *) packetbuf_hdrptr())[29] == 0xD8) { if(((uint8_t *) packetbuf_hdrptr())[29] == 0xD8) {
printf("Success\n"); printf("Success\n");
} else { } else {
@ -105,7 +110,13 @@ test_sec_lvl_6()
} }
printf("Testing decryption ... "); 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) { if(((uint8_t *) packetbuf_hdrptr())[29] == 0xCE) {
printf("Success\n"); printf("Success\n");
} else { } else {

View file

@ -101,9 +101,11 @@ test_sec_lvl_2()
0x84 , 0x1A , 0xB5 , 0x53 }; 0x84 , 0x1A , 0xB5 , 0x53 };
frame802154_frame_counter_t counter; frame802154_frame_counter_t counter;
uint8_t mic[LLSEC802154_MIC_LENGTH]; uint8_t mic[LLSEC802154_MIC_LENGTH];
uint8_t nonce[13];
printf("Testing verification ... "); printf("Testing verification ... ");
linkaddr_copy(&linkaddr_node_addr, &source_address);
packetbuf_clear(); packetbuf_clear();
packetbuf_set_datalen(26); packetbuf_set_datalen(26);
memcpy(packetbuf_hdrptr(), data, 26); memcpy(packetbuf_hdrptr(), data, 26);
@ -114,9 +116,14 @@ test_sec_lvl_2()
packetbuf_hdrreduce(18); packetbuf_hdrreduce(18);
CCM_STAR.set_key(key); 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"); printf("Success\n");
} else { } else {
printf("Failure\n"); printf("Failure\n");