Implement psa_allocate_key, psa_open_key, psa_create_key,
psa_close_key.
Add support for keys designated to handles to psa_get_key_slot, and
thereby to the whole API.
Allocated and non-allocated keys can coexist. This is a temporary
stage in order to transition from the use of direct slot numbers to
allocated handles only. Once all the tests and sample programs have
been migrated to use handles, the implementation will be simplified
and made more robust with support for handles only.
At the moment, the in-storage slot identifier is the in-memory slot
number. But track them separately, to prepare for API changes that
will let them be different (psa_open_key, psa_create_key).
Add missing compilation guards that broke the build if either GCM or
CCM was not defined.
Add missing guards on test cases that require GCM or CBC.
The build and tests now pass for any subset of {MBEDTLS_CCM_C,
MBEDTLS_GCM_C}. There are still unused variables warnings if neither
is defined.
Add a function to configure entropy sources. For testing only.
Use it to test that the library initialization fails properly if there is no
entropy source.
There is a probability that r will be encoded as 31 or less bytes in DER,
so additional padding is added in such case.
Added a signature-part extraction function to tidy up the code further.
Return early from mbedtls_pk_write_pubkey_der - public opaque key
exporting is expected to contain all of the needed data, therefore it shouldn't
be written again.
It's better for names in the API to describe the "what" (opaque keys) rather
than the "how" (using PSA), at least since we don't intend to have multiple
function doing the same "what" in different ways in the foreseeable future.
Unfortunately the can_do wrapper does not receive the key context as an
argument, so it cannot check psa_get_key_information(). Later we might want to
change our internal structures to fix this, but for now we'll just restrict
opaque PSA keys to be ECDSA keypairs, as this is the only thing we need for
now. It also simplifies testing a bit (no need to test each key type).
Reasons:
- For the first release, we attempt to support TLS-1.2 only,
- At least TLS-1.0 is known to not work at the moment, as
for CBC ciphersuites the code in mbedtls_ssl_decrypt_buf()
and mbedtls_ssl_encrypt_buf() assumes that mbedtls_cipher_crypt()
updates the structure field for the IV in the cipher context,
which the PSA-based implementation currently doesn't.
This commit modifies the default SSL ticket implementation
from `library/ssl_ticket.c` to use PSA-based cipher context
for ticket creation and parsing.
As in mbedtls_ssl_derive_keys() adapted in an earlier commit,
we allow fallback to the ordinary mbedtls_cipher_setup()
if the provided cipher is not known. We do this even though
we always call mbedtls_ssl_ticket_setup() with AES-GCM
in our own code since this function is public and might
be used with other ciphers by users.
This commit changes the code path in mbedtls_ssl_derive_keys()
responsible for setting up record protection cipher contexts
to attempt to use the new API mbedtls_cipher_setup_psa() in
case MBEDTLS_USE_PSA_CRYPTO is set.
For that, the AEAD tag length must be provided, which is already
computed earlier in mbedtls_ssl_derive_keys() and only needs to be
stored a function scope to be available for mbedtls_cipher_setup_psa().
If mbedtls_cipher_setup_psa() fails cleanly indicating that the
requested cipher is not supported in PSA, we fall through to
the default setup using mbedtls_cipher_setup(). However, we print
a debug message in this case, to allow catching the fallthrough in
tests where we know we're using a cipher which should be supported
by PSA.
mbedtls_cipher_setup_psa() should return
MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE when the requested
cipher is not supported by PSA, so that the caller can
try the original mbedtls_cipher_setup() instead.
The previous version of mbedtls_cipher_setup_psa(), however,
only attempted to translate the cipher mode (GCM, CCM, CBC,
ChaChaPoly, Stream), but didn't consider the underlying
cipher primitive. Hence, it wouldn't fail when attempting
to setup a cipher context for, say, 3DES-CBC, where CBC
is currently supported by PSA but 3DES isn't.
This commit adds a check to mbedtls_cipher_setup_psa()
for whether the requested cipher primitive is available
in the underlying PSA Crypto implementation, and fails
cleanly with MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE if
it is isn't.
For AEAD ciphers, the information contained in mbedtls_cipher_info
is not enough to deduce a PSA algorithm value of type psa_algorithm_t.
This is because mbedtls_cipher_info doesn't contain the AEAD tag
length, while values of type psa_algorithm_t do.
This commit adds the AEAD tag length as a separate parameter
to mbedtls_cipher_setup_psa(). For Non-AEAD ciphers, the value
must be 0.
This approach is preferred over passing psa_algorithm_t directly
in order to keep the changes in existing code using the cipher layer
small.
Mbed TLS cipher layer allows usage of keys for other purposes
than indicated in the `operation` parameter of `mbedtls_cipher_setkey()`.
The semantics of the PSA Crypto API, in contrast, checks key
usage against the key policy.
As a remedy, this commit modifies the PSA key slot setup to
always allow both encryption and decryption.
This commit implements the internal key slot management performed
by PSA-based cipher contexts. Specifically, `mbedtls_cipher_setkey()`
wraps the provided raw key material into a key slot, and
`mbedtls_cipher_free()` destroys that key slot.
This field determines whether a cipher context should
use an external implementation of the PSA Crypto API for
cryptographic operations, or Mbed TLS' own crypto library.
The commit also adds dummy implementations for the cipher API.
The code maintains the invariant that raw and opaque PSKs are never
configured simultaneously, so strictly speaking `ssl_conf_remove_psk()`
need not consider clearing the raw PSK if it has already cleared an
opaque one - and previously, it didn't. However, it doesn't come at
any cost to keep this check as a safe-guard to future unforeseen
situations where opaque and raw PSKs _are_ both present.
In multiple places, it occurrs as the fixed length of
the master secret, so use a constant with a descriptive
name instead. This is reinforced by the fact the some
further occurrences of '48' are semantically different.
Allow mbedtls_psa_crypto_free to be called twice, or without a prior
call to psa_crypto_init. Keep track of the initialization state more
precisely in psa_crypto_init so that mbedtls_psa_crypto_free knows
what to do.
For Makefiles, enable overriding where includes can come from in order to
enable the parent module to set the include path. This allows the parent
module to specify that its config.h should be used, even when the submodule
when built standalone would use a different config.h.
For CMake, always look in the parent's include folder and our own. List the
parent's include folder first, so that preference is given to parent
include files.
When building Mbed Crypto as a subproject, don't add targets for
libmbedx509 or libmbedtls, as the parent project should build these. The
parent project will define USE_CRYPTO_SUBMODULE variable when using Mbed
Crypto as a submodule, so we can depend on that variable to control whether
or not we build non-crypto libraries.
The new file is conditionally compiled with the new mbedtls
configuration option that Mbed OS would set by default -
`MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C`.
-
When generating keys that have persistent lifetime, we will need
the keys to be in the exported format to save to persistent storage.
This refactoring to separate checking the slots usage from the
exporting of the key data will be necessary for using
psa_internal_export_key in psa_generate_key.
Allow use of persistent keys, including configuring them, importing and
exporting them, and destroying them.
When getting a slot using psa_get_key_slot, there are 3 scenarios that
can occur if the keys lifetime is persistent:
1. Key type is PSA_KEY_TYPE_NONE, no persistent storage entry:
- The key slot is treated as a standard empty key slot
2. Key type is PSA_KEY_TYPE_NONE, persistent storage entry exists:
- Attempt to load the key from persistent storage
3. Key type is not PSA_KEY_TYPE_NONE:
- As checking persistent storage on every use of the key could
be expensive, the persistent key is assumed to be saved in
persistent storage, the in-memory key is continued to be used.