raw
ch2_truerandom          1 #include <stdio.h>
ch2_truerandom 2 #include <stdlib.h>
ch2_truerandom 3 #include <string.h>
ch2_truerandom 4
ch2_truerandom 5 #include <fcntl.h>
ch2_truerandom 6 #include <unistd.h>
ch2_truerandom 7 #include <termios.h>
ch2_truerandom 8 #include <errno.h>
ch2_truerandom 9
ch2_truerandom 10 #include "smg_rsa.h"
ch2_truerandom 11
ch2_truerandom 12
ch2_truerandom 13 int set_usb_attribs(int fd, int speed) {
ch2_truerandom 14 struct termios tty;
ch2_truerandom 15 if (tcgetattr(fd, &tty) < 0) {
ch2_truerandom 16 return -1;
ch2_truerandom 17 }
ch2_truerandom 18
eucrypt_ch4_rpng 19 /* input and output speeds */
ch2_truerandom 20 cfsetospeed(&tty, (speed_t)speed);
ch2_truerandom 21 cfsetispeed(&tty, (speed_t)speed);
ch2_truerandom 22
eucrypt_ch4_rpng 23 /* raw */
eucrypt_ch4_rpng 24 tty.c_lflag &= ~(ECHO | ECHOE | ECHOK);
eucrypt_ch4_rpng 25 tty.c_oflag &= ~OPOST;
ch2_truerandom 26
eucrypt_ch4_rpng 27 /* read at least one octet at a time; BLOCK until at least VMIN octets read */
ch2_truerandom 28 tty.c_cc[VMIN] = 1;
eucrypt_ch4_rpng 29 tty.c_cc[VTIME] = 0;
ch2_truerandom 30
eucrypt_ch4_rpng 31 if (tcsetattr(fd, TCSAFLUSH, &tty) != 0)
ch2_truerandom 32 return -1;
ch2_truerandom 33
ch2_truerandom 34 return 0;
ch2_truerandom 35 }
ch2_truerandom 36
ch2_truerandom 37 int open_entropy_source(char* source_name) {
ch2_truerandom 38 int in, err;
ch2_truerandom 39
ch2_truerandom 40 in = open(source_name, O_RDONLY | O_NOCTTY | O_NDELAY);
ch2_truerandom 41 if (in == -1) {
ch2_truerandom 42 printf("ERROR: failure to open entropy source %s: %s\n", source_name, strerror(errno));
ch2_truerandom 43 return in; //failed to access entropy source
ch2_truerandom 44 }
ch2_truerandom 45
ch2_truerandom 46 fcntl(in, F_SETFL, 0);
ch2_truerandom 47
ch2_truerandom 48 err = set_usb_attribs(in, B115200);
ch2_truerandom 49 if (err==-1) {
ch2_truerandom 50 printf("Error setting attributes on %s: %s\n", source_name, strerror(errno));
ch2_truerandom 51 return err;
ch2_truerandom 52 }
ch2_truerandom 53
ch2_truerandom 54 return in; //source opened, return its descriptor
ch2_truerandom 55 }
ch2_truerandom 56
ch2_truerandom 57 int get_random_octets_from(int noctets, unsigned char *out, int from) {
ch2_truerandom 58
ch2_truerandom 59 int nread;
ch2_truerandom 60 int total = 0;
ch2_truerandom 61
ch2_truerandom 62 while (total < noctets) {
eucrypt_ch3_mille... 63 errno = 0;
ch2_truerandom 64 nread = read(from, out+total, noctets-total);
ch2_truerandom 65 //on interrupt received just try again
ch2_truerandom 66 if (nread == -1 && errno == EINTR)
ch2_truerandom 67 continue;
ch2_truerandom 68 //on error condition abort
eucrypt_ch3_mille... 69 if (errno != 0 && (nread == -1 || nread == 0)) {
eucrypt_ch3_mille... 70 printf("Error reading from entropy source %s after %d read: %s\n", ENTROPY_SOURCE, total, strerror(errno));
ch2_truerandom 71 return total; //total read so far
ch2_truerandom 72 }
ch2_truerandom 73
ch2_truerandom 74 if (nread > 0)
ch2_truerandom 75 total = total + nread;
ch2_truerandom 76 }
ch2_truerandom 77 return total; //return number of octets read
ch2_truerandom 78 }
ch2_truerandom 79
ch2_truerandom 80 int get_random_octets(int noctets, unsigned char *out) {
ch2_truerandom 81 int in;
ch2_truerandom 82 int nread = 0;
ch2_truerandom 83
ch2_truerandom 84 in = open_entropy_source(ENTROPY_SOURCE);
ch2_truerandom 85 if (in > 0) {
ch2_truerandom 86 nread = get_random_octets_from(noctets, out, in);
ch2_truerandom 87 close(in);
ch2_truerandom 88 }
ch2_truerandom 89 return nread;
ch2_truerandom 90 }
ch2_truerandom 91