From 65fb236799af6634e44860040f4ba1ec1eb00936 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Tue, 26 Jun 2018 13:55:30 +0100 Subject: [PATCH 1/5] psa: Make psa_set_key_lifetime() match declaration Previously, the psa_set_key_lifetime() implementation did not match the function declaration in psa/crypto.h. Value types don't need const, since they are passed by value. Fix psa_set_key_lifetime() implementation by making it match its declaration in the header. --- library/psa_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 8ce668ce3..7d7882745 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2513,7 +2513,7 @@ psa_status_t psa_get_key_lifetime( psa_key_slot_t key, } psa_status_t psa_set_key_lifetime( psa_key_slot_t key, - const psa_key_lifetime_t lifetime ) + psa_key_lifetime_t lifetime ) { key_slot_t *slot; From 045bd50a78a3d8d639ea470c79300eb6331bedff Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Tue, 26 Jun 2018 14:00:08 +0100 Subject: [PATCH 2/5] psa: Use key slot type in mbedtls_psa_crypto_free() To avoid a possible loss of precision, and to be semantically correct, use psa_key_slot_t (which is 16 bits) instead of size_t (which is 32 or 64 bits on common platforms) in mbedtls_psa_crypto_free(). --- library/psa_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 7d7882745..4b17e5594 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2941,7 +2941,7 @@ psa_status_t psa_generate_key( psa_key_slot_t key, void mbedtls_psa_crypto_free( void ) { - size_t key; + psa_key_slot_t key; for( key = 1; key < PSA_KEY_SLOT_COUNT; key++ ) psa_destroy_key( key ); mbedtls_ctr_drbg_free( &global_data.ctr_drbg ); From 5390f695909db67994d2193f1115132b0a49b551 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Tue, 26 Jun 2018 14:18:50 +0100 Subject: [PATCH 3/5] psa: Use type of block_size consistently Use size_t for block_size in psa_mac_abort() because psa_get_hash_block_size() returns a size_t. This also helps to avoid compiler warnings on LLP64 systems. --- library/psa_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 4b17e5594..dc0a27d6b 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1253,7 +1253,7 @@ psa_status_t psa_mac_abort( psa_mac_operation_t *operation ) #if defined(MBEDTLS_MD_C) if( PSA_ALG_IS_HMAC( operation->alg ) ) { - unsigned int block_size = + size_t block_size = psa_get_hash_block_size( PSA_ALG_HMAC_HASH( operation->alg ) ); if( block_size == 0 ) From 23bbb757adc2bc84ff29f02db566e9755b123de2 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Tue, 26 Jun 2018 14:16:54 +0100 Subject: [PATCH 4/5] psa: Pass the number of bits with explicit types The GCM, CCM, RSA, and cipher modules inconsistently use int or unsigned int for a count of bits. The PSA Crypto API uses size_t for counting things. This causes issues on LLP64 systems where a size_t can hold more than an unsigned int. Add casts for where key_bits and bits are passed to mbedtls_* APIs. --- library/psa_crypto.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index dc0a27d6b..1bea9ed37 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1163,7 +1163,8 @@ static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa( if( cipher_id != NULL ) *cipher_id = cipher_id_tmp; - return( mbedtls_cipher_info_from_values( cipher_id_tmp, key_bits, mode ) ); + return( mbedtls_cipher_info_from_values( cipher_id_tmp, + (int) key_bits, mode ) ); } static size_t psa_get_hash_block_size( psa_algorithm_t alg ) @@ -2188,7 +2189,7 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, { ret = mbedtls_cipher_setkey( &operation->ctx.cipher, slot->data.raw.data, - key_bits, cipher_operation ); + (int) key_bits, cipher_operation ); } if( ret != 0 ) { @@ -2604,7 +2605,7 @@ psa_status_t psa_aead_encrypt( psa_key_slot_t key, mbedtls_gcm_init( &gcm ); ret = mbedtls_gcm_setkey( &gcm, cipher_id, slot->data.raw.data, - key_bits ); + (unsigned int) key_bits ); if( ret != 0 ) { mbedtls_gcm_free( &gcm ); @@ -2637,7 +2638,8 @@ psa_status_t psa_aead_encrypt( psa_key_slot_t key, mbedtls_ccm_init( &ccm ); ret = mbedtls_ccm_setkey( &ccm, cipher_id, - slot->data.raw.data, key_bits ); + slot->data.raw.data, + (unsigned int) key_bits ); if( ret != 0 ) { mbedtls_ccm_free( &ccm ); @@ -2743,7 +2745,8 @@ psa_status_t psa_aead_decrypt( psa_key_slot_t key, mbedtls_gcm_init( &gcm ); ret = mbedtls_gcm_setkey( &gcm, cipher_id, - slot->data.raw.data, key_bits ); + slot->data.raw.data, + (unsigned int) key_bits ); if( ret != 0 ) { mbedtls_gcm_free( &gcm ); @@ -2775,7 +2778,8 @@ psa_status_t psa_aead_decrypt( psa_key_slot_t key, mbedtls_ccm_init( &ccm ); ret = mbedtls_ccm_setkey( &ccm, cipher_id, - slot->data.raw.data, key_bits ); + slot->data.raw.data, + (unsigned int) key_bits ); if( ret != 0 ) { mbedtls_ccm_free( &ccm ); @@ -2882,7 +2886,7 @@ psa_status_t psa_generate_key( psa_key_slot_t key, ret = mbedtls_rsa_gen_key( rsa, mbedtls_ctr_drbg_random, &global_data.ctr_drbg, - bits, + (unsigned int) bits, exponent ); if( ret != 0 ) { From bbf97e3cf16cd2678dedf6c875eeb4e8c86acf54 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Tue, 26 Jun 2018 14:20:51 +0100 Subject: [PATCH 5/5] psa: Pass hash_length with explicit types The RSA module uses unsigned int for hash_length. The PSA Crypto API uses size_t for hash_length. Cast hash_length to unsigned int when passed to the hash module. --- library/psa_crypto.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 1bea9ed37..4a3363952 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1661,6 +1661,15 @@ static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa, if( signature_size < rsa->len ) return( PSA_ERROR_BUFFER_TOO_SMALL ); + /* The Mbed TLS RSA module uses an unsigned int for hash_length. See if + * hash_length will fit and return an error if it doesn't. */ +#if defined(MBEDTLS_PKCS1_V15) || defined(MBEDTLS_PKCS1_V21) +#if SIZE_MAX > UINT_MAX + if( hash_length > UINT_MAX ) + return( PSA_ERROR_NOT_SUPPORTED ); +#endif +#endif + #if defined(MBEDTLS_PKCS1_V15) if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) ) { @@ -1670,7 +1679,9 @@ static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa, mbedtls_ctr_drbg_random, &global_data.ctr_drbg, MBEDTLS_RSA_PRIVATE, - md_alg, hash_length, hash, + md_alg, + (unsigned int) hash_length, + hash, signature ); } else @@ -1683,7 +1694,9 @@ static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa, mbedtls_ctr_drbg_random, &global_data.ctr_drbg, MBEDTLS_RSA_PRIVATE, - md_alg, hash_length, hash, + md_alg, + (unsigned int) hash_length, + hash, signature ); } else @@ -1715,6 +1728,15 @@ static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa, if( signature_length < rsa->len ) return( PSA_ERROR_BUFFER_TOO_SMALL ); +#if defined(MBEDTLS_PKCS1_V15) || defined(MBEDTLS_PKCS1_V21) +#if SIZE_MAX > UINT_MAX + /* The Mbed TLS RSA module uses an unsigned int for hash_length. See if + * hash_length will fit and return an error if it doesn't. */ + if( hash_length > UINT_MAX ) + return( PSA_ERROR_NOT_SUPPORTED ); +#endif +#endif + #if defined(MBEDTLS_PKCS1_V15) if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) ) { @@ -1725,7 +1747,7 @@ static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa, &global_data.ctr_drbg, MBEDTLS_RSA_PUBLIC, md_alg, - hash_length, + (unsigned int) hash_length, hash, signature ); } @@ -1739,7 +1761,9 @@ static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa, mbedtls_ctr_drbg_random, &global_data.ctr_drbg, MBEDTLS_RSA_PUBLIC, - md_alg, hash_length, hash, + md_alg, + (unsigned int) hash_length, + hash, signature ); } else