1 | /* $NetBSD: consttime_memequal.c,v 1.6 2015/03/18 20:11:35 riastradh Exp $ */ |
2 | |
3 | /* |
4 | * Written by Matthias Drochner <drochner@NetBSD.org>. |
5 | * Public domain. |
6 | */ |
7 | |
8 | #if !defined(_KERNEL) && !defined(_STANDALONE) |
9 | #include "namespace.h" |
10 | #include <string.h> |
11 | #ifdef __weak_alias |
12 | __weak_alias(consttime_memequal,_consttime_memequal) |
13 | #endif |
14 | #else |
15 | #include <lib/libkern/libkern.h> |
16 | #endif |
17 | |
18 | int |
19 | consttime_memequal(const void *b1, const void *b2, size_t len) |
20 | { |
21 | const unsigned char *c1 = b1, *c2 = b2; |
22 | unsigned int res = 0; |
23 | |
24 | while (len--) |
25 | res |= *c1++ ^ *c2++; |
26 | |
27 | /* |
28 | * Map 0 to 1 and [1, 256) to 0 using only constant-time |
29 | * arithmetic. |
30 | * |
31 | * This is not simply `!res' because although many CPUs support |
32 | * branchless conditional moves and many compilers will take |
33 | * advantage of them, certain compilers generate branches on |
34 | * certain CPUs for `!res'. |
35 | */ |
36 | return (1 & ((res - 1) >> 8)); |
37 | } |
38 | |