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>
chromium-5359
David Benjamin 3 years ago committed by Boringssl LUCI CQ
parent a51821a531
commit 701d8b28c8
  1. 30
      include/openssl/cipher.h

@ -174,6 +174,11 @@ OPENSSL_EXPORT int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx,
// 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 @@ OPENSSL_EXPORT int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out,
// 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_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out,
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

Loading…
Cancel
Save