Commit Graph

10569 Commits

Author SHA1 Message Date
Hanno Becker
2eb716d626 Restructure incoming CliKeyExch: Remove old code
The code from the previous function ssl_parse_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
e7c4eed9b8 Restructure incoming CliKeyExch: Parsing code 2019-08-12 17:05:03 +01:00
Hanno Becker
1e23af8fa8 Restructure incoming CliKeyExch: Move PMS assembly code
After parsing and performing key generation operations,
the server-side incoming 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 comes done after the ClientKeyExchange
has been parsed and the respective keying material has been generated,
and this commit moves it to the new postprocessing function
ssl_client_key_exchange_postprocess().
2019-08-12 17:05:03 +01:00
Hanno Becker
dc8bfb9001 Restructure incoming CliKeyExch: Move key derivation code
This commit moves the generation of the master secret and session keys
from the premaster secret (done in mbedtlsssl_derive_keys()) from the
previous ClientKeyExchange parsing function ssl_parse_client_key_exchange()
to the new postprocessing function ssl_client_key_exchange_postprocess().
2019-08-12 17:05:03 +01:00
Hanno Becker
7ec345d95f Restructure incoming CliKeyExch: Add frame for restructuring
This commit adds declarations and dummy implementations for
the restructured incoming client key exchange handling that
will replace the previous ssl_parse_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:

- Fetching: Read next message from the messaging layer
            and check that it has the correct type.
            The ClientKeyExchange message is never
            omitted, so there is no ambiguity in what
            to expect, and hence no dedicated preparation
            step as for other handshake states.
- Parsing:  Parse the ClientKeyExchange message and
            use the information in it to derive keying
            material such as the shared (EC)DHE secret.
- Postprocessing:
            Compute the session keys from the available
            keying material. This splits in two steps:
            (1) Build the PreMasterSecret (PMS) from the
                available keying material, e.g. concatenate
                the (EC)DHE secret with a PSK, if used.
            (2) Extract the MasterSecret and Session Keys
                from the PreMasterSecret.

The subsequent commits will scatter the code from the previous
monolithic function ssl_parse_client_key_exchange() among those
dedicated functions, commenting out each part of
ssl_parse_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_parse_client_key_exchange() will be removed.
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
Gilles Peskine
560f332dd2 Document the rationale for the armel build
Call the component xxx_arm5vte, because that's what it does. Explain
"armel", and more generally why this component exists, in a comment.
2019-08-09 16:06:27 +02:00
Simon Butcher
88eda1a11c Merge remote-tracking branch 'origin/pr/636' into baremetal 2019-08-09 14:07:12 +01:00
Simon Butcher
7c1380d9d4 Merge remote-tracking branch 'origin/pr/619' into baremetal 2019-08-09 14:05:50 +01:00
Gilles Peskine
e07b9ff2d9 Switch armel build to -Os
Without any -O option, the default is -O0, and then the assembly code
is not used, so this would not be a non-regression test for the
assembly code that doesn't build.
2019-08-08 16:12:46 +02:00
Gilles Peskine
8aa5c2faa5
Merge pull request #2775 from gilles-peskine-arm/pr_2419-changelog
Backport 2.16: Changelog entry for test certificates update
2019-08-06 10:51:52 +02:00
Gilles Peskine
0bd284dc51 Add a build on ARMv5TE in ARM mode
Non-regression test for
"bn_mul.h: require at least ARMv6 to enable the ARM DSP code"
2019-08-05 11:34:25 +02:00
Gilles Peskine
9ff53ffbda Add changelog entry for ARM assembly fix 2019-08-05 11:34:11 +02:00
Gilles Peskine
c3c738e0fe
Merge pull request #639 from ARMmbed/mbedtls-2.16-proposed
Merge mbedtls-2.16 into mbedtls-2.16-restricted
2019-08-05 11:06:37 +02:00
Aurelien Jarno
a6901796f6 bn_mul.h: require at least ARMv6 to enable the ARM DSP code
Commit 16b1bd8932 "bn_mul.h: add ARM DSP optimized MULADDC code"
added some ARM DSP instructions that was assumed to always be available
when __ARM_FEATURE_DSP is defined to 1. Unfortunately it appears that
the ARMv5TE architecture (GCC flag -march=armv5te) supports the DSP
instructions, but only in Thumb mode and not in ARM mode, despite
defining __ARM_FEATURE_DSP in both cases.

This patch fixes the build issue by requiring at least ARMv6 in addition
to the DSP feature.
2019-08-03 14:22:32 +02:00
Gilles Peskine
77a2916bbd Changelog entry for test certificates update 2019-08-03 14:10:44 +02:00
Gilles Peskine
a60dc25e9f
Merge pull request #2419 from RonEld/Backport2.16_2734
Backport 2.16: Update soon to be expired crl
2019-08-03 13:38:20 +02:00
Gilles Peskine
1e3eb28ae3
Merge pull request #2735 from hanno-arm/skip_test-2.16
2.16: Add TEST_ASSUME macro to allow skipping tests at runtime
2019-08-03 13:37:59 +02:00
Gilles Peskine
56216b5a3c
Merge pull request #2761 from dgreen-arm/backport-2.16-fix-rev-parse-in-abi-script
Backport 2.16: Change worktree_rev to HEAD for rev-parse
2019-08-03 13:37:14 +02:00
Manuel Pégourié-Gonnard
f3a15b3de0 Fix possibly-lossy conversion warning from MSVC
ssl_tls.c(4876): warning C4267: '=': conversion from 'size_t' to 'uint8_t', possible loss of data
2019-08-02 10:17:15 +02:00
Manuel Pégourié-Gonnard
39581c7cf4 Merge branch 'mbedtls-2.16' into baremetal-2.16-20190801
* mbedtls-2.16:
  Fix parsing issue when int parameter is in base 16
  Refactor receive_uint32()
  Refactor get_byte function
  Make the script portable to both pythons
  Update the test encoding to support python3
  update the test script
  tests: Limit each log to 10 GiB
2019-08-01 11:05:18 +02:00
Manuel Pégourié-Gonnard
646a466ae2
Merge pull request #628 from hanno-arm/hardcoding_tests-baremetal
[Baremetal] Add all.sh tests for hardcoded SSL configuration options
2019-08-01 10:53:51 +02:00
Hanno Becker
8844055b0e Remove compression field from SSL session if compression disabled 2019-08-01 10:11:20 +02:00
Hanno Becker
ec01408389 Reintroduce length 0 check for records 2019-08-01 09:51:54 +02:00
Hanno Becker
8061c6e894 Don't use memcpy() for 2-byte copy operation
Manual copying is slightly shorter here.
2019-08-01 09:51:54 +02:00
Hanno Becker
7b5ba84624 Remove integer parsing macro
If this is introduced, it should be defined in a prominent place
and put to use throughout the library, but this is left for another
time.
2019-08-01 09:51:54 +02:00
Hanno Becker
618176126c Fix alignment in record header parsing routine 2019-08-01 09:51:54 +02:00
Hanno Becker
e03eb7bb64 Don't disallow 'record from another epoch' log msg in proxy ref test
It happens regularly in test runs that the server example application
shuts down a connection, goes into waiting mode for a new connection,
and then receives the encrypted ClosureAlert from the client. The only
reason why this does currently not trigger the 'record from another epoch'
message is that we handle ClientHello parsing outside of the main record
stack because we want to be able to detect SSLv2 ClientHellos. However,
this is likely to go away, and once it happens, we'll see the log message.
Further, when record checking is used, every record, including the mentioned
closure alert, is passed to the record checking API before being passed to
the rest of the stack, which leads to the log message being printed.

In summary, grepping for 'record from another epoch' is a fragile way
of checking whether a reordered message has arrived. A more reliable
way is to grep for 'Buffer record from epoch' which is printed when
a record from a future epoch is actually buffered, and 'ssl_buffer_message'
which is the function buffering a future handshake message.
2019-08-01 09:51:53 +02:00
Hanno Becker
c1c173cadf Make sure 'record from another epoch' is displayed for next epoch
The test 'DTLS proxy: delay ChangeCipherSpec' from ssl-opt.sh
relies on this.
2019-08-01 09:51:53 +02:00
Hanno Becker
5579c5399b Add x509_internal.h to cpp_dummy_build.cpp 2019-08-01 09:51:53 +02:00
Hanno Becker
03e2db6f35 Implement record checking API
This commit implements the record checking API

   mbedtls_ssl_check_record()

on top of the restructured incoming record stack.

Specifically, it makes use of the fact that the core processing routines

  ssl_parse_record_header()
  mbedtls_ssl_decrypt_buf()

now operate on instances of the SSL record structure mbedtls_record
instead of the previous mbedtls_ssl_context::in_xxx fields.
2019-08-01 09:51:53 +02:00
Hanno Becker
21fc61c7a7 Mark ssl_parse_record_header() as const in SSL context 2019-08-01 09:51:53 +02:00
Hanno Becker
c360dcc679 [API break] Remove mbedtls_ssl_context::in_iv field
After the rewrite of incoming record processing to use the internal
SSL record structure mbedtls_record (which contains the data_offset
field to indicate where the IV resides), this field is no longer
necessary.

Note: This is an API break.
2019-08-01 09:51:53 +02:00
Hanno Becker
f903dc8354 Make mbedtls_ssl_in_hdr_len() CID-unaware
The function mbedtls_ssl_in_hdr_len() is supposed to return the length
of the record header of the current incoming record. With the advent
of the DTLS Connection ID, this length is only known at runtime and
hence so far needed to be derived from the internal in_iv pointer
pointing to the beginning of the payload of the current incooing
record.

By now, however, those uses of mbedtls_ssl_in_hdr_len() where the
presence of a CID would need to be detected have been removed
(specifically, ssl_parse_record_header() doesn't use it anymore
when checking that the current datagram is large enough to hold
the record header, including the CID), and it's sufficient to
statically return the default record header sizes of 5 / 13 Bytes
for TLS / DTLS.
2019-08-01 09:51:53 +02:00
Hanno Becker
05413d9041 Remove duplicate setting of ssl->in_msgtype and ssl->in_msglen 2019-08-01 09:51:53 +02:00
Hanno Becker
bd70c8e771 Move update of in_xxx fields in ssl_get_next_record()
ssl_get_next_record() updates the legacy in_xxx fields in two places,
once before record decryption and once after. Now that record decryption
doesn't use or affect the in_xxx fields anymore, setting up the these
legacy fields can entirely be moved to the end of ssl_get_next_record(),
which is what this comit does.

This commit solely moves existing code, but doesn't yet simplify the
now partially redundant settings of the in_xxx fields. This will be
done in a separate commit.
2019-08-01 09:51:53 +02:00
Hanno Becker
bf256cdb0b Move update of in_xxx fields outside of ssl_prepare_record_content()
Multiple record attributes such as content type and payload length
may change during record decryption, and the legacy in_xxx fields
in the SSL context therefore need to be updated after the record
decryption routine ssl_decrypt_buf() has been called.

After the previous commit has made ssl_prepare_record_content()
independent of the in_xxx fields, setting them can be moved
outside of ssl_prepare_record_content(), which is what this
commit does.
2019-08-01 09:51:53 +02:00
Hanno Becker
106f3dab57 Reduce dependency of ssl_prepare_record_content() on in_xxx fields 2019-08-01 09:51:53 +02:00
Hanno Becker
68379720b6 Move ssl_update_in_pointers() to after record hdr parsing
Previously, ssl_update_in_pointers() ensured that the in_xxx pointers
in the SSL context are set to their default state so that the record
header parsing function ssl_parse_record_header() could make use of them.
By now, the latter is independent of these pointers, so they don't need
to be setup before calling ssl_parse_record_header() anymore.
However, other parts of the messaging stack might still depend on it
(to be studied), and hence this commit does not yet reomve
ssl_update_in_pointers() entirely.
2019-08-01 09:51:53 +02:00
Hanno Becker
fc55172c41 Mark DTLS replay check as const on the SSL context 2019-08-01 09:51:53 +02:00
Hanno Becker
6941245852 Move updating the internal rec ptrs to outside of rec hdr parsing
The stack maintains pointers mbedtls_ssl_context::in_xxx pointing to
various parts of the [D]TLS record header. Originally, these fields
were determined and set in ssl_parse_record_header(). By now,
ssl_parse_record_header() has been modularized to setup an instance
of the internal SSL record structure mbedtls_record, and to derive
the old in_xxx fields from that.

This commit takes a further step towards removing the in_xxx fields
by deriving them from the established record structure _outside_ of
ssl_parse_record_header() after the latter has succeeded.

One exception is the handling of possible client reconnects,
which happens in the case then ssl_parse_record_header() returns
MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; since ssl_check_client_reconnect()
so far uses the in_xxx fields, they need to be derived from the
record structure beforehand.
2019-08-01 09:51:53 +02:00
Hanno Becker
40478be987 Mark ssl_decrypt_buf() as `const in the input SSL context
In fact, the SSL context is only used to access the debug callback.
2019-08-01 09:51:52 +02:00
Hanno Becker
a89610aaf2 Adapt ssl_prepare_record_content() to use SSL record structure 2019-08-01 09:51:52 +02:00
Hanno Becker
9babbf7e75 Use record length from record structure when fetching content in TLS 2019-08-01 09:51:52 +02:00
Hanno Becker
2720f4c33c Use record structure when remembering offset of next record in dgram 2019-08-01 09:51:52 +02:00
Hanno Becker
2528ee09ac Use SSL record structure when skipping over unexpected record 2019-08-01 09:51:52 +02:00