Encrypted communication on Sparrow v4

Velciu Veronica-Mihaela - AAC

Introduction

Nowadays, security becomes a great concern, as the devices start to process more and more sensitive data, leading to an increased number of attacks. The nodes in an wireless sensors network usually collect environment-related information and then send the data to a gateway, in order to be processed. There might be cases when the collected information leaks sensitive user data, so encrypting the communication would be a good practice is this cases. This project proposes and implements a method of securing the radio communication using symmetric cryptography on Sparrow v4 nodes.

ATmega128RFA1 Security module

The security module (AES) is characterized by:

  • Hardware accelerated encryption and decryption;
  • Compatible with AES-128 standard (128 bit key and data block size);
  • ECB (encryption/decryption) mode and CBC (encryption) mode support;
  • Stand-alone operation, independent of other blocks;
  • Uses 16MHz crystal clock of the transceiver;

Controlling the security block is possible over 5 Registers within AVR I/O space:

  • AES_STATUS - AES status register
  • AES_CTRL - AES control register
  • AES_KEY - Access to 16 Byte key buffer
  • AES_STATE - Access to 16 Byte data buffer

The use of the security module requires a configuration of the security engine before starting a security operation. The following steps are required:

  1. Key Setup - Write encryption or decryption key to KEY buffer (16 consecutive byte writes to AES_KEY)
  2. AES configuration:
    • Select AES mode: ECB or CBC
    • Select encryption or decryption
    • Enable the AES Encryption Ready Interrupt AES_READY, if needed
  3. Write Data - Write plain text or cipher text to DATA buffer (16 consecutive byte writes to AES_STATE)
  4. Start operation - Start AES operation
  5. Wait until AES encryption/decryption is finished: AES_READY IRQ or polling AES_DONE bit (register AES_STATUS)
  6. Read Data - Read cipher text or plain text from DATA buffer (16 consecutive byte reads from AES_STATE)

AES library

In order to make use of the Security module presented in the previous section, I implemented a driver exposed as an Arduino library named AES. The library has the following interface:

void encryptECB(uint8_t *key, uint8_t *plaintext, uint8_t len, uint8_t *ciphertext);

This function encrypts (using AES in ECB mode) len bytes of the plaintext buffer using the given key and writes the result to the ciphertext buffer.

void decryptECB(uint8_t *key, uint8_t *ciphertext, uint8_t len, uint8_t *plaintext);

This function decrypts (using AES in ECB mode) len bytes of the ciphertext buffer using the given key and writes the result to the plaintext buffer.

void encryptCBC(uint8_t *key, uint8_t *iv, uint8_t *plaintext, uint8_t len, uint8_t *ciphertext);

This function encrypts (using AES in CBC mode) len bytes of the plaintext buffer using the given key and writes the result to the ciphertext buffer.

As it can be observed, there is no function for AES in CBC mode decryption. This is due to the lack of support in the ATmega128RFA1 Security Module for this functionality.

Testing the AES library

In order to test the implemented interface, I created 6 tests:

  1. Encryption of a single block using ECB mode:
    • Plain text: 00000000000000000000000000000000
    • Key: 00000000000000000000000000000000
    • Cipher text: 66e94bd4ef8a2c3b884cfa59ca342b2e
  2. Decryption of a single block using ECB mode:
    • Cipher text: 66e94bd4ef8a2c3b884cfa59ca342b2e
    • Key: 00000000000000000000000000000000
    • Plain text: 00000000000000000000000000000000
  3. Encryption of a single block using CBC mode:
    • Plain text: 00000000000000000000000000000000
    • Key: 00000000000000000000000000000000
    • IV: 00000000000000000000000000000000
    • Cipher text: 66e94bd4ef8a2c3b884cfa59ca342b2e
  4. Encryption of two blocks using ECB mode:
    • Plain text: 000102030405060708090a0b0c0d0e0f 101112131415161718191a1b1c1d1e1f
    • Key: 000102030405060708090a0b0c0d0e0f
    • Cipher text: 0a940bb5416ef045f1c39458c653ea5a 07feef74e1d5036e900eee118e949293
  5. Decryption of two blocks using ECB mode:
    • Plain text: 0a940bb5416ef045f1c39458c653ea5a 07feef74e1d5036e900eee118e949293
    • Key: 000102030405060708090a0b0c0d0e0f
    • Cipher text: 000102030405060708090a0b0c0d0e0f 101112131415161718191a1b1c1d1e1f
  6. Encryption of two blocks using CBC mode:
    • Plain text: 000102030405060708090a0b0c0d0e0f 101112131415161718191a1b1c1d1e1f
    • Key: 000102030405060708090a0b0c0d0e0f
    • IV: 66e94bd4ef8a2c3b884cfa59ca342b2e
    • Cipher text: c58522244df6eff9c84cf1f84ec8609a 8de9747eb509687e1337028614be3893

The test vectors were generated using an AES online encryption tool.

Encrypted communication

The encrypted communication was implemented by extending the SparrowTransfer library with two functions:

void sendEncData(uint8_t* key);
uint8_t receiveEncData(uint8_t *key);

The sendEncData function receives a key as first parameter, which will be used in order to encrypt the data prior to sending it. The implementation follows these steps:

  1. Set the header and the size of the message. Please note that the size represents a multiple of 16 bytes (as this is the size of the AES encryption block).
  2. Copy the data structure to be sent to a message buffer.
  3. Pad the message buffer with 0, until its length is a multiple of 16.
  4. Encrypt the payload of the message using encryptECB with the given key (the header and the size are not encrypted in order to keep the receive functionality).
  5. Compute and add the checksum to the message.
  6. Send the message.

The receiveEncData function receives a key as first parameter, which will be used in order to decrypt the payload of the incoming message. The implementation follows these steps:

  1. Continue reading bytes until the header is encountered.
  2. Read the size of the message and check that it corresponds to the size needed for the data structure to be encrypted (the first number greater than the size which is also a multiple of 16).
  3. Continue reading byte by byte until the payload is received.
  4. Receive the checksum and check it.
  5. Decrypt the message by using decryptECB with the give key and save the plain text to the user data structure.

Testing the encrypted communication

In order to demonstrate the implemented functionality, I created three Arduino projects:

  • EncTransmitter: Sends encrypted messages using the sendEncData function and a hard-coded key.
  • EncReceiver: Receives encrypted messages using the receiveEncData function and the same key.
  • BadReceiver: “The bad guy” - Tries to listen to what the other two nodes talk. Receives messages using the receiveData function, as he does not know the secret key.

 Encrypted communication

Results

The below picture shows the output of the implemented project. In the upper left corner you can see the output of EncTransmitter and in the upper right the output of EncReceiver. Below them is the attacker, represented by the BadReceiver project.

Resources

iothings/proiecte/2017/encrypted-communication.txt · Last modified: 2021/12/06 18:26 by dan.tudose
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0