-
+ 234021F88C073C4C0E719125E55546A98351A2CF0DF584701FF19A9E8D9EA5B134FD9FDBCC24CD412C56802099A2929B608C41D3ACF7E8FB545EB1C04F8BDF9F
smg_comms/rsa/truerandom.c
(0 . 0)(1 . 176)
9963 #include <stdio.h>
9964 #include <stdlib.h>
9965 #include <string.h>
9966
9967 #include <fcntl.h>
9968 #include <unistd.h>
9969 #include <termios.h>
9970 #include <errno.h>
9971
9972 #include "smg_rsa.h"
9973
9974
9975 int set_usb_attribs(int fd, int speed) {
9976 struct termios tty;
9977 if (tcgetattr(fd, &tty) < 0) {
9978 return -1;
9979 }
9980
9981 /* input and output speeds */
9982 cfsetospeed(&tty, (speed_t)speed);
9983 cfsetispeed(&tty, (speed_t)speed);
9984
9985 /* raw */
9986 tty.c_lflag &= ~(ECHO | ECHOE | ECHOK);
9987 tty.c_oflag &= ~OPOST;
9988
9989 /* read at least one octet at a time; BLOCK until at least VMIN octets read */
9990 tty.c_cc[VMIN] = 1;
9991 tty.c_cc[VTIME] = 0;
9992
9993 if (tcsetattr(fd, TCSAFLUSH, &tty) != 0)
9994 return -1;
9995
9996 return 0;
9997 }
9998
9999 int open_entropy_source(char* source_name) {
10000 int in, err;
10001
10002 in = open(source_name, O_RDONLY | O_NOCTTY | O_NDELAY);
10003 if (in == -1) {
10004 printf("ERROR: failure to open entropy source %s: %s\n", source_name, strerror(errno));
10005 return in; //failed to access entropy source
10006 }
10007
10008 fcntl(in, F_SETFL, 0);
10009
10010 err = set_usb_attribs(in, B115200);
10011 if (err==-1) {
10012 printf("Error setting attributes on %s: %s\n", source_name, strerror(errno));
10013 return err;
10014 }
10015
10016 return in; //source opened, return its descriptor
10017 }
10018
10019 int get_random_octets_from(int noctets, unsigned char *out, int from) {
10020
10021 int nread;
10022 int total = 0;
10023
10024 while (total < noctets) {
10025 errno = 0;
10026 nread = read(from, out+total, noctets-total);
10027 //on interrupt received just try again
10028 if (nread == -1 && errno == EINTR)
10029 continue;
10030 //on error condition abort
10031 if (errno != 0 && (nread == -1 || nread == 0)) {
10032 printf("Error reading from entropy source %s after %d read: %s\n", ENTROPY_SOURCE, total, strerror(errno));
10033 return total; //total read so far
10034 }
10035
10036 if (nread > 0)
10037 total = total + nread;
10038 }
10039 return total; //return number of octets read
10040 }
10041
10042 int get_random_octets(int noctets, unsigned char *out) {
10043 int in;
10044 int nread = 0;
10045
10046 in = open_entropy_source(ENTROPY_SOURCE);
10047 if (in > 0) {
10048 nread = get_random_octets_from(noctets, out, in);
10049 close(in);
10050 }
10051 return nread;
10052 }
10053
10054 int rng_dirty_float(float *n) {
10055 int status; /* for aborting in case of error */
10056 uint32_t r; /* a random value on 32 bits */
10057 uint32_t maxval = 0xffffffff; /* maximum value on 32 bits */
10058
10059 /* obtain a random number on 32 bits using ENTROPY_SOURCE */
10060 status = rng_uint32( &r );
10061 if ( status < 0 )
10062 return status;
10063
10064 /* calculate and assign the floating-point random value as (r*1.0)/max val */
10065 /* multiplication by 1.0 IS NEEDED to do float division rather than int div*/
10066 *n = ( r * 1.0 ) / maxval;
10067
10068 return 1;
10069 }
10070
10071 int rng_float_754_1985(float *n) {
10072 /* Single float ieee 754/1985 has 23 bits that can be set for the mantissa
10073 * (and one implicit bit=1).
10074 * Full single float ieee 754/1985 representation takes 4 octets in total.
10075 */
10076 int noctets = 4; /* number of octets to read from ENTROPY_SOURCE */
10077 int nread; /* number of octets *read* from ENTROPY_SOURCE */
10078 unsigned char bits[ noctets ]; /* the random bits from ENTROPY_SOURCE */
10079 int oSignExp, oExpM;/* offsets for sign+exponent octet, exponent+mantissa*/
10080
10081 /* obtain random bits */
10082 nread = get_random_octets( noctets, bits );
10083
10084 if (nread != noctets )
10085 return -1; /* something wrong at reading from ENTROPY_SOURCE, abort */
10086
10087 /* set offsets for bit diddling depending on endianness of iron */
10088 if (is_bigendian()) {
10089 oSignExp = 0;
10090 oExpM = 1;
10091 }
10092 else {
10093 oSignExp = 3;
10094 oExpM = 2;
10095 }
10096
10097 /* set sign=0; exponent=127; explicit mantissa = random bits (23 bits) */
10098 *(bits+oExpM) = *(bits+2) | 0x80; /* one bit of exponent set */
10099 *(bits+oSignExp) = 0x3f; /* sign=0; exponent bits for 127 */
10100
10101 /* now copy the bits to the result var (i.e. as a float's representation */
10102 memcpy( n, bits, noctets );
10103 return 1;
10104 }
10105
10106 int rng_uint32( uint32_t *n ) {
10107 int noctets = 4; /* 32 bits aka 4 octets to read from ENTROPY_SOURCE */
10108 int nread; /* the number of octets read from ENTROPY_SOURCE */
10109 unsigned char bits[ noctets ]; /* for storing the bits from ENTROPY_SOURCE */
10110
10111 /* read random 32 bits from ENTROPY_SOURCE */
10112 nread = get_random_octets( noctets, bits );
10113 if ( nread != noctets )
10114 return -1;
10115
10116 /* copy the random bits to n, to be interpreted as uint32 */
10117 /* endianness is irrelevant here - the bits are random anyway */
10118 memcpy( n, bits, noctets );
10119
10120 return 1;
10121 }
10122
10123 int rng_uint64( uint64_t *n ) {
10124 int noctets = 8; /* 64 bits aka 8 octets to read from ENTROPY_SOURCE */
10125 int nread; /* the number of octets read from ENTROPY_SOURCE */
10126 unsigned char bits[ noctets ]; /* for storing the bits from ENTROPY_SOURCE */
10127
10128 /* read random 64 bits from ENTROPY_SOURCE */
10129 nread = get_random_octets( noctets, bits );
10130 if ( nread != noctets )
10131 return -1;
10132
10133 /* copy the random bits to n, to be interpreted as uint64 */
10134 /* endianness is irrelevant here - the bits are random anyway */
10135 memcpy( n, bits, noctets );
10136
10137 return 1;
10138 }