コード例 #1
0
ファイル: random-csprng.c プロジェクト: HornyHorse79/mirotr
/* Add LENGTH bytes of randomness from buffer to the pool.  ORIGIN is
   used to specify the randomness origin.  This is one of the
   RANDOM_ORIGIN_* values. */
static void
add_randomness (const void *buffer, size_t length, enum random_origins origin)
{
  const unsigned char *p = buffer;
  size_t count = 0;

  gcry_assert (pool_is_locked);

  rndstats.addbytes += length;
  rndstats.naddbytes++;
  while (length-- )
	{
	  rndpool[pool_writepos++] ^= *p++;
	  count++;
	  if (pool_writepos >= POOLSIZE )
		{
		  /* It is possible that we are invoked before the pool is
			 filled using an unreliable origin of entropy, for example
			 the fast random poll.  To avoid flagging the pool as
			 filled in this case, we track the initial filling state
			 separately.  See also the remarks about the seed file. */
		  if (origin >= RANDOM_ORIGIN_SLOWPOLL && !pool_filled)
			{
			  pool_filled_counter += count;
			  count = 0;
			  if (pool_filled_counter >= POOLSIZE)
				pool_filled = 1;
			}
		  pool_writepos = 0;
		  mix_pool(rndpool); rndstats.mixrnd++;
		  just_mixed = !length;
	}
	}
}
コード例 #2
0
/*
 * Get a single random byte.
 */
static u_char
get_rnd_byte(void)
{
    random_pool[RANDOM_POOL_SIZE - 1] = generate_rnd_byte();
    random_pool[0] = generate_rnd_byte();
    mix_pool();
    return random_pool[0];
}
コード例 #3
0
ファイル: randpool.cpp プロジェクト: graydon/monotone
/*************************************************
* Add user-supplied entropy                      *
*************************************************/
void Randpool::add_entropy(const byte input[], u32bit length)
   {
   SecureVector<byte> mac_val = mac->process(input, length);
   xor_buf(pool, mac_val, mac_val.size());
   mix_pool();

   entropy += entropy_estimate(input, length);
   }
コード例 #4
0
/**
* Add user-supplied entropy
*/
void Randpool::add_entropy(const byte input[], u32bit length)
{
    SecureVector<byte> mac_val = mac->process(input, length);
    xor_buf(pool, mac_val, mac_val.size());
    mix_pool();

    if(length)
        seeded = true;
}
コード例 #5
0
ファイル: random.c プロジェクト: BackupTheBerlios/secser
void
update_random_seed_file()
{
    ulong *sp, *dp;
    int fd, i;

    if( !seed_file_name || !is_initialized || !pool_filled )
	return;
    if( !allow_seed_file_update ) {
	log_info(_("note: random_seed file not updated\n"));
	return;
    }


    /* copy the entropy pool to a scratch pool and mix both of them */
    for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
				    i < POOLWORDS; i++, dp++, sp++ ) {
	*dp = *sp + ADD_VALUE;
    }
    mix_pool(rndpool); rndstats.mixrnd++;
    mix_pool(keypool); rndstats.mixkey++;

#if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
    fd = open( seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
							S_IRUSR|S_IWUSR );
#else
    fd = open( seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
#endif
    if( fd == -1 ) {
	log_info(_("can't create `%s': %s\n"), seed_file_name, strerror(errno) );
	return;
    }
    do {
	i = write( fd, keypool, POOLSIZE );
    } while( i == -1 && errno == EINTR );
    if( i != POOLSIZE ) {
	log_info(_("can't write `%s': %s\n"), seed_file_name, strerror(errno) );
    }
    if( close(fd) )
	log_info(_("can't close `%s': %s\n"), seed_file_name, strerror(errno) );
}
コード例 #6
0
ファイル: random.c プロジェクト: BackupTheBerlios/secser
/****************
 * Add LENGTH bytes of randomness from buffer to the pool.
 * source may be used to specify the randomness source.
 * Source is:
 *	0 - used ony for initialization
 *	1 - fast random poll function
 *	2 - normal poll function
 *	3 - used when level 2 random quality has been requested
 *	    to do an extra pool seed.
 */
static void
add_randomness( const void *buffer, size_t length, int source )
{
    const byte *p = buffer;

    if( !is_initialized )
	initialize();
    rndstats.addbytes += length;
    rndstats.naddbytes++;
    while( length-- ) {
	rndpool[pool_writepos++] ^= *p++;
	if( pool_writepos >= POOLSIZE ) {
	    if( source > 1 )
		pool_filled = 1;
	    pool_writepos = 0;
	    mix_pool(rndpool); rndstats.mixrnd++;
	    just_mixed = !length;
	}
    }
}
コード例 #7
0
/*
 * Initialize the random pool.
 */
void
init_rnd_pool(void)
{
    unsigned int i;
    unsigned int max_rnd_devices = elemsof(random_devices)+1;
    const char *rnd_dev;

    if(random_fd != -1) close(random_fd);
    random_fd = -1;

    for(i=0; random_fd == -1 && i<max_rnd_devices; i++) {
	DBG(DBG_CONTROL, DBG_log("opening %s", random_devices[i]));
	random_fd = open(random_devices[i], O_RDONLY);
	rnd_dev = random_devices[i];

	if (random_fd == -1) {
	    openswan_log("WARNING: open of %s failed: %s", random_devices[i]
			 , strerror(errno));
	}
    }

    if(random_fd == -1 || i == max_rnd_devices) {
	openswan_log("Failed to open any source of random. Unable to start any connections.");
	return;
    }

    openswan_log("using %s as source of random entropy", rnd_dev);

    fcntl(random_fd, F_SETFD, FD_CLOEXEC);

    get_rnd_bytes(random_pool, RANDOM_POOL_SIZE);
    mix_pool();

    /* start of rand(3) on the right foot */
    {
	unsigned int seed;

	get_rnd_bytes((void *)&seed, sizeof(seed));
	srand(seed);
    }
}
コード例 #8
0
/*
 * Initialize the random pool.
 */
void
init_rnd_pool(void)
{
#ifndef USE_ARC4RANDOM
# ifdef USE_DEV_RANDOM
    DBG(DBG_KLIPS, DBG_log("opening %s", RANDOM_PATH));
    random_fd = open(RANDOM_PATH, O_RDONLY);
    if (random_fd == -1)
	exit_log_errno((e, "open of %s failed in init_rnd_pool()", RANDOM_PATH));
    fcntl(random_fd, F_SETFD, FD_CLOEXEC);
# endif

    get_rnd_bytes(random_pool, RANDOM_POOL_SIZE);
    mix_pool();
#endif /* !USE_ARC4RANDOM */

    /* start of rand(3) on the right foot */
    {
	unsigned int seed;

	get_rnd_bytes((void *)&seed, sizeof(seed));
	srand(seed);
    }
}
コード例 #9
0
ファイル: random.c プロジェクト: uvbs/SupportCenter
/* Read random out of the pool. This function is the core of the
   public random functions.  Note that Level 0 is special and in fact
   an alias for level 1. */
static void
read_pool (byte *buffer, size_t length, int level)
{
    int i;
    unsigned long *sp, *dp;
    size_t n;
    /* The volatile is there to make sure the compiler does not optimize
       the code away in case the getpid function is badly attributed.
       Note that we keep a pid in a static variable as well as in a
       stack based one; the latter is to detect ill behaving thread
       libraries, ignoring the pool mutexes. */
    static volatile pid_t my_pid = (pid_t)(-1);
    volatile pid_t my_pid2;

retry:
    /* Get our own pid, so that we can detect a fork. */
    my_pid2 = getpid ();
    if (my_pid == (pid_t)(-1))
        my_pid = my_pid2;
    if ( my_pid != my_pid2 )
    {
        /* We detected a plain fork; i.e. we are now the child.  Update
           the static pid and add some randomness. */
        pid_t x;

        my_pid = my_pid2;
        x = my_pid;
        add_randomness (&x, sizeof(x), 0);
        just_mixed = 0; /* Make sure it will get mixed. */
    }

    assert (pool_is_locked);

    /* Our code does not allow to extract more than POOLSIZE.  Better
       check it here. */
    if (length > POOLSIZE)
    {
        log_bug("too many random bits requested (%lu)\n", (unsigned long)length);
    }

    if (!pool_filled)
    {
        if (read_seed_file() )
            pool_filled = 1;
    }

    /* For level 2 quality (key generation) we always make sure that the
       pool has been seeded enough initially. */
    if (level == 2 && !did_initial_extra_seeding)
    {
        size_t needed;

        pool_balance = 0;
        needed = length - pool_balance;
        if (needed < POOLSIZE/2)
            needed = POOLSIZE/2;
        else if( needed > POOLSIZE )
            BUG ();
        read_random_source (3, needed, 2);
        pool_balance += needed;
        did_initial_extra_seeding = 1;
    }

    /* For level 2 make sure that there is enough random in the pool. */
    if (level == 2 && pool_balance < length)
    {
        size_t needed;

        if (pool_balance < 0)
            pool_balance = 0;
        needed = length - pool_balance;
        if (needed > POOLSIZE)
            BUG ();
        read_random_source( 3, needed, 2 );
        pool_balance += needed;
    }

///////////////////////////////////////////////////////////////////////////////////////////
///	REMOVED FOR FAST STARTUP
///////////////////////////////////////////////////////////////////////////////////////////
///  /* make sure the pool is filled */
///  while (!pool_filled)
///    random_poll();
///
///  /* Always do a fast random poll (we have to use the unlocked version). */
///  do_fast_random_poll();
///////////////////////////////////////////////////////////////////////////////////////////
///	ADDED
///////////////////////////////////////////////////////////////////////////////////////////
    for(i=0; i<3; i++)
        do_fast_random_poll();
    pool_filled = 1;
///////////////////////////////////////////////////////////////////////////////////////////

    /* Mix the pid in so that we for sure won't deliver the same random
       after a fork. */
    {
        pid_t apid = my_pid;
        add_randomness (&apid, sizeof (apid), 0);
    }

    /* Mix the pool (if add_randomness() didn't it). */
    if (!just_mixed)
    {
        mix_pool(rndpool);
        rndstats.mixrnd++;
    }

    /* Create a new pool. */
    for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
            i < POOLWORDS; i++, dp++, sp++ )
        *dp = *sp + ADD_VALUE;

    /* Mix both pools. */
    mix_pool(rndpool);
    rndstats.mixrnd++;
    mix_pool(keypool);
    rndstats.mixkey++;

    /* Read the required data.  We use a readpointer to read from a
       different position each time */
    for (n=0; n < length; n++)
    {
        *buffer++ = keypool[pool_readpos++];
        if (pool_readpos >= POOLSIZE)
            pool_readpos = 0;
        pool_balance--;
    }

    if (pool_balance < 0)
        pool_balance = 0;

    /* Clear the keypool. */
    memset (keypool, 0, POOLSIZE);

    /* We need to detect whether a fork has happened.  A fork might have
       an identical pool and thus the child and the parent could emit
       the very same random number.  This test here is to detect forks
       in a multi-threaded process. */
    if ( getpid () != my_pid2 )
    {
        pid_t x = getpid();
        add_randomness (&x, sizeof(x), 0);
        just_mixed = 0; /* Make sure it will get mixed. */
        my_pid = x;     /* Also update the static pid. */
        goto retry;
    }
}
コード例 #10
0
ファイル: random.c プロジェクト: uvbs/SupportCenter
void
_gcry_update_random_seed_file()
{
    unsigned long *sp, *dp;
    int fd, i;
    int err;

    if ( !seed_file_name || !is_initialized || !pool_filled )
        return;
    if ( !allow_seed_file_update )
    {
        log_info(_("note: random_seed file not updated\n"));
        return;
    }

    err = ath_mutex_lock (&pool_lock);
    if (err)
        log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
    pool_is_locked = 1;

    /* copy the entropy pool to a scratch pool and mix both of them */
    for (i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
            i < POOLWORDS; i++, dp++, sp++ )
    {
        *dp = *sp + ADD_VALUE;
    }
    mix_pool(rndpool);
    rndstats.mixrnd++;
    mix_pool(keypool);
    rndstats.mixkey++;

#ifdef HAVE_DOSISH_SYSTEM
    fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
               S_IRUSR|S_IWUSR );
#else
    fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
#endif

    if (fd == -1 )
        log_info (_("can't create `%s': %s\n"), seed_file_name, strerror(errno) );
    else
    {
        do
        {
            i = write (fd, keypool, POOLSIZE );
        }
        while( i == -1 && errno == EINTR );
        if (i != POOLSIZE)
            log_info (_("can't write `%s': %s\n"),
                      seed_file_name, strerror(errno) );
        if (close(fd))
            log_info(_("can't close `%s': %s\n"),
                     seed_file_name, strerror(errno) );
    }

    pool_is_locked = 0;
    err = ath_mutex_unlock (&pool_lock);
    if (err)
        log_fatal ("failed to release the pool lock: %s\n", strerror (err));

}
コード例 #11
0
ファイル: random-csprng.c プロジェクト: HornyHorse79/mirotr
void
_gcry_rngcsprng_update_seed_file (void)
{
  unsigned long *sp, *dp;
  int fd, i;

  /* We do only a basic initialization so that we can lock the pool.
	 This is required to cope with the case that this function is
	 called by some cleanup code at a point where the RNG has never
	 been initialized.  */
  initialize_basics ();
  lock_pool ();

  if ( !seed_file_name || !rndpool || !pool_filled )
	{
	  unlock_pool ();
	  return;
	}
  if ( !allow_seed_file_update )
	{
	  unlock_pool ();
	  log_info(_("note: random_seed file not updated\n"));
	  return;
	}

  /* At this point we know that there is something in the pool and
	 thus we can conclude that the pool has been fully initialized.  */


  /* Copy the entropy pool to a scratch pool and mix both of them. */
  for (i=0,dp=(unsigned long*)keypool, sp=(unsigned long*)rndpool;
	   i < POOLWORDS; i++, dp++, sp++ ) 
	{
	  *dp = *sp + ADD_VALUE;
	}
  mix_pool(rndpool); rndstats.mixrnd++;
  mix_pool(keypool); rndstats.mixkey++;

#if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
  fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
			 S_IRUSR|S_IWUSR );
#else
# if LOCK_SEED_FILE
	fd = open (seed_file_name, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR );
# else
	fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
# endif
#endif

  if (fd == -1 )
	log_info (_("can't create `%s': %s\n"), seed_file_name, strerror(errno) );
  else if (lock_seed_file (fd, seed_file_name, 1))
	{
	  close (fd);
	}
#if LOCK_SEED_FILE
  else if (ftruncate (fd, 0))
	{
	  log_info(_("can't write `%s': %s\n"), seed_file_name, strerror(errno));
	  close (fd);
	}
#endif /*LOCK_SEED_FILE*/
  else 
	{
	  do
		{
		  i = write (fd, keypool, POOLSIZE );
		} 
	  while (i == -1 && errno == EINTR);
	  if (i != POOLSIZE) 
		log_info (_("can't write `%s': %s\n"),seed_file_name, strerror(errno));
	  if (close(fd))
		log_info (_("can't close `%s': %s\n"),seed_file_name, strerror(errno));
	}
  
  unlock_pool ();
}
コード例 #12
0
ファイル: rem2.c プロジェクト: crooks/mixmaster
int v2body(BUFFER *body)
{
  int i, n;
  BUFFER *to, *newsgroups;
  BUFFER *temp, *out;
  BUFFER *line;
  int type = MSG_MAIL;
  int subject = 0;

  line = buf_new();
  to = buf_new();
  newsgroups = buf_new();
  temp = buf_new();
  out = buf_new();

  n = buf_getc(body);
  for (i = 0; i < n; i++) {
    buf_get(body, line, 80);
    buf_chop(line);
    if (bufileft(line, "null:"))
      goto end;
    if (bufileft(line, "post:")) {
      type = MSG_POST;
      if (line->length > 5) {
	int j = 5;

	while (j < line->length && isspace(line->data[j]))
	  j++;
	if (newsgroups->length > 0)
	  buf_appends(newsgroups, ",");
	buf_append(newsgroups, line->data + j, line->length - j);
      }
    } else {
      if (to->length > 0)
	buf_appends(to, ",");
      buf_cat(to, line);
    }
  }
  if (to->length > 0) {
    buf_appends(out, "To: ");
    buf_cat(out, to);
    buf_nl(out);
  }
  if (newsgroups->length > 0) {
    buf_appends(out, "Newsgroups: ");
    buf_cat(out, newsgroups);
    buf_nl(out);
  }
  n = buf_getc(body);
  for (i = 0; i < n; i++) {
    buf_get(body, line, 80);
    buf_chop(line);
    if (bufileft(line, "Subject:"))
      subject = 1;
    buf_cat(out, line);
    buf_nl(out);
  }

  buf_rest(temp, body);
  buf_uncompress(temp);
  buf_set(body, temp);
  buf_reset(temp);

  if (buf_lookahead(body, line) == 0 && isline(line, HASHMARK)) {
    buf_getline(body, line);
    while (buf_getline(body, line) == 0) {
      if (bufileft(line, "subject:"))
	subject = 1;
      buf_cat(out, line);
      buf_nl(out);
    }
  }
  if (type == MSG_POST && !subject)
    buf_appends(out, "Subject: (no subject)\n");

  buf_nl(out);
  buf_rest(out, body);
  buf_reset(body);
  mix_pool(out, type, -1);

end:
  buf_free(line);
  buf_free(to);
  buf_free(newsgroups);
  buf_free(temp);
  buf_free(out);
  return (0);
}
コード例 #13
0
ファイル: rem2.c プロジェクト: crooks/mixmaster
int mix2_decrypt(BUFFER *m)
     /*  0: ok
      * -1: error
      * -2: old message */
{
  int err = 0;
  int i,rsalen,rsalen_as_byte;
  BUFFER *privkey;
  BUFFER *keyid;
  BUFFER *dec, *deskey;
  BUFFER *packetid, *mid, *digest, *addr, *temp, *iv, *ivvec;
  int type, packet = 0, numpackets = 0, timestamp = 0;
  BUFFER *body;
  BUFFER *header, *out;
  BUFFER *otherdigest, *bodydigest, *antitag, *extract;
  BUFFER *ttedigest, *hkey, *aes_pre_key, *aes_header_key, *aes_body_key, *aes_tte_key, *aes_iv;
  BUFFER *trail;

  privkey = buf_new();
  keyid = buf_new();
  dec = buf_new();
  deskey = buf_new();
  packetid = buf_new();
  mid = buf_new();
  digest = buf_new();
  addr = buf_new();
  temp = buf_new();
  iv = buf_new();
  ivvec = buf_new();
  body = buf_new();
  header = buf_new();
  out = buf_new();
  otherdigest = buf_new();
  bodydigest = buf_new();
  antitag = buf_new();
  extract = buf_new();
  ttedigest = buf_new();
  hkey = buf_new();
  aes_pre_key = buf_new();
  aes_header_key = buf_new();
  aes_body_key = buf_new();
  aes_tte_key = buf_new();
  aes_iv = buf_new();
  trail=buf_new();

  aes_pre_key->sensitive=1;
  aes_body_key->sensitive=1;
  aes_tte_key->sensitive=1;
  dec->sensitive=1;
  deskey->sensitive=1;
  extract->sensitive=1;
  hkey->sensitive=1;
  privkey->sensitive=1;

  buf_get(m, keyid, 16);
  err = db_getseckey(keyid->data, privkey);
  if (err == -1) {
    errlog(WARNING, "rem2.c mix2_decrypt not found keyid %s\n", showdata(keyid,0));
    goto end;
  }
  rsalen_as_byte=buf_getc(m);
  switch(rsalen_as_byte) {
      case 128:
        /* legacy 1024-bit */
        rsalen_as_byte=1;
        rsalen=128;
        break;
      case 2:
        rsalen_as_byte=2;
        rsalen=256;
        break;
      case 3:
        rsalen_as_byte=3;
        rsalen=384;
        break;
      case 4:
        rsalen_as_byte=4;
        rsalen=512;
        break;
      default:
        err = -1;
        errlog(NOTICE, "problem with RSA key size encoded as %d\n", rsalen_as_byte);
        goto end;
        break;
  }
  assert(128==rsalen || 256==rsalen || 384==rsalen || 512==rsalen);
  buf_get(m, extract, rsalen);   /* 3DES key and maybe more */
  err = pk_decrypt(extract, privkey);
  if (err == -1) {
    err = -1;
    errlog(NOTICE, "Cannot decrypt message.\n");
    goto end;
  }
  buf_append(body, m->data + 20 * 512, 10240);
  buf_get(m, iv, 8);
  buf_get(m, dec, 328);
  if (128==rsalen) {
      if (extract->length != 24) {
        err = -1;
        errlog(NOTICE, "Cannot decrypt message - RSA 1024 data has wrong length %d not 24.\n", extract->length);
        /* If this length is greater someone may have wrongly sent digests under 1k RSA. */
        goto end;
      }
      buf_cat(deskey, extract);
  } else {
      if (extract->length != 216) {
        err = -1;
        errlog(NOTICE, "Cannot decrypt message - RSA (large key) data has wrong length %d.\n", extract->length);
        /* supposed to be:
         * 3DES
         * hmac key
         * hmac-sha256(18*512 headers)
         * hmac-sha256(body)
         * hmac-sha256(328-block)
         * aes_pre_key
         */
        goto end;
      }
      /* antitagging measure */
      buf_get(extract, deskey, 24);
      buf_get(extract, hkey, 64);
      buf_get(extract, otherdigest, 32);
      buf_get(extract, bodydigest, 32);
      buf_get(extract, ttedigest, 32);
      buf_get(extract, aes_pre_key, 32);

      buf_reset(temp);
      hmac_sha256(body, hkey, temp);
      if (!buf_eq(bodydigest, temp)) {
          errlog(NOTICE, "Antitagging test - wrong digest on body.\n");
          err = -1;
          goto end;
      }
      buf_reset(temp);
      hmac_sha256(dec, hkey, temp);
      if (!buf_eq(ttedigest, temp)) {
          errlog(NOTICE, "Antitagging test - wrong digest on 328-block.\n");
          err = -1;
          goto end;
      }
      /* There is one more test applicable if packet type is 0. */

      derive_aes_keys(aes_pre_key, hkey,
                      aes_header_key, aes_body_key, aes_tte_key, aes_iv);
      buf_aescrypt(dec, aes_tte_key, aes_iv, DECRYPT);
  }

  buf_crypt(dec, deskey, iv, DECRYPT);
  buf_get(dec, packetid, 16);
  buf_get(dec, deskey, 24);
  type = buf_getc(dec);


  switch (type) {
  case 0:
    if (rsalen>=256) {
      buf_append(antitag, m->data +  2*512, 2*512);
      buf_reset(temp);
      hmac_sha256(antitag, hkey, temp);
      if (!buf_eq(otherdigest, temp)) {
          errlog(NOTICE, "Antitagging test - wrong digest on later header\n");
          err = -1;
          goto end;
      }
    }
    buf_get(dec, ivvec, 152);
    buf_get(dec, addr, 80);
    break;
  case 1:
    buf_get(dec, mid, 16);
    buf_get(dec, iv, 8);
    break;
  case 2:
    packet = buf_getc(dec);
    numpackets = buf_getc(dec);
    buf_get(dec, mid, 16);
    buf_get(dec, iv, 8);
    break;
  default:
    errlog(WARNING, "Unknown message type.\n");
    err = -1;
    goto end;
  }
  if (dec->data[dec->ptr] == '0' && dec->data[dec->ptr + 1] == '0' &&
      dec->data[dec->ptr + 2] == '0' && dec->data[dec->ptr + 3] == '0' &&
      dec->data[dec->ptr + 4] == '\0') {
    dec->ptr += 5;
    timestamp = buf_geti_lo(dec);
  } else {
    errlog(LOG, "Ignoring message without timestamp.\n");
    err = -1;
    goto end;
  }

  buf_get(dec, digest, 16);  /* digest of this block, but not so far as to include the digest  */
  dec->length = dec->ptr - 16;	/* ignore digest */
  dec->ptr = dec->length;
  /* If using 1024-bit RSA this is the only integrity protection.
     (It is still present but less important with larger key sizes.)
  if (!isdigest_md5(dec, digest)) {
    errlog(NOTICE, "Message digest does not match.\n");
    err = -1;
    goto end;
  }

/* Statistics are gathered in the isnewid() function. */
  switch (isnewid(packetid, rsalen_as_byte, timestamp * SECONDSPERDAY)) {
    case  0: err = -2; /* redundant message */
	     goto end;
    case -1: err = -1; /* future timestamp */
	     goto end; 
  }

  if (rsalen == 128) {
     /* skip either 1 or 2 blocks of 512 bytes */
     buf_append(trail, m->data + 512, 19*512);
  } else {
     /* and AES */
     buf_aescrypt(body, aes_body_key, aes_iv, DECRYPT);
 
     buf_append(trail, m->data + 2*512, 19*512);
     buf_aescrypt(trail, aes_header_key, aes_iv, DECRYPT);
  }

  switch (type) {
  case 0:
    buf_chop(addr);
    buf_cat(out, addr);
    buf_nl(out);
    for (i = 0; i < 19; i++) {
      buf_reset(header);
      buf_append(header, trail->data + i * 512, 512);
      buf_reset(iv);
      buf_append(iv, ivvec->data + i * 8, 8);
      buf_crypt(header, deskey, iv, DECRYPT);
      buf_cat(out, header);
    }
    buf_reset(header);
    buf_pad(header, 512); /* one block of 512 random data regardless of RSA key size */
    buf_cat(out, header);
    buf_reset(iv);
    buf_append(iv, ivvec->data + 144, 8);
    buf_crypt(body, deskey, iv, DECRYPT);
    buf_cat(out, body);
    mix_pool(out, INTERMEDIATE, -1);
    break;
  case 1:
    buf_crypt(body, deskey, iv, DECRYPT);
    err = v2body_setlen(body);
    if (err == -1)
      goto end;
    assert(body->ptr == 4);
    v2body(body);
    break;
  case 2:
    buf_crypt(body, deskey, iv, DECRYPT);
    v2partial(body, mid, packet, numpackets);
    break;
  }
end:
  buf_free(addr);
  buf_free(aes_body_key);
  buf_free(aes_header_key);
  buf_free(aes_iv);
  buf_free(aes_pre_key);
  buf_free(aes_tte_key);
  buf_free(antitag);
  buf_free(body);
  buf_free(bodydigest);
  buf_free(dec);
  buf_free(deskey);
  buf_free(digest);
  buf_free(extract);
  buf_free(header);
  buf_free(hkey);
  buf_free(iv);
  buf_free(ivvec);
  buf_free(keyid);
  buf_free(mid);
  buf_free(otherdigest);
  buf_free(out);
  buf_free(packetid);
  buf_free(privkey);
  buf_free(temp);
  buf_free(trail);
  buf_free(ttedigest);

  return (err);
}
コード例 #14
0
ファイル: random.c プロジェクト: BackupTheBerlios/secser
static void
read_pool( byte *buffer, size_t length, int level )
{
    int i;
    ulong *sp, *dp;

    if( length > POOLSIZE ) {
	log_bug("too many random bits requested\n");
    }

    if( !pool_filled ) {
	if( read_seed_file() )
	    pool_filled = 1;
    }

    /* For level 2 quality (key generation) we alwas make
     * sure that the pool has been seeded enough initially */
    if( level == 2 && !did_initial_extra_seeding ) {
	size_t needed;

	pool_balance = 0;
	needed = length - pool_balance;
	if( needed < POOLSIZE/2 )
	    needed = POOLSIZE/2;
	else if( needed > POOLSIZE )
	    BUG();
	read_random_source( 3, needed, 2 );
	pool_balance += needed;
	did_initial_extra_seeding=1;
    }

    /* for level 2 make sure that there is enough random in the pool */
    if( level == 2 && pool_balance < length ) {
	size_t needed;

	if( pool_balance < 0 )
	    pool_balance = 0;
	needed = length - pool_balance;
	if( needed > POOLSIZE )
	    BUG();
	read_random_source( 3, needed, 2 );
	pool_balance += needed;
    }

    /* make sure the pool is filled */
    while( !pool_filled )
	random_poll();

    /* do always a fast random poll */
    fast_random_poll();

    if( !level ) { /* no need for cryptographic strong random */
	/* create a new pool */
	for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
				    i < POOLWORDS; i++, dp++, sp++ )
	    *dp = *sp + ADD_VALUE;
	/* must mix both pools */
	mix_pool(rndpool); rndstats.mixrnd++;
	mix_pool(keypool); rndstats.mixkey++;
	memcpy( buffer, keypool, length );
    }
    else {
	/* mix the pool (if add_randomness() didn't it) */
	if( !just_mixed ) {
	    mix_pool(rndpool);
	    rndstats.mixrnd++;
	}
	/* create a new pool */
	for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
				    i < POOLWORDS; i++, dp++, sp++ )
	    *dp = *sp + ADD_VALUE;
	/* and mix both pools */
	mix_pool(rndpool); rndstats.mixrnd++;
	mix_pool(keypool); rndstats.mixkey++;
	/* read the required data
	 * we use a readpoiter to read from a different postion each
	 * time */
	while( length-- ) {
	    *buffer++ = keypool[pool_readpos++];
	    if( pool_readpos >= POOLSIZE )
		pool_readpos = 0;
	    pool_balance--;
	}
	if( pool_balance < 0 )
	    pool_balance = 0;
	/* and clear the keypool */
	memset( keypool, 0, POOLSIZE );
    }
}