HashVerificationFilter

From Crypto++ Wiki
Jump to: navigation, search

HashVerificationFilter.png

A HashVerificationFilter is a filter that encapsulates a message digest algorithm with the purpose of verifying digests of input messages.

Construction

HashVerificationFilter (HashTransformation &hm, BufferedTransformation *attachment=NULL,
    word32 flags=DEFAULT_FLAGS)

The first parameter, hm, is a reference to a HashTransformation object such as Whirlpool or SHA. The second parameter, attachment, is usually (but not always) NULL. Example two demonstrates use of a non-NULL attached sink. The third parameter, flags, is most interesting. The values and their meanings are as follows. Note that HASH_AT_BEGIN and HASH_AT_END are mutually exclusive.

  • DEFAULT_FLAGS = HASH_AT_BEGIN | PUT_RESULT
  • HASH_AT_END (0)
    • specifies the hash value will be located at the end of the message
  • HASH_AT_BEGIN (1)
    • specifies the hash value will be located at the beginning of the message
  • PUT_MESSAGE (2)
    • specifies whether the message should be forwarded to the attached transformation
  • PUT_HASH (4)
    • specifies whether the the hash should be forwarded to the attached transformation
  • PUT_RESULT (8)
    • specifies whether the result of the verification (a boolean) should be forwarded to the attached transformation
  • THROW_EXCEPTION (16)
    • specifies whether an exception should be thrown if digest verification fails

Verification with THROW_EXCEPTION

The sample program below demonstrates a HMAC with SHA256 using filters (see pipelining). The HashVerificationFilter uses the THROW_EXCEPTION flag, which causes Crypto++ to throw an exception on verification failure.

AutoSeededRandomPool prng;

SecByteBlock key(16);   // SHA256::BLOCKSIZE will also work
prng.GenerateBlock(key, key.size());

string plain = "HMAC Test";
string mac, encoded;

/*********************************\
\*********************************/

try
{
    HMAC< SHA256 > hmac(key, key.size());

    StringSource(plain, true, 
        new HashFilter(hmac,
            new StringSink(mac)
        ) // HashFilter      
    ); // StringSource
}
catch(const CryptoPP::Exception& e)
{
    cerr << e.what() << endl;
    exit(1);
}

/*********************************\
\*********************************/

try
{
    HMAC< SHA256 > hmac(key, key.size());
    const int flags = HashVerificationFilter::THROW_EXCEPTION | HashVerificationFilter::HASH_AT_END;
    
    StringSource(plain + mac, true, 
        new HashVerificationFilter(hmac, NULL, flags)
    ); // StringSource

    cout << "Verified message" << endl;
}
catch(const CryptoPP::Exception& e)
{
    cerr << e.what() << endl;
    exit(1);
}

Testing the try/catch block is easily accomplished by tampering with the message or the MAC:

HMAC< SHA256 > hmac(key, key.size());

// Tamper with message
plain[0] ^= 0x01;

// Tamper with MAC
mac[0] ^= 0x01;

StringSource(plain + mac, true, 
    new HashVerificationFilter(hmac, NULL, flags)
); // StringSource

Verification without THROW_EXCEPTION

The sample program below demonstrates verification using PUT_RESULT. When using the flag, the result is forwarded to the attached buffered transformation (attachment), which is a bool wrapped using an ArraySink.

AutoSeededRandomPool prng;

SecByteBlock key(16);
prng.GenerateBlock(key, key.size());

string plain = "HMAC Test";
string mac, encoded;

/*********************************\
\*********************************/

HMAC< SHA256 > hmac1(key, key.size());

StringSource(plain, true, 
    new HashFilter(hmac1,
        new StringSink(mac)
    ) // HashFilter      
); // StringSource

/*********************************\
\*********************************/

HMAC< SHA256 > hmac2(key, key.size());
    
bool result = false;
StringSource(plain + mac, true, 
    new HashVerificationFilter(hmac2,
        new ArraySink((byte*)&result, sizeof(result)),
        PUT_RESULT | HASH_AT_END
    ) // HashVerificationFilter
); // StringSource

if(result)
    cout << "Verified message" << endl;
else
    cerr << "Failed to verify message" << endl;

Downloads

CMAC-AES-Filter.zip - Demonstrates an AES based CMAC and verification with filters

HMAC-SHA-Filter.zip - Demonstrates a SHA256 based HMAC and verification with filters