Wei Dai wrote:
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.
    



  

>> 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.

Yes this is surprising because did not find any documentation on this :\
The FAQ-O-MATIC also does not provide nothing.
Well for now it is clear how it works.

Reply via email to