Re: [cryptopp-users] HMACs of files

2021-09-08 Thread Jeffrey Walton
On Wed, Sep 8, 2021 at 6:46 AM Jeffrey Walton  wrote:
>
> On Tue, Sep 7, 2021 at 7:45 AM Tom  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.

Here is the documentation:
https://www.cryptopp.com/wiki/HashVerificationFilter#String_and_File_Sources

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 cryptopp-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/cryptopp-users/CAH8yC8mgQkpX-emDh9mnvXALTbKpDCFcTbuGGjRF2EEh%2BPK0CA%40mail.gmail.com.


Re: [cryptopp-users] HMACs of files

2021-09-08 Thread Jeffrey Walton


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  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 cryptopp-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/cryptopp-users/a36821f1-3d7a-46ec-9b6f-1618ab1ded53n%40googlegroups.com.
#include 
#include 

#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(, 
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;
}


Re: [cryptopp-users] HMACs of files

2021-09-08 Thread Jeffrey Walton
On Tue, Sep 7, 2021 at 7:45 AM Tom  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.
Instead of PUT_RESULT (or THROW), I used PUT_HASH to see the hash that
was calculated during verification. When using PUT_HASH, the
calculated digest has 32 0's appending to it. So the calculated digest
in the example program is
AD7FACB2586FC6E966C004D7D1D16B024F5805FF7CB47C7A85DABD8B48892CA7
.

I'll add the example to the wiki once I get the problem sorted out.

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 cryptopp-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/cryptopp-users/CAH8yC8nio-zV0CTMp7ttUPCxL%2B%2BfvbGOcJpZevHn_v7nq9G4mQ%40mail.gmail.com.
#include 
#include 

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

using namespace CryptoPP;

class CombinedSource : public Source
{
public:
// Pumps s1 first, and then s2
CombinedSource(Source& s1, Source& s2, bool pumpAll,
BufferedTransformation* attachment)
: Source(attachment), m_s1(s1), m_s2(s2) {
if (pumpAll)
PumpAll();
}

virtual size_t Pump2(lword , bool blocking=true)
{
std::cout << "Pump2: " << byteCount << std::endl;

if (byteCount)
m_s1.TransferTo2(*AttachedTransformation(), byteCount, 
DEFAULT_CHANNEL, blocking);

if (byteCount)
m_s2.TransferTo2(*AttachedTransformation(), byteCount, 
DEFAULT_CHANNEL, blocking);

return static_cast(byteCount);
}

virtual size_t PumpMessages2(unsigned int , bool blocking=true)
{
std::cout << "PumpMessages2: " << messageCount << std::endl;

if (messageCount)
m_s1.TransferMessagesTo2(*AttachedTransformation(), messageCount, 
DEFAULT_CHANNEL, blocking);

if (messageCount)
m_s2.TransferMessagesTo2(*AttachedTransformation(), messageCount, 
DEFAULT_CHANNEL, blocking);

return messageCount;
}

virtual bool SourceExhausted() const {
return m_s1.SourceExhausted() && m_s2.SourceExhausted();
}

private:
Source _s1, _s2;
};

int main(int argc, char* argv[])
{
// 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 hash on the file
FileSource("zero.dat", true, new HashFilter(sha256, new 
StringSink(digest)));

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

StringSource ss(digest, true);
FileSource fs("zero.dat", true);

byte result = 0;
std::string digest2;
CombinedSource cs(ss, fs, true,
new HashVerificationFilter(sha256,
// new ArraySink(, sizeof(result;
new StringSink(digest2), 4));

std::cout << "Digest: ";
StringSource(digest2, true, new HexEncoder(new FileSink(std::cout)));
std::cout << std::endl;

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

return 0;
}