Skip to content

polfosol/micro-AES

Repository files navigation

µAES

A minimalist ANSI-C compatible API for the AES encryption and block cipher modes.

this C version License

This is a highly flexible, small and portable implementation of most of the AES related algorithms.

Features

  • Comprehensive — supports all standard AES key sizes (128, 192 and 256 bits) along with almost every block-cipher mode.

    All popular (and some unpopular) block ciphering modes of the AES are implemented in this library, such as ECB, CBC, CFB, OFB, CTR, GCM, CCM, XTS, KW (KWA), OCB, EAX /EAX', SIV, GCM-SIV, FPE (FF1 /FF3-1), and furthermore, authentication APIs for CMAC and Poly1305-AES.

  • All in one — the whole implementation code is in a single C file with no external dependencies.

  • Clear and readable code — written in a layman-friendly way with lots of comments to clarify its purpose. Also the code styling is a bit different, and IMHO more eye-catching, than what you might see in other implementations.

  • Flexible — most features are controllable by macros, so that you can just pick up what you need and disable the unnecessary parts. These macros are defined in the header file and comments are added for each of them to explain what they represent. Please read those comments carefully before using the code.

  • Lightweight — the API has very little memory footprint and compiled code size. The amount of RAM used by the functions doesn't exceed a few hundred bytes in most extreme cases. Moreover, the ROM space of µAES is optimized as much as possible.

    For example if you disable all other macros and just stick with the GCM, the compiled code size with gcc -Os will be less than 2.5KB for either AES-128-GCM or AES-256-GCM. You can verify this by running:

    $ arm-none-eabi-gcc      -Os -c micro_aes.c -o arm.o
    $ avr-gcc -mmcu=atmega16 -Os -c micro_aes.c -o avr.o
    

    and checking the results with size command. See this page for more info.

    $ size arm.o
       text      data     bss     dec     hex filename
       2088         0     176    2264     8d8 arm.o
    
    $ avr-size avr.o
       text      data     bss     dec     hex filename
       2196         0     176    2372     944 avr.o
    
  • Portable — µAES is fully compliant with the ANSI-C or C89 standard which, combined with its small size and independence from external libraries, makes it a competent candidate for embedded systems and mini applications.

    You can even compile it with Tiny C Compiler:

    path/to/tcc.exe -c micro_aes.c
    path/to/tcc.exe micro_aes.c -run main.c
    
  • Fast — the encryption or decryption speed is fairly high, especially when there is no authentication. Since code simplicity and minimizing memory usage was a top priority, some functions may not look so efficient speed-wise; though faster methods are hardly portable or easy to understand. As a result, paralellization or advanced CPU optimizations are not a feature of µAES —which might affect its overall speed.

    For 32-bit CPUs a few tweaks are discussed in x86 improvements. It's worth noting that speed is not always a blessing in cryptography and sometimes slower codes turn out to be more secure. One must be wary of those speedups that make the code more susceptible to timing attacks.

Examples

See the main C file which has some example codes demonstrating how to use the API functions, along with test vectors. Also check out the /testvectors directory.

Remarks

  • First, please keep in mind that most security experts strongly warn against implementing your own version of AES—or other ciphering algorithms; AND THEY ARE ABSOLUTELY RIGHT!

    Everyone who is becoming familiar with cryptography, should first sign Jeff Moser's so-called "Foot Shooting Prevention Agreement". It's a great article if you haven't read it yet. But to save you a click and scroll, I put a copy of the contract below.

    With that in mind, I shall say that the main purpose of developing µAES was purely educational. I learned a lot during writing these codes and hope that somebody, some day, would gain a bit of knowledge from it.

  • The code is optimized for small embedded systems and 8-bit microcontrollers with limited amount of memory. So for stronger CPUs it is plausible to speed-up the code by applying some simple changes. If you are working with an 8-bit microcontroller, it is recommended to take a look at Nigel Jones' rather old article "Efficient C Code for 8-bit Microcontrollers". It contains some highly useful tips to better program such systems.

  • There are some standard encryption algorithms specifically designed for small embedded systems, that minimize the use of computational resources while maintaining a high level of security. The most prominent one is the ASCON cipher suite which recently got approved by the NIST. I have created another repository to implement those algorithms as well.

  • For the sake of simplicity, it is often assumed that the input parameters of the functions are well defined, and the user knows what they're doing. As a result, a bunch of error checks are just skipped. Obviously, this is a naive and sometimes dangerous assumption. One must be aware that in a serious application, anything can be fed into the functions and they must take all the necessary precautions for erroneous parameters.

  • µAES was originally influenced by kokke's tiny-AES library, but I have made a handful of modifications to make it smaller and more efficient.

The foot-shooting prevention agreement taken from Jeff Moser's blog


All the contents of this repository (except the ones that I didn't write!) are subject to the terms of Apache 2.0 license.

µAES

Copyright © 2022 - polfosol

In sorrowful memory of Mahsa Amini 🖤