#include #include #include #include #include #include #include #include "smg_rsa.h" int set_usb_attribs(int fd, int speed) { struct termios tty; if (tcgetattr(fd, &tty) < 0) { return -1; } //input and output speeds cfsetospeed(&tty, (speed_t)speed); cfsetispeed(&tty, (speed_t)speed); tty.c_cflag |= (CLOCAL | CREAD); //ignore modem controls tty.c_cflag &= ~CSIZE; tty.c_cflag |= CS8; //8 bit characters tty.c_cflag &= ~PARENB; //no parity bit tty.c_cflag &= ~CSTOPB; //only need 1 stop bit tty.c_cflag &= ~CRTSCTS; //no hardware flow control //non-canonical mode tty.c_cflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); tty.c_cflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); tty.c_cflag &= ~OPOST; //read at least one octet at a time; timeout 1 tenth of second between octets read tty.c_cc[VMIN] = 1; tty.c_cc[VTIME] = 1; if (tcsetattr(fd, TCSANOW, &tty) != 0) return -1; return 0; } int open_entropy_source(char* source_name) { int in, err; in = open(source_name, O_RDONLY | O_NOCTTY | O_NDELAY); if (in == -1) { printf("ERROR: failure to open entropy source %s: %s\n", source_name, strerror(errno)); return in; //failed to access entropy source } fcntl(in, F_SETFL, 0); err = set_usb_attribs(in, B115200); if (err==-1) { printf("Error setting attributes on %s: %s\n", source_name, strerror(errno)); return err; } return in; //source opened, return its descriptor } int get_random_octets_from(int noctets, unsigned char *out, int from) { int nread; int total = 0; while (total < noctets) { errno = 0; nread = read(from, out+total, noctets-total); //on interrupt received just try again if (nread == -1 && errno == EINTR) continue; //on error condition abort if (errno != 0 && (nread == -1 || nread == 0)) { printf("Error reading from entropy source %s after %d read: %s\n", ENTROPY_SOURCE, total, strerror(errno)); return total; //total read so far } if (nread > 0) total = total + nread; } return total; //return number of octets read } int get_random_octets(int noctets, unsigned char *out) { int in; int nread = 0; in = open_entropy_source(ENTROPY_SOURCE); if (in > 0) { nread = get_random_octets_from(noctets, out, in); close(in); } return nread; }