rngd_tpm_support.patch 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. Patch taken from http://sourceforge.net/tracker/?func=detail&aid=2261574&group_id=3242&atid=353242
  2. diff -uNr rng-tools-2-orig/rngd.c rng-tools-2/rngd.c
  3. --- rng-tools-2-orig/rngd.c 2004-08-24 23:30:00.000000000 +0530
  4. +++ rng-tools-2/rngd.c 2008-11-11 15:39:31.000000000 +0530
  5. @@ -91,6 +91,8 @@
  6. { "timeout", 't', "nnn", 0,
  7. "Interval written to random-device when the entropy pool is full, in seconds (default: 60)" },
  8. + { "no-tpm", 'n', "1|0", 0,
  9. + "do not use tpm as a source of random number input (default: 0)" },
  10. { 0 },
  11. };
  12. @@ -102,6 +104,7 @@
  13. .random_step = 64,
  14. .fill_watermark = 2048,
  15. .daemon = 1,
  16. + .no_tpm =0,
  17. };
  18. struct arguments *arguments = &default_arguments;
  19. @@ -147,6 +150,15 @@
  20. arguments->fill_watermark = n;
  21. break;
  22. }
  23. + case 'n': {
  24. + int n;
  25. + if ((sscanf(arg,"%i", &n) == 0) || ((n | 1)!=1))
  26. + argp_usage(state);
  27. + else
  28. + arguments->no_tpm=0;
  29. + break;
  30. +
  31. + }
  32. default:
  33. return ARGP_ERR_UNKNOWN;
  34. @@ -162,26 +174,41 @@
  35. double poll_timeout)
  36. {
  37. unsigned char buf[FIPS_RNG_BUFFER_SIZE];
  38. - unsigned char *p;
  39. - int fips;
  40. + int fips,retval;
  41. for (;;) {
  42. - xread(buf, sizeof buf);
  43. + if (arguments->no_tpm == 0) {
  44. + retval=xread_tpm(buf, sizeof buf);
  45. + if (retval < 0)
  46. + sleep(1);
  47. + else
  48. + update_kernel_random(random_step,
  49. + poll_timeout, buf, &tpm_fipsctx);
  50. + }
  51. + retval=xread(buf, sizeof buf);
  52. + if (retval > 0)
  53. + update_kernel_random(random_step,
  54. + poll_timeout, buf, &fipsctx);
  55. + }
  56. +}
  57. - fips = fips_run_rng_test(&fipsctx, buf);
  58. +int update_kernel_random(int random_step, double poll_timeout,
  59. + unsigned char *buf, fips_ctx_t *fipsctx) {
  60. - if (fips) {
  61. - message(LOG_DAEMON|LOG_ERR, "failed fips test\n");
  62. - sleep(1);
  63. - continue;
  64. - }
  65. + int fips;
  66. + unsigned char *p;
  67. + fips = fips_run_rng_test(fipsctx, buf);
  68. + if (fips) {
  69. + message(LOG_DAEMON|LOG_ERR, "failed fips test\n");
  70. + return 1;
  71. + }
  72. - for (p = buf; p + random_step <= &buf[sizeof buf];
  73. - p += random_step) {
  74. - random_add_entropy(p, random_step);
  75. - random_sleep(poll_timeout);
  76. - }
  77. + for (p = buf; p + random_step <= &buf[FIPS_RNG_BUFFER_SIZE];
  78. + p += random_step) {
  79. + random_add_entropy(p, random_step);
  80. + random_sleep(poll_timeout);
  81. }
  82. + return 0;
  83. }
  84. diff -uNr rng-tools-2-orig/rngd_entsource.c rng-tools-2/rngd_entsource.c
  85. --- rng-tools-2-orig/rngd_entsource.c 2004-04-15 10:36:17.000000000 +0530
  86. +++ rng-tools-2/rngd_entsource.c 2008-11-11 15:39:31.000000000 +0530
  87. @@ -35,6 +35,7 @@
  88. #include <errno.h>
  89. #include <syslog.h>
  90. #include <string.h>
  91. +#include <signal.h>
  92. #include "rngd.h"
  93. #include "fips.h"
  94. @@ -42,17 +43,27 @@
  95. #include "rngd_entsource.h"
  96. -/* Logic and contexts */
  97. -static int rng_fd; /* rng data source */
  98. -fips_ctx_t fipsctx; /* Context for the FIPS tests */
  99. +/* The overhead incured when tpm returns the random nos as per TCG spec
  100. + * it is 14 bytes.*/
  101. +#define TPM_GET_RNG_OVERHEAD 14
  102. +static const char *rng_device="/dev/tpm0";
  103. +/* Logic and contexts */
  104. +static int rng_fd; /* rng data source */
  105. +fips_ctx_t fipsctx; /* Context for the FIPS tests */
  106. +fips_ctx_t tpm_fipsctx; /* Context for the tpm FIPS tests */
  107. /* Read data from the entropy source */
  108. -void xread(void *buf, size_t size)
  109. +int xread(void *buf, size_t size)
  110. {
  111. size_t off = 0;
  112. ssize_t r;
  113. + /* Do nothing if we have no hw rng, maybe we have tpm */
  114. + if (rng_fd < 0) {
  115. + message(LOG_DAEMON|LOG_ERR, "Invalid file handle\n");
  116. + return -1;
  117. + }
  118. while (size > 0) {
  119. do {
  120. r = read(rng_fd, buf + off, size);
  121. @@ -65,8 +76,85 @@
  122. if (size) {
  123. message(LOG_DAEMON|LOG_ERR, "read error\n");
  124. - exit(1);
  125. + return -1;
  126. + }
  127. + return 0;
  128. +}
  129. +
  130. +alarm_handler(int i) {
  131. + ;
  132. +}
  133. +/* tpm rng read call to kernel has 13 bytes of overhead
  134. + * the logic to process this involves reading to a temporary_buf
  135. + * and copying the no generated to buf*/
  136. +int xread_tpm(void *buf, size_t size)
  137. +{
  138. + size_t bytes_read = 0;
  139. + ssize_t r;
  140. + int retval,rngtpm_fd;
  141. + unsigned char *temp_buf=NULL;
  142. + unsigned char rng_cmd[] = {
  143. + 0, 193, /* TPM_TAG_RQU_COMMAND */
  144. + 0, 0, 0, 14, /* length */
  145. + 0, 0, 0, 70, /* TPM_ORD_GetRandom */
  146. + 0, 0, 0, 0, /* number of bytes to return */
  147. + };
  148. + char *offset;
  149. +
  150. + rngtpm_fd=open(rng_device, O_RDWR);
  151. + if (rngtpm_fd < 0) {
  152. + message(LOG_ERR|LOG_INFO,
  153. + "Unable to open %s: %s\n",rng_device,strerror(errno));
  154. + return -1;
  155. + }
  156. +
  157. + temp_buf= (unsigned char *) malloc(size + TPM_GET_RNG_OVERHEAD);
  158. + memset(temp_buf,0,(size+TPM_GET_RNG_OVERHEAD));
  159. + if (temp_buf == NULL) {
  160. + message(LOG_ERR|LOG_INFO,"No memory");
  161. + return -1;
  162. + }
  163. + /* 32 bits has been reserved for random byte size */
  164. + rng_cmd[13]=(unsigned char)(size & 0xFF);
  165. + rng_cmd[12]=(unsigned char)((size >> 8) & 0xFF);
  166. + rng_cmd[11]=(unsigned char)((size >> 16) & 0xFF);
  167. + rng_cmd[10]=(unsigned char)((size >> 24) & 0xFF);
  168. + offset=buf;
  169. + while (bytes_read < size) {
  170. + r=0;
  171. + while (r < sizeof(rng_cmd)) {
  172. + retval=write(rngtpm_fd,rng_cmd + r,sizeof(rng_cmd)-r);
  173. + if (retval < 0) {
  174. + message(LOG_ERR|LOG_INFO,
  175. + "Error writing %s\n",rng_device);
  176. + retval=-1;
  177. + goto error_out;
  178. + }
  179. + r+=retval;
  180. + }
  181. + if (r < sizeof(rng_cmd)) {
  182. + message(LOG_ERR|LOG_INFO,
  183. + "Error writing %s\n",rng_device);
  184. + retval=-1;
  185. + goto error_out;
  186. + }
  187. + r=read(rngtpm_fd,temp_buf,size);
  188. + r=(r - TPM_GET_RNG_OVERHEAD);
  189. + bytes_read=bytes_read + r;
  190. + if (bytes_read > size) {
  191. + memcpy(offset,temp_buf + TPM_GET_RNG_OVERHEAD,
  192. + r - (bytes_read - size));
  193. + break;
  194. + }
  195. + memcpy(offset, temp_buf + TPM_GET_RNG_OVERHEAD,
  196. + r);
  197. + offset=offset+r;
  198. }
  199. + retval=0;
  200. +error_out:
  201. + free(temp_buf);
  202. + close(rngtpm_fd);
  203. + return retval;
  204. }
  205. /* Initialize entropy source */
  206. @@ -93,14 +181,31 @@
  207. */
  208. void init_entropy_source(const char* sourcedev)
  209. {
  210. + /* We cannot keep the tpm device open always.
  211. + * We need to open get random data and close
  212. + * to allow tpm-tools and other utilities
  213. + * access to /dev/tpm */
  214. + int tpm_fd;
  215. rng_fd = open(sourcedev, O_RDONLY);
  216. if (rng_fd == -1) {
  217. message(LOG_DAEMON|LOG_ERR, "can't open %s: %s",
  218. sourcedev, strerror(errno));
  219. - exit(EXIT_FAIL);
  220. + /* Try to open tpm this is just a test, no point in proceeding further
  221. + * if no source of entropy is present
  222. + */
  223. + tpm_fd = open(rng_device, O_RDONLY);
  224. + if (tpm_fd < 0 ) {
  225. + message(LOG_DAEMON|LOG_ERR,
  226. + "can't open entropy source(tpm or intel/amd rng) %s",
  227. + strerror(errno));
  228. + message(LOG_DAEMON|LOG_ERR,"Maybe RNG device modules are not loaded\n");
  229. + exit(1);
  230. + }
  231. + close(tpm_fd);
  232. }
  233. /* Bootstrap FIPS tests */
  234. fips_init(&fipsctx, discard_initial_data());
  235. + fips_init(&tpm_fipsctx, 0);
  236. }
  237. diff -uNr rng-tools-2-orig/rngd_entsource.h rng-tools-2/rngd_entsource.h
  238. --- rng-tools-2-orig/rngd_entsource.h 2004-04-15 10:34:45.000000000 +0530
  239. +++ rng-tools-2/rngd_entsource.h 2008-11-11 15:39:31.000000000 +0530
  240. @@ -28,7 +28,7 @@
  241. /* Logic and contexts */
  242. extern fips_ctx_t fipsctx; /* Context for the FIPS tests */
  243. -
  244. +extern fips_ctx_t tpm_fipsctx; /* Context for the tpm FIPS tests */
  245. /*
  246. * Initialize entropy source and entropy conditioning
  247. *
  248. @@ -37,6 +37,6 @@
  249. extern void init_entropy_source(const char* sourcedev);
  250. /* Read data from the entropy source */
  251. -void xread(void *buf, size_t size);
  252. +int xread(void *buf, size_t size);
  253. #endif /* RNGD_ENTSOURCE__H */
  254. diff -uNr rng-tools-2-orig/rngd.h rng-tools-2/rngd.h
  255. --- rng-tools-2-orig/rngd.h 2004-08-24 23:23:04.000000000 +0530
  256. +++ rng-tools-2/rngd.h 2008-11-11 15:39:31.000000000 +0530
  257. @@ -42,6 +42,7 @@
  258. double poll_timeout;
  259. int daemon;
  260. + int no_tpm;
  261. };
  262. extern struct arguments *arguments;