1

I am writing an application using the crypto++ library. For those not familiar with it, the ECB_Mode template classes inherit from CipherModeBase. The program compiles and runs, but the output I am getting is incorrect. When I call the encryption method from the cipher_object, it doesn't work the same way as if I use an ECB_Mode object directly. I have verified that the options object instance variables are getting assigned correctly. I would like to create the instances within an if_then_else structure or switch_case so I can keep the code nice and DRY. What am I doing wrong?

Here is what I am trying but doesn't work:

    CipherModeBase *cipher_object;
    cipher_object == NULL;

    if(options->cipher == BS_AES)
    {
        ECB_Mode<AES >::Encryption ecbEncryption(options->key, options->keylen);
        cipher_object = &ecbEncryption;
    }
    else if(options->cipher == BS_TWOFISH)
    {
        ECB_Mode<Twofish >::Encryption ecbEncryption(options->key, options->keylen);
        cipher_object = &ecbEncryption;     
    }
cipher_object->processData(args);

Here is what does work:

ECB_Mode<AES >::Encryption ecbEncryption(options->key, options->keylen);
ecbEncryption.processData(args);

PS. I know not to use ECB mode. I just don't want to mess with IVs until I can get everything working. I am also relatively inexperienced with C++.

2 Answers 2

2

Your ecbEncryption objects are declared on the stack within the if and else scopes. (Scopes are the things enclosed by curly brackets).

An object will be destroyed when the scope it was declared in exits. So, the object you're calling processData on has been deleted before you call that method. Clearly that won't work.

One option is you could declare the objects on the heap instead of the stack. That way the lifetime could be controlled to work the way you want.

Try to use a std::unique_ptr for the cipher_object instead of a raw pointer. Then, in the if and else clauses assign to it like:

cipher_object.reset( new ECB_Mode<AES>::Encryption(options->key, options->keylen) );

Then the object will remain on the heap until the end of the cipher_object's scope, at which point the unique_ptr will delete it for you. And, the cipher_object's scope will last until after you call any methods on it.

Sign up to request clarification or add additional context in comments.

Comments

1

Here:

cipher_object == NULL;

if(options->cipher == BS_AES)
{
    // v
    ECB_Mode<AES >::Encryption ecbEncryption(options->key, options->keylen);
    cipher_object = &ecbEncryption;
}

ecbEncryption is local to that scope. You are storing the address of a local, and using it after it goes out of scope. That's undefined behaviour. You should allocate it on the heap using the new keyword:

if(options->cipher == BS_AES)
{
    cipher_object = new ECB_Mode<AES >::Encryption(options->key, options->keylen);
}

You should do the same for the other if statement.

Also note that this:

cipher_object == NULL;

Should be changed to this:

cipher_object = NULL;

The problem should be solved using the above code, though.

2 Comments

Thanks! It worked. Good catch on the comparison operator, maybe its time to take a break...
You will also need to remember to "delete cipher_object" after you have finished using it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.