Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4db6d4b6bb | ||
|
|
fd8027d8ba |
20
README.md
20
README.md
@@ -2,7 +2,7 @@
|
||||
|
||||
**A minimalist ANSI-C compatible API for the AES encryption and block cipher modes**.
|
||||
|
||||
[](../../ "µAES")  [](../../files/12339506/micro_aes-v1.8.0.zip "micro_aes-v1.8.0.zip") [](https://opensource.org/licenses/Apache-2.0)
|
||||
[](../../ "µAES")  [](../../files/14983350/micro_aes-v1.9.zip "micro_aes-v1.9.zip") [](https://opensource.org/licenses/Apache-2.0)
|
||||
|
||||
This is a highly flexible, small and portable implementation of most of the AES related algorithms.
|
||||
|
||||
@@ -10,7 +10,7 @@ This is a highly flexible, small and portable implementation of most of the AES
|
||||
|
||||
* <font size="4">Comprehensive</font> — 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_**](https://csrc.nist.gov/publications/detail/sp/800-38a/final "Described in NIST SP 800-38A"), [**_GCM_**](https://csrc.nist.gov/publications/detail/sp/800-38d/final "NIST SP 800-38D"), [**_CCM_**](https://csrc.nist.gov/publications/detail/sp/800-38c/final "NIST SP 800-38C"), [**_XTS_**](https://csrc.nist.gov/publications/detail/sp/800-38e/final "NIST SP 800-38E"), [**_KW_**](https://csrc.nist.gov/publications/detail/sp/800-38f/final "NIST SP 800-38F") [(_KWA_)](https://www.rfc-editor.org/rfc/rfc3394 "RFC-3394"), [**_OCB_**](https://www.rfc-editor.org/rfc/rfc7253.html "RFC-7253"), [**_EAX_**](../../files/10318260/eax.pdf "Bellare-Rogaway-Wagner paper. For more info, see wikipedia.") / [**_EAX'_**](../../files/10318265/eax-prime.pdf "It is theoretically broken and shouldn't be used. The ANSI C12.22 has not withdrawn it yet, so here we go."), [**_SIV_**](../../files/10318348/siv.pdf "You may also refer to the RFC-5297"), [**_GCM-SIV_**](https://www.rfc-editor.org/rfc/rfc8452.html "RFC-8452"), [**_FPE_** (**_FF1_** / **_FF3-1_**)](https://csrc.nist.gov/publications/detail/sp/800-38g/final "NIST SP 800-38G"), and furthermore, authentication APIs for [**_CMAC_**](https://csrc.nist.gov/publications/detail/sp/800-38b/final "NIST SP 800-38B") and [**_Poly1305-AES_**](../../files/10319003/poly1305.pdf "From D. J. Bernstein's website: cr.yp.to/mac.html").
|
||||
All popular (and some unpopular) block ciphering modes of the AES are implemented in this library, such as [**_ECB_**, **_CBC_**, **_CFB_**, **_OFB_**, **_CTR_**](https://csrc.nist.gov/publications/detail/sp/800-38a/final "Described in NIST SP 800-38A"), [**_GCM_**](https://csrc.nist.gov/publications/detail/sp/800-38d/final "NIST SP 800-38D"), [**_CCM_**](https://csrc.nist.gov/publications/detail/sp/800-38c/final "NIST SP 800-38C"), [**_XTS_**](https://csrc.nist.gov/publications/detail/sp/800-38e/final "NIST SP 800-38E"), [**_KW_**](https://csrc.nist.gov/publications/detail/sp/800-38f/final "NIST SP 800-38F") [(_KWA_)](https://www.rfc-editor.org/rfc/rfc3394 "RFC-3394"), [**_OCB_**](https://www.rfc-editor.org/rfc/rfc7253.html "RFC-7253"), [**_EAX_**](../../files/10318260/eax.pdf "Bellare-Rogaway-Wagner paper. For more info, see wikipedia.") /[**_EAX'_**](../../files/10318265/eax-prime.pdf "It is theoretically broken and shouldn't be used. The ANSI C12.22 has not withdrawn it yet, so here we go."), [**_SIV_**](../../files/10318348/siv.pdf "You may also refer to the RFC-5297"), [**_GCM-SIV_**](https://www.rfc-editor.org/rfc/rfc8452.html "RFC-8452"), [**_FPE_** (**_FF1_** /**_FF3-1_**)](https://csrc.nist.gov/publications/detail/sp/800-38g/final "NIST SP 800-38G"), and furthermore, authentication APIs for [**_CMAC_**](https://csrc.nist.gov/publications/detail/sp/800-38b/final "NIST SP 800-38B") and [**_Poly1305-AES_**](../../files/10319003/poly1305.pdf "From D. J. Bernstein's website: cr.yp.to/mac.html").
|
||||
|
||||
* <font size="4">All in one</font> — the whole implementation code is in a single C file with no external dependencies.
|
||||
|
||||
@@ -20,7 +20,7 @@ This is a highly flexible, small and portable implementation of most of the AES
|
||||
|
||||
* <font size="4">Lightweight</font> — 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 **3KB** for either _AES-128-GCM_ or _AES-256-GCM_. You can verify this by running:
|
||||
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
|
||||
@@ -28,12 +28,12 @@ This is a highly flexible, small and portable implementation of most of the AES
|
||||
and checking the results with `size` command. See [this page](https://stackoverflow.com/q/31217181/5358284) for more info.
|
||||
```
|
||||
$ size arm.o
|
||||
text data bss dec hex filename
|
||||
2092 0 176 2268 8dc 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
|
||||
2246 0 176 2422 976 avr.o
|
||||
text data bss dec hex filename
|
||||
2196 0 176 2372 944 avr.o
|
||||
```
|
||||
|
||||
* <font size="4">Portable</font> — µ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.
|
||||
@@ -55,12 +55,14 @@ See the [main C](main.c) file which has some example codes demonstrating how to
|
||||
|
||||
* 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](https://www.moserware.com/2009/09/stick-figure-guide-to-advanced.html "A stick figure guide to AES") so-called "Foot Shooting Prevention Agreement". To save you a click and scroll, I have put a copy of it below (but please follow the link and read that article if you haven't).
|
||||
Everyone who is becoming familiar with cryptography, should first sign [Jeff Moser's](https://www.moserware.com/2009/09/stick-figure-guide-to-advanced.html "A stick figure guide to AES") 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 I hope that somebody, some day, would gain a bit of knowledge from it.
|
||||
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](x86-improvements). 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](https://barrgroup.com/embedded-systems/how-to/efficient-c-code)". 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](https://csrc.nist.gov/Projects/lightweight-cryptography/finalists). I have created [another repository](../../../simple-ASCON "Simple ASCON") 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](https://github.com/kokke/tiny-AES-c) library, but I have made a handful of modifications to make it smaller and more efficient.
|
||||
|
||||
8
main.c
8
main.c
@@ -28,9 +28,7 @@ static const char
|
||||
*ecbcipher = "af1893f0fbb09a43 7f6b0fd4f4977890 7bb85cccf1e9d2e3 ebe5bae935107868"
|
||||
"c6d72cb2ca375c12 ce6b6b1141141fd0 d268d14db351d680 5aabb99427341da9",
|
||||
*k_wrapped = "031D33264E15D332 68F24EC260743EDC E1C6C7DDEE725A93 6BA814915C6762D2";
|
||||
#else /* ↓↓↓↓ zero-padded input */
|
||||
*ecbcipher = "5d00c273f8b2607d a834632dcbb521f4 697dd4ab20bb0645 32a6545e24e33ae9"
|
||||
"f545176111f93773 dbecd262841cf83b 10d145e71b772cf7 a12889cda84be795",
|
||||
#else /* AES-128, sizeof key =16 */
|
||||
#if CTS
|
||||
*cbccipher = "65c48fdf9fbd6261 28f2d8bac3f71251 75e7f4821fda0263 70011632779d7403"
|
||||
"c119ef461ac4e1bc 8a7e36bf92b3b3d1 7e9e2d298e154bc4 2d",
|
||||
@@ -38,6 +36,8 @@ static const char
|
||||
*cbccipher = "65c48fdf9fbd6261 28f2d8bac3f71251 75e7f4821fda0263 70011632779d7403"
|
||||
"7e9e2d298e154bc4 2dc7a9bc419b915d c119ef461ac4e1bc 8a7e36bf92b3b3d1",
|
||||
#endif
|
||||
*ecbcipher = "5d00c273f8b2607d a834632dcbb521f4 697dd4ab20bb0645 32a6545e24e33ae9"
|
||||
"f545176111f93773 dbecd262841cf83b 10d145e71b772cf7 a12889cda84be795",
|
||||
*xtscipher = "10f9301a157bfceb 3eb9e7bd38500b7e 959e21ba3cc1179a d7f7d7d99460e695"
|
||||
"5e8bcb177571c719 6de58ff28c381913 e7c82d0adfd90c45 ca",
|
||||
*cfbcipher = "edab3105e673bc9e b9102539a9f457bc 245c14e1bff81b5b 4a4a147c988cb0a6"
|
||||
@@ -119,7 +119,7 @@ int main()
|
||||
hex2bytes(secretKey, authKey);
|
||||
hex2bytes(iVec, iv);
|
||||
hex2bytes(plainText, input);
|
||||
#if M_RIJNDAEL
|
||||
#if MICRO_RJNDL
|
||||
hex2bytes(iVec, input + 48);
|
||||
hex2bytes(secondKey, test);
|
||||
a = AES_KEY_SIZE == 16 ? key : input + (AES___ - 192) / 2;
|
||||
|
||||
784
micro_aes.c
784
micro_aes.c
File diff suppressed because it is too large
Load Diff
10
micro_aes.h
10
micro_aes.h
@@ -2,7 +2,7 @@
|
||||
==============================================================================
|
||||
Name : micro_aes.h
|
||||
Author : polfosol
|
||||
Version : 9.9.8.4
|
||||
Version : 10
|
||||
Copyright : copyright © 2022 - polfosol
|
||||
Description : μAES ™ is a minimalist all-in-one library for AES encryption
|
||||
==============================================================================
|
||||
@@ -69,7 +69,7 @@ AES block-cipher modes of operation. The following modes can be enabled/disabled
|
||||
#endif
|
||||
|
||||
#define WTF ! (BLOCKCIPHERS | AEAD_MODES)
|
||||
#define M_RIJNDAEL WTF /* none of above; just rijndael API. dude.., why? */
|
||||
#define MICRO_RJNDL WTF /* none of above; just rijndael API. dude.., why? */
|
||||
|
||||
/**----------------------------------------------------------------------------
|
||||
Refer to the BOTTOM OF THIS DOCUMENT for some explanations about these macros:
|
||||
@@ -79,7 +79,7 @@ Refer to the BOTTOM OF THIS DOCUMENT for some explanations about these macros:
|
||||
#define AES_PADDING 0 /* standard values: (1) PKCS#7 (2) ISO/IEC7816-4 */
|
||||
#endif
|
||||
|
||||
#if ECB || CBC || XEX || KWA || M_RIJNDAEL
|
||||
#if ECB || CBC || XEX || KWA || MICRO_RJNDL
|
||||
#define DECRYPTION 1 /* rijndael decryption is NOT required otherwise. */
|
||||
#endif
|
||||
|
||||
@@ -136,7 +136,7 @@ extern "C" {
|
||||
/**----------------------------------------------------------------------------
|
||||
Encryption/decryption of a single block with Rijndael
|
||||
-----------------------------------------------------------------------------*/
|
||||
#if M_RIJNDAEL
|
||||
#if MICRO_RJNDL
|
||||
void AES_Cipher( const uint8_t* key, /* encryption/decryption key */
|
||||
const char mode, /* encrypt: 'E', decrypt: 'D' */
|
||||
const uint8_t x[16], /* input bytes (or input block) */
|
||||
@@ -459,7 +459,7 @@ The error codes and key length should be defined here for external references:
|
||||
#define ENCRYPTION_FAILURE 0x1E
|
||||
#define DECRYPTION_FAILURE 0x1D
|
||||
#define AUTHENTICATION_FAILURE 0x1A
|
||||
#define ENDED_IN_SUCCESS 0x00
|
||||
#define NO_ERROR_RETURNED 0x00
|
||||
|
||||
#if (AES___ != 256) && (AES___ != 192)
|
||||
#define AES_KEY_SIZE 16
|
||||
|
||||
30
micro_fpe.h
30
micro_fpe.h
@@ -2,7 +2,7 @@
|
||||
==============================================================================
|
||||
Name : micro_fpe.h
|
||||
Author : polfosol
|
||||
Version : 2.1.1.2
|
||||
Version : 2.1.2.0
|
||||
Copyright : copyright © 2022 - polfosol
|
||||
Description : demonstrating some sample alphabets for the FPE mode of μAES ™
|
||||
==============================================================================
|
||||
@@ -24,16 +24,16 @@
|
||||
* These strings are commonly used in ASCII-based alphabets. The declaration of
|
||||
* an alphabet must be followed by its number of characters (RADIX).
|
||||
*/
|
||||
#define DECDIGIT "0123456789"
|
||||
#define LCLETTER "abcdefghijklmnopqrstuvwxyz"
|
||||
#define UCLETTER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
#define HEXDIGIT DECDIGIT "ABCDEFabcdef"
|
||||
#define DECIMALS "0123456789"
|
||||
#define LLETTERS "abcdefghijklmnopqrstuvwxyz"
|
||||
#define ULETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
#define HEXCHARS DECIMALS "ABCDEFabcdef"
|
||||
|
||||
/**
|
||||
numbers
|
||||
*/
|
||||
#if CUSTOM_ALPHABET == 0
|
||||
#define ALPHABET DECDIGIT
|
||||
#define ALPHABET DECIMALS
|
||||
#define RADIX 10
|
||||
#endif
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
lowercase english words
|
||||
*/
|
||||
#if CUSTOM_ALPHABET == 2
|
||||
#define ALPHABET LCLETTER
|
||||
#define ALPHABET LLETTERS
|
||||
#define RADIX 26
|
||||
#endif
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
lowercase alphanumeric strings
|
||||
*/
|
||||
#if CUSTOM_ALPHABET == 3
|
||||
#define ALPHABET DECDIGIT LCLETTER
|
||||
#define ALPHABET DECIMALS LLETTERS
|
||||
#define RADIX 36
|
||||
#endif
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
the English alphabet
|
||||
*/
|
||||
#if CUSTOM_ALPHABET == 4
|
||||
#define ALPHABET UCLETTER LCLETTER
|
||||
#define ALPHABET ULETTERS LLETTERS
|
||||
#define RADIX 52
|
||||
#endif
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
base-64 encoded strings (RFC-4648), with no padding character
|
||||
*/
|
||||
#if CUSTOM_ALPHABET == 5
|
||||
#define ALPHABET UCLETTER LCLETTER DECDIGIT "+/"
|
||||
#define ALPHABET ULETTERS LLETTERS DECIMALS "+/"
|
||||
#define RADIX 64
|
||||
#endif
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
base-85 encoded strings (RFC-1924)
|
||||
*/
|
||||
#if CUSTOM_ALPHABET == 6
|
||||
#define ALPHABET DECDIGIT UCLETTER LCLETTER "!#$%&()*+-;<=>?@^_`{|}~"
|
||||
#define ALPHABET DECIMALS ULETTERS LLETTERS "!#$%&()*+-;<=>?@^_`{|}~"
|
||||
#define RADIX 85
|
||||
#endif
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
a character set with length 26, used by some test vectors
|
||||
*/
|
||||
#if CUSTOM_ALPHABET == 7
|
||||
#define ALPHABET DECDIGIT "abcdefghijklmnop"
|
||||
#define ALPHABET DECIMALS "abcdefghijklmnop"
|
||||
#define RADIX 26
|
||||
#endif
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
base-64 character set with DIFFERENT ORDERING, used by some test vectors
|
||||
*/
|
||||
#if CUSTOM_ALPHABET == 8
|
||||
#define ALPHABET DECDIGIT UCLETTER LCLETTER "+/"
|
||||
#define ALPHABET DECIMALS ULETTERS LLETTERS "+/"
|
||||
#define RADIX 64
|
||||
#endif
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
all printable ascii characters
|
||||
*/
|
||||
#if CUSTOM_ALPHABET == 9
|
||||
#define ALPHABET " !\"#$%&\'()*+,-./"DECDIGIT":;<=>?@"UCLETTER"[\\]^_`"LCLETTER"{|}~"
|
||||
#define ALPHABET " !\"#$%&\'()*+,-./"DECIMALS":;<=>?@"ULETTERS"[\\]^_`"LLETTERS"{|}~"
|
||||
#define RADIX 95
|
||||
#endif
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
* set it as a constant, or let it be calculated dynamically like this:
|
||||
*/
|
||||
#include <math.h>
|
||||
#define LOGRDX (log( RADIX ) / log( 2 )) /* log2( RADIX ) if std=C99 */
|
||||
#define LOGRDX (log( RADIX ) / log( 2 )) /* log2(RADIX) if std >= C99 */
|
||||
#if FF_X == 3
|
||||
#define MAXLEN (2 * (int) (96.000001 / LOGRDX))
|
||||
#endif
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Since µAES code is optimized for 8-bit CPUs, it might be much less efficient
|
||||
* for a 32-bit machine. We can apply a few tweaks, especially in the process of
|
||||
* mixing columns, to boost its performance on such systems. For example, here's
|
||||
* a piece of code to replace the lines #83 to #131 of "micro_aes.c" source file
|
||||
* a piece of code to replace the lines #83 to #130 of "micro_aes.c" source file
|
||||
* —starting with `#if DONT_USE_FUNCTIONS`. The endian-ness of system is crucial
|
||||
* and must be determined by appropriate macros, e.g. let BIG_ENDIAN_INTEGERS be
|
||||
* FALSE when compiling for a little-endian system and TRUE otherwise. Note that
|
||||
|
||||
Reference in New Issue
Block a user