When MBEDTLS_SSL_ENCRYPT_THEN_MAC is enabled, but not
MBEDTLS_SSL_SOME_MODES_USE_MAC, mbedtls_ssl_derive_keys() and
build_transforms() will attempt to use a non-existent `encrypt_then_mac`
field in the ssl_transform.
Compile [ 93.7%]: ssl_tls.c
[Error] ssl_tls.c@865,14: 'mbedtls_ssl_transform {aka struct mbedtls_ssl_transform}' ha
s no member named 'encrypt_then_mac'
[ERROR] ./mbed-os/features/mbedtls/src/ssl_tls.c: In function 'mbedtls_ssl_derive_keys'
:
./mbed-os/features/mbedtls/src/ssl_tls.c:865:14: error: 'mbedtls_ssl_transform {aka str
uct mbedtls_ssl_transform}' has no member named 'encrypt_then_mac'
transform->encrypt_then_mac = session->encrypt_then_mac;
^~
Change mbedtls_ssl_derive_keys() and build_transforms() to only access
`encrypt_then_mac` if `encrypt_then_mac` is actually present.
Add a regression test to detect when we have regressions with
configurations that do not include any MAC ciphersuites.
Fixes d56ed2491b ("Reduce size of `ssl_transform` if no MAC ciphersuite is enabled")
When MBEDTLS_PSA_INJECT_ENTROPY is used, we now require also defining
MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES. When
MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES is defined, we do not add entropy
sources by default. This includes the NV seed entropy source, which the
PSA entropy injection API is built upon.
The PSA entropy injection feature depends on using NV seed as an entropy
source. Add NV seed as an entropy source for PSA entropy injection.
Fixes e3dbdd8d90 ("Gate entropy injection through a dedicated configuration option")
Now that psa_allocate_key() is no longer a public function, expose
psa_internal_allocate_key_slot() instead, which provides a pointer to
the slot to its caller.
Remove the key creation functions from before the attribute-based API,
i.e. the key creation functions that worked by allocating a slot, then
setting metadata through the handle and finally creating key material.
- Explain the use of explicit ASN.1 tagging for the extensions structuree
- Remove misleading comment which suggests that mbedtls_x509_get_ext()
also parsed the header of the first extension, which is not the case.
Some functions within the X.509 module return an ASN.1 low level
error code where instead this error code should be wrapped by a
high-level X.509 error code as in the bulk of the module.
Specifically, the following functions are affected:
- mbedtls_x509_get_ext()
- x509_get_version()
- x509_get_uid()
This commit modifies these functions to always return an
X.509 high level error code.
Care has to be taken when adapting `mbetls_x509_get_ext()`:
Currently, the callers `mbedtls_x509_crt_ext()` treat the
return code `MBEDTLS_ERR_ASN1_UNEXPECTED_TAG` specially to
gracefully detect and continue if the extension structure is not
present. Wrapping the ASN.1 error with
`MBEDTLS_ERR_X509_INVALID_EXTENSIONS` and adapting the check
accordingly would mean that an unexpected tag somewhere
down the extension parsing would be ignored by the caller.
The way out of this is the following: Luckily, the extension
structure is always the last field in the surrounding structure,
so if there is some data remaining, it must be an Extension
structure, so we don't need to deal with a tag mismatch gracefully
in the first place.
We may therefore wrap the return code from the initial call to
`mbedtls_asn1_get_tag()` in `mbedtls_x509_get_ext()` by
`MBEDTLS_ERR_X509_INVALID_EXTENSIONS` and simply remove
the special treatment of `MBEDTLS_ERR_ASN1_UNEXPECTED_TAG`
in the callers `x509_crl_get_ext()` and `x509_crt_get_ext()`.
This renders `mbedtls_x509_get_ext()` unsuitable if it ever
happened that an Extension structure is optional and does not
occur at the end of its surrounding structure, but for CRTs
and CRLs, it's fine.
The following tests need to be adapted:
- "TBSCertificate v3, issuerID wrong tag"
The issuerID is optional, so if we look for its presence
but find a different tag, we silently continue and try
parsing the subjectID, and then the extensions. The tag '00'
used in this test doesn't match either of these, and the
previous code would hence return LENGTH_MISMATCH after
unsucessfully trying issuerID, subjectID and Extensions.
With the new code, any data remaining after issuerID and
subjectID _must_ be Extension data, so we fail with
UNEXPECTED_TAG when trying to parse the Extension data.
- "TBSCertificate v3, UIDs, invalid length"
The test hardcodes the expectation of
MBEDTLS_ERR_ASN1_INVALID_LENGTH, which needs to be
wrapped in MBEDTLS_ERR_X509_INVALID_FORMAT now.
Fixes#2431.
When parsing a substructure of an ASN.1 structure, no field within
the substructure must exceed the bounds of the substructure.
Concretely, the `end` pointer passed to the ASN.1 parsing routines
must be updated to point to the end of the substructure while parsing
the latter.
This was previously not the case for the routines
- x509_get_attr_type_and_value(),
- mbedtls_x509_get_crt_ext(),
- mbedtls_x509_get_crl_ext().
These functions kept using the end of the parent structure as the
`end` pointer and would hence allow substructure fields to cross
the substructure boundary. This could lead to successful parsing
of ill-formed X.509 CRTs.
This commit fixes this.
Care has to be taken when adapting `mbedtls_x509_get_crt_ext()`
and `mbedtls_x509_get_crl_ext()`, as the underlying function
`mbedtls_x509_get_ext()` returns `0` if no extensions are present
but doesn't set the variable which holds the bounds of the Extensions
structure in case the latter is present. This commit addresses
this by returning early from `mbedtls_x509_get_crt_ext()` and
`mbedtls_x509_get_crl_ext()` if parsing has reached the end of
the input buffer.
The following X.509 parsing tests need to be adapted:
- "TBSCertificate, issuer two inner set datas"
This test exercises the X.509 CRT parser with a Subject name
which has two empty `AttributeTypeAndValue` structures.
This is supposed to fail with `MBEDTLS_ERR_ASN1_OUT_OF_DATA`
because the parser should attempt to parse the first structure
and fail because of a lack of data. Previously, it failed to
obey the (0-length) bounds of the first AttributeTypeAndValue
structure and would try to interpret the beginning of the second
AttributeTypeAndValue structure as the first field of the first
AttributeTypeAndValue structure, returning an UNEXPECTED_TAG error.
- "TBSCertificate, issuer, no full following string"
This test exercises the parser's behaviour on an AttributeTypeAndValue
structure which contains more data than expected; it should therefore
fail with MBEDTLS_ERR_ASN1_LENGTH_MISMATCH. Because of the missing bounds
check, it previously failed with UNEXPECTED_TAG because it interpreted
the remaining byte in the first AttributeTypeAndValue structure as the
first byte in the second AttributeTypeAndValue structure.
- "SubjectAltName repeated"
This test should exercise two SubjectAltNames extensions in succession,
but a wrong length values makes the second SubjectAltNames extension appear
outside of the Extensions structure. With the new bounds in place, this
therefore fails with a LENGTH_MISMATCH error. This commit adapts the test
data to put the 2nd SubjectAltNames extension inside the Extensions
structure, too.
All of them are copied from (former) CRT and key files in `tests/data_files`.
For files which have been regenerated since they've been copied to `certs.c`,
update the copy.
Add declarations for DER encoded test CRTs to certs.h
Add DER encoded versions of CRTs to certs.c
fix comment in certs.c
Don't use (signed) char for DER encoded certificates
Consistently use `const char *` for test CRTs regardless of encoding
Remove non-sensical and unused PW variable for DER encoded key
Provide test CRTs in PEM and DER fmt, + pick suitable per config
This commit modifies `certs.h` and `certs.c` to start following the
following pattern for the provided test certificates and files:
- Raw test data is named `NAME_ATTR1_ATTR2_..._ATTRn`
For example, there are
`TEST_CA_CRT_{RSA|EC}_{PEM|DER}_{SHA1|SHA256}`.
- Derived test data with fewer attributes, iteratively defined as one
of the raw test data instances which suits the current configuration.
For example,
`TEST_CA_CRT_RSA_PEM`
is one of `TEST_CA_CRT_RSA_PEM_SHA1` or `TEST_CA_CRT_RSA_PEM_SHA256`,
depending on whether SHA-1 and/or SHA-256 are defined in the current
config.
Add missing public declaration of test key password
Fix signedness and naming mismatches
Further improve structure of certs.h and certs.c
Fix definition of mbedtls_test_cas test CRTs depending on config
Remove semicolon after macro string constant in certs.c
This commit modifies mbedtls_ssl_get_peer_cid() to also allow passing
NULL pointers in the arguments for the peer's CID value and length, in
case this information is needed.
For example, some users might only be interested in whether the use of
the CID was negotiated, in which case both CID value and length pointers
can be set to NULL. Other users might only be interested in confirming
that the use of CID was negotiated and the peer chose the empty CID,
in which case the CID value pointer only would be set to NULL.
It doesn't make sense to pass a NULL pointer for the CID length but a
non-NULL pointer for the CID value, as the caller has no way of telling
the length of the returned CID - and this case is therefore forbidden.
This commit modifies the CID configuration API mbedtls_ssl_conf_cid_len()
to allow the configuration of the stack's behaviour when receiving an
encrypted DTLS record with unexpected CID.
Currently, the stack silently ignores DTLS frames with an unexpected CID.
However, in a system which performs CID-based demultiplexing before passing
datagrams to the Mbed TLS stack, unexpected CIDs are a sign of something not
working properly, and users might want to know about it.
This commit introduces an SSL error code MBEDTLS_ERR_SSL_UNEXPECTED_CID
which the stack can return in response to an unexpected CID. It will
conditionally be put to use in subsequent commits.
There are two options:
1. Don't set it, and don't use it during record protection,
guarding the respective paths by a check whether TLS or
DTLS is used.
2. Set it to the default value even for TLS, and avoid the
protocol-dependent branch during record protection.
This commit picks option 2.
This commit changes the stack's behaviour when facing a record
with a non-matching CID. Previously, the stack failed in this
case, while now we silently skip over the current record.
Previously, ssl_get_next_record() would fetch 13 Bytes for the
record header and hand over to ssl_parse_record_header() to parse
and validate these. With the introduction of CID-based records, the
record length is not known in advance, and parsing and validating
must happen at the same time. ssl_parse_record_header() is therefore
rewritten in the following way:
1. Fetch and validate record content type and version.
2. If the record content type indicates a record including a CID,
adjust the record header pointers accordingly; here, we use the
statically configured length of incoming CIDs, avoiding any
elaborate CID parsing mechanism or dependency on the record
epoch, as explained in the previous commit.
3. Fetch the rest of the record header (note: this doesn't actually
fetch anything, but makes sure that the datagram fetched in the
earlier call to ssl_fetch_input() contains enough data).
4. Parse and validate the rest of the record header as before.
This commit modifies the code surrounding the invocations of
ssl_decrypt_buf() and ssl_encrypt_buf() to deal with a change
of record content type during CID-based record encryption/decryption.
mbedtls_ssl_context contains pointers in_buf, in_hdr, in_len, ...
which point to various parts of the header of an incoming TLS or
DTLS record; similarly, there are pointers out_buf, ... for
outgoing records.
This commit adds fields in_cid and out_cid which point to where
the CID of incoming/outgoing records should reside, if present,
namely prior to where the record length resides.
Quoting https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-04:
The DTLSInnerPlaintext value is then encrypted and the CID added to
produce the final DTLSCiphertext.
struct {
ContentType special_type = tls12_cid; /* 25 */
ProtocolVersion version;
uint16 epoch;
uint48 sequence_number;
opaque cid[cid_length]; // New field
uint16 length;
opaque enc_content[DTLSCiphertext.length];
} DTLSCiphertext;
For outgoing records, out_cid is set in ssl_update_out_pointers()
based on the settings in the current outgoing transform.
For incoming records, ssl_update_in_pointers() sets in_cid as if no
CID was present, and it is the responsibility of ssl_parse_record_header()
to update the field (as well as in_len, in_msg and in_iv) when parsing
records that do contain a CID. This will be done in a subsequent commit.
Finally, the code around the invocations of ssl_decrypt_buf()
and ssl_encrypt_buf() is adapted to transfer the CID from the
input/output buffer to the CID field in the internal record
structure (which is what ssl_{encrypt/decrypt}_buf() uses).
Note that mbedtls_ssl_in_hdr_len() doesn't need change because
it infers the header length as in_iv - in_hdr, which will account
for the CID for records using such.
Using the Connection ID extension increases the maximum record expansion
because
- the real record content type is added to the plaintext
- the plaintext may be padded with an arbitrary number of
zero bytes, in order to prevent leakage of information
through package length analysis. Currently, we always
pad the plaintext in a minimal way so that its length
is a multiple of 16 Bytes.
This commit adapts the various parts of the library to account
for that additional source of record expansion.
Context:
The CID draft does not require that the length of CIDs used for incoming
records must not change in the course of a connection. Since the record
header does not contain a length field for the CID, this means that if
CIDs of varying lengths are used, the CID length must be inferred from
other aspects of the record header (such as the epoch) and/or by means
outside of the protocol, e.g. by coding its length in the CID itself.
Inferring the CID length from the record's epoch is theoretically possible
in DTLS 1.2, but it requires the information about the epoch to be present
even if the epoch is no longer used: That's because one should silently drop
records from old epochs, but not the entire datagrams to which they belong
(there might be entire flights in a single datagram, including a change of
epoch); however, in order to do so, one needs to parse the record's content
length, the position of which is only known once the CID length for the epoch
is known. In conclusion, it puts a significant burden on the implementation
to infer the CID length from the record epoch, which moreover mangles record
processing with the high-level logic of the protocol (determining which epochs
are in use in which flights, when they are changed, etc. -- this would normally
determine when we drop epochs).
Moreover, with DTLS 1.3, CIDs are no longer uniquely associated to epochs,
but every epoch may use a set of CIDs of varying lengths -- in that case,
it's even theoretically impossible to do record header parsing based on
the epoch configuration only.
We must therefore seek a way for standalone record header parsing, which
means that we must either (a) fix the CID lengths for incoming records,
or (b) allow the application-code to configure a callback to implement
an application-specific CID parsing which would somehow infer the length
of the CID from the CID itself.
Supporting multiple lengths for incoming CIDs significantly increases
complexity while, on the other hand, the restriction to a fixed CID length
for incoming CIDs (which the application controls - in contrast to the
lengths of the CIDs used when writing messages to the peer) doesn't
appear to severely limit the usefulness of the CID extension.
Therefore, the initial implementation of the CID feature will require
a fixed length for incoming CIDs, which is what this commit enforces,
in the following way:
In order to avoid a change of API in case support for variable lengths
CIDs shall be added at some point, we keep mbedtls_ssl_set_cid(), which
includes a CID length parameter, but add a new API mbedtls_ssl_conf_cid_len()
which applies to an SSL configuration, and which fixes the CID length that
any call to mbetls_ssl_set_cid() which applies to an SSL context that is bound
to the given SSL configuration must use.
While this creates a slight redundancy of parameters, it allows to
potentially add an API like mbedtls_ssl_conf_cid_len_cb() later which
could allow users to register a callback which dynamically infers the
length of a CID at record header parsing time, without changing the
rest of the API.
The function mbedtls_ssl_hdr_len() returns the length of the record
header (so far: always 13 Bytes for DTLS, and always 5 Bytes for TLS).
With the introduction of the CID extension, the lengths of record
headers depends on whether the records are incoming or outgoing,
and also on the current transform.
Preparing for this, this commit splits mbedtls_ssl_hdr_len() in two
-- so far unmodified -- functions mbedtls_ssl_in_hdr_len() and
mbedtls_ssl_out_hdr_len() and replaces the uses of mbedtls_ssl_hdr_len()
according to whether they are about incoming or outgoing records.
There is no need to change the signature of mbedtls_ssl_{in/out}_hdr_len()
in preparation for its dependency on the currently active transform,
since the SSL context is passed as an argument, and the currently
active transform is referenced from that.
With the introduction of the CID feature, the stack needs to be able
to handle a change of record content type during record protection,
which in particular means that the record content type check will
need to move or be duplicated.
This commit introduces a tiny static helper function which checks
the validity of record content types, which hopefully makes it
easier to subsequently move or duplicate this check.
With the introduction of the CID extension, the record content type
may change during decryption; we must therefore re-consider every
record content type check that happens before decryption, and either
move or duplicate it to ensure it also applies to records whose
real content type is only revealed during decryption.
This commit does this for the silent dropping of unexpected
ApplicationData records in DTLS. Previously, this was caught
in ssl_parse_record_header(), returning
MBEDTLS_ERR_SSL_UNEXPECTED_RECORD which in ssl_get_next_record()
would lead to silent skipping of the record.
When using CID, this check wouldn't trigger e.g. when delayed
encrypted ApplicationData records come on a CID-based connection
during a renegotiation.
This commit moves the check to mbedtls_ssl_handle_message_type()
and returns MBEDTLS_ERR_SSL_NON_FATAL if it triggers, which leads
so silent skipover in the caller mbedtls_ssl_read_record().
The SSL context structure mbedtls_ssl_context contains several pointers
ssl->in_hdr, ssl->in_len, ssl->in_iv, ssl->in_msg pointing to various
parts of the record header in an incoming record, and they are setup
in the static function ssl_update_in_pointers() based on the _expected_
transform for the next incoming record.
In particular, the pointer ssl->in_msg is set to where the record plaintext
should reside after record decryption, and an assertion double-checks this
after each call to ssl_decrypt_buf().
This commit removes the dependency of ssl_update_in_pointers() on the
expected incoming transform by setting ssl->in_msg to ssl->in_iv --
the beginning of the record content (potentially including the IV) --
and adjusting ssl->in_msg after calling ssl_decrypt_buf() on a protected
record.
Care has to be taken to not load ssl->in_msg before calling
mbedtls_ssl_read_record(), then, which was previously the
case in ssl_parse_server_hello(); the commit fixes that.
If a record exhibits an invalid feature only after successful
authenticated decryption, this is a protocol violation by the
peer and should hence lead to connection failure. The previous
code, however, would silently ignore such records. This commit
fixes this.
So far, the only case to which this applies is the non-acceptance
of empty non-AD records in TLS 1.2. With the present commit, such
records lead to connection failure, while previously, they were
silently ignored.
With the introduction of the Connection ID extension (or TLS 1.3),
this will also apply to records whose real content type -- which
is only revealed during authenticated decryption -- is invalid.
In contrast to other aspects of the Connection ID extension,
the CID-based additional data for MAC computations differs from
the non-CID case even if the CID length is 0, because it
includes the CID length.
Quoting the CID draft 04:
- Block Ciphers:
MAC(MAC_write_key, seq_num +
tls12_cid + // New input
DTLSPlaintext.version +
cid + // New input
cid_length + // New input
length_of_DTLSInnerPlaintext + // New input
DTLSInnerPlaintext.content + // New input
DTLSInnerPlaintext.real_type + // New input
DTLSInnerPlaintext.zeros // New input
)
And similar for AEAD and Encrypt-then-MAC.
This commit temporarily comments the copying of the negotiated CIDs
into the established ::mbedtls_ssl_transform in mbedtls_ssl_derive_keys()
until the CID feature has been fully implemented.
While mbedtls_ssl_decrypt_buf() and mbedtls_ssl_encrypt_buf() do
support CID-based record protection by now and can be unit tested,
the following two changes in the rest of the stack are still missing
before CID-based record protection can be integrated:
- Parsing of CIDs in incoming records.
- Allowing the new CID record content type for incoming records.
- Dealing with a change of record content type during record
decryption.
Further, since mbedtls_ssl_get_peer_cid() judges the use of CIDs by
the CID fields in the currently transforms, this change also requires
temporarily disabling some grepping for ssl_client2 / ssl_server2
debug output in ssl-opt.sh.
This commit modifies ssl_decrypt_buf() and ssl_encrypt_buf()
to include the CID into authentication data during record
protection.
It does not yet implement the new DTLSInnerPlaintext format
from https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-04
If MBEDTLS_PEM_PARSE_C is unset, the DHM selftest fails because
it uses PEM encoded test data.
This commit fixes this by providing the DER encoded form of the
test data instead in case MBEDTLS_PEM_PARSE_C is unset.
Conflicts:
* library/ssl_cli.c, library/ssl_tls.c:
Removed on the development branch. Keep them removed.
* include/psa/crypto_extra.h, library/psa_crypto_storage.c,
tests/suites/test_suite_psa_crypto.data,
tests/suites/test_suite_psa_crypto.function,
tests/suites/test_suite_psa_crypto_persistent_key.data,
tests/suites/test_suite_psa_crypto_slot_management.data,
tests/suites/test_suite_psa_crypto_slot_management.function:
Modified on the development branch only to implement the enrollment
algorithm, which has been reimplemented on the API branch.
Keep the API branch.
* origin/pr/2403: (24 commits)
crypto: Update to Mbed Crypto 8907b019e7
Create seedfile before running tests
crypto: Update to Mbed Crypto 81f9539037
ssl_cli.c : add explicit casting to unsigned char
Generating visualc files - let Mbed TLS take precedence over crypto
Add a link to the seedfile for out-of-tree cmake builds
Adjust visual studio file generation to always use the crypto submodule
all.sh: unparallelize mingw tests
all.sh - disable parallelization for shared target tests
config.pl: disable PSA_ITS_FILE and PSA_CRYPTO_STORAGE for baremetal
all.sh: unset crypto storage define in a psa full config cmake asan test
all.sh: unset FS_IO-dependent defines for tests that do not have it
curves.pl - change test script to not depend on the implementation
Export the submodule flag to sub-cmakes
Disable MBEDTLS_ECP_RESTARTABLE in full config
Export the submodule flag to sub-makes
Force the usage of crypto submodule
Fix crypto submodule usage in Makefile
Documentation rewording
Typo fixes in documentation
...
Signal casting from size_t to unsigned char explicitly, so that the compiler
does not raise a warning about possible loss of data on MSVC, targeting
64-bit Windows.
The guard for the definition of the function was different from the guard on
its only use - make it the same.
This has been caught by tests/scripts/key-exchanges.pl. It had not been caught
by this script in earlier CI runs, because previously USE_PSA_CRYPTO was
disabled in the builds used by this script; enabling it uncovered the issue.
Adapt tests in all.sh:
- tests with submodule enabled (default) no longer need to enable it
explicitly, and no longer need runtime tests, as those are now handled by
all other test cases in this script
- tests with submodule disabled (old default) now need to disable it
explicitly, and execute some runtime tests, as those are no longer tested
anywhere else in this script
Adapt documentation in Readme: remove the section "building with submodule"
and replace it with a new section before the other building sections.
Purposefully don't document how to build not from the submodule, as that
option is going away soon.
Set the next sequence of the subject_alt_name to NULL when deleting
sequence on failure in `get_subject_alt_name()`.
Found by Philippe Antoine. Credit to OSS-Fuzz.
When running lcov, files can't be found relative to the parent project
(Mbed TLS) root. Use full, non-relative paths to refer to files used in
building Mbed Crypto from Mbed TLS in order to enable lcov to locate the
files properly.
When importing a private elliptic curve key, require the input to have
exactly the right size. RFC 5915 requires the right size (you aren't
allowed to omit leading zeros). A different buffer size likely means
that something is wrong, e.g. a mismatch between the declared key type
and the actual data.
Resolve conflicts by performing the following operations:
- Reject changes to files removed during the creation of Mbed Crypto
from Mbed TLS.
- Reject the addition of certificates that would not be used by any
tests, including rejecting the addition of Makefile rules to
generate these certificates.
- Reject changes to error.c referencing modules that are not part of
Mbed Crypto.
* origin/development: (80 commits)
Style fix
Fix test data
Update test data
Add some negative test cases
Fix minor issues
Add ChangeLog entry about listing all SAN
Remove unneeded whitespaces
Fix mingw CI failures
Initialize psa_crypto in ssl test
Check that SAN is not malformed when parsing
Documentation fixes
Fix ChangeLog entry
Fix missing tls version test failures
Fix typo
Fix ChangeLog entry location
Add changeLog entry
Add test for export keys functionality
Add function to retrieve the tls_prf type
Add tests for the public tls_prf API
Add public API for tls_prf
...
* origin/pr/2530: (27 commits)
Style fix
Fix test data
Update test data
Add some negative test cases
Fix minor issues
Add ChangeLog entry about listing all SAN
Check that SAN is not malformed when parsing
Documentation fixes
Fix ChangeLog entry
Fail in case critical crt policy not supported
Update SAN parsing documentation
change the type of hardware_module_name member
Change mbedtls_x509_subject_alternative_name
Add length checking in certificate policy parsing
Rephrase x509_crt extension member description
Rephrase changeLog entries
Remove redundant memset()
Propogate error when parsing SubjectAltNames
Tidy up style in x509_info_subject_alt_name
Print unparseable SubjectAlternativeNames
...
* origin/pr/2538:
Remove unneeded whitespaces
Fix mingw CI failures
Initialize psa_crypto in ssl test
Fix missing tls version test failures
Fix typo
Fix ChangeLog entry location
Add changeLog entry
Add test for export keys functionality
Add function to retrieve the tls_prf type
Add tests for the public tls_prf API
Add public API for tls_prf
Add eap-tls key derivation in the examples.
Add ChangeLog entry
Add an extra key export function
Have the temporary buffer allocated dynamically
Zeroize secret data in the exit point
Add a single exit point in key derivation function
generate_key is a more classical name. The longer name was only
introduced to avoid confusion with getting a key from a generator,
which is key derivation, but we no longer use the generator
terminology so this reason no longer applies.
perl -i -pe 's/psa_generate_random_key/psa_generate_key/g' $(git ls-files)
“Tampering detected” was misleading because in the real world it can
also arise due to a software bug. “Corruption detected” is neutral and
more precisely reflects what can trigger the error.
perl -i -pe 's/PSA_ERROR_TAMPERING_DETECTED/PSA_ERROR_CORRUPTION_DETECTED/gi' $(git ls-files)
Generators are mostly about key derivation (currently: only about key
derivation). "Generator" is not a commonly used term in cryptography.
So favor "derivation" as terminology. Call a generator a key
derivation operation structure, since it behaves like other multipart
operation structures. Furthermore, the function names are not fully
consistent.
In this commit, I rename the functions to consistently have the prefix
"psa_key_derivation_". I used the following command:
perl -i -pe '%t = (
psa_crypto_generator_t => "psa_key_derivation_operation_t",
psa_crypto_generator_init => "psa_key_derivation_init",
psa_key_derivation_setup => "psa_key_derivation_setup",
psa_key_derivation_input_key => "psa_key_derivation_input_key",
psa_key_derivation_input_bytes => "psa_key_derivation_input_bytes",
psa_key_agreement => "psa_key_derivation_key_agreement",
psa_set_generator_capacity => "psa_key_derivation_set_capacity",
psa_get_generator_capacity => "psa_key_derivation_get_capacity",
psa_generator_read => "psa_key_derivation_output_bytes",
psa_generate_derived_key => "psa_key_derivation_output_key",
psa_generator_abort => "psa_key_derivation_abort",
PSA_CRYPTO_GENERATOR_INIT => "PSA_KEY_DERIVATION_OPERATION_INIT",
PSA_GENERATOR_UNBRIDLED_CAPACITY => "PSA_KEY_DERIVATION_UNLIMITED_CAPACITY",
); s/\b(@{[join("|", keys %t)]})\b/$t{$1}/ge' $(git ls-files)
When importing a private elliptic curve key, require the input to have
exactly the right size. RFC 5915 requires the right size (you aren't
allow to omit leading zeros). A different buffer size likely means
that something is wrong, e.g. a mismatch between the declared key type
and the actual data.
In psa_import_key, change the order of parameters to pass
the pointer where the newly created handle will be stored last.
This is consistent with most other library functions that put inputs
before outputs.
In psa_generate_derived_key, change the order of parameters to pass
the pointer where the newly created handle will be stored last.
This is consistent with most other library functions that put inputs
before outputs.
Add an additional function `mbedtls_ssl_export_keys_ext_t()`
for exporting key, that adds additional information such as
the used `tls_prf` and the random bytes.
In case the certificate policy is not of type `AnyPolicy`
set the returned error code to `MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE`
and continue parsing. If the extension is critical, return error anyway,
unless `MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION` is configured.
Fail parsing on any other error.
Make `mbedtls_x509_subject_alternative_name` to be a single item
rather than a list. Adapt the subject alternative name parsing function,
to receive a signle `mbedtls_x509_buf` item from the subject_alt_names
sequence of the certificate.
The preceding calloc() already zeroizes that memory area, therfore the
memset() is not necessary. Compilers are likely to optimize this out,
but it still can be confusing to readers.
The previous behaviour of mbedtls_x509_parse_subject_alternative_name()
was to silently ignore errors coming from x509_get_other_name(). The
current commit fixes it and returns with an error.
In x509_info_subject_alt_name() we silently dropped names that we
couldn't parse because they are not supported or are malformed. (Being
malformed might mean damaged file, but can be a sign of incompatibility
between applications.)
This commit adds code notifying the user that there is something, but
we can't parse it.
Lengths are aleady checked in mbedtls_asn1_get_len() which is called in
mbedtls_asn1_get_tag(), therefore it is not necessary to check
the lengths explicitly afterwards.
Also with the previous flow data was left in the output buffer on some
errors.
Only allow creating keys in the application (user) range. Allow
opening keys in the implementation (vendor) range as well.
Compared with what the implementation allowed, which was undocumented:
0 is now allowed; values from 0x40000000 to 0xfffeffff are now
forbidden.
Change the scope of key identifiers to be global, rather than
per lifetime. As a result, you now need to specify the lifetime of a
key only when creating it.
Make it a little easier to add ChaCha20-Poly1305.
This also fixes the error code in case mbedtls_gcm_setkey() fails with
a status that doesn't map to INVALID_ARGUMENT.
This commit rewrites mbedtls_x509write_crt_pem() to not use
a statically size stack buffer to temporarily store the DER
encoded form of the certificate to be written.
This is not necessary because the DER-to-PEM conversion
accepts overlapping input and output buffers.
The CRT writing routine mbedtls_x509write_crt_der() prepares the TBS
(to-be-signed) part of the CRT in a temporary stack-allocated buffer,
copying it to the actual output buffer at the end of the routine.
This comes at the cost of a very large stack buffer. Moreover, its size
must be hardcoded to an upper bound for the lengths of all CRTs to be
written through the routine. So far, this upper bound was set to 2Kb, which
isn't sufficient some larger certificates, as was reported e.g. in #2631.
This commit fixes this by changing mbedtls_x509write_crt_der() to write
the certificate in-place in the output buffer, thereby avoiding the use
of a statically sized stack buffer for the TBS.
Fixes#2631.
In psa_import_key and psa_copy_key, some information comes from the
key data (input buffer or source key) rather than from the attributes:
key size for import, key size and type and domain parameters for copy.
If an unused attribute is nonzero in the attribute structure, check
that it matches the correct value. This protects against application
errors.
* origin/pr/1633: (26 commits)
Fix uninitialized variable access in debug output of record enc/dec
Adapt PSA code to ssl_transform changes
Ensure non-NULL key buffer when building SSL test transforms
Catch errors while building SSL test transforms
Use mbedtls_{calloc|free}() in SSL unit test suite
Improve documentation of mbedtls_record
Adapt record length value after encryption
Alternative between send/recv transform in SSL record test suite
Fix memory leak on failure in test_suite_ssl
Rename ssl_decrypt_buf() to mbedtls_ssl_decrypt_buf() in comment
Add record encryption/decryption tests for ARIA to SSL test suite
Improve documentation of mbedtls_ssl_transform
Double check that record expansion is as expected during decryption
Move debugging output after record decryption
Add encryption/decryption tests for small records
Add tests for record encryption/decryption
Reduce size of `ssl_transform` if no MAC ciphersuite is enabled
Remove code from `ssl_derive_keys` if relevant modes are not enabled
Provide standalone version of `ssl_decrypt_buf`
Provide standalone version of `ssl_encrypt_buf`
...
Resolve merge conflicts by performing the following actions:
- Reject changes to deleted files.
- Reject changes to generate_errors.pl and generate_visualc_files.pl.
Don't add an 'include-crypto' option which would attempt to use the
non-existent crypto submodule.
- list-identifiers.sh had the `--internal` option added to it, which
lists identifiers only in internal headers. Add PSA-specific internal
headers to list-identifiers.sh.
* origin/development: (40 commits)
Document the scripts behaviour further
Use check_output instead of Popen
all.sh: Require i686-w64-mingw32-gcc version >= 6
generate_visualc_files.pl: add mbedtls source shadowing by crypto
generate_errors.pl: refactor and simplify the code
Start unused variable with underscore
Correct documentation
generate_errors.pl: typo fix
revert changes to generate_features.pl and generate_query_config.pl
Check that the report directory is a directory
Use namespaces instead of full classes
Fix pylint issues
Don't put abi dumps in subfolders
Add verbose switch to silence all output except the final report
Fetch the remote crypto branch, rather than cloning it
Prefix internal functions with underscore
Add RepoVersion class to make handling of many arguments easier
Reduce indentation levels
Improve documentation
Use optional arguments for setting repositories
...
Autogenerate errors.c There are changes in error.c due to updating the
crypto submodule to a version that no longer has the SSL, X.509, or net
modules. The errors are correctly sourced from Mbed TLS and not Mbed
Crypto, but they do move around within the file due to how the error
generator script is written.
Remove debug print added to print list of source files used in making
libmbedcrypto.
Fixes 92da0bd862 ("Makefile: Use generated source files from parent").
Read extra data from the domain parameters in the attribute structure
instead of taking an argument on the function call.
Implement this for RSA key generation, where the public exponent can
be set as a domain parameter.
Add tests that generate RSA keys with various public exponents.
Change psa_get_domain_parameters() and psa_set_domain_parameters() to
access a psa_key_attributes_t structure rather than a key handle.
In psa_get_key_attributes(), treat the RSA public exponent as a domain
parameter and read it out. This is in preparation for removing the
`extra` parameter of psa_generate_key() and setting the RSA public
exponent for key generation via domain parameters.
In this commit, the default public exponent 65537 is not treated
specially, which allows us to verify that test code that should be
calling psa_reset_key_attributes() after retrieving the attributes of
an RSA key is doing so properly (if it wasn't, there would be a memory
leak), even if the test data happens to use an RSA key with the
default public exponent.
When building as a submodule of a parent project, like Mbed TLS, use the
parent projects generated source files (error.c, version.c,
version_features.c)
When building as a submodule of a parent project, like Mbed TLS, use the
parent projects generated source files (error.c, version.c,
version_features.c)
Don't depend on the C compiler's default output file name and path. Make
knows what it wants to build and where it should go, and this may not
always align with the C compiler default, so tell the C compilter to
output to the Make target explicitly.
Instead of passing a separate parameter for the key size to
psa_generate_key and psa_generator_import_key, set it through the
attributes, like the key type and other metadata.
This commit adds tests exercising mutually inverse pairs of
record encryption and decryption transformations for the various
transformation types allowed in TLS: Stream, CBC, and AEAD.
The hash contexts `ssl_transform->md_ctx_{enc/dec}` are not used if
only AEAD ciphersuites are enabled. This commit removes them from the
`ssl_transform` struct in this case, saving a few bytes.
This commit guards code specific to AEAD, CBC and stream cipher modes
in `ssl_derive_keys` by the respective configuration flags, analogous
to the guards that are already in place in the record decryption and
encryption functions `ssl_decrypt_buf` resp. `ssl_decrypt_buf`.
Analogous to the previous commit, but concerning the record decryption
routine `ssl_decrypt_buf`.
An important change regards the checking of CBC padding:
Prior to this commit, the CBC padding check always read 256 bytes at
the end of the internal record buffer, almost always going past the
boundaries of the record under consideration. In order to stay within
the bounds of the given record, this commit changes this behavior by
always reading the last min(256, plaintext_len) bytes of the record
plaintext buffer and taking into consideration the last `padlen` of
these for the padding check. With this change, the memory access
pattern and runtime of the padding check is entirely determined by
the size of the encrypted record, in particular not giving away
any information on the validity of the padding.
The following depicts the different behaviors:
1) Previous CBC padding check
1.a) Claimed padding length <= plaintext length
+----------------------------------------+----+
| Record plaintext buffer | | PL |
+----------------------------------------+----+
\__ PL __/
+------------------------------------...
| read for padding check ...
+------------------------------------...
|
contents discarded
from here
1.b) Claimed padding length > plaintext length
+----------------------------------------+----+
| Record plaintext buffer | PL |
+----------------------------------------+----+
+-------------------------...
| read for padding check ...
+-------------------------...
|
contents discarded
from here
2) New CBC padding check
+----------------------------------------+----+
| Record plaintext buffer | | PL |
+----------------------------------------+----+
\__ PL __/
+---------------------------------------+
| read for padding check |
+---------------------------------------+
|
contents discarded
until here
The previous version of the record encryption function
`ssl_encrypt_buf` takes the entire SSL context as an argument,
while intuitively, it should only depend on the current security
parameters and the record buffer.
Analyzing the exact dependencies, it turned out that in addition
to the currently active `ssl_transform` instance and the record
information, the encryption function needs access to
- the negotiated protocol version, and
- the status of the encrypt-then-MAC extension.
This commit moves these two fields into `ssl_transform` and
changes the signature of `ssl_encrypt_buf` to only use an instance
of `ssl_transform` and an instance of the new `ssl_record` type.
The `ssl_context` instance is *solely* kept for the debugging macros
which need an SSL context instance.
The benefit of the change is twofold:
1) It avoids the need of the MPS to deal with instances of
`ssl_context`. The MPS should only work with records and
opaque security parameters, which is what the change in
this commit makes progress towards.
2) It significantly eases testing of the encryption function:
independent of any SSL context, the encryption function can
be passed some record buffer to encrypt alongside some arbitrary
choice of parameters, and e.g. be checked to not overflow the
provided memory.
The macro constant `MBEDTLS_SSL_MAC_ADD` defined in `ssl_internal.h`
defines an upper bound for the amount of space needed for the record
authentication tag. Its definition distinguishes between the
presence of an ARC4 or CBC ciphersuite suite, in which case the maximum
size of an enabled SHA digest is used; otherwise, `MBEDTLS_SSL_MAC_ADD`
is set to 16 to accomodate AEAD authentication tags.
This assignment has a flaw in the situation where confidentiality is
not needed and the NULL cipher is in use. In this case, the
authentication tag also uses a SHA digest, but the definition of
`MBEDTLS_SSL_MAC_ADD` doesn't guarantee enough space.
The present commit fixes this by distinguishing between the presence
of *some* ciphersuite using a MAC, including those using a NULL cipher.
For that, the previously internal macro `SSL_SOME_MODES_USE_MAC` from
`ssl_tls.c` is renamed and moved to the public macro
`MBEDTLS_SOME_MODES_USE_MAC` defined in `ssl_internal.h`.
Prior to this commit, the security parameter struct `ssl_transform`
contained a `ciphersuite_info` field pointing to the information
structure for the negotiated ciphersuite. However, the only
information extracted from that structure that was used in the core
encryption and decryption functions `ssl_encrypt_buf`/`ssl_decrypt_buf`
was the authentication tag length in case of an AEAD cipher.
The present commit removes the `ciphersuite_info` field from the
`ssl_transform` structure and adds an explicit `taglen` field
for AEAD authentication tag length.
This is in accordance with the principle that the `ssl_transform`
structure should contain the raw parameters needed for the record
encryption and decryption functions to work, but not the higher-level
information that gave rise to them. For example, the `ssl_transform`
structure implicitly contains the encryption/decryption keys within
their cipher contexts, but it doesn't contain the SSL master or
premaster secrets. Likewise, it contains an explicit `maclen`, while
the status of the 'Truncated HMAC' extension -- which determines the
value of `maclen` when the `ssl_transform` structure is created in
`ssl_derive_keys` -- is not contained in `ssl_transform`.
The `ciphersuite_info` pointer was used in other places outside
the encryption/decryption functions during the handshake, and for
these functions to work, this commit adds a `ciphersuite_info` pointer
field to the handshake-local `ssl_handshake_params` structure.
The `ssl_transform` security parameter structure contains opaque
cipher contexts for use by the record encryption/decryption functions
`ssl_decrypt_buf`/`ssl_encrypt_buf`, while the underlying key material
is configured once in `ssl_derive_keys` and is not explicitly dealt with
anymore afterwards. In particular, the key length is not needed
explicitly by the encryption/decryption functions but is nonetheless
stored in an explicit yet superfluous `keylen` field in `ssl_transform`.
This commit removes this field.
We've removed all software that depends on or uses the TLS, NET, and
X.509 modules. This means TLS, NET, and X.509 are unused and can be
removed. Remove TLS, NET, and X.509.
Remove TLS and NET options from config files and scripts.
Note that this fails check-names.sh because options that TLS and NET
files use are no longer present in config.h.
Implement attribute querying.
Test attribute getters and setters. Use psa_get_key_attributes instead
of the deprecated functions psa_get_key_policy or
psa_get_key_information in most tests.
Implement the new, attribute-based psa_import_key and some basic
functions to access psa_key_attributes_t. Replace
psa_import_key_to_handle by psa_import_key in a few test functions.
This commit does not handle persistence attributes yet.
This commit starts a migration to a new interface for key creation.
Today, the application allocates a handle, then fills its metadata,
and finally injects key material. The new interface fills metadata
into a temporary structure, and a handle is allocated at the same time
it gets filled with both metadata and key material.
This commit was obtained by moving the declaration of the old-style
functions to crypto_extra.h and renaming them with the to_handle
suffix, adding declarations for the new-style functions in crypto.h
under their new name, and running
perl -i -pe 's/\bpsa_(import|copy|generator_import|generate)_key\b/$&_to_handle/g' library/*.c tests/suites/*.function programs/psa/*.c
perl -i -pe 's/\bpsa_get_key_lifetime\b/$&_from_handle/g' library/*.c tests/suites/*.function programs/psa/*.c
Many functions that are specific to the old interface, and which will
not remain under the same name with the new interface, are still in
crypto.h for now.
All functional tests should still pass. The documentation may have
some broken links.