updated readme

This commit is contained in:
polfosol
2023-08-22 17:23:53 +03:30
parent 0c9ca7ebec
commit 691d859ff4
31 changed files with 3818 additions and 1489 deletions

23
.vscode/c_cpp_properties.json vendored Normal file
View File

@@ -0,0 +1,23 @@
{
"configurations": [
{
"name": "GCC",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c89",
"cppStandard": "c++17",
"intelliSenseMode": "gcc-x64",
"compilerArgs": [
"-pedantic"
]
}
],
"version": 4
}

34
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,34 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "C/C++: gcc build and debug active file",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/bin/${fileBasenameNoExtension}.out",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
],
"preLaunchTask": "C/C++: gcc build active file"
}
]
}

28
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,28 @@
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc build active file",
"command": "gcc",
"args": [
"-fdiagnostics-color=always",
"-g",
"${workspaceFolder}/*.c",
"-o",
"${fileDirname}/bin/${fileBasenameNoExtension}.out"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Building microAES with GCC/VScode."
}
],
"version": "2.0.0"
}

View File

@@ -1,61 +1,80 @@
# µAES
# **µAES**
**A minimalist ANSI-C compatible code for most of the AES-related algorithms**.
**A minimalist ANSI-C compatible API for the AES encryption and block cipher modes**.
[![GitHub release](https://img.shields.io/static/v1?message=%C2%B5AES&logo=github&labelColor=gray&color=blue&logoColor=white&label=%20)](https://github.com/polfosol/micro-AES) ![C](https://img.shields.io/badge/langauge-C-blue.svg) [![Build Status](https://img.shields.io/badge/v1.2.0-blue)](https://github.com/polfosol/micro-AES/files/10149095/micro_aes-v1.2.0.zip) [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![here](https://img.shields.io/badge/%C2%B5AES-white.png?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAFGklEQVR42r1XA5RjSxD9Wtu2bWX2e23btm3btm17Nxpmx8zYiK3XLzO/6vz0nuxb7yQ759xJ0l1V93Z1tX762r+cnJyCFoulJnxWART5Cvu8n+n+atLShJBlgCCi1WrtsbEpbHx8CnzXQZsUsAtEVef6sSzb12w1m6FfAXgIv/tgO8MwF+C3HuAL2Avxy3ySHIynEr1eyW7dKrB37ChlW7fOBuRQ2D084sjcuXwik8mA4AAEy099IbhXlVlV/POMzqPusb2HAAltNlsjaZo0Fdp0xSYVi3wc+DgEOCZ9bNS/QMc5wucHs+3apSLZZ9GmjZ5cveoDJBLwLQm+zcOTwxN/G/VbNiBnzvk5KGAFiDzRbWs3AbYBbCmKlEywr8zlx/QdJvfvSyA4gwRfiWx240Yk8gEB5ztt7kSJTHKdXA6jb6A1apUweg22N17S2AtsH3yMfCATEhIDAU1cEjuPF0tGjhSSceP49n/+CYE2O8fGjsJ1Zp2JErVZ1UYEgq4B5q25uUaEbQhMPwjo9kHqoTGcdOoU+F7gtm0zyNOnflh0IPAQFh6OlISERENtRL1n2727ZO2NtWJKJIwQRoHtn4AonHdsKzKhSDTEiUW+9wSgIfH2DuPMr46Ni0uCvgVcB6x0VqPJYni8eGpP9u8XlZteLgiJik4oiuRhaPcs+FkYFbXo0iIhtC/CGFwBe8iMGQJnATiv2P6ZlTKdvHz5LmMmiV84kLBIVGF6hUDozzKajRn4nQp44P8A0/8CBpSHK+CJvVOnIOfCIqmpGWBY6TP7xG/Eas2A1ZKFPno/LxyplZLlH5s/Jf+Y/Jn0NwLqQ2+wGPTgW4wrQGz/448op/RroS3zI7xcv5dQlMHoQ+bP548/Oh5XgJ0S4pRg0RUcVzABfzdf1lwMPne4IykGjTFY6c7zD20qwLYvIAKLj64Ext8/qvKMyv604KA/C7DLxtiU/HB+ZKIsEX//4UxeGBqi2ePHxbipOE0Bw/bv7/01AD+5Q7QxPjYkDsgJClhxbYUIC5hOF9RES/jN4xbSHPbECTEGyDXGjRMO3DuQ75hrncagUQBxiS/N4Wpa/bmFOdA/Kt/ofFko4M+NfwphCZ5Gjh8igPz9d/DeJ3u9kRyQHZAQEA/ZbfXjBJw/74UVT/cAPAExvisFMOzAgV7s8OHcYsXtWuEv9Y6iJ+CBpwd8IP1jXSqAPH7sj2se0nqdjYjA5Wp51zdvHt9jnYfQsflkmS1mPGoLuE5Au3YpMKI4CPqrw+cZ6dFDQjcsVWxEfJ5ReQwoYPC+wXzo34l2LhMAJCpiMOC2XN7h85bufriEeWt5QiQHkISshAyr1VrLtQIAZM0aPJg2OE7ChJTU2DTy4IHEpFKo6dYL6U+HKUqksV1bhKtWYWqXQxYKAYkJDxrcanc92uWF5Ihpp6bxoe+yWwSQmzd9YeQD8HbjG+sb3XJFSzGS0ttPwfEF4+HqlQoCy7pFgF0qjYe5rYPnBpIhqRPo5XM5xnSHAAuc+wxeQOC+z+ClkiPAqNAp5Dh69wiAjQangGRmKrpv7y4oMblEhLOAdqvb4eXzEsZziwAKMnq06Ib3Nf+qs6u+LTu1bDAV4CX1wnPfw+0CEHgTZqOjEyvP+v/SUWZKGbzjBX/3+w8rm0gkEfQt8DUgly550zo4zT8twWfc9/LTLOxjMzOziL9/5NeAzcjAa5UyWZEsg88AfBe64iVcAp/fX4ka+E4AlAH8lhve/wC9phuOb7e8lwAAAABJRU5ErkJggg==)](../../ "µAES") ![C](https://img.shields.io/badge/langauge-C-blue.svg) [![version](https://img.shields.io/badge/version-1.8.0-blue)](../../files/12339506/micro_aes-v1.8.0.zip "micro_aes-v1.8.0.zip") [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
This library is a highly flexible and portable implementation of different AES encryption schemes and block cipher modes.
This is a highly flexible, small and portable implementation of most of the AES related algorithms.
## Features
* $\textrm{\textbf{Comprehensive}}$ — supports all standard AES key sizes (128, 192 and 256 bits) along with almost every block-cipher mode.
* <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), [**_GCM_**](https://csrc.nist.gov/publications/detail/sp/800-38d/final), [**_CCM_**](https://csrc.nist.gov/publications/detail/sp/800-38c/final), [**_XTS_**](https://csrc.nist.gov/publications/detail/sp/800-38e/final), [**_OCB_**](https://www.rfc-editor.org/rfc/rfc7253.html), [**_EAX_**](https://en.wikipedia.org/wiki/EAX_mode), [**_KW_** (**_KWA_**)](https://csrc.nist.gov/publications/detail/sp/800-38f/final), [**_SIV_**](https://www.rfc-editor.org/rfc/rfc5297.html), [**_GCM-SIV_**](https://www.rfc-editor.org/rfc/rfc8452.html), [**_FPE_**](https://csrc.nist.gov/publications/detail/sp/800-38g/final), and furthermore, authentication APIs for [**_CMAC_**](https://csrc.nist.gov/publications/detail/sp/800-38b/final) and [**_Poly1305-AES_**](https://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").
* $\textrm{\textbf{All in one}}$ — the whole implementation code is in a single C file with no external dependencies.
* <font size="4">All in one</font> — the whole implementation code is in a single C file with no external dependencies.
* $\textrm{\textbf{Clear and readable code}}$ — hopefully, the code is 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.
* <font size="4">Clear and readable code</font> — 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.
* $\textrm{\textbf{Flexible}}$ — many features of µAES 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 `micro_aes.h` and comments are added for each of them to explain what they represent. *Please read those comments carefully before using the code*.
* <font size="4">Flexible</font> — 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](micro_aes.h) and comments are added for each of them to explain what they represent. *Please read those comments carefully before using the code*.
* $\textrm{\textbf{Lightweight}}$ — the API has very little memory footprint and compiled code size. In my own tests, the amount of RAM used by the functions didn'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 will be around **3KB** with `gcc -Os` on x86 machine for either AES-128-GCM or AES-256-GCM.
* <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.
* $\textrm{\textbf{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. But it is worth noting that faster methods are hardly portable or easy to understand. So it's no surprise that paralellization or advanced CPU optimizations are not a feature of µAES —which will affect its overall speed.
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:
```
$ 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](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
As a side note, 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](https://en.wikipedia.org/wiki/Timing_attack).
$ avr-size avr.o
text data bss dec hex filename
2246 0 176 2422 976 avr.o
```
* $\textrm{\textbf{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.
* <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.
You can even compile it with [Tiny C Compiler](https://bellard.org/tcc/):
```
path/to/tcc.exe -c micro_aes.c
path/to/tcc.exe micro_aes.c -run main.c
```
* <font size="4">Fast</font> — 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](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](https://en.wikipedia.org/wiki/Timing_attack).
```
tcc -c main.c -o main.o
tcc -c micro_aes.c -o micro_aes.o
tcc -o micro_aes.exe main.o micro_aes.o
```
## Examples
See the `main.c` file which has some example codes illustrating how to use the API functions, along with test vectors.
See the [main C](main.c) file which has some example codes demonstrating how to use the API functions, along with test vectors. Also check out the [/testvectors](testvectors/README.md) 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](https://www.moserware.com/2009/09/stick-figure-guide-to-advanced.html) so-called "Foot Shooting Prevention Agreement". To save you a click and scroll, I have put a copy of it below (but it is recommended to 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". 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).
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.
* 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.
* 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.
* Part of µAES is palpably influenced by [kokke's tiny-AES](https://github.com/kokke/tiny-AES-c) library, but I have made some modifications to make it smaller and more efficient. I shall give kudos to their great effort which paved the way for many other branches.
* µ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.
<p align="center">
<img src="https://i.stack.imgur.com/SoY7x.png" alt="The foot-shooting prevention agreement taken from Jeff Moser's blog"/>
<img src="https://user-images.githubusercontent.com/1939363/221410529-ea6bc2ab-b44c-4a34-a617-4a2ec3d16d0f.png" alt="The foot-shooting prevention agreement taken from Jeff Moser's blog"/>
</p>
---
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](https://user-images.githubusercontent.com/1939363/223065653-57eb5da3-6826-4939-a4f8-88992731e976.png "µAES")
Copyright © 2022 - polfosol
$In$ $sorrowful$ $memory$ $of$ [**_Mahsa Amini_**](https://en.wikipedia.org/wiki/Death_of_Mahsa_Amini) :black_heart:
<font size="3" face="Georgia">_In sorrowful memory of_ [**_Mahsa Amini_**](https://en.wikipedia.org/wiki/Death_of_Mahsa_Amini "MAY ALL THE DICTATORS ROT IN HELL")</font> :black_heart:

BIN
images/header.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

1
images/logo-smooth.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 22 KiB

BIN
images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

1
images/logo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 70 KiB

BIN
images/logo.xcf Normal file

Binary file not shown.

8
images/micro_aes.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 27 KiB

626
main.c
View File

@@ -2,378 +2,396 @@
==============================================================================
Name : main.c
Author : polfosol
Version : 9.8.1.0
Version : 10
Copyright : copyright © 2022 - polfosol
Description : test vectors for µAES ™ library, mostly generated by Crypto++ ®
==============================================================================
*/
#define HEXSTR_LENGTH 114 /* plaintext hex characters */
#include "micro_aes.h"
#define TestStringSize 114 /* hex characters in plain-text */
#define BuffL ((TestStringSize / 2 + 31) & ~15)
static const char
*masterKey = "0001020304050607 08090A0B0C0D0E0F 1011121314151617 18191A1B1C1D1E1F",
*secretKey = "0011223344556677 8899AABBCCDDEEFF 0001020304050607 08090A0B0C0D0E0F",
*cipherKey = "279fb74a7572135e 8f9b8ef6d1eee003 69c4e0d86a7b0430 d8cdb78070b4c55a",
*iVec = "8ea2b7ca516745bf eafc49904b496089",
*plainText = "c9f775baafa36c25 cd610d3c75a482ea dda97ca4864cdfe0 6eaf70a0ec0d7191\
d55027cf8f900214 e634412583ff0b47 8ea2b7ca516745bf ea",
#if AES_KEY_LENGTH == 16
*ecbcipher = "5d00c273f8b2607d a834632dcbb521f4 697dd4ab20bb0645 32a6545e24e33ae9\
f545176111f93773 dbecd262841cf83b 10d145e71b772cf7 a12889cda84be795",
#if !CTS /* ↑↑ and ↓↓ both zero-padded plain text. */
*cbccipher = "65c48fdf9fbd6261 28f2d8bac3f71251 75e7f4821fda0263 70011632779d7403\
7e9e2d298e154bc4 2dc7a9bc419b915d c119ef461ac4e1bc 8a7e36bf92b3b3d1",
#else
*cbccipher = "65c48fdf9fbd6261 28f2d8bac3f71251 75e7f4821fda0263 70011632779d7403\
c119ef461ac4e1bc 8a7e36bf92b3b3d1 7e9e2d298e154bc4 2d",
#endif
*cfbcipher = "edab3105e673bc9e b9102539a9f457bc 245c14e1bff81b5b 4a4a147c988cb0a6\
3f9c56525efbe64a 876ad1d761d3fc93 59fb4f5b2354acd4 90",
*ofbcipher = "edab3105e673bc9e b9102539a9f457bc d28c8e4c92995f5c d9426926be1e775d\
e22b8ce4d0278b18 181b8bec93b9726f 959aa5d701d46102 f0",
#if CTR_IV_LENGTH == 16
*ctrcipher = "edab3105e673bc9e b9102539a9f457bc f2e2606dfa3f93c5 c51b910a89cddb67\
191a118531ea0427 97626c9bfd370426 fdf3f59158bf7d4d 43",
#elif CTR_STARTVALUE == 1
*ctrcipher = "6c6bae886c235d8c 7997d45c1bf0bca2 48b4bca9eb396d1b f6945e5b7a4fc10f\
488cfe76fd5eaeff 2b8fb469f78fa61e 285e4cf9b9aee3d0 a8",
#endif
*xtscipher = "10f9301a157bfceb 3eb9e7bd38500b7e 959e21ba3cc1179a d7f7d7d99460e695\
5e8bcb177571c719 6de58ff28c381913 e7c82d0adfd90c45 ca",
*ccmcipher = "d2575123438338d7 0b2955537fdfcf41 729870884e85af15 f0a74975a72b337d\
04d426de87594b9a be3e6dcf07f21c99 db3999f81299d302 ad1e5ba683e9039a\
5483685f1bd2c3fa 3b", /* <---- with 16 bytes tag */
*gcmcipher = "5ceab5b7c2d6dede 555a23c7e3e63274 4075a51df482730b a31485ec987ddcc8\
73acdcfc6759a47b a424d838e7c0cb71 b9a4d8f4572e2141 18c8ab284ca845c1\
4394618703cddf3a fb", /* <---- with 16 bytes tag */
*ocbcipher = "fc254896eb785b05 dd87f240722dd935 61f5a0ef6aff2eb6 5953da0b26257ed0\
d69cb496e9a0cb1b f646151aa07e629a 28d99f0ffd7ea753 5c39f440df33c988\
c55cbcc8ac086ffa 23", /* <---- with 16 bytes tag */
#if EAXP
*eaxcipher = "f516e9c20069292c c51ba8b6403ddedf 5a34798f62187f58 d723fa33573fd80b\
f08ffbb09dadbd0b 6fa4812ca4bb5e6d db9a384943b36690 e81738a7a1",
#else /* ↑↑↑↑ with 4 bytes tag */
*eaxcipher = "4e2fa1bef9ffc23f 6965ee7135981c91 af9bfe97a6b13c01 b8b99e114dda2391\
50661c618335a005 47cca55a8f22fbd5 ed5ab4b4a17d0aa3 29febd14ef271bae\
986810a504f01ec6 02", /* <---- with 16 bytes tag */
#endif
*gsvcipher = "2f1488496ada3f70 9760420ac72e5acf a977f6add4c55ac6 85f1b9dff8f381e0\
2a64bbdd64cdd778 525462949bb0b141 db908c5cfa365750 3666f879ac879fcb\
f25c15d496a1e6f7 f8", /* <---- with 16 bytes tag */
*sivcipher = "f6d8137b17d58d13 af040e8abadd965b 9bae3a3de90ca6f7 049c2528767da2cf\
ef17de85b1d07b59 d26b0595071ae428 3015840928e2c7f5 9abf06003b14b9ee\
25111d34bb2bfcc2 25", /* 16 bytes i.v. PREPENDED */
*cmac_hash = "b887df1fd8c239c3 e8a64d9822e21128",
*p1305_mac = "3175bed9bd01821a 62d4c7bef26722be",
*fpe_plain = "0123456789abcdefghi",
*wrapped = "1FA68B0A8112B447 AEF34BD8FB5A7B82 9D3E862371D2CFE5";
#elif AES_KEY_LENGTH == 24 /* ↓↓↓↓ PKCS#7 is enabled */
*ecbcipher = "af1893f0fbb09a43 7f6b0fd4f4977890 7bb85cccf1e9d2e3 ebe5bae935107868\
c6d72cb2ca375c12 ce6b6b1141141fd0 d268d14db351d680 5aabb99427341da9",
*wrapped = "031D33264E15D332 68F24EC260743EDC E1C6C7DDEE725A93 6BA814915C6762D2";
#else
*xtscipher = "40bfcc14845b1bb4 15dd13abf1e6f89d 3bfd794cf6655ffd 14c0d7e4177eeaf4\
5dd95f05663fcfb4 47671154a91b9d00 d1bd7a35c14c7410 9a",
*wrapped = "28C9F404C4B810F4 CBCCB35CFB87F826 3F5786E2D80ED326 CBC7F0E71A99F43B\
FB988B9B7A02DD21"; /* <---- it is in RFC-3394 */
#endif
#include <stdio.h>
static void check(const char* method, uint8_t* result, uint8_t* expected, size_t size)
static const char
*secretKey = "0001020304050607 08090A0B0C0D0E0F 1011121314151617 18191A1B1C1D1E1F",
*secondKey = "0011223344556677 8899AABBCCDDEEFF 0001020304050607 08090A0B0C0D0E0F",
*cipherKey = "279fb74a7572135e 8f9b8ef6d1eee003 69c4e0d86a7b0430 d8cdb78070b4c55a",
*plainText = "c9f775baafa36c25 cd610d3c75a482ea dda97ca4864cdfe0 6eaf70a0ec0d7191"
"d55027cf8f900214 e634412583ff0b47 8ea2b7ca516745bf ea",
*iVec = "8ea2b7ca516745bf eafc49904b496089",
#if AES___ == 256
*k_wrapped = "28C9F404C4B810F4 CBCCB35CFB87F826 3F5786E2D80ED326 CBC7F0E71A99F43B"
"FB988B9B7A02DD21", /* <---- p. 34 of RFC-3394 */
*xtscipher = "40bfcc14845b1bb4 15dd13abf1e6f89d 3bfd794cf6655ffd 14c0d7e4177eeaf4"
"5dd95f05663fcfb4 47671154a91b9d00 d1bd7a35c14c7410 9a";
#elif AES___ == 192 /* ↓↓↓↓ if PKCS#7 enabled */
*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",
#if CTS
*cbccipher = "65c48fdf9fbd6261 28f2d8bac3f71251 75e7f4821fda0263 70011632779d7403"
"c119ef461ac4e1bc 8a7e36bf92b3b3d1 7e9e2d298e154bc4 2d",
#else /* ↓↓↓↓ zero-padded input */
*cbccipher = "65c48fdf9fbd6261 28f2d8bac3f71251 75e7f4821fda0263 70011632779d7403"
"7e9e2d298e154bc4 2dc7a9bc419b915d c119ef461ac4e1bc 8a7e36bf92b3b3d1",
#endif
*xtscipher = "10f9301a157bfceb 3eb9e7bd38500b7e 959e21ba3cc1179a d7f7d7d99460e695"
"5e8bcb177571c719 6de58ff28c381913 e7c82d0adfd90c45 ca",
*cfbcipher = "edab3105e673bc9e b9102539a9f457bc 245c14e1bff81b5b 4a4a147c988cb0a6"
"3f9c56525efbe64a 876ad1d761d3fc93 59fb4f5b2354acd4 90",
*ofbcipher = "edab3105e673bc9e b9102539a9f457bc d28c8e4c92995f5c d9426926be1e775d"
"e22b8ce4d0278b18 181b8bec93b9726f 959aa5d701d46102 f0",
#if CTR_IV_LENGTH == 16
*ctrcipher = "edab3105e673bc9e b9102539a9f457bc f2e2606dfa3f93c5 c51b910a89cddb67"
"191a118531ea0427 97626c9bfd370426 fdf3f59158bf7d4d 43",
#else
*ctrcipher = "6c6bae886c235d8c 7997d45c1bf0bca2 48b4bca9eb396d1b f6945e5b7a4fc10f"
"488cfe76fd5eaeff 2b8fb469f78fa61e 285e4cf9b9aee3d0 a8",
#endif
*ccmcipher = "d2575123438338d7 0b2955537fdfcf41 729870884e85af15 f0a74975a72b337d"
"04d426de87594b9a be3e6dcf07f21c99 db3999f81299d302 ad1e5ba683e9039a"
"5483685f1bd2c3fa 3b", /* <---- with 16 bytes tag */
*gcmcipher = "5ceab5b7c2d6dede 555a23c7e3e63274 4075a51df482730b a31485ec987ddcc8"
"73acdcfc6759a47b a424d838e7c0cb71 b9a4d8f4572e2141 18c8ab284ca845c1"
"4394618703cddf3a fb", /* <---- with 16 bytes tag */
*sivcipher = "ff2537a371fba0bb ed11acf2a3631300 97964f088881bdbd f163e261afd158e6"
"09272e759213c76a edc83a451d094c9e 06e2600e50a27cbb c0d9fad10eb6d369"
"4614362e5cd68b90 a9", /* 16 bytes i.v. PREPENDED */
*ocbcipher = "fc254896eb785b05 dd87f240722dd935 61f5a0ef6aff2eb6 5953da0b26257ed0"
"d69cb496e9a0cb1b f646151aa07e629a 28d99f0ffd7ea753 5c39f440df33c988"
"c55cbcc8ac086ffa 23", /* ↑↑↓↓ with 16 bytes tag */
*gsvcipher = "2f1488496ada3f70 9760420ac72e5acf a977f6add4c55ac6 85f1b9dff8f381e0"
"2a64bbdd64cdd778 525462949bb0b141 db908c5cfa365750 3666f879ac879fcb"
"f25c15d496a1e6f7 f8",
#if EAXP /* ↓↓↓↓ with 4 bytes tag */
*eaxcipher = "f516e9c20069292c c51ba8b6403ddedf 5a34798f62187f58 d723fa33573fd80b"
"f08ffbb09dadbd0b 6fa4812ca4bb5e6d db9a384943b36690 e81738a7a1",
#else /* ↓↓↓↓ with 16 bytes tag */
*eaxcipher = "4e2fa1bef9ffc23f 6965ee7135981c91 af9bfe97a6b13c01 b8b99e114dda2391"
"50661c618335a005 47cca55a8f22fbd5 ed5ab4b4a17d0aa3 29febd14ef271bae"
"986810a504f01ec6 02",
#endif /* ↓↓ a large Prime Number */
*fpe_plain = "122333444455555666666777777788888888999999999012345682747",
#if FF_X == 3 /* <-- MAXLEN=56 if RDX=10 */
*fpecipher = "0053317760589559020399280014720716878020198371161819152",
#else
*fpecipher = "000260964766881620856103152534002821752468680082944565411",
#endif
*ptextcmac = "b887df1fd8c239c3 e8a64d9822e21128",
*poly_1305 = "3175bed9bd01821a 62d4c7bef26722be",
*k_wrapped = "1FA68B0A8112B447 AEF34BD8FB5A7B82 9D3E862371D2CFE5";
#endif
enum buffer_sizes
{
int c = memcmp(expected, result, size);
printf("AES-%d %s: %s\n", AES_KEY_LENGTH *8, method, c ? "FAILED :(" : "PASSED!");
memset(result, 0xcc , BuffL);
PBYTES = HEXSTR_LENGTH / 2,
PADDED = PBYTES + 15 & ~15,
TAGGED = PBYTES + 16
};
static void hex2bytes(const char* hex, uint8_t* bytes)
{
unsigned shl = 0;
for (--bytes; *hex; ++hex)
{
if (*hex < '0' || 'f' < *hex) continue;
if ((shl ^= 4) != 0) *++bytes = 0;
*bytes |= (*hex % 16 + (*hex > '9') * 9) << shl;
}
}
static void str2bytes(const char* str, uint8_t* bytes)
#define char2num(c) (c > '9' ? (c & 7) + 9 : c & 0xF)
static void check(const char* method, void* result, const void* expected, size_t size)
{
unsigned i, j;
for (i = 0, j = ~0U; str[i]; ++i)
{
if (str[i] < '0' || str[i] > 'f') continue;
if (j++ & 1) bytes[j / 2] = char2num(str[i]) << 4;
else bytes[j / 2] |= char2num(str[i]);
}
int c = memcmp(expected, result, size);
printf("AES-%d %s: %s\n", AES_KEY_SIZE * 8, method, c ? "FAILED :`(" : "PASSED!");
memset(result, 0xcc, TAGGED);
}
int main()
{
uint8_t mainKey[32], key[64], iv[16], input[BuffL - 16], test[BuffL], output[BuffL],
*a = mainKey + 1, sa = sizeof mainKey - 1, st = TestStringSize / 2;
str2bytes(cipherKey, key);
str2bytes(secretKey, key + 32);
str2bytes(masterKey, mainKey);
str2bytes(iVec, iv);
str2bytes(plainText, input);
printf("Test results...\n");
uint8_t iv[16], key[64], authKey[32], input[PADDED], test[TAGGED], output[TAGGED],
*a = authKey + 1, sa = sizeof authKey - 1, sp = PBYTES;
hex2bytes(cipherKey, key);
hex2bytes(secondKey, key + 32);
hex2bytes(secretKey, authKey);
hex2bytes(iVec, iv);
hex2bytes(plainText, input);
#if M_RIJNDAEL
memcpy(input + 48, iv, 16);
a = AES_KEY_LENGTH == 16 ? key : input + (AES_KEY_LENGTH - 24) * 4;
hex2bytes(iVec, input + 48);
hex2bytes(secondKey, test);
a = AES_KEY_SIZE == 16 ? key : input + (AES___ - 192) / 2;
memcpy(test, a, 32);
memcpy(test + 32, mainKey, 16);
memcpy(test + 48, key + 32, 16);
AES_Cipher(key + 32, 'E', mainKey, output);
AES_Cipher(mainKey, 'E', key + 32, output + 16);
AES_Cipher(key + 32, 'D', a, output + 32);
AES_Cipher(mainKey, 'D', a + 16, output + 48);
check("encryption & decryption", output, test, 64);
AES_Cipher(test, 'E', authKey, output);
AES_Cipher(authKey, 'E', test, output + 16);
check("Encryption test", output, a, 32);
AES_Cipher(test, 'D', a, output + 16);
AES_Cipher(authKey, 'D', a + 16, output);
check("Decryption test", output, test, 32);
return 0;
#endif
#if ECB && AES_KEY_LENGTH + 8 * !AES_PADDING == 24
str2bytes(ecbcipher, test);
AES_ECB_encrypt(key, input, st, output);
printf("%s %s Test results\n", __DATE__, __TIME__);
#if ECB && AES_KEY_SIZE + 8 * !AES_PADDING == 24
hex2bytes(ecbcipher, test);
AES_ECB_encrypt(key, input, sp, output);
check("ECB encryption", output, test, sizeof input);
AES_ECB_decrypt(key, test, sizeof input, output);
check("ECB decryption", output, input, st);
check("ECB decryption", output, input, sp);
#endif
#if CBC && AES_KEY_LENGTH == 16
str2bytes(cbccipher, test);
AES_CBC_encrypt(key, iv, input, st, output);
check("CBC encryption", output, test, CTS ? st : sizeof input);
AES_CBC_decrypt(key, iv, test, CTS ? st : sizeof input, output);
check("CBC decryption", output, input, st);
#if CBC && AES_KEY_SIZE == 16
hex2bytes(cbccipher, test);
AES_CBC_encrypt(key, iv, input, sp, output);
check("CBC encryption", output, test, CTS ? sp : sizeof input);
AES_CBC_decrypt(key, iv, test, CTS ? sp : sizeof input, output);
check("CBC decryption", output, input, sp);
#endif
#if CFB && AES_KEY_LENGTH == 16
str2bytes(cfbcipher, test);
AES_CFB_encrypt(key, iv, input, st, output);
check("CFB encryption", output, test, st);
AES_CFB_decrypt(key, iv, test, st, output);
check("CFB decryption", output, input, st);
#if CFB && AES_KEY_SIZE == 16
hex2bytes(cfbcipher, test);
AES_CFB_encrypt(key, iv, input, sp, output);
check("CFB encryption", output, test, sp);
AES_CFB_decrypt(key, iv, test, sp, output);
check("CFB decryption", output, input, sp);
#endif
#if OFB && AES_KEY_LENGTH == 16
str2bytes(ofbcipher, test);
AES_OFB_encrypt(key, iv, input, st, output);
check("OFB encryption", output, test, st);
AES_OFB_decrypt(key, iv, test, st, output);
check("OFB decryption", output, input, st);
#if OFB && AES_KEY_SIZE == 16
hex2bytes(ofbcipher, test);
AES_OFB_encrypt(key, iv, input, sp, output);
check("OFB encryption", output, test, sp);
AES_OFB_decrypt(key, iv, test, sp, output);
check("OFB decryption", output, input, sp);
#endif
#if CTR_NA && AES_KEY_LENGTH == 16
str2bytes(ctrcipher, test);
AES_CTR_encrypt(key, iv, input, st, output);
check("CTR encryption", output, test, st);
AES_CTR_decrypt(key, iv, test, st, output);
check("CTR decryption", output, input, st);
#if CTR_NA && AES_KEY_SIZE == 16
hex2bytes(ctrcipher, test);
AES_CTR_encrypt(key, iv, input, sp, output);
check("CTR encryption", output, test, sp);
AES_CTR_decrypt(key, iv, test, sp, output);
check("CTR decryption", output, input, sp);
#endif
#if XTS && AES_KEY_LENGTH != 24
str2bytes(xtscipher, test);
AES_XTS_encrypt(key, iv, input, st, output);
check("XTS encryption", output, test, st);
AES_XTS_decrypt(key, iv, test, st, output);
check("XTS decryption", output, input, st);
#if XTS && AES_KEY_SIZE != 24
hex2bytes(xtscipher, test);
AES_XTS_encrypt(key, iv, input, sp, output);
check("XTS encryption", output, test, sp);
AES_XTS_decrypt(key, iv, test, sp, output);
check("XTS decryption", output, input, sp);
#endif
#if CMAC && AES_KEY_LENGTH == 16
str2bytes(cmac_hash, test);
AES_CMAC(key, input, st, output);
check("validate CMAC ", output, test, 16);
#if CMAC && AES_KEY_SIZE == 16
hex2bytes(ptextcmac, test);
AES_CMAC(key, input, sp, output);
check("plaintext CMAC", output, test, 16);
#endif
#if POLY1305 && AES_KEY_LENGTH == 16
str2bytes(p1305_mac, test);
AES_Poly1305(key, iv, input, st, output);
check("Poly-1305 mac ", output, test, 16);
#if POLY1305 && AES_KEY_SIZE == 16
hex2bytes(poly_1305, test);
AES_Poly1305(key, iv, input, sp, output);
check("Poly-1305 mac.", output, test, 16);
#endif
#if GCM && AES_KEY_LENGTH == 16
str2bytes(gcmcipher, test);
AES_GCM_encrypt(key, iv, input, st, a, sa, output, output + st);
check("GCM encryption", output, test, st + 16);
*output ^= AES_GCM_decrypt(key, iv, test, st, a, sa, 16, output);
check("GCM decryption", output, input, st);
#if GCM && AES_KEY_SIZE == 16
hex2bytes(gcmcipher, test);
AES_GCM_encrypt(key, iv, input, sp, a, sa, output, output + sp);
check("GCM encryption", output, test, sp + 16);
AES_GCM_decrypt(key, iv, test, sp, a, sa, 16, output);
check("GCM decryption", output, input, sp);
#endif
#if CCM && AES_KEY_LENGTH == 16
str2bytes(ccmcipher, test);
AES_CCM_encrypt(key, iv, input, st, a, sa, output, output + st);
check("CCM encryption", output, test, st + CCM_TAG_LEN);
*output ^= AES_CCM_decrypt(key, iv, test, st, a, sa, CCM_TAG_LEN, output);
check("CCM decryption", output, input, st);
#if CCM && AES_KEY_SIZE == 16
hex2bytes(ccmcipher, test);
AES_CCM_encrypt(key, iv, input, sp, a, sa, output, output + sp);
check("CCM encryption", output, test, sp + CCM_TAG_LEN);
*output ^= AES_CCM_decrypt(key, iv, test, sp, a, sa, CCM_TAG_LEN, output);
check("CCM decryption", output, input, sp);
#endif
#if OCB && AES_KEY_LENGTH == 16
str2bytes(ocbcipher, test);
AES_OCB_encrypt(key, iv, input, st, a, sa, output, output + st);
check("OCB encryption", output, test, st + OCB_TAG_LEN);
*output ^= AES_OCB_decrypt(key, iv, test, st, a, sa, OCB_TAG_LEN, output);
check("OCB decryption", output, input, st);
#if OCB && AES_KEY_SIZE == 16
hex2bytes(ocbcipher, test);
AES_OCB_encrypt(key, iv, input, sp, a, sa, output, output + sp);
check("OCB encryption", output, test, sp + OCB_TAG_LEN);
*output ^= AES_OCB_decrypt(key, iv, test, sp, a, sa, OCB_TAG_LEN, output);
check("OCB decryption", output, input, sp);
#endif
#if SIV && AES_KEY_LENGTH == 16
str2bytes(sivcipher, test);
AES_SIV_encrypt(key, input, st, a, sa, output, output + 16);
check("SIV encryption", output, test, st + 16);
*output ^= AES_SIV_decrypt(key, test, test + 16, st, a, sa, output);
check("SIV decryption", output, input, st);
#if SIV && AES_KEY_SIZE == 16
hex2bytes(sivcipher, test);
AES_SIV_encrypt(key, input, sp, a, sa, output, output + 16);
check("SIV encryption", output, test, sp + 16);
*output ^= AES_SIV_decrypt(key, test, test + 16, sp, a, sa, output);
check("SIV decryption", output, input, sp);
#endif
#if GCM_SIV && AES_KEY_LENGTH == 16
str2bytes(gsvcipher, test);
GCM_SIV_encrypt(key, iv, input, st, a, sa, output, output + st);
check("GCMSIV encrypt", output, test, st + 16);
*output ^= GCM_SIV_decrypt(key, iv, test, st, a, sa, 16, output);
check("GCMSIV decrypt", output, input, st);
#if GCM_SIV && AES_KEY_SIZE == 16
hex2bytes(gsvcipher, test);
GCM_SIV_encrypt(key, iv, input, sp, a, sa, output, output + sp);
check("GCMSIV encrypt", output, test, sp + 16);
*output ^= GCM_SIV_decrypt(key, iv, test, sp, a, sa, 16, output);
check("GCMSIV decrypt", output, input, sp);
#endif
#if EAX && AES_KEY_LENGTH == 16
str2bytes(eaxcipher, test);
#if EAX && AES_KEY_SIZE == 16
hex2bytes(eaxcipher, test);
#if EAXP
AES_EAX_encrypt(key, a, input, st, sa, output);
check("EAX encryption", output, test, st + 4);
*output ^= AES_EAX_decrypt(key, a, test, st, sa, output);
AES_EAX_encrypt(key, a, input, sp, sa, output);
check("EAX encryption", output, test, sp + 4);
AES_EAX_decrypt(key, a, test, sp, sa, output);
#else
AES_EAX_encrypt(key, iv, input, st, a, sa, output, output + st);
check("EAX encryption", output, test, st + 16);
*output ^= AES_EAX_decrypt(key, iv, test, st, a, sa, 16, output);
AES_EAX_encrypt(key, iv, input, sp, a, sa, output, output + sp);
check("EAX encryption", output, test, sp + 16);
AES_EAX_decrypt(key, iv, test, sp, a, sa, 16, output);
#endif
check("EAX decryption", output, input, st);
check("EAX decryption", output, input, sp);
#endif
#if FPE && AES_KEY_SIZE + CUSTOM_ALPHABET == 16
memcpy(test, fpecipher, FF_X == 3 ? (sp = 55) : sp);
#if FF_X == 3
AES_FPE_encrypt(key, a, fpe_plain, sp, output);
check("FF3 encryption", output, test, sp);
AES_FPE_decrypt(key, a, test, sp, output);
#else
AES_FPE_encrypt(key, a, sa, fpe_plain, sp, output);
check("FF1 encryption", output, test, sp);
AES_FPE_decrypt(key, a, sa, test, sp, output);
#endif
check("FPE decryption", output, fpe_plain, sp);
#endif
#if KWA
str2bytes(wrapped, test);
AES_KEY_wrap(mainKey, key + 32, AES_KEY_LENGTH, output);
check("key wrapping ", output, test, AES_KEY_LENGTH + 8);
AES_KEY_unwrap(mainKey, test, AES_KEY_LENGTH + 8, output);
check("key unwrapping", output, key + 32, AES_KEY_LENGTH);
hex2bytes(k_wrapped, test);
AES_KEY_wrap(authKey, key + 32, AES_KEY_SIZE, output);
check("key wrapping ", output, test, AES_KEY_SIZE + 8);
AES_KEY_unwrap(authKey, test, AES_KEY_SIZE + 8, output);
check("key unwrapping", output, key + 32, AES_KEY_SIZE);
#endif
#if FF_X == 3 && AES_KEY_LENGTH == 16
str2bytes("EF 43 59 D8 D5 80 AA 4F 7F 03 6D 6F 04 FC 6A 94", key);
str2bytes("D8 E7 92 0A FA 33 0A 73", a);
#elif FPE && AES_KEY_LENGTH == 16
str2bytes("2B 7E 15 16 28 AE D2 A6 AB F7 15 88 09 CF 4F 3C", key);
#if CUSTOM_ALPHABET == 2
st = 19; sa = 11;
str2bytes("37 37 37 37 70 71 72 73 37 37 37", a);
memcpy(test, "a9tv40mll9kdu509eum", st);
#elif !CUSTOM_ALPHABET
sa = 10; st = 10;
str2bytes("39 38 37 36 35 34 33 32 31 30", a);
memcpy(test, "6124200773", st);
AES_FPE_encrypt(key, a, sa, fpe_plain, st, output);
check("FF1 encryption", output, test, st);
AES_FPE_decrypt(key, a, sa, test, st, output);
check("FF1 decryption", output, (void*) fpe_plain, st);
memcpy(test, "2433477484", st); sa = 0;
#endif
AES_FPE_encrypt(key, a, sa, fpe_plain, st, output);
check("FF1 encryption", output, test, st);
AES_FPE_decrypt(key, a, sa, test, st, output);
check("FF1 decryption", output, (void*) fpe_plain, st);
#endif
/** a template for "OFFICIAL TEST VECTORS": */
#if OCB && EAX && SIV && GCM_SIV && POLY1305 && AES_KEY_LENGTH == 16
#if OCB * EAX * SIV * GCM_SIV * POLY1305 * FPE * (16 / AES_KEY_SIZE)
printf("+-> Let's do some extra tests\n");
st = sa = 24; /* taken from RFC 7253: */
str2bytes("000102030405060708090A0B0C0D0E0F", key);
str2bytes("BBAA99887766554433221107", iv);
str2bytes("000102030405060708090A0B0C0D0E0F1011121314151617", a);
str2bytes("000102030405060708090A0B0C0D0E0F1011121314151617", input);
str2bytes("1CA2207308C87C010756104D8840CE1952F09673A448A122\
sp = sa = 24; /* taken from RFC 7253: */
hex2bytes("000102030405060708090A0B0C0D0E0F", key);
hex2bytes("BBAA99887766554433221107", iv);
hex2bytes("000102030405060708090A0B0C0D0E0F1011121314151617", a);
hex2bytes("000102030405060708090A0B0C0D0E0F1011121314151617", input);
hex2bytes("1CA2207308C87C010756104D8840CE1952F09673A448A122\
C92C62241051F57356D7F3C90BB0E07F", test);
AES_OCB_encrypt(key, iv, input, st, a, sa, output, output + st);
check("OCB encryption", output, test, st + OCB_TAG_LEN);
*output ^= AES_OCB_decrypt(key, iv, test, st, a, sa, OCB_TAG_LEN, output);
check("OCB decryption", output, input, st);
AES_OCB_encrypt(key, iv, input, sp, a, sa, output, output + sp);
check("OCB encryption", output, test, sp + OCB_TAG_LEN);
*output ^= AES_OCB_decrypt(key, iv, test, sp, a, sa, OCB_TAG_LEN, output);
check("OCB decryption", output, input, sp);
st = 11; sa = 7; /* taken from RFC 8452: */
str2bytes("ee8e1ed9ff2540ae8f2ba9f50bc2f27c", key);
str2bytes("752abad3e0afb5f434dc4310", iv);
str2bytes("6578616d706c65", a);
str2bytes("48656c6c6f20776f726c64", input);
str2bytes("5d349ead175ef6b1def6fd4fbcdeb7e4793f4a1d7e4faa70100af1", test);
GCM_SIV_encrypt(key, iv, input, st, a, sa, output, output + st);
check("GCMSIV encrypt", output, test, st + 16);
*output ^= GCM_SIV_decrypt(key, iv, test, st, a, sa, 16, output);
check("GCMSIV decrypt", output, input, st);
st = 12; sa = 1; /* taken from RFC 8452: */
str2bytes("01000000000000000000000000000000", key);
str2bytes("030000000000000000000000", iv);
str2bytes("01", a);
str2bytes("020000000000000000000000", input);
str2bytes("296c7889fd99f41917f4462008299c51\
sp = 11; sa = 7; /* taken from RFC 8452: */
hex2bytes("ee8e1ed9ff2540ae8f2ba9f50bc2f27c", key);
hex2bytes("752abad3e0afb5f434dc4310", iv);
hex2bytes("6578616d706c65", a);
hex2bytes("48656c6c6f20776f726c64", input);
hex2bytes("5d349ead175ef6b1def6fd4fbcdeb7e4793f4a1d7e4faa70100af1", test);
GCM_SIV_encrypt(key, iv, input, sp, a, sa, output, output + sp);
check("GCMSIV encrypt", output, test, sp + 16);
*output ^= GCM_SIV_decrypt(key, iv, test, sp, a, sa, 16, output);
check("GCMSIV decrypt", output, input, sp);
sp = 12; sa = 1; /* taken from RFC 8452: */
hex2bytes("01000000000000000000000000000000", key);
hex2bytes("030000000000000000000000", iv);
hex2bytes("01", a);
hex2bytes("020000000000000000000000", input);
hex2bytes("296c7889fd99f41917f4462008299c51\
02745aaa3a0c469fad9e075a", test);
GCM_SIV_encrypt(key, iv, input, st, a, sa, output, output + st);
check("GCMSIV encrypt", output, test, st + 16);
*output ^= GCM_SIV_decrypt(key, iv, test, st, a, sa, 16, output);
check("GCMSIV decrypt", output, input, st);
GCM_SIV_encrypt(key, iv, input, sp, a, sa, output, output + sp);
check("GCMSIV encrypt", output, test, sp + 16);
*output ^= GCM_SIV_decrypt(key, iv, test, sp, a, sa, 16, output);
check("GCMSIV decrypt", output, input, sp);
st = 14; sa = 24; /* taken from RFC 5297: */
str2bytes("fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0\
sp = 14; sa = 24; /* taken from RFC 5297: */
hex2bytes("fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0\
f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff", key);
str2bytes("10111213 14151617 18191a1b 1c1d1e1f\
hex2bytes("10111213 14151617 18191a1b 1c1d1e1f\
20212223 24252627", a);
str2bytes("11223344 55667788 99aabbcc ddee", input);
str2bytes("85632d07 c6e8f37f 950acd32 0a2ecc93\
hex2bytes("11223344 55667788 99aabbcc ddee", input);
hex2bytes("85632d07 c6e8f37f 950acd32 0a2ecc93\
40c02b96 90c4dc04 daef7f6a fe5c", test);
AES_SIV_encrypt(key, input, st, a, sa, output, output + 16);
check("SIV encryption", output, test, st + 16);
*output ^= AES_SIV_decrypt(key, test, test + 16, st, a, sa, output);
check("SIV decryption", output, input, st);
st = 16; sa = 0; /* from miscreant: https://bit.ly/3yc2GBs */
str2bytes("fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", key);
str2bytes("00112233445566778899aabbccddeeff", input);
str2bytes("f304f912863e303d5b540e5057c7010c942ffaf45b0e5ca5fb9a56a5263bb065", test);
AES_SIV_encrypt(key, input, st, a, sa, output, output + 16);
check("SIV encryption", output, test, st + 16);
*output ^= AES_SIV_decrypt(key, test, test + 16, st, a, sa, output);
check("SIV decryption", output, input, st);
AES_SIV_encrypt(key, input, sp, a, sa, output, output + 16);
check("SIV encryption", output, test, sp + 16);
*output ^= AES_SIV_decrypt(key, test, test + 16, sp, a, sa, output);
check("SIV decryption", output, input, sp);
sp = 16; sa = 0; /* from miscreant on github: bit.ly/3ycgGB */
hex2bytes("fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", key);
hex2bytes("00112233445566778899aabbccddeeff", input);
hex2bytes("f304f912863e303d5b540e5057c7010c942ffaf45b0e5ca5fb9a56a5263bb065", test);
AES_SIV_encrypt(key, input, sp, a, sa, output, output + 16);
check("SIV encryption", output, test, sp + 16);
*output ^= AES_SIV_decrypt(key, test, test + 16, sp, a, sa, output);
check("SIV decryption", output, input, sp);
#if EAXP
st = 0; sa = 50; /* from Annex G of the IEEE Std 1703-2012 */
str2bytes("01020304050607080102030405060708", mainKey);
str2bytes("A20D060B607C86F7540116007BC175A8\
sp = 0; sa = 50; /* from Annex G of the IEEE Std 1703-2012 */
hex2bytes("01020304050607080102030405060708", key);
hex2bytes("A20D060B607C86F7540116007BC175A8\
03020100BE0D280B810984A60C060A60\
7C86F7540116007B040248F3C2040330\
0005", test);
str2bytes("515AE775", key);
AES_EAX_encrypt(mainKey, test, input, st, sa, output);
check("EAX encryption", output, key, st + 4);
*output ^= AES_EAX_decrypt(mainKey, test, key, st, sa, output);
check("EAX decryption", output, input, st);
st = 28; sa = 65; /* from Moise-Beroset-Phinney-Burns paper: */
str2bytes("10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 00", mainKey);
str2bytes("a2 0e 06 0c 60 86 48 01 86 fc 2f 81 1c aa 4e 01\
0005", input);
hex2bytes("515AE775", test);
AES_EAX_encrypt(key, input, NULL, sp, sa, output);
check("EAX encryption", output, test, sp + 4);
sp += AES_EAX_decrypt(key, input, test, sp, sa, output);
check("EAX decryption", output, input, sp);
sp = 28; sa = 65; /* from Moise-Beroset-Phinney-Burns paper: */
hex2bytes("10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 00", authKey);
hex2bytes("a2 0e 06 0c 60 86 48 01 86 fc 2f 81 1c aa 4e 01\
a8 06 02 04 39 a0 0e bb ac 0f a2 0d a0 0b a1 09\
80 01 00 81 04 4b ce e2 c3 be 25 28 23 81 21 88\
a6 0a 06 08 2b 06 01 04 01 82 85 63 00 4b ce e2\
c3", test);
str2bytes("17 51 30 30 30 30 30 30 30 30 30 30 30 30 30 30\
hex2bytes("17 51 30 30 30 30 30 30 30 30 30 30 30 30 30 30\
30 30 30 30 30 30 00 00 03 30 00 01", input);
str2bytes("9c f3 2c 7e c2 4c 25 0b e7 b0 74 9f ee e7 1a 22\
hex2bytes("9c f3 2c 7e c2 4c 25 0b e7 b0 74 9f ee e7 1a 22\
0d 0e ee 97 6e c2 3d bf 0c aa 08 ea 00 54 3e 66", key);
AES_EAX_encrypt(mainKey, test, input, st, sa, output);
check("EAX encryption", output, key, st + 4);
*output ^= AES_EAX_decrypt(mainKey, test, key, st, sa, output);
AES_EAX_encrypt(authKey, test, input, sp, sa, output);
check("EAX encryption", output, key, sp + 4);
AES_EAX_decrypt(authKey, test, key, sp, sa, output);
#else
st = 12; sa = 8; /* from Bellare-Rogaway-Wagner 2004 paper: */
str2bytes("BD8E6E11475E60B268784C38C62FEB22", key);
str2bytes("6EAC5C93072D8E8513F750935E46DA1B", iv);
str2bytes("D4482D1CA78DCE0F", a);
str2bytes("4DE3B35C3FC039245BD1FB7D", input);
str2bytes("835BB4F15D743E350E728414ABB8644FD6CCB86947C5E10590210A4F", test);
AES_EAX_encrypt(key, iv, input, st, a, sa, output, output + st);
check("EAX encryption", output, test, st + 16);
*output ^= AES_EAX_decrypt(key, iv, test, st, a, sa, 16, output);
sp = 12; sa = 8; /* from Bellare-Rogaway-Wagner 2004 paper: */
hex2bytes("BD8E6E11475E60B268784C38C62FEB22", key);
hex2bytes("6EAC5C93072D8E8513F750935E46DA1B", iv);
hex2bytes("D4482D1CA78DCE0F", a);
hex2bytes("4DE3B35C3FC039245BD1FB7D", input);
hex2bytes("835BB4F15D743E350E728414ABB8644FD6CCB86947C5E10590210A4F", test);
AES_EAX_encrypt(key, iv, input, sp, a, sa, output, output + sp);
check("EAX encryption", output, test, sp + 16);
AES_EAX_decrypt(key, iv, test, sp, a, sa, 16, output);
#endif
check("EAX decryption", output, input, st);
check("EAX decryption", output, input, sp);
st = 32; /* D.J.B. [2005] https://cr.yp.to/mac.html */
str2bytes("66 3c ea 19 0f fb 83 d8 95 93 f3 f4 76 b6 bc 24\
#if FF_X == 3 && !CUSTOM_ALPHABET
sp = 29; /* zero tweak works for both FF3 and FF3-1 */
hex2bytes("EF 43 59 D8 D5 80 AA 4F 7F 03 6D 6F 04 FC 6A 94", key);
hex2bytes("00 00 00 00 00 00 00 00", a);
memcpy(input, "89012123456789000000789000000", sp);
memcpy(output, "34695224821734535122613701434", sp);
AES_FPE_encrypt(key, a, input, sp, test);
check("FF3 encryption", test, output, sp);
AES_FPE_decrypt(key, a, output, sp, test);
check("FF3 decryption", test, input, sp);
#elif FF_X != 3 && CUSTOM_ALPHABET == 3
sp = 19; sa = 11;
hex2bytes("2B 7E 15 16 28 AE D2 A6 AB F7 15 88 09 CF 4F 3C", key);
hex2bytes("37 37 37 37 70 71 72 73 37 37 37", a);
memcpy(input, "0123456789abcdefghi", sp);
memcpy(output, "a9tv40mll9kdu509eum", sp);
AES_FPE_encrypt(key, a, sa, input, sp, test);
check("FF1 encryption", test, output, sp);
AES_FPE_decrypt(key, a, sa, output, sp, test);
check("FF1 decryption", test, input, sp);
#endif
sp = 32; /* ↓ from Daniel J. Bernstein's 2005 paper */
hex2bytes("66 3c ea 19 0f fb 83 d8 95 93 f3 f4 76 b6 bc 24\
d7 e6 79 10 7e a2 6a db 8c af 66 52 d0 65 61 36", input);
str2bytes("6a cb 5f 61 a7 17 6d d3 20 c5 c1 eb 2e dc dc 74\
hex2bytes("6a cb 5f 61 a7 17 6d d3 20 c5 c1 eb 2e dc dc 74\
48 44 3d 0b b0 d2 11 09 c8 9a 10 0b 5c e2 c2 08", key);
str2bytes("ae 21 2a 55 39 97 29 59 5d ea 45 8b c6 21 ff 0e", iv);
str2bytes("0e e1 c1 6b b7 3f 0f 4f d1 98 81 75 3c 01 cd be", test);
AES_Poly1305(key, iv, input, st, output);
check("Poly-1305 mac ", output, test, 16);
st = 63;
str2bytes("ab 08 12 72 4a 7f 1e 34 27 42 cb ed 37 4d 94 d1\
hex2bytes("ae 21 2a 55 39 97 29 59 5d ea 45 8b c6 21 ff 0e", iv);
hex2bytes("0e e1 c1 6b b7 3f 0f 4f d1 98 81 75 3c 01 cd be", test);
AES_Poly1305(key, iv, input, sp, output);
check("Poly-1305 mac.", output, test, 16);
sp = 63;
hex2bytes("ab 08 12 72 4a 7f 1e 34 27 42 cb ed 37 4d 94 d1\
36 c6 b8 79 5d 45 b3 81 98 30 f2 c0 44 91 fa f0\
99 0c 62 e4 8b 80 18 b2 c3 e4 a0 fa 31 34 cb 67\
fa 83 e1 58 c9 94 d9 61 c4 cb 21 09 5c 1b f9", input);
str2bytes("e1 a5 66 8a 4d 5b 66 a5 f6 8c c5 42 4e d5 98 2d\
hex2bytes("e1 a5 66 8a 4d 5b 66 a5 f6 8c c5 42 4e d5 98 2d\
12 97 6a 08 c4 42 6d 0c e8 a8 24 07 c4 f4 82 07", key);
str2bytes("9a e8 31 e7 43 97 8d 3a 23 52 7c 71 28 14 9e 3a", iv);
str2bytes("51 54 ad 0d 2c b2 6e 01 27 4f c5 11 48 49 1f 1b", test);
AES_Poly1305(key, iv, input, st, output);
check("Poly-1305 mac ", output, test, 16);
hex2bytes("9a e8 31 e7 43 97 8d 3a 23 52 7c 71 28 14 9e 3a", iv);
hex2bytes("51 54 ad 0d 2c b2 6e 01 27 4f c5 11 48 49 1f 1b", test);
AES_Poly1305(key, iv, input, sp, output);
check("Poly-1305 mac.", output, test, 16);
#endif
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
==============================================================================
Name : micro_aes.h
Author : polfosol
Version : 9.8.1.0
Version : 9.9.8.4
Copyright : copyright © 2022 - polfosol
Description : μAES ™ is a minimalist all-in-one library for AES encryption
==============================================================================
@@ -38,7 +38,7 @@ AES block-cipher modes of operation. The following modes can be enabled/disabled
#define CMAC 1 /* message authentication code (NIST SP 800-38B) */
#if CTR
#define CCM 1 /* counter with CBC-MAC (RFC-3610 & SP 800-38C) */
#define CCM 1 /* counter with CBC-MAC (RFC-3610/NIST SP 800-38C) */
#define GCM 1 /* Galois/counter mode with GMAC (NIST SP 800-38D) */
#define EAX 1 /* encrypt-authenticate-translate (ANSI C12.22) */
#define SIV 1 /* synthetic initialization vector (RFC-5297) */
@@ -68,19 +68,19 @@ AES block-cipher modes of operation. The following modes can be enabled/disabled
#define EAXP 1 /* EAX-prime, as specified by IEEE Std 1703 */
#endif
#define WTF ! (POLY1305 || CMAC || BLOCKCIPHERS)
#define M_RIJNDAEL WTF /* none of above; just rijndael API. dude.., why? */
#define WTF ! (BLOCKCIPHERS | AEAD_MODES)
#define M_RIJNDAEL WTF /* none of above; just rijndael API. dude.., why? */
/**----------------------------------------------------------------------------
Refer to the BOTTOM OF THIS DOCUMENT for some explanations about these macros:
-----------------------------------------------------------------------------*/
#if ECB || CBC || XEX || KWA || M_RIJNDAEL
#define DECRYPTION 1
#if ECB || (CBC && !CTS) || (XEX && !XTS)
#define AES_PADDING 0 /* standard values: (1) PKCS#7 (2) ISO/IEC7816-4 */
#endif
#if ECB || (CBC && !CTS) || (XEX && !XTS)
#define AES_PADDING 0 /* other valid values: (1) PKCS#7 (2) IEC7816-4 */
#if ECB || CBC || XEX || KWA || M_RIJNDAEL
#define DECRYPTION 1 /* rijndael decryption is NOT required otherwise. */
#endif
#if FPE
@@ -103,7 +103,7 @@ Refer to the BOTTOM OF THIS DOCUMENT for some explanations about these macros:
#endif
#if EAX && !EAXP
#define EAX_NONCE_LEN 16 /* practically no limit; can be arbitrarily large */
#define EAX_NONCE_LEN 16 /* no specified limit; can be arbitrarily large. */
#endif
#if OCB
@@ -112,15 +112,17 @@ Refer to the BOTTOM OF THIS DOCUMENT for some explanations about these macros:
#endif
/**----------------------------------------------------------------------------
Since stdint.h is not a part of ANSI-C, we may need a 'trick' to use uint8_t
Since <stdint.h> is not a part of ANSI-C, we may need a 'trick' to use uint8_t
-----------------------------------------------------------------------------*/
#include <string.h>
#if __STDC_VERSION__ > 199900L || __cplusplus > 201100L || defined(_MSC_VER)
#include <stdint.h>
#else
#include <limits.h>
#if CHAR_BIT == 8
typedef unsigned char uint8_t;
#if INT_MAX > 100000L
#endif
#if INT_MAX > 200000L
typedef int int32_t;
#else
typedef long int32_t;
@@ -137,8 +139,8 @@ Encryption/decryption of a single block with Rijndael
#if M_RIJNDAEL
void AES_Cipher( const uint8_t* key, /* encryption/decryption key */
const char mode, /* encrypt: 'E', decrypt: 'D' */
const uint8_t* x, /* input block byte array */
uint8_t* y ); /* output block byte array */
const uint8_t x[16], /* input bytes (or input block) */
uint8_t y[16] ); /* output block */
#endif
/**----------------------------------------------------------------------------
@@ -161,13 +163,13 @@ Main functions for CBC-AES block ciphering
-----------------------------------------------------------------------------*/
#if CBC
char AES_CBC_encrypt( const uint8_t* key, /* encryption key */
const uint8_t* iVec, /* initialization vector */
const uint8_t iVec[16], /* initialization vector */
const uint8_t* pntxt, /* plaintext buffer */
const size_t ptextLen, /* length of input plain text */
uint8_t* crtxt ); /* cipher-text result */
char AES_CBC_decrypt( const uint8_t* key, /* decryption key */
const uint8_t* iVec, /* initialization vector */
const uint8_t iVec[16], /* initialization vector */
const uint8_t* crtxt, /* cipher-text buffer */
const size_t crtxtLen, /* length of input cipher text */
uint8_t* pntxt ); /* plaintext result */
@@ -178,13 +180,13 @@ Main functions for CFB-AES block ciphering
-----------------------------------------------------------------------------*/
#if CFB
void AES_CFB_encrypt( const uint8_t* key, /* encryption key */
const uint8_t* iVec, /* initialization vector */
const uint8_t iVec[16], /* initialization vector */
const uint8_t* pntxt, /* plaintext buffer */
const size_t ptextLen, /* length of input plain text */
uint8_t* crtxt ); /* cipher-text result */
void AES_CFB_decrypt( const uint8_t* key, /* decryption key */
const uint8_t* iVec, /* initialization vector */
const uint8_t iVec[16], /* initialization vector */
const uint8_t* crtxt, /* cipher-text buffer */
const size_t crtxtLen, /* length of input cipher text */
uint8_t* pntxt ); /* plaintext result */
@@ -195,13 +197,13 @@ Main functions for OFB-AES block ciphering
-----------------------------------------------------------------------------*/
#if OFB
void AES_OFB_encrypt( const uint8_t* key, /* encryption key */
const uint8_t* iVec, /* initialization vector */
const uint8_t iVec[16], /* initialization vector */
const uint8_t* pntxt, /* plaintext buffer */
const size_t ptextLen, /* length of input plain text */
uint8_t* crtxt ); /* cipher-text result */
void AES_OFB_decrypt( const uint8_t* key, /* decryption key */
const uint8_t* iVec, /* initialization vector */
const uint8_t iVec[16], /* initialization vector */
const uint8_t* crtxt, /* cipher-text buffer */
const size_t crtxtLen, /* length of input cipher text */
uint8_t* pntxt ); /* plaintext result */
@@ -212,13 +214,13 @@ Main functions for XTS-AES block ciphering
-----------------------------------------------------------------------------*/
#if XTS
char AES_XTS_encrypt( const uint8_t* keys, /* encryption key pair */
const uint8_t* unitId, /* tweak value (sector ID) */
const uint8_t* tweak, /* tweak value (unit/sector ID) */
const uint8_t* pntxt, /* plaintext buffer */
const size_t ptextLen, /* length of input plain text */
uint8_t* crtxt ); /* cipher-text result */
char AES_XTS_decrypt( const uint8_t* keys, /* decryption key pair */
const uint8_t* unitId, /* tweak value (sector ID) */
const uint8_t* tweak, /* tweak value (unit/sector ID) */
const uint8_t* crtxt, /* cipher-text buffer */
const size_t crtxtLen, /* length of input cipher text */
uint8_t* pntxt ); /* plaintext result */
@@ -250,11 +252,11 @@ void AES_SIV_encrypt( const uint8_t* keys, /* encryption key pair */
const size_t ptextLen, /* length of input plain text */
const uint8_t* aData, /* added authentication data */
const size_t aDataLen, /* size of authentication data */
uint8_t* iv, /* synthesized initial-vector */
uint8_t iv[16], /* synthesized initial-vector */
uint8_t* crtxt ); /* cipher-text result */
char AES_SIV_decrypt( const uint8_t* keys, /* decryption key pair */
const uint8_t* iv, /* provided initial-vector */
const uint8_t iv[16], /* provided initial-vector */
const uint8_t* crtxt, /* cipher text */
const size_t crtxtLen, /* length of input cipher-text */
const uint8_t* aData, /* added authentication data */
@@ -273,7 +275,7 @@ void AES_GCM_encrypt( const uint8_t* key, /* encryption key */
const uint8_t* aData, /* added authentication data */
const size_t aDataLen, /* size of authentication data */
uint8_t* crtxt, /* cipher-text result */
uint8_t* auTag ); /* message authentication tag */
uint8_t auTag[16] ); /* message authentication tag */
char AES_GCM_decrypt( const uint8_t* key, /* decryption key */
const uint8_t* nonce, /* a.k.a initialization vector */
@@ -296,7 +298,7 @@ void AES_CCM_encrypt( const uint8_t* key, /* encryption key */
const uint8_t* aData, /* added authentication data */
const size_t aDataLen, /* size of authentication data */
uint8_t* crtxt, /* cipher-text result */
uint8_t* auTag ); /* message authentication tag */
uint8_t auTag[16] ); /* message authentication tag */
char AES_CCM_decrypt( const uint8_t* key, /* decryption key */
const uint8_t* nonce, /* a.k.a initialization vector */
@@ -319,7 +321,7 @@ void AES_OCB_encrypt( const uint8_t* key, /* encryption key */
const uint8_t* aData, /* added authentication data */
const size_t aDataLen, /* size of authentication data */
uint8_t* crtxt, /* cipher-text result */
uint8_t* auTag ); /* message authentication tag */
uint8_t auTag[16] ); /* message authentication tag */
char AES_OCB_decrypt( const uint8_t* key, /* decryption key */
const uint8_t* nonce, /* a.k.a initialization vector */
@@ -346,7 +348,7 @@ void AES_EAX_encrypt( const uint8_t* key, /* encryption key */
const uint8_t* aData, /* added authentication data */
const size_t aDataLen, /* size of authentication data */
uint8_t* crtxt, /* cipher-text result */
uint8_t* auTag ); /* message authentication tag */
uint8_t auTag[16] ); /* message authentication tag */
#endif
char AES_EAX_decrypt( const uint8_t* key, /* decryption key */
@@ -374,7 +376,7 @@ void GCM_SIV_encrypt( const uint8_t* key, /* encryption key */
const uint8_t* aData, /* added authentication data */
const size_t aDataLen, /* size of authentication data */
uint8_t* crtxt, /* cipher-text result */
uint8_t* auTag ); /* 16-bytes mandatory tag */
uint8_t auTag[16] ); /* 16-bytes mandatory tag */
char GCM_SIV_decrypt( const uint8_t* key, /* decryption key */
const uint8_t* nonce, /* provided 96-bit nonce */
@@ -407,7 +409,9 @@ Main functions for FPE-AES; more info at the bottom of this page.
#if FPE
char AES_FPE_encrypt( const uint8_t* key, /* encryption key */
const uint8_t* tweak, /* tweak bytes */
#if FF_X != 3
#if FF_X == 3
#define FF3_TWEAK_LEN 7 /* either 8 (FF3), or 7 (FF3-1) */
#else
const size_t tweakLen, /* size of tweak array */
#endif
const void* pntxt, /* input plaintext string */
@@ -429,10 +433,10 @@ Main function for Poly1305-AES message authentication code
-----------------------------------------------------------------------------*/
#if POLY1305
void AES_Poly1305( const uint8_t* keys, /* encryption/mixing key pair */
const uint8_t* nonce, /* the 128-bit nonce */
const uint8_t nonce[16], /* the 128-bit nonce */
const void* data, /* input data buffer */
const size_t dataSize, /* size of data in bytes */
uint8_t* mac ); /* calculated poly1305-AES mac */
uint8_t mac[16] ); /* poly1305-AES mac of data */
#endif
/**----------------------------------------------------------------------------
@@ -442,7 +446,7 @@ Main function for AES Cipher-based Message Authentication Code
void AES_CMAC( const uint8_t* key, /* encryption/cipher key */
const void* data, /* input data buffer */
const size_t dataSize, /* size of data in bytes */
uint8_t* mac ); /* calculated CMAC hash */
uint8_t mac[16] ); /* CMAC result of input data */
#endif
#ifdef __cplusplus
@@ -457,26 +461,22 @@ The error codes and key length should be defined here for external references:
#define AUTHENTICATION_FAILURE 0x1A
#define ENDED_IN_SUCCESS 0x00
#if (AES___ == 256) || (AES___ == 192)
#define AES_KEY_LENGTH (AES___/8)
#if (AES___ != 256) && (AES___ != 192)
#define AES_KEY_SIZE 16
#else
#define AES_KEY_LENGTH 16
#define AES_KEY_SIZE (AES___ / 8)
#endif
#endif /* header guard */
/**¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯**\
/******************************************************************************\
¦ Notes and remarks about the above-defined macros ¦
--------------------------------------------------------------------------------
* Some AES modes just use the 'encryption' part of the Rijndael algorithm. So if
you are NOT using the decryption functions of ECB/CBC/KWA/XEX modes, you can
safely disable DECRYPTION macro and save a few kilobytes in compiled code.
* In EBC/CBC/XEX modes, the size of input must be a multiple of block-size.
Otherwise it needs to be padded. The simplest (default) padding mode is to
fill the rest of block by zeros. Supported standard padding methods are
PKCS#7 and ISO/IEC 7816-4, which can be enabled by AES_PADDING macro.
PKCS#7 and ISO/IEC 7816-4, which can be enabled by the AES_PADDING macro.
* In many texts, you may see that the words 'nonce' and 'initialization vector'
are used interchangeably. But they have a subtle difference. Sometimes nonce
@@ -486,7 +486,7 @@ The error codes and key length should be defined here for external references:
start at CTR_STARTVALUE, or use a full block IV.
* In AEAD modes, the size of nonce and tag might be a parameter of the algorithm
such that changing them affect the results. The GCM/EAX modes support
such that changing them affect the results. The GCM and EAX modes support
arbitrary sizes for nonce. In CCM, the nonce length may vary from 8 to 13
bytes. Also the tag size is an EVEN number between 4..16. In OCB, the nonce
size is 1..15 and the tag is 0..16 bytes. Note that the 'calculated' tag-
@@ -508,28 +508,27 @@ The error codes and key length should be defined here for external references:
called 'the alphabet'. The default alphabet is the set of digits {'0'..'9'}.
If you want to use a different alphabet, set the CUSTOM_ALPHABET macro and
refer to the "micro_fpe.h" header. This file is needed only when a custom
alphabet has to be defined, and contains some illustrative examples and
clear guidelines on how to do so.
alphabet has to be defined. It contains some illustrative examples and clear
guidelines on how to do so.
* The key wrapping mode is also denoted by KW. In this mode, the input secret is
divided into 64bit blocks. Number of blocks is at least 2, and it is assumed
that no padding is required. For padding, the KWP mode is used which is
easily implementable, but left as an exercise! In the NIST document you may
find some mentions of TKW which is for 3DES and irrelevant here. Anyway, the
wrapped output has an additional block, i.e. wrappedSize = secretSize + 8.
that no padding is required. For padding, the KWP mode must be used which is
easily implementable, but left as an exercise! The key-wrapped output is an
extra block (8 bytes) longer than the secret. In the NIST SP800-38F document
you may find some mentions of TKW which is for 3DES and irrelevant here.
* Let me explain three extra options that are defined in the source file. If the
length of the input cipher/plain text is 'always' less than 4KB, you can
enable the SMALL_CIPHER macro to save a few bytes in the compiled code. Note
that for key-wrapping, this limit is 42 blocks (336 bytes) of secret key.
These assumptions are likely to be valid for some embedded systems and small
applications. Furthermore, enabling that other macro, REDUCE_CODE_SIZE had a
considerable effect on the size of the compiled code in my own tests.
Nonetheless, others might get a different result from them.
enable the SMALL_CIPHER macro to save a few bytes in the compiled code. This
assumption is likely to be valid for some embedded systems and small-scale
applications. Furthermore by enabling the DONT_USE_FUNCTIONS macro, you may
witness a positive effect on the speed while increasing the size of compiled
code. Nonetheless, others might get a different result from them.
The INCREASE_SECURITY macro, as its name suggests, is dealing with security
considerations. For example, since the RoundKey is declared as static array,
it might be exposed to some attacks. By enabling this macro, round-keys are
considerations. For example, since the RoundKey is declared as static array
it might get exposed to some attacks. By enabling this macro, round-keys are
wiped out at the end of ciphering operations. However, please keep in mind
that this is NOT A GUARANTEE against side-channel attacks.

168
micro_fpe.h Normal file
View File

@@ -0,0 +1,168 @@
/*
==============================================================================
Name : micro_fpe.h
Author : polfosol
Version : 2.1.1.2
Copyright : copyright © 2022 - polfosol
Description : demonstrating some sample alphabets for the FPE mode of μAES ™
==============================================================================
*/
#ifndef MICRO_FPE_H_
#define MICRO_FPE_H_
/******************************************************************************
* If your desired alphabet contains non-ASCII characters, the CUSTOM_ALPHABET
* macro 'must be' set to a double-digit number, e.g 21. In what follows, there
* are some sample alphabets along with their corresponding macro definitions.
* It is straightforward to define another alphabet according to these samples.
*/
#define NON_ASCII_CHARACTER_SET (CUSTOM_ALPHABET >= 10)
/******************************************************************************
* 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"
/**
numbers
*/
#if CUSTOM_ALPHABET == 0
#define ALPHABET DECDIGIT
#define RADIX 10
#endif
/**
binary numbers
*/
#if CUSTOM_ALPHABET == 1
#define ALPHABET "01"
#define RADIX 2
#endif
/**
lowercase english words
*/
#if CUSTOM_ALPHABET == 2
#define ALPHABET LCLETTER
#define RADIX 26
#endif
/**
lowercase alphanumeric strings
*/
#if CUSTOM_ALPHABET == 3
#define ALPHABET DECDIGIT LCLETTER
#define RADIX 36
#endif
/**
the English alphabet
*/
#if CUSTOM_ALPHABET == 4
#define ALPHABET UCLETTER LCLETTER
#define RADIX 52
#endif
/**
base-64 encoded strings (RFC-4648), with no padding character
*/
#if CUSTOM_ALPHABET == 5
#define ALPHABET UCLETTER LCLETTER DECDIGIT "+/"
#define RADIX 64
#endif
/**
base-85 encoded strings (RFC-1924)
*/
#if CUSTOM_ALPHABET == 6
#define ALPHABET DECDIGIT UCLETTER LCLETTER "!#$%&()*+-;<=>?@^_`{|}~"
#define RADIX 85
#endif
/**
a character set with length 26, used by some test vectors
*/
#if CUSTOM_ALPHABET == 7
#define ALPHABET DECDIGIT "abcdefghijklmnop"
#define RADIX 26
#endif
/**
base-64 character set with DIFFERENT ORDERING, used by some test vectors
*/
#if CUSTOM_ALPHABET == 8
#define ALPHABET DECDIGIT UCLETTER LCLETTER "+/"
#define RADIX 64
#endif
/**
all printable ascii characters
*/
#if CUSTOM_ALPHABET == 9
#define ALPHABET " !\"#$%&\'()*+,-./"DECDIGIT":;<=>?@"UCLETTER"[\\]^_`"LCLETTER"{|}~"
#define RADIX 95
#endif
/******************************************************************************
* Here goes non-ASCII alphabets. Note that C89/ANSI-C standard does not fully
* support such characters, and the code may lose its compliance in this case.
*/
#if NON_ASCII_CHARACTER_SET
#include <locale.h>
#include <wchar.h>
#define string_t wchar_t* /* type of plain/cipher-text */
#else
#define string_t char*
#endif
/**
Greek alphabet (LTR)
*/
#if CUSTOM_ALPHABET == 10
#define ALPHABET L"ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφϕχψω"
#define RADIX 50
#endif
/**
Persian alphabet (RTL)
*/
#if CUSTOM_ALPHABET == 20
#define ALPHABET L"ءئؤآابپتثجچحخدذرزژسشصضطظعغفقکگلمنوهی"
#define RADIX 36
#endif
/******************************************************************************
* It is mandatory to determine these constants for the alphabet. You can either
* pre-calculate the logarithm value (with at least 10 significant digits) and
* 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 */
#if FF_X == 3
#define MAXLEN (2 * (int) (96.000001 / LOGRDX))
#endif
#define MINLEN ((int) (19.931568 / LOGRDX + 1))
/******************************************************************************
* or we can do something like this to set MINLEN:
*
#if RADIX >= 32
#define MINLEN (2 + (RADIX < 1000) + (RADIX < 100))
#elif RADIX > 5
#define MINLEN (5 + (RADIX < 16) + (RADIX < 10) + (RADIX < 8))
#else
#define MINLEN (40 / RADIX + RADIX / 5)
#endif
*/
#endif /* header guard */

View File

@@ -2,40 +2,38 @@
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="micro_aes" />
<Option title="µAES" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Option compiler="clang" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/micro_aes" prefix_auto="1" extension_auto="1" />
<Option output="bin/Debug" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Option compiler="clang" />
<Compiler>
<Add option="-pedantic" />
<Add option="-ansi" />
<Add option="-Og" />
<Add option="-pedantic-errors" />
<Add option="-Wall" />
<Add option="-std=c90" />
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/micro_aes" prefix_auto="1" extension_auto="1" />
<Option output="bin/Release" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Option compiler="clang" />
<Compiler>
<Add option="-Os" />
<Add option="-pedantic" />
<Add option="-ansi" />
<Add option="-pedantic-errors" />
<Add option="-Wall" />
<Add option="-std=c90" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
</Compiler>
<Unit filename="main.c">
<Option compilerVar="CC" />
</Unit>
@@ -43,6 +41,9 @@
<Option compilerVar="CC" />
</Unit>
<Unit filename="micro_aes.h" />
<Extensions />
<Unit filename="micro_fpe.h" />
<Extensions>
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@@ -1,107 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<CodeLite_Project Name="microAES" Version="11000" InternalType="Console">
<Plugins>
<Plugin Name="qmake">
<![CDATA[00020001N0005Debug0000000000000001N0007Release000000000000]]>
</Plugin>
</Plugins>
<Description/>
<Dependencies/>
<VirtualDirectory Name="src">
<File Name="micro_aes.h"/>
<File Name="micro_aes.c"/>
<File Name="main.c"/>
</VirtualDirectory>
<Dependencies Name="Debug"/>
<Dependencies Name="Release"/>
<Settings Type="Executable">
<GlobalSettings>
<Compiler Options="" C_Options="" Assembler="">
<IncludePath Value="."/>
</Compiler>
<Linker Options="">
<LibraryPath Value="."/>
</Linker>
<ResourceCompiler Options=""/>
</GlobalSettings>
<Configuration Name="Debug" CompilerType="clang" DebuggerType="LLDB Debugger" Type="Executable" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
<Compiler Options="-g;-O0;-Wall" C_Options="-pedantic-errors;-g;-O0;-ansi;-W" Assembler="" Required="yes" PreCompiledHeader="" PCHInCommandLine="no" PCHFlags="" PCHFlagsPolicy="0">
<IncludePath Value="."/>
</Compiler>
<Linker Options="" Required="yes"/>
<ResourceCompiler Options="" Required="no"/>
<General OutputFile="$(IntermediateDirectory)/$(ProjectName)" IntermediateDirectory="./Debug" Command="./$(ProjectName)" CommandArguments="" UseSeparateDebugArgs="no" DebugArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes" IsGUIProgram="no" IsEnabled="yes"/>
<BuildSystem Name="Default"/>
<Environment EnvVarSetName="&lt;Use Defaults&gt;" DbgSetName="&lt;Use Defaults&gt;">
<![CDATA[]]>
</Environment>
<Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="" IsExtended="no">
<DebuggerSearchPaths/>
<PostConnectCommands/>
<StartupCommands/>
</Debugger>
<PreBuild/>
<PostBuild/>
<CustomBuild Enabled="no">
<RebuildCommand/>
<CleanCommand/>
<BuildCommand/>
<PreprocessFileCommand/>
<SingleFileCommand/>
<MakefileGenerationCommand/>
<ThirdPartyToolName>None</ThirdPartyToolName>
<WorkingDirectory/>
</CustomBuild>
<AdditionalRules>
<CustomPostBuild/>
<CustomPreBuild/>
</AdditionalRules>
<Completion EnableCpp11="no" EnableCpp14="no">
<ClangCmpFlagsC/>
<ClangCmpFlags/>
<ClangPP/>
<SearchPaths/>
</Completion>
</Configuration>
<Configuration Name="Release" CompilerType="clang" DebuggerType="LLDB Debugger" Type="Executable" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
<Compiler Options="-O2;-Wall" C_Options="-pedantic-errors;-Os;-ansi;-fexpensive-optimizations;-W" Assembler="" Required="yes" PreCompiledHeader="" PCHInCommandLine="no" PCHFlags="" PCHFlagsPolicy="0">
<IncludePath Value="."/>
<Preprocessor Value="NDEBUG"/>
</Compiler>
<Linker Options="" Required="yes"/>
<ResourceCompiler Options="" Required="no"/>
<General OutputFile="$(IntermediateDirectory)/$(ProjectName)" IntermediateDirectory="./Release" Command="./$(ProjectName)" CommandArguments="" UseSeparateDebugArgs="no" DebugArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes" IsGUIProgram="no" IsEnabled="yes"/>
<BuildSystem Name="Default"/>
<Environment EnvVarSetName="&lt;Use Defaults&gt;" DbgSetName="&lt;Use Defaults&gt;">
<![CDATA[]]>
</Environment>
<Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="" IsExtended="no">
<DebuggerSearchPaths/>
<PostConnectCommands/>
<StartupCommands/>
</Debugger>
<PreBuild/>
<PostBuild/>
<CustomBuild Enabled="no">
<RebuildCommand/>
<CleanCommand/>
<BuildCommand/>
<PreprocessFileCommand/>
<SingleFileCommand/>
<MakefileGenerationCommand/>
<ThirdPartyToolName>None</ThirdPartyToolName>
<WorkingDirectory/>
</CustomBuild>
<AdditionalRules>
<CustomPostBuild/>
<CustomPreBuild/>
</AdditionalRules>
<Completion EnableCpp11="no" EnableCpp14="no">
<ClangCmpFlagsC/>
<ClangCmpFlags/>
<ClangPP/>
<SearchPaths/>
</Completion>
</Configuration>
</Settings>
</CodeLite_Project>

View File

@@ -81,6 +81,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="micro_aes.h" />
<ClInclude Include="micro_fpe.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@@ -2,9 +2,9 @@
==============================================================================
Name : CCMtest.c
Author : polfosol
Version : 1.6.0.0
Version : 1.6.1.2
Copyright : copyright © 2022 - polfosol
Description : illustrating how the NIST's vectors for AES-CCM mode are used
Description : illustrating how to validate NIST's vectors for AES-CCM mode
==============================================================================
*/
@@ -13,35 +13,34 @@
#define TESTFILEPATH "CCM_VNT128.rsp"
static void str2bytes(const char* str, uint8_t* bytes)
#define char2num(c) (c > '9' ? (c & 7) + 9 : c & 0xF)
static void str2bytes(const char* hex, uint8_t* bytes)
{
size_t i, j;
for (i = 0, j = ~0; str[i]; ++i)
unsigned shl = 0;
for (--bytes; *hex; ++hex)
{
if (str[i] < '0' || str[i] > 'f') continue;
if (j++ & 1) bytes[j / 2] = char2num(str[i]) << 4;
else bytes[j / 2] |= char2num(str[i]);
if (*hex < '0' || 'f' < *hex) continue;
if ((shl ^= 4) != 0) *++bytes = 0;
*bytes |= (*hex % 16 + (*hex > '9') * 9) << shl;
}
}
static void bytes2str(const uint8_t* bytes, char* str, size_t len)
#define num2char(x) ((x) > 9 ? 'a' - 10 + (x) : '0' + (x))
static void bytes2str(const uint8_t* bytes, char* str, const size_t len)
{
size_t i, j;
for (i = 0, j = 0; i < len; ++i)
const char offset = 0x27; /* offset must be 7 for uppercase */
size_t i = len + len, shr = 0;
for (str[i] = 0; i--; shr ^= 4)
{
str[j++] = num2char(bytes[i] >> 4);
str[j++] = num2char(bytes[i] & 15);
str[i] = bytes[i / 2] >> shr & 0xF | '0';
if (str[i] > '9') str[i] += offset;
}
str[j] = 0;
}
static int ciphertest(uint8_t* key, uint8_t* iv, uint8_t* p, uint8_t* a, uint8_t* c, uint8_t np, uint8_t na, char* r)
static int ciphertest(uint8_t* key, uint8_t* iv, uint8_t* p, uint8_t* a, uint8_t* c,
size_t np, size_t na, char* r)
{
char sk[70], si[40], sp[80], sc[96], sa[80], msg[30];
char sk[2*AES_KEY_SIZE + 1], si[33], sp[80], sc[96], sa[80], msg[30];
uint8_t tmp[64], t = 0;
sprintf(msg, "%s", "success");
sprintf(msg, "%s", "passed the test");
AES_CCM_encrypt(key, iv, p, np, a, na, tmp, tmp + np);
if (memcmp(c, tmp, np + CCM_TAG_LEN))
@@ -55,7 +54,7 @@ static int ciphertest(uint8_t* key, uint8_t* iv, uint8_t* p, uint8_t* a, uint8_t
{
sprintf(msg, "%sdecrypt failure", t & 1 ? "encrypt & " : "");
}
bytes2str(key, sk, AES_KEY_LENGTH);
bytes2str(key, sk, AES_KEY_SIZE);
bytes2str(iv, si, CCM_NONCE_LEN);
bytes2str(p, sp, np);
bytes2str(a, sa, na);
@@ -69,7 +68,7 @@ int main()
const char *linehdr[] = { "Key = ", "Nonce = ", "Adata = ", "Payload = ", "CT = " };
char buffer[0x800], *value = "";
size_t pass = 0, df = 0, ef = 0, sk = 0, sn = 0, sp = 0, sc = 0, sa = 0;
uint8_t i, n = 0, key[AES_KEY_LENGTH], iv[16], p[64], c[80], a[64];
uint8_t i, n = 0, key[AES_KEY_SIZE], iv[16], p[64], c[80], a[64];
FILE *fp, *fs, *ferr;
fp = fopen(TESTFILEPATH, "r");
@@ -99,7 +98,7 @@ int main()
{
case 0:
sk = strlen(value) / 2;
if (sk == AES_KEY_LENGTH) str2bytes(value, key);
if (sk == AES_KEY_SIZE) str2bytes(value, key);
break;
case 1:
sn = strlen(value) / 2;
@@ -122,7 +121,7 @@ int main()
}
if (n == 2)
{
if (sk == AES_KEY_LENGTH && sn == CCM_NONCE_LEN && sp == sc)
if (sk == AES_KEY_SIZE && sn == CCM_NONCE_LEN && sp == sc)
{
n = ciphertest(key, iv, p, a, c, sp, sa, buffer);
fprintf(n ? ferr : fs, "%s\n", buffer); /* save the log */
@@ -137,7 +136,7 @@ int main()
}
}
printf ("test cases: %d\nsuccessful: %d\nfailed encrypt: %d, failed decrypt: %d\n",
pass + ef + df, pass, ef, df);
pass + (ef > df ? ef : df), pass, ef, df);
fclose(fp); fclose(fs); fclose(ferr);
if (ef + df == 0)

View File

@@ -2,9 +2,9 @@
==============================================================================
Name : CMACtest.c
Author : polfosol
Version : 1.5.0.0
Version : 1.5.1.1
Copyright : copyright © 2022 - polfosol
Description : illustrating how the NIST's vectors for AES-CMAC are used
Description : illustrating how to validate NIST's vectors for AES-CMAC
==============================================================================
*/
@@ -13,41 +13,39 @@
#define TESTFILEPATH "CMACGenAES128.rsp"
static void str2bytes(const char* str, uint8_t* bytes)
#define char2num(c) (c > '9' ? (c & 7) + 9 : c & 0xF)
static void str2bytes(const char* hex, uint8_t* bytes)
{
size_t i, j;
for (i = 0, j = ~0; str[i]; ++i)
unsigned shl = 0;
for (--bytes; *hex; ++hex)
{
if (str[i] < '0' || str[i] > 'f') continue;
if (j++ & 1) bytes[j / 2] = char2num(str[i]) << 4;
else bytes[j / 2] |= char2num(str[i]);
if (*hex < '0' || 'f' < *hex) continue;
if ((shl ^= 4) != 0) *++bytes = 0;
*bytes |= (*hex % 16 + (*hex > '9') * 9) << shl;
}
}
static void bytes2str(const uint8_t* bytes, char* str, size_t len)
#define num2char(x) ((x) > 9 ? 'a' - 10 + (x) : '0' + (x))
static void bytes2str(const uint8_t* bytes, char* str, const size_t len)
{
size_t i, j;
for (i = 0, j = 0; i < len; ++i)
const char offset = 0x27; /* offset must be 7 for uppercase */
size_t i = len + len, shr = 0;
for (str[i] = 0; i--; shr ^= 4)
{
str[j++] = num2char(bytes[i] >> 4);
str[j++] = num2char(bytes[i] & 15);
str[i] = bytes[i / 2] >> shr & 0xF | '0';
if (str[i] > '9') str[i] += offset;
}
str[j] = 0;
}
static int ciphertest(uint8_t* key, uint8_t* d, uint8_t* m, size_t ds, size_t ms, char* r)
{
char sk[2*AES_KEY_LENGTH + 8], smac[40], msg[30];
char sk[2*AES_KEY_SIZE + 1], smac[33], msg[30];
uint8_t tmp[32], t = 0;
sprintf(msg, "%s", "success");
sprintf(msg, "%s", "passed the test");
AES_CMAC(key, d, ds, tmp);
t = memcmp(m, tmp, ms);
if (t) sprintf(msg, "%s", "failed");
bytes2str(key, sk, AES_KEY_LENGTH);
bytes2str(key, sk, AES_KEY_SIZE);
bytes2str(m, smac, ms);
sprintf(r, "%s\nK: %s\nmac: %s\n", msg, sk, smac);
return t;
@@ -88,7 +86,7 @@ int main()
{
case 0:
sk = strlen(value) / 2;
if (sk == AES_KEY_LENGTH) str2bytes(value, key);
if (sk == AES_KEY_SIZE) str2bytes(value, key);
break;
case 1:
sd = strlen(value) / 2;
@@ -104,7 +102,7 @@ int main()
}
if (n == 2)
{
if (sk == AES_KEY_LENGTH)
if (sk == AES_KEY_SIZE)
{
n = ciphertest(key, d, m, sd, sm, buffer);
fprintf(n ? ferr : fs, "%s\n", buffer); /* save the log */

View File

@@ -0,0 +1,563 @@
# NIST Test Vectors for FPE-AES
# IMPORTANT NOTE:
# Some FF3 test vectors are for the old version of FF3, which was based on 64-bit tweaks.
# The last revision of "NIST SP 800-38G" demands using 56-bit tweaks in FF3-1.
#
# Extracted from PDF files in
# https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/example-values
# Also a bunch of vectors are taken from:
# https://pages.nist.gov/ACVP/draft-celi-acvp-symmetric.html
# https://github.com/mysto/python-fpe/blob/main/ff3/ff3_test.py
# https://github.com/ubiqsecurity/ubiq-fpe-c/tree/master/src/test
#
Count = 1
Method = FF1
Alphabet = 0123456789
Key = 2B7E151628AED2A6ABF7158809CF4F3C
Tweak =
PT = 0123456789
CT = 2433477484
Count = 2
Method = FF1
Alphabet = 0123456789
Key = 2B7E151628AED2A6ABF7158809CF4F3C
Tweak = 39383736353433323130
PT = 0123456789
CT = 6124200773
Count = 3
Method = FF1
Alphabet = 0123456789abcdefghijklmnopqrstuvwxyz
Key = 2B7E151628AED2A6ABF7158809CF4F3C
Tweak = 3737373770717273373737
PT = 0123456789abcdefghi
CT = a9tv40mll9kdu509eum
Count = 4
Method = FF1
Alphabet = 0123456789
Key = 2B7E151628AED2A6ABF7158809CF4F3CEF4359D8D580AA4F
Tweak =
PT = 0123456789
CT = 2830668132
Count = 5
Method = FF1
Alphabet = 0123456789
Key = 2B7E151628AED2A6ABF7158809CF4F3CEF4359D8D580AA4F
Tweak = 39383736353433323130
PT = 0123456789
CT = 2496655549
Count = 6
Method = FF1
Alphabet = 0123456789abcdefghijklmnopqrstuvwxyz
Key = 2B7E151628AED2A6ABF7158809CF4F3CEF4359D8D580AA4F
Tweak = 3737373770717273373737
PT = 0123456789abcdefghi
CT = xbj3kv35jrawxv32ysr
Count = 7
Method = FF1
Alphabet = 0123456789
Key = 2B7E151628AED2A6ABF7158809CF4F3CEF4359D8D580AA4F7F036D6F04FC6A94
Tweak =
PT = 0123456789
CT = 6657667009
Count = 8
Method = FF1
Alphabet = 0123456789
Key = 2B7E151628AED2A6ABF7158809CF4F3CEF4359D8D580AA4F7F036D6F04FC6A94
Tweak = 39383736353433323130
PT = 0123456789
CT = 1001623463
Count = 9
Method = FF1
Alphabet = 0123456789abcdefghijklmnopqrstuvwxyz
Key = 2B7E151628AED2A6ABF7158809CF4F3CEF4359D8D580AA4F7F036D6F04FC6A94
Tweak = 3737373770717273373737
PT = 0123456789abcdefghi
CT = xs8a0azh2avyalyzuwd
Count = 10
Method = FF1
Alphabet = 0123456789
Key = FA407521178EDB931997C9EF5FF4F8BB
Tweak =
PT = 5989891000
CT = 4896500946
Count = 11
Method = FF1
Alphabet = abcdefghijklmnopqrstuvwxyz
Key = D263686051802ECAE0217F4123000376
Tweak =
PT = zlwagydvpt
CT = odmrhltvlj
Count = 12
Method = FF1
Alphabet = 01
Key = f4a116d6ee406a53a56cbe0f4aa7b1001cdc0a55cac963cf5ace390488b3477a
Tweak = fd7f4b9945a3c535adb4720027116ca0f4987d7f3fdba9bbc40e75375feaa63c
PT = 00000101011011011101001001010011100111100011001
CT = 10110101001110101101110000011000000011111100111
Count = 13
Method = FF1
Alphabet = 01
Key = f4a116d6ee406a53a56cbe0f4aa7b1001cdc0a55cac963cf5ace390488b3477a
Tweak = fd7f4b9945a3c535adb4720027116ca0f4987d7f3fdba9bbc40e75375feaa63c
PT = 000010101100011111010000111001100001011010011110100100110010010000000101000011000000001111110101111100111001001001100100100110101111110000011101010111001111010000010010111110101100001001100011
CT = 111110001101110010010110001010100001101011001010011010111001001101101000011110000110110000001101011110101100001101000011101110110101001111100001011010010000010111001110010011001100001111100101
Count = 14
Method = FF1
Alphabet = 01
Key = f4a116d6ee406a53a56cbe0f4aa7b1001cdc0a55cac963cf5ace390488b3477a
Tweak = fd7f4b9945a3c535adb4720027116ca0f4987d7f3fdba9bbc40e75375feaa63c
PT = 00000111011010010101111110011110001011111000110100000101001010001100001101111000010000101011100100010111011101001010010100101010100011010101010000101111111001111100110100001100011001011010010000110
CT = 00110011001000111100010111110001000110110110010010101101001011101001101010010001111001010100100001110101010101101110110010100110101110111011111010110010101110000001101000101010100011010100111011000
Count = 15
Method = FF1
Alphabet = 01
Key = f4a116d6ee406a53a56cbe0f4aa7b1001cdc0a55cac963cf5ace390488b3477a
Tweak = fd7f4b9945a3c535adb4720027116ca0f4987d7f3fdba9bbc40e75375feaa63c
PT = 00001100010001110001000111100100001111110110000000001010000001111100000111100101110111101100101011001010010010001011100000100100011100010111111000111101010111010110011001000010000101000100000111011001000010000111001010100101111011111100111111101010001111101111101000101111101100101001000010110101011100011011001110101101001100100101101000000111100100110000001111011000110011110000011011101111001110101101111001001111010101011001100011001111001110
CT = 10101101001111110110110001010101110111011010101001110011111101101101000001110010100110110011011101000101010001111101100000110000101110000000110001011000100000111001111011101011100011100010100001010011110100010001001000001101110010110111100010101001000100100000010111100000101000010100011001100011111110011100111110011100111111011001101011100010100110001100111000100000101011111110100011110011101001010110001000011010011011101001101000001100110100
Count = 16
Method = FF1
Alphabet = 01
Key = f4a116d6ee406a53a56cbe0f4aa7b1001cdc0a55cac963cf5ace390488b3477a
Tweak = fd7f4b9945a3c535adb4720027116ca0f4987d7f3fdba9bbc40e75375feaa63c
PT = 0000100001110000110111000100110011101011100100100000011011100101010101010100111000001001001010110110101100010001111111101001100100001110000001101100101000110000001101100100110101101101111011010100010100110101110011101101001000010100110111101111000100001011010011000000000011001010110000110111110010111110001010111000011100010010100111011110010100110101000100101010010100001110010101001100010001111000011110001101011010001010110110010000111001110110101
CT = 0101111000110110000111000111011100110111101000100000100010100110100010001101000101111000100000111000000011110111001001101010100001111100100101100100000000000011100011110010100010000010001001101100011100111110101110000101111010100111100000111000000111011011010101111100110101000110001110110001110011111000111110010000100010000101010110000010010100001111011010110111011111101000100000010111101010000011011110001000000011111010110010100101001000111101110
Count = 17
Method = FF1
Alphabet = 01
Key = f4a116d6ee406a53a56cbe0f4aa7b1001cdc0a55cac963cf5ace390488b3477a
Tweak = fd7f4b9945a3c535adb4720027116ca0f4987d7f3fdba9bbc40e75375feaa63c
PT = 0000100001110000110111000100110011101011100100100000011011100101010101010100111000001001001010110110101100010001111111101001100100001110000001101100101000110000001101100100110101101101111011010100010100110101110011101101001000010100110111101111000100001011010011000000000011001010110000110111110010111110001010111000011100010010100111011110010100110101000100101010010100001110010101001100010001111000011110001101011010001010110110010000111001110110101000010000111000011011100010011001110101110010010000001101110010101010101010011100000100100101011011010110001000111111110100110010000111000000110110010100011000000110110010011010110110111101101010001010011010111001110110100100001010011011110111100010000101101001100000000001100101011000011011111001011111000101011100001110001001010011101111001010011010100010010101001010000111001010100110001000111100001111000110101101000101011011001000011100111011010100001000011100001101110001001100111010111001001000000110111001010101010101001110000010010010101101101011000100011111111010011001000011100000011011001010001100000011011001001101011011011110110101000101001101011100111011010010000101001101111011110001000010110100110000000000110010101100001101111100101111100010101110000111000100101001110111100101001101010001001010100101000011100101010011000100011110000111100011010110100010101101100100001110011101101010000100001110000110111000100110011101011100100100000011011100101010101010100111000001001001010110110101100010001111111101001100100001110000001101100101000110000001101100100110101101101111011010100010100110101110011101101001000010100110111101111000100001011010011000000000011001010110000110111110010111110001010111000011100010010100111011110010100110101000100101010010100001110010101001100010001111000011110001101011010001010110110010000111001110110101
CT = 0000010100010011101101101111101011010101110011111000100110100110001101001001111110001100001010111011001001101100011110010111111111100011111111111011100000101000000101101100011001110110011011110111011101101111110110000101000011111101100100100101010110111010101111001011000001100000100000110110110111001101010101001111101111010111010111001101101000000101100001000100100001111001001001001000001010010000101000110111010010000010010101000000111111101001011101111111000100101001100110001111001101110001010110011000000000101011001010110110011101100111001110010111011010101110100100111010111000010011010000001001001111110110001110010110111101101000001100101101100010101101010110010001001110010001100110101100011001010010011001100101010001111010100000101010011111010001110110000111101010111111101101001001110001110110111111100101001010110010011000011111110111110000010010110110111100110101000111000011010100100001101001010001110000011110001110101001010110011111100010001011001110110100000001010001010101001000011000001010010001110110001011000010010011111011101001110010100101001000011111100011111111110000110111001101101001111111010011011110101101011111010010101000100011010011111010100101011001100110110101011110110000010110111101001100000001011000010000110111100111110001101011011000010010011111101010001100010010001100111111110011101000111110101001100011010100100110110111010010010001100001101000111000000010000111101010001011111100011111001111000111001110100110010110000101000100001000001100100000100101011001000001011010000000000011100110001001011111001011101010100001101101000111101010111000101001000001100011110000101111100110110100001111001110011111111000100011000010000000110110101011101001010000001011010010101111101100100011110101110101110101010110001110100000000010100011000111011011110100111111111100
Count = 18
Method = FF1
Alphabet = 0123456789
Key = f4a116d6ee406a53a56cbe0f4aa7b1001cdc0a55cac963cf5ace390488b3477a
Tweak = fd7f4b9945a3c535adb4720027116ca0f4987d7f3fdba9bbc40e75375feaa63c
PT = 0000100001110000110111000100110011101011100100100000011011100101010101010100111000001001001010110110101100010001111111101001100100001110000001101100101000110000001101100100110101101101111011010100010100110101110011101101001000010100110111101111000100001011010011000000000011001010110000110111110010111110001010111000011100010010100111011110010100110101000100101010010100001110010101001100010001111000011110001101011010001010110110010000111001110110101000010000111000011011100010011001110101110010010000001101110010101010101010011100000100100101011011010110001000111111110100110010000111000000110110010100011000000110110010011010110110111101101010001010011010111001110110100100001010011011110111100010000101101001100000000001100101011000011011111001011111000101011100001110001001010011101111001010011010100010010101001010000111001010100110001000111100001111000110101101000101011011001000011100111011010100001000011100001101110001001100111010111001001000000110111001010101010101001110000010010010101101101011000100011111111010011001000011100000011011001010001100000011011001001101011011011110110101000101001101011100111011010010000101001101111011110001000010110100110000000000110010101100001101111100101111100010101110000111000100101001110111100101001101010001001010100101000011100101010011000100011110000111100011010110100010101101100100001110011101101010000100001110000110111000100110011101011100100100000011011100101010101010100111000001001001010110110101100010001111111101001100100001110000001101100101000110000001101100100110101101101111011010100010100110101110011101101001000010100110111101111000100001011010011000000000011001010110000110111110010111110001010111000011100010010100111011110010100110101000100101010010100001110010101001100010001111000011110001101011010001010110110010000111001110110101
CT = 3553494089916656541184478908087049735544912674297349664796606620188730753059002844128234255625871546044854395209962926784724128560713512248808687211149744598195412712940468163774096628350620951413711803950518594617373351544393856373450320087523262022383945648127372062478231148038471844014871132794421592688429360388632538622007325709023114489620502858661369331722385345630805557726657301103731476891939356540625190861223831202018869059523597995303290074121079428721457071756416572728029177746810900307020259537765410201929963086982307837186509364236956511999350147323721010332857847774386067644233703989840323109138134072973241903156111826976160812600185129257000146824574348291127595725594892501619634508128488731892352987207154538043275865206720407431701986579498575764625682405793438116486315329904924734993624192175538907728005546006779836347751281158514862256352526481718064122564580367217956237464358103196538875291283690155429858297253893898279060676625001618108275714219171491371113956773762844941034947472026591341252339034136627998253233817606250024841230463067533567089935603756301565820369079927700758805948772321763265628871349903204249162513281402250087834393259987925784678440411900598614732588243252529912937631866659880744158524571625718103685314053287308120410823249151599910726383359255592539946379861183034458490744302067049236667020141763610651851768955009732517336400650838408764716423829225801720580144333813816604222676507183341558005308742505170406478517237115923457992442034329915124651627732600793249273733794088807416454414747271994796609670521986503851051553369292884493564374526214897996510458573439669519885826154261070811550077849422033063494354368756584234578197857360235955389059655914778268996127569020343877063422715737926819877510937231474460324658469989214234346399
Count = 19
Method = FF1
Alphabet = 23456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01
Key = f4a116d6ee406a53a56cbe0f4aa7b1001cdc0a55cac963cf5ace390488b3477a
Tweak = fd7f4b9945a3c535adb4720027116ca0f4987d7f3fdba9bbc40e75375feaa63c
PT = 3456789AB2CDEFGHcdefgh
CT = 8MPH0buu9UDS9y9wfWyuxA
Count = 20
Method = FF1
Alphabet = 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()
Key = f4a116d6ee406a53a56cbe0f4aa7b1001cdc0a55cac963cf5ace390488b3477a
Tweak = fd7f4b9945a3c535adb4720027116ca0f4987d7f3fdba9bbc40e75375feaa63c
PT = 1234567890ABCDEFabcdef
CT = x%$lEuv$QuA5HykL#2WZW0
###############################################################
# FF3 test vectors
###############################################################
Count = 21
Method = FF3
Alphabet = 0123456789
Key = EF4359D8D580AA4F7F036D6F04FC6A94
Tweak = D8E7920AFA330A73
PT = 890121234567890000
CT = 750918814058654607
Count = 22
Method = FF3
Alphabet = 0123456789
Key = EF4359D8D580AA4F7F036D6F04FC6A94
Tweak = 9A768A92F60E12D8
PT = 890121234567890000
CT = 018989839189395384
Count = 23
Method = FF3
Alphabet = 0123456789
Key = EF4359D8D580AA4F7F036D6F04FC6A94
Tweak = D8E7920AFA330A73
PT = 89012123456789000000789000000
CT = 48598367162252569629397416226
Count = 24
Method = FF3
Alphabet = 0123456789abcdefghijklmnop
Key = EF4359D8D580AA4F7F036D6F04FC6A94
Tweak = 9A768A92F60E12D8
PT = 0123456789abcdefghi
CT = g2pk40i992fn20cjakb
Count = 25
Method = FF3
Alphabet = 0123456789
Key = EF4359D8D580AA4F7F036D6F04FC6A942B7E151628AED2A6
Tweak = D8E7920AFA330A73
PT = 890121234567890000
CT = 646965393875028755
Count = 26
Method = FF3
Alphabet = 0123456789
Key = EF4359D8D580AA4F7F036D6F04FC6A942B7E151628AED2A6
Tweak = 9A768A92F60E12D8
PT = 890121234567890000
CT = 961610514491424446
Count = 27
Method = FF3
Alphabet = 0123456789
Key = EF4359D8D580AA4F7F036D6F04FC6A942B7E151628AED2A6
Tweak = D8E7920AFA330A73
PT = 89012123456789000000789000000
CT = 53048884065350204541786380807
Count = 28
Method = FF3
Alphabet = 0123456789abcdefghijklmnop
Key = EF4359D8D580AA4F7F036D6F04FC6A942B7E151628AED2A6
Tweak = 9A768A92F60E12D8
PT = 0123456789abcdefghi
CT = i0ihe2jfj7a9opf9p88
Count = 29
Method = FF3
Alphabet = 0123456789
Key = EF4359D8D580AA4F7F036D6F04FC6A942B7E151628AED2A6ABF7158809CF4F3C
Tweak = D8E7920AFA330A73
PT = 890121234567890000
CT = 922011205562777495
Count = 30
Method = FF3
Alphabet = 0123456789
Key = EF4359D8D580AA4F7F036D6F04FC6A942B7E151628AED2A6ABF7158809CF4F3C
Tweak = 9A768A92F60E12D8
PT = 890121234567890000
CT = 504149865578056140
Count = 31
Method = FF3
Alphabet = 0123456789
Key = EF4359D8D580AA4F7F036D6F04FC6A942B7E151628AED2A6ABF7158809CF4F3C
Tweak = D8E7920AFA330A73
PT = 89012123456789000000789000000
CT = 04344343235792599165734622699
Count = 32
Method = FF3
Alphabet = 0123456789abcdefghijklmnop
Key = EF4359D8D580AA4F7F036D6F04FC6A942B7E151628AED2A6ABF7158809CF4F3C
Tweak = 9A768A92F60E12D8
PT = 0123456789abcdefghi
CT = p0b2godfja9bhb7bk38
###############################################################
# FF3-1 test vectors
###############################################################
Count = 33
Method = FF3-1
Alphabet = 0123456789
Key = EF4359D8D580AA4F7F036D6F04FC6A94
Tweak = 0000000000000000
PT = 89012123456789000000789000000
CT = 34695224821734535122613701434
Count = 34
Method = FF3-1
Alphabet = 0123456789
Key = EF4359D8D580AA4F7F036D6F04FC6A942B7E151628AED2A6
Tweak = 0000000000000000
PT = 89012123456789000000789000000
CT = 98083802678820389295041483512
Count = 35
Method = FF3-1
Alphabet = 0123456789
Key = EF4359D8D580AA4F7F036D6F04FC6A942B7E151628AED2A6ABF7158809CF4F3C
Tweak = 0000000000000000
PT = 89012123456789000000789000000
CT = 30859239999374053872365555822
Count = 36
Method = FF3-1
Alphabet = 0123456789
Key = 2DE79D232DF5585D68CE47882AE256D6
Tweak = CBD09280979564
PT = 3992520240
CT = 8901801106
Count = 37
Method = FF3-1
Alphabet = 0123456789
Key = 01C63017111438F7FC8E24EB16C71AB5
Tweak = C4E822DCD09F27
PT = 60761757463116869318437658042297305934914824457484538562
CT = 35637144092473838892796702739628394376915177448290847293
Count = 38
Method = FF3-1
Alphabet = abcdefghijklmnopqrstuvwxyz
Key = 718385E6542534604419E83CE387A437
Tweak = B6F35084FA90E1
PT = wfmwlrorcd
CT = ywowehycyd
Count = 39
Method = FF3-1
Alphabet = abcdefghijklmnopqrstuvwxyz
Key = DB602DFF22ED7E84C8D8C865A941A238
Tweak = EBEFD63BCC2083
PT = kkuomenbzqvggfbteqdyanwpmhzdmoicekiihkrm
CT = belcfahcwwytwrckieymthabgjjfkxtxauipmjja
Count = 40
Method = FF3-1
Alphabet = 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/
Key = AEE87D0D485B3AFD12BD1E0B9D03D50D
Tweak = 5F9140601D224B
PT = ixvuuIHr0e
CT = GR90R1q838
Count = 41
Method = FF3-1
Alphabet = 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/
Key = 7B6C88324732F7F4AD435DA9AD77F917
Tweak = 3F42102C0BAB39
PT = 21q1kbbIVSrAFtdFWzdMeIDpRqpo
CT = cvQ/4aGUV4wRnyO3CHmgEKW5hk8H
Count = 42
Method = FF3-1
Alphabet = 0123456789
Key = F62EDB777A671075D47563F3A1E9AC797AA706A2D8E02FC8
Tweak = 493B8451BF6716
PT = 4406616808
CT = 1807744762
Count = 43
Method = FF3-1
Alphabet = 0123456789
Key = 0951B475D1A327C52756F2624AF224C80E9BE85F09B2D44F
Tweak = D679E2EA3054E1
PT = 99980459818278359406199791971849884432821321826358606310
CT = 84359031857952748660483617398396641079558152339419110919
Count = 44
Method = FF3-1
Alphabet = abcdefghijklmnopqrstuvwxyz
Key = 49CCB8F62D941E5684599ECA0300937B5C766D053E109777
Tweak = 0BFCF75CDC2FC1
PT = jaxlrchjjx
CT = kjdbfqyahd
Count = 45
Method = FF3-1
Alphabet = abcdefghijklmnopqrstuvwxyz
Key = 03D253674A9309FF07ED0E71B24CBFE769025E09FCE544D7
Tweak = B33176B1DA0F6C
PT = tafzrybuvhiqvcyztuxfnwfprmqlwpayphxbawpl
CT = loaemzbgqkywkdhmncrijzildzleoqibtthdiliv
Count = 46
Method = FF3-1
Alphabet = 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/
Key = 1C24B74B7C1B9969314CB53E92F98EFD620D5520017FB076
Tweak = 0380341C425A6F
PT = 6np8r2t8zo
CT = HgpCXoA1Rt
Count = 47
Method = FF3-1
Alphabet = 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/
Key = C0ABADFC071379824A070E8C3FD40DD9BFD7A3C99A0D5FE3
Tweak = 6C2926C705DDAF
PT = GKB6sa9g56BSJ09iJ4dsaxRdsMvo
CT = gC0tTSdDPxM79QOWi+z+SNL9C4V+
Count = 48
Method = FF3-1
Alphabet = 0123456789
Key = 1FAA03EFF55A06F8FAB3F1DC57127D493E2F8F5C365540467A3A055BDBE6481D
Tweak = 4D67130C030445
PT = 3679409436
CT = 1735794859
Count = 49
Method = FF3-1
Alphabet = 0123456789
Key = 9CE16E125BD422A011408EB083355E7089E70A4CD2F59E141D0B94A74BCC5967
Tweak = 4684635BD2C821
PT = 85783290820098255530464619643265070052870796363685134012
CT = 75104723514036464144839960480545848044718729603261409917
Count = 50
Method = FF3-1
Alphabet = abcdefghijklmnopqrstuvwxyz
Key = 6187F8BDE99F7DAF9E3EE8A8654308E7E51D31FA88AFFAEB5592041C033B736B
Tweak = 5820812B3D5DD1
PT = mkblaoiyfd
CT = ifpyiihvvq
Count = 51
Method = FF3-1
Alphabet = abcdefghijklmnopqrstuvwxyz
Key = F6807FB9688937E4D4956006C8F0CB2394148A5F4B14666CF353F4941428FFD7
Tweak = 30C87B99890096
PT = wrammvhudopmaazlsxevzwzwpezzmghwfnmkitnk
CT = nzftnfkliuctlmtdfrxfhwgevrbcbgljurnytxkj
Count = 52
Method = FF3-1
Alphabet = 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/
Key = 9C2B69F7DDF181C54398E345BE04C2F6B00B9DD1679200E1E04C4FF961AE0F09
Tweak = 103C238B4B1E44
PT = H2/c6FblSA
CT = EOg4H1bE+8
Count = 53
Method = FF3-1
Alphabet = 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/
Key = C58BCBD08B90006CEC7E82B2D987D79F6A21111DEF0CEBB273CBAEB2D6CD4044
Tweak = 7036604882667B
PT = bz5TcS1krnD8IOLdrQeKzXkLAa6h
CT = Z6x3/9LPW8SZunRezRM8J68Q4J03
Count = 54
Method = FF3-1
Alphabet = 0123456789abcdefghijklmnopqrstuvwxyz
Key = ef4359d8d580aa4f7f036d6f04fc6a943b806aeb6308271f65cf33c7391b27f7
Tweak = 37373737707172
PT = 89012123456789abcde
CT = 0sxaooj0jjj5qqfomh8

167
testvectors/FPEtest.c Normal file
View File

@@ -0,0 +1,167 @@
/*
==============================================================================
Name : FPEtest.c
Author : polfosol
Version : 1.4.1.0
Copyright : copyright © 2022 - polfosol
Description : illustrating how to validate NIST's vectors for AES-FPE mode
==============================================================================
*/
#include <stdio.h>
#include "../micro_aes.h"
#define TESTFILEPATH "FPE_FF1&FF3&FF3-1.tv"
static void str2bytes(const char* hex, uint8_t* bytes)
{
unsigned shl = 0;
for (--bytes; *hex; ++hex)
{
if (*hex < '0' || 'f' < *hex) continue;
if ((shl ^= 4) != 0) *++bytes = 0;
*bytes |= (*hex % 16 + (*hex > '9') * 9) << shl;
}
}
static void bytes2str(const uint8_t* bytes, char* str, const size_t len)
{
const char offset = 0x27; /* offset must be 7 for uppercase */
size_t i = len + len, shr = 0;
for (str[i] = 0; i--; shr ^= 4)
{
str[i] = bytes[i / 2] >> shr & 0xF | '0';
if (str[i] > '9') str[i] += offset;
}
}
static int ciphertest(uint8_t* key, uint8_t* tk, char* a, char* p, char* c,
size_t n, size_t nt, char* r)
{
char sk[2*AES_KEY_SIZE + 1], st[65], msg[30], tmp[0x800], t = 0;
sprintf(msg, "%s", "passed the test");
#if FF_X == 3
AES_FPE_encrypt(key, tk, p, n, tmp);
#else
AES_FPE_encrypt(key, tk, nt, p, n, tmp);
#endif
if (memcmp(c, tmp, n))
{
sprintf(msg, "%s", "encrypt failure");
t = 1;
}
memset(tmp, 0xcc , sizeof tmp);
#if FF_X == 3
AES_FPE_decrypt(key, tk, c, n, tmp);
#else
AES_FPE_decrypt(key, tk, nt, c, n, tmp);
#endif
if (memcmp(p, tmp, n))
{
sprintf(msg, "%sdecrypt failure", t ? "encrypt & " : "");
t |= 2;
}
bytes2str(key, sk, AES_KEY_SIZE);
bytes2str(tk, st, nt);
sprintf(r, "%s\nA: %s\nK: %s\nT: %s\nP: %s\nC: %s", msg, a, sk, st, p, c);
return t;
}
int main()
{
const char *linehdr[] =
{
"Method = ", "Alphabet = ", "Key = ", "Tweak = ", "PT = ", "CT = "
}, *alphabets[] =
{
"0123456789", "01", "abcdefghijklmnopqrstuvwxyz",
"0123456789abcdefghijklmnopqrstuvwxyz", "*", "*", "*", "0123456789abcdefghijklmnop",
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"
};
char buffer[0x1000], alpha[90], p[0x800], c[0x800], m[6], a = 0, *value = "";
size_t pass = 0, df = 0, ef = 0, sp = 0, st = 0;
uint8_t i, key[2*AES_KEY_SIZE], twk[32], sk = 0, n = 0;
FILE *fp, *fs, *ferr;
fp = fopen(TESTFILEPATH, "r");
fs = fopen("passed.log", "w");
ferr = fopen("failed.log", "w");
if (fp == NULL)
{
printf("File not found: %s\n", TESTFILEPATH);
return 1;
}
if (!fs || !ferr) return 1;
while (fgets(buffer, sizeof buffer, fp) != NULL)
{
buffer[strcspn(buffer, "\n")] = 0;
if (strlen(buffer) < 4) continue;
for (i = 0; i < 6; i++)
{
if (strncmp(buffer, linehdr[i], strlen(linehdr[i])) == 0)
{
value = strrchr(buffer, ' ') + 1;
break;
}
}
switch (i)
{
case 0:
strcpy(m, value);
break;
case 1:
for (i = 0; i < 9; i++)
{
if ((a = strlen(alphabets[i])) != strlen(value)) continue;
if (strncmp(value, alphabets[i], a) == 0) break;
}
strcpy(alpha, value); a = i;
break;
case 2:
sk = strlen(value) / 2;
str2bytes(value, key);
break;
case 3:
st = strlen(value) / 2; ++n;
str2bytes(value, twk);
break;
case 4:
sp = strlen(value);
strcpy(p, value);
break;
case 5:
++n;
strcpy(c, value);
break;
}
if (n == 2)
{
n = (FF_X == 3) ^ (m[2] != '3');
#if FF3_TWEAK_LEN == 8
n &= (st == 8); /* old FF3 with 8-byte tweak */
#else
n &= FF_X != 3 || !(st == 8 && twk[7]); /* FF3-1 */
#endif
if (n && a == CUSTOM_ALPHABET && sk == AES_KEY_SIZE)
{
n = ciphertest(key, twk, alpha, p, c, sp, st, buffer);
fprintf(n ? ferr : fs, "%s\n\n", buffer); /* save the log */
if (n == 0) ++pass;
if (n & 1) ++ef;
if (n & 2) ++df;
}
n = 0;
}
}
printf ("test cases: %d\nsuccessful: %d\nfailed encrypt: %d, failed decrypt: %d\n",
pass + (ef > df ? ef : df), pass, ef, df);
fclose(fp); fclose(fs); fclose(ferr);
if (ef + df == 0)
{
remove("passed.log"); remove("failed.log");
}
return 0;
}

46
testvectors/FPEtest.cbp Normal file
View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="FPEtest" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/testvecs" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-pedantic" />
<Add option="-ansi" />
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/testvecs" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
<Add option="-pedantic" />
<Add option="-ansi" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Unit filename="../micro_aes.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../micro_aes.h" />
<Unit filename="FPEtest.c">
<Option compilerVar="CC" />
</Unit>
<Extensions>
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@@ -2,9 +2,9 @@
==============================================================================
Name : GCMtest.c
Author : polfosol
Version : 2.0.0.0
Version : 2.0.1.1
Copyright : copyright © 2022 - polfosol
Description : illustrating how the NIST's vectors for AES-GCM mode are used
Description : illustrating how to validate NIST's vectors for AES-GCM mode
==============================================================================
*/
@@ -13,36 +13,34 @@
#define TESTFILEPATH "GCM_EncryptExtIV128.rsp"
static void str2bytes(const char* str, uint8_t* bytes)
#define char2num(c) (c > '9' ? (c & 7) + 9 : c & 0xF)
static void str2bytes(const char* hex, uint8_t* bytes)
{
size_t i, j;
for (i = 0, j = ~0; str[i]; ++i)
unsigned shl = 0;
for (--bytes; *hex; ++hex)
{
if (str[i] < '0' || str[i] > 'f') continue;
if (j++ & 1) bytes[j / 2] = char2num(str[i]) << 4;
else bytes[j / 2] |= char2num(str[i]);
if (*hex < '0' || 'f' < *hex) continue;
if ((shl ^= 4) != 0) *++bytes = 0;
*bytes |= (*hex % 16 + (*hex > '9') * 9) << shl;
}
}
static void bytes2str(const uint8_t* bytes, char* str, size_t len)
#define num2char(x) ((x) > 9 ? 'a' - 10 + (x) : '0' + (x))
static void bytes2str(const uint8_t* bytes, char* str, const size_t len)
{
size_t i, j;
for (i = 0, j = 0; i < len; ++i)
const char offset = 0x27; /* offset must be 7 for uppercase */
size_t i = len + len, shr = 0;
for (str[i] = 0; i--; shr ^= 4)
{
str[j++] = num2char(bytes[i] >> 4);
str[j++] = num2char(bytes[i] & 15);
str[i] = bytes[i / 2] >> shr & 0xF | '0';
if (str[i] > '9') str[i] += offset;
}
str[j] = 0;
}
static int ciphertest(uint8_t* key, uint8_t* iv, uint8_t* p, uint8_t* a, uint8_t* c,
uint8_t np, uint8_t na, uint8_t nt, char* r)
size_t np, size_t na, uint8_t nt, char* r)
{
char sk[70], si[GCM_NONCE_LEN*2+6], sp[0x100], sc[0x100], sa[0x100], msg[30];
char sk[65], si[2*GCM_NONCE_LEN + 1], sp[0x100], sc[0x100], sa[0x100], msg[30];
uint8_t tmp[0x80], t = 0;
sprintf(msg, "%s", "success");
sprintf(msg, "%s", "passed the test");
AES_GCM_encrypt(key, iv, p, np, a, na, tmp, tmp + np);
if (memcmp(c, tmp, np + nt))
@@ -56,7 +54,7 @@ static int ciphertest(uint8_t* key, uint8_t* iv, uint8_t* p, uint8_t* a, uint8_t
{
sprintf(msg, "%sdecrypt failure", t & 1 ? "encrypt & " : "");
}
bytes2str(key, sk, AES_KEY_LENGTH);
bytes2str(key, sk, AES_KEY_SIZE);
bytes2str(iv, si, GCM_NONCE_LEN);
bytes2str(p, sp, np);
bytes2str(a, sa, na);
@@ -70,7 +68,7 @@ int main()
const char *linehdr[] = { "Key = ", "IV = ", "AAD = ", "PT = ", "CT = ", "Tag = " };
char buffer[0x800], *value = "", *line = "";
size_t pass = 0, df = 0, ef = 0, sk = 0, sn = 0, sp = 0, sa = 0, st = 0;
uint8_t key[AES_KEY_LENGTH], tmp[AES_KEY_LENGTH], iv[GCM_NONCE_LEN];
uint8_t key[AES_KEY_SIZE], tmp[AES_KEY_SIZE], iv[GCM_NONCE_LEN];
uint8_t i, p[96], c[112], a[96], t[16], rc = 1;
FILE *fp, *fs, *ferr;
@@ -104,7 +102,7 @@ int main()
{
case 0:
sk = strlen(value) / 2;
if (sk == AES_KEY_LENGTH) str2bytes(value, tmp);
if (sk == AES_KEY_SIZE) str2bytes(value, tmp);
break;
case 1:
sn = strlen(value) / 2;
@@ -128,7 +126,7 @@ int main()
}
if (i == 0 || line == NULL)
{
if (!rc && sn == GCM_NONCE_LEN && sk == AES_KEY_LENGTH)
if (!rc && sn == GCM_NONCE_LEN && sk == AES_KEY_SIZE)
{
memcpy(c + sp, t, st); /* put tag at the end */
rc = ciphertest(key, iv, p, a, c, sp, sa, st, buffer);
@@ -145,7 +143,7 @@ int main()
}
} while (line != NULL);
printf ("test cases: %d\nsuccessful: %d\nfailed encrypt: %d, failed decrypt: %d\n",
pass + ef + df, pass, ef, df);
pass + (ef > df ? ef : df), pass, ef, df);
fclose(fp); fclose(fs); fclose(ferr);
if (ef + df == 0)

View File

@@ -2,9 +2,9 @@
==============================================================================
Name : OCBtest.c
Author : polfosol
Version : 1.1.0.0
Version : 1.1.1.1
Copyright : copyright © 2022 - polfosol
Description : illustrating how the OpenSSL's vectors for AES-OCB mode are used
Description : illustrating how to validate OpenSSL's vectors for AES-OCB mode
==============================================================================
*/
@@ -13,36 +13,34 @@
#define TESTFILEPATH "OCB_AES128.tv"
static void str2bytes(const char* str, uint8_t* bytes)
#define char2num(c) (c > '9' ? (c & 7) + 9 : c & 0xF)
static void str2bytes(const char* hex, uint8_t* bytes)
{
size_t i, j;
for (i = 0, j = ~0; str[i]; ++i)
unsigned shl = 0;
for (--bytes; *hex; ++hex)
{
if (str[i] < '0' || str[i] > 'f') continue;
if (j++ & 1) bytes[j / 2] = char2num(str[i]) << 4;
else bytes[j / 2] |= char2num(str[i]);
if (*hex < '0' || 'f' < *hex) continue;
if ((shl ^= 4) != 0) *++bytes = 0;
*bytes |= (*hex % 16 + (*hex > '9') * 9) << shl;
}
}
static void bytes2str(const uint8_t* bytes, char* str, size_t len)
#define num2char(x) ((x) > 9 ? 'a' - 10 + (x) : '0' + (x))
static void bytes2str(const uint8_t* bytes, char* str, const size_t len)
{
size_t i, j;
for (i = 0, j = 0; i < len; ++i)
const char offset = 0x27; /* offset must be 7 for uppercase */
size_t i = len + len, shr = 0;
for (str[i] = 0; i--; shr ^= 4)
{
str[j++] = num2char(bytes[i] >> 4);
str[j++] = num2char(bytes[i] & 15);
str[i] = bytes[i / 2] >> shr & 0xF | '0';
if (str[i] > '9') str[i] += offset;
}
str[j] = 0;
}
static int ciphertest(uint8_t* key, uint8_t* iv, uint8_t* p, uint8_t* a, uint8_t* c,
uint8_t np, uint8_t na, uint8_t err, char* r)
size_t np, size_t na, uint8_t err, char* r)
{
char sk[70], si[30], sp[0x100], sc[0x100], sa[0x100], msg[30];
char sk[2*AES_KEY_SIZE + 1], si[31], sp[0x100], sc[0x100], sa[0x100], msg[30];
uint8_t tmp[0x90], t = 0;
sprintf(msg, "%s", "success");
sprintf(msg, "%s", "passed the test");
AES_OCB_encrypt(key, iv, p, np, a, na, tmp, tmp + np);
if (memcmp(c, tmp, np + OCB_TAG_LEN) && !err)
@@ -56,7 +54,7 @@ static int ciphertest(uint8_t* key, uint8_t* iv, uint8_t* p, uint8_t* a, uint8_t
{
sprintf(msg, "%sdecrypt failure", t & 1 ? "encrypt & " : "");
}
bytes2str(key, sk, AES_KEY_LENGTH);
bytes2str(key, sk, AES_KEY_SIZE);
bytes2str(iv, si, OCB_NONCE_LEN);
bytes2str(p, sp, np);
bytes2str(a, sa, na);
@@ -71,7 +69,7 @@ int main()
{ "Key = ", "IV = ", "AAD = ", "Plaintext = ", "Ciphertext = ", "Tag = ", "Result = " };
char buffer[0x800], *value = "";
size_t pass = 0, df = 0, ef = 0, sk = 0, sn = 0, sp = 0, sa = 0, st = 0;
uint8_t key[AES_KEY_LENGTH], tmp[AES_KEY_LENGTH], iv[OCB_NONCE_LEN];
uint8_t key[AES_KEY_SIZE], tmp[AES_KEY_SIZE], iv[OCB_NONCE_LEN];
uint8_t i, p[0x80], c[0x90], a[0x80], t[16], rc = 1;
FILE *fp, *fs, *ferr;
@@ -102,7 +100,7 @@ int main()
{
case 0:
sk = strlen(value) / 2;
if (sk == AES_KEY_LENGTH) str2bytes(value, tmp);
if (sk == AES_KEY_SIZE) str2bytes(value, tmp);
break;
case 1:
sn = strlen(value) / 2;
@@ -130,7 +128,7 @@ int main()
}
if (i == 0 || i > 7)
{
if (!rc && sk == AES_KEY_LENGTH && sn == OCB_NONCE_LEN && st == OCB_TAG_LEN)
if (!rc && sk == AES_KEY_SIZE && sn == OCB_NONCE_LEN && st == OCB_TAG_LEN)
{
memcpy(c + sp, t, st); /* put tag at the end */
rc = ciphertest(key, iv, p, a, c, sp, sa, i, buffer);
@@ -147,7 +145,7 @@ int main()
}
}
printf ("test cases: %d\nsuccessful: %d\nfailed encrypt: %d, failed decrypt: %d\n",
pass + ef + df, pass, ef, df);
pass + (ef > df ? ef : df), pass, ef, df);
fclose(fp); fclose(fs); fclose(ferr);
if (ef + df == 0)

View File

@@ -2,7 +2,7 @@
==============================================================================
Name : Poly1305test.c
Author : polfosol
Version : 1.1.0.0
Version : 1.1.1.1
Copyright : copyright © 2022 - polfosol
Description : illustrating how the test vectors of Poly1305-AES are processed
==============================================================================
@@ -13,41 +13,39 @@
#define TESTFILEPATH "Poly1305AES128.tv"
static void str2bytes(const char* str, uint8_t* bytes)
#define char2num(c) (c > '9' ? (c & 7) + 9 : c & 0xF)
static void str2bytes(const char* hex, uint8_t* bytes)
{
size_t i, j;
for (i = 0, j = ~0; str[i]; ++i)
unsigned shl = 0;
for (--bytes; *hex; ++hex)
{
if (str[i] < '0' || str[i] > 'f') continue;
if (j++ & 1) bytes[j / 2] = char2num(str[i]) << 4;
else bytes[j / 2] |= char2num(str[i]);
if (*hex < '0' || 'f' < *hex) continue;
if ((shl ^= 4) != 0) *++bytes = 0;
*bytes |= (*hex % 16 + (*hex > '9') * 9) << shl;
}
}
static void bytes2str(const uint8_t* bytes, char* str, size_t len)
#define num2char(x) ((x) > 9 ? 'a' - 10 + (x) : '0' + (x))
static void bytes2str(const uint8_t* bytes, char* str, const size_t len)
{
size_t i, j;
for (i = 0, j = 0; i < len; ++i)
const char offset = 0x27; /* offset must be 7 for uppercase */
size_t i = len + len, shr = 0;
for (str[i] = 0; i--; shr ^= 4)
{
str[j++] = num2char(bytes[i] >> 4);
str[j++] = num2char(bytes[i] & 15);
str[i] = bytes[i / 2] >> shr & 0xF | '0';
if (str[i] > '9') str[i] += offset;
}
str[j] = 0;
}
static int ciphertest(uint8_t* key, uint8_t* nnc, uint8_t* d, uint8_t* m, size_t ds, char* r)
{
char sk[2*AES_KEY_LENGTH + 40], smac[40], msg[30];
char sk[2*AES_KEY_SIZE + 33], smac[33], msg[30];
uint8_t tmp[32], t = 0;
sprintf(msg, "%s", "success");
sprintf(msg, "%s", "passed the test");
AES_Poly1305(key, nnc, d, ds, tmp);
t = memcmp(m, tmp, 16);
if (t) sprintf(msg, "%s", "failed");
bytes2str(key, sk, AES_KEY_LENGTH + 16);
bytes2str(key, sk, AES_KEY_SIZE + 16);
bytes2str(m, smac, 16);
sprintf(r, "%s\nK: %s\npoly: %s\n", msg, sk, smac);
return t;
@@ -58,7 +56,7 @@ int main()
const char *linehdr[] = { "Keys = ", "Nonce = ", "Msg = ", "PolyMac = " };
char buffer[0x20100], *value = "";
size_t pass = 0, nf = 0, sk = 0, sd = 0;
uint8_t i, n = 0, key[AES_KEY_LENGTH + 16], nc[16], d[0x10100], m[16];
uint8_t i, n = 0, key[AES_KEY_SIZE + 16], nc[16], d[0x10100], m[16];
FILE *fp, *fs, *ferr;
fp = fopen(TESTFILEPATH, "r");
@@ -88,7 +86,7 @@ int main()
{
case 0:
sk = strlen(value) / 2;
if (sk == AES_KEY_LENGTH + 16) str2bytes(value, key);
if (sk == AES_KEY_SIZE + 16) str2bytes(value, key);
break;
case 1:
str2bytes(value, nc);
@@ -105,7 +103,7 @@ int main()
}
if (n == 2)
{
if (sk == AES_KEY_LENGTH + 16)
if (sk == AES_KEY_SIZE + 16)
{
n = ciphertest(key, nc, d, m, sd, buffer);
fprintf(n ? ferr : fs, "%s\n", buffer); /* save the log */

View File

@@ -1,6 +1,8 @@
### Testing µAES
---
This folder contains some of the NIST's official [CAVP](https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/cavp-testing-block-cipher-modes) test vectors. The `*.rsp` files are courtesy of the NIST. Some sample codes are provided alongside them to illustrate how they are used. The test vectors of OCB mode are borrowed from [OpenSSL](https://github.com/openssl/openssl/blob/5a7bc0be97dee9ac715897fe8180a08e211bc6ea/test/evpciph.txt).
This folder contains some of the NIST's official [CAVP](https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/cavp-testing-block-cipher-modes) test vectors. The `*.rsp` files are courtesy of the NIST. Some sample codes are provided alongside them to demonstrate how they are used. As of late 2022, they have set up an [official repository](https://github.com/usnistgov/ACVP-Server) for cryptographic algorithm validation.
To do some extra tests, a bunch of additional FPE test vectors are taken from [[1](https://github.com/ubiqsecurity/ubiq-fpe-c/tree/master/src/test), [2](https://github.com/mysto/python-fpe/tree/main/ff3), [3](https://github.com/0NG/Format-Preserving-Encryption)], and the OCB test vectors are borrowed from [OpenSSL](https://github.com/openssl/openssl/blob/5a7bc0be97dee9ac715897fe8180a08e211bc6ea/test/evpciph.txt).
Also in the `main.c` file of parent directory, you will find some other test vectors that are either generated by the [Crypto++®](https://www.cryptopp.com) library or taken from various online documents. Please let me know if you faced any issues in verifying them.

821
testvectors/SIV_GCM_ACVP.tv Normal file
View File

@@ -0,0 +1,821 @@
# ACVP-AES-GCM-SIV-1.0
# Borrowed from ACVP-Server:
# https://github.com/usnistgov/ACVP-Server/tree/master/gen-val/json-files/ACVP-AES-GCM-SIV-1.0
#
Count = 1
pt =
key = 312E9DD81301647F47FA2E5281233EF1
aad =
iv = 9CA3721AAF612D03100095DC
ct = 26CA12DDBCDE0D8AF9B0393EE8253392
Count = 2
pt =
key = 5190547597E652810E047148EB0F83EA
aad =
iv = 795BC62FD83633F9FBDDD4EC
ct = 5328711791D48874940B59E1C197F8AF
Count = 3
pt =
key = E008596478366607798935C2B80C6251
aad =
iv = A6D4E66FFD4EAEC1D5BEB5A4
ct = 733C162B9CDADFB41CF2E2F32D65B1A8
Count = 4
pt =
key = 7651C6896ED51904583B2F146DCB425D
aad =
iv = F40FE960F35227B9620DA9E7
ct = 6D9D69D2C64FF1BBA9CFFBFDB31CA254
Count = 5
pt =
key = 7646382F186BC2CCA9808F28FAFD0FAD
aad =
iv = 1E4D23775A86FD8A7944FF09
ct = 06382CF4365CAD7B06C629774124B5CA
Count = 6
pt =
key = 00657B00613A2B6F7E0F29574F56035A
aad =
iv = BF7F42F9CACA0818D0E7DF29
ct = 777BD4E3AF363DD94F4CBA0AF5CB60F7
Count = 7
pt =
key = D0601288F6A219C5100951A9DD56424B
aad =
iv = 566667C37FF9591A07AE4445
ct = 0BDE05F1B8BA4999B24F1B708F8B671F
Count = 8
pt =
key = 54975987BD75990BDC81D74501E0E126
aad =
iv = 1869A0843830CFF0A0F4B6E3
ct = F3EF2451336613F513E8E60A4DFB0E05
Count = 9
pt =
key = 983985090BB929ECC2BE53A67E3F9B3C
aad =
iv = E2A2F703C37D0BDFCBE3DD67
ct = 2F12D3EAB58F5B5C1FEABF60409CD51D
Count = 10
pt =
key = 178C0842E749EF27B6644DF3415A508A
aad =
iv = 7C549CD9A5CB3E1040FAE641
ct = 6D43942D85530602FB39E8CD1324D9B1
Count = 11
pt =
key = 6D1BC37659AB04D77712899E5F3F87BE
aad =
iv = C95D8CE586387845A779CD4D
ct = 0828C0296B2CB13C6E8ECAD60F4F287C
Count = 12
pt =
key = 1B508785F2FEF4EFED4438F613827D7F
aad =
iv = C3CF0C1D9C598A2B682307B1
ct = EC439F858169CAC36687FECC48756AB6
Count = 13
pt =
key = 285F84901D011EA314A97937CD9481FC
aad =
iv = 8E4AE113E8AC08B4353A54CE
ct = A71E479E751BBAF9A31278E3A3E4B7F6
Count = 14
pt =
key = D7EB662EB29335E546DCB46F39C8D1E9
aad =
iv = 588B88F22BD213CEE3B21D50
ct = 37ABA8E7CAAD44EB300A5B75BCE2E28E
Count = 15
pt =
key = CF5EE8E7C7435AD05E6D264A2C507F62
aad =
iv = FD2CFA086E55499F8DECEB1F
ct = 6DBA7D89D0E90163C09F5646D724C6C7
Count = 16
pt =
key = 10C975B5BC0E62B93526BC81D348A533
aad = C78763F666B789C626E3A7F34169E4
iv = 29CE94A5F4A1C66059E93F1C
ct = AF003692B8011D318C9AC4D5E3EE4958
Count = 17
pt =
key = 5C13D25E6A588563E8718A4E118C171E
aad = DDECE7EE7E28B90E8FD33D1D8E3A04
iv = 6C8A666E5D2B3892383E7068
ct = F78C376229C9D6FBF665D037000AB762
Count = 18
pt =
key = 20C377120156198290930CCBD51D9AE6
aad = DF8886FF4322EAB106F7270D85767E
iv = 3799082343F6354D27D34094
ct = AFAAE0FD0811DEAE234347E14D656831
Count = 19
pt =
key = F9122C9A4D24B1C172CC3B3BAA834F76
aad = 2633193282F1D8C1B68620EFA6AE40
iv = 188800B4D9E041E69A025272
ct = C1F0CF22A644A50C28C0F0859661AB4D
Count = 20
pt =
key = 68662C5029454E7F7E9760082FBEECD4
aad = 80CAFA5F9D22EE99F20A0397F1690C
iv = 2264527E5AA1F3EBBAA0717B
ct = B438173C7A1EDDB726351DBCE04F1B36
Count = 21
pt =
key = A6317EDAD141FD8F682261B5C238BC83
aad = C31E9A48215018E69DC7E894F5DB32
iv = E80CE799D938F333071363AD
ct = B2D51B5988532F960FEED61F238AFB38
Count = 22
pt =
key = CC99D350B5EE4F15F13D1EFFC42442B4
aad = D666592131A4A1E14A891104CC39D1
iv = ECCC9687F82D38812C371C55
ct = 2D517FDE4C35357529A5BB26A976524D
Count = 23
pt =
key = DA9A2403052A6E1C2C7F477EA0694A8D
aad = B332699F49A2F085D16FF95024E12A
iv = 18A22FAE6084A7ED2E2B95AF
ct = 8DA6230D1D2A83D9D702F70DE5CB05E5
Count = 24
pt =
key = 06E169444D159001471D9DF841EF0E17
aad = 74FE1B912029D3BD9162410483A388
iv = B05A8FBAEE6EEC0CFAF3B6BB
ct = 06714F9637CC64868E757AB442A4C908
Count = 25
pt =
key = CD1DD32692EA23BFB53D20CB12192B28
aad = C207F92CEBB62445C1D5EFC90BCDEE
iv = 4282487F569B29C9F37F7273
ct = 062351873C3B3A6ECC3B08C934D73109
Count = 26
pt =
key = 382B1E3A6B8D24D9C3774DBE92BDD2EE
aad = 15BA92D5A6A84C5E88B3735FEB5797
iv = 3F3169C623FE9ECB97A1DF79
ct = D2AC5BF3077FE6AA19BC955AA443BA33
Count = 27
pt =
key = 2D54036DD744A19A3A45B8F3B21D7485
aad = A72F9E70DAE2877F1CFED9F6F3D864
iv = 86034FD2141B204F51FCEEEC
ct = F09BAFD78883F4C7A5BA6FFCB4F636CF
Count = 28
pt =
key = A21FA9FBAC7C58C9D58AE44E80F4658F
aad = C8C57C4D21C5EEDB94EBC7CE605F7D
iv = 20314BA58B8494EA2B2BFCBB
ct = DD014E782EEF03FB56FFC5F160149226
Count = 29
pt =
key = A14615E136702686335D6B018660CD06
aad = 1FB46FEAF2628115C93CABEC929B07
iv = 326F45E341240B7C3D4A52DF
ct = 5F001BEDDCCCD304DD6FEF2B32242AE1
Count = 30
pt =
key = 3D2C147B938E5AB851DCB28A38FD8410
aad = 13E8F439415D89731D621BD216EAB0
iv = 2AB889C6A4E983DB20515169
ct = 0354282E336D8974654A50135F01FAB9
Count = 31
pt = AE69B95B1CAF65F1ABD0A8CEB43D10
key = 37204932035A61997A9AF1F4E1825084
aad =
iv = 734AA6722506BB50DDD3D5E4
ct = 9DBA45471EF43DC292185089653BBA3870EDC07971B04B9615EA3D5860A59A
Count = 32
pt = 1BCE62672D91B3130634B8E25EBBB8
key = C549658540F30B1852D874E767BFFC12
aad =
iv = D65063721BE490551C06B3AC
ct = 79900966E3987337A6A34BABF23032CC10417D036E7471DF2E3170EE5BE4C0
Count = 33
pt = 16C7CB49E57CED7D53816AC375F804
key = 7C1F59EB0E5CF52E93305D3D844E9684
aad =
iv = 845214D1E0459257AE3ECBF5
ct = 581603997A475AD5A54059C59EE0A21B733650C4D8DCABE473B8CD8CC5AB8A
Count = 34
pt = DBD1EA273AB50A339F0C83D46C22D3
key = 53F2648A1F8F10992CBA536254F5FB18
aad =
iv = F0DB358FC2B636BB24F7F3EE
ct = CF0C845CAD06E3DA1700624A13352C03D8663A3DEEA0B93BFD5265E1DA79AE
Count = 35
pt = CAD687F39A3CDFAAC39FFDFA89882F
key = 6CEE09CEE81AA6F22FA8B0968D1EF9C9
aad =
iv = 5707B836DCAEB1603502BA69
ct = 93EC3E489719355A7C4710372A3ABB940260FD01C7640C2A697AE787B0F8E2
Count = 36
pt = A96F3462E2FDD39121E652445AD3E3
key = CFCF80205076132C350B1331B4B33BF6
aad =
iv = D31D1E3135BB5906FC1AB280
ct = C94D093A91E38D5C2ADD44EE9BE74BA780EBCC6233C935BC340CC91D503E29
Count = 37
pt = 07DF5CD2752A8B8071100E55225969
key = E8A5E66EBE9C5B102DCF9DEFCBB15B10
aad =
iv = 487C0025031BF87FDEA8F895
ct = 7D930FE2A18C858DC926DCC149885D8D7EF4A1A5FC8E96C9690625CD2CBBA9
Count = 38
pt = D9A3B1D5CDA49A6101C3CB2BE027EF
key = D4FD713511701AD948930C125C73C3B1
aad =
iv = EB147D73CDDD431B0755C4A0
ct = 1DAABE15498C48E981B859BFCBA0BD7D6300CD3B424D41283E569B590A2D4C
Count = 39
pt = 14C6BB12C0DD74C035B4B2399C458D
key = 7A7B1E31027541E21ABA3DA4C45E2307
aad =
iv = 23784F5459808DA635DBB0AE
ct = D39FBD45D310EBB7771A5412AF04C6E359BC3138AD2EDF3EE6E60F64772DD3
Count = 40
pt = 0AA63037DFE7C1A00436289A5F5E31
key = E61969501C05819082444C7D3E373DBC
aad =
iv = 0C3B31FBC102BEA968D66F4D
ct = E8660D107C6826A7C36ED08526F3629306E60C1048F3FB1C17DD343075C453
Count = 41
pt = C38FFF9C3245BAC5BD3BC0F8D4A0F3
key = 5286BDA9D71251A32118F1C6FB9D8293
aad =
iv = 50083106C250AAB6A866C2FA
ct = 400325C371D1C97DF46176A787C50FB52C70297CE4BFEFD9AC7CD005DFBE7A
Count = 42
pt = 51EAD86C1740AF4EB7A1D21D6650EE
key = B4D6080CC4FBABB30374CD2A0C4BF848
aad =
iv = 2F13DEEF600572921D3B4A59
ct = EB95C4710A2182BCFC99FEF7DE044374E69C5BED8801F51F8215DF68646D65
Count = 43
pt = EB5FDA504097C5B2C97920B28C130A
key = 480E13A3E65ADFBB36017E26B886A28F
aad =
iv = 1A5690EA5884DAF36FE361DC
ct = FAE5559764C88BFDEFE09CC65C0D331AE84E5B139071663C51D7BCCBB9214F
Count = 44
pt = D0DD0927AE2EE95BBEC261FA6E750D
key = CD2D1EB5F7F0F7EF644EB79E2592C5D2
aad =
iv = 5FB355E18460714629E62896
ct = F211B200512AA3B3B42732A5F6FF01EE46D91312299CAE0A4C9090CF762816
Count = 45
pt = 634BE17EEB796791B83CA2A23A80BC
key = 40D45979CC394526AD5D167174FCB5B1
aad =
iv = 89D854E5C2B044D9E47320BF
ct = 673FC112E62EA83E43FA6057183DA21803C099AF11123A1CFA752F220D51C3
Count = 46
pt = D2F619F7AB5C934D12DD99C89CF07B
key = C53245E21FACF3334B6117CE14ECF4C3
aad = 69A519D90D20A2CEF263C50B004891
iv = C0A552AC86C773A8B1CA772C
ct = DE0CB428F324355C014DF626F1DE65B29FB6CAAE4E2CE208306837E5C250D1
Count = 47
pt = 65DE049BD1019D26E9B0A97ACB27B6
key = 894F6757F3D78C49A1C544B4435D966F
aad = 8186F1F46B76491EFE90CFD8EE7E09
iv = 23643B0A317734F950E0C20E
ct = 3625F5FBC5B8DA8192EFBA5EEF670B4E62698893CD5F4FAF3ACCA19A7E459F
Count = 48
pt = B92AD2A4FE33A4A075F7190FD01C89
key = 7005A27A6D91DF621162F9A204B23CF7
aad = 6E0B262AD64AA11C88D47B6237B17B
iv = D5DAA93AE86570C69096C554
ct = 8BFB347853CE25818C419ED3A5E854D715A0F4951C1831803155E8877489BC
Count = 49
pt = 589A8CFA4508CFC86774CCCFF582AA
key = 180F0CB3B8F61878BB44CEA0B1F90172
aad = 7DC7654547433F3FEA30D89068D5CA
iv = 462248B6ECB9D0213F6FF32B
ct = 3DD2CE9B4172AA2335B6443D1E5B327CC65B34026E1BDE5162F0794BA8CD31
Count = 50
pt = D8548D45C0C4CA8DCD60DD047D5084
key = 294F1B11A8322F7EFE3FB08776C977B2
aad = FE5244CD4381404A8BAF1B92893EE8
iv = 202A9E1BADBD13FFD9848970
ct = 045FF919DE8CF74E6A73349AF92BD600C0DFC9C1E98F20404B003CCD420DFF
Count = 51
pt = B24D790797F8BD9CF10AD92C8860CD
key = 1CEBF2D5BFCC9C22BD8BD846AADDD772
aad = 65A24157CD33128992C044A434B261
iv = F73A1602EBCE22533545BA4C
ct = 8B6F77842F85C90BBA577C7CC70F2B06386C8CF01F54C76CFD6D8E7C9A7863
Count = 52
pt = B956716E6EEAC8C374A28AEE15D851
key = 552F0BC063ACB738588D992ED58939F6
aad = DD7FC42F4BF87BBD231633B979E38A
iv = 98EF0240CF3CF6566C72AC7A
ct = 3B9F9DFC85122CC77319D2D81A559B7477C8E22363EE3B6182108FCE44939F
Count = 53
pt = 0D48A1375B1D061AEFC0BCB4BBD5B6
key = 2AACE8D8CF2182E065B0A2F1FEAB58FB
aad = DB6F06DBD66699EF4731F749F97D73
iv = 61BADA856694FA1602525ADA
ct = E76B6C0ED800033E9A9090585338C6E1E2054731A2A780125DFCD1E2B87E7B
Count = 54
pt = 4CB3C38953E580835E52E9F0E5BF0C
key = D5088794E02462C8FDAFF91902275D09
aad = 1CC25D27BFA6BA20D7393F4A052E08
iv = 8BBF07A771FF504A59466E55
ct = 24DB3DB4667B69DF4C3B8628564C271C745CF97E9991CA908D28B8F25E396F
Count = 55
pt = D1519C07EC79251DE230ABC85E58A5
key = 1AD333F14AEBBB3D7FFC824D3F571A2B
aad = 21D9A9E17EE186F30E8F81EE0C4365
iv = F95BF0350A666747FEB68668
ct = 9900CB8374E2A28DEAE719DE29DBD792FE578468511879612254CCC6AAC720
Count = 56
pt = 63EA6923C3F01F6BF7547D09BAA529
key = 86250A3603F1E53B130D70946D0ADBCA
aad = 7E911CD3EF577B60C7F681BCB9A875
iv = 50DB67FE6570A63D27035294
ct = 9BEE504C2F29E8FCEA46E7707C6A21B23F34DA82C2DBFF56994AFFEBD2EE20
Count = 57
pt = 45C301F7454EDC80F25A3216F09A31
key = 77847490BDA0A7D8D88962F24EE71678
aad = 17C2A8797DB7F3BFED542B463AB2FA
iv = 1CFD810788C395CB631EA6FC
ct = 247BBA1D8FA0CEE04C2AA031AE6347E80F317B8254EE10DA7B9616A2E01D36
Count = 58
pt = B7BB2CF3FFDE5018DA47462D10528F
key = 9480A0754D0A37DA75C89AA3F27DF8D3
aad = 35DDC612A02BEEA90FC79BE056EC5D
iv = 42000392A4879DEA79FD0D4C
ct = F084E14CF7F137610457C9496317BDC6AF096FC6646FF927342FAB13FC00CB
Count = 59
pt = A55A0B39CA6EF8A6707BA0E850577D
key = D00D3C14593102EF99A490C22D640004
aad = 60BDD99084450E6B51EA44AA7B8E09
iv = 771092977218771860AD791B
ct = E957075B3C0E687827A5F241DD70FB3554DA07C153C5274E55D2700423409F
Count = 60
pt = 162CDA0CA126A51E26CBCB39CA8124
key = 8E2DCC4E2CD80BF2078E4428046A1AD1
aad = D879965AB0F4B5D3E55F04973528B1
iv = 372958673FAE957E090D375B
ct = DC71A1C146BF3924EF3B5D0950CEF3473DEB505C82B68F0406BEBC95B86D2D
Count = 61
pt =
key = 40B1BAC332016315249223BB0B736AFC
aad =
iv = 98BD87707CE1028177CD64C1
ct = 57F3B1509E2A65D2C77E90449D96446C
Count = 62
pt =
key = D74569E0739BCEEB5EAFD704EB60C6E9
aad =
iv = 82C6B15CB381CB69AE81F4C4
ct = 5632DB3F68EE84CD204B2EE927CEBF24
Count = 63
pt =
key = BE56E8790B567BA6ADD94C27AB0A2F63
aad =
iv = 56F7EBF35F3EC2E8D6F5A3D0
ct = 69C0A9138A356BB7D24AC53659931A76
Count = 64
pt =
key = 5BB55DB9015A7D1BFD1078FCCA72C48E
aad =
iv = 1AE7B05BA0D95D9AF4243A12
ct = 09DE92C66434B95C58B10E549BF3377C
Count = 65
pt =
key = 18DDD9EBB5AD3C08AA5269012383F4A4
aad =
iv = 441D6CA2E27E570C4AEB3C93
ct = 23FD530A2EC1F5644EC54A23FF678D2E
Count = 66
pt =
key = E7CD55F4E8E1E3D065658FAF50335DD3
aad =
iv = BAA21CB52C2B63612BD5B6A5
ct = A42F99E1CAC0BD1ECC1B7B14BB91D111
Count = 67
pt =
key = 487E320BE85FFF2EAC1054AF1C83C45D
aad =
iv = D9F920EEB676317241C9D8DC
ct = B31B592F87A9EE89EEFD5EAB402E314E
Count = 68
pt =
key = 465E52E37960E25048D6580C619C916F
aad =
iv = 84C4863C925A6C26DD6C6570
ct = 46C7E95C1A62070DC7B4C189744292B7
Count = 69
pt =
key = 6EA56B2426C365D12F6AFA60C0508B23
aad =
iv = 0AC4424081352C939EBC952D
ct = AEF8F30F4E66794A24241468745C2647
Count = 70
pt =
key = B63B242B91BD655AA56D18BF7CF12C70
aad =
iv = 8A67BFF4E67E87692C8D919F
ct = 63104E5F1E8315A8E4ED277C61C045A2
Count = 71
pt =
key = 94BAFDFF63E9FEC2F49499B7B33EDD36
aad = B6EEF5FF384E01F10519D7A8436082
iv = DA71E8A92FF23E55CDF4AA2C
ct = 009029026752181F82941888DC224C81
Count = 72
pt =
key = D41A5B2E02C7BB03C29AF33A4CAADFEA
aad = BDDFA69C4ED87406B5570764483648
iv = EDE81BCD9E8FA4625D53174E
ct = CDF63B57A78FF27CB5D2725BAFC7423B
Count = 73
pt =
key = 1D20D7188D36ED09EC19DFA4291B94C7
aad = 71C3A89DCD75B71B3934EDC3FA08F0
iv = 81C56866241ACF74D4EEFEB7
ct = 984DF62F7A4F057A7C747DD0D71D8227
Count = 74
pt =
key = 4EDCC3BB5B522127C3C0B085A6BD66EC
aad = 287C30984EDE6B4B1C4538BA2A342C
iv = D5F5EB378BE2A1C5F4245997
ct = 0846218D0BA3F3C034E5BA2C2CFD9479
Count = 75
pt =
key = 1852FD7DAA2B69F3F254394328B28F9A
aad = CBF80AC13D886F1FCEFEACEBB86B7B
iv = 8BC291505D02556833105999
ct = 7627DF35527BB8EB40DD31EE13DDE79B
Count = 76
pt =
key = A8F2084F5F17334D4BDBD2A91C4B0C8F
aad = E767852490FAB6DE3FBDB0F4EEED18
iv = 0A6160157A27686F5C949E2F
ct = 8EF25446DADC3932B3AB0967DDBF8557
Count = 77
pt =
key = 4906D1E527F545ADB89D8B208142602D
aad = 46354F8DEAE01DB44DB68008D76F0D
iv = 34F113C992AE23455F32D170
ct = BB0807686CA263065C5F1073C2B29384
Count = 78
pt =
key = D204CD158EE53237B75F2CFC06DEF93B
aad = 30FE107C57A0C1CE7055B62DC86C13
iv = F41DBC259A1CF75C362DA7BB
ct = 012992B45A0DBB0AAAE820C765509F97
Count = 79
pt =
key = 4B83E3298DF106E56D2D1C778ECC231A
aad = 8795156E81445697AC9DAA4F40F048
iv = D48429B20968BF4F40A3AD19
ct = CFBC213C494D654752AFD4DE6719421D
Count = 80
pt =
key = 3FE144DC44E58FDDDDACB1EC98E40349
aad = 4FEBC0620884D82150F5C65E26B14F
iv = 1B11365CBFD7B769CBA46A0F
ct = 00F5B2BF7265A29585A821AE95791A50
Count = 81
pt =
key = 9A6F32834B5C9270BCD7326892DC514B
aad = 496D5DF96C620EE63F587849C38C0A
iv = B9E290A6752298F6F297EABB
ct = A86C41DA3D91A36326806623F2E62E47
Count = 82
pt = 090FEBF888B1CF851E63C1C023B34A
key = D8F571DE92C8F7E68B41BA6172BA28CF
aad =
iv = D8BE421E18B0C4F6E5378766
ct = 7BD7382D3228AE554B7184E467041FC0FF796277718191C854746812A0E674
Count = 83
pt = E7B648111446C5407701CB1538D9F9
key = B603121200C770DECEC08E437892A4F8
aad =
iv = 4673736B55909EB6B4587870
ct = 04A9F3E8BA245264D23A209B97DC2F1B0A2D7D569D9384F7073EFA5470D77B
Count = 84
pt = 76CF6C5E1CFB20A40E48F070F5B85A
key = 78D265B62EC59FA41B5389F8E06D511D
aad =
iv = CC20DE0D3960D38A132FDF1F
ct = 91503C83DE0603A75D8D43AE1A6652C96B631E67EDC32303B5BCB1F506FD58
Count = 85
pt = 69E1FB348943EE36BF626CCE902F93
key = DEDAF6B443140FE5ADF869586AB302DA
aad =
iv = 7228BEBDC47D155BF0CB25AE
ct = DCCA9B58A1C0E0ADD603D3FE1AA958BECA9195295962ABB886B30560C48A9D
Count = 86
pt = 42D20CCD61D8510E93C2002DA3519D
key = 646AA7D3C6EE11D4EE36E271A4267812
aad =
iv = 8235AB5AC1F3D24EC7F47A89
ct = BA5758A951826E2857138C58F3DAEC5A8E7135DC5B9CE779FB01DAAD479A1C
Count = 87
pt = 637DB0554AA8C8D58C7D4E88959D7D
key = 479CFFD6D766BB3FA99576A8B88DC543
aad =
iv = 0F16DAB1640BA047C88329E6
ct = ADE3FB4372F68E16D1398880DB1F4830546BC20236DE14C7D7E186AE826C40
Count = 88
pt = 414059A01DEEE201C85D8BDF6773DC
key = F5E624F4713A4F12FE45DD7C8A0E97E7
aad =
iv = 394EBE28661E8C7B118069E9
ct = 024A0DBC6D778D231CE2468128D677C317F9161F9BD61F0C06C5992E7AF6B8
Count = 89
pt = 8E864F35149742C891686EA47CA8B1
key = 19D749F1FE62F140F35F6FDE17FE13C9
aad =
iv = 8D97801F88FD9D1D5FB2EB42
ct = 653DC96E2CA456046995B82B35FCBE2A79F96C9EC65B742688C51C353AB25B
Count = 90
pt = 00A02B11532FC09E7F1B2034F6E979
key = 6296913323D8E20C100C5DBE6C426887
aad =
iv = C2040995395BC305F4770DDE
ct = 8A8B45621F7DC4535160AE801D46EB0FB72D870AF540F600836AC1BEB55A19
Count = 91
pt = B3159AAC85CED9FD38886F86E61D7D
key = 8A24BADBF200200719E2C73004D64DA1
aad =
iv = 1FB9A7B46EF5AEDC89500BC0
ct = BAEB6182C534D59074994C467AC46556DDE4308B9F4898171C707C4BF9FDB1
Count = 92
pt = 67E6E1B2AB862ACB283C0C8EBE62A8
key = BC374CB6C93E71EA3B158E37067A9A16
aad =
iv = 26C42C388B58941F668B1682
ct = 65E795EAF5A4AB84F14D401B38557D627FF3C38331B4CC3DBB4335ADD2C4BD
Count = 93
pt = C93C270900557C3BD76944F2060D91
key = 1F53A1770A1329B47021D9DA1340D0F9
aad = 529C6F4CFEAB024D1FE787CEDC3631
iv = E99C1E08999FC1E9556568FB
ct = 887C460AC255F41DFD66099F6D78852FEF2FC2BCC2EBC408C49A155F05AE49
Count = 94
pt = 4664D3C18C0061924C0FA3900F321E
key = B36E51F1BE198D7EEF00CD2468730ECD
aad = 90421DB62EAC5ED2774CF3DA7C3EF5
iv = 1A8C0DDB6ACBE6FC74AC0B28
ct = 501FAF2DFB13821D8A905F4E82E9948A96E70D64780CF11DC43232311D8475
Count = 95
pt = 42FE2758E60F81C75B339BC3563D22
key = C69056657B404EE5369723E6B93E11AF
aad = 71068A344D2198CAB7C160EDC5EC55
iv = 2AD1C9426EA551260207B3D8
ct = 735C70B66CB30D0317B8AC9107E16E517E35FABE51A45BFF4146969760217E
Count = 96
pt = C97D063C9AFB8A514FC5841AB02BC3
key = ACA69C6E615AB919E399AE8E33DD4833
aad = 9648294B4E59676CD519719149EE25
iv = 1E8A4E4195C6FF10C0E68907
ct = 8D870B64593A73D1764F0CB89A131B10AB20D22699D8F07F1E2FE36B5DB5FD
Count = 97
pt = 2FECE5F79F1575595430068508C83A
key = 4FF13FA305438B2C3BF628E30500E7A2
aad = DC8D44B409E2EE97868921A9DC9D07
iv = 19E0B03B83E16594F05BA550
ct = B5AB3C431766758C599A674A6420742BEF36AC5DCA50CC51F48D92731D6C8D
Count = 98
pt = 7F10BE63B76A5892B1091665BCB3AD
key = 440D65618AB422FE1860BB3C09CA7103
aad = BD9B4CA4764B17135CF2356A83702B
iv = 759B6DABE18A3B3CB6EE0449
ct = CDF0CB84D91F68A767ED8F02DE95E775A997589F259C3E9AC5F1AB57D1C963
Count = 99
pt = E7404ED214DC1CCBF1268477E60BA9
key = 0B73FC3CE8732D46245025F43C57D8D0
aad = 9FE659C7973708199AA36ED93B5243
iv = CED56F8EED1E74CA90E8E169
ct = F1A07582D3A7E8BB864F9353DCF7623047120A4B6ACC544CCAE3EAF37176FA
Count = 100
pt = 60A936A965FA2211BB26A64D6F5C4A
key = 79B84E462EA22DA5D799A08C667A29DF
aad = CA84B029D1266B5C59179B71D06852
iv = 4A09074FB25E957A2C492B11
ct = 8028ADD00BC82C02CCC07355EA58DD02CEF10B5398B2F7CC9C594130FBA0E7
Count = 101
pt = B33BB551E6874FC56C2FCB94B7792F
key = 5EF776152C71269C4AD27D6B7FA06A0B
aad = 1A2F5D2F2118DFB57C4A61680ECC63
iv = F2546A1A2569AA781045D2D7
ct = DF3DB8F1756A2D885C7E242B3ABBF3BCE6728905DF9B7E53F0B42FCBF4C6BF
Count = 102
pt = F2478134B8BC1FB3934FE4B4E16429
key = 969B3BAD443AC754F0C96F2BBD7B243F
aad = 8C735FF16B8BAE270E671FEAA160B4
iv = 71965AD63AD56DDD6B6568C7
ct = 2A0017A8E139195463F05AD246757867D01C5DB239C9B5D36A7C3C870F9E5C

143
testvectors/SIV_GCMtest.c Normal file
View File

@@ -0,0 +1,143 @@
/*
==============================================================================
Name : SIV_GCMtest.c
Author : polfosol
Version : 1.0.1.1
Copyright : copyright © 2023 - polfosol
Description : demonstrating how to validate ACVP vectors for AES-GCM-SIV mode
==============================================================================
*/
#include <stdio.h>
#include "../micro_aes.h"
#define TESTFILEPATH "SIV_GCM_ACVP.tv"
static void str2bytes(const char* hex, uint8_t* bytes)
{
unsigned shl = 0;
for (--bytes; *hex; ++hex)
{
if (*hex < '0' || 'f' < *hex) continue;
if ((shl ^= 4) != 0) *++bytes = 0;
*bytes |= (*hex % 16 + (*hex > '9') * 9) << shl;
}
}
static void bytes2str(const uint8_t* bytes, char* str, const size_t len)
{
const char offset = 0x27; /* offset must be 7 for uppercase */
size_t i = len + len, shr = 0;
for (str[i] = 0; i--; shr ^= 4)
{
str[i] = bytes[i / 2] >> shr & 0xF | '0';
if (str[i] > '9') str[i] += offset;
}
}
static int ciphertest(uint8_t* key, uint8_t* iv, uint8_t* p, uint8_t* a, uint8_t* c,
size_t np, size_t na, char* r)
{
char sk[2*AES_KEY_SIZE + 1], si[25], sp[0x100], sc[0x100], sa[0x100], msg[30];
uint8_t tmp[0x90], t = 0;
sprintf(msg, "%s", "passed the test");
GCM_SIV_encrypt(key, iv, p, np, a, na, tmp, tmp + np);
if (memcmp(c, tmp, np + 16))
{
sprintf(msg, "%s", "encrypt failure");
t = 1;
}
memset(tmp, 0xcc , sizeof tmp);
t |= 2 * GCM_SIV_decrypt(key, iv, c, np, a, na, 16, tmp);
if (t > 1)
{
sprintf(msg, "%sdecrypt failure", t & 1 ? "encrypt & " : "");
}
bytes2str(key, sk, AES_KEY_SIZE);
bytes2str(iv, si, 12);
bytes2str(p, sp, np);
bytes2str(a, sa, na);
bytes2str(c, sc, np + 16);
sprintf(r, "%s\nK: %s\ni: %s\nP: %s\nA: %s\nC: %s", msg, sk, si, sp, sa, sc);
return t;
}
int main()
{
const char *linehdr[] = { "key = ", "iv = ", "aad = ", "pt = ", "ct = " };
char buffer[0x400], *value = "";
size_t pass = 0, df = 0, ef = 0, sk = 0, sp = 0, sa = 0, n = 0;
uint8_t key[AES_KEY_SIZE], iv[12], p[80], c[96], a[80], i, j = 0;
FILE *fp, *fs, *ferr;
fp = fopen(TESTFILEPATH, "r");
fs = fopen("passed.log", "w");
ferr = fopen("failed.log", "w");
if (fp == NULL)
{
printf("File not found: %s\n", TESTFILEPATH);
return 1;
}
if (!fs || !ferr) return 1;
while (fgets(buffer, sizeof buffer, fp) != NULL)
{
buffer[strcspn(buffer, "\n")] = 0;
if (strlen(buffer) < 4) continue;
for (i = 0; i < 5; i++)
{
if (strncmp(buffer, linehdr[i], strlen(linehdr[i])) == 0)
{
value = strrchr(buffer, ' ') + 1;
break;
}
}
switch (i)
{
case 0:
sk = strlen(value) / 2;
if (sk == AES_KEY_SIZE) str2bytes(value, key);
break;
case 1:
if (strlen(value) == 24) str2bytes(value, iv);
break;
case 2:
sa = strlen(value) / 2;
str2bytes(value, a);
break;
case 3:
sp = strlen(value) / 2;
str2bytes(value, p); ++n;
break;
case 4:
str2bytes(value, c); ++n;
break;
}
if (n == 2)
{
if (sk == AES_KEY_SIZE)
{
n = ciphertest(key, iv, p, a, c, sp, sa, buffer);
fprintf(n ? ferr : fs, "%s\n", buffer); /* save the log */
if (n == 0) ++pass;
else
{
if (n & 1) ++ef;
if (n & 2) ++df;
}
}
n = 0;
}
}
printf ("test cases: %d\nsuccessful: %d\nfailed encrypt: %d, failed decrypt: %d\n",
pass + (ef > df ? ef : df), pass, ef, df);
fclose(fp); fclose(fs); fclose(ferr);
if (ef + df == 0)
{
remove("passed.log"); remove("failed.log");
}
return 0;
}

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="GCM_SIV_test" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/testvecs" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-pedantic" />
<Add option="-g" />
<Add option="-ansi" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/testvecs" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
<Add option="-pedantic" />
<Add option="-ansi" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Unit filename="../micro_aes.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="../micro_aes.h" />
<Unit filename="SIV_GCMtest.c">
<Option compilerVar="CC" />
</Unit>
<Extensions>
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@@ -2,9 +2,9 @@
==============================================================================
Name : XTStest.c
Author : polfosol
Version : 2.3.0.0
Version : 2.3.1.0
Copyright : copyright © 2022 - polfosol
Description : illustrating how the NIST's vectors for AES-XTS mode are used
Description : illustrating how to validate NIST's vectors for AES-XTS mode
==============================================================================
*/
@@ -37,11 +37,11 @@ static void bytes2str(const uint8_t* bytes, char* str, size_t len)
str[j] = 0;
}
static int ciphertest(uint8_t* key, uint8_t* iv, uint8_t* p, uint8_t* c, uint8_t n, char* r)
static int ciphertest(uint8_t* key, uint8_t* iv, uint8_t* p, uint8_t* c, size_t n, char* r)
{
char sk[4*AES_KEY_LENGTH + 16], si[40], sp[0x80], sc[0x80], msg[30];
char sk[4*AES_KEY_SIZE + 1], si[33], sp[0x80], sc[0x80], msg[30];
uint8_t tmp[0x80], t = 0;
sprintf(msg, "%s", "success");
sprintf(msg, "%s", "passed the test");
AES_XTS_encrypt(key, iv, p, n, tmp);
if (memcmp(c, tmp, n))
@@ -56,7 +56,7 @@ static int ciphertest(uint8_t* key, uint8_t* iv, uint8_t* p, uint8_t* c, uint8_t
sprintf(msg, "%sdecrypt failure", t ? "encrypt & " : "");
t |= 2;
}
bytes2str(key, sk, 2*AES_KEY_LENGTH);
bytes2str(key, sk, 2*AES_KEY_SIZE);
bytes2str(iv, si, 16);
bytes2str(p, sp, n);
bytes2str(c, sc, n);
@@ -69,7 +69,7 @@ int main()
const char *linehdr[] = { "Key = ", "i = ", "PT = ", "CT = ", "DataUnitLen = " };
char buffer[0x800], *value = "";
size_t i, n = 0, pass = 0, df = 0, ef = 0, s = 0, sk = 0;
uint8_t key[2*AES_KEY_LENGTH], iv[16], p[0x80], c[0x80], ul[2];
uint8_t key[2*AES_KEY_SIZE], iv[16], p[0x80], c[0x80], ul[2];
FILE *fp, *fs, *ferr;
fp = fopen(TESTFILEPATH, "r");
@@ -99,7 +99,7 @@ int main()
{
case 0:
sk = strlen(value) / 2;
if (sk == 2 * AES_KEY_LENGTH) str2bytes(value, key);
if (sk == 2 * AES_KEY_SIZE) str2bytes(value, key);
break;
case 1:
str2bytes(value, iv);
@@ -119,7 +119,7 @@ int main()
if (n == 2)
{
s = (ul[0] >> 4) *100 + (ul[0] & 15) *10 + (ul[1] >> 4);
if (sk == 2 * AES_KEY_LENGTH && s % 8 == 0)
if (sk == 2 * AES_KEY_SIZE && s % 8 == 0)
{
n = ciphertest(key, iv, p, c, s / 8, buffer);
fprintf(n ? ferr : fs, "%s\n", buffer); /* save the log */
@@ -131,7 +131,7 @@ int main()
}
}
printf ("test cases: %d\nsuccessful: %d\nfailed encrypt: %d, failed decrypt: %d\n",
pass + ef + df, pass, ef, df);
pass + (ef > df ? ef : df), pass, ef, df);
fclose(fp); fclose(fs); fclose(ferr);
if (ef + df == 0)

318
x86-improvements Normal file
View File

@@ -0,0 +1,318 @@
/**
* 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
* —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
* the `unsigned` keyword is actually equivalent to `uint32_t`. Furthermore, the
* body code of `MixColumns` and `InvMixColumns` must be changed as follows.. */
#if BIG_ENDIAN_INTEGERS
#define RL8(x) rotl( x, 8 )
#else
#define RL8(x) rotl( x, 24 ) /* equivalent little-endian rotation */
#endif
#define R16(x) rotl( x, 16 )
#define RRR(x) rotl( x, 8 ) ^ rotl( x, 16 ) ^ rotl( x, 24 )
/** This method must simply compile to a bit-rotate CPU instruction (ror/rol) */
static unsigned rotl( const unsigned value, unsigned shift )
{
return (value << shift) | (value >> (32 - shift));
}
/** XOR two 128-bit numbers (blocks) src and dest: optimized for 32-bit CPUs. */
static void xorBlock( const block_t src, block_t dest )
{
XOR32BITS( src[ 0], dest[ 0] );
XOR32BITS( src[ 4], dest[ 4] );
XOR32BITS( src[ 8], dest[ 8] );
XOR32BITS( src[12], dest[12] );
}
/** all 4 bytes of an unsigned integer are doubled [i.e. xtime-ed] in GF(2^8) */
static void quad_xtime( unsigned* x )
{
unsigned cc = (*x >> 7 & 0x1010101L) * 0x1b;
*x = (*x << 1 & ~0x1010101L) ^ cc;
}
--------------------------------------------------------------------------------
MixColumns:
unsigned rt, i, *s = (unsigned*) &state[0];
for (i = Nb; i--; ++s)
{
rt = RRR( *s );
*s ^= RL8( *s );
quad_xtime( s );
*s ^= rt;
}
InvMixColumns:
unsigned rt, i, *s = (unsigned*) &state[0];
for (i = Nb; i--; ++s)
{
rt = RRR( *s );
quad_xtime( s );
rt ^= RL8( *s ) ^ *s;
quad_xtime( s );
rt ^= R16( *s ) ^ *s;
quad_xtime( s );
*s ^= RRR( *s ) ^ rt;
}
================================================================================
a sample compiled assembly output, given by gcc using `-S -Os` flags:
xorBlock(unsigned char const*, unsigned char*):
mov eax, QWORD PTR [rdi]
xor QWORD PTR [rsi], eax
mov eax, QWORD PTR [rdi+8]
xor QWORD PTR [rsi+8], eax
ret
quad_xtime(unsigned int*):
mov edx, DWORD PTR [rdi]
mov eax, edx
add edx, edx
shr eax, 7
and edx, -16843010
and eax, 16843009
imul eax, eax, 27
xor eax, edx
mov DWORD PTR [rdi], eax
ret
KeyExpansion(unsigned char const*):
movups xmm0, XMMWORD PTR [rdi]
mov eax, 16
mov dl, 1
movaps XMMWORD PTR RoundKey[rip], xmm0
.L7:
test al, 15
jne .L4
movaps xmm1, XMMWORD PTR RoundKey[rax-16]
movups XMMWORD PTR RoundKey[rax], xmm1
test dl, dl
jne .L5
mov dl, 27
.L5:
movzx ecx, BYTE PTR RoundKey[rax-3]
mov cl, BYTE PTR sbox[rcx]
xor cl, BYTE PTR RoundKey[rax]
xor ecx, edx
add edx, edx
mov BYTE PTR RoundKey[rax], cl
movzx ecx, BYTE PTR RoundKey[rax-2]
mov cl, BYTE PTR sbox[rcx]
xor BYTE PTR RoundKey[rax+1], cl
movzx ecx, BYTE PTR RoundKey[rax-1]
mov cl, BYTE PTR sbox[rcx]
xor BYTE PTR RoundKey[rax+2], cl
movzx ecx, BYTE PTR RoundKey[rax-4]
mov cl, BYTE PTR sbox[rcx]
xor BYTE PTR RoundKey[rax+3], cl
jmp .L6
.L4:
mov ecx, DWORD PTR RoundKey[rax]
xor ecx, DWORD PTR RoundKey[rax-4]
mov DWORD PTR RoundKey[rax], ecx
.L6:
add rax, 4
cmp rax, 176
jne .L7
ret
SubBytes(unsigned char*):
xor eax, eax
.L12:
movzx edx, BYTE PTR [rdi+rax]
mov dl, BYTE PTR sbox[rdx]
mov BYTE PTR [rdi+rax], dl
inc rax
cmp rax, 16
jne .L12
ret
ShiftRows(unsigned char (*) [4][4]):
mov dl, BYTE PTR [rdi+5]
mov al, BYTE PTR [rdi+1]
mov BYTE PTR [rdi+1], dl
mov dl, BYTE PTR [rdi+9]
mov BYTE PTR [rdi+5], dl
mov dl, BYTE PTR [rdi+13]
mov BYTE PTR [rdi+13], al
mov al, BYTE PTR [rdi+2]
mov BYTE PTR [rdi+9], dl
mov dl, BYTE PTR [rdi+10]
mov BYTE PTR [rdi+10], al
mov al, BYTE PTR [rdi+6]
mov BYTE PTR [rdi+2], dl
mov dl, BYTE PTR [rdi+14]
mov BYTE PTR [rdi+14], al
mov al, BYTE PTR [rdi+3]
mov BYTE PTR [rdi+6], dl
mov dl, BYTE PTR [rdi+15]
mov BYTE PTR [rdi+3], dl
mov dl, BYTE PTR [rdi+11]
mov BYTE PTR [rdi+15], dl
mov dl, BYTE PTR [rdi+7]
mov BYTE PTR [rdi+7], al
mov BYTE PTR [rdi+11], dl
ret
MixColumns(unsigned char (*) [4][4]):
lea r8, [rdi+16]
.L16:
mov eax, DWORD PTR [rdi]
mov esi, eax
mov ecx, eax
mov edx, eax
ror esi, 8
rol edx, 16
xor eax, esi
rol ecx, 8
mov DWORD PTR [rdi], eax
xor ecx, edx
call quad_xtime(unsigned int*)
xor ecx, DWORD PTR [rdi]
add rdi, 4
xor ecx, esi
mov DWORD PTR [rdi-4], ecx
cmp rdi, r8
jne .L16
ret
rijndaelEncrypt(unsigned char const*, unsigned char*):
mov r9, rsi
push rdx
cmp rsi, rdi
je .L19
movups xmm0, XMMWORD PTR [rdi]
movups XMMWORD PTR [rsi], xmm0
.L19:
mov r10d, OFFSET FLAT:RoundKey
.L21:
mov rdi, r10
mov rsi, r9
add r10, 16
call xorBlock(unsigned char const*, unsigned char*)
mov rdi, r9
call SubBytes(unsigned char*)
call ShiftRows(unsigned char (*) [4][4])
cmp r10, OFFSET FLAT:RoundKey+160
je .L20
call MixColumns(unsigned char (*) [4][4])
jmp .L21
.L20:
mov edi, OFFSET FLAT:RoundKey+160
pop rax
jmp xorBlock(unsigned char const*, unsigned char*)
InvSubBytes(unsigned char*):
xor eax, eax
.L24:
movzx edx, BYTE PTR [rdi+rax]
mov dl, BYTE PTR rsbox[rdx]
mov BYTE PTR [rdi+rax], dl
inc rax
cmp rax, 16
jne .L24
ret
InvShiftRows(unsigned char (*) [4][4]):
mov dl, BYTE PTR [rdi+9]
mov al, BYTE PTR [rdi+13]
mov BYTE PTR [rdi+13], dl
mov dl, BYTE PTR [rdi+5]
mov BYTE PTR [rdi+9], dl
mov dl, BYTE PTR [rdi+1]
mov BYTE PTR [rdi+1], al
mov al, BYTE PTR [rdi+2]
mov BYTE PTR [rdi+5], dl
mov dl, BYTE PTR [rdi+10]
mov BYTE PTR [rdi+10], al
mov al, BYTE PTR [rdi+6]
mov BYTE PTR [rdi+2], dl
mov dl, BYTE PTR [rdi+14]
mov BYTE PTR [rdi+14], al
mov al, BYTE PTR [rdi+3]
mov BYTE PTR [rdi+6], dl
mov dl, BYTE PTR [rdi+7]
mov BYTE PTR [rdi+3], dl
mov dl, BYTE PTR [rdi+11]
mov BYTE PTR [rdi+7], dl
mov dl, BYTE PTR [rdi+15]
mov BYTE PTR [rdi+15], al
mov BYTE PTR [rdi+11], dl
ret
InvMixColumns(unsigned char (*) [4][4]):
mov rcx, rdi
lea rsi, [rdi+16]
.L28:
mov rdi, rcx
mov r8d, DWORD PTR [rcx]
add rcx, 4
call quad_xtime(unsigned int*)
mov r10d, DWORD PTR [rcx-4]
call quad_xtime(unsigned int*)
mov r9d, DWORD PTR [rcx-4]
call quad_xtime(unsigned int*)
mov edx, DWORD PTR [rcx-4]
mov eax, r10d
mov edi, r8d
rol edi, 8
xor eax, r9d
ror r10d, 8
xor eax, edx
rol r9d, 16
xor eax, edi
mov edi, r8d
ror r8d, 8
rol edi, 16
xor eax, edi
mov edi, edx
xor eax, r8d
rol edi, 8
xor eax, r10d
xor eax, r9d
xor eax, edi
mov edi, edx
ror edx, 8
rol edi, 16
xor eax, edi
xor eax, edx
mov DWORD PTR [rcx-4], eax
cmp rsi, rcx
jne .L28
ret
rijndaelDecrypt(unsigned char const*, unsigned char*):
push rbp
mov r11, rsi
push rbx
push rdx
cmp rsi, rdi
je .L31
movups xmm0, XMMWORD PTR [rdi]
movups XMMWORD PTR [rsi], xmm0
.L31:
mov ebp, OFFSET FLAT:RoundKey+144
mov bl, 10
.L34:
cmp bl, 10
je .L32
mov rdi, r11
call InvMixColumns(unsigned char (*) [4][4])
jmp .L33
.L32:
mov rsi, r11
mov edi, OFFSET FLAT:RoundKey+160
call xorBlock(unsigned char const*, unsigned char*)
.L33:
mov rdi, r11
mov rsi, r11
call InvShiftRows(unsigned char (*) [4][4])
call InvSubBytes(unsigned char*)
mov rdi, rbp
sub rbp, 16
call xorBlock(unsigned char const*, unsigned char*)
dec bl
jne .L34
pop rax
pop rbx
pop rbp
ret