1 /*	$OpenBSD: timingsafe.c,v 1.3 2014/06/21 22:57:15 tedu 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 <assert.h>
19 #include <stdlib.h>
20 #include <string.h>
21 
22 #define ASSERT_EQ(a, b) assert((a) == (b))
23 
24 enum {
25 	N = 8
26 };
27 
28 static unsigned char bufone[N], buftwo[N];
29 
30 void
31 check()
32 {
33 	int cmp = memcmp(bufone, buftwo, N);
34 
35 	/* Check for reflexivity. */
36 	ASSERT_EQ(0, timingsafe_bcmp(bufone, bufone, N));
37 	ASSERT_EQ(0, timingsafe_bcmp(buftwo, buftwo, N));
38 	ASSERT_EQ(0, timingsafe_memcmp(bufone, bufone, N));
39 	ASSERT_EQ(0, timingsafe_memcmp(buftwo, buftwo, N));
40 
41 	/* Check that timingsafe_bcmp returns 0 iff memcmp returns 0. */
42 	ASSERT_EQ(cmp == 0, timingsafe_bcmp(bufone, buftwo, N) == 0);
43 
44 	/* Check that timingsafe_memcmp returns cmp... */
45 	ASSERT_EQ(cmp < 0, timingsafe_memcmp(bufone, buftwo, N) < 0);
46 
47 	/* ... or -cmp if the argument order is swapped. */
48 	ASSERT_EQ(-cmp < 0, timingsafe_memcmp(buftwo, bufone, N) < 0);
49 }
50 
51 int
52 main()
53 {
54 	int i, j;
55 
56 	for (i = 0; i < 10000; i++) {
57 		arc4random_buf(bufone, N);
58 		arc4random_buf(buftwo, N);
59 
60 		check();
61 		for (j = 0; j < N; j++) {
62 			buftwo[j] = bufone[j];
63 			check();
64 		}
65 	}
66 
67 	return (0);
68 }
69