diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..81e29c1 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.6.0) + +project( CryptLib ) + +# 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 ) + + +# Add the demo project directories +add_subdirectory( projects/CryptLibTest ) +add_subdirectory( projects/Md5String ) +add_subdirectory( projects/Rc4Output ) +add_subdirectory( projects/Sha1String ) +add_subdirectory( projects/Sha256String ) +add_subdirectory( projects/Sha512String ) +add_subdirectory( projects/AesBlock ) +add_subdirectory( projects/AesCtrOutput ) diff --git a/Exe/Linux/AesBlock b/Exe/Linux/AesBlock new file mode 100644 index 0000000..de58c8a Binary files /dev/null and b/Exe/Linux/AesBlock differ diff --git a/Exe/Linux/AesCtrOutput b/Exe/Linux/AesCtrOutput new file mode 100644 index 0000000..c35d102 Binary files /dev/null and b/Exe/Linux/AesCtrOutput differ diff --git a/Exe/MacOS/AesBlock b/Exe/MacOS/AesBlock new file mode 100644 index 0000000..9cc9273 Binary files /dev/null and b/Exe/MacOS/AesBlock differ diff --git a/Exe/MacOS/AesCtrOutput b/Exe/MacOS/AesCtrOutput new file mode 100644 index 0000000..322b88e Binary files /dev/null and b/Exe/MacOS/AesCtrOutput differ diff --git a/Exe/OSX/Md5String b/Exe/MacOS/Md5String similarity index 100% rename from Exe/OSX/Md5String rename to Exe/MacOS/Md5String diff --git a/Exe/OSX/Rc4Output b/Exe/MacOS/Rc4Output similarity index 100% rename from Exe/OSX/Rc4Output rename to Exe/MacOS/Rc4Output diff --git a/Exe/OSX/Sha1String b/Exe/MacOS/Sha1String similarity index 100% rename from Exe/OSX/Sha1String rename to Exe/MacOS/Sha1String diff --git a/Exe/OSX/Sha256String b/Exe/MacOS/Sha256String similarity index 100% rename from Exe/OSX/Sha256String rename to Exe/MacOS/Sha256String diff --git a/Exe/OSX/Sha512String b/Exe/MacOS/Sha512String similarity index 100% rename from Exe/OSX/Sha512String rename to Exe/MacOS/Sha512String diff --git a/Exe/Windows/AesBlock.exe b/Exe/Windows/AesBlock.exe new file mode 100644 index 0000000..be08d3c Binary files /dev/null and b/Exe/Windows/AesBlock.exe differ diff --git a/Exe/Windows/AesCtrOutput.exe b/Exe/Windows/AesCtrOutput.exe new file mode 100644 index 0000000..720294d Binary files /dev/null and b/Exe/Windows/AesCtrOutput.exe differ diff --git a/Projects.sln b/Projects.sln deleted file mode 100644 index 63bbcef..0000000 --- a/Projects.sln +++ /dev/null @@ -1,85 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ProofOfWork", "VSProjectFiles\ProofOfWork.vcxproj", "{78DE2AA5-4DEB-4601-AAB8-A3452BAC810C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Md5String", "VSProjectFiles\Md5String.vcxproj", "{2F5CA1B6-92CC-4142-86AC-62FADFF0B834}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Rc4Output", "VSProjectFiles\Rc4Output.vcxproj", "{E5A739D1-4246-4FB1-8AA4-673068EDE33A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Sha1String", "VSProjectFiles\Sha1String.vcxproj", "{B01EA8DA-3ABB-410A-B28E-8336467F94F8}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Sha256String", "VSProjectFiles\Sha256String.vcxproj", "{43164E66-9EA5-48E5-9708-6AF8C3642F6E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Sha512String", "VSProjectFiles\Sha512String.vcxproj", "{FC8B119A-DF2A-48A6-B834-F1CDF80AECB6}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CryptLibTest", "VSProjectFiles\CryptLibTest.vcxproj", "{543C3780-F2F4-47BA-8263-278B911A73AC}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {78DE2AA5-4DEB-4601-AAB8-A3452BAC810C}.Debug|Win32.ActiveCfg = Debug|Win32 - {78DE2AA5-4DEB-4601-AAB8-A3452BAC810C}.Debug|Win32.Build.0 = Debug|Win32 - {78DE2AA5-4DEB-4601-AAB8-A3452BAC810C}.Debug|x64.ActiveCfg = Debug|x64 - {78DE2AA5-4DEB-4601-AAB8-A3452BAC810C}.Debug|x64.Build.0 = Debug|x64 - {78DE2AA5-4DEB-4601-AAB8-A3452BAC810C}.Release|Win32.ActiveCfg = Release|Win32 - {78DE2AA5-4DEB-4601-AAB8-A3452BAC810C}.Release|Win32.Build.0 = Release|Win32 - {78DE2AA5-4DEB-4601-AAB8-A3452BAC810C}.Release|x64.ActiveCfg = Release|x64 - {78DE2AA5-4DEB-4601-AAB8-A3452BAC810C}.Release|x64.Build.0 = Release|x64 - {2F5CA1B6-92CC-4142-86AC-62FADFF0B834}.Debug|Win32.ActiveCfg = Debug|Win32 - {2F5CA1B6-92CC-4142-86AC-62FADFF0B834}.Debug|Win32.Build.0 = Debug|Win32 - {2F5CA1B6-92CC-4142-86AC-62FADFF0B834}.Debug|x64.ActiveCfg = Debug|x64 - {2F5CA1B6-92CC-4142-86AC-62FADFF0B834}.Debug|x64.Build.0 = Debug|x64 - {2F5CA1B6-92CC-4142-86AC-62FADFF0B834}.Release|Win32.ActiveCfg = Release|Win32 - {2F5CA1B6-92CC-4142-86AC-62FADFF0B834}.Release|Win32.Build.0 = Release|Win32 - {2F5CA1B6-92CC-4142-86AC-62FADFF0B834}.Release|x64.ActiveCfg = Release|x64 - {2F5CA1B6-92CC-4142-86AC-62FADFF0B834}.Release|x64.Build.0 = Release|x64 - {E5A739D1-4246-4FB1-8AA4-673068EDE33A}.Debug|Win32.ActiveCfg = Debug|Win32 - {E5A739D1-4246-4FB1-8AA4-673068EDE33A}.Debug|Win32.Build.0 = Debug|Win32 - {E5A739D1-4246-4FB1-8AA4-673068EDE33A}.Debug|x64.ActiveCfg = Debug|x64 - {E5A739D1-4246-4FB1-8AA4-673068EDE33A}.Debug|x64.Build.0 = Debug|x64 - {E5A739D1-4246-4FB1-8AA4-673068EDE33A}.Release|Win32.ActiveCfg = Release|Win32 - {E5A739D1-4246-4FB1-8AA4-673068EDE33A}.Release|Win32.Build.0 = Release|Win32 - {E5A739D1-4246-4FB1-8AA4-673068EDE33A}.Release|x64.ActiveCfg = Release|x64 - {E5A739D1-4246-4FB1-8AA4-673068EDE33A}.Release|x64.Build.0 = Release|x64 - {B01EA8DA-3ABB-410A-B28E-8336467F94F8}.Debug|Win32.ActiveCfg = Debug|Win32 - {B01EA8DA-3ABB-410A-B28E-8336467F94F8}.Debug|Win32.Build.0 = Debug|Win32 - {B01EA8DA-3ABB-410A-B28E-8336467F94F8}.Debug|x64.ActiveCfg = Debug|x64 - {B01EA8DA-3ABB-410A-B28E-8336467F94F8}.Debug|x64.Build.0 = Debug|x64 - {B01EA8DA-3ABB-410A-B28E-8336467F94F8}.Release|Win32.ActiveCfg = Release|Win32 - {B01EA8DA-3ABB-410A-B28E-8336467F94F8}.Release|Win32.Build.0 = Release|Win32 - {B01EA8DA-3ABB-410A-B28E-8336467F94F8}.Release|x64.ActiveCfg = Release|x64 - {B01EA8DA-3ABB-410A-B28E-8336467F94F8}.Release|x64.Build.0 = Release|x64 - {43164E66-9EA5-48E5-9708-6AF8C3642F6E}.Debug|Win32.ActiveCfg = Debug|Win32 - {43164E66-9EA5-48E5-9708-6AF8C3642F6E}.Debug|Win32.Build.0 = Debug|Win32 - {43164E66-9EA5-48E5-9708-6AF8C3642F6E}.Debug|x64.ActiveCfg = Debug|x64 - {43164E66-9EA5-48E5-9708-6AF8C3642F6E}.Debug|x64.Build.0 = Debug|x64 - {43164E66-9EA5-48E5-9708-6AF8C3642F6E}.Release|Win32.ActiveCfg = Release|Win32 - {43164E66-9EA5-48E5-9708-6AF8C3642F6E}.Release|Win32.Build.0 = Release|Win32 - {43164E66-9EA5-48E5-9708-6AF8C3642F6E}.Release|x64.ActiveCfg = Release|x64 - {43164E66-9EA5-48E5-9708-6AF8C3642F6E}.Release|x64.Build.0 = Release|x64 - {FC8B119A-DF2A-48A6-B834-F1CDF80AECB6}.Debug|Win32.ActiveCfg = Debug|Win32 - {FC8B119A-DF2A-48A6-B834-F1CDF80AECB6}.Debug|Win32.Build.0 = Debug|Win32 - {FC8B119A-DF2A-48A6-B834-F1CDF80AECB6}.Debug|x64.ActiveCfg = Debug|x64 - {FC8B119A-DF2A-48A6-B834-F1CDF80AECB6}.Debug|x64.Build.0 = Debug|x64 - {FC8B119A-DF2A-48A6-B834-F1CDF80AECB6}.Release|Win32.ActiveCfg = Release|Win32 - {FC8B119A-DF2A-48A6-B834-F1CDF80AECB6}.Release|Win32.Build.0 = Release|Win32 - {FC8B119A-DF2A-48A6-B834-F1CDF80AECB6}.Release|x64.ActiveCfg = Release|x64 - {FC8B119A-DF2A-48A6-B834-F1CDF80AECB6}.Release|x64.Build.0 = Release|x64 - {543C3780-F2F4-47BA-8263-278B911A73AC}.Debug|Win32.ActiveCfg = Debug|Win32 - {543C3780-F2F4-47BA-8263-278B911A73AC}.Debug|Win32.Build.0 = Debug|Win32 - {543C3780-F2F4-47BA-8263-278B911A73AC}.Debug|x64.ActiveCfg = Debug|x64 - {543C3780-F2F4-47BA-8263-278B911A73AC}.Debug|x64.Build.0 = Debug|x64 - {543C3780-F2F4-47BA-8263-278B911A73AC}.Release|Win32.ActiveCfg = Release|Win32 - {543C3780-F2F4-47BA-8263-278B911A73AC}.Release|Win32.Build.0 = Release|Win32 - {543C3780-F2F4-47BA-8263-278B911A73AC}.Release|x64.ActiveCfg = Release|x64 - {543C3780-F2F4-47BA-8263-278B911A73AC}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/ReadMe.md b/ReadMe.md new file mode 100644 index 0000000..06a4f97 --- /dev/null +++ b/ReadMe.md @@ -0,0 +1,113 @@ +CryptLib +======== + +CryptLib is a collection of cryptographic functions written in C. Each +module is fully independent and generally requires only a single .c file +and a a single .h file. AES-CTR does depend on the AES module, so in this +case all four files are needed. + +The functions are designed to be portable and have been tested on both +a Little-Endian and a Big-Endian architecture + +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* + +Version 2.0.0 - December 2017 +----------------------------- + +Changes: + +* Added AES and AES-CTR modules. AES-CTR conforms to the same counter +mode used with AES in *OpenSSL*. +* All algorithms now work on Big-Endian architectures. +* Now uses CMake for building rather than make files and Visual Studio +projects. CMake will generate whatever system is required. +* Input function parameters are now marked `const` +* File names have been changed to have the prefix `CryptLib_` rather +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. + +* 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) + +Test Programs +------------- + +In the projects directory there are several programs that compile to +command line executables. One is CryptLibTest. 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. + +Additionally there are sample programs that demonstrate the functions. For +each of the hash functions there is a program that creates a hash from a +string given on command line. For RC4 and AES-CTR there are programs that +output the stream in hex. + +* Md5String +* Sha1String +* Sha256String +* Sha512String +* Rc4Output +* AesBlock +* AesCtrOutput + +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 +======= + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to + diff --git a/VSProjectFiles/CryptLibTest.vcxproj b/VSProjectFiles/CryptLibTest.vcxproj deleted file mode 100644 index d785bc7..0000000 --- a/VSProjectFiles/CryptLibTest.vcxproj +++ /dev/null @@ -1,76 +0,0 @@ - - - - - Debug - x64 - - - Debug - Win32 - - - Release - x64 - - - Release - Win32 - - - - - - - - - - - - - - - - - - - {543C3780-F2F4-47BA-8263-278B911A73AC} - CryptLibTest - Win32Proj - - - - Application - - - Application - - - Application - - - Application - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - - - - - \ No newline at end of file diff --git a/VSProjectFiles/CryptLibTest.vcxproj.filters b/VSProjectFiles/CryptLibTest.vcxproj.filters deleted file mode 100644 index 44f6cea..0000000 --- a/VSProjectFiles/CryptLibTest.vcxproj.filters +++ /dev/null @@ -1,49 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {aabf3f27-af59-42e0-94ef-f81adde8e682} - - - - - lib - - - lib - - - lib - - - lib - - - lib - - - Source Files - - - - - lib - - - lib - - - lib - - - lib - - - lib - - - \ No newline at end of file diff --git a/VSProjectFiles/Md5String.vcxproj b/VSProjectFiles/Md5String.vcxproj deleted file mode 100644 index 0386dfe..0000000 --- a/VSProjectFiles/Md5String.vcxproj +++ /dev/null @@ -1,68 +0,0 @@ - - - - - Debug - x64 - - - Debug - Win32 - - - Release - x64 - - - Release - Win32 - - - - - - - - - - - {2F5CA1B6-92CC-4142-86AC-62FADFF0B834} - Md5String - Win32Proj - - - - Application - - - Application - - - Application - - - Application - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - - - - - \ No newline at end of file diff --git a/VSProjectFiles/Md5String.vcxproj.filters b/VSProjectFiles/Md5String.vcxproj.filters deleted file mode 100644 index b787e0a..0000000 --- a/VSProjectFiles/Md5String.vcxproj.filters +++ /dev/null @@ -1,25 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {aabf3f27-af59-42e0-94ef-f81adde8e682} - - - - - lib - - - Source Files - - - - - lib - - - \ No newline at end of file diff --git a/VSProjectFiles/ProofOfWork.vcxproj b/VSProjectFiles/ProofOfWork.vcxproj deleted file mode 100644 index c01d815..0000000 --- a/VSProjectFiles/ProofOfWork.vcxproj +++ /dev/null @@ -1,78 +0,0 @@ - - - - - Debug - x64 - - - Debug - Win32 - - - Release - x64 - - - Release - Win32 - - - - - - - - - - - - - - - - - - - - - {78DE2AA5-4DEB-4601-AAB8-A3452BAC810C} - ProofOfWork - Win32Proj - - - - Application - - - Application - - - Application - - - Application - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - - - - - \ No newline at end of file diff --git a/VSProjectFiles/ProofOfWork.vcxproj.filters b/VSProjectFiles/ProofOfWork.vcxproj.filters deleted file mode 100644 index 7dbdb5c..0000000 --- a/VSProjectFiles/ProofOfWork.vcxproj.filters +++ /dev/null @@ -1,55 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {6ec1a200-d167-4831-b36c-9ddd0b2ba00a} - - - - - lib - - - lib - - - lib - - - lib - - - lib - - - lib - - - Source Files - - - - - lib - - - lib - - - lib - - - lib - - - lib - - - Source Files - - - \ No newline at end of file diff --git a/VSProjectFiles/Rc4Output.vcxproj b/VSProjectFiles/Rc4Output.vcxproj deleted file mode 100644 index 8df7e1d..0000000 --- a/VSProjectFiles/Rc4Output.vcxproj +++ /dev/null @@ -1,68 +0,0 @@ - - - - - Debug - x64 - - - Debug - Win32 - - - Release - x64 - - - Release - Win32 - - - - - - - - - - - {E5A739D1-4246-4FB1-8AA4-673068EDE33A} - Rc4Output - Win32Proj - - - - Application - - - Application - - - Application - - - Application - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - - - - - \ No newline at end of file diff --git a/VSProjectFiles/Rc4Output.vcxproj.filters b/VSProjectFiles/Rc4Output.vcxproj.filters deleted file mode 100644 index dfbb720..0000000 --- a/VSProjectFiles/Rc4Output.vcxproj.filters +++ /dev/null @@ -1,25 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {aabf3f27-af59-42e0-94ef-f81adde8e682} - - - - - lib - - - Source Files - - - - - lib - - - \ No newline at end of file diff --git a/VSProjectFiles/Sha1String.vcxproj b/VSProjectFiles/Sha1String.vcxproj deleted file mode 100644 index ab08ebc..0000000 --- a/VSProjectFiles/Sha1String.vcxproj +++ /dev/null @@ -1,68 +0,0 @@ - - - - - Debug - x64 - - - Debug - Win32 - - - Release - x64 - - - Release - Win32 - - - - - - - - - - - {B01EA8DA-3ABB-410A-B28E-8336467F94F8} - Sha1String - Win32Proj - - - - Application - - - Application - - - Application - - - Application - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - - - - - \ No newline at end of file diff --git a/VSProjectFiles/Sha1String.vcxproj.filters b/VSProjectFiles/Sha1String.vcxproj.filters deleted file mode 100644 index 35f513a..0000000 --- a/VSProjectFiles/Sha1String.vcxproj.filters +++ /dev/null @@ -1,29 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {aabf3f27-af59-42e0-94ef-f81adde8e682} - - - - - Source Files - - - lib - - - - - lib - - - \ No newline at end of file diff --git a/VSProjectFiles/Sha256String.vcxproj b/VSProjectFiles/Sha256String.vcxproj deleted file mode 100644 index d75ba0e..0000000 --- a/VSProjectFiles/Sha256String.vcxproj +++ /dev/null @@ -1,68 +0,0 @@ - - - - - Debug - x64 - - - Debug - Win32 - - - Release - x64 - - - Release - Win32 - - - - - - - - - - - {43164E66-9EA5-48E5-9708-6AF8C3642F6E} - Sha256String - Win32Proj - - - - Application - - - Application - - - Application - - - Application - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - - - - - \ No newline at end of file diff --git a/VSProjectFiles/Sha256String.vcxproj.filters b/VSProjectFiles/Sha256String.vcxproj.filters deleted file mode 100644 index e210814..0000000 --- a/VSProjectFiles/Sha256String.vcxproj.filters +++ /dev/null @@ -1,29 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {aabf3f27-af59-42e0-94ef-f81adde8e682} - - - - - Source Files - - - lib - - - - - lib - - - \ No newline at end of file diff --git a/VSProjectFiles/Sha512String.vcxproj b/VSProjectFiles/Sha512String.vcxproj deleted file mode 100644 index c516774..0000000 --- a/VSProjectFiles/Sha512String.vcxproj +++ /dev/null @@ -1,68 +0,0 @@ - - - - - Debug - x64 - - - Debug - Win32 - - - Release - x64 - - - Release - Win32 - - - - - - - - - - - {FC8B119A-DF2A-48A6-B834-F1CDF80AECB6} - Sha512String - Win32Proj - - - - Application - - - Application - - - Application - - - Application - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - - - - - \ No newline at end of file diff --git a/VSProjectFiles/Sha512String.vcxproj.filters b/VSProjectFiles/Sha512String.vcxproj.filters deleted file mode 100644 index f2f7ac4..0000000 --- a/VSProjectFiles/Sha512String.vcxproj.filters +++ /dev/null @@ -1,29 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {aabf3f27-af59-42e0-94ef-f81adde8e682} - - - - - Source Files - - - lib - - - - - lib - - - \ No newline at end of file diff --git a/VSProjectFiles/props/All.props b/VSProjectFiles/props/All.props deleted file mode 100644 index f9e64b9..0000000 --- a/VSProjectFiles/props/All.props +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - $(SolutionDir)Binaries\$(Platform)$(Configuration)\ - - - $(SolutionDir)Build\$(Platform)$(Configuration)\$(ProjectName)\ - - - - Level4 - - - - - true - true - MultiThreaded - Full - AnySuitable - Speed - true - _WIN32_WINNT=0x0600;_CRT_SECURE_NO_WARNINGS - true - $(SolutionDir)\lib;$(SolutionDir)\stdbool - - - $(IntDir)$(TargetName)$(TargetExt) - - - 6.0 - - - false - true - true - - - - \ No newline at end of file diff --git a/VSProjectFiles/props/Debug.props b/VSProjectFiles/props/Debug.props deleted file mode 100644 index b1327ef..0000000 --- a/VSProjectFiles/props/Debug.props +++ /dev/null @@ -1,21 +0,0 @@ - - - - - false - - - - true - - - false - - - MultiThreadedDebug - Disabled - Disabled - - - - \ No newline at end of file diff --git a/VSProjectFiles/props/Win32.props b/VSProjectFiles/props/Win32.props deleted file mode 100644 index 7135522..0000000 --- a/VSProjectFiles/props/Win32.props +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/VSProjectFiles/props/Win32Debug.props b/VSProjectFiles/props/Win32Debug.props deleted file mode 100644 index 14cf868..0000000 --- a/VSProjectFiles/props/Win32Debug.props +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/VSProjectFiles/props/Win32Release.props b/VSProjectFiles/props/Win32Release.props deleted file mode 100644 index 1626439..0000000 --- a/VSProjectFiles/props/Win32Release.props +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/VSProjectFiles/props/x64.props b/VSProjectFiles/props/x64.props deleted file mode 100644 index dead7f9..0000000 --- a/VSProjectFiles/props/x64.props +++ /dev/null @@ -1,8 +0,0 @@ - - - - - false - - - \ No newline at end of file diff --git a/VSProjectFiles/props/x64Debug.props b/VSProjectFiles/props/x64Debug.props deleted file mode 100644 index 50aab89..0000000 --- a/VSProjectFiles/props/x64Debug.props +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/VSProjectFiles/props/x64Release.props b/VSProjectFiles/props/x64Release.props deleted file mode 100644 index 92468f8..0000000 --- a/VSProjectFiles/props/x64Release.props +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/lib/CryptLib_Aes.c b/lib/CryptLib_Aes.c new file mode 100644 index 0000000..dd91706 --- /dev/null +++ b/lib/CryptLib_Aes.c @@ -0,0 +1,577 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLib_Aes +// +// Implementation of AES block cipher. Originally written by Kokke (https://github.com/kokke). Modified by WaterJuice +// retaining Public Domain license. +// +// AES is a block cipher that operates on 128 bit blocks. Encryption an Decryption routines use an AesContext which +// must be initialised with the key. An AesContext can be initialised with a 128, 192, or 256 bit key. Use the +// AesInitialise[n] functions to initialise the context with the key. Once an AES context is initialised its contents +// are not changed by the encrypting and decrypting functions. A context only needs to be initialised once for any +// given key and the context may be used by the encrypt/decrypt functions in simultaneous threads. +// All operations are performed byte wise and this implementation works in both little and endian processors. +// There are no alignment requirements with the keys and data blocks. +// +// This is free and unencumbered software released into the public domain - November 2017 waterjuice.org +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IMPORTS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "CryptLib_Aes.h" +#include +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DEFINES +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// Array holding the intermediate results during decryption. +typedef struct +{ + uint8_t state[4][4]; +} AesState; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CONSTANTS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// AES lookup values +static const uint8_t SBOX[256] = +{ + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +}; + +static const uint8_t RSBOX[256] = +{ + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; + +// The round constant word array, RCON[i], contains the values given by +// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8) +static const uint8_t RCON[11] = { 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// INTERNAL FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// KeyExpansion +// +// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static +void + KeyExpansion + ( + uint8_t const* Key, // [in] + AesContext* Context // [in out] + ) +{ + uint32_t i; + uint8_t k; + uint8_t temp [4]; // Used for the column/row operations + + // The first round key is the key itself. + for( i=0; iKeySizeInWords; i++ ) + { + Context->RoundKey[(i * 4) + 0] = Key[(i * 4) + 0]; + Context->RoundKey[(i * 4) + 1] = Key[(i * 4) + 1]; + Context->RoundKey[(i * 4) + 2] = Key[(i * 4) + 2]; + Context->RoundKey[(i * 4) + 3] = Key[(i * 4) + 3]; + } + + // All other round keys are found from the previous round keys. + for( i=Context->KeySizeInWords; i<4*(Context->NumberOfRounds+1); i++ ) + { + #ifdef _MSC_VER + // Visual Studio code analysis complains about the following code that the index into Context->RoundKey + // may be -4. This is because it is concerned that 'i' may be zero. However we know that 'i' will not + // be zero as it starts at Context->KeySizeInWords which is never going to be zero when this function + // is called (It will have one of 3 values assigned to it by the initialise functions). So we need to + // just suppress the warning here to stop Visual Studio complaining. + #pragma warning( suppress : 6385 ) + #endif + temp[0] = Context->RoundKey[(i-1) * 4 + 0]; + temp[1] = Context->RoundKey[(i-1) * 4 + 1]; + temp[2] = Context->RoundKey[(i-1) * 4 + 2]; + temp[3] = Context->RoundKey[(i-1) * 4 + 3]; + + if( 0 == i % Context->KeySizeInWords ) + { + // This function shifts the 4 bytes in a word to the left once. + // [a0,a1,a2,a3] becomes [a1,a2,a3,a0] + k = temp[0]; + temp[0] = temp[1]; + temp[1] = temp[2]; + temp[2] = temp[3]; + temp[3] = k; + + // SubWord is a function that takes a four-byte input word and + // applies the S-box to each of the four bytes to produce an output word. + temp[0] = SBOX[temp[0]]; + temp[1] = SBOX[temp[1]]; + temp[2] = SBOX[temp[2]]; + temp[3] = SBOX[temp[3]]; + + temp[0] = temp[0] ^ RCON[i/Context->KeySizeInWords]; + } + + if( AES_KEY_SIZE_256/4 == Context->KeySizeInWords ) + { + // Only performed with 256 bit sized keys + if( 4 == i % Context->KeySizeInWords ) + { + // Function Subword() + temp[0] = SBOX[temp[0]]; + temp[1] = SBOX[temp[1]]; + temp[2] = SBOX[temp[2]]; + temp[3] = SBOX[temp[3]]; + } + } + + Context->RoundKey[i*4 + 0] = Context->RoundKey[(i-Context->KeySizeInWords)*4 + 0] ^ temp[0]; + Context->RoundKey[i*4 + 1] = Context->RoundKey[(i-Context->KeySizeInWords)*4 + 1] ^ temp[1]; + Context->RoundKey[i*4 + 2] = Context->RoundKey[(i-Context->KeySizeInWords)*4 + 2] ^ temp[2]; + Context->RoundKey[i*4 + 3] = Context->RoundKey[(i-Context->KeySizeInWords)*4 + 3] ^ temp[3]; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AddRoundKey +// +// This function adds the round key to state. The round key is added to the state by an XOR function. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static +void + AddRoundKey + ( + uint32_t Round, // [in] + AesContext const* Context, // [in] + AesState* State // [in out] + ) +{ + uint32_t i; + uint32_t j; + + for( i=0; i<4; i++ ) + { + for( j=0; j<4; j++ ) + { + State->state[i][j] ^= Context->RoundKey[(Round*4*4) + (i*4) + j]; + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// SubBytes +// +// The SubBytes Function Substitutes the values in the state matrix with values in an S-box. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static +void + SubBytes + ( + AesState* State // [in out] + ) +{ + uint32_t i; + uint32_t j; + + for( i=0; i<4; i++ ) + { + for( j=0; j<4; j++ ) + { + State->state[j][i] = SBOX[ State->state[j][i] ]; + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ShiftRows +// +// The ShiftRows() function shifts the rows in the state to the left. Each row is shifted with different offset. +// Offset = Row number. So the first row is not shifted. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static +void + ShiftRows + ( + AesState* State // [in out] + ) +{ + uint8_t temp; + + // Rotate first row 1 columns to left + temp = State->state[0][1]; + State->state[0][1] = State->state[1][1]; + State->state[1][1] = State->state[2][1]; + State->state[2][1] = State->state[3][1]; + State->state[3][1] = temp; + + // Rotate second row 2 columns to left + temp = State->state[0][2]; + State->state[0][2] = State->state[2][2]; + State->state[2][2] = temp; + + temp = State->state[1][2]; + State->state[1][2] = State->state[3][2]; + State->state[3][2] = temp; + + // Rotate third row 3 columns to left + temp = State->state[0][3]; + State->state[0][3] = State->state[3][3]; + State->state[3][3] = State->state[2][3]; + State->state[2][3] = State->state[1][3]; + State->state[1][3] = temp; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// xtime +// +// Performs a calculation +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static +uint8_t + xtime + ( + uint8_t x // [in] + ) +{ + return (x<<1) ^ ( ((x>>7) & 1) * 0x1b ); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// MixColumns +// +// MixColumns function mixes the columns of the state matrix +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static +void + MixColumns + ( + AesState* State // [in out] + ) +{ + uint32_t i; + uint8_t Tmp; + uint8_t Tm; + uint8_t t; + + for( i=0; i<4; i++ ) + { + t = State->state[i][0]; + Tmp = State->state[i][0] ^ State->state[i][1] ^ State->state[i][2] ^ State->state[i][3] ; + Tm = State->state[i][0] ^ State->state[i][1] ; Tm = xtime(Tm); State->state[i][0] ^= Tm ^ Tmp ; + Tm = State->state[i][1] ^ State->state[i][2] ; Tm = xtime(Tm); State->state[i][1] ^= Tm ^ Tmp ; + Tm = State->state[i][2] ^ State->state[i][3] ; Tm = xtime(Tm); State->state[i][2] ^= Tm ^ Tmp ; + Tm = State->state[i][3] ^ t ; Tm = xtime(Tm); State->state[i][3] ^= Tm ^ Tmp ; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Multiply +// +// Multiply is used to multiply numbers in the field GF(2^8). This is defined as a macro. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define Multiply(x, y) \ + ( ((y & 1) * x) ^ \ + ((y>>1 & 1) * xtime(x)) ^ \ + ((y>>2 & 1) * xtime(xtime(x))) ^ \ + ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \ + ((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \ + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// InvMixColumns +// +// InvMixColumns function mixes the columns of the state matrix. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static +void + InvMixColumns + ( + AesState* State // [in out] + ) +{ + uint32_t i; + uint8_t a; + uint8_t b; + uint8_t c; + uint8_t d; + + for( i=0; i<4; i++ ) + { + a = State->state[i][0]; + b = State->state[i][1]; + c = State->state[i][2]; + d = State->state[i][3]; + + State->state[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09); + State->state[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d); + State->state[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b); + State->state[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// InvSubBytes +// +// The InvSubBytes Function Substitutes the values in the state matrix with values in an S-box. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static +void + InvSubBytes + ( + AesState* State // [in out] + ) +{ + uint32_t i; + uint32_t j; + + for( i=0; i<4; i++ ) + { + for( j=0; j<4; j++ ) + { + State->state[j][i] = RSBOX[ State->state[j][i] ]; + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// InvShiftRows +// +// Inverse of ShiftRows +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static +void + InvShiftRows + ( + AesState* State // [in out] + ) +{ + uint8_t temp; + + // Rotate first row 1 columns to right + temp = State->state[3][1]; + State->state[3][1] = State->state[2][1]; + State->state[2][1] = State->state[1][1]; + State->state[1][1] = State->state[0][1]; + State->state[0][1] = temp; + + // Rotate second row 2 columns to right + temp = State->state[0][2]; + State->state[0][2] = State->state[2][2]; + State->state[2][2] = temp; + + temp = State->state[1][2]; + State->state[1][2] = State->state[3][2]; + State->state[3][2] = temp; + + // Rotate third row 3 columns to right + temp = State->state[0][3]; + State->state[0][3] = State->state[1][3]; + State->state[1][3] = State->state[2][3]; + State->state[2][3] = State->state[3][3]; + State->state[3][3] = temp; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// EXPORTED FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesInitialise128 +// +// Initialises an AesContext with a 128 bit key. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesInitialise128 + ( + uint8_t const Key [AES_KEY_SIZE_128], // [in] + AesContext* Context // [out] + ) +{ + memset( Context, 0, sizeof(*Context) ); + + Context->KeySizeInWords = AES_KEY_SIZE_128 / sizeof(uint32_t); + Context->NumberOfRounds = 10; + + KeyExpansion( Key, Context ); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesInitialise192 +// +// Initialises an AesContext with a 192 bit key. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesInitialise192 + ( + uint8_t const Key [AES_KEY_SIZE_192], // [in] + AesContext* Context // [out] + ) +{ + memset( Context, 0, sizeof(*Context) ); + + Context->KeySizeInWords = AES_KEY_SIZE_192 / sizeof(uint32_t); + Context->NumberOfRounds = 12; + + KeyExpansion( Key, Context ); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesInitialise256 +// +// Initialises an AesContext with a 256 bit key. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesInitialise256 + ( + uint8_t const Key [AES_KEY_SIZE_256], // [in] + AesContext* Context // [out] + ) +{ + memset( Context, 0, sizeof(*Context) ); + + Context->KeySizeInWords = AES_KEY_SIZE_256 / sizeof(uint32_t); + Context->NumberOfRounds = 14; + + KeyExpansion( Key, Context ); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesEncrypt +// +// Performs an AES encryption of one block (128 bits) with the AesContext initialised with one of the functions +// AesInitialise[n]. Input and Output can point to same memory location, however it is more efficient to use +// AesEncryptInPlace in this situation. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesEncrypt + ( + AesContext const* Context, // [in] + uint8_t const Input [AES_BLOCK_SIZE], // [in] + uint8_t Output [AES_BLOCK_SIZE] // [out] + ) +{ + memcpy( Output, Input, AES_BLOCK_SIZE ); + AesEncryptInPlace( Context, Output ); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesDecrypt +// +// Performs an AES decryption of one block (128 bits) with the AesContext initialised with one of the functions +// AesInitialise[n]. Input and Output can point to same memory location, however it is more efficient to use +// AesDecryptInPlace in this situation. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesDecrypt + ( + AesContext const* Context, // [in] + uint8_t const Input [AES_BLOCK_SIZE], // [in] + uint8_t Output [AES_BLOCK_SIZE] // [out] + ) +{ + memcpy( Output, Input, AES_BLOCK_SIZE); + AesDecryptInPlace(Context, Output ); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesEncryptInPlace +// +// Performs an AES encryption of one block (128 bits) with the AesContext initialised with one of the functions +// AesInitialise[n]. The encryption is performed in place. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesEncryptInPlace + ( + AesContext const* Context, // [in] + uint8_t Block [AES_BLOCK_SIZE] // [in out] + ) +{ + uint32_t round = 0; + + // Add the First round key to the state before starting the rounds. + AddRoundKey( 0, Context, (AesState*)Block ); + + // There will be Nr rounds. + // The first Nr-1 rounds are identical. + // These Nr-1 rounds are executed in the loop below. + for( round=1; roundNumberOfRounds; round++ ) + { + SubBytes( (AesState*)Block ); + ShiftRows( (AesState*)Block ); + MixColumns( (AesState*)Block ); + AddRoundKey( round, Context, (AesState*)Block ); + } + + // The last round is given below. + // The MixColumns function is not here in the last round. + SubBytes( (AesState*)Block); + ShiftRows( (AesState*)Block); + AddRoundKey( Context->NumberOfRounds, Context, (AesState*)Block ); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesDecryptInPlace +// +// Performs an AES decryption of one block (128 bits) with the AesContext initialised with one of the functions +// AesInitialise[n]. The decryption is performed in place. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesDecryptInPlace + ( + AesContext const* Context, // [in] + uint8_t Block [AES_BLOCK_SIZE] // [in out] + ) +{ + uint32_t round = 0; + + // Add the First round key to the state before starting the rounds. + AddRoundKey( Context->NumberOfRounds, Context, (AesState*)Block ); + + // The first NumberOfRounds-1 rounds are identical. + for( round=(Context->NumberOfRounds-1); round>0; round-- ) + { + InvShiftRows( (AesState*)Block ); + InvSubBytes( (AesState*)Block ); + AddRoundKey( round, Context, (AesState*)Block ); + InvMixColumns( (AesState*)Block ); + } + + // The MixColumns function is not here in the last round. + InvShiftRows( (AesState*)Block ); + InvSubBytes( (AesState*)Block ); + AddRoundKey( 0, Context, (AesState*)Block ); +} diff --git a/lib/CryptLib_Aes.h b/lib/CryptLib_Aes.h new file mode 100644 index 0000000..ae8461c --- /dev/null +++ b/lib/CryptLib_Aes.h @@ -0,0 +1,138 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLib_Aes +// +// Implementation of AES block cipher. Originally written by Kokke (https://github.com/kokke). Modified by WaterJuice +// retaining Public Domain license. +// +// AES is a block cipher that operates on 128 bit blocks. Encryption an Decryption routines use an AesContext which +// must be initialised with the key. An AesContext can be initialised with a 128, 192, or 256 bit key. Use the +// AesInitialise[n] functions to initialise the context with the key. Once an AES context is initialised its contents +// are not changed by the encrypting and decrypting functions. A context only needs to be initialised once for any +// given key and the context may be used by the encrypt/decrypt functions in simultaneous threads. +// All operations are performed byte wise and this implementation works in both little and endian processors. +// There are no alignment requirements with the keys and data blocks. +// +// This is free and unencumbered software released into the public domain - November 2017 waterjuice.org +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IMPORTS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TYPES +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define AES_KEY_SIZE_128 16 +#define AES_KEY_SIZE_192 24 +#define AES_KEY_SIZE_256 32 +#define AES_BLOCK_SIZE 16 + +// AesContext - This must be initialised using AesInitialise128, AesInitialise192 or AesInitialise256 +// Do not modify the contents of this structure directly. +typedef struct +{ + uint32_t KeySizeInWords; + uint32_t NumberOfRounds; + uint8_t RoundKey[240]; +} AesContext; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PUBLIC FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesInitialise128 +// +// Initialises an AesContext with a 128 bit key. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesInitialise128 + ( + uint8_t const Key [AES_KEY_SIZE_128], // [in] + AesContext* Context // [out] + ); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesInitialise192 +// +// Initialises an AesContext with a 192 bit key. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesInitialise192 + ( + uint8_t const Key [AES_KEY_SIZE_192], // [in] + AesContext* Context // [out] + ); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesInitialise256 +// +// Initialises an AesContext with a 256 bit key. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesInitialise256 + ( + uint8_t const Key [AES_KEY_SIZE_256], // [in] + AesContext* Context // [out] + ); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesEncrypt +// +// Performs an AES encryption of one block (128 bits) with the AesContext initialised with one of the functions +// AesInitialise[n]. Input and Output can point to same memory location, however it is more efficient to use +// AesEncryptInPlace in this situation. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesEncrypt + ( + AesContext const* Context, // [in] + uint8_t const Input [AES_BLOCK_SIZE], // [in] + uint8_t Output [AES_BLOCK_SIZE] // [out] + ); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesDecrypt +// +// Performs an AES decryption of one block (128 bits) with the AesContext initialised with one of the functions +// AesInitialise[n]. Input and Output can point to same memory location, however it is more efficient to use +// AesDecryptInPlace in this situation. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesDecrypt + ( + AesContext const* Context, // [in] + uint8_t const Input [AES_BLOCK_SIZE], // [in] + uint8_t Output [AES_BLOCK_SIZE] // [out] + ); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesEncryptInPlace +// +// Performs an AES encryption of one block (128 bits) with the AesContext initialised with one of the functions +// AesInitialise[n]. The encryption is performed in place. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesEncryptInPlace + ( + AesContext const* Context, // [in] + uint8_t Block [AES_BLOCK_SIZE] // [in out] + ); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesDecryptInPlace +// +// Performs an AES decryption of one block (128 bits) with the AesContext initialised with one of the functions +// AesInitialise[n]. The decryption is performed in place. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesDecryptInPlace + ( + AesContext const* Context, // [in] + uint8_t Block [AES_BLOCK_SIZE] // [in out] + ); diff --git a/lib/CryptLib_AesCtr.c b/lib/CryptLib_AesCtr.c new file mode 100644 index 0000000..1f1f8e8 --- /dev/null +++ b/lib/CryptLib_AesCtr.c @@ -0,0 +1,283 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLib_AesCtr +// +// Implementation of AES CTR stream cipher. +// +// Depends on: CryptoLib_Aes +// +// AES CTR is a stream cipher using the AES block cipher in counter mode. +// This implementation works on both little and big endian architectures. +// +// This is free and unencumbered software released into the public domain - November 2017 waterjuice.org +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IMPORTS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "CryptLib_AesCtr.h" +#include "CryptLib_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 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CreateCurrentCipherBlock +// +// Takes the IV and the counter in the AesCtrContext and produces the cipher block (CurrentCipherBlock). The cipher +// block is produced by first creating a 128 bit block with the IV as first 64 bits and the CurrentCipherBlockIndex +// stored as the remaining 64bits in Network byte order (Big Endian) +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static +void + CreateCurrentCipherBlock + ( + AesCtrContext* Context // [in out] + ) +{ + // Build block by first copying in the IV + memcpy( Context->CurrentCipherBlock, Context->IV, AES_CTR_IV_SIZE ); + + // Now place in the counter in Big Endian form + STORE64H( Context->CurrentCipherBlockIndex, Context->CurrentCipherBlock + AES_CTR_IV_SIZE ); + + // Perform AES encryption on the block + AesEncryptInPlace( &Context->Aes, Context->CurrentCipherBlock ); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// 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->IV, IV, AES_CTR_IV_SIZE ); + Context->StreamIndex = 0; + Context->CurrentCipherBlockIndex = 0; + + // Generate the first cipher block of the stream. + CreateCurrentCipherBlock( Context ); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesCtrInitialiseWithKey +// +// Initialises an AesCtrContext with an AES Key and an IV. This combines the initialising an AES Context and then +// running AesCtrInitialise. 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 + AesCtrInitialiseWithKey + ( + uint8_t const* Key, // [in] + uint32_t KeySize, // [in] + uint8_t const IV [AES_CTR_IV_SIZE], // [in] + AesCtrContext* Context // [out] + ) +{ + AesContext aes; + + // Initialise AES Context + switch( KeySize ) + { + case AES_KEY_SIZE_128: AesInitialise128( Key, &aes ); break; + case AES_KEY_SIZE_192: AesInitialise192( Key, &aes ); break; + case AES_KEY_SIZE_256: AesInitialise256( Key, &aes ); break; + default: + // Invalid key size + return -1; + } + + // Now set-up AesCtrContext + AesCtrInitialise( &aes, IV, Context ); + return 0; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesCtrSetStreamIndex +// +// Sets the current stream index to any arbitrary position. Setting to 0 sets it to the beginning of the stream. Any +// subsequent output will start from this position +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesCtrSetStreamIndex + ( + AesCtrContext* Context, // [in out] + uint64_t StreamIndex // [in] + ) +{ + uint64_t blockIndex = StreamIndex / AES_BLOCK_SIZE; + + Context->StreamIndex = StreamIndex; + if( blockIndex != Context->CurrentCipherBlockIndex ) + { + // Update block index and generate new cipher block as the new StreamIndex is inside a different block to the + // one we currently had. + Context->CurrentCipherBlockIndex = blockIndex; + CreateCurrentCipherBlock( Context ); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesCtrXor +// +// XORs the stream of byte of the AesCtrContext 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 inplace encrypting/decrypting +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesCtrXor + ( + AesCtrContext* 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->StreamIndex % AES_BLOCK_SIZE); + + // Determine how much of the current block we will take, either all that is available, or less + // if the amount requested is smaller. + chunkSize = MIN( amountAvailableInBlock, amountLeft ); + + // XOR the bytes from the cipher block + XorBuffers( InBuffer, Context->CurrentCipherBlock + (AES_BLOCK_SIZE - amountAvailableInBlock), OutBuffer, chunkSize ); + + amountLeft -= chunkSize; + outputOffset += chunkSize; + + // Now start generating new cipher blocks as required. + while( amountLeft > 0 ) + { + // Increment block index and regenerate cipher block + Context->CurrentCipherBlockIndex += 1; + CreateCurrentCipherBlock( Context ); + + // 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; + } + + // All data read out now, so update index in the context. + Context->StreamIndex += Size; + + // If we ended up completely reading the last cipher block we need to generate a new one for next time. + if( AES_BLOCK_SIZE == chunkSize ) + { + Context->CurrentCipherBlockIndex += 1; + CreateCurrentCipherBlock( Context ); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesCtrOutput +// +// Outputs the stream of byte of the AesCtrContext from its current stream position. This will advance the stream +// index by that number of bytes. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesCtrOutput + ( + AesCtrContext* Context, // [in out] + void* Buffer, // [out] + uint32_t Size // [in] + ) +{ + memset( Buffer, 0, Size ); + AesCtrXor( Context, Buffer, Buffer, Size ); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesCtrXorWithKey +// +// This function combines AesCtrInitialiseWithKey and AesCtrXor. 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 + AesCtrXorWithKey + ( + uint8_t const* Key, // [in] + uint32_t KeySize, // [in] + uint8_t const IV [AES_CTR_IV_SIZE], // [in] + void const* InBuffer, // [in] + void* OutBuffer, // [out] + uint32_t BufferSize // [in] + ) +{ + int error; + AesCtrContext context; + + error = AesCtrInitialiseWithKey( Key, KeySize, IV, &context ); + if( 0 == error ) + { + AesCtrXor( &context, InBuffer, OutBuffer, BufferSize ); + } + + return error; +} diff --git a/lib/CryptLib_AesCtr.h b/lib/CryptLib_AesCtr.h new file mode 100644 index 0000000..9b53db4 --- /dev/null +++ b/lib/CryptLib_AesCtr.h @@ -0,0 +1,140 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLib_AesCtr +// +// Implementation of AES CTR stream cipher. +// +// Depends on: CryptoLib_Aes +// +// AES CTR is a stream cipher using the AES block cipher in counter mode. +// This implementation works on both little and big endian architectures. +// +// This is free and unencumbered software released into the public domain - November 2017 waterjuice.org +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IMPORTS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include "CryptLib_Aes.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TYPES +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define AES_CTR_IV_SIZE 8 + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TYPES +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// AesCtrContext +// Do not modify the contents of this structure directly. +typedef struct +{ + AesContext Aes; + uint8_t IV [AES_CTR_IV_SIZE]; + uint64_t StreamIndex; + uint64_t CurrentCipherBlockIndex; + uint8_t CurrentCipherBlock [AES_BLOCK_SIZE]; +} AesCtrContext; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PUBLIC FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesCtrInitialise +// +// Initialises an AesCtrContext with an already initialised AesContext and a IV. This function can quickly be used +// to change the IV without requiring the more length processes of reinitialising an AES key. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesCtrInitialise + ( + AesContext const* InitialisedAesContext, // [in] + uint8_t const IV [AES_CTR_IV_SIZE], // [in] + AesCtrContext* Context // [out] + ); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesCtrInitialiseWithKey +// +// Initialises an AesCtrContext with an AES Key and an IV. This combines the initialising an AES Context and then +// running AesCtrInitialise. 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 + AesCtrInitialiseWithKey + ( + uint8_t const* Key, // [in] + uint32_t KeySize, // [in] + uint8_t const IV [AES_CTR_IV_SIZE], // [in] + AesCtrContext* Context // [out] + ); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesCtrSetStreamIndex +// +// Sets the current stream index to any arbitrary position. Setting to 0 sets it to the beginning of the stream. Any +// subsequent output will start from this position +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesCtrSetStreamIndex + ( + AesCtrContext* Context, // [in out] + uint64_t StreamIndex // [in] + ); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesCtrXor +// +// XORs the stream of byte of the AesCtrContext 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 inplace encrypting/decrypting +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesCtrXor + ( + AesCtrContext* Context, // [in out] + void const* InBuffer, // [in] + void* OutBuffer, // [out] + uint32_t Size // [in] + ); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesCtrOutput +// +// Outputs the stream of byte of the AesCtrContext from its current stream position. This will advance the stream +// index by that number of bytes. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void + AesCtrOutput + ( + AesCtrContext* Context, // [in out] + void* Buffer, // [out] + uint32_t Size // [in] + ); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesCtrXorWithKey +// +// This function combines AesCtrInitialiseWithKey and AesCtrXor. 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. +// Returns 0 if successful, or -1 if invalid KeySize provided +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +int + AesCtrXorWithKey + ( + uint8_t const* Key, // [in] + uint32_t KeySize, // [in] + uint8_t const IV [AES_CTR_IV_SIZE], // [in] + void const* InBuffer, // [in] + void* OutBuffer, // [out] + uint32_t BufferSize // [in] + ); diff --git a/lib/LibMd5.c b/lib/CryptLib_Md5.c similarity index 85% rename from lib/LibMd5.c rename to lib/CryptLib_Md5.c index 24f712d..86fa98f 100644 --- a/lib/LibMd5.c +++ b/lib/CryptLib_Md5.c @@ -1,65 +1,56 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// LibMd5 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLib_Md5 // // Implementation of MD5 hash function. Originally written by Alexander Peslyak. Modified by WaterJuice retaining // Public Domain license. // // This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#include "LibMd5.h" +#include "CryptLib_Md5.h" #include -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // INTERNAL FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // F, G, H, I // -// The basic MD5 functions. F and G are optimized compared to their RFC 1321 definitions for architectures that lack +// The basic MD5 functions. F and G are optimised compared to their RFC 1321 definitions for architectures that lack // an AND-NOT instruction, just like in Colin Plumb's implementation. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #define F( x, y, z ) ( (z) ^ ((x) & ((y) ^ (z))) ) #define G( x, y, z ) ( (y) ^ ((z) & ((x) ^ (y))) ) #define H( x, y, z ) ( (x) ^ (y) ^ (z) ) #define I( x, y, z ) ( (y) ^ ((x) | ~(z)) ) - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // STEP // // The MD5 transformation for all four rounds. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #define STEP( f, a, b, c, d, x, t, s ) \ (a) += f((b), (c), (d)) + (x) + (t); \ (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ (a) += (b); -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// SET, GET -// -// SET reads 4 input bytes in little-endian byte order and stores them in a properly aligned word in host byte order. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#define SET(n) (*(uint32_t *)&ptr[(n) * 4]) -#define GET(n) SET(n) - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TransformFunction // // This processes one or more 64-byte data blocks, but does NOT update the bit counters. There are no alignment // requirements. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static void* TransformFunction ( Md5Context* ctx, - void* data, + void const* data, uintmax_t size ) { @@ -73,6 +64,13 @@ void* uint32_t saved_c; uint32_t saved_d; + #define GET(n) (ctx->block[(n)]) + #define SET(n) (ctx->block[(n)] = \ + ((uint32_t)ptr[(n)*4 + 0] << 0 ) \ + | ((uint32_t)ptr[(n)*4 + 1] << 8 ) \ + | ((uint32_t)ptr[(n)*4 + 2] << 16) \ + | ((uint32_t)ptr[(n)*4 + 3] << 24) ) + ptr = (uint8_t*)data; a = ctx->a; @@ -172,18 +170,21 @@ void* ctx->c = c; ctx->d = d; + #undef GET + #undef SET + return ptr; } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // EXPORTED FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Md5Initialise // // Initialises an MD5 Context. Use this to initialise/reset a context. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Md5Initialise ( @@ -199,17 +200,17 @@ void Context->hi = 0; } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Md5Update // // Adds data to the MD5 context. This will process the data and update the internal state of the context. Keep on // calling this function until all the data has been added. Then call Md5Finalise to calculate the hash. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Md5Update ( Md5Context* Context, - void* Buffer, + void const* Buffer, uint32_t BufferSize ) { @@ -251,12 +252,12 @@ void memcpy( Context->buffer, Buffer, BufferSize ); } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Md5Finalise // // Performs the final calculation of the hash and returns the digest (16 byte buffer containing 128bit hash). After // calling this, Md5Initialised must be used to reuse the context. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Md5Finalise ( @@ -312,4 +313,3 @@ void Digest->bytes[14] = (uint8_t)( Context->d >> 16 ); Digest->bytes[15] = (uint8_t)( Context->d >> 24 ); } - diff --git a/lib/LibMd5.h b/lib/CryptLib_Md5.h similarity index 71% rename from lib/LibMd5.h rename to lib/CryptLib_Md5.h index 9091432..f14686a 100644 --- a/lib/LibMd5.h +++ b/lib/CryptLib_Md5.h @@ -1,25 +1,24 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// LibMd5 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLib_Md5 // // Implementation of MD5 hash function. Originally written by Alexander Peslyak. Modified by WaterJuice retaining // Public Domain license. // // This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#ifndef _LibMd5_h_ -#define _LibMd5_h_ +#pragma once -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include #include -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TYPES -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Md5Context - This must be initialised using Md5Initialised. Do not modify the contents of this structure directly. typedef struct @@ -41,49 +40,44 @@ typedef struct uint8_t bytes [MD5_HASH_SIZE]; } MD5_HASH; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Md5Initialise // // Initialises an MD5 Context. Use this to initialise/reset a context. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Md5Initialise ( Md5Context* Context ); -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Md5Update // // Adds data to the MD5 context. This will process the data and update the internal state of the context. Keep on // calling this function until all the data has been added. Then call Md5Finalise to calculate the hash. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Md5Update ( Md5Context* Context, - void* Buffer, + void const* Buffer, uint32_t BufferSize ); -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Md5Finalise // // Performs the final calculation of the hash and returns the digest (16 byte buffer containing 128bit hash). After // calling this, Md5Initialised must be used to reuse the context. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Md5Finalise ( Md5Context* Context, MD5_HASH* Digest ); - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#endif //_LibMd5_h_ - diff --git a/lib/LibRc4.c b/lib/CryptLib_Rc4.c similarity index 79% rename from lib/LibRc4.c rename to lib/CryptLib_Rc4.c index 6e3c1f5..3cc41e3 100644 --- a/lib/LibRc4.c +++ b/lib/CryptLib_Rc4.c @@ -1,21 +1,21 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// LibRC4 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLib_RC4 // // An implementation of RC4 stream cipher // // This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#include "LibRc4.h" +#include "CryptLib_Rc4.h" #include -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // INTERNAL FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #define SwapBytes( Value1, Value2 ) \ { \ @@ -24,20 +24,20 @@ Value2 = temp; \ } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Rc4Initialise // // Initialises an RC4 cipher and discards the specified number of first bytes. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Rc4Initialise ( Rc4Context* Context, - void* Key, + void const* Key, uint32_t KeySize, uint32_t DropN ) @@ -74,11 +74,11 @@ void Context->j = j; } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Rc4Output // // Outputs the requested number of bytes from the RC4 stream -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Rc4Output ( @@ -99,17 +99,17 @@ void } } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Rc4Xor // // XORs the RC4 stream with an input buffer and puts the results in an output buffer. This is used for encrypting // and decrypting data. InBuffer and OutBuffer can point to the same location for inplace encrypting/decrypting -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Rc4Xor ( Rc4Context* Context, - void* InBuffer, + void const* InBuffer, void* OutBuffer, uint32_t Size ) @@ -126,4 +126,3 @@ void ^ ( Context->S[ (Context->S[Context->i] + Context->S[Context->j]) % 256 ] ); } } - diff --git a/lib/LibRc4.h b/lib/CryptLib_Rc4.h similarity index 67% rename from lib/LibRc4.h rename to lib/CryptLib_Rc4.h index 578d44b..81ffd32 100644 --- a/lib/LibRc4.h +++ b/lib/CryptLib_Rc4.h @@ -1,23 +1,22 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// LibRC4 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLib_RC4 // // An implementation of RC4 stream cipher // // This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#ifndef _LibRc4_h_ -#define _LibRc4_h_ +#pragma once -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TYPES -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Rc4Context - This must be initialised using Rc4Initialised. Do not modify the contents of this structure directly. typedef struct @@ -27,29 +26,29 @@ typedef struct uint8_t S[256]; } Rc4Context; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Rc4Initialise // // Initialises an RC4 cipher and discards the specified number of first bytes. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Rc4Initialise ( Rc4Context* Context, - void* Key, + void const* Key, uint32_t KeySize, uint32_t DropN ); -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Rc4Output // // Outputs the requested number of bytes from the RC4 stream -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Rc4Output ( @@ -58,21 +57,17 @@ void uint32_t Size ); -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Rc4Xor // // XORs the RC4 stream with an input buffer and puts the results in an output buffer. This is used for encrypting // and decrypting data. InBuffer and OutBuffer can point to the same location for inplace encrypting/decrypting -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Rc4Xor ( Rc4Context* Context, - void* InBuffer, + void const* InBuffer, void* OutBuffer, uint32_t Size ); - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#endif //_LibRc4_h_ - diff --git a/lib/LibSha1.c b/lib/CryptLib_Sha1.c similarity index 66% rename from lib/LibSha1.c rename to lib/CryptLib_Sha1.c index 3d14b42..5c599ee 100644 --- a/lib/LibSha1.c +++ b/lib/CryptLib_Sha1.c @@ -1,5 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// LibSha1 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLib_Sha1 // // Implementation of SHA1 hash function. // Original author: Steve Reid @@ -8,18 +8,33 @@ // Modified by WaterJuice retaining Public Domain license. // // This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#include "LibSha1.h" +#include "CryptLib_Sha1.h" #include -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DEFINES +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// Decide whether to use the Little-Endian shortcut. If the shortcut is not used then the code will work correctly +// on either big or little endian, however if we do know it is a little endian architecture we can speed it up a bit. +// Note, there are TWO places where USE_LITTLE_ENDIAN_SHORTCUT is used. They MUST be paired together. +#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) + // gcc defines __BYTE_ORDER__ so if it says its little endian we can use that. + #define USE_LITTLE_ENDIAN_SHORTCUT +#elif defined( _WIN32 ) + // Windows is always little endian so we can use that. + #define USE_LITTLE_ENDIAN_SHORTCUT +#endif + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TYPES -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// typedef union { @@ -27,18 +42,27 @@ typedef union uint32_t l [16]; } CHAR64LONG16; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // INTERNAL FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// Endian neutral macro for loading 32 bit value from 4 byte array (in big endian form). +#define LOAD32H(x, y) \ + { x = ((uint32_t)((y)[0] & 255)<<24) | \ + ((uint32_t)((y)[1] & 255)<<16) | \ + ((uint32_t)((y)[2] & 255)<<8) | \ + ((uint32_t)((y)[3] & 255)); } #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) // blk0() and blk() perform the initial expand. -#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ - |(rol(block->l[i],8)&0x00FF00FF)) +#ifdef USE_LITTLE_ENDIAN_SHORTCUT + #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) | (rol(block->l[i],8)&0x00FF00FF)) +#else + #define blk0(i) block->l[i] +#endif -#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ - ^block->l[(i+2)&15]^block->l[i&15],1)) +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15] ^ block->l[(i+8)&15] ^ block->l[(i+2)&15] ^ block->l[i&15],1)) // (R0+R1), R2, R3, R4 are the different operations used in SHA1 #define R0(v,w,x,y,z,i) z += ((w&(x^y))^y) + blk0(i)+ 0x5A827999 + rol(v,5); w=rol(w,30); @@ -47,18 +71,32 @@ typedef union #define R3(v,w,x,y,z,i) z += (((w|x)&y)|(w&x)) + blk(i) + 0x8F1BBCDC + rol(v,5); w=rol(w,30); #define R4(v,w,x,y,z,i) z += (w^x^y) + blk(i) + 0xCA62C1D6 + rol(v,5); w=rol(w,30); +// Loads the 128 bits from ByteArray into WordArray, treating ByteArray as big endian data +#ifdef USE_LITTLE_ENDIAN_SHORTCUT + #define Load128BitsAsWords( WordArray, ByteArray ) \ + memcpy( WordArray, ByteArray, 64 ) +#else + #define Load128BitsAsWords( WordArray, ByteArray ) \ + { \ + uint32_t i; \ + for( i=0; i<16; i++ ) \ + { \ + LOAD32H( (WordArray)[i], (ByteArray)+(i*4) ); \ + } \ + } +#endif -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TransformFunction // // Hash a single 512-bit block. This is the core of the algorithm -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static void TransformFunction ( uint32_t state[5], - const uint8_t buffer[64] + uint8_t const buffer[64] ) { uint32_t a; @@ -69,7 +107,7 @@ void uint8_t workspace[64]; CHAR64LONG16* block = (CHAR64LONG16*) workspace; - memcpy( block, buffer, 64 ); + Load128BitsAsWords( block->l, buffer ); // Copy context->state[] to working vars a = state[0]; @@ -108,22 +146,22 @@ void state[4] += e; } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha1Initialise // // Initialises an SHA1 Context. Use this to initialise/reset a context. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha1Initialise ( Sha1Context* Context ) { - // SHA1 initialization constants + // SHA1 initialisation constants Context->State[0] = 0x67452301; Context->State[1] = 0xEFCDAB89; Context->State[2] = 0x98BADCFE; @@ -133,17 +171,17 @@ void Context->Count[1] = 0; } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha1Update // // Adds data to the SHA1 context. This will process the data and update the internal state of the context. Keep on // calling this function until all the data has been added. Then call Sha1Finalise to calculate the hash. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha1Update ( Sha1Context* Context, - void* Buffer, + void const* Buffer, uint32_t BufferSize ) { @@ -176,12 +214,12 @@ void memcpy( &Context->Buffer[j], &((uint8_t*)Buffer)[i], BufferSize - i ); } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha1Finalise // // Performs the final calculation of the hash and returns the digest (20 byte buffer containing 160bit hash). After // calling this, Sha1Initialised must be used to reuse the context. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha1Finalise ( @@ -209,4 +247,3 @@ void Digest->bytes[i] = (uint8_t)((Context->State[i>>2] >> ((3-(i & 3)) * 8) ) & 255); } } - diff --git a/lib/LibSha1.h b/lib/CryptLib_Sha1.h similarity index 72% rename from lib/LibSha1.h rename to lib/CryptLib_Sha1.h index 042859d..7e00089 100644 --- a/lib/LibSha1.h +++ b/lib/CryptLib_Sha1.h @@ -1,5 +1,5 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// LibSha1 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLib_Sha1 // // Implementation of SHA1 hash function. // Original author: Steve Reid @@ -8,21 +8,20 @@ // Modified by WaterJuice retaining Public Domain license. // // This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#ifndef _LibSha1_h_ -#define _LibSha1_h_ +#pragma once -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include #include -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TYPES -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha1Context - This must be initialised using Sha1Initialised. Do not modify the contents of this structure directly. typedef struct @@ -39,48 +38,44 @@ typedef struct uint8_t bytes [SHA1_HASH_SIZE]; } SHA1_HASH; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha1Initialise // // Initialises an SHA1 Context. Use this to initialise/reset a context. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha1Initialise ( Sha1Context* Context ); -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha1Update // // Adds data to the SHA1 context. This will process the data and update the internal state of the context. Keep on // calling this function until all the data has been added. Then call Sha1Finalise to calculate the hash. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha1Update ( Sha1Context* Context, - void* Buffer, + void const* Buffer, uint32_t BufferSize ); -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha1Finalise // // Performs the final calculation of the hash and returns the digest (20 byte buffer containing 160bit hash). After // calling this, Sha1Initialised must be used to reuse the context. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha1Finalise ( Sha1Context* Context, SHA1_HASH* Digest ); - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#endif //_LibSha1_h_ - diff --git a/lib/LibSha256.c b/lib/CryptLib_Sha256.c similarity index 87% rename from lib/LibSha256.c rename to lib/CryptLib_Sha256.c index 4e7ba05..59071d8 100644 --- a/lib/LibSha256.c +++ b/lib/CryptLib_Sha256.c @@ -1,23 +1,23 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// LibSha256 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLib_Sha256 // // Implementation of SHA256 hash function. // Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org // Modified by WaterJuice retaining Public Domain license. // // This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#include "LibSha256.h" +#include "CryptLib_Sha256.h" #include -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // MACROS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #define ror(value, bits) (((value) >> (bits)) | ((value) << (32 - (bits)))) @@ -39,10 +39,9 @@ (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); } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // CONSTANTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // The K array static const uint32_t K[64] = { @@ -63,9 +62,9 @@ static const uint32_t K[64] = { #define BLOCK_SIZE 64 -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // INTERNAL FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Various logical functions #define Ch( x, y, z ) (z ^ (x & (y ^ z))) @@ -83,17 +82,17 @@ static const uint32_t K[64] = { d += t0; \ h = t0 + t1; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TransformFunction // // Compress 512-bits -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static void TransformFunction ( Sha256Context* Context, - uint8_t* Buffer + uint8_t const* Buffer ) { uint32_t S[8]; @@ -143,15 +142,15 @@ void } } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha256Initialise // // Initialises a SHA256 Context. Use this to initialise/reset a context. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha256Initialise ( Sha256Context* Context @@ -169,16 +168,16 @@ void Sha256Initialise Context->state[7] = 0x5BE0CD19UL; } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha256Update // // Adds data to the SHA256 context. This will process the data and update the internal state of the context. Keep on // calling this function until all the data has been added. Then call Sha256Finalise to calculate the hash. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha256Update ( Sha256Context* Context, - void* Buffer, + void const* Buffer, uint32_t BufferSize ) { @@ -215,12 +214,12 @@ void Sha256Update } } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha256Finalise // // Performs the final calculation of the hash and returns the digest (32 byte buffer containing 256bit hash). After // calling this, Sha256Initialised must be used to reuse the context. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha256Finalise ( @@ -270,4 +269,3 @@ void STORE32H( Context->state[i], Digest->bytes+(4*i) ); } } - diff --git a/lib/LibSha256.h b/lib/CryptLib_Sha256.h similarity index 71% rename from lib/LibSha256.h rename to lib/CryptLib_Sha256.h index 84fdc0c..cf7d839 100644 --- a/lib/LibSha256.h +++ b/lib/CryptLib_Sha256.h @@ -1,19 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// LibSha256 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLib_Sha256 // // Implementation of SHA256 hash function. // Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org // Modified by WaterJuice retaining Public Domain license. // // This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#ifndef _LibSha256_h_ -#define _LibSha256_h_ +#pragma once -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include #include @@ -33,46 +32,42 @@ typedef struct uint8_t bytes [SHA256_HASH_SIZE]; } SHA256_HASH; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha256Initialise // // Initialises a SHA256 Context. Use this to initialise/reset a context. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha256Initialise ( Sha256Context* Context ); -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha256Update // // Adds data to the SHA256 context. This will process the data and update the internal state of the context. Keep on // calling this function until all the data has been added. Then call Sha256Finalise to calculate the hash. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha256Update ( Sha256Context* Context, - void* Buffer, + void const* Buffer, uint32_t BufferSize ); -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha256Finalise // // Performs the final calculation of the hash and returns the digest (32 byte buffer containing 256bit hash). After // calling this, Sha256Initialised must be used to reuse the context. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha256Finalise ( Sha256Context* Context, SHA256_HASH* Digest ); - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#endif //_LibSha256_h_ - diff --git a/lib/LibSha512.c b/lib/CryptLib_Sha512.c similarity index 88% rename from lib/LibSha512.c rename to lib/CryptLib_Sha512.c index f16f3bf..e6d8c7e 100644 --- a/lib/LibSha512.c +++ b/lib/CryptLib_Sha512.c @@ -1,23 +1,23 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// LibSha512 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLib_Sha512 // // Implementation of SHA512 hash function. // Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org // Modified by WaterJuice retaining Public Domain license. // // This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#include "LibSha512.h" +#include "CryptLib_Sha512.h" #include -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // MACROS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #define ROR64( value, bits ) (((value) >> (bits)) | ((value) << (64 - (bits)))) @@ -35,10 +35,9 @@ (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); } - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // CONSTANTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // The K array static const uint64_t K[80] = { @@ -66,9 +65,9 @@ static const uint64_t K[80] = { #define BLOCK_SIZE 128 -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // INTERNAL FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Various logical functions #define Ch( x, y, z ) (z ^ (x & (y ^ z))) @@ -86,17 +85,17 @@ static const uint64_t K[80] = { d += t0; \ h = t0 + t1; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TransformFunction // // Compress 1024-bits -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static void TransformFunction ( Sha512Context* Context, - uint8_t* Buffer + uint8_t const* Buffer ) { uint64_t S[8]; @@ -143,16 +142,16 @@ void } } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha512Initialise // // Initialises a SHA512 Context. Use this to initialise/reset a context. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Sha512Initialise ( Sha512Context* Context @@ -170,17 +169,17 @@ void Context->state[7] = 0x5be0cd19137e2179ULL; } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha512Update // // Adds data to the SHA512 context. This will process the data and update the internal state of the context. Keep on // calling this function until all the data has been added. Then call Sha512Finalise to calculate the hash. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha512Update ( Sha512Context* Context, - void* Buffer, + void const* Buffer, uint32_t BufferSize ) { @@ -217,12 +216,12 @@ void } } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha512Finalise // // Performs the final calculation of the hash and returns the digest (64 byte buffer containing 512bit hash). After // calling this, Sha512Initialised must be used to reuse the context. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha512Finalise ( @@ -269,9 +268,8 @@ void TransformFunction( Context, Context->buf ); // Copy output - for( i=0; i<8; i++ ) + for( i=0; i<8; i++ ) { STORE64H( Context->state[i], Digest->bytes+(8*i) ); } } - diff --git a/lib/LibSha512.h b/lib/CryptLib_Sha512.h similarity index 71% rename from lib/LibSha512.h rename to lib/CryptLib_Sha512.h index b379582..5cade5e 100644 --- a/lib/LibSha512.h +++ b/lib/CryptLib_Sha512.h @@ -1,19 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// LibSha512 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLib_Sha512 // // Implementation of SHA512 hash function. // Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org // Modified by WaterJuice retaining Public Domain license. // // This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#ifndef _LibSha512_h_ -#define _LibSha512_h_ +#pragma once -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include #include @@ -33,46 +32,42 @@ typedef struct uint8_t bytes [SHA512_HASH_SIZE]; } SHA512_HASH; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha512Initialise // // Initialises a SHA512 Context. Use this to initialise/reset a context. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha512Initialise ( Sha512Context* Context ); -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha512Update // // Adds data to the SHA512 context. This will process the data and update the internal state of the context. Keep on // calling this function until all the data has been added. Then call Sha512Finalise to calculate the hash. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha512Update ( Sha512Context* Context, - void* Buffer, + void const* Buffer, uint32_t BufferSize ); -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha512Finalise // // Performs the final calculation of the hash and returns the digest (64 byte buffer containing 512bit hash). After // calling this, Sha512Initialised must be used to reuse the context. -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sha512Finalise ( Sha512Context* Context, SHA512_HASH* Digest ); - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#endif //_LibSha512_h_ - diff --git a/makefile b/makefile deleted file mode 100644 index 5ea8d89..0000000 --- a/makefile +++ /dev/null @@ -1,70 +0,0 @@ -OUTDIR = Bin/$(PLATFORM) -INCLUDES = -I ./lib - -all: CryptLibTest Md5String Sha1String Sha256String Sha512String Rc4Output - -CryptLibTest: dir - $(COMPILE) projects/CryptLibTest/CryptLibTest.c lib/LibRc4.c lib/LibMd5.c lib/LibSha1.c lib/LibSha256.c lib/LibSha512.c $(TAIL) - $(STRIP) - -Md5String: dir - $(COMPILE) projects/Md5String/Md5String.c lib/LibMd5.c lib/LibSha1.c lib/LibSha256.c lib/LibSha512.c $(TAIL) - $(STRIP) - -Sha1String: dir - $(COMPILE) projects/Sha1String/Sha1String.c lib/LibSha1.c $(TAIL) - $(STRIP) - -Sha256String: dir - $(COMPILE) projects/Sha256String/Sha256String.c lib/LibSha256.c $(TAIL) - $(STRIP) - -Sha512String: dir - $(COMPILE) projects/Sha512String/Sha512String.c lib/LibSha512.c $(TAIL) - $(STRIP) - -Rc4Output: dir - $(COMPILE) projects/Rc4Output/Rc4Output.c lib/LibRc4.c $(TAIL) - $(STRIP) - -dir: - @mkdir -p $(OUTDIR) - - -###### Setup build parameters ##### -ifeq ($(OS),Windows_NT) - ifdef VSINSTALLDIR - ifeq ($(Platform),X64) - PLATFORM = Windows - else - PLATFORM = WindowsX86 - endif - INTDIR = Build/$(PLATFORM)/$@ - INCLUDES := $(INCLUDES) /I ./stdbool - COMPILE = @echo & echo ::::: Building $(PLATFORM) $@ & mkdir -p $(INTDIR) & cl $(INCLUDES) /nologo /Ox /Oi /Ot /GL /MD /W4 /WX /Fe$(OUTDIR)/$@ /D_CRT_SECURE_NO_WARNINGS /Fo$(INTDIR)/ - TAIL=/link /RELEASE - else ifneq (,$findstring /cygwin/,$(PATH)) - PLATFORM = Cygwin - COMPILE = @echo ::::: Building $(PLATFORM) $@ & gcc $(INCLUDES) -O3 -Wall -Werror -o $(OUTDIR)/$@ - STRIP = @strip $(OUTDIR)/$@ - else - PLATFORM = None - COMPILE = echo - STRIP = - $(error Windows requires VS environment, or Cygwin) - endif -else - PLATFORM = $(shell uname) - ifeq ($(PLATFORM),Darwin) - PLATFORM=OSX - else ifeq ($(PLATFORM),Linux) - PLATFORM=Linux - else - $(error Unsupported platform. Non Windows platform support: OSX and Linux) - endif - COMPILE = @echo ::::: Building $(PLATFORM) $@ & gcc $(INCLUDES) -O3 -Wall -Werror -pthread -o $(OUTDIR)/$@ - STRIP = @strip $(OUTDIR)/$@ - TAIL = -lm -endif - - diff --git a/projects/AesBlock/AesBlock.c b/projects/AesBlock/AesBlock.c new file mode 100644 index 0000000..d8a13ea --- /dev/null +++ b/projects/AesBlock/AesBlock.c @@ -0,0 +1,174 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// AesBlock +// +// Encrypts or Decrypts a single 128 bit block specified on the command line as a hex string. Key is also on +// command line and may be 128, 192, or 256 bits in size. +// +// This is free and unencumbered software released into the public domain - November 2017 waterjuice.org +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IMPORTS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include "CryptLib_Aes.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DEFINES +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef _MSC_VER + #define StringCaseInsensitiveCmp stricmp +#else + #define StringCaseInsensitiveCmp strcasecmp +#endif + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// INTERNAL 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, + uint8_t* Data, + uint32_t* pDataSize + ) +{ + 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; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PUBLIC FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// main +// +// Program entry point +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +int + main + ( + int ArgC, + char** ArgV + ) +{ + uint8_t block [128 / 8] = {0}; + uint32_t blockSize = sizeof( block ); + uint8_t key [256 / 8] = {0}; + uint32_t keySize = sizeof( key ); + uint8_t* bufferPtr; + uint32_t* bufferSizePtr; + uint32_t i; + uint32_t paramIndex = 0; + bool decryptMode = false; + AesContext aesContext; + + if( 4 != ArgC && 3 != ArgC ) + { + printf( + "Syntax\n" + " AesBlock [-D] \n" ); + return 1; + } + + for( i=1; i<(uint32_t)ArgC; i++ ) + { + if( 0 == StringCaseInsensitiveCmp( ArgV[i], "-d" ) ) + { + decryptMode = true; + } + else + { + if ( 0 == paramIndex ) { bufferPtr = key; bufferSizePtr = &keySize; } + else if( 1 == paramIndex ) { bufferPtr = block; bufferSizePtr = &blockSize; } + else + { + printf( "Invalid syntax\n" ); + exit( 1 ); + } + + ReadHexData( ArgV[i], bufferPtr, bufferSizePtr ); + paramIndex += 1; + } + } + + if( 128/8 != blockSize ) + { + printf( "Invalid block size, must be 128 bits (was %u bits)\n", blockSize*8 ); + exit( 1 ); + } + + switch( keySize ) + { + case 128/8: AesInitialise128( key, &aesContext ); break; + case 192/8: AesInitialise192( key, &aesContext ); break; + case 256/8: AesInitialise256( key, &aesContext ); break; + default: + printf( "Invalid key size, must be 128, 192, or 256 bits (was %u bits)\n", keySize*8 ); + exit( 1 ); + } + + if( decryptMode ) + { + AesDecryptInPlace( &aesContext, block ); + } + else + { + AesEncryptInPlace( &aesContext, block ); + } + + // Display + for( i=0; i +#include +#include +#include +#include "CryptLib_AesCtr.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; + AesCtrContext aesCtr = {{0}}; + uint8_t key [AES_KEY_SIZE_256]; + uint32_t keySize = sizeof(key); + uint8_t IV [AES_CTR_IV_SIZE]; + uint32_t IVSize = sizeof(IV); + + if( 4 != ArgC ) + { + printf( + "Syntax\n" + " AesCtrOutput \n" + " - 128, 192, or 256 bit written as hex\n" + " - 64 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_CTR_IV_SIZE != IVSize ) + { + printf( "Invalid IV size. Must be 64 bits\n" ); + return 1; + } + + numBytes = atoi( ArgV[3] ); + + AesCtrInitialiseWithKey( key, keySize, IV, &aesCtr ); + + amountLeft = numBytes; + while( amountLeft > 0 ) + { + chunk = __min( amountLeft, BUFFER_SIZE ); + AesCtrOutput( &aesCtr, buffer, chunk ); + amountLeft -= chunk; + + for( i=0; i #include #include #include #include -#include "LibRc4.h" -#include "LibMd5.h" -#include "LibSha1.h" -#include "LibSha256.h" -#include "LibSha512.h" +#include "CryptLibTest_Aes.h" +#include "CryptLibTest_AesCtr.h" +#include "CryptLibTest_Hashes.h" +#include "CryptLibTest_Rc4.h" -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// TYPES -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -#define MAX_PLAINTEXT_SIZE 100 - -typedef struct -{ - char PlainText [MAX_PLAINTEXT_SIZE]; - int PlainTextSize; // 0 to use (int)strlen - MD5_HASH Md5Hash; - SHA1_HASH Sha1Hash; - SHA256_HASH Sha256Hash; - SHA512_HASH Sha512Hash; -} TestVector; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// GLOBALS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -static TestVector gTestVectors [] = -{ - { - "", 0, - {{0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,0x7e}}, // md5 - {{0xda,0x39,0xa3,0xee,0x5e,0x6b,0x4b,0x0d,0x32,0x55,0xbf,0xef,0x95,0x60,0x18,0x90,0xaf,0xd8,0x07,0x09}}, // sha1 - {{0xe3,0xb0,0xc4,0x42,0x98,0xfc,0x1c,0x14,0x9a,0xfb,0xf4,0xc8,0x99,0x6f,0xb9,0x24, - 0x27,0xae,0x41,0xe4,0x64,0x9b,0x93,0x4c,0xa4,0x95,0x99,0x1b,0x78,0x52,0xb8,0x55}}, // sha256 - {{0xcf,0x83,0xe1,0x35,0x7e,0xef,0xb8,0xbd,0xf1,0x54,0x28,0x50,0xd6,0x6d,0x80,0x07, - 0xd6,0x20,0xe4,0x05,0x0b,0x57,0x15,0xdc,0x83,0xf4,0xa9,0x21,0xd3,0x6c,0xe9,0xce, - 0x47,0xd0,0xd1,0x3c,0x5d,0x85,0xf2,0xb0,0xff,0x83,0x18,0xd2,0x87,0x7e,0xec,0x2f, - 0x63,0xb9,0x31,0xbd,0x47,0x41,0x7a,0x81,0xa5,0x38,0x32,0x7a,0xf9,0x27,0xda,0x3e}}, // sha512 - }, - { - "a", 0, - {{0x0c,0xc1,0x75,0xb9,0xc0,0xf1,0xb6,0xa8,0x31,0xc3,0x99,0xe2,0x69,0x77,0x26,0x61}}, // md5 - {{0x86,0xf7,0xe4,0x37,0xfa,0xa5,0xa7,0xfc,0xe1,0x5d,0x1d,0xdc,0xb9,0xea,0xea,0xea,0x37,0x76,0x67,0xb8}}, // sha1 - {{0xca,0x97,0x81,0x12,0xca,0x1b,0xbd,0xca,0xfa,0xc2,0x31,0xb3,0x9a,0x23,0xdc,0x4d, - 0xa7,0x86,0xef,0xf8,0x14,0x7c,0x4e,0x72,0xb9,0x80,0x77,0x85,0xaf,0xee,0x48,0xbb}}, // sha256 - {{0x1f,0x40,0xfc,0x92,0xda,0x24,0x16,0x94,0x75,0x09,0x79,0xee,0x6c,0xf5,0x82,0xf2, - 0xd5,0xd7,0xd2,0x8e,0x18,0x33,0x5d,0xe0,0x5a,0xbc,0x54,0xd0,0x56,0x0e,0x0f,0x53, - 0x02,0x86,0x0c,0x65,0x2b,0xf0,0x8d,0x56,0x02,0x52,0xaa,0x5e,0x74,0x21,0x05,0x46, - 0xf3,0x69,0xfb,0xbb,0xce,0x8c,0x12,0xcf,0xc7,0x95,0x7b,0x26,0x52,0xfe,0x9a,0x75}}, // sha512 - }, - { - "aaa", 0, - {{0x47,0xbc,0xe5,0xc7,0x4f,0x58,0x9f,0x48,0x67,0xdb,0xd5,0x7e,0x9c,0xa9,0xf8,0x08}}, // md5 - {{0x7e,0x24,0x0d,0xe7,0x4f,0xb1,0xed,0x08,0xfa,0x08,0xd3,0x80,0x63,0xf6,0xa6,0xa9,0x14,0x62,0xa8,0x15}}, // sha1 - {{0x98,0x34,0x87,0x6d,0xcf,0xb0,0x5c,0xb1,0x67,0xa5,0xc2,0x49,0x53,0xeb,0xa5,0x8c, - 0x4a,0xc8,0x9b,0x1a,0xdf,0x57,0xf2,0x8f,0x2f,0x9d,0x09,0xaf,0x10,0x7e,0xe8,0xf0}}, // sha256 - {{0xd6,0xf6,0x44,0xb1,0x98,0x12,0xe9,0x7b,0x5d,0x87,0x16,0x58,0xd6,0xd3,0x40,0x0e, - 0xcd,0x47,0x87,0xfa,0xeb,0x9b,0x89,0x90,0xc1,0xe7,0x60,0x82,0x88,0x66,0x4b,0xe7, - 0x72,0x57,0x10,0x4a,0x58,0xd0,0x33,0xbc,0xf1,0xa0,0xe0,0x94,0x5f,0xf0,0x64,0x68, - 0xeb,0xe5,0x3e,0x2d,0xff,0x36,0xe2,0x48,0x42,0x4c,0x72,0x73,0x11,0x7d,0xac,0x09}}, // sha512 - }, - { - "abc", 0, - {{0x90,0x01,0x50,0x98,0x3c,0xd2,0x4f,0xb0,0xd6,0x96,0x3f,0x7d,0x28,0xe1,0x7f,0x72}}, // md5 - {{0xa9,0x99,0x3e,0x36,0x47,0x06,0x81,0x6a,0xba,0x3e,0x25,0x71,0x78,0x50,0xc2,0x6c,0x9c,0xd0,0xd8,0x9d}}, // sha1 - {{0xba,0x78,0x16,0xbf,0x8f,0x01,0xcf,0xea,0x41,0x41,0x40,0xde,0x5d,0xae,0x22,0x23, - 0xb0,0x03,0x61,0xa3,0x96,0x17,0x7a,0x9c,0xb4,0x10,0xff,0x61,0xf2,0x00,0x15,0xad}}, // sha256 - {{0xdd,0xaf,0x35,0xa1,0x93,0x61,0x7a,0xba,0xcc,0x41,0x73,0x49,0xae,0x20,0x41,0x31, - 0x12,0xe6,0xfa,0x4e,0x89,0xa9,0x7e,0xa2,0x0a,0x9e,0xee,0xe6,0x4b,0x55,0xd3,0x9a, - 0x21,0x92,0x99,0x2a,0x27,0x4f,0xc1,0xa8,0x36,0xba,0x3c,0x23,0xa3,0xfe,0xeb,0xbd, - 0x45,0x4d,0x44,0x23,0x64,0x3c,0xe8,0x0e,0x2a,0x9a,0xc9,0x4f,0xa5,0x4c,0xa4,0x9f}}, // sha512 - }, - { - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 0, - {{0x82,0x15,0xef,0x07,0x96,0xa2,0x0b,0xca,0xaa,0xe1,0x16,0xd3,0x87,0x6c,0x66,0x4a}}, // md5 - {{0x84,0x98,0x3e,0x44,0x1c,0x3b,0xd2,0x6e,0xba,0xae,0x4a,0xa1,0xf9,0x51,0x29,0xe5,0xe5,0x46,0x70,0xf1}}, // sha1 - {{0x24,0x8d,0x6a,0x61,0xd2,0x06,0x38,0xb8,0xe5,0xc0,0x26,0x93,0x0c,0x3e,0x60,0x39, - 0xa3,0x3c,0xe4,0x59,0x64,0xff,0x21,0x67,0xf6,0xec,0xed,0xd4,0x19,0xdb,0x06,0xc1}}, // sha256 - {{0x20,0x4a,0x8f,0xc6,0xdd,0xa8,0x2f,0x0a,0x0c,0xed,0x7b,0xeb,0x8e,0x08,0xa4,0x16, - 0x57,0xc1,0x6e,0xf4,0x68,0xb2,0x28,0xa8,0x27,0x9b,0xe3,0x31,0xa7,0x03,0xc3,0x35, - 0x96,0xfd,0x15,0xc1,0x3b,0x1b,0x07,0xf9,0xaa,0x1d,0x3b,0xea,0x57,0x78,0x9c,0xa0, - 0x31,0xad,0x85,0xc7,0xa7,0x1d,0xd7,0x03,0x54,0xec,0x63,0x12,0x38,0xca,0x34,0x45}}, // sha512 - }, - { - "The quick brown fox jumps over the lazy dog", 0, - {{0x9e,0x10,0x7d,0x9d,0x37,0x2b,0xb6,0x82,0x6b,0xd8,0x1d,0x35,0x42,0xa4,0x19,0xd6}}, // md5 - {{0x2f,0xd4,0xe1,0xc6,0x7a,0x2d,0x28,0xfc,0xed,0x84,0x9e,0xe1,0xbb,0x76,0xe7,0x39,0x1b,0x93,0xeb,0x12}}, // sha1 - {{0xd7,0xa8,0xfb,0xb3,0x07,0xd7,0x80,0x94,0x69,0xca,0x9a,0xbc,0xb0,0x08,0x2e,0x4f, - 0x8d,0x56,0x51,0xe4,0x6d,0x3c,0xdb,0x76,0x2d,0x02,0xd0,0xbf,0x37,0xc9,0xe5,0x92}}, // sha256 - {{0x07,0xe5,0x47,0xd9,0x58,0x6f,0x6a,0x73,0xf7,0x3f,0xba,0xc0,0x43,0x5e,0xd7,0x69, - 0x51,0x21,0x8f,0xb7,0xd0,0xc8,0xd7,0x88,0xa3,0x09,0xd7,0x85,0x43,0x6b,0xbb,0x64, - 0x2e,0x93,0xa2,0x52,0xa9,0x54,0xf2,0x39,0x12,0x54,0x7d,0x1e,0x8a,0x3b,0x5e,0xd6, - 0xe1,0xbf,0xd7,0x09,0x78,0x21,0x23,0x3f,0xa0,0x53,0x8f,0x3d,0xb8,0x54,0xfe,0xe6}}, // sha512 - }, - { - "The quick brown fox jumps over the lazy dog.", 0, - {{0xe4,0xd9,0x09,0xc2,0x90,0xd0,0xfb,0x1c,0xa0,0x68,0xff,0xad,0xdf,0x22,0xcb,0xd0}}, // md5 - {{0x40,0x8d,0x94,0x38,0x42,0x16,0xf8,0x90,0xff,0x7a,0x0c,0x35,0x28,0xe8,0xbe,0xd1,0xe0,0xb0,0x16,0x21}}, // sha1 - {{0xef,0x53,0x7f,0x25,0xc8,0x95,0xbf,0xa7,0x82,0x52,0x65,0x29,0xa9,0xb6,0x3d,0x97, - 0xaa,0x63,0x15,0x64,0xd5,0xd7,0x89,0xc2,0xb7,0x65,0x44,0x8c,0x86,0x35,0xfb,0x6c}}, // sha256 - {{0x91,0xea,0x12,0x45,0xf2,0x0d,0x46,0xae,0x9a,0x03,0x7a,0x98,0x9f,0x54,0xf1,0xf7, - 0x90,0xf0,0xa4,0x76,0x07,0xee,0xb8,0xa1,0x4d,0x12,0x89,0x0c,0xea,0x77,0xa1,0xbb, - 0xc6,0xc7,0xed,0x9c,0xf2,0x05,0xe6,0x7b,0x7f,0x2b,0x8f,0xd4,0xc7,0xdf,0xd3,0xa7, - 0xa8,0x61,0x7e,0x45,0xf3,0xc4,0x63,0xd4,0x81,0xc7,0xe5,0x86,0xc3,0x9a,0xc1,0xed}}, // sha512 - }, - { - "message digest", 0, - {{0xf9,0x6b,0x69,0x7d,0x7c,0xb7,0x93,0x8d,0x52,0x5a,0x2f,0x31,0xaa,0xf1,0x61,0xd0}}, // md5 - {{0xc1,0x22,0x52,0xce,0xda,0x8b,0xe8,0x99,0x4d,0x5f,0xa0,0x29,0x0a,0x47,0x23,0x1c,0x1d,0x16,0xaa,0xe3}}, // sha1 - {{0xf7,0x84,0x6f,0x55,0xcf,0x23,0xe1,0x4e,0xeb,0xea,0xb5,0xb4,0xe1,0x55,0x0c,0xad, - 0x5b,0x50,0x9e,0x33,0x48,0xfb,0xc4,0xef,0xa3,0xa1,0x41,0x3d,0x39,0x3c,0xb6,0x50}}, // sha256 - {{0x10,0x7d,0xbf,0x38,0x9d,0x9e,0x9f,0x71,0xa3,0xa9,0x5f,0x6c,0x05,0x5b,0x92,0x51, - 0xbc,0x52,0x68,0xc2,0xbe,0x16,0xd6,0xc1,0x34,0x92,0xea,0x45,0xb0,0x19,0x9f,0x33, - 0x09,0xe1,0x64,0x55,0xab,0x1e,0x96,0x11,0x8e,0x8a,0x90,0x5d,0x55,0x97,0xb7,0x20, - 0x38,0xdd,0xb3,0x72,0xa8,0x98,0x26,0x04,0x6d,0xe6,0x66,0x87,0xbb,0x42,0x0e,0x7c}}, // sha512 - }, - { - "abcdefghijklmnopqrstuvwxyz", 0, - {{0xc3,0xfc,0xd3,0xd7,0x61,0x92,0xe4,0x00,0x7d,0xfb,0x49,0x6c,0xca,0x67,0xe1,0x3b}}, // md5 - {{0x32,0xd1,0x0c,0x7b,0x8c,0xf9,0x65,0x70,0xca,0x04,0xce,0x37,0xf2,0xa1,0x9d,0x84,0x24,0x0d,0x3a,0x89}}, // sha1 - {{0x71,0xc4,0x80,0xdf,0x93,0xd6,0xae,0x2f,0x1e,0xfa,0xd1,0x44,0x7c,0x66,0xc9,0x52, - 0x5e,0x31,0x62,0x18,0xcf,0x51,0xfc,0x8d,0x9e,0xd8,0x32,0xf2,0xda,0xf1,0x8b,0x73}}, // sha256 - {{0x4d,0xbf,0xf8,0x6c,0xc2,0xca,0x1b,0xae,0x1e,0x16,0x46,0x8a,0x05,0xcb,0x98,0x81, - 0xc9,0x7f,0x17,0x53,0xbc,0xe3,0x61,0x90,0x34,0x89,0x8f,0xaa,0x1a,0xab,0xe4,0x29, - 0x95,0x5a,0x1b,0xf8,0xec,0x48,0x3d,0x74,0x21,0xfe,0x3c,0x16,0x46,0x61,0x3a,0x59, - 0xed,0x54,0x41,0xfb,0x0f,0x32,0x13,0x89,0xf7,0x7f,0x48,0xa8,0x79,0xc7,0xb1,0xf1}}, // sha512 - }, - { - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 0, - {{0xd1,0x74,0xab,0x98,0xd2,0x77,0xd9,0xf5,0xa5,0x61,0x1c,0x2c,0x9f,0x41,0x9d,0x9f}}, // md5 - {{0x76,0x1c,0x45,0x7b,0xf7,0x3b,0x14,0xd2,0x7e,0x9e,0x92,0x65,0xc4,0x6f,0x4b,0x4d,0xda,0x11,0xf9,0x40}}, // sha1 - {{0xdb,0x4b,0xfc,0xbd,0x4d,0xa0,0xcd,0x85,0xa6,0x0c,0x3c,0x37,0xd3,0xfb,0xd8,0x80, - 0x5c,0x77,0xf1,0x5f,0xc6,0xb1,0xfd,0xfe,0x61,0x4e,0xe0,0xa7,0xc8,0xfd,0xb4,0xc0}}, // sha256 - {{0x1e,0x07,0xbe,0x23,0xc2,0x6a,0x86,0xea,0x37,0xea,0x81,0x0c,0x8e,0xc7,0x80,0x93, - 0x52,0x51,0x5a,0x97,0x0e,0x92,0x53,0xc2,0x6f,0x53,0x6c,0xfc,0x7a,0x99,0x96,0xc4, - 0x5c,0x83,0x70,0x58,0x3e,0x0a,0x78,0xfa,0x4a,0x90,0x04,0x1d,0x71,0xa4,0xce,0xab, - 0x74,0x23,0xf1,0x9c,0x71,0xb9,0xd5,0xa3,0xe0,0x12,0x49,0xf0,0xbe,0xbd,0x58,0x94}}, // sha512 - }, - { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 0, - {{0x57,0xed,0xf4,0xa2,0x2b,0xe3,0xc9,0x55,0xac,0x49,0xda,0x2e,0x21,0x07,0xb6,0x7a}}, // md5 - {{0x50,0xab,0xf5,0x70,0x6a,0x15,0x09,0x90,0xa0,0x8b,0x2c,0x5e,0xa4,0x0f,0xa0,0xe5,0x85,0x55,0x47,0x32}}, // sha1 - {{0xf3,0x71,0xbc,0x4a,0x31,0x1f,0x2b,0x00,0x9e,0xef,0x95,0x2d,0xd8,0x3c,0xa8,0x0e, - 0x2b,0x60,0x02,0x6c,0x8e,0x93,0x55,0x92,0xd0,0xf9,0xc3,0x08,0x45,0x3c,0x81,0x3e}}, // sha256 - {{0x72,0xec,0x1e,0xf1,0x12,0x4a,0x45,0xb0,0x47,0xe8,0xb7,0xc7,0x5a,0x93,0x21,0x95, - 0x13,0x5b,0xb6,0x1d,0xe2,0x4e,0xc0,0xd1,0x91,0x40,0x42,0x24,0x6e,0x0a,0xec,0x3a, - 0x23,0x54,0xe0,0x93,0xd7,0x6f,0x30,0x48,0xb4,0x56,0x76,0x43,0x46,0x90,0x0c,0xb1, - 0x30,0xd2,0xa4,0xfd,0x5d,0xd1,0x6a,0xbb,0x5e,0x30,0xbc,0xb8,0x50,0xde,0xe8,0x43}}, // sha512 - }, - -}; -#define NUM_TEST_VECTORS ( sizeof(gTestVectors) / sizeof(gTestVectors[0]) ) - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// PRIVATE FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// TestMd5 -// -// Test MD5 algorithm against test vectors -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static -bool - TestMd5 - ( - void - ) -{ - int i; - int k; - int len; - Md5Context context; - MD5_HASH hash; - bool success = true; - - for( i=0; i +#include +#include +#include +#include +#include "CryptLib_Aes.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TYPES +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define MAX_PLAINTEXT_SIZE 100 + +typedef struct +{ + uint8_t PlainText [16]; + uint8_t Key128 [16]; + uint8_t CipherText128 [16]; + uint8_t Key192 [24]; + uint8_t CipherText192 [16]; + uint8_t Key256 [32]; + uint8_t CipherText256 [16]; +} TestVector; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// GLOBALS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static TestVector gTestVectors [] = +{ + { + { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a }, + { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, + { 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97 }, + { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b }, + { 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f, 0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc }, + { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 }, + { 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c, 0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8 }, + }, + { + { 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 }, + { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, + { 0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf }, + { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b }, + { 0x97, 0x41, 0x04, 0x84, 0x6d, 0x0a, 0xd3, 0xad, 0x77, 0x34, 0xec, 0xb3, 0xec, 0xee, 0x4e, 0xef }, + { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 }, + { 0x59, 0x1c, 0xcb, 0x10, 0xd4, 0x10, 0xed, 0x26, 0xdc, 0x5b, 0xa7, 0x4a, 0x31, 0x36, 0x28, 0x70 }, + }, + { + { 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef }, + { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, + { 0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88 }, + { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b }, + { 0xef, 0x7a, 0xfd, 0x22, 0x70, 0xe2, 0xe6, 0x0a, 0xdc, 0xe0, 0xba, 0x2f, 0xac, 0xe6, 0x44, 0x4e }, + { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 }, + { 0xb6, 0xed, 0x21, 0xb9, 0x9c, 0xa6, 0xf4, 0xf9, 0xf1, 0x53, 0xe7, 0xb1, 0xbe, 0xaf, 0xed, 0x1d }, + }, + { + { 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }, + { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, + { 0x7b, 0x0c, 0x78, 0x5e, 0x27, 0xe8, 0xad, 0x3f, 0x82, 0x23, 0x20, 0x71, 0x04, 0x72, 0x5d, 0xd4 }, + { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b }, + { 0x9a, 0x4b, 0x41, 0xba, 0x73, 0x8d, 0x6c, 0x72, 0xfb, 0x16, 0x69, 0x16, 0x03, 0xc1, 0x8e, 0x0e }, + { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 }, + { 0x23, 0x30, 0x4b, 0x7a, 0x39, 0xf9, 0xf3, 0xff, 0x06, 0x7d, 0x8d, 0x8f, 0x9e, 0x24, 0xec, 0xc7 }, + }, +}; + +#define NUM_TEST_VECTORS ( sizeof(gTestVectors) / sizeof(gTestVectors[0]) ) + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// EXPORTED FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TestAes +// +// Test AES algorithm against test vectors +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool + TestAes + ( + void + ) +{ + uint32_t i; + AesContext context; + bool success = true; + uint8_t decBlock128 [16]; + uint8_t encBlock128 [16]; + uint8_t decBlock192 [16]; + uint8_t encBlock192 [16]; + uint8_t decBlock256 [16]; + uint8_t encBlock256 [16]; + + for( i=0; i + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// EXPORTED FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TestAes +// +// Test AES algorithm against test vectors +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool + TestAes + ( + void + ); diff --git a/projects/CryptLibTest/CryptLibTest_AesCtr.c b/projects/CryptLibTest/CryptLibTest_AesCtr.c new file mode 100644 index 0000000..5847a72 --- /dev/null +++ b/projects/CryptLibTest/CryptLibTest_AesCtr.c @@ -0,0 +1,306 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLibTest_AesCtr +// +// Tests the cryptography functions against known test vectors to verify algorithms are correct. +// Tests the following: +// AES CTR +// +// This is free and unencumbered software released into the public domain - November 2017 waterjuice.org +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IMPORTS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include "CryptLib_AesCtr.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: +// > openssl enc -aes-128-ctr -K 00000000000000000000000000000000 -iv 0000000000000000 -in zero.bin -out output0.bin +// > openssl enc -aes-128-ctr -K 0102030405060708a1a2a3a4a5a6a7a8 -iv 0000000000000000 -in zero.bin -out output1.bin +// > openssl enc -aes-128-ctr -K 00000000000000000000000000000000 -iv b1b2b3b4b5b6b7b8 -in zero.bin -out output2.bin +// > openssl enc -aes-128-ctr -K 0102030405060708a1a2a3a4a5a6a7a8 -iv b1b2b3b4b5b6b7b8 -in zero.bin -out output3.bin +// > openssl enc -aes-192-ctr -K 0102030405060708a1a2a3a4a5a6a7a8b1b2b3b4b5b6b7b8 -iv c1c2c3c4c5c6c7c8 -in zero.bin -out output4.bin +// > openssl enc -aes-256-ctr -K 0102030405060708a1a2a3a4a5a6a7a8b1b2b3b4b5b6b7b8c1c2c3c4c5c6c7c8 -iv d1d2d3d4d5d6d7d8 -in zero.bin -out output5.bin +// Where zero.bin is a file containing 48 zero bytes. +static TestVector gTestVectors [] = +{ + { + "00000000000000000000000000000000", + "0000000000000000", + "66e94bd4ef8a2c3b884cfa59ca342b2e58e2fccefa7e3061367f1d57a4e7455a0388dace60b6a392f328c2b971b2fe78" + }, + { + "0102030405060708a1a2a3a4a5a6a7a8", + "0000000000000000", + "cdb33c236caa155b28d14e6db350537141fa2f4eafecf40a986f83229c7e74d30a981d4547b3c802ea215ed55a858a08" + }, + { + "00000000000000000000000000000000", + "b1b2b3b4b5b6b7b8", + "5ddcedba6a63f96e2b0429ee1a4459fc85e7e624ab33b89fdc4e88c034d483273568e033c96ad8a0bf5b420f4b43600d" + }, + { + "0102030405060708a1a2a3a4a5a6a7a8", + "b1b2b3b4b5b6b7b8", + "7f1e34c4f33ee8dc162af7fbed6f317aa5806d244dd86557268be2296708ef7327aa4e5ed5780a3c070209ea2db04d79" + }, + { + "0102030405060708a1a2a3a4a5a6a7a8b1b2b3b4b5b6b7b8", + "c1c2c3c4c5c6c7c8", + "8bd0847cad4f66dec6abeadcc85d1e0a62ab64931e16f1e8ccb6212c5cea3672c27d4cfd74b3e87ee2d787cc93f24496" + }, + { + "0102030405060708a1a2a3a4a5a6a7a8b1b2b3b4b5b6b7b8c1c2c3c4c5c6c7c8", + "d1d2d3d4d5d6d7d8", + "1419da0fdac1f19ec0eb64af657201c672ab0df425d3faec3b67d70c86d5f780a222b63dbbc71ae7749417449dc39bfb" + }, +}; + +#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 ) + { + uint32_t thisChunkSize = MIN( chunkSize, amountLeft ); + + // Set stream position to +8 where it currently is, this will mean half the time it will have to + // reset the internal block. We are going to ignore this position and bring it back straight away, + // we just want to verify that it can handle being moved around. + AesCtrSetStreamIndex( &context, offset+8 ); + + // Set stream pointer to correct place and output the chunk + AesCtrSetStreamIndex( &context, offset ); + AesCtrOutput( &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 CTR Stream not consistent\n" ); + success = false; + break; + } + } + + #undef STREAMSIZE + + return success; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TestEndianCorrectness +// +// Verifies that endianess is handled correctly. This will force the internal block counter to be a large number +// that uses multiple bytes, and then checks the final output. +// This should return correctly regardless of big or little endian processor. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static +bool + TestEndianCorrectness + ( + void + ) +{ + AesCtrContext context; + uint8_t const key [AES_KEY_SIZE_128] = { 1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4 }; + uint8_t const iv [AES_CTR_IV_SIZE] = { 5,5,5,5,6,6,6,6 }; + uint64_t const positionIndex = 0x1020304050607080ULL; + uint8_t output [256 / 8] = {0}; + uint8_t const vector [256 / 8] = + { 0x17, 0x07, 0x27, 0x7b, 0x9e, 0x51, 0xdf, 0x5b, + 0x23, 0xbe, 0xa1, 0xce, 0xc9, 0x40, 0x49, 0xfc, + 0xf8, 0x8f, 0x45, 0xd1, 0xf6, 0x68, 0x28, 0x54, + 0x6f, 0xef, 0xce, 0xf9, 0x23, 0x1b, 0xb0, 0x08 }; + + AesCtrInitialiseWithKey( key, sizeof(key), iv, &context ); + AesCtrSetStreamIndex( &context, positionIndex ); + AesCtrOutput( &context, output, sizeof(output) ); + + if( 0 != memcmp( vector, output, sizeof(vector) ) ) + { + printf( "Fail on endianness test\n" ); + return false; + } + + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PUBLIC FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TestAesCtr +// +// Test AES CTR algorithm +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool + TestAesCtr + ( + void + ) +{ + bool totalSuccess = true; + bool success; + + success = TestVectors( ); + if( !success ) { totalSuccess = false; } + + success = TestStreamConsistency( ); + if( !success ) { totalSuccess = false; } + + success = TestEndianCorrectness( ); + if( !success ) { totalSuccess = false; } + + return totalSuccess; +} diff --git a/projects/CryptLibTest/CryptLibTest_AesCtr.h b/projects/CryptLibTest/CryptLibTest_AesCtr.h new file mode 100644 index 0000000..c994add --- /dev/null +++ b/projects/CryptLibTest/CryptLibTest_AesCtr.h @@ -0,0 +1,30 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLibTest_AesCtr +// +// Tests the cryptography functions against known test vectors to verify algorithms are correct. +// Tests the following: +// AES CTR +// +// This is free and unencumbered software released into the public domain - November 2017 waterjuice.org +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IMPORTS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// EXPORTED FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TestAesCtr +// +// Test AES CTR algorithm +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool + TestAesCtr + ( + void + ); \ No newline at end of file diff --git a/projects/CryptLibTest/CryptLibTest_Hashes.c b/projects/CryptLibTest/CryptLibTest_Hashes.c new file mode 100644 index 0000000..9184e23 --- /dev/null +++ b/projects/CryptLibTest/CryptLibTest_Hashes.c @@ -0,0 +1,462 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLibTest_Hashes +// +// Tests the hash functions against known test vectors to verify algorithms are correct. +// Tests the following: +// MD5 +// SHA1 +// SHA256 +// SHA512 +// +// This is free and unencumbered software released into the public domain - June 2013 waterjuice.org +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IMPORTS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include "CryptLib_Md5.h" +#include "CryptLib_Sha1.h" +#include "CryptLib_Sha256.h" +#include "CryptLib_Sha512.h" +#include "CryptLibTest_Aes.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TYPES +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define MAX_PLAINTEXT_SIZE 100 + +typedef struct +{ + char PlainText [MAX_PLAINTEXT_SIZE]; + uint32_t PlainTextSize; // 0 to use (uint32_t)strlen + MD5_HASH Md5Hash; + SHA1_HASH Sha1Hash; + SHA256_HASH Sha256Hash; + SHA512_HASH Sha512Hash; +} TestVector; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// GLOBALS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static TestVector gTestVectors [] = +{ + { + "", 0, + {{0xd4,0x1d,0x8c,0xd9,0x8f,0x00,0xb2,0x04,0xe9,0x80,0x09,0x98,0xec,0xf8,0x42,0x7e}}, // md5 + {{0xda,0x39,0xa3,0xee,0x5e,0x6b,0x4b,0x0d,0x32,0x55,0xbf,0xef,0x95,0x60,0x18,0x90,0xaf,0xd8,0x07,0x09}}, // sha1 + {{0xe3,0xb0,0xc4,0x42,0x98,0xfc,0x1c,0x14,0x9a,0xfb,0xf4,0xc8,0x99,0x6f,0xb9,0x24, + 0x27,0xae,0x41,0xe4,0x64,0x9b,0x93,0x4c,0xa4,0x95,0x99,0x1b,0x78,0x52,0xb8,0x55}}, // sha256 + {{0xcf,0x83,0xe1,0x35,0x7e,0xef,0xb8,0xbd,0xf1,0x54,0x28,0x50,0xd6,0x6d,0x80,0x07, + 0xd6,0x20,0xe4,0x05,0x0b,0x57,0x15,0xdc,0x83,0xf4,0xa9,0x21,0xd3,0x6c,0xe9,0xce, + 0x47,0xd0,0xd1,0x3c,0x5d,0x85,0xf2,0xb0,0xff,0x83,0x18,0xd2,0x87,0x7e,0xec,0x2f, + 0x63,0xb9,0x31,0xbd,0x47,0x41,0x7a,0x81,0xa5,0x38,0x32,0x7a,0xf9,0x27,0xda,0x3e}}, // sha512 + }, + { + "a", 0, + {{0x0c,0xc1,0x75,0xb9,0xc0,0xf1,0xb6,0xa8,0x31,0xc3,0x99,0xe2,0x69,0x77,0x26,0x61}}, // md5 + {{0x86,0xf7,0xe4,0x37,0xfa,0xa5,0xa7,0xfc,0xe1,0x5d,0x1d,0xdc,0xb9,0xea,0xea,0xea,0x37,0x76,0x67,0xb8}}, // sha1 + {{0xca,0x97,0x81,0x12,0xca,0x1b,0xbd,0xca,0xfa,0xc2,0x31,0xb3,0x9a,0x23,0xdc,0x4d, + 0xa7,0x86,0xef,0xf8,0x14,0x7c,0x4e,0x72,0xb9,0x80,0x77,0x85,0xaf,0xee,0x48,0xbb}}, // sha256 + {{0x1f,0x40,0xfc,0x92,0xda,0x24,0x16,0x94,0x75,0x09,0x79,0xee,0x6c,0xf5,0x82,0xf2, + 0xd5,0xd7,0xd2,0x8e,0x18,0x33,0x5d,0xe0,0x5a,0xbc,0x54,0xd0,0x56,0x0e,0x0f,0x53, + 0x02,0x86,0x0c,0x65,0x2b,0xf0,0x8d,0x56,0x02,0x52,0xaa,0x5e,0x74,0x21,0x05,0x46, + 0xf3,0x69,0xfb,0xbb,0xce,0x8c,0x12,0xcf,0xc7,0x95,0x7b,0x26,0x52,0xfe,0x9a,0x75}}, // sha512 + }, + { + "aaa", 0, + {{0x47,0xbc,0xe5,0xc7,0x4f,0x58,0x9f,0x48,0x67,0xdb,0xd5,0x7e,0x9c,0xa9,0xf8,0x08}}, // md5 + {{0x7e,0x24,0x0d,0xe7,0x4f,0xb1,0xed,0x08,0xfa,0x08,0xd3,0x80,0x63,0xf6,0xa6,0xa9,0x14,0x62,0xa8,0x15}}, // sha1 + {{0x98,0x34,0x87,0x6d,0xcf,0xb0,0x5c,0xb1,0x67,0xa5,0xc2,0x49,0x53,0xeb,0xa5,0x8c, + 0x4a,0xc8,0x9b,0x1a,0xdf,0x57,0xf2,0x8f,0x2f,0x9d,0x09,0xaf,0x10,0x7e,0xe8,0xf0}}, // sha256 + {{0xd6,0xf6,0x44,0xb1,0x98,0x12,0xe9,0x7b,0x5d,0x87,0x16,0x58,0xd6,0xd3,0x40,0x0e, + 0xcd,0x47,0x87,0xfa,0xeb,0x9b,0x89,0x90,0xc1,0xe7,0x60,0x82,0x88,0x66,0x4b,0xe7, + 0x72,0x57,0x10,0x4a,0x58,0xd0,0x33,0xbc,0xf1,0xa0,0xe0,0x94,0x5f,0xf0,0x64,0x68, + 0xeb,0xe5,0x3e,0x2d,0xff,0x36,0xe2,0x48,0x42,0x4c,0x72,0x73,0x11,0x7d,0xac,0x09}}, // sha512 + }, + { + "abc", 0, + {{0x90,0x01,0x50,0x98,0x3c,0xd2,0x4f,0xb0,0xd6,0x96,0x3f,0x7d,0x28,0xe1,0x7f,0x72}}, // md5 + {{0xa9,0x99,0x3e,0x36,0x47,0x06,0x81,0x6a,0xba,0x3e,0x25,0x71,0x78,0x50,0xc2,0x6c,0x9c,0xd0,0xd8,0x9d}}, // sha1 + {{0xba,0x78,0x16,0xbf,0x8f,0x01,0xcf,0xea,0x41,0x41,0x40,0xde,0x5d,0xae,0x22,0x23, + 0xb0,0x03,0x61,0xa3,0x96,0x17,0x7a,0x9c,0xb4,0x10,0xff,0x61,0xf2,0x00,0x15,0xad}}, // sha256 + {{0xdd,0xaf,0x35,0xa1,0x93,0x61,0x7a,0xba,0xcc,0x41,0x73,0x49,0xae,0x20,0x41,0x31, + 0x12,0xe6,0xfa,0x4e,0x89,0xa9,0x7e,0xa2,0x0a,0x9e,0xee,0xe6,0x4b,0x55,0xd3,0x9a, + 0x21,0x92,0x99,0x2a,0x27,0x4f,0xc1,0xa8,0x36,0xba,0x3c,0x23,0xa3,0xfe,0xeb,0xbd, + 0x45,0x4d,0x44,0x23,0x64,0x3c,0xe8,0x0e,0x2a,0x9a,0xc9,0x4f,0xa5,0x4c,0xa4,0x9f}}, // sha512 + }, + { + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 0, + {{0x82,0x15,0xef,0x07,0x96,0xa2,0x0b,0xca,0xaa,0xe1,0x16,0xd3,0x87,0x6c,0x66,0x4a}}, // md5 + {{0x84,0x98,0x3e,0x44,0x1c,0x3b,0xd2,0x6e,0xba,0xae,0x4a,0xa1,0xf9,0x51,0x29,0xe5,0xe5,0x46,0x70,0xf1}}, // sha1 + {{0x24,0x8d,0x6a,0x61,0xd2,0x06,0x38,0xb8,0xe5,0xc0,0x26,0x93,0x0c,0x3e,0x60,0x39, + 0xa3,0x3c,0xe4,0x59,0x64,0xff,0x21,0x67,0xf6,0xec,0xed,0xd4,0x19,0xdb,0x06,0xc1}}, // sha256 + {{0x20,0x4a,0x8f,0xc6,0xdd,0xa8,0x2f,0x0a,0x0c,0xed,0x7b,0xeb,0x8e,0x08,0xa4,0x16, + 0x57,0xc1,0x6e,0xf4,0x68,0xb2,0x28,0xa8,0x27,0x9b,0xe3,0x31,0xa7,0x03,0xc3,0x35, + 0x96,0xfd,0x15,0xc1,0x3b,0x1b,0x07,0xf9,0xaa,0x1d,0x3b,0xea,0x57,0x78,0x9c,0xa0, + 0x31,0xad,0x85,0xc7,0xa7,0x1d,0xd7,0x03,0x54,0xec,0x63,0x12,0x38,0xca,0x34,0x45}}, // sha512 + }, + { + "The quick brown fox jumps over the lazy dog", 0, + {{0x9e,0x10,0x7d,0x9d,0x37,0x2b,0xb6,0x82,0x6b,0xd8,0x1d,0x35,0x42,0xa4,0x19,0xd6}}, // md5 + {{0x2f,0xd4,0xe1,0xc6,0x7a,0x2d,0x28,0xfc,0xed,0x84,0x9e,0xe1,0xbb,0x76,0xe7,0x39,0x1b,0x93,0xeb,0x12}}, // sha1 + {{0xd7,0xa8,0xfb,0xb3,0x07,0xd7,0x80,0x94,0x69,0xca,0x9a,0xbc,0xb0,0x08,0x2e,0x4f, + 0x8d,0x56,0x51,0xe4,0x6d,0x3c,0xdb,0x76,0x2d,0x02,0xd0,0xbf,0x37,0xc9,0xe5,0x92}}, // sha256 + {{0x07,0xe5,0x47,0xd9,0x58,0x6f,0x6a,0x73,0xf7,0x3f,0xba,0xc0,0x43,0x5e,0xd7,0x69, + 0x51,0x21,0x8f,0xb7,0xd0,0xc8,0xd7,0x88,0xa3,0x09,0xd7,0x85,0x43,0x6b,0xbb,0x64, + 0x2e,0x93,0xa2,0x52,0xa9,0x54,0xf2,0x39,0x12,0x54,0x7d,0x1e,0x8a,0x3b,0x5e,0xd6, + 0xe1,0xbf,0xd7,0x09,0x78,0x21,0x23,0x3f,0xa0,0x53,0x8f,0x3d,0xb8,0x54,0xfe,0xe6}}, // sha512 + }, + { + "The quick brown fox jumps over the lazy dog.", 0, + {{0xe4,0xd9,0x09,0xc2,0x90,0xd0,0xfb,0x1c,0xa0,0x68,0xff,0xad,0xdf,0x22,0xcb,0xd0}}, // md5 + {{0x40,0x8d,0x94,0x38,0x42,0x16,0xf8,0x90,0xff,0x7a,0x0c,0x35,0x28,0xe8,0xbe,0xd1,0xe0,0xb0,0x16,0x21}}, // sha1 + {{0xef,0x53,0x7f,0x25,0xc8,0x95,0xbf,0xa7,0x82,0x52,0x65,0x29,0xa9,0xb6,0x3d,0x97, + 0xaa,0x63,0x15,0x64,0xd5,0xd7,0x89,0xc2,0xb7,0x65,0x44,0x8c,0x86,0x35,0xfb,0x6c}}, // sha256 + {{0x91,0xea,0x12,0x45,0xf2,0x0d,0x46,0xae,0x9a,0x03,0x7a,0x98,0x9f,0x54,0xf1,0xf7, + 0x90,0xf0,0xa4,0x76,0x07,0xee,0xb8,0xa1,0x4d,0x12,0x89,0x0c,0xea,0x77,0xa1,0xbb, + 0xc6,0xc7,0xed,0x9c,0xf2,0x05,0xe6,0x7b,0x7f,0x2b,0x8f,0xd4,0xc7,0xdf,0xd3,0xa7, + 0xa8,0x61,0x7e,0x45,0xf3,0xc4,0x63,0xd4,0x81,0xc7,0xe5,0x86,0xc3,0x9a,0xc1,0xed}}, // sha512 + }, + { + "message digest", 0, + {{0xf9,0x6b,0x69,0x7d,0x7c,0xb7,0x93,0x8d,0x52,0x5a,0x2f,0x31,0xaa,0xf1,0x61,0xd0}}, // md5 + {{0xc1,0x22,0x52,0xce,0xda,0x8b,0xe8,0x99,0x4d,0x5f,0xa0,0x29,0x0a,0x47,0x23,0x1c,0x1d,0x16,0xaa,0xe3}}, // sha1 + {{0xf7,0x84,0x6f,0x55,0xcf,0x23,0xe1,0x4e,0xeb,0xea,0xb5,0xb4,0xe1,0x55,0x0c,0xad, + 0x5b,0x50,0x9e,0x33,0x48,0xfb,0xc4,0xef,0xa3,0xa1,0x41,0x3d,0x39,0x3c,0xb6,0x50}}, // sha256 + {{0x10,0x7d,0xbf,0x38,0x9d,0x9e,0x9f,0x71,0xa3,0xa9,0x5f,0x6c,0x05,0x5b,0x92,0x51, + 0xbc,0x52,0x68,0xc2,0xbe,0x16,0xd6,0xc1,0x34,0x92,0xea,0x45,0xb0,0x19,0x9f,0x33, + 0x09,0xe1,0x64,0x55,0xab,0x1e,0x96,0x11,0x8e,0x8a,0x90,0x5d,0x55,0x97,0xb7,0x20, + 0x38,0xdd,0xb3,0x72,0xa8,0x98,0x26,0x04,0x6d,0xe6,0x66,0x87,0xbb,0x42,0x0e,0x7c}}, // sha512 + }, + { + "abcdefghijklmnopqrstuvwxyz", 0, + {{0xc3,0xfc,0xd3,0xd7,0x61,0x92,0xe4,0x00,0x7d,0xfb,0x49,0x6c,0xca,0x67,0xe1,0x3b}}, // md5 + {{0x32,0xd1,0x0c,0x7b,0x8c,0xf9,0x65,0x70,0xca,0x04,0xce,0x37,0xf2,0xa1,0x9d,0x84,0x24,0x0d,0x3a,0x89}}, // sha1 + {{0x71,0xc4,0x80,0xdf,0x93,0xd6,0xae,0x2f,0x1e,0xfa,0xd1,0x44,0x7c,0x66,0xc9,0x52, + 0x5e,0x31,0x62,0x18,0xcf,0x51,0xfc,0x8d,0x9e,0xd8,0x32,0xf2,0xda,0xf1,0x8b,0x73}}, // sha256 + {{0x4d,0xbf,0xf8,0x6c,0xc2,0xca,0x1b,0xae,0x1e,0x16,0x46,0x8a,0x05,0xcb,0x98,0x81, + 0xc9,0x7f,0x17,0x53,0xbc,0xe3,0x61,0x90,0x34,0x89,0x8f,0xaa,0x1a,0xab,0xe4,0x29, + 0x95,0x5a,0x1b,0xf8,0xec,0x48,0x3d,0x74,0x21,0xfe,0x3c,0x16,0x46,0x61,0x3a,0x59, + 0xed,0x54,0x41,0xfb,0x0f,0x32,0x13,0x89,0xf7,0x7f,0x48,0xa8,0x79,0xc7,0xb1,0xf1}}, // sha512 + }, + { + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 0, + {{0xd1,0x74,0xab,0x98,0xd2,0x77,0xd9,0xf5,0xa5,0x61,0x1c,0x2c,0x9f,0x41,0x9d,0x9f}}, // md5 + {{0x76,0x1c,0x45,0x7b,0xf7,0x3b,0x14,0xd2,0x7e,0x9e,0x92,0x65,0xc4,0x6f,0x4b,0x4d,0xda,0x11,0xf9,0x40}}, // sha1 + {{0xdb,0x4b,0xfc,0xbd,0x4d,0xa0,0xcd,0x85,0xa6,0x0c,0x3c,0x37,0xd3,0xfb,0xd8,0x80, + 0x5c,0x77,0xf1,0x5f,0xc6,0xb1,0xfd,0xfe,0x61,0x4e,0xe0,0xa7,0xc8,0xfd,0xb4,0xc0}}, // sha256 + {{0x1e,0x07,0xbe,0x23,0xc2,0x6a,0x86,0xea,0x37,0xea,0x81,0x0c,0x8e,0xc7,0x80,0x93, + 0x52,0x51,0x5a,0x97,0x0e,0x92,0x53,0xc2,0x6f,0x53,0x6c,0xfc,0x7a,0x99,0x96,0xc4, + 0x5c,0x83,0x70,0x58,0x3e,0x0a,0x78,0xfa,0x4a,0x90,0x04,0x1d,0x71,0xa4,0xce,0xab, + 0x74,0x23,0xf1,0x9c,0x71,0xb9,0xd5,0xa3,0xe0,0x12,0x49,0xf0,0xbe,0xbd,0x58,0x94}}, // sha512 + }, + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 0, + {{0x57,0xed,0xf4,0xa2,0x2b,0xe3,0xc9,0x55,0xac,0x49,0xda,0x2e,0x21,0x07,0xb6,0x7a}}, // md5 + {{0x50,0xab,0xf5,0x70,0x6a,0x15,0x09,0x90,0xa0,0x8b,0x2c,0x5e,0xa4,0x0f,0xa0,0xe5,0x85,0x55,0x47,0x32}}, // sha1 + {{0xf3,0x71,0xbc,0x4a,0x31,0x1f,0x2b,0x00,0x9e,0xef,0x95,0x2d,0xd8,0x3c,0xa8,0x0e, + 0x2b,0x60,0x02,0x6c,0x8e,0x93,0x55,0x92,0xd0,0xf9,0xc3,0x08,0x45,0x3c,0x81,0x3e}}, // sha256 + {{0x72,0xec,0x1e,0xf1,0x12,0x4a,0x45,0xb0,0x47,0xe8,0xb7,0xc7,0x5a,0x93,0x21,0x95, + 0x13,0x5b,0xb6,0x1d,0xe2,0x4e,0xc0,0xd1,0x91,0x40,0x42,0x24,0x6e,0x0a,0xec,0x3a, + 0x23,0x54,0xe0,0x93,0xd7,0x6f,0x30,0x48,0xb4,0x56,0x76,0x43,0x46,0x90,0x0c,0xb1, + 0x30,0xd2,0xa4,0xfd,0x5d,0xd1,0x6a,0xbb,0x5e,0x30,0xbc,0xb8,0x50,0xde,0xe8,0x43}}, // sha512 + }, + +}; +#define NUM_TEST_VECTORS ( sizeof(gTestVectors) / sizeof(gTestVectors[0]) ) + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PRIVATE FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TestMd5 +// +// Test MD5 algorithm against test vectors +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static +bool + TestMd5 + ( + void + ) +{ + uint32_t i; + uint32_t k; + uint32_t len; + Md5Context context; + MD5_HASH hash; + bool success = true; + + for( i=0; i + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PUBLIC FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TestHashes +// +// Test Hash functions algorithm against test vectors +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool + TestHashes + ( + void + ); diff --git a/projects/CryptLibTest/CryptLibTest_Rc4.c b/projects/CryptLibTest/CryptLibTest_Rc4.c new file mode 100644 index 0000000..0c0b598 --- /dev/null +++ b/projects/CryptLibTest/CryptLibTest_Rc4.c @@ -0,0 +1,84 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CryptLibTest_Rc4 +// +// Tests the RC4 function against known test vectors to verify algorithms are correct. +// +// This is free and unencumbered software released into the public domain - June 2013 waterjuice.org +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IMPORTS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include "CryptLib_Rc4.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PUBLIC FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TestRc4 +// +// Test RC4 algorithm against test vectors +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool + TestRc4 + ( + void + ) +{ + struct + { + char Key [100]; + uint32_t Drop; + uint8_t Output [16]; + } TestVectors [] = + { + { "Key", 0, {0xeb,0x9f,0x77,0x81,0xb7,0x34,0xca,0x72,0xa7,0x19,0x4a,0x28,0x67,0xb6,0x42,0x95} }, + { "Wiki", 0, {0x60,0x44,0xdb,0x6d,0x41,0xb7,0xe8,0xe7,0xa4,0xd6,0xf9,0xfb,0xd4,0x42,0x83,0x54} }, + { "Secret", 0, {0x04,0xd4,0x6b,0x05,0x3c,0xa8,0x7b,0x59,0x41,0x72,0x30,0x2a,0xec,0x9b,0xb9,0x92} }, + { "Key", 1, {0x9f,0x77,0x81,0xb7,0x34,0xca,0x72,0xa7,0x19,0x4a,0x28,0x67,0xb6,0x42,0x95,0x0d} }, + { "Key", 256, {0x92,0xfd,0xd9,0xb6,0xe4,0x04,0xef,0x4f,0xa0,0x75,0xf1,0xa3,0x44,0xed,0x81,0x6b} }, + }; + + Rc4Context context; + uint8_t output [16]; + uint32_t i; + bool success = true; + + for( i=0; i<(sizeof(TestVectors)/sizeof(TestVectors[0])); i++ ) + { + Rc4Initialise( &context, TestVectors[i].Key, (uint8_t)strlen(TestVectors[i].Key), TestVectors[i].Drop ); + Rc4Output( &context, output, sizeof(output) ); + if( memcmp( output, TestVectors[i].Output, sizeof(output) ) != 0 ) + { + printf( "TestRc4 - Failed test vector: %u\n", i ); + success = false; + } + } + + // Test by doing drop manually + for( i=0; i<(sizeof(TestVectors)/sizeof(TestVectors[0])); i++ ) + { + uint32_t x; + + Rc4Initialise( &context, TestVectors[i].Key, (uint8_t)strlen(TestVectors[i].Key), 0 ); + for( x=0; x + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PUBLIC FUNCTIONS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TestRc4 +// +// Test RC4 algorithm against test vectors +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool + TestRc4 + ( + void + ); diff --git a/projects/Md5String/CMakeLists.txt b/projects/Md5String/CMakeLists.txt new file mode 100644 index 0000000..5dc8e48 --- /dev/null +++ b/projects/Md5String/CMakeLists.txt @@ -0,0 +1,8 @@ +SET( MODULE_NAME Md5String ) + +add_executable( ${MODULE_NAME} + Md5String.c ) +target_link_libraries( ${MODULE_NAME} + CryptLib ) + +install(TARGETS ${MODULE_NAME} DESTINATION .) diff --git a/projects/Md5String/Md5String.c b/projects/Md5String/Md5String.c index 55830ce..ddc50d1 100644 --- a/projects/Md5String/Md5String.c +++ b/projects/Md5String/Md5String.c @@ -1,30 +1,30 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Md5String // // Outputs MD5 hash of a string specified on command line. Hash is output in hex // // This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include #include #include #include -#include "LibMd5.h" +#include "CryptLib_Md5.h" -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // main // // Program entry point -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int main ( @@ -59,4 +59,3 @@ int return 0; } - diff --git a/projects/Rc4Output/CMakeLists.txt b/projects/Rc4Output/CMakeLists.txt new file mode 100644 index 0000000..db64f48 --- /dev/null +++ b/projects/Rc4Output/CMakeLists.txt @@ -0,0 +1,7 @@ +add_executable( Rc4Output + Rc4Output.c ) +target_link_libraries( Rc4Output + CryptLib ) + +install(TARGETS Rc4Output DESTINATION .) + diff --git a/projects/Rc4Output/Rc4Output.c b/projects/Rc4Output/Rc4Output.c index 979d562..04884c6 100644 --- a/projects/Rc4Output/Rc4Output.c +++ b/projects/Rc4Output/Rc4Output.c @@ -1,44 +1,44 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Rc4String // // Outputs bytes from an RC4 stream. Key is taken from command line. Bytes are output as hex // // This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include #include #include #include -#include "LibRc4.h" +#include "CryptLib_Rc4.h" -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // DEFINITIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef __min #define __min( x, y ) (((x) < (y))?(x):(y)) #endif -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // CONSTANTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #define BUFFER_SIZE 1024 -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // main // // Program entry point -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int main ( @@ -72,7 +72,6 @@ int Rc4Initialise( &rc4, string, (uint32_t)strlen(string), dropN ); - amountLeft = numBytes; while( amountLeft > 0 ) { @@ -90,4 +89,3 @@ int return 0; } - diff --git a/projects/Sha1String/CMakeLists.txt b/projects/Sha1String/CMakeLists.txt new file mode 100644 index 0000000..ef8d5ac --- /dev/null +++ b/projects/Sha1String/CMakeLists.txt @@ -0,0 +1,7 @@ +add_executable( Sha1String + Sha1String.c ) +target_link_libraries( Sha1String + CryptLib ) + +install(TARGETS Sha1String DESTINATION .) + diff --git a/projects/Sha1String/Sha1String.c b/projects/Sha1String/Sha1String.c index c5fbd35..4c16f2c 100644 --- a/projects/Sha1String/Sha1String.c +++ b/projects/Sha1String/Sha1String.c @@ -1,30 +1,30 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha1String // // Outputs SHA1 hash of a string specified on command line. Hash is output in hex // // This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include #include #include #include -#include "LibSha1.h" +#include "CryptLib_Sha1.h" -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // main // // Program entry point -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int main ( @@ -59,4 +59,3 @@ int return 0; } - diff --git a/projects/Sha256String/CMakeLists.txt b/projects/Sha256String/CMakeLists.txt new file mode 100644 index 0000000..6c1af99 --- /dev/null +++ b/projects/Sha256String/CMakeLists.txt @@ -0,0 +1,6 @@ +add_executable( Sha256String + Sha256String.c ) +target_link_libraries( Sha256String + CryptLib ) + +install(TARGETS Sha256String DESTINATION .) diff --git a/projects/Sha256String/Sha256String.c b/projects/Sha256String/Sha256String.c index e53c16e..984fd2f 100644 --- a/projects/Sha256String/Sha256String.c +++ b/projects/Sha256String/Sha256String.c @@ -1,30 +1,30 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha256String // // Outputs SHA256 hash of a string specified on command line. Hash is output in hex // // This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include #include #include #include -#include "LibSha256.h" +#include "CryptLib_Sha256.h" -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // main // // Program entry point -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int main ( @@ -59,4 +59,3 @@ int return 0; } - diff --git a/projects/Sha512String/CMakeLists.txt b/projects/Sha512String/CMakeLists.txt new file mode 100644 index 0000000..e70d881 --- /dev/null +++ b/projects/Sha512String/CMakeLists.txt @@ -0,0 +1,7 @@ +add_executable( Sha512String + Sha512String.c ) +target_link_libraries( Sha512String + CryptLib ) + +install(TARGETS Sha512String DESTINATION .) + diff --git a/projects/Sha512String/Sha512String.c b/projects/Sha512String/Sha512String.c index eb9b89f..ba602ed 100644 --- a/projects/Sha512String/Sha512String.c +++ b/projects/Sha512String/Sha512String.c @@ -1,30 +1,30 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Sha512String // // Outputs SHA512 hash of a string specified on command line. Hash is output in hex // // This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // IMPORTS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include #include #include #include -#include "LibSha512.h" +#include "CryptLib_Sha512.h" -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FUNCTIONS -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // main // // Program entry point -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int main ( @@ -59,4 +59,3 @@ int return 0; } - diff --git a/stdbool/stdbool.h b/stdbool/stdbool.h deleted file mode 100644 index 3f367c8..0000000 --- a/stdbool/stdbool.h +++ /dev/null @@ -1,27 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// -// stdbool.h is part of the C99 standard. Unforunately MSVC compiler does not support C99. Although it has several -// types such as stdint.h, it does not include stdbool.h. This file defines the type bool and values true and false -// according to the C99 standard. This only needs to be included on systems such as MSVC that do not have stdbool.h -// gcc has its own version of stdbool.h that should be used in preference. -// -// This is free and unencumbered software released into the public domain - June 2013 waterjuice.org -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -#ifndef _STDBOOL_H_ -#define _STDBOOL_H_ - -#ifndef __cplusplus -#ifndef __bool_true_false_are_defined - -typedef int bool; -#define true 1 -#define false 0 - -#define __bool_true_false_are_defined - -#endif //__bool_true_false_are_defined -#endif //__cplusplus - -#endif //_STDBOOL_H_