1 Commits

Author SHA1 Message Date
waterjuice
1683e5d9f6 Version 2.2.0
* Added AES-OFB module.
* File names have been changed to have the prefix `WjCryptLib_` rather
than `CryptLib_`.
* Removed compiled binaries from source tree.
2018-01-07 18:00:57 +11:00
68 changed files with 1028 additions and 136 deletions

View File

@@ -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.

View File

@@ -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.

View File

@@ -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 <stdint.h>
#include <memory.h>

View File

@@ -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.

View File

@@ -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>

View File

@@ -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

226
lib/WjCryptLib_AesOfb.c Normal file
View 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
View 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]
);

View File

@@ -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>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -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.

View File

@@ -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>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CryptLib_RC4
// WjCryptLib_RC4
//
// An implementation of RC4 stream cipher
//

View File

@@ -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>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CryptLib_Sha1
// WjCryptLib_Sha1
//
// Implementation of SHA1 hash function.
// Original author: Steve Reid <sreid@sea-to-sky.net>

View File

@@ -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>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CryptLib_Sha256
// WjCryptLib_Sha256
//
// Implementation of SHA256 hash function.
// Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org

View File

@@ -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>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CryptLib_Sha512
// WjCryptLib_Sha512
//
// Implementation of SHA512 hash function.
// Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org

View File

@@ -16,7 +16,7 @@
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include "CryptLib_Aes.h"
#include "WjCryptLib_Aes.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DEFINES

View File

@@ -1,6 +1,6 @@
add_executable( AesBlock
AesBlock.c )
target_link_libraries( AesBlock
CryptLib )
WjCryptLib )
install(TARGETS AesBlock DESTINATION .)

View File

@@ -14,7 +14,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "CryptLib_AesCtr.h"
#include "WjCryptLib_AesCtr.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DEFINITIONS

View File

@@ -1,7 +1,7 @@
add_executable( AesCtrOutput
AesCtrOutput.c )
target_link_libraries( AesCtrOutput
CryptLib )
WjCryptLib )
install(TARGETS AesCtrOutput DESTINATION .)

View 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;
}

View File

@@ -0,0 +1,7 @@
add_executable( AesOfbOutput
AesOfbOutput.c )
target_link_libraries( AesOfbOutput
WjCryptLib )
install(TARGETS AesOfbOutput DESTINATION .)

View File

@@ -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 .)

View File

@@ -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 .)

View File

@@ -14,7 +14,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "CryptLib_Md5.h"
#include "WjCryptLib_Md5.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS

View File

@@ -1,7 +1,7 @@
add_executable( Rc4Output
Rc4Output.c )
target_link_libraries( Rc4Output
CryptLib )
WjCryptLib )
install(TARGETS Rc4Output DESTINATION .)

View File

@@ -14,7 +14,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "CryptLib_Rc4.h"
#include "WjCryptLib_Rc4.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DEFINITIONS

View File

@@ -1,7 +1,7 @@
add_executable( Sha1String
Sha1String.c )
target_link_libraries( Sha1String
CryptLib )
WjCryptLib )
install(TARGETS Sha1String DESTINATION .)

View File

@@ -14,7 +14,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "CryptLib_Sha1.h"
#include "WjCryptLib_Sha1.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS

View File

@@ -1,6 +1,6 @@
add_executable( Sha256String
Sha256String.c )
target_link_libraries( Sha256String
CryptLib )
WjCryptLib )
install(TARGETS Sha256String DESTINATION .)

View File

@@ -14,7 +14,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "CryptLib_Sha256.h"
#include "WjCryptLib_Sha256.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS

View File

@@ -1,7 +1,7 @@
add_executable( Sha512String
Sha512String.c )
target_link_libraries( Sha512String
CryptLib )
WjCryptLib )
install(TARGETS Sha512String DESTINATION .)

View File

@@ -14,7 +14,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "CryptLib_Sha512.h"
#include "WjCryptLib_Sha512.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS

View 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 .)

View File

@@ -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 )

View File

@@ -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

View File

@@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CryptLibTest_Aes
// WjCryptLibTest_Aes
//
// Tests the cryptography functions against known test vectors to verify algorithms are correct.
// Tests the following:

View File

@@ -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 <stdint.h>
#include <string.h>
#include <stdbool.h>
#include "CryptLib_AesCtr.h"
#include "CryptLib_Sha1.h"
#include "WjCryptLib_AesCtr.h"
#include "WjCryptLib_Sha1.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// MACROS

View File

@@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CryptLibTest_AesCtr
// WjCryptLibTest_AesCtr
//
// Tests the cryptography functions against known test vectors to verify algorithms are correct.
// Tests the following:

View 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;
}

View 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
);

View File

@@ -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;
}

View File

@@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CryptLibTest_Hashes
// WjCryptLibTest_Hashes
//
// Tests the hash functions against known test vectors to verify algorithms are correct.
// Tests the following:

View File

@@ -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

View File

@@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CryptLibTest_Rc4
// WjCryptLibTest_Rc4
//
// Tests the RC4 function against known test vectors to verify algorithms are correct.
//