1*5a2ca44cSriastradh /* $NetBSD: consttime_memequal.c,v 1.6 2015/03/18 20:11:35 riastradh Exp $ */ 21970d452Sdrochner 31970d452Sdrochner /* 41970d452Sdrochner * Written by Matthias Drochner <drochner@NetBSD.org>. 51970d452Sdrochner * Public domain. 61970d452Sdrochner */ 782db4b98Sriastradh 882db4b98Sriastradh #if !defined(_KERNEL) && !defined(_STANDALONE) 91239c2bbSriastradh #include "namespace.h" 1082db4b98Sriastradh #include <string.h> 111239c2bbSriastradh #ifdef __weak_alias __weak_alias(consttime_memequal,_consttime_memequal)121239c2bbSriastradh__weak_alias(consttime_memequal,_consttime_memequal) 131239c2bbSriastradh #endif 1482db4b98Sriastradh #else 1582db4b98Sriastradh #include <lib/libkern/libkern.h> 1682db4b98Sriastradh #endif 1782db4b98Sriastradh 1882db4b98Sriastradh int 1982db4b98Sriastradh consttime_memequal(const void *b1, const void *b2, size_t len) 2082db4b98Sriastradh { 21*5a2ca44cSriastradh const unsigned char *c1 = b1, *c2 = b2; 22*5a2ca44cSriastradh unsigned int res = 0; 2382db4b98Sriastradh 2482db4b98Sriastradh while (len--) 2582db4b98Sriastradh res |= *c1++ ^ *c2++; 263db7caeeSriastradh 273db7caeeSriastradh /* 28*5a2ca44cSriastradh * Map 0 to 1 and [1, 256) to 0 using only constant-time 29*5a2ca44cSriastradh * arithmetic. 303db7caeeSriastradh * 31*5a2ca44cSriastradh * This is not simply `!res' because although many CPUs support 32*5a2ca44cSriastradh * branchless conditional moves and many compilers will take 33*5a2ca44cSriastradh * advantage of them, certain compilers generate branches on 34*5a2ca44cSriastradh * certain CPUs for `!res'. 353db7caeeSriastradh */ 36*5a2ca44cSriastradh return (1 & ((res - 1) >> 8)); 3782db4b98Sriastradh } 38