HASH_OBJ="hash_nettle.o"
HASH_LINK="$test_link"
MYCPPFLAGS="$MYCPPFLAGS $test_cflags"
+ add_def HAVE_NETTLE
add_def FEAT_SECHASH
if test_code 'CMAC in nettle' 'nettle/cmac.h' "$test_cflags" "$test_link" \
HASH_OBJ="hash_gnutls.o"
HASH_LINK="$test_link"
MYCPPFLAGS="$MYCPPFLAGS $test_cflags"
+ add_def HAVE_GNUTLS
add_def FEAT_SECHASH
if test_code 'CMAC in gnutls' 'gnutls/crypto.h' "$test_cflags" "$test_link" \
void
test_unit(void)
{
+ char buf[16], buf2[16], *s, *s2, *words[3];
struct timespec ts, ts2, ts3, ts4;
- char buf[16], *s, *s2, *words[3];
NTP_int64 ntp_ts, ntp_ts2, ntp_fuzz;
NTP_int32 ntp32_ts;
struct timeval tv;
TEST_CHECK(strcmp(words[0], "a") == 0);
TEST_CHECK(strcmp(words[1], "b") == 0);
+ for (i = 0; i < 1000; i++) {
+ UTI_GetRandomBytes(buf, sizeof (buf));
+ memcpy(buf2, buf, sizeof (buf));
+ for (j = 0; j < sizeof (buf); j++)
+ TEST_CHECK(UTI_IsMemoryEqual(buf, buf2, j));
+
+ for (j = 0; j < 8 * sizeof (buf); j++) {
+ buf2[j / 8] ^= 1U << j % 8;
+ TEST_CHECK(!UTI_IsMemoryEqual(buf, buf2, sizeof (buf)));
+ buf2[j / 8] ^= 1U << j % 8;
+ TEST_CHECK(UTI_IsMemoryEqual(buf, buf2, sizeof (buf)));
+ }
+ }
+
HSH_Finalise();
}
#include "sysincl.h"
+#if defined(HAVE_NETTLE)
+#include <nettle/memops.h>
+#elif defined(HAVE_GNUTLS)
+#include <gnutls/gnutls.h>
+#endif
+
#include "logging.h"
#include "memory.h"
#include "util.h"
return i;
}
+
+/* ================================================== */
+
+int
+UTI_IsMemoryEqual(const void *s1, const void *s2, unsigned int len)
+{
+#if defined(HAVE_NETTLE)
+ return nettle_memeql_sec(s1, s2, len);
+#elif defined(HAVE_GNUTLS)
+ return gnutls_memcmp(s1, s2, len) == 0;
+#else
+ unsigned int i, x;
+
+ for (i = 0, x = 0; i < len; i++)
+ x |= ((const unsigned char *)s1)[i] ^ ((const unsigned char *)s2)[i];
+
+ return x == 0;
+#endif
+}
number of pointers to the words. */
extern int UTI_SplitString(char *string, char **words, int max_saved_words);
+/* Check if two buffers of the same length contain the same data, but do the
+ comparison in constant time with respect to the returned value to avoid
+ creating a timing side channel */
+extern int UTI_IsMemoryEqual(const void *s1, const void *s2, unsigned int len);
+
/* Macros to get maximum and minimum of two values */
#ifdef MAX
#undef MAX