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