Skip to content

Commit

Permalink
nrf_802154: rev 1247ab9c1eb4bd8bba3b699414eb0cd4c57092ce
Browse files Browse the repository at this point in the history
This commit updates revision of the nrf_802154 component.

Signed-off-by: Jędrzej Ciupis <[email protected]>
  • Loading branch information
Jędrzej Ciupis committed Mar 7, 2024
1 parent 3c77b49 commit b53a685
Show file tree
Hide file tree
Showing 22 changed files with 334 additions and 142 deletions.
6 changes: 4 additions & 2 deletions nrf_802154/doc/CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ Changelog
All notable changes to this project are documented in this file.
See also :ref:`nrf_802154_limitations` for permanent limitations.

Main branch - nRF 802.15.4 Radio Driver
***************************************
nRF Connect SDK v2.6.0 - nRF 802.15.4 Radio Driver
**************************************************

Notable changes
===============

* Added the :c:func:`nrf_802154_rx_on_when_idle_set` function which allows to choose between the receive and sleep states during radio idle periods. (KRKNWK-17962)
* Added a safeguard in the :c:func:`nrf_802154_delayed_trx_receive` to disallow scheduling of two delayed reception windows with the same value of ``id`` parameter. (KRKNWK-18263)
* The encryption module for the nRF52 and nRF53 series' SoCs based on the ECB peripheral uses the :c:func:`nrf_802154_sl_ecb_block_encrypt` function. (KRKNWK-18576)
The :c:func:`nrf_802154_sl_ecb_block_encrypt` provided by the closed-source SL uses :ref:`mpsl` to share the ECB peripheral in the multiprotocol scenario.

Added
=====
Expand Down
227 changes: 89 additions & 138 deletions nrf_802154/driver/src/nrf_802154_aes_ccm_acc_ecb.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,10 @@
#include "nrf_802154_assert.h"
#include <string.h>

#include "hal/nrf_ecb.h"
#include "nrf_802154_const.h"
#include "nrf_802154_config.h"
#include "nrf_802154_tx_work_buffer.h"
#include "platform/nrf_802154_irq.h"
#include "nrf_802154_sl_ecb.h"

#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b)) ///< Leaves the minimum of the two arguments
Expand All @@ -63,6 +62,14 @@
#define NRF_802154_AES_CCM_AUTH_DATA_LENGTH_OCTET 0 // AnnnexB4.1.1b) - Position of octet for length of auth data in AddAuthData
#define NRF_802154_AES_CCM_AUTH_DATA_OCTET 2 // AnnnexB4.1.1b) - Position of octet for data of auth data in AddAuthData

#if NRF_802154_AES_CCM_BLOCK_SIZE != NRF_802154_SL_ECB_CLEARTEXT_LENGTH
#error NRF_802154_AES_CCM_BLOCK_SIZE != NRF_802154_SL_ECB_CLEARTEXT_LENGTH
#endif

#if NRF_802154_AES_CCM_BLOCK_SIZE != NRF_802154_SL_ECB_CIPHERTEXT_LENGTH
#error NRF_802154_AES_CCM_BLOCK_SIZE != NRF_802154_SL_ECB_CLEARTEXT_LENGTH
#endif

/**
* @brief Steps of AES-CCM* algorithm.
*/
Expand Down Expand Up @@ -90,7 +97,6 @@ static uint8_t m_m[NRF_802154_AES_CCM_BLOCK_SIZE];
static uint8_t m_a[NRF_802154_AES_CCM_BLOCK_SIZE]; ///< A[i] octet for Encryption Transformation - Annex B4.1.3 b)
static ccm_state_t m_state; ///< State of AES-CCM* transformation
static uint8_t m_auth_tag[MIC_128_SIZE]; ///< Authorization Tag
static bool m_initialized; ///< Flag that indicates whether the module has been initialized.
static uint8_t * mp_ciphertext; ///< Pointer to ciphertext destination buffer.
static uint8_t * mp_work_buffer; ///< Pointer to work buffer that stores the frame being transformed.

Expand All @@ -100,46 +106,22 @@ static const uint8_t m_mic_size[] = { 0, MIC_32_SIZE, MIC_64_SIZE, MIC_128_SIZE
/******************************************************************************/
/******************************************************************************/

static uint8_t m_ecb_data[48]; ///< ECB data structure for RNG peripheral to access.
static uint8_t * mp_ecb_key; ///< Key: Starts at ecb_data
static uint8_t * mp_ecb_cleartext; ///< Cleartext: Starts at ecb_data + 16 bytes.
static uint8_t * mp_ecb_ciphertext; ///< Ciphertext: Starts at ecb_data + 32 bytes.
static nrf_802154_sl_ecb_data_t m_ecb_hal_data;
static bool m_ecb_hal_req_run;

static void nrf_ecb_init(void)
static inline uint8_t * ecb_hal_cleartext_ptr_get(void)
{
mp_ecb_key = m_ecb_data;
mp_ecb_cleartext = m_ecb_data + 16;
mp_ecb_ciphertext = m_ecb_data + 32;

nrf_ecb_data_pointer_set(NRF_ECB, m_ecb_data);
return (uint8_t *)m_ecb_hal_data.cleartext;
}

static void nrf_ecb_set_key(const uint8_t * p_key)
static inline uint8_t * ecb_hal_ciphertext_ptr_get(void)
{
memcpy(mp_ecb_key, p_key, 16);
return (uint8_t *)m_ecb_hal_data.ciphertext;
}

static void ecb_irq_handler(void);

/**
* @brief Initializes the ECB peripheral.
*/
static void ecb_init(void)
static void ecb_hal_key_set(const uint8_t * p_key)
{
if (!m_initialized)
{
nrf_802154_irq_init(nrfx_get_irq_number(NRF_ECB), NRF_802154_ECB_PRIORITY, ecb_irq_handler);
m_initialized = true;
}

// TODO: ensure ECB initialization is handled by zephyr
// TODO: what about ECB initialization in baremetal scenario?
nrf_ecb_init();

nrf_802154_irq_clear_pending(nrfx_get_irq_number(NRF_ECB));
nrf_802154_irq_enable(nrfx_get_irq_number(NRF_ECB));
nrf_ecb_int_enable(NRF_ECB, NRF_ECB_INT_ENDECB_MASK);
nrf_ecb_int_enable(NRF_ECB, NRF_ECB_INT_ERRORECB_MASK);
memcpy(m_ecb_hal_data.key, p_key, NRF_802154_SL_ECB_KEY_LENGTH);
}

/******************************************************************************/
Expand Down Expand Up @@ -316,9 +298,11 @@ static bool plain_text_data_get(const nrf_802154_aes_ccm_data_t * p_frame,
static inline void process_ecb_auth_iteration(void)
{
m_state.iteration++;
two_blocks_xor(mp_ecb_ciphertext, m_b, NRF_802154_AES_CCM_BLOCK_SIZE);
memcpy(mp_ecb_cleartext, mp_ecb_ciphertext, NRF_802154_AES_CCM_BLOCK_SIZE);
nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STARTECB);
two_blocks_xor(ecb_hal_ciphertext_ptr_get(), m_b, NRF_802154_AES_CCM_BLOCK_SIZE);
memcpy(ecb_hal_cleartext_ptr_get(),
ecb_hal_ciphertext_ptr_get(),
NRF_802154_AES_CCM_BLOCK_SIZE);
m_ecb_hal_req_run = true;
}

/**
Expand All @@ -327,16 +311,16 @@ static inline void process_ecb_auth_iteration(void)
static inline void process_ecb_encrypt_iteration(void)
{
ai_format(&m_aes_ccm_data, m_state.iteration, m_a);
memcpy(mp_ecb_cleartext, m_a, NRF_802154_AES_CCM_BLOCK_SIZE);
nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STARTECB);
memcpy(ecb_hal_cleartext_ptr_get(), m_a, NRF_802154_AES_CCM_BLOCK_SIZE);
m_ecb_hal_req_run = true;
}

/**
* @brief helper function for plain text encryption in ECB IRQ
*/
static void perform_plain_text_encryption(void)
{
memcpy(m_auth_tag, mp_ecb_ciphertext, m_mic_size[m_aes_ccm_data.mic_level]);
memcpy(m_auth_tag, ecb_hal_ciphertext_ptr_get(), m_mic_size[m_aes_ccm_data.mic_level]);

m_state.iteration = 0;
m_state.transformation = PLAIN_TEXT_ENCRYPT;
Expand Down Expand Up @@ -377,99 +361,72 @@ static void transformation_finished(void)
m_aes_ccm_data.raw_frame = NULL;
}

/**
* @brief Handler to ECB Interrupt Routine
* Performs AES-CCM* calculation in pipeline
*/
static void ecb_irq_handler(void)
static void ecb_hal_block_encrypted_handler(void)
{
uint8_t len = 0;
uint8_t offset;

if (nrf_ecb_int_enable_check(NRF_ECB, NRF_ECB_INT_ENDECB_MASK) &&
nrf_ecb_event_check(NRF_ECB, NRF_ECB_EVENT_ENDECB))
switch (m_state.transformation)
{
nrf_ecb_event_clear(NRF_ECB, NRF_ECB_EVENT_ENDECB);

switch (m_state.transformation)
{
case ADD_AUTH_DATA_AUTH:
if (add_auth_data_get(&m_aes_ccm_data, m_state.iteration, m_b))
{
process_ecb_auth_iteration();
}
else
{
m_state.iteration = 0;
m_state.transformation = PLAIN_TEXT_AUTH;
perform_plain_text_authorization();
}
break;

case PLAIN_TEXT_AUTH:
case ADD_AUTH_DATA_AUTH:
if (add_auth_data_get(&m_aes_ccm_data, m_state.iteration, m_b))
{
process_ecb_auth_iteration();
}
else
{
m_state.iteration = 0;
m_state.transformation = PLAIN_TEXT_AUTH;
perform_plain_text_authorization();
break;

case PLAIN_TEXT_ENCRYPT:
two_blocks_xor(m_m, mp_ecb_ciphertext, NRF_802154_AES_CCM_BLOCK_SIZE);

offset = (m_state.iteration - 1) * NRF_802154_AES_CCM_BLOCK_SIZE;
len = MIN(m_aes_ccm_data.plain_text_data_len - offset,
NRF_802154_AES_CCM_BLOCK_SIZE);
memcpy(mp_ciphertext + offset, m_m, len);
if (plain_text_data_get(&m_aes_ccm_data, m_state.iteration, m_m))
}
break;

case PLAIN_TEXT_AUTH:
perform_plain_text_authorization();
break;

case PLAIN_TEXT_ENCRYPT:
two_blocks_xor(m_m, ecb_hal_ciphertext_ptr_get(), NRF_802154_AES_CCM_BLOCK_SIZE);

offset = (m_state.iteration - 1) * NRF_802154_AES_CCM_BLOCK_SIZE;
len = MIN(m_aes_ccm_data.plain_text_data_len - offset,
NRF_802154_AES_CCM_BLOCK_SIZE);
memcpy(mp_ciphertext + offset, m_m, len);
if (plain_text_data_get(&m_aes_ccm_data, m_state.iteration, m_m))
{
m_state.iteration++;
process_ecb_encrypt_iteration();
}
else
{
if (m_mic_size[m_aes_ccm_data.mic_level] != 0)
{
m_state.iteration++;
m_state.iteration = 0;
m_state.transformation = CALCULATE_ENCRYPTED_TAG;
process_ecb_encrypt_iteration();
}
else
{
if (m_mic_size[m_aes_ccm_data.mic_level] != 0)
{
m_state.iteration = 0;
m_state.transformation = CALCULATE_ENCRYPTED_TAG;
process_ecb_encrypt_iteration();
}
else
{
transformation_finished();
}
transformation_finished();
}
break;

case CALCULATE_ENCRYPTED_TAG:
two_blocks_xor(m_auth_tag,
mp_ecb_ciphertext,
m_mic_size[m_aes_ccm_data.mic_level]);
memcpy(mp_work_buffer +
(mp_work_buffer[PHR_OFFSET] - FCS_SIZE -
m_mic_size[m_aes_ccm_data.mic_level] +
PHR_SIZE),
m_auth_tag,
m_mic_size[m_aes_ccm_data.mic_level]);
transformation_finished();
break;

default:
break;
}
}

if (nrf_ecb_int_enable_check(NRF_ECB, NRF_ECB_INT_ERRORECB_MASK) &&
nrf_ecb_event_check(NRF_ECB, NRF_ECB_EVENT_ERRORECB))
{
/*
* It is possible that the ERRORECB event is caused by the
* AAR and CCM peripherals, which share the same hardware resources.
* At this point it is assumed, that ECB, AAR and CCM peripherals
* are not used by anything, except the 802.15.4 driver and
* other MPSL clients and thus it is impossible that ECB was aborted
* for any other reason, than the TX failed event caused by a terminated
* 802.15.4 transmit operation or end of timeslot.
*
* Therefore no action is taken in this handler.
*/
nrf_ecb_event_clear(NRF_ECB, NRF_ECB_EVENT_ERRORECB);
}
break;

case CALCULATE_ENCRYPTED_TAG:
two_blocks_xor(m_auth_tag,
ecb_hal_ciphertext_ptr_get(),
m_mic_size[m_aes_ccm_data.mic_level]);
memcpy(mp_work_buffer +
(mp_work_buffer[PHR_OFFSET] - FCS_SIZE -
m_mic_size[m_aes_ccm_data.mic_level] +
PHR_SIZE),
m_auth_tag,
m_mic_size[m_aes_ccm_data.mic_level]);
transformation_finished();
break;

default:
break;
}
}

Expand All @@ -478,11 +435,18 @@ static void ecb_irq_handler(void)
*/
static void start_ecb_auth_transformation(void)
{
memcpy((uint8_t *)nrf_ecb_data_pointer_get(NRF_ECB) + 16, m_x, 16);
ecb_hal_key_set(m_aes_ccm_data.key);
memcpy(ecb_hal_cleartext_ptr_get(), m_x, NRF_802154_SL_ECB_CLEARTEXT_LENGTH);
m_state.iteration = 0;
m_state.transformation = ADD_AUTH_DATA_AUTH;
nrf_ecb_event_clear(NRF_ECB, NRF_ECB_EVENT_ENDECB);
nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STARTECB);
m_ecb_hal_req_run = true;

while (m_ecb_hal_req_run)
{
m_ecb_hal_req_run = false;
nrf_802154_sl_ecb_block_encrypt(&m_ecb_hal_data);
ecb_hal_block_encrypted_handler();
}
}

void nrf_802154_aes_ccm_transform_reset(void)
Expand Down Expand Up @@ -554,9 +518,6 @@ void nrf_802154_aes_ccm_transform_start(uint8_t * p_frame)
b0_format(&m_aes_ccm_data, auth_flags, p_b);

two_blocks_xor(p_x, p_b, NRF_802154_AES_CCM_BLOCK_SIZE);
ecb_init();
memset(mp_ecb_key, 0, 48);
nrf_ecb_set_key(m_aes_ccm_data.key);
start_ecb_auth_transformation();
}

Expand All @@ -568,16 +529,6 @@ void nrf_802154_aes_ccm_transform_abort(uint8_t * p_frame)
return;
}

/*
* Temporarily disable ENDECB interrupt, trigger STOPECB task
* to stop encryption in case it is still running and clear
* the ENDECB event in case the encryption has completed.
*/
nrf_ecb_int_disable(NRF_ECB, NRF_ECB_INT_ENDECB_MASK);
nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STOPECB);
nrf_ecb_event_clear(NRF_ECB, NRF_ECB_EVENT_ENDECB);
nrf_ecb_int_enable(NRF_ECB, NRF_ECB_INT_ENDECB_MASK);

m_aes_ccm_data.raw_frame = NULL;
}

Expand Down
Loading

0 comments on commit b53a685

Please sign in to comment.