Commit graph

4512 commits

Author SHA1 Message Date
Hanno Becker 1facd552fc Replace xxx_send_alert by xxx_pend_alert to save code 2019-07-24 13:20:27 +01:00
Hanno Becker f46e1ce812 Introduce SSL helper function to mark pending alerts 2019-07-24 13:20:27 +01:00
Simon Butcher 3b014fc23a Merge remote-tracking branch 'origin/pr/604' into baremetal 2019-07-23 16:16:24 +01:00
Simon Butcher 6fe6b437da Merge remote-tracking branch 'origin/pr/589' into baremetal 2019-07-23 16:10:56 +01:00
Simon Butcher c0b3633194 Merge remote-tracking branch 'origin/pr/627' into baremetal 2019-07-23 16:06:07 +01:00
Hanno Becker 95d1b93c69 Don't reset timer during mbedtls_ssl_setup()
At that point, the timer might not yet be configured.

The timer is reset at the following occasions:

- when it is initially configured through
    mbedtls_ssl_set_timer_cb() or
    mbedtls_ssl_set_timer_cb_cx()
- when a session is reset in mbedtls_ssl_session_reset()
- when a handshake finishes via mbedtls_ssl_handshake_wrap()
2019-07-22 11:15:28 +01:00
Hanno Becker 981f81dc30 Add missing uses of mbedtls_ssl_get_minor() 2019-07-19 16:12:54 +01:00
Hanno Becker ce8bdf82a1 ECP restart: Don't calculate address of sub ctx if ctx is NULL
All modules using restartable ECC operations support passing `NULL`
as the restart context as a means to not use the feature.

The restart contexts for ECDSA and ECP are nested, and when calling
restartable ECP operations from restartable ECDSA operations, the
address of the ECP restart context to use is calculated by adding
the to the address of the ECDSA restart context the offset the of
the ECP restart context.

If the ECP restart context happens to not reside at offset `0`, this
leads to a non-`NULL` pointer being passed to restartable ECP
operations from restartable ECDSA-operations; those ECP operations
will hence assume that the pointer points to a valid ECP restart
address and likely run into a segmentation fault when trying to
dereference the non-NULL but close-to-NULL address.

The problem doesn't arise currently because luckily the ECP restart
context has offset 0 within the ECDSA restart context, but we should
not rely on it.

This commit fixes the passage from restartable ECDSA to restartable ECP
operations by propagating NULL as the restart context pointer.

Apart from being fragile, the previous version could also lead to
NULL pointer dereference failures in ASanDbg builds which dereferenced
the ECDSA restart context even though it's not needed to calculate the
address of the offset'ed ECP restart context.
2019-07-19 14:56:09 +01:00
Hanno Becker 56595f4f7b Allow hardcoding single signature hash at compile-time
This commit introduces the option MBEDTLS_SSL_CONF_SINGLE_HASH
which can be used to register a single supported signature hash
algorithm at compile time. It replaces the runtime configuration
API mbedtls_ssl_conf_sig_hashes() which allows to register a _list_
of supported signature hash algorithms.

In contrast to other options used to hardcode configuration options,
MBEDTLS_SSL_CONF_SINGLE_HASH isn't a numeric option, but instead it's
only relevant if it's defined or not. To actually set the single
supported hash algorithm that should be supported, numeric options

MBEDTLS_SSL_CONF_SINGLE_HASH_TLS_ID
MBEDTLS_SSL_CONF_SINGLE_HASH_MD_ID

must both be defined and provide the TLS ID and the Mbed TLS internal
ID and the chosen hash algorithm, respectively.
2019-07-17 10:19:27 +01:00
Hanno Becker f1bc9e1c69 Introduce helper functions to traverse signature hashes 2019-07-17 10:19:27 +01:00
Hanno Becker 0af717b520 Don't use mbedtls_ssL_set_calc_verify_md writing CertificateRequest
mbedtls_ssl_set_calc_verify_md() serves two purposes:
(a) It checks whether a hash algorithm is suitable to be used
    in the CertificateVerify message.
(b) It updates the function callback pointing to the function that
    computes handshake transcript for the CertificateVerify message
    w.r.t. the chosen hash function.

Step (b) is only necessary when receiving the CertificateVerify
message, while writing the CertificateRequest only involves (a).

This commit modifies the writing code for the CertificateRequest
message to inline the check (a) and thereby avoiding the call to
mbedtls_ssl_calc_verify_md().
2019-07-17 10:19:27 +01:00
Hanno Becker 627fbee41a Don't offer SHA-1 in CertificateRequest message in TLS 1.2
mbedtls_ssL_set_calc_verify_md() is used to select valid hashes when
writing the server's CertificateRequest message, as well as to verify
and act on the client's choice when reading its CertificateVerify
message.

If enabled at compile-time and configured via mbedtls_ssl_conf_sig_hashes()
the current code also offers SHA-1 in TLS 1.2. However, the SHA-1-based
handshake transcript in TLS 1.2 is different from the SHA-1 handshake
transcript used in TLS < 1.2, and we only maintain the latter
(through ssl_update_checksum_md5sha1()), but not the former.
Concretely, this will lead to CertificateVerify verification failure
if the client picks SHA-1 for the CertificateVerify message in a TLS 1.2
handshake.

This commit removes SHA-1 from the list of supported hashes in
the CertificateRequest message, and adapts two tests in ssl-opt.sh
which expect SHA-1 to be listed in the CertificateRequest message.
2019-07-17 10:19:27 +01:00
Hanno Becker 0a6417041e Remove redundant check in mbedtls_ssl_set_calc_verify_md()
mbedtls_ssl_set_calc_verify_md() is only called from places
where it has been checked that TLS 1.2 is being used. The
corresponding compile-time and runtime guards checking the
version in mbedtls_ssl_set_calc_verify_md() are therefore
redundant and can be removed.
2019-07-17 10:19:25 +01:00
Simon Butcher ae3f8511fd Merge remote-tracking branch 'origin/pr/615' into baremetal 2019-07-15 19:24:44 +01:00
Simon Butcher feb1cee36e Merge remote-tracking branch 'origin/pr/602' into baremetal 2019-07-15 19:24:11 +01:00
Hanno Becker 7decea9ea9 Simplify supported EC extension writing code
The previous code writes the content (the EC curve list) of the extension
before writing the extension length field at the beginning, which is common
in the library in places where we don't know the length upfront. Here,
however, we do traverse the EC curve list upfront to infer its length
and do the bounds check, so we can reorder the code to write the extension
linearly and hence improve readability.
2019-07-12 15:25:03 +01:00
Hanno Becker c1096e7514 Allow hardcoding single supported elliptic curve
This commit introduces the option MBEDTLS_SSL_CONF_SINGLE_EC
which can be used to register a single supported elliptic curve
at compile time. It replaces the runtime configuration API
mbedtls_ssl_conf_curves() which allows to register a _list_
of supported elliptic curves.

In contrast to other options used to hardcode configuration options,
MBEDTLS_SSL_CONF_SINGLE_EC isn't a numeric option, but instead it's
only relevant if it's defined or not. To actually set the single
elliptic curve that should be supported, numeric options

MBEDTLS_SSL_CONF_SINGLE_EC_TLS_ID
MBEDTLS_SSL_CONF_SINGLE_EC_GRP_ID

must both be defined and provide the TLS ID and the Mbed TLS internal
ID and the chosen curve, respectively.
2019-07-12 15:25:03 +01:00
Hanno Becker ee24f8cecb Remove unnecessary check for presence of supported EC list
For both client/server the EC curve list is assumed not to be NULL:

- On the client-side, it's assumed when writing the
  supported elliptic curve extension:

    c54ee936d7/library/ssl_cli.c (L316)

- On the server, it is assumed when searching for a
  suitable curve for the ECDHE exchange:

    c54ee936d7/library/ssl_srv.c (L3200)

It is therefore not necessary to check this in mbedtls_ssl_check_curve().
2019-07-12 15:25:03 +01:00
Hanno Becker a4a9c696c1 Introduce helper macro for traversal of supported EC TLS IDs 2019-07-12 15:25:03 +01:00
Hanno Becker 80855881ec Remove unnecessary guards in client-side EC curve extension writing
ssl_write_supported_elliptic_curves_ext() is guarded by

```
    #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
       defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
```

each of which implies (by check_config.h) that MBEDTLS_ECP_C
is enabled.
2019-07-12 15:25:03 +01:00
Hanno Becker 84fb902ea5 Work on client-provided supported EC TLS ID list in-place 2019-07-12 15:25:01 +01:00
Hanno Becker 004619fa25 Store TLS curve ID instead of information structure
This will reduce the number of grp ID <-> tls ID <-> curve info structs
conversions once a single EC can be hardcoded through its TLS ID.
2019-07-12 15:19:43 +01:00
Hanno Becker 33b9b25a48 Remove SSL version configuration API if versions are hardcoded 2019-07-12 15:15:08 +01:00
Hanno Becker 0a92b8156d Remove mbedtls_ssl_transform::minor_ver if the version is hardcoded 2019-07-12 15:15:08 +01:00
Hanno Becker 18729aeaac Guard RSA-only max_major/minor_ver fields from SSL handshake params
The fields
- mbedtls_ssl_handshake_params::max_major_ver,
- mbedtls_ssl_handshake_params::max_minor_ver
are used only for server-side RSA-based key exchanges
can be removed otherwise.
2019-07-12 15:15:07 +01:00
Hanno Becker 7b628e5b88 Make mbedtls_ssl_read/write_version static inline
Reasons:
- If the transport type is fixed at compile-time,
  mbedtls_ssl_read_version() and mbedtls_ssl_write_version()
  are called with a compile-time determined `transport`
  parameter, so the transport-type branch in their body
  can be eliminated at compile-time.
- mbedtls_ssl_read_version() is called with addresses of
  local variables, which so far need to be put on the stack
  to be addressable. Inlining the call allows to read directly
  into the registers holding these local variables.

This saves 60 bytes w.r.t. the measurement performed by

> ./scripts/baremetal.sh --rom --gcc
2019-07-12 15:15:07 +01:00
Hanno Becker 381eaa5976 Remove min/maj version from SSL context if only one version enabled
If the minor/major version is enforced at compile-time, the `major_ver`
and `minor_ver` fields in `mbedtls_ssl_context` are redundant and can
be removed.
2019-07-12 15:15:07 +01:00
Hanno Becker 2881d80138 Introduce getter function for max/min SSL version
This is a first step towards hardcoding ssl->{major|minor}_ver
in configurations which accept only a single version.
2019-07-12 15:15:06 +01:00
Hanno Becker 3fa1ee567c Set SSL minor version only after validation 2019-07-12 15:14:53 +01:00
Hanno Becker e965bd397e Allow hardcoding of min/max minor/major SSL version at compile-time
This commit introduces the numeric compile-time constants

- MBEDTLS_SSL_CONF_MIN_MINOR_VER
- MBEDTLS_SSL_CONF_MAX_MINOR_VER
- MBEDTLS_SSL_CONF_MIN_MAJOR_VER
- MBEDTLS_SSL_CONF_MAX_MAJOR_VER

which, when defined, overwrite the runtime configurable fields
mbedtls_ssl_config::min_major_ver etc. in the SSL configuration.

As for the preceding case of the ExtendedMasterSecret configuration,
it also introduces and puts to use getter functions for these variables
which evaluate to either a field access or the macro value, maintaining
readability of the code.

The runtime configuration API mbedtls_ssl_conf_{min|max}_version()
is kept for now but has no effect if MBEDTLS_SSL_CONF_XXX are set.
This is likely to be changed in a later commit but deliberately omitted
for now, in order to be able to study code-size benefits earlier in the
process.
2019-07-12 15:14:51 +01:00
Simon Butcher fabfb8578a Merge remote-tracking branch 'origin/pr/603' into baremetal 2019-07-10 15:40:32 +01:00
Simon Butcher 133294eb4a Merge remote-tracking branch 'origin/mbedtls-2.16' into baremetal 2019-07-10 11:38:01 +01:00
Hanno Becker 14a4a44e60 Remove mbedtls_ssl_conf_dbg() if !MBEDTLS_DEBUG_C 2019-07-08 11:32:50 +01:00
Hanno Becker 272063abfd Don't store debug func ptr cb + ctx in SSL config if !DEBUG_C
Note: This is an structure-API breaking change that we might
      not be able to upstream.
2019-07-08 11:32:10 +01:00
Hanno Becker 779d79dcd7 Restore static inline qualif'n of some helpers in ssl_ciphersuites.h 2019-07-08 11:23:25 +01:00
Hanno Becker a1552ac37c Use "unknown" instead of NULL as name of unknown ciphersuite 2019-07-08 11:23:25 +01:00
Hanno Becker 9b3ec12863 Add missing spaces at the end of comments 2019-07-08 11:23:24 +01:00
Hanno Becker f4d6b49352 Allow use of continue in single-ciphersuite 'loops' 2019-07-08 11:23:24 +01:00
Hanno Becker 67fb16e59d Make ciphersuite helpers static inline if only one suite enabled
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.
2019-07-08 11:23:24 +01:00
Hanno Becker 73f4cb126d Rename XXX_SINGLE_CIPHERSUITE -> XXX_CONF_SINGLE_CIPHERSUITE
This is in line with the other configurations options used
to hardcoded aspects of the SSL configuration.
2019-07-08 11:23:24 +01:00
Hanno Becker e02758c9c8 Remove ciphersuite from SSL session if single suite hardcoded
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.
2019-07-08 11:23:24 +01:00
Hanno Becker 6ace4657b6 Remove ciphersuite from SSL config if single suite hardcoded
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.
2019-07-08 11:23:24 +01:00
Hanno Becker df64596733 Remove ciphersuite from handshake params if single suite hardcoded
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.
2019-07-08 11:23:24 +01:00
Hanno Becker 2d46b4f2a1 Adapt ClientHello parsing to case of single hardcoded ciphersuite
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().
2019-07-08 11:23:17 +01:00
Hanno Becker 1499027d02 Adapt ClientHello writing to case of single hardcoded ciphersuite
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.
2019-07-08 11:17:53 +01:00
Hanno Becker 5cce936e62 Add compile-time option to hardcode choice of single ciphersuite 2019-07-08 11:17:53 +01:00
Hanno Becker b09132d33a 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.
2019-07-08 11:17:53 +01:00
Hanno Becker 473f98f2e0 Introduce ciphersuite handle type
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.
2019-07-08 11:17:53 +01:00
Jaeden Amero c041b4fc94 Merge remote-tracking branch 'origin/pr/2700' into mbedtls-2.16
* origin/pr/2700:
  Changelog entry for HAVEGE fix
  Prevent building the HAVEGE module on platforms where it doesn't work
  Fix misuse of signed ints in the HAVEGE module
2019-07-05 15:43:18 +01:00
Manuel Pégourié-Gonnard 5455afd74e
Merge pull request #599 from ARMmbed/baremetal-ec-preparation
[Baremetal] Avoid heap-allocation for client-supported elliptic curves
2019-07-05 14:16:41 +02:00