diff options
author | Xin LI <delphij@FreeBSD.org> | 2016-04-27 07:46:38 +0000 |
---|---|---|
committer | Xin LI <delphij@FreeBSD.org> | 2016-04-27 07:46:38 +0000 |
commit | 4990d495fcc77c51b3f46c91ba3a064b565afae0 (patch) | |
tree | 89c803d8ff6ef95cafc2a4cb08de66848195099a /contrib/ntp/lib | |
parent | 0fbe6eaef6fbb001b91bd8a57a9b3817c1b07b24 (diff) | |
parent | c1950318d1af96666bb3a80bf73cb4790f6dbcea (diff) | |
download | src-test2-4990d495fcc77c51b3f46c91ba3a064b565afae0.tar.gz src-test2-4990d495fcc77c51b3f46c91ba3a064b565afae0.zip |
Notes
Diffstat (limited to 'contrib/ntp/lib')
-rw-r--r-- | contrib/ntp/lib/isc/hmacmd5.c | 2 | ||||
-rw-r--r-- | contrib/ntp/lib/isc/hmacsha.c | 10 | ||||
-rw-r--r-- | contrib/ntp/lib/isc/include/isc/string.h | 18 | ||||
-rw-r--r-- | contrib/ntp/lib/isc/tsmemcmp.c | 55 |
4 files changed, 79 insertions, 6 deletions
diff --git a/contrib/ntp/lib/isc/hmacmd5.c b/contrib/ntp/lib/isc/hmacmd5.c index 6abe6e27df8e..0388b17083b7 100644 --- a/contrib/ntp/lib/isc/hmacmd5.c +++ b/contrib/ntp/lib/isc/hmacmd5.c @@ -145,5 +145,5 @@ isc_hmacmd5_verify2(isc_hmacmd5_t *ctx, unsigned char *digest, size_t len) { REQUIRE(len <= ISC_MD5_DIGESTLENGTH); isc_hmacmd5_sign(ctx, newdigest); - return (ISC_TF(memcmp(digest, newdigest, len) == 0)); + return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0)); } diff --git a/contrib/ntp/lib/isc/hmacsha.c b/contrib/ntp/lib/isc/hmacsha.c index d7b9f1897eb0..75b1cb14d29d 100644 --- a/contrib/ntp/lib/isc/hmacsha.c +++ b/contrib/ntp/lib/isc/hmacsha.c @@ -538,7 +538,7 @@ isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { REQUIRE(len <= ISC_SHA1_DIGESTLENGTH); isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH); - return (ISC_TF(memcmp(digest, newdigest, len) == 0)); + return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0)); } /* @@ -551,7 +551,7 @@ isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) REQUIRE(len <= ISC_SHA224_DIGESTLENGTH); isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH); - return (ISC_TF(memcmp(digest, newdigest, len) == 0)); + return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0)); } /* @@ -564,7 +564,7 @@ isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) REQUIRE(len <= ISC_SHA256_DIGESTLENGTH); isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH); - return (ISC_TF(memcmp(digest, newdigest, len) == 0)); + return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0)); } /* @@ -577,7 +577,7 @@ isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) REQUIRE(len <= ISC_SHA384_DIGESTLENGTH); isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH); - return (ISC_TF(memcmp(digest, newdigest, len) == 0)); + return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0)); } /* @@ -590,5 +590,5 @@ isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) REQUIRE(len <= ISC_SHA512_DIGESTLENGTH); isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH); - return (ISC_TF(memcmp(digest, newdigest, len) == 0)); + return (ISC_TF(isc_tsmemcmp(digest, newdigest, len) == 0)); } diff --git a/contrib/ntp/lib/isc/include/isc/string.h b/contrib/ntp/lib/isc/include/isc/string.h index b49fdbc327f1..395b550218fc 100644 --- a/contrib/ntp/lib/isc/include/isc/string.h +++ b/contrib/ntp/lib/isc/include/isc/string.h @@ -199,6 +199,24 @@ isc_string_regiondup(isc_mem_t *mctx, const isc_region_t *source); * */ +int +isc_tsmemcmp(const void *p1, const void *p2, size_t len); +/* + * Lexicographic compare 'len' unsigned bytes from 'p1' and 'p2' + * like 'memcmp()'. + * + * This function is safe from timing attacks as it has a runtime that + * only depends on 'len' and has no early-out option. + * + * Use this to check MACs and other material that is security sensitive. + * + * Returns: + * (let x be the byte offset of the first different byte) + * -1 if (u_char)p1[x] < (u_char)p2[x] + * 1 if (u_char)p1[x] > (u_char)p2[x] + * 0 if byte series are equal + */ + char * isc_string_separate(char **stringp, const char *delim); diff --git a/contrib/ntp/lib/isc/tsmemcmp.c b/contrib/ntp/lib/isc/tsmemcmp.c new file mode 100644 index 000000000000..e6af42eafc0f --- /dev/null +++ b/contrib/ntp/lib/isc/tsmemcmp.c @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2004-2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2001, 2003 Internet Software Consortium. + * + * 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 <limits.h> +#include <isc/string.h> + +/* Making a portable memcmp that has no internal branches and loops always + * once for every byte without early-out shortcut has a few challenges. + * + * Inspired by 'timingsafe_memcmp()' from the BSD system and + * https://github.com/libressl-portable/openbsd/blob/master/src/lib/libc/string/timingsafe_memcmp.c + * + * Sadly, that one is not portable C: It makes assumptions on the representation + * of negative integers and assumes sign-preserving right-shift of negative + * signed values. This is a rewrite from scratch that should not suffer from + * such issues. + * + * 2015-12-12, J. Perlinger (perlinger-at-ntp-dot-org) + */ +int +isc_tsmemcmp(const void *p1, const void *p2, size_t nb) { + const unsigned char *ucp1 = p1; + const unsigned char *ucp2 = p2; + unsigned int isLT = 0u; + unsigned int isGT = 0u; + volatile unsigned int mask = (1u << CHAR_BIT); + + for (/*NOP*/; 0 != nb; --nb, ++ucp1, ++ucp2) { + isLT |= mask & + ((unsigned int)*ucp1 - (unsigned int)*ucp2); + isGT |= mask & + ((unsigned int)*ucp2 - (unsigned int)*ucp1); + mask &= ~(isLT | isGT); + } + return (int)(isGT >> CHAR_BIT) - (int)(isLT >> CHAR_BIT); +} |