title: Crypto++ symmetric algorithms and authenticated block modes combinations
body: <p>I've implemented a C++ wrapper library for <a href="http://cryptopp.com" rel="nofollow">Crypto++</a> v5.6.2 and have a question about combinations of symmetric algorithms (e. g. Blowfish) and block modes (e. g. GCM).</p>
  
  <p>I am able to encrypt and decrypt data via Blowfish/EAX, but I can't achieve the same by using Blowfish/GCM. AES/EAX and AES/GCM both work.</p>
  
  <p>The following simple application demonstrates my problem:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;string&gt;
  
  #include "cryptopp/blowfish.h"
  #include "cryptopp/filters.h"
  #include "cryptopp/eax.h"
  #include "cryptopp/gcm.h"
  #include "cryptopp/osrng.h"
  #include "cryptopp/hex.h"
  
  std::string encrypt(
      CryptoPP::AuthenticatedSymmetricCipher &amp;encryption,
      std::string const kPlainText,
      CryptoPP::SecByteBlock const kKey,
      unsigned const char * kIV) {
    std::string cipher_text;
  
    // TODO Is this the source of the problem?
    // BlockSize always returns 0 which leads to an exception if GCM block mode is used!
    std::cout &lt;&lt; encryption.BlockSize() &lt;&lt; " bytes" &lt;&lt; std::endl;
  
    encryption.SetKeyWithIV(
        kKey,
        kKey.size(),
        kIV
    );
  
    CryptoPP::StringSink *string_sink = new CryptoPP::StringSink(cipher_text);
    CryptoPP::BufferedTransformation *transformator = NULL;
  
    // The AuthenticatedEncryptionFilter adds padding as required.
    transformator = new CryptoPP::AuthenticatedEncryptionFilter(
        encryption,
        string_sink);
  
    bool const kPumpAll = true;
    CryptoPP::StringSource(
        kPlainText,
        kPumpAll,
        transformator);
  
    return cipher_text;
  }
  
  std::string decrypt(
      CryptoPP::AuthenticatedSymmetricCipher &amp;decryption,
      std::string const kCipherText,
      CryptoPP::SecByteBlock const kKey,
      unsigned const char * kIV) {
    std::string recovered_plain_text;
  
    decryption.SetKeyWithIV(
        kKey,
        kKey.size(),
        kIV);
  
    CryptoPP::StringSink *string_sink = new CryptoPP::StringSink(
        recovered_plain_text);
    CryptoPP::BufferedTransformation *transformator = NULL;
    CryptoPP::AuthenticatedDecryptionFilter *decryption_filter = NULL;
  
    decryption_filter = new CryptoPP::AuthenticatedDecryptionFilter(
        decryption,
        string_sink);
    transformator = new CryptoPP::Redirector(*decryption_filter);
  
    bool const kPumpAll = true;
    CryptoPP::StringSource(
        kCipherText,
        kPumpAll,
        transformator);
  
    return recovered_plain_text;
  }
  
  int main() {
    CryptoPP::AutoSeededRandomPool prng;
    CryptoPP::SecByteBlock key(CryptoPP::Blowfish::DEFAULT_KEYLENGTH);
    prng.GenerateBlock(key, key.size());
  
    byte iv[CryptoPP::Blowfish::BLOCKSIZE];
    prng.GenerateBlock(iv, sizeof(iv));
  
    // Creates templated mode objects of  block ciphers.
  
    // This works...
  //  CryptoPP::EAX&lt;CryptoPP::Blowfish&gt;::Encryption encryption;
  //  CryptoPP::EAX&lt;CryptoPP::Blowfish&gt;::Decryption decryption;
  
    // This does NOT work...
    CryptoPP::GCM&lt;CryptoPP::Blowfish&gt;::Encryption encryption;
    CryptoPP::GCM&lt;CryptoPP::Blowfish&gt;::Decryption decryption;
  
    std::string plain_text = "Block Mode Test";
    std::string cipher_text = encrypt(encryption, plain_text, key, iv);
    // terminate called after throwing an instance of 'CryptoPP::InvalidArgument'
    // what():  Blowfish/GCM: block size of underlying block cipher is not 16
  
    std::cout &lt;&lt; "cipher text: " &lt;&lt; std::hex &lt;&lt; cipher_text &lt;&lt; std::endl;
    std::cout &lt;&lt; "recovered plain text: " &lt;&lt; decrypt(decryption, cipher_text, key, iv) &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>A <code>CryptoPP::InvalidArgument</code> exception is thrown if running the code above with the following text:</p>
  
  <pre><code>Blowfish/GCM: block size of underlying block cipher is not 16
  </code></pre>
  
  <p>But when running the code instead with the block mode EAX, no exception is thrown. So my questions are:</p>
  
  <ul>
  <li>Does GCM only work with AES? Can GCM also be used with Blowfish or 3DES?</li>
  <li>Is there a matrix available which lists all possible combinations of symmetric algorithms with block modes?</li>
  <li>Or is this a bug in Crypto++? Because the method <code>BlockSize()</code> <strong>always</strong> returns <code>0</code> but the exception is only raised if using Blowfish (or 3DES) instead of AES. This seems to raise the exception mentioned.</li>
  </ul>