xref: /dflybsd-src/contrib/dhcpcd/compat/consttime_memequal.h (revision 8d36e1df80df39bec701fcb39b0b7982e1b94e77)
1*8d36e1dfSRoy Marples /*
2*8d36e1dfSRoy Marples  * Written by Matthias Drochner <drochner@NetBSD.org>.
3*8d36e1dfSRoy Marples  * Public domain.
4*8d36e1dfSRoy Marples  */
5*8d36e1dfSRoy Marples 
6*8d36e1dfSRoy Marples #ifndef CONSTTIME_MEMEQUAL_H
7*8d36e1dfSRoy Marples #define CONSTTIME_MEMEQUAL_H
8*8d36e1dfSRoy Marples inline static int
consttime_memequal(const void * b1,const void * b2,size_t len)9*8d36e1dfSRoy Marples consttime_memequal(const void *b1, const void *b2, size_t len)
10*8d36e1dfSRoy Marples {
11*8d36e1dfSRoy Marples 	const unsigned char *c1 = b1, *c2 = b2;
12*8d36e1dfSRoy Marples 	unsigned int res = 0;
13*8d36e1dfSRoy Marples 
14*8d36e1dfSRoy Marples 	while (len--)
15*8d36e1dfSRoy Marples 		res |= *c1++ ^ *c2++;
16*8d36e1dfSRoy Marples 
17*8d36e1dfSRoy Marples 	/*
18*8d36e1dfSRoy Marples 	 * Map 0 to 1 and [1, 256) to 0 using only constant-time
19*8d36e1dfSRoy Marples 	 * arithmetic.
20*8d36e1dfSRoy Marples 	 *
21*8d36e1dfSRoy Marples 	 * This is not simply `!res' because although many CPUs support
22*8d36e1dfSRoy Marples 	 * branchless conditional moves and many compilers will take
23*8d36e1dfSRoy Marples 	 * advantage of them, certain compilers generate branches on
24*8d36e1dfSRoy Marples 	 * certain CPUs for `!res'.
25*8d36e1dfSRoy Marples 	 */
26*8d36e1dfSRoy Marples 	return (1 & ((res - 1) >> 8));
27*8d36e1dfSRoy Marples }
28*8d36e1dfSRoy Marples #endif /* CONSTTIME_MEMEQUAL_H */
29