phalcon/cphalcon · error · MissingAuthData

Auth data must be provided when using AEAD mode

Error message

Auth data must be provided when using AEAD mode

What it means

For AEAD modes (gcm/ccm) Crypt::encryptGcmCcm() requires associated authentication data: it reads $this->authData (set via setAuthData()) and throws MissingAuthData if it is empty. GCM/CCM distinguish 'additional authenticated data' from the message itself, and Phalcon mandates it rather than defaulting to empty, so encrypted payloads always carry an AEAD context.

Source

Thrown at phalcon/Encryption/Crypt.zep:895

        string mode,
        string padded,
        string encryptKey,
        string iv
    ) -> string {
        var authData, authTag, authTagLength, cipher, encrypted;

        let cipher  = this->cipher,
            authTag = "";

        /**
         * If the mode is "gcm" or "ccm" and auth data has been passed call it
         * with that data
         */
        if true === this->checkIsMode(["ccm", "gcm"], mode) {
            let authData = this->authData;

            if true === empty(authData) {
                throw new MissingAuthData();
            }

            let authTag       = this->authTag,
                authTagLength = this->authTagLength;

            let encrypted = openssl_encrypt(
                padded,
                cipher,
                encryptKey,
                OPENSSL_RAW_DATA,
                iv,
                authTag,
                authData,
                authTagLength
            );

            let this->authTag = authTag;
        } else {

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Call $crypt->setAuthData($aad) before encrypting with a gcm/ccm cipher - use stable context such as the user id, record id, or app name so decryption can reproduce it exactly.
  2. The same auth data must be present (and identical) when decrypting - keep it alongside your configuration, not per-random values.
  3. If you have no meaningful AAD, prefer aes-256-cbc (with default HMAC signing) instead of passing dummy data - it sidesteps AEAD semantics entirely.

Example fix

// before
$crypt->setCipher('aes-256-gcm');
$crypt->setKey($key);
$token = $crypt->encrypt($payload); // MissingAuthData

// after
$crypt->setCipher('aes-256-gcm');
$crypt->setKey($key);
$crypt->setAuthData('user:' . $user->id);
$token = $crypt->encrypt($payload);
Defensive patterns

Strategy: validation

Validate before calling

if ($crypt->getAuthData() === '') {
    throw new \RuntimeException('AEAD cipher requires auth data - call setAuthData() before encrypt');
}
$cipherText = $crypt->encrypt($payload);

Type guard

function isAeadReady(\Phalcon\Encryption\Crypt $crypt): bool
{
    $mode = substr($crypt->getCipher(), -3); // 'gcm'/'ccm'

    return !in_array($mode, ['gcm', 'ccm'], true) || '' !== $crypt->getAuthData();
}

Try / catch

try {
    $token = $crypt->encrypt($payload);
} catch (\Phalcon\Encryption\Crypt\Exception\MissingAuthData $e) {
    throw new \RuntimeException('AEAD misconfigured: setAuthData() missing in Crypt setup', 0, $e);
}

Prevention

When it happens

Trigger: setCipher('aes-256-gcm') followed by encrypt() without ever calling setAuthData('...'); or setAuthData('') (empty string counts as empty). Decrypting never throws this - only the encrypt path checks.

Common situations: Switching a service from aes-256-cbc to aes-256-gcm without adding the new required call; copying example code that predates the auth-data requirement; config defining auth_data only in some environments.

Related errors


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/ab8823d803363d2a. Report an issue: GitHub.