1/*	$OpenBSD: timingsafe.c,v 1.4 2024/02/04 20:51:21 tb 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
24enum {
25	N = 8
26};
27
28static unsigned char bufone[N], buftwo[N];
29
30void
31check(void)
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
51int
52main(void)
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