Introduce framework for macro-based definitions of ciphersuites

This commit is a step towards the goal of allowing to hardcode the choice
of a single ciphersuite at compile-time. The hoped for benefit of this is
that whereever a ciphersuite attribute is queried and checked against a
compile-time constant, the check can be recognized as either true or false
at compile-time, hence leading to a code-size reduction.

For this to work, the ciphersuite attribute getter functions
mbedtls_ssl_suite_get_xxx() will be modified to return something
the compiler can recognize as a compile-time constant. In particular,
in order to avoid relying on constant propagation abilities of the
compiler, these functions should ideally return constant symbols
(instead of, say, fields in a globally const structure instance).

This puts us in the following situation: On the one hand, there's the
array of ciphersuite information structures defining the attribute of
those ciphersuites the stack knows about. On the other hand, we need
direct access to those fields through constant symbols in the getter
functions.

In order to avoid any duplication of information, this commit exemplifies
how ciphersuites can be conveniently defined on the basis of macro
definitions, and how the corresponding instances of the ciphersuite
information structure can be auto-generated from this.

In the approach, to add support for a ciphersuite with official name
NAME (such as TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8), the following macro
constants need to be defined in ssl_ciphersuites.h:

  MBEDTLS_SUITE__ NAME __ID
  MBEDTLS_SUITE__ NAME __NAME
  MBEDTLS_SUITE__ NAME __CIPHER
  MBEDTLS_SUITE__ NAME __MAC
  ...

To make check-names.sh happy, one also needs a dummy macro

  MBEDTLS_SUITE__ NAME()

These ciphersuite attribute values can then be queried via

  MBEDTLS_SSL_SUITE_ID( NAME_MACRO )
  ...

where NAME_MACRO can be any macro expanding to a defined NAME.

Further, a convenience macro

  MBEDTLS_SSL_SUITE_INFO( NAME_MACRO )

is provided that again takes a macro NAME_MACRO expanding to a
defined NAME, and itself expands to an instance of
mbedtls_ssl_ciphersuite_info_t using the macro attributes
defined for NAME. This macro is then used in ssl_ciphersuites.c
when defining the array of known ciphersuite information structures,
(a) without duplicating the information, and (b) with increased
readability, because there's only one line for each ciphersuite.
This commit is contained in:
Hanno Becker 2019-06-26 10:53:02 +01:00
parent 473f98f2e0
commit b09132d33a
2 changed files with 69 additions and 5 deletions

View File

@ -33,6 +33,7 @@
#include "pk.h" #include "pk.h"
#include "cipher.h" #include "cipher.h"
#include "md.h" #include "md.h"
#include "ssl.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -311,6 +312,58 @@ typedef struct mbedtls_ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t;
eg for CCM_8 */ eg for CCM_8 */
#define MBEDTLS_CIPHERSUITE_NODTLS 0x04 /**< Can't be used with DTLS */ #define MBEDTLS_CIPHERSUITE_NODTLS 0x04 /**< Can't be used with DTLS */
/*
* Ciphersuite macro definitions
*
* This is highly incomplete and only contains those ciphersuites for
* which we need to be able to build the library with support for that
* ciphersuite only (currently MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
* as an example).
*/
#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8()
#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_ID MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_NAME "TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8"
#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_CIPHER MBEDTLS_CIPHER_AES_128_CCM
#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_MAC MBEDTLS_MD_SHA256
#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_KEY_EXCHANGE MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_MIN_MAJOR_VER MBEDTLS_SSL_MAJOR_VERSION_3
#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_MIN_MINOR_VER MBEDTLS_SSL_MINOR_VERSION_3
#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_MAX_MAJOR_VER MBEDTLS_SSL_MAJOR_VERSION_3
#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_MAX_MINOR_VER MBEDTLS_SSL_MINOR_VERSION_3
#define MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8_FLAGS MBEDTLS_CIPHERSUITE_SHORT_TAG
/*
* Helper macros to extract fields from ciphersuites.
*/
#define MBEDTLS_SSL_SUITE_ID_T( SUITE ) SUITE ## _ID
#define MBEDTLS_SSL_SUITE_NAME_T( SUITE ) SUITE ## _NAME
#define MBEDTLS_SSL_SUITE_CIPHER_T( SUITE ) SUITE ## _CIPHER
#define MBEDTLS_SSL_SUITE_MAC_T( SUITE ) SUITE ## _MAC
#define MBEDTLS_SSL_SUITE_KEY_EXCHANGE_T( SUITE ) SUITE ## _KEY_EXCHANGE
#define MBEDTLS_SSL_SUITE_MIN_MAJOR_VER_T( SUITE ) SUITE ## _MIN_MAJOR_VER
#define MBEDTLS_SSL_SUITE_MIN_MINOR_VER_T( SUITE ) SUITE ## _MIN_MINOR_VER
#define MBEDTLS_SSL_SUITE_MAX_MAJOR_VER_T( SUITE ) SUITE ## _MAX_MAJOR_VER
#define MBEDTLS_SSL_SUITE_MAX_MINOR_VER_T( SUITE ) SUITE ## _MAX_MINOR_VER
#define MBEDTLS_SSL_SUITE_FLAGS_T( SUITE ) SUITE ## _FLAGS
/* Wrapper around MBEDTLS_SSL_SUITE_XXX_T() which makes sure that
* the argument is macro-expanded before concatenated with the
* field name. This allows to call these macros as
* MBEDTLS_SSL_SUITE_XXX( MBEDTLS_SSL_SINGLE_CIPHERSUITE ),
* where MBEDTLS_SSL_SINGLE_CIPHERSUITE expands to MBEDTLS_SSL_SUITE_XXX. */
#define MBEDTLS_SSL_SUITE_ID( SUITE ) MBEDTLS_SSL_SUITE_ID_T( SUITE )
#define MBEDTLS_SSL_SUITE_NAME( SUITE ) MBEDTLS_SSL_SUITE_NAME_T( SUITE )
#define MBEDTLS_SSL_SUITE_CIPHER( SUITE ) MBEDTLS_SSL_SUITE_CIPHER_T( SUITE )
#define MBEDTLS_SSL_SUITE_MAC( SUITE ) MBEDTLS_SSL_SUITE_MAC_T( SUITE )
#define MBEDTLS_SSL_SUITE_KEY_EXCHANGE( SUITE ) MBEDTLS_SSL_SUITE_KEY_EXCHANGE_T( SUITE )
#define MBEDTLS_SSL_SUITE_MIN_MAJOR_VER( SUITE ) MBEDTLS_SSL_SUITE_MIN_MAJOR_VER_T( SUITE )
#define MBEDTLS_SSL_SUITE_MIN_MINOR_VER( SUITE ) MBEDTLS_SSL_SUITE_MIN_MINOR_VER_T( SUITE )
#define MBEDTLS_SSL_SUITE_MAX_MAJOR_VER( SUITE ) MBEDTLS_SSL_SUITE_MAX_MAJOR_VER_T( SUITE )
#define MBEDTLS_SSL_SUITE_MAX_MINOR_VER( SUITE ) MBEDTLS_SSL_SUITE_MAX_MINOR_VER_T( SUITE )
#define MBEDTLS_SSL_SUITE_FLAGS( SUITE ) MBEDTLS_SSL_SUITE_FLAGS_T( SUITE )
/** /**
* \brief This structure is used for storing ciphersuite information * \brief This structure is used for storing ciphersuite information
*/ */
@ -334,6 +387,21 @@ struct mbedtls_ssl_ciphersuite_t
typedef mbedtls_ssl_ciphersuite_t const * mbedtls_ssl_ciphersuite_handle_t; typedef mbedtls_ssl_ciphersuite_t const * mbedtls_ssl_ciphersuite_handle_t;
#define MBEDTLS_SSL_CIPHERSUITE_INVALID_HANDLE ( (mbedtls_ssl_ciphersuite_handle_t) NULL ) #define MBEDTLS_SSL_CIPHERSUITE_INVALID_HANDLE ( (mbedtls_ssl_ciphersuite_handle_t) NULL )
/**
* \brief This macro builds an instance of ::mbedtls_ssl_ciphersuite_t
* from an \c MBEDTLS_SUITE_XXX identifier.
*/
#define MBEDTLS_SSL_SUITE_INFO( SUITE ) \
{ MBEDTLS_SSL_SUITE_ID( SUITE ), \
MBEDTLS_SSL_SUITE_NAME( SUITE ), \
MBEDTLS_SSL_SUITE_CIPHER( SUITE ), \
MBEDTLS_SSL_SUITE_MAC( SUITE ), \
MBEDTLS_SSL_SUITE_KEY_EXCHANGE( SUITE ), \
MBEDTLS_SSL_SUITE_MIN_MAJOR_VER( SUITE ), \
MBEDTLS_SSL_SUITE_MIN_MINOR_VER( SUITE ), \
MBEDTLS_SSL_SUITE_MAX_MAJOR_VER( SUITE ), \
MBEDTLS_SSL_SUITE_MAX_MINOR_VER( SUITE ), \
MBEDTLS_SSL_SUITE_FLAGS( SUITE ) }
/* /*
* Getter functions for the extraction of ciphersuite attributes * Getter functions for the extraction of ciphersuite attributes
* from a ciphersuite handle. * from a ciphersuite handle.

View File

@ -449,11 +449,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 }, 0 },
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8", MBEDTLS_SSL_SUITE_INFO( MBEDTLS_SUITE_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ),
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_CIPHERSUITE_SHORT_TAG },
#endif /* MBEDTLS_CCM_C */ #endif /* MBEDTLS_CCM_C */
#endif /* MBEDTLS_AES_C */ #endif /* MBEDTLS_AES_C */