summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/patches/random0001-xxx-standalone-random-translator.patch3214
-rw-r--r--debian/patches/series1
2 files changed, 0 insertions, 3215 deletions
diff --git a/debian/patches/random0001-xxx-standalone-random-translator.patch b/debian/patches/random0001-xxx-standalone-random-translator.patch
deleted file mode 100644
index fe3bba2c..00000000
--- a/debian/patches/random0001-xxx-standalone-random-translator.patch
+++ /dev/null
@@ -1,3214 +0,0 @@
-From 1ea5ac6db5000a16eea08111478504599d3c3295 Mon Sep 17 00:00:00 2001
-From: Justus Winter <4winter@informatik.uni-hamburg.de>
-Date: Thu, 12 Nov 2015 22:16:49 +0100
-Subject: [PATCH hurd] xxx standalone random translator
-
----
- Makefile | 1 -
- random/Makefile | 30 --
- random/TODO | 11 -
- random/gnupg-bithelp.h | 41 ---
- random/gnupg-glue.h | 40 ---
- random/gnupg-random.c | 810 -------------------------------------------------
- random/gnupg-random.h | 47 ---
- random/gnupg-rmd.h | 38 ---
- random/gnupg-rmd160.c | 656 ---------------------------------------
- random/random.c | 650 ---------------------------------------
- random/random.h | 32 --
- sutils/MAKEDEV.sh | 6 +-
- trans/Makefile | 7 +-
- trans/random.c | 682 +++++++++++++++++++++++++++++++++++++++++
- 14 files changed, 691 insertions(+), 2360 deletions(-)
- delete mode 100644 random/Makefile
- delete mode 100644 random/TODO
- delete mode 100644 random/gnupg-bithelp.h
- delete mode 100644 random/gnupg-glue.h
- delete mode 100644 random/gnupg-random.c
- delete mode 100644 random/gnupg-random.h
- delete mode 100644 random/gnupg-rmd.h
- delete mode 100644 random/gnupg-rmd160.c
- delete mode 100644 random/random.c
- delete mode 100644 random/random.h
- create mode 100644 trans/random.c
-
-diff --git a/Makefile b/Makefile
-index 3178740..6544cd2 100644
---- a/Makefile
-+++ b/Makefile
-@@ -38,7 +38,6 @@ prog-subdirs = auth proc exec term \
- hostmux usermux ftpfs trans \
- console-client utils sutils \
- benchmarks fstests \
-- random \
- procfs \
- startup \
- init \
-diff --git a/random/Makefile b/random/Makefile
-deleted file mode 100644
-index 0949b63..0000000
---- a/random/Makefile
-+++ /dev/null
-@@ -1,30 +0,0 @@
--#
--# Copyright (C) 1994,95,96,97,99,2000,2001 Free Software Foundation, Inc.
--#
--# This program is free software; you can redistribute it and/or
--# modify it under the terms of the GNU General Public License as
--# published by the Free Software Foundation; either version 2, or (at
--# your option) any later version.
--#
--# This program is distributed in the hope that it will be useful, but
--# WITHOUT ANY WARRANTY; without even the implied warranty of
--# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
--# General Public License for more details.
--#
--# You should have received a copy of the GNU General Public License
--# along with this program; if not, write to the Free Software
--# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
--
--dir := random
--makemode := server
--
--CFLAGS += -D__HURD__
--
--target = random
--SRCS = random.c gnupg-random.c gnupg-rmd160.c
--OBJS = $(SRCS:.c=.o) startup_notifyServer.o
--LCLHDRS = gnupg-random.h gnupg-rmd.h gnupg-bithelp.h random.h
--HURDLIBS = trivfs ports fshelp ihash shouldbeinlibc
--OTHERLIBS = -lpthread
--
--include ../Makeconf
-diff --git a/random/TODO b/random/TODO
-deleted file mode 100644
-index 9cc57ab..0000000
---- a/random/TODO
-+++ /dev/null
-@@ -1,11 +0,0 @@
--* read_poll uses random_poll until the pool is filled. This is ian
-- issue at first initialization, as this requries POOLSIZE good random (level 1 from
-- gather_random) even in level 0 and 1.
-- For now, the code is only applied to level 2. Eventually, readable_pool
-- should be fixed to return 0 if initialization is not done yet and not enough bytes
-- are available. Otherwise it enters an infinite loop.
--
--* Permissions?
--
--* Off by one error in gather_random/io_write? I can only get GATHERBUFSIZE - 1
-- bytes from it.
-diff --git a/random/gnupg-bithelp.h b/random/gnupg-bithelp.h
-deleted file mode 100644
-index 188db16..0000000
---- a/random/gnupg-bithelp.h
-+++ /dev/null
-@@ -1,41 +0,0 @@
--/* bithelp.h - Some bit manipulation helpers
-- * Copyright (C) 1999 Free Software Foundation, Inc.
-- *
-- * This file is part of GnuPG.
-- *
-- * GnuPG is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License as published by
-- * the Free Software Foundation; either version 2 of the License, or
-- * (at your option) any later version.
-- *
-- * GnuPG is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- * GNU General Public License for more details.
-- *
-- * You should have received a copy of the GNU General Public License
-- * along with this program; if not, write to the Free Software
-- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-- */
--#ifndef G10_BITHELP_H
--#define G10_BITHELP_H
--
--
--/****************
-- * Rotate a 32 bit integer by n bytes
-- */
--#if defined(__GNUC__) && defined(__i386__)
--static inline u32
--rol( u32 x, int n)
--{
-- __asm__("roll %%cl,%0"
-- :"=r" (x)
-- :"0" (x),"c" (n));
-- return x;
--}
--#else
-- #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
--#endif
--
--
--#endif /*G10_BITHELP_H*/
-diff --git a/random/gnupg-glue.h b/random/gnupg-glue.h
-deleted file mode 100644
-index cbf0a10..0000000
---- a/random/gnupg-glue.h
-+++ /dev/null
-@@ -1,40 +0,0 @@
--#ifndef __GNUPG_GLUE_H__
--#define __GNUPG_GLUE_H__
--
--#include <sys/types.h>
--#include <random.h>
--
--#define SIZEOF_UNSIGNED_LONG 4
--typedef unsigned int u32;
--typedef unsigned char byte;
--
--/* GnuPG's config.h */
--#define HAVE_GETTIMEOFDAY 1
--#define HAVE_GETRUSAGE 1
--#define HAVE_RAND 1
--
--/* GnuPG's memory.h */
--#define m_alloc malloc
--#define m_alloc_secure malloc
--#define m_alloc_clear(x) calloc(x, 1)
--#define m_alloc_secure_clear(x) calloc(x, 1)
--#define m_free free
--#define m_strdup strdup
--
--/* GnuPG's dynaload.h */
--#define dynload_getfnc_fast_random_poll() (0)
--#define dynload_getfnc_gather_random() &gather_random
--int
--gather_random( void (*add)(const void*, size_t, int), int requester,
-- size_t length, int level );
--
--/* GnuPG's miscellaneous stuff. */
--#define BUG() assert(0)
--#define _(x) x
--#define make_timestamp() time(0)
--#define tty_printf printf
--#define log_info(format, args...) printf(format , ## args)
--#define log_fatal(format, args...) { printf(format , ## args) ; exit(2); }
--#define DIM(v) (sizeof(v)/sizeof((v)[0]))
--
--#endif /* __GNUPG_GLUE_H__ */
-diff --git a/random/gnupg-random.c b/random/gnupg-random.c
-deleted file mode 100644
-index 54ee3c5..0000000
---- a/random/gnupg-random.c
-+++ /dev/null
-@@ -1,810 +0,0 @@
--/* random.c - random number generator
-- * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
-- *
-- * This file is part of GnuPG.
-- *
-- * GnuPG is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License as published by
-- * the Free Software Foundation; either version 2 of the License, or
-- * (at your option) any later version.
-- *
-- * GnuPG is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- * GNU General Public License for more details.
-- *
-- * You should have received a copy of the GNU General Public License
-- * along with this program; if not, write to the Free Software
-- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-- */
--
--
--/****************
-- * This random number generator is modelled after the one described
-- * in Peter Gutmann's Paper: "Software Generation of Practically
-- * Strong Random Numbers".
-- */
--
--#ifndef __HURD__
--#include <config.h>
--#else
--#include "gnupg-glue.h"
--#endif
--#include <stdio.h>
--#include <stdlib.h>
--#include <assert.h>
--#include <errno.h>
--#include <string.h>
--#include <time.h>
--#include <sys/time.h>
--#include <sys/types.h>
--#include <sys/stat.h>
--#include <unistd.h>
--#include <fcntl.h>
--#ifdef HAVE_GETHRTIME
-- #include <sys/times.h>
--#endif
--#ifdef HAVE_GETTIMEOFDAY
-- #include <sys/times.h>
--#endif
--#ifdef HAVE_GETRUSAGE
-- #include <sys/resource.h>
--#endif
--#ifdef __MINGW32__
-- #include <process.h>
--#endif
--#ifndef __HURD__
--#include "util.h"
--#endif
--#ifndef __HURD__
--#include "rmd.h"
--#include "ttyio.h"
--#include "i18n.h"
--#include "random.h"
--#include "rand-internal.h"
--#include "dynload.h"
--#else
--#include "gnupg-rmd.h"
--#include "gnupg-random.h"
--#endif
--
--#ifndef RAND_MAX /* for SunOS */
-- #define RAND_MAX 32767
--#endif
--
--
--#if SIZEOF_UNSIGNED_LONG == 8
-- #define ADD_VALUE 0xa5a5a5a5a5a5a5a5
--#elif SIZEOF_UNSIGNED_LONG == 4
-- #define ADD_VALUE 0xa5a5a5a5
--#else
-- #error weird size for an unsigned long
--#endif
--
--#define BLOCKLEN 64 /* hash this amount of bytes */
--#define DIGESTLEN 20 /* into a digest of this length (rmd160) */
--/* poolblocks is the number of digests which make up the pool
-- * and poolsize must be a multiple of the digest length
-- * to make the AND operations faster, the size should also be
-- * a multiple of ulong
-- */
--#define POOLBLOCKS 30
--#define POOLSIZE (POOLBLOCKS*DIGESTLEN)
--#if (POOLSIZE % SIZEOF_UNSIGNED_LONG)
-- #error Please make sure that poolsize is a multiple of ulong
--#endif
--#define POOLWORDS (POOLSIZE / SIZEOF_UNSIGNED_LONG)
--
--
--static int is_initialized;
--#define MASK_LEVEL(a) do {if( a > 2 ) a = 2; else if( a < 0 ) a = 0; } while(0)
--static char *rndpool; /* allocated size is POOLSIZE+BLOCKLEN */
--static char *keypool; /* allocated size is POOLSIZE+BLOCKLEN */
--static size_t pool_readpos;
--static size_t pool_writepos;
--static int pool_filled;
--static int pool_balance;
--static int just_mixed;
--static int did_initial_extra_seeding;
--static char *seed_file_name;
--static int allow_seed_file_update;
--
--static int secure_alloc;
--static int quick_test;
--static int faked_rng;
--
--
--#ifndef __HURD__
--static void read_pool( byte *buffer, size_t length, int level );
--#else
--int read_pool( byte *buffer, size_t length, int level );
--#endif
--static void add_randomness( const void *buffer, size_t length, int source );
--static void random_poll(void);
--#ifndef __HURD__
--static void read_random_source( int requester, size_t length, int level);
--#else
--static int read_random_source( int requester, size_t length, int level);
--#endif
--static int gather_faked( void (*add)(const void*, size_t, int), int requester,
-- size_t length, int level );
--
--static struct {
-- ulong mixrnd;
-- ulong mixkey;
-- ulong slowpolls;
-- ulong fastpolls;
-- ulong getbytes1;
-- ulong ngetbytes1;
-- ulong getbytes2;
-- ulong ngetbytes2;
-- ulong addbytes;
-- ulong naddbytes;
--} rndstats;
--
--static void
--initialize(void)
--{
-- /* The data buffer is allocated somewhat larger, so that
-- * we can use this extra space (which is allocated in secure memory)
-- * as a temporary hash buffer */
-- rndpool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN)
-- : m_alloc_clear(POOLSIZE+BLOCKLEN);
-- keypool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN)
-- : m_alloc_clear(POOLSIZE+BLOCKLEN);
-- is_initialized = 1;
--#ifndef __HURD__
-- cipher_modules_constructor();
--#endif
--}
--
--static void
--burn_stack (int bytes)
--{
-- char buf[128];
--
-- memset (buf, 0, sizeof buf);
-- bytes -= sizeof buf;
-- if (bytes > 0)
-- burn_stack (bytes);
--}
--
--void
--random_dump_stats()
--{
-- fprintf(stderr,
-- "random usage: poolsize=%d mixed=%lu polls=%lu/%lu added=%lu/%lu\n"
-- " outmix=%lu getlvl1=%lu/%lu getlvl2=%lu/%lu\n",
-- POOLSIZE, rndstats.mixrnd, rndstats.slowpolls, rndstats.fastpolls,
-- rndstats.naddbytes, rndstats.addbytes,
-- rndstats.mixkey, rndstats.ngetbytes1, rndstats.getbytes1,
-- rndstats.ngetbytes2, rndstats.getbytes2 );
--}
--
--void
--secure_random_alloc()
--{
-- secure_alloc = 1;
--}
--
--
--int
--quick_random_gen( int onoff )
--{
-- int last;
--
-- read_random_source(0,0,0); /* init */
-- last = quick_test;
-- if( onoff != -1 )
-- quick_test = onoff;
-- return faked_rng? 1 : last;
--}
--
--
--/****************
-- * Fill the buffer with LENGTH bytes of cryptographically strong
-- * random bytes. level 0 is not very strong, 1 is strong enough
-- * for most usage, 2 is good for key generation stuff but may be very slow.
-- */
--void
--randomize_buffer( byte *buffer, size_t length, int level )
--{
-- char *p = get_random_bits( length*8, level, 1 );
-- memcpy( buffer, p, length );
-- m_free(p);
--}
--
--
--int
--random_is_faked()
--{
-- if( !is_initialized )
-- initialize();
-- return faked_rng || quick_test;
--}
--
--/****************
-- * Return a pointer to a randomized buffer of level 0 and LENGTH bits
-- * caller must free the buffer.
-- * Note: The returned value is rounded up to bytes.
-- */
--byte *
--get_random_bits( size_t nbits, int level, int secure )
--{
-- byte *buf, *p;
-- size_t nbytes = (nbits+7)/8;
--
-- if( quick_test && level > 1 )
-- level = 1;
-- MASK_LEVEL(level);
-- if( level == 1 ) {
-- rndstats.getbytes1 += nbytes;
-- rndstats.ngetbytes1++;
-- }
-- else if( level >= 2 ) {
-- rndstats.getbytes2 += nbytes;
-- rndstats.ngetbytes2++;
-- }
--
-- buf = secure && secure_alloc ? m_alloc_secure( nbytes ) : m_alloc( nbytes );
-- for( p = buf; nbytes > 0; ) {
-- size_t n = nbytes > POOLSIZE? POOLSIZE : nbytes;
--#ifdef __HURD__
-- n =
--#endif
-- read_pool( p, n, level );
-- nbytes -= n;
-- p += n;
--
-- }
-- return buf;
--}
--
--
--/****************
-- * Mix the pool
-- */
--static void
--mix_pool(byte *pool)
--{
-- char *hashbuf = pool + POOLSIZE;
-- char *p, *pend;
-- int i, n;
-- RMD160_CONTEXT md;
--
-- rmd160_init( &md );
-- #if DIGESTLEN != 20
-- #error must have a digest length of 20 for ripe-md-160
-- #endif
-- /* loop over the pool */
-- pend = pool + POOLSIZE;
-- memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN );
-- memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN);
-- rmd160_mixblock( &md, hashbuf);
-- memcpy(pool, hashbuf, 20 );
--
-- p = pool;
-- for( n=1; n < POOLBLOCKS; n++ ) {
-- memcpy(hashbuf, p, DIGESTLEN );
--
-- p += DIGESTLEN;
-- if( p+DIGESTLEN+BLOCKLEN < pend )
-- memcpy(hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN);
-- else {
-- char *pp = p+DIGESTLEN;
-- for(i=DIGESTLEN; i < BLOCKLEN; i++ ) {
-- if( pp >= pend )
-- pp = pool;
-- hashbuf[i] = *pp++;
-- }
-- }
--
-- rmd160_mixblock( &md, hashbuf);
-- memcpy(p, hashbuf, 20 );
-- }
-- burn_stack (200); /* for the rmd160_mixblock() */
--}
--
--
--void
--set_random_seed_file( const char *name )
--{
-- if( seed_file_name )
-- BUG();
-- seed_file_name = m_strdup( name );
--}
--
--/****************
-- * Read in a seed form the random_seed file
-- * and return true if this was successful
-- */
--static int
--read_seed_file()
--{
-- int fd;
-- struct stat sb;
-- unsigned char buffer[POOLSIZE];
-- int n;
--
-- if( !seed_file_name )
-- return 0;
--
-- #ifdef HAVE_DOSISH_SYSTEM
-- fd = open( seed_file_name, O_RDONLY | O_BINARY );
-- #else
-- fd = open( seed_file_name, O_RDONLY );
-- #endif
-- if( fd == -1 && errno == ENOENT) {
-- allow_seed_file_update = 1;
-- return 0;
-- }
--
-- if( fd == -1 ) {
-- log_info(_("can't open `%s': %s\n"), seed_file_name, strerror(errno) );
-- return 0;
-- }
-- if( fstat( fd, &sb ) ) {
-- log_info(_("can't stat `%s': %s\n"), seed_file_name, strerror(errno) );
-- close(fd);
-- return 0;
-- }
-- if( !S_ISREG(sb.st_mode) ) {
-- log_info(_("`%s' is not a regular file - ignored\n"), seed_file_name );
-- close(fd);
-- return 0;
-- }
-- if( !sb.st_size ) {
-- log_info(_("note: random_seed file is empty\n") );
-- close(fd);
-- allow_seed_file_update = 1;
-- return 0;
-- }
-- if( sb.st_size != POOLSIZE ) {
-- log_info(_("warning: invalid size of random_seed file - not used\n") );
-- close(fd);
-- return 0;
-- }
-- do {
-- n = read( fd, buffer, POOLSIZE );
-- } while( n == -1 && errno == EINTR );
-- if( n != POOLSIZE ) {
-- log_fatal(_("can't read `%s': %s\n"), seed_file_name,strerror(errno) );
-- close(fd);
-- return 0;
-- }
--
-- close(fd);
--
-- add_randomness( buffer, POOLSIZE, 0 );
-- /* add some minor entropy to the pool now (this will also force a mixing) */
-- { pid_t x = getpid();
-- add_randomness( &x, sizeof(x), 0 );
-- }
-- { time_t x = time(NULL);
-- add_randomness( &x, sizeof(x), 0 );
-- }
-- { clock_t x = clock();
-- add_randomness( &x, sizeof(x), 0 );
-- }
-- /* And read a few bytes from our entropy source. By using
-- * a level of 0 this will not block and might not return anything
-- * with some entropy drivers, however the rndlinux driver will use
-- * /dev/urandom and return some stuff - Do not read to much as we
-- * want to be friendly to the scare system entropy resource. */
-- read_random_source( 0, 16, 0 );
--
-- allow_seed_file_update = 1;
-- return 1;
--}
--
--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++;
--
-- #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) );
-- 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) );
--}
--
--#ifdef __HURD__
--int readable_pool( size_t length, int level )
--{
-- size_t needed = 0;
-- size_t my_balance = pool_balance;
-- size_t available = (gatherwpos - gatherrpos + GATHERBUFSIZE) % GATHERBUFSIZE;
--
-- if (length > POOLSIZE)
-- length = POOLSIZE;
--
-- if (level < 2)
-- return length;
--
-- if( !pool_filled ) {
-- if( read_seed_file() )
-- pool_filled = 1;
-- }
--
-- if (!did_initial_extra_seeding)
-- {
-- /* Take account for initial extra seeding. */
-- needed = length;
-- if (needed < POOLSIZE/2)
-- needed = POOLSIZE/2;
-- my_balance = needed;
--
-- if (!pool_filled && pool_writepos + needed < POOLSIZE)
-- {
-- /* If the pool is not filled yet, we couldn't read the seed
-- file. Too bad. We will now have to take account for so many
-- random_poll()s as fit into the remaining pool. */
--
-- needed += (POOLSIZE - pool_writepos + needed + POOLSIZE/5 - 1) / (POOLSIZE/5);
-- }
-- }
-- else
-- {
-- if (!pool_filled)
-- needed += (POOLSIZE - pool_writepos + needed + POOLSIZE/5 - 1) / (POOLSIZE/5);
-- }
--
-- /* NEEDED contains the bytes needed for initialization, MY_BALANCE the resulting
-- available bytes. */
-- if (available < needed)
-- return 0;
-- return available + my_balance - needed;
--}
--#endif
--
--#ifndef __HURD__
--static void
--#else
--int
--#endif
--read_pool( byte *buffer, size_t length, int level )
--{
-- int i;
-- ulong *sp, *dp;
--
-- if( length > POOLSIZE ) {
--#ifndef __HURD__
-- log_fatal(_("too many random bits requested; the limit is %d\n"),
-- POOLSIZE*8-1 );
--#else
-- length = POOLSIZE;
--#endif
-- }
--
-- 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();
--#ifdef __HURD__
-- needed =
--#endif
-- read_random_source( 3, needed, 2 );
--#ifdef __HURD__
-- if (! needed)
-- return 0;
-- /* XXX This will succeed with needed < POOLSIZE/2 even. But
-- erroring out will waste the random we already got. */
--#endif
-- 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();
--#ifdef __HURD__
-- needed =
--#endif
-- read_random_source( 3, needed, 2 );
-- pool_balance += needed;
-- }
--
--#ifdef __HURD__
-- /* XXX This makes level 0 and 1 worse than needed at first start up. */
-- if (level == 2)
--#endif
-- /* 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 );
-- return length;
-- }
-- else {
--#ifdef __HURD__
-- int amount;
--#endif
-- /* 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 readpointer to read from a different position each
-- * time */
--#ifdef __HURD__
-- if (level == 2 && length > pool_balance)
-- length = pool_balance;
-- amount = length;
--#endif
-- 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 );
--#ifdef __HURD__
-- return amount;
--#endif
-- }
--}
--
--
--/****************
-- * 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;
-- }
-- }
--}
--
--
--
--static void
--random_poll()
--{
-- rndstats.slowpolls++;
-- read_random_source( 2, POOLSIZE/5, 1 );
--}
--
--
--void
--fast_random_poll()
--{
-- static void (*fnc)( void (*)(const void*, size_t, int), int) = NULL;
-- static int initialized = 0;
--
-- rndstats.fastpolls++;
-- if( !initialized ) {
-- if( !is_initialized )
-- initialize();
-- initialized = 1;
-- fnc = dynload_getfnc_fast_random_poll();
-- }
-- if( fnc ) {
-- (*fnc)( add_randomness, 1 );
-- return;
-- }
--
-- /* fall back to the generic function */
-- #if HAVE_GETHRTIME
-- { hrtime_t tv;
-- tv = gethrtime();
-- add_randomness( &tv, sizeof(tv), 1 );
-- }
-- #elif HAVE_GETTIMEOFDAY
-- { struct timeval tv;
-- if( gettimeofday( &tv, NULL ) )
-- BUG();
-- add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
-- add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), 1 );
-- }
-- #elif HAVE_CLOCK_GETTIME
-- { struct timespec tv;
-- if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 )
-- BUG();
-- add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
-- add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), 1 );
-- }
-- #else /* use times */
-- #ifndef HAVE_DOSISH_SYSTEM
-- { struct tms buf;
-- times( &buf );
-- add_randomness( &buf, sizeof buf, 1 );
-- }
-- #endif
-- #endif
-- #ifdef HAVE_GETRUSAGE
-- #ifndef RUSAGE_SELF
-- #ifdef __GCC__
-- #warning There is no RUSAGE_SELF on this system
-- #endif
-- #else
-- { struct rusage buf;
-- /* QNX/Neutrino does return ENOSYS - so we just ignore it and
-- * add whatever is in buf. In a chroot environment it might not
-- * work at all (i.e. because /proc/ is not accessible), so we better
-- * ognore all error codes and hope for the best
-- */
-- getrusage( RUSAGE_SELF, &buf );
--
-- add_randomness( &buf, sizeof buf, 1 );
-- memset( &buf, 0, sizeof buf );
-- }
-- #endif
-- #endif
-- /* time and clock are available on all systems - so
-- * we better do it just in case one of the above functions
-- * didn't work */
-- { time_t x = time(NULL);
-- add_randomness( &x, sizeof(x), 1 );
-- }
-- { clock_t x = clock();
-- add_randomness( &x, sizeof(x), 1 );
-- }
--}
--
--
--#ifndef __HURD__
--static void
--#else
--static int
--#endif
--read_random_source( int requester, size_t length, int level )
--{
-- static int (*fnc)(void (*)(const void*, size_t, int), int,
-- size_t, int) = NULL;
--#ifdef __HURD__
-- int got;
--#endif
-- if( !fnc ) {
-- if( !is_initialized )
-- initialize();
-- fnc = dynload_getfnc_gather_random();
-- if( !fnc ) {
-- faked_rng = 1;
-- fnc = gather_faked;
-- }
-- if( !requester && !length && !level )
--#ifndef __HURD__
-- return; /* init only */
--#else
-- return 0;
--#endif
-- }
--#ifndef __HURD__
-- if( (*fnc)( add_randomness, requester, length, level ) < 0 )
-- log_fatal("No way to gather entropy for the RNG\n");
--#else
-- got = (*fnc)( add_randomness, requester, length, level );
-- if (got < 0)
-- log_fatal("No way to gather entropy for the RNG\n");
-- return got;
--#endif
--}
--
--
--static int
--gather_faked( void (*add)(const void*, size_t, int), int requester,
-- size_t length, int level )
--{
-- static int initialized=0;
-- size_t n;
-- char *buffer, *p;
--
-- if( !initialized ) {
-- log_info(_("WARNING: using insecure random number generator!!\n"));
-- tty_printf(_("The random number generator is only a kludge to let\n"
-- "it run - it is in no way a strong RNG!\n\n"
-- "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n"));
-- initialized=1;
-- #ifdef HAVE_RAND
-- srand(make_timestamp()*getpid());
-- #else
-- srandom(make_timestamp()*getpid());
-- #endif
-- }
-- printf("WAITING FOR %i bytes.\n", length);
-- p = buffer = m_alloc( length );
-- n = length;
-- #ifdef HAVE_RAND
-- while( n-- )
-- *p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);
-- #else
-- while( n-- )
-- *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1);
-- #endif
-- add_randomness( buffer, length, requester );
-- m_free(buffer);
-- return 0; /* okay */
--}
--
-diff --git a/random/gnupg-random.h b/random/gnupg-random.h
-deleted file mode 100644
-index ee18feb..0000000
---- a/random/gnupg-random.h
-+++ /dev/null
-@@ -1,47 +0,0 @@
--/* random.h - random functions
-- * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
-- *
-- * This file is part of GnuPG.
-- *
-- * GnuPG is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License as published by
-- * the Free Software Foundation; either version 2 of the License, or
-- * (at your option) any later version.
-- *
-- * GnuPG is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- * GNU General Public License for more details.
-- *
-- * You should have received a copy of the GNU General Public License
-- * along with this program; if not, write to the Free Software
-- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-- */
--#ifndef G10_RANDOM_H
--#define G10_RANDOM_H
--
--#ifndef __HURD__
--#include "types.h"
--#else
--#include "gnupg-glue.h"
--int read_pool (byte *, size_t, int);
--int readable_pool (size_t, int);
--#endif
--
--/*-- random.c --*/
--void random_dump_stats(void);
--void secure_random_alloc(void);
--void set_random_seed_file(const char *);
--void update_random_seed_file(void);
--int quick_random_gen( int onoff );
--int random_is_faked(void);
--void randomize_buffer( byte *buffer, size_t length, int level );
--byte *get_random_bits( size_t nbits, int level, int secure );
--void fast_random_poll( void );
--
--/*-- rndw32.c --*/
--#ifdef USE_STATIC_RNDW32
--void rndw32_set_dll_name( const char *name );
--#endif
--
--#endif /*G10_RANDOM_H*/
-diff --git a/random/gnupg-rmd.h b/random/gnupg-rmd.h
-deleted file mode 100644
-index 2446fc7..0000000
---- a/random/gnupg-rmd.h
-+++ /dev/null
-@@ -1,38 +0,0 @@
--/* rmd.h - RIPE-MD hash functions
-- * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
-- *
-- * This file is part of GnuPG.
-- *
-- * GnuPG is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License as published by
-- * the Free Software Foundation; either version 2 of the License, or
-- * (at your option) any later version.
-- *
-- * GnuPG is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- * GNU General Public License for more details.
-- *
-- * You should have received a copy of the GNU General Public License
-- * along with this program; if not, write to the Free Software
-- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-- */
--#ifndef G10_RMD_H
--#define G10_RMD_H
--
--#ifdef __HURD__
--#include "gnupg-glue.h"
--#endif
--
--/* we need this here because random.c must have direct access */
--typedef struct {
-- u32 h0,h1,h2,h3,h4;
-- u32 nblocks;
-- byte buf[64];
-- int count;
--} RMD160_CONTEXT;
--
--void rmd160_init( RMD160_CONTEXT *hd );
--void rmd160_mixblock( RMD160_CONTEXT *hd, char *buffer );
--
--#endif /*G10_RMD_H*/
-diff --git a/random/gnupg-rmd160.c b/random/gnupg-rmd160.c
-deleted file mode 100644
-index 6610768..0000000
---- a/random/gnupg-rmd160.c
-+++ /dev/null
-@@ -1,656 +0,0 @@
--/* rmd160.c - RIPE-MD160
-- * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
-- *
-- * This file is part of GnuPG.
-- *
-- * GnuPG is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License as published by
-- * the Free Software Foundation; either version 2 of the License, or
-- * (at your option) any later version.
-- *
-- * GnuPG is distributed in the hope that it will be useful,
-- * but WITHOUT ANY WARRANTY; without even the implied warranty of
-- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- * GNU General Public License for more details.
-- *
-- * You should have received a copy of the GNU General Public License
-- * along with this program; if not, write to the Free Software
-- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-- */
--
--#ifndef __HURD__
--#include <config.h>
--#endif
--#include <stdio.h>
--#include <stdlib.h>
--#include <string.h>
--#include <assert.h>
--#ifndef __HURD__
--#include "util.h"
--#include "memory.h"
--#include "rmd.h"
--#include "cipher.h" /* only used for the rmd160_hash_buffer() prototype */
--#include "dynload.h"
--
--#include "bithelp.h"
--#else
--#include "gnupg-rmd.h"
--#include "gnupg-bithelp.h"
--#endif
--
--
--/*********************************
-- * RIPEMD-160 is not patented, see (as of 25.10.97)
-- * http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
-- * Note that the code uses Little Endian byteorder, which is good for
-- * 386 etc, but we must add some conversion when used on a big endian box.
-- *
-- *
-- * Pseudo-code for RIPEMD-160
-- *
-- * RIPEMD-160 is an iterative hash function that operates on 32-bit words.
-- * The round function takes as input a 5-word chaining variable and a 16-word
-- * message block and maps this to a new chaining variable. All operations are
-- * defined on 32-bit words. Padding is identical to that of MD4.
-- *
-- *
-- * RIPEMD-160: definitions
-- *
-- *
-- * nonlinear functions at bit level: exor, mux, -, mux, -
-- *
-- * f(j, x, y, z) = x XOR y XOR z (0 <= j <= 15)
-- * f(j, x, y, z) = (x AND y) OR (NOT(x) AND z) (16 <= j <= 31)
-- * f(j, x, y, z) = (x OR NOT(y)) XOR z (32 <= j <= 47)
-- * f(j, x, y, z) = (x AND z) OR (y AND NOT(z)) (48 <= j <= 63)
-- * f(j, x, y, z) = x XOR (y OR NOT(z)) (64 <= j <= 79)
-- *
-- *
-- * added constants (hexadecimal)
-- *
-- * K(j) = 0x00000000 (0 <= j <= 15)
-- * K(j) = 0x5A827999 (16 <= j <= 31) int(2**30 x sqrt(2))
-- * K(j) = 0x6ED9EBA1 (32 <= j <= 47) int(2**30 x sqrt(3))
-- * K(j) = 0x8F1BBCDC (48 <= j <= 63) int(2**30 x sqrt(5))
-- * K(j) = 0xA953FD4E (64 <= j <= 79) int(2**30 x sqrt(7))
-- * K'(j) = 0x50A28BE6 (0 <= j <= 15) int(2**30 x cbrt(2))
-- * K'(j) = 0x5C4DD124 (16 <= j <= 31) int(2**30 x cbrt(3))
-- * K'(j) = 0x6D703EF3 (32 <= j <= 47) int(2**30 x cbrt(5))
-- * K'(j) = 0x7A6D76E9 (48 <= j <= 63) int(2**30 x cbrt(7))
-- * K'(j) = 0x00000000 (64 <= j <= 79)
-- *
-- *
-- * selection of message word
-- *
-- * r(j) = j (0 <= j <= 15)
-- * r(16..31) = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8
-- * r(32..47) = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12
-- * r(48..63) = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2
-- * r(64..79) = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
-- * r0(0..15) = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12
-- * r0(16..31)= 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2
-- * r0(32..47)= 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13
-- * r0(48..63)= 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14
-- * r0(64..79)= 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
-- *
-- *
-- * amount for rotate left (rol)
-- *
-- * s(0..15) = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8
-- * s(16..31) = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12
-- * s(32..47) = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5
-- * s(48..63) = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12
-- * s(64..79) = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
-- * s'(0..15) = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6
-- * s'(16..31)= 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11
-- * s'(32..47)= 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5
-- * s'(48..63)= 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8
-- * s'(64..79)= 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
-- *
-- *
-- * initial value (hexadecimal)
-- *
-- * h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476;
-- * h4 = 0xC3D2E1F0;
-- *
-- *
-- * RIPEMD-160: pseudo-code
-- *
-- * It is assumed that the message after padding consists of t 16-word blocks
-- * that will be denoted with X[i][j], with 0 <= i <= t-1 and 0 <= j <= 15.
-- * The symbol [+] denotes addition modulo 2**32 and rol_s denotes cyclic left
-- * shift (rotate) over s positions.
-- *
-- *
-- * for i := 0 to t-1 {
-- * A := h0; B := h1; C := h2; D = h3; E = h4;
-- * A' := h0; B' := h1; C' := h2; D' = h3; E' = h4;
-- * for j := 0 to 79 {
-- * T := rol_s(j)(A [+] f(j, B, C, D) [+] X[i][r(j)] [+] K(j)) [+] E;
-- * A := E; E := D; D := rol_10(C); C := B; B := T;
-- * T := rol_s'(j)(A' [+] f(79-j, B', C', D') [+] X[i][r'(j)]
-- [+] K'(j)) [+] E';
-- * A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T;
-- * }
-- * T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A';
-- * h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T;
-- * }
-- */
--
--/* Some examples:
-- * "" 9c1185a5c5e9fc54612808977ee8f548b2258d31
-- * "a" 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe
-- * "abc" 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc
-- * "message digest" 5d0689ef49d2fae572b881b123a85ffa21595f36
-- * "a...z" f71c27109c692c1b56bbdceb5b9d2865b3708dbc
-- * "abcdbcde...nopq" 12a053384a9c0c88e405a06c27dcf49ada62eb2b
-- * "A...Za...z0...9" b0e20b6e3116640286ed3a87a5713079b21f5189
-- * 8 times "1234567890" 9b752e45573d4b39f4dbd3323cab82bf63326bfb
-- * 1 million times "a" 52783243c1697bdbe16d37f97f68f08325dc1528
-- */
--
--static void
--burn_stack (int bytes)
--{
-- char buf[150];
--
-- memset (buf, 0, sizeof buf);
-- bytes -= sizeof buf;
-- if (bytes > 0)
-- burn_stack (bytes);
--}
--
--
--
--void
--rmd160_init( RMD160_CONTEXT *hd )
--{
-- hd->h0 = 0x67452301;
-- hd->h1 = 0xEFCDAB89;
-- hd->h2 = 0x98BADCFE;
-- hd->h3 = 0x10325476;
-- hd->h4 = 0xC3D2E1F0;
-- hd->nblocks = 0;
-- hd->count = 0;
--}
--
--
--
--/****************
-- * Transform the message X which consists of 16 32-bit-words
-- */
--static void
--transform( RMD160_CONTEXT *hd, byte *data )
--{
-- u32 a,b,c,d,e,aa,bb,cc,dd,ee,t;
-- #ifdef BIG_ENDIAN_HOST
-- u32 x[16];
-- { int i;
-- byte *p2, *p1;
-- for(i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 ) {
-- p2[3] = *p1++;
-- p2[2] = *p1++;
-- p2[1] = *p1++;
-- p2[0] = *p1++;
-- }
-- }
-- #else
-- #if 0
-- u32 *x =(u32*)data;
-- #else
-- /* this version is better because it is always aligned;
-- * The performance penalty on a 586-100 is about 6% which
-- * is acceptable - because the data is more local it might
-- * also be possible that this is faster on some machines.
-- * This function (when compiled with -02 on gcc 2.7.2)
-- * executes on a 586-100 (39.73 bogomips) at about 1900kb/sec;
-- * [measured with a 4MB data and "gpgm --print-md rmd160"] */
-- u32 x[16];
-- memcpy( x, data, 64 );
-- #endif
-- #endif
--
--
--#define K0 0x00000000
--#define K1 0x5A827999
--#define K2 0x6ED9EBA1
--#define K3 0x8F1BBCDC
--#define K4 0xA953FD4E
--#define KK0 0x50A28BE6
--#define KK1 0x5C4DD124
--#define KK2 0x6D703EF3
--#define KK3 0x7A6D76E9
--#define KK4 0x00000000
--#define F0(x,y,z) ( (x) ^ (y) ^ (z) )
--#define F1(x,y,z) ( ((x) & (y)) | (~(x) & (z)) )
--#define F2(x,y,z) ( ((x) | ~(y)) ^ (z) )
--#define F3(x,y,z) ( ((x) & (z)) | ((y) & ~(z)) )
--#define F4(x,y,z) ( (x) ^ ((y) | ~(z)) )
--#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \
-- a = rol(t,s) + e; \
-- c = rol(c,10); \
-- } while(0)
--
-- /* left lane */
-- a = hd->h0;
-- b = hd->h1;
-- c = hd->h2;
-- d = hd->h3;
-- e = hd->h4;
-- R( a, b, c, d, e, F0, K0, 0, 11 );
-- R( e, a, b, c, d, F0, K0, 1, 14 );
-- R( d, e, a, b, c, F0, K0, 2, 15 );
-- R( c, d, e, a, b, F0, K0, 3, 12 );
-- R( b, c, d, e, a, F0, K0, 4, 5 );
-- R( a, b, c, d, e, F0, K0, 5, 8 );
-- R( e, a, b, c, d, F0, K0, 6, 7 );
-- R( d, e, a, b, c, F0, K0, 7, 9 );
-- R( c, d, e, a, b, F0, K0, 8, 11 );
-- R( b, c, d, e, a, F0, K0, 9, 13 );
-- R( a, b, c, d, e, F0, K0, 10, 14 );
-- R( e, a, b, c, d, F0, K0, 11, 15 );
-- R( d, e, a, b, c, F0, K0, 12, 6 );
-- R( c, d, e, a, b, F0, K0, 13, 7 );
-- R( b, c, d, e, a, F0, K0, 14, 9 );
-- R( a, b, c, d, e, F0, K0, 15, 8 );
-- R( e, a, b, c, d, F1, K1, 7, 7 );
-- R( d, e, a, b, c, F1, K1, 4, 6 );
-- R( c, d, e, a, b, F1, K1, 13, 8 );
-- R( b, c, d, e, a, F1, K1, 1, 13 );
-- R( a, b, c, d, e, F1, K1, 10, 11 );
-- R( e, a, b, c, d, F1, K1, 6, 9 );
-- R( d, e, a, b, c, F1, K1, 15, 7 );
-- R( c, d, e, a, b, F1, K1, 3, 15 );
-- R( b, c, d, e, a, F1, K1, 12, 7 );
-- R( a, b, c, d, e, F1, K1, 0, 12 );
-- R( e, a, b, c, d, F1, K1, 9, 15 );
-- R( d, e, a, b, c, F1, K1, 5, 9 );
-- R( c, d, e, a, b, F1, K1, 2, 11 );
-- R( b, c, d, e, a, F1, K1, 14, 7 );
-- R( a, b, c, d, e, F1, K1, 11, 13 );
-- R( e, a, b, c, d, F1, K1, 8, 12 );
-- R( d, e, a, b, c, F2, K2, 3, 11 );
-- R( c, d, e, a, b, F2, K2, 10, 13 );
-- R( b, c, d, e, a, F2, K2, 14, 6 );
-- R( a, b, c, d, e, F2, K2, 4, 7 );
-- R( e, a, b, c, d, F2, K2, 9, 14 );
-- R( d, e, a, b, c, F2, K2, 15, 9 );
-- R( c, d, e, a, b, F2, K2, 8, 13 );
-- R( b, c, d, e, a, F2, K2, 1, 15 );
-- R( a, b, c, d, e, F2, K2, 2, 14 );
-- R( e, a, b, c, d, F2, K2, 7, 8 );
-- R( d, e, a, b, c, F2, K2, 0, 13 );
-- R( c, d, e, a, b, F2, K2, 6, 6 );
-- R( b, c, d, e, a, F2, K2, 13, 5 );
-- R( a, b, c, d, e, F2, K2, 11, 12 );
-- R( e, a, b, c, d, F2, K2, 5, 7 );
-- R( d, e, a, b, c, F2, K2, 12, 5 );
-- R( c, d, e, a, b, F3, K3, 1, 11 );
-- R( b, c, d, e, a, F3, K3, 9, 12 );
-- R( a, b, c, d, e, F3, K3, 11, 14 );
-- R( e, a, b, c, d, F3, K3, 10, 15 );
-- R( d, e, a, b, c, F3, K3, 0, 14 );
-- R( c, d, e, a, b, F3, K3, 8, 15 );
-- R( b, c, d, e, a, F3, K3, 12, 9 );
-- R( a, b, c, d, e, F3, K3, 4, 8 );
-- R( e, a, b, c, d, F3, K3, 13, 9 );
-- R( d, e, a, b, c, F3, K3, 3, 14 );
-- R( c, d, e, a, b, F3, K3, 7, 5 );
-- R( b, c, d, e, a, F3, K3, 15, 6 );
-- R( a, b, c, d, e, F3, K3, 14, 8 );
-- R( e, a, b, c, d, F3, K3, 5, 6 );
-- R( d, e, a, b, c, F3, K3, 6, 5 );
-- R( c, d, e, a, b, F3, K3, 2, 12 );
-- R( b, c, d, e, a, F4, K4, 4, 9 );
-- R( a, b, c, d, e, F4, K4, 0, 15 );
-- R( e, a, b, c, d, F4, K4, 5, 5 );
-- R( d, e, a, b, c, F4, K4, 9, 11 );
-- R( c, d, e, a, b, F4, K4, 7, 6 );
-- R( b, c, d, e, a, F4, K4, 12, 8 );
-- R( a, b, c, d, e, F4, K4, 2, 13 );
-- R( e, a, b, c, d, F4, K4, 10, 12 );
-- R( d, e, a, b, c, F4, K4, 14, 5 );
-- R( c, d, e, a, b, F4, K4, 1, 12 );
-- R( b, c, d, e, a, F4, K4, 3, 13 );
-- R( a, b, c, d, e, F4, K4, 8, 14 );
-- R( e, a, b, c, d, F4, K4, 11, 11 );
-- R( d, e, a, b, c, F4, K4, 6, 8 );
-- R( c, d, e, a, b, F4, K4, 15, 5 );
-- R( b, c, d, e, a, F4, K4, 13, 6 );
--
-- aa = a; bb = b; cc = c; dd = d; ee = e;
--
-- /* right lane */
-- a = hd->h0;
-- b = hd->h1;
-- c = hd->h2;
-- d = hd->h3;
-- e = hd->h4;
-- R( a, b, c, d, e, F4, KK0, 5, 8);
-- R( e, a, b, c, d, F4, KK0, 14, 9);
-- R( d, e, a, b, c, F4, KK0, 7, 9);
-- R( c, d, e, a, b, F4, KK0, 0, 11);
-- R( b, c, d, e, a, F4, KK0, 9, 13);
-- R( a, b, c, d, e, F4, KK0, 2, 15);
-- R( e, a, b, c, d, F4, KK0, 11, 15);
-- R( d, e, a, b, c, F4, KK0, 4, 5);
-- R( c, d, e, a, b, F4, KK0, 13, 7);
-- R( b, c, d, e, a, F4, KK0, 6, 7);
-- R( a, b, c, d, e, F4, KK0, 15, 8);
-- R( e, a, b, c, d, F4, KK0, 8, 11);
-- R( d, e, a, b, c, F4, KK0, 1, 14);
-- R( c, d, e, a, b, F4, KK0, 10, 14);
-- R( b, c, d, e, a, F4, KK0, 3, 12);
-- R( a, b, c, d, e, F4, KK0, 12, 6);
-- R( e, a, b, c, d, F3, KK1, 6, 9);
-- R( d, e, a, b, c, F3, KK1, 11, 13);
-- R( c, d, e, a, b, F3, KK1, 3, 15);
-- R( b, c, d, e, a, F3, KK1, 7, 7);
-- R( a, b, c, d, e, F3, KK1, 0, 12);
-- R( e, a, b, c, d, F3, KK1, 13, 8);
-- R( d, e, a, b, c, F3, KK1, 5, 9);
-- R( c, d, e, a, b, F3, KK1, 10, 11);
-- R( b, c, d, e, a, F3, KK1, 14, 7);
-- R( a, b, c, d, e, F3, KK1, 15, 7);
-- R( e, a, b, c, d, F3, KK1, 8, 12);
-- R( d, e, a, b, c, F3, KK1, 12, 7);
-- R( c, d, e, a, b, F3, KK1, 4, 6);
-- R( b, c, d, e, a, F3, KK1, 9, 15);
-- R( a, b, c, d, e, F3, KK1, 1, 13);
-- R( e, a, b, c, d, F3, KK1, 2, 11);
-- R( d, e, a, b, c, F2, KK2, 15, 9);
-- R( c, d, e, a, b, F2, KK2, 5, 7);
-- R( b, c, d, e, a, F2, KK2, 1, 15);
-- R( a, b, c, d, e, F2, KK2, 3, 11);
-- R( e, a, b, c, d, F2, KK2, 7, 8);
-- R( d, e, a, b, c, F2, KK2, 14, 6);
-- R( c, d, e, a, b, F2, KK2, 6, 6);
-- R( b, c, d, e, a, F2, KK2, 9, 14);
-- R( a, b, c, d, e, F2, KK2, 11, 12);
-- R( e, a, b, c, d, F2, KK2, 8, 13);
-- R( d, e, a, b, c, F2, KK2, 12, 5);
-- R( c, d, e, a, b, F2, KK2, 2, 14);
-- R( b, c, d, e, a, F2, KK2, 10, 13);
-- R( a, b, c, d, e, F2, KK2, 0, 13);
-- R( e, a, b, c, d, F2, KK2, 4, 7);
-- R( d, e, a, b, c, F2, KK2, 13, 5);
-- R( c, d, e, a, b, F1, KK3, 8, 15);
-- R( b, c, d, e, a, F1, KK3, 6, 5);
-- R( a, b, c, d, e, F1, KK3, 4, 8);
-- R( e, a, b, c, d, F1, KK3, 1, 11);
-- R( d, e, a, b, c, F1, KK3, 3, 14);
-- R( c, d, e, a, b, F1, KK3, 11, 14);
-- R( b, c, d, e, a, F1, KK3, 15, 6);
-- R( a, b, c, d, e, F1, KK3, 0, 14);
-- R( e, a, b, c, d, F1, KK3, 5, 6);
-- R( d, e, a, b, c, F1, KK3, 12, 9);
-- R( c, d, e, a, b, F1, KK3, 2, 12);
-- R( b, c, d, e, a, F1, KK3, 13, 9);
-- R( a, b, c, d, e, F1, KK3, 9, 12);
-- R( e, a, b, c, d, F1, KK3, 7, 5);
-- R( d, e, a, b, c, F1, KK3, 10, 15);
-- R( c, d, e, a, b, F1, KK3, 14, 8);
-- R( b, c, d, e, a, F0, KK4, 12, 8);
-- R( a, b, c, d, e, F0, KK4, 15, 5);
-- R( e, a, b, c, d, F0, KK4, 10, 12);
-- R( d, e, a, b, c, F0, KK4, 4, 9);
-- R( c, d, e, a, b, F0, KK4, 1, 12);
-- R( b, c, d, e, a, F0, KK4, 5, 5);
-- R( a, b, c, d, e, F0, KK4, 8, 14);
-- R( e, a, b, c, d, F0, KK4, 7, 6);
-- R( d, e, a, b, c, F0, KK4, 6, 8);
-- R( c, d, e, a, b, F0, KK4, 2, 13);
-- R( b, c, d, e, a, F0, KK4, 13, 6);
-- R( a, b, c, d, e, F0, KK4, 14, 5);
-- R( e, a, b, c, d, F0, KK4, 0, 15);
-- R( d, e, a, b, c, F0, KK4, 3, 13);
-- R( c, d, e, a, b, F0, KK4, 9, 11);
-- R( b, c, d, e, a, F0, KK4, 11, 11);
--
--
-- t = hd->h1 + d + cc;
-- hd->h1 = hd->h2 + e + dd;
-- hd->h2 = hd->h3 + a + ee;
-- hd->h3 = hd->h4 + b + aa;
-- hd->h4 = hd->h0 + c + bb;
-- hd->h0 = t;
--}
--
--
--/* Update the message digest with the contents
-- * of INBUF with length INLEN.
-- */
--static void
--rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen)
--{
-- if( hd->count == 64 ) { /* flush the buffer */
-- transform( hd, hd->buf );
-- burn_stack (108+5*sizeof(void*));
-- hd->count = 0;
-- hd->nblocks++;
-- }
-- if( !inbuf )
-- return;
-- if( hd->count ) {
-- for( ; inlen && hd->count < 64; inlen-- )
-- hd->buf[hd->count++] = *inbuf++;
-- rmd160_write( hd, NULL, 0 );
-- if( !inlen )
-- return;
-- }
--
-- while( inlen >= 64 ) {
-- transform( hd, inbuf );
-- hd->count = 0;
-- hd->nblocks++;
-- inlen -= 64;
-- inbuf += 64;
-- }
-- burn_stack (108+5*sizeof(void*));
-- for( ; inlen && hd->count < 64; inlen-- )
-- hd->buf[hd->count++] = *inbuf++;
--}
--
--/****************
-- * Apply the rmd160 transform function on the buffer which must have
-- * a length 64 bytes. Do not use this function together with the
-- * other functions, use rmd160_init to initialize internal variables.
-- * Returns: 16 bytes in buffer with the mixed contentes of buffer.
-- */
--void
--rmd160_mixblock( RMD160_CONTEXT *hd, char *buffer )
--{
-- char *p = buffer;
-- transform( hd, buffer );
-- #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
-- X(0);
-- X(1);
-- X(2);
-- X(3);
-- X(4);
-- #undef X
--}
--
--
--/* The routine terminates the computation
-- */
--
--static void
--rmd160_final( RMD160_CONTEXT *hd )
--{
-- u32 t, msb, lsb;
-- byte *p;
--
-- rmd160_write(hd, NULL, 0); /* flush */;
--
-- t = hd->nblocks;
-- /* multiply by 64 to make a byte count */
-- lsb = t << 6;
-- msb = t >> 26;
-- /* add the count */
-- t = lsb;
-- if( (lsb += hd->count) < t )
-- msb++;
-- /* multiply by 8 to make a bit count */
-- t = lsb;
-- lsb <<= 3;
-- msb <<= 3;
-- msb |= t >> 29;
--
-- if( hd->count < 56 ) { /* enough room */
-- hd->buf[hd->count++] = 0x80; /* pad */
-- while( hd->count < 56 )
-- hd->buf[hd->count++] = 0; /* pad */
-- }
-- else { /* need one extra block */
-- hd->buf[hd->count++] = 0x80; /* pad character */
-- while( hd->count < 64 )
-- hd->buf[hd->count++] = 0;
-- rmd160_write(hd, NULL, 0); /* flush */;
-- memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
-- }
-- /* append the 64 bit count */
-- hd->buf[56] = lsb ;
-- hd->buf[57] = lsb >> 8;
-- hd->buf[58] = lsb >> 16;
-- hd->buf[59] = lsb >> 24;
-- hd->buf[60] = msb ;
-- hd->buf[61] = msb >> 8;
-- hd->buf[62] = msb >> 16;
-- hd->buf[63] = msb >> 24;
-- transform( hd, hd->buf );
-- burn_stack (108+5*sizeof(void*));
--
-- p = hd->buf;
-- #ifdef BIG_ENDIAN_HOST
-- #define X(a) do { *p++ = hd->h##a ; *p++ = hd->h##a >> 8; \
-- *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
-- #else /* little endian */
-- #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
-- #endif
-- X(0);
-- X(1);
-- X(2);
-- X(3);
-- X(4);
-- #undef X
--}
--
--static byte *
--rmd160_read( RMD160_CONTEXT *hd )
--{
-- return hd->buf;
--}
--
--
--
--/****************
-- * Shortcut functions which puts the hash value of the supplied buffer
-- * into outbuf which must have a size of 20 bytes.
-- */
--void
--rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length )
--{
-- RMD160_CONTEXT hd;
--
-- rmd160_init( &hd );
-- rmd160_write( &hd, (byte*)buffer, length );
-- rmd160_final( &hd );
-- memcpy( outbuf, hd.buf, 20 );
--}
--
--
--/****************
-- * Return some information about the algorithm. We need algo here to
-- * distinguish different flavors of the algorithm.
-- * Returns: A pointer to string describing the algorithm or NULL if
-- * the ALGO is invalid.
-- */
--static const char *
--rmd160_get_info( int algo, size_t *contextsize,
-- byte **r_asnoid, int *r_asnlen, int *r_mdlen,
-- void (**r_init)( void *c ),
-- void (**r_write)( void *c, byte *buf, size_t nbytes ),
-- void (**r_final)( void *c ),
-- byte *(**r_read)( void *c )
-- )
--{
-- static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */
-- { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
-- 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
--
-- if( algo != 3 )
-- return NULL;
--
-- *contextsize = sizeof(RMD160_CONTEXT);
-- *r_asnoid = asn;
-- *r_asnlen = DIM(asn);
-- *r_mdlen = 20;
-- *(void (**)(RMD160_CONTEXT *))r_init = rmd160_init;
-- *(void (**)(RMD160_CONTEXT *, byte*, size_t))r_write = rmd160_write;
-- *(void (**)(RMD160_CONTEXT *))r_final = rmd160_final;
-- *(byte *(**)(RMD160_CONTEXT *))r_read = rmd160_read;
--
-- return "RIPEMD160";
--}
--
--
--#ifndef IS_MODULE
--static
--#endif
--const char * const gnupgext_version = "RMD160 ($Revision: 1.17.2.4 $)";
--
--static struct {
-- int class;
-- int version;
-- int value;
-- void (*func)(void);
--} func_table[] = {
-- { 10, 1, 0, (void(*)(void))rmd160_get_info },
-- { 11, 1, 3 },
--};
--
--
--#ifndef IS_MODULE
--static
--#endif
--void *
--gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
--{
-- void *ret;
-- int i = *sequence;
--
-- do {
-- if( i >= DIM(func_table) || i < 0 ) {
-- return NULL;
-- }
-- *class = func_table[i].class;
-- *vers = func_table[i].version;
-- switch( *class ) {
-- case 11:
-- case 21:
-- case 31:
-- ret = &func_table[i].value;
-- break;
-- default:
-- ret = func_table[i].func;
-- break;
-- }
-- i++;
-- } while( what && what != *class );
--
-- *sequence = i;
-- return ret;
--}
--
--
--
--#ifndef __HURD__
--#ifndef IS_MODULE
--void
--rmd160_constructor(void)
--{
-- register_internal_cipher_extension( gnupgext_version, gnupgext_enum_func );
--}
--#endif
--#endif
-diff --git a/random/random.c b/random/random.c
-deleted file mode 100644
-index 8f76c5b..0000000
---- a/random/random.c
-+++ /dev/null
-@@ -1,650 +0,0 @@
--/* random.c - A single-file translator providing random data
-- Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
-- published by the Free Software Foundation; either version 2, or (at
-- your option) any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
--
--#define _GNU_SOURCE 1
--
--#include <hurd/paths.h>
--#include <hurd/trivfs.h>
--#include <hurd/startup.h>
--#include <stdio.h>
--#include <stdlib.h>
--#include <argp.h>
--#include <argz.h>
--#include <error.h>
--#include <string.h>
--#include <fcntl.h>
--#include <sys/mman.h>
--#include <pthread.h>
--#include <assert.h>
--
--#include <version.h>
--
--#include "random.h"
--#include "gnupg-random.h"
--
--/* Our control port. */
--struct trivfs_control *fsys;
--
--int read_blocked; /* For read and select. */
--pthread_cond_t wait; /* For read and select. */
--pthread_cond_t select_alert; /* For read and select. */
--
--
--/* The quality of randomness we provide.
-- 0: Very weak randomness based on time() and getrusage().
-- No external random data is used.
-- 1: Pseudo random numbers based on all available real random
-- numbers.
-- 2: Strong random numbers with a somewhat guaranteed entropy.
--*/
--#define DEFAULT_LEVEL 2
--static int level = DEFAULT_LEVEL;
--
--/* Name of file to use as seed. */
--static char *seed_file;
--
--/* The random bytes we collected. */
--char gatherbuf[GATHERBUFSIZE];
--
--/* The current positions in gatherbuf[]. */
--int gatherrpos;
--int gatherwpos;
--
--/* XXX Yuk Yuk. */
--#define POOLSIZE 600
--
--/* Take up to length bytes from gather_random if available. If
-- nothing is available, sleep until something becomes available.
-- Must be called with global_lock held. */
--int
--gather_random( void (*add)(const void*, size_t, int), int requester,
-- size_t length, int level )
--{
-- int avail = (gatherwpos - gatherrpos + GATHERBUFSIZE) % GATHERBUFSIZE;
-- int first = GATHERBUFSIZE - gatherrpos;
-- int second = length - first;
--
-- /* If level is zero, we should not block and not add anything
-- to the pool. */
-- if( !level )
-- return 0;
--
-- /* io_read() should guarantee that there is always data available. */
-- if (level == 2)
-- assert (avail);
--
-- if (length > avail)
-- length = avail;
--
-- if (first > length)
-- first = length;
-- (*add) (&gatherbuf[gatherrpos], first, requester);
-- gatherrpos = (gatherrpos + first) % GATHERBUFSIZE;
-- if (second > 0)
-- {
-- (*add) (&gatherbuf[gatherrpos], second, requester);
-- gatherrpos += second;
-- }
-- return length;
--}
--
--
--const char *argp_program_version = STANDARD_HURD_VERSION (random);
--
--/* This lock protects the GnuPG code. */
--static pthread_mutex_t global_lock;
--
--/* Trivfs hooks. */
--int trivfs_fstype = FSTYPE_MISC;
--int trivfs_fsid = 0;
--
--int trivfs_allow_open = O_READ | O_WRITE;
--
--int trivfs_support_read = 1;
--int trivfs_support_write = 1;
--int trivfs_support_exec = 0;
--
--void
--trivfs_modify_stat (struct trivfs_protid *cred, struct stat *st)
--{
-- /* Mark the node as a read-only plain file. */
-- st->st_mode &= ~S_IFMT;
-- st->st_mode |= (S_IFCHR);
-- st->st_size = 0;
--}
--
--error_t
--trivfs_goaway (struct trivfs_control *cntl, int flags)
--{
-- update_random_seed_file ();
-- exit (0);
--}
--
--/* Read data from an IO object. If offset is -1, read from the object
-- maintained file pointer. If the object is not seekable, offset is
-- ignored. The amount desired to be read is in AMOUNT. */
--error_t
--trivfs_S_io_read (struct trivfs_protid *cred,
-- mach_port_t reply, mach_msg_type_name_t reply_type,
-- data_t *data, mach_msg_type_number_t *data_len,
-- loff_t offs, mach_msg_type_number_t amount)
--{
-- error_t err;
-- mach_msg_type_number_t read_amount = 0;
-- void *buf = NULL;
-- size_t length;
--
-- /* Deny access if they have bad credentials. */
-- if (! cred)
-- return EOPNOTSUPP;
-- else if (! (cred->po->openmodes & O_READ))
-- return EBADF;
--
-- pthread_mutex_lock (&global_lock);
--
-- while (amount > 0)
-- {
-- mach_msg_type_number_t new_amount;
-- /* XXX: It would be nice to fix readable_pool to work for sizes
-- greater than the POOLSIZE. Otherwise we risk detecting too
-- late that we run out of entropy and all that entropy is
-- wasted. */
-- while (readable_pool (amount, level) == 0)
-- {
-- if (cred->po->openmodes & O_NONBLOCK)
-- {
-- pthread_mutex_unlock (&global_lock);
-- err = EWOULDBLOCK;
-- goto errout;
-- }
-- read_blocked = 1;
-- if (pthread_hurd_cond_wait_np (&wait, &global_lock))
-- {
-- pthread_mutex_unlock (&global_lock);
-- err = EINTR;
-- goto errout;
-- }
-- /* See term/users.c for possible race? */
-- }
--
-- /* Possibly allocate a new buffer. */
-- if (*data_len < amount)
-- {
-- *data = mmap (0, amount, PROT_READ|PROT_WRITE,
-- MAP_ANON, 0, 0);
--
-- if (*data == MAP_FAILED)
-- {
-- pthread_mutex_unlock (&global_lock);
-- return errno;
-- }
--
-- /* Keep track of our map in case of errors. */
-- buf = *data, length = amount;
--
-- /* Update DATA_LEN to reflect the new buffers size. */
-- *data_len = amount;
-- }
--
-- new_amount = read_pool (((byte *) *data) + read_amount, amount, level);
-- read_amount += new_amount;
-- amount -= new_amount;
-- }
--
-- /* Set atime, see term/users.c */
--
-- pthread_mutex_unlock (&global_lock);
-- *data_len = read_amount;
-- return 0;
--
-- errout:
-- if (buf)
-- munmap (buf, length);
-- return err;
--}
--
--/* Write data to an IO object. If offset is -1, write at the object
-- maintained file pointer. If the object is not seekable, offset is
-- ignored. The amount successfully written is returned in amount. A
-- given user should not have more than one outstanding io_write on an
-- object at a time; servers implement congestion control by delaying
-- responses to io_write. Servers may drop data (returning ENOBUFS)
-- if they receive more than one write when not prepared for it. */
--error_t
--trivfs_S_io_write (struct trivfs_protid *cred,
-- mach_port_t reply,
-- mach_msg_type_name_t replytype,
-- data_t data,
-- mach_msg_type_number_t datalen,
-- loff_t offset,
-- mach_msg_type_number_t *amount)
--{
-- int i = 0;
-- /* Deny access if they have bad credentials. */
-- if (! cred)
-- return EOPNOTSUPP;
-- else if (! (cred->po->openmodes & O_WRITE))
-- return EBADF;
--
-- pthread_mutex_lock (&global_lock);
--
-- while (i < datalen)
-- {
-- gatherbuf[gatherwpos] = data[i++];
-- gatherwpos = (gatherwpos + 1) % GATHERBUFSIZE;
-- if (gatherrpos == gatherwpos)
-- /* Overrun. */
-- gatherrpos = (gatherrpos + 1) % GATHERBUFSIZE;
-- }
-- *amount = datalen;
--
-- if (datalen > 0 && read_blocked)
-- {
-- read_blocked = 0;
-- pthread_cond_broadcast (&wait);
-- pthread_cond_broadcast (&select_alert);
-- }
--
-- pthread_mutex_unlock (&global_lock);
-- return 0;
--}
--
--/* Tell how much data can be read from the object without blocking for
-- a "long time" (this should be the same meaning of "long time" used
-- by the nonblocking flag. */
--kern_return_t
--trivfs_S_io_readable (struct trivfs_protid *cred,
-- mach_port_t reply, mach_msg_type_name_t replytype,
-- mach_msg_type_number_t *amount)
--{
-- /* Deny access if they have bad credentials. */
-- if (! cred)
-- return EOPNOTSUPP;
-- else if (! (cred->po->openmodes & O_READ))
-- return EBADF;
--
-- pthread_mutex_lock (&global_lock);
--
-- /* XXX: Before initialization, the amount depends on the amount we
-- want to read. Assume some medium value. */
-- *amount = readable_pool (POOLSIZE/2, level);
--
-- pthread_mutex_unlock (&global_lock);
--
-- return 0;
--}
--
--/* SELECT_TYPE is the bitwise OR of SELECT_READ, SELECT_WRITE, and SELECT_URG.
-- Block until one of the indicated types of i/o can be done "quickly", and
-- return the types that are then available. ID_TAG is returned as passed; it
-- is just for the convenience of the user in matching up reply messages with
-- specific requests sent. */
--error_t
--trivfs_S_io_select (struct trivfs_protid *cred,
-- mach_port_t reply,
-- mach_msg_type_name_t reply_type,
-- int *type)
--{
-- if (!cred)
-- return EOPNOTSUPP;
--
-- /* We only deal with SELECT_READ and SELECT_WRITE here. */
-- if (*type & ~(SELECT_READ | SELECT_WRITE))
-- return EINVAL;
--
-- if (*type == 0)
-- return 0;
--
-- pthread_mutex_lock (&global_lock);
--
-- while (1)
-- {
-- /* XXX Before initialization, readable_pool depends on length. */
-- int avail = readable_pool (POOLSIZE/2, level);
--
-- if (avail != 0 || *type & SELECT_WRITE)
-- {
-- *type = (avail ? SELECT_READ : 0) | (*type & SELECT_WRITE);
-- pthread_mutex_unlock (&global_lock);
-- return 0;
-- }
--
-- ports_interrupt_self_on_port_death (cred, reply);
-- read_blocked = 1;
--
-- if (pthread_hurd_cond_wait_np (&select_alert, &global_lock))
-- {
-- *type = 0;
-- pthread_mutex_unlock (&global_lock);
-- return EINTR;
-- }
-- }
--}
--
--
--/* Change current read/write offset */
--error_t
--trivfs_S_io_seek (struct trivfs_protid *cred,
-- mach_port_t reply, mach_msg_type_name_t reply_type,
-- loff_t offs, int whence, loff_t *new_offs)
--{
-- if (! cred)
-- return EOPNOTSUPP;
--
-- /* Not seekable. */
-- return ESPIPE;
--}
--
--/* Change the size of the file. If the size increases, new blocks are
-- zero-filled. After successful return, it is safe to reference mapped
-- areas of the file up to NEW_SIZE. */
--error_t
--trivfs_S_file_set_size (struct trivfs_protid *cred,
-- mach_port_t reply, mach_msg_type_name_t reply_type,
-- loff_t size)
--{
-- if (!cred)
-- return EOPNOTSUPP;
--
-- return size == 0 ? 0 : EINVAL;
--}
--
--/* These four routines modify the O_APPEND, O_ASYNC, O_FSYNC, and
-- O_NONBLOCK bits for the IO object. In addition, io_get_openmodes
-- will tell you which of O_READ, O_WRITE, and O_EXEC the object can
-- be used for. The O_ASYNC bit affects icky async I/O; good async
-- I/O is done through io_async which is orthogonal to these calls. */
--error_t
--trivfs_S_io_set_all_openmodes(struct trivfs_protid *cred,
-- mach_port_t reply,
-- mach_msg_type_name_t reply_type,
-- int mode)
--{
-- if (!cred)
-- return EOPNOTSUPP;
--
-- return 0;
--}
--
--error_t
--trivfs_S_io_set_some_openmodes (struct trivfs_protid *cred,
-- mach_port_t reply,
-- mach_msg_type_name_t reply_type,
-- int bits)
--{
-- if (!cred)
-- return EOPNOTSUPP;
--
-- return 0;
--}
--
--error_t
--trivfs_S_io_get_owner (struct trivfs_protid *cred,
-- mach_port_t reply,
-- mach_msg_type_name_t reply_type,
-- pid_t *owner)
--{
-- if (!cred)
-- return EOPNOTSUPP;
--
-- *owner = 0;
-- return 0;
--}
--
--error_t
--trivfs_S_io_mod_owner (struct trivfs_protid *cred,
-- mach_port_t reply, mach_msg_type_name_t reply_type,
-- pid_t owner)
--{
-- if (!cred)
-- return EOPNOTSUPP;
--
-- return EINVAL;
--}
--
--/* Return objects mapping the data underlying this memory object. If
-- the object can be read then memobjrd will be provided; if the
-- object can be written then memobjwr will be provided. For objects
-- where read data and write data are the same, these objects will be
-- equal, otherwise they will be disjoint. Servers are permitted to
-- implement io_map but not io_map_cntl. Some objects do not provide
-- mapping; they will set none of the ports and return an error. Such
-- objects can still be accessed by io_read and io_write. */
--error_t
--trivfs_S_io_map(struct trivfs_protid *cred,
-- mach_port_t reply, mach_msg_type_name_t reply_type,
-- mach_port_t *rdobj,
-- mach_msg_type_name_t *rdtype,
-- mach_port_t *wrobj,
-- mach_msg_type_name_t *wrtype)
--{
-- if (!cred)
-- return EOPNOTSUPP;
--
-- return EINVAL;
--}
--
--
--int
--random_demuxer (mach_msg_header_t *inp,
-- mach_msg_header_t *outp)
--{
-- extern int startup_notify_server (mach_msg_header_t *, mach_msg_header_t *);
--
-- return (trivfs_demuxer (inp, outp)
-- || startup_notify_server (inp, outp));
--}
--
--
--/* Options processing. We accept the same options on the command line
-- and from fsys_set_options. */
--
--static const struct argp_option options[] =
--{
-- {"weak", 'w', 0, 0, "Output weak pseudo random data"},
-- {"fast", 'f', 0, 0, "Output cheap random data fast"},
-- {"secure", 's', 0, 0, "Output cryptographically secure random"},
-- {"seed-file", 'S', "FILE", 0, "Use FILE to remember the seed"},
-- {0}
--};
--
--static error_t
--parse_opt (int opt, char *arg, struct argp_state *state)
--{
-- switch (opt)
-- {
-- default:
-- return ARGP_ERR_UNKNOWN;
-- case ARGP_KEY_INIT:
-- case ARGP_KEY_SUCCESS:
-- case ARGP_KEY_ERROR:
-- break;
--
-- case 'w':
-- {
-- level = 0;
-- break;
-- }
-- case 'f':
-- {
-- level = 1;
-- break;
-- }
-- case 's':
-- {
-- level = 2;
-- break;
-- }
-- case 'S':
-- {
-- seed_file = strdup (arg);
-- set_random_seed_file (arg);
-- }
-- }
-- return 0;
--}
--
--/* This will be called from libtrivfs to help construct the answer
-- to an fsys_get_options RPC. */
--error_t
--trivfs_append_args (struct trivfs_control *fsys,
-- char **argz, size_t *argz_len)
--{
-- error_t err = 0;
-- char *opt;
--
-- pthread_mutex_lock (&global_lock);
-- switch (level)
-- {
-- case 0:
-- opt = "--weak";
-- break;
--
-- case 1:
-- opt = "--fast";
-- break;
--
-- default:
-- opt = "--secure";
-- }
-- if (level != DEFAULT_LEVEL)
-- err = argz_add (argz, argz_len, opt);
--
-- if (!err && seed_file)
-- {
-- if (asprintf (&opt, "--seed-file=%s", seed_file) < 0)
-- err = ENOMEM;
-- else
-- {
-- err = argz_add (argz, argz_len, opt);
-- free (opt);
-- }
-- }
-- pthread_mutex_unlock (&global_lock);
--
-- return err;
--}
--
--static struct argp random_argp =
--{ options, parse_opt, 0,
-- "A translator providing random output." };
--
--/* Setting this variable makes libtrivfs use our argp to
-- parse options passed in an fsys_set_options RPC. */
--struct argp *trivfs_runtime_argp = &random_argp;
--
--struct port_class *shutdown_notify_class;
--
--/* The system is going down; destroy all the extant port rights. That
-- will cause net channels and such to close promptly. */
--error_t
--S_startup_dosync (mach_port_t handle)
--{
-- struct port_info *inpi = ports_lookup_port (fsys->pi.bucket, handle,
-- shutdown_notify_class);
--
-- if (!inpi)
-- return EOPNOTSUPP;
--
-- update_random_seed_file ();
-- return 0;
--}
--
--void
--sigterm_handler (int signo)
--{
-- update_random_seed_file ();
-- signal (SIGTERM, SIG_DFL);
-- raise (SIGTERM);
--}
--
--static error_t
--arrange_shutdown_notification ()
--{
-- error_t err;
-- mach_port_t initport, notify;
-- struct port_info *pi;
--
-- shutdown_notify_class = ports_create_class (0, 0);
--
-- signal (SIGTERM, sigterm_handler);
--
-- /* Arrange to get notified when the system goes down,
-- but if we fail for some reason, just silently give up. No big deal. */
--
-- err = ports_create_port (shutdown_notify_class, fsys->pi.bucket,
-- sizeof (struct port_info), &pi);
-- if (err)
-- return err;
--
-- initport = file_name_lookup (_SERVERS_STARTUP, 0, 0);
-- if (! MACH_PORT_VALID (initport))
-- return errno;
--
-- notify = ports_get_send_right (pi);
-- ports_port_deref (pi);
-- err = startup_request_notification (initport, notify,
-- MACH_MSG_TYPE_MAKE_SEND,
-- program_invocation_short_name);
--
-- mach_port_deallocate (mach_task_self (), notify);
-- mach_port_deallocate (mach_task_self (), initport);
-- return err;
--}
--
--
--int
--main (int argc, char **argv)
--{
-- error_t err;
-- mach_port_t bootstrap;
--
-- /* Initialize the lock that will protect everything.
-- We must do this before argp_parse, because parse_opt (above) will
-- use the lock. */
-- pthread_mutex_init (&global_lock, NULL);
--
-- /* The conditions are used to implement proper read/select
-- behaviour. */
-- pthread_cond_init (&wait, NULL);
-- pthread_cond_init (&select_alert, NULL);
--
-- /* We use the same argp for options available at startup
-- as for options we'll accept in an fsys_set_options RPC. */
-- argp_parse (&random_argp, argc, argv, 0, 0, 0);
--
-- task_get_bootstrap_port (mach_task_self (), &bootstrap);
-- if (bootstrap == MACH_PORT_NULL)
-- error (1, 0, "Must be started as a translator");
--
-- /* Reply to our parent */
-- err = trivfs_startup (bootstrap, 0, 0, 0, 0, 0, &fsys);
-- mach_port_deallocate (mach_task_self (), bootstrap);
-- if (err)
-- error (3, err, "trivfs_startup");
--
-- err = arrange_shutdown_notification ();
-- if (err)
-- error (0, err, "Cannot request shutdown notification");
--
-- /* Launch. */
-- ports_manage_port_operations_multithread (fsys->pi.bucket, random_demuxer,
-- 10 * 1000, /* idle thread */
-- 10 * 60 * 1000, /* idle server */
-- 0);
-- return 0;
--}
-diff --git a/random/random.h b/random/random.h
-deleted file mode 100644
-index a38a417..0000000
---- a/random/random.h
-+++ /dev/null
-@@ -1,32 +0,0 @@
--/* random.c - A single-file translator providing random data
-- Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
-- published by the Free Software Foundation; either version 2, or (at
-- your option) any later version.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
--
--#ifndef __RANDOM_H__
--#define __RANDOM_H__
--
--/* How many random bytes to gather at most.
-- XXX: Should be at least POOLSIZE. */
--#define GATHERBUFSIZE 32768
--
--/* The random bytes we collected. */
--extern char gatherbuf[GATHERBUFSIZE];
--
--/* The current positions in gatherbuf[]. */
--extern int gatherrpos;
--extern int gatherwpos;
--
--#endif
-diff --git a/sutils/MAKEDEV.sh b/sutils/MAKEDEV.sh
-index 1baec15..9fd4b1d 100644
---- a/sutils/MAKEDEV.sh
-+++ b/sutils/MAKEDEV.sh
-@@ -100,7 +100,7 @@ mkdev() {
- ;;
-
- std)
-- mkdev console tty urandom null zero full fd time mem klog shm
-+ mkdev console tty random urandom null zero full fd time mem klog shm
- ;;
- console|com[0-9])
- st $I root 600 /hurd/term ${DEVDIR}/$I device $I;;
-@@ -111,8 +111,10 @@ mkdev() {
- ${DEVDIR}/vcs/`echo $I | sed -e s/tty//`/console;;
- lpr[0-9])
- st $I root 660 /hurd/streamio "$I";;
-+ random)
-+ st $I root 644 /hurd/random --secure --seed-file /var/lib/random-seed;;
- urandom)
-- st $I root 644 /hurd/random --fast --seed-file /var/lib/random-seed;;
-+ st $I root 644 /hurd/random --fast --seed-file /var/lib/urandom-seed;;
- null)
- st $I root 666 /hurd/null;;
- full)
-diff --git a/trans/Makefile b/trans/Makefile
-index ce1eae7..ec0586e 100644
---- a/trans/Makefile
-+++ b/trans/Makefile
-@@ -21,14 +21,14 @@ makemode := servers
-
- targets = symlink firmlink ifsock magic null fifo new-fifo fwd crash \
- password hello hello-mt streamio fakeroot proxy-defpager remap \
-- mtab
-+ mtab random
- SRCS = ifsock.c symlink.c magic.c null.c fifo.c new-fifo.c fwd.c \
- crash.c firmlink.c password.c hello.c hello-mt.c streamio.c \
- fakeroot.c proxy-defpager.c remap.c mtab.c
- OBJS = $(SRCS:.c=.o) fsysServer.o ifsockServer.o passwordServer.o \
- crashServer.o crash_replyUser.o msgServer.o \
- default_pagerServer.o default_pagerUser.o \
-- device_replyServer.o elfcore.o
-+ device_replyServer.o elfcore.o startup_notifyServer.o
- HURDLIBS = ports netfs trivfs iohelp fshelp pipe ihash shouldbeinlibc
- LDLIBS += -lpthread
- password-LDLIBS = -lcrypt
-@@ -51,6 +51,8 @@ device_reply-MIGSFLAGS="-DMACH_PAYLOAD_TO_PORT=ports_payload_get_name"
- # libports. Disable the default payload to port conversion.
- fsys-MIGSFLAGS = "-DHURD_DEFAULT_PAYLOAD_TO_PORT=1"
-
-+random-LDLIBS = -lgcrypt
-+
- include ../Makeconf
-
- vpath elfcore.c $(top_srcdir)/exec
-@@ -71,6 +73,7 @@ hello: ../libtrivfs/libtrivfs.a ../libfshelp/libfshelp.a ../libports/libports.a
- fakeroot: ../libnetfs/libnetfs.a ../libfshelp/libfshelp.a ../libiohelp/libiohelp.a ../libports/libports.a ../libihash/libihash.a
- remap: ../libtrivfs/libtrivfs.a ../libfshelp/libfshelp.a ../libports/libports.a ../libihash/libihash.a
- mtab: ../libtrivfs/libtrivfs.a ../libfshelp/libfshelp.a ../libports/libports.a ../libihash/libihash.a fsUser.o
-+random: ../libtrivfs/libtrivfs.a ../libports/libports.a ../libihash/libihash.a startup_notifyServer.o mach_debugUser.o
- $(targets): ../libshouldbeinlibc/libshouldbeinlibc.a
-
- $(targets): %: %.o
-diff --git a/trans/random.c b/trans/random.c
-new file mode 100644
-index 0000000..83f0579
---- /dev/null
-+++ b/trans/random.c
-@@ -0,0 +1,682 @@
-+/* random.c - A single-file translator providing random data
-+ Copyright (C) 1998, 1999, 2001, 2015 Free Software Foundation, Inc.
-+
-+ This program is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU General Public License as
-+ published by the Free Software Foundation; either version 2, or (at
-+ your option) any later version.
-+
-+ This program is distributed in the hope that it will be useful, but
-+ WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the Free Software
-+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-+
-+#include <argp.h>
-+#include <argz.h>
-+#include <assert.h>
-+#include <error.h>
-+#include <fcntl.h>
-+#include <gcrypt.h>
-+#include <hurd/paths.h>
-+#include <hurd/startup.h>
-+#include <hurd/trivfs.h>
-+#include <mach_debug/mach_debug_types.h>
-+#include <pthread.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <sys/mman.h>
-+#include <sys/stat.h>
-+#include <unistd.h>
-+#include <version.h>
-+
-+#include "mach_debug_U.h"
-+
-+/* Our control port. */
-+struct trivfs_control *fsys;
-+
-+int read_blocked; /* For read and select. */
-+pthread_cond_t wait; /* For read and select. */
-+pthread_cond_t select_alert; /* For read and select. */
-+
-+/* The quality of randomness we provide. If URANDOM is set, return
-+ unlimited random data. */
-+static int urandom;
-+
-+/* Name of file to use as seed. */
-+static char *seed_file;
-+
-+/* Entropy management. */
-+
-+/* Estimate of available entropy measured in bytes. */
-+static size_t entropy;
-+
-+/* Protected by this lock. */
-+static pthread_mutex_t entropy_lock;
-+
-+static error_t
-+entropy_add (const void *buf, size_t length, float factor)
-+{
-+ gcry_error_t cerr;
-+ size_t new_entropy;
-+ pthread_mutex_lock (&entropy_lock);
-+
-+ cerr = gcry_random_add_bytes (buf, length, -1);
-+ if (cerr)
-+ {
-+ pthread_mutex_unlock (&entropy_lock);
-+ error (0, 0, "Failed to add random bytes: %s",
-+ gcry_strerror (cerr));
-+ return EINVAL;
-+ }
-+ new_entropy = (size_t) ((float) length * factor);
-+ entropy += new_entropy;
-+
-+ if (new_entropy > 0 && read_blocked)
-+ {
-+ read_blocked = 0;
-+ pthread_cond_broadcast (&wait);
-+ pthread_cond_broadcast (&select_alert);
-+ }
-+
-+ pthread_mutex_unlock (&entropy_lock);
-+ return 0;
-+}
-+
-+static void
-+update_random_seed_file (void)
-+{
-+ gcry_error_t cerr;
-+ cerr = gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE, seed_file, 0);
-+ if (cerr)
-+ error (0, 0, "Updating random seed file %s failed: %s",
-+ seed_file, gcry_strerror (cerr));
-+}
-+
-+static void
-+initialize_gcrypt (void)
-+{
-+ gcry_error_t cerr;
-+ struct stat s;
-+
-+ if (! gcry_check_version (GCRYPT_VERSION))
-+ error (1, 0, "libgcrypt version mismatch\n");
-+
-+ cerr = gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE,
-+ GCRY_RNG_TYPE_STANDARD, 0);
-+ if (cerr)
-+ error (1, 0, "Selecting preferred rng type failed: %s",
-+ gcry_strerror (cerr));
-+
-+ cerr = gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, seed_file, 0);
-+ if (cerr)
-+ error (1, 0, "Setting seed file %s failed: %s",
-+ seed_file, gcry_strerror (cerr));
-+
-+ cerr = gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
-+ if (cerr)
-+ error (1, 0, "Finalizing gcrypt failed: %s",
-+ gcry_strerror (cerr));
-+
-+ if (stat (seed_file, &s) == 0)
-+ /* Libgcrypt will read the seed file on demand. Set entropy
-+ accordingly. */
-+ entropy = s.st_size;
-+}
-+
-+static void
-+gather_slab_info (void)
-+{
-+ error_t err;
-+ cache_info_array_t cache_info;
-+ mach_msg_type_number_t cache_info_count, i;
-+
-+ cache_info = NULL;
-+ cache_info_count = 0;
-+
-+ err = host_slab_info (mach_host_self(), &cache_info, &cache_info_count);
-+ if (err)
-+ {
-+ error (0, err, "host_slab_info");
-+ return;
-+ }
-+
-+ for (i = 0; i < cache_info_count; i++)
-+ if (cache_info[i].nr_bufs > 500)
-+ entropy_add (&cache_info[i].nr_objs, sizeof cache_info[i].nr_objs,
-+ 0.25);
-+
-+ vm_deallocate (mach_task_self (),
-+ (vm_address_t) cache_info,
-+ cache_info_count * sizeof *cache_info);
-+}
-+
-+static void *
-+gather_thread (void *args)
-+{
-+ while (1)
-+ {
-+ gather_slab_info ();
-+ sleep (1); /* XXX vary sleep time */
-+ }
-+
-+ assert (! "reached");
-+}
-+
-+error_t
-+start_gather_thread (void)
-+{
-+ error_t err;
-+ pthread_t thread;
-+
-+ err = pthread_create (&thread, NULL, gather_thread, NULL);
-+ if (err)
-+ return err;
-+
-+ err = pthread_detach (thread);
-+ return err;
-+}
-+
-+const char *argp_program_version = STANDARD_HURD_VERSION (random);
-+
-+/* Trivfs hooks. */
-+int trivfs_fstype = FSTYPE_MISC;
-+int trivfs_fsid = 0;
-+
-+int trivfs_allow_open = O_READ | O_WRITE;
-+
-+int trivfs_support_read = 1;
-+int trivfs_support_write = 1;
-+int trivfs_support_exec = 0;
-+
-+void
-+trivfs_modify_stat (struct trivfs_protid *cred, struct stat *st)
-+{
-+ /* Mark the node as a read-only plain file. */
-+ st->st_mode &= ~((unsigned) S_IFMT);
-+ st->st_mode |= (S_IFCHR);
-+ st->st_size = 0;
-+}
-+
-+error_t
-+trivfs_goaway (struct trivfs_control *cntl, int flags)
-+{
-+ update_random_seed_file ();
-+ exit (0);
-+}
-+
-+/* Read data from an IO object. If offset is -1, read from the object
-+ maintained file pointer. If the object is not seekable, offset is
-+ ignored. The amount desired to be read is in AMOUNT. */
-+error_t
-+trivfs_S_io_read (struct trivfs_protid *cred,
-+ mach_port_t reply, mach_msg_type_name_t reply_type,
-+ data_t *data, mach_msg_type_number_t *data_len,
-+ loff_t offs, mach_msg_type_number_t amount)
-+{
-+ error_t err;
-+ void *buf = NULL;
-+ size_t length = 0;
-+
-+ if (! cred)
-+ return EOPNOTSUPP;
-+ else if (! (cred->po->openmodes & O_READ))
-+ return EBADF;
-+
-+ pthread_mutex_lock (&entropy_lock);
-+
-+ if (amount > 0)
-+ {
-+ while (! urandom && amount > entropy)
-+ {
-+ if (cred->po->openmodes & O_NONBLOCK)
-+ {
-+ err = EWOULDBLOCK;
-+ goto errout;
-+ }
-+ read_blocked = 1;
-+ if (pthread_hurd_cond_wait_np (&wait, &entropy_lock))
-+ {
-+ err = EINTR;
-+ goto errout;
-+ }
-+ /* See term/users.c for possible race? */
-+ }
-+
-+ /* Possibly allocate a new buffer. */
-+ if (*data_len < amount)
-+ {
-+ *data = mmap (0, amount, PROT_READ|PROT_WRITE,
-+ MAP_ANON, 0, 0);
-+
-+ if (*data == MAP_FAILED)
-+ {
-+ pthread_mutex_unlock (&entropy_lock);
-+ return errno;
-+ }
-+
-+ /* Keep track of our map in case of errors. */
-+ buf = *data, length = amount;
-+
-+ /* Update DATA_LEN to reflect the new buffers size. */
-+ *data_len = amount;
-+ }
-+
-+ if (! urandom)
-+ assert (entropy >= amount);
-+ else if (entropy >= amount)
-+ entropy -= amount;
-+ else
-+ entropy = 0;
-+
-+ gcry_randomize ((unsigned char *) *data, amount, GCRY_STRONG_RANDOM);
-+ }
-+
-+ /* Set atime, see term/users.c */
-+
-+ pthread_mutex_unlock (&entropy_lock);
-+ *data_len = amount;
-+ return 0;
-+
-+ errout:
-+ pthread_mutex_unlock (&entropy_lock);
-+ if (buf)
-+ munmap (buf, length);
-+ return err;
-+}
-+
-+/* Write data to an IO object. If offset is -1, write at the object
-+ maintained file pointer. If the object is not seekable, offset is
-+ ignored. The amount successfully written is returned in amount. A
-+ given user should not have more than one outstanding io_write on an
-+ object at a time; servers implement congestion control by delaying
-+ responses to io_write. Servers may drop data (returning ENOBUFS)
-+ if they receive more than one write when not prepared for it. */
-+error_t
-+trivfs_S_io_write (struct trivfs_protid *cred,
-+ mach_port_t reply,
-+ mach_msg_type_name_t replytype,
-+ data_t data,
-+ mach_msg_type_number_t datalen,
-+ loff_t offset,
-+ mach_msg_type_number_t *amount)
-+{
-+ error_t err;
-+
-+ /* Deny access if they have bad credentials. */
-+ if (! cred)
-+ return EOPNOTSUPP;
-+ else if (! (cred->po->openmodes & O_WRITE))
-+ return EBADF;
-+
-+ err = entropy_add (data, datalen, 0);
-+ *amount = datalen;
-+ return err;
-+}
-+
-+/* Tell how much data can be read from the object without blocking for
-+ a "long time" (this should be the same meaning of "long time" used
-+ by the nonblocking flag. */
-+kern_return_t
-+trivfs_S_io_readable (struct trivfs_protid *cred,
-+ mach_port_t reply, mach_msg_type_name_t replytype,
-+ mach_msg_type_number_t *amount)
-+{
-+ /* Deny access if they have bad credentials. */
-+ if (! cred)
-+ return EOPNOTSUPP;
-+ else if (! (cred->po->openmodes & O_READ))
-+ return EBADF;
-+
-+ pthread_mutex_lock (&entropy_lock);
-+
-+ *amount = entropy;
-+
-+ pthread_mutex_unlock (&entropy_lock);
-+
-+ return 0;
-+}
-+
-+/* SELECT_TYPE is the bitwise OR of SELECT_READ, SELECT_WRITE, and SELECT_URG.
-+ Block until one of the indicated types of i/o can be done "quickly", and
-+ return the types that are then available. ID_TAG is returned as passed; it
-+ is just for the convenience of the user in matching up reply messages with
-+ specific requests sent. */
-+error_t
-+trivfs_S_io_select (struct trivfs_protid *cred,
-+ mach_port_t reply,
-+ mach_msg_type_name_t reply_type,
-+ int *type)
-+{
-+ if (!cred)
-+ return EOPNOTSUPP;
-+
-+ /* We only deal with SELECT_READ and SELECT_WRITE here. */
-+ if (*type & ~(SELECT_READ | SELECT_WRITE))
-+ return EINVAL;
-+
-+ if (*type == 0)
-+ return 0;
-+
-+ pthread_mutex_lock (&entropy_lock);
-+
-+ while (1)
-+ {
-+ if (entropy > 0 || *type & SELECT_WRITE)
-+ {
-+ *type = (entropy > 0 ? SELECT_READ : 0) | (*type & SELECT_WRITE);
-+ pthread_mutex_unlock (&entropy_lock);
-+ return 0;
-+ }
-+
-+ ports_interrupt_self_on_port_death (cred, reply);
-+ read_blocked = 1;
-+
-+ if (pthread_hurd_cond_wait_np (&select_alert, &entropy_lock))
-+ {
-+ *type = 0;
-+ pthread_mutex_unlock (&entropy_lock);
-+ return EINTR;
-+ }
-+ }
-+}
-+
-+
-+/* Change current read/write offset */
-+error_t
-+trivfs_S_io_seek (struct trivfs_protid *cred,
-+ mach_port_t reply, mach_msg_type_name_t reply_type,
-+ loff_t offs, int whence, loff_t *new_offs)
-+{
-+ if (! cred)
-+ return EOPNOTSUPP;
-+
-+ /* Not seekable. */
-+ return ESPIPE;
-+}
-+
-+/* Change the size of the file. If the size increases, new blocks are
-+ zero-filled. After successful return, it is safe to reference mapped
-+ areas of the file up to NEW_SIZE. */
-+error_t
-+trivfs_S_file_set_size (struct trivfs_protid *cred,
-+ mach_port_t reply, mach_msg_type_name_t reply_type,
-+ loff_t size)
-+{
-+ if (!cred)
-+ return EOPNOTSUPP;
-+
-+ return size == 0 ? 0 : EINVAL;
-+}
-+
-+/* These four routines modify the O_APPEND, O_ASYNC, O_FSYNC, and
-+ O_NONBLOCK bits for the IO object. In addition, io_get_openmodes
-+ will tell you which of O_READ, O_WRITE, and O_EXEC the object can
-+ be used for. The O_ASYNC bit affects icky async I/O; good async
-+ I/O is done through io_async which is orthogonal to these calls. */
-+error_t
-+trivfs_S_io_set_all_openmodes(struct trivfs_protid *cred,
-+ mach_port_t reply,
-+ mach_msg_type_name_t reply_type,
-+ int mode)
-+{
-+ if (!cred)
-+ return EOPNOTSUPP;
-+
-+ return 0;
-+}
-+
-+error_t
-+trivfs_S_io_set_some_openmodes (struct trivfs_protid *cred,
-+ mach_port_t reply,
-+ mach_msg_type_name_t reply_type,
-+ int bits)
-+{
-+ if (!cred)
-+ return EOPNOTSUPP;
-+
-+ return 0;
-+}
-+
-+error_t
-+trivfs_S_io_get_owner (struct trivfs_protid *cred,
-+ mach_port_t reply,
-+ mach_msg_type_name_t reply_type,
-+ pid_t *owner)
-+{
-+ if (!cred)
-+ return EOPNOTSUPP;
-+
-+ *owner = 0;
-+ return 0;
-+}
-+
-+error_t
-+trivfs_S_io_mod_owner (struct trivfs_protid *cred,
-+ mach_port_t reply, mach_msg_type_name_t reply_type,
-+ pid_t owner)
-+{
-+ if (!cred)
-+ return EOPNOTSUPP;
-+
-+ return EINVAL;
-+}
-+
-+/* Return objects mapping the data underlying this memory object. If
-+ the object can be read then memobjrd will be provided; if the
-+ object can be written then memobjwr will be provided. For objects
-+ where read data and write data are the same, these objects will be
-+ equal, otherwise they will be disjoint. Servers are permitted to
-+ implement io_map but not io_map_cntl. Some objects do not provide
-+ mapping; they will set none of the ports and return an error. Such
-+ objects can still be accessed by io_read and io_write. */
-+error_t
-+trivfs_S_io_map(struct trivfs_protid *cred,
-+ mach_port_t reply, mach_msg_type_name_t reply_type,
-+ mach_port_t *rdobj,
-+ mach_msg_type_name_t *rdtype,
-+ mach_port_t *wrobj,
-+ mach_msg_type_name_t *wrtype)
-+{
-+ if (!cred)
-+ return EOPNOTSUPP;
-+
-+ return EINVAL;
-+}
-+
-+
-+int
-+random_demuxer (mach_msg_header_t *inp,
-+ mach_msg_header_t *outp)
-+{
-+ extern int startup_notify_server (mach_msg_header_t *, mach_msg_header_t *);
-+
-+ return (trivfs_demuxer (inp, outp)
-+ || startup_notify_server (inp, outp));
-+}
-+
-+
-+/* Options processing. We accept the same options on the command line
-+ and from fsys_set_options. */
-+
-+static const struct argp_option options[] =
-+{
-+ {"fast", 'f', 0, 0, "Output cheap random data fast"},
-+ {"secure", 's', 0, 0,
-+ "Output cryptographically secure random (the default)"},
-+ {"seed-file", 'S', "FILE", 0, "Use FILE to remember the seed"},
-+ {0}
-+};
-+
-+static error_t
-+parse_opt (int opt, char *arg, struct argp_state *state)
-+{
-+ switch (opt)
-+ {
-+ default:
-+ return ARGP_ERR_UNKNOWN;
-+ case ARGP_KEY_INIT:
-+ case ARGP_KEY_SUCCESS:
-+ case ARGP_KEY_ERROR:
-+ break;
-+
-+ case 'f':
-+ urandom = 1;
-+ break;
-+
-+ case 's':
-+ urandom = 0;
-+ break;
-+
-+ case 'S':
-+ seed_file = strdup (arg);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+/* This will be called from libtrivfs to help construct the answer
-+ to an fsys_get_options RPC. */
-+error_t
-+trivfs_append_args (struct trivfs_control *fsys,
-+ char **argz, size_t *argz_len)
-+{
-+ error_t err = 0;
-+ char *opt;
-+
-+ err = argz_add (argz, argz_len, urandom ? "--fast" : "--secure");
-+ if (err)
-+ return err;
-+
-+ if (seed_file)
-+ {
-+ if (asprintf (&opt, "--seed-file=%s", seed_file) < 0)
-+ err = ENOMEM;
-+ else
-+ {
-+ err = argz_add (argz, argz_len, opt);
-+ free (opt);
-+ }
-+ }
-+
-+ return err;
-+}
-+
-+static struct argp random_argp =
-+{ options, parse_opt, 0,
-+ "A translator providing random output." };
-+
-+/* Setting this variable makes libtrivfs use our argp to
-+ parse options passed in an fsys_set_options RPC. */
-+struct argp *trivfs_runtime_argp = &random_argp;
-+
-+struct port_class *shutdown_notify_class;
-+
-+/* The system is going down; destroy all the extant port rights. That
-+ will cause net channels and such to close promptly. */
-+error_t
-+S_startup_dosync (mach_port_t handle)
-+{
-+ struct port_info *inpi = ports_lookup_port (fsys->pi.bucket, handle,
-+ shutdown_notify_class);
-+
-+ if (!inpi)
-+ return EOPNOTSUPP;
-+
-+ update_random_seed_file ();
-+ return 0;
-+}
-+
-+void
-+sigterm_handler (int signo)
-+{
-+ update_random_seed_file ();
-+ signal (SIGTERM, SIG_DFL);
-+ raise (SIGTERM);
-+}
-+
-+static error_t
-+arrange_shutdown_notification ()
-+{
-+ error_t err;
-+ mach_port_t initport, notify;
-+ struct port_info *pi;
-+
-+ shutdown_notify_class = ports_create_class (0, 0);
-+
-+ signal (SIGTERM, sigterm_handler);
-+
-+ /* Arrange to get notified when the system goes down,
-+ but if we fail for some reason, just silently give up. No big deal. */
-+
-+ err = ports_create_port (shutdown_notify_class, fsys->pi.bucket,
-+ sizeof (struct port_info), &pi);
-+ if (err)
-+ return err;
-+
-+ initport = file_name_lookup (_SERVERS_STARTUP, 0, 0);
-+ if (! MACH_PORT_VALID (initport))
-+ return errno;
-+
-+ notify = ports_get_send_right (pi);
-+ ports_port_deref (pi);
-+ err = startup_request_notification (initport, notify,
-+ MACH_MSG_TYPE_MAKE_SEND,
-+ program_invocation_short_name);
-+
-+ mach_port_deallocate (mach_task_self (), notify);
-+ mach_port_deallocate (mach_task_self (), initport);
-+ return err;
-+}
-+
-+int
-+main (int argc, char **argv)
-+{
-+ error_t err;
-+ mach_port_t bootstrap;
-+
-+ /* Initialize the lock that will protect everything.
-+ We must do this before argp_parse, because parse_opt (above) will
-+ use the lock. */
-+ pthread_mutex_init (&entropy_lock, NULL);
-+
-+ /* The conditions are used to implement proper read/select
-+ behaviour. */
-+ pthread_cond_init (&wait, NULL);
-+ pthread_cond_init (&select_alert, NULL);
-+
-+ /* We use the same argp for options available at startup
-+ as for options we'll accept in an fsys_set_options RPC. */
-+ argp_parse (&random_argp, argc, argv, 0, 0, 0);
-+
-+ initialize_gcrypt ();
-+
-+ task_get_bootstrap_port (mach_task_self (), &bootstrap);
-+ if (bootstrap == MACH_PORT_NULL)
-+ error (1, 0, "Must be started as a translator");
-+
-+ /* Reply to our parent */
-+ err = trivfs_startup (bootstrap, 0, 0, 0, 0, 0, &fsys);
-+ mach_port_deallocate (mach_task_self (), bootstrap);
-+ if (err)
-+ error (3, err, "trivfs_startup");
-+
-+ err = arrange_shutdown_notification ();
-+ if (err)
-+ error (0, err, "Cannot request shutdown notification");
-+
-+ err = start_gather_thread ();
-+ if (err)
-+ error (0, err, "Starting gatherer thread failed");
-+
-+ /* Launch. */
-+ ports_manage_port_operations_multithread (fsys->pi.bucket, random_demuxer,
-+ 10 * 1000, /* idle thread */
-+ 10 * 60 * 1000, /* idle server */
-+ 0);
-+ return 0;
-+}
---
-2.1.4
-
diff --git a/debian/patches/series b/debian/patches/series
index 6f4eeb34..66ea1767 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,4 +1,3 @@
-random0001-xxx-standalone-random-translator.patch
diskfs_no_inherit_dir_group.patch
init_try_runsystem.gnu.patch
makedev.diff