diff --git a/CMakeLists.txt b/CMakeLists.txt index 81e29c1..eeecb17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 ) diff --git a/Exe/Linux/AesBlock b/Exe/Linux/AesBlock deleted file mode 100644 index 2e7029a..0000000 Binary files a/Exe/Linux/AesBlock and /dev/null differ diff --git a/Exe/Linux/AesCtrOutput b/Exe/Linux/AesCtrOutput deleted file mode 100644 index 51f0ff9..0000000 Binary files a/Exe/Linux/AesCtrOutput and /dev/null differ diff --git a/Exe/Linux/Md5String b/Exe/Linux/Md5String deleted file mode 100644 index 2bd55c1..0000000 Binary files a/Exe/Linux/Md5String and /dev/null differ diff --git a/Exe/Linux/Rc4Output b/Exe/Linux/Rc4Output deleted file mode 100644 index fb7115e..0000000 Binary files a/Exe/Linux/Rc4Output and /dev/null differ diff --git a/Exe/Linux/Sha1String b/Exe/Linux/Sha1String deleted file mode 100644 index cd16c23..0000000 Binary files a/Exe/Linux/Sha1String and /dev/null differ diff --git a/Exe/Linux/Sha256String b/Exe/Linux/Sha256String deleted file mode 100644 index c9da072..0000000 Binary files a/Exe/Linux/Sha256String and /dev/null differ diff --git a/Exe/Linux/Sha512String b/Exe/Linux/Sha512String deleted file mode 100644 index 881d62e..0000000 Binary files a/Exe/Linux/Sha512String and /dev/null differ diff --git a/Exe/MacOS/AesBlock b/Exe/MacOS/AesBlock deleted file mode 100644 index 49462db..0000000 Binary files a/Exe/MacOS/AesBlock and /dev/null differ diff --git a/Exe/MacOS/AesCtrOutput b/Exe/MacOS/AesCtrOutput deleted file mode 100644 index fdd777c..0000000 Binary files a/Exe/MacOS/AesCtrOutput and /dev/null differ diff --git a/Exe/MacOS/Md5String b/Exe/MacOS/Md5String deleted file mode 100644 index f12c506..0000000 Binary files a/Exe/MacOS/Md5String and /dev/null differ diff --git a/Exe/MacOS/Rc4Output b/Exe/MacOS/Rc4Output deleted file mode 100644 index 1884f18..0000000 Binary files a/Exe/MacOS/Rc4Output and /dev/null differ diff --git a/Exe/MacOS/Sha1String b/Exe/MacOS/Sha1String deleted file mode 100644 index 60abeee..0000000 Binary files a/Exe/MacOS/Sha1String and /dev/null differ diff --git a/Exe/MacOS/Sha256String b/Exe/MacOS/Sha256String deleted file mode 100644 index 605d309..0000000 Binary files a/Exe/MacOS/Sha256String and /dev/null differ diff --git a/Exe/MacOS/Sha512String b/Exe/MacOS/Sha512String deleted file mode 100644 index 5b9167f..0000000 Binary files a/Exe/MacOS/Sha512String and /dev/null differ diff --git a/Exe/Windows/AesBlock.exe b/Exe/Windows/AesBlock.exe deleted file mode 100644 index a41b104..0000000 Binary files a/Exe/Windows/AesBlock.exe and /dev/null differ diff --git a/Exe/Windows/AesCtrOutput.exe b/Exe/Windows/AesCtrOutput.exe deleted file mode 100644 index a80a375..0000000 Binary files a/Exe/Windows/AesCtrOutput.exe and /dev/null differ diff --git a/Exe/Windows/Md5String.exe b/Exe/Windows/Md5String.exe deleted file mode 100644 index 87c0262..0000000 Binary files a/Exe/Windows/Md5String.exe and /dev/null differ diff --git a/Exe/Windows/Rc4Output.exe b/Exe/Windows/Rc4Output.exe deleted file mode 100644 index f7aebc4..0000000 Binary files a/Exe/Windows/Rc4Output.exe and /dev/null differ diff --git a/Exe/Windows/Sha1String.exe b/Exe/Windows/Sha1String.exe deleted file mode 100644 index fb4b6cd..0000000 Binary files a/Exe/Windows/Sha1String.exe and /dev/null differ diff --git a/Exe/Windows/Sha256String.exe b/Exe/Windows/Sha256String.exe deleted file mode 100644 index 5a85237..0000000 Binary files a/Exe/Windows/Sha256String.exe and /dev/null differ diff --git a/Exe/Windows/Sha512String.exe b/Exe/Windows/Sha512String.exe deleted file mode 100644 index 4f06e23..0000000 Binary files a/Exe/Windows/Sha512String.exe and /dev/null differ diff --git a/ReadMe.md b/ReadMe.md index 4f4baff..3e7a3bf 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -1,7 +1,7 @@ -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. @@ -14,7 +14,33 @@ 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 ----------------------------- @@ -44,35 +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. @@ -88,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. diff --git a/lib/CryptLib_Aes.c b/lib/WjCryptLib_Aes.c similarity index 99% rename from lib/CryptLib_Aes.c rename to lib/WjCryptLib_Aes.c index 12b9929..0668654 100644 --- a/lib/CryptLib_Aes.c +++ b/lib/WjCryptLib_Aes.c @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CryptLib_Aes +// WjCryptLib_Aes // // 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. @@ -23,7 +23,7 @@ // IMPORTS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#include "CryptLib_Aes.h" +#include "WjCryptLib_Aes.h" #include #include diff --git a/lib/CryptLib_Aes.h b/lib/WjCryptLib_Aes.h similarity index 99% rename from lib/CryptLib_Aes.h rename to lib/WjCryptLib_Aes.h index 3239530..8c8c219 100644 --- a/lib/CryptLib_Aes.h +++ b/lib/WjCryptLib_Aes.h @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CryptLib_Aes +// WjCryptLib_Aes // // 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. diff --git a/lib/CryptLib_AesCtr.c b/lib/WjCryptLib_AesCtr.c similarity index 99% rename from lib/CryptLib_AesCtr.c rename to lib/WjCryptLib_AesCtr.c index 8e5e08d..a5e67b6 100644 --- a/lib/CryptLib_AesCtr.c +++ b/lib/WjCryptLib_AesCtr.c @@ -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 #include diff --git a/lib/CryptLib_AesCtr.h b/lib/WjCryptLib_AesCtr.h similarity index 99% rename from lib/CryptLib_AesCtr.h rename to lib/WjCryptLib_AesCtr.h index efb3601..127f2cb 100644 --- a/lib/CryptLib_AesCtr.h +++ b/lib/WjCryptLib_AesCtr.h @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CryptLib_AesCtr +// WjCryptLib_AesCtr // // Implementation of AES CTR stream cipher. // @@ -18,7 +18,7 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include -#include "CryptLib_Aes.h" +#include "WjCryptLib_Aes.h" //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TYPES diff --git a/lib/WjCryptLib_AesOfb.c b/lib/WjCryptLib_AesOfb.c new file mode 100644 index 0000000..719fb47 --- /dev/null +++ b/lib/WjCryptLib_AesOfb.c @@ -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 +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// 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; iAes = *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; +} diff --git a/lib/WjCryptLib_AesOfb.h b/lib/WjCryptLib_AesOfb.h new file mode 100644 index 0000000..06d0e8d --- /dev/null +++ b/lib/WjCryptLib_AesOfb.h @@ -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 +#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] + ); diff --git a/lib/CryptLib_Md5.c b/lib/WjCryptLib_Md5.c similarity index 99% rename from lib/CryptLib_Md5.c rename to lib/WjCryptLib_Md5.c index 8b299bf..5809b14 100644 --- a/lib/CryptLib_Md5.c +++ b/lib/WjCryptLib_Md5.c @@ -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 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/lib/CryptLib_Md5.h b/lib/WjCryptLib_Md5.h similarity index 99% rename from lib/CryptLib_Md5.h rename to lib/WjCryptLib_Md5.h index f7ca92d..fd860ca 100644 --- a/lib/CryptLib_Md5.h +++ b/lib/WjCryptLib_Md5.h @@ -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. diff --git a/lib/CryptLib_Rc4.c b/lib/WjCryptLib_Rc4.c similarity index 98% rename from lib/CryptLib_Rc4.c rename to lib/WjCryptLib_Rc4.c index 6352f78..5c453cc 100644 --- a/lib/CryptLib_Rc4.c +++ b/lib/WjCryptLib_Rc4.c @@ -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 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/lib/CryptLib_Rc4.h b/lib/WjCryptLib_Rc4.h similarity index 99% rename from lib/CryptLib_Rc4.h rename to lib/WjCryptLib_Rc4.h index fed71de..95ebf36 100644 --- a/lib/CryptLib_Rc4.h +++ b/lib/WjCryptLib_Rc4.h @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CryptLib_RC4 +// WjCryptLib_RC4 // // An implementation of RC4 stream cipher // diff --git a/lib/CryptLib_Sha1.c b/lib/WjCryptLib_Sha1.c similarity index 99% rename from lib/CryptLib_Sha1.c rename to lib/WjCryptLib_Sha1.c index 3542604..e3f1df3 100644 --- a/lib/CryptLib_Sha1.c +++ b/lib/WjCryptLib_Sha1.c @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CryptLib_Sha1 +// WjCryptLib_Sha1 // // Implementation of SHA1 hash function. // Original author: Steve Reid @@ -14,7 +14,7 @@ // IMPORTS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#include "CryptLib_Sha1.h" +#include "WjCryptLib_Sha1.h" #include //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/lib/CryptLib_Sha1.h b/lib/WjCryptLib_Sha1.h similarity index 99% rename from lib/CryptLib_Sha1.h rename to lib/WjCryptLib_Sha1.h index 8e15442..2180788 100644 --- a/lib/CryptLib_Sha1.h +++ b/lib/WjCryptLib_Sha1.h @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CryptLib_Sha1 +// WjCryptLib_Sha1 // // Implementation of SHA1 hash function. // Original author: Steve Reid diff --git a/lib/CryptLib_Sha256.c b/lib/WjCryptLib_Sha256.c similarity index 99% rename from lib/CryptLib_Sha256.c rename to lib/WjCryptLib_Sha256.c index 5e2f679..af466d3 100644 --- a/lib/CryptLib_Sha256.c +++ b/lib/WjCryptLib_Sha256.c @@ -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 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/lib/CryptLib_Sha256.h b/lib/WjCryptLib_Sha256.h similarity index 99% rename from lib/CryptLib_Sha256.h rename to lib/WjCryptLib_Sha256.h index 7e6aadd..06d3761 100644 --- a/lib/CryptLib_Sha256.h +++ b/lib/WjCryptLib_Sha256.h @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CryptLib_Sha256 +// WjCryptLib_Sha256 // // Implementation of SHA256 hash function. // Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org diff --git a/lib/CryptLib_Sha512.c b/lib/WjCryptLib_Sha512.c similarity index 99% rename from lib/CryptLib_Sha512.c rename to lib/WjCryptLib_Sha512.c index 43fb3b2..3d0aa23 100644 --- a/lib/CryptLib_Sha512.c +++ b/lib/WjCryptLib_Sha512.c @@ -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 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/lib/CryptLib_Sha512.h b/lib/WjCryptLib_Sha512.h similarity index 99% rename from lib/CryptLib_Sha512.h rename to lib/WjCryptLib_Sha512.h index 2d63eef..1c7fb17 100644 --- a/lib/CryptLib_Sha512.h +++ b/lib/WjCryptLib_Sha512.h @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CryptLib_Sha512 +// WjCryptLib_Sha512 // // Implementation of SHA512 hash function. // Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org diff --git a/projects/AesBlock/AesBlock.c b/projects/AesBlock/AesBlock.c index 9648287..b8a6cfb 100644 --- a/projects/AesBlock/AesBlock.c +++ b/projects/AesBlock/AesBlock.c @@ -16,7 +16,7 @@ #include #include #include -#include "CryptLib_Aes.h" +#include "WjCryptLib_Aes.h" //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // DEFINES diff --git a/projects/AesBlock/CMakeLists.txt b/projects/AesBlock/CMakeLists.txt index fa113b5..7ffe0e0 100644 --- a/projects/AesBlock/CMakeLists.txt +++ b/projects/AesBlock/CMakeLists.txt @@ -1,6 +1,6 @@ add_executable( AesBlock AesBlock.c ) target_link_libraries( AesBlock - CryptLib ) + WjCryptLib ) install(TARGETS AesBlock DESTINATION .) diff --git a/projects/AesCtrOutput/AesCtrOutput.c b/projects/AesCtrOutput/AesCtrOutput.c index 98ea4f6..9013a38 100644 --- a/projects/AesCtrOutput/AesCtrOutput.c +++ b/projects/AesCtrOutput/AesCtrOutput.c @@ -14,7 +14,7 @@ #include #include #include -#include "CryptLib_AesCtr.h" +#include "WjCryptLib_AesCtr.h" //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // DEFINITIONS diff --git a/projects/AesCtrOutput/CMakeLists.txt b/projects/AesCtrOutput/CMakeLists.txt index d8b9f06..7c45492 100644 --- a/projects/AesCtrOutput/CMakeLists.txt +++ b/projects/AesCtrOutput/CMakeLists.txt @@ -1,7 +1,7 @@ add_executable( AesCtrOutput AesCtrOutput.c ) target_link_libraries( AesCtrOutput - CryptLib ) + WjCryptLib ) install(TARGETS AesCtrOutput DESTINATION .) diff --git a/projects/AesOfbOutput/AesOfbOutput.c b/projects/AesOfbOutput/AesOfbOutput.c new file mode 100644 index 0000000..efdd14d --- /dev/null +++ b/projects/AesOfbOutput/AesOfbOutput.c @@ -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 +#include +#include +#include +#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= '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 \n" + " - 128, 192, or 256 bit written as hex\n" + " - 128 bit written as hex\n" + " - 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 #include #include -#include "CryptLib_Md5.h" +#include "WjCryptLib_Md5.h" //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FUNCTIONS diff --git a/projects/Rc4Output/CMakeLists.txt b/projects/Rc4Output/CMakeLists.txt index db64f48..8e87a70 100644 --- a/projects/Rc4Output/CMakeLists.txt +++ b/projects/Rc4Output/CMakeLists.txt @@ -1,7 +1,7 @@ add_executable( Rc4Output Rc4Output.c ) target_link_libraries( Rc4Output - CryptLib ) + WjCryptLib ) install(TARGETS Rc4Output DESTINATION .) diff --git a/projects/Rc4Output/Rc4Output.c b/projects/Rc4Output/Rc4Output.c index 04884c6..a37831d 100644 --- a/projects/Rc4Output/Rc4Output.c +++ b/projects/Rc4Output/Rc4Output.c @@ -14,7 +14,7 @@ #include #include #include -#include "CryptLib_Rc4.h" +#include "WjCryptLib_Rc4.h" //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // DEFINITIONS diff --git a/projects/Sha1String/CMakeLists.txt b/projects/Sha1String/CMakeLists.txt index ef8d5ac..63fb63a 100644 --- a/projects/Sha1String/CMakeLists.txt +++ b/projects/Sha1String/CMakeLists.txt @@ -1,7 +1,7 @@ add_executable( Sha1String Sha1String.c ) target_link_libraries( Sha1String - CryptLib ) + WjCryptLib ) install(TARGETS Sha1String DESTINATION .) diff --git a/projects/Sha1String/Sha1String.c b/projects/Sha1String/Sha1String.c index 4c16f2c..fdf0c43 100644 --- a/projects/Sha1String/Sha1String.c +++ b/projects/Sha1String/Sha1String.c @@ -14,7 +14,7 @@ #include #include #include -#include "CryptLib_Sha1.h" +#include "WjCryptLib_Sha1.h" //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FUNCTIONS diff --git a/projects/Sha256String/CMakeLists.txt b/projects/Sha256String/CMakeLists.txt index 6c1af99..da5c5fc 100644 --- a/projects/Sha256String/CMakeLists.txt +++ b/projects/Sha256String/CMakeLists.txt @@ -1,6 +1,6 @@ add_executable( Sha256String Sha256String.c ) target_link_libraries( Sha256String - CryptLib ) + WjCryptLib ) install(TARGETS Sha256String DESTINATION .) diff --git a/projects/Sha256String/Sha256String.c b/projects/Sha256String/Sha256String.c index 984fd2f..88f1976 100644 --- a/projects/Sha256String/Sha256String.c +++ b/projects/Sha256String/Sha256String.c @@ -14,7 +14,7 @@ #include #include #include -#include "CryptLib_Sha256.h" +#include "WjCryptLib_Sha256.h" //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FUNCTIONS diff --git a/projects/Sha512String/CMakeLists.txt b/projects/Sha512String/CMakeLists.txt index e70d881..ccf2213 100644 --- a/projects/Sha512String/CMakeLists.txt +++ b/projects/Sha512String/CMakeLists.txt @@ -1,7 +1,7 @@ add_executable( Sha512String Sha512String.c ) target_link_libraries( Sha512String - CryptLib ) + WjCryptLib ) install(TARGETS Sha512String DESTINATION .) diff --git a/projects/Sha512String/Sha512String.c b/projects/Sha512String/Sha512String.c index ba602ed..6f910a3 100644 --- a/projects/Sha512String/Sha512String.c +++ b/projects/Sha512String/Sha512String.c @@ -14,7 +14,7 @@ #include #include #include -#include "CryptLib_Sha512.h" +#include "WjCryptLib_Sha512.h" //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FUNCTIONS diff --git a/projects/WjCryptLibTest/CMakeLists.txt b/projects/WjCryptLibTest/CMakeLists.txt new file mode 100644 index 0000000..ca0ad70 --- /dev/null +++ b/projects/WjCryptLibTest/CMakeLists.txt @@ -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 .) diff --git a/projects/CryptLibTest/CryptLibTest.c b/projects/WjCryptLibTest/WjCryptLibTest.c similarity index 78% rename from projects/CryptLibTest/CryptLibTest.c rename to projects/WjCryptLibTest/WjCryptLibTest.c index b6f5ffe..e2065d1 100644 --- a/projects/CryptLibTest/CryptLibTest.c +++ b/projects/WjCryptLibTest/WjCryptLibTest.c @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CryptLibTest +// WjCryptLibTest // // Tests the cryptography functions against known test vectors to verify algorithms are correct. // @@ -15,10 +15,11 @@ #include #include #include -#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 ) diff --git a/projects/CryptLibTest/CryptLibTest_Aes.c b/projects/WjCryptLibTest/WjCryptLibTest_Aes.c similarity index 99% rename from projects/CryptLibTest/CryptLibTest_Aes.c rename to projects/WjCryptLibTest/WjCryptLibTest_Aes.c index 813404c..e67ed97 100644 --- a/projects/CryptLibTest/CryptLibTest_Aes.c +++ b/projects/WjCryptLibTest/WjCryptLibTest_Aes.c @@ -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 #include #include -#include "CryptLib_Aes.h" +#include "WjCryptLib_Aes.h" //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TYPES diff --git a/projects/CryptLibTest/CryptLibTest_Aes.h b/projects/WjCryptLibTest/WjCryptLibTest_Aes.h similarity index 98% rename from projects/CryptLibTest/CryptLibTest_Aes.h rename to projects/WjCryptLibTest/WjCryptLibTest_Aes.h index c839bc2..e5abbba 100644 --- a/projects/CryptLibTest/CryptLibTest_Aes.h +++ b/projects/WjCryptLibTest/WjCryptLibTest_Aes.h @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CryptLibTest_Aes +// WjCryptLibTest_Aes // // Tests the cryptography functions against known test vectors to verify algorithms are correct. // Tests the following: diff --git a/projects/CryptLibTest/CryptLibTest_AesCtr.c b/projects/WjCryptLibTest/WjCryptLibTest_AesCtr.c similarity index 99% rename from projects/CryptLibTest/CryptLibTest_AesCtr.c rename to projects/WjCryptLibTest/WjCryptLibTest_AesCtr.c index 0e18e73..31089d4 100644 --- a/projects/CryptLibTest/CryptLibTest_AesCtr.c +++ b/projects/WjCryptLibTest/WjCryptLibTest_AesCtr.c @@ -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,8 +17,8 @@ #include #include #include -#include "CryptLib_AesCtr.h" -#include "CryptLib_Sha1.h" +#include "WjCryptLib_AesCtr.h" +#include "WjCryptLib_Sha1.h" //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // MACROS diff --git a/projects/CryptLibTest/CryptLibTest_AesCtr.h b/projects/WjCryptLibTest/WjCryptLibTest_AesCtr.h similarity index 97% rename from projects/CryptLibTest/CryptLibTest_AesCtr.h rename to projects/WjCryptLibTest/WjCryptLibTest_AesCtr.h index c994add..fc5bf14 100644 --- a/projects/CryptLibTest/CryptLibTest_AesCtr.h +++ b/projects/WjCryptLibTest/WjCryptLibTest_AesCtr.h @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CryptLibTest_AesCtr +// WjCryptLibTest_AesCtr // // Tests the cryptography functions against known test vectors to verify algorithms are correct. // Tests the following: diff --git a/projects/WjCryptLibTest/WjCryptLibTest_AesOfb.c b/projects/WjCryptLibTest/WjCryptLibTest_AesOfb.c new file mode 100644 index 0000000..ec9e08f --- /dev/null +++ b/projects/WjCryptLibTest/WjCryptLibTest_AesOfb.c @@ -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 +#include +#include +#include +#include +#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 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; +} diff --git a/projects/WjCryptLibTest/WjCryptLibTest_AesOfb.h b/projects/WjCryptLibTest/WjCryptLibTest_AesOfb.h new file mode 100644 index 0000000..298e864 --- /dev/null +++ b/projects/WjCryptLibTest/WjCryptLibTest_AesOfb.h @@ -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 + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// EXPORTED FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TestAesOfb +// +// Test AES OFB algorithm +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool + TestAesOfb + ( + void + ); \ No newline at end of file diff --git a/projects/CryptLibTest/CryptLibTest_Hashes.c b/projects/WjCryptLibTest/WjCryptLibTest_Hashes.c similarity index 97% rename from projects/CryptLibTest/CryptLibTest_Hashes.c rename to projects/WjCryptLibTest/WjCryptLibTest_Hashes.c index 9184e23..90a4670 100644 --- a/projects/CryptLibTest/CryptLibTest_Hashes.c +++ b/projects/WjCryptLibTest/WjCryptLibTest_Hashes.c @@ -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 #include #include -#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; } diff --git a/projects/CryptLibTest/CryptLibTest_Hashes.h b/projects/WjCryptLibTest/WjCryptLibTest_Hashes.h similarity index 98% rename from projects/CryptLibTest/CryptLibTest_Hashes.h rename to projects/WjCryptLibTest/WjCryptLibTest_Hashes.h index 2f8f105..ebbd436 100644 --- a/projects/CryptLibTest/CryptLibTest_Hashes.h +++ b/projects/WjCryptLibTest/WjCryptLibTest_Hashes.h @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CryptLibTest_Hashes +// WjCryptLibTest_Hashes // // Tests the hash functions against known test vectors to verify algorithms are correct. // Tests the following: diff --git a/projects/CryptLibTest/CryptLibTest_Rc4.c b/projects/WjCryptLibTest/WjCryptLibTest_Rc4.c similarity index 98% rename from projects/CryptLibTest/CryptLibTest_Rc4.c rename to projects/WjCryptLibTest/WjCryptLibTest_Rc4.c index 0c0b598..c00754c 100644 --- a/projects/CryptLibTest/CryptLibTest_Rc4.c +++ b/projects/WjCryptLibTest/WjCryptLibTest_Rc4.c @@ -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 #include #include -#include "CryptLib_Rc4.h" +#include "WjCryptLib_Rc4.h" //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS diff --git a/projects/CryptLibTest/CryptLibTest_Rc4.h b/projects/WjCryptLibTest/WjCryptLibTest_Rc4.h similarity index 98% rename from projects/CryptLibTest/CryptLibTest_Rc4.h rename to projects/WjCryptLibTest/WjCryptLibTest_Rc4.h index f919b77..7e4ccfc 100644 --- a/projects/CryptLibTest/CryptLibTest_Rc4.h +++ b/projects/WjCryptLibTest/WjCryptLibTest_Rc4.h @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CryptLibTest_Rc4 +// WjCryptLibTest_Rc4 // // Tests the RC4 function against known test vectors to verify algorithms are correct. //