new approach for error handling
This commit is contained in:
@@ -148,44 +148,42 @@ int main(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *message;
|
char *message = "no data?";
|
||||||
|
bool errorFlag = false;
|
||||||
if (opts.listDevices) {
|
if (opts.listDevices) {
|
||||||
if(!listUSBDevices(&ftdic, &message)) {
|
if(!listUSBDevices(&ftdic, &message)) {
|
||||||
fputs(message, stderr);
|
fputs(message, stderr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
//fputs(message, stdout); // todo: put list of devices to &message and print here, not in libinfnoise
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.devRandom) {
|
if (opts.devRandom) {
|
||||||
inmWriteEntropyStart(BUFLEN/8u, opts.debug); // todo: create method in libinfnoise.h for this
|
inmWriteEntropyStart(BUFLEN/8u, opts.debug); // todo: create method in libinfnoise.h for this?
|
||||||
// also todo: check if superUser in this mode (it will fail silently if not :-/)
|
// also todo: check superUser in this mode (it will fail silently if not :-/)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optionally run in the background and optionally write a PID-file
|
// Optionally run in the background and optionally write a PID-file
|
||||||
startDaemon(&opts);
|
startDaemon(&opts);
|
||||||
|
|
||||||
// initialize USB device and health check
|
// initialize USB device, health check and Keccak state (see libinfnoise)
|
||||||
if (initInfnoise(&ftdic, opts.serial, &message, opts.debug) != true) {
|
if (initInfnoise(&ftdic, opts.serial, &message, !opts.raw, opts.debug) != true) {
|
||||||
fputs(message, stderr);
|
fputs(message, stderr);
|
||||||
return 1; // ERROR (message still goes to stderr)
|
return 1; // ERROR
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize keccak
|
// endless loop
|
||||||
KeccakInitialize();
|
|
||||||
uint8_t keccakState[KeccakPermutationSizeInBytes];
|
|
||||||
KeccakInitializeState(keccakState);
|
|
||||||
|
|
||||||
uint64_t totalBytesWritten = 0u;
|
uint64_t totalBytesWritten = 0u;
|
||||||
while(true) {
|
while(true) {
|
||||||
uint64_t prevTotalBytesWritten = totalBytesWritten;
|
uint64_t prevTotalBytesWritten = totalBytesWritten;
|
||||||
uint64_t bytesWritten = readData_private(&ftdic, keccakState, NULL, &message, opts.noOutput, opts.raw, opts.outputMultiplier, opts.devRandom); // calling libinfnoise's private readData method
|
totalBytesWritten += readData_private(&ftdic, NULL, &message, &errorFlag, opts.noOutput, opts.raw, opts.outputMultiplier, opts.devRandom); // calling libinfnoise's private readData method
|
||||||
|
|
||||||
if (totalBytesWritten == (unsigned long)-1) {
|
if (errorFlag) {
|
||||||
fputs(message, stderr);
|
fprintf(stderr, "%s\n", message);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
totalBytesWritten += bytesWritten;
|
|
||||||
if(opts.debug && (1u << 20u)*(totalBytesWritten/(1u << 20u)) > (1u << 20u)*(prevTotalBytesWritten/(1u << 20u))) {
|
if(opts.debug && (1u << 20u)*(totalBytesWritten/(1u << 20u)) > (1u << 20u)*(prevTotalBytesWritten/(1u << 20u))) {
|
||||||
fprintf(stderr, "Output %lu bytes\n", (unsigned long)totalBytesWritten);
|
fprintf(stderr, "Output %lu bytes\n", (unsigned long)totalBytesWritten);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Driver for the Infinite Noise Multiplier USB stick */
|
/* Library for the Infinite Noise Multiplier USB stick */
|
||||||
|
|
||||||
// Required to include clock_gettime
|
// Required to include clock_gettime
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
@@ -18,11 +18,61 @@
|
|||||||
#include "libinfnoise.h"
|
#include "libinfnoise.h"
|
||||||
#include "KeccakF-1600-interface.h"
|
#include "KeccakF-1600-interface.h"
|
||||||
|
|
||||||
|
uint8_t keccakState[KeccakPermutationSizeInBytes];
|
||||||
|
bool initInfnoise(struct ftdi_context *ftdic,char *serial, char **message, bool keccak, bool debug) {
|
||||||
|
prepareOutputBuffer();
|
||||||
|
|
||||||
|
// initialize health check
|
||||||
|
if (!inmHealthCheckStart(PREDICTION_BITS, DESIGN_K, debug)) {
|
||||||
|
*message="Can't initialize health checker";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize USB
|
||||||
|
if(!initializeUSB(ftdic, message, serial)) {
|
||||||
|
// Sometimes have to do it twice - not sure why
|
||||||
|
if(!initializeUSB(ftdic, message, serial)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize keccak
|
||||||
|
if (keccak) {
|
||||||
|
KeccakInitialize();
|
||||||
|
KeccakInitializeState(keccakState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// let healthcheck collect some data
|
||||||
|
uint32_t maxWarmupRounds = 500;
|
||||||
|
uint32_t warmupRounds = 0;
|
||||||
|
bool errorFlag = false;
|
||||||
|
while(!inmHealthCheckOkToUseData()) {
|
||||||
|
readData_private(ftdic, NULL, message, &errorFlag, false, true, 0, false);
|
||||||
|
warmupRounds++;
|
||||||
|
}
|
||||||
|
if (warmupRounds > maxWarmupRounds) {
|
||||||
|
*message = "Unable to collect enough entropy to initialize health checker.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t outBuf[BUFLEN];
|
||||||
|
void prepareOutputBuffer() {
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
// Endless loop: set SW1EN and SW2EN alternately
|
||||||
|
for(i = 0u; i < BUFLEN; i++) {
|
||||||
|
// Alternate Ph1 and Ph2
|
||||||
|
outBuf[i] = i & 1? (1 << SWEN2) : (1 << SWEN1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Extract the INM output from the data received. Basically, either COMP1 or COMP2
|
// Extract the INM output from the data received. Basically, either COMP1 or COMP2
|
||||||
// changes, not both, so alternate reading bits from them. We get 1 INM bit of output
|
// changes, not both, so alternate reading bits from them. We get 1 INM bit of output
|
||||||
// per byte read. Feed bits from the INM to the health checker. Return the expected
|
// per byte read. Feed bits from the INM to the health checker. Return the expected
|
||||||
// bits of entropy.
|
// bits of entropy.
|
||||||
uint32_t extractBytes(uint8_t *bytes, uint8_t *inBuf) {
|
uint32_t extractBytes(uint8_t *bytes, uint8_t *inBuf, char **message, bool *errorFlag) {
|
||||||
inmClearEntropyLevel();
|
inmClearEntropyLevel();
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
for(i = 0u; i < BUFLEN/8u; i++) {
|
for(i = 0u; i < BUFLEN/8u; i++) {
|
||||||
@@ -35,10 +85,12 @@ uint32_t extractBytes(uint8_t *bytes, uint8_t *inBuf) {
|
|||||||
bool even = j & 1u; // Use the even bit if j is odd
|
bool even = j & 1u; // Use the even bit if j is odd
|
||||||
uint8_t bit = even? evenBit : oddBit;
|
uint8_t bit = even? evenBit : oddBit;
|
||||||
byte = (byte << 1u) | bit;
|
byte = (byte << 1u) | bit;
|
||||||
|
|
||||||
// This is a good place to feed the bit from the INM to the health checker.
|
// This is a good place to feed the bit from the INM to the health checker.
|
||||||
if(!inmHealthCheckAddBit(evenBit, oddBit, even)) {
|
if(!inmHealthCheckAddBit(evenBit, oddBit, even)) {
|
||||||
fputs("Health check of Infinite Noise Multiplier failed!\n", stderr);
|
*message = "Health check of Infinite Noise Multiplier failed!";
|
||||||
exit(1);
|
*errorFlag = true;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bytes[i] = byte;
|
bytes[i] = byte;
|
||||||
@@ -54,16 +106,17 @@ double diffTime(struct timespec *start, struct timespec *end) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write the bytes to either stdout, or /dev/random.
|
// Write the bytes to either stdout, or /dev/random.
|
||||||
void outputBytes(uint8_t *bytes, uint32_t length, uint32_t entropy, bool writeDevRandom) {
|
bool outputBytes(uint8_t *bytes, uint32_t length, uint32_t entropy, bool writeDevRandom, char **message) {
|
||||||
if(!writeDevRandom) {
|
if(!writeDevRandom) {
|
||||||
if(fwrite(bytes, 1, length, stdout) != length) {
|
if(fwrite(bytes, 1, length, stdout) != length) {
|
||||||
fputs("Unable to write output from Infinite Noise Multiplier\n", stderr);
|
*message = "Unable to write output from Infinite Noise Multiplier";
|
||||||
exit(1);
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
inmWaitForPoolToHaveRoom();
|
inmWaitForPoolToHaveRoom();
|
||||||
inmWriteEntropyToPool(bytes, length, entropy);
|
inmWriteEntropyToPool(bytes, length, entropy);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isSuperUser(void) {
|
bool isSuperUser(void) {
|
||||||
@@ -76,8 +129,9 @@ bool isSuperUser(void) {
|
|||||||
// outputMultiplier is 0, we output only as many bits as we measure in entropy.
|
// outputMultiplier is 0, we output only as many bits as we measure in entropy.
|
||||||
// This allows a user to generate hundreds of MiB per second if needed, for use
|
// This allows a user to generate hundreds of MiB per second if needed, for use
|
||||||
// as cryptographic keys.
|
// as cryptographic keys.
|
||||||
uint32_t processBytes(uint8_t *keccakState, uint8_t *bytes, uint8_t *result, uint32_t entropy, bool raw,
|
uint32_t processBytes(uint8_t *bytes, uint8_t *result, uint32_t entropy,
|
||||||
bool writeDevRandom, uint32_t outputMultiplier, bool noOutput) {
|
bool raw, bool writeDevRandom, uint32_t outputMultiplier, bool noOutput,
|
||||||
|
char **message, bool *errorFlag) {
|
||||||
//Use the lower of the measured entropy and the provable lower bound on
|
//Use the lower of the measured entropy and the provable lower bound on
|
||||||
//average entropy.
|
//average entropy.
|
||||||
if(entropy > inmExpectedEntropyPerBit*BUFLEN/INM_ACCURACY) {
|
if(entropy > inmExpectedEntropyPerBit*BUFLEN/INM_ACCURACY) {
|
||||||
@@ -86,7 +140,10 @@ uint32_t processBytes(uint8_t *keccakState, uint8_t *bytes, uint8_t *result, uin
|
|||||||
if(raw) {
|
if(raw) {
|
||||||
// In raw mode, we just output raw data from the INM.
|
// In raw mode, we just output raw data from the INM.
|
||||||
if (!noOutput) {
|
if (!noOutput) {
|
||||||
outputBytes(bytes, BUFLEN/8u, entropy, writeDevRandom);
|
if (!outputBytes(bytes, BUFLEN/8u, entropy, writeDevRandom, message)) {
|
||||||
|
*errorFlag = true;
|
||||||
|
return 0; // write failed
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
memcpy(result, bytes, BUFLEN/8u * sizeof(uint8_t));
|
memcpy(result, bytes, BUFLEN/8u * sizeof(uint8_t));
|
||||||
@@ -108,7 +165,10 @@ uint32_t processBytes(uint8_t *keccakState, uint8_t *bytes, uint8_t *result, uin
|
|||||||
// Output all the bytes of entropy we have
|
// Output all the bytes of entropy we have
|
||||||
KeccakExtract(keccakState, dataOut, (entropy + 63u)/64u);
|
KeccakExtract(keccakState, dataOut, (entropy + 63u)/64u);
|
||||||
if (!noOutput) {
|
if (!noOutput) {
|
||||||
outputBytes(dataOut, entropy/8u, entropy & 0x7u, writeDevRandom);
|
if (!outputBytes(dataOut, entropy/8u, entropy & 0x7u, writeDevRandom, message)) {
|
||||||
|
*errorFlag = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
memcpy(result, dataOut, entropy/8u * sizeof(uint8_t));
|
memcpy(result, dataOut, entropy/8u * sizeof(uint8_t));
|
||||||
@@ -133,7 +193,10 @@ uint32_t processBytes(uint8_t *keccakState, uint8_t *bytes, uint8_t *result, uin
|
|||||||
entropyThisTime = 8u*bytesToWrite;
|
entropyThisTime = 8u*bytesToWrite;
|
||||||
}
|
}
|
||||||
if (!noOutput) {
|
if (!noOutput) {
|
||||||
outputBytes(dataOut, bytesToWrite, entropyThisTime, writeDevRandom);
|
if (!outputBytes(dataOut, bytesToWrite, entropyThisTime, writeDevRandom, message)) {
|
||||||
|
*errorFlag = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
//memcpy(result + bytesWritten, dataOut, bytesToWrite * sizeof(uint8_t)); //doesn't work?
|
//memcpy(result + bytesWritten, dataOut, bytesToWrite * sizeof(uint8_t)); //doesn't work?
|
||||||
// alternative: loop through dataOut and append array elements to result..
|
// alternative: loop through dataOut and append array elements to result..
|
||||||
@@ -151,8 +214,9 @@ uint32_t processBytes(uint8_t *keccakState, uint8_t *bytes, uint8_t *result, uin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(bytesWritten != outputMultiplier*(256u/8u)) {
|
if(bytesWritten != outputMultiplier*(256u/8u)) {
|
||||||
fprintf(stderr, "Internal error outputing bytes\n");
|
*message = "Internal error outputing bytes";
|
||||||
exit(1);
|
*errorFlag = true;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return bytesWritten;
|
return bytesWritten;
|
||||||
}
|
}
|
||||||
@@ -171,9 +235,9 @@ bool listUSBDevices(struct ftdi_context *ftdic, char** message) {
|
|||||||
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
if (!isSuperUser()) {
|
if (!isSuperUser()) {
|
||||||
*message = "Can't find Infinite Noise Multiplier. Try running as super user?\n";
|
*message = "Can't find Infinite Noise Multiplier. Try running as super user?";
|
||||||
} else {
|
} else {
|
||||||
*message = "Can't find Infinite Noise Multiplier\n";
|
*message = "Can't find Infinite Noise Multiplier";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,7 +246,7 @@ bool listUSBDevices(struct ftdi_context *ftdic, char** message) {
|
|||||||
rc = ftdi_usb_get_strings(ftdic, curdev->dev, manufacturer, 128, description, 128, serial, 128);
|
rc = ftdi_usb_get_strings(ftdic, curdev->dev, manufacturer, 128, description, 128, serial, 128);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
if (!isSuperUser()) {
|
if (!isSuperUser()) {
|
||||||
*message = "Can't find Infinite Noise Multiplier. Try running as super user?\n";
|
*message = "Can't find Infinite Noise Multiplier. Try running as super user?";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//*message = "ftdi_usb_get_strings failed: %d (%s)\n", rc, ftdi_get_error_string(ftdic));
|
//*message = "ftdi_usb_get_strings failed: %d (%s)\n", rc, ftdi_get_error_string(ftdic));
|
||||||
@@ -190,7 +254,7 @@ bool listUSBDevices(struct ftdi_context *ftdic, char** message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// print to stdout
|
// print to stdout
|
||||||
printf("Manufacturer: %s, Description: %s, Serial: %s\n", manufacturer, description, serial);
|
printf("Manufacturer: %s, Description: %s, Serial: %s", manufacturer, description, serial);
|
||||||
curdev = curdev->next;
|
curdev = curdev->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +269,7 @@ bool initializeUSB(struct ftdi_context *ftdic, char **message, char *serial) {
|
|||||||
// search devices
|
// search devices
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
if ((rc = ftdi_usb_find_all(ftdic, &devlist, INFNOISE_VENDOR_ID, INFNOISE_PRODUCT_ID)) < 0) {
|
if ((rc = ftdi_usb_find_all(ftdic, &devlist, INFNOISE_VENDOR_ID, INFNOISE_PRODUCT_ID)) < 0) {
|
||||||
*message = "Can't find Infinite Noise Multiplier\n";
|
*message = "Can't find Infinite Noise Multiplier";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,13 +278,13 @@ bool initializeUSB(struct ftdi_context *ftdic, char **message, char *serial) {
|
|||||||
if (serial == NULL) {
|
if (serial == NULL) {
|
||||||
// more than one found AND no serial given
|
// more than one found AND no serial given
|
||||||
if (rc >= 2) {
|
if (rc >= 2) {
|
||||||
*message = "Multiple Infnoise TRNGs found and serial not specified, using the first one!\n";
|
*message = "Multiple Infnoise TRNGs found and serial not specified, using the first one!";
|
||||||
}
|
}
|
||||||
if (ftdi_usb_open(ftdic, INFNOISE_VENDOR_ID, INFNOISE_PRODUCT_ID) < 0) {
|
if (ftdi_usb_open(ftdic, INFNOISE_VENDOR_ID, INFNOISE_PRODUCT_ID) < 0) {
|
||||||
if(!isSuperUser()) {
|
if(!isSuperUser()) {
|
||||||
*message = "Can't open Infinite Noise Multiplier. Try running as super user?\n";
|
*message = "Can't open Infinite Noise Multiplier. Try running as super user?";
|
||||||
} else {
|
} else {
|
||||||
*message = "Can't open Infinite Noise Multiplier\n";
|
*message = "Can't open Infinite Noise Multiplier";
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -229,9 +293,9 @@ bool initializeUSB(struct ftdi_context *ftdic, char **message, char *serial) {
|
|||||||
rc = ftdi_usb_open_desc(ftdic, INFNOISE_VENDOR_ID, INFNOISE_PRODUCT_ID, NULL, serial);
|
rc = ftdi_usb_open_desc(ftdic, INFNOISE_VENDOR_ID, INFNOISE_PRODUCT_ID, NULL, serial);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
if(!isSuperUser()) {
|
if(!isSuperUser()) {
|
||||||
*message = "Can't find Infinite Noise Multiplier. Try running as super user?\n";
|
*message = "Can't find Infinite Noise Multiplier. Try running as super user?";
|
||||||
} else {
|
} else {
|
||||||
*message = "Can't find Infinite Noise Multiplier with given serial\n";
|
*message = "Can't find Infinite Noise Multiplier with given serial";
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -241,18 +305,18 @@ bool initializeUSB(struct ftdi_context *ftdic, char **message, char *serial) {
|
|||||||
// Set high baud rate
|
// Set high baud rate
|
||||||
rc = ftdi_set_baudrate(ftdic, 30000);
|
rc = ftdi_set_baudrate(ftdic, 30000);
|
||||||
if(rc == -1) {
|
if(rc == -1) {
|
||||||
*message = "Invalid baud rate\n";
|
*message = "Invalid baud rate";
|
||||||
return false;
|
return false;
|
||||||
} else if(rc == -2) {
|
} else if(rc == -2) {
|
||||||
*message = "Setting baud rate failed\n";
|
*message = "Setting baud rate failed";
|
||||||
return false;
|
return false;
|
||||||
} else if(rc == -3) {
|
} else if(rc == -3) {
|
||||||
*message = "Infinite Noise Multiplier unavailable\n";
|
*message = "Infinite Noise Multiplier unavailable";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
rc = ftdi_set_bitmode(ftdic, MASK, BITMODE_SYNCBB);
|
rc = ftdi_set_bitmode(ftdic, MASK, BITMODE_SYNCBB);
|
||||||
if(rc == -1) {
|
if(rc == -1) {
|
||||||
*message = "Can't enable bit-bang mode\n";
|
*message = "Can't enable bit-bang mode";
|
||||||
return false;
|
return false;
|
||||||
} else if(rc == -2) {
|
} else if(rc == -2) {
|
||||||
*message = "Infinite Noise Multiplier unavailable\n";
|
*message = "Infinite Noise Multiplier unavailable\n";
|
||||||
@@ -262,51 +326,40 @@ bool initializeUSB(struct ftdi_context *ftdic, char **message, char *serial) {
|
|||||||
// Just test to see that we can write and read.
|
// Just test to see that we can write and read.
|
||||||
uint8_t buf[64u] = {0u,};
|
uint8_t buf[64u] = {0u,};
|
||||||
if(ftdi_write_data(ftdic, buf, 64) != 64) {
|
if(ftdi_write_data(ftdic, buf, 64) != 64) {
|
||||||
*message = "USB write failed\n";
|
*message = "USB write failed";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(ftdi_read_data(ftdic, buf, 64) != 64) {
|
if(ftdi_read_data(ftdic, buf, 64) != 64) {
|
||||||
*message = "USB read failed\n";
|
*message = "USB read failed";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t readRawData(struct ftdi_context *ftdic, uint8_t *result, char **message, bool *errorFlag) {
|
||||||
uint64_t readRawData(struct ftdi_context *ftdic, uint8_t *result, char **message) {
|
return readData_private(ftdic, result, message, errorFlag, false, true, 0, false);
|
||||||
return readData_private(ftdic, NULL, result, message, false, true, 0, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t readData(struct ftdi_context *ftdic, uint8_t *keccakState, uint8_t *result, char **message, uint32_t outputMultiplier) {
|
uint32_t readData(struct ftdi_context *ftdic, uint8_t *result, char **message, bool *errorFlag, uint32_t outputMultiplier) {
|
||||||
return readData_private(ftdic, keccakState, result, message, false, false, outputMultiplier, false);
|
return readData_private(ftdic, result, message, errorFlag, false, false, outputMultiplier, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t outBuf[BUFLEN];
|
uint32_t readData_private(struct ftdi_context *ftdic, uint8_t *result, char **message, bool *errorFlag,
|
||||||
void prepareOutputBuffer() {
|
bool noOutput, bool raw, uint32_t outputMultiplier, bool devRandom) {
|
||||||
uint32_t i;
|
|
||||||
|
|
||||||
// Endless loop: set SW1EN and SW2EN alternately
|
|
||||||
for(i = 0u; i < BUFLEN; i++) {
|
|
||||||
// Alternate Ph1 and Ph2
|
|
||||||
outBuf[i] = i & 1? (1 << SWEN2) : (1 << SWEN1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t readData_private(struct ftdi_context *ftdic, uint8_t *keccakState, uint8_t *result, char **message, bool noOutput, bool raw, uint32_t outputMultiplier, bool devRandom) {
|
|
||||||
uint8_t inBuf[BUFLEN];
|
uint8_t inBuf[BUFLEN];
|
||||||
uint64_t totalBytesWritten = 0u;
|
|
||||||
struct timespec start;
|
struct timespec start;
|
||||||
clock_gettime(CLOCK_REALTIME, &start);
|
clock_gettime(CLOCK_REALTIME, &start);
|
||||||
|
|
||||||
// write clock signal
|
// write clock signal
|
||||||
if(ftdi_write_data(ftdic, outBuf, BUFLEN) != BUFLEN) {
|
if(ftdi_write_data(ftdic, outBuf, BUFLEN) != BUFLEN) {
|
||||||
*message = "USB write failed";
|
*message = "USB write failed";
|
||||||
return -1;
|
*errorFlag = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// and read 512 byte from the internal buffer (in synchronous bitbang mode)
|
// and read 512 byte from the internal buffer (in synchronous bitbang mode)
|
||||||
if(ftdi_read_data(ftdic, inBuf, BUFLEN) != BUFLEN) {
|
if(ftdi_read_data(ftdic, inBuf, BUFLEN) != BUFLEN) {
|
||||||
*message = "USB read failed";
|
*message = "USB read failed";
|
||||||
return -1;
|
*errorFlag = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct timespec end;
|
struct timespec end;
|
||||||
@@ -314,37 +367,15 @@ uint64_t readData_private(struct ftdi_context *ftdic, uint8_t *keccakState, uint
|
|||||||
uint32_t us = diffTime(&start, &end);
|
uint32_t us = diffTime(&start, &end);
|
||||||
if(us <= MAX_MICROSEC_FOR_SAMPLES) {
|
if(us <= MAX_MICROSEC_FOR_SAMPLES) {
|
||||||
uint8_t bytes[BUFLEN/8u];
|
uint8_t bytes[BUFLEN/8u];
|
||||||
uint32_t entropy = extractBytes(bytes, inBuf);
|
uint32_t entropy = extractBytes(bytes, inBuf, message, errorFlag);
|
||||||
|
|
||||||
// call health check and process bytes if OK
|
// call health check and process bytes if OK
|
||||||
if(!noOutput && inmHealthCheckOkToUseData() && inmEntropyOnTarget(entropy, BUFLEN)) {
|
if (inmHealthCheckOkToUseData() && inmEntropyOnTarget(entropy, BUFLEN)) {
|
||||||
totalBytesWritten += processBytes(keccakState, bytes, result, entropy, raw, devRandom, outputMultiplier, noOutput);
|
uint32_t byteswritten = processBytes(bytes, result, entropy, raw, devRandom, outputMultiplier, noOutput, message, errorFlag);
|
||||||
|
return byteswritten;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return totalBytesWritten;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t keccakState[KeccakPermutationSizeInBytes];
|
|
||||||
bool initInfnoise(struct ftdi_context *ftdic,char *serial, char **message, bool debug) {
|
|
||||||
prepareOutputBuffer();
|
|
||||||
// initialize health check
|
|
||||||
if (!inmHealthCheckStart(PREDICTION_BITS, DESIGN_K, debug)) {
|
|
||||||
*message="Can't initialize health checker";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize USB
|
|
||||||
if(!initializeUSB(ftdic, message, serial)) {
|
|
||||||
// Sometimes have to do it twice - not sure why
|
|
||||||
if(!initializeUSB(ftdic, message, serial)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// initialize keccak
|
|
||||||
KeccakInitialize();
|
|
||||||
KeccakInitializeState(keccakState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LIB_EXAMPLE_PROGRAM
|
#ifdef LIB_EXAMPLE_PROGRAM
|
||||||
@@ -368,7 +399,6 @@ int main() {
|
|||||||
} else {
|
} else {
|
||||||
resultSize = multiplier*32u;
|
resultSize = multiplier*32u;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "%d\n", resultSize);
|
|
||||||
|
|
||||||
uint64_t totalBytesWritten = 0u;
|
uint64_t totalBytesWritten = 0u;
|
||||||
|
|
||||||
|
|||||||
@@ -47,18 +47,18 @@ void inmWriteEntropyStart(uint32_t bufLen, bool debug);
|
|||||||
void inmWriteEntropyToPool(uint8_t *bytes, uint32_t length, uint32_t entropy);
|
void inmWriteEntropyToPool(uint8_t *bytes, uint32_t length, uint32_t entropy);
|
||||||
void inmWaitForPoolToHaveRoom(void);
|
void inmWaitForPoolToHaveRoom(void);
|
||||||
void inmDumpStats(void);
|
void inmDumpStats(void);
|
||||||
//bool isSuperUser(void);
|
|
||||||
|
|
||||||
extern double inmK, inmExpectedEntropyPerBit;
|
extern double inmK, inmExpectedEntropyPerBit;
|
||||||
|
|
||||||
|
bool initializeUSB(struct ftdi_context *ftdic, char **message, char *serial);
|
||||||
|
void prepareOutputBuffer();
|
||||||
|
|
||||||
struct timespec;
|
struct timespec;
|
||||||
double diffTime(struct timespec *start, struct timespec *end);
|
double diffTime(struct timespec *start, struct timespec *end);
|
||||||
uint32_t extractBytes(uint8_t *bytes, uint8_t *inBuf);
|
uint32_t extractBytes(uint8_t *bytes, uint8_t *inBuf, char **message, bool *errorFlag);
|
||||||
void outputBytes(uint8_t *bytes, uint32_t length, uint32_t entropy, bool writeDevRandom);
|
|
||||||
uint32_t processBytes(uint8_t *keccakState, uint8_t *bytes, uint8_t *result, uint32_t entropy, bool raw,
|
|
||||||
bool writeDevRandom, uint32_t outputMultiplier, bool noOutput);
|
|
||||||
|
|
||||||
uint64_t readData_private(struct ftdi_context *ftdic, uint8_t *keccakState, uint8_t *result, char **message,
|
bool outputBytes(uint8_t *bytes, uint32_t length, uint32_t entropy, bool writeDevRandom, char **message);
|
||||||
bool noOutput, bool raw, uint32_t outputMultiplier, bool devRandom);
|
uint32_t processBytes(uint8_t *bytes, uint8_t *result, uint32_t entropy, bool raw,
|
||||||
|
bool writeDevRandom, uint32_t outputMultiplier, bool noOutput, char **message, bool *errorFlag);
|
||||||
//void add_to_list(struct inm_devlist *list, struct infnoise_device *dev);
|
|
||||||
|
|
||||||
|
uint32_t readData_private(struct ftdi_context *ftdic, uint8_t *result, char **message, bool *errorFlag, bool noOutput, bool raw, uint32_t outputMultiplier, bool devRandom);
|
||||||
|
|||||||
Reference in New Issue
Block a user