VoodooPad's ETM-AEAD provides an AEAD cipher (Authenticated Encryption with Authenticated Data) based on the composition of an unauthenticated block cipher and HMAC.
VoodooPad's implementation of ETM-AEAD is based on the composition of well-understood standards and recommendations:
To prevent padding oracle attacks, as well as to decrease the potential attack surface of the application, ETM-AEAD uses encrypt-then-MAC for all authenticated encrypted data.
This choice of standards for ETM-AEAD was based on their industry prevalence, availability in platform-standard cryptography libraries, and NIST recommendation's for our use cases. While an authenticating encryption mode such as CCM may be preferable from an implementation perspective, platform support is lacking: neither Mac OS X nor iOS ship with support for an authenticated encryption mode in the standard system libraries.
This specification defines the implementation of authenticated encryption with associated data based on the composition of AES-CBC with PKCS#7 padding, with HMAC providing encrypt-then-MAC authentication.
This specification does not define the mechanism by which the encryption and authentication keys are acquired, nor the use of a specific AES key size or HMAC cryptographic hash function.
The specification of encryption and decryption assumes the following definitions:
ASSOC_DATA_LEN: Length of the associated data.
ENC_KEY: AES encryption key.
ENC_IV: AES-CBC IV.
MAC_KEY: HMAC secret.
||: Denotes concatenation.
To perform encryption:
ENC_PRIVATE_DATA = aes-cbc-encrypt(ENC_KEY, ENC_IV, pkcs7_pad(PRIVATE_DATA))
HMAC_INPUT = ENC_IV || ENC_PRIVATE_DATA || ASSOC_DATA || ASSOC_DATA_LEN
HMAC = hmac(MAC_KEY, HMAC_INPUT)
The decryption process operates on inputs ENC_KEY, ENC_IV, MAC_KEY, ASSOC_DATA_LEN, and ciphertext value C (as emitted by the encryption process)
To perform decryption of ciphertext C:
HMAC_INPUT = ENC_IV || C.ENC_PRIVATE_DATA || C.ASSOC_DATA || ASSOC_DATA_LEN
HMAC = hmac(MAC_KEY, HMAC_INPUT)
if (!constant_time_compare(HMAC, C.HMAC)) return E_INVALID_HMAC;
To ensure the initial bytes of ASSOC_DATA are not interpreted as the final bytes of ENC_PRIVATE_DATA, the original length of ENC_PRIVATE_DATA must be computed from ASSOC_DATA_LEN.
Using the input length computed in step #3, the plaintext representation of ENC_PRIVATE_DATA is decrypted:
PADDED_PRIVATE_DATA = aes-cbc-decrypt(ENC_KEY, ENC_IV, ENC_PRIVATE_DATA).
PRIVATE_DATA = pkcs7_unpad(PADDED_PRIVATE_DATA)
This section defines a non-mandatory byte-level serialization format for use with ETM-AEAD.
This serialization format is defined using ABNF notation, as specified in RFC 5234. All terminal rules are binary encoded, without padding unless otherwise specified. All multi-byte integers MUST be stored in little-endian format.
aead_data = aes_iv
assoc_data_len
enc_private_data
assoc_data
hmac
aes_iv = *OCTET ; AES-CBC IV used to encrypt enc_private_data
enc_private_data = *OCTET ; AES-CBC-PKCS7 encrypted ENC_PRIVATE_DATA
assoc_data = *OCTET ; HMAC-authenticated, unencrypted ASSOC_DATA
assoc_data_len = UINT64 ; The size of assoc_data, in bytes.
hmac = *OCTET ; HMAC computed as per the ETM-AEAD specification.