+3611. [bug] Improved resistance to a theoretical authentication
+ attack based on differential timing. [RT #33939]
+
3608. [port] win32: added todos.pl script to ensure all text files
the win32 build depends on are converted to DOS
newline format. [RT #22067]
ETAGS
LN
ARFLAGS
+CCNOOPT
CCOPT
STD_CWARNINGS
STD_CDEFINES
+
# Warn if the user specified libbind, which is now deprecated
# Check whether --enable-libbind was given.
if test "${enable_libbind+set}" = set; then :
;;
esac
+#
+# CCNOOPT defaults to -O0 on gcc and disables optimization when is last
+#
+if test "X$CCNOOPT" = "X" -a "X$GCC" = "Xyes"; then
+ CCNOOPT="-O0"
+fi
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
$as_echo_n "checking for ANSI C header files... " >&6; }
if ${ac_cv_header_stdc+:} false; then :
*-freebsd*)
CC="$CC -pthread"
CCOPT="$CCOPT -pthread"
+ CCNOOPT="$CCNOOPT -pthread"
STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE"
;;
*-openbsd*)
CC="$CC -pthread"
CCOPT="$CCOPT -pthread"
+ CCNOOPT="$CCNOOPT -pthread"
;;
*-solaris*)
LIBS="$LIBS -lthread"
*-dec-osf*)
CC="$CC -pthread"
CCOPT="$CCOPT -pthread"
+ CCNOOPT="$CCNOOPT -pthread"
;;
*-solaris*)
CC="$CC -mt"
CCOPT="$CCOPT -mt"
+ CCNOOPT="$CCNOOPT -mt"
;;
*-ibm-aix*)
STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE"
*-sco-sysv*uw*|*-*-sysv*UnixWare*)
CC="$CC -Kthread"
CCOPT="$CCOPT -Kthread"
+ CCNOOPT="$CCNOOPT -Kthread"
;;
*-*-sysv*OpenUNIX*)
CC="$CC -Kpthread"
CCOPT="$CCOPT -Kpthread"
+ CCNOOPT="$CCNOOPT -Kpthread"
;;
esac
fi
*-dec-osf*)
CC="$CC -std"
CCOPT="$CCOPT -std"
+ CCNOOPT="$CCNOOPT -std"
MKDEPCC="$CC"
;;
*-hp-hpux*)
;;
esac
CCOPT="$CCOPT -Ae -z"
+ CCNOOPT="$CCNOOPT -Ae -z"
LDFLAGS="-Wl,+vnocompatwarnings $LDFLAGS"
MKDEPPROG='cc -Ae -E -Wp,-M >/dev/null 2>>$TMP'
;;
AC_SUBST(STD_CDEFINES)
AC_SUBST(STD_CWARNINGS)
AC_SUBST(CCOPT)
+AC_SUBST(CCNOOPT)
# Warn if the user specified libbind, which is now deprecated
AC_ARG_ENABLE(libbind, [ --enable-libbind deprecated])
;;
esac
+#
+# CCNOOPT defaults to -O0 on gcc and disables optimization when is last
+#
+if test "X$CCNOOPT" = "X" -a "X$GCC" = "Xyes"; then
+ CCNOOPT="-O0"
+fi
+
AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h sys/time.h unistd.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h,,,
*-freebsd*)
CC="$CC -pthread"
CCOPT="$CCOPT -pthread"
+ CCNOOPT="$CCNOOPT -pthread"
STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE"
;;
*-openbsd*)
CC="$CC -pthread"
CCOPT="$CCOPT -pthread"
+ CCNOOPT="$CCNOOPT -pthread"
;;
*-solaris*)
LIBS="$LIBS -lthread"
*-dec-osf*)
CC="$CC -pthread"
CCOPT="$CCOPT -pthread"
+ CCNOOPT="$CCNOOPT -pthread"
;;
*-solaris*)
CC="$CC -mt"
CCOPT="$CCOPT -mt"
+ CCNOOPT="$CCNOOPT -mt"
;;
*-ibm-aix*)
STD_CDEFINES="$STD_CDEFINES -D_THREAD_SAFE"
*-sco-sysv*uw*|*-*-sysv*UnixWare*)
CC="$CC -Kthread"
CCOPT="$CCOPT -Kthread"
+ CCNOOPT="$CCNOOPT -Kthread"
;;
*-*-sysv*OpenUNIX*)
CC="$CC -Kpthread"
CCOPT="$CCOPT -Kpthread"
+ CCNOOPT="$CCNOOPT -Kpthread"
;;
esac
fi
*-dec-osf*)
CC="$CC -std"
CCOPT="$CCOPT -std"
+ CCNOOPT="$CCNOOPT -std"
MKDEPCC="$CC"
;;
*-hp-hpux*)
;;
esac
CCOPT="$CCOPT -Ae -z"
+ CCNOOPT="$CCNOOPT -Ae -z"
LDFLAGS="-Wl,+vnocompatwarnings $LDFLAGS"
MKDEPPROG='cc -Ae -E -Wp,-M >/dev/null 2>>$TMP'
;;
#include <isc/md5.h>
#include <isc/sha1.h>
#include <isc/mem.h>
+#include <isc/safe.h>
#include <isc/string.h>
#include <isc/util.h>
else if (hkey1 == NULL || hkey2 == NULL)
return (ISC_FALSE);
- if (memcmp(hkey1->key, hkey2->key, HMAC_LEN) == 0)
+ if (isc_safe_memcmp(hkey1->key, hkey2->key, HMAC_LEN))
return (ISC_TRUE);
else
return (ISC_FALSE);
else if (hkey1 == NULL || hkey2 == NULL)
return (ISC_FALSE);
- if (memcmp(hkey1->key, hkey2->key, ISC_SHA1_DIGESTLENGTH) == 0)
+ if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA1_DIGESTLENGTH))
return (ISC_TRUE);
else
return (ISC_FALSE);
else if (hkey1 == NULL || hkey2 == NULL)
return (ISC_FALSE);
- if (memcmp(hkey1->key, hkey2->key, ISC_SHA224_DIGESTLENGTH) == 0)
+ if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA224_DIGESTLENGTH))
return (ISC_TRUE);
else
return (ISC_FALSE);
else if (hkey1 == NULL || hkey2 == NULL)
return (ISC_FALSE);
- if (memcmp(hkey1->key, hkey2->key, ISC_SHA256_DIGESTLENGTH) == 0)
+ if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA256_DIGESTLENGTH))
return (ISC_TRUE);
else
return (ISC_FALSE);
else if (hkey1 == NULL || hkey2 == NULL)
return (ISC_FALSE);
- if (memcmp(hkey1->key, hkey2->key, ISC_SHA384_DIGESTLENGTH) == 0)
+ if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA384_DIGESTLENGTH))
return (ISC_TRUE);
else
return (ISC_FALSE);
else if (hkey1 == NULL || hkey2 == NULL)
return (ISC_FALSE);
- if (memcmp(hkey1->key, hkey2->key, ISC_SHA512_DIGESTLENGTH) == 0)
+ if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA512_DIGESTLENGTH))
return (ISC_TRUE);
else
return (ISC_FALSE);
netaddr.@O@ netscope.@O@ ondestroy.@O@ \
parseint.@O@ portset.@O@ quota.@O@ radix.@O@ random.@O@ \
ratelimiter.@O@ refcount.@O@ region.@O@ result.@O@ rwlock.@O@ \
- serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ \
+ safe.@O@ serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ \
string.@O@ strtoul.@O@ symtab.@O@ task.@O@ taskpool.@O@ \
timer.@O@ version.@O@ ${UNIXOBJS} ${NLSOBJS} ${THREADOBJS}
netaddr.c netscope.c ondestroy.c \
parseint.c portset.c quota.c radix.c random.c \
ratelimiter.c refcount.c region.c result.c rwlock.c \
- serial.c sha1.c sha2.c sockaddr.c stats.c string.c strtoul.c \
- symtab.c task.c taskpool.c timer.c version.c
+ safe.c serial.c sha1.c sha2.c sockaddr.c stats.c \
+ string.c strtoul.c symtab.c \
+ task.c taskpool.c timer.c version.c
LIBS = @LIBS@
@BIND9_MAKE_RULES@
+safe.@O@: safe.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} @CCNOOPT@ \
+ -c ${srcdir}/safe.c
+
version.@O@: version.c
${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
-DVERSION=\"${VERSION}\" \
#include <isc/assertions.h>
#include <isc/hmacmd5.h>
#include <isc/md5.h>
+#include <isc/safe.h>
#include <isc/string.h>
#include <isc/types.h>
#include <isc/util.h>
REQUIRE(len <= ISC_MD5_DIGESTLENGTH);
isc_hmacmd5_sign(ctx, newdigest);
- return (ISC_TF(memcmp(digest, newdigest, len) == 0));
+ return (isc_safe_memcmp(digest, newdigest, len));
}
#include <isc/assertions.h>
#include <isc/hmacsha.h>
+#include <isc/safe.h>
#include <isc/sha1.h>
#include <isc/sha2.h>
#include <isc/string.h>
REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
- return (ISC_TF(memcmp(digest, newdigest, len) == 0));
+ return (isc_safe_memcmp(digest, newdigest, len));
}
/*
REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
- return (ISC_TF(memcmp(digest, newdigest, len) == 0));
+ return (isc_safe_memcmp(digest, newdigest, len));
}
/*
REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
- return (ISC_TF(memcmp(digest, newdigest, len) == 0));
+ return (isc_safe_memcmp(digest, newdigest, len));
}
/*
REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
- return (ISC_TF(memcmp(digest, newdigest, len) == 0));
+ return (isc_safe_memcmp(digest, newdigest, len));
}
/*
REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
- return (ISC_TF(memcmp(digest, newdigest, len) == 0));
+ return (isc_safe_memcmp(digest, newdigest, len));
}
mutexblock.h netaddr.h ondestroy.h os.h parseint.h \
print.h quota.h radix.h random.h ratelimiter.h \
refcount.h region.h resource.h \
- result.h resultclass.h rwlock.h serial.h sha1.h sha2.h \
- sockaddr.h socket.h stdio.h stdlib.h string.h \
- symtab.h \
+ result.h resultclass.h rwlock.h \
+ safe.h serial.h sha1.h sha2.h \
+ sockaddr.h socket.h stdio.h stdlib.h string.h symtab.h \
task.h taskpool.h timer.h types.h util.h version.h \
xml.h
--- /dev/null
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC 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.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_SAFE_H
+#define ISC_SAFE_H 1
+
+/*! \file isc/safe.h */
+
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+isc_boolean_t
+isc_safe_memcmp(const void *s1, const void *s2, size_t n);
+/*%<
+ * Clone of libc memcmp() safe to differential timing attacks.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_SAFE_H */
--- /dev/null
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC 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.
+ */
+
+/* $Id$ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <isc/safe.h>
+#include <isc/util.h>
+
+#ifdef _MSC_VER
+#pragma optimize("", off)
+#endif
+
+isc_boolean_t
+isc_safe_memcmp(const void *s1, const void *s2, size_t n) {
+ isc_uint8_t acc = 0;
+
+ if (n != 0) {
+ const isc_uint8_t *p1 = s1, *p2 = s2;
+
+ do {
+ acc |= *p1++ ^ *p2++;
+ } while (--n != 0);
+ }
+ return (ISC_TF(acc == 0));
+}
OBJS = isctest.@O@
-SRCS = isctest.c hash_test.c sockaddr_test.c \
+SRCS = isctest.c hash_test.c safe_test.c sockaddr_test.c \
symtab_test.c parse_test.c
SUBDIRS =
-TARGETS = hash_test@EXEEXT@ sockaddr_test@EXEEXT@ \
+TARGETS = hash_test@EXEEXT@ safe_test@EXEEXT@ sockaddr_test@EXEEXT@ \
symtab_test@EXEEXT@ parse_test@EXEEXT@
@BIND9_MAKE_RULES@
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
sockaddr_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+safe_test@EXEEXT@: safe_test.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ safe_test.@O@ ${ISCLIBS} ${LIBS}
+
unit::
sh ${top_srcdir}/unit/unittest.sh
--- /dev/null
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC 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.
+ */
+
+/* $Id$ */
+
+/* ! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <isc/safe.h>
+#include <isc/util.h>
+
+ATF_TC(isc_safe_memcmp);
+ATF_TC_HEAD(isc_safe_memcmp, tc) {
+ atf_tc_set_md_var(tc, "descr", "safe memcmp()");
+}
+ATF_TC_BODY(isc_safe_memcmp, tc) {
+ UNUSED(tc);
+
+ ATF_CHECK(isc_safe_memcmp("test", "test", 4));
+ ATF_CHECK(!isc_safe_memcmp("test", "tesc", 4));
+ ATF_CHECK(isc_safe_memcmp("\x00\x00\x00\x00", "\x00\x00\x00\x00", 4));
+ ATF_CHECK(!isc_safe_memcmp("\x00\x00\x00\x00", "\x00\x00\x00\x01", 4));
+ ATF_CHECK(!isc_safe_memcmp("\x00\x00\x00\x02", "\x00\x00\x00\x00", 4));
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, isc_safe_memcmp);
+ return (atf_no_error());
+}
+
isc_rwlock_trylock
isc_rwlock_tryupgrade
isc_rwlock_unlock
+isc_safe_memcmp
isc_serial_eq
isc_serial_ge
isc_serial_gt
# End Source File\r
# Begin Source File\r
\r
+SOURCE=..\safe.c\r
+# End Source File\r
+# Begin Source File\r
+\r
SOURCE=..\serial.c\r
# End Source File\r
# Begin Source File\r
-@erase "$(INTDIR)\resource.obj"
-@erase "$(INTDIR)\result.obj"
-@erase "$(INTDIR)\rwlock.obj"
+ -@erase "$(INTDIR)\safe.obj"
-@erase "$(INTDIR)\serial.obj"
-@erase "$(INTDIR)\sha1.obj"
-@erase "$(INTDIR)\sha2.obj"
"$(INTDIR)\refcount.obj" \
"$(INTDIR)\result.obj" \
"$(INTDIR)\rwlock.obj" \
+ "$(INTDIR)\safe.obj" \
"$(INTDIR)\serial.obj" \
"$(INTDIR)\sha1.obj" \
"$(INTDIR)\sha2.obj" \
-@erase "$(INTDIR)\result.sbr"
-@erase "$(INTDIR)\rwlock.obj"
-@erase "$(INTDIR)\rwlock.sbr"
+ -@erase "$(INTDIR)\safe.obj"
+ -@erase "$(INTDIR)\safe.sbr"
-@erase "$(INTDIR)\serial.obj"
-@erase "$(INTDIR)\serial.sbr"
-@erase "$(INTDIR)\sha1.obj"
"$(INTDIR)\refcount.sbr" \
"$(INTDIR)\result.sbr" \
"$(INTDIR)\rwlock.sbr" \
+ "$(INTDIR)\safe.sbr" \
"$(INTDIR)\serial.sbr" \
"$(INTDIR)\sha1.sbr" \
"$(INTDIR)\sha2.sbr" \
"$(INTDIR)\refcount.obj" \
"$(INTDIR)\result.obj" \
"$(INTDIR)\rwlock.obj" \
+ "$(INTDIR)\safe.obj" \
"$(INTDIR)\serial.obj" \
"$(INTDIR)\sha1.obj" \
"$(INTDIR)\sha2.obj" \
$(CPP) $(CPP_PROJ) $(SOURCE)
+!ENDIF
+
+SOURCE=..\safe.c
+
+!IF "$(CFG)" == "libisc - Win32 Release"
+
+
+"$(INTDIR)\safe.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "libisc - Win32 Debug"
+
+
+"$(INTDIR)\safe.obj" "$(INTDIR)\safe.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
!ENDIF
SOURCE=..\serial.c
#include <isc/assertions.h>
#include <isc/hmacmd5.h>
#include <isc/print.h>
+#include <isc/safe.h>
#include <isc/stdlib.h>
#include <isccc/alist.h>
/*
* Verify.
*/
- if (strcmp((char *)digestb64, isccc_sexpr_tostring(hmd5)) != 0)
+ if (!isc_safe_memcmp((unsigned char *) isccc_sexpr_tostring(hmd5),
+ digestb64, HMD5_LENGTH))
return (ISCCC_R_BADAUTH);
return (ISC_R_SUCCESS);