I have written a simple implementation for using the ccm module with mesh. It encrypts and decrypts as it should but when enabled the processor makes a soft reset. It happens quiet often but not on every sent or received packet. In addition to the code below, I have modified the packet format to match what the ccm needs and declared som data structures. The code is based on https://github.com/NordicSemiconductor/nRF51-ble-bcast-mesh
The source as follows( crypto.c):
#include <string.h>
#include "services.h"
#include "crypto.h"
#include "nrf.h"
#include "rand.h"
#include "nrf_drv_ppi.h"
uint8_t aes_ccm_key[16] = {'N', 'O', 'T', 'A', 'G', 'O', 'O', 'D', 'P', 'A', 'S', 'S', 'W', 'O', 'R', 'D'};
uint8_t scratch_area[16+255];//16 bytes + 2^(max(length field size))
ccm_data_t ccm_data;
typedef uint32_t pkt_counter_t[5];
void crypto_encrypt(uint32_t *in_ptr, uint32_t *out_ptr)
{
uint32_t i;
for(i= 0; i<16; i++)
ccm_data.KEY[i] = aes_ccm_key[i];
for(i=0;i<5;i++)
ccm_data.PKTCTR[i] = packet_counter(i);
ccm_data.dir =0; //undocumented does 1 mean encrypt or decrypt?
//rand_hw_rng_get(&ccm_data.IV, 8); //random initialisation vector
NRF_AAR->ENABLE = (AAR_ENABLE_ENABLE_Disabled << AAR_ENABLE_ENABLE_Pos) & AAR_ENABLE_ENABLE_Msk; //make sure AAR is disabled
NRF_CCM->ENABLE = (CCM_ENABLE_ENABLE_Disabled << CCM_ENABLE_ENABLE_Pos) & CCM_ENABLE_ENABLE_Msk;
NRF_CCM->CNFPTR =(uint32_t) &ccm_data;
NRF_CCM->SCRATCHPTR =(uint32_t) &scratch_area;
NRF_CCM->MODE = 1<<24|1<<16|0<<0; // mode length extended, 1 mbit datarate, encrypt
NRF_CCM->INPTR = (uint32_t)in_ptr;
NRF_CCM->OUTPTR = (uint32_t)out_ptr;
NRF_CCM->SHORTS = 1; //Shorts enabled'
NRF_CCM->ENABLE = (CCM_ENABLE_ENABLE_Enabled << CCM_ENABLE_ENABLE_Pos) & CCM_ENABLE_ENABLE_Msk;
}
void crypto_decrypt(uint32_t *in_ptr, uint32_t *out_ptr)
{
uint32_t i;
for(i= 0; i<16; i++)
ccm_data.KEY[i] = aes_ccm_key[i];
for(i=0;i<5;i++)
ccm_data.PKTCTR[i] = packet_counter(i);
ccm_data.dir = 0; //undocumented does 1 mean encrypt or decrypt?
NRF_AAR->ENABLE = (AAR_ENABLE_ENABLE_Disabled << AAR_ENABLE_ENABLE_Pos) & AAR_ENABLE_ENABLE_Msk; //make sure AAR is disabled
NRF_CCM->ENABLE = (CCM_ENABLE_ENABLE_Disabled << CCM_ENABLE_ENABLE_Pos) & CCM_ENABLE_ENABLE_Msk;
NRF_CCM->CNFPTR =(uint32_t) &ccm_data;
NRF_CCM->SCRATCHPTR =(uint32_t) &scratch_area;
NRF_CCM->MODE = 1<<24|1<<16|1<<0; // mode length extended, 1 mbit datarate, decrypt
NRF_CCM->INPTR = (uint32_t)in_ptr;
NRF_CCM->OUTPTR = (uint32_t)out_ptr;
NRF_CCM->SHORTS = 1; //Shorts enabled'
NRF_CCM->ENABLE = (CCM_ENABLE_ENABLE_Enabled << CCM_ENABLE_ENABLE_Pos) & CCM_ENABLE_ENABLE_Msk;
}
Radio_control.c is modified to call the above functions:
static void setup_event(radio_event_t* p_evt)
{
NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_ADDRESS_RSSISTART_Msk;
radio_channel_set(p_evt->channel);
NRF_RADIO->PACKETPTR = (uint32_t)packet_buffer;
//NRF_RADIO->PACKETPTR =(uint32_t)p_evt->packet_ptr;
NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk;
NRF_RADIO->EVENTS_END = 0;
NRF_RADIO->PREFIX0 |= (((m_alt_aa >> 24) << 8) & 0x0000FF00);
NRF_RADIO->BASE1 = ((m_alt_aa << 8) & 0xFFFFFF00);
nrf_drv_ppi_channel_enable(24); //activate ppi between ccm and radio
NRF_CCM->EVENTS_ENDCRYPT=0;
if (p_evt->event_type == RADIO_EVENT_TYPE_TX)
{
crypto_encrypt((uint32_t *)p_evt->packet_ptr,(uint32_t *)packet_buffer);
DEBUG_RADIO_SET_STATE(PIN_RADIO_STATE_TX);
NRF_RADIO->TXADDRESS = p_evt->access_address;
NRF_RADIO->TXPOWER = p_evt->tx_power;
NRF_RADIO->TASKS_TXEN = 1;
NRF_CCM->TASKS_KSGEN =1;
m_radio_state = RADIO_STATE_TX;
}
else
{
DEBUG_RADIO_SET_STATE(PIN_RADIO_STATE_RX);
if (m_alt_aa != RADIO_DEFAULT_ADDRESS)
{
/* only enable alt-addr if it's different */
NRF_RADIO->RXADDRESSES = 0x03;
}
else
{
NRF_RADIO->RXADDRESSES = 0x01;
}
crypto_decrypt((uint32_t *)packet_buffer, (uint32_t *)p_evt->packet_ptr);
NRF_CCM->TASKS_KSGEN =1;
NRF_RADIO->TASKS_RXEN = 1;
m_radio_state = RADIO_STATE_RX;
}
}