Search code examples
c++aesaccess-violationcrypto++

Exception thrown: write access violation. this was 0xDDDDDDDD


I'm trying to encrypt a string using AES encryption provided by Crypto++ library API, version 5.6.0, linked statically

string AESEncryptor::encrypt(const string& plain)
{
    string ciphertext_buffer;

    // Hex decode symmetric key:
    HexDecoder decoder;
    decoder.Put((byte *)PRIVATE_KEY, 32 * 2);
    decoder.MessageEnd();
    word64 size = decoder.MaxRetrievable();
    char *decoded_key = new char[size];
    decoder.Get(reinterpret_cast<byte*>(decoded_key), size);

    // Generate Cipher, Key, and CBC
    byte key[AES::MAX_KEYLENGTH], iv[AES::BLOCKSIZE];
    StringSource(reinterpret_cast<const char *>(decoded_key), true, 
        new HashFilter(*(new SHA256), new ArraySink(key, AES::MAX_KEYLENGTH)));
    memset(iv, 0x00, AES::BLOCKSIZE);

    CBC_Mode<AES>::Encryption Encryptor(key, sizeof(key), iv);
    StringSource(plain, true, 
        new StreamTransformationFilter(Encryptor, new HexEncoder(new StringSink(ciphertext_buffer))));
    return ciphertext_buffer;
}

On the function exit I'm receiving the following exception, while trying to call the std::string move constructor to return the value:

Exception thrown: write access violation. this was 0xDDDDDDDD.

Looked like StringSink "owns" returned std::string some way and deletes it before trying to return, however I tried to assign it to another std::string and got the same exception.

Same exception appears while returning any other string, so it seems memory corrupted some way


Solution

  • StringSource(plain, true, 
        new StreamTransformationFilter(Encryptor,
            new HexEncoder(new StringSink(ciphertext_buffer))));
    
    return ciphertext_buffer;
    

    This code is mostly OK, but you should avoid the anonymous declarations.

    Exception thrown: write access violation. this was 0xDDDDDDDD.
    

    0xDDDDDDDD is the "dead memory" bit pattern There's quite a few issues with the code, and its hard to say which is causing you to use the dead memory. Maybe PRIVATE_KEY is smaller than 32 * 2 bytes?

    You should do four things:

    • Upgrade to Crypto++ 5.6.4 (5.6.0 is from 2009)
    • Turn on memory checking with flags like _CRTDBG_LEAK_CHECK_DF (see test.cpp and main for an example)
    • Stop using anonymous declarations (I've seen destructors run too soon because of them)
    • Use EAX Mode sample code from the Crypto++ wiki as a starting point

    // Generate Cipher, Key, and CBC
    byte key[AES::MAX_KEYLENGTH], iv[AES::BLOCKSIZE];
    StringSource(reinterpret_cast<const char *>(decoded_key), true, 
        new HashFilter(*(new SHA256), new ArraySink(key, AES::MAX_KEYLENGTH)));
    

    Use HKDF from Crypto++ 5.6.3 and above.


    memset(iv, 0x00, AES::BLOCKSIZE);
    

    I believe this destroys some of CBC's security properties. You should use an Authenticated Encryption mode. It relieves you of some of the details, like generating random IVs. It also has better security properties than CBC alone.