VerifyBufsEqual
Documentation |
#include <cryptopp/misc.h>
|
VerifyBufsEqual is a constant time memory comparison function. The code is written in a way that makes it difficult for the optimizer to short-circuit if the buffers are not equal. The function serves the same purpose as OpenSSL's CRYPTO_memcmp
.
Crypto++ classes like SignatureVerificationFilter
and HashVerificationFilter
indirectly use the function. For example, SignatureVerificationFilter
will call Verify
on the PK_Verifier
, and the PK_Verifier
will use VerifyBufsEqual
.
VerifyBufsEqual
requires two equally sized buffers to compare. You should ensure you have valid, non-null buffers to compare before calling this function. A related question is on the Information Security Stack Exchange at Constant time compares when array sizes are not equal?.
If your code is using the C++ runtime's memcmp
or std::compare
on non-public data, then it should probably be using VerifyBufsEqual
.
Source Code
The source code for VerifyBufsEqual
is shown below. The asserts are present in debug builds to alert the developer a buffer is not valid.
// VerifyBufsEqual simplified at https://github.com/weidai11/cryptopp/issues/1020 bool VerifyBufsEqual(const byte *buf, const byte *mask, size_t count) { CRYPTOPP_ASSERT(buf != NULLPTR); CRYPTOPP_ASSERT(mask != NULLPTR); // CRYPTOPP_ASSERT(count > 0); #if CRYPTOPP_BOOL_64BIT word64 acc64 = 0; while (count >= 8) { word64 b, m; memcpy(&b, buf, 8); memcpy(&m, mask, 8); acc64 |= b ^ m; buf += 8; mask += 8; count -= 8; } word32 acc8 = (acc64 >> 32) | (acc64 & 0xffffffff); acc8 = static_cast<byte>(acc8) | static_cast<byte>(acc8 >> 8) | static_cast<byte>(acc8 >> 16) | static_cast<byte>(acc8 >> 24); #else word32 acc32 = 0; while (count >= 4) { word32 b, m; memcpy(&b, buf, 4); memcpy(&m, mask, 4); acc32 |= b ^ m; buf += 4; mask += 4; count -= 4; } word32 acc8 = acc32; acc8 = static_cast<byte>(acc8) | static_cast<byte>(acc8 >> 8) | static_cast<byte>(acc8 >> 16) | static_cast<byte>(acc8 >> 24); #endif for (size_t i=0; i<count; i++) acc8 |= buf[i] ^ mask[i]; return acc8 == 0; }