Clarify the "restart vs use PSA" situation in TLS
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
diff --git a/docs/architecture/psa-migration/psa-limitations.md b/docs/architecture/psa-migration/psa-limitations.md
index e565b28..c368023 100644
--- a/docs/architecture/psa-migration/psa-limitations.md
+++ b/docs/architecture/psa-migration/psa-limitations.md
@@ -17,8 +17,11 @@
There is currently no support for that in PSA at all, but it will be added at
some point, see <https://github.com/orgs/Mbed-TLS/projects/1#column-18816849>.
-Currently, `MBEDTLS_USE_PSA_CRYPTO` is simply incompatible with
-`MBEDTLS_ECP_RESTARTABLE`.
+Currently, when `MBEDTLS_USE_PSA_CRYPTO` and `MBEDTLS_ECP_RESTARTABLE` are
+both enabled, some operations that should be restartable are not (ECDH in TLS
+1.2 clients using ECDHE-ECDSA), as they are using PSA instead, and some
+operations that should use PSA do not (signature generation & verification) as
+they use the legacy API instead, in order to get restartable behaviour.
Things that are in the API but not implemented yet
--------------------------------------------------
diff --git a/docs/use-psa-crypto.md b/docs/use-psa-crypto.md
index 11442ed..194d96f 100644
--- a/docs/use-psa-crypto.md
+++ b/docs/use-psa-crypto.md
@@ -7,9 +7,6 @@
General considerations
----------------------
-**Compile-time:** enabling `MBEDTLS_USE_PSA_CRYPTO` requires
-`MBEDTLS_ECP_RESTARTABLE` to be disabled.
-
**Application code:** when this option is enabled, you need to call
`psa_crypto_init()` before calling any function from the SSL/TLS, X.509 or PK
module.
@@ -86,28 +83,34 @@
Current exceptions:
-- finite-field (non-EC) Diffie-Hellman (used in key exchanges: DHE-RSA,
- DHE-PSK)
+- Finite-field (non-EC) Diffie-Hellman (used in key exchanges: DHE-RSA,
+ DHE-PSK).
+- Restartable operations when `MBEDTLS_ECP_RESTARTABLE` is also enabled (see
+ the documentation of that option).
Other than the above exceptions, all crypto operations are based on PSA when
`MBEDTLS_USE_PSA_CRYPTO` is enabled.
### X.509: most crypto operations based on PSA
-Current exception:
+Current exceptions:
-- verification of RSA-PSS signatures with a salt length that is different from
+- Verification of RSA-PSS signatures with a salt length that is different from
the hash length.
+- Restartable operations when `MBEDTLS_ECP_RESTARTABLE` is also enabled (see
+ the documentation of that option).
Other than the above exception, all crypto operations are based on PSA when
`MBEDTLS_USE_PSA_CRYPTO` is enabled.
### PK layer: most crypto operations based on PSA
-Current exception:
+Current exceptions:
-- verification of RSA-PSS signatures with a salt length that is different from
+- Verification of RSA-PSS signatures with a salt length that is different from
the hash length, or with an MGF hash that's different from the message hash.
+- Restartable operations when `MBEDTLS_ECP_RESTARTABLE` is also enabled (see
+ the documentation of that option).
Other than the above exception, all crypto operations are based on PSA when
`MBEDTLS_USE_PSA_CRYPTO` is enabled.
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index 219dd45..7a681d1 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -701,22 +701,25 @@
* - Changes the behaviour of TLS 1.2 clients (not servers) when using the
* ECDHE-ECDSA key exchange (not other key exchanges) to make all ECC
* computations restartable:
- * - ECDH operations from the key exchange;
+ * - ECDH operations from the key exchange - unless MBEDTLS_USE_PSA_CRYPTO
+ * is also enabled.
* - verification of the server's key exchange signature;
* - verification of the server's certificate chain;
* - generation of our signature if client authentication is used, with an
* ECC key/certificate.
*
- * TODO: document interation with USE_PSA_CRYPTO
- *
* \note In the cases above, the usual SSL/TLS functions, such as
* mbedtls_ssl_handshake(), can now return
* MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS.
*
+ * \note When this option and MBEDTLS_USE_PSA_CRYPTO are both enabled,
+ * restartable operations in PK, X.509 and TLS (see above) are not
+ * using PSA. On the other hand, ECDH computations in TLS are using
+ * PSA, and are not restartable.
+ *
* \note This option only works with the default software implementation of
* elliptic curve functionality. It is incompatible with
- * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT, MBEDTLS_ECDSA_XXX_ALT,
- * and MBEDTLS_USE_PSA_CRYPTO.
+ * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT, MBEDTLS_ECDSA_XXX_ALT.
*
* Uncomment this macro to enable restartable ECC computations.
*/
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 154ba34..b9b2bc5 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -8395,10 +8395,12 @@
-C "mbedtls_ecdh_make_public.*4b00" \
-C "mbedtls_pk_sign.*4b00"
+# With USE_PSA disabled we expect full restartable behaviour.
requires_config_enabled MBEDTLS_ECP_RESTARTABLE
requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-run_test "EC restart: TLS, max_ops=1000" \
+requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: TLS, max_ops=1000 (no USE_PSA)" \
"$P_SRV curves=secp256r1 auth_mode=required" \
"$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
key_file=data_files/server5.key crt_file=data_files/server5.crt \
@@ -8409,6 +8411,25 @@
-c "mbedtls_ecdh_make_public.*4b00" \
-c "mbedtls_pk_sign.*4b00"
+# With USE_PSA enabled we expect only partial restartable behaviour:
+# everything except ECDH (where TLS calls PSA directly).
+requires_config_enabled MBEDTLS_ECP_RESTARTABLE
+requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: TLS, max_ops=1000 (USE_PSA)" \
+ "$P_SRV curves=secp256r1 auth_mode=required" \
+ "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
+ key_file=data_files/server5.key crt_file=data_files/server5.crt \
+ debug_level=1 ec_max_ops=1000" \
+ 0 \
+ -c "x509_verify_cert.*4b00" \
+ -c "mbedtls_pk_verify.*4b00" \
+ -C "mbedtls_ecdh_make_public.*4b00" \
+ -c "mbedtls_pk_sign.*4b00"
+
+# This works the same with & without USE_PSA as we never get to ECDH:
+# we abort as soon as we determined the cert is bad.
requires_config_enabled MBEDTLS_ECP_RESTARTABLE
requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
@@ -8428,10 +8449,12 @@
-c "! mbedtls_ssl_handshake returned" \
-c "X509 - Certificate verification failed"
+# With USE_PSA disabled we expect full restartable behaviour.
requires_config_enabled MBEDTLS_ECP_RESTARTABLE
requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-run_test "EC restart: TLS, max_ops=1000, auth_mode=optional badsign" \
+requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: TLS, max_ops=1000, auth_mode=optional badsign (no USE_PSA)" \
"$P_SRV curves=secp256r1 auth_mode=required \
crt_file=data_files/server5-badsign.crt \
key_file=data_files/server5.key" \
@@ -8447,10 +8470,34 @@
-C "! mbedtls_ssl_handshake returned" \
-C "X509 - Certificate verification failed"
+# With USE_PSA enabled we expect only partial restartable behaviour:
+# everything except ECDH (where TLS calls PSA directly).
requires_config_enabled MBEDTLS_ECP_RESTARTABLE
requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-run_test "EC restart: TLS, max_ops=1000, auth_mode=none badsign" \
+requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: TLS, max_ops=1000, auth_mode=optional badsign (USE_PSA)" \
+ "$P_SRV curves=secp256r1 auth_mode=required \
+ crt_file=data_files/server5-badsign.crt \
+ key_file=data_files/server5.key" \
+ "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
+ key_file=data_files/server5.key crt_file=data_files/server5.crt \
+ debug_level=1 ec_max_ops=1000 auth_mode=optional" \
+ 0 \
+ -c "x509_verify_cert.*4b00" \
+ -c "mbedtls_pk_verify.*4b00" \
+ -C "mbedtls_ecdh_make_public.*4b00" \
+ -c "mbedtls_pk_sign.*4b00" \
+ -c "! The certificate is not correctly signed by the trusted CA" \
+ -C "! mbedtls_ssl_handshake returned" \
+ -C "X509 - Certificate verification failed"
+
+# With USE_PSA disabled we expect full restartable behaviour.
+requires_config_enabled MBEDTLS_ECP_RESTARTABLE
+requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: TLS, max_ops=1000, auth_mode=none badsign (no USE_PSA)" \
"$P_SRV curves=secp256r1 auth_mode=required \
crt_file=data_files/server5-badsign.crt \
key_file=data_files/server5.key" \
@@ -8466,10 +8513,34 @@
-C "! mbedtls_ssl_handshake returned" \
-C "X509 - Certificate verification failed"
+# With USE_PSA enabled we expect only partial restartable behaviour:
+# everything except ECDH (where TLS calls PSA directly).
requires_config_enabled MBEDTLS_ECP_RESTARTABLE
requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-run_test "EC restart: DTLS, max_ops=1000" \
+requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: TLS, max_ops=1000, auth_mode=none badsign (USE_PSA)" \
+ "$P_SRV curves=secp256r1 auth_mode=required \
+ crt_file=data_files/server5-badsign.crt \
+ key_file=data_files/server5.key" \
+ "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
+ key_file=data_files/server5.key crt_file=data_files/server5.crt \
+ debug_level=1 ec_max_ops=1000 auth_mode=none" \
+ 0 \
+ -C "x509_verify_cert.*4b00" \
+ -c "mbedtls_pk_verify.*4b00" \
+ -C "mbedtls_ecdh_make_public.*4b00" \
+ -c "mbedtls_pk_sign.*4b00" \
+ -C "! The certificate is not correctly signed by the trusted CA" \
+ -C "! mbedtls_ssl_handshake returned" \
+ -C "X509 - Certificate verification failed"
+
+# With USE_PSA disabled we expect full restartable behaviour.
+requires_config_enabled MBEDTLS_ECP_RESTARTABLE
+requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: DTLS, max_ops=1000 (no USE_PSA)" \
"$P_SRV curves=secp256r1 auth_mode=required dtls=1" \
"$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
key_file=data_files/server5.key crt_file=data_files/server5.crt \
@@ -8480,10 +8551,29 @@
-c "mbedtls_ecdh_make_public.*4b00" \
-c "mbedtls_pk_sign.*4b00"
+# With USE_PSA enabled we expect only partial restartable behaviour:
+# everything except ECDH (where TLS calls PSA directly).
requires_config_enabled MBEDTLS_ECP_RESTARTABLE
requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
-run_test "EC restart: TLS, max_ops=1000 no client auth" \
+requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: DTLS, max_ops=1000 (USE_PSA)" \
+ "$P_SRV curves=secp256r1 auth_mode=required dtls=1" \
+ "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
+ key_file=data_files/server5.key crt_file=data_files/server5.crt \
+ dtls=1 debug_level=1 ec_max_ops=1000" \
+ 0 \
+ -c "x509_verify_cert.*4b00" \
+ -c "mbedtls_pk_verify.*4b00" \
+ -C "mbedtls_ecdh_make_public.*4b00" \
+ -c "mbedtls_pk_sign.*4b00"
+
+# With USE_PSA disabled we expect full restartable behaviour.
+requires_config_enabled MBEDTLS_ECP_RESTARTABLE
+requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_disabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: TLS, max_ops=1000 no client auth (no USE_PSA)" \
"$P_SRV curves=secp256r1" \
"$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
debug_level=1 ec_max_ops=1000" \
@@ -8494,6 +8584,22 @@
-C "mbedtls_pk_sign.*4b00"
+# With USE_PSA enabled we expect only partial restartable behaviour:
+# everything except ECDH (where TLS calls PSA directly).
+requires_config_enabled MBEDTLS_ECP_RESTARTABLE
+requires_config_enabled MBEDTLS_ECP_DP_SECP256R1_ENABLED
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
+requires_config_enabled MBEDTLS_USE_PSA_CRYPTO
+run_test "EC restart: TLS, max_ops=1000 no client auth (USE_PSA)" \
+ "$P_SRV curves=secp256r1" \
+ "$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 \
+ debug_level=1 ec_max_ops=1000" \
+ 0 \
+ -c "x509_verify_cert.*4b00" \
+ -c "mbedtls_pk_verify.*4b00" \
+ -C "mbedtls_ecdh_make_public.*4b00" \
+ -C "mbedtls_pk_sign.*4b00"
+
# Restartable is only for ECDHE-ECDSA, with another ciphersuite we expect no
# restartable behaviour at all (not even client auth).
# This is the same as "EC restart: TLS, max_ops=1000" except with ECDHE-RSA,