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.

Reply via email to