VerifyBufsEqual

From Crypto++ Wiki
Jump to: navigation, search
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.

If your code is using the runtime's memcmp or std::compare on non-public data, then it should probably be using VerifyBufsEqual.

VerifyBufsEqual requires two equally sized buffers to compare. A related question is on the Information Security Stack Exchange at Constant time compares when array sizes are not equal?.

Source Code

The source code for VerifyBufsEqual is shown below.

00079 bool VerifyBufsEqual(const byte *buf, const byte *mask, size_t count)
00080 {
00081         size_t i;
00082         byte acc8 = 0;
00083 
00084         if (IsAligned<word32>(buf) && IsAligned<word32>(mask))
00085         {
00086                 word32 acc32 = 0;
00087                 if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(mask))
00088                 {
00089                         word64 acc64 = 0;
00090                         for (i=0; i<count/8; i++)
00091                                 acc64 |= ((word64*)buf)[i] ^ ((word64*)mask)[i];
00092                         count -= 8*i;
00093                         if (!count)
00094                                 return acc64 == 0;
00095                         buf += 8*i;
00096                         mask += 8*i;
00097                         acc32 = word32(acc64) | word32(acc64>>32);
00098                 }
00099 
00100                 for (i=0; i<count/4; i++)
00101                         acc32 |= ((word32*)buf)[i] ^ ((word32*)mask)[i];
00102                 count -= 4*i;
00103                 if (!count)
00104                         return acc32 == 0;
00105                 buf += 4*i;
00106                 mask += 4*i;
00107                 acc8 = byte(acc32) | byte(acc32>>8) | byte(acc32>>16) | byte(acc32>>24);
00108         }
00109 
00110         for (i=0; i<count; i++)
00111                 acc8 |= buf[i] ^ mask[i];
00112         return acc8 == 0;
00113 }