diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h index 1dc31c9c24..6ef703ddab 100644 --- a/include/mbedtls/cipher.h +++ b/include/mbedtls/cipher.h @@ -881,7 +881,7 @@ int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx, * 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() + * 4. mbedtls_cipher_finish() or mbedtls_cipher_finish_padded() * . * This sequence can be repeated to encrypt or decrypt multiple * messages with the same key. @@ -892,7 +892,7 @@ int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx, * 2. mbedtls_cipher_reset() * 3. mbedtls_cipher_update_ad() * 4. mbedtls_cipher_update() one or more times - * 5. mbedtls_cipher_finish() + * 5. mbedtls_cipher_finish() or mbedtls_cipher_finish_padded() * 6. mbedtls_cipher_check_tag() (for decryption) or * mbedtls_cipher_write_tag() (for encryption). * . @@ -930,7 +930,8 @@ int mbedtls_cipher_update_ad(mbedtls_cipher_context_t *ctx, * many block-sized blocks of data as possible to output. * Any data that cannot be written immediately is either * added to the next block, or flushed when - * mbedtls_cipher_finish() is called. + * mbedtls_cipher_finish() or mbedtls_cipher_finish_padded() + * is called. * Exception: For MBEDTLS_MODE_ECB, expects a single block * in size. For example, 16 Bytes for AES. * @@ -964,6 +965,19 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, * contained in it is padded to the size of * the last block, and written to the \p output buffer. * + * \warning This function reports invalid padding through an error + * code. Adversaries may be able to decrypt encrypted + * data if they can submit chosen ciphertexts and + * detect whether it has valid padding or not, + * either through direct observation or through a side + * channel such as timing. This is known as a + * padding oracle attack. + * Therefore applications that call this function for + * decryption with a cipher that involves padding + * should take care around error handling. Preferably, + * such applicatios should use + * mbedtls_cipher_finish_padded() instead of this function. + * * \param ctx The generic cipher context. This must be initialized and * bound to a key. * \param output The buffer to write data to. This needs to be a writable @@ -977,12 +991,56 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption * expecting a full block but not receiving one. * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding - * while decrypting. + * while decrypting. Note that invalid-padding errors + * should be handled carefully; see the warning above. * \return A cipher-specific error code on failure. */ int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx, unsigned char *output, size_t *olen); +/** + * \brief The generic cipher finalization function. If data still + * needs to be flushed from an incomplete block, the data + * contained in it is padded to the size of + * the last block, and written to the \p output buffer. + * + * \note This function is similar to mbedtls_cipher_finish(). + * The only difference is that it reports invalid padding + * decryption differently, through the \p invalid_padding + * parameter rather than an error code. + * For encryption, and in modes without padding (including + * all authenticated modes), this function is identical + * to mbedtls_cipher_finish(). + * + * \param[in,out] ctx The generic cipher context. This must be initialized and + * bound to a key. + * \param[out] output The buffer to write data to. This needs to be a writable + * buffer of at least block_size Bytes. + * \param[out] olen The length of the data written to the \p output buffer. + * This may not be \c NULL. + * \param[out] invalid_padding + * If this function returns \c 0 on decryption, + * \p *invalid_padding is \c 0 if the ciphertext was + * valid, and all-bits-one if the ciphertext had invalid + * padding. + * On encryption, or in a mode without padding (including + * all authenticated modes), \p *invalid_padding is \c 0 + * on success. + * The value in \p *invalid_padding is unspecified if + * this function returns a nonzero status. + * + * \return \c 0 on success. + * Also \c 0 for decryption with invalid padding. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption + * expecting a full block but not receiving one. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_finish_padded(mbedtls_cipher_context_t *ctx, + unsigned char *output, size_t *olen, + size_t *invalid_padding); + #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) /** * \brief This function writes a tag for AEAD ciphers. diff --git a/library/cipher.c b/library/cipher.c index 2ae01dd84d..f3e2f91f82 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -1124,6 +1124,23 @@ int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx, return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; } +int mbedtls_cipher_finish_padded(mbedtls_cipher_context_t *ctx, + unsigned char *output, size_t *olen, + size_t *invalid_padding) +{ + *invalid_padding = 0; + int ret = mbedtls_cipher_finish(ctx, output, olen); +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) || \ + defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) || \ + defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) + if (ret == MBEDTLS_ERR_CIPHER_INVALID_PADDING) { + ret = 0; + *invalid_padding = SIZE_MAX; + } +#endif + return ret; +} + #if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode) diff --git a/tests/suites/test_suite_cipher.aes.data b/tests/suites/test_suite_cipher.aes.data index dd8bf719e0..4298b1d595 100644 --- a/tests/suites/test_suite_cipher.aes.data +++ b/tests/suites/test_suite_cipher.aes.data @@ -1590,6 +1590,114 @@ AES-256-CBC Decrypt test vector, PKCS7 (short, bad pad 17) depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7 decrypt_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"3e536c7917a695485ef046bda7c6a3e6":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 +AES-128-CBC Decrypt with finish_padded, no padding +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_NONE:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"23f710842b9bb9c32f26648c786807ca":"00000000000000000000000000000000":"":"":0:0 + +AES-192-CBC Decrypt with finish_padded, no padding +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_NONE:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"707b1dbb0ffa40ef7d95def421233fae":"fffffffff80000000000000000000000":"":"":0:0 + +AES-256-CBC Decrypt with finish_padded, no padding +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_NONE:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"49af6b372135acef10132e548f217b17":"ff000000000000000000000000000000":"":"":0:0 + +AES-128-CBC Decrypt with finish_padded, PKCS7 (good pad 1) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"6dbd04d1579f6a7bee0842b9ae491588":"000000000000000000000000000000":"":"":0:0 + +AES-192-CBC Decrypt with finish_padded, PKCS7 (good pad 1) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"593ebdf9a785f414cbed5d8a9eee1e4d":"fffffffff800000000000000000000":"":"":0:0 + +AES-256-CBC Decrypt with finish_padded, PKCS7 (good pad 1) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"f1b27ac78b93f6b0ab9787d8827176e6":"ff0000000000000000000000000000":"":"":0:0 + +AES-128-CBC Decrypt with finish_padded, PKCS7 (good pad 2) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"175334ced3166a22437861f4bcced178":"0000000000000000000000000000":"":"":0:0 + +AES-192-CBC Decrypt with finish_padded, PKCS7 (good pad 2) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"5d9ee7bc7066e438582c86c165604f2e":"fffffffff8000000000000000000":"":"":0:0 + +AES-256-CBC Decrypt with finish_padded, PKCS7 (good pad 2) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"cc71abea78b8e82c3791b52d3dba55e2":"ff00000000000000000000000000":"":"":0:0 + +AES-128-CBC Decrypt with finish_padded, PKCS7 (good pad 15) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"7d340c60b9067883962c69766cf9ec35":"2a":"":"":0:0 + +AES-192-CBC Decrypt with finish_padded, PKCS7 (good pad 15) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"48fef8aaa78c4a148f241aaf14866772":"2a":"":"":0:0 + +AES-256-CBC Decrypt with finish_padded, PKCS7 (good pad 15) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"6ad50ca266a3e32024818f11839afb2f":"2a":"":"":0:0 + +AES-128-CBC Decrypt with finish_padded, PKCS7 (good pad 16) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"e9844992c4b55bcaf8199d5df842adad":"":"":"":0:0 + +AES-192-CBC Decrypt with finish_padded, PKCS7 (good pad 16) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"02bb292527e726fd51eb29894d6f0aad":"":"":"":0:0 + +AES-256-CBC Decrypt with finish_padded, PKCS7 (good pad 16) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"1f788fe6d86c317549697fbf0c07fa43":"":"":"":0:0 + +AES-128-CBC Decrypt with finish_padded, PKCS7 (bad pad 0) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"23f710842b9bb9c32f26648c786807ca":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +AES-192-CBC Decrypt with finish_padded, PKCS7 (bad pad 0) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"707b1dbb0ffa40ef7d95def421233fae":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +AES-256-CBC Decrypt with finish_padded, PKCS7 (bad pad 0) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"49af6b372135acef10132e548f217b17":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +AES-128-CBC Decrypt with finish_padded, PKCS7 (bad pad 0102) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"e651289760d35177eade56eae724f8fd":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +AES-192-CBC Decrypt with finish_padded, PKCS7 (bad pad 0102) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"f5b599490354e71a3b3fb5f1419fb971":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +AES-256-CBC Decrypt with finish_padded, PKCS7 (bad pad 0102) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"6852d318a0884a289a725c558e761e25":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +AES-128-CBC Decrypt with finish_padded, PKCS7 (long, bad pad 17) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"9c336551cc31074ffcefc161bac686b7afa572c3b53bd14a1b98d201229ddd03":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +AES-192-CBC Decrypt with finish_padded, PKCS7 (long, bad pad 17) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"33a31ec7605c85893872a467777f3ddb5c4271870e51a0c618f20a0efccc2bfc":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +AES-256-CBC Decrypt with finish_padded, PKCS7 (long, bad pad 17) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"3e536c7917a695485ef046bda7c6a3e64f439d87aa0deb338029253bea0ba54f":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +AES-128-CBC Decrypt with finish_padded, PKCS7 (short, bad pad 17) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"9c336551cc31074ffcefc161bac686b7":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +AES-192-CBC Decrypt with finish_padded, PKCS7 (short, bad pad 17) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"33a31ec7605c85893872a467777f3ddb":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +AES-256-CBC Decrypt with finish_padded, PKCS7 (short, bad pad 17) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7 +decrypt_padded_test_vec:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"3e536c7917a695485ef046bda7c6a3e6":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + AES-128-CFB Decrypt test vector depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CFB decrypt_test_vec:MBEDTLS_CIPHER_AES_128_CFB128:-1:"fffffffe000000000000000000000000":"00000000000000000000000000000000":"1114bc2028009b923f0b01915ce5e7c4":"00000000000000000000000000000000":"":"":0:0: diff --git a/tests/suites/test_suite_cipher.constant_time.data b/tests/suites/test_suite_cipher.constant_time.data index 7f9f4af6ff..2de31ed15c 100644 --- a/tests/suites/test_suite_cipher.constant_time.data +++ b/tests/suites/test_suite_cipher.constant_time.data @@ -13,6 +13,114 @@ get_pkcs_padding:"00112233445566778899AABBCCDDEE00":MBEDTLS_ERR_CIPHER_INVALID_P Constant-time PKCS7 padding, invalid > 16 get_pkcs_padding:"00112233445566778899AABBCCDDEE11":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 +CF AES-128-CBC Decrypt with finish_padded, no padding +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_NONE:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"23f710842b9bb9c32f26648c786807ca":"00000000000000000000000000000000":"":"":0:0 + +CF AES-192-CBC Decrypt with finish_padded, no padding +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_NONE:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"707b1dbb0ffa40ef7d95def421233fae":"fffffffff80000000000000000000000":"":"":0:0 + +CF AES-256-CBC Decrypt with finish_padded, no padding +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_NONE:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"49af6b372135acef10132e548f217b17":"ff000000000000000000000000000000":"":"":0:0 + +CF AES-128-CBC Decrypt with finish_padded, PKCS7 (good pad 1) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"6dbd04d1579f6a7bee0842b9ae491588":"000000000000000000000000000000":"":"":0:0 + +CF AES-192-CBC Decrypt with finish_padded, PKCS7 (good pad 1) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"593ebdf9a785f414cbed5d8a9eee1e4d":"fffffffff800000000000000000000":"":"":0:0 + +CF AES-256-CBC Decrypt with finish_padded, PKCS7 (good pad 1) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"f1b27ac78b93f6b0ab9787d8827176e6":"ff0000000000000000000000000000":"":"":0:0 + +CF AES-128-CBC Decrypt with finish_padded, PKCS7 (good pad 2) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"175334ced3166a22437861f4bcced178":"0000000000000000000000000000":"":"":0:0 + +CF AES-192-CBC Decrypt with finish_padded, PKCS7 (good pad 2) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"5d9ee7bc7066e438582c86c165604f2e":"fffffffff8000000000000000000":"":"":0:0 + +CF AES-256-CBC Decrypt with finish_padded, PKCS7 (good pad 2) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"cc71abea78b8e82c3791b52d3dba55e2":"ff00000000000000000000000000":"":"":0:0 + +CF AES-128-CBC Decrypt with finish_padded, PKCS7 (good pad 15) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"7d340c60b9067883962c69766cf9ec35":"2a":"":"":0:0 + +CF AES-192-CBC Decrypt with finish_padded, PKCS7 (good pad 15) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"48fef8aaa78c4a148f241aaf14866772":"2a":"":"":0:0 + +CF AES-256-CBC Decrypt with finish_padded, PKCS7 (good pad 15) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"6ad50ca266a3e32024818f11839afb2f":"2a":"":"":0:0 + +CF AES-128-CBC Decrypt with finish_padded, PKCS7 (good pad 16) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"e9844992c4b55bcaf8199d5df842adad":"":"":"":0:0 + +CF AES-192-CBC Decrypt with finish_padded, PKCS7 (good pad 16) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"02bb292527e726fd51eb29894d6f0aad":"":"":"":0:0 + +CF AES-256-CBC Decrypt with finish_padded, PKCS7 (good pad 16) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"1f788fe6d86c317549697fbf0c07fa43":"":"":"":0:0 + +CF AES-128-CBC Decrypt with finish_padded, PKCS7 (bad pad 0) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"23f710842b9bb9c32f26648c786807ca":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +CF AES-192-CBC Decrypt with finish_padded, PKCS7 (bad pad 0) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"707b1dbb0ffa40ef7d95def421233fae":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +CF AES-256-CBC Decrypt with finish_padded, PKCS7 (bad pad 0) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"49af6b372135acef10132e548f217b17":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +CF AES-128-CBC Decrypt with finish_padded, PKCS7 (bad pad 0102) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"e651289760d35177eade56eae724f8fd":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +CF AES-192-CBC Decrypt with finish_padded, PKCS7 (bad pad 0102) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"f5b599490354e71a3b3fb5f1419fb971":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +CF AES-256-CBC Decrypt with finish_padded, PKCS7 (bad pad 0102) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"6852d318a0884a289a725c558e761e25":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +CF AES-128-CBC Decrypt with finish_padded, PKCS7 (long, bad pad 17) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"9c336551cc31074ffcefc161bac686b7afa572c3b53bd14a1b98d201229ddd03":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +CF AES-192-CBC Decrypt with finish_padded, PKCS7 (long, bad pad 17) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"33a31ec7605c85893872a467777f3ddb5c4271870e51a0c618f20a0efccc2bfc":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +CF AES-256-CBC Decrypt with finish_padded, PKCS7 (long, bad pad 17) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"3e536c7917a695485ef046bda7c6a3e64f439d87aa0deb338029253bea0ba54f":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +CF AES-128-CBC Decrypt with finish_padded, PKCS7 (short, bad pad 17) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_PKCS7:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"9c336551cc31074ffcefc161bac686b7":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +CF AES-192-CBC Decrypt with finish_padded, PKCS7 (short, bad pad 17) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_192_CBC:MBEDTLS_PADDING_PKCS7:"000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"33a31ec7605c85893872a467777f3ddb":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + +CF AES-256-CBC Decrypt with finish_padded, PKCS7 (short, bad pad 17) +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7:HAVE_CONSTANT_TIME_AES +decrypt_padded_test_vec_cf:MBEDTLS_CIPHER_AES_256_CBC:MBEDTLS_PADDING_PKCS7:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"3e536c7917a695485ef046bda7c6a3e6":"":"":"":MBEDTLS_ERR_CIPHER_INVALID_PADDING:0 + CF AES-128-CBC Decrypt test vector, no padding depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:HAVE_CONSTANT_TIME_AES decrypt_test_vec_cf:MBEDTLS_CIPHER_AES_128_CBC:MBEDTLS_PADDING_NONE:"ffffffffe00000000000000000000000":"00000000000000000000000000000000":"23f710842b9bb9c32f26648c786807ca":"00000000000000000000000000000000":"":"":0:0 diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function index 8ae2234d4c..fbc48b7974 100644 --- a/tests/suites/test_suite_cipher.function +++ b/tests/suites/test_suite_cipher.function @@ -946,6 +946,179 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void decrypt_padded_test_vec(int cipher_id, int pad_mode, data_t *key, + data_t *iv, data_t *cipher, + data_t *clear, data_t *ad, data_t *tag, + int expected_finish_result, int tag_result) +{ + unsigned char output[265]; + mbedtls_cipher_context_t ctx; + size_t outlen, total_len; + + mbedtls_cipher_init(&ctx); + + memset(output, 0x00, sizeof(output)); + +#if !defined(MBEDTLS_GCM_C) && !defined(MBEDTLS_CHACHAPOLY_C) + ((void) ad); + ((void) tag); +#endif + + /* Prepare context */ + TEST_ASSERT(0 == mbedtls_cipher_setup(&ctx, + mbedtls_cipher_info_from_type(cipher_id))); + TEST_ASSERT(0 == mbedtls_cipher_setkey(&ctx, key->x, 8 * key->len, MBEDTLS_DECRYPT)); +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) + if (pad_mode != -1) { + TEST_ASSERT(0 == mbedtls_cipher_set_padding_mode(&ctx, pad_mode)); + } +#else + (void) pad_mode; +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + TEST_ASSERT(0 == mbedtls_cipher_set_iv(&ctx, iv->x, iv->len)); + TEST_ASSERT(0 == mbedtls_cipher_reset(&ctx)); +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) + int expected = (ctx.cipher_info->mode == MBEDTLS_MODE_GCM || + ctx.cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305) ? + 0 : MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + + TEST_EQUAL(expected, mbedtls_cipher_update_ad(&ctx, ad->x, ad->len)); +#endif + + /* decode buffer and check tag->x */ + total_len = 0; + TEST_ASSERT(0 == mbedtls_cipher_update(&ctx, cipher->x, cipher->len, output, &outlen)); + total_len += outlen; + + size_t invalid_padding = 42; + int actual_finish_result = + mbedtls_cipher_finish_padded(&ctx, output + outlen, &outlen, + &invalid_padding); + switch (expected_finish_result) { + case 0: + TEST_EQUAL(actual_finish_result, 0); + TEST_EQUAL(invalid_padding, 0); + break; + case MBEDTLS_ERR_CIPHER_INVALID_PADDING: + TEST_EQUAL(actual_finish_result, 0); + TEST_EQUAL(invalid_padding, SIZE_MAX); + break; + default: + TEST_EQUAL(actual_finish_result, expected_finish_result); + /* Check output parameter is set to the least-harmful value on error */ + TEST_EQUAL(0, outlen); + break; + } + total_len += outlen; + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) + int tag_expected = (ctx.cipher_info->mode == MBEDTLS_MODE_GCM || + ctx.cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305) ? + tag_result : MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + + TEST_EQUAL(tag_expected, mbedtls_cipher_check_tag(&ctx, tag->x, tag->len)); +#endif + + /* check plaintext only if everything went fine */ + if (0 == expected_finish_result && 0 == tag_result) { + TEST_ASSERT(total_len == clear->len); + TEST_ASSERT(0 == memcmp(output, clear->x, clear->len)); + } + +exit: + mbedtls_cipher_free(&ctx); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void decrypt_padded_test_vec_cf(int cipher_id, int pad_mode, data_t *key, + data_t *iv, data_t *cipher, + data_t *clear, data_t *ad, data_t *tag, + int expected_finish_result, int tag_result) +{ + unsigned char output[265]; + mbedtls_cipher_context_t ctx; + size_t outlen, total_len; + + mbedtls_cipher_init(&ctx); + + memset(output, 0x00, sizeof(output)); + +#if !defined(MBEDTLS_GCM_C) && !defined(MBEDTLS_CHACHAPOLY_C) + ((void) ad); + ((void) tag); +#endif + + TEST_CF_SECRET(key->x, key->len); + TEST_CF_SECRET(cipher->x, cipher->len); + + /* Prepare context */ + TEST_ASSERT(0 == mbedtls_cipher_setup(&ctx, + mbedtls_cipher_info_from_type(cipher_id))); + TEST_ASSERT(0 == mbedtls_cipher_setkey(&ctx, key->x, 8 * key->len, MBEDTLS_DECRYPT)); +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) + if (pad_mode != -1) { + TEST_ASSERT(0 == mbedtls_cipher_set_padding_mode(&ctx, pad_mode)); + } +#else + (void) pad_mode; +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + TEST_ASSERT(0 == mbedtls_cipher_set_iv(&ctx, iv->x, iv->len)); + TEST_ASSERT(0 == mbedtls_cipher_reset(&ctx)); +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) + int expected = (ctx.cipher_info->mode == MBEDTLS_MODE_GCM || + ctx.cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305) ? + 0 : MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + + TEST_EQUAL(expected, mbedtls_cipher_update_ad(&ctx, ad->x, ad->len)); +#endif + + /* decode buffer and check tag->x */ + total_len = 0; + TEST_ASSERT(0 == mbedtls_cipher_update(&ctx, cipher->x, cipher->len, output, &outlen)); + total_len += outlen; + + size_t invalid_padding = 42; + int actual_finish_result = + mbedtls_cipher_finish_padded(&ctx, output + outlen, &outlen, + &invalid_padding); + switch (expected_finish_result) { + case 0: + TEST_EQUAL(actual_finish_result, 0); + TEST_EQUAL(invalid_padding, 0); + break; + case MBEDTLS_ERR_CIPHER_INVALID_PADDING: + TEST_EQUAL(actual_finish_result, 0); + TEST_EQUAL(invalid_padding, SIZE_MAX); + break; + default: + TEST_EQUAL(actual_finish_result, expected_finish_result); + /* Check output parameter is set to the least-harmful value on error */ + TEST_EQUAL(0, outlen); + break; + } + total_len += outlen; + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) + int tag_expected = (ctx.cipher_info->mode == MBEDTLS_MODE_GCM || + ctx.cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305) ? + tag_result : MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + + TEST_EQUAL(tag_expected, mbedtls_cipher_check_tag(&ctx, tag->x, tag->len)); +#endif + + /* check plaintext only if everything went fine */ + if (0 == expected_finish_result && 0 == tag_result) { + TEST_CF_PUBLIC(output, sizeof(output)); + TEST_MEMORY_COMPARE(output, total_len, clear->x, clear->len); + } + +exit: + mbedtls_cipher_free(&ctx); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_AEAD */ void auth_crypt_tv(int cipher_id, data_t *key, data_t *iv, data_t *ad, data_t *cipher, data_t *tag,