// SPDX-License-Identifier: BSD-2-Clause
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
 *
 * LibTomCrypt is a library that provides various cryptographic
 * algorithms in a highly modular and flexible manner.
 *
 * The library is free for all purposes without any express
 * guarantee it works.
 */
#include "tomcrypt_private.h"

#ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED
#if defined(_WIN32)
  #include <windows.h>
#elif defined(LTC_CLOCK_GETTIME)
  #include <time.h> /* struct timespec + clock_gettime */
#else
  #include <sys/time.h> /* struct timeval + gettimeofday */
#endif
#endif

/**
  @file fortuna.c
  Fortuna PRNG, Tom St Denis
*/

/* Implementation of Fortuna by Tom St Denis

We deviate slightly here for reasons of simplicity [and to fit in the API].  First all "sources"
in the AddEntropy function are fixed to 0.  Second since no reliable timer is provided
we reseed automatically when len(pool0) >= 64 or every LTC_FORTUNA_WD calls to the read function */

#ifdef LTC_FORTUNA

/* requries LTC_SHA256 and AES  */
#if !(defined(LTC_RIJNDAEL) && defined(LTC_SHA256))
   #error LTC_FORTUNA requires LTC_SHA256 and LTC_RIJNDAEL (AES)
#endif

#ifndef LTC_FORTUNA_POOLS
   #warning LTC_FORTUNA_POOLS was not previously defined (old headers?)
   #define LTC_FORTUNA_POOLS 32
#endif

#if LTC_FORTUNA_POOLS < 4 || LTC_FORTUNA_POOLS > 32
   #error LTC_FORTUNA_POOLS must be in [4..32]
#endif

const struct ltc_prng_descriptor fortuna_desc = {
    "fortuna",
    64,
    &fortuna_start,
    &fortuna_add_entropy,
    &fortuna_ready,
    &fortuna_read,
    &fortuna_done,
    &fortuna_export,
    &fortuna_import,
    &fortuna_test
};

/* update the IV */
static void _fortuna_update_iv(prng_state *prng)
{
   int            x;
   unsigned char *IV;
   /* update IV */
   IV = prng->u.fortuna.IV;
   for (x = 0; x < 16; x++) {
      IV[x] = (IV[x] + 1) & 255;
      if (IV[x] != 0) break;
   }
}

#ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED
/* get the current time in 100ms steps */
static ulong64 _fortuna_current_time(void)
{
   ulong64 cur_time;
#if defined(_WIN32)
   FILETIME CurrentTime;
   ULARGE_INTEGER ul;
   GetSystemTimeAsFileTime(&CurrentTime);
   ul.LowPart  = CurrentTime.dwLowDateTime;
   ul.HighPart = CurrentTime.dwHighDateTime;
   cur_time = ul.QuadPart; /* now we have 100ns intervals since 1 January 1601 */
   cur_time -= CONST64(116444736000000000); /* subtract 100ns intervals between 1601-1970 */
   cur_time /= 10; /* 100ns intervals > microseconds */
#elif defined(LTC_CLOCK_GETTIME)
  struct timespec ts;
  clock_gettime(CLOCK_MONOTONIC, &ts);
  cur_time = (ulong64)(ts.tv_sec) * 1000000 + (ulong64)(ts.tv_nsec) / 1000; /* get microseconds */
#else
  struct timeval tv;
  gettimeofday(&tv, NULL);
  cur_time = (ulong64)(tv.tv_sec) * 1000000 + (ulong64)(tv.tv_usec); /* get microseconds */
#endif
   return cur_time / 100;
}
#endif

/* reseed the PRNG */
static int _fortuna_reseed(prng_state *prng)
{
   unsigned char tmp[MAXBLOCKSIZE];
   hash_state    md;
   ulong64       reset_cnt;
   int           err, x;

#ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED
   ulong64 now = _fortuna_current_time();
   if (now == prng->u.fortuna.wd) {
      return CRYPT_OK;
   }
#else
   if (++prng->u.fortuna.wd < LTC_FORTUNA_WD) {
      return CRYPT_OK;
   }
#endif

   /* new K == LTC_SHA256(K || s) where s == LTC_SHA256(P0) || LTC_SHA256(P1) ... */
   sha256_init(&md);
   if ((err = sha256_process(&md, prng->u.fortuna.K, 32)) != CRYPT_OK) {
      sha256_done(&md, tmp);
      return err;
   }

   reset_cnt = prng->u.fortuna.reset_cnt + 1;

   for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
       if (x == 0 || ((reset_cnt >> (x-1)) & 1) == 0) {
          /* terminate this hash */
          if ((err = sha256_done(&prng->u.fortuna.pool[x], tmp)) != CRYPT_OK) {
             sha256_done(&md, tmp);
             return err;
          }
          /* add it to the string */
          if ((err = sha256_process(&md, tmp, 32)) != CRYPT_OK) {
             sha256_done(&md, tmp);
             return err;
          }
          /* reset this pool */
          if ((err = sha256_init(&prng->u.fortuna.pool[x])) != CRYPT_OK) {
             sha256_done(&md, tmp);
             return err;
          }
       } else {
          break;
       }
   }

   /* finish key */
   if ((err = sha256_done(&md, prng->u.fortuna.K)) != CRYPT_OK) {
      return err;
   }
   if ((err = rijndael_setup(prng->u.fortuna.K, 32, 0, &prng->u.fortuna.skey)) != CRYPT_OK) {
      return err;
   }
   _fortuna_update_iv(prng);

   /* reset/update internals */
   prng->u.fortuna.pool0_len = 0;
#ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED
   prng->u.fortuna.wd        = now;
#else
   prng->u.fortuna.wd        = 0;
#endif
   prng->u.fortuna.reset_cnt = reset_cnt;


#ifdef LTC_CLEAN_STACK
   zeromem(&md, sizeof(md));
   zeromem(tmp, sizeof(tmp));
#endif

   return CRYPT_OK;
}

/**
  "Update Seed File"-compliant update of K

  @param in       The PRNG state
  @param inlen    Size of the state
  @param prng     The PRNG to import
  @return CRYPT_OK if successful
*/
int fortuna_update_seed(const unsigned char *in, unsigned long inlen, prng_state *prng)
{
   int           err;
   unsigned char tmp[MAXBLOCKSIZE];
   hash_state    md;

   LTC_MUTEX_LOCK(&prng->lock);
   /* new K = LTC_SHA256(K || in) */
   sha256_init(&md);
   if ((err = sha256_process(&md, prng->u.fortuna.K, 32)) != CRYPT_OK) {
      sha256_done(&md, tmp);
      goto LBL_UNLOCK;
   }
   if ((err = sha256_process(&md, in, inlen)) != CRYPT_OK) {
      sha256_done(&md, tmp);
      goto LBL_UNLOCK;
   }
   /* finish key */
   if ((err = sha256_done(&md, prng->u.fortuna.K)) != CRYPT_OK) {
      goto LBL_UNLOCK;
   }
   _fortuna_update_iv(prng);

LBL_UNLOCK:
   LTC_MUTEX_UNLOCK(&prng->lock);
#ifdef LTC_CLEAN_STACK
   zeromem(&md, sizeof(md));
#endif

   return err;
}

/**
  Start the PRNG
  @param prng     [out] The PRNG state to initialize
  @return CRYPT_OK if successful
*/
int fortuna_start(prng_state *prng)
{
   int err, x, y;
   unsigned char tmp[MAXBLOCKSIZE];

   LTC_ARGCHK(prng != NULL);
   prng->ready = 0;

   /* initialize the pools */
   for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
       if ((err = sha256_init(&prng->u.fortuna.pool[x])) != CRYPT_OK) {
          for (y = 0; y < x; y++) {
              sha256_done(&prng->u.fortuna.pool[y], tmp);
          }
          return err;
       }
   }
   prng->u.fortuna.pool_idx = prng->u.fortuna.pool0_len = prng->u.fortuna.wd = 0;
   prng->u.fortuna.reset_cnt = 0;

   /* reset bufs */
   zeromem(prng->u.fortuna.K, 32);
   if ((err = rijndael_setup(prng->u.fortuna.K, 32, 0, &prng->u.fortuna.skey)) != CRYPT_OK) {
      for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
          sha256_done(&prng->u.fortuna.pool[x], tmp);
      }
      return err;
   }
   zeromem(prng->u.fortuna.IV, 16);

   LTC_MUTEX_INIT(&prng->lock)

   return CRYPT_OK;
}

static int _fortuna_add(unsigned long source, unsigned long pool, const unsigned char *in, unsigned long inlen, prng_state *prng)
{
   unsigned char tmp[2];
   int err;

   /* ensure inlen <= 32 */
   if (inlen > 32) {
      inlen = 32;
   }

   /* add s || length(in) || in to pool[pool_idx] */
   tmp[0] = (unsigned char)source;
   tmp[1] = (unsigned char)inlen;

   if ((err = sha256_process(&prng->u.fortuna.pool[pool], tmp, 2)) != CRYPT_OK) {
      return err;
   }
   if ((err = sha256_process(&prng->u.fortuna.pool[pool], in, inlen)) != CRYPT_OK) {
      return err;
   }
   if (pool == 0) {
      prng->u.fortuna.pool0_len += inlen;
   }
   return CRYPT_OK; /* success */
}

/**
  Add random event to the PRNG state as proposed by the original paper.
  @param source   The source this random event comes from (0 .. 255)
  @param pool     The pool where to add the data to (0 .. LTC_FORTUNA_POOLS)
  @param in       The data to add
  @param inlen    Length of the data to add
  @param prng     PRNG state to update
  @return CRYPT_OK if successful
*/
int fortuna_add_random_event(unsigned long source, unsigned long pool, const unsigned char *in, unsigned long inlen, prng_state *prng)
{
   int           err;

   LTC_ARGCHK(prng != NULL);
   LTC_ARGCHK(in != NULL);
   LTC_ARGCHK(inlen > 0);
   LTC_ARGCHK(source <= 255);
   LTC_ARGCHK(pool < LTC_FORTUNA_POOLS);

   LTC_MUTEX_LOCK(&prng->lock);

   err = _fortuna_add(source, pool, in, inlen, prng);

   LTC_MUTEX_UNLOCK(&prng->lock);

   return err;
}

/**
  Add entropy to the PRNG state
  @param in       The data to add
  @param inlen    Length of the data to add
  @param prng     PRNG state to update
  @return CRYPT_OK if successful
*/
int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
{
   int err;

   LTC_ARGCHK(prng != NULL);
   LTC_ARGCHK(in != NULL);
   LTC_ARGCHK(inlen > 0);

   LTC_MUTEX_LOCK(&prng->lock);

   err = _fortuna_add(0, prng->u.fortuna.pool_idx, in, inlen, prng);

   if (err == CRYPT_OK) {
      ++(prng->u.fortuna.pool_idx);
      prng->u.fortuna.pool_idx %= LTC_FORTUNA_POOLS;
   }

   LTC_MUTEX_UNLOCK(&prng->lock);

   return err;
}

/**
  Make the PRNG ready to read from
  @param prng   The PRNG to make active
  @return CRYPT_OK if successful
*/
int fortuna_ready(prng_state *prng)
{
   int err;
   LTC_ARGCHK(prng != NULL);

   LTC_MUTEX_LOCK(&prng->lock);
   /* make sure the reseed doesn't fail because
    * of the chosen rate limit */
#ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED
   prng->u.fortuna.wd = _fortuna_current_time() - 1;
#else
   prng->u.fortuna.wd = LTC_FORTUNA_WD;
#endif
   err = _fortuna_reseed(prng);
   prng->ready = (err == CRYPT_OK) ? 1 : 0;

   LTC_MUTEX_UNLOCK(&prng->lock);
   return err;
}

/**
  Read from the PRNG
  @param out      Destination
  @param outlen   Length of output
  @param prng     The active PRNG to read from
  @return Number of octets read
*/
unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng)
{
   unsigned char tmp[16];
   unsigned long tlen = 0;

   if (outlen == 0 || prng == NULL || out == NULL) return 0;

   LTC_MUTEX_LOCK(&prng->lock);

   if (!prng->ready) {
      goto LBL_UNLOCK;
   }

   /* do we have to reseed? */
   if (prng->u.fortuna.pool0_len >= 64) {
      if (_fortuna_reseed(prng) != CRYPT_OK) {
         goto LBL_UNLOCK;
      }
   }

   /* ensure that one reseed happened before allowing to read */
   if (prng->u.fortuna.reset_cnt == 0) {
      goto LBL_UNLOCK;
   }

   /* now generate the blocks required */
   tlen = outlen;

   /* handle whole blocks without the extra XMEMCPY */
   while (outlen >= 16) {
      /* encrypt the IV and store it */
      rijndael_ecb_encrypt(prng->u.fortuna.IV, out, &prng->u.fortuna.skey);
      out += 16;
      outlen -= 16;
      _fortuna_update_iv(prng);
   }

   /* left over bytes? */
   if (outlen > 0) {
      rijndael_ecb_encrypt(prng->u.fortuna.IV, tmp, &prng->u.fortuna.skey);
      XMEMCPY(out, tmp, outlen);
      _fortuna_update_iv(prng);
   }

   /* generate new key */
   rijndael_ecb_encrypt(prng->u.fortuna.IV, prng->u.fortuna.K   , &prng->u.fortuna.skey);
   _fortuna_update_iv(prng);

   rijndael_ecb_encrypt(prng->u.fortuna.IV, prng->u.fortuna.K+16, &prng->u.fortuna.skey);
   _fortuna_update_iv(prng);

   if (rijndael_setup(prng->u.fortuna.K, 32, 0, &prng->u.fortuna.skey) != CRYPT_OK) {
      tlen = 0;
   }

LBL_UNLOCK:
#ifdef LTC_CLEAN_STACK
   zeromem(tmp, sizeof(tmp));
#endif
   LTC_MUTEX_UNLOCK(&prng->lock);
   return tlen;
}

/**
  Terminate the PRNG
  @param prng   The PRNG to terminate
  @return CRYPT_OK if successful
*/
int fortuna_done(prng_state *prng)
{
   int           err, x;
   unsigned char tmp[32];

   LTC_ARGCHK(prng != NULL);

   LTC_MUTEX_LOCK(&prng->lock);
   prng->ready = 0;

   /* terminate all the hashes */
   for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
       if ((err = sha256_done(&(prng->u.fortuna.pool[x]), tmp)) != CRYPT_OK) {
          goto LBL_UNLOCK;
       }
   }
   /* call cipher done when we invent one ;-) */
   err = CRYPT_OK; /* success */

LBL_UNLOCK:
#ifdef LTC_CLEAN_STACK
   zeromem(tmp, sizeof(tmp));
#endif
   LTC_MUTEX_UNLOCK(&prng->lock);
   LTC_MUTEX_DESTROY(&prng->lock);
   return err;
}

/**
  Export the PRNG state
  @param out       [out] Destination
  @param outlen    [in/out] Max size and resulting size of the state
  @param prng      The PRNG to export
  @return CRYPT_OK if successful
*/
_LTC_PRNG_EXPORT(fortuna)

/**
  Import a PRNG state
  @param in       The PRNG state
  @param inlen    Size of the state
  @param prng     The PRNG to import
  @return CRYPT_OK if successful
*/
int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
{
   int           err;

   LTC_ARGCHK(in    != NULL);
   LTC_ARGCHK(prng  != NULL);

   if (inlen < (unsigned long)fortuna_desc.export_size) {
      return CRYPT_INVALID_ARG;
   }

   if ((err = fortuna_start(prng)) != CRYPT_OK) {
      return err;
   }

   if ((err = fortuna_update_seed(in, inlen, prng)) != CRYPT_OK) {
      return err;
   }

   return err;
}

/**
  PRNG self-test
  @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
*/
int fortuna_test(void)
{
#ifndef LTC_TEST
   return CRYPT_NOP;
#else
   int err;

   if ((err = sha256_test()) != CRYPT_OK) {
      return err;
   }
   return rijndael_test();
#endif
}

#endif


/* ref:         $Format:%D$ */
/* git commit:  $Format:%H$ */
/* commit time: $Format:%ai$ */
