HashVerificationFilter
From Crypto++ Wiki
A HashVerificationFilter is a filter that encapsulates a message digest algorithm with the purpose of verifying digests of input messages.
Contents |
[edit] 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
[edit] 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
[edit] 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;
[edit] 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
