/*
 * Copyright (c) 1997-2007  The Stanford SRP Authentication Project
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
 *
 * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Redistributions in source or binary form must retain an intact copy
 * of this copyright notice.
 */

#include "t_defines.h"

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#ifdef WIN32
#include <process.h>
#include <io.h>
#endif

#include "t_sha.h"

#ifndef NULL
#define NULL 0
#endif

#ifdef OPENSSL
#include <openssl/opensslv.h>
#include <openssl/rand.h>
#elif defined(TOMCRYPT)
#include "tomcrypt.h"
static prng_state g_rng;
static unsigned char entropy[32];
#elif defined(CRYPTOLIB)
# include "libcrypt.h"
static unsigned char crpool[64];
#else
static unsigned char randpool[SHA_DIGESTSIZE], randout[SHA_DIGESTSIZE];
static unsigned long randcnt = 0;
static unsigned int outpos = 0;
SHA1_CTX randctxt;
#endif /* OPENSSL */

/*
 * t_envhash - Generate a 160-bit SHA hash of the environment
 *
 * This routine performs an SHA hash of all the "name=value" pairs
 * in the environment concatenated together and dumps them in the
 * output.  While it is true that anyone on the system can see
 * your environment, someone not on the system will have a very
 * difficult time guessing it, especially since some systems play
 * tricks with variable ordering and sometimes define quirky
 * environment variables like $WINDOWID or $_.
 */
extern char ** environ;

static void
t_envhash(unsigned char * out)
{
  char ** ptr;
  char ebuf[256];
  SHA1_CTX ctxt;

  SHA1Init(&ctxt);
  for(ptr = environ; *ptr; ++ptr) {
    strncpy(ebuf, *ptr, 255);
    ebuf[255] = '\0';
    SHA1Update(&ctxt, ebuf, strlen(ebuf));
  }
  SHA1Final(out, &ctxt);
}

/*
 * t_fshash - Generate a 160-bit SHA hash from the file system
 *
 * This routine climbs up the directory tree from the current
 * directory, running stat() on each directory until it hits the
 * root directory.  This information is sensitive to the last
 * access/modification times of all the directories above you,
 * so someone who lists one of those directories injects some
 * entropy into the system.  Obviously, this hash is very sensitive
 * to your current directory when the program is run.
 *
 * For good measure, it also performs an fstat on the standard input,
 * usually your tty, throws that into the buffer, creates a file in
 * /tmp (the inode is unpredictable on a busy system), and runs stat()
 * on that before deleting it.
 *
 * The entire buffer is run once through SHA to obtain the final result.
 */
static void
t_fshash(unsigned char * out)
{
  char dotpath[128];
  struct stat st;
  SHA1_CTX ctxt;
  int i, pinode;
  dev_t pdev;

  SHA1Init(&ctxt);
  if(stat(".", &st) >= 0) {
    SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
    pinode = st.st_ino;
    pdev = st.st_dev;
    strcpy(dotpath, "..");
    for(i = 0; i < 40; ++i) {
      if(stat(dotpath, &st) < 0)
	break;
      if(st.st_ino == pinode && st.st_dev == pdev)
	break;
      SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
      pinode = st.st_ino;
      pdev = st.st_dev;
      strcat(dotpath, "/..");
    }
  }

  if(fstat(0, &st) >= 0)
    SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));

  sprintf(dotpath, "/tmp/rnd.%d", getpid());
  if(creat(dotpath, 0600) >= 0 && stat(dotpath, &st) >= 0)
    SHA1Update(&ctxt, (unsigned char *) &st, sizeof(st));
  unlink(dotpath);

  SHA1Final(out, &ctxt);
}

/*
 * Generate a high-entropy seed for the strong random number generator.
 * This uses a wide variety of quickly gathered and somewhat unpredictable
 * system information.  The 'preseed' structure is assembled from:
 *
 *   The system time in seconds
 *   The system time in microseconds
 *   The current process ID
 *   The parent process ID
 *   A hash of the user's environment
 *   A hash gathered from the file system
 *   Input from a random device, if available
 *   Timings of system interrupts
 *
 * The entire structure (60 bytes on most systems) is fed to SHA to produce
 * a 160-bit seed for the strong random number generator.  It is believed
 * that in the worst case (on a quiet system with no random device versus
 * an attacker who has access to the system already), the seed contains at
 * least about 80 bits of entropy.  Versus an attacker who does not have
 * access to the system, the entropy should be slightly over 128 bits.
 */
static char initialized = 0;

static struct {
  unsigned int trand1;
  time_t sec;
  time_t subsec;
  short pid;
  short ppid;
  unsigned char envh[SHA_DIGESTSIZE];
  unsigned char fsh[SHA_DIGESTSIZE];
  unsigned char devrand[20];
  unsigned int trand2;
} preseed;

unsigned long raw_truerand();

static void
t_initrand()
{
  SHA1_CTX ctxt;
#ifdef USE_FTIME
  struct timeb t;
#else
  struct timeval t;
#endif
  int i, r=0;

  if(initialized)
    return;

  initialized = 1;

#if defined(OPENSSL)	/* OpenSSL has nifty win32 entropy-gathering code */
#if OPENSSL_VERSION_NUMBER >= 0x00905100
  r = RAND_status();
#if defined(WINDOWS) || defined(WIN32)
  if(r)		/* Don't do the Unix-y stuff on Windows if possible */
    return;
#else
#endif
#endif

#elif defined(TOMCRYPT)
  yarrow_start(&g_rng);
  r = rng_get_bytes(entropy, sizeof(entropy), NULL);
  if(r > 0) {
    yarrow_add_entropy(entropy, r, &g_rng);
    memset(entropy, 0, sizeof(entropy));
# if defined(WINDOWS) || defined(WIN32)
    /* Don't do the Unix-y stuff on Windows if possible */
    yarrow_ready(&g_rng);
    return;
# endif
  }
#endif

#if !defined(WINDOWS) && !defined(WIN32)
  i = open("/dev/urandom", O_RDONLY);
  if(i > 0) {
    r += read(i, preseed.devrand, sizeof(preseed.devrand));
    close(i);
  }
#endif /* !WINDOWS && !WIN32 */

  /* Resort to truerand only if desperate for some Real entropy */
  if(r == 0)
    preseed.trand1 = raw_truerand();

#ifdef USE_FTIME
  ftime(&t);
  preseed.sec = t.time;
  preseed.subsec = t.millitm;
#else
  gettimeofday(&t, NULL);
  preseed.sec = t.tv_sec;
  preseed.subsec = t.tv_usec;
#endif
  preseed.pid = getpid();
#ifndef WIN32
  preseed.ppid = getppid();
#endif
  t_envhash(preseed.envh);
  t_fshash(preseed.fsh);

  if(r == 0)
    preseed.trand2 = raw_truerand();

#ifdef OPENSSL
  RAND_seed((unsigned char *)&preseed, sizeof(preseed));
#elif defined(TOMCRYPT)
  yarrow_add_entropy((unsigned char *)&preseed, sizeof(preseed), &g_rng);
  yarrow_ready(&g_rng);
#elif defined(CRYPTOLIB)
  t_mgf1(crpool, sizeof(crpool), (unsigned char *) &preseed, sizeof(preseed));
  seedDesRandom(crpool, sizeof(crpool));
  memset(crpool, 0, sizeof(crpool));
#elif defined(GCRYPT)
  gcry_random_add_bytes((unsigned char *)&preseed, sizeof(preseed), -1);
#else
  SHA1Init(&ctxt);
  SHA1Update(&ctxt, (unsigned char *) &preseed, sizeof(preseed));
  SHA1Final(randpool, &ctxt);
  memset((unsigned char *) &ctxt, 0, sizeof(ctxt));
  outpos = 0;
#endif /* OPENSSL */
  memset((unsigned char *) &preseed, 0, sizeof(preseed));
}

#define NUM_RANDOMS 12

_TYPE( void )
t_stronginitrand()
{
#if 1	/* t_initrand() has been improved enough to make this unnecessary */
  t_initrand();
#else
  SHA1_CTX ctxt;
  unsigned int rawrand[NUM_RANDOMS];
  int i;

  if(!initialized)
    t_initrand();
  for(i = 0; i < NUM_RANDOMS; ++i)
    rawrand[i] = raw_truerand();
  SHA1Init(&ctxt);
  SHA1Update(&ctxt, (unsigned char *) rawrand, sizeof(rawrand));
  SHA1Final(randkey2, &ctxt);
  memset(rawrand, 0, sizeof(rawrand));
#endif
}

/*
 * The strong random number generator.  This uses a 160-bit seed
 * and uses SHA-1 in a feedback configuration to generate successive
 * outputs.  If S[0] is set to the initial seed, then:
 *
 *         S[i+1] = SHA-1(i || S[i])
 *         A[i] = SHA-1(S[i])
 *
 * where the A[i] are the output blocks starting with i=0.
 * Each cycle generates 20 bytes of new output.
 */
_TYPE( void )
t_random(unsigned char * data, unsigned size)
{
  if(!initialized)
    t_initrand();

  if(size <= 0)		/* t_random(NULL, 0) forces seed initialization */
    return;

#ifdef OPENSSL
  RAND_bytes(data, size);
#elif defined(TOMCRYPT)
  yarrow_read(data, size, &g_rng);
#elif defined(GCRYPT)
  gcry_randomize(data, size, GCRY_STRONG_RANDOM);
#elif defined(CRYPTOLIB)
  randomBytes(data, size, PSEUDO);
#else
  while(size > outpos) {
    if(outpos > 0) {
      memcpy(data, randout + (sizeof(randout) - outpos), outpos);
      data += outpos;
      size -= outpos;
    }

    /* Recycle */
    SHA1Init(&randctxt);
    SHA1Update(&randctxt, randpool, sizeof(randpool));
    SHA1Final(randout, &randctxt);
    SHA1Init(&randctxt);
    SHA1Update(&randctxt, (unsigned char *) &randcnt, sizeof(randcnt));
    SHA1Update(&randctxt, randpool, sizeof(randpool));
    SHA1Final(randpool, &randctxt);
    ++randcnt;
    outpos = sizeof(randout);
  }

  if(size > 0) {
    memcpy(data, randout + (sizeof(randout) - outpos), size);
    outpos -= size;
  }
#endif
}

/*
 * The interleaved session-key hash.  This separates the even and the odd
 * bytes of the input (ignoring the first byte if the input length is odd),
 * hashes them separately, and re-interleaves the two outputs to form a
 * single 320-bit value.
 */
_TYPE( unsigned char * )
t_sessionkey(unsigned char * key, unsigned char * sk, unsigned sklen)
{
  unsigned i, klen;
  unsigned char * hbuf;
  unsigned char hout[SHA_DIGESTSIZE];
  SHA1_CTX ctxt;

  while(sklen > 0 && *sk == 0) {	/* Skip leading 0's */
    --sklen;
    ++sk;
  }

  klen = sklen / 2;
  if((hbuf = malloc(klen * sizeof(char))) == 0)
    return 0;

  for(i = 0; i < klen; ++i)
    hbuf[i] = sk[sklen - 2 * i - 1];
  SHA1Init(&ctxt);
  SHA1Update(&ctxt, hbuf, klen);
  SHA1Final(hout, &ctxt);
  for(i = 0; i < sizeof(hout); ++i)
    key[2 * i] = hout[i];

  for(i = 0; i < klen; ++i)
    hbuf[i] = sk[sklen - 2 * i - 2];
  SHA1Init(&ctxt);
  SHA1Update(&ctxt, hbuf, klen);
  SHA1Final(hout, &ctxt);
  for(i = 0; i < sizeof(hout); ++i)
    key[2 * i + 1] = hout[i];

  memset(hout, 0, sizeof(hout));
  memset(hbuf, 0, klen);
  free(hbuf);
  return key;
}

_TYPE( void )
t_mgf1(unsigned char * mask, unsigned masklen, const unsigned char * seed, unsigned seedlen)
{
  SHA1_CTX ctxt;
  unsigned i = 0;
  unsigned pos = 0;
  unsigned char cnt[4];
  unsigned char hout[SHA_DIGESTSIZE];

  while(pos < masklen) {
    cnt[0] = (i >> 24) & 0xFF;
    cnt[1] = (i >> 16) & 0xFF;
    cnt[2] = (i >> 8) & 0xFF;
    cnt[3] = i & 0xFF;
    SHA1Init(&ctxt);
    SHA1Update(&ctxt, seed, seedlen);
    SHA1Update(&ctxt, cnt, 4);

    if(pos + SHA_DIGESTSIZE > masklen) {
      SHA1Final(hout, &ctxt);
      memcpy(mask + pos, hout, masklen - pos);
      pos = masklen;
    }
    else {
      SHA1Final(mask + pos, &ctxt);
      pos += SHA_DIGESTSIZE;
    }

    ++i;
  }

  memset(hout, 0, sizeof(hout));
  memset((unsigned char *)&ctxt, 0, sizeof(ctxt));
}
