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
eucrypt_ch13_smg_rng 92 int rng_dirty_float(float *n) {
eucrypt_ch13_smg_rng 93 int status; /* for aborting in case of error */
eucrypt_ch13_smg_rng 94 uint32_t r; /* a random value on 32 bits */
eucrypt_ch13_smg_rng 95 uint32_t maxval = 0xffffffff; /* maximum value on 32 bits */
eucrypt_ch13_smg_rng 96
eucrypt_ch13_smg_rng 97 /* obtain a random number on 32 bits using ENTROPY_SOURCE */
eucrypt_ch13_smg_rng 98 status = rng_uint32( &r );
eucrypt_ch13_smg_rng 99 if ( status < 0 )
eucrypt_ch13_smg_rng 100 return status;
eucrypt_ch13_smg_rng 101
eucrypt_ch13_smg_rng 102 /* calculate and assign the floating-point random value as (r*1.0)/max val */
eucrypt_ch13_smg_rng 103 /* multiplication by 1.0 IS NEEDED to do float division rather than int div*/
eucrypt_ch13_smg_rng 104 *n = ( r * 1.0 ) / maxval;
eucrypt_ch13_smg_rng 105
eucrypt_ch13_smg_rng 106 return 1;
eucrypt_ch13_smg_rng 107 }
eucrypt_ch13_smg_rng 108
eucrypt_ch13_smg_rng 109 int rng_float_754_1985(float *n) {
eucrypt_ch13_smg_rng 110 /* Single float ieee 754/1985 has 23 bits that can be set for the mantissa
eucrypt_ch13_smg_rng 111 * (and one implicit bit=1).
eucrypt_ch13_smg_rng 112 * Full single float ieee 754/1985 representation takes 4 octets in total.
eucrypt_ch13_smg_rng 113 */
eucrypt_ch13_smg_rng 114 int noctets = 4; /* number of octets to read from ENTROPY_SOURCE */
eucrypt_ch13_smg_rng 115 int nread; /* number of octets *read* from ENTROPY_SOURCE */
eucrypt_ch13_smg_rng 116 unsigned char bits[ noctets ]; /* the random bits from ENTROPY_SOURCE */
eucrypt_ch13_smg_rng 117 int oSignExp, oExpM;/* offsets for sign+exponent octet, exponent+mantissa*/
eucrypt_ch13_smg_rng 118
eucrypt_ch13_smg_rng 119 /* obtain random bits */
eucrypt_ch13_smg_rng 120 nread = get_random_octets( noctets, bits );
eucrypt_ch13_smg_rng 121
eucrypt_ch13_smg_rng 122 if (nread != noctets )
eucrypt_ch13_smg_rng 123 return -1; /* something wrong at reading from ENTROPY_SOURCE, abort */
eucrypt_ch13_smg_rng 124
eucrypt_ch13_smg_rng 125 /* set offsets for bit diddling depending on endianness of iron */
eucrypt_ch13_smg_rng 126 if (is_bigendian()) {
eucrypt_ch13_smg_rng 127 oSignExp = 0;
eucrypt_ch13_smg_rng 128 oExpM = 1;
eucrypt_ch13_smg_rng 129 }
eucrypt_ch13_smg_rng 130 else {
eucrypt_ch13_smg_rng 131 oSignExp = 3;
eucrypt_ch13_smg_rng 132 oExpM = 2;
eucrypt_ch13_smg_rng 133 }
eucrypt_ch13_smg_rng 134
eucrypt_ch13_smg_rng 135 /* set sign=0; exponent=127; explicit mantissa = random bits (23 bits) */
eucrypt_ch13_smg_rng 136 *(bits+oExpM) = *(bits+2) | 0x80; /* one bit of exponent set */
eucrypt_ch13_smg_rng 137 *(bits+oSignExp) = 0x3f; /* sign=0; exponent bits for 127 */
eucrypt_ch13_smg_rng 138
eucrypt_ch13_smg_rng 139 /* now copy the bits to the result var (i.e. as a float's representation */
eucrypt_ch13_smg_rng 140 memcpy( n, bits, noctets );
eucrypt_ch13_smg_rng 141 return 1;
eucrypt_ch13_smg_rng 142 }
eucrypt_ch13_smg_rng 143
eucrypt_ch13_smg_rng 144 int rng_uint32( uint32_t *n ) {
eucrypt_ch13_smg_rng 145 int noctets = 4; /* 32 bits aka 4 octets to read from ENTROPY_SOURCE */
eucrypt_ch13_smg_rng 146 int nread; /* the number of octets read from ENTROPY_SOURCE */
eucrypt_ch13_smg_rng 147 unsigned char bits[ noctets ]; /* for storing the bits from ENTROPY_SOURCE */
eucrypt_ch13_smg_rng 148
eucrypt_ch13_smg_rng 149 /* read random 32 bits from ENTROPY_SOURCE */
eucrypt_ch13_smg_rng 150 nread = get_random_octets( noctets, bits );
eucrypt_ch13_smg_rng 151 if ( nread != noctets )
eucrypt_ch13_smg_rng 152 return -1;
eucrypt_ch13_smg_rng 153
eucrypt_ch13_smg_rng 154 /* copy the random bits to n, to be interpreted as uint32 */
eucrypt_ch13_smg_rng 155 /* endianness is irrelevant here - the bits are random anyway */
eucrypt_ch13_smg_rng 156 memcpy( n, bits, noctets );
eucrypt_ch13_smg_rng 157
eucrypt_ch13_smg_rng 158 return 1;
eucrypt_ch13_smg_rng 159 }
eucrypt_ch13_smg_rng 160
eucrypt_ch13_smg_rng 161 int rng_uint64( uint64_t *n ) {
eucrypt_ch13_smg_rng 162 int noctets = 8; /* 64 bits aka 8 octets to read from ENTROPY_SOURCE */
eucrypt_ch13_smg_rng 163 int nread; /* the number of octets read from ENTROPY_SOURCE */
eucrypt_ch13_smg_rng 164 unsigned char bits[ noctets ]; /* for storing the bits from ENTROPY_SOURCE */
eucrypt_ch13_smg_rng 165
eucrypt_ch13_smg_rng 166 /* read random 64 bits from ENTROPY_SOURCE */
eucrypt_ch13_smg_rng 167 nread = get_random_octets( noctets, bits );
eucrypt_ch13_smg_rng 168 if ( nread != noctets )
eucrypt_ch13_smg_rng 169 return -1;
eucrypt_ch13_smg_rng 170
eucrypt_ch13_smg_rng 171 /* copy the random bits to n, to be interpreted as uint64 */
eucrypt_ch13_smg_rng 172 /* endianness is irrelevant here - the bits are random anyway */
eucrypt_ch13_smg_rng 173 memcpy( n, bits, noctets );
eucrypt_ch13_smg_rng 174
eucrypt_ch13_smg_rng 175 return 1;
eucrypt_ch13_smg_rng 176 }