Moved processBytes() closer to readData(), as only readData() is using this function
This commit is contained in:
@@ -120,73 +120,6 @@ uint32_t extractBytes(uint8_t *bytes, uint32_t length, uint8_t *inBuf, const cha
|
||||
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.
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// 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) {
|
||||
// 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) {
|
||||
|
||||
Reference in New Issue
Block a user