This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

AES-CCM encryption

I want to encrypt advertisements using aes-ccm peripheral present on the nrf51 board. I am not using softdevice, instead I am generating my own packets and transmitting them on radio. I want the packets to be encrypted on the fly. Even after setting up ccm peripheral as mentioned in the reference manual, I am getting unencrypted ads. Currently, the ads contain only the address. I am using ubertooth one to sniff the ble ads.

I am using this code to encrypt the packet :

uint8_t aes_ccm_key[16] = {'N', 'O', 'T', 'A', 'G', 'O', 'O', 'D', 'P', 'A', 'S', 'S', 'W', 'O', 'R', 'D'};
uint8_t aes_ccm_nonce[12] = {'N', 'O', 'T', 'A', 'G', 'O', 'O', 'D', 'P', 'A', 'S', 'S'};

struct aes_ccm_cnfptr {
	uint8_t key[16];
	uint8_t nonce[12];
};
struct aes_ccm_cnfptr ccm_cnfptr;

struct aes_ccm_cnfptr ccm_cnfptr;
memcpy(ccm_cnfptr.key, aes_ccm_key, 16);
memcpy(&ccm_cnfptr.nonce, aes_ccm_nonce, 12);

void send_encrypted_packet()
{
    // send the packet:
    NRF_RADIO->EVENTS_READY = 0U;
    NRF_RADIO->TASKS_TXEN   = 1;

    while (NRF_RADIO->EVENTS_READY == 0U)
    {
        // wait
    }
		
		NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Msk;
		NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk;
		NRF_CCM->INPTR = (uint32_t) ble_adv_data;
		NRF_CCM->OUTPTR = (uint32_t) ccm_outptr;
		NRF_RADIO->PACKETPTR = (uint32_t) ccm_outptr;
		NRF_CCM->SCRATCHPTR = (uint32_t) ccm_scratchptr;
		NRF_CCM->CNFPTR = (uint32_t) &ccm_cnfptr;
		
		NRF_CCM->EVENTS_ENDKSGEN = 0U;
		NRF_CCM->TASKS_KSGEN = 1U;
		
		while(NRF_CCM->EVENTS_ENDKSGEN == 0U){
			//wait
		}
		
		NRF_CCM->EVENTS_ENDCRYPT = 0;
		NRF_CCM->TASKS_CRYPT = 1;
		while(NRF_CCM->EVENTS_ENDCRYPT == 0){
			//wait
		}
		
    NRF_RADIO->EVENTS_END  = 0U;
    NRF_RADIO->TASKS_START = 1U;

    while (NRF_RADIO->EVENTS_END == 0U)
    {
        // wait
    }

    //uint32_t err_code = bsp_indication_text_set(BSP_INDICATE_SENT_OK, "The packet was sent\r\n");
    //APP_ERROR_CHECK(err_code);

    NRF_RADIO->EVENTS_DISABLED = 0U;
    // Disable radio
    NRF_RADIO->TASKS_DISABLE = 1U;

    while (NRF_RADIO->EVENTS_DISABLED == 0U)
    {
        // wait
    }
}

UPDATE : I have modified the code to use PPI and shortcuts but still its not working. Now, it is sending ads but there is no data in ad (device address should be there).

static void sm_enter_adv_send(void)
{
	SEGGER_RTT_printf(0, "inside sm_enter_adv_send()");
	periph_radio_ch_set(channel);
	
	NRF_PPI->CHEN = (PPI_CHEN_CH24_Enabled << PPI_CHEN_CH24_Pos);
	
	NRF_RADIO->TASKS_TXEN = 1;
	
	aes_ccm();

	periph_radio_shorts_set(RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk);    
	
	periph_radio_intenset(RADIO_INTENSET_DISABLED_Msk);
}

void aes_ccm(){
		NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk;
		NRF_CCM->INPTR = (uint32_t) ble_adv_data;
		NRF_CCM->OUTPTR = (uint32_t) ccm_outptr;
		NRF_RADIO->PACKETPTR = (uint32_t) ccm_outptr;
		NRF_CCM->SCRATCHPTR = (uint32_t) ccm_scratchptr;
		NRF_CCM->CNFPTR = (uint32_t) &ccm_cnfptr;
		
		NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Msk;
}

Where am I doing mistake in this code ? Thanks in advance.

Related