]>
git.ipfire.org Git - thirdparty/rng-tools.git/blob - rngd_entsource.c
2 * rngd_entsource.c -- Entropy source and conditioning
4 * Copyright (C) 2001 Philipp Rumpf
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
24 #error Invalid or missing autoconf build environment
27 #include "rng-tools-config.h"
32 #include <sys/types.h>
43 #include "rngd_entsource.h"
46 /* The overhead incured when tpm returns the random nos as per TCG spec
48 #define TPM_GET_RNG_OVERHEAD 14
50 /* Read data from the entropy source */
51 int xread(void *buf
, size_t size
, struct rng
*ent_src
)
58 r
= read(ent_src
->rng_fd
, buf
+ off
, size
);
59 } while ((r
== -1) && (errno
== EINTR
));
67 message(LOG_DAEMON
|LOG_ERR
, "read error\n");
73 /* tpm rng read call to kernel has 13 bytes of overhead
74 * the logic to process this involves reading to a temporary_buf
75 * and copying the no generated to buf */
76 int xread_tpm(void *buf
, size_t size
, struct rng
*ent_src
)
78 size_t bytes_read
= 0;
81 unsigned char *temp_buf
= NULL
;
82 unsigned char rng_cmd
[] = {
83 0, 193, /* TPM_TAG_RQU_COMMAND */
84 0, 0, 0, 14, /* length */
85 0, 0, 0, 70, /* TPM_ORD_GetRandom */
86 0, 0, 0, 0, /* number of bytes to return */
90 ent_src
->rng_fd
= open(ent_src
->rng_name
, O_RDWR
);
91 if (ent_src
->rng_fd
== -1) {
92 message(LOG_ERR
|LOG_INFO
,"Unable to open file: %s",ent_src
->rng_name
);
96 temp_buf
= (unsigned char *) malloc(size
+ TPM_GET_RNG_OVERHEAD
);
97 memset(temp_buf
, 0, (size
+TPM_GET_RNG_OVERHEAD
));
98 if (temp_buf
== NULL
) {
99 message(LOG_ERR
|LOG_INFO
,"No memory");
100 close(ent_src
->rng_fd
);
103 /* 32 bits has been reserved for random byte size */
104 rng_cmd
[13] = (unsigned char)(size
& 0xFF);
105 rng_cmd
[12] = (unsigned char)((size
>> 8) & 0xFF);
106 rng_cmd
[11] = (unsigned char)((size
>> 16) & 0xFF);
107 rng_cmd
[10] = (unsigned char)((size
>> 24) & 0xFF);
109 while (bytes_read
< size
) {
111 while (r
< sizeof(rng_cmd
)) {
112 retval
= write(ent_src
->rng_fd
,
114 sizeof(rng_cmd
) - r
);
116 message(LOG_ERR
|LOG_INFO
,
117 "Error writing %s\n",
124 if (r
< sizeof(rng_cmd
)) {
125 message(LOG_ERR
|LOG_INFO
,
126 "Error writing %s\n", ent_src
->rng_name
);
130 r
= read(ent_src
->rng_fd
, temp_buf
,size
);
131 r
= (r
- TPM_GET_RNG_OVERHEAD
);
133 message(LOG_ERR
|LOG_INFO
,
134 "Error reading from TPM, no entropy gathered");
138 bytes_read
= bytes_read
+ r
;
139 if (bytes_read
> size
) {
140 memcpy(offset
,temp_buf
+ TPM_GET_RNG_OVERHEAD
,
141 r
- (bytes_read
- size
));
144 memcpy(offset
, temp_buf
+ TPM_GET_RNG_OVERHEAD
, r
);
149 close(ent_src
->rng_fd
);
154 /* Initialize entropy source */
155 static int discard_initial_data(struct rng
*ent_src
)
157 /* Trash 32 bits of what is probably stale (non-random)
158 * initial state from the RNG. For Intel's, 8 bits would
159 * be enough, but since AMD's generates 32 bits at a time...
161 * The kernel drivers should be doing this at device powerup,
162 * but at least up to 2.4.24, it doesn't. */
163 unsigned char tempbuf
[4];
164 xread(tempbuf
, sizeof(tempbuf
), ent_src
);
166 /* Return 32 bits of bootstrap data */
167 xread(tempbuf
, sizeof(tempbuf
), ent_src
);
169 return tempbuf
[0] | (tempbuf
[1] << 8) |
170 (tempbuf
[2] << 16) | (tempbuf
[3] << 24);
174 * Open entropy source, and initialize it
176 int init_entropy_source(struct rng
*ent_src
)
178 ent_src
->rng_fd
= open(ent_src
->rng_name
, O_RDONLY
);
179 if (ent_src
->rng_fd
== -1) {
182 src_list_add(ent_src
);
183 /* Bootstrap FIPS tests */
184 ent_src
->fipsctx
= malloc(sizeof(fips_ctx_t
));
185 fips_init(ent_src
->fipsctx
, discard_initial_data(ent_src
));
190 * Open tpm entropy source, and initialize it
192 int init_tpm_entropy_source(struct rng
*ent_src
)
194 ent_src
->rng_fd
= open(ent_src
->rng_name
, O_RDWR
);
195 if (ent_src
->rng_fd
== -1) {
196 message(LOG_ERR
|LOG_INFO
,"Unable to open file: %s",ent_src
->rng_name
);
199 src_list_add(ent_src
);
200 /* Bootstrap FIPS tests */
201 ent_src
->fipsctx
= malloc(sizeof(fips_ctx_t
));
202 fips_init(ent_src
->fipsctx
, 0);
203 close(ent_src
->rng_fd
);