Commit graph

477 commits

Author SHA1 Message Date
Hanno Becker 29d165565c Add MBEDTLS_ECDH_C guards to ECDH code-paths using legacy ECDH
Previously, MBEDTLS_KEY_EXCHANGE_ECDH[E]_XXX_ENABLED would imply
that MBEDTLS_ECDH_C is set, but with the introduction of tinyCrypt
as an alternative ECDH implementation, this is no longer the case.
2019-08-12 18:01:40 +01:00
Hanno Becker 975b9ee3c8 Fix guards around use of legacy ECDH context
mbedtls_ssl_handshake_params::ecdh_ctx should only be guarded
by MBEDTLS_ECDH_C, not by MBEDTLS_ECDSA_C.
2019-08-12 17:05:38 +01:00
Hanno Becker 621113fd3a tinyCrypt: Write client's key share 2019-08-12 17:05:38 +01:00
Hanno Becker a3c2c1712c tinyCrypt: Share ECDH secret calculation code-path 2019-08-12 17:05:38 +01:00
Hanno Becker 75f12d1eb9 tinyCrypt: Add ServerKeyExchange parsing code 2019-08-12 17:05:38 +01:00
Hanno Becker ef982d57bf tinyCrypt: Bind RNG wrapper to tinyCrypt in mbedtls_ssl_setup() 2019-08-12 17:05:38 +01:00
Jarno Lamsa e12aafbdc7 tinyCrypt: Initial commit towards ECDHE support
This commit is a first step towards using uECC for ECDH
during TLS handshakes.
2019-08-12 17:05:38 +01:00
Hanno Becker 3328b1822a Move ssl_process_in_server_key_exchange to avoid func use-before-def 2019-08-12 17:05:03 +01:00
Hanno Becker 4e46709800 Document precoditions on some HS parsing/writing functions
Eventually, all HS parsing/writing functions should take an arbitrary buffer +
length pair as their argument, and return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if
the provided buffer is too short. So far, we've only made a first step by
allowing to pass an arbitrary buffer, but don't yet add bounds checks
throughout. While deliberate for now, this must be clearly documented.
2019-08-12 17:05:03 +01:00
Hanno Becker 7d552fad65 Avoid collision of ssl_xxx_key_exchange_yyy() func names in cli/srv
This makes grepping the functions more difficult, and also leads to compilation failures
when trying to build the library from a single source file (which might be useful for
code-size reasons).
2019-08-12 17:05:03 +01:00
Hanno Becker 48e526b380 Document parameter precondition for ssl_rsa_generate_partial_pms() 2019-08-12 17:05:03 +01:00
Hanno Becker aa49620f6e Minor documentation improvement to ssl_rsa_encrypt_partial_pms() 2019-08-12 17:05:03 +01:00
Hanno Becker 084694dd57 Fix copy-pasta in documentation for outgoing CliKeyExchange 2019-08-12 17:05:03 +01:00
Hanno Becker 44a29f4a6f Remove redundant use of local variable in CliKeyExch writing 2019-08-12 17:05:03 +01:00
Hanno Becker ae22dd3820 Simplify logic of restartable ECDHE in CliKeyExch writing 2019-08-12 17:05:03 +01:00
Hanno Becker 91cf7693b9 Remove restartable ECP return code check from ECDH suite handling
mbedtls_ecdh_read_params() is not restartable.
2019-08-12 17:05:03 +01:00
Manuel Pégourié-Gonnard 8793fab635 Fix two typos in comments 2019-08-12 17:05:03 +01:00
Hanno Becker 587c1ae195 Make IAR happy by dummy-initializing an unused variable
IAR doesn't like `((void) var);` as a means to indicate an unused
variable if that variable hasn't been initialized before. Make it
happy by initializing the variable before.
2019-08-12 17:05:03 +01:00
Hanno Becker a855cb635d Avoid unused variable warning in ServerKeyExchange parsing
ssl_server_key_exchange_parse() is compiled even if there's no ciphersuite
enabled which uses it (for example, that's the case in RSA-only builds).
The rationale for that is to avoid cluttering the code with numerous
compile-time guards. A consequence, however, is the top of
ssl_server_key_exchange_parse() contains declarations for variables
which are never put to use, and rightfully leading to compiler warnings.

This commit silences these warnings by putting `((void) VAR);` statements
in the branch which detects if we ever happen to call the function in an
unexpected ciphersuite.
2019-08-12 17:05:03 +01:00
Hanno Becker 868cb586cc Rename SSL_PROC_CHK -> MBEDTLS_SSL_CHK 2019-08-12 17:05:03 +01:00
Hanno Becker 9a12243b01 Introduce getter function for RNG context 2019-08-12 17:05:03 +01:00
Hanno Becker 4ec73cb251 Restructure SrvKeyExchange: Move parsing code 2019-08-12 17:05:03 +01:00
Hanno Becker 8b7b879143 Restructure SrvKeyExchange: Move msg skipping for PSK and RSA-PSK
In the PSK and RSA-PSK ciphersuites, the ServerKeyExchange message
MAY be skipped. This commit moves the code-path peeking at the
incoming message to decide whether it's probably a ServerKeyExchange
to the new coordination function ssl_server_key_exchange_coordinate().
2019-08-12 17:05:03 +01:00
Hanno Becker eb76c20496 Restructure SrvKeyExchange: Move code for skipping SrvKeyExchange
This commit moves the code checking whether a SrvKeyExchange message
is expected or not to the new function ssl_srv_key_exchange_coordinate().

Note that the potential static DH extraction is done prior to the
coordination step.
2019-08-12 17:05:03 +01:00
Hanno Becker fca604d355 Restructure SrvKeyExchange: Move static DH parameter extraction
This code moves the code-path that extracts static DH parameters
from the server's CRT (if applicable) to the new function
ssl_server_key_exchange_prepare().
2019-08-12 17:05:03 +01:00
Hanno Becker 04769ddb84 Restructure SrvKeyExchange: Add frame for structure
This commit adds declarations and dummy implementations for
the restructured incoming server key exchange handling that
will replace the previous ssl_parse_server_key_exchange().

The entry point for the SrvKeyExchange handling that is called
from the handshake state machine is

   `ssl_process_server_key_exchange()`,

splitting the processing into the following steps:

- Preparation: For a static DH key exchange, extract
               DH parameters from the server's CRT.
- Coordination: Check if a SrvKeyExchange message is expected
  (e.g., it isn't for a RSA-based key exchange)
- Reading: Fetch and check content and handshake type
           of incoming message.
- Parsing: Parse and store the ServerKeyExchange message.
- Postprocessing: Update handstate state machine.

The subsequent commits will scatter the code from the previous
monolithic function ssl_parse_server_key_exchange() among those
dedicated functions, commenting out each part of
ssl_parse_server_key_exchange() that has already been dealt with.
This gradual progression is meant to ease reviewing. Once all
code has been moved and all changes explained,
ssl_parse_server_key_exchange() will be removed.
2019-08-12 17:05:03 +01:00
Hanno Becker 09d236419e Share code between In-CliKeyExch and Out-CliKeyExch
The postprocessing code for the server-side incoming client key
exchange and the client-side outgoing client key exchange both
contain the same code-paths for building the premaster secret
depending on the chosen ciphersuite (e.g., for ECDHE-PSK,
concatenating the ECDHE secret with the chosen PSK).

This commit moves this common code to ssl_tls.c, allowing
client- and server-side to share it.
2019-08-12 17:05:03 +01:00
Hanno Becker 4f68b04018 Restructure outgoing CliKeyExch: Remove old code
The code from the previous function ssl_write_client_key_exchange()
has been entirely moved to one of the newly introduced subroutines
and is no longer needed. This commit removes it.
2019-08-12 17:05:03 +01:00
Hanno Becker 87e3c9aae8 Restructure outgoing CliKeyExch: Move writing code
This commit moves the code responsible for
(a) generating the client's private and public (EC)DHE keys
(b) writing it to the message buffer
to the new writing function ssl_client_key_exchange_write().

As mentioned in the previous commit message, (a) and (b) are
currently inseparable at the (EC)DHE API level, which is why
(a) can't be moved to the preparation step.
2019-08-12 17:05:03 +01:00
Hanno Becker 01290c7240 Restructure outgoing CliKeyExch: Move RSA/RSA-PSK PMS generation
For RSA or RSA-PSK exchanges, the PMS contains 46 random bytes
picked by the client. These bytes are generated prior to the
writing of the ClientKeyExchange message.

This commit splits the previous function ssl_write_encrypted_pms() into
PPMS-GEN: ssl_rsa_generate_partial_pms()
PPMS-ENC: ssl_rsa_encrypt_partial_pms().
The prefix 'partial' is meant to emphasize that the generation of the PMS
is not always entirely done by these functions: For RSA-PSK e.g., the
PSK still needs to be added.

The two calls of ssl_write_encrypted_pms() in
ssl_write_client_key_exchange() will split in calls of the functions
PPMS-GEN and PPMS-ENC each, with PPMS-GEN being moved to the new
preparation function ssl_client_key_exchange_prepare() in this commit,
and PPMS-ENC being moved to ssl_client_key_exchange_write() in the
next commit.
2019-08-12 17:05:03 +01:00
Hanno Becker 6fb638b2fb Restructure outgoing CliKeyExch: Move PMS assembly code
After and performing key generation operations,
the client-side outgoing ClientKeyExchange handling includes
code-paths to assembly the PreMasterSecret (PMS) from the
available keying material, the exact assembly procedure
depending on which ciphersuite is in use. E.g., in an
(EC)DHE-PSK ciphersuite, the (EC)DHE secret would be concatenated
with the PSK to form the PMS.

This assembly of the PMS logically can be done after the ClientKeyExchange
has been written and the respective keying material has been generated,
and this commit moves it to the new postprocessing function
ssl_client_key_exchange_postprocess().

Ideally, the PMS assembly could be done prior to writing the
ClientKeyExchange message, but the (EC)DHE API does currently
not allow splitting secret-generation and secret-export; as
long as that's the case, we to generation and exporting in the
message writing function, forcing PMS assembly to be done in
the postprocessing.
2019-08-12 17:05:03 +01:00
Hanno Becker 5d397686a9 Restructure outgoing CliKeyExch: Add frame for new structure
This commit adds declarations and dummy implementations for
the restructured outgoing client key exchange handling that
will replace the previous ssl_write_client_key_exchange().

The entry point for the CliKeyExchange handling that is called
from the handshake state machine is

   `ssl_process_client_key_exchange()`,

splitting the processing into the following steps:

- Preparation
  Compute the keying material to be sent.
  * For (EC)DH: Pick parameters and compute PMS.
  * For ECJPAKE: Run round 2
  * For RSA: Encrypt PMS
- Writing: Prepare the writing of a new messae.
- Postprocessing: Update handstate state machine.

The subsequent commits will scatter the code from the previous
monolithic function ssl_write_client_key_exchange() among those
dedicated functions, commenting out each part of
ssl_write_client_key_exchange() that has already been dealt with.
This gradual progression is meant to ease reviewing. Once all
code has been moved and all changes explained,
ssl_write_client_key_exchange() will be removed.
2019-08-12 17:05:03 +01:00
Hanno Becker de62da9d3c Use separate functions to pend fatal and non-fatal alerts 2019-07-24 13:45:35 +01:00
Hanno Becker 1facd552fc Replace xxx_send_alert by xxx_pend_alert to save code 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
Hanno Becker 981f81dc30 Add missing uses of mbedtls_ssl_get_minor() 2019-07-19 16:12:54 +01:00
Hanno Becker f1bc9e1c69 Introduce helper functions to traverse signature hashes 2019-07-17 10:19:27 +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 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 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
Hanno Becker f4d6b49352 Allow use of continue in single-ciphersuite 'loops' 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 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 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