next big step completed: fixed keccak multiplicator and --dev-random mode after libinfnoise refactoring (interface changed!)

This commit is contained in:
Manuel Domke
2018-08-27 17:48:27 +02:00
parent 25605e673e
commit 71df49d7bf
5 changed files with 85 additions and 74 deletions

View File

@@ -287,15 +287,17 @@ int main(int argc, char **argv) {
uint8_t result[resultSize];
uint64_t bytesWritten = readData(&context, result, opts.raw, opts.outputMultiplier);
totalBytesWritten += bytesWritten;
fprintf(stderr, "Stats: %d\n", context.entropyThisTime);
// fprintf(stderr, "Stats: %d\n", context.entropyThisTime);
if (context.errorFlag) {
fprintf(stderr, "Error: %s\n", context.message);
return 1;
}
//fprintf(stderr, "Error: %s\n", context.message);
if (!opts.noOutput) {
fprintf(stderr, "E: %ul\n", context.entropyThisTime);
//fprintf(stderr, "B: %lu\n", bytesWritten);
//fprintf(stderr, "E: %ul\n", context.entropyThisTime);
if (!outputBytes(result, bytesWritten, context.entropyThisTime, opts.devRandom,
&context.message)) {
fprintf(stderr, "Error: %s\n", context.message);

View File

@@ -50,7 +50,7 @@ bool initInfnoise(struct infnoise_context *context, char *serial, bool keccak, b
}
// let healthcheck collect some data
uint32_t maxWarmupRounds = 500;
uint32_t maxWarmupRounds = 5000;
uint32_t warmupRounds = 0;
//bool errorFlag = false;
while (!inmHealthCheckOkToUseData()) {
@@ -99,7 +99,7 @@ uint32_t extractBytes(uint8_t *bytes, uint8_t *inBuf, char **message, bool *erro
if (!inmHealthCheckAddBit(evenBit, oddBit, even)) {
*message = "Health check of Infinite Noise Multiplier failed!";
*errorFlag = true;
fprintf(stderr, "Error: %s\n", *message);
fprintf(stderr, "health-Error: %s\n", *message);
return 0;
}
}
@@ -115,7 +115,8 @@ uint32_t extractBytes(uint8_t *bytes, uint8_t *inBuf, char **message, bool *erro
// This allows a user to generate hundreds of MiB per second if needed, for use
// as cryptographic keys.
uint32_t processBytes(uint8_t *bytes, uint8_t *result, uint32_t *entropy,
bool raw, uint32_t outputMultiplier, char **message, bool *errorFlag) {
uint32_t *numBits, uint32_t *bytesWritten,
bool raw, uint32_t outputMultiplier) {
//Use the lower of the measured entropy and the provable lower bound on
//average entropy.
if (*entropy > inmExpectedEntropyPerBit * BUFLEN / INM_ACCURACY) {
@@ -136,62 +137,46 @@ uint32_t processBytes(uint8_t *bytes, uint8_t *result, uint32_t *entropy,
// we instantly recover (reseed) from a state compromise, which is when an attacker
// gets a snapshot of the keccak state. BUFLEN must be a multiple of 64, since
// Keccak-1600 uses 64-bit "lanes".
uint8_t dataOut[1024u];
KeccakAbsorb(keccakState, bytes, BUFLEN / 64u);
if (outputMultiplier == 0u) {
uint8_t dataOut[16u*8u]; // ???
// Output all the bytes of entropy we have
KeccakExtract(keccakState, dataOut, (*entropy + 63u) / 64u);
if (result != NULL) {
memcpy(result, dataOut, *entropy / 8u * sizeof(uint8_t));
}
return *entropy / 8u;
}
// Output 256*outputMultipler bits.
uint32_t numBits = outputMultiplier * 256u;
uint32_t bytesWritten = 0u;
uint8_t dataOut[outputMultiplier * 32u]; // ???
// Output 256*outputMultipler bits (in chunks of 1024)
// only the first 1024 now,
if (*numBits == 0u) {
*numBits = outputMultiplier*256u;
*bytesWritten = 0u;
while (numBits > 0u) {
// Write up to 1024 bits at a time.
// Output up to 1024 bits at a time.
uint32_t bytesToWrite = 1024u / 8u;
if (bytesToWrite > numBits / 8u) {
bytesToWrite = numBits / 8u;
if (bytesToWrite > *numBits / 8u) {
bytesToWrite = *numBits / 8u;
}
KeccakExtract(keccakState, dataOut, bytesToWrite / 8u);
uint32_t entropyThisTime = *entropy;
if (entropyThisTime > 8u * bytesToWrite) {
entropyThisTime = 8u * bytesToWrite;
}
// memcpy(result + bytesWritten, dataOut, bytesToWrite * sizeof(uint8_t)); // ?
// alternative: loop through dataOut and append array elements to result..
if (result != NULL) {
for (uint32_t i = 0; i < bytesToWrite; i++) {
result[bytesWritten + i] = dataOut[i];
}
}
//fprintf(stderr, "bytesWritten: %ul\n", bytesWritten);
//fprintf(stderr, "entropy: %ul\n", *entropy);
bytesWritten += bytesToWrite;
numBits -= bytesToWrite * 8u;
//*entropy -= entropyThisTime;
if (numBits > 0u) {
//uint32_t entropyThisTime = *entropy;
//if (entropyThisTime > 8u * bytesToWrite) {
// entropyThisTime = 8u * bytesToWrite;
//}
KeccakExtract(keccakState, result, bytesToWrite / 8u);
KeccakPermutation(keccakState);
}
}
if (bytesWritten != outputMultiplier * (256u / 8u)) {
*message = "Internal error outputting bytes";
//fprintf(stderr, "ERROR: %ul", bytesWritten);
*errorFlag = true;
return 0;
}
fprintf(stderr, "bytesWritten_end: %ul\n", bytesWritten);
return bytesWritten;
*bytesWritten = bytesToWrite;
*numBits -= bytesToWrite * 8u;
}
//fprintf(stderr, "bytesWritten_end: %ul\n", bytesWritten);
return *bytesWritten;
}
// Return the difference in the times as a double in microseconds.
double diffTime(struct timespec *start, struct timespec *end) {
@@ -334,6 +319,24 @@ bool initializeUSB(struct ftdi_context *ftdic, char **message, char *serial) {
}
uint32_t readData(struct infnoise_context *context, uint8_t *result, bool raw, uint32_t outputMultiplier) {
// check if data can be squeezed from the keccak spongr from previous state (or we need to collect some new entropy to get numBits >0)
if (context->numBits > 0u) {
// squeeze the sponge!
// Output up to 1024 bits at a time.
uint32_t bytesToWrite = 1024u / 8u;
if (bytesToWrite > context->numBits / 8u) {
bytesToWrite = context->numBits / 8u;
}
KeccakExtract(keccakState, result, bytesToWrite / 8u);
KeccakPermutation(keccakState);
context->bytesWritten += bytesToWrite;
context->numBits -= bytesToWrite * 8u;
return 1024/8u;
} else { // collect new entropy
uint8_t inBuf[BUFLEN];
struct timespec start;
clock_gettime(CLOCK_REALTIME, &start);
@@ -354,17 +357,19 @@ uint32_t readData(struct infnoise_context *context, uint8_t *result, bool raw, u
struct timespec end;
clock_gettime(CLOCK_REALTIME, &end);
uint32_t us = diffTime(&start, &end);
if (us <= MAX_MICROSEC_FOR_SAMPLES) {
uint8_t bytes[BUFLEN / 8u];
context->entropyThisTime = extractBytes(bytes, inBuf, &context->message, &context->errorFlag);
if (context->errorFlag) {
//fprintf(stderr, "ERROR1: %ul\n", context->entropyThisTime);
fprintf(stderr, "ERROR1: %ul\n", context->entropyThisTime);
return 0;
}
// call health check and return bytes if OK
if (inmHealthCheckOkToUseData() && inmEntropyOnTarget(context->entropyThisTime, BUFLEN)) {
return processBytes(bytes, result, &context->entropyThisTime, raw, outputMultiplier, &context->message,
&context->errorFlag);
return processBytes(bytes, result, &context->entropyThisTime, &context->numBits, &context->bytesWritten,
raw, outputMultiplier);
}
}
}
return 0;

View File

@@ -21,6 +21,10 @@ struct infnoise_context {
char *message;
bool errorFlag;
//uint8_t keccakState[KeccakPermutationSizeInBytes];
// used in multiplier mode to keep track of bytes to be put out
uint32_t numBits;
uint32_t bytesWritten;
};
struct infnoise_devlist_node {

View File

@@ -60,7 +60,7 @@ uint32_t extractBytes(uint8_t *bytes, uint8_t *inBuf, char **message, bool *erro
bool outputBytes(uint8_t *bytes, uint32_t length, uint32_t entropy, bool writeDevRandom, char **message);
uint32_t processBytes(uint8_t *bytes, uint8_t *result, uint32_t *entropy, bool raw,
uint32_t outputMultiplier, char **message, bool *errorFlag);
uint32_t processBytes(uint8_t *bytes, uint8_t *result, uint32_t *entropy, uint32_t *numBits, uint32_t *bytesWritten, bool raw,
uint32_t outputMultiplier);
//uint32_t readData_private(struct infnoise_context *context, uint8_t *result, char **message, bool *errorFlag, bool noOutput, bool raw, uint32_t outputMultiplier, bool devRandom);