Microchip® Advanced Software Framework

Quick Start Guide for AES - Basic

The supported board list:

  • SAM L21 Xplained Pro
  • SAM L22 Xplained Pro

This example demonstrates how to use the AES driver to perform:

  • ECB encryption and decryption

Upon startup, the program uses the USART driver to display application output message from which ECB encryption/decryption modes can be tested.

Quick Start

Prerequisites

There are no prerequisites for this use case.

Code

Add to the main application source file, outside of any functions:

#define AES_EXAMPLE_REFBUF_SIZE 4
/* @{ */
0xe2bec16b,
0x969f402e,
0x117e3de9,
0x2a179373
};
0xb47bd73a,
0x60367a0d,
0xf3ca9ea8,
0x97ef6624
};
const uint32_t key128[4] = {
0x16157e2b,
0xa6d2ae28,
0x8815f7ab,
0x3c4fcf09
};
/* @} */

Add to the main application source file, outside of any functions:

/* Output data array */
/* State indicate */
volatile bool state = false;
/* AES configuration */
/* AES instance*/
struct aes_module aes_instance;

Copy-paste the following setup code to your user application:

static void configure_usart(void)
{
struct usart_config config_usart;
usart_get_config_defaults(&config_usart);
config_usart.baudrate = 38400;
config_usart.mux_setting = EDBG_CDC_SERCOM_MUX_SETTING;
config_usart.pinmux_pad0 = EDBG_CDC_SERCOM_PINMUX_PAD0;
config_usart.pinmux_pad1 = EDBG_CDC_SERCOM_PINMUX_PAD1;
config_usart.pinmux_pad2 = EDBG_CDC_SERCOM_PINMUX_PAD2;
config_usart.pinmux_pad3 = EDBG_CDC_SERCOM_PINMUX_PAD3;
stdio_serial_init(&usart_instance, EDBG_CDC_MODULE, &config_usart);
}
static void ecb_mode_test(void)
{
printf("\r\n-----------------------------------\r\n");
printf("- 128bit cryptographic key\r\n");
printf("- ECB cipher mode\r\n");
printf("- Auto start mode\r\n");
printf("- 4 32bit words\r\n");
printf("-----------------------------------\r\n");
state = false;
/* Configure the AES. */
g_aes_cfg.lod = false;
/* Set the cryptographic key. */
/* The initialization vector is not used by the ECB cipher mode. */
/* Write the data to be ciphered to the input data registers. */
/* Wait for the end of the encryption process. */
}
if ((ref_cipher_text_ecb[0] != output_data[0]) ||
(ref_cipher_text_ecb[1] != output_data[1]) ||
(ref_cipher_text_ecb[2] != output_data[2]) ||
(ref_cipher_text_ecb[3] != output_data[3])) {
printf("\r\nKO!!!\r\n");
} else {
printf("\r\nOK!!!\r\n");
}
printf("\r\n-----------------------------------\r\n");
printf("- 128bit cryptographic key\r\n");
printf("- ECB decipher mode\r\n");
printf("- Auto start mode\r\n");
printf("- 4 32bit words\r\n");
printf("-----------------------------------\r\n");
state = false;
/* Configure the AES. */
g_aes_cfg.lod = false;
/* Set the cryptographic key. */
/* The initialization vector is not used by the ECB cipher mode. */
/* Write the data to be deciphered to the input data registers. */
aes_write_input_data(&aes_instance, ref_cipher_text_ecb);
/* Wait for the end of the decryption process. */
while (!(aes_get_status(&aes_instance) & AES_ENCRYPTION_COMPLETE)) {
}
/* check the result. */
if ((ref_plain_text[0] != output_data[0]) ||
(ref_plain_text[1] != output_data[1]) ||
(ref_plain_text[2] != output_data[2]) ||
(ref_plain_text[3] != output_data[3])) {
printf("\r\nKO!!!\r\n");
} else {
printf("\r\nOK!!!\r\n");
}
}

Add to user application initialization (typically the start of main()):

Workflow

  1. Define sample data from NIST-800-38A appendix F for ECB mode.
    #define AES_EXAMPLE_REFBUF_SIZE 4
    /* @{ */
    uint32_t ref_plain_text[AES_EXAMPLE_REFBUF_SIZE] = {
    0xe2bec16b,
    0x969f402e,
    0x117e3de9,
    0x2a179373
    };
    uint32_t ref_cipher_text_ecb[AES_EXAMPLE_REFBUF_SIZE] = {
    0xb47bd73a,
    0x60367a0d,
    0xf3ca9ea8,
    0x97ef6624
    };
    const uint32_t key128[4] = {
    0x16157e2b,
    0xa6d2ae28,
    0x8815f7ab,
    0x3c4fcf09
    };
    /* @} */
  2. Create related module variable and software instance structure.
    /* Output data array */
    static uint32_t output_data[AES_EXAMPLE_REFBUF_SIZE];
    /* State indicate */
    volatile bool state = false;
    /* AES configuration */
    /* AES instance*/
    struct aes_module aes_instance;
  3. Configure, initialize, and enable AES module.
    1. Configuration AES struct, which can be filled out to adjust the configuration of a physical AES peripheral.
    2. Initialize the AES configuration struct with the module's default values.
    3. Enable the AES module.

Use Case

Code

Copy-paste the following code to your user application:

/* Run ECB mode test*/

Workflow

  1. Configure ECB mode encryption and run test.
    state = false;
    /* Configure the AES. */
    g_aes_cfg.lod = false;
    /* Set the cryptographic key. */
    /* The initialization vector is not used by the ECB cipher mode. */
    /* Write the data to be ciphered to the input data registers. */
    /* Wait for the end of the encryption process. */
    while (!(aes_get_status(&aes_instance) & AES_ENCRYPTION_COMPLETE)) {
    }
    if ((ref_cipher_text_ecb[0] != output_data[0]) ||
    (ref_cipher_text_ecb[1] != output_data[1]) ||
    (ref_cipher_text_ecb[2] != output_data[2]) ||
    (ref_cipher_text_ecb[3] != output_data[3])) {
    printf("\r\nKO!!!\r\n");
    } else {
    printf("\r\nOK!!!\r\n");
    }
  2. Configure ECB mode decryption and run test.
    state = false;
    /* Configure the AES. */
    g_aes_cfg.lod = false;
    /* Set the cryptographic key. */
    /* The initialization vector is not used by the ECB cipher mode. */
    /* Write the data to be deciphered to the input data registers. */
    aes_write_input_data(&aes_instance, ref_cipher_text_ecb);
    /* Wait for the end of the decryption process. */
    while (!(aes_get_status(&aes_instance) & AES_ENCRYPTION_COMPLETE)) {
    }
    /* check the result. */
    if ((ref_plain_text[0] != output_data[0]) ||
    (ref_plain_text[1] != output_data[1]) ||
    (ref_plain_text[2] != output_data[2]) ||
    (ref_plain_text[3] != output_data[3])) {
    printf("\r\nKO!!!\r\n");
    } else {
    printf("\r\nOK!!!\r\n");
    }