Use the getrandom() syscall on systems that support it.

This commit is contained in:
LoRd_MuldeR 2020-10-13 17:42:22 +02:00
parent 75f929e4e5
commit 7a95a1a561
Signed by: mulder
GPG Key ID: 2B5913365F57E03F
8 changed files with 146 additions and 25 deletions

55
frontend/MCrypt.rc Normal file
View File

@ -0,0 +1,55 @@
/////////////////////////////////////////////////////////////////////////////
//
// Microsoft Visual C++ generated resource script.
//
#define APSTUDIO_READONLY_SYMBOLS
#include "WinResrc.h" //"afxres.h"
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Neutral resources
//
#ifdef _WIN32
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x3L
#else
FILEFLAGS 0x2L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "000004b0"
BEGIN
VALUE "ProductName", "MCrypt"
VALUE "FileDescription", "MCrypt Utility"
VALUE "ProductVersion", "1.0.0"
VALUE "FileVersion", "1.0.0"
VALUE "InternalName", "mcrypt"
VALUE "OriginalFilename", "mcrypt.exe"
VALUE "LegalCopyright", "Created by LoRd_MuldeR <MuldeR2@GMX.de>"
VALUE "CompanyName", "Muldersoft"
VALUE "LegalTrademarks", "Muldersoft"
VALUE "Comments", "This work has been released under the CC0 1.0 Universal license!"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0, 1200
END
END

View File

@ -33,12 +33,15 @@
<ClInclude Include="src\platform.h" /> <ClInclude Include="src\platform.h" />
<ClInclude Include="src\utils.h" /> <ClInclude Include="src\utils.h" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ResourceCompile Include="MCrypt.rc" />
</ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion> <VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<ProjectGuid>{86d28793-713e-4cec-9686-335514ac5ef0}</ProjectGuid> <ProjectGuid>{86d28793-713e-4cec-9686-335514ac5ef0}</ProjectGuid>
<RootNamespace>MCrypt</RootNamespace> <RootNamespace>MCrypt</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>7.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@ -89,21 +92,25 @@
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<TargetName>mcrypt</TargetName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<TargetName>mcrypt</TargetName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<TargetName>mcrypt</TargetName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<TargetName>mcrypt</TargetName>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
@ -140,7 +147,8 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -177,7 +185,8 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>false</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -36,4 +36,9 @@
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ResourceCompile Include="MCrypt.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project> </Project>

View File

@ -11,6 +11,7 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <inttypes.h> #include <inttypes.h>
#include <ctype.h>
static void print_string(const char *const text, const size_t length) static void print_string(const char *const text, const size_t length)
{ {
@ -42,16 +43,34 @@ static int open_files(FILE** const fin, FILE** const fout, const CHR* const inpu
return 0; return 0;
} }
static int weak_passphrase(const CHR *str)
{
int flags[4U] = { 0, 0, 0, 0 };
while (*str)
{
const CHR c = *str++;
if (iswupper(c)) flags[0U] = 1;
else if (iswlower(c)) flags[1U] = 1;
else if (iswdigit(c)) flags[2U] = 1;
else if (iswgraph(c)) flags[3U] = 1;
}
const int strong = flags[0U] && flags[1U] && flags[2U] && flags[3U];
return !strong;
}
static int encrypt(const CHR* const passphrase, const CHR* const input, const CHR* const output) static int encrypt(const CHR* const passphrase, const CHR* const input, const CHR* const output)
{ {
mcrypt_t ctx = NULL; mcrypt_t ctx = NULL;
FILE *fin = NULL, *fout = NULL; FILE *fin = NULL, *fout = NULL;
int result = -1; int result = -1;
if (!passphrase[0U]) if (STRLEN(passphrase) < 8U)
{ {
FPUTS(T("Error: The given passphrase is empty!\n\n"), stderr); FPUTS(L"Warning: Using a short passphrase. Eight characters or more are recommended!\n\n", stderr);
goto clean_up; }
else if (weak_passphrase(passphrase))
{
FPUTS(L"Warning: Using a weak passphrase. A mix of upper-case characters, lower-case characters, digits and 'special' characters is recommended!\n\n", stderr);
} }
char *const passphrase_utf8 = utf16_to_bytes(passphrase, CP_UTF8); char *const passphrase_utf8 = utf16_to_bytes(passphrase, CP_UTF8);
@ -188,12 +207,6 @@ static int decrypt(const CHR* const passphrase, const CHR* const input, const CH
FILE *fin = NULL, *fout = NULL; FILE *fin = NULL, *fout = NULL;
int result = -1; int result = -1;
if (!passphrase[0U])
{
FPUTS(T("Error: The given passphrase is empty!\n\n"), stderr);
goto clean_up;
}
char *const passphrase_utf8 = utf16_to_bytes(passphrase, CP_UTF8); char *const passphrase_utf8 = utf16_to_bytes(passphrase, CP_UTF8);
if (!passphrase_utf8) if (!passphrase_utf8)
{ {
@ -329,32 +342,50 @@ clean_up:
int MAIN(int argc, CHR* argv[]) int MAIN(int argc, CHR* argv[])
{ {
FPRINTF(stderr, T("MCrypt Utility [%") T(PRIstr) T("]\n"), __DATE__" "__TIME__); FPRINTF(stderr, T("MCrypt Utility [%") T(PRIstr) T("]\n"), __DATE__", "__TIME__);
FPRINTF(stderr, T("Powered by libMCrypt v%") T(PRIstr) T(" [%") T(PRIstr) T("]\n\n"), LIBMCRYPT_VERSION, LIBMCRYPT_BUILDNO); FPRINTF(stderr, T("Powered by libMCrypt v%") T(PRIstr) T(" [%") T(PRIstr) T("]\n\n"), LIBMCRYPT_VERSION, LIBMCRYPT_BUILDNO);
if (argc < 4) if ((argc < 5) || (!STRICMP(argv[1U], T("--help"))) || (!STRICMP(argv[1U], T("--version"))))
{ {
FPUTS(T("This software has been released under the CC0 1.0 Universal license:\n"), stderr);
FPUTS(T("https://creativecommons.org/publicdomain/zero/1.0/legalcode\n\n"), stderr);
if (argc < 2)
{
FPUTS(T("Nothing to do!\n\n"), stderr);
}
FPUTS(T("Usage:\n"), stderr); FPUTS(T("Usage:\n"), stderr);
FPRINTF(stderr, T(" %s [--decrypt] <passphrase> <input> <output>\n\n"), argv[0U]); FPRINTF(stderr, T(" %") T(PRIwcs) T(" --encrypt <passphrase> <input.txt> <output.enc>\n"), argv[0U]);
FPRINTF(stderr, T(" %") T(PRIwcs) T(" --decrypt <passphrase> <input.enc> <output.txt>\n\n"), argv[0U]);
return 1; return 1;
} }
int result = -1; if (!argv[1U][0U])
const clock_t clk_start = clock(); {
FPUTS(T("Error: The passphrase must not be empty!\n\n"), stderr);
return 1;
}
if ((argc > 4) && ((!STRICMP(argv[1U], T("-d"))) || (!STRICMP(argv[1U], T("--decrypt"))))) const clock_t clk_start = clock();
int result = -1;
if (!STRICMP(argv[1U], T("--encrypt")))
{
result = encrypt(argv[2U], argv[3U], argv[4U]);
}
else if (!STRICMP(argv[1U], T("--decrypt")))
{ {
result = decrypt(argv[2U], argv[3U], argv[4U]); result = decrypt(argv[2U], argv[3U], argv[4U]);
erase(argv[2U], STRLEN(argv[2U]) * sizeof(CHR));
} }
else else
{ {
result = encrypt(argv[1U], argv[2U], argv[3U]); FPRINTF(stderr, T("Error: Command \"%") T(PRIwcs) T("\" is unknown!\n\n"), argv[1U]);
erase(argv[1U], STRLEN(argv[1U]) * sizeof(CHR)); erase(argv[2U], STRLEN(argv[2U]) * sizeof(CHR));
return 1;
} }
FPUTS(T("--------\n\n"), stderr); FPUTS(T("--------\n\n"), stderr);
fflush(stderr); fflush(stderr);
erase(argv[2U], STRLEN(argv[2U]) * sizeof(CHR));
const clock_t clk_end = clock(); const clock_t clk_end = clock();
FPRINTF(stderr, T("Operation completed after %.1f seconds.\n\n"), (clk_end - clk_start) / ((double)CLOCKS_PER_SEC)); FPRINTF(stderr, T("Operation completed after %.1f seconds.\n\n"), (clk_end - clk_start) / ((double)CLOCKS_PER_SEC));

View File

@ -20,8 +20,10 @@
#define STAT64_T struct _stati64 #define STAT64_T struct _stati64
#ifdef __MINGW32__ #ifdef __MINGW32__
#define PRIstr "hs" #define PRIstr "hs"
#define PRIwcs "ls"
#else #else
#define PRIstr "S" #define PRIstr "S"
#define PRIwcs "s"
#endif #endif
#else #else
#define MAIN main #define MAIN main
@ -36,6 +38,7 @@
#define FSTAT64(X,Y) fstat64((X),(Y)) #define FSTAT64(X,Y) fstat64((X),(Y))
#define STAT64_T struct stat64 #define STAT64_T struct stat64
#define PRIstr "s" #define PRIstr "s"
#define PRIwcs "ls"
#endif #endif
#define T(X) _T(X) #define T(X) _T(X)

View File

@ -31,7 +31,7 @@
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<ProjectGuid>{a4a3879c-bd2c-4304-af66-7349cef7e4c0}</ProjectGuid> <ProjectGuid>{a4a3879c-bd2c-4304-af66-7349cef7e4c0}</ProjectGuid>
<RootNamespace>libMCrypt</RootNamespace> <RootNamespace>libMCrypt</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>7.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@ -82,21 +82,25 @@
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<TargetName>libmcrypt-1</TargetName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<TargetName>libmcrypt-1</TargetName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<TargetName>libmcrypt-1</TargetName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir> <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
<TargetName>libmcrypt-1</TargetName>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>

View File

@ -12,7 +12,7 @@
#include <string.h> #include <string.h>
const char* const LIBMCRYPT_VERSION = "1.0.0"; const char* const LIBMCRYPT_VERSION = "1.0.0";
const char* const LIBMCRYPT_BUILDNO = __DATE__" "__TIME__; const char* const LIBMCRYPT_BUILDNO = __DATE__", "__TIME__;
typedef struct typedef struct
{ {

View File

@ -12,6 +12,12 @@
#ifdef __unix__ #ifdef __unix__
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#if (defined(__GLIBC__) && defined(__GLIBC_MINOR__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25)) || (defined(__FreeBSD__) && (__FreeBSD__ >= 12))
#define HAVE_GENRANDOM_SYSCALL 1
#include <sys/random.h>
#else
#undef HAVE_GENRANDOM_SYSCALL
#endif
#endif #endif
int mcrypt_random_bytes(uint8_t* const buffer, const size_t length) int mcrypt_random_bytes(uint8_t* const buffer, const size_t length)
@ -36,9 +42,16 @@ int mcrypt_random_bytes(uint8_t* const buffer, const size_t length)
return 0; return 0;
#else #else
#ifdef __unix__ #ifdef __unix__
static const char* const PATH[] = { "/dev/urandom", "/dev/random" }; #ifdef HAVE_GENRANDOM_SYSCALL
if (getrandom(buffer, length, 0U) >= length)
{
return 0;
}
return -1;
#else
static const char* const PATH[] = { "/dev/urandom", "/dev/arandom", "/dev/random" };
int result = -1; int result = -1;
for (size_t i = 0; (i < 2U) && (result < 0); ++i) for (size_t i = 0; (i < 3U) && (result < 0); ++i)
{ {
const int fd = open(PATH[i], O_RDONLY); const int fd = open(PATH[i], O_RDONLY);
if (fd >= 0) if (fd >= 0)
@ -51,6 +64,7 @@ int mcrypt_random_bytes(uint8_t* const buffer, const size_t length)
} }
} }
return result; return result;
#endif
#else #else
#error Unsupported target platform! #error Unsupported target platform!
#endif #endif