utils: Add a constant time memeq() variant for cryptographic purposes

This commit is contained in:
Martin Willi
2015-04-14 11:51:54 +02:00
parent 39e1ddec2e
commit b833963270
4 changed files with 79 additions and 1 deletions
@@ -306,6 +306,48 @@ START_TEST(test_memxor_aligned)
}
END_TEST
/*******************************************************************************
* memeq/const
*/
static struct {
char *a;
char *b;
size_t n;
bool res;
} memeq_data[] = {
{NULL, NULL, 0, TRUE},
{"a", "b", 0, TRUE},
{"", "", 1, TRUE},
{"abcdefgh", "abcdefgh", 8, TRUE},
{"a", "b", 1, FALSE},
{"A", "a", 1, FALSE},
{"\0a", "\0b", 2, FALSE},
{"abc", "abd", 3, FALSE},
{"abc", "dbd", 3, FALSE},
{"abcdefgh", "abcdffgh", 8, FALSE},
{"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", 52, TRUE},
{"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyy", 52, FALSE},
{"bbcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", 52, FALSE},
};
START_TEST(test_memeq)
{
ck_assert(memeq(memeq_data[_i].a, memeq_data[_i].b,
memeq_data[_i].n) == memeq_data[_i].res);
}
END_TEST
START_TEST(test_memeq_const)
{
ck_assert(memeq_const(memeq_data[_i].a, memeq_data[_i].b,
memeq_data[_i].n) == memeq_data[_i].res);
}
END_TEST
/*******************************************************************************
* memstr
*/
@@ -779,6 +821,11 @@ Suite *utils_suite_create()
tcase_add_test(tc, test_memxor_aligned);
suite_add_tcase(s, tc);
tc = tcase_create("memeq");
tcase_add_loop_test(tc, test_memeq, 0, countof(memeq_data));
tcase_add_loop_test(tc, test_memeq_const, 0, countof(memeq_data));
suite_add_tcase(s, tc);
tc = tcase_create("memstr");
tcase_add_loop_test(tc, test_memstr, 0, countof(memstr_data));
suite_add_tcase(s, tc);
+19
View File
@@ -109,6 +109,25 @@ void memwipe_noinline(void *ptr, size_t n)
memwipe_inline(ptr, n);
}
/**
* Described in header.
*/
bool memeq_const(const void *x, const void *y, size_t len)
{
const u_char *a, *b;
u_int bad = 0;
size_t i;
a = (const u_char*)x;
b = (const u_char*)y;
for (i = 0; i < len; i++)
{
bad |= a[i] != b[i];
}
return !bad;
}
/**
* Described in header.
*/
+5
View File
@@ -184,6 +184,11 @@ static inline bool memeq(const void *x, const void *y, size_t len)
return memcmp(x, y, len) == 0;
}
/**
* Same as memeq(), but with a constant runtime, safe for cryptographic use.
*/
bool memeq_const(const void *x, const void *y, size_t len);
/**
* Calling memcpy() with NULL pointers, even with n == 0, results in undefined
* behavior according to the C standard. This version is guaranteed to not