Compare commits
2 Commits
Version_2.
...
Version_2.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1683e5d9f6 | ||
|
|
3201fb4d83 |
@@ -1,29 +1,31 @@
|
||||
cmake_minimum_required(VERSION 3.6.0)
|
||||
|
||||
project( CryptLib )
|
||||
project( WjCryptLib )
|
||||
|
||||
# CryptLib Static Library
|
||||
add_library( CryptLib STATIC
|
||||
lib/CryptLib_Aes.h
|
||||
lib/CryptLib_Aes.c
|
||||
lib/CryptLib_AesCtr.h
|
||||
lib/CryptLib_AesCtr.c
|
||||
lib/CryptLib_Md5.h
|
||||
lib/CryptLib_Md5.c
|
||||
lib/CryptLib_Rc4.h
|
||||
lib/CryptLib_Rc4.c
|
||||
lib/CryptLib_Sha1.h
|
||||
lib/CryptLib_Sha1.c
|
||||
lib/CryptLib_Sha256.h
|
||||
lib/CryptLib_Sha256.c
|
||||
lib/CryptLib_Sha512.h
|
||||
lib/CryptLib_Sha512.c )
|
||||
target_include_directories( CryptLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/lib )
|
||||
set_target_properties ( CryptLib PROPERTIES FOLDER lib )
|
||||
# WjCryptLib Static Library
|
||||
add_library( WjCryptLib STATIC
|
||||
lib/WjCryptLib_Aes.h
|
||||
lib/WjCryptLib_Aes.c
|
||||
lib/WjCryptLib_AesCtr.h
|
||||
lib/WjCryptLib_AesCtr.c
|
||||
lib/WjCryptLib_AesOfb.h
|
||||
lib/WjCryptLib_AesOfb.c
|
||||
lib/WjCryptLib_Md5.h
|
||||
lib/WjCryptLib_Md5.c
|
||||
lib/WjCryptLib_Rc4.h
|
||||
lib/WjCryptLib_Rc4.c
|
||||
lib/WjCryptLib_Sha1.h
|
||||
lib/WjCryptLib_Sha1.c
|
||||
lib/WjCryptLib_Sha256.h
|
||||
lib/WjCryptLib_Sha256.c
|
||||
lib/WjCryptLib_Sha512.h
|
||||
lib/WjCryptLib_Sha512.c )
|
||||
target_include_directories( WjCryptLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/lib )
|
||||
set_target_properties ( WjCryptLib PROPERTIES FOLDER lib )
|
||||
|
||||
|
||||
# Add the demo project directories
|
||||
add_subdirectory( projects/CryptLibTest )
|
||||
add_subdirectory( projects/WjCryptLibTest )
|
||||
add_subdirectory( projects/Md5String )
|
||||
add_subdirectory( projects/Rc4Output )
|
||||
add_subdirectory( projects/Sha1String )
|
||||
@@ -31,3 +33,4 @@ add_subdirectory( projects/Sha256String )
|
||||
add_subdirectory( projects/Sha512String )
|
||||
add_subdirectory( projects/AesBlock )
|
||||
add_subdirectory( projects/AesCtrOutput )
|
||||
add_subdirectory( projects/AesOfbOutput )
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
90
ReadMe.md
90
ReadMe.md
@@ -1,19 +1,59 @@
|
||||
CryptLib
|
||||
========
|
||||
WjCryptLib
|
||||
==========
|
||||
|
||||
CryptLib is a collection of cryptographic functions written in C. Each
|
||||
WjCryptLib is a collection of cryptographic functions written in C. Each
|
||||
module is fully independent and generally requires only a single .c file
|
||||
and a a single .h file. AES-CTR does depend on the AES module, so in this
|
||||
case all four files are needed.
|
||||
|
||||
The functions are designed to be portable and have been tested on both
|
||||
a Little-Endian and a Big-Endian architecture
|
||||
a Little-Endian and a Big-Endian architecture. OpenMP is supported where
|
||||
parallelisation can occur.
|
||||
|
||||
The library and the demo programs can be built using CMake to generate
|
||||
a build setup for any system, including Visual Studio on Windows and
|
||||
Make or Ninja for Linux. Refer to cmake.org to get CMake.
|
||||
|
||||
*Placed into Public Domain by WaterJuice 2013 - 2017*
|
||||
*Placed into Public Domain by WaterJuice 2013 - 2018*
|
||||
|
||||
Library
|
||||
-------
|
||||
|
||||
To use the library functions, only the following files are required,
|
||||
depending on what cryptographic functions are wanted.
|
||||
|
||||
* MD5 - (WjCryptLib_Md5.h, and WjCryptLib_Md5.c)
|
||||
* SHA1 - (WjCryptLib_Sha1.h, and WjCryptLib_Sha1.c)
|
||||
* SHA256 - (WjCryptLib_Sha256.h, and WjCryptLib_Sha256.c)
|
||||
* SHA512 - (WjCryptLib_Sha512.h, and WjCryptLib_Sha512.c)
|
||||
* RC4 - (WjCryptLib_Rc4.h, and WjCryptLib_Rc4.c)
|
||||
* AES - (WjCryptLib_Aes.h, and WjCryptLib_Aes.c)
|
||||
* AES-CTR - (WjCryptLib_AesCtr.h, and WjCryptLib_AesCtr.c, WjCryptLib_Aes.h,
|
||||
and WjCryptLib_Aes.c)
|
||||
* AES-OFB - (WjCryptLib_AesOfb.h, and WjCryptLib_AesOfb.c, WjCryptLib_Aes.h,
|
||||
and WjCryptLib_Aes.c)
|
||||
|
||||
|
||||
Version 2.2.0 - January 2018
|
||||
------------
|
||||
|
||||
* Added AES-OFB module.
|
||||
* File names have been changed to have the prefix `WjCryptLib_` rather
|
||||
than `CryptLib_`.
|
||||
* Removed compiled binaries from source tree.
|
||||
|
||||
Version 2.1.0 - December 2017
|
||||
-----------------------------
|
||||
|
||||
Changes:
|
||||
|
||||
* Changed implementation of AES to one which is almost 5 times as fast.
|
||||
The new implementation comes from LibTomCrypt. The newer implementation
|
||||
produces a larger binary size as a trade-off.
|
||||
* AES-CTR module now supports OpenMP and when compiled with OpenMP will
|
||||
run in parallel giving a much greater speed.
|
||||
* Changed interface for Initialisation functions for both AES and AES-CTR
|
||||
to be match RC4 (The context is first parameter not last)
|
||||
|
||||
Version 2.0.0 - December 2017
|
||||
-----------------------------
|
||||
@@ -30,36 +70,22 @@ projects. CMake will generate whatever system is required.
|
||||
than `Lib`.
|
||||
* Various formatting changes to the files.
|
||||
|
||||
To use the library functions, only the following files are required,
|
||||
depending on what cryptographic functions are wanted.
|
||||
|
||||
* MD5 - (CryptLib_Md5.h, and CryptLib_Md5.c)
|
||||
* SHA1 - (CryptLib_Sha1.h, and CryptLib_Sha1.c)
|
||||
* SHA256 - (CryptLib_Sha256.h, and CryptLib_Sha256.c)
|
||||
* SHA512 - (CryptLib_Sha512.h, and CryptLib_Sha512.c)
|
||||
* RC4 - (CryptLib_Rc4.h, and CryptLib_Rc4.c)
|
||||
* AES - (CryptLib_Aes.h, and CryptLib_Aes.c)
|
||||
* AES-CTR - (CryptLib_AesCtr.h, and CryptLib_AesCtr.c, CryptLib_Aes.h,
|
||||
and CryptLib_Aes.c)
|
||||
|
||||
|
||||
Version 1.0.0 - June 2013
|
||||
-------------------------
|
||||
|
||||
To use the library functions, only the following files are required,
|
||||
depending on what cryptographic functions are wanted.
|
||||
Contains following algorithms:
|
||||
|
||||
* MD5 - (LibMd5.h, and LibMd5.c)
|
||||
* SHA1 - (LibSha1.h, and LibSha1.c)
|
||||
* SHA256 - (LibSha256.h, and LibSha256.c)
|
||||
* SHA512 - (LibSha512.h, and LibSha512.c)
|
||||
* RC4 - (LibRc4.h, and LibRc4.c)
|
||||
* MD5
|
||||
* SHA1
|
||||
* SHA256
|
||||
* SHA512
|
||||
* RC4
|
||||
|
||||
Test Programs
|
||||
-------------
|
||||
|
||||
In the projects directory there are several programs that compile to
|
||||
command line executables. One is CryptLibTest. This tests the algorithms
|
||||
command line executables. One is WjCryptLibTest. This tests the algorithms
|
||||
against known test vectors. If compiling on a different system this
|
||||
is useful to verify that the results are still valid.
|
||||
|
||||
@@ -75,16 +101,10 @@ output the stream in hex.
|
||||
* Rc4Output
|
||||
* AesBlock
|
||||
* AesCtrOutput
|
||||
* AesOfbOutput
|
||||
|
||||
Executables
|
||||
-----------
|
||||
|
||||
Included in the Exe directory are executables of the above programs for Windows,
|
||||
MacOS, and Linux. All of them are compiled for x64 versions of the operating
|
||||
systems.
|
||||
|
||||
License
|
||||
=======
|
||||
Unlicense
|
||||
=========
|
||||
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
|
||||
@@ -1,577 +0,0 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLib_Aes
|
||||
//
|
||||
// Implementation of AES block cipher. Originally written by Kokke (https://github.com/kokke). Modified by WaterJuice
|
||||
// retaining Public Domain license.
|
||||
//
|
||||
// AES is a block cipher that operates on 128 bit blocks. Encryption an Decryption routines use an AesContext which
|
||||
// must be initialised with the key. An AesContext can be initialised with a 128, 192, or 256 bit key. Use the
|
||||
// AesInitialise[n] functions to initialise the context with the key. Once an AES context is initialised its contents
|
||||
// are not changed by the encrypting and decrypting functions. A context only needs to be initialised once for any
|
||||
// given key and the context may be used by the encrypt/decrypt functions in simultaneous threads.
|
||||
// All operations are performed byte wise and this implementation works in both little and endian processors.
|
||||
// There are no alignment requirements with the keys and data blocks.
|
||||
//
|
||||
// This is free and unencumbered software released into the public domain - November 2017 waterjuice.org
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// IMPORTS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "CryptLib_Aes.h"
|
||||
#include <stdint.h>
|
||||
#include <memory.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// DEFINES
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Array holding the intermediate results during decryption.
|
||||
typedef struct
|
||||
{
|
||||
uint8_t state[4][4];
|
||||
} AesState;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CONSTANTS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// AES lookup values
|
||||
static const uint8_t SBOX[256] =
|
||||
{
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
|
||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
|
||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
|
||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
|
||||
};
|
||||
|
||||
static const uint8_t RSBOX[256] =
|
||||
{
|
||||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
|
||||
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
|
||||
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
|
||||
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
|
||||
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
|
||||
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
|
||||
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
|
||||
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
|
||||
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
|
||||
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
|
||||
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
|
||||
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
|
||||
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
|
||||
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
|
||||
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
|
||||
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
|
||||
|
||||
// The round constant word array, RCON[i], contains the values given by
|
||||
// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
|
||||
static const uint8_t RCON[11] = { 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// INTERNAL FUNCTIONS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// KeyExpansion
|
||||
//
|
||||
// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static
|
||||
void
|
||||
KeyExpansion
|
||||
(
|
||||
uint8_t const* Key, // [in]
|
||||
AesContext* Context // [in out]
|
||||
)
|
||||
{
|
||||
uint32_t i;
|
||||
uint8_t k;
|
||||
uint8_t temp [4]; // Used for the column/row operations
|
||||
|
||||
// The first round key is the key itself.
|
||||
for( i=0; i<Context->KeySizeInWords; i++ )
|
||||
{
|
||||
Context->RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
|
||||
Context->RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
|
||||
Context->RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
|
||||
Context->RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
|
||||
}
|
||||
|
||||
// All other round keys are found from the previous round keys.
|
||||
for( i=Context->KeySizeInWords; i<4*(Context->NumberOfRounds+1); i++ )
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
// Visual Studio code analysis complains about the following code that the index into Context->RoundKey
|
||||
// may be -4. This is because it is concerned that 'i' may be zero. However we know that 'i' will not
|
||||
// be zero as it starts at Context->KeySizeInWords which is never going to be zero when this function
|
||||
// is called (It will have one of 3 values assigned to it by the initialise functions). So we need to
|
||||
// just suppress the warning here to stop Visual Studio complaining.
|
||||
#pragma warning( suppress : 6385 )
|
||||
#endif
|
||||
temp[0] = Context->RoundKey[(i-1) * 4 + 0];
|
||||
temp[1] = Context->RoundKey[(i-1) * 4 + 1];
|
||||
temp[2] = Context->RoundKey[(i-1) * 4 + 2];
|
||||
temp[3] = Context->RoundKey[(i-1) * 4 + 3];
|
||||
|
||||
if( 0 == i % Context->KeySizeInWords )
|
||||
{
|
||||
// This function shifts the 4 bytes in a word to the left once.
|
||||
// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
|
||||
k = temp[0];
|
||||
temp[0] = temp[1];
|
||||
temp[1] = temp[2];
|
||||
temp[2] = temp[3];
|
||||
temp[3] = k;
|
||||
|
||||
// SubWord is a function that takes a four-byte input word and
|
||||
// applies the S-box to each of the four bytes to produce an output word.
|
||||
temp[0] = SBOX[temp[0]];
|
||||
temp[1] = SBOX[temp[1]];
|
||||
temp[2] = SBOX[temp[2]];
|
||||
temp[3] = SBOX[temp[3]];
|
||||
|
||||
temp[0] = temp[0] ^ RCON[i/Context->KeySizeInWords];
|
||||
}
|
||||
|
||||
if( AES_KEY_SIZE_256/4 == Context->KeySizeInWords )
|
||||
{
|
||||
// Only performed with 256 bit sized keys
|
||||
if( 4 == i % Context->KeySizeInWords )
|
||||
{
|
||||
// Function Subword()
|
||||
temp[0] = SBOX[temp[0]];
|
||||
temp[1] = SBOX[temp[1]];
|
||||
temp[2] = SBOX[temp[2]];
|
||||
temp[3] = SBOX[temp[3]];
|
||||
}
|
||||
}
|
||||
|
||||
Context->RoundKey[i*4 + 0] = Context->RoundKey[(i-Context->KeySizeInWords)*4 + 0] ^ temp[0];
|
||||
Context->RoundKey[i*4 + 1] = Context->RoundKey[(i-Context->KeySizeInWords)*4 + 1] ^ temp[1];
|
||||
Context->RoundKey[i*4 + 2] = Context->RoundKey[(i-Context->KeySizeInWords)*4 + 2] ^ temp[2];
|
||||
Context->RoundKey[i*4 + 3] = Context->RoundKey[(i-Context->KeySizeInWords)*4 + 3] ^ temp[3];
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AddRoundKey
|
||||
//
|
||||
// This function adds the round key to state. The round key is added to the state by an XOR function.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static
|
||||
void
|
||||
AddRoundKey
|
||||
(
|
||||
uint32_t Round, // [in]
|
||||
AesContext const* Context, // [in]
|
||||
AesState* State // [in out]
|
||||
)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
|
||||
for( i=0; i<4; i++ )
|
||||
{
|
||||
for( j=0; j<4; j++ )
|
||||
{
|
||||
State->state[i][j] ^= Context->RoundKey[(Round*4*4) + (i*4) + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SubBytes
|
||||
//
|
||||
// The SubBytes Function Substitutes the values in the state matrix with values in an S-box.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static
|
||||
void
|
||||
SubBytes
|
||||
(
|
||||
AesState* State // [in out]
|
||||
)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
|
||||
for( i=0; i<4; i++ )
|
||||
{
|
||||
for( j=0; j<4; j++ )
|
||||
{
|
||||
State->state[j][i] = SBOX[ State->state[j][i] ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ShiftRows
|
||||
//
|
||||
// The ShiftRows() function shifts the rows in the state to the left. Each row is shifted with different offset.
|
||||
// Offset = Row number. So the first row is not shifted.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static
|
||||
void
|
||||
ShiftRows
|
||||
(
|
||||
AesState* State // [in out]
|
||||
)
|
||||
{
|
||||
uint8_t temp;
|
||||
|
||||
// Rotate first row 1 columns to left
|
||||
temp = State->state[0][1];
|
||||
State->state[0][1] = State->state[1][1];
|
||||
State->state[1][1] = State->state[2][1];
|
||||
State->state[2][1] = State->state[3][1];
|
||||
State->state[3][1] = temp;
|
||||
|
||||
// Rotate second row 2 columns to left
|
||||
temp = State->state[0][2];
|
||||
State->state[0][2] = State->state[2][2];
|
||||
State->state[2][2] = temp;
|
||||
|
||||
temp = State->state[1][2];
|
||||
State->state[1][2] = State->state[3][2];
|
||||
State->state[3][2] = temp;
|
||||
|
||||
// Rotate third row 3 columns to left
|
||||
temp = State->state[0][3];
|
||||
State->state[0][3] = State->state[3][3];
|
||||
State->state[3][3] = State->state[2][3];
|
||||
State->state[2][3] = State->state[1][3];
|
||||
State->state[1][3] = temp;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// xtime
|
||||
//
|
||||
// Performs a calculation
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static
|
||||
uint8_t
|
||||
xtime
|
||||
(
|
||||
uint8_t x // [in]
|
||||
)
|
||||
{
|
||||
return (x<<1) ^ ( ((x>>7) & 1) * 0x1b );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// MixColumns
|
||||
//
|
||||
// MixColumns function mixes the columns of the state matrix
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static
|
||||
void
|
||||
MixColumns
|
||||
(
|
||||
AesState* State // [in out]
|
||||
)
|
||||
{
|
||||
uint32_t i;
|
||||
uint8_t Tmp;
|
||||
uint8_t Tm;
|
||||
uint8_t t;
|
||||
|
||||
for( i=0; i<4; i++ )
|
||||
{
|
||||
t = State->state[i][0];
|
||||
Tmp = State->state[i][0] ^ State->state[i][1] ^ State->state[i][2] ^ State->state[i][3] ;
|
||||
Tm = State->state[i][0] ^ State->state[i][1] ; Tm = xtime(Tm); State->state[i][0] ^= Tm ^ Tmp ;
|
||||
Tm = State->state[i][1] ^ State->state[i][2] ; Tm = xtime(Tm); State->state[i][1] ^= Tm ^ Tmp ;
|
||||
Tm = State->state[i][2] ^ State->state[i][3] ; Tm = xtime(Tm); State->state[i][2] ^= Tm ^ Tmp ;
|
||||
Tm = State->state[i][3] ^ t ; Tm = xtime(Tm); State->state[i][3] ^= Tm ^ Tmp ;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Multiply
|
||||
//
|
||||
// Multiply is used to multiply numbers in the field GF(2^8). This is defined as a macro.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define Multiply(x, y) \
|
||||
( ((y & 1) * x) ^ \
|
||||
((y>>1 & 1) * xtime(x)) ^ \
|
||||
((y>>2 & 1) * xtime(xtime(x))) ^ \
|
||||
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \
|
||||
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// InvMixColumns
|
||||
//
|
||||
// InvMixColumns function mixes the columns of the state matrix.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static
|
||||
void
|
||||
InvMixColumns
|
||||
(
|
||||
AesState* State // [in out]
|
||||
)
|
||||
{
|
||||
uint32_t i;
|
||||
uint8_t a;
|
||||
uint8_t b;
|
||||
uint8_t c;
|
||||
uint8_t d;
|
||||
|
||||
for( i=0; i<4; i++ )
|
||||
{
|
||||
a = State->state[i][0];
|
||||
b = State->state[i][1];
|
||||
c = State->state[i][2];
|
||||
d = State->state[i][3];
|
||||
|
||||
State->state[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
|
||||
State->state[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
|
||||
State->state[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
|
||||
State->state[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// InvSubBytes
|
||||
//
|
||||
// The InvSubBytes Function Substitutes the values in the state matrix with values in an S-box.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static
|
||||
void
|
||||
InvSubBytes
|
||||
(
|
||||
AesState* State // [in out]
|
||||
)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
|
||||
for( i=0; i<4; i++ )
|
||||
{
|
||||
for( j=0; j<4; j++ )
|
||||
{
|
||||
State->state[j][i] = RSBOX[ State->state[j][i] ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// InvShiftRows
|
||||
//
|
||||
// Inverse of ShiftRows
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static
|
||||
void
|
||||
InvShiftRows
|
||||
(
|
||||
AesState* State // [in out]
|
||||
)
|
||||
{
|
||||
uint8_t temp;
|
||||
|
||||
// Rotate first row 1 columns to right
|
||||
temp = State->state[3][1];
|
||||
State->state[3][1] = State->state[2][1];
|
||||
State->state[2][1] = State->state[1][1];
|
||||
State->state[1][1] = State->state[0][1];
|
||||
State->state[0][1] = temp;
|
||||
|
||||
// Rotate second row 2 columns to right
|
||||
temp = State->state[0][2];
|
||||
State->state[0][2] = State->state[2][2];
|
||||
State->state[2][2] = temp;
|
||||
|
||||
temp = State->state[1][2];
|
||||
State->state[1][2] = State->state[3][2];
|
||||
State->state[3][2] = temp;
|
||||
|
||||
// Rotate third row 3 columns to right
|
||||
temp = State->state[0][3];
|
||||
State->state[0][3] = State->state[1][3];
|
||||
State->state[1][3] = State->state[2][3];
|
||||
State->state[2][3] = State->state[3][3];
|
||||
State->state[3][3] = temp;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// EXPORTED FUNCTIONS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesInitialise128
|
||||
//
|
||||
// Initialises an AesContext with a 128 bit key.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesInitialise128
|
||||
(
|
||||
uint8_t const Key [AES_KEY_SIZE_128], // [in]
|
||||
AesContext* Context // [out]
|
||||
)
|
||||
{
|
||||
memset( Context, 0, sizeof(*Context) );
|
||||
|
||||
Context->KeySizeInWords = AES_KEY_SIZE_128 / sizeof(uint32_t);
|
||||
Context->NumberOfRounds = 10;
|
||||
|
||||
KeyExpansion( Key, Context );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesInitialise192
|
||||
//
|
||||
// Initialises an AesContext with a 192 bit key.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesInitialise192
|
||||
(
|
||||
uint8_t const Key [AES_KEY_SIZE_192], // [in]
|
||||
AesContext* Context // [out]
|
||||
)
|
||||
{
|
||||
memset( Context, 0, sizeof(*Context) );
|
||||
|
||||
Context->KeySizeInWords = AES_KEY_SIZE_192 / sizeof(uint32_t);
|
||||
Context->NumberOfRounds = 12;
|
||||
|
||||
KeyExpansion( Key, Context );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesInitialise256
|
||||
//
|
||||
// Initialises an AesContext with a 256 bit key.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesInitialise256
|
||||
(
|
||||
uint8_t const Key [AES_KEY_SIZE_256], // [in]
|
||||
AesContext* Context // [out]
|
||||
)
|
||||
{
|
||||
memset( Context, 0, sizeof(*Context) );
|
||||
|
||||
Context->KeySizeInWords = AES_KEY_SIZE_256 / sizeof(uint32_t);
|
||||
Context->NumberOfRounds = 14;
|
||||
|
||||
KeyExpansion( Key, Context );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesEncrypt
|
||||
//
|
||||
// Performs an AES encryption of one block (128 bits) with the AesContext initialised with one of the functions
|
||||
// AesInitialise[n]. Input and Output can point to same memory location, however it is more efficient to use
|
||||
// AesEncryptInPlace in this situation.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesEncrypt
|
||||
(
|
||||
AesContext const* Context, // [in]
|
||||
uint8_t const Input [AES_BLOCK_SIZE], // [in]
|
||||
uint8_t Output [AES_BLOCK_SIZE] // [out]
|
||||
)
|
||||
{
|
||||
memcpy( Output, Input, AES_BLOCK_SIZE );
|
||||
AesEncryptInPlace( Context, Output );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesDecrypt
|
||||
//
|
||||
// Performs an AES decryption of one block (128 bits) with the AesContext initialised with one of the functions
|
||||
// AesInitialise[n]. Input and Output can point to same memory location, however it is more efficient to use
|
||||
// AesDecryptInPlace in this situation.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesDecrypt
|
||||
(
|
||||
AesContext const* Context, // [in]
|
||||
uint8_t const Input [AES_BLOCK_SIZE], // [in]
|
||||
uint8_t Output [AES_BLOCK_SIZE] // [out]
|
||||
)
|
||||
{
|
||||
memcpy( Output, Input, AES_BLOCK_SIZE);
|
||||
AesDecryptInPlace(Context, Output );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesEncryptInPlace
|
||||
//
|
||||
// Performs an AES encryption of one block (128 bits) with the AesContext initialised with one of the functions
|
||||
// AesInitialise[n]. The encryption is performed in place.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesEncryptInPlace
|
||||
(
|
||||
AesContext const* Context, // [in]
|
||||
uint8_t Block [AES_BLOCK_SIZE] // [in out]
|
||||
)
|
||||
{
|
||||
uint32_t round = 0;
|
||||
|
||||
// Add the First round key to the state before starting the rounds.
|
||||
AddRoundKey( 0, Context, (AesState*)Block );
|
||||
|
||||
// There will be Nr rounds.
|
||||
// The first Nr-1 rounds are identical.
|
||||
// These Nr-1 rounds are executed in the loop below.
|
||||
for( round=1; round<Context->NumberOfRounds; round++ )
|
||||
{
|
||||
SubBytes( (AesState*)Block );
|
||||
ShiftRows( (AesState*)Block );
|
||||
MixColumns( (AesState*)Block );
|
||||
AddRoundKey( round, Context, (AesState*)Block );
|
||||
}
|
||||
|
||||
// The last round is given below.
|
||||
// The MixColumns function is not here in the last round.
|
||||
SubBytes( (AesState*)Block);
|
||||
ShiftRows( (AesState*)Block);
|
||||
AddRoundKey( Context->NumberOfRounds, Context, (AesState*)Block );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesDecryptInPlace
|
||||
//
|
||||
// Performs an AES decryption of one block (128 bits) with the AesContext initialised with one of the functions
|
||||
// AesInitialise[n]. The decryption is performed in place.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesDecryptInPlace
|
||||
(
|
||||
AesContext const* Context, // [in]
|
||||
uint8_t Block [AES_BLOCK_SIZE] // [in out]
|
||||
)
|
||||
{
|
||||
uint32_t round = 0;
|
||||
|
||||
// Add the First round key to the state before starting the rounds.
|
||||
AddRoundKey( Context->NumberOfRounds, Context, (AesState*)Block );
|
||||
|
||||
// The first NumberOfRounds-1 rounds are identical.
|
||||
for( round=(Context->NumberOfRounds-1); round>0; round-- )
|
||||
{
|
||||
InvShiftRows( (AesState*)Block );
|
||||
InvSubBytes( (AesState*)Block );
|
||||
AddRoundKey( round, Context, (AesState*)Block );
|
||||
InvMixColumns( (AesState*)Block );
|
||||
}
|
||||
|
||||
// The MixColumns function is not here in the last round.
|
||||
InvShiftRows( (AesState*)Block );
|
||||
InvSubBytes( (AesState*)Block );
|
||||
AddRoundKey( 0, Context, (AesState*)Block );
|
||||
}
|
||||
1006
lib/WjCryptLib_Aes.c
Normal file
1006
lib/WjCryptLib_Aes.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,18 +1,22 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLib_Aes
|
||||
// WjCryptLib_Aes
|
||||
//
|
||||
// Implementation of AES block cipher. Originally written by Kokke (https://github.com/kokke). Modified by WaterJuice
|
||||
// retaining Public Domain license.
|
||||
// Implementation of AES block cipher. This implementation was modified from LibTomCrypt written by Tom St Denis
|
||||
// (https://github.com/libtom). Modified by WaterJuice retaining Public Domain license.
|
||||
// Derived from Public Domain source by original authors:
|
||||
// Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
|
||||
// Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
|
||||
// Paulo Barreto <paulo.barreto@terra.com.br>
|
||||
//
|
||||
// AES is a block cipher that operates on 128 bit blocks. Encryption an Decryption routines use an AesContext which
|
||||
// must be initialised with the key. An AesContext can be initialised with a 128, 192, or 256 bit key. Use the
|
||||
// AesInitialise[n] functions to initialise the context with the key. Once an AES context is initialised its contents
|
||||
// are not changed by the encrypting and decrypting functions. A context only needs to be initialised once for any
|
||||
// given key and the context may be used by the encrypt/decrypt functions in simultaneous threads.
|
||||
// All operations are performed byte wise and this implementation works in both little and endian processors.
|
||||
// All operations are performed BYTE wise and this implementation works in both little and endian processors.
|
||||
// There are no alignment requirements with the keys and data blocks.
|
||||
//
|
||||
// This is free and unencumbered software released into the public domain - November 2017 waterjuice.org
|
||||
// This is free and unencumbered software released into the public domain - December 2017 waterjuice.org
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
@@ -36,9 +40,9 @@
|
||||
// Do not modify the contents of this structure directly.
|
||||
typedef struct
|
||||
{
|
||||
uint32_t KeySizeInWords;
|
||||
uint32_t NumberOfRounds;
|
||||
uint8_t RoundKey[240];
|
||||
uint32_t eK[60];
|
||||
uint32_t dK[60];
|
||||
uint_fast32_t Nr;
|
||||
} AesContext;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -46,39 +50,17 @@ typedef struct
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesInitialise128
|
||||
// AesInitialise
|
||||
//
|
||||
// Initialises an AesContext with a 128 bit key.
|
||||
// Initialises an AesContext with an AES Key. KeySize must be 16, 24, or 32 (for 128, 192, or 256 bit key size)
|
||||
// Returns 0 if successful, or -1 if invalid KeySize provided
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesInitialise128
|
||||
int
|
||||
AesInitialise
|
||||
(
|
||||
uint8_t const Key [AES_KEY_SIZE_128], // [in]
|
||||
AesContext* Context // [out]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesInitialise192
|
||||
//
|
||||
// Initialises an AesContext with a 192 bit key.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesInitialise192
|
||||
(
|
||||
uint8_t const Key [AES_KEY_SIZE_192], // [in]
|
||||
AesContext* Context // [out]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesInitialise256
|
||||
//
|
||||
// Initialises an AesContext with a 256 bit key.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesInitialise256
|
||||
(
|
||||
uint8_t const Key [AES_KEY_SIZE_256], // [in]
|
||||
AesContext* Context // [out]
|
||||
AesContext* Context, // [out]
|
||||
void const* Key, // [in]
|
||||
uint32_t KeySize // [in]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLib_AesCtr
|
||||
// WjCryptLib_AesCtr
|
||||
//
|
||||
// Implementation of AES CTR stream cipher.
|
||||
//
|
||||
@@ -15,8 +15,8 @@
|
||||
// IMPORTS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "CryptLib_AesCtr.h"
|
||||
#include "CryptLib_Aes.h"
|
||||
#include "WjCryptLib_AesCtr.h"
|
||||
#include "WjCryptLib_Aes.h"
|
||||
#include <stdint.h>
|
||||
#include <memory.h>
|
||||
|
||||
@@ -96,9 +96,9 @@ void
|
||||
void
|
||||
AesCtrInitialise
|
||||
(
|
||||
AesCtrContext* Context, // [out]
|
||||
AesContext const* InitialisedAesContext, // [in]
|
||||
uint8_t const IV [AES_CTR_IV_SIZE], // [in]
|
||||
AesCtrContext* Context // [out]
|
||||
uint8_t const IV [AES_CTR_IV_SIZE] // [in]
|
||||
)
|
||||
{
|
||||
// Setup context values
|
||||
@@ -121,27 +121,22 @@ void
|
||||
int
|
||||
AesCtrInitialiseWithKey
|
||||
(
|
||||
AesCtrContext* Context, // [out]
|
||||
uint8_t const* Key, // [in]
|
||||
uint32_t KeySize, // [in]
|
||||
uint8_t const IV [AES_CTR_IV_SIZE], // [in]
|
||||
AesCtrContext* Context // [out]
|
||||
uint8_t const IV [AES_CTR_IV_SIZE] // [in]
|
||||
)
|
||||
{
|
||||
AesContext aes;
|
||||
|
||||
// Initialise AES Context
|
||||
switch( KeySize )
|
||||
if( 0 != AesInitialise( &aes, Key, KeySize ) )
|
||||
{
|
||||
case AES_KEY_SIZE_128: AesInitialise128( Key, &aes ); break;
|
||||
case AES_KEY_SIZE_192: AesInitialise192( Key, &aes ); break;
|
||||
case AES_KEY_SIZE_256: AesInitialise256( Key, &aes ); break;
|
||||
default:
|
||||
// Invalid key size
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Now set-up AesCtrContext
|
||||
AesCtrInitialise( &aes, IV, Context );
|
||||
AesCtrInitialise( Context, &aes, IV );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -177,7 +172,7 @@ void
|
||||
// advance the stream index by that number of bytes.
|
||||
// Use once over data to encrypt it. Use it a second time over the same data from the same stream position and the
|
||||
// data will be decrypted.
|
||||
// InBuffer and OutBuffer can point to the same location for inplace encrypting/decrypting
|
||||
// InBuffer and OutBuffer can point to the same location for in-place encrypting/decrypting
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesCtrXor
|
||||
@@ -188,47 +183,68 @@ void
|
||||
uint32_t Size // [in]
|
||||
)
|
||||
{
|
||||
uint32_t amountLeft = Size;
|
||||
uint32_t outputOffset = 0;
|
||||
uint32_t chunkSize;
|
||||
uint32_t amountAvailableInBlock;
|
||||
uint32_t firstChunkSize;
|
||||
uint32_t amountAvailableInBlock;
|
||||
int numIterations;
|
||||
int i;
|
||||
uint64_t loopStartingCipherBlockIndex;
|
||||
uint32_t loopStartingOutputOffset;
|
||||
uint8_t preCipherBlock [AES_KEY_SIZE_128];
|
||||
uint8_t encCipherBlock [AES_KEY_SIZE_128];
|
||||
uint64_t cipherBlockIndex = 0;
|
||||
|
||||
// First determine how much is available in the current block.
|
||||
amountAvailableInBlock = AES_BLOCK_SIZE - (Context->StreamIndex % AES_BLOCK_SIZE);
|
||||
|
||||
// Determine how much of the current block we will take, either all that is available, or less
|
||||
// if the amount requested is smaller.
|
||||
chunkSize = MIN( amountAvailableInBlock, amountLeft );
|
||||
firstChunkSize = MIN( amountAvailableInBlock, Size );
|
||||
|
||||
// XOR the bytes from the cipher block
|
||||
XorBuffers( InBuffer, Context->CurrentCipherBlock + (AES_BLOCK_SIZE - amountAvailableInBlock), OutBuffer, chunkSize );
|
||||
XorBuffers( InBuffer, Context->CurrentCipherBlock + (AES_BLOCK_SIZE - amountAvailableInBlock), OutBuffer, firstChunkSize );
|
||||
|
||||
amountLeft -= chunkSize;
|
||||
outputOffset += chunkSize;
|
||||
// Determine how many iterations will be needed for generating cipher blocks.
|
||||
// We always have to finish with a non-depleted cipher block.
|
||||
// Also calculate the cipher block index and the output offset for when we start the loop.
|
||||
// This function may be built with OpenMP and the loop will run in parallel. So we set-up variables that will
|
||||
// be common at the start of the loop.
|
||||
numIterations = ( (Size - firstChunkSize) + AES_BLOCK_SIZE ) / AES_BLOCK_SIZE;
|
||||
loopStartingCipherBlockIndex = Context->CurrentCipherBlockIndex + 1;
|
||||
loopStartingOutputOffset = firstChunkSize;
|
||||
|
||||
// Copy the IV into the first half of the preCipherBlock. When built for OpenMP preCipherBlock will be copied into
|
||||
// a local version within the loop.
|
||||
memcpy( preCipherBlock, Context->IV, AES_CTR_IV_SIZE );
|
||||
|
||||
// Now start generating new cipher blocks as required.
|
||||
while( amountLeft > 0 )
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for firstprivate( preCipherBlock, cipherBlockIndex ) lastprivate( encCipherBlock, cipherBlockIndex )
|
||||
#endif
|
||||
for( i=0; i<numIterations; i++ )
|
||||
{
|
||||
uint32_t outputOffset = loopStartingOutputOffset + (AES_BLOCK_SIZE * i);
|
||||
uint32_t amountLeft = Size - outputOffset;
|
||||
uint32_t chunkSize = MIN( amountLeft, AES_BLOCK_SIZE );
|
||||
|
||||
// Increment block index and regenerate cipher block
|
||||
Context->CurrentCipherBlockIndex += 1;
|
||||
CreateCurrentCipherBlock( Context );
|
||||
cipherBlockIndex = loopStartingCipherBlockIndex + i;
|
||||
|
||||
// Determine how much of the current block we need and XOR it out onto the buffer
|
||||
chunkSize = MIN( amountLeft, AES_BLOCK_SIZE );
|
||||
XorBuffers( (uint8_t*)InBuffer + outputOffset, Context->CurrentCipherBlock, (uint8_t*)OutBuffer + outputOffset, chunkSize );
|
||||
// Now place in the counter in Big Endian form in second half of preCipherBlock
|
||||
STORE64H( cipherBlockIndex, preCipherBlock + AES_CTR_IV_SIZE );
|
||||
|
||||
amountLeft -= chunkSize;
|
||||
outputOffset += chunkSize;
|
||||
// Perform AES encryption on the preCipherBlock and put result in encCipherBlock
|
||||
AesEncrypt( &Context->Aes, preCipherBlock, encCipherBlock );
|
||||
|
||||
// XOR block out onto the buffer.
|
||||
XorBuffers( (uint8_t*)InBuffer + outputOffset, encCipherBlock, (uint8_t*)OutBuffer + outputOffset, chunkSize );
|
||||
}
|
||||
|
||||
// All data read out now, so update index in the context.
|
||||
// Update context
|
||||
Context->StreamIndex += Size;
|
||||
|
||||
// If we ended up completely reading the last cipher block we need to generate a new one for next time.
|
||||
if( AES_BLOCK_SIZE == chunkSize )
|
||||
if( numIterations > 0 )
|
||||
{
|
||||
Context->CurrentCipherBlockIndex += 1;
|
||||
CreateCurrentCipherBlock( Context );
|
||||
Context->CurrentCipherBlockIndex = cipherBlockIndex;
|
||||
memcpy( Context->CurrentCipherBlock, encCipherBlock, AES_BLOCK_SIZE );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,7 +289,7 @@ int
|
||||
int error;
|
||||
AesCtrContext context;
|
||||
|
||||
error = AesCtrInitialiseWithKey( Key, KeySize, IV, &context );
|
||||
error = AesCtrInitialiseWithKey( &context, Key, KeySize, IV );
|
||||
if( 0 == error )
|
||||
{
|
||||
AesCtrXor( &context, InBuffer, OutBuffer, BufferSize );
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLib_AesCtr
|
||||
// WjCryptLib_AesCtr
|
||||
//
|
||||
// Implementation of AES CTR stream cipher.
|
||||
//
|
||||
@@ -18,7 +18,7 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdint.h>
|
||||
#include "CryptLib_Aes.h"
|
||||
#include "WjCryptLib_Aes.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TYPES
|
||||
@@ -54,9 +54,9 @@ typedef struct
|
||||
void
|
||||
AesCtrInitialise
|
||||
(
|
||||
AesCtrContext* Context, // [out]
|
||||
AesContext const* InitialisedAesContext, // [in]
|
||||
uint8_t const IV [AES_CTR_IV_SIZE], // [in]
|
||||
AesCtrContext* Context // [out]
|
||||
uint8_t const IV [AES_CTR_IV_SIZE] // [in]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -69,10 +69,10 @@ void
|
||||
int
|
||||
AesCtrInitialiseWithKey
|
||||
(
|
||||
AesCtrContext* Context, // [out]
|
||||
uint8_t const* Key, // [in]
|
||||
uint32_t KeySize, // [in]
|
||||
uint8_t const IV [AES_CTR_IV_SIZE], // [in]
|
||||
AesCtrContext* Context // [out]
|
||||
uint8_t const IV [AES_CTR_IV_SIZE] // [in]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -95,7 +95,7 @@ void
|
||||
// advance the stream index by that number of bytes.
|
||||
// Use once over data to encrypt it. Use it a second time over the same data from the same stream position and the
|
||||
// data will be decrypted.
|
||||
// InBuffer and OutBuffer can point to the same location for inplace encrypting/decrypting
|
||||
// InBuffer and OutBuffer can point to the same location for in-place encrypting/decrypting
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesCtrXor
|
||||
226
lib/WjCryptLib_AesOfb.c
Normal file
226
lib/WjCryptLib_AesOfb.c
Normal file
@@ -0,0 +1,226 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// WjCryptLib_AesOfb
|
||||
//
|
||||
// Implementation of AES OFB stream cipher.
|
||||
//
|
||||
// Depends on: CryptoLib_Aes
|
||||
//
|
||||
// AES OFB is a stream cipher using the AES block cipher in output feedback mode.
|
||||
// This implementation works on both little and big endian architectures.
|
||||
//
|
||||
// This is free and unencumbered software released into the public domain - January 2018 waterjuice.org
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// IMPORTS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "WjCryptLib_AesOfb.h"
|
||||
#include "WjCryptLib_Aes.h"
|
||||
#include <stdint.h>
|
||||
#include <memory.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// MACROS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define MIN( x, y ) ( ((x)<(y))?(x):(y) )
|
||||
|
||||
#define STORE64H( x, y ) \
|
||||
{ (y)[0] = (uint8_t)(((x)>>56)&255); (y)[1] = (uint8_t)(((x)>>48)&255); \
|
||||
(y)[2] = (uint8_t)(((x)>>40)&255); (y)[3] = (uint8_t)(((x)>>32)&255); \
|
||||
(y)[4] = (uint8_t)(((x)>>24)&255); (y)[5] = (uint8_t)(((x)>>16)&255); \
|
||||
(y)[6] = (uint8_t)(((x)>>8)&255); (y)[7] = (uint8_t)((x)&255); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// INTERNAL FUNCTIONS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// XorBuffer
|
||||
//
|
||||
// Takes two Source buffers and XORs them together and puts the result in DestinationBuffer
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static
|
||||
void
|
||||
XorBuffers
|
||||
(
|
||||
uint8_t const* SourceBuffer1, // [in]
|
||||
uint8_t const* SourceBuffer2, // [in]
|
||||
uint8_t* DestinationBuffer, // [out]
|
||||
uint32_t Amount // [in]
|
||||
)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for( i=0; i<Amount; i++ )
|
||||
{
|
||||
DestinationBuffer[i] = SourceBuffer1[i] ^ SourceBuffer2[i];
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PUBLIC FUNCTIONS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesOfbInitialise
|
||||
//
|
||||
// Initialises an AesOfbContext with an already initialised AesContext and a IV. This function can quickly be used
|
||||
// to change the IV without requiring the more lengthy processes of reinitialising an AES key.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesOfbInitialise
|
||||
(
|
||||
AesOfbContext* Context, // [out]
|
||||
AesContext const* InitialisedAesContext, // [in]
|
||||
uint8_t const IV [AES_OFB_IV_SIZE] // [in]
|
||||
)
|
||||
{
|
||||
// Setup context values
|
||||
Context->Aes = *InitialisedAesContext;
|
||||
memcpy( Context->CurrentCipherBlock, IV, sizeof(Context->CurrentCipherBlock) );
|
||||
Context->IndexWithinCipherBlock = 0;
|
||||
|
||||
// Generate the first cipher block of the stream.
|
||||
AesEncryptInPlace( &Context->Aes, Context->CurrentCipherBlock );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesOfbInitialiseWithKey
|
||||
//
|
||||
// Initialises an AesOfbContext with an AES Key and an IV. This combines the initialising an AES Context and then
|
||||
// running AesOfbInitialise. KeySize must be 16, 24, or 32 (for 128, 192, or 256 bit key size)
|
||||
// Returns 0 if successful, or -1 if invalid KeySize provided
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
int
|
||||
AesOfbInitialiseWithKey
|
||||
(
|
||||
AesOfbContext* Context, // [out]
|
||||
uint8_t const* Key, // [in]
|
||||
uint32_t KeySize, // [in]
|
||||
uint8_t const IV [AES_OFB_IV_SIZE] // [in]
|
||||
)
|
||||
{
|
||||
AesContext aes;
|
||||
|
||||
// Initialise AES Context
|
||||
if( 0 != AesInitialise( &aes, Key, KeySize ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Now set-up AesOfbContext
|
||||
AesOfbInitialise( Context, &aes, IV );
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesOfbXor
|
||||
//
|
||||
// XORs the stream of byte of the AesOfbContext from its current stream position onto the specified buffer. This will
|
||||
// advance the stream index by that number of bytes.
|
||||
// Use once over data to encrypt it. Use it a second time over the same data from the same stream position and the
|
||||
// data will be decrypted.
|
||||
// InBuffer and OutBuffer can point to the same location for in-place encrypting/decrypting
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesOfbXor
|
||||
(
|
||||
AesOfbContext* Context, // [in out]
|
||||
void const* InBuffer, // [in]
|
||||
void* OutBuffer, // [out]
|
||||
uint32_t Size // [in]
|
||||
)
|
||||
{
|
||||
uint32_t amountLeft = Size;
|
||||
uint32_t outputOffset = 0;
|
||||
uint32_t chunkSize;
|
||||
uint32_t amountAvailableInBlock;
|
||||
|
||||
// First determine how much is available in the current block.
|
||||
amountAvailableInBlock = AES_BLOCK_SIZE - Context->IndexWithinCipherBlock;
|
||||
|
||||
// Determine how much of the current block we will take, either all that is available, or less
|
||||
// if the amount requested is smaller.
|
||||
chunkSize = MIN( amountAvailableInBlock, amountLeft );
|
||||
|
||||
// XOR the bytes from the cipher block
|
||||
XorBuffers( InBuffer, Context->CurrentCipherBlock + (AES_BLOCK_SIZE - amountAvailableInBlock), OutBuffer, chunkSize );
|
||||
|
||||
amountLeft -= chunkSize;
|
||||
outputOffset += chunkSize;
|
||||
Context->IndexWithinCipherBlock += chunkSize;
|
||||
|
||||
// Now start generating new cipher blocks as required.
|
||||
while( amountLeft > 0 )
|
||||
{
|
||||
// Generate new cipher block
|
||||
AesEncryptInPlace( &Context->Aes, Context->CurrentCipherBlock );
|
||||
|
||||
// Determine how much of the current block we need and XOR it out onto the buffer
|
||||
chunkSize = MIN( amountLeft, AES_BLOCK_SIZE );
|
||||
XorBuffers( (uint8_t*)InBuffer + outputOffset, Context->CurrentCipherBlock, (uint8_t*)OutBuffer + outputOffset, chunkSize );
|
||||
|
||||
amountLeft -= chunkSize;
|
||||
outputOffset += chunkSize;
|
||||
Context->IndexWithinCipherBlock = chunkSize; // Note: Not incremented
|
||||
}
|
||||
|
||||
// If we ended up completely reading the last cipher block we need to generate a new one for next time.
|
||||
if( AES_BLOCK_SIZE == chunkSize )
|
||||
{
|
||||
AesEncryptInPlace( &Context->Aes, Context->CurrentCipherBlock );
|
||||
Context->IndexWithinCipherBlock = 0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesOfbOutput
|
||||
//
|
||||
// Outputs the stream of byte of the AesOfbContext from its current stream position. This will advance the stream
|
||||
// index by that number of bytes.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesOfbOutput
|
||||
(
|
||||
AesOfbContext* Context, // [in out]
|
||||
void* Buffer, // [out]
|
||||
uint32_t Size // [in]
|
||||
)
|
||||
{
|
||||
memset( Buffer, 0, Size );
|
||||
AesOfbXor( Context, Buffer, Buffer, Size );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesOfbXorWithKey
|
||||
//
|
||||
// This function combines AesOfbInitialiseWithKey and AesOfbXor. This is suitable when encrypting/decypting data in
|
||||
// one go with a key that is not going to be reused.
|
||||
// This will used the provided Key and IV and generate a stream that is XORed over Buffer.
|
||||
// InBuffer and OutBuffer can point to the same location for inplace encrypting/decrypting
|
||||
// Returns 0 if successful, or -1 if invalid KeySize provided
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
int
|
||||
AesOfbXorWithKey
|
||||
(
|
||||
uint8_t const* Key, // [in]
|
||||
uint32_t KeySize, // [in]
|
||||
uint8_t const IV [AES_OFB_IV_SIZE], // [in]
|
||||
void const* InBuffer, // [in]
|
||||
void* OutBuffer, // [out]
|
||||
uint32_t BufferSize // [in]
|
||||
)
|
||||
{
|
||||
int error;
|
||||
AesOfbContext context;
|
||||
|
||||
error = AesOfbInitialiseWithKey( &context, Key, KeySize, IV );
|
||||
if( 0 == error )
|
||||
{
|
||||
AesOfbXor( &context, InBuffer, OutBuffer, BufferSize );
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
126
lib/WjCryptLib_AesOfb.h
Normal file
126
lib/WjCryptLib_AesOfb.h
Normal file
@@ -0,0 +1,126 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// WjCryptLib_AesOfb
|
||||
//
|
||||
// Implementation of AES OFB stream cipher.
|
||||
//
|
||||
// Depends on: CryptoLib_Aes
|
||||
//
|
||||
// AES OFB is a stream cipher using the AES block cipher in output feedback mode.
|
||||
// This implementation works on both little and big endian architectures.
|
||||
//
|
||||
// This is free and unencumbered software released into the public domain - January 2018 waterjuice.org
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// IMPORTS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdint.h>
|
||||
#include "WjCryptLib_Aes.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TYPES
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define AES_OFB_IV_SIZE AES_BLOCK_SIZE
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TYPES
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// AesOfbContext
|
||||
// Do not modify the contents of this structure directly.
|
||||
typedef struct
|
||||
{
|
||||
AesContext Aes;
|
||||
uint8_t CurrentCipherBlock [AES_BLOCK_SIZE];
|
||||
uint32_t IndexWithinCipherBlock;
|
||||
} AesOfbContext;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PUBLIC FUNCTIONS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesOfbInitialise
|
||||
//
|
||||
// Initialises an AesOfbContext with an already initialised AesContext and a IV. This function can quickly be used
|
||||
// to change the IV without requiring the more lengthy processes of reinitialising an AES key.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesOfbInitialise
|
||||
(
|
||||
AesOfbContext* Context, // [out]
|
||||
AesContext const* InitialisedAesContext, // [in]
|
||||
uint8_t const IV [AES_OFB_IV_SIZE] // [in]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesOfbInitialiseWithKey
|
||||
//
|
||||
// Initialises an AesOfbContext with an AES Key and an IV. This combines the initialising an AES Context and then
|
||||
// running AesOfbInitialise. KeySize must be 16, 24, or 32 (for 128, 192, or 256 bit key size)
|
||||
// Returns 0 if successful, or -1 if invalid KeySize provided
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
int
|
||||
AesOfbInitialiseWithKey
|
||||
(
|
||||
AesOfbContext* Context, // [out]
|
||||
uint8_t const* Key, // [in]
|
||||
uint32_t KeySize, // [in]
|
||||
uint8_t const IV [AES_OFB_IV_SIZE] // [in]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesOfbXor
|
||||
//
|
||||
// XORs the stream of byte of the AesOfbContext from its current stream position onto the specified buffer. This will
|
||||
// advance the stream index by that number of bytes.
|
||||
// Use once over data to encrypt it. Use it a second time over the same data from the same stream position and the
|
||||
// data will be decrypted.
|
||||
// InBuffer and OutBuffer can point to the same location for in-place encrypting/decrypting
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesOfbXor
|
||||
(
|
||||
AesOfbContext* Context, // [in out]
|
||||
void const* InBuffer, // [in]
|
||||
void* OutBuffer, // [out]
|
||||
uint32_t Size // [in]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesOfbOutput
|
||||
//
|
||||
// Outputs the stream of byte of the AesOfbContext from its current stream position. This will advance the stream
|
||||
// index by that number of bytes.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
AesOfbOutput
|
||||
(
|
||||
AesOfbContext* Context, // [in out]
|
||||
void* Buffer, // [out]
|
||||
uint32_t Size // [in]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesOfbXorWithKey
|
||||
//
|
||||
// This function combines AesOfbInitialiseWithKey and AesOfbXor. This is suitable when encrypting/decypting data in
|
||||
// one go with a key that is not going to be reused.
|
||||
// This will used the provided Key and IV and generate a stream that is XORed over Buffer.
|
||||
// InBuffer and OutBuffer can point to the same location for inplace encrypting/decrypting
|
||||
// Returns 0 if successful, or -1 if invalid KeySize provided
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
int
|
||||
AesOfbXorWithKey
|
||||
(
|
||||
uint8_t const* Key, // [in]
|
||||
uint32_t KeySize, // [in]
|
||||
uint8_t const IV [AES_OFB_IV_SIZE], // [in]
|
||||
void const* InBuffer, // [in]
|
||||
void* OutBuffer, // [out]
|
||||
uint32_t BufferSize // [in]
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLib_Md5
|
||||
// WjCryptLib_Md5
|
||||
//
|
||||
// Implementation of MD5 hash function. Originally written by Alexander Peslyak. Modified by WaterJuice retaining
|
||||
// Public Domain license.
|
||||
@@ -11,7 +11,7 @@
|
||||
// IMPORTS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "CryptLib_Md5.h"
|
||||
#include "WjCryptLib_Md5.h"
|
||||
#include <memory.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -66,10 +66,10 @@ void*
|
||||
|
||||
#define GET(n) (ctx->block[(n)])
|
||||
#define SET(n) (ctx->block[(n)] = \
|
||||
((uint32_t)ptr[(n)*4 + 0] << 0 ) \
|
||||
| ((uint32_t)ptr[(n)*4 + 1] << 8 ) \
|
||||
| ((uint32_t)ptr[(n)*4 + 2] << 16) \
|
||||
| ((uint32_t)ptr[(n)*4 + 3] << 24) )
|
||||
((uint32_t)ptr[(n)*4 + 0] << 0 ) \
|
||||
| ((uint32_t)ptr[(n)*4 + 1] << 8 ) \
|
||||
| ((uint32_t)ptr[(n)*4 + 2] << 16) \
|
||||
| ((uint32_t)ptr[(n)*4 + 3] << 24) )
|
||||
|
||||
ptr = (uint8_t*)data;
|
||||
|
||||
@@ -188,7 +188,7 @@ void*
|
||||
void
|
||||
Md5Initialise
|
||||
(
|
||||
Md5Context* Context
|
||||
Md5Context* Context // [out]
|
||||
)
|
||||
{
|
||||
Context->a = 0x67452301;
|
||||
@@ -209,9 +209,9 @@ void
|
||||
void
|
||||
Md5Update
|
||||
(
|
||||
Md5Context* Context,
|
||||
void const* Buffer,
|
||||
uint32_t BufferSize
|
||||
Md5Context* Context, // [in out]
|
||||
void const* Buffer, // [in]
|
||||
uint32_t BufferSize // [in]
|
||||
)
|
||||
{
|
||||
uint32_t saved_lo;
|
||||
@@ -261,8 +261,8 @@ void
|
||||
void
|
||||
Md5Finalise
|
||||
(
|
||||
Md5Context* Context,
|
||||
MD5_HASH* Digest
|
||||
Md5Context* Context, // [in out]
|
||||
MD5_HASH* Digest // [in]
|
||||
)
|
||||
{
|
||||
uint32_t used;
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLib_Md5
|
||||
// WjCryptLib_Md5
|
||||
//
|
||||
// Implementation of MD5 hash function. Originally written by Alexander Peslyak. Modified by WaterJuice retaining
|
||||
// Public Domain license.
|
||||
@@ -52,7 +52,7 @@ typedef struct
|
||||
void
|
||||
Md5Initialise
|
||||
(
|
||||
Md5Context* Context
|
||||
Md5Context* Context // [out]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -64,9 +64,9 @@ void
|
||||
void
|
||||
Md5Update
|
||||
(
|
||||
Md5Context* Context,
|
||||
void const* Buffer,
|
||||
uint32_t BufferSize
|
||||
Md5Context* Context, // [in out]
|
||||
void const* Buffer, // [in]
|
||||
uint32_t BufferSize // [in]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -78,6 +78,6 @@ void
|
||||
void
|
||||
Md5Finalise
|
||||
(
|
||||
Md5Context* Context,
|
||||
MD5_HASH* Digest
|
||||
Md5Context* Context, // [in out]
|
||||
MD5_HASH* Digest // [in]
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLib_RC4
|
||||
// WjCryptLib_RC4
|
||||
//
|
||||
// An implementation of RC4 stream cipher
|
||||
//
|
||||
@@ -10,7 +10,7 @@
|
||||
// IMPORTS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "CryptLib_Rc4.h"
|
||||
#include "WjCryptLib_Rc4.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -36,10 +36,10 @@
|
||||
void
|
||||
Rc4Initialise
|
||||
(
|
||||
Rc4Context* Context,
|
||||
void const* Key,
|
||||
uint32_t KeySize,
|
||||
uint32_t DropN
|
||||
Rc4Context* Context, // [out]
|
||||
void const* Key, // [in]
|
||||
uint32_t KeySize, // [in]
|
||||
uint32_t DropN // [in]
|
||||
)
|
||||
{
|
||||
uint32_t i;
|
||||
@@ -82,9 +82,9 @@ void
|
||||
void
|
||||
Rc4Output
|
||||
(
|
||||
Rc4Context* Context,
|
||||
void* Buffer,
|
||||
uint32_t Size
|
||||
Rc4Context* Context, // [in out]
|
||||
void* Buffer, // [out]
|
||||
uint32_t Size // [in]
|
||||
)
|
||||
{
|
||||
uint32_t n;
|
||||
@@ -108,10 +108,10 @@ void
|
||||
void
|
||||
Rc4Xor
|
||||
(
|
||||
Rc4Context* Context,
|
||||
void const* InBuffer,
|
||||
void* OutBuffer,
|
||||
uint32_t Size
|
||||
Rc4Context* Context, // [in out]
|
||||
void const* InBuffer, // [in]
|
||||
void* OutBuffer, // [out]
|
||||
uint32_t Size // [in]
|
||||
)
|
||||
{
|
||||
uint32_t n;
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLib_RC4
|
||||
// WjCryptLib_RC4
|
||||
//
|
||||
// An implementation of RC4 stream cipher
|
||||
//
|
||||
@@ -38,10 +38,10 @@ typedef struct
|
||||
void
|
||||
Rc4Initialise
|
||||
(
|
||||
Rc4Context* Context,
|
||||
void const* Key,
|
||||
uint32_t KeySize,
|
||||
uint32_t DropN
|
||||
Rc4Context* Context, // [out]
|
||||
void const* Key, // [in]
|
||||
uint32_t KeySize, // [in]
|
||||
uint32_t DropN // [in]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -52,9 +52,9 @@ void
|
||||
void
|
||||
Rc4Output
|
||||
(
|
||||
Rc4Context* Context,
|
||||
void* Buffer,
|
||||
uint32_t Size
|
||||
Rc4Context* Context, // [in out]
|
||||
void* Buffer, // [out]
|
||||
uint32_t Size // [in]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -66,8 +66,8 @@ void
|
||||
void
|
||||
Rc4Xor
|
||||
(
|
||||
Rc4Context* Context,
|
||||
void const* InBuffer,
|
||||
void* OutBuffer,
|
||||
uint32_t Size
|
||||
Rc4Context* Context, // [in out]
|
||||
void const* InBuffer, // [in]
|
||||
void* OutBuffer, // [out]
|
||||
uint32_t Size // [in]
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLib_Sha1
|
||||
// WjCryptLib_Sha1
|
||||
//
|
||||
// Implementation of SHA1 hash function.
|
||||
// Original author: Steve Reid <sreid@sea-to-sky.net>
|
||||
@@ -14,7 +14,7 @@
|
||||
// IMPORTS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "CryptLib_Sha1.h"
|
||||
#include "WjCryptLib_Sha1.h"
|
||||
#include <memory.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -158,7 +158,7 @@ void
|
||||
void
|
||||
Sha1Initialise
|
||||
(
|
||||
Sha1Context* Context
|
||||
Sha1Context* Context // [out]
|
||||
)
|
||||
{
|
||||
// SHA1 initialisation constants
|
||||
@@ -180,9 +180,9 @@ void
|
||||
void
|
||||
Sha1Update
|
||||
(
|
||||
Sha1Context* Context,
|
||||
void const* Buffer,
|
||||
uint32_t BufferSize
|
||||
Sha1Context* Context, // [in out]
|
||||
void const* Buffer, // [in]
|
||||
uint32_t BufferSize // [in]
|
||||
)
|
||||
{
|
||||
uint32_t i;
|
||||
@@ -223,8 +223,8 @@ void
|
||||
void
|
||||
Sha1Finalise
|
||||
(
|
||||
Sha1Context* Context,
|
||||
SHA1_HASH* Digest
|
||||
Sha1Context* Context, // [in out]
|
||||
SHA1_HASH* Digest // [in]
|
||||
)
|
||||
{
|
||||
uint32_t i;
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLib_Sha1
|
||||
// WjCryptLib_Sha1
|
||||
//
|
||||
// Implementation of SHA1 hash function.
|
||||
// Original author: Steve Reid <sreid@sea-to-sky.net>
|
||||
@@ -50,7 +50,7 @@ typedef struct
|
||||
void
|
||||
Sha1Initialise
|
||||
(
|
||||
Sha1Context* Context
|
||||
Sha1Context* Context // [out]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -62,9 +62,9 @@ void
|
||||
void
|
||||
Sha1Update
|
||||
(
|
||||
Sha1Context* Context,
|
||||
void const* Buffer,
|
||||
uint32_t BufferSize
|
||||
Sha1Context* Context, // [in out]
|
||||
void const* Buffer, // [in]
|
||||
uint32_t BufferSize // [in]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -76,6 +76,6 @@ void
|
||||
void
|
||||
Sha1Finalise
|
||||
(
|
||||
Sha1Context* Context,
|
||||
SHA1_HASH* Digest
|
||||
Sha1Context* Context, // [in out]
|
||||
SHA1_HASH* Digest // [in]
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLib_Sha256
|
||||
// WjCryptLib_Sha256
|
||||
//
|
||||
// Implementation of SHA256 hash function.
|
||||
// Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org
|
||||
@@ -12,7 +12,7 @@
|
||||
// IMPORTS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "CryptLib_Sha256.h"
|
||||
#include "WjCryptLib_Sha256.h"
|
||||
#include <memory.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -151,9 +151,10 @@ void
|
||||
//
|
||||
// Initialises a SHA256 Context. Use this to initialise/reset a context.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Sha256Initialise
|
||||
void
|
||||
Sha256Initialise
|
||||
(
|
||||
Sha256Context* Context
|
||||
Sha256Context* Context // [out]
|
||||
)
|
||||
{
|
||||
Context->curlen = 0;
|
||||
@@ -174,15 +175,16 @@ void Sha256Initialise
|
||||
// Adds data to the SHA256 context. This will process the data and update the internal state of the context. Keep on
|
||||
// calling this function until all the data has been added. Then call Sha256Finalise to calculate the hash.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Sha256Update
|
||||
void
|
||||
Sha256Update
|
||||
(
|
||||
Sha256Context* Context,
|
||||
void const* Buffer,
|
||||
uint32_t BufferSize
|
||||
Sha256Context* Context, // [in out]
|
||||
void const* Buffer, // [in]
|
||||
uint32_t BufferSize // [in]
|
||||
)
|
||||
{
|
||||
uint32_t n
|
||||
;
|
||||
uint32_t n;
|
||||
|
||||
if( Context->curlen > sizeof(Context->buf) )
|
||||
{
|
||||
return;
|
||||
@@ -223,8 +225,8 @@ void Sha256Update
|
||||
void
|
||||
Sha256Finalise
|
||||
(
|
||||
Sha256Context* Context,
|
||||
SHA256_HASH* Digest
|
||||
Sha256Context* Context, // [in out]
|
||||
SHA256_HASH* Digest // [out]
|
||||
)
|
||||
{
|
||||
int i;
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLib_Sha256
|
||||
// WjCryptLib_Sha256
|
||||
//
|
||||
// Implementation of SHA256 hash function.
|
||||
// Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org
|
||||
@@ -41,9 +41,10 @@ typedef struct
|
||||
//
|
||||
// Initialises a SHA256 Context. Use this to initialise/reset a context.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Sha256Initialise
|
||||
void
|
||||
Sha256Initialise
|
||||
(
|
||||
Sha256Context* Context
|
||||
Sha256Context* Context // [out]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -52,11 +53,12 @@ void Sha256Initialise
|
||||
// Adds data to the SHA256 context. This will process the data and update the internal state of the context. Keep on
|
||||
// calling this function until all the data has been added. Then call Sha256Finalise to calculate the hash.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Sha256Update
|
||||
void
|
||||
Sha256Update
|
||||
(
|
||||
Sha256Context* Context,
|
||||
void const* Buffer,
|
||||
uint32_t BufferSize
|
||||
Sha256Context* Context, // [in out]
|
||||
void const* Buffer, // [in]
|
||||
uint32_t BufferSize // [in]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -68,6 +70,6 @@ void Sha256Update
|
||||
void
|
||||
Sha256Finalise
|
||||
(
|
||||
Sha256Context* Context,
|
||||
SHA256_HASH* Digest
|
||||
Sha256Context* Context, // [in out]
|
||||
SHA256_HASH* Digest // [out]
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLib_Sha512
|
||||
// WjCryptLib_Sha512
|
||||
//
|
||||
// Implementation of SHA512 hash function.
|
||||
// Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org
|
||||
@@ -12,7 +12,7 @@
|
||||
// IMPORTS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "CryptLib_Sha512.h"
|
||||
#include "WjCryptLib_Sha512.h"
|
||||
#include <memory.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -154,7 +154,7 @@ void
|
||||
void
|
||||
Sha512Initialise
|
||||
(
|
||||
Sha512Context* Context
|
||||
Sha512Context* Context // [out]
|
||||
)
|
||||
{
|
||||
Context->curlen = 0;
|
||||
@@ -178,9 +178,9 @@ void
|
||||
void
|
||||
Sha512Update
|
||||
(
|
||||
Sha512Context* Context,
|
||||
void const* Buffer,
|
||||
uint32_t BufferSize
|
||||
Sha512Context* Context, // [in out]
|
||||
void const* Buffer, // [in]
|
||||
uint32_t BufferSize // [in]
|
||||
)
|
||||
{
|
||||
uint32_t n;
|
||||
@@ -225,8 +225,8 @@ void
|
||||
void
|
||||
Sha512Finalise
|
||||
(
|
||||
Sha512Context* Context,
|
||||
SHA512_HASH* Digest
|
||||
Sha512Context* Context, // [in out]
|
||||
SHA512_HASH* Digest // [out]
|
||||
)
|
||||
{
|
||||
int i;
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLib_Sha512
|
||||
// WjCryptLib_Sha512
|
||||
//
|
||||
// Implementation of SHA512 hash function.
|
||||
// Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org
|
||||
@@ -41,9 +41,10 @@ typedef struct
|
||||
//
|
||||
// Initialises a SHA512 Context. Use this to initialise/reset a context.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Sha512Initialise
|
||||
void
|
||||
Sha512Initialise
|
||||
(
|
||||
Sha512Context* Context
|
||||
Sha512Context* Context // [out]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -52,11 +53,12 @@ void Sha512Initialise
|
||||
// Adds data to the SHA512 context. This will process the data and update the internal state of the context. Keep on
|
||||
// calling this function until all the data has been added. Then call Sha512Finalise to calculate the hash.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Sha512Update
|
||||
void
|
||||
Sha512Update
|
||||
(
|
||||
Sha512Context* Context,
|
||||
void const* Buffer,
|
||||
uint32_t BufferSize
|
||||
Sha512Context* Context, // [in out]
|
||||
void const* Buffer, // [in]
|
||||
uint32_t BufferSize // [in]
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -68,6 +70,6 @@ void Sha512Update
|
||||
void
|
||||
Sha512Finalise
|
||||
(
|
||||
Sha512Context* Context,
|
||||
SHA512_HASH* Digest
|
||||
Sha512Context* Context, // [in out]
|
||||
SHA512_HASH* Digest // [out]
|
||||
);
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "CryptLib_Aes.h"
|
||||
#include "WjCryptLib_Aes.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// DEFINES
|
||||
@@ -146,9 +146,9 @@ int
|
||||
|
||||
switch( keySize )
|
||||
{
|
||||
case 128/8: AesInitialise128( key, &aesContext ); break;
|
||||
case 192/8: AesInitialise192( key, &aesContext ); break;
|
||||
case 256/8: AesInitialise256( key, &aesContext ); break;
|
||||
case 128/8: AesInitialise( &aesContext, key, AES_KEY_SIZE_128 ); break;
|
||||
case 192/8: AesInitialise( &aesContext, key, AES_KEY_SIZE_192 ); break;
|
||||
case 256/8: AesInitialise( &aesContext, key, AES_KEY_SIZE_256 ); break;
|
||||
default:
|
||||
printf( "Invalid key size, must be 128, 192, or 256 bits (was %u bits)\n", keySize*8 );
|
||||
exit( 1 );
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
add_executable( AesBlock
|
||||
AesBlock.c )
|
||||
target_link_libraries( AesBlock
|
||||
CryptLib )
|
||||
WjCryptLib )
|
||||
|
||||
install(TARGETS AesBlock DESTINATION .)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "CryptLib_AesCtr.h"
|
||||
#include "WjCryptLib_AesCtr.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// DEFINITIONS
|
||||
@@ -101,7 +101,7 @@ int
|
||||
uint8_t buffer [BUFFER_SIZE];
|
||||
uint32_t amountLeft;
|
||||
uint32_t chunk;
|
||||
AesCtrContext aesCtr = {{0}};
|
||||
AesCtrContext aesCtr;
|
||||
uint8_t key [AES_KEY_SIZE_256];
|
||||
uint32_t keySize = sizeof(key);
|
||||
uint8_t IV [AES_CTR_IV_SIZE];
|
||||
@@ -134,7 +134,7 @@ int
|
||||
|
||||
numBytes = atoi( ArgV[3] );
|
||||
|
||||
AesCtrInitialiseWithKey( key, keySize, IV, &aesCtr );
|
||||
AesCtrInitialiseWithKey( &aesCtr, key, keySize, IV );
|
||||
|
||||
amountLeft = numBytes;
|
||||
while( amountLeft > 0 )
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
add_executable( AesCtrOutput
|
||||
AesCtrOutput.c )
|
||||
target_link_libraries( AesCtrOutput
|
||||
CryptLib )
|
||||
WjCryptLib )
|
||||
|
||||
install(TARGETS AesCtrOutput DESTINATION .)
|
||||
|
||||
|
||||
155
projects/AesOfbOutput/AesOfbOutput.c
Normal file
155
projects/AesOfbOutput/AesOfbOutput.c
Normal file
@@ -0,0 +1,155 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AesOfbOutput
|
||||
//
|
||||
// Outputs bytes from an AES OFB stream. Key and IV are taken from command line. Bytes are output as hex
|
||||
//
|
||||
// This is free and unencumbered software released into the public domain - January 2018 waterjuice.org
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// IMPORTS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "WjCryptLib_AesOfb.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// DEFINITIONS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __min
|
||||
#define __min( x, y ) (((x) < (y))?(x):(y))
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CONSTANTS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// FUNCTIONS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ReadHexData
|
||||
//
|
||||
// Reads a string as hex and places it in Data. *pDataSize on entry specifies maximum number of bytes that can be
|
||||
// read, and on return is set to how many were read. This will be zero if it failed to read any.
|
||||
// This function ignores any character that isn't a hex character.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static
|
||||
void
|
||||
ReadHexData
|
||||
(
|
||||
char const* HexString, // [in]
|
||||
uint8_t* Data, // [out]
|
||||
uint32_t* pDataSize // [in out]
|
||||
)
|
||||
{
|
||||
uint32_t i;
|
||||
char holdingBuffer [3] = {0};
|
||||
uint32_t holdingBufferIndex = 0;
|
||||
unsigned hexToNumber;
|
||||
unsigned outputIndex = 0;
|
||||
|
||||
for( i=0; i<strlen(HexString); i++ )
|
||||
{
|
||||
if( ( HexString[i] >= '0' && HexString[i] <= '9' )
|
||||
|| ( HexString[i] >= 'A' && HexString[i] <= 'F' )
|
||||
|| ( HexString[i] >= 'a' && HexString[i] <= 'f' ) )
|
||||
{
|
||||
holdingBuffer[holdingBufferIndex] = HexString[i];
|
||||
holdingBufferIndex += 1;
|
||||
|
||||
if( 2 == holdingBufferIndex )
|
||||
{
|
||||
// Have two digits now so read it as a byte.
|
||||
sscanf( holdingBuffer, "%x", &hexToNumber );
|
||||
Data[outputIndex] = (uint8_t) hexToNumber;
|
||||
outputIndex += 1;
|
||||
if( outputIndex == *pDataSize )
|
||||
{
|
||||
// No more space so stop reading
|
||||
break;
|
||||
}
|
||||
holdingBufferIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*pDataSize = outputIndex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// main
|
||||
//
|
||||
// Program entry point
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
int
|
||||
main
|
||||
(
|
||||
int ArgC,
|
||||
char** ArgV
|
||||
)
|
||||
{
|
||||
uint32_t numBytes;
|
||||
uint32_t i;
|
||||
uint8_t buffer [BUFFER_SIZE];
|
||||
uint32_t amountLeft;
|
||||
uint32_t chunk;
|
||||
AesOfbContext aesOfb;
|
||||
uint8_t key [AES_KEY_SIZE_256];
|
||||
uint32_t keySize = sizeof(key);
|
||||
uint8_t IV [AES_OFB_IV_SIZE];
|
||||
uint32_t IVSize = sizeof(IV);
|
||||
|
||||
if( 4 != ArgC )
|
||||
{
|
||||
printf(
|
||||
"Syntax\n"
|
||||
" AesOfbOutput <Key> <IV> <NumBytes>\n"
|
||||
" <Key> - 128, 192, or 256 bit written as hex\n"
|
||||
" <IV> - 128 bit written as hex\n"
|
||||
" <NumBytes> - Number of bytes of stream to output\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
ReadHexData( ArgV[1], key, &keySize );
|
||||
if( AES_KEY_SIZE_128 != keySize && AES_KEY_SIZE_192 != keySize && AES_KEY_SIZE_256 != keySize )
|
||||
{
|
||||
printf( "Invalid key size. Must be 128, 192, or 256 bits\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
ReadHexData( ArgV[2], IV, &IVSize );
|
||||
if( AES_OFB_IV_SIZE != IVSize )
|
||||
{
|
||||
printf( "Invalid IV size. Must be 128 bits\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
numBytes = atoi( ArgV[3] );
|
||||
|
||||
AesOfbInitialiseWithKey( &aesOfb, key, keySize, IV );
|
||||
|
||||
amountLeft = numBytes;
|
||||
while( amountLeft > 0 )
|
||||
{
|
||||
chunk = __min( amountLeft, BUFFER_SIZE );
|
||||
AesOfbOutput( &aesOfb, buffer, chunk );
|
||||
amountLeft -= chunk;
|
||||
|
||||
for( i=0; i<chunk; i++ )
|
||||
{
|
||||
printf( "%2.2x", buffer[i] );
|
||||
}
|
||||
}
|
||||
|
||||
printf( "\n" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
7
projects/AesOfbOutput/CMakeLists.txt
Normal file
7
projects/AesOfbOutput/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
add_executable( AesOfbOutput
|
||||
AesOfbOutput.c )
|
||||
target_link_libraries( AesOfbOutput
|
||||
WjCryptLib )
|
||||
|
||||
install(TARGETS AesOfbOutput DESTINATION .)
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
SET( MODULE_NAME CryptLibTest )
|
||||
|
||||
add_executable( ${MODULE_NAME}
|
||||
CryptLibTest.c
|
||||
CryptLibTest_Hashes.c
|
||||
CryptLibTest_Hashes.h
|
||||
CryptLibTest_Rc4.c
|
||||
CryptLibTest_Rc4.h
|
||||
CryptLibTest_Aes.c
|
||||
CryptLibTest_Aes.h
|
||||
CryptLibTest_AesCtr.c
|
||||
CryptLibTest_AesCtr.h )
|
||||
target_link_libraries( ${MODULE_NAME}
|
||||
CryptLib )
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION .)
|
||||
@@ -3,6 +3,6 @@ SET( MODULE_NAME Md5String )
|
||||
add_executable( ${MODULE_NAME}
|
||||
Md5String.c )
|
||||
target_link_libraries( ${MODULE_NAME}
|
||||
CryptLib )
|
||||
WjCryptLib )
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION .)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "CryptLib_Md5.h"
|
||||
#include "WjCryptLib_Md5.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// FUNCTIONS
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
add_executable( Rc4Output
|
||||
Rc4Output.c )
|
||||
target_link_libraries( Rc4Output
|
||||
CryptLib )
|
||||
WjCryptLib )
|
||||
|
||||
install(TARGETS Rc4Output DESTINATION .)
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "CryptLib_Rc4.h"
|
||||
#include "WjCryptLib_Rc4.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// DEFINITIONS
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
add_executable( Sha1String
|
||||
Sha1String.c )
|
||||
target_link_libraries( Sha1String
|
||||
CryptLib )
|
||||
WjCryptLib )
|
||||
|
||||
install(TARGETS Sha1String DESTINATION .)
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "CryptLib_Sha1.h"
|
||||
#include "WjCryptLib_Sha1.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// FUNCTIONS
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
add_executable( Sha256String
|
||||
Sha256String.c )
|
||||
target_link_libraries( Sha256String
|
||||
CryptLib )
|
||||
WjCryptLib )
|
||||
|
||||
install(TARGETS Sha256String DESTINATION .)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "CryptLib_Sha256.h"
|
||||
#include "WjCryptLib_Sha256.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// FUNCTIONS
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
add_executable( Sha512String
|
||||
Sha512String.c )
|
||||
target_link_libraries( Sha512String
|
||||
CryptLib )
|
||||
WjCryptLib )
|
||||
|
||||
install(TARGETS Sha512String DESTINATION .)
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "CryptLib_Sha512.h"
|
||||
#include "WjCryptLib_Sha512.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// FUNCTIONS
|
||||
|
||||
18
projects/WjCryptLibTest/CMakeLists.txt
Normal file
18
projects/WjCryptLibTest/CMakeLists.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
SET( MODULE_NAME WjCryptLibTest )
|
||||
|
||||
add_executable( ${MODULE_NAME}
|
||||
WjCryptLibTest.c
|
||||
WjCryptLibTest_Hashes.c
|
||||
WjCryptLibTest_Hashes.h
|
||||
WjCryptLibTest_Rc4.c
|
||||
WjCryptLibTest_Rc4.h
|
||||
WjCryptLibTest_Aes.c
|
||||
WjCryptLibTest_Aes.h
|
||||
WjCryptLibTest_AesCtr.c
|
||||
WjCryptLibTest_AesCtr.h
|
||||
WjCryptLibTest_AesOfb.c
|
||||
WjCryptLibTest_AesOfb.h )
|
||||
target_link_libraries( ${MODULE_NAME}
|
||||
WjCryptLib )
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION .)
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLibTest
|
||||
// WjCryptLibTest
|
||||
//
|
||||
// Tests the cryptography functions against known test vectors to verify algorithms are correct.
|
||||
//
|
||||
@@ -15,10 +15,11 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "CryptLibTest_Aes.h"
|
||||
#include "CryptLibTest_AesCtr.h"
|
||||
#include "CryptLibTest_Hashes.h"
|
||||
#include "CryptLibTest_Rc4.h"
|
||||
#include "WjCryptLibTest_Aes.h"
|
||||
#include "WjCryptLibTest_AesCtr.h"
|
||||
#include "WjCryptLibTest_AesOfb.h"
|
||||
#include "WjCryptLibTest_Hashes.h"
|
||||
#include "WjCryptLibTest_Rc4.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// FUNCTIONS
|
||||
@@ -39,7 +40,7 @@ int
|
||||
bool allSuccess = true;
|
||||
|
||||
printf(
|
||||
"CryptLibTest\n"
|
||||
"WjCryptLibTest\n"
|
||||
"------------\n"
|
||||
"\n" );
|
||||
|
||||
@@ -48,16 +49,19 @@ int
|
||||
|
||||
success = TestRc4( );
|
||||
if( !success ) { allSuccess = false; }
|
||||
printf( "Test RC4 - %s\n", success?"Pass":"Fail" );
|
||||
printf( "Test RC4 - %s\n", success?"Pass":"Fail" );
|
||||
|
||||
success = TestAes( );
|
||||
if( !success ) { allSuccess = false; }
|
||||
printf( "Test AES - %s\n", success?"Pass":"Fail" );
|
||||
printf( "Test AES - %s\n", success?"Pass":"Fail" );
|
||||
|
||||
success = TestAesCtr( );
|
||||
if( !success ) { allSuccess = false; }
|
||||
printf( "Test AES CTR- %s\n", success?"Pass":"Fail" );
|
||||
printf( "Test AES CTR - %s\n", success?"Pass":"Fail" );
|
||||
|
||||
success = TestAesOfb( );
|
||||
if( !success ) { allSuccess = false; }
|
||||
printf( "Test AES OFB - %s\n", success?"Pass":"Fail" );
|
||||
|
||||
printf( "\n" );
|
||||
if( allSuccess )
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLibTest_Aes
|
||||
// WjCryptLibTest_Aes
|
||||
//
|
||||
// Tests the cryptography functions against known test vectors to verify algorithms are correct.
|
||||
// Tests the following:
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "CryptLib_Aes.h"
|
||||
#include "WjCryptLib_Aes.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TYPES
|
||||
@@ -117,15 +117,15 @@ bool
|
||||
|
||||
for( i=0; i<NUM_TEST_VECTORS; i++ )
|
||||
{
|
||||
AesInitialise128( gTestVectors[i].Key128, &context );
|
||||
AesInitialise( &context, gTestVectors[i].Key128, AES_KEY_SIZE_128 );
|
||||
AesEncrypt( &context, gTestVectors[i].PlainText, encBlock128 );
|
||||
AesDecrypt( &context, gTestVectors[i].CipherText128, decBlock128 );
|
||||
|
||||
AesInitialise192( gTestVectors[i].Key192, &context );
|
||||
AesInitialise( &context, gTestVectors[i].Key192, AES_KEY_SIZE_192 );
|
||||
AesEncrypt( &context, gTestVectors[i].PlainText, encBlock192 );
|
||||
AesDecrypt( &context, gTestVectors[i].CipherText192, decBlock192 );
|
||||
|
||||
AesInitialise256( gTestVectors[i].Key256, &context );
|
||||
AesInitialise( &context, gTestVectors[i].Key256, AES_KEY_SIZE_256 );
|
||||
AesEncrypt( &context, gTestVectors[i].PlainText, encBlock256 );
|
||||
AesDecrypt( &context, gTestVectors[i].CipherText256, decBlock256 );
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLibTest_Aes
|
||||
// WjCryptLibTest_Aes
|
||||
//
|
||||
// Tests the cryptography functions against known test vectors to verify algorithms are correct.
|
||||
// Tests the following:
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLibTest_AesCtr
|
||||
// WjCryptLibTest_AesCtr
|
||||
//
|
||||
// Tests the cryptography functions against known test vectors to verify algorithms are correct.
|
||||
// Tests the following:
|
||||
@@ -17,7 +17,8 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "CryptLib_AesCtr.h"
|
||||
#include "WjCryptLib_AesCtr.h"
|
||||
#include "WjCryptLib_Sha1.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// MACROS
|
||||
@@ -163,6 +164,76 @@ bool
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TestLargeVector
|
||||
//
|
||||
// Tests AES CTR against a known large vector (of 1 million bytes). We check it against a known SHA-1 hash of
|
||||
// the output.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static
|
||||
bool
|
||||
TestLargeVector
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
|
||||
//dd if=/dev/zero iflag=count_bytes count=1000000 status=none | openssl enc -aes-128-ctr -K 00001111222233334444555566667777 -iv 88889999aaaabbbb | openssl sha1
|
||||
//(stdin)= 6227c0192b110133fadd6d229790bbdf13c068ab
|
||||
|
||||
uint8_t const* key = (uint8_t const*)"\x00\x00\x11\x11\x22\x22\x33\x33\x44\x44\x55\x55\x66\x66\x77\x77";
|
||||
uint8_t const* iv = (uint8_t const*)"\x88\x88\x99\x99\xaa\xaa\xbb\xbb";
|
||||
uint8_t const* sha1Hash = (uint8_t const*)"\xe1\x63\x5f\xa4\xf5\x7c\x98\x54\xf6\x18\xec\x0c\x8f\x18\x7f\x04\x34\xa2\xe1\x72";
|
||||
uint32_t const numBytesToGenerate = 1000000;
|
||||
|
||||
uint8_t* buffer = malloc( numBytesToGenerate );
|
||||
uint32_t amountLeft = numBytesToGenerate;
|
||||
uint32_t chunkSize;
|
||||
Sha1Context sha1Context;
|
||||
AesCtrContext aesCtrContext;
|
||||
SHA1_HASH calcSha1;
|
||||
|
||||
// Encrypt in one go first.
|
||||
memset( buffer, 0, numBytesToGenerate );
|
||||
AesCtrXorWithKey( key, AES_KEY_SIZE_128, iv, buffer, buffer, numBytesToGenerate );
|
||||
|
||||
Sha1Initialise( &sha1Context );
|
||||
Sha1Update( &sha1Context, buffer, numBytesToGenerate );
|
||||
Sha1Finalise( &sha1Context, &calcSha1 );
|
||||
|
||||
if( 0 != memcmp( &calcSha1, sha1Hash, SHA1_HASH_SIZE ) )
|
||||
{
|
||||
printf( "Large test vector failed\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
memset( buffer, 0, numBytesToGenerate );
|
||||
|
||||
// Now encrypt in smaller pieces (10000 bytes at a time)
|
||||
Sha1Initialise( &sha1Context );
|
||||
AesCtrInitialiseWithKey( &aesCtrContext, key, AES_KEY_SIZE_128, iv );
|
||||
|
||||
while( amountLeft > 0 )
|
||||
{
|
||||
memset( buffer, 0, numBytesToGenerate );
|
||||
chunkSize = MIN( amountLeft, 10000 );
|
||||
AesCtrOutput( &aesCtrContext, buffer, chunkSize );
|
||||
Sha1Update( &sha1Context, buffer, chunkSize );
|
||||
amountLeft -= chunkSize;
|
||||
}
|
||||
|
||||
Sha1Finalise( &sha1Context, &calcSha1 );
|
||||
|
||||
if( 0 != memcmp( &calcSha1, sha1Hash, SHA1_HASH_SIZE ) )
|
||||
{
|
||||
printf( "Large test vector failed\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TestStreamConsistency
|
||||
//
|
||||
@@ -199,7 +270,7 @@ bool
|
||||
}
|
||||
|
||||
// Now recreate the stream in small bits. Starting at 1 byte at a time and increasing chunk size
|
||||
AesCtrInitialiseWithKey( key, sizeof(key), iv, &context );
|
||||
AesCtrInitialiseWithKey( &context, key, sizeof(key), iv );
|
||||
for( chunkSize=1; chunkSize<64; chunkSize++ )
|
||||
{
|
||||
uint32_t amountLeft = STREAMSIZE;
|
||||
@@ -262,7 +333,7 @@ bool
|
||||
0xf8, 0x8f, 0x45, 0xd1, 0xf6, 0x68, 0x28, 0x54,
|
||||
0x6f, 0xef, 0xce, 0xf9, 0x23, 0x1b, 0xb0, 0x08 };
|
||||
|
||||
AesCtrInitialiseWithKey( key, sizeof(key), iv, &context );
|
||||
AesCtrInitialiseWithKey( &context, key, sizeof(key), iv );
|
||||
AesCtrSetStreamIndex( &context, positionIndex );
|
||||
AesCtrOutput( &context, output, sizeof(output) );
|
||||
|
||||
@@ -296,6 +367,9 @@ bool
|
||||
success = TestVectors( );
|
||||
if( !success ) { totalSuccess = false; }
|
||||
|
||||
success = TestLargeVector( );
|
||||
if( !success ) { totalSuccess = false; }
|
||||
|
||||
success = TestStreamConsistency( );
|
||||
if( !success ) { totalSuccess = false; }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLibTest_AesCtr
|
||||
// WjCryptLibTest_AesCtr
|
||||
//
|
||||
// Tests the cryptography functions against known test vectors to verify algorithms are correct.
|
||||
// Tests the following:
|
||||
332
projects/WjCryptLibTest/WjCryptLibTest_AesOfb.c
Normal file
332
projects/WjCryptLibTest/WjCryptLibTest_AesOfb.c
Normal file
@@ -0,0 +1,332 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// WjCryptLibTest_AesOfb
|
||||
//
|
||||
// Tests the cryptography functions against known test vectors to verify algorithms are correct.
|
||||
// Tests the following:
|
||||
// AES OFB
|
||||
//
|
||||
// This is free and unencumbered software released into the public domain - January 2018 waterjuice.org
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// IMPORTS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "WjCryptLib_AesOfb.h"
|
||||
#include "WjCryptLib_Sha1.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// MACROS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define MIN( x, y ) ( ((x)<(y))?(x):(y) )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TYPES
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define MAX_PLAINTEXT_SIZE 100
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char* KeyHex;
|
||||
char* IvHex;
|
||||
char* CipherTextHex;
|
||||
} TestVector;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GLOBALS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// These test vectors were created using openssl. Using the following commands:
|
||||
// > dd if=/dev/zero iflag=count_bytes count=48 status=none | openssl enc -aes-128-ofb -K 00000000000000000000000000000000 -iv 00000000000000000000000000000000 | xxd -p -c 48
|
||||
// > dd if=/dev/zero iflag=count_bytes count=48 status=none | openssl enc -aes-128-ofb -K 0102030405060708a1a2a3a4a5a6a7a8 -iv 00000000000000000000000000000000 | xxd -p -c 48
|
||||
// > dd if=/dev/zero iflag=count_bytes count=48 status=none | openssl enc -aes-128-ofb -K 00000000000000000000000000000000 -iv b1b2b3b4b5b6b7b8c1c2c3c4c5c6c7c8 | xxd -p -c 48
|
||||
// > dd if=/dev/zero iflag=count_bytes count=48 status=none | openssl enc -aes-128-ofb -K 0102030405060708a1a2a3a4a5a6a7a8 -iv b1b2b3b4b5b6b7b8c1c2c3c4c5c6c7c8 | xxd -p -c 48
|
||||
// > dd if=/dev/zero iflag=count_bytes count=48 status=none | openssl enc -aes-192-ofb -K 0102030405060708a1a2a3a4a5a6a7a8b1b2b3b4b5b6b7b8 -iv c1c2c3c4c5c6c7c8d1d2d3d4d5d6d7d8 | xxd -p -c 48
|
||||
// > dd if=/dev/zero iflag=count_bytes count=48 status=none | openssl enc -aes-256-ofb -K 0102030405060708a1a2a3a4a5a6a7a8b1b2b3b4b5b6b7b8c1c2c3c4c5c6c7c8 -iv d1d2d3d4d5d6d7d8e1e2e3e4e5e6e7e8 | xxd -p -c 48
|
||||
static TestVector gTestVectors [] =
|
||||
{
|
||||
{
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"66e94bd4ef8a2c3b884cfa59ca342b2ef795bd4a52e29ed713d313fa20e98dbca10cf66d0fddf3405370b4bf8df5bfb3"
|
||||
},
|
||||
{
|
||||
"0102030405060708a1a2a3a4a5a6a7a8",
|
||||
"00000000000000000000000000000000",
|
||||
"cdb33c236caa155b28d14e6db35053718a906fc0050ae8ad054621e487e5b0a264873309a9471152104a0a51361a91af"
|
||||
},
|
||||
{
|
||||
"00000000000000000000000000000000",
|
||||
"b1b2b3b4b5b6b7b8c1c2c3c4c5c6c7c8",
|
||||
"93fc4d6374dc544d40181d39066e9b0077aa627a84dbd57c9e72a1bbbc8bd1e082faf44d5ce57f6320e9f33d38a3a268"
|
||||
},
|
||||
{
|
||||
"0102030405060708a1a2a3a4a5a6a7a8",
|
||||
"b1b2b3b4b5b6b7b8c1c2c3c4c5c6c7c8",
|
||||
"551eb0c4d89d7e1b537b30f627cc5a0afdebd5a07483107df8555dbae9453189ae13766c9678554971151486cee958af"
|
||||
},
|
||||
{
|
||||
"0102030405060708a1a2a3a4a5a6a7a8b1b2b3b4b5b6b7b8",
|
||||
"c1c2c3c4c5c6c7c8d1d2d3d4d5d6d7d8",
|
||||
"e9128df92fd1da443f826d84fd46be40fffb4ad23477a02efb14cbfd9a28ebcc2e6a5948cd1980e7cd6f5d386f7f6539"
|
||||
},
|
||||
{
|
||||
"0102030405060708a1a2a3a4a5a6a7a8b1b2b3b4b5b6b7b8c1c2c3c4c5c6c7c8",
|
||||
"d1d2d3d4d5d6d7d8e1e2e3e4e5e6e7e8",
|
||||
"06a9a20023d47df78a5ead97715a85921cab7d5114fb74a1b99e66d915a0e125a0fcf198d93364235f9a33c02dc170f6"
|
||||
},
|
||||
};
|
||||
|
||||
#define NUM_TEST_VECTORS ( sizeof(gTestVectors) / sizeof(gTestVectors[0]) )
|
||||
#define TEST_VECTOR_OUTPUT_SIZE 48
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// INTERNAL FUNCTIONS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// HexToBytes
|
||||
//
|
||||
// Reads a string as hex and places it in Data. This function will output as many bytes as represented in the input
|
||||
// string, it will not check the output buffer length. On return *pDataSize will be number of bytes read.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static
|
||||
void
|
||||
HexToBytes
|
||||
(
|
||||
char const* HexString, // [in]
|
||||
uint8_t* Data, // [out]
|
||||
uint32_t* pDataSize // [out optional]
|
||||
)
|
||||
{
|
||||
uint32_t i;
|
||||
char holdingBuffer [3] = {0};
|
||||
unsigned hexToNumber;
|
||||
uint32_t outputIndex = 0;
|
||||
|
||||
for( i=0; i<strlen(HexString)/2; i++ )
|
||||
{
|
||||
holdingBuffer[0] = HexString[i*2 + 0];
|
||||
holdingBuffer[1] = HexString[i*2 + 1];
|
||||
sscanf( holdingBuffer, "%x", &hexToNumber );
|
||||
Data[i] = (uint8_t) hexToNumber;
|
||||
outputIndex += 1;
|
||||
}
|
||||
|
||||
if( NULL != pDataSize )
|
||||
{
|
||||
*pDataSize = outputIndex;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TestVectors
|
||||
//
|
||||
// Tests AES OFB against fixed test vectors
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static
|
||||
bool
|
||||
TestVectors
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
uint32_t vectorIndex;
|
||||
uint8_t key [AES_KEY_SIZE_256];
|
||||
uint32_t keySize = 0;
|
||||
uint8_t iv [AES_OFB_IV_SIZE];
|
||||
uint8_t vector [TEST_VECTOR_OUTPUT_SIZE];
|
||||
uint8_t aesOfbOutput [TEST_VECTOR_OUTPUT_SIZE];
|
||||
uint8_t const zeroBuffer [TEST_VECTOR_OUTPUT_SIZE] = {0};
|
||||
|
||||
for( vectorIndex=0; vectorIndex<NUM_TEST_VECTORS; vectorIndex++ )
|
||||
{
|
||||
HexToBytes( gTestVectors[vectorIndex].KeyHex, key, &keySize );
|
||||
HexToBytes( gTestVectors[vectorIndex].IvHex, iv, NULL );
|
||||
HexToBytes( gTestVectors[vectorIndex].CipherTextHex, vector, NULL );
|
||||
|
||||
AesOfbXorWithKey( key, keySize, iv, zeroBuffer, aesOfbOutput, TEST_VECTOR_OUTPUT_SIZE );
|
||||
if( 0 != memcmp( aesOfbOutput, vector, TEST_VECTOR_OUTPUT_SIZE ) )
|
||||
{
|
||||
printf( "Test vector (index:%u) failed\n", vectorIndex );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TestLargeVector
|
||||
//
|
||||
// Tests AES OFB against a known large vector (of 1 million bytes). We check it against a known SHA-1 hash of
|
||||
// the output.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static
|
||||
bool
|
||||
TestLargeVector
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
|
||||
//dd if=/dev/zero iflag=count_bytes count=1000000 status=none | openssl enc -aes-128-ofb -K 00001111222233334444555566667777 -iv 88889999aaaabbbbccccddddeeeeffff | openssl sha1
|
||||
//(stdin)= a0824dca21938b33a5a8db26c8ab2428624db6d3
|
||||
|
||||
uint8_t const* key = (uint8_t const*)"\x00\x00\x11\x11\x22\x22\x33\x33\x44\x44\x55\x55\x66\x66\x77\x77";
|
||||
uint8_t const* iv = (uint8_t const*)"\x88\x88\x99\x99\xaa\xaa\xbb\xbb\xcc\xcc\xdd\xdd\xee\xee\xff\xff";
|
||||
uint8_t const* sha1Hash = (uint8_t const*)"\xa0\x82\x4d\xca\x21\x93\x8b\x33\xa5\xa8\xdb\x26\xc8\xab\x24\x28\x62\x4d\xb6\xd3";
|
||||
uint32_t const numBytesToGenerate = 1000000;
|
||||
|
||||
uint8_t* buffer = malloc( numBytesToGenerate );
|
||||
uint32_t amountLeft = numBytesToGenerate;
|
||||
uint32_t chunkSize;
|
||||
Sha1Context sha1Context;
|
||||
AesOfbContext aesOfbContext;
|
||||
SHA1_HASH calcSha1;
|
||||
|
||||
// Encrypt in one go first.
|
||||
memset( buffer, 0, numBytesToGenerate );
|
||||
AesOfbXorWithKey( key, AES_KEY_SIZE_128, iv, buffer, buffer, numBytesToGenerate );
|
||||
|
||||
Sha1Initialise( &sha1Context );
|
||||
Sha1Update( &sha1Context, buffer, numBytesToGenerate );
|
||||
Sha1Finalise( &sha1Context, &calcSha1 );
|
||||
|
||||
if( 0 != memcmp( &calcSha1, sha1Hash, SHA1_HASH_SIZE ) )
|
||||
{
|
||||
printf( "Large test vector failed\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
memset( buffer, 0, numBytesToGenerate );
|
||||
|
||||
// Now encrypt in smaller pieces (10000 bytes at a time)
|
||||
Sha1Initialise( &sha1Context );
|
||||
AesOfbInitialiseWithKey( &aesOfbContext, key, AES_KEY_SIZE_128, iv );
|
||||
|
||||
while( amountLeft > 0 )
|
||||
{
|
||||
memset( buffer, 0, numBytesToGenerate );
|
||||
chunkSize = MIN( amountLeft, 10000 );
|
||||
AesOfbOutput( &aesOfbContext, buffer, chunkSize );
|
||||
Sha1Update( &sha1Context, buffer, chunkSize );
|
||||
amountLeft -= chunkSize;
|
||||
}
|
||||
|
||||
Sha1Finalise( &sha1Context, &calcSha1 );
|
||||
|
||||
if( 0 != memcmp( &calcSha1, sha1Hash, SHA1_HASH_SIZE ) )
|
||||
{
|
||||
printf( "Large test vector failed\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TestStreamConsistency
|
||||
//
|
||||
// Tests that an AES OFB stream is consistent regardless of the chunk sizes of the requests and/or stream
|
||||
// repositioning.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static
|
||||
bool
|
||||
TestStreamConsistency
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
bool success = true;
|
||||
uint8_t const key[AES_KEY_SIZE_128] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
|
||||
uint8_t const iv[AES_OFB_IV_SIZE] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
|
||||
#define STREAMSIZE 1000
|
||||
uint8_t stream [STREAMSIZE];
|
||||
uint8_t newStream [STREAMSIZE];
|
||||
uint8_t const zeroStream [STREAMSIZE] = {0};
|
||||
AesOfbContext context;
|
||||
uint32_t chunkSize;
|
||||
|
||||
// First fill in stream with 1000 bytes generated in one go.
|
||||
memset( stream, 0, STREAMSIZE );
|
||||
AesOfbXorWithKey( key, sizeof(key), iv, stream, stream, STREAMSIZE );
|
||||
|
||||
// Perform sanity check that the key is not all zero!
|
||||
if( 0 == memcmp( stream, zeroStream, STREAMSIZE ) )
|
||||
{
|
||||
printf( "AES OFB Stream all zero\n" );
|
||||
success = false;
|
||||
return success;
|
||||
}
|
||||
|
||||
// Now recreate the stream in small bits. Starting at 1 byte at a time and increasing chunk size
|
||||
for( chunkSize=1; chunkSize<64; chunkSize++ )
|
||||
{
|
||||
uint32_t amountLeft = STREAMSIZE;
|
||||
uint32_t offset = 0;
|
||||
memset( newStream, 0, STREAMSIZE );
|
||||
|
||||
AesOfbInitialiseWithKey( &context, key, sizeof(key), iv );
|
||||
|
||||
while( amountLeft > 0 )
|
||||
{
|
||||
uint32_t thisChunkSize = MIN( chunkSize, amountLeft );
|
||||
|
||||
AesOfbOutput( &context, newStream+offset, thisChunkSize );
|
||||
|
||||
offset += thisChunkSize;
|
||||
amountLeft -= thisChunkSize;
|
||||
}
|
||||
|
||||
// Now verify that the stream is consistent with the one generated all at once.
|
||||
if( 0 != memcmp( stream, newStream, STREAMSIZE ) )
|
||||
{
|
||||
printf( "AES OFB Stream not consistent\n" );
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#undef STREAMSIZE
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PUBLIC FUNCTIONS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TestAesOfb
|
||||
//
|
||||
// Test AES OFB algorithm
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool
|
||||
TestAesOfb
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
bool totalSuccess = true;
|
||||
bool success;
|
||||
|
||||
success = TestVectors( );
|
||||
if( !success ) { totalSuccess = false; }
|
||||
|
||||
success = TestLargeVector( );
|
||||
if( !success ) { totalSuccess = false; }
|
||||
|
||||
success = TestStreamConsistency( );
|
||||
if( !success ) { totalSuccess = false; }
|
||||
|
||||
return totalSuccess;
|
||||
}
|
||||
30
projects/WjCryptLibTest/WjCryptLibTest_AesOfb.h
Normal file
30
projects/WjCryptLibTest/WjCryptLibTest_AesOfb.h
Normal file
@@ -0,0 +1,30 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// WjCryptLibTest_AesOfb
|
||||
//
|
||||
// Tests the cryptography functions against known test vectors to verify algorithms are correct.
|
||||
// Tests the following:
|
||||
// AES OFB
|
||||
//
|
||||
// This is free and unencumbered software released into the public domain - January 2018 waterjuice.org
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// IMPORTS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// EXPORTED FUNCTIONS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TestAesOfb
|
||||
//
|
||||
// Test AES OFB algorithm
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool
|
||||
TestAesOfb
|
||||
(
|
||||
void
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLibTest_Hashes
|
||||
// WjCryptLibTest_Hashes
|
||||
//
|
||||
// Tests the hash functions against known test vectors to verify algorithms are correct.
|
||||
// Tests the following:
|
||||
@@ -20,11 +20,11 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "CryptLib_Md5.h"
|
||||
#include "CryptLib_Sha1.h"
|
||||
#include "CryptLib_Sha256.h"
|
||||
#include "CryptLib_Sha512.h"
|
||||
#include "CryptLibTest_Aes.h"
|
||||
#include "WjCryptLib_Md5.h"
|
||||
#include "WjCryptLib_Sha1.h"
|
||||
#include "WjCryptLib_Sha256.h"
|
||||
#include "WjCryptLib_Sha512.h"
|
||||
#include "WjCryptLibTest_Aes.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TYPES
|
||||
@@ -444,19 +444,19 @@ bool
|
||||
|
||||
success = TestMd5( );
|
||||
if( !success ) { allSuccess = false; }
|
||||
printf( "Test MD5 - %s\n", success?"Pass":"Fail" );
|
||||
printf( "Test MD5 - %s\n", success?"Pass":"Fail" );
|
||||
|
||||
success = TestSha1( );
|
||||
if( !success ) { allSuccess = false; }
|
||||
printf( "Test SHA1 - %s\n", success?"Pass":"Fail" );
|
||||
printf( "Test SHA1 - %s\n", success?"Pass":"Fail" );
|
||||
|
||||
success = TestSha256( );
|
||||
if( !success ) { allSuccess = false; }
|
||||
printf( "Test SHA256 - %s\n", success?"Pass":"Fail" );
|
||||
printf( "Test SHA256 - %s\n", success?"Pass":"Fail" );
|
||||
|
||||
success = TestSha512( );
|
||||
if( !success ) { allSuccess = false; }
|
||||
printf( "Test SHA512 - %s\n", success?"Pass":"Fail" );
|
||||
printf( "Test SHA512 - %s\n", success?"Pass":"Fail" );
|
||||
|
||||
return allSuccess;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLibTest_Hashes
|
||||
// WjCryptLibTest_Hashes
|
||||
//
|
||||
// Tests the hash functions against known test vectors to verify algorithms are correct.
|
||||
// Tests the following:
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLibTest_Rc4
|
||||
// WjCryptLibTest_Rc4
|
||||
//
|
||||
// Tests the RC4 function against known test vectors to verify algorithms are correct.
|
||||
//
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "CryptLib_Rc4.h"
|
||||
#include "WjCryptLib_Rc4.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PUBLIC FUNCTIONS
|
||||
@@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CryptLibTest_Rc4
|
||||
// WjCryptLibTest_Rc4
|
||||
//
|
||||
// Tests the RC4 function against known test vectors to verify algorithms are correct.
|
||||
//
|
||||
Reference in New Issue
Block a user