📄 entropy.c
字号:
#if defined _WIN32 && defined _MSC_VER
#include <windows.h>
#include <winbase.h>
#include <wincrypt.h>
#endif /* _WIN32 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include "ripemd.h"
#include "flint.h"
#include "entropy.h"
static void * local_memset (void *ptr, int val, size_t len);
/******************************************************************************/
/* */
/* Function: Generation of entropy for initialization of Pseudo- */
/* randomnumber generators. In addition to a user defined byte */
/* vector (optional) entropy bytes are read from system specific */
/* sources: */
/* - For Win32: Value from QueryPerformanceCounter (64 bytes), */
/* Values from CryptGenRandom */
/* - For Unix/Linux systems: */
/* Entropy is read from virtual device /dev/urandom */
/* if this source is available. */
/* Altogether a number of LenRndStr+AddEntropy bytes are fed */
/* into the result, which is returned as CLINT-value and in */
/* addition as Ripemd-160 hashvalue. */
/* */
/* Usage with Windows 9x/ME/NT/2K/XP: */
/* ----------------------------------------- */
/* Usage of Win32-function GenRandom() requires linking with */
/* advapi32.lib and accessibility of DLL advapi32.dll at runtime */
/* (available under Windows 95 OSR2 and higher, Windows NT 4.x */
/* Windows 2000, XP). */
/* */
/* Syntax: GetEntropy_l (CLINT Seed_l, char *Hashres, int AddEntropy, */
/* char *RndStr, int LenRndStr); */
/* Input: AddEntropy (Number of entropy btes to be generated) */
/* RndStr (User defined byte vector, NULL-pointer accepted) */
/* LenRndStr (Laenge von RndStr in Bytes) */
/* Output: Seed_l (Entropie as CLINT-value. If Seed_l == NULL-pointer */
/* no output is given) */
/* Hashres (Entropy as Ripemd-160-hashvalue, length of 20 bytes */
/* If Hashres == NULL-pointer no Output is given) */
/* Returns: 0 if everything is OK */
/* n > 0 if n bytes less than the requested number of entropy */
/* bytes could be generated */
/* E_CLINT_MAL error in allocation of memory */
/* */
/******************************************************************************/
int __FLINT_API
GetEntropy_l (CLINT Seed_l, UCHAR *Hashres, int AddEntropy, char *RndStr, int LenRndStr)
{
unsigned nextfree = 0, MissingEntropy = MAX(AddEntropy, sizeof (time_t));
unsigned i, j;
UCHAR *Seedbytes;
int BytesRead;
int LenSeedbytes = LenRndStr + MissingEntropy +
sizeof (time_t) + 2*sizeof (ULONG);
RMDSTAT hws;
time_t SeedTime;
FILE *fp;
#if defined _WIN32 && defined _MSC_VER
LARGE_INTEGER PCountBuff;
HCRYPTPROV hProvider = 0;
#endif /*defined _WIN32 && defined _MSC_VER? */
if ((Seedbytes = (UCHAR*)malloc(LenSeedbytes)) == NULL)
{
return E_CLINT_MAL;
}
if (RndStr != NULL && LenRndStr > 0)
{
memcpy (Seedbytes, RndStr, LenRndStr);
#ifdef FLINT_TEST
printf("\nRndStr in Seedbytes = ");
for (i = 0 ; i < LenRndStr; i++)
printf("%.2x ",(unsigned char)Seedbytes[nextfree+i]);
#endif /* FLINT_TEST */
nextfree = LenRndStr;
}
SeedTime = (time_t)time(NULL);
/* System time in Seed */
for (i = 0; i < sizeof(time_t); i++)
{
j = i << 3;
/* right shift of signed SeedTime doesn't matter, turn lint off */
Seedbytes[nextfree+i] = (UCHAR)((SeedTime >> j) & (time_t)0xff); /*lint !e704, !e713 */
}
#ifdef FLINT_TEST
printf("\nWert Time in Seedbytes = ");
for (i = 0 ; i < sizeof (time_t); i++)
printf("%.2x ",(unsigned char)Seedbytes[nextfree+i]);
#endif /* FLINT_TEST */
nextfree += sizeof (time_t);
MissingEntropy -= sizeof (time_t);
#if defined _WIN32 && defined _MSC_VER /* Get Win32-generated Entropy */
if (MissingEntropy)
{
/* Chaining with 64-bit-value QueryPerformanceCounter() (Win32-Function) */
QueryPerformanceCounter (&PCountBuff);
for (i = 0; i < sizeof (DWORD); i++)
{
j = i << 3;
Seedbytes[nextfree + i] =
(char)((PCountBuff.HighPart >> j) & (DWORD)0xff);
Seedbytes[nextfree + sizeof (DWORD) + i] =
(char)((PCountBuff.LowPart >> j) & (DWORD)0xff);
}
#ifdef FLINT_TEST
printf("\nWert PerformanceCounter in Seedbytes = ");
for (i = 0; i < 2*sizeof (DWORD); i++)
printf("%.2x ",(unsigned char)Seedbytes[nextfree+i]);
#endif
nextfree += 2*sizeof (DWORD);
MissingEntropy -= 2*sizeof (DWORD);
}
/* Chaining with output from CryptGenRandom() (Win32-Function) */
if (CryptAcquireContext(&hProvider,
NULL,
NULL,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT))
{
if (CryptGenRandom (hProvider,
MissingEntropy,
&Seedbytes[nextfree]))
{
#ifdef FLINT_TEST
printf("\nWert CryptGenRandom in Seedbytes = ");
for (i = 0 ; i < MissingEntropy; i++)
printf("%.2x ",(unsigned char)Seedbytes[nextfree+i]);
printf("\n");
#endif /* FLINT_TEST */
nextfree += MissingEntropy;
MissingEntropy = 0;
}
}
if (hProvider)
{
CryptReleaseContext (hProvider, 0);
}
#endif /* defined _WIN32 && _MSC_VER */
/* Get entropy from /dev/urandom if available */
if ((fp = fopen("/dev/urandom", "r")) != NULL)
{
BytesRead = fread(&Seedbytes[nextfree], sizeof (UCHAR), MissingEntropy, fp);
#ifdef FLINT_TEST
printf("\nWert aus /dev/urandom in Seedbytes = ");
for (i = 0; i < BytesRead; i++)
printf("%.2x ",(unsigned char)Seedbytes[nextfree+i]);
printf("\n");
#endif /* FLINT_TEST */
nextfree += BytesRead;
MissingEntropy -= BytesRead;
fclose (fp);
}
/* Hashing of chained entropy-values */
if (Hashres != NULL)
{
ripeinit (&hws);
ripefinish (Hashres, &hws, Seedbytes, nextfree);
#ifdef FLINT_TEST
printf("\nHashwert in Hashres = ");
for (i = 0; i < 20; i++) printf("%.2x ", (unsigned char)Hashres[i]);
printf("\n");
#endif /* FLINT_TEST */
}
/* Seed as CLINT-values */
if (Seed_l != NULL)
{
byte2clint_l (Seed_l, Seedbytes, nextfree);
#ifdef FLINT_TEST
disp_l ("Random Seed in Seed_l = ", Seed_l);
#endif /* FLINT_TEST */
}
/* Security: Purge Seed by overwriting with 0 */
SeedTime = 0;
local_memset (Seedbytes, 0, LenSeedbytes);
local_memset (&hws, 0, sizeof (hws));
free (Seedbytes);
return MissingEntropy;
}
/******************************************************************************/
/* */
/* Function: Calculation of the entropy of a password from the */
/* number of characters of the underlying alphabet and number */
/* of characters of the password itself, using the formular */
/* Entropie = log2 (n^m) */
/* with n the size of the alphabet and m the size of the */
/* password in characters. */
/* This value is important for the calculation of a */
/* cryptographic key from a password. If all printable ASCII- */
/* characters can be used for a password (93 characters), then */
/* the password should have */
/* - 20 characters for generating a key of 128-bit length */
/* - 30 characters for generating a key of 192-bit length */
/* - 40 characters for generating a key of 256-bit length. */
/* Syntax: int PWDQual_l (char *pwd, int len_pwd, int len_alpha); */
/* Input: char *PWD (Password, RFU, not beeing evaluated here) */
/* int LenPWD (Length of the password in characters) */
/* int LenAlpha (Size of the alphabet in characters) */
/* Output: - */
/* Returns: Entropy of password */
/* */
/******************************************************************************/
int __FLINT_API
PWDQual_l (char *PWD, int LenPWD, int LenAlpha)
{
return (int)((double)LenAlpha * log10 (LenPWD) / log10 (2));
}
/******************************************************************************/
/* */
/* Local memset-Function, does the same as memset() */
/* Needed to make compiler purge variables in spite of optimization. */
/* */
/******************************************************************************/
static void *
local_memset (void *ptr, int val, size_t len)
{
return memset (ptr, val, len);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -