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.
So far, make sure we test the following ciphersuites
without any fallback to non-PSA ciphers:
TLS-ECDHE-ECDSA-WITH-AES-128-CCM
TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8
TLS-ECDHE-ECDSA-WITH-AES-256-CCM
TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8
TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384
TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA
TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256
TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384
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.
The sanity checking script tests/scripts/check-names.sh uses a
simple state machine paired with a sequence of `sed` commands to
extract enumeration constants from the code. This code, however,
doesn't work properly when using multiline comments in enumerations
such as recently done in the constants MBEDTLS_CIPHER_PSA_KEY_XXX.
This commit doesn't attempt to make check-names.sh more robust
but instead uses /* ... */ comment indicators in each comment line,
while silences check-names.sh.
Increasing the robustness of check-names.sh is instead tracked
in #2210.
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 test suites `test_suite_gcm.aes{128,192,256}_en.data` contains
numerous NIST test vectors for AES-*-GCM against which the GCM
API mbedtls_gcm_xxx() is tested.
However, one level higher at the cipher API, no tests exist which
exercise mbedtls_cipher_auth_{encrypt/decrypt}() for GCM ciphers,
although test_suite_cipher.function contains the test auth_crypt_tv
which does precisely that and is already used e.g. in
test_suite_cipher.ccm.
This commit replicates the test vectors from
test_suite_gcm.aes{128,192,256}_en.data in test_suite_cipher.gcm.data
and adds a run of auth_crypt_tv for each of them.
The conversion was mainly done through the sed command line
```
s/gcm_decrypt_and_verify:\([^:]*\):\([^:]*\):\([^:]*\):\([^:]*\):
\([^:]*\):\([^:]*\):\([^:]*\):\([^:]*\):\([^:]*\):\([^:]*\)/auth_crypt_tv:
\1:\2:\4:\5:\3:\7:\8:\9/
```
In case of AEAD ciphers, the cipher mode (and not even the entire content
of mbedtls_cipher_info_t) doesn't uniquely determine a psa_algorithm_t
because it doesn't specify the AEAD tag length, which however is included
in psa_algorithm_t identifiers.
This commit adds a tag length value to mbedtls_psa_translate_cipher_mode()
to account for that ambiguity.