Adding Security

This page is under construction.

CCM* on the AT86RF231

The security module works independently from other blocks on the AT86RF231. Encryption and decryption can be performed in parallel to a frame transmission or reception.

Access to the security block is not possible while the radio transceiver is in state SLEEP.
All configurations of the security module, the SRAM content and keys are reset during SLEEP or RESET states.

Steps:

  1. Configure the security key with use case AES_SET_KEY.
  2. Set the AES mode and direction with use case AES_ECB_SINGLE_BLOCK.
  3. Transfer the data for the security operation to the security engine (see for example AES_ECB_SINGLE_BLOCK).
  4. Start the security operation by setting AES_REQUEST bit at SRAM address 0x94.
  5. The processed data is stored in the SRAM address range 0x84 - 0x93.

_
When decrypting, due to the nature of AES algorithm, the initial key to be used is not the same
as the one used for encryption, but rather the last round key instead. This last round key is the
content of the key address space stored after running one full encryption cycle, and must be
saved for decryption. If the decryption key has not been saved, it has to be recomputed by first
running a dummy encryption (of an arbitrary plaintext) using the original encryption key, then
fetching the resulting round key from the key memory, and writing it back into the key memory as
the decryption key.
_

Functions and #defines needed:

trx_aes_write(AES_MODE_KEY, 0, aeskey);
#define AES_MODE_KEY   (0x10)
/**
\brief Write data from AES block.

\param [in]   cmd AES control byte (excluding start bit)
\param [in] start flag that indicates, if the start bit will be set for these transaction
\param [in] idata 16 byte data array, written to the AES block
*/

void trx_aes_write( uint8_t  cmd,
                    bool     start,
                    uint8_t* idata)
/**
\brief Write and read data from AES block simultaneously.

\param [in]    cmd AES control byte (excluding start bit)
\param [in]  start flag that indicates, if the start bit will be set for these transaction
\param [in]  idata 16 byte data array, written to the AES block
\param [out] odata 16 byte data array, read from the AES block 
*/

void trx_aes_wrrd( uint8_t  cmd,
                   bool     start,
                   uint8_t* idata,
                   uint8_t* odata)
/**
\brief Read data from AES block.

\param [in]    cmd AES control byte (excluding start bit)
\param [out] odata 16 byte data array, read from the AES block 
*/
void trx_aes_read( uint8_t  cmd,
                   uint8_t* odata)          

AES_ECB_MULTIPLE_BLOCKS

{/* AT86RF231::[ACTIVE] */
    aesctrl = AES_MODE_ECB | aesdir;
    trx_aes_write(aesctrl, 1, idata1);
    delay(t12);
    trx_aes_wrrd(aesctrl, 1, idata2, odata1);
    delay(t12);
    trx_aes_wrrd(aesctrl, 1, idata3, odata2);
    proc_other_blocks();
    delay(t12);
    trx_aes_read(aesctrl, odataN);
}
t12    AES core cycle time    µs    24 

#define AES_CTRL          (0x83) // Security module control, AES mode, SRAM address
#define AES_CTRL_MIRROR   (0x94) // mirrored version of AES_CTRL, SRAM address
#define AES_DIR_DECRYPT   (0x08) // AES core operation direction: Decryption (ECB)
#define AES_DIR_ENCRYPT   (0)    // AES core operation direction: Encryption (ECB, CBC)
#define AES_DONE          (0x01) // AES core operation status: AES core operation status
#define AES_MODE_CBC      (0x20) // Set CBC mode
#define AES_MODE_ECB      (0x0)  // Set ECB mode
#define AES_MODE_KEY      (0x10) // Set key mode
#define AES_OP_DONE       (1)    // AES core operation status: AES module finished
#define AES_OP_NOT_DONE   (0)    // AES core operation status: AES module did not finish
#define AES_REQUEST       (0x80) // Initiate an AES operation
#define AES_STATE         (0x82) // Signal status of the security module and operation, SRAM address
#define AES_STATE_KEY     (0x84) // depending on AES mode, it contains either AES key or AES state, SRAM address