⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 entropy.c

📁 Entropy Generation for very large psueduo-random integer.
💻 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 + -