Re: [cryptopp-users] HMACs of files
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
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
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; }