From 750f684c7f0117b16adc02c28d1c329958c2b470 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Fri, 22 Jan 2010 22:36:39 +0100 Subject: rng-tools review: add tpm support patch and init-file --- package/rng-tools/Makefile | 2 +- package/rng-tools/files/rng-tools.postinst | 2 + package/rng-tools/files/rngd.init | 40 ++++ package/rng-tools/patches/rngd_tpm_support.patch | 288 +++++++++++++++++++++++ 4 files changed, 331 insertions(+), 1 deletion(-) create mode 100644 package/rng-tools/files/rng-tools.postinst create mode 100644 package/rng-tools/files/rngd.init create mode 100644 package/rng-tools/patches/rngd_tpm_support.patch diff --git a/package/rng-tools/Makefile b/package/rng-tools/Makefile index 522668e6d..6e0769681 100644 --- a/package/rng-tools/Makefile +++ b/package/rng-tools/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:= rng-tools PKG_VERSION:= 2 -PKG_RELEASE:= 1 +PKG_RELEASE:= 2 PKG_MD5SUM:= 63d503191eabed630324c104cc024475 PKG_DESCR:= Daemon to use hardware random number generators. PKG_SECTION:= utils diff --git a/package/rng-tools/files/rng-tools.postinst b/package/rng-tools/files/rng-tools.postinst new file mode 100644 index 000000000..4e769fe4b --- /dev/null +++ b/package/rng-tools/files/rng-tools.postinst @@ -0,0 +1,2 @@ +. $IPKG_INSTROOT/etc/functions.sh +add_rcconf rngd rngd NO diff --git a/package/rng-tools/files/rngd.init b/package/rng-tools/files/rngd.init new file mode 100644 index 000000000..1464209c0 --- /dev/null +++ b/package/rng-tools/files/rngd.init @@ -0,0 +1,40 @@ +#!/bin/sh +#PKG rng-tools +#INIT 60 + +. /etc/rc.conf + +case $1 in +autostop) ;; +autostart) + test x"${rngd:-NO}" = x"NO" && exit 0 + exec sh $0 start + ;; +start) + devnode="" + for node in hw_random hwrandom i810_rng hwrng; do + if [ -e /dev/$node ]; then + devnode=/dev/$node + break + fi + done + if [ -z "$devnode" ]; then + echo "no hardware RNG found, falling back to /dev/urandom" + devnode=/dev/urandom + fi + rngd -b -r $devnode + ;; +stop) + pkill rngd + ;; +restart) + sh $0 stop + sleep 1 + sh $0 start + ;; +*) + echo "Usage: $0 {start | stop | restart}" + exit 1 + ;; +esac +exit $? diff --git a/package/rng-tools/patches/rngd_tpm_support.patch b/package/rng-tools/patches/rngd_tpm_support.patch new file mode 100644 index 000000000..0edc47109 --- /dev/null +++ b/package/rng-tools/patches/rngd_tpm_support.patch @@ -0,0 +1,288 @@ +Patch taken from http://sourceforge.net/tracker/?func=detail&aid=2261574&group_id=3242&atid=353242 + +diff -uNr rng-tools-2-orig/rngd.c rng-tools-2/rngd.c +--- rng-tools-2-orig/rngd.c 2004-08-24 23:30:00.000000000 +0530 ++++ rng-tools-2/rngd.c 2008-11-11 15:39:31.000000000 +0530 +@@ -91,6 +91,8 @@ + + { "timeout", 't', "nnn", 0, + "Interval written to random-device when the entropy pool is full, in seconds (default: 60)" }, ++ { "no-tpm", 'n', "1|0", 0, ++ "do not use tpm as a source of random number input (default: 0)" }, + + { 0 }, + }; +@@ -102,6 +104,7 @@ + .random_step = 64, + .fill_watermark = 2048, + .daemon = 1, ++ .no_tpm =0, + }; + struct arguments *arguments = &default_arguments; + +@@ -147,6 +150,15 @@ + arguments->fill_watermark = n; + break; + } ++ case 'n': { ++ int n; ++ if ((sscanf(arg,"%i", &n) == 0) || ((n | 1)!=1)) ++ argp_usage(state); ++ else ++ arguments->no_tpm=0; ++ break; ++ ++ } + + default: + return ARGP_ERR_UNKNOWN; +@@ -162,26 +174,41 @@ + double poll_timeout) + { + unsigned char buf[FIPS_RNG_BUFFER_SIZE]; +- unsigned char *p; +- int fips; ++ int fips,retval; + + for (;;) { +- xread(buf, sizeof buf); ++ if (arguments->no_tpm == 0) { ++ retval=xread_tpm(buf, sizeof buf); ++ if (retval < 0) ++ sleep(1); ++ else ++ update_kernel_random(random_step, ++ poll_timeout, buf, &tpm_fipsctx); ++ } ++ retval=xread(buf, sizeof buf); ++ if (retval > 0) ++ update_kernel_random(random_step, ++ poll_timeout, buf, &fipsctx); ++ } ++} + +- fips = fips_run_rng_test(&fipsctx, buf); ++int update_kernel_random(int random_step, double poll_timeout, ++ unsigned char *buf, fips_ctx_t *fipsctx) { + +- if (fips) { +- message(LOG_DAEMON|LOG_ERR, "failed fips test\n"); +- sleep(1); +- continue; +- } ++ int fips; ++ unsigned char *p; ++ fips = fips_run_rng_test(fipsctx, buf); ++ if (fips) { ++ message(LOG_DAEMON|LOG_ERR, "failed fips test\n"); ++ return 1; ++ } + +- for (p = buf; p + random_step <= &buf[sizeof buf]; +- p += random_step) { +- random_add_entropy(p, random_step); +- random_sleep(poll_timeout); +- } ++ for (p = buf; p + random_step <= &buf[FIPS_RNG_BUFFER_SIZE]; ++ p += random_step) { ++ random_add_entropy(p, random_step); ++ random_sleep(poll_timeout); + } ++ return 0; + } + + +diff -uNr rng-tools-2-orig/rngd_entsource.c rng-tools-2/rngd_entsource.c +--- rng-tools-2-orig/rngd_entsource.c 2004-04-15 10:36:17.000000000 +0530 ++++ rng-tools-2/rngd_entsource.c 2008-11-11 15:39:31.000000000 +0530 +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + + #include "rngd.h" + #include "fips.h" +@@ -42,17 +43,27 @@ + #include "rngd_entsource.h" + + +-/* Logic and contexts */ +-static int rng_fd; /* rng data source */ +-fips_ctx_t fipsctx; /* Context for the FIPS tests */ ++/* The overhead incured when tpm returns the random nos as per TCG spec ++ * it is 14 bytes.*/ ++#define TPM_GET_RNG_OVERHEAD 14 + ++static const char *rng_device="/dev/tpm0"; ++/* Logic and contexts */ ++static int rng_fd; /* rng data source */ ++fips_ctx_t fipsctx; /* Context for the FIPS tests */ ++fips_ctx_t tpm_fipsctx; /* Context for the tpm FIPS tests */ + + /* Read data from the entropy source */ +-void xread(void *buf, size_t size) ++int xread(void *buf, size_t size) + { + size_t off = 0; + ssize_t r; + ++ /* Do nothing if we have no hw rng, maybe we have tpm */ ++ if (rng_fd < 0) { ++ message(LOG_DAEMON|LOG_ERR, "Invalid file handle\n"); ++ return -1; ++ } + while (size > 0) { + do { + r = read(rng_fd, buf + off, size); +@@ -65,8 +76,85 @@ + + if (size) { + message(LOG_DAEMON|LOG_ERR, "read error\n"); +- exit(1); ++ return -1; ++ } ++ return 0; ++} ++ ++alarm_handler(int i) { ++ ; ++} ++/* tpm rng read call to kernel has 13 bytes of overhead ++ * the logic to process this involves reading to a temporary_buf ++ * and copying the no generated to buf*/ ++int xread_tpm(void *buf, size_t size) ++{ ++ size_t bytes_read = 0; ++ ssize_t r; ++ int retval,rngtpm_fd; ++ unsigned char *temp_buf=NULL; ++ unsigned char rng_cmd[] = { ++ 0, 193, /* TPM_TAG_RQU_COMMAND */ ++ 0, 0, 0, 14, /* length */ ++ 0, 0, 0, 70, /* TPM_ORD_GetRandom */ ++ 0, 0, 0, 0, /* number of bytes to return */ ++ }; ++ char *offset; ++ ++ rngtpm_fd=open(rng_device, O_RDWR); ++ if (rngtpm_fd < 0) { ++ message(LOG_ERR|LOG_INFO, ++ "Unable to open %s: %s\n",rng_device,strerror(errno)); ++ return -1; ++ } ++ ++ temp_buf= (unsigned char *) malloc(size + TPM_GET_RNG_OVERHEAD); ++ memset(temp_buf,0,(size+TPM_GET_RNG_OVERHEAD)); ++ if (temp_buf == NULL) { ++ message(LOG_ERR|LOG_INFO,"No memory"); ++ return -1; ++ } ++ /* 32 bits has been reserved for random byte size */ ++ rng_cmd[13]=(unsigned char)(size & 0xFF); ++ rng_cmd[12]=(unsigned char)((size >> 8) & 0xFF); ++ rng_cmd[11]=(unsigned char)((size >> 16) & 0xFF); ++ rng_cmd[10]=(unsigned char)((size >> 24) & 0xFF); ++ offset=buf; ++ while (bytes_read < size) { ++ r=0; ++ while (r < sizeof(rng_cmd)) { ++ retval=write(rngtpm_fd,rng_cmd + r,sizeof(rng_cmd)-r); ++ if (retval < 0) { ++ message(LOG_ERR|LOG_INFO, ++ "Error writing %s\n",rng_device); ++ retval=-1; ++ goto error_out; ++ } ++ r+=retval; ++ } ++ if (r < sizeof(rng_cmd)) { ++ message(LOG_ERR|LOG_INFO, ++ "Error writing %s\n",rng_device); ++ retval=-1; ++ goto error_out; ++ } ++ r=read(rngtpm_fd,temp_buf,size); ++ r=(r - TPM_GET_RNG_OVERHEAD); ++ bytes_read=bytes_read + r; ++ if (bytes_read > size) { ++ memcpy(offset,temp_buf + TPM_GET_RNG_OVERHEAD, ++ r - (bytes_read - size)); ++ break; ++ } ++ memcpy(offset, temp_buf + TPM_GET_RNG_OVERHEAD, ++ r); ++ offset=offset+r; + } ++ retval=0; ++error_out: ++ free(temp_buf); ++ close(rngtpm_fd); ++ return retval; + } + + /* Initialize entropy source */ +@@ -93,14 +181,31 @@ + */ + void init_entropy_source(const char* sourcedev) + { ++ /* We cannot keep the tpm device open always. ++ * We need to open get random data and close ++ * to allow tpm-tools and other utilities ++ * access to /dev/tpm */ ++ int tpm_fd; + rng_fd = open(sourcedev, O_RDONLY); + if (rng_fd == -1) { + message(LOG_DAEMON|LOG_ERR, "can't open %s: %s", + sourcedev, strerror(errno)); +- exit(EXIT_FAIL); ++ /* Try to open tpm this is just a test, no point in proceeding further ++ * if no source of entropy is present ++ */ ++ tpm_fd = open(rng_device, O_RDONLY); ++ if (tpm_fd < 0 ) { ++ message(LOG_DAEMON|LOG_ERR, ++ "can't open entropy source(tpm or intel/amd rng) %s", ++ strerror(errno)); ++ message(LOG_DAEMON|LOG_ERR,"Maybe RNG device modules are not loaded\n"); ++ exit(1); ++ } ++ close(tpm_fd); + } + + /* Bootstrap FIPS tests */ + fips_init(&fipsctx, discard_initial_data()); ++ fips_init(&tpm_fipsctx, 0); + } + +diff -uNr rng-tools-2-orig/rngd_entsource.h rng-tools-2/rngd_entsource.h +--- rng-tools-2-orig/rngd_entsource.h 2004-04-15 10:34:45.000000000 +0530 ++++ rng-tools-2/rngd_entsource.h 2008-11-11 15:39:31.000000000 +0530 +@@ -28,7 +28,7 @@ + + /* Logic and contexts */ + extern fips_ctx_t fipsctx; /* Context for the FIPS tests */ +- ++extern fips_ctx_t tpm_fipsctx; /* Context for the tpm FIPS tests */ + /* + * Initialize entropy source and entropy conditioning + * +@@ -37,6 +37,6 @@ + extern void init_entropy_source(const char* sourcedev); + + /* Read data from the entropy source */ +-void xread(void *buf, size_t size); ++int xread(void *buf, size_t size); + + #endif /* RNGD_ENTSOURCE__H */ +diff -uNr rng-tools-2-orig/rngd.h rng-tools-2/rngd.h +--- rng-tools-2-orig/rngd.h 2004-08-24 23:23:04.000000000 +0530 ++++ rng-tools-2/rngd.h 2008-11-11 15:39:31.000000000 +0530 +@@ -42,6 +42,7 @@ + double poll_timeout; + + int daemon; ++ int no_tpm; + }; + extern struct arguments *arguments; + -- cgit v1.2.3