From 12006ca8ed08eb0858fe75f07623b5670c07b625 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Wed, 26 Mar 2025 04:03:00 +0800 Subject: [PATCH 4/4] Restore timingsafe --- Makefile | 9 ++- missing.h | 2 + src/lib/libc/string/timingsafe_bcmp.c | 30 ++++++++ src/lib/libc/string/timingsafe_memcmp.c | 47 +++++++++++++ src/regress/lib/libc/timingsafe/CVS/Entries | 3 + .../lib/libc/timingsafe/CVS/Repository | 1 + src/regress/lib/libc/timingsafe/CVS/Root | 1 + src/regress/lib/libc/timingsafe/Makefile | 5 ++ src/regress/lib/libc/timingsafe/timingsafe.c | 68 +++++++++++++++++++ 9 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 src/lib/libc/string/timingsafe_bcmp.c create mode 100644 src/lib/libc/string/timingsafe_memcmp.c create mode 100644 src/regress/lib/libc/timingsafe/CVS/Entries create mode 100644 src/regress/lib/libc/timingsafe/CVS/Repository create mode 100644 src/regress/lib/libc/timingsafe/CVS/Root create mode 100644 src/regress/lib/libc/timingsafe/Makefile create mode 100644 src/regress/lib/libc/timingsafe/timingsafe.c diff --git Makefile Makefile index ecf00fd..341cdb4 100644 --- Makefile +++ Makefile @@ -12,6 +12,7 @@ SRCS+= src/lib/libc/gen/readpassphrase.c SRCS+= src/lib/libc/hash/sha2.c SRCS+= src/lib/libc/net/base64.c SRCS+= src/lib/libc/string/explicit_bzero.c +SRCS+= src/lib/libc/string/timingsafe_bcmp.c SRCS+= src/lib/libutil/bcrypt_pbkdf.c SRCS+= src/lib/libutil/ohash.c SRCS+= src/usr.bin/signify/crypto_api.c @@ -115,9 +116,15 @@ REGRESS_BZ_SRCS+= src/regress/lib/libc/explicit_bzero/explicit_bzero.c explicit_bzero: ${REGRESS_BZ_SRCS} ${CC} ${CFLAGS} -o $@ ${REGRESS_BZ_SRCS} +REGRESS_TS_SRCS= src/lib/libc/string/timingsafe_bcmp.c +REGRESS_TS_SRCS+= src/lib/libc/string/timingsafe_memcmp.c +REGRESS_TS_SRCS+= src/regress/lib/libc/timingsafe/timingsafe.c +timingsafe: ${REGRESS_TS_SRCS} + ${CC} ${CFLAGS} -o $@ ${REGRESS_TS_SRCS} + check: test -test: signify explicit_bzero +test: signify explicit_bzero timingsafe @sh ./regress.sh diff --git missing.h missing.h index 4925153..2f456f2 100644 --- missing.h +++ missing.h @@ -2,3 +2,5 @@ void explicit_bzero(void *, size_t); void freezero(void *, size_t); +int timingsafe_bcmp(const void *, const void *, size_t); +int timingsafe_memcmp(const void *, const void *, size_t); diff --git src/lib/libc/string/timingsafe_bcmp.c src/lib/libc/string/timingsafe_bcmp.c new file mode 100644 index 0000000..0409ec3 --- /dev/null +++ src/lib/libc/string/timingsafe_bcmp.c @@ -0,0 +1,30 @@ +/* $OpenBSD: timingsafe_bcmp.c,v 1.3 2015/08/31 02:53:57 guenther Exp $ */ +/* + * Copyright (c) 2010 Damien Miller. All rights reserved. + * + * 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 + +int +timingsafe_bcmp(const void *b1, const void *b2, size_t n) +{ + const unsigned char *p1 = b1, *p2 = b2; + int ret = 0; + + for (; n > 0; n--) + ret |= *p1++ ^ *p2++; + return (ret != 0); +} +DEF_WEAK(timingsafe_bcmp); diff --git src/lib/libc/string/timingsafe_memcmp.c src/lib/libc/string/timingsafe_memcmp.c new file mode 100644 index 0000000..373f8cb --- /dev/null +++ src/lib/libc/string/timingsafe_memcmp.c @@ -0,0 +1,47 @@ +/* $OpenBSD: timingsafe_memcmp.c,v 1.2 2015/08/31 02:53:57 guenther 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 +#include + +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); +} +DEF_WEAK(timingsafe_memcmp); diff --git src/regress/lib/libc/timingsafe/CVS/Entries src/regress/lib/libc/timingsafe/CVS/Entries new file mode 100644 index 0000000..69c9466 --- /dev/null +++ src/regress/lib/libc/timingsafe/CVS/Entries @@ -0,0 +1,3 @@ +/Makefile/1.1/Fri Jun 13 01:55:02 2014// +/timingsafe.c/1.3/Sat Jun 21 22:57:15 2014// +D diff --git src/regress/lib/libc/timingsafe/CVS/Repository src/regress/lib/libc/timingsafe/CVS/Repository new file mode 100644 index 0000000..c390889 --- /dev/null +++ src/regress/lib/libc/timingsafe/CVS/Repository @@ -0,0 +1 @@ +src/regress/lib/libc/timingsafe diff --git src/regress/lib/libc/timingsafe/CVS/Root src/regress/lib/libc/timingsafe/CVS/Root new file mode 100644 index 0000000..844b841 --- /dev/null +++ src/regress/lib/libc/timingsafe/CVS/Root @@ -0,0 +1 @@ +anoncvs@anoncvs3.usa.openbsd.org:/cvs diff --git src/regress/lib/libc/timingsafe/Makefile src/regress/lib/libc/timingsafe/Makefile new file mode 100644 index 0000000..9a679b6 --- /dev/null +++ src/regress/lib/libc/timingsafe/Makefile @@ -0,0 +1,5 @@ +# $OpenBSD: Makefile,v 1.1 2014/06/13 01:55:02 matthew Exp $ + +PROG= timingsafe + +.include diff --git src/regress/lib/libc/timingsafe/timingsafe.c src/regress/lib/libc/timingsafe/timingsafe.c new file mode 100644 index 0000000..f6605f8 --- /dev/null +++ src/regress/lib/libc/timingsafe/timingsafe.c @@ -0,0 +1,68 @@ +/* $OpenBSD: timingsafe.c,v 1.3 2014/06/21 22:57:15 tedu 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 +#include +#include + +#define ASSERT_EQ(a, b) assert((a) == (b)) + +enum { + N = 8 +}; + +static unsigned char bufone[N], buftwo[N]; + +void +check() +{ + int cmp = memcmp(bufone, buftwo, N); + + /* Check for reflexivity. */ + ASSERT_EQ(0, timingsafe_bcmp(bufone, bufone, N)); + ASSERT_EQ(0, timingsafe_bcmp(buftwo, buftwo, N)); + ASSERT_EQ(0, timingsafe_memcmp(bufone, bufone, N)); + ASSERT_EQ(0, timingsafe_memcmp(buftwo, buftwo, N)); + + /* Check that timingsafe_bcmp returns 0 iff memcmp returns 0. */ + ASSERT_EQ(cmp == 0, timingsafe_bcmp(bufone, buftwo, N) == 0); + + /* Check that timingsafe_memcmp returns cmp... */ + ASSERT_EQ(cmp < 0, timingsafe_memcmp(bufone, buftwo, N) < 0); + + /* ... or -cmp if the argument order is swapped. */ + ASSERT_EQ(-cmp < 0, timingsafe_memcmp(buftwo, bufone, N) < 0); +} + +int +main() +{ + int i, j; + + for (i = 0; i < 10000; i++) { + arc4random_buf(bufone, N); + arc4random_buf(buftwo, N); + + check(); + for (j = 0; j < N; j++) { + buftwo[j] = bufone[j]; + check(); + } + } + + return (0); +} -- 2.48.0