> /* one-time initialization */ > ERR_load_crypto_strings(); > OpenSSL_add_all_algorithms(); > EVP_CIPHER_CTX_init(&enc_ctx); > EVP_CIPHER_CTX_init(&dec_ctx); > EVP_EncryptInit_ex(&enc_ctx, EVP_aes_256_cbc(), NULL, key, iv); > EVP_CIPHER_CTX_set_padding(&enc_ctx, 0); > EVP_DecryptInit_ex(&dec_ctx, EVP_aes_256_cbc(), NULL, key, iv); > EVP_CIPHER_CTX_set_padding(&dec_ctx, 0); > > /* encrypt first block */ > EVP_EncryptUpdate(&enc_ctx, block1, &outlen, block1, 4096); > /* encrypt second block */ > EVP_EncryptUpdate(&enc_ctx, block2, &outlen, block2, 4096); > > /* decrypt second block */ > EVP_DecryptUpdate(&dec_ctx, block2, &outlen, block2, 4096); > /* decrypt first block */ > EVP_DecryptUpdate(&dec_ctx, block1, &outlen, block1, 4096); > > The above code produces wrong data for block2. One of the following > seems to fix this problem. But is there any way to use CBC without > repeated calls to EVP_EncryptInit_ex/EVP_DecryptInit_ex? > > 1. Call EVP_EncryptInit_ex/EVP_DecryptInit_ex before each > EVP_EncryptUpdate/EVP_DecryptUpdate. > 2. Replace EVP_aes_256_cbc() with EVP_aes_256_ecb().
To my understanding : With ECB, the order in which the blocks are crypted/decrypted doesn't matter. With CBC and most block modes, it DOES matter ! So if block 1 is encrypted first it MUST be decrypted first. /* decrypt second block */ EVP_DecryptUpdate(&dec_ctx, block2, &outlen, block2, 4096); /* decrypt first block */ EVP_DecryptUpdate(&dec_ctx, block1, &outlen, block1, 4096); is WRONG EVP_DecryptUpdate(&dec_ctx, block1, &outlen, block1, 4096); EVP_DecryptUpdate(&dec_ctx, block2, &outlen, block2, 4096); should work better