Re: HMACs of files

Jeffrey Walton <[email protected]>
Newsgroups gmane.comp.encryption.cryptopp
Message-ID <[email protected]>

On Wednesday, September 8, 2021 at 6:47:45 AM UTC-4 Jeffrey Walton wrote:

> On Tue, Sep 7, 2021 at 7:45 AM Tom <[email protected]> wrote: 
> > 
> > I can create HMACs of files using pipelines via filesources but... I 
> can't seem to figure out to verify the HMAC without throwing the file into 
> a string in memory. 
> > 
> > like this: 
> > 
> > StringSource(plain + mac, true, new HashVerificationFilter(hmac, NULL, 
> flags) ); // StringSource 
> > 
> > Is there a way to use a FileSource without loading the file fully into 
> memory? 
> > 
> > I think its possible but do I append the hmac if I use a file? 
>
> Yeah, that's a problem. We should have some documentation covering it. 
>
> I think you need a custom source that takes two sources - the existing 
> HMAC wrapped in a StringSource and the FileSource. The custom source 
> then pumps the data to the attached filter. 
>
> Another option is a HashVerificationFilter that takes two sources. It 
> could be tricky since the source is expected to pump its data. I did 
> not test this option. 
>
> Attached is an example. It uses a hash rather than HMAC to simplify the 
> code. 
>
> The example has a bug, though. HashVerificationFilter is failing...
>

Attached is a corrected example that works as expected. Unfortunately, I 
was not able to get the CombinedSource class to work as expected. Instead, 
I had to manually fiddle with both Sources. It is not as elegant, but it 
should get you through your task.

Jeff

-- 
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion on the web visit https://groups.google.com/d/msgid/cryptopp-users/a36821f1-3d7a-46ec-9b6f-1618ab1ded53n%40googlegroups.com.
test.cxx (text/plain, 1.2 KB)
#include <iostream>
#include <string>

#include "cryptlib.h"
#include "filters.h"
#include "files.h"
#include "sha.h"
#include "hex.h"

int main(int argc, char* argv[])
{
    using namespace CryptoPP;

    // Create a file of all 0's with:
    // dd if=/dev/zero of=./zero.dat bs=4096 count=1

    std::string digest;
    SHA256 sha256;

    // Create the digest on the file
    FileSource("zero.dat", true, new HashFilter(sha256, new StringSink(digest)));

    // Print the digest
    std::cout << "Digest: ";
    StringSource(digest, true, new HexEncoder(new FileSink(std::cout)));
    std::cout << std::endl;

	// Create a verifier
    byte result = 0;
    HashVerificationFilter verifier(sha256, new ArraySink(&result, sizeof(result)));

	// Wrap the data in sources
	StringSource ss(digest, true);
    FileSource fs("zero.dat", true);

	// Add the data to the filter
    ss.TransferTo(verifier);
    fs.TransferTo(verifier);

	// Signal end of data. The verifier will finish calculating
	// the digest, and compare the expected and calculated digests.
    verifier.MessageEnd();

    if (result)
        std::cout << "Verified hash on file" << std::endl;
    else
        std::cout << "Failed to verify hash on file" << std::endl;

    return 0;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.