summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatthew <>2014-06-13 02:12:17 +0000
committermatthew <>2014-06-13 02:12:17 +0000
commitcc594d5ff9b7bb08404d34d62287ee1dfd6b8332 (patch)
tree228054f338d1a5a8d53b4b58798bd55801ab2ce2
parent5a1fd238ffb5612e4dd1965f694b7f04ab0d5ecb (diff)
downloadopenbsd-cc594d5ff9b7bb08404d34d62287ee1dfd6b8332.tar.gz
openbsd-cc594d5ff9b7bb08404d34d62287ee1dfd6b8332.tar.bz2
openbsd-cc594d5ff9b7bb08404d34d62287ee1dfd6b8332.zip
Add timingsafe_memcmp().
ok deraadt, jmc, tedu
-rw-r--r--src/lib/libc/string/Makefile.inc11
-rw-r--r--src/lib/libc/string/bcmp.331
-rw-r--r--src/lib/libc/string/memcmp.35
-rw-r--r--src/lib/libc/string/timingsafe_bcmp.392
-rw-r--r--src/lib/libc/string/timingsafe_memcmp.c46
-rw-r--r--src/regress/lib/libc/timingsafe/timingsafe.c6
6 files changed, 153 insertions, 38 deletions
diff --git a/src/lib/libc/string/Makefile.inc b/src/lib/libc/string/Makefile.inc
index 1f6d756182..a293219058 100644
--- a/src/lib/libc/string/Makefile.inc
+++ b/src/lib/libc/string/Makefile.inc
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile.inc,v 1.34 2014/03/23 23:16:48 tedu Exp $ 1# $OpenBSD: Makefile.inc,v 1.35 2014/06/13 02:12:17 matthew Exp $
2 2
3# string sources 3# string sources
4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/string ${LIBCSRCDIR}/string 4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/string ${LIBCSRCDIR}/string
@@ -7,11 +7,11 @@ SRCS+= explicit_bzero.c memccpy.c memmem.c memrchr.c stpcpy.c stpncpy.c \
7 strcasecmp.c strcasestr.c strcoll.c strdup.c \ 7 strcasecmp.c strcasestr.c strcoll.c strdup.c \
8 strerror.c strerror_r.c strlcat.c strmode.c strndup.c strnlen.c \ 8 strerror.c strerror_r.c strlcat.c strmode.c strndup.c strnlen.c \
9 strsignal.c strtok.c strxfrm.c \ 9 strsignal.c strtok.c strxfrm.c \
10 timingsafe_bcmp.c timingsafe_memcmp.c \
10 wcscat.c wcschr.c wcscmp.c wcscpy.c wcscspn.c wcslcat.c wcslcpy.c \ 11 wcscat.c wcschr.c wcscmp.c wcscpy.c wcscspn.c wcslcat.c wcslcpy.c \
11 wcslen.c wcsncat.c wcsncmp.c wcsncpy.c wcspbrk.c wcsrchr.c wcsspn.c \ 12 wcslen.c wcsncat.c wcsncmp.c wcsncpy.c wcspbrk.c wcsrchr.c wcsspn.c \
12 wcsstr.c wcstok.c wcswcs.c wcswidth.c wmemchr.c wmemcmp.c wmemcpy.c \ 13 wcsstr.c wcstok.c wcswcs.c wcswidth.c wmemchr.c wmemcmp.c wmemcpy.c \
13 wmemmove.c wmemset.c wcsdup.c \ 14 wmemmove.c wmemset.c wcsdup.c wcscasecmp.c
14 timingsafe_bcmp.c wcscasecmp.c
15 15
16# machine-dependent net sources 16# machine-dependent net sources
17# m-d Makefile.inc must include sources for: 17# m-d Makefile.inc must include sources for:
@@ -149,7 +149,8 @@ MAN+= bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 memccpy.3 memchr.3 \
149 strcat.3 strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strdup.3 \ 149 strcat.3 strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strdup.3 \
150 strerror.3 string.3 strlen.3 strmode.3 strncat.3 strncpy.3 strpbrk.3 \ 150 strerror.3 string.3 strlen.3 strmode.3 strncat.3 strncpy.3 strpbrk.3 \
151 strrchr.3 strsep.3 strsignal.3 strspn.3 strstr.3 strtok.3 strxfrm.3 \ 151 strrchr.3 strsep.3 strsignal.3 strspn.3 strstr.3 strtok.3 strxfrm.3 \
152 swab.3 strlcpy.3 wcscasecmp.3 wcscat.3 wcschr.3 wcscmp.3 wcscpy.3 \ 152 swab.3 strlcpy.3 timingsafe_bcmp.3 \
153 wcscasecmp.3 wcscat.3 wcschr.3 wcscmp.3 wcscpy.3 \
153 wcscspn.3 wcsdup.3 wcslcpy.3 wcslen.3 wcspbrk.3 wcsrchr.3 wcsspn.3 \ 154 wcscspn.3 wcsdup.3 wcslcpy.3 wcslen.3 wcspbrk.3 wcsrchr.3 wcsspn.3 \
154 wcsstr.3 wcstok.3 wcswidth.3 wmemchr.3 wmemcmp.3 wmemcpy.3 wmemmove.3 \ 155 wcsstr.3 wcstok.3 wcswidth.3 wmemchr.3 wmemcmp.3 wmemcpy.3 wmemmove.3 \
155 wmemset.3 156 wmemset.3
@@ -167,9 +168,9 @@ MLINKS+=strlen.3 strnlen.3
167MLINKS+=strstr.3 strcasestr.3 168MLINKS+=strstr.3 strcasestr.3
168MLINKS+=strtok.3 strtok_r.3 169MLINKS+=strtok.3 strtok_r.3
169MLINKS+=strerror.3 strerror_r.3 170MLINKS+=strerror.3 strerror_r.3
171MLINKS+=timingsafe_bcmp.3 timingsafe_memcmp.3
170MLINKS+=wcscasecmp.3 wcsncasecmp.3 172MLINKS+=wcscasecmp.3 wcsncasecmp.3
171MLINKS+=wcscat.3 wcsncat.3 173MLINKS+=wcscat.3 wcsncat.3
172MLINKS+=wcscmp.3 wcsncmp.3 174MLINKS+=wcscmp.3 wcsncmp.3
173MLINKS+=wcscpy.3 wcsncpy.3 175MLINKS+=wcscpy.3 wcsncpy.3
174MLINKS+=wcslcpy.3 wcslcat.3 176MLINKS+=wcslcpy.3 wcslcat.3
175MLINKS+=bcmp.3 timingsafe_bcmp.3
diff --git a/src/lib/libc/string/bcmp.3 b/src/lib/libc/string/bcmp.3
index 52584b4b83..720a8bf304 100644
--- a/src/lib/libc/string/bcmp.3
+++ b/src/lib/libc/string/bcmp.3
@@ -27,21 +27,18 @@
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
29.\" 29.\"
30.\" $OpenBSD: bcmp.3,v 1.10 2013/06/05 03:39:23 tedu Exp $ 30.\" $OpenBSD: bcmp.3,v 1.11 2014/06/13 02:12:17 matthew Exp $
31.\" 31.\"
32.Dd $Mdocdate: June 5 2013 $ 32.Dd $Mdocdate: June 13 2014 $
33.Dt BCMP 3 33.Dt BCMP 3
34.Os 34.Os
35.Sh NAME 35.Sh NAME
36.Nm bcmp , 36.Nm bcmp
37.Nm timingsafe_bcmp
38.Nd compare byte string 37.Nd compare byte string
39.Sh SYNOPSIS 38.Sh SYNOPSIS
40.In string.h 39.In string.h
41.Ft int 40.Ft int
42.Fn bcmp "const void *b1" "const void *b2" "size_t len" 41.Fn bcmp "const void *b1" "const void *b2" "size_t len"
43.Ft int
44.Fn timingsafe_bcmp "const void *b1" "const void *b2" "size_t len"
45.Sh DESCRIPTION 42.Sh DESCRIPTION
46The 43The
47.Fn bcmp 44.Fn bcmp
@@ -56,33 +53,15 @@ bytes long.
56Zero-length strings are always identical. 53Zero-length strings are always identical.
57.Pp 54.Pp
58The strings may overlap. 55The strings may overlap.
59.Pp
60The
61.Fn timingsafe_bcmp
62function has the same semantics as
63.Fn bcmp ,
64but its running time is independent of the contents of
65.Fa b1
66and
67.Fa b2 ,
68making it safe to use for comparing secret values such as cryptographic MACs.
69In contrast,
70.Fn bcmp
71returns after finding the first differing byte,
72making it vulnerable to timing attacks.
73.Sh SEE ALSO 56.Sh SEE ALSO
74.Xr memcmp 3 , 57.Xr memcmp 3 ,
75.Xr strcasecmp 3 , 58.Xr strcasecmp 3 ,
76.Xr strcmp 3 , 59.Xr strcmp 3 ,
77.Xr strcoll 3 , 60.Xr strcoll 3 ,
78.Xr strxfrm 3 61.Xr strxfrm 3 ,
62.Xr timingsafe_bcmp 3
79.Sh HISTORY 63.Sh HISTORY
80The 64The
81.Fn bcmp 65.Fn bcmp
82function first appeared in 66function first appeared in
83.Bx 4.2 . 67.Bx 4.2 .
84.Pp
85The
86.Fn timingsafe_bcmp
87function first appeared in
88.Ox 4.9 .
diff --git a/src/lib/libc/string/memcmp.3 b/src/lib/libc/string/memcmp.3
index ebd838825a..25d308e617 100644
--- a/src/lib/libc/string/memcmp.3
+++ b/src/lib/libc/string/memcmp.3
@@ -1,4 +1,4 @@
1.\" $OpenBSD: memcmp.3,v 1.8 2013/06/05 03:39:23 tedu Exp $ 1.\" $OpenBSD: memcmp.3,v 1.9 2014/06/13 02:12:17 matthew Exp $
2.\" 2.\"
3.\" Copyright (c) 1990, 1991 The Regents of the University of California. 3.\" Copyright (c) 1990, 1991 The Regents of the University of California.
4.\" All rights reserved. 4.\" All rights reserved.
@@ -31,7 +31,7 @@
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE. 32.\" SUCH DAMAGE.
33.\" 33.\"
34.Dd $Mdocdate: June 5 2013 $ 34.Dd $Mdocdate: June 13 2014 $
35.Dt MEMCMP 3 35.Dt MEMCMP 3
36.Os 36.Os
37.Sh NAME 37.Sh NAME
@@ -70,6 +70,7 @@ Zero-length strings are always identical.
70.Xr strcmp 3 , 70.Xr strcmp 3 ,
71.Xr strcoll 3 , 71.Xr strcoll 3 ,
72.Xr strxfrm 3 , 72.Xr strxfrm 3 ,
73.Xr timingsafe_memcmp 3 ,
73.Xr wmemcmp 3 74.Xr wmemcmp 3
74.Sh STANDARDS 75.Sh STANDARDS
75The 76The
diff --git a/src/lib/libc/string/timingsafe_bcmp.3 b/src/lib/libc/string/timingsafe_bcmp.3
new file mode 100644
index 0000000000..0886731ce7
--- /dev/null
+++ b/src/lib/libc/string/timingsafe_bcmp.3
@@ -0,0 +1,92 @@
1.\" $OpenBSD: timingsafe_bcmp.3,v 1.1 2014/06/13 02:12:17 matthew Exp $
2.\"
3.\" Copyright (c) 2014 Google Inc.
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.Dd $Mdocdate: June 13 2014 $
17.Dt TIMINGSAFE_BCMP 3
18.Os
19.Sh NAME
20.Nm timingsafe_bcmp ,
21.Nm timingsafe_memcmp
22.Nd timing-safe byte sequence comparisons
23.Sh SYNOPSIS
24.In string.h
25.Ft int
26.Fn timingsafe_bcmp "const void *b1" "const void *b2" "size_t len"
27.Ft int
28.Fn timingsafe_memcmp "const void *b1" "const void *b2" "size_t len"
29.Sh DESCRIPTION
30The
31.Fn timingsafe_bcmp
32and
33.Fn timingsafe_memcmp
34functions lexicographically compare the first
35.Fa len
36bytes (each interpreted as an
37.Vt unsigned char )
38pointed to by
39.Fa b1
40and
41.Fa b2 .
42.Pp
43Additionally, their running times are independent of the byte sequences compared,
44making them safe to use for comparing secret values such as cryptographic MACs.
45In contrast,
46.Xr bcmp 3
47and
48.Xr memcmp 3
49may short-circuit after finding the first differing byte.
50.Sh RETURN VALUES
51The
52.Fn timingsafe_bcmp
53function returns 0 or 1 if the byte sequence pointed to by
54.Fa b1
55compares equal to or not equal to (respectively)
56the byte sequence pointed to by
57.Fa b2 .
58.Pp
59The
60.Fn timingsafe_memcmp
61function returns \-1, 0, or 1 if the byte sequence pointed to by
62.Fa b1
63compares less than, equal to, or greater than (respectively)
64the byte sequence pointed to by
65.Fa b2 .
66.Pp
67Note that these return values are compatible with, but stricter than,
68the ones specified for
69.Xr bcmp 3
70and
71.Xr memcmp 3 .
72.Sh SEE ALSO
73.Xr bcmp 3 ,
74.Xr memcmp 3
75.Sh STANDARDS
76The
77.Fn timingsafe_bcmp
78and
79.Fn timingsafe_memcmp
80functions are
81.Ox
82extensions.
83.Sh HISTORY
84The
85.Fn timingsafe_bcmp
86function first appeared in
87.Ox 4.9 .
88.Pp
89The
90.Fn timingsafe_memcmp
91function first appeared in
92.Ox 5.6 .
diff --git a/src/lib/libc/string/timingsafe_memcmp.c b/src/lib/libc/string/timingsafe_memcmp.c
new file mode 100644
index 0000000000..04e2ac5e20
--- /dev/null
+++ b/src/lib/libc/string/timingsafe_memcmp.c
@@ -0,0 +1,46 @@
1/* $OpenBSD: timingsafe_memcmp.c,v 1.1 2014/06/13 02:12:17 matthew Exp $ */
2/*
3 * Copyright (c) 2014 Google Inc.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <limits.h>
19#include <string.h>
20
21int
22timingsafe_memcmp(const void *b1, const void *b2, size_t len)
23{
24 const unsigned char *p1 = b1, *p2 = b2;
25 size_t i;
26 int res = 0, done = 0;
27
28 for (i = 0; i < len; i++) {
29 /* lt is -1 if p1[i] < p2[i]; else 0. */
30 int lt = (p1[i] - p2[i]) >> CHAR_BIT;
31
32 /* gt is -1 if p1[i] > p2[i]; else 0. */
33 int gt = (p2[i] - p1[i]) >> CHAR_BIT;
34
35 /* cmp is 1 if p1[i] > p2[i]; -1 if p1[i] < p2[i]; else 0. */
36 int cmp = lt - gt;
37
38 /* set res = cmp if !done. */
39 res |= cmp & ~done;
40
41 /* set done if p1[i] != p2[i]. */
42 done |= lt | gt;
43 }
44
45 return (res);
46}
diff --git a/src/regress/lib/libc/timingsafe/timingsafe.c b/src/regress/lib/libc/timingsafe/timingsafe.c
index 9ecac93c09..e7807db258 100644
--- a/src/regress/lib/libc/timingsafe/timingsafe.c
+++ b/src/regress/lib/libc/timingsafe/timingsafe.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: timingsafe.c,v 1.1 2014/06/13 01:55:02 matthew Exp $ */ 1/* $OpenBSD: timingsafe.c,v 1.2 2014/06/13 02:12:17 matthew Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Google Inc. 3 * Copyright (c) 2014 Google Inc.
4 * 4 *
@@ -42,21 +42,17 @@ check()
42 /* Check for reflexivity. */ 42 /* Check for reflexivity. */
43 ASSERT_EQ(0, timingsafe_bcmp(bufone, bufone, N)); 43 ASSERT_EQ(0, timingsafe_bcmp(bufone, bufone, N));
44 ASSERT_EQ(0, timingsafe_bcmp(buftwo, buftwo, N)); 44 ASSERT_EQ(0, timingsafe_bcmp(buftwo, buftwo, N));
45#if notyet
46 ASSERT_EQ(0, timingsafe_memcmp(bufone, bufone, N)); 45 ASSERT_EQ(0, timingsafe_memcmp(bufone, bufone, N));
47 ASSERT_EQ(0, timingsafe_memcmp(buftwo, buftwo, N)); 46 ASSERT_EQ(0, timingsafe_memcmp(buftwo, buftwo, N));
48#endif
49 47
50 /* Check that timingsafe_bcmp returns 0 iff memcmp returns 0. */ 48 /* Check that timingsafe_bcmp returns 0 iff memcmp returns 0. */
51 ASSERT_EQ(cmp == 0, timingsafe_bcmp(bufone, buftwo, N) == 0); 49 ASSERT_EQ(cmp == 0, timingsafe_bcmp(bufone, buftwo, N) == 0);
52 50
53#if notyet
54 /* Check that timingsafe_memcmp returns cmp... */ 51 /* Check that timingsafe_memcmp returns cmp... */
55 ASSERT_EQ(cmp, timingsafe_memcmp(bufone, buftwo, N)); 52 ASSERT_EQ(cmp, timingsafe_memcmp(bufone, buftwo, N));
56 53
57 /* ... or -cmp if the argument order is swapped. */ 54 /* ... or -cmp if the argument order is swapped. */
58 ASSERT_EQ(-cmp, timingsafe_memcmp(buftwo, bufone, N)); 55 ASSERT_EQ(-cmp, timingsafe_memcmp(buftwo, bufone, N));
59#endif
60} 56}
61 57
62int 58int