title: Steps to decrypt encrypted data in Crypto++ in libgcrypt
body: <p>I need to decrypt the encrypted data by Crypto++ in libgcrypt due to C language restriction on target platform. So I've decided to use libgcrypt since it supporting the AES128 and GCM mode.</p>
  
  <p>In Crypto++, the data is encrypted this way:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>std::string encrypt_data(const std::string &amp;data,
                           const std::vector&lt;unsigned char&gt; &amp;iv,
                           const std::vector&lt;unsigned char&gt; &amp;key)
  {
      CryptoPP::GCM&lt;CryptoPP::AES&gt;::Encryption encryptor;
      encryptor.SetKeyWithIV(&amp;key[0], key.size(), &amp;iv[0]);
  
      std::string ciphertext;
      CryptoPP::StringSource ss( data, true,
                              new CryptoPP::AuthenticatedEncryptionFilter(
                                  encryptor,
                                  new CryptoPP::StringSink(ciphertext)
                                  )
                              );
  
      return ciphertext;
  }
  </code></pre>
  
  <p>and successfully decrypted this way:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>std::string decrypt_data(const std::string &amp;data,
                           const std::vector&lt;unsigned char&gt; &amp;iv,
                           const std::vector&lt;unsigned char&gt; &amp;key)
  {
      CryptoPP::GCM&lt;CryptoPP::AES&gt;::Decryption decryptor;
      decryptor.SetKeyWithIV(&amp;key[0], key.size(), &amp;iv[0]);
  
      std::string recovered;
      CryptoPP::StringSource ss( data, true,
                              new CryptoPP::AuthenticatedDecryptionFilter(
                                  decryptor,
                                  new CryptoPP::StringSink( recovered )
                                  )
                              );
  
      return recovered;
  }                       
  </code></pre>
  
  <p>But the decoded data is wrong when I try to decode <code>ciphertext</code> using libgcrypt by these steps:</p>
  
  <ol>
  <li><code>gcry_cipher_open()</code></li>
  <li><code>gcry_cipher_setkey()</code></li>
  <li><code>gcry_cipher_setiv()</code></li>
  <li>Seperate the cipher text and authentication tag</li>
  <li><code>gcry_cipher_decrypt(cipher text)</code></li>
  <li><code>gcry_cipher_checktag(authentication tag)</code></li>
  </ol>
  
  <p>Is there any steps I missed to replicate the Crypto++ decoding process?</p>
  
  <p>Gcrypt decryption code (Expected output <code>Decrypted cipher = password</code>):</p>
  
  <pre class="lang-c prettyprint-override"><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;gcrypt.h&gt;
  
  static unsigned char const aesSymKey[] = { 0x38, 0xb4, 0x8f, 0x1f, 0xcd, 0x63, 0xef, 0x32, 0xc5, 0xd1, 0x3f, 0x52, 0xbc, 0x4f, 0x5b, 0x24 };
  
  static unsigned char const aesIV[] = { 0xE4, 0xEF, 0xC8, 0x08, 0xEB, 0xB8, 0x69, 0x95, 0xF3, 0x44, 0x6C, 0xE9, 0x15, 0xE4, 0x99, 0x7E };
  
  static unsigned char const aesPass[] = { 0xda, 0x84, 0x3f, 0x01, 0xa0, 0x14, 0xfd, 0x85 };
  
  static unsigned char const aesTag[] = { 0xdf, 0x5f, 0x9f, 0xe2, 0x9d, 0x7e, 0xc3, 0xdf, 0x7a, 0x1e, 0x59, 0xd8, 0xe6, 0x61, 0xf7, 0x7e };
  
  #define GCRY_CIPHER GCRY_CIPHER_AES128
  #define GCRY_MODE GCRY_CIPHER_MODE_GCM
  
  int main(){
      gcry_error_t     gcryError;
      gcry_cipher_hd_t gcryCipherHd;
  
      if (!gcry_check_version(GCRYPT_VERSION))
       {
         fputs("libgcrypt version mismatch\n", stderr);
         exit(2);
       }
  
      gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
  
      gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
  
      if(!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P))
      {
          fputs("libgcrypt has not been initialized\n", stderr);
          abort();
      }
  
      size_t keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER);
      size_t blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER);
  
      char * outBuffer = malloc(blkLength);
  
      gcryError = gcry_cipher_open(
          &amp;gcryCipherHd, // gcry_cipher_hd_t *
          GCRY_CIPHER,   // int
          GCRY_MODE,     // int
          0);            // unsigned int
      if (gcryError)
      {
          printf("gcry_cipher_open failed:  %s/%s\n",
                 gcry_strsource(gcryError),
                 gcry_strerror(gcryError));
          return;
      }
  
      gcryError = gcry_cipher_setkey(gcryCipherHd, aesSymKey, keyLength);
      if (gcryError)
      {
          printf("gcry_cipher_setkey failed:  %s/%s\n",
                 gcry_strsource(gcryError),
                 gcry_strerror(gcryError));
          return;
      }
  
      gcryError = gcry_cipher_setiv(gcryCipherHd, aesIV, blkLength);
      if (gcryError)
      {
          printf("gcry_cipher_setiv failed:  %s/%s\n",
                 gcry_strsource(gcryError),
                 gcry_strerror(gcryError));
          return;
      }
  
      gcryError = gcry_cipher_decrypt(
          gcryCipherHd, // gcry_cipher_hd_t
          outBuffer,    // void *
          blkLength,    // size_t
          aesPass,      // const void *
          8);           // size_t
      if (gcryError)
      {
          printf("gcry_cipher_decrypt failed:  %s/%s\n",
                 gcry_strsource(gcryError),
                 gcry_strerror(gcryError));
          return;
      }
  
      gcryError = gcry_cipher_checktag(
          gcryCipherHd,
          aesTag,
          blkLength);
      if (gcryError)
      {
          printf("gcry_cipher_checktag failed:  %s/%s\n",
                 gcry_strsource(gcryError),
                 gcry_strerror(gcryError));
          return;
      }
  
      printf("Decrypted cipher = %s\n", outBuffer);
  
      // clean up after ourselves
      gcry_cipher_close(gcryCipherHd);
      free(outBuffer);
  
      return 0;
  }
  </code></pre>
  
  <p>EDIT: Just to be clear, the steps to decrypt I'm searching for is for the <code>ciphertext</code> output of the Crypto++ encryption function shown above; the <code>encrypt_data()</code>. So I won't accept any answer where it can't be applied to successfully decrypt <code>ciphertext</code>.</p>