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).
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.
* 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 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>
* 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().
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.