From 70edd689a8cc774e6359ebee982e0c8bcd504453 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 3 Dec 2020 20:27:27 +0100 Subject: [PATCH] cipher_auth_xxcrypt(): fix some null pointer handling Make sure that if a buffer is allowed to be empty, a null pointer is accepted if the buffer length is 0. This was already the case for most but not all arguments to mbedtls_cipher_auth_{en,de}crypt{,_ext}. Make sure to pass NULL for an empty buffer in the tests. Signed-off-by: Gilles Peskine --- library/cipher.c | 16 ++++++++-------- tests/suites/test_suite_cipher.function | 19 ++++++++++++++----- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/library/cipher.c b/library/cipher.c index 44cba34bc3..cf45446f79 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -1313,7 +1313,7 @@ static int mbedtls_cipher_aead_encrypt( mbedtls_cipher_context_t *ctx, /* PSA Crypto API always writes the authentication tag * at the end of the encrypted message. */ - if( tag != output + ilen ) + if( output == NULL || tag != output + ilen ) return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); status = psa_aead_encrypt( cipher_psa->slot, @@ -1393,7 +1393,7 @@ static int mbedtls_cipher_aead_decrypt( mbedtls_cipher_context_t *ctx, /* PSA Crypto API always writes the authentication tag * at the end of the encrypted message. */ - if( tag != input + ilen ) + if( input == NULL || tag != input + ilen ) return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); status = psa_aead_decrypt( cipher_psa->slot, @@ -1481,10 +1481,10 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, unsigned char *tag, size_t tag_len ) { CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv != NULL ); + CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); + CIPHER_VALIDATE_RET( ilen == 0 || output != NULL ); CIPHER_VALIDATE_RET( olen != NULL ); CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); @@ -1515,10 +1515,10 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, const unsigned char *tag, size_t tag_len ) { CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv != NULL ); + CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); - CIPHER_VALIDATE_RET( output != NULL ); + CIPHER_VALIDATE_RET( ilen == 0 || output != NULL ); CIPHER_VALIDATE_RET( olen != NULL ); CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL ); @@ -1552,7 +1552,7 @@ int mbedtls_cipher_auth_encrypt_ext( mbedtls_cipher_context_t *ctx, size_t *olen, size_t tag_len ) { CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv != NULL ); + CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); CIPHER_VALIDATE_RET( output != NULL ); @@ -1601,7 +1601,7 @@ int mbedtls_cipher_auth_decrypt_ext( mbedtls_cipher_context_t *ctx, size_t *olen, size_t tag_len ) { CIPHER_VALIDATE_RET( ctx != NULL ); - CIPHER_VALIDATE_RET( iv != NULL ); + CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL ); CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL ); CIPHER_VALIDATE_RET( ilen == 0 || input != NULL ); CIPHER_VALIDATE_RET( output_len == 0 || output != NULL ); diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function index 47a763cc88..ffe3284587 100644 --- a/tests/suites/test_suite_cipher.function +++ b/tests/suites/test_suite_cipher.function @@ -1155,6 +1155,16 @@ void auth_crypt_tv( int cipher_id, data_t * key, data_t * iv, unsigned char *tag_buf = NULL; #endif /* !MBEDTLS_DEPRECATED_WARNING && !MBEDTLS_DEPRECATED_REMOVED */ + /* Null pointers are documented as valid for inputs of length 0. + * The test framework passes non-null pointers, so set them to NULL. + * key, cipher and tag can't be empty. */ + if( iv->len == 0 ) + iv->x = NULL; + if( ad->len == 0 ) + ad->x = NULL; + if( clear->len == 0 ) + clear->x = NULL; + mbedtls_cipher_init( &ctx ); /* Initialize PSA Crypto */ @@ -1345,8 +1355,7 @@ void auth_crypt_tv( int cipher_id, data_t * key, data_t * iv, * Authenticate and decrypt, and check result */ - /* We can't pass a NULL output buffer to this function */ - ASSERT_ALLOC( decrypt_buf, cipher->len ? cipher->len : 1 ); + ASSERT_ALLOC( decrypt_buf, cipher->len ); outlen = 0; ret = mbedtls_cipher_auth_decrypt( &ctx, iv->x, iv->len, ad->x, ad->len, tmp_cipher, cipher->len, decrypt_buf, &outlen, @@ -1397,8 +1406,7 @@ void auth_crypt_tv( int cipher_id, data_t * key, data_t * iv, else #endif /* MBEDTLS_USE_PSA_CRYPTO */ { - /* can't pass a NULL output buffer to this function */ - ASSERT_ALLOC( encrypt_buf, cipher->len ? cipher->len : 1 ); + ASSERT_ALLOC( encrypt_buf, cipher->len ); ASSERT_ALLOC( tag_buf, tag->len ); tmp_cipher = encrypt_buf; tmp_tag = tag_buf; @@ -1421,7 +1429,8 @@ void auth_crypt_tv( int cipher_id, data_t * key, data_t * iv, TEST_ASSERT( ret == 0 ); TEST_ASSERT( outlen == cipher->len ); - TEST_ASSERT( memcmp( tmp_cipher, cipher->x, cipher->len ) == 0 ); + if( cipher->len != 0 ) + TEST_ASSERT( memcmp( tmp_cipher, cipher->x, cipher->len ) == 0 ); TEST_ASSERT( memcmp( tmp_tag, tag->x, tag->len ) == 0 ); } }