Fix docs for EVP_Cipher given an AEAD.
For AEADs (our only EVP_CIPH_FLAG_CUSTOM_CIPHER is GCM), EVP_Cipher is
not a one-shot operation. It is a thin wrapper over the internal
cipher callback in the EVP_CIPHER, complete with treating in == NULL as
EVP_CipherFinal_ex. Also document that you should not do this.
Also document how you feed in the AAD for an AEAD EVP_CIPHER. (Although
callers really should use EVP_AEAD for a much less complex interface.)
Bug: 494
Change-Id: I0beb1c88cdf0406506af2772e53e9d3f8d07172a
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/52727
Commit-Queue: Bob Beck <bbe@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
diff --git a/include/openssl/cipher.h b/include/openssl/cipher.h
index c19b78d..380d25d 100644
--- a/include/openssl/cipher.h
+++ b/include/openssl/cipher.h
@@ -174,6 +174,11 @@
// of output bytes may be up to |in_len| plus the block length minus one and
// |out| must have sufficient space. The number of bytes actually output is
// written to |*out_len|. It returns one on success and zero otherwise.
+//
+// If |ctx| is an AEAD cipher, e.g. |EVP_aes_128_gcm|, and |out| is NULL, this
+// function instead adds |in_len| bytes from |in| to the AAD and sets |*out_len|
+// to |in_len|. The AAD must be fully specified in this way before this function
+// is used to encrypt plaintext.
OPENSSL_EXPORT int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out,
int *out_len, const uint8_t *in,
int in_len);
@@ -191,6 +196,11 @@
// output bytes may be up to |in_len| plus the block length minus one and |out|
// must have sufficient space. The number of bytes actually output is written
// to |*out_len|. It returns one on success and zero otherwise.
+//
+// If |ctx| is an AEAD cipher, e.g. |EVP_aes_128_gcm|, and |out| is NULL, this
+// function instead adds |in_len| bytes from |in| to the AAD and sets |*out_len|
+// to |in_len|. The AAD must be fully specified in this way before this function
+// is used to decrypt ciphertext.
OPENSSL_EXPORT int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out,
int *out_len, const uint8_t *in,
int in_len);
@@ -204,16 +214,18 @@
OPENSSL_EXPORT int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out,
int *out_len);
-// EVP_Cipher performs a one-shot encryption/decryption operation. No partial
-// blocks are maintained between calls. However, any internal cipher state is
-// still updated. For CBC-mode ciphers, the IV is updated to the final
-// ciphertext block. For stream ciphers, the stream is advanced past the bytes
-// used. It returns one on success and zero otherwise, unless |EVP_CIPHER_flags|
-// has |EVP_CIPH_FLAG_CUSTOM_CIPHER| set. Then it returns the number of bytes
-// written or -1 on error.
+// EVP_Cipher performs a one-shot encryption/decryption operation for non-AEAD
+// ciphers. No partial blocks are maintained between calls. However, any
+// internal cipher state is still updated. For CBC-mode ciphers, the IV is
+// updated to the final ciphertext block. For stream ciphers, the stream is
+// advanced past the bytes used. It returns one on success and zero otherwise.
//
-// WARNING: this differs from the usual return value convention when using
-// |EVP_CIPH_FLAG_CUSTOM_CIPHER|.
+// WARNING: This function behaves completely differently on AEAD ciphers, such
+// as |EVP_aes_128_gcm|. Rather than being a one-shot operation, it behaves like
+// |EVP_CipherUpdate| or |EVP_CipherFinal_ex|, depending on whether |in| is
+// NULL. It also instead returns the number of bytes written or -1 on error.
+// This behavior is deprecated. Use |EVP_CipherUpdate| or |EVP_CipherFinal_ex|
+// instead.
//
// TODO(davidben): The normal ciphers currently never fail, even if, e.g.,
// |in_len| is not a multiple of the block size for CBC-mode decryption. The