llsec: Added AEAD mode to CCM*
This commit is contained in:
parent
c656a4d1c5
commit
0a6b1cb646
|
@ -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
|
|
||||||
};
|
};
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -55,33 +55,26 @@
|
||||||
*/
|
*/
|
||||||
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;
|
||||||
|
|
|
@ -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());
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
|
|
|
@ -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_ */
|
||||||
|
|
|
@ -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();
|
aead(1);
|
||||||
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);
|
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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");
|
||||||
|
|
Loading…
Reference in a new issue