[PATCH 4/5] Add timingsafe_memcmp()
Sebastian Huber
sebastian.huber at embedded-brains.de
Fri Mar 18 10:49:27 UTC 2016
This function is used by LibreSSL and OpenSSH and is provided by the
OpenBSD libc.
* libc/include/string.h (timingsafe_memcmp): Declare.
* libc/string/timingsafe_memcmp.c: New file.
* libc/string/Makefile.am: Add new file.
* libc/string/Makefile.in: Regenerate.
---
newlib/libc/include/string.h | 1 +
newlib/libc/string/Makefile.am | 1 +
newlib/libc/string/Makefile.in | 44 +++++++++++++++++++-------------
newlib/libc/string/timingsafe_memcmp.c | 46 ++++++++++++++++++++++++++++++++++
4 files changed, 74 insertions(+), 18 deletions(-)
create mode 100644 newlib/libc/string/timingsafe_memcmp.c
diff --git a/newlib/libc/include/string.h b/newlib/libc/include/string.h
index 2bda8f9..68ee412 100644
--- a/newlib/libc/include/string.h
+++ b/newlib/libc/include/string.h
@@ -54,6 +54,7 @@ void _EXFUN(bzero,(void *, size_t));
#if __BSD_VISIBLE
void _EXFUN(explicit_bzero,(void *, size_t));
int _EXFUN(timingsafe_bcmp,(const void *, const void *, size_t));
+int _EXFUN(timingsafe_memcmp,(const void *, const void *, size_t));
#endif
#if __MISC_VISIBLE || __POSIX_VISIBLE >= 200809
int _EXFUN(ffs,(int));
diff --git a/newlib/libc/string/Makefile.am b/newlib/libc/string/Makefile.am
index c227bbd..1c047f5 100644
--- a/newlib/libc/string/Makefile.am
+++ b/newlib/libc/string/Makefile.am
@@ -47,6 +47,7 @@ GENERAL_SOURCES = \
strstr.c \
swab.c \
timingsafe_bcmp.c \
+ timingsafe_memcmp.c \
u_strerr.c \
wcscat.c \
wcschr.c \
diff --git a/newlib/libc/string/Makefile.in b/newlib/libc/string/Makefile.in
index 1db7f0e..4d42c90 100644
--- a/newlib/libc/string/Makefile.in
+++ b/newlib/libc/string/Makefile.in
@@ -93,20 +93,21 @@ am__objects_1 = lib_a-bcopy.$(OBJEXT) lib_a-bzero.$(OBJEXT) \
lib_a-strtok_r.$(OBJEXT) lib_a-strupr.$(OBJEXT) \
lib_a-strxfrm.$(OBJEXT) lib_a-strstr.$(OBJEXT) \
lib_a-swab.$(OBJEXT) lib_a-timingsafe_bcmp.$(OBJEXT) \
- lib_a-u_strerr.$(OBJEXT) lib_a-wcscat.$(OBJEXT) \
- lib_a-wcschr.$(OBJEXT) lib_a-wcscmp.$(OBJEXT) \
- lib_a-wcscoll.$(OBJEXT) lib_a-wcscpy.$(OBJEXT) \
- lib_a-wcscspn.$(OBJEXT) lib_a-wcslcat.$(OBJEXT) \
- lib_a-wcslcpy.$(OBJEXT) lib_a-wcslen.$(OBJEXT) \
- lib_a-wcsncat.$(OBJEXT) lib_a-wcsncmp.$(OBJEXT) \
- lib_a-wcsncpy.$(OBJEXT) lib_a-wcsnlen.$(OBJEXT) \
- lib_a-wcspbrk.$(OBJEXT) lib_a-wcsrchr.$(OBJEXT) \
- lib_a-wcsspn.$(OBJEXT) lib_a-wcsstr.$(OBJEXT) \
- lib_a-wcstok.$(OBJEXT) lib_a-wcswidth.$(OBJEXT) \
- lib_a-wcsxfrm.$(OBJEXT) lib_a-wcwidth.$(OBJEXT) \
- lib_a-wmemchr.$(OBJEXT) lib_a-wmemcmp.$(OBJEXT) \
- lib_a-wmemcpy.$(OBJEXT) lib_a-wmemmove.$(OBJEXT) \
- lib_a-wmemset.$(OBJEXT) lib_a-xpg_strerror_r.$(OBJEXT)
+ lib_a-timingsafe_memcmp.$(OBJEXT) lib_a-u_strerr.$(OBJEXT) \
+ lib_a-wcscat.$(OBJEXT) lib_a-wcschr.$(OBJEXT) \
+ lib_a-wcscmp.$(OBJEXT) lib_a-wcscoll.$(OBJEXT) \
+ lib_a-wcscpy.$(OBJEXT) lib_a-wcscspn.$(OBJEXT) \
+ lib_a-wcslcat.$(OBJEXT) lib_a-wcslcpy.$(OBJEXT) \
+ lib_a-wcslen.$(OBJEXT) lib_a-wcsncat.$(OBJEXT) \
+ lib_a-wcsncmp.$(OBJEXT) lib_a-wcsncpy.$(OBJEXT) \
+ lib_a-wcsnlen.$(OBJEXT) lib_a-wcspbrk.$(OBJEXT) \
+ lib_a-wcsrchr.$(OBJEXT) lib_a-wcsspn.$(OBJEXT) \
+ lib_a-wcsstr.$(OBJEXT) lib_a-wcstok.$(OBJEXT) \
+ lib_a-wcswidth.$(OBJEXT) lib_a-wcsxfrm.$(OBJEXT) \
+ lib_a-wcwidth.$(OBJEXT) lib_a-wmemchr.$(OBJEXT) \
+ lib_a-wmemcmp.$(OBJEXT) lib_a-wmemcpy.$(OBJEXT) \
+ lib_a-wmemmove.$(OBJEXT) lib_a-wmemset.$(OBJEXT) \
+ lib_a-xpg_strerror_r.$(OBJEXT)
@ELIX_LEVEL_1_FALSE at am__objects_2 = lib_a-bcmp.$(OBJEXT) \
@ELIX_LEVEL_1_FALSE@ lib_a-memccpy.$(OBJEXT) \
@ELIX_LEVEL_1_FALSE@ lib_a-mempcpy.$(OBJEXT) \
@@ -138,10 +139,10 @@ am__objects_4 = bcopy.lo bzero.lo explicit_bzero.lo index.lo memchr.lo \
strncasecmp.lo strncat.lo strncmp.lo strncpy.lo strnlen.lo \
strpbrk.lo strrchr.lo strsep.lo strsignal.lo strspn.lo \
strtok.lo strtok_r.lo strupr.lo strxfrm.lo strstr.lo swab.lo \
- timingsafe_bcmp.lo u_strerr.lo wcscat.lo wcschr.lo wcscmp.lo \
- wcscoll.lo wcscpy.lo wcscspn.lo wcslcat.lo wcslcpy.lo \
- wcslen.lo wcsncat.lo wcsncmp.lo wcsncpy.lo wcsnlen.lo \
- wcspbrk.lo wcsrchr.lo wcsspn.lo wcsstr.lo wcstok.lo \
+ timingsafe_bcmp.lo timingsafe_memcmp.lo u_strerr.lo wcscat.lo \
+ wcschr.lo wcscmp.lo wcscoll.lo wcscpy.lo wcscspn.lo wcslcat.lo \
+ wcslcpy.lo wcslen.lo wcsncat.lo wcsncmp.lo wcsncpy.lo \
+ wcsnlen.lo wcspbrk.lo wcsrchr.lo wcsspn.lo wcsstr.lo wcstok.lo \
wcswidth.lo wcsxfrm.lo wcwidth.lo wmemchr.lo wmemcmp.lo \
wmemcpy.lo wmemmove.lo wmemset.lo xpg_strerror_r.lo
@ELIX_LEVEL_1_FALSE at am__objects_5 = bcmp.lo memccpy.lo mempcpy.lo \
@@ -371,6 +372,7 @@ GENERAL_SOURCES = \
strstr.c \
swab.c \
timingsafe_bcmp.c \
+ timingsafe_memcmp.c \
u_strerr.c \
wcscat.c \
wcschr.c \
@@ -781,6 +783,12 @@ lib_a-timingsafe_bcmp.o: timingsafe_bcmp.c
lib_a-timingsafe_bcmp.obj: timingsafe_bcmp.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-timingsafe_bcmp.obj `if test -f 'timingsafe_bcmp.c'; then $(CYGPATH_W) 'timingsafe_bcmp.c'; else $(CYGPATH_W) '$(srcdir)/timingsafe_bcmp.c'; fi`
+lib_a-timingsafe_memcmp.o: timingsafe_memcmp.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-timingsafe_memcmp.o `test -f 'timingsafe_memcmp.c' || echo '$(srcdir)/'`timingsafe_memcmp.c
+
+lib_a-timingsafe_memcmp.obj: timingsafe_memcmp.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-timingsafe_memcmp.obj `if test -f 'timingsafe_memcmp.c'; then $(CYGPATH_W) 'timingsafe_memcmp.c'; else $(CYGPATH_W) '$(srcdir)/timingsafe_memcmp.c'; fi`
+
lib_a-u_strerr.o: u_strerr.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-u_strerr.o `test -f 'u_strerr.c' || echo '$(srcdir)/'`u_strerr.c
diff --git a/newlib/libc/string/timingsafe_memcmp.c b/newlib/libc/string/timingsafe_memcmp.c
new file mode 100644
index 0000000..04e2ac5
--- /dev/null
+++ b/newlib/libc/string/timingsafe_memcmp.c
@@ -0,0 +1,46 @@
+/* $OpenBSD: timingsafe_memcmp.c,v 1.1 2014/06/13 02:12:17 matthew Exp $ */
+/*
+ * Copyright (c) 2014 Google Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <limits.h>
+#include <string.h>
+
+int
+timingsafe_memcmp(const void *b1, const void *b2, size_t len)
+{
+ const unsigned char *p1 = b1, *p2 = b2;
+ size_t i;
+ int res = 0, done = 0;
+
+ for (i = 0; i < len; i++) {
+ /* lt is -1 if p1[i] < p2[i]; else 0. */
+ int lt = (p1[i] - p2[i]) >> CHAR_BIT;
+
+ /* gt is -1 if p1[i] > p2[i]; else 0. */
+ int gt = (p2[i] - p1[i]) >> CHAR_BIT;
+
+ /* cmp is 1 if p1[i] > p2[i]; -1 if p1[i] < p2[i]; else 0. */
+ int cmp = lt - gt;
+
+ /* set res = cmp if !done. */
+ res |= cmp & ~done;
+
+ /* set done if p1[i] != p2[i]. */
+ done |= lt | gt;
+ }
+
+ return (res);
+}
--
1.8.4.5
More information about the devel
mailing list