From 3e56130fb990863e2c912ddb44bab416f088dd21 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 14 Apr 2022 00:17:15 +0200 Subject: [PATCH] psa_raw_key_agreement: return BUFFER_TOO_SMALL when warranted psa_raw_key_agreement() returned PSA_ERROR_INVALID_ARGUMENT instead of PSA_ERROR_BUFFER_TOO_SMALL when the output buffer was too small for ECDH, the only algorithm that is currently implemented. Make it return the correct error code. The reason for the wrong error code is that ecdh.c returns MBEDTLS_ERR_ECP_BAD_INPUT_DATA, presumably for similarith with dhm.c. It might make sense to change ecdh.c to use MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL, but dhm.c doesn't have an existing BUFFER_TOO_SMALL error. To minimize the impact of the fix, handle this in the PSA layer. Fixes #5735. Signed-off-by: Gilles Peskine --- .../psa_raw_key_agreement-buffer_too_small.txt | 3 +++ library/psa_crypto.c | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 ChangeLog.d/psa_raw_key_agreement-buffer_too_small.txt diff --git a/ChangeLog.d/psa_raw_key_agreement-buffer_too_small.txt b/ChangeLog.d/psa_raw_key_agreement-buffer_too_small.txt new file mode 100644 index 000000000..415c8491e --- /dev/null +++ b/ChangeLog.d/psa_raw_key_agreement-buffer_too_small.txt @@ -0,0 +1,3 @@ +Bugfix + * psa_raw_key_agreement() now returns PSA_ERROR_BUFFER_TOO_SMALL when + applicable. Fixes #5735. diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 635981d95..c3af7aab7 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5766,6 +5766,22 @@ psa_status_t psa_raw_key_agreement( psa_algorithm_t alg, if( status != PSA_SUCCESS ) goto exit; + /* PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE() is in general an upper bound + * for the output size. The PSA specification only guarantees that this + * function works if output_size >= PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(...), + * but it might be nice to allow smaller buffers if the output fits. + * At the time of writing this comment, with only ECDH implemented, + * PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE() is exact so the point is moot. + * If FFDH is implemented, PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE() can easily + * be exact for it as well. */ + size_t expected_length = + PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE( slot->attr.type, slot->attr.bits ); + if( output_size < expected_length ) + { + status = PSA_ERROR_BUFFER_TOO_SMALL; + goto exit; + } + status = psa_key_agreement_raw_internal( alg, slot, peer_key, peer_key_length, output, output_size,