diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/libstrongswan/tests/suites/test_utils.c | 47 | ||||
| -rw-r--r-- | src/libstrongswan/utils/utils.c | 19 | ||||
| -rw-r--r-- | src/libstrongswan/utils/utils.h | 5 |
3 files changed, 71 insertions, 0 deletions
diff --git a/src/libstrongswan/tests/suites/test_utils.c b/src/libstrongswan/tests/suites/test_utils.c index 85a854456..f151fb35e 100644 --- a/src/libstrongswan/tests/suites/test_utils.c +++ b/src/libstrongswan/tests/suites/test_utils.c @@ -307,6 +307,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); diff --git a/src/libstrongswan/utils/utils.c b/src/libstrongswan/utils/utils.c index 02a720945..3d5e3dfc9 100644 --- a/src/libstrongswan/utils/utils.c +++ b/src/libstrongswan/utils/utils.c @@ -112,6 +112,25 @@ void memwipe_noinline(void *ptr, size_t 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. + */ void *memstr(const void *haystack, const char *needle, size_t n) { const u_char *pos = haystack; diff --git a/src/libstrongswan/utils/utils.h b/src/libstrongswan/utils/utils.h index 7c48d949f..2675acae8 100644 --- a/src/libstrongswan/utils/utils.h +++ b/src/libstrongswan/utils/utils.h @@ -185,6 +185,11 @@ static inline bool memeq(const void *x, const void *y, size_t len) } /** + * 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 * access the pointers if n is 0. |
