Add a parameter to the key import method of a secure element driver to
make it report the key size in bits. This is necessary (otherwise the
core has no idea what the bit-size is), and making import report it is
easier than adding a separate method (for other key creation methods,
this information is an input, not an output).
Nothing has been saved to disk yet, but there is stale data in
psa_crypto_transaction. This stale data should not be reused, but do
wipe it to reduce the risk of it mattering somehow in the future.
Introduce a new function psa_get_transparent_key which returns
NOT_SUPPORTED if the key is in a secure element. Use this function in
functions that don't support keys in a secure element.
After this commit, all functions that access a key slot directly via
psa_get_key_slot or psa_get_key_from_slot rather than via
psa_get_transparent_key have at least enough support for secure
elements not to crash or otherwise cause undefined behavior. Lesser
bad behavior such as wrong results or resource leakage is still
possible in error cases.
The following provides more information on this PR:
- PSA stands for Platform Security Architecture.
- Add support for use of psa_trusted_storage_api internal_trusted_storage.h v1.0.0
as the interface to the psa_trusted_storage_linux backend (i.e. for persistent
storage when MBEDTLS_PSA_ITS_FILE_C is not defined). This requires changes
to psa_crypto_its.h and psa_crypto_storage.c to migrate to the new API.
Stored keys must contain lifetime information. The lifetime used to be
implied by the location of the key, back when applications supplied
the lifetime value when opening the key. Now that all keys' metadata
are stored in a central location, this location needs to store the
lifetime explicitly.
Pass information via a key attribute structure rather than as separate
parameters to psa_crypto_storage functions. This makes it easier to
maintain the code when the metadata of a key evolves.
This has negligible impact on code size (+4B with "gcc -Os" on x86_64).
Key creation and key destruction for a key in a secure element both
require updating three pieces of data: the key data in the secure
element, the key metadata in internal storage, and the SE driver's
persistent data. Perform these actions in a transaction so that
recovery is possible if the action is interrupted midway.
Implement a transaction record that can be used for actions that
modify more than one piece of persistent data (whether in the
persistent storage or elsewhere such as in a secure element).
While performing a transaction, the transaction file is present in
storage. If the system starts with an ongoing transaction, it must
complete the transaction (not implemented yet).
In the generic message digest abstraction, instead of storing method
pointers in the per-algorithm data structure and using wrapper
functions as those methods, call the per-algorithm function directly.
This saves some code size (2336B -> 2043B for md with all algorithms
enabled on M0+ with gcc -Os). This should also make it easier to
optimize the case when a single algorithm is supported. In addition,
this is a very slight security improvement since it removes one
opportunity for a buffer overflow to directly turn into letting the
attacker overwrite a pointer to a function pointer.
This commit does not modify the documented API. However, it removes
the possibility for users to define their own hash implementations and
use them by building their own md_info.
Changing mbedtls_md_context to contain a md type identifier rather
than a pointer to an info structure would save a few more bytes and a
few more runtime memory accesses, but would be a major API break since
a lot of code uses `const mbedtls_md_info *` to keep track of which
hash is in use.
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.
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.
dummy
Replace some frequently-used macros by inline functions: instead of
calling MOD_{ADD,SUB,MUL} after the mbedtls_mpi_{add,sub,mul}_mpi,
call a function mbedtls_mpi_xxx_mod that does the same.
In the baremetal config, with "gcc -Os -mthumb -mcpu=cortex-m0plus",
ecp.o goes down from 13878 bytes to 12234.
No noticeable performance change for benchmarks on x86_64 with either
"gcc -O2" or "gcc -Os".
When creating a key with a lifetime that places it in a secure
element, retrieve the appropriate driver table entry.
This commit doesn't yet achieve behavior: so far the code only
retrieves the driver, it doesn't call the driver.
Expose the type of an entry in the SE driver table as an opaque type
to other library modules. Soon, driver table entries will have state,
and callers will need to be able to access this state through
functions using this opaque type.
Provide functions to look up a driver by its lifetime and to retrieve
the method table from an entry.
Remove use of CMAKE_SOURCE_DIR in case mbedtls is built from within
another CMake project. Define MBEDTLS_DIR to ${CMAKE_CURRENT_SOURCE_DIR}
in the main CMakeLists.txt file and refer to that when defining target
include paths to enable mbedtls to be built as a sub project.
Fixes#2609
Signed-off-by: Ashley Duncan <ashes.man@gmail.com>
Signed-off-by: Jaeden Amero <jaeden.amero@arm.com>
* origin/development: (33 commits)
Test with MBEDTLS_ECP_RESTARTABLE
Allow TODO in code
Use the docstring in the command line help
Split _abi_compliance_command into smaller functions
Record the commits that were compared
Document how to build the typical argument for -s
Allow running /somewhere/else/path/to/abi_check.py
Warn if VLAs are used
Remove redundant compiler flag
Consistently spell -Wextra
Update Mbed Crypto to contain mbed-crypto#152
Improve compatibility with firewalled networks
Dockerfile: apt -> apt-get
Change Docker container to bionic
Clean up file prologue comments
Add docker-based test scripts
ChangeLog: Add ChangeLog entry for #2681
Allow declarations after statements
CMake: Add a subdirectory build regression test
README: Enable builds as a CMake subproject
...
* origin/pr/2706:
Update Mbed Crypto to contain mbed-crypto#152
CMake: Add a subdirectory build regression test
README: Enable builds as a CMake subproject
ChangeLog: Enable builds as a CMake subproject
Remove use of CMAKE_SOURCE_DIR
* origin/pr/2632:
Adapt ChangeLog
Avoid use of large stack buffers in mbedtls_x509_write_crt_pem()
Improve documentation of mbedtls_pem_write_buffer()
Perform CRT writing in-place on the output buffer
Adapt x509write_crt.c to coding style
The failure of mbedtls_md was not checked in one place. This could have led
to an incorrect computation if a hardware accelerator failed. In most cases
this would have led to the key exchange failing, so the impact would have been
a hard-to-diagnose error reported in the wrong place. If the two sides of the
key exchange failed in the same way with an output from mbedtls_md that was
independent of the input, this could have led to an apparently successful key
exchange with a predictable key, thus a glitching md accelerator could have
caused a security vulnerability.
The window size variable in ecp_pick_window_size() can take values
4, 5 or 6, but we clamp it not to exceed the value of
MBEDTLS_ECP_WINDOW_SIZE. If that is 6 (default) or higher, the
static analyzer will point out that the test:
w > MBEDTLS_ECP_WINDOW_SIZE always evaluates to false.
This commit removes the test for the cases of the window size
large enough to fit all the potential values of the variable.
The psa_tls12_prf_set_seed() and psa_tls12_prf_set_label() functions did
not work on platforms where malloc(0) returns NULL.
It does not affect the TLS use case but these PRFs are used in other
protocols as well and might not be used the same way. For example EAP
uses the TLS PRF with an empty secret. (This would not trigger the bug,
but is a strong indication that it is not safe to assume that certain
inputs to this function are not zero length.)
The conditional block includes the memcpy() call as well to avoid
passing a NULL pointer as a parameter resulting in undefined behaviour.
The current tests are already using zero length label and seed, there is
no need to add new test for this bug.
Secure element support has its own source file, and in addition
requires many hooks in other files. This is a nontrivial amount of
code, so make it optional (but default on).
Remove use of CMAKE_SOURCE_DIR in case mbedtls is built from within
another CMake project. Define MBEDTLS_DIR to ${CMAKE_CURRENT_SOURCE_DIR}
in the main CMakeLists.txt file and refer to that when defining target
include paths to enable mbedtls to be built as a sub project.
Fixes https://github.com/ARMmbed/mbedtls/issues/2609
Signed-off-by: Ashley Duncan <ashes.man@gmail.com>
Signed-off-by: Jaeden Amero <jaeden.amero@arm.com>
PSA_ERROR_BAD_STATE means that the function was called on a context in a
bad state.
This error is something that can't happen while only using the PSA API and
therefore a PSA_ERROR_CORRUPTION_DETECTED is a more appropriate error
code.
The macro initialiser might leave bytes in the union unspecified.
Zeroising it in setup makes sure that the behaviour is the same
independently of the initialisation method used.
The TLS 1.2 pseudorandom function does a lot of distinct HMAC operations
with the same key. To save the battery and CPU cycles spent on
calculating the paddings and hashing the inner padding, we keep the
hash context in the status right after the inner padding having been
hashed and clone it as needed.
Technically we could have reused the old one for the new API, but then
we had to set an extra field during setup. The new version works when
all the fields that haven't been set explicitely are zero-initialised.
The specific key derivation input functions support a subset of the
input options and need to check it anyway. Checking it at the top level
is redundant, it brings a very little value and comes with a cost in
code size and maintainability.
This change affects the psa_key_derivation_s structure. With the buffer
removed from the union, it is empty if MBEDTLS_MD_C is not defined.
We can avoid undefined behaviour by adding a new dummy field that is
always present or make the whole union conditional on MBEDTLS_MD_C.
In this latter case the initialiser macro has to depend on MBEDTLS_MD_C
as well. Furthermore the first structure would be either
psa_hkdf_key_derivation_t or psa_tls12_prf_key_derivation_t both of
which are very deep and would make the initialisation macro difficult
to maintain, therefore we go with the first option.
Some key derivation operation contexts (like
psa_tls12_prf_key_derivation_t) directly contain buffers with parts of
the derived key. Erase them safely as part of the abort.
Add the compile time option PSA_PRE_1_0_KEY_DERIVATION. If this is not
turned on, then the function `psa_key_derivation()` is removed.
Most of the tests regarding key derivation haven't been adapted to the
new API yet and some of them have only been adapted partially. When this
new option is turned off, the tests using the old API and test cases
using the old API of partially adapted tests are skipped.
The sole purpose of this option is to make the transition to the new API
smoother. Once the transition is complete it can and should be removed
along with the old API and its implementation.
Remove use of CMAKE_SOURCE_DIR in case mbedtls is built from within
another CMake project. Define MBEDTLS_DIR to ${CMAKE_CURRENT_SOURCE_DIR}
in the main CMakeLists.txt file and refer to that when defining target
include paths to enable mbedtls to be built as a sub project.
Fixes#2609
Signed-off-by: Ashley Duncan <ashes.man@gmail.com>
Signed-off-by: Jaeden Amero <jaeden.amero@arm.com>
* restricted/pr/573:
Remove redundant config.pl call
Add a test for signing content with a long ECDSA key
Add documentation notes about the required size of the signature buffers
Add missing MBEDTLS_ECP_C dependencies in check_config.h
Change size of preallocated buffer for pk_sign() calls
* origin/pr/2711:
programs: Make `make clean` clean all programs always
ssl_tls: Enable Suite B with subset of ECP curves
windows: Fix Release x64 configuration
platform: Include stdarg.h where needed
timing: Remove redundant include file
net_sockets: Fix typo in net_would_block()
* origin/pr/2697:
Update crypto submodule
Add all.sh component that exercises invalid_param checks
Remove mbedtls_param_failed from programs
Make it easier to define MBEDTLS_PARAM_FAILED as assert
Make test suites compatible with #include <assert.h>
Pass -m32 to the linker as well
Don't systematically rebuild programs
The elements of the HAVEGE state are manipulated with bitwise
operations, with the expectations that the elements are 32-bit
unsigned integers (or larger). But they are declared as int, and so
the code has undefined behavior. Clang with Asan correctly points out
some shifts that reach the sign bit.
Since these are supposed to be 32-bit unsigned integers, declare them
as uint32_t.
This is technically an API break, since the type mbedtls_havege_state
is exposed in a public header. However normal applications should not
be affected.
* origin/pr/2260:
Update crypto submodule
Remove heading spaces in tests/data_files/Makefile
Re-generate library/certs.c from script
Add new line at the end of test-ca2.key.enc
Use strict syntax to annotate origin of test data in certs.c
Add run to all.sh exercising !MBEDTLS_PEM_PARSE_C + !MBEDTLS_FS_IO
Allow DHM self test to run without MBEDTLS_PEM_PARSE_C
ssl-opt.sh: Auto-skip tests that use files if MBEDTLS_FS_IO unset
Document origin of hardcoded certificates in library/certs.c
Adapt ChangeLog
Rename server1.der to server1.crt.der
Add DER encoded files to git tree
Add build instructions to generate DER versions of CRTs and keys
Document "none" value for ca_path/ca_file in ssl_client2/ssl_server2
ssl_server2: Skip CA setup if `ca_path` or `ca_file` argument "none"
ssl_client2: Skip CA setup if `ca_path` or `ca_file` argument "none"
Correct white spaces in ssl_server2 and ssl_client2
Adapt ssl_client2 to parse DER encoded test CRTs if PEM is disabled
Adapt ssl_server2 to parse DER encoded test CRTs if PEM is disabled
Introduce a new configuration option MBEDTLS_CHECK_PARAMS_ASSERT,
which is disabled by default. When this option is enabled,
MBEDTLS_PARAM_FAILED defaults to assert rather than to a call to
mbedtls_param_failed, and <assert.h> is included.
This fixes#2671 (no easy way to make MBEDTLS_PARAM_FAILED assert)
without breaking backward compatibility. With this change,
`config.pl full` runs tests with MBEDTLS_PARAM_FAILED set to assert,
so the tests will fail if a validation check fails, and programs don't
need to provide their own definition of mbedtls_param_failed().
Increase the SO versions of libmbedx509 and libmbedtls due to the
addition of fields in publicly visible (non-opaque) structs:
- mbedtls_ssl_config
- mbedtls_ssl_context
- mbedtls_x509_crt
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.
Merge Mbed TLS at f790a6cbee into Mbed Crypto.
Resolve conflicts by performing the following:
- Reject changes to README.md
- Don't add crypto as a submodule
- Remove test/ssl_cert_test from programs/Makefile
- Add cipher.nist_kw test to tests/CMakeLists.txt
- Reject removal of crypto-specific all.sh tests
- Reject update to SSL-specific portion of component_test_valgrind
in all.sh
- Reject addition of ssl-opt.sh testing to component_test_m32_o1 in
all.sh
* tls/development: (87 commits)
Call mbedtls_cipher_free() to reset a cipher context
Don't call mbedtls_cipher_setkey twice
Update crypto submodule
Minor fixes in get certificate policies oid test
Add certificate policy oid x509 extension
cpp_dummy_build: Add missing header psa_util.h
Clarify comment mangled by an earlier refactoring
Add an "out-of-box" component
Run ssl-opt.sh on 32-bit runtime
Don't use debug level 1 for informational messages
Skip uncritical unsupported extensions
Give credit to OSS-Fuzz for #2404
all.sh: remove component_test_new_ecdh_context
Remove crypto-only related components from all.sh
Remove ssl_cert_test sample app
Make CRT callback tests more robust
Rename constant in client2.c
Document and test flags in x509_verify
Fix style issues and a typo
Fix a rebase error
...
Resolve conflicts by performing the following:
- Ensure calls to mbedtls_x509_crt_verify_* are made with callbacks
* origin/pr/2539:
Make CRT callback tests more robust
Rename constant in client2.c
Fix typo
Add test for configuration specific CRT callback
Fix doxygen documentation of mbedtls_ssl_set_verify()
Add test exercising context-specific CRT callback to ssl-opt.sh
Add cmd to use context-specific CRT callback in ssl_client2
Implement context-specific verification callbacks
Add context-specific CRT verification callbacks
Improve documentation of mbedtls_ssl_conf_verify()
* origin/pr/2532: (29 commits)
Document and test flags in x509_verify
Fix style issues and a typo
Fix name to function call
Address comments for x509 tests
Address review comments regarding ssl_client2 and ssl tests
Remove mbedtls_ from the static function name
Change docs according to review comments
Change the verify function naming
Fix ssl_client2 and ssl_server2 if !PLATFORM_C
Correct placement of usage macro in ssl_client2
Update version_features.c
Remove trailing whitespace in test_suite_x509parse.function
Update query_config.c
Add ssl-opt.sh tests for trusted CA callbacks
Only run X.509 CRT verification tests with CA callback tests if !CRL
Minor fixes to CA callback tests
Declare CA callback type even if feature is disabled
Implement X.509 CRT verification using CA callback
Add prototype for CRT verification with static and dynamic CA list
Make use of CA callback if present when verifying peer CRT chain
...
On Windows, rename() fails if the new filename already exists.
Use the Windows specific function MoveFileExA with the
MOVEFILE_REPLACE_EXISTING flag set instead to do renames.
Merge the Mbed Crypto development branch a little after
mbedcrypto-1.0.0 into the PSA Crypto API 1.0 beta branch a little
after beta 2.
Summary of merge conflicts:
* Some features (psa_copy_key, public key format without
SubjectPublicKeyInfo wrapping) went into both sides, but with a few
improvements on the implementation side. For those, take the
implementation side.
* The key derivation API changed considerably on the API side. This
merge commit generally goes with the updated API except in the tests
where it keeps some aspects of the implementation.
Due to the divergence between the two branches on key derivation and
key agreement, test_suite_psa_crypto does not compile. This will be
resolved in subsequent commits.
So far, there were the following CRT verification functions:
- `mbedtls_x509_crt_verify()` -- no profile, no restartable ECC
- `mbedtls_x509_crt_verify_with_profile()` -- profile, no restartable ECC
- `mbedtls_x509_crt_verify_restartable()` -- profile, restartable ECC
all publicly declared and offering increasing functionality.
On the implementation-side,
- `mbedtls_x509_crt_verify()` resolves to
a call to `mbedtls_x509_crt_verify_with_profile()` setting
the profile to `NULL`, and
- `mbedtls_x509_crt_verify_with_profile()`
resolves to a call to ``mbedtls_x509_crt_verify_restartable()`
setting the ECC restart context to NULL.
This commit adds two more functions to this zoo:
- `mbedtls_x509_crt_verify_with_cb()`
- `x509_crt_verify_restartable_cb()`
Here, `mbedtls_x509_crt_verify_with_cb()` is similar to
`mbedtls_x509_crt_verify_with_profile()` but uses a CA callback
instead of a static CA list, and no restart context.
`x509_crt_verify_restartable_cb()` is similar to
`mbedtls_x509_crt_verify_restartable()` but allows to either use
a static list of trusted CAs _or_ a trusted CA callback.
On the implementation-side,
- the body of `mbedtls_x509_crt_verify_restartable()` is moved to
`x509_crt_verify_restartable_cb()`, and the new version of
`mbedtls_x509_crt_verify_restartable()` just resolves to
`x509_crt_verify_restartable_cb()` with the trusted CA callback
set to NULL.
- The new function `mbedtls_x509_crt_verify_with_cb()`
forward to `x509_crt_verify_restartable_cb()` with the restart
context set to `NULL`.
There's no change to the implementation yet, and in particular,
`mbedtls_x509_crt_verify_with_cb()` isn't yet usable.
Resolve conflicts actions:
- Reject path changes to config.h
- Reject submodule-related changes in build scripts (Makefile,
CMakeLists.txt)
- Add oid test suite to list of tests in tests/CMakeLists.txt,
rejecting any test filtering related changes (which TLS uses to avoid
duplicating crypto tests)
- Add legacy ECDH test to all.sh without including
all.sh tests that depend on SSL
* restricted/pr/551:
ECP: Clarify test descriptions
ECP: remove extra whitespaces
Fix ECDH secret export for Mongomery curves
Improve ECP test names
Make ecp_get_type public
Add more tests for ecp_read_key
ECP: Catch unsupported import/export
Improve documentation of mbedtls_ecp_read_key
Fix typo in ECP module
Remove unnecessary cast from ECP test
Improve mbedtls_ecp_point_read_binary tests
Add Montgomery points to ecp_point_write_binary
ECDH: Add test vectors for Curve25519
Add little endian export to Bignum
Add mbedtls_ecp_read_key
Add Montgomery points to ecp_point_read_binary
Add little endian import to Bignum
Ensure this merge passes tests by auto-generating query_config.c, adding
MBEDTLS_ECDH_LEGACY_CONTEXT to it.
* restricted/pr/552:
Fix mbedtls_ecdh_get_params with new ECDH context
Test undefining MBEDTLS_ECDH_LEGACY_CONTEXT in all.sh
Define MBEDTLS_ECDH_LEGACY_CONTEXT in config.h
Add changelog entry for mbedtls_ecdh_get_params robustness
Fix ecdh_get_params with mismatching group
Add test case for ecdh_get_params with mismatching group
Add test case for ecdh_calc_secret
Fix typo in documentation
Ensure tests pass when the submodule is used by updating the list of
crypto tests to include test_suite_oid in both tests/CMakeLists.txt and
tests/Makefile.
* origin/pr/2531:
Add changeLog entry
Add certificate policy of type any policy id
* origin/pr/2509:
all.sh: Generate seedfile for crypto submodule tests
Update crypto submodule to test with private headers
tests: Use globbing in test suite exclusion list
Update crypto submodule to Mbed Crypto development
tests: Test crypto via the crypto submodule
Update the crypto submodule to the top of the Mbed Crypto development
branch. This brings in a version of Mbed Crypto that enables building
Mbed Crypto tests that depend on private headers, like
'psa_crypto_invasive.h'.
This also requires updating our config.h to include new configuration
options added to Mbed Crypto. MBEDTLS_PSA_ITS_FILE_C replaces
MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C and MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C.
MBEDTLS_PSA_INJECT_ENTROPY replaces MBEDTLS_PSA_HAS_ITS_IO.
MBEDTLS_PSA_HAS_ITS_IO is not really useful since it doesn't actually
enable anything except the entropy seed file support, which only
requires the ITS interface and not a native implemetation. Remove it.
Since there is now a single storage backend, we don't need a backend
interface. Make the functions that were declared in
psa_crypto_storage_backend.h and are now both defined and used in
psa_crypto_storage.c static, except for psa_is_key_present_in_storage
which is used by the gray-box tests and is now declared in
psa_crypto_storage.h.
Since the ITS API has stabilized and we don't plan to make use of more
than ITS, we don't need an abstraction layer between key storage and
key storage over ITS. Merge the ITS code into the generic storage
module.
Now that we have ITS over files, we no longer need a direct backend
for key storage over files. Remove psa_crypto_storage_file and its
tests.
Switch MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C and MBEDTLS_PSA_ITS_FILE_C on
by default. This preserves functionality and test coverage in the
default configuration, but forgets any key previously stored using the
file backend.
Merge storage_common.h and internal_trusted_storage.h into a single
file for convenience.
Remove #include of <psa/error.h> which crypto doesn't have yet and
include <psa/crypto_types.h> and <psa/crypto_values.h> instead.
Drop __cplusplus support which we don't need.
Tweak style (whitespace, line breaks, comment formatting) to satisfy
check-names.sh and check-files.sh.
Commit a72c10c44d5d54d05aceb00e0368f02f9f62151a in the
psa_trusted_storage_api repository, from which the PSA ITS
specification version 1.1 is derived.
* origin/development: (113 commits)
Update query_config.c
Fix failure in SSLv3 per-version suites test
Adjust DES exclude lists in test scripts
Clarify 3DES changes in ChangeLog
Fix documentation for 3DES removal
Exclude 3DES tests in test scripts
Fix wording of ChangeLog and 3DES_REMOVE docs
Reduce priority of 3DES ciphersuites
Fix unused variable warning in ssl_parse_certificate_coordinate()
Update the crypto submodule to a78c958
Fix ChangeLog entry to correct release version
Fix typo in x509write test data
Add ChangeLog entry for unused bits in bitstrings
Improve docs for named bitstrings and their usage
Add tests for (named) bitstring to suite_asn1write
Add new function mbedtls_asn1_write_named_bitstring()
Add missing compile time guard in ssl_client2
Update programs/ssl/query_config.c
ssl_client2: Reset peer CRT info string on reconnect
Add further debug statements on assertion failures
...
* origin/pr/1520:
Use certificates from data_files and refer them
Specify server certificate to use in SHA-1 test
refactor CA and SRV certificates into separate blocks
refactor SHA-1 certificate defintions and assignment
refactor server SHA-1 certificate definition into a new block
define TEST_SRV_CRT_RSA_SOME in similar logic to TEST_CA_CRT_RSA_SOME
server SHA-256 certificate now follows the same logic as CA SHA-256 certificate
add entry to ChangeLog
* public/pr/2421: (68 commits)
Fix unused variable warning in ssl_parse_certificate_coordinate()
Add missing compile time guard in ssl_client2
Update programs/ssl/query_config.c
ssl_client2: Reset peer CRT info string on reconnect
Add further debug statements on assertion failures
Fix typo in documentation of ssl_parse_certificate_chain()
Add debug output in case of assertion failure
Fix typo in SSL ticket documentation
Add config sanity check for !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
ssl_client2: Zeroize peer CRT info buffer when reconnecting
Reintroduce numerous ssl-opt.sh tests if !MBEDTLS_SSL_KEEP_PEER_CERT
ssl_client2: Extract peer CRT info from verification callback
Improve documentation of mbedtls_ssl_get_peer_cert()
Improve documentation of MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
Fix indentation of Doxygen comment in ssl_internal.h
Set peer CRT length only after successful allocation
Remove question in comment about verify flags on cli vs. server
Remove misleading and redundant guard around restartable ECC field
Add test for !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE to all.sh
Free peer CRT chain immediately after verifying it
...
* restricted/pr/528:
Update query_config.c
Fix failure in SSLv3 per-version suites test
Adjust DES exclude lists in test scripts
Clarify 3DES changes in ChangeLog
Fix documentation for 3DES removal
Exclude 3DES tests in test scripts
Fix wording of ChangeLog and 3DES_REMOVE docs
Reduce priority of 3DES ciphersuites
* public/pr/2028:
Update the crypto submodule to a78c958
Fix ChangeLog entry to correct release version
Fix typo in x509write test data
Add ChangeLog entry for unused bits in bitstrings
Improve docs for named bitstrings and their usage
Add tests for (named) bitstring to suite_asn1write
Add new function mbedtls_asn1_write_named_bitstring()
Add a new function mbedtls_asn1_write_named_bitstring() that removes
trailing 0s at the end of DER encoded bitstrings. The function is
implemented according to Hanno Becker's suggestions.
This commit also changes the functions x509write_crt_set_ns_cert_type
and crt_set_key_usage to call the new function as the use named
bitstrings instead of the regular bitstrings.
Additional work done as part of merge:
- Run ./tests/scripts/check-generated-files.sh and check in the
resulting changes to programs/ssl/query_config.c
The ecp_get_type function comes handy in higher level modules and tests
as well. It is not inline anymore, to enable alternative implementations
to implement it for themselves.
mbedtls_ecp_read_key() module returned without an error even when
importing keys corresponding to the requested group was not
implemented.
We change this and return an error when the requested group is not
supported and make the remaining import/export functions more robust.
If we don't need to store the peer's CRT chain permanently, we may
free it immediately after verifying it. Moreover, since we parse the
CRT chain in-place from the input buffer in this case, pointers from
the CRT structure remain valid after freeing the structure, and we
use that to extract the digest and pubkey from the CRT after freeing
the structure.
It is used in `mbedtls_ssl_session_free()` under
`MBEDTLS_X509_CRT_PARSE_C`, but defined only if
`MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED`.
Issue #2422 tracks the use of
`MBEDTLS_KEY_EXCHANGE__WITH_CERT_ENABLED` instead of
`MBEDTLS_X509_CRT_PARSE_C` for code and fields
related to CRT-based ciphersuites.
The server expects a CertificateVerify message only if it has
previously received a Certificate from the client.
So far, this was detected by looking at the `peer_cert` field
in the current session. Preparing to remove the latter, this
commit changes this to instead determine the presence of a peer
certificate by checking the new `peer_cert_digest` pointer.
We must dispatch between the peer's public key stored as part of
the peer's CRT in the current session structure (situation until
now, and future behaviour if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is
enabled), and the sole public key stored in the handshake structure
(new, if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is disabled).
We must dispatch between the peer's public key stored as part of
the peer's CRT in the current session structure (situation until
now, and future behaviour if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is
enabled), and the sole public key stored in the handshake structure
(new, if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is disabled).
We must dispatch between the peer's public key stored as part of
the peer's CRT in the current session structure (situation until
now, and future behaviour if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is
enabled), and the sole public key stored in the handshake structure
(new, if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is disabled).
We must dispatch between the peer's public key stored as part of
the peer's CRT in the current session structure (situation until
now, and future behaviour if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is
enabled), and the sole public key stored in the handshake structure
(new, if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is disabled).
This commit modifies `mbedtls_ssl_parse_certificate()` to store a
copy of the peer's public key after parsing and verifying the peer's
CRT chain.
So far, this leads to heavy memory duplication: We have the CRT chain
in the I/O buffer, then parse (and, thereby, copy) it to a
`mbedtls_x509_crt` structure, and then make another copy of the
peer's public key, plus the overhead from the MPI and ECP structures.
This inefficiency will soon go away to a significant extend, because:
- Another PR adds functionality to parse CRTs without taking
ownership of the input buffers. Applying this here will allow
parsing and verifying the peer's chain without making an additional
raw copy. The overhead reduces to the size of `mbedtls_x509_crt`,
the public key, and the DN structures referenced in the CRT.
- Once copyless parsing is in place and the removal of the peer CRT
is fully implemented, we can extract the public key bounds from
the parsed certificate and then free the entire chain before
parsing the public key again. This means that we never store
the parsed public key twice at the same time.
When removing the (session-local) copy of the peer's CRT chain, we must
keep a handshake-local copy of the peer's public key, as (naturally) every
key exchange will make use of that public key at some point to verify that
the peer actually owns the corresponding private key (e.g., verify signatures
from ServerKeyExchange or CertificateVerify, or encrypt a PMS in a RSA-based
exchange, or extract static (EC)DH parameters).
This commit adds a PK context field `peer_pubkey` to the handshake parameter
structure `mbedtls_handshake_params_init()` and adapts the init and free
functions accordingly. It does not yet make actual use of the new field.
This commit adds an ASN.1 buffer field `pk_raw` to `mbedtls_x509_crt`
which stores the bounds of the raw public key data within an X.509 CRT.
This will be useful in subsequent commits to extract the peer's public
key from its certificate chain.
This commit changes the format of session tickets to include
the digest of the peer's CRT if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
is disabled.
This commit does not yet remove the peer CRT itself.
`mbedtls_ssl_parse_certificate()` parses the peer's certificate chain
directly into the `peer_cert` field of the `mbedtls_ssl_session`
structure being established. To allow to optionally remove this field
from the session structure, this commit changes this to parse the peer's
chain into a local variable instead first, which can then either be freed
after CRT verification - in case the chain should not be stored - or
mapped to the `peer_cert` if it should be kept. For now, only the latter
is implemented.
mbedtls_ssl_parse_certificate() will fail if a ciphersuite requires
a certificate, but none is provided. While it is sensible to double-
check this, failure should be reported as an internal error and not
as an unexpected message.
A subsequent commit will need this function in the session ticket
and session cache implementations. As the latter are server-side,
this commit also removes the MBEDTLS_SSL_CLI_C guard.
For now, the function is declared in ssl_internal.h and hence not
part of the public API.
This commit modifies the helper `ssl_parse_certificate_chain()` to
accep any target X.509 CRT chain instead of hardcoding it to
`session_negotiate->peer_cert`. This increases modularity and paves
the way towards removing `mbedtls_ssl_session::peer_cert`.
This commit simplifies the client-side code for outgoing CertificateVerify
messages, and server-side code for outgoing CertificateRequest messages and
incoming CertificateVerify messages, through the use of the macro
`MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED`
indicating whether a ciphersuite allowing CertificateRequest messages
is enabled in the configuration, as well as the helper function
`mbedtls_ssl_ciphersuite_cert_req_allowed()`
indicating whether a particular ciphersuite allows CertificateRequest
messages.
These were already used in the client-side code to simplify the
parsing functions for CertificateRequest messages.
This commit adds a helper function `ssl_parse_certificate_coordinate()`
which checks whether a `Certificate` message is expected from the peer.
The logic is the following:
- For ciphersuites which don't use server-side CRTs, no Certificate
message is expected (neither for the server, nor the client).
- On the server, no client certificate is expected in the following cases:
* The server server didn't request a Certificate, which is controlled
by the `authmode` setting.
* A RSA-PSK suite is used; this is the only suite using server CRTs
but not allowing client-side authentication.
This commit introduces a static helper function
`mbedtls_ssl_ciphersuite_uses_srv_cert()`
which determines whether a ciphersuite may make use of server-side CRTs.
This function is in turn uses in `mbedtls_ssl_parse_certificate()` to
skip certificate parsing for ciphersuites which don't involve CRTs.
Note: Ciphersuites not using server-side CRTs don't allow client-side CRTs
either, so it is safe to guard `mbedtls_ssl_{parse/write}_certificate()`
this way.
Note: Previously, the code uses a positive check over the suites
- MBEDTLS_KEY_EXCHANGE_PSK
- MBEDTLS_KEY_EXCHANGE_DHE_PSK
- MBEDTLS_KEY_EXCHANGE_ECDHE_PSK
- MBEDTLS_KEY_EXCHANGE_ECJPAKE,
while now, it uses a negative check over `mbedtls_ssl_ciphersuite_uses_srv_cert()`,
which checks for the suites
- MBEDTLS_KEY_EXCHANGE_RSA
- MBEDTLS_KEY_EXCHANGE_RSA_PSK
- MBEDTLS_KEY_EXCHANGE_DHE_RSA
- MBEDTLS_KEY_EXCHANGE_ECDH_RSA
- MBEDTLS_KEY_EXCHANGE_ECDHE_RSA
- MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA
- MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
This is equivalent since, together, those are all ciphersuites.
Quoting ssl_ciphersuites.h:
```
typedef enum {
MBEDTLS_KEY_EXCHANGE_NONE = 0,
MBEDTLS_KEY_EXCHANGE_RSA,
MBEDTLS_KEY_EXCHANGE_DHE_RSA,
MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
MBEDTLS_KEY_EXCHANGE_PSK,
MBEDTLS_KEY_EXCHANGE_DHE_PSK,
MBEDTLS_KEY_EXCHANGE_RSA_PSK,
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
MBEDTLS_KEY_EXCHANGE_ECJPAKE,
} mbedtls_key_exchange_type_t;
```
The handler `mbedtls_ssl_parse_certificate()` for incoming `Certificate`
messages contains many branches updating the handshake state. For easier
reasoning about state evolution, this commit introduces a single code-path
updating the state machine at the end of `mbedtls_ssl_parse_certificate()`.
If an attempt for session resumption fails, the `session_negotiate` structure
might be partially filled, and in particular already contain a peer certificate
structure. This certificate structure needs to be freed before parsing the
certificate sent in the `Certificate` message.
This commit moves the code-path taking care of this from the helper
function `ssl_parse_certificate_chain()`, whose purpose should be parsing
only, to the top-level handler `mbedtls_ssl_parse_certificate()`.
The fact that we don't know the state of `ssl->session_negotiate` after
a failed attempt for session resumption is undesirable, and a separate
issue #2414 has been opened to improve on this.
This commit introduces a server-side static helper function
`ssl_srv_check_client_no_crt_notification()`, which checks if
the message we received during the incoming certificate state
notifies the server of the lack of certificate on the client.
For SSLv3, such a notification comes as a specific alert,
while for all other TLS versions, it comes as a `Certificate`
handshake message with an empty CRT list.
So far, we've used the `peer_cert` pointer to detect whether
we're parsing the first CRT, but that will soon be removed
if `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` is unset.
This commit introduces a helper function `ssl_clear_peer_cert()`
which frees all data related to the peer's certificate from an
`mbedtls_ssl_session` structure. Currently, this is the peer's
certificate itself, while eventually, it'll be its digest only.
After mitigating the 'triple handshake attack' by checking that
the peer's end-CRT didn't change during renegotation, the current
code avoids re-parsing the CRT by moving the CRT-pointer from the
old session to the new one. While efficient, this will no longer
work once only the hash of the peer's CRT is stored beyond the
handshake.
This commit removes the code-path moving the old CRT, and instead
frees the entire peer CRT chain from the initial handshake as soon
as the 'triple handshake attack' protection has completed.
Renamed the tests because they are explicitly testing Curve25519 and
nothing else. Improved test coverage, test documentation and extended
in-code documentation with a specific reference to the standard as well.
The library is able to perform computations and cryptographic schemes on
curves with x coordinate ladder representation. Here we add the
capability to export such points.
The function `mbedtls_mpi_write_binary()` writes big endian byte order,
but we need to be able to write little endian in some caseses. (For
example when handling keys corresponding to Montgomery curves.)
Used `echo xx | tac -rs ..` to transform the test data to little endian.
The private keys used in ECDH differ in the case of Weierstrass and
Montgomery curves. They have different constraints, the former is based
on big endian, the latter little endian byte order. The fundamental
approach is different too:
- Weierstrass keys have to be in the right interval, otherwise they are
rejected.
- Any byte array of the right size is a valid Montgomery key and it
needs to be masked before interpreting it as a number.
Historically it was sufficient to use mbedtls_mpi_read_binary() to read
private keys, but as a preparation to improve support for Montgomery
curves we add mbedtls_ecp_read_key() to enable uniform treatment of EC
keys.
For the masking the `mbedtls_mpi_set_bit()` function is used. This is
suboptimal but seems to provide the best trade-off at this time.
Alternatives considered:
- Making a copy of the input buffer (less efficient)
- removing the `const` constraint from the input buffer (breaks the api
and makes it less user friendly)
- applying the mask directly to the limbs (violates the api between the
modules and creates and unwanted dependency)
The library is able to perform computations and cryptographic schemes on
curves with x coordinate ladder representation. Here we add the
capability to import such points.
The function `mbedtls_mpi_read_binary()` expects big endian byte order,
but we need to be able to read from little endian in some caseses. (For
example when handling keys corresponding to Montgomery curves.)
Used `echo xx | tac -rs .. | tr [a-z] [A-Z]` to transform the test data
to little endian and `echo "ibase=16;xx" | bc` to convert to decimal.
Define MBEDTLS_ECDH_LEGACY_CONTEXT in config.h instead of hard-coding
this in ecdh.h so that its absence can be tested. Document it as
experimental so that we reserve the right to change it in the future.
If mbedtls_ecdh_get_params is called with keys belonging to
different groups, make it return an error the second time, rather than
silently interpret the first key as being on the second curve.
This makes the non-regression test added by the previous commit pass.
In places where we detect a context is in a bad state and there is no
sensitive data to clear, simply return PSA_ERROR_BAD_STATE and don't
abort on behalf of the application. The application will choose what to
do when it gets a bad state error.
The motivation for this change is that an application should decide what
to do when it misuses the API and encounters a PSA_ERROR_BAD_STATE
error. The library should not attempt to abort on behalf of the
application, as that may not be the correct thing to do in all
circumstances.
Calling psa_*_setup() twice on a MAC, cipher, or hash context should
result in a PSA_ERROR_BAD_STATE error because the operation has already
been set up.
Fixes#10
When building for the PSA crypto service (defined(PSA_CRYPTO_SECURE)),
define psa_key_owner_id_t as int32_t, which is how a PSA platform
encodes partition identity. Note that this only takes effect when the
build option MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER is active.
Support this configuration in the ITS backend.
Declare the owner as psa_key_owner_id_t, of which an implementation
must be provided separately.
Make this a configuration option
MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER, to make the conditional
compilation flow easier to follow. Declare it in config.h to
pacify check_names.sh.
Support for a specific implementation of psa_key_owner_id_t in storage
backends will come in a subsequent commit.
Differentiate between _key identifiers_, which are always `uint32_t`,
and _key file identifiers_, which are platform-dependent. Normally,
the two are the same.
In `psa/crypto_platform.h`, define `psa_app_key_id_t` (which is always
32 bits, the standard key identifier type) and
`psa_key_file_id_t` (which will be different in some service builds).
A subsequent commit will introduce a platform where the two are different.
It would make sense for the function declarations in `psa/crypto.h` to
use `psa_key_file_id_t`. However this file is currently part of the
PSA Crypto API specification, so it must stick to the standard type
`psa_key_id_t`. Hence, as long as the specification and Mbed Crypto
are not separate, use the implementation-specific file
`psa/crypto_platform.h` to define `psa_key_id_t` as `psa_key_file_id_t`.
In the library, systematically use `psa_key_file_id_t`.
perl -i -pe 's/psa_key_id_t/psa_key_file_id_t/g' library/*.[hc]
PSA_MAX_PERSISTENT_KEY_IDENTIFIER was actually one plus the maximum
key identifier. Change it to be the maximum value, and change the code
that uses it accordingly.
There is no semantic change here (the maximum value hasn't changed).
This commit only makes the implementation clearer.
This commit improves hygiene and formatting of macro definitions
throughout the library. Specifically:
- It adds brackets around parameters to avoid unintended
interpretation of arguments, e.g. due to operator precedence.
- It adds uses of the `do { ... } while( 0 )` idiom for macros that
can be used as commands.
Check generator validity (i.e. that alg has been initialized) before
allowing reads from the generator or allowing reads of the generator's
capacity.
This aligns our implementation with the documented error code behavior
in our crypto.h and the PSA Crypto API.
- Populate the ECDH private key slot with a fresh private EC key
designated for the correct algorithm.
- Export the public part of the ECDH private key from PSA and
reformat it to suite the format of the ClientKeyExchange message.
- Perform the PSA-based ECDH key agreement and store the result
as the premaster secret for the connection.
- Reformat the server's ECDH public key to make it suitable
for the PSA key agreement API. Currently, the key agreement
API needs a full SubjectPublicKeyInfo structure, while the
TLS ServerKeyExchange message only contains a ECPoint structure.
PSA spec now defines more generic PSA storage types instead of the ITS
specific ones. This is necessary in order to integrate with
the newer implementation of PSA ITS landing in Mbed OS soon.
Changes include the following:
- psa_status_t replaces psa_its_status_t
- psa_storage_info_t replaces psa_its_info_t
- psa_storage_uid_t replaces psa_its_uid_t
When `MBEDTLS_PLATFORM_C` is not enabled, our PSA Crypto implementation
depends on the standard C library for functions like snprintf() and
exit(). However, our implementation was not including the proper header
files nor redefining all `mbedtls_*` symbols properly to ensure
successful builds without MBEDTLS_PLATFORM_C. Add the necessary header
files and macro definitions to our PSA Crypto implementation.
Mbed TLS has deprecated a few module specific error codes in favor of
more general-purpose or cross-module error codes. Use these new error
codes instead of the deprecated error codes.
Resolve conflicts by performing the following.
- Take the upstream Mbed TLS ChangeLog verbatim.
- Reject changes to Makefiles and CMake that are related to using Mbed
Crypto as a submodule. It doesn't make sense to use Mbed Crypto as a
submodule of itself.
- Reject README changes, as Mbed Crypto has its own, different README.
- Reject PSA-related changes to config.h. We don't want to disable the
availability of the PSA Crypto API by default in the Mbed Crypto
config.h.
- Don't inadvertently revert dead code removal in
mbedtls_cipher_write_tag() which was added in f2a7529403 ("Fix
double return statement in cipher.c")
- Where Mbed Crypto already had some MBEDTLS_USE_PSA_CRYPTO code (from
past companion PRs) take the latest version from Mbed TLS which
includes integration with MBEDTLS_CHECK_PARAMS.
- Update the version of the shared library files to match what's
currently present in Mbed TLS.
- Reject removal of testing with PSA from config full tests.
- Resolve conflicts in test tests/suites/helpers.function, where both
Mbed Crypto and Mbed TLS both added documentation for TEST_ASSERT.
Combine text from both documentation efforts.
- Reject adding a submodule of ourselves.
- Reject addition of submodule tests in all.sh.
- Reject addition of submodule to library path in
tests/scripts/run-test-suites.pl.
- Avoid using USE_CRYPTO_SUBMODULE=1 in
component_test_use_psa_crypto_full_cmake_asan() in all.sh.
Enable handling of zero-length null output in PKCS1 v1.5 decryption.
Prevent undefined behavior by avoiding a memcpy() to zero-length null
output buffers.
In mbedtls_rsa_rsaes_oaep_encrypt and
mbedtls_rsa_rsaes_pkcs1_v15_encrypt, if the input length is 0 (which
is unusual and mostly useless, but permitted) then it is fine for the
input pointer to be NULL. Don't return an error in this case.
When `input` is NULL, `memcpy( p, input, ilen )` has undefined behavior
even if `ilen` is zero. So skip the `memcpy` call in this case.
Likewise, in `mbedtls_rsa_rsaes_oaep_decrypt`, skip the `memcpy` call if
`*olen` is zero.
Context: During a handshake, the SSL/TLS handshake logic constructs
an instance of ::mbedtls_ssl_session representing the SSL session
being established. This structure contains information such as the
session's master secret, the peer certificate, or the session ticket
issues by the server (if applicable).
During a renegotiation, the new session is constructed aside the existing
one and destroys and replaces the latter only when the renegotiation is
complete. While conceptually clear, this means that during the renegotiation,
large pieces of information such as the peer's CRT or the session ticket
exist twice in memory, even though the original versions are removed
eventually.
This commit removes the simultaneous presence of two peer CRT chains
in memory during renegotiation, in the following way:
- Unlike in the case of SessionTickets handled in the previous commit,
we cannot simply free the peer's CRT chain from the previous handshake
before parsing the new one, as we need to verify that the peer's end-CRT
hasn't changed to mitigate the 'Triple Handshake Attack'.
- Instead, we perform a binary comparison of the original peer end-CRT
with the one presented during renegotiation, and if it succeeds, we
avoid re-parsing CRT by moving the corresponding CRT pointer from the
old to the new session structure.
- The remaining CRTs in the peer's chain are not affected by the triple
handshake attack protection, and for them we may employ the canonical
approach of freeing them before parsing the remainder of the new chain.
Note that this commit intends to not change any observable behavior
of the stack. In particular:
- The peer's CRT chain is still verified during renegotiation.
- The tail of the peer's CRT chain may change during renegotiation.
Context: During a handshake, the SSL/TLS handshake logic constructs
an instance of ::mbedtls_ssl_session representing the SSL session
being established. This structure contains information such as the
session's master secret, the peer certificate, or the session ticket
issues by the server (if applicable).
During a renegotiation, the new session is constructed aside the existing
one and destroys and replaces the latter only when the renegotiation is
complete. While conceptually clear, this means that during the renegotiation,
large pieces of information such as the peer's CRT or the session ticket
exist twice in memory, even though the original versions are removed
eventually.
This commit starts removing this memory inefficiency by freeing the old
session's SessionTicket before the one for the new session is allocated.