waywardgeek / infnoise

The world's easiest TRNG to get right
Creative Commons Zero v1.0 Universal
723 stars 99 forks source link

libinfnoise #51

Closed sbates130272 closed 6 years ago

sbates130272 commented 6 years ago

Hi

Awesome project ;-). Right now infnoise compiles as a executable. Could we develop a libinfnoise target for both windows and Linux so it's easier for people to pull the TRNG streams into their user-space applications?

Stephen

manuel-domke commented 6 years ago

Great idea! I recently came up with the similar idea to write a python lib based on one of the libftdi python wrappers. Good luck I never started, as this seems much easier (and more sustainable, as we could then build such C wrappers for any language).

Currently the only ways to integrate are calling that binary or reading from /dev/random. Both have their downsides, but anyway I'll show some examples on how to do it for now (in an upcoming campaign update).

I've started with the necessary refactoring for a libinfnoise in a branch: https://github.com/manuel-domke/infnoise/tree/libinfnoise

It was a bit hard to make it "return" byte arrays instead of writing to stdout, but it works. There is a small example program in libinfnoise.c how it can be used for now.

Still todo:

Click to show the example program from libinfnoise.c ``` // example use of libinfnoise int main() { // initialize health check if (!inmHealthCheckStart(PREDICTION_BITS, DESIGN_K, false)) { fputs("Can't initialize health checker\n", stderr); return 1; } // initialize keccak KeccakInitialize(); uint8_t keccakState[KeccakPermutationSizeInBytes]; KeccakInitializeState(keccakState); // initialize USB struct ftdi_context ftdic; char *message; char *serial=NULL; // use any device, can be set to a specific serial if(!initializeUSB(&ftdic, &message, serial)) { // Sometimes have to do it twice - not sure why if(!initializeUSB(&ftdic, &message, serial)) { fputs(message, stderr); return 1; } } uint64_t totalBytesWritten = 0u; // parameters for readData(..): bool rawOutput = true; uint32_t multiplier = 10u; bool debug = false; // calculate output size based on the parameters: // when using the multiplier, we need a result array of multiplier*32 bytes - otherwise the full buffer size (512 bytes) uint32_t resultSize; if (multiplier == 0 || rawOutput == true) { resultSize = BUFLEN; } else { resultSize = multiplier*32; } fprintf(stderr, "%d\n", resultSize); // read and print while (totalBytesWritten < 100000) { fprintf(stderr, "%lu\n", (unsigned long)totalBytesWritten); uint8_t result[resultSize]; //uint8_t *result = malloc(resultSize * sizeof(uint8_t)); // array to hold the (whitened) result uint64_t bytesWritten = 0u; bytesWritten = readData(&ftdic, keccakState, result, rawOutput, multiplier, debug); fprintf(stderr, "bw2: %lu\n", (unsigned long)bytesWritten); totalBytesWritten += bytesWritten; fwrite(result, 1, bytesWritten, stdout); } } ```
manuel-domke commented 6 years ago

I've worked on the interface, feedback aprecciated:

bool listUSBDevices(struct ftdi_context *ftdic, struct inm_devlist **result, char **message);

bool initInfnoise(struct ftdi_context *ftdic, char *serial, bool debug);

bool initKeccak(struct ftdi_context *ftdic, char *serial);

uint64_t readRawData(struct ftdi_context *ftdic, uint8_t *result);

uint64_t readData(struct ftdi_context *ftdic, uint8_t *keccakState, uint8_t *result, uint32_t outputMultiplier);

The infnoise binary still has dependencies to libinfnoise_private.h, which are really hard to avoid without duplicating lots of code - but I think its pretty OK this way.

Still some stuff to clean up and fix - but this could become a release candidate soon.

manuel-domke commented 6 years ago

I created pull request #55 for the current state of work.

libinfnoise is usable for now, but the interface may change. Feedback wanted!

sbates130272 commented 6 years ago

This looks great! I have some hardware coming soon so let me play with it and get you some feedback on the API into the library. Thanks!

manuel-domke commented 6 years ago

I've opened another fork for further libinfnoise developments.

My next goal is to fully separate input and output, so libinfnoise can be used independently.

edit: almost done, but we still need to find an elegant way to keep track of the number of bits worth entropy in the result. Currently its only needed for /dev/random mode. Maybe we can even hide it completely. See f0b407b

And finally, clean up the mess!

https://github.com/13-37-org/infnoise/tree/libinfnoise/software

manuel-domke commented 6 years ago

IMO the refactoring is done. This is how the interface finally looks:

// initialize device
bool initInfnoise(struct infnoise_context *context, char *serial, bool keccak, bool debug);

// reads data in chunks of 32-128KB, depending in multiplier
uint32_t readData(struct infnoise_context *context, uint8_t *result, bool raw, uint32_t outputMultiplier);

// returns a struct listing the connected (FTDI) devices.
devlist_node listUSBDevices(char **message);