emLib AES
Encrypt & decrypt data files with AES
The emLib AES module allows encryption and decryption of data using AES, the Advanced Encryption Standard as standardized by NIST in 2001. This page describes the AES API functions and shows their usage based on example code.
What is AES?
The Advanced Encryption Standard, short AES, is a symmetric-key algorithm used for encryption and decryption of data. It was established by the U.S. National Institute of Standards and Technology (NIST) and is the standard for encrypting electronic data since 2001. AES supersedes the Data Encryption Standard (DES).
AES is a substitution-permutation network block cipher using a fixed block size of 128 bits and a key size of 128, 192 or 256 bits. The data block is stored in a 4-row matrix with a cell size of 8 bits. Based on the key length, these blocks are transformed using parts of the key in a number of rounds.
AES128 uses 10 rounds, AES256 14. Therefore encryption with AES256 is ~40% slower than AES128. In each round a round key is derived from the original key. Afterwards each byte is non-linear substituted according to a lookup table, the rows of the data matrix are shifted cyclically and mixed.
emLib AES uses a key of 128 or 256 bits to encrypt a block of 16 bytes of data at a time. To optimize the performance of the algorithms the generation of the round keys can be done before the actual encryption or decryption and used more than one time.
For the substitution and mixing steps, emLib can be built with pre-calculated lookup tables, to increase the speed performance. emLib can also be built without these tables, to save memory.
AES can also be used in cipher block chaining (CBC) mode to process a multiple of 16 bytes. In CBC mode every chunk of 16 bytes is XOR linked with the result of the previous encryption (the cipher text), before being encrypted.To decrypt one block, all previous blocks have to be known.
For the encryption of the first block an initialization vector which will be linked with the block, can be used to make sure the first block cannot be brute-force decrypted by comparing it to common first data blocks.
Using emLib AES
The emLib AES module has a simple yet powerful API. It can be easily integrated into an existing application. The code is completely written in ANSI-C.
All functionality can be verified with standard test patterns using the Validation API functions. The functions for generating the tables used for higher optimization levels are also included for full transparency.
The module can be built with configurable optimizations to fit any requirement of high speed or low memory usage. To simply encrypt or decrypt data the application will only need to call one function.
If more than one block needs to be processed with the same key, a context containing the round keys calculated from the key can be prepared and directly used by the encryption and decryption functions. For more than one call of these functions this method results in a slightly higher processing speed.
Performance and Memory Footprint
The following table shows the en- and decryption speed of emLib AES128 as tested on an STM32F4:
Configuration | Speed [MB/s] | ROM usage [KB] |
---|---|---|
Fastest speed | 2.15 | 11.37 |
Default | 1.15 | 6.36 |
Smallest size | 0.50 | 2.86 |
AES Configuration
emLib AES aims for portability and is designed to fit speed and size requirements for different targets. It includes configurable defines to switch between speed and size optimizations. The values can be changed in AES_Config.h.
#define | Values | Description |
---|---|---|
OPTIMIZE_MIX_SUBST | 0 (Smallest) 1* (Fastest) | Use a 32-bit tablesaw to perform "MixColumns" and "SubBytes" at the same time. |
OPTIMIZE_MIX_COLUMNS | 0* (Smallest) 1 2 (Fastest) | Use tables for matrix multiplication. |
COPY_CONST_TO_RAM | 0* (Off - Least RAM) 1 (On - Fastest) | Copy timing critical constant data to RAM, which yields higher performance on systems where const are in (slower) flash memory. |
Options marked with * are default.
AES API Functions
The table below lists the available AES API functions.
Function | Description |
---|---|
AES128_CBC_Decrypt() | Decrypts data with AES 128 Bit using CBC. |
AES128_CBC_Encrypt() | Encrypts data with AES 128 Bit using CBC. |
AES128_Decrypt() | Decrypts 16 Bytes with AES 128 Bit. |
AES128_Encrypt() | Encrypts 16 Bytes with AES 128 Bit. |
AES128_Prepare() | Prepares the context for de-/encryption. |
AES256_CBC_Decrypt() | Decrypts data with AES 256 Bit using CBC. |
AES256_CBC_Encrypt() | Encrypts data with AES 256 Bit using CBC. |
AES256_Decrypt() | Decrypts 16 Bytes with AES 256 Bit. |
AES256_Encrypt() | Encrypts 16 Bytes with AES 256 Bit. |
AES256_Prepare() | Prepares the context for de-/encryption. |
AES_Validate() | Test function for validation of AES. |
Detailed descriptions of all functions can be found in the emLib user manual.
Example Code
AES 128bit en-/decryption of 32 Bytes using CBC
This sample shows how to encrypt and afterwards decrypt 32 bytes of data with AES and a 128 bit key using Cipher Block Chaining.
#include “AES.h”
const U8 _aKey[16] = { 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0,
0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a};
static const U8 _aIV[16] = { 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28,
0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58};
static const U8 _aPlaintext[32] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
static const U8 _aCiphertext[32] = {
0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a,
0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a,
0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9,
0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1};
int main() {
U8 aEnc[32];
U8 aPlain[32];
AES_CONTEXT Context;
//
// Prepare the context with _aKey
//
AES128_Prepare(&Context, &_aKey[0]);
//
// Encrypt the data of _aPlaintext
// and compare it with the desired result.
//
AES128_CBC_Encrypt(&Context, &aEnc[0], &_aPlaintext[0], 32, &_aIV[0]);
if (memcmp(&aEnc[0], &_aCiphertext[0], 32)) {
return -1;
}
//
// Decrypt the data of aEnc
// and compare it with the previously used _aPlaintext
//
AES128_CBC_Decrypt(&Context, &aPlain[0], &aEnc[0], 32, &_aIV[0]);
if (memcmp(&aPlain[0], &_aPlaintext[0], 32)) {
return -1;
}
return 0; // AES 128 CBC works fine.
}
Sample Applications
emLib includes some sample applications to show the modules functionality and provide an easy to use starting point for your application. The application's source code is included within the module. The following applications are included in emLib AES:
Application name | Target platform | Description |
---|---|---|
AESCrypt.exe | Windows | Commandline tool to en-/decrypt a file using AES 256. |
AESSpeedtest.exe | Windows | Console application testing the speed of emLib AES. |
AESValidate.exe | Windows | Console application validating emLib AES with standard test patterns. |
AESCrypt
AESCrypt is a windows application, encrypting and decrypting a file with the given keyword. The tool can be used to easily keep files secured.
Usage: AESCrypt <sourcefile> <password> [option]
The password can contain any character and does not have a fixed required length. The output file after encryption will have the extension ".enc". If present, the original file will be renamed to <filename>.orig, when decrypting a file with the same name.</filename>
Parameter | Description |
---|---|
<sourcefile> | Path to the file, which has to be en-/decrypted |
<password> | Password used for en-/decryption |
[option] | (optional) "-en": Force encryption of the source file. "-de": Force decryption of the source file. If no option is given, operation depends on source file extension. |
AESSpeedtest
AESSpeedtest is a windows application, testing the performance of the emLib AES algorithms.
AESValidate
AESValidate is a Windows application used to test and validate the implementation of the AES algorithms. The application uses the Validation API and compares the results of encryption and decryption with the expected results. AESValidate will show an error message, if a validation test fails.