diff --git a/ChangeLog.d/cipher-delayed-output.txt b/ChangeLog.d/cipher-delayed-output.txt new file mode 100644 index 000000000..4ca3a0cc0 --- /dev/null +++ b/ChangeLog.d/cipher-delayed-output.txt @@ -0,0 +1,6 @@ +API changes + * For multi-part AEAD operations with the cipher module, calling + mbedtls_cipher_finish() is now mandatory. Previously the documentation + was unclear on this point, and this function happened to never do + anything with the currently implemented AEADs, so in practice it was + possible to skip calling it, which is no longer supported. diff --git a/docs/3.0-migration-guide.d/cipher-delayed-output.md b/docs/3.0-migration-guide.d/cipher-delayed-output.md new file mode 100644 index 000000000..18d327152 --- /dev/null +++ b/docs/3.0-migration-guide.d/cipher-delayed-output.md @@ -0,0 +1,15 @@ +Calling `mbedtls_cipher_finish()` is mandatory for all multi-part operations +---------------------------------------------------------------------------- + +This only affects people who use the cipher module to perform AEAD operations +using the multi-part API. + +Previously, the documentation didn't state explicitly if it was OK to call +`mbedtls_cipher_check_tag()` or `mbedtls_cipher_write_tag()` directly after +the last call to `mbedtls_cipher_update()` - that is, without calling +`mbedtls_cipher_finish()` in-between. If you code was missing that call, +please add it and be prepared to get as much as 15 bytes of output. + +Currently the output is always 0 bytes, but it may be more when alternative +implementations of the underlying primitives are in use, or with future +versions of the library. diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h index ffb20a676..06a29e752 100644 --- a/include/mbedtls/cipher.h +++ b/include/mbedtls/cipher.h @@ -437,10 +437,23 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ); /** - * \brief This function initializes a cipher context for + * \brief This function prepares a cipher context for * use with the given cipher primitive. * - * \param ctx The context to initialize. This must be initialized. + * \note After calling this function, you should call + * mbedtls_cipher_setkey() and, if the mode uses padding, + * mbedtls_cipher_set_padding_mode(), then for each + * message to encrypt or decrypt with this key, either: + * - mbedtls_cipher_crypt() for one-shot processing with + * non-AEAD modes; + * - mbedtls_cipher_auth_encrypt_ext() or + * mbedtls_cipher_auth_decrypt_ext() for one-shot + * processing with AEAD modes or NIST_KW; + * - for multi-part processing, see the documentation of + * mbedtls_cipher_reset(). + * + * \param ctx The context to prepare. This must be initialized by + * a call to mbedtls_cipher_init() first. * \param cipher_info The cipher to use. * * \return \c 0 on success. @@ -448,10 +461,6 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ); * parameter-verification failure. * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the * cipher-specific context fails. - * - * \internal Currently, the function also clears the structure. - * In future versions, the caller will be required to call - * mbedtls_cipher_init() on the structure first. */ int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info ); @@ -687,7 +696,30 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, /** * \brief This function resets the cipher state. * - * \param ctx The generic cipher context. This must be initialized. + * \note With non-AEAD ciphers, the order of calls for each message + * is as follows: + * 1. mbedtls_cipher_set_iv() if the mode uses an IV/nonce. + * 2. mbedtls_cipher_reset() + * 3. mbedtls_cipher_update() one or more times + * 4. mbedtls_cipher_finish() + * . + * This sequence can be repeated to encrypt or decrypt multiple + * messages with the same key. + * + * \note With AEAD ciphers, the order of calls for each message + * is as follows: + * 1. mbedtls_cipher_set_iv() if the mode uses an IV/nonce. + * 2. mbedtls_cipher_reset() + * 3. mbedtls_cipher_update_ad() + * 4. mbedtls_cipher_update() one or more times + * 5. mbedtls_cipher_finish() + * 6. mbedtls_cipher_check_tag() (for decryption) or + * mbedtls_cipher_write_tag() (for encryption). + * . + * This sequence can be repeated to encrypt or decrypt multiple + * messages with the same key. + * + * \param ctx The generic cipher context. This must be bound to a key. * * \return \c 0 on success. * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on