In an implementation of AEAD_AES_128_GCM, if the AAD is defined as a "zero-length octet sequence", is it necessary to call the encryption code that adds an AAD at all? In particular, does an OpenSSL/LibreSSL libcrypto client need the EVP_En/DecryptUpdate
invocation that adds the AAD, if its length is 0?
I'm working on an implementation of RFC 8188, a protocol for encrypting HTTP messages with AEAD_AES_128_GCM, which has this to say:
The additional data passed to each invocation of AEAD_AES_128_GCM is
a zero-length octet sequence.
Currently my test code (just in a mockup stage) has this:
static const unsigned char *aad = (const void *)&aad;
static const int aad_len = 0;
#if 0
/* XXX not sure if this is necessary, examples work with & without */
if (EVP_DecryptUpdate(&ctx, NULL, &len, aad, aad_len) != 1) {
ERR("decryption: adding aad");
return -1;
}
#endif
The resulting code produces the expected decryptions and intermediate values for the examples in chapter 3 of the RFC. As you can see, this part is #if 0
-d out, so in fact nothing is done to add an AAD.
Since this may seem like a remarkably silly question (already I'm pre-emptively embarrassed), let me explain why I'm asking:
The RFC has all of two examples, both of which decrypt ciphertext to "I am the walrus" (with two different record sizes). So the "it works" result may be a lucky accident of sparse test data.
Since the RFC goes to the trouble of saying "zero-length octet sequence", rather than something like "there is no AAD", it feels like there might be a reason for putting it that way.
An assumption on my part, a crypto layman, that "it's zero-length so I don't have to do anything" feels like the sort of thing that leads to errors and insecurity in code that uses cryptography. Operations on zero-length structures don't always mean the same thing as "do nothing" (consider SHA hashes of the empty string).
So I thought I'd ask others if there might be more going on here than meets the eye.