This commit introduces the configuration option
MBEDTLS_MD_SINGLE_HASH
which can be used to hardcode support for a single digest algorithm
at compile-time, at the benefit of reduced code-size.
To use, it needs to be defined to evaluate to a macro of the form
MBEDTLS_MD_INFO_{DIGEST}, and macros MBEDTLS_MD_INFO_{DIGEST}_FIELD
must be defined, giving rise to the various aspects (name, type,
size, ...) of the chosen digest algorithm. MBEDTLS_MD_INFO_SHA256
provides an example, but other algorithms can be added if needed.
At the moment, the effect of using MBEDTLS_MD_SINGLE_HASH is that
the implementation of the MD API (e.g. mbedtls_md_update()) need no
longer to through the abstraction of the mbedtls_md_info structures
by calling their corresponding function pointers fields (akin to
virtual functions in C++), but the directly call the corresponding
core digest function (such as mbedtls_sha256_update()).
Therefore, MBEDTLS_MD_SINGLE_HASH so far removes the second layer
of indirection in the chain
User calls MD API -> MD API calls underlying digest impl'n
-> Core digest impl'n does the actual work,
but the first indirection remains, as the MD API remains untouched
and cannot yet be inlined. Studying to what extend inlining the
shortened MD API implementations would lead to further code-savings
is left for a later commit.
In builds enabling only a single MD digest, we want to be able to
implement the MD info getter functions by returning compile-time
constants matching the fields of the MD info structures used so far.
To avoid information duplication hardening maintainability, this
commit introduces the possibility of providing the various aspects
of a particular digest implementation by defining macros
MBEDTLS_MD_INFO_DIGEST_FIELD (e.g. MBEDTLS_MD_INFO_SHA256_SIZE)
and to generate the corresponding mbedtls_md_info instance from
this set of macros, via the new macro MBEDTLS_MD_INFO().
This way, we'll be able to switch between MD info based builds
and single-digest builds without information duplication.
This commit continues the introduction of the MD digest implementation
abstraction layer given by `mbedtls_md_handle_t` by adding getter
functions returning the various properties of an implementation
(e.g. name, digest type, digest size). For the existing implementation,
these are just structure field accesses; however, in configurations
hardcoding the choice of a fixed digest algorithm, we'll be able to
implement them as inline functions returning compile-time constants.
As has been previously done for ciphersuites, this commit introduces
a zero-cost abstraction layer around the type
mbedtls_md_info const *
whose valid values represent implementations of message digest algorithms.
Access to a particular digest implementation can be requested by name or
digest ID through the API mbedtls_md_info_from_xxx(), which either returns
a valid implementation or NULL, representing failure.
This commit replaces such uses of `mbedtls_md_info const *` by an abstract
type `mbedtls_md_handle_t` whose valid values represent digest implementations,
and which has a designated invalid value MBEDTLS_MD_INVALID_HANDLE.
The purpose of this abstraction layer is to pave the way for builds which
support precisely one digest algorithm. In this case, mbedtls_md_handle_t
can be implemented as a two-valued type, with one value representing the
invalid handle, and the unique valid value representing the unique enabled
digest.
Cookies are fully opaque so we can change the hash used at any time, it's not
part of the API.
The cookie module handles truncation, so it's simpler to always use SHA-256
rather than check if SHA-224 is available.
This doesn't make a difference after link time optimization because
tickets aren't used, but it yields more accurate code-size figures
from baremetal.sh.
No need to play tricks with macros and functions depending on whether
SHA256_SMALLER is enabled or not, with a static inline function all common
compilers (tested with arm-gcc, armcc5, arm-clang) will Do The Right Thing
depending on whether we told them to optimize for size or speed.
The TinyCrypt PK signature wrapper uses ASN.1 writing functions
for length and tag, accounting for the only dependency of the
baremetal build on ASN.1 writing.
Since all lengths to be encoded are below 128 Bytes and are hence
ASN.1 encoded as single Bytes, the dependency on ASN.1 writing can
be removed at low complexity by writing the length and tags directly.
Previously, this wasn't necessary because ecdh.h was included
through ssl.h, but now that this is no longer the case (because
ssl.h doesn't use ECDH), we have to include it explicitly.
Previously, ecp.h was included only if MBEDTLS_ECDH_C was set,
which broke the build in configurations using ECDSA, but not ECDH.
An example of such a config is configs/config-thread.h, which
uses ECJPAKE exclusively.
Moreover, the inclusion of ecdh.h isn't needed, because the header
only uses constants defined in the ECP module.