The problem turned out to be in CryptStreamBuffer::GetNextChar() and
was fixed by replacing:

// If there are no more bytes currently available then pump the source
if (m_StreamTransformationFilter->MaxRetrievable() == 0) {
    m_Source->Pump(1024);
}

With the following which ewnsure that the last few bytes are
processed:

// If there are no more bytes currently available from the filter then
// pump the source.
if (m_StreamTransformationFilter->MaxRetrievable() == 0) {
    if (0 == m_Source->Pump(1024)) {
        // This seems to be required to ensure the final bytes are
readable
        // from the filter.
        m_StreamTransformationFilter-
>ChannelMessageEnd(CryptoPP::DEFAULT_CHANNEL);
    }
}

Tom

On Jun 16, 6:46 pm, Don <donfai...@gmail.com> wrote:
> here is your answer.
> It has to do with the cipher that you picked.
>
> "ECB Mode is electronic codebook. ECB was originally specified by NIST
> in FIPS 81. The standard, issued in 1981, only offers confidentiality.
> Other modes, such as CCM and GCM, offer authenticated encryption which
> places an integrity assurance over the encrpyted data.
>
> <B>ECB mode does not use an IV, and the plain text must be padded to
> the block size of the cipher</B>. For additional information on this
> mode, see Block Cipher Modes of Operation. "
>
> On Jun 16, 12:05 pm, Don <donfai...@gmail.com> wrote:
>
> > Hi
> > I compiled your code and your stopping on the last BLOCKSIZE boundary.
> > Bet your losing the remainder and only getting even BLOCKSIZE out put.
>
> > In other words your not losing 16 bytes your losing the last < 16
> > bytes.
>
> > don
>
> > I will see if I can find out why.
>
> > On Jun 11, 10:54 am, Tom <thw...@ntlworld.com> wrote:
>
> > > Hi,
>
> > > To answer my own previous question (http://groups.google.com/group/
> > > cryptopp-users/browse_thread/thread/721dbd6fa5992a57) I wrote the code
> > > given at the end of this post.
>
> > > However it appears that DecryptFile() is not attempting to decrypt the
> > > last 16 bytes (block size) of the encrypted file. Can anybody tell me
> > > what I am doing wrong?
>
> > > Yours truly,
>
> > > Tom
>
> > > ---------------------------------------------------------------------------­­-----
>
> > > // Runtime Includes
> > > #include <iostream>
>
> > > // Crypto++ Includes
> > > #include "aes.h"
> > > #include "modes.h"      // xxx_Mode< >
> > > #include "filters.h"    // StringSource and
> > >                         // StreamTransformation
> > > #include "files.h"
>
> > > using namespace std;
>
> > > class CryptStreamBuffer: public std::streambuf {
>
> > > public:
>
> > >     CryptStreamBuffer(istream& encryptedInput,
> > > CryptoPP::StreamTransformation& c);
>
> > >     CryptStreamBuffer(ostream& encryptedOutput,
> > > CryptoPP::StreamTransformation& c);
>
> > > protected:
> > >     virtual int_type overflow(int_type ch = traits_type::eof());
>
> > >     virtual int_type uflow();
>
> > >     virtual int_type underflow();
>
> > >     virtual int_type pbackfail(int_type ch);
>
> > >     virtual int sync();
>
> > > private:
> > >     int GetNextChar();
>
> > >     int m_NextChar; // Buffered character
>
> > >     CryptoPP::StreamTransformationFilter*
> > > m_StreamTransformationFilter;
>
> > >     CryptoPP::FileSource* m_Source;
>
> > >     CryptoPP::FileSink* m_Sink;
>
> > > }; // class CryptStreamBuffer
>
> > > CryptStreamBuffer::CryptStreamBuffer(istream& encryptedInput,
> > > CryptoPP::StreamTransformation& c) :
> > >     m_NextChar(traits_type::eof()),
> > >     m_StreamTransformationFilter(0),
> > >     m_Source(0),
> > >     m_Sink(0) {
>
> > >     m_StreamTransformationFilter = new
> > > CryptoPP::StreamTransformationFilter(c);
> > >     m_Source = new CryptoPP::FileSource(encryptedInput, false,
> > > m_StreamTransformationFilter);
>
> > > }
>
> > > CryptStreamBuffer::CryptStreamBuffer(ostream& encryptedOutput,
> > > CryptoPP::StreamTransformation& c) :
> > >     m_NextChar(traits_type::eof()),
> > >     m_StreamTransformationFilter(0),
> > >     m_Source(0),
> > >     m_Sink(0) {
>
> > >     m_Sink = new CryptoPP::FileSink(encryptedOutput);
> > >     m_StreamTransformationFilter = new
> > > CryptoPP::StreamTransformationFilter(c, m_Sink);
>
> > > }
>
> > > CryptStreamBuffer::int_type CryptStreamBuffer::overflow(int_type ch) {
>
> > >     return m_StreamTransformationFilter->Put((byte)ch);
>
> > > }
>
> > > CryptStreamBuffer::int_type CryptStreamBuffer::uflow() {
>
> > >     int_type result = GetNextChar();
>
> > >     // Reset the buffered character
> > >     m_NextChar = traits_type::eof();
>
> > >     return result;
>
> > > }
>
> > > CryptStreamBuffer::int_type CryptStreamBuffer::underflow() {
>
> > >     return GetNextChar();
>
> > > }
>
> > > CryptStreamBuffer::int_type CryptStreamBuffer::pbackfail(int_type ch)
> > > {
>
> > >     return traits_type::eof();
>
> > > }
>
> > > int CryptStreamBuffer::sync() {
>
> > >     if (m_Sink) {
> > >         m_StreamTransformationFilter->MessageEnd();
> > >     }
>
> > > }
>
> > > int CryptStreamBuffer::GetNextChar() {
>
> > >     // If we have a buffered character do nothing
> > >     if (m_NextChar != traits_type::eof()) {
> > >         return m_NextChar;
> > >     }
>
> > >     // If there are no more bytes currently available then pump the
> > > source
> > >     if (m_StreamTransformationFilter->MaxRetrievable() == 0) {
> > >         m_Source->Pump(1024);
> > >     }
>
> > >     // Retrieve the next byte
> > >     byte nextByte;
> > >     size_t noBytes = m_StreamTransformationFilter->Get(nextByte);
> > >     if (0 == noBytes) {
> > >         return traits_type::eof();
> > >     }
>
> > >     // Buffer up the next character
> > >     m_NextChar = nextByte;
>
> > >     return m_NextChar;
>
> > > }
>
> > > void InitKey(byte key[]) {
>
> > >     key[0] = -62;
> > >     key[1] = 102;
> > >     key[2] = 78;
> > >     key[3] = 75;
> > >     key[4] = -96;
> > >     key[5] = 125;
> > >     key[6] = 66;
> > >     key[7] = 125;
> > >     key[8] = -95;
> > >     key[9] = -66;
> > >     key[10] = 114;
> > >     key[11] = 22;
> > >     key[12] = 48;
> > >     key[13] = 111;
> > >     key[14] = -51;
> > >     key[15] = 112;
>
> > > }
>
> > > void DecryptFile(const char* sourceFileName, const char* destFileName)
> > > {
>
> > >     ifstream ifs(sourceFileName, ios::in | ios::binary);
> > >     ofstream ofs(destFileName, ios::out | ios::binary);
>
> > >     byte key[CryptoPP::AES::DEFAULT_KEYLENGTH];
> > >     InitKey(key);
> > >     CryptoPP::ECB_Mode<CryptoPP::AES>::Decryption decryptor(key,
> > > sizeof(key));
>
> > >     if (ifs) {
> > >         if (ofs) {
> > >             CryptStreamBuffer cryptBuf(ifs, decryptor);
> > >             std::istream decrypt(&cryptBuf);
>
> > >             int c;
> > >             while (EOF != (c = decrypt.get())) {
> > >                 ofs << (char)c;
> > >             }
> > >             ofs.flush();
> > >         }
> > >         else {
> > >             std::cerr << "Failed to open file '" << destFileName <<
> > > "'." << endl;
> > >         }
> > >     }
> > >     else {
> > >         std::cerr << "Failed to open file '" << sourceFileName << "'."
> > > << endl;
> > >     }
>
> > > }
>
> > > void EncryptFile(const char* sourceFileName, const char* destFileName)
> > > {
>
> > >     ifstream ifs(sourceFileName, ios::in | ios::binary);
> > >     ofstream ofs(destFileName, ios::out | ios::binary);
>
> > >     byte key[CryptoPP::AES::DEFAULT_KEYLENGTH];
> > >     InitKey(key);
>
> > >     CryptoPP::ECB_Mode<CryptoPP::AES>::Encryption encryptor(key,
> > > sizeof(key));
>
> > >     if (ifs) {
> > >         if (ofs) {
> > >             CryptStreamBuffer cryptBuf(ofs, encryptor);
> > >             std::ostream encrypt(&cryptBuf);
>
> > >             int c;
> > >             while (EOF != (c = ifs.get())) {
> > >                 encrypt << (char)c;
> > >             }
> > >             encrypt.flush();
> > >         }
> > >         else {
> > >             std::cerr << "Failed to open file '" << destFileName <<
> > > "'." << endl;
> > >         }
> > >     }
> > >     else {
> > >         std::cerr << "Failed to open file '" << sourceFileName << "'."
> > > << endl;
> > >     }
>
> > > }
>
> > > int main(int argc, char* argv[])
> > > {
> > >     EncryptFile(argv[1], "encrypted.out");
> > >     DecryptFile("encrypted.out", "decrypted.out");
> > >     return 0;
>
> > > }
>
> > > ---------------------------------------------------------------------------­­------
> > >  Hide quoted text -
>
> > - Show quoted text -

-- 
You received this message because you are subscribed to the "Crypto++ Users" 
Google Group.
To unsubscribe, send an email to cryptopp-users-unsubscr...@googlegroups.com.
More information about Crypto++ and this group is available at 
http://www.cryptopp.com.

Reply via email to