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
ch2_truerandom 19 //input and output speeds
ch2_truerandom 20 cfsetospeed(&tty, (speed_t)speed);
ch2_truerandom 21 cfsetispeed(&tty, (speed_t)speed);
ch2_truerandom 22
ch2_truerandom 23 tty.c_cflag |= (CLOCAL | CREAD); //ignore modem controls
ch2_truerandom 24 tty.c_cflag &= ~CSIZE;
ch2_truerandom 25 tty.c_cflag |= CS8; //8 bit characters
ch2_truerandom 26 tty.c_cflag &= ~PARENB; //no parity bit
ch2_truerandom 27 tty.c_cflag &= ~CSTOPB; //only need 1 stop bit
ch2_truerandom 28 tty.c_cflag &= ~CRTSCTS; //no hardware flow control
ch2_truerandom 29
ch2_truerandom 30 //non-canonical mode
ch2_truerandom 31 tty.c_cflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
ch2_truerandom 32 tty.c_cflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
ch2_truerandom 33 tty.c_cflag &= ~OPOST;
ch2_truerandom 34
ch2_truerandom 35 //read at least one octet at a time; timeout 1 tenth of second between octets read
ch2_truerandom 36 tty.c_cc[VMIN] = 1;
ch2_truerandom 37 tty.c_cc[VTIME] = 1;
ch2_truerandom 38
ch2_truerandom 39 if (tcsetattr(fd, TCSANOW, &tty) != 0)
ch2_truerandom 40 return -1;
ch2_truerandom 41
ch2_truerandom 42 return 0;
ch2_truerandom 43 }
ch2_truerandom 44
ch2_truerandom 45 int open_entropy_source(char* source_name) {
ch2_truerandom 46 int in, err;
ch2_truerandom 47
ch2_truerandom 48 in = open(source_name, O_RDONLY | O_NOCTTY | O_NDELAY);
ch2_truerandom 49 if (in == -1) {
ch2_truerandom 50 printf("ERROR: failure to open entropy source %s: %s\n", source_name, strerror(errno));
ch2_truerandom 51 return in; //failed to access entropy source
ch2_truerandom 52 }
ch2_truerandom 53
ch2_truerandom 54 fcntl(in, F_SETFL, 0);
ch2_truerandom 55
ch2_truerandom 56 err = set_usb_attribs(in, B115200);
ch2_truerandom 57 if (err==-1) {
ch2_truerandom 58 printf("Error setting attributes on %s: %s\n", source_name, strerror(errno));
ch2_truerandom 59 return err;
ch2_truerandom 60 }
ch2_truerandom 61
ch2_truerandom 62 return in; //source opened, return its descriptor
ch2_truerandom 63 }
ch2_truerandom 64
ch2_truerandom 65 int get_random_octets_from(int noctets, unsigned char *out, int from) {
ch2_truerandom 66
ch2_truerandom 67 int nread;
ch2_truerandom 68 int total = 0;
ch2_truerandom 69
ch2_truerandom 70 while (total < noctets) {
ch2_truerandom 71 nread = read(from, out+total, noctets-total);
ch2_truerandom 72 //on interrupt received just try again
ch2_truerandom 73 if (nread == -1 && errno == EINTR)
ch2_truerandom 74 continue;
ch2_truerandom 75 //on error condition abort
ch2_truerandom 76 if (nread == -1 || nread == 0) {
ch2_truerandom 77 printf("Error reading from entropy source %s: %s\n", ENTROPY_SOURCE, strerror(errno));
ch2_truerandom 78 return total; //total read so far
ch2_truerandom 79 }
ch2_truerandom 80
ch2_truerandom 81 if (nread > 0)
ch2_truerandom 82 total = total + nread;
ch2_truerandom 83 }
ch2_truerandom 84 return total; //return number of octets read
ch2_truerandom 85 }
ch2_truerandom 86
ch2_truerandom 87 int get_random_octets(int noctets, unsigned char *out) {
ch2_truerandom 88 int in;
ch2_truerandom 89 int nread = 0;
ch2_truerandom 90
ch2_truerandom 91 in = open_entropy_source(ENTROPY_SOURCE);
ch2_truerandom 92 if (in > 0) {
ch2_truerandom 93 nread = get_random_octets_from(noctets, out, in);
ch2_truerandom 94 close(in);
ch2_truerandom 95 }
ch2_truerandom 96 return nread;
ch2_truerandom 97 }
ch2_truerandom 98