Functions

AES encryption
[Libraries (LIB)]


Example implementation for encrypting/decrypting data.

The encryption is based on AES counter mode (CTR) where a 128 bit hybrid counter is used for encryption/decryption. The counter is split in two, 11 bytes as MS11B and 5 bytes as LS5B. The LS5B part is not secret and tells the receiver how to decrypt an encrypted message.

The library is customized for low report rate data communication, such as a keyboard or remote control. When using this library, the 5 byte part (LS5B) of the counter should be transmitted in plain text along with the encrypted data. On the receive side the encrypted data should simply be decrypted using the received plain text LS5B counter (in addition to the secret cipher key). This concept will eliminate any issue related to the counters on the receiver and transmitter becoming unsynchronized, and still maintain the data pattern supression properties of the CTR AES mode. As long as a relatively low packet rate is maintained, the added data overhead due to the 5 byte counter will in any case be ignorable.

Note that the security of the link will not be reduced as a consequence of sending the counter value in plain text as long as the following criteria are met:

encryption_figs.png

The library can be used on both nRF24LU1 and nRF24LE1 devices, but the implementation is slightly different between these. In the nRF24LE1 implementation the LS5B is not a counter, but random values generated by the embedded random number generator. The reason for this is that the counter value would have to be stored in data memory in between each packet, which is not possible when residing in "deep sleep" power save mode.

Functions

void lib_crypt_init (uint8_t *key, const uint8_t *init_counter)
void lib_crypt_set_counter (const uint8_t *counter)
void lib_crypt (uint8_t *dest_buf, const uint8_t *src_buf, uint8_t length, const uint8_t *ls5b_value)
void lib_crypt_generate_ls5b (uint8_t *dest_buf)

Function Documentation

void lib_crypt_init ( uint8_t *  key,
const uint8_t *  init_counter 
)

Initialize the encryption/decryption library. This function will set up the underlying AES encryption module with correct mode and set the encryption key.

Parameters:
keysets the encryption/decryption key (16 Bytes)
init_countersets the encryption counter (16 Bytes)

Definition at line 39 of file lib_crypt.c.

{
    hal_aes_setup(false, ECB, key, NULL);

    if(init_counter)
    {
        lib_crypt_set_counter(init_counter);
    }
}
void lib_crypt_set_counter ( const uint8_t *  counter )

This function is used to set a new counter value.

Remarks:
The counter should be changed before lib_crypt(..) function has been called: 2^40 = 1'099'511'627'776 times.
Parameters:
counterThe 16 byte counter to use.

Definition at line 49 of file lib_crypt.c.

{
    uint8_t i;
    for(i=0;i<16;i++)
    {
        aes_counter[i] = counter[i];
    }
}
void lib_crypt ( uint8_t *  dest_buf,
const uint8_t *  src_buf,
uint8_t  length,
const uint8_t *  ls5b_value 
)

This function is used to encrypt or decrypt data. It is possible to encrypt or decrypt data-blocks by as many as 16 bytes. If more data needs to be encrypted or decrypted this function needs to be used multiple times.

Remarks:
This function can only encrypt up to 16 bytes.

[Encryption] Each encryption needs to be encrypted with a unique LS5B value. A new value can be generated by using the lib_crypt_generate_ls5b() function.

See also:
lib_crypt_generate_ls5b();

[Decryption] To decrypt it is required to specify the LS5B value which was used to encrypt the data. This value should be provided together with the encrypted data.

[Param]

Parameters:
src_bufWhere to find data to encrypt/decrypt
dest_bufWhere to put the encrypted/decrypted result
lengthThe length of the data to be encrypted (max 16 Bytes)
ls5b_valueThe the least significant 5 bytes of the counter used for encryption or decryption.

Definition at line 58 of file lib_crypt.c.

{
    uint8_t i;
  uint8_t encr_buffer[16];   //AES buffer. Needed to do XOR

  //Set LS5B
    for(i=0;i<5;i++)
    {
        aes_counter[i] = ls5b_value[i];
    }   

  //Run AES with aes_counter
    hal_aes_crypt(encr_buffer,aes_counter);
    
  //Encrypt data, based on XOR operation in AES counter mode.
    for(i=0;i<length; i++)
    {
        dest_buf[i] = src_buf[i] ^ encr_buffer[i];
    }
}
void lib_crypt_generate_ls5b ( uint8_t *  dest_buf )

This function is used to generate a new LS5B value (5 bytes) used to encrypt data. This function should be called before using lib_crypt() to encrypt data.

See also:
lib_crypt();
Parameters:
dest_bufwhere to put the new ls5b-value (5 bytes).

Definition at line 22 of file lib_crypt_le1.c.

{ 
  uint8_t i; 
  hal_rng_power_up(true);

  for(i=0;i<5;i++)
    {   
    while(!hal_rng_data_ready())
    {}  
    dest_buf[i] = hal_rng_read();
    } 
  
  hal_rng_power_up(false);
}