11.6Sriastrad/* $NetBSD: consttime_memequal.c,v 1.6 2015/03/18 20:11:35 riastradh Exp $ */
21.5Sdrochner
31.5Sdrochner/*
41.5Sdrochner * Written by Matthias Drochner <drochner@NetBSD.org>.
51.5Sdrochner * Public domain.
61.5Sdrochner */
71.1Sriastrad
81.1Sriastrad#if !defined(_KERNEL) && !defined(_STANDALONE)
91.3Sriastrad#include "namespace.h"
101.1Sriastrad#include <string.h>
111.3Sriastrad#ifdef __weak_alias
121.3Sriastrad__weak_alias(consttime_memequal,_consttime_memequal)
131.3Sriastrad#endif
141.1Sriastrad#else
151.1Sriastrad#include <lib/libkern/libkern.h>
161.1Sriastrad#endif
171.1Sriastrad
181.1Sriastradint
191.1Sriastradconsttime_memequal(const void *b1, const void *b2, size_t len)
201.1Sriastrad{
211.6Sriastrad	const unsigned char *c1 = b1, *c2 = b2;
221.6Sriastrad	unsigned int res = 0;
231.1Sriastrad
241.6Sriastrad	while (len--)
251.1Sriastrad		res |= *c1++ ^ *c2++;
261.4Sriastrad
271.4Sriastrad	/*
281.6Sriastrad	 * Map 0 to 1 and [1, 256) to 0 using only constant-time
291.6Sriastrad	 * arithmetic.
301.4Sriastrad	 *
311.6Sriastrad	 * This is not simply `!res' because although many CPUs support
321.6Sriastrad	 * branchless conditional moves and many compilers will take
331.6Sriastrad	 * advantage of them, certain compilers generate branches on
341.6Sriastrad	 * certain CPUs for `!res'.
351.4Sriastrad	 */
361.6Sriastrad	return (1 & ((res - 1) >> 8));
371.1Sriastrad}
38