From Crypto++ Wiki
Jump to navigation Jump to search
GCM Mode
#include <cryptopp/gcm.h>

GMAC is a special case of GCM Mode where data is only authenticated, and not encrypted and authenticated. GMAC uses a universal hash function which is not considered secure outside the context of GCM Mode.

GCM uses a key size of 128, 192 or 256 bits according to AES, and the block size of 128 bits. The initialization vector (iv) is restricted to lengths less than or equal to 264-1 in multiples of 8. You cannot use a symmetric cipher with a smaller block size because GCM was designed for 128-bit ciphers. For example, Blowfish, with a 64-bit block size, will not work.

Regarding the iv, SP 800-38D recommends limiting the iv to 96 bits or less to "promote interoperability, efficiency, and simplicity of design". And Microsoft's WinCrypt implementation only allows iv's of 96-bits or 128-bits. Also see How do I use AES-GMAC with a secret in BCrypt? on Stack Overflow.

GCM mode mode operates on both plain text data and additionally authenticated data called AAD. AAD data is only authenticated, and it is not encrypted. AAD is useful in some situations, like authenticating the fields of an IP packet when using IPsec. Obviously the source and destination addresses, and the source and destination ports cannot be encrypted for routing.

You can MAC a message using GMAC by only passing aad data. An example is shown below.

Sample Programs

#include "cryptlib.h"
#include "secblock.h"
#include "files.h"
#include "hex.h"

#include "aes.h"
#include "gcm.h"
#include "modes.h"

#include <iostream>
#include <string>

int main(int argc, char* argv[])
    using namespace CryptoPP;

    std::string message = "Yoda said, do or do not. There is no try.";

    SecByteBlock key(AES::DEFAULT_KEYLENGTH);
    SecByteBlock iv(AES::BLOCKSIZE);

    std::memset(key, 0x00, key.size());
    std::memset(iv,  0x00, iv.size());

    // Setup encryptor
    GCM<AES>::Encryption enc;
    enc.SetKeyWithIV(key, key.size(), iv, iv.size());

    // Setup filter
    AuthenticatedEncryptionFilter filter(enc);

    // Process message
    filter.ChannelPut(AAD_CHANNEL, (const byte*)&message[0], message.size());
    filter.ChannelMessageEnd( AAD_CHANNEL );

    // Signal end of all messages

    // Retrieve MAC
    size_t macSize = filter.MaxRetrievable();
    SecByteBlock mac(macSize);
    filter.Get( mac, mac.size());

    // Print parameters
    HexEncoder encoder(new FileSink(std::cout));

    std::cout << "Key: ";
    encoder.Put(key, key.size());
    std::cout << std::endl;

    std::cout << " IV: ";
    encoder.Put(iv, iv.size());
    std::cout << std::endl;

    std::cout << "Message: ";
    std::cout << message;
    std::cout << std::endl;

    std::cout << "GMAC: ";
    encoder.Put(mac, mac.size());
    std::cout << std::endl;

    return 0;

Running the program produces the following result.

$ ./test.exe 
Key: 00000000000000000000000000000000
 IV: 00000000000000000000000000000000
Message: Yoda said, do or do not. There is no try.


No downloads available.