title: OpenSSL EVP_DecryptFinal_ex returns "wrong final block length" error when decrypting a file
body: <p>I am using the <code>EVP Symmetric Encryption and Decryption</code> algorithm to encrypt and decrypt a file of text.</p>
  
  <p>The encryption works file, a new encrypted file is generated, but when I try to decrypt the file back it always crashes when <code>EVP_DecryptFinal_ex</code> is called the first time.</p>
  
  <p>I am using two Visual Studio projects: one for encryption and one for decryption.<br>
  The libraries I am using I presumed they are build in DEBUG mode (because they have the .pdb files), so that is how my project is also build. (if I choose release mode, the compiler cannot find the openssl include header anymore).</p>
  
  <p>This is the error I get:  </p>
  
  <pre><code>digital envelope routines:EVP_DecryptFinal_ex:wrong final block length
  </code></pre>
  
  <p>I am using the C++11 version, here is my code:</p>
  
  <pre><code>void Cipher::Encrypt(const byte key[KEY_SIZE], const byte iv[BLOCK_SIZE], const secure_string&amp; ptext, secure_string&amp; ctext) {
      EVP_CIPHER_CTX_free_ptr ctx(EVP_CIPHER_CTX_new(), ::EVP_CIPHER_CTX_free);
      int rc = EVP_EncryptInit_ex(ctx.get(), EVP_aes_256_cbc(), NULL, key, iv);
      if (rc != 1)
          throw std::runtime_error("EVP_EncryptInit_ex failed");
  
      // Recovered text expands upto BLOCK_SIZE
      ctext.resize(ptext.size() + BLOCK_SIZE);
      int out_len1 = (int)ctext.size();
  
      rc = EVP_EncryptUpdate(ctx.get(), (byte*)&amp;ctext[0], &amp;out_len1, (const byte*)&amp;ptext[0], (int)ptext.size());
      if (rc != 1)
          throw std::runtime_error("EVP_EncryptUpdate failed");
  
      int out_len2 = (int)ctext.size() - out_len1;
      rc = EVP_EncryptFinal_ex(ctx.get(), (byte*)&amp;ctext[0] + out_len1, &amp;out_len2);
      if (rc != 1)
          throw std::runtime_error("EVP_EncryptFinal_ex failed");
  
      // Set cipher text size now that we know it
      ctext.resize(out_len1 + out_len2);
  }
  
  void Cipher::Decrypt(const byte key[KEY_SIZE], const byte iv[BLOCK_SIZE], const secure_string&amp; ctext, secure_string&amp; rtext) {
      EVP_CIPHER_CTX_free_ptr ctx(EVP_CIPHER_CTX_new(), ::EVP_CIPHER_CTX_free);
      int rc = EVP_DecryptInit_ex(ctx.get(), EVP_aes_256_cbc(), NULL, key, iv);
      if (rc != 1)
          throw std::runtime_error("EVP_DecryptInit_ex failed");
  
      // Recovered text contracts upto BLOCK_SIZEB
      rtext.resize(ctext.size());
      int out_len1 = (int)rtext.size();
  
      rc = EVP_DecryptUpdate(ctx.get(), (byte*)&amp;rtext[0], &amp;out_len1, (const byte*)&amp;ctext[0], (int)ctext.size());
      if (rc != 1)
          throw std::runtime_error("EVP_DecryptUpdate failed");
  
      int out_len2 = (int)rtext.size() - out_len1;
      rc = EVP_DecryptFinal_ex(ctx.get(), (byte*)&amp;rtext[0] + out_len1, &amp;out_len2);
      if (rc != 1) {
          ERR_print_errors_fp(stderr);
          throw std::runtime_error("EVP_DecryptFinal_ex failed");
      }
  
      // Set recovered text size now that we know it
      rtext.resize(out_len1 + out_len2);
  }
  int main(int argc, char* argv[])
  {
      // Load the necessary cipher
      EVP_add_cipher(EVP_aes_256_cbc());
  
      // create Cipher object
      Cipher cipher;
      ifstream f("d:/temp.YML");
      ofstream out("d:/tempDecrypt.YML");
  
      byte key[KEY_SIZE] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2};
      byte iv[BLOCK_SIZE] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6};
      //cipher.gen_params(key, iv);
  
      secure_string line;
      secure_string temp;
      while (getline(f, line)) {
          cipher.Decrypt(key, iv, line, temp);
          std::cout &lt;&lt; temp &lt;&lt; std::endl;
          out &lt;&lt; temp;
      }
  
      OPENSSL_cleanse(key, KEY_SIZE);
      OPENSSL_cleanse(iv, BLOCK_SIZE);
  
      return 0;
  }
  </code></pre>
  
  <p>I also read that it could be a padding issue, not sure if that is the case and what should I do. I am not that good with encryption.  </p>
  
  <p>Any pointers on how to proceed further would be welcomed. If you need more information let me know.</p>