Moved processBytes() closer to readData(), as only readData() is using this function

This commit is contained in:
Patrick Siegl
2020-04-15 18:23:02 +02:00
parent e77e1b7810
commit 4a09610d50

View File

@@ -120,73 +120,6 @@ uint32_t extractBytes(uint8_t *bytes, uint32_t length, uint8_t *inBuf, const cha
return inmGetEntropyLevel(); return inmGetEntropyLevel();
} }
// Whiten the output, if requested, with a Keccak sponge. Output bytes only if the health
// checker says it's OK. Using outputMultiplier > 1 is a nice way to generate a lot more
// cryptographically secure pseudo-random data than the INM generates. If
// 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
// as cryptographic keys.
uint32_t processBytes(uint8_t *bytes, uint8_t *result, uint32_t *entropy,
uint32_t *bytesGiven, 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) {
*entropy = inmExpectedEntropyPerBit * BUFLEN / INM_ACCURACY;
}
if (raw) {
// In raw mode, we just output raw data from the INM.
if (result != NULL) {
memcpy(result, bytes, BUFLEN / 8u * sizeof(uint8_t));
}
return BUFLEN / 8u;
}
// Note that BUFLEN has to be less than 1600 by enough to make the sponge secure,
// since outputting all 1600 bits would tell an attacker the Keccak state, allowing
// him to predict any further output, when outputMultiplier > 1, until the next call
// to processBytes. All 512 bits are absorbed before squeezing data out to ensure that
// 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 resultSize;
if (outputMultiplier <= 2) {
resultSize = 64u;
} else {
resultSize = 128u;
}
uint8_t dataOut[resultSize];
KeccakAbsorb(keccakState, bytes, BUFLEN / 64u);
if (outputMultiplier == 0u) {
// 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 (in chunks of 1024)
// only the first 1024 now,
if (*bytesGiven == 0u) {
*bytesGiven = outputMultiplier*256u / 8u;
*bytesWritten = 0u;
// Output up to 1024 bits at a time.
uint32_t bytesToWrite = 1024u / 8u;
if (bytesToWrite > *bytesGiven) {
bytesToWrite = *bytesGiven;
}
KeccakExtract(keccakState, result, bytesToWrite / 8u);
KeccakPermutation(keccakState);
*bytesWritten = bytesToWrite;
*bytesGiven -= bytesToWrite;
}
return *bytesWritten;
}
// Return the difference in the times as a double in microseconds. // Return the difference in the times as a double in microseconds.
double diffTime(struct timespec *start, struct timespec *end) { double diffTime(struct timespec *start, struct timespec *end) {
@@ -351,6 +284,75 @@ bool initializeUSB(struct ftdi_context *ftdic, const char **message, char *seria
return true; return true;
} }
// Whiten the output, if requested, with a Keccak sponge. Output bytes only if the health
// checker says it's OK. Using outputMultiplier > 1 is a nice way to generate a lot more
// cryptographically secure pseudo-random data than the INM generates. If
// 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
// as cryptographic keys.
uint32_t processBytes(uint8_t *bytes, uint8_t *result, uint32_t *entropy,
uint32_t *bytesGiven, 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) {
*entropy = inmExpectedEntropyPerBit * BUFLEN / INM_ACCURACY;
}
if (raw) {
// In raw mode, we just output raw data from the INM.
if (result != NULL) {
memcpy(result, bytes, BUFLEN / 8u * sizeof(uint8_t));
}
return BUFLEN / 8u;
}
// Note that BUFLEN has to be less than 1600 by enough to make the sponge secure,
// since outputting all 1600 bits would tell an attacker the Keccak state, allowing
// him to predict any further output, when outputMultiplier > 1, until the next call
// to processBytes. All 512 bits are absorbed before squeezing data out to ensure that
// 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 resultSize;
if (outputMultiplier <= 2) {
resultSize = 64u;
} else {
resultSize = 128u;
}
uint8_t dataOut[resultSize];
KeccakAbsorb(keccakState, bytes, BUFLEN / 64u);
if (outputMultiplier == 0u) {
// 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 (in chunks of 1024)
// only the first 1024 now,
if (*bytesGiven == 0u) {
*bytesGiven = outputMultiplier*256u / 8u;
*bytesWritten = 0u;
// Output up to 1024 bits at a time.
uint32_t bytesToWrite = 1024u / 8u;
if (bytesToWrite > *bytesGiven) {
bytesToWrite = *bytesGiven;
}
KeccakExtract(keccakState, result, bytesToWrite / 8u);
KeccakPermutation(keccakState);
*bytesWritten = bytesToWrite;
*bytesGiven -= bytesToWrite;
}
return *bytesWritten;
}
uint32_t readData(struct infnoise_context *context, uint8_t *result, bool raw, uint32_t outputMultiplier) { uint32_t readData(struct infnoise_context *context, uint8_t *result, bool raw, uint32_t outputMultiplier) {
// check if data can be squeezed from the keccak sponge from previous state (or we need to collect some new entropy to get bytesGiven >0) // check if data can be squeezed from the keccak sponge from previous state (or we need to collect some new entropy to get bytesGiven >0)
if (context->bytesGiven > 0u) { if (context->bytesGiven > 0u) {