From e1f2d7d1ac985df3c5330fe33479e77fff58cca6 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 21 Aug 2018 14:54:54 +0200 Subject: [PATCH] Document and check the consistency of truncated MAC encodings Add comments noting that the maximum length of a MAC must fit in PSA_ALG_MAC_TRUNCATION_MASK. Add a unit test that verifies that the maximum MAC size fits. --- include/psa/crypto.h | 11 +++++++++++ include/psa/crypto_sizes.h | 3 +++ tests/suites/test_suite_psa_crypto.data | 3 +++ tests/suites/test_suite_psa_crypto.function | 13 +++++++++++++ 4 files changed, 30 insertions(+) diff --git a/include/psa/crypto.h b/include/psa/crypto.h index a64610773..3d99933c0 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -756,6 +756,13 @@ typedef uint32_t psa_algorithm_t; (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_MAC_SUBCATEGORY_MASK)) == \ PSA_ALG_HMAC_BASE) +/* In the encoding of a MAC algorithm, the bits corresponding to + * PSA_ALG_MAC_TRUNCATION_MASK encode the length to which the MAC is + * truncated. As an exception, the value 0 means the untruncated algorithm, + * whatever its length is. The length is encoded in 6 bits, so it can + * reach up to 63; the largest MAC is 64 bytes so its trivial truncation + * to full length is correctly encoded as 0 and any non-trivial truncation + * is correctly encoded as a value between 1 and 63. */ #define PSA_ALG_MAC_TRUNCATION_MASK ((psa_algorithm_t)0x00003f00) #define PSA_MAC_TRUNCATION_OFFSET 8 @@ -887,6 +894,10 @@ typedef uint32_t psa_algorithm_t; #define PSA_ALG_CCM ((psa_algorithm_t)0x06001001) #define PSA_ALG_GCM ((psa_algorithm_t)0x06001002) +/* In the encoding of a AEAD algorithm, the bits corresponding to + * PSA_ALG_AEAD_TAG_LENGTH_MASK encode the length of the AEAD tag. + * The constants for default lengths follow this encoding. + */ #define PSA_ALG_AEAD_TAG_LENGTH_MASK ((psa_algorithm_t)0x00003f00) #define PSA_AEAD_TAG_LENGTH_OFFSET 8 diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h index 169566ece..b5ff2aac3 100644 --- a/include/psa/crypto_sizes.h +++ b/include/psa/crypto_sizes.h @@ -79,6 +79,9 @@ */ /* All non-HMAC MACs have a maximum size that's smaller than the * minimum possible value of PSA_HASH_MAX_SIZE in this implementation. */ +/* Note that the encoding of truncated MAC algorithms limits this value + * to 64 bytes. + */ #define PSA_MAC_MAX_SIZE PSA_HASH_MAX_SIZE /* The maximum size of an RSA key on this implementation, in bits. diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index d8a5924cb..e8b119ea6 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -1,3 +1,6 @@ +PSA compile-time sanity checks +static_checks: + PSA init/deinit init_deinit: diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 5503c94b6..63d837fdc 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -793,6 +793,19 @@ static int exercise_key( psa_key_slot_t slot, * END_DEPENDENCIES */ +/* BEGIN_CASE */ +void static_checks( ) +{ + size_t max_truncated_mac_size = + PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET; + + /* Check that the length for a truncated MAC always fits in the algorithm + * encoding. The shifted mask is the maximum truncated value. The + * untruncated algorithm may be one byte larger. */ + TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size ); +} +/* END_CASE */ + /* BEGIN_CASE */ void init_deinit( ) {