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);
}
/*---------------------------------------------------------------------------*/
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
};
/*---------------------------------------------------------------------------*/

View File

@ -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;

View File

@ -39,7 +39,7 @@
*/
#include "llsec/ccm-star-packetbuf.h"
#include "lib/ccm-star.h"
#include "net/linkaddr.h"
#include "net/packetbuf.h"
#include <string.h>
@ -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());
}
/*---------------------------------------------------------------------------*/

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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 {

View File

@ -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");