1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 01:18:00 +00:00
putty-source/utils/smemeq.c
Simon Tatham 31db2e67bb Make smemeq return unsigned, not bool.
bool is dangerous in a time-safe context, because C compilers might
insert a control flow divergence to implement the implicit
normalisation of nonzero integers to 1 when you assign to a bool.
Everywhere else time-safe, I avoid using it; but smemeq has been an
exception until now, because the response to smemeq returning failure
was to do an obvious protocol-level divergence _anyway_ (like
disconnecting due to MAC mismatch).

But I'm about to want to use smemeq in a context where I use the
result _subtly_ and don't want to give away what it is, so now it's
time to get rid of that bool and have smemeq return unsigned.
2022-04-15 17:46:06 +01:00

26 lines
818 B
C

/*
* Compare two fixed-size regions of memory, in a crypto-safe way,
* i.e. without timing or cache side channels indicating anything
* about what the answer was or where the first difference (if any)
* might have been.
*/
#include "defs.h"
#include "misc.h"
unsigned smemeq(const void *av, const void *bv, size_t len)
{
const unsigned char *a = (const unsigned char *)av;
const unsigned char *b = (const unsigned char *)bv;
unsigned val = 0;
while (len-- > 0) {
val |= *a++ ^ *b++;
}
/* Now val is 0 iff we want to return 1, and in the range
* 0x01..0xFF iff we want to return 0. So subtracting from 0x100
* will clear bit 8 iff we want to return 0, and leave it set iff
* we want to return 1, so then we can just shift down. */
return (0x100 - val) >> 8;
}