This commit restructures ssl_ciphersuites.h and ssl_ciphersuites.c to
define all ciphersuite helper functions static inline in ssl_ciphersuites.h
if MBEDTLS_SSL_CONF_SINGLE_CIPHERSUITE is set, and to otherwise put their
definitions in ssl_ciphersuites.c.
If MBEDTLS_SSL_SINGLE_CIPHERSUITE is enabled, the type
mbedtls_ssl_ciphersuite_handle_t
is logically a boolean (concretely realized as `unsigned char`),
containing the invalid handle and the unique valid handle, which
represents the single enabled ciphersuite.
The SSL session structure mbedtls_ssl_session contains an instance
of mbedtls_ssl_ciphersuite_handle_t which is guaranteed to be valid,
and which is hence redundant in any two-valued implementation of
mbedtls_ssl_ciphersuite_handle_t.
This commit replaces read-uses of
mbedtls_ssl_session::ciphersuite_info
by a getter functions which, and defines this getter function
either by just reading the field from the session structure
(in case MBEDTLS_SSL_SINGLE_CIPHERSUITE is disabled), or by
returning the single valid ciphersuite handle (in case
MBEDTLS_SSL_SINGLE_CIPHERSUITE is enabled) and removing the
field from mbedtls_ssl_session in this case.
If MBEDTLS_SSL_SINGLE_CIPHERSUITE is enabled, it overwrites
the runtime configuration of supported ciphersuites, which
includes both the configuration API and the fields which are
used to store the configuration. Both are therefore no longer
needed and should be removed for the benefit of code-size,
memory usage, and API clarity (no accidental hiccup of runtime
vs. compile-time configuration possible).
The configuration API mbedtls_ssl_conf_ciphersuites() has
already been removed in case MBEDTLS_SSL_SINGLE_CIPHERSUITE,
and this commit removes the field
mbedtls_ssl_config::ciphersuite_list
which it updates.
If MBEDTLS_SSL_SINGLE_CIPHERSUITE is enabled, the type
mbedtls_ssl_ciphersuite_handle_t
is logically a boolean (concretely realized as `unsigned char`),
containing the invalid handle and the unique valid handle, which
represents the single enabled ciphersuite.
The SSL handshake structure mbedtls_ssl_handshake_params contains
an instance of mbedtls_ssl_ciphersuite_handle_t which is guaranteed
to be valid, and which is hence redundant in any two-valued
implementation of mbedtls_ssl_ciphersuite_handle_t.
This commit replaces read-uses of
mbedtls_ssl_handshake_params::ciphersuite_info
by a getter functions which, and defines this getter function
either by just reading the field from the handshake structure
(in case MBEDTLS_SSL_SINGLE_CIPHERSUITE is disabled), or by
returning the single valid ciphersuite handle (in case
MBEDTLS_SSL_SINGLE_CIPHERSUITE is enabled) and removing the
field from mbedtls_ssl_handshake_params in this case.
This commit adapts the ClientHello parsing routines in ssl_srv.c
to use the ciphersuite traversal macros
MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE
MBEDTLS_SSL_END_FOR_EACH_CIPHERSUITE
introduced in the last commit, thereby making them work
both with and without MBEDTLS_SSL_SINGLE_CIPHERSUITE.
Another notable change concerns the ssl_ciphersuite_match:
Previous, this function would take a ciphersuite ID and a
pointer to a destination ciphersuite info structure as input
and write eithe NULL or a valid ciphersuite info structure
to that destination address, depending on whether the suite
corresponding to the given ID was suitable or not. The
function would always return 0 outside of a fatal error.
This commit changes this to ssl_ciphersuite_is_match() which
instead already takes a ciphersuite handle (which outside
of a hardcoded ciphersuite is the same as the ptr to a
ciphersuite info structure) and returns 0 or 1 (or a
negative error code in case of a fatal error) indicating
whether the suite corresponding to the handle was acceptable
or not. The conversion of the ciphersuite ID to the ciphersuite
info structure is done prior to calling ssl_ciphersuite_is_match().
This commit modifies the ClientHello writing routine ssl_write_client_hello
in ssl_cli.c to switch between
(a) listing all runtime configured ciphersuites
(in case MBEDTLS_SSL_SINGLE_CIPHERSUITE is not defined)
(b) listing just the single hardcoded ciphersuite
(in case MBEDTLS_SSL_SINGLE_CIPHERSUITE is defined)
The approach taken is to introduce a pair of helper macros
MBEDTLS_SSL_BEGIN_FOR_EACH_CIPHERSUITE( ssl, ver, info )
MBEDTLS_SSL_END_FOR_EACH_CIPHERSUITE
which when delimiting a block of code lead to that block of
code being run once for each ciphersuite that's enabled in the
context `ssl` and version `ver`, referenced through the (fresh)
`info` variable. Internally, this is implemented either through
a plain `for` loop traversing the runtime configured ciphersuite
list (if MBEDTLS_SSL_SINGLE_CIPHERSUITE is disabled) or by just
hardcoding `info` to the single enabled ciphersuite (if
MBEDTLS_SSL_SINGLE_CIPHERSUITE is enabled).
These helper macros will prove useful whereever previous code
traversed the runtime configured ciphersuite list, but adaptations
of those occasions outside ClientHello writing are left for later
commits.
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 introduces an internal zero-cost abstraction layer for
SSL ciphersuites: Instead of addressing ciphersuites via pointers
to instances of mbedtls_ssl_ciphersuite_t and accessing their fields
directly, this commit introduces an opaque type
mbedtls_ssl_ciphersuite_handle_t,
and getter functions
mbedtls_ssl_suite_get_xxx()
operating on ciphersuite handles.
The role of NULL is played by a new macro constant
MBEDTLS_SSL_CIPHERSUITE_INVALID_HANDLE
which results of functions returning handles can be checked against.
(For example, when doing a lookup of a ciphersuite from a peer-provided
ciphersuite ID in the per's Hello message).
The getter functions have the validity of the handle as a precondition
and are undefined if the handle is invalid.
So far, there's only one implementation of this abstraction layer, namely
mbedtls_ssl_ciphersuite_handle_t being mbedtls_ssl_ciphersuite_t const *
and
getter functions being field accesses.
In subsequent commits, however, the abstraction layer will be useful
to save code in the situation where only a single ciphersuite is enabled.
Previously, ssl.h included ssl_ciphersuites.h to have access to the
helper macros MBEDTLS_KEY_EXCHANGE_XXX_ENABLED, and for no other
reason. This commit moves the definitions of these macros to ssl.h,
thereby removing the dependency of ssl.h on ssl_ciphersuites.h.
So far, the client-proposed list of elliptic curves was stored for the
duration of the entire handshake in a heap-allocated buffer referenced
from mbedtls_ssl_handshake_params::curves. It is used in the following
places:
1) When the server chooses a suitable ciphersuite, it checks that
it has a certificate matching the ciphersuite; in particular, if
the ciphersuite involves ECDHE, the server needs an EC certificate
with a curve suitable for the client.
2) When performing the ECDHE key exchange, the server choose one
curve among those proposed by the client which matches the server's
own supported curve configuration.
This commit removes the hold back the entire client-side curve list
during the handshake, by performing (1) and (2) on during ClientHello
parsing, and in case of (2) only remembering the curve chosen for ECDHE
within mbedtls_ssl_handshake_params.
Fix an "unused variable" warning that happened in some configurations
(without EC, found by depend-pkalg.pl) and was not present in any parent PR
but only in the result of merging them: one of the PRs clarified the
distinction between `ret` and `verify_ret` and the other removed one
occurrence of using `ret`, and the conjunction of the two made `ret` unused in
some cases. Resolving by reducing the scope of that variable.
* restricted/pr/608:
programs: Make `make clean` clean all programs always
ssl_tls: Enable Suite B with subset of ECP curves
windows: Fix Release x64 configuration
timing: Remove redundant include file
net_sockets: Fix typo in net_would_block()
Add all.sh component that exercises invalid_param checks
Remove mbedtls_param_failed from programs
Make it easier to define MBEDTLS_PARAM_FAILED as assert
Make test suites compatible with #include <assert.h>
Pass -m32 to the linker as well
Update library to 2.16.2
Use 'config.pl baremetal' in all.sh
Clarify ChangeLog entry for fix to #1628Fix#2370, minor typos and spelling mistakes
Add Changelog entry for clang test-ref-configs.pl fix
Enable more compiler warnings in tests/Makefile
Change file scoping of test helpers.function
* restricted/pr/594:
Adapt baremetal.h and baremetal.sh
Don't incl. CAs in CertReq message in baremetal build
Allow config'n of incl of CertificateReq CA list Y/N at compile-time
Allow configuration of endpoint (cli/srv) at compile-time
Allow configuration of read timeouts at compile-time
Allow configuration of ConnectionID at compile-time
Allow compile-time configuration of legacy renegotiation
Allow compile-time configuration of authentication mode
Allow compile-time configuration of DTLS badmac limit
Allow compile-time configuration of DTLS anti replay
* restricted/pr/601: (27 commits)
Fix compile-time guard for optional field in struct
Move code to reduce probability of conflicts
Fix typos caught by check-names.sh
Clarify conditions related to resumption in client
Introduce getter function for renego_status
Add getter function for handshake->resume
Remove now-redundant code
Remove cache callbacks from config on client
Fix a few style issues
Expand documentation of new options a bit
Fix renaming oversight in documentation
Remove backticks in doxygen in config.h
Declare dependency on tickets for two ssl-opt.sh tests
Exclude new negative options from config.pl full
Restore config.h defaults
Address review comments
Fix ssl_cli resumption guards
Fix check-files, check-names and check-generated-features
Add test to all.sh
Add changelog entry
...
* restricted/pr/584: (140 commits)
Remove superfluous new line in x509.c
Add comment about X.509 name comparison of buffer with itself
[Fixup] Add missing PK release call in Cert Verify parsing
Fix guard controlling whether nested acquire calls are allowed
Add X.509 CRT test for nested calls for CRT frame / PK acquire
Don't return threading error on release()-without-acquire() calls
Don't allow nested CRT acquire()-calls if MBEDTLS_X509_ALWAYS_FLUSH
Make X.509 CRT cache reference counting unconditional
Remove memory buffer alloc from i386 test in all.sh
Don't mention pk_sign() in the context of public-key contexts
Don't use assertion for failures of mbedtls_x509_crt_x_acquire()
Fix copy pasta in x509_crt.h
Reference copy-less versions of X.509 CRT frame/PK getters
x509_crt.c: Add blank line to increase readability
[FIXUP] Fix bug in ASN.1 traversal of silently ignored tag
[FIXUP] Fix typo in declaration of mbedtls_x509_memcasecmp()
Move signature-info extraction out of MBEDTLS_X509_REMOVE_INFO
Fix certificate validity checking logic to work with !TIME_DATE
Simplify X.509 CRT version check in UID parsing
Remove unused variable warning in on-demand X.509 parsing
...
This commit modifies the baremetal configuration to disables the inclusion
of the list of accepted CAs in the CertificateRequest message sent by the
server.
Impact on code-size:
| | GCC 8.2.1 | ARMC5 5.06 | ARMC6 6.12 |
| --- | --- | --- | --- |
| `libmbedtls.a` before | 23099 | 23781 | 26639 |
| `libmbedtls.a` before | 22995 | 23689 | 26515 |
| gain in Bytes | 104 | 92 | 124 |