diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h index 9c9a2e88c..7921f4d85 100644 --- a/include/mbedtls/cipher.h +++ b/include/mbedtls/cipher.h @@ -414,6 +414,82 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_ciph int key_bitlen, const mbedtls_cipher_mode_t mode ); +/** + * \brief Retrieve the identifier for a cipher info structure. + * + * \param[in] info The cipher info structure to query. + * This may be \c NULL. + * + * \return The full cipher identifier (\c MBEDTLS_CIPHER_xxx). + * \return #MBEDTLS_CIPHER_NONE if \p info is \c NULL. + */ +static inline mbedtls_cipher_type_t mbedtls_cipher_info_get_type( + const mbedtls_cipher_info_t *info ) +{ + if( info == NULL ) + return( MBEDTLS_CIPHER_NONE ); + else + return( info->MBEDTLS_PRIVATE(type) ); +} + +/** + * \brief Retrieve the operation mode for a cipher info structure. + * + * \param[in] info The cipher info structure to query. + * This may be \c NULL. + * + * \return The cipher mode (\c MBEDTLS_MODE_xxx). + * \return #MBEDTLS_MODE_NONE if \p info is \c NULL. + */ +static inline mbedtls_cipher_mode_t mbedtls_cipher_info_get_mode( + const mbedtls_cipher_info_t *info ) +{ + if( info == NULL ) + return( MBEDTLS_MODE_NONE ); + else + return( info->MBEDTLS_PRIVATE(mode) ); +} + +/** + * \brief Retrieve the key size for a cipher info structure. + * + * \param[in] info The cipher info structure to query. + * This may be \c NULL. + * + * \return The key length in bits. + * For variable-sized ciphers, this is the default length. + * For DES, this includes the parity bits. + * \return \c 0 if \p info is \c NULL. + */ +static inline size_t mbedtls_cipher_info_get_key_bitlen( + const mbedtls_cipher_info_t *info ) +{ + if( info == NULL ) + return( 0 ); + else + return( info->MBEDTLS_PRIVATE(key_bitlen) ); +} + +/** + * \brief Retrieve the human-readable name for a + * cipher info structure. + * + * \param[in] info The cipher info structure to query. + * This may be \c NULL. + * + * \return The cipher name, which is a human readable string, + * with static storage duration. + * \return \c NULL if \c info is \p NULL. + */ +static inline const char *mbedtls_cipher_info_get_name( + const mbedtls_cipher_info_t *info ) +{ + if( info == NULL ) + return( NULL ); + else + return( info->MBEDTLS_PRIVATE(name) ); +} + /** * \brief This function initializes a \p cipher_context as NONE. * diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function index 674349f76..94ea88f79 100644 --- a/tests/suites/test_suite_cipher.function +++ b/tests/suites/test_suite_cipher.function @@ -13,6 +13,38 @@ #define MBEDTLS_CIPHER_AUTH_CRYPT #endif +/* Check the internal consistency of a cipher info structure, and + * check it against mbedtls_cipher_info_from_xxx(). */ +static int check_cipher_info( mbedtls_cipher_type_t type, + const mbedtls_cipher_info_t *info ) +{ + size_t key_bitlen; + + TEST_ASSERT( info != NULL ); + TEST_EQUAL( type, mbedtls_cipher_info_get_type( info ) ); + TEST_EQUAL( type, info->type ); + TEST_ASSERT( mbedtls_cipher_info_from_type( type ) == info ); + + TEST_EQUAL( info->mode, mbedtls_cipher_info_get_mode( info ) ); + + /* Insist that get_name() return the string from the structure and + * not a copy. A copy would have an unknown storage duration. */ + TEST_ASSERT( mbedtls_cipher_info_get_name( info ) == info->name ); + TEST_ASSERT( mbedtls_cipher_info_from_string( info->name ) == info ); + + key_bitlen = mbedtls_cipher_info_get_key_bitlen( info ); + TEST_ASSERT( key_bitlen % 8 == 0 ); + /* All current and plausible supported ciphers use a 64-bit, 128-bit + * or 256-bit key, except XTS which uses a double AES key. */ + TEST_ASSERT( key_bitlen >= 64 ); + TEST_ASSERT( key_bitlen <= 512 ); + + return( 1 ); + +exit: + return( 0 ); +} + #if defined(MBEDTLS_CIPHER_AUTH_CRYPT) /* Helper for resetting key/direction * @@ -81,7 +113,13 @@ void mbedtls_cipher_list( ) const int *cipher_type; for( cipher_type = mbedtls_cipher_list(); *cipher_type != 0; cipher_type++ ) - TEST_ASSERT( mbedtls_cipher_info_from_type( *cipher_type ) != NULL ); + { + const mbedtls_cipher_info_t *info = + mbedtls_cipher_info_from_type( *cipher_type ); + mbedtls_test_set_step( *cipher_type ); + if( ! check_cipher_info( *cipher_type, info ) ) + goto exit; + } } /* END_CASE */ @@ -309,6 +347,8 @@ void enc_dec_buf( int cipher_id, char * cipher_string, int key_len, cipher_info = mbedtls_cipher_info_from_type( cipher_id ); TEST_ASSERT( NULL != cipher_info ); TEST_ASSERT( mbedtls_cipher_info_from_string( cipher_string ) == cipher_info ); + TEST_ASSERT( strcmp( mbedtls_cipher_info_get_name( cipher_info ), + cipher_string ) == 0 ); /* Initialise enc and dec contexts */ TEST_ASSERT( 0 == mbedtls_cipher_setup( &ctx_dec, cipher_info ) );