-
+ 4B729AFBF1B614C0E53367586D7880C27856E0A7A7996735C718091124FC436C3F9003B213B8BA56E80ACC41E4CDF98E5F56D8B3CF1573D6BB699F0B59FD89ECeucrypt/smg_rsa/truerandom.c(0 . 0)(1 . 98)
202 #include <stdio.h>
203 #include <stdlib.h>
204 #include <string.h>
205
206 #include <fcntl.h>
207 #include <unistd.h>
208 #include <termios.h>
209 #include <errno.h>
210
211 #include "smg_rsa.h"
212
213
214 int set_usb_attribs(int fd, int speed) {
215 struct termios tty;
216 if (tcgetattr(fd, &tty) < 0) {
217 return -1;
218 }
219
220 //input and output speeds
221 cfsetospeed(&tty, (speed_t)speed);
222 cfsetispeed(&tty, (speed_t)speed);
223
224 tty.c_cflag |= (CLOCAL | CREAD); //ignore modem controls
225 tty.c_cflag &= ~CSIZE;
226 tty.c_cflag |= CS8; //8 bit characters
227 tty.c_cflag &= ~PARENB; //no parity bit
228 tty.c_cflag &= ~CSTOPB; //only need 1 stop bit
229 tty.c_cflag &= ~CRTSCTS; //no hardware flow control
230
231 //non-canonical mode
232 tty.c_cflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
233 tty.c_cflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
234 tty.c_cflag &= ~OPOST;
235
236 //read at least one octet at a time; timeout 1 tenth of second between octets read
237 tty.c_cc[VMIN] = 1;
238 tty.c_cc[VTIME] = 1;
239
240 if (tcsetattr(fd, TCSANOW, &tty) != 0)
241 return -1;
242
243 return 0;
244 }
245
246 int open_entropy_source(char* source_name) {
247 int in, err;
248
249 in = open(source_name, O_RDONLY | O_NOCTTY | O_NDELAY);
250 if (in == -1) {
251 printf("ERROR: failure to open entropy source %s: %s\n", source_name, strerror(errno));
252 return in; //failed to access entropy source
253 }
254
255 fcntl(in, F_SETFL, 0);
256
257 err = set_usb_attribs(in, B115200);
258 if (err==-1) {
259 printf("Error setting attributes on %s: %s\n", source_name, strerror(errno));
260 return err;
261 }
262
263 return in; //source opened, return its descriptor
264 }
265
266 int get_random_octets_from(int noctets, unsigned char *out, int from) {
267
268 int nread;
269 int total = 0;
270
271 while (total < noctets) {
272 nread = read(from, out+total, noctets-total);
273 //on interrupt received just try again
274 if (nread == -1 && errno == EINTR)
275 continue;
276 //on error condition abort
277 if (nread == -1 || nread == 0) {
278 printf("Error reading from entropy source %s: %s\n", ENTROPY_SOURCE, strerror(errno));
279 return total; //total read so far
280 }
281
282 if (nread > 0)
283 total = total + nread;
284 }
285 return total; //return number of octets read
286 }
287
288 int get_random_octets(int noctets, unsigned char *out) {
289 int in;
290 int nread = 0;
291
292 in = open_entropy_source(ENTROPY_SOURCE);
293 if (in > 0) {
294 nread = get_random_octets_from(noctets, out, in);
295 close(in);
296 }
297 return nread;
298 }
299