> Unfortunately, it appears to have a bug. The unfortunate thing is the bug > appears to be in the Crypto++ library (modulo me doing something dumb).
Forgot to mention... The issue appears to lie somewhere in the HashVerificationFilter. On Saturday, April 4, 2015 at 10:54:42 PM UTC-4, Jeffrey Walton wrote: > > > I need to encrypt a stream (with a symmetric algorithm) > > and compute its HMAC at the same time. > > You have to be careful here. Combining a confidentiality mode with an > authenticity mode can cause some trouble if you combine them incorrectly. > Its probably best to use a mode that does it for you, like EAX, CCM or GCM > mode. > > Getting authenticated encryption wrong is easy. SSL/TLS and SSH got them > wrong, and they've been dealing with the associated bugs for decades. IPSec > got it right with Encrypt-Then-Authenticate. > > To have a chance at getting it right, you have to encrypt the data first > and then MAC it. That's what IPSec does. See > http://www.cryptopp.com/wiki/Authenticated_Encryption - private > <http://www.cryptopp.com/wiki/Authenticated_Encryption> for more details. > > > In Botan you do it with the Fork class. > > Crypto++ has a ChannelSwitch which allows you to take data and send it to > multiple sinks. But I don't think that's what you want in the is case. > > If you were doing authenticated encryption using Encrypt-And-Authenticate > (like SSH), then you could use the ChannelSwitch. > > > Is there an easy way to do that in crypto++, without going through it > twice > > Yes, just pipeline the data. Have the output of the encryptor feed the > HMAC. > > You can read more about pipelining at > http://www.cryptopp.com/wiki/Pipeline - private > <http://www.cryptopp.com/wiki/Pipeline>. > > > without going through it twice > > You will *always* have to touch the data twice. The only mode that > supports touching the data once is CWC mode. Its patented, so everything > else touches the data twice. > > With that out of the way, below is a program that kind of does what you > want. It streams plaintext data through and encryptor and then a HMAC. > Unfortunately, it appears to have a bug. The unfortunate thing is the bug > appears to be in the Crypto++ library (modulo me doing something dumb). > > I have not analyzed the stack trace, yet. I'm tossing it out there in case > someone else has time to look at it and develop a patch. > > ******** > > static const int DIGEST_SIZE = HMAC<SHA256>::DIGESTSIZE; > > SecByteBlock keys(16 /*AES key*/ + 16 /*AES IV*/ + 16 /*HMAC key*/); > OS_GenerateRandomBlock(false, keys, keys.size()); > > CBC_Mode<AES>::Encryption encryptor; > encryptor.SetKeyWithIV(keys.data() + 0 /*key*/, 16, keys.data() + 16 > /*iv*/, 16); > CBC_Mode<AES>::Decryption decryptor; > encryptor.SetKeyWithIV(keys.data() + 0 /*key*/, 16, keys.data() + 16 > /*iv*/, 16); > HMAC<SHA256> hmac1; > hmac1.SetKey(keys.data() + 32, 16); > HMAC<SHA256> hmac2; > hmac2.SetKey(keys.data() + 32, 16); > > HexEncoder encoder(new FileSink(cout)); > > cout << "AES key: "; > encoder.Put(keys.data() + 0, 16); > encoder.MessageEnd(); cout << endl; > > cout << "AES IV: "; > encoder.Put(keys.data() + 16, 16); > encoder.MessageEnd(); cout << endl; > > cout << "HMAC key: "; > encoder.Put(keys.data() + 32, 16); > encoder.MessageEnd(); cout << endl; > > string plain = "Now is the time for all good men to come to the aide of > their country"; > string cipher, recover; > > cout << plain << endl; > > // Encrypt with HMAC > > StringSource ss1(plain, true /*pumpAll*/, > new StreamTransformationFilter(encryptor, > new HashFilter(hmac1, > new > StringSink(cipher), > true > /*putMessage*/, > DIGEST_SIZE))); > > > cout << "Ciphertext+MAC: "; > encoder.Put((byte*)cipher.data(), cipher.size()); > encoder.MessageEnd(); cout << endl; > > // Decrypt with HMAC verification > > StringSource ss2(cipher, true /*pumpAll*/, > new HashVerificationFilter(hmac2, > new > StreamTransformationFilter(decryptor, > new StringSink(recover)), > HASH_AT_END | PUT_MESSAGE, > DIGEST_SIZE)); > > cout << recover << endl; > -- -- You received this message because you are subscribed to the "Crypto++ Users" Google Group. To unsubscribe, send an email to [email protected]. More information about Crypto++ and this group is available at http://www.cryptopp.com. --- 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]. For more options, visit https://groups.google.com/d/optout.
