hash_len = generate_auth(key, data, data_len, buf, sizeof (buf));
- return MIN(hash_len, trunc_len) == auth_len && !memcmp(buf, auth, auth_len);
+ return MIN(hash_len, trunc_len) == auth_len && UTI_IsMemoryEqual(buf, auth, auth_len);
}
/* ================================================== */
*/
#include <config.h>
+#include <local.h>
#include "test.h"
#include <keys.c>
#define KEYS 100
#define KEYFILE "keys.test-keys"
+#define MIN_TIMING_INTERVAL 1.0e-3
static
uint32_t write_random_key(FILE *f)
void
test_unit(void)
{
- int i, j, data_len, auth_len, type, bits;
+ int i, j, data_len, auth_len, type, bits, s, timing_fails, timing_iters;
uint32_t keys[KEYS], key;
- unsigned char data[100], auth[MAX_HASH_LENGTH];
+ unsigned char data[100], auth[MAX_HASH_LENGTH], auth2[MAX_HASH_LENGTH];
+ struct timespec ts1, ts2;
+ double diff1, diff2;
char conf[][100] = {
"keyfile "KEYFILE
};
CNF_Initialise(0, 0);
for (i = 0; i < sizeof conf / sizeof conf[0]; i++)
CNF_ParseLine(NULL, i + 1, conf[i]);
+ LCL_Initialise();
generate_key_file(KEYFILE, keys);
KEY_Initialise();
}
}
+ if (!getenv("NO_TIMING_TESTS") &&
+ LCL_GetSysPrecisionAsQuantum() < MIN_TIMING_INTERVAL / 100.0) {
+ auth_len = sizeof (auth);
+ UTI_GetRandomBytes(auth, auth_len);
+ memcpy(auth2, auth, auth_len);
+
+ timing_fails = 0;
+ timing_iters = 1000;
+
+ i = 0;
+ for (i = 0; i < 100; i++) {
+ int d = random() % 2;
+
+ auth2[0] = auth[0] + d;
+
+ for (j = s = 0; j < timing_iters; j++) {
+ if (j == 100)
+ LCL_ReadRawTime(&ts1);
+ s += UTI_IsMemoryEqual(auth, auth2, auth_len);
+ }
+ LCL_ReadRawTime(&ts2);
+ TEST_CHECK(s == (d + 1) % 2 * timing_iters);
+ diff1 = UTI_DiffTimespecsToDouble(&ts2, &ts1);
+
+ auth2[0] = auth[0] + (d + 1) % 2;
+
+ for (j = s = 0; j < timing_iters; j++) {
+ if (j == 100)
+ LCL_ReadRawTime(&ts1);
+ s += UTI_IsMemoryEqual(auth, auth2, auth_len);
+ }
+ LCL_ReadRawTime(&ts2);
+ TEST_CHECK(s == d * timing_iters);
+ diff2 = UTI_DiffTimespecsToDouble(&ts2, &ts1);
+
+ DEBUG_LOG("d=%d diff1=%e diff2=%e iters=%d", d, diff1, diff2, timing_iters);
+
+ if (diff1 < MIN_TIMING_INTERVAL && diff2 < MIN_TIMING_INTERVAL) {
+ if (timing_iters >= INT_MAX / 2)
+ break;
+ timing_iters *= 2;
+ i--;
+ continue;
+ }
+
+ if ((d == 0 && 0.8 * diff1 > diff2) || (d == 1 && diff1 < 0.8 * diff2))
+ timing_fails++;
+ }
+
+ DEBUG_LOG("timing fails %d/%d", timing_fails, i);
+ TEST_CHECK(timing_fails < i / 2);
+ }
+
unlink(KEYFILE);
KEY_Finalise();
+ LCL_Finalise();
CNF_Finalise();
HSH_Finalise();
}