From d6dce9f4f310efc7f60f23d1e7987fe4f7501f4b Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 4 Jul 2019 09:11:38 +0100 Subject: [PATCH] Fix zero-length seed or label in TLS 1.2 PRF The psa_tls12_prf_set_seed() and psa_tls12_prf_set_label() functions did not work on platforms where malloc(0) returns NULL. It does not affect the TLS use case but these PRFs are used in other protocols as well and might not be used the same way. For example EAP uses the TLS PRF with an empty secret. (This would not trigger the bug, but is a strong indication that it is not safe to assume that certain inputs to this function are not zero length.) The conditional block includes the memcpy() call as well to avoid passing a NULL pointer as a parameter resulting in undefined behaviour. The current tests are already using zero length label and seed, there is no need to add new test for this bug. --- library/psa_crypto.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 953a3ede5..a47f9567d 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -4901,12 +4901,15 @@ static psa_status_t psa_tls12_prf_set_seed( psa_tls12_prf_key_derivation_t *prf, if( prf->state != TLS12_PRF_STATE_INIT ) return( PSA_ERROR_BAD_STATE ); - prf->seed = mbedtls_calloc( 1, data_length ); - if( prf->seed == NULL ) - return( PSA_ERROR_INSUFFICIENT_MEMORY ); + if( data_length != 0 ) + { + prf->seed = mbedtls_calloc( 1, data_length ); + if( prf->seed == NULL ) + return( PSA_ERROR_INSUFFICIENT_MEMORY ); - memcpy( prf->seed, data, data_length ); - prf->seed_length = data_length; + memcpy( prf->seed, data, data_length ); + prf->seed_length = data_length; + } prf->state = TLS12_PRF_STATE_SEED_SET; @@ -4973,12 +4976,15 @@ static psa_status_t psa_tls12_prf_set_label( psa_tls12_prf_key_derivation_t *prf if( prf->state != TLS12_PRF_STATE_KEY_SET ) return( PSA_ERROR_BAD_STATE ); - prf->label = mbedtls_calloc( 1, data_length ); - if( prf->label == NULL ) - return( PSA_ERROR_INSUFFICIENT_MEMORY ); + if( data_length != 0 ) + { + prf->label = mbedtls_calloc( 1, data_length ); + if( prf->label == NULL ) + return( PSA_ERROR_INSUFFICIENT_MEMORY ); - memcpy( prf->label, data, data_length ); - prf->label_length = data_length; + memcpy( prf->label, data, data_length ); + prf->label_length = data_length; + } prf->state = TLS12_PRF_STATE_LABEL_SET;