Skip to main content
Version: 0.1.23

AES GCM

AES GCM (Galois/Counter Mode) is an authenticated encryption with associated data (AEAD) mode. It provides both confidentiality and integrity in a single primitive: plaintext is encrypted using a variant of CTR mode, and a Galois-field authenticator is computed over the ciphertext and any associated data (AAD). No padding is required—plaintext and AAD can be any length.

How it works:

  • A 96-bit (12-byte) nonce is typically used to derive a per-message counter block.
  • Encryption is CTR-like: a keystream is generated by encrypting successive counter values and XORed with the plaintext.
  • The authentication tag is computed via GHASH over AAD (padded), ciphertext (padded), and length blocks, then encrypted with the block cipher.
  • Output is ciphertext plus a tag (e.g. 16 bytes); the tag must be verified in constant time on decrypt.

Security implications:
GCM provides confidentiality and authenticity. Nonce uniqueness is critical: reusing the same (key, nonce) for two different messages can expose the authentication key and allow forgeries. Use a counter or cryptographically random nonce; limit the number of encryptions per key per NIST/standard guidance. Tag verification must be constant-time to avoid timing attacks.

Recommended use cases:

  • Default choice for new symmetric encryption when AES is available (TLS 1.3, IPsec, storage, APIs).
  • Any scenario requiring authenticated encryption with optional cleartext metadata (AAD) that must be bound to the ciphertext.

Prefer AES-GCM (or ChaCha20-Poly1305 where AES-NI is unavailable) over unauthenticated or MAC-then-encrypt schemes for new designs.

When to use

  • Authenticated encryption (AEAD) for most new applications: TLS 1.3, IPsec, storage encryption, APIs. AES-GCM provides both confidentiality and integrity in one primitive.
  • When you need nonce-based encryption with a 96-bit nonce (12 bytes) and optional associated data (AAD), e.g. for headers or context that must be authenticated but not encrypted.

What to be careful of

  • Nonce must never repeat. Reusing the same (key, nonce) for two different messages can allow an attacker to recover the authentication key and forge ciphertexts. Use a counter or random 96-bit nonce; if random, ensure collision probability is negligible (e.g. limit number of encryptions per key).
  • Tag verification. Always verify the tag in constant time before using decrypted data. If verification fails, do not expose any part of the plaintext or error details that could aid an attacker.
  • AAD. Use AAD for any metadata that must be bound to the ciphertext (e.g. length, protocol version). AAD is not encrypted but is authenticated.

Practical deployment

  • Default choice for new symmetric encryption when AES is available: use a 256-bit key, 12-byte random or counter-based nonce, and 16-byte tag; include any context in AAD.
  • Key and nonce management: Rotate keys before reaching the recommended encryption limit (e.g. 2^32 messages per key with 96-bit random nonces, or follow NIST/standard guidance). Never reuse a nonce under the same key.
  • Hardware support: On platforms with AES-NI and CLMUL, GCM is fast. On very constrained or non-AES-NI systems, ChaCha20-Poly1305 can be a simpler or faster alternative.

API

noxtls_aes_gcm_encrypt

noxtls_return_t noxtls_aes_gcm_encrypt(const uint8_t *key, noxtls_aes_type_t type, const uint8_t nonce[12], const uint8_t *aad, uint32_t aad_len, const uint8_t *plaintext, uint32_t plaintext_len, uint8_t *ciphertext, uint8_t tag[16]);

Encrypt the data

Parameters:

  • key — is the key to use
  • type — is the type of the key
  • nonce — is the nonce to use
  • aad — is the AAD to use
  • aad_len — is the length of the AAD
  • plaintext — is the plaintext to encrypt
  • plaintext_len — is the length of the plaintext
  • ciphertext — is the ciphertext to encrypt
  • tag — is the tag to use

Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success, NOXTLS_RETURN_NULL if any required pointer is NULL

noxtls_aes_gcm_decrypt

noxtls_return_t noxtls_aes_gcm_decrypt(const uint8_t *key, noxtls_aes_type_t type, const uint8_t nonce[12], const uint8_t *aad, uint32_t aad_len, const uint8_t *ciphertext, uint32_t ciphertext_len, const uint8_t tag[16], uint8_t *plaintext);

Decrypt the data

Parameters:

  • key — is the key to use
  • type — is the type of the key
  • nonce — is the nonce to use
  • aad — is the AAD to use
  • aad_len — is the length of the AAD
  • ciphertext — is the ciphertext to decrypt
  • ciphertext_len — is the length of the ciphertext
  • tag — is the tag to use
  • plaintext — is the plaintext to decrypt

Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success, NOXTLS_RETURN_NULL if any required pointer is NULL, NOXTLS_RETURN_BAD_DATA if tag verification fails