This is not a bug. I don't understand why you think it is. Of course if
you want to use ECB or CBC mode decryption with an external DES cipher
object, you'll need a DES decryption object rather than a DES encryption
object. Why is this surprising? Is it because CFB, OFB, and CTR modes use
a DES encryption object instead? That's because those modes actually uses
the DES cipher in the encryption direction even for decryption.
On Fri, Jun 25, 2004 at 07:39:08PM +0300, Cornel Maftuleac wrote:
>
> This is intresting, it seems to me that this should not work that way.
> I will try to explain how to reproduce this.
> Consider the following sample:
>
> #include <stdio.h>
> #include <cryptopp/dll.h>
> using namespace CryptoPP;
> #define EXTERN_CIPHERS
> int main()
> {
> AutoSeededRandomPool rng;
> unsigned char m_Key[DES::DEFAULT_KEYLENGTH];
> rng.GenerateBlock(m_Key,sizeof(m_Key));
>
> unsigned char m_iv[DES::BLOCKSIZE];
> rng.GenerateBlock(m_iv,sizeof(m_iv));
>
> #ifdef EXTERN_CIPHERS
> DES::Encryption cipher(m_Key,DES::DEFAULT_KEYLENGTH);
> StreamTransformation* cipherEncrypt = new
> ECB_Mode_ExternalCipher::Encryption(cipher,m_iv);
> StreamTransformation* cipherDecrypt = new
> ECB_Mode_ExternalCipher::Decryption(cipher,m_iv);
> #else
> StreamTransformation* cipherEncrypt = new
> ECB_Mode<DES>::Encryption(m_Key,DES::DEFAULT_KEYLENGTH,m_iv);
> StreamTransformation* cipherDecrypt = new
> ECB_Mode<DES>::Decryption(m_Key,DES::DEFAULT_KEYLENGTH,m_iv);
> #endif
>
> StreamTransformationFilter STFilterEncrypt(*cipherEncrypt,NULL);
> StreamTransformationFilter STFilterDecrypt(*cipherDecrypt,NULL);
>
> unsigned char plaintext[] = "1234567";
> unsigned char ciphertext[sizeof(plaintext)+DES::BLOCKSIZE]={0};
> unsigned char out_plaintext[sizeof(ciphertext)*3]={0};
>
>
> STFilterEncrypt.PutMessageEnd(plaintext,sizeof(plaintext));
> int ciphersize = STFilterEncrypt.MaxRetrievable();
> if(ciphersize>sizeof(ciphertext))printf("ERROR: buffer overrun\n");
> STFilterEncrypt.Get(ciphertext,ciphersize);
>
>
> STFilterDecrypt.PutMessageEnd(ciphertext,ciphersize);
> int out_plainsize = STFilterDecrypt.MaxRetrievable();
> if(out_plainsize>sizeof(out_plaintext))printf("ERROR: buffer
> overrun\n");
> STFilterDecrypt.Get(out_plaintext,out_plainsize);
>
>
> if(!memcmp(plaintext,out_plaintext,sizeof(plaintext)))
> printf("Decryption OK\n");
> else printf("Decryption FAILED\n");
>
>
> delete cipherEncrypt;
> delete cipherDecrypt;
>
> return 0;
> }
>
> ------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Here I used a macro to switch beetween externals/internal chipers, just
> undef the EXTERN_CIPHERS macro to switch.
> When working with internal chiper all is correct.
> External chipers by definition should work too, but when the encryption
> mode is: ECB or CBC (chipertext size multiple to block length) the
> result is not correct.
> For the code to work in ECB or CBC mode the following must be done:
>
> DES::Encryption cipher(m_Key,DES::DEFAULT_KEYLENGTH);
> here ---> DES::Decryption cipher_dec(m_Key,DES::DEFAULT_KEYLENGTH);
> StreamTransformation* cipherEncrypt = new
> ECB_Mode_ExternalCipher::Encryption(cipher,m_iv);
> StreamTransformation* cipherDecrypt = new
> ECB_Mode_ExternalCipher::Decryption(cipher_dec,m_iv);
>
> While for other modes no changes is required.