OSDN Git Service

Some code refactoring + improved command-line front-end.
authorLoRd_MuldeR <mulder2@gmx.de>
Mon, 12 Oct 2020 21:10:47 +0000 (23:10 +0200)
committerLoRd_MuldeR <mulder2@gmx.de>
Sat, 20 Mar 2021 20:18:00 +0000 (21:18 +0100)
MCrypt.sln
frontend/MCrypt.vcxproj [moved from MCrypt.vcxproj with 82% similarity]
frontend/MCrypt.vcxproj.filters [moved from MCrypt.vcxproj.filters with 100% similarity]
frontend/src/main.c [new file with mode: 0644]
libMCrypt/include/mcrypt.h
libMCrypt/libMCrypt.vcxproj
libMCrypt/src/mcrypt.c
src/main.c [deleted file]

index 726e043..8793d78 100644 (file)
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio Version 16
 VisualStudioVersion = 16.0.30523.141
 MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MCrypt", "MCrypt.vcxproj", "{86D28793-713E-4CEC-9686-335514AC5EF0}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MCrypt", "frontend\MCrypt.vcxproj", "{86D28793-713E-4CEC-9686-335514AC5EF0}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libMCrypt", "libMCrypt\libMCrypt.vcxproj", "{A4A3879C-BD2C-4304-AF66-7349CEF7E4C0}"
 EndProject
similarity index 82%
rename from MCrypt.vcxproj
rename to frontend/MCrypt.vcxproj
index 3323d60..0914b60 100644 (file)
@@ -22,7 +22,7 @@
     <ClCompile Include="src\main.c" />
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="libMCrypt\libMCrypt.vcxproj">
+    <ProjectReference Include="..\libMCrypt\libMCrypt.vcxproj">
       <Project>{a4a3879c-bd2c-4304-af66-7349cef7e4c0}</Project>
     </ProjectReference>
   </ItemGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v141_xp</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v141_xp</PlatformToolset>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v141_xp</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v141_xp</PlatformToolset>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <LinkIncremental>true</LinkIncremental>
     <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\</IntDir>
+    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LinkIncremental>false</LinkIncremental>
     <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\</IntDir>
+    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <LinkIncremental>true</LinkIncremental>
     <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\</IntDir>
+    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <LinkIncremental>false</LinkIncremental>
     <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\</IntDir>
+    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <WarningLevel>Level3</WarningLevel>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <SDLCheck>true</SDLCheck>
       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ConformanceMode>true</ConformanceMode>
       <AdditionalIncludeDirectories>$(SolutionDir)libMCrypt\include</AdditionalIncludeDirectories>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <WholeProgramOptimization>true</WholeProgramOptimization>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
       <WarningLevel>Level3</WarningLevel>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <SDLCheck>true</SDLCheck>
       <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ConformanceMode>true</ConformanceMode>
       <AdditionalIncludeDirectories>$(SolutionDir)libMCrypt\include</AdditionalIncludeDirectories>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <WholeProgramOptimization>true</WholeProgramOptimization>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
diff --git a/frontend/src/main.c b/frontend/src/main.c
new file mode 100644 (file)
index 0000000..734c70d
--- /dev/null
@@ -0,0 +1,488 @@
+/******************************************************************************/
+/* MCrypt, by LoRd_MuldeR <MuldeR2@GMX.de>                                    */
+/* This work has been released under the CC0 1.0 Universal license!           */
+/******************************************************************************/
+
+#define WIN32_LEAN_AND_MEAN 1
+#define _CRT_SECURE_NO_WARNINGS 1
+
+#include <mcrypt.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <Windows.h>
+
+static const uint64_t CRC64_TAB[256] =
+{
+       0x0000000000000000ULL,  0x42f0e1eba9ea3693ULL,
+       0x85e1c3d753d46d26ULL,  0xc711223cfa3e5bb5ULL,
+       0x493366450e42ecdfULL,  0x0bc387aea7a8da4cULL,
+       0xccd2a5925d9681f9ULL,  0x8e224479f47cb76aULL,
+       0x9266cc8a1c85d9beULL,  0xd0962d61b56fef2dULL,
+       0x17870f5d4f51b498ULL,  0x5577eeb6e6bb820bULL,
+       0xdb55aacf12c73561ULL,  0x99a54b24bb2d03f2ULL,
+       0x5eb4691841135847ULL,  0x1c4488f3e8f96ed4ULL,
+       0x663d78ff90e185efULL,  0x24cd9914390bb37cULL,
+       0xe3dcbb28c335e8c9ULL,  0xa12c5ac36adfde5aULL,
+       0x2f0e1eba9ea36930ULL,  0x6dfeff5137495fa3ULL,
+       0xaaefdd6dcd770416ULL,  0xe81f3c86649d3285ULL,
+       0xf45bb4758c645c51ULL,  0xb6ab559e258e6ac2ULL,
+       0x71ba77a2dfb03177ULL,  0x334a9649765a07e4ULL,
+       0xbd68d2308226b08eULL,  0xff9833db2bcc861dULL,
+       0x388911e7d1f2dda8ULL,  0x7a79f00c7818eb3bULL,
+       0xcc7af1ff21c30bdeULL,  0x8e8a101488293d4dULL,
+       0x499b3228721766f8ULL,  0x0b6bd3c3dbfd506bULL,
+       0x854997ba2f81e701ULL,  0xc7b97651866bd192ULL,
+       0x00a8546d7c558a27ULL,  0x4258b586d5bfbcb4ULL,
+       0x5e1c3d753d46d260ULL,  0x1cecdc9e94ace4f3ULL,
+       0xdbfdfea26e92bf46ULL,  0x990d1f49c77889d5ULL,
+       0x172f5b3033043ebfULL,  0x55dfbadb9aee082cULL,
+       0x92ce98e760d05399ULL,  0xd03e790cc93a650aULL,
+       0xaa478900b1228e31ULL,  0xe8b768eb18c8b8a2ULL,
+       0x2fa64ad7e2f6e317ULL,  0x6d56ab3c4b1cd584ULL,
+       0xe374ef45bf6062eeULL,  0xa1840eae168a547dULL,
+       0x66952c92ecb40fc8ULL,  0x2465cd79455e395bULL,
+       0x3821458aada7578fULL,  0x7ad1a461044d611cULL,
+       0xbdc0865dfe733aa9ULL,  0xff3067b657990c3aULL,
+       0x711223cfa3e5bb50ULL,  0x33e2c2240a0f8dc3ULL,
+       0xf4f3e018f031d676ULL,  0xb60301f359dbe0e5ULL,
+       0xda050215ea6c212fULL,  0x98f5e3fe438617bcULL,
+       0x5fe4c1c2b9b84c09ULL,  0x1d14202910527a9aULL,
+       0x93366450e42ecdf0ULL,  0xd1c685bb4dc4fb63ULL,
+       0x16d7a787b7faa0d6ULL,  0x5427466c1e109645ULL,
+       0x4863ce9ff6e9f891ULL,  0x0a932f745f03ce02ULL,
+       0xcd820d48a53d95b7ULL,  0x8f72eca30cd7a324ULL,
+       0x0150a8daf8ab144eULL,  0x43a04931514122ddULL,
+       0x84b16b0dab7f7968ULL,  0xc6418ae602954ffbULL,
+       0xbc387aea7a8da4c0ULL,  0xfec89b01d3679253ULL,
+       0x39d9b93d2959c9e6ULL,  0x7b2958d680b3ff75ULL,
+       0xf50b1caf74cf481fULL,  0xb7fbfd44dd257e8cULL,
+       0x70eadf78271b2539ULL,  0x321a3e938ef113aaULL,
+       0x2e5eb66066087d7eULL,  0x6cae578bcfe24bedULL,
+       0xabbf75b735dc1058ULL,  0xe94f945c9c3626cbULL,
+       0x676dd025684a91a1ULL,  0x259d31cec1a0a732ULL,
+       0xe28c13f23b9efc87ULL,  0xa07cf2199274ca14ULL,
+       0x167ff3eacbaf2af1ULL,  0x548f120162451c62ULL,
+       0x939e303d987b47d7ULL,  0xd16ed1d631917144ULL,
+       0x5f4c95afc5edc62eULL,  0x1dbc74446c07f0bdULL,
+       0xdaad56789639ab08ULL,  0x985db7933fd39d9bULL,
+       0x84193f60d72af34fULL,  0xc6e9de8b7ec0c5dcULL,
+       0x01f8fcb784fe9e69ULL,  0x43081d5c2d14a8faULL,
+       0xcd2a5925d9681f90ULL,  0x8fdab8ce70822903ULL,
+       0x48cb9af28abc72b6ULL,  0x0a3b7b1923564425ULL,
+       0x70428b155b4eaf1eULL,  0x32b26afef2a4998dULL,
+       0xf5a348c2089ac238ULL,  0xb753a929a170f4abULL,
+       0x3971ed50550c43c1ULL,  0x7b810cbbfce67552ULL,
+       0xbc902e8706d82ee7ULL,  0xfe60cf6caf321874ULL,
+       0xe224479f47cb76a0ULL,  0xa0d4a674ee214033ULL,
+       0x67c58448141f1b86ULL,  0x253565a3bdf52d15ULL,
+       0xab1721da49899a7fULL,  0xe9e7c031e063acecULL,
+       0x2ef6e20d1a5df759ULL,  0x6c0603e6b3b7c1caULL,
+       0xf6fae5c07d3274cdULL,  0xb40a042bd4d8425eULL,
+       0x731b26172ee619ebULL,  0x31ebc7fc870c2f78ULL,
+       0xbfc9838573709812ULL,  0xfd39626eda9aae81ULL,
+       0x3a28405220a4f534ULL,  0x78d8a1b9894ec3a7ULL,
+       0x649c294a61b7ad73ULL,  0x266cc8a1c85d9be0ULL,
+       0xe17dea9d3263c055ULL,  0xa38d0b769b89f6c6ULL,
+       0x2daf4f0f6ff541acULL,  0x6f5faee4c61f773fULL,
+       0xa84e8cd83c212c8aULL,  0xeabe6d3395cb1a19ULL,
+       0x90c79d3fedd3f122ULL,  0xd2377cd44439c7b1ULL,
+       0x15265ee8be079c04ULL,  0x57d6bf0317edaa97ULL,
+       0xd9f4fb7ae3911dfdULL,  0x9b041a914a7b2b6eULL,
+       0x5c1538adb04570dbULL,  0x1ee5d94619af4648ULL,
+       0x02a151b5f156289cULL,  0x4051b05e58bc1e0fULL,
+       0x87409262a28245baULL,  0xc5b073890b687329ULL,
+       0x4b9237f0ff14c443ULL,  0x0962d61b56fef2d0ULL,
+       0xce73f427acc0a965ULL,  0x8c8315cc052a9ff6ULL,
+       0x3a80143f5cf17f13ULL,  0x7870f5d4f51b4980ULL,
+       0xbf61d7e80f251235ULL,  0xfd913603a6cf24a6ULL,
+       0x73b3727a52b393ccULL,  0x31439391fb59a55fULL,
+       0xf652b1ad0167feeaULL,  0xb4a25046a88dc879ULL,
+       0xa8e6d8b54074a6adULL,  0xea16395ee99e903eULL,
+       0x2d071b6213a0cb8bULL,  0x6ff7fa89ba4afd18ULL,
+       0xe1d5bef04e364a72ULL,  0xa3255f1be7dc7ce1ULL,
+       0x64347d271de22754ULL,  0x26c49cccb40811c7ULL,
+       0x5cbd6cc0cc10fafcULL,  0x1e4d8d2b65facc6fULL,
+       0xd95caf179fc497daULL,  0x9bac4efc362ea149ULL,
+       0x158e0a85c2521623ULL,  0x577eeb6e6bb820b0ULL,
+       0x906fc95291867b05ULL,  0xd29f28b9386c4d96ULL,
+       0xcedba04ad0952342ULL,  0x8c2b41a1797f15d1ULL,
+       0x4b3a639d83414e64ULL,  0x09ca82762aab78f7ULL,
+       0x87e8c60fded7cf9dULL,  0xc51827e4773df90eULL,
+       0x020905d88d03a2bbULL,  0x40f9e43324e99428ULL,
+       0x2cffe7d5975e55e2ULL,  0x6e0f063e3eb46371ULL,
+       0xa91e2402c48a38c4ULL,  0xebeec5e96d600e57ULL,
+       0x65cc8190991cb93dULL,  0x273c607b30f68faeULL,
+       0xe02d4247cac8d41bULL,  0xa2dda3ac6322e288ULL,
+       0xbe992b5f8bdb8c5cULL,  0xfc69cab42231bacfULL,
+       0x3b78e888d80fe17aULL,  0x7988096371e5d7e9ULL,
+       0xf7aa4d1a85996083ULL,  0xb55aacf12c735610ULL,
+       0x724b8ecdd64d0da5ULL,  0x30bb6f267fa73b36ULL,
+       0x4ac29f2a07bfd00dULL,  0x08327ec1ae55e69eULL,
+       0xcf235cfd546bbd2bULL,  0x8dd3bd16fd818bb8ULL,
+       0x03f1f96f09fd3cd2ULL,  0x41011884a0170a41ULL,
+       0x86103ab85a2951f4ULL,  0xc4e0db53f3c36767ULL,
+       0xd8a453a01b3a09b3ULL,  0x9a54b24bb2d03f20ULL,
+       0x5d45907748ee6495ULL,  0x1fb5719ce1045206ULL,
+       0x919735e51578e56cULL,  0xd367d40ebc92d3ffULL,
+       0x1476f63246ac884aULL,  0x568617d9ef46bed9ULL,
+       0xe085162ab69d5e3cULL,  0xa275f7c11f7768afULL,
+       0x6564d5fde549331aULL,  0x279434164ca30589ULL,
+       0xa9b6706fb8dfb2e3ULL,  0xeb46918411358470ULL,
+       0x2c57b3b8eb0bdfc5ULL,  0x6ea7525342e1e956ULL,
+       0x72e3daa0aa188782ULL,  0x30133b4b03f2b111ULL,
+       0xf7021977f9cceaa4ULL,  0xb5f2f89c5026dc37ULL,
+       0x3bd0bce5a45a6b5dULL,  0x79205d0e0db05dceULL,
+       0xbe317f32f78e067bULL,  0xfcc19ed95e6430e8ULL,
+       0x86b86ed5267cdbd3ULL,  0xc4488f3e8f96ed40ULL,
+       0x0359ad0275a8b6f5ULL,  0x41a94ce9dc428066ULL,
+       0xcf8b0890283e370cULL,  0x8d7be97b81d4019fULL,
+       0x4a6acb477bea5a2aULL,  0x089a2aacd2006cb9ULL,
+       0x14dea25f3af9026dULL,  0x562e43b4931334feULL,
+       0x913f6188692d6f4bULL,  0xd3cf8063c0c759d8ULL,
+       0x5dedc41a34bbeeb2ULL,  0x1f1d25f19d51d821ULL,
+       0xd80c07cd676f8394ULL,  0x9afce626ce85b507ULL,
+};
+
+
+static char* utf16_to_bytes(const wchar_t* const input, const UINT code_page)
+{
+       char* buffer;
+       DWORD buffer_size = 0U, result = 0U;
+
+       buffer_size = WideCharToMultiByte(code_page, 0, input, -1, NULL, 0, NULL, NULL);
+       if (buffer_size < 1U)
+       {
+               return NULL;
+       }
+
+       buffer = (char*)malloc(sizeof(char) * buffer_size);
+       if (!buffer)
+       {
+               return NULL;
+       }
+
+       result = WideCharToMultiByte(code_page, 0, input, -1, (LPSTR)buffer, buffer_size, NULL, NULL);
+       if ((result > 0U) && (result <= buffer_size))
+       {
+               return buffer;
+       }
+
+       free(buffer);
+       return NULL;
+}
+
+static void print_string(const char *const text, const size_t length)
+{
+       fputc('"', stderr);
+       for (size_t i = 0; i < length; ++i)
+       {
+               fputc((text[i] >= 0x20) ? text[i] : '?', stderr);
+       }
+       fputs("\"\n\n", stderr);
+}
+
+static int encrypt(const wchar_t* const passphrase, const wchar_t* const input, const wchar_t* const output)
+{
+       char* passphrase_utf8 = utf16_to_bytes(passphrase, CP_UTF8);
+       if (!passphrase_utf8)
+       {
+               fputws(L"Error: Failed to convert passphrase to UTF-8 format!\n\n", stderr);
+               return 1;
+       }
+
+       FILE *fin = _wfopen(input, L"rb");
+       if (!fin)
+       {
+               fputws(L"Error: Failed to open input file!\n\n", stderr);
+               free(passphrase_utf8);
+               return 1;
+       }
+
+       FILE* fout = _wfopen(output, L"wb");
+       if (!fout)
+       {
+               fputws(L"Error: Failed to open output file!\n\n", stderr);
+               fclose(fin);
+               free(passphrase_utf8);
+               return 1;
+       }
+
+       uint64_t seed;
+       if (mcrypt_generate_seed(&seed) != 0)
+       {
+               fputws(L"MCrypt error: Failed to generate seed!\n\n", stderr);
+               fclose(fout);
+               fclose(fin);
+               free(passphrase_utf8);
+               return 1;
+       }
+
+       if (fwrite(&seed, sizeof(uint64_t), 1U, fout) < 1U)
+       {
+               fputws(L"I/O error: Failed to write encrypted data!\n\n", stderr);
+               fclose(fout);
+               fclose(fin);
+               free(passphrase_utf8);
+               return 1;
+       }
+
+       const mcrypt_t ctx = mcrypt_init(seed, passphrase_utf8);
+       if (!ctx)
+       {
+               fputws(L"MCrypt error: Failed to initialize encryption!\n\n", stderr);
+               fclose(fout);
+               fclose(fin);
+               free(passphrase_utf8);
+               return 1;
+       }
+
+       fputws(L"Encrypting, please be patient... ", stderr);
+
+       uint8_t buffer[1024U];
+       uint64_t crc_actual = ~0U;
+
+       while (!feof(fin))
+       {
+               const size_t count = fread(buffer, sizeof(uint8_t), 1024U, fin);
+               if (ferror(fin))
+               {
+                       fputws(L"failed!\n\nI/O error: Failed to read input data!\n\n", stderr);
+                       mcrypt_free(ctx);
+                       fclose(fout);
+                       fclose(fin);
+                       free(passphrase_utf8);
+                       return 1;
+               }
+               if (count > 0U)
+               {
+                       for (size_t i = 0U; i < count; ++i)
+                       {
+                               crc_actual = CRC64_TAB[((crc_actual >> 56) ^ buffer[i]) & 0xFF] ^ (crc_actual << 8);
+                       }
+                       if (mcrypt_enc_process_inplace(ctx, buffer, count) != 0)
+                       {
+                               fputws(L"failed!\n\nMCrypt error: Failed to encrypt data!\n\n", stderr);
+                               mcrypt_free(ctx);
+                               fclose(fout);
+                               fclose(fin);
+                               free(passphrase_utf8);
+                               return 1;
+                       }
+                       if (fwrite(buffer, sizeof(uint8_t), count, fout) < count)
+                       {
+                               fputws(L"failed!\n\nI/O error: Failed to write encrypted data!\n\n", stderr);
+                               mcrypt_free(ctx);
+                               fclose(fout);
+                               fclose(fin);
+                               free(passphrase_utf8);
+                               return 1;
+                       }
+               }
+       }
+
+       crc_actual ^= ~0U;
+
+       if (fwrite(&crc_actual, sizeof(uint64_t), 1U, fout) < 1U)
+       {
+               fputws(L"failed!\n\nI/O error: Failed to write CRC checksum!\n\n", stderr);
+               mcrypt_free(ctx);
+               fclose(fout);
+               fclose(fin);
+               free(passphrase_utf8);
+               return 1;
+       }
+
+       fputws(L"done.\n\n", stderr);
+
+       mcrypt_free(ctx);
+       fclose(fout);
+       fclose(fin);
+       free(passphrase_utf8);
+       return 0;
+}
+
+static int decrypt(const wchar_t* const passphrase, const wchar_t* const input, const wchar_t* const output)
+{
+       char* passphrase_utf8 = utf16_to_bytes(passphrase, CP_UTF8);
+       if (!passphrase_utf8)
+       {
+               fputws(L"Error: Failed to convert passphrase to UTF-8 format!\n\n", stderr);
+               return 1;
+       }
+
+       FILE* fin = _wfopen(input, L"rb");
+       if (!fin)
+       {
+               fputws(L"Error: Failed to open input file!\n\n", stderr);
+               free(passphrase_utf8);
+               return 1;
+       }
+
+       FILE* fout = _wfopen(output, L"wb");
+       if (!fout)
+       {
+               fputws(L"Error: Failed to open output file!\n\n", stderr);
+               fclose(fin);
+               free(passphrase_utf8);
+               return 1;
+       }
+
+       struct _stati64 stat;
+       if (_fstati64(_fileno(fin), &stat) != 0)
+       {
+               fputws(L"I/O error: Failed to determine size of input file!\n\n", stderr);
+               fclose(fin);
+               free(passphrase_utf8);
+               return 1;
+       }
+
+       if (stat.st_size < 12LL)
+       {
+               fputws(L"Error: Input file is too small!\n\n", stderr);
+               fclose(fin);
+               free(passphrase_utf8);
+               return 1;
+       }
+
+       const int64_t limit = stat.st_size - sizeof(uint64_t);
+
+       uint64_t seed;
+       if (fread(&seed, sizeof(uint64_t), 1U, fin) < 1U)
+       {
+               fputws(L"I/O error: Failed to read encrypted data!\n\n", stderr);
+               fclose(fout);
+               fclose(fin);
+               free(passphrase_utf8);
+               return 1;
+       }
+
+       const mcrypt_t ctx = mcrypt_init(seed, passphrase_utf8);
+       if (!ctx)
+       {
+               fputws(L"MCrypt error: Failed to initialize decryption!\n\n", stderr);
+               fclose(fout);
+               fclose(fin);
+               free(passphrase_utf8);
+               return 1;
+       }
+
+       fputws(L"Decrypting, please be patient... ", stderr);
+       
+       uint64_t crc_actual = ~0U;
+       int64_t bytes_read = sizeof(uint64_t);
+       uint8_t buffer[1024U];
+
+       while ((!feof(fin)) && (bytes_read < limit))
+       {
+               const int64_t bytes_remaining = limit - bytes_read;
+               const size_t read_len = (bytes_remaining < 1024U) ? ((size_t)bytes_remaining) : 1024U;
+               const size_t count = fread(buffer, sizeof(uint8_t), read_len, fin);
+               if (ferror(fin))
+               {
+                       fputws(L"failed!\n\nI/O error: Failed to read encrypted data!\n\n", stderr);
+                       mcrypt_free(ctx);
+                       fclose(fout);
+                       fclose(fin);
+                       free(passphrase_utf8);
+                       return 1;
+               }
+               if (count > 0U)
+               {
+                       bytes_read += count;
+                       if (mcrypt_dec_process_inplace(ctx, buffer, count) != 0)
+                       {
+                               fputws(L"failed!\n\nMCrypt error: Failed to decrypt data!\n\n", stderr);
+                               mcrypt_free(ctx);
+                               fclose(fout);
+                               fclose(fin);
+                               free(passphrase_utf8);
+                               return 1;
+                       }
+                       for (size_t i = 0U; i < count; ++i)
+                       {
+                               crc_actual = CRC64_TAB[((crc_actual >> 56) ^ buffer[i]) & 0xFF] ^ (crc_actual << 8);
+                       }
+                       if (fwrite(buffer, sizeof(uint8_t), count, fout) < count)
+                       {
+                               fputws(L"failed!\n\nI/O error: Failed to write decrypted data!\n\n", stderr);
+                               mcrypt_free(ctx);
+                               fclose(fout);
+                               fclose(fin);
+                               free(passphrase_utf8);
+                               return 1;
+                       }
+               }
+       }
+
+       crc_actual ^= ~0U;
+
+       if (bytes_read < limit)
+       {
+               fputws(L"failed!\n\nI/O error: Input file could not be fully read!\n\n", stderr);
+               mcrypt_free(ctx);
+               fclose(fout);
+               fclose(fin);
+               free(passphrase_utf8);
+               return 1;
+       }
+
+       uint64_t crc_expected;
+       if (fread(&crc_expected, sizeof(uint64_t), 1U, fin) < 1U)
+       {
+               fputws(L"failed!\n\nI/O error: Failed to read CRC checksum!\n\n", stderr);
+               mcrypt_free(ctx);
+               fclose(fout);
+               fclose(fin);
+               free(passphrase_utf8);
+               return 1;
+       }
+
+       if (crc_actual != crc_expected)
+       {
+               fwprintf(stderr, L"failed!\n\nCRC error: Checksum mismatch detected! [0x%016llX vs. 0x%016llX]\n\nWrong passphrase?\n\n", crc_actual, crc_expected);
+               mcrypt_free(ctx);
+               fclose(fout);
+               fclose(fin);
+               free(passphrase_utf8);
+               return 1;
+       }
+
+       fputws(L"done.\n\nCRC checksum is correct.\n\n", stderr);
+
+       mcrypt_free(ctx);
+       fclose(fout);
+       fclose(fin);
+       free(passphrase_utf8);
+       return 0;
+}
+
+int wmain(int argc, wchar_t* argv[])
+{
+       fwprintf(stderr, L"MCrypt Utility [%S]\n", __DATE__" "__TIME__);
+       fwprintf(stderr, L"Powered by libMCrypt v%S [%S]\n\n", LIBMCRYPT_VERSION, LIBMCRYPT_BUILDNO);
+
+       if (argc < 4)
+       {
+               fputws(L"Usage:\n", stderr);
+               fwprintf(stderr, L"  %s [--decrypt] <passphrase> <input> <output>\n\n", argv[0U]);
+               return 1;
+       }
+
+       int result = -1;
+       const clock_t clk_start = clock();
+
+       if ((argc > 4) && (_wcsicmp(argv[1U], L"--decrypt") == 0))
+       {
+               result = decrypt(argv[2U], argv[3U], argv[4U]);
+       }
+       else
+       {
+               result = encrypt(argv[1U], argv[2U], argv[3U]);
+       }
+
+       const clock_t clk_end = clock();
+       fwprintf(stderr, L"--------\n\nOperation completed after %.1f seconds.\n\n", ((double)(clk_end - clk_start)) / ((double)CLOCKS_PER_SEC));
+}
index a0a74f6..20004e0 100644 (file)
@@ -10,7 +10,7 @@
 #include <stdint.h>
 
 extern const char *const LIBMCRYPT_VERSION;
-extern const char* const LIBMCRYPT_BUILD;
+extern const char* const LIBMCRYPT_BUILDNO;
 
 typedef uintptr_t mcrypt_t;
 
index 4885fd2..87f3947 100644 (file)
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v141_xp</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v141_xp</PlatformToolset>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v141_xp</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v142</PlatformToolset>
+    <PlatformToolset>v141_xp</PlatformToolset>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <LinkIncremental>true</LinkIncremental>
     <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\</IntDir>
+    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LinkIncremental>false</LinkIncremental>
     <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\</IntDir>
+    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <LinkIncremental>true</LinkIncremental>
     <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\</IntDir>
+    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <LinkIncremental>false</LinkIncremental>
     <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\</IntDir>
+    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <WarningLevel>Level3</WarningLevel>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <SDLCheck>true</SDLCheck>
       <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ConformanceMode>true</ConformanceMode>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <AdditionalIncludeDirectories>$(ProjectDir)include</AdditionalIncludeDirectories>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <WholeProgramOptimization>true</WholeProgramOptimization>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
     </ClCompile>
     <Link>
       <SubSystem>
       <WarningLevel>Level3</WarningLevel>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
-      <SDLCheck>true</SDLCheck>
       <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ConformanceMode>true</ConformanceMode>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <AdditionalIncludeDirectories>$(ProjectDir)include</AdditionalIncludeDirectories>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <OmitFramePointers>true</OmitFramePointers>
+      <WholeProgramOptimization>true</WholeProgramOptimization>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
     </ClCompile>
     <Link>
       <SubSystem>
index 54ef665..22e818b 100644 (file)
@@ -11,7 +11,7 @@
 #include <string.h>
 
 const char* const LIBMCRYPT_VERSION = "1.0.0";
-const char* const LIBMCRYPT_BUILD   = __DATE__" "__TIME__;
+const char* const LIBMCRYPT_BUILDNO = __DATE__" "__TIME__;
 
 typedef struct
 {
@@ -98,11 +98,11 @@ static void hash_update(uint64_t* const h, const uint8_t* const data, const size
        }
 }
 
-static uint64_t hash_code(const uint64_t salt, const uint8_t pepper, const uint8_t* const data, const size_t data_len)
+static uint64_t hash_code(const uint64_t salt, const uint16_t pepper, const uint8_t* const data, const size_t data_len)
 {
        uint64_t h = 0xCBF29CE484222325ull;
        hash_update(&h, (uint8_t*)&salt, sizeof(uint64_t));
-       hash_update(&h, &pepper, 1U);
+       hash_update(&h, (uint8_t*)&pepper, sizeof(uint16_t));
        hash_update(&h, data, data_len);
        return h;
 }
@@ -134,9 +134,11 @@ static uint32_t random_next(rand_state_t* const state)
        return t + (state->counter += 362437U);
 }
 
-static void random_seed(rand_state_t* const state, const uint64_t salt, const uint8_t* const key, const size_t key_len)
+static void random_seed(rand_state_t* const state, const uint64_t salt, const uint16_t pepper, const uint8_t* const key, const size_t key_len)
 {
-       random_init(state, hash_code(salt, 0x6B, key, key_len), hash_code(salt, 0x94, key, key_len));
+       const uint64_t hash_code_0 = hash_code(salt, pepper + 0xB8A1, key, key_len);
+       const uint64_t hash_code_1 = hash_code(salt, pepper + 0x475E, key, key_len);
+       random_init(state, hash_code_0, hash_code_1);
        for (size_t i = 0U; i < 13U; ++i)
        {
                random_next(state);
@@ -147,12 +149,12 @@ static void random_seed(rand_state_t* const state, const uint64_t salt, const ui
 // Initialization
 // ==========================================================================
 
-static void initialize_state(crypt_state_t *const crypt_state, const uint64_t salt, const uint8_t *const key, const size_t key_len)
+static void initialize_state(crypt_state_t* const crypt_state, const uint64_t salt, const uint8_t* const key, const size_t key_len)
 {
        rand_state_t rand_state;
        for (size_t r = 0U; r < 256U; ++r)
        {
-               random_seed(&rand_state, salt + r, key, key_len);
+               random_seed(&rand_state, salt, (uint16_t)r, key, key_len);
                crypt_state->off[r] = (uint8_t)random_next(&rand_state);
                for (size_t i = 0U; i < 256U; ++i)
                {
@@ -169,7 +171,7 @@ static void initialize_state(crypt_state_t *const crypt_state, const uint64_t sa
                        crypt_state->inv[r][j] = (uint8_t)i;
                }
        }
-       random_seed(&rand_state, salt + 9973U, key, key_len);
+       random_seed(&rand_state, salt, 0x0100, key, key_len);
        crypt_state->pos = (uint8_t)random_next(&rand_state);
        erase(&rand_state, sizeof(rand_state_t));
 }
@@ -191,7 +193,7 @@ static uint8_t process_enc(crypt_state_t* const crypt_state, uint8_t value)
 static uint8_t process_dec(crypt_state_t* const crypt_state, uint8_t value)
 {
        size_t i = 256U;
-       while(i--)
+       while (i--)
        {
                value = (crypt_state->inv[i][value] - crypt_state->off[i]) & 0xFF;
        }
@@ -203,7 +205,7 @@ static uint8_t process_dec(crypt_state_t* const crypt_state, uint8_t value)
 // Public API
 // ==========================================================================
 
-int mcrypt_generate_seed(uint64_t *const seed)
+int mcrypt_generate_seed(uint64_tconst seed)
 {
        if (seed)
        {
@@ -218,7 +220,7 @@ mcrypt_t mcrypt_init(const uint64_t salt, const char* const passphrase)
        {
                return ((mcrypt_t)NULL);
        }
-       crypt_state_t *const state = (crypt_state_t*) malloc(sizeof(crypt_state_t));
+       crypt_state_t* const state = (crypt_state_t*)malloc(sizeof(crypt_state_t));
        if (!state)
        {
                return ((mcrypt_t)NULL);
@@ -227,7 +229,7 @@ mcrypt_t mcrypt_init(const uint64_t salt, const char* const passphrase)
        return ((mcrypt_t)state);
 }
 
-int mcrypt_enc_process(const mcrypt_t context, const uint8_t *const input, uint8_t *const output, size_t length)
+int mcrypt_enc_process(const mcrypt_t context, const uint8_t* const input, uint8_t* const output, size_t length)
 {
        crypt_state_t* const state = (crypt_state_t*)context;
        if (!context)
diff --git a/src/main.c b/src/main.c
deleted file mode 100644 (file)
index 0c2a35a..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/******************************************************************************/
-/* MCrypt, by LoRd_MuldeR <MuldeR2@GMX.de>                                    */
-/* This work has been released under the CC0 1.0 Universal license!           */
-/******************************************************************************/
-
-#include <mcrypt.h>
-#include <stdio.h>
-#include <string.h>
-
-int main()
-{
-       printf("MCrypt Demo [%s]\n", __DATE__" "__TIME__);
-       printf("Using libMCrypt v%s [%s]\n\n", LIBMCRYPT_VERSION, LIBMCRYPT_BUILD);
-
-       const char *const plaintext = "AAAALorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.";
-       const size_t length = strlen(plaintext) + 1U;
-
-       fprintf(stderr, "\"%s\"\n\n", plaintext);
-
-       /* ---- Allocate buffers ---- */
-
-       char* ciphertext = malloc(length);
-       if (!ciphertext)
-       {
-               abort();
-       }
-
-       char* decoded = malloc(length);
-       if (!decoded)
-       {
-               abort();
-       }
-
-       /* ---- Generate seed ---- */
-
-       uint64_t seed;
-       if (mcrypt_generate_seed(&seed) != 0)
-       {
-               abort();
-       }
-
-       /* ---- Encryt message ---- */
-
-       mcrypt_t enc = mcrypt_init(seed, "Yp#QaQfH)t`DT23q");
-       if (!enc)
-       {
-               abort();
-       }
-
-       mcrypt_enc_process(enc, plaintext, ciphertext, length);
-       mcrypt_free(enc);
-
-       fprintf(stderr, "\"%s\"\n\n", ciphertext);
-
-
-       /* ---- Decryt message ---- */
-       
-       mcrypt_t dec = mcrypt_init(seed, "Yp#QaQfH)t`DT23q");
-       if (!dec)
-       {
-               abort();
-       }
-
-       mcrypt_dec_process(dec, ciphertext, decoded, length);
-       mcrypt_free(dec);
-
-       fprintf(stderr, "\"%s\"\n\n", decoded);
-
-}
\ No newline at end of file