From 0d0a104b2d3751e9ebb33e6dd193c59a91cb6c14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 22 Sep 2021 12:15:27 +0200 Subject: [PATCH 01/21] Add study for TLS/X.509 dependencies on crypto MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is an updated version of the study that was done a few years ago. The script `syms` was used to list symbols form libmbedtls.a / libmbedx509.a that are defined externally. It was run with config.py full minus MBEDTLS_USE_PSA_CRYPTO minus MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL. Signed-off-by: Manuel Pégourié-Gonnard --- .../psa-migration/dependencies-tls.md | 563 ++++++++++++++++++ .../psa-migration/dependencies-x509.md | 206 +++++++ docs/architecture/psa-migration/syms.sh | 58 ++ 3 files changed, 827 insertions(+) create mode 100644 docs/architecture/psa-migration/dependencies-tls.md create mode 100644 docs/architecture/psa-migration/dependencies-x509.md create mode 100755 docs/architecture/psa-migration/syms.sh diff --git a/docs/architecture/psa-migration/dependencies-tls.md b/docs/architecture/psa-migration/dependencies-tls.md new file mode 100644 index 000000000000..74f78d57b070 --- /dev/null +++ b/docs/architecture/psa-migration/dependencies-tls.md @@ -0,0 +1,563 @@ +Dependencies of the TLS library on the Crypto library +===================================================== + +This document is part of the technical study on how to port Mbed TLS to PSA +Crypto. It describes the dependencies of libmbedtls.a on libmbedcrypto.a. + +More precisely, it describes what functions from libmbedcrypto.a are called +from libmbedtls.a - other forms of dependencies such as using static inline +functions or types, accessing private struct members, etc., are not listed. + +It is based on Mbed TLS 3.0, excluding experimental support for TLS 1.3, and +also excluding support for restartble ECP operations. + +Non-Crypto dependencies +----------------------- + +The TLS library has a number of dependencies on libmbedcrypto.a that are not +cryptographic, hence are unlikely to be covered by the PSA Crypto API. + +These involve the following modules: + +- threading +- platform + +It also depends on the X.509 library, which is excluded from further analysis +as the focus here is on dependencies on libmbedcrypto.a. + +Crypto dependencies (high-level) +-------------------------------- + +The TLS library depends on the following cryptographic modules: + +- cipher +- dhm +- ecdh +- ecjpake +- ecp +- md +- mpi +- pk +- sha256 +- sha512 + +More specifically, calls are made to the following API functions: + +``` +mbedtls_cipher_auth_decrypt_ext +mbedtls_cipher_auth_encrypt_ext +mbedtls_cipher_crypt +mbedtls_cipher_free +mbedtls_cipher_info_from_type +mbedtls_cipher_init +mbedtls_cipher_set_padding_mode +mbedtls_cipher_setkey +mbedtls_cipher_setup + +mbedtls_dhm_calc_secret +mbedtls_dhm_free +mbedtls_dhm_get_bitlen +mbedtls_dhm_get_len +mbedtls_dhm_get_value +mbedtls_dhm_init +mbedtls_dhm_make_params +mbedtls_dhm_make_public +mbedtls_dhm_read_params +mbedtls_dhm_read_public +mbedtls_dhm_set_group + +mbedtls_ecdh_calc_secret +mbedtls_ecdh_free +mbedtls_ecdh_get_params +mbedtls_ecdh_init +mbedtls_ecdh_make_params +mbedtls_ecdh_make_public +mbedtls_ecdh_read_params +mbedtls_ecdh_read_public +mbedtls_ecdh_setup + +mbedtls_ecjpake_check +mbedtls_ecjpake_derive_secret +mbedtls_ecjpake_free +mbedtls_ecjpake_init +mbedtls_ecjpake_read_round_one +mbedtls_ecjpake_read_round_two +mbedtls_ecjpake_set_point_format +mbedtls_ecjpake_setup +mbedtls_ecjpake_write_round_one +mbedtls_ecjpake_write_round_two + +mbedtls_ecp_curve_info_from_grp_id +mbedtls_ecp_curve_info_from_tls_id + +mbedtls_md_clone +mbedtls_md_finish +mbedtls_md_free +mbedtls_md_get_size +mbedtls_md_get_type +mbedtls_md_hmac_finish +mbedtls_md_hmac_reset +mbedtls_md_hmac_starts +mbedtls_md_hmac_update +mbedtls_md_info_from_type +mbedtls_md_init +mbedtls_md_setup +mbedtls_md_starts +mbedtls_md_update + +mbedtls_mpi_bitlen +mbedtls_mpi_free +mbedtls_mpi_read_binary + +mbedtls_pk_can_do +mbedtls_pk_debug +mbedtls_pk_decrypt +mbedtls_pk_encrypt +mbedtls_pk_get_bitlen +mbedtls_pk_sign +mbedtls_pk_sign_restartable +mbedtls_pk_verify +mbedtls_pk_verify_restartable + +mbedtls_sha256_clone +mbedtls_sha256_finish +mbedtls_sha256_free +mbedtls_sha256_init +mbedtls_sha256_starts +mbedtls_sha256_update + +mbedtls_sha512_clone +mbedtls_sha512_finish +mbedtls_sha512_free +mbedtls_sha512_init +mbedtls_sha512_starts +mbedtls_sha512_update +``` + +Note: the direct dependency on MPI functions is in order to manage DHM +parameters, that are currently stored as a pair of MPIs in the +`mbedtls_ssl_config` structure. (The public API uses byte arrays or a +`mbedtls_dhm_context` structure.) + +Note: the direct dependency on ECP APIs is in order to access information; +no crypto operation is done directly via this API, only via the PK and ECDH +APIs. + +Note: the direct dependencies on the SHA-2 modules instead of using the +MD layer is for convenience (and perhaps to save some memory as well) and can +easily be replace by use of a more generic API. + +Key exchanges and other configuration options +--------------------------------------------- + +In the file-level analysis below, many things are only used if certain key +exchanges or other configuration options are enabled. This section sums up +those key exchanges and options. + +Key exchanges: + +- DHE-PSK +- DHE-RSA +- ECDH-ECDSA +- ECDH-RSA +- ECDHE-ECDSA +- ECDHE-PSK +- ECDHE-RSA +- ECJPAKE +- PSK +- RSA +- RSA-PSK + +Protocol: + +- `MBEDTLS_SSL_PROTO_TLS1_2` +- `MBEDTLS_SSL_PROTO_DTLS` +- `MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL` (excluded from this analysis) + +TLS sides: + +- `MBEDTLS_SSL_CLI_C` +- `MBEDTLS_SSL_SRV_C` + +TLS support modules: + +- `MBEDTLS_SSL_CACHE_C` +- `MBEDTLS_SSL_COOKIE_C` +- `MBEDTLS_SSL_TICKET_C` + +Cipher modes: + +- `MBEDTLS_CIPHER_MODE_CBC` +- `MBEDTLS_CIPHER_NULL_CIPHER` +- `MBEDTLS_GCM_C` +- `MBEDTLS_CCM_C` +- `MBEDTLS_CHACHAPOLY_C` + +Hashes: + +- `MBEDTLS_MD5_C` (ciphersuites using HMAC-MD5) +- `MBEDTLS_SHA1_C` (ciphersuites using HMAC-SHA1) +- `MBEDTLS_SHA256_C` +- `MBEDTLS_SHA512_C` + +Other options: + +- `MBEDTLS_X509_CRT_PARSE_C` +- `MBEDTLS_SSL_SESSION_TICKETS` +- `MBEDTLS_SSL_ENCRYPT_THEN_MAC` + + +File-level analysis +------------------- + +The TLS library consists of the following files (excluding TLS 1.3 which is +currently experimental and changing rapidly): + +``` +library/debug.c +library/net_sockets.c +library/ssl_cache.c +library/ssl_ciphersuites.c +library/ssl_cli.c +library/ssl_cookie.c +library/ssl_msg.c +library/ssl_srv.c +library/ssl_ticket.c +library/ssl_tls.c +``` + +The file `net_sockets.c` is excluded from further analysis as it's unrelated. + +**Note:** Calls to `f_rng` in the files below could also be replaced with +direct calls to the global PSA RNG; however these calls are not included in +the current analysis, since the PSA RNG can already be used by setting it +explicitly. + +### `debug.c` + +- In `debug_print_pk()` + call `mbedtls_pk_debug()` + to print info (or "invalid PK context" on failure) + if `MBEDTLS_X509_CRT_PARSE_C` is enabled. + +- In `mbedtls_debug_print_mpi()` + call `mbedtls_mpi_print_mpi()` + +### `ssl_cache.c` + +**Note:** This module is only used server side. + +No call to any crypto API function from this file. + +_Note :_ in the future, work may be required in order to securely store +session secrets in the cache, but it's outside the scope of this analysis. + +### `ssl_ciphersuites.c` + +No call to any crypto API function from this file. + +### `ssl_cookie.c` + +**Note:** this module is only used server-side, only for DTLS. + +- In `mbedtls_ssl_cookie_init()` / `mbedtls_ssl_cookie_free()` + call `mbedtls_md_init()` / `mbedtls_md_free()` + +- In `mbedtls_ssl_cookie_setup()` + call `mbedtls_md_setup()`, `mbedtls_md_info_from_type()` and `mbedtls_md_hmac_starts()` + to set up an HMAC key. + +- In `ssl_cookie_hmac()` + call `mbedtls_md_hmac_reset()`, `mbedtls_md_hmac_update()` and `mbedtls_md_hmac_finish()` + +### `ssl_ticket.c` + +**Note:** This module is only used server-side. + +- In `ssl_ticket_gen_key()` + call `mbedtls_cipher_setkey()` and `mbedtls_cipher_get_key_bitlen()` + +- In `mbedtls_ssl_ticket_setup()` + call `mbedtls_cipher_info_from_type()` and `mbedtls_cipher_setup()` + +- In `mbedtls_ssl_ticket_write()` + call `mbedtls_cipher_auth_encrypt_ext()` + +- In `mbedtls_ssl_ticket_parse()` + call `mbedtls_cipher_auth_decrypt_ext()` + +### `ssl_cli.c` + +**Note:** This module is only used client-side. + +- In `ssl_write_supported_elliptic_curves_ext()` + call `mbedtls_ecp_curve_list()` and `mbedtls_ecp_curve_info_from_grp_id()` + if ECDH, ECDSA or ECJPAKE is enabled + +- In `ssl_write_ecjpake_kkpp_ext()` + call `mbedtls_ecjpake_check()` and `mbedtls_ecjpake_write_round_one()` + if ECJPAKE is enabled + +- In `ssl_parse_supported_point_formats_ext()` + call `mbedtls_ecjpake_set_point_format()` + if ECJPAKE is enabled. + +- In `ssl_validate_ciphersuite()` + call `mbedtls_ecjpake_check()` + if ECJPAKE is enabled. + +- In `ssl_parse_ecjpake_kkpp()` + call `mbedtls_ecjpake_read_round_one()` + if ECJPAKE is enabled. + +- In `ssl_parse_server_dh_params()` + call `mbedtls_dhm_read_params()` and `mbedtls_dhm_get_bitlen()` + if DHE-RSA or DHE-PSK key echange is enabled. + +- In `ssl_check_server_ecdh_params()` + call `mbedtls_ecp_curve_info_from_grp_id()` + if ECDHE-RSA, ECDHE-ECDSA, ECDHE-PSK, ECDH-RSA or ECDH-ECDSA key exchange is enabled. + +- In `ssl_parse_server_ecdh_params()` + call `mbedtls_ecdh_read_params()` + if ECDHE-RSA, ECDHE-ECDSA or ECDHE-PSK is enabled. + +- In `ssl_write_encrypted_pms()` + call `mbedtls_pk_can_do()` and `mbedtls_pk_encrypt()` on peer's public key + if RSA or RSA-PSK key exchange enabled. + +- In `ssl_get_ecdh_params_from_cert()` + call `mbedtls_pk_can_do()` and `mbedtls_pk_ec()` and `mbedtls_ecdh_get_params()` + if ECDH-RSA or ECDH-ECDSA key exchange is enabled + to import public key of peer's cert to ECDH context. + +- In `ssl_parse_server_key_exchange()` + call `mbedtls_ecjpake_read_round_two()` + if ECJPAKE is enabled. + +- In `ssl_parse_server_key_exchange()` + call `mbedtls_pk_can_do()` and `mbedtls_pk_verify_restartable()` + if DHE-RSA, ECDHE-RSA or ECDHE-ECDSA is enabled. + (Note: the hash is computed by `mbedtls_ssl_get_key_exchange_md_tls1_2()`.) + +- In `ssl_write_client_key_exchange()` + call `mbedtls_dhm_make_public()`, `mbedtls_dhm_get_len()` and `mbedtls_dhm_calc_secret()` + if DHE-RSA key exchange is enabled. + +- In `ssl_write_client_key_exchange()` + call `mbedtls_ecdh_make_public()` and `mbedtls_ecdh_calc_secret()` + if ECDHE-RSA, ECDHE-ECDSA, ECDH-RSA or ECDH-ECDSA is enabled. + +- In `ssl_write_client_key_exchange()` + call `mbedtls_dhm_make_public()` and `mbedtls_dhm_get_len()` + if DHE-PSK is enabled. + +- In `ssl_write_client_key_exchange()` + call `mbedtls_ecdh_make_public()` + if ECDHE-PSK is enabled. + +- In `ssl_write_client_key_exchange()` + call `mbedtls_ecjpake_write_round_two()` and `mbedtls_ecjpake_derive_secret()` + if ECJPAKE is enabled. + +- In `ssl_write_certificate_verify()` + call `mbedtls_pk_can_do()` and `mbedtls_pk_sign_restartable()` + if RSA, DHE-RSA, ECDH-RSA, ECDHE-RSA, ECDH-ECDSA or ECDHE-ECDSA is enabled. + (Note: the hash is computed by `calc_verify()`.) + +### `ssl_srv.c` + +**Note:** This module is only used server-side. + +- In `ssl_parse_supported_elliptic_curves()` + call `mbedtls_ecp_curve_info_from_tls_id()` + if ECDH, ECDSA or ECJPAKE is enabled. + +- In `ssl_parse_supported_point_formats()` + call `mbedtls_ecjpake_set_point_format()` + if ECJPAKE is enabled. + +- In `ssl_parse_ecjpake_kkpp()` + call `mbedtls_ecjpake_check()` and `mbedtls_ecjpake_read_round_one()` + if ECJPAKE is enabled. + +- In `ssl_check_key_curve()` to get group ID + call `mbedtls_pk_ec()` + if certificates and ECDSA are enabled. + +- In `ssl_pick_cert()` + call `mbedtls_pk_can_do()` + if certificates are enabled. + +- In `ssl_write_encrypt_then_mac_ext()` + call `mbedtls_cipher_info_from_type()` on ciphersuite info + if EtM is enabled + +- In `ssl_write_ecjpake_kkpp_ext()` + call `mbedtls_ecjpake_write_round_one()` + if ECJPAKE is enabled. + +- In `ssl_get_ecdh_params_from_cert()` + call `mbedtls_pk_can_do()`, `mbedtls_pk_ec()` and `mbedtls_ecdh_get_params()` + if ECDH-RSA or ECDH-ECDSA is enabled, + in order to import own private key to ecdh context. + +- In `ssl_prepare_server_key_exchange()` + call `mbedtls_ecjpake_write_round_two()` + if ECJPAKE is enabled. + +- In `ssl_prepare_server_key_exchange()` + call `mbedtls_dhm_set_group()`, `mbedtls_dhm_make_params()` and `mbedtls_dhm_get_len()` + if DHE-RSA or DHE-PSK key exchange is enabled. + +- In `ssl_prepare_server_key_exchange()` + call `mbedtls_ecdh_setup()` and `mbedtls_ecdh_make_params()` + if ECDHE-RSA, ECDHE-ECDSA or ECDHE-PSK is enabled. + +- In `ssl_prepare_server_key_exchange()` + call `mbedtls_pk_sign()` from `ssl_prepare_server_key_exchange()` + if DHE-RSA, ECDHE-RSA or ECDHE-ECDSA is enabled. + +- In `ssl_parse_client_dh_public()` + call `mbedtls_dhm_read_public()` + if DHE-RSA or DHE-PSK is enabled. + +- In `ssl_decrypt_encrypted_pms()` + call `mbedtls_pk_get_len()`, `mbedtls_pk_can_do()` and `mbedtls_pk_decrypt()` + if RSA or RSA-PSK key exchange is enabled. + +- In `ssl_parse_client_key_exchange()` + call `mbedtls_dhm_calc_secret()` + if DHE-RSA enabled. + (Note: `ssl_parse_client_dh_public()` called first.) + +- In `ssl_parse_client_key_exchange()` + call `mbedtls_ecdh_read_public()` and `mbedtls_ecdh_calc_secret()` + if ECDHE-RSA, ECDHE-ECDSA, ECDH-RSA or ECDH-ECDSA enabled. + +- In `ssl_parse_client_key_exchange()` + call `mbedtls_ecdh_read_public()` + if ECDHE-PSK enabled. + (Note: calling `mbedtls_ssl_psk_derive_premaster()` afterwards.) + +- In `ssl_parse_client_key_exchange()` + call `mbedtls_ecjpake_read_round_two()` and `mbedtls_ecjpake_derive_secret()` + if ECJPAKE enabled. + +- In `ssl_parse_certificate_verify()` + call `mbedtls_pk_can_do()` and `mbedtls_pk_verify()` + if RSA, DHE-RSA, ECDH-RSA, ECDHE-RSA, ECDH-ECDSA or ECDHE-ECDSA enabled. + +### `ssl_tls.c` + +**Note:** This module is used both server-side and client-side. + +- In `tls_prf_generic()` + call `mbedtls_md_init()`, `mbedtls_md_info_from_type()`, `mbedtls_md_get_size()`, `mbedtls_md_setup()`, `mbedtls_md_hmac_starts()`, `mbedtls_md_hmac_update()`, `mbedtls_md_hmac_finish()`, `mbedtls_md_hmac_reset()` and `mbedtls_md_free()` + +- In `mbedtls_ssl_derive_keys()` + call `mbedtls_cipher_info_from_type()`, `mbedtls_cipher_setup_psa()` or `mbedtls_cipher_setup()`, `mbedtls_cipher_setkey()`, and `mbedtls_cipher_set_padding_mode()` + +- In `mbedtls_ssl_derive_keys()`. + call `mbedtls_md_info_from_type()`, `mbedtls_md_setup()`, `mbedtls_md_get_size()` and `mbedtls_md_hmac_starts()` + Note: should be only if CBC/NULL ciphersuites enabled, but is currently unconditional. + +- In `ssl_calc_verify_tls_sha256()` + call `mbedtls_sha256_init()` `mbedtls_sha256_clone()` `mbedtls_sha256_finish()` `mbedtls_sha256_free()` + if SHA256 is enabled. + +- In `ssl_calc_verify_tls_sha384()` + call `mbedtls_sha512_init()` `mbedtls_sha512_clone()` `mbedtls_sha512_finish()` `mbedtls_sha512_free()` + if SHA512 is enabled. + +- In `mbedtls_ssl_psk_derive_premaster()` + call `mbedtls_dhm_calc_secret()` + if DHE-PSK is enabled. + +- In `mbedtls_ssl_psk_derive_premaster()` + call `mbedtls_ecdh_calc_secret()` + if ECDHE-PSK is enabled. + +- In `ssl_encrypt_buf()` + call `mbedtls_cipher_get_cipher_mode()` `mbedtls_md_hmac_update()` `mbedtls_md_hmac_finish()` `mbedtls_md_hmac_reset()` `mbedtls_cipher_crypt()` + if CBC or NULL is enabled. + +- In `ssl_encrypt_buf()` + call `mbedtls_cipher_get_cipher_mode()`, `mbedtls_cipher_auth_encrypt()` + if GCM, CCM or CHACHAPOLY is enabled. + +- In `ssl_decrypt_buf()` + call `mbedtls_cipher_get_cipher_mode()` `mbedtls_md_hmac_update()` `mbedtls_md_hmac_finish()` `mbedtls_md_hmac_reset()` `mbedtls_cipher_crypt()` + if CBC and Encrypt-then-Mac +are enabled. + +- In `mbedtls_ssl_cf_hmac()` + call `mbedtls_md_clone()` + if CBC or NULL is enabled. + +- In `ssl_decrypt_buf()` + call `mbedtls_cipher_get_cipher_mode()`, `mbedtls_cipher_auth_decrypt()` + if GCM, CCM or CHACHAPOLY is enabled. + +- In `mbedtls_ssl_parse_certificate()` + call `mbedtls_pk_can_do()` and `mbedtls_pk_ec()` + to get and check group ID. + +- In `mbedtls_ssl_reset_checksum()`. + call `mbedtls_sha256_starts()` `mbedtls_sha512_starts()` + +- In `ssl_update_checksum_start()`. + call `mbedtls_sha256_update()` `mbedtls_sha512_update()` + +- In `ssl_update_checksum_sha256()` + call `mbedtls_sha256_update()` + if SHA256 is enabled. + +- In `ssl_update_checksum_sha512()` + call `mbedtls_sha512_update()` + if SHA512 is enabled. + +- In `ssl_calc_finished_tls_sha256()` + call `mbedtls_sha256_init()` `mbedtls_sha256_clone()` `mbedtls_sha256_finish()` `mbedtls_sha256_free()` + if SHA256 is enabled. + +- In `ssl_calc_finished_tls_sha512()` + call `mbedtls_sha512_init()` `mbedtls_sha512_clone()` `mbedtls_sha512_finish()` `mbedtls_sha512_free()` + if SHA512 is enabled. + +- In `ssl_handshake_params_init()`. + call `mbedtls_sha256_init()` `mbedtls_sha256_starts()` `mbedtls_sha512_init()` `mbedtls_sha512_starts()` `mbedtls_dhm_init()` `mbedtls_ecdh_init()` `mbedtls_ecjpake_init()` + +- In `ssl_transform_init()`. + call `mbedtls_cipher_init()` `mbedtls_md_init()` + +- In `mbedtls_ssl_set_hs_ecjpake_password()` + call `mbedtls_ecjpake_setup()` + if ECJPAKE is enabled. + +- In `mbedtls_ssl_conf_dh_param_bin()` + call `mbedtls_mpi_read_binary()` and `mbedtls_mpi_free()` + if DHM and SRV are enabled. + +- In `mbedtls_ssl_conf_dh_param_ctx()` + call `mbedtls_dhm_get_value()` and `mbedtls_mpi_free()` + if DHM and SRV are enabled. + +- In `mbedtls_ssl_get_record_expansion()`. + call `mbedtls_cipher_get_cipher_mode()` and `mbedtls_cipher_get_block_size()` + +- In `mbedtls_ssl_transform_free()`. + call `mbedtls_cipher_free()` and `mbedtls_md_free()` + +- In `mbedtls_ssl_handshake_free()`. + call `mbedtls_sha256_free()` `mbedtls_sha512_free()` `mbedtls_dhm_free()` `mbedtls_ecdh_free()` `mbedtls_ecjpake_free()` + +- In `mbedtls_ssl_config_free()` + call `mbedtls_mpi_free()` + if DHM is enabled. + +- In `mbedtls_ssl_sig_from_pk()`. + call `mbedtls_pk_can_do()` + +- In `mbedtls_ssl_get_key_exchange_md_tls1_2()` + call `mbedtls_md_info_from_type()` `mbedtls_md_get_size()` `mbedtls_md_init()` `mbedtls_md_setup()` `mbedtls_md_starts()` `mbedtls_md_update()` `mbedtls_md_update()` `mbedtls_md_finish()` `mbedtls_md_free()` diff --git a/docs/architecture/psa-migration/dependencies-x509.md b/docs/architecture/psa-migration/dependencies-x509.md new file mode 100644 index 000000000000..dfbff8304a68 --- /dev/null +++ b/docs/architecture/psa-migration/dependencies-x509.md @@ -0,0 +1,206 @@ +Dependencies of the X.509 library on the Crypto library +======================================================= + +This document is part of the technical study on how to port Mbed TLS to PSA +Crypto. It describes the dependencies of libmbedx509.a on libmbedcrypto.a. + +More precisely, it describes what functions from libmbedcrypto.a are called +from libmbedx509.a - other forms of dependencies such as using static inline +functions or types, accessing private struct members, etc., are not listed. + +It is based on Mbed TLS 3.0, excluding support for restartble ECP operations. + +Non-Crypto dependencies +----------------------- + +The X.509 library has a number of dependencies on libmbedcrypto.a that are not +cryptographic, hence are unlikely to be covered by the PSA Crypto API. + +These involve the following modules: + +- asn1 +- oid +- pem +- platform +- threading + +Crypto dependencies (high-level) +-------------------------------- + +The X.509 library depends on the following cryptographic modules: + +- pk +- md +- mpi +- sha1 + +More specifically, calls are made to the following API functions: + +``` +mbedtls_pk_can_do +mbedtls_pk_free +mbedtls_pk_get_bitlen +mbedtls_pk_get_name +mbedtls_pk_get_type +mbedtls_pk_load_file +mbedtls_pk_parse_subpubkey +mbedtls_pk_sign +mbedtls_pk_verify_ext +mbedtls_pk_write_pubkey +mbedtls_pk_write_pubkey_der + +mbedtls_md +mbedtls_md_get_name +mbedtls_md_get_size +mbedtls_md_info_from_type + +mbedtls_mpi_copy +mbedtls_mpi_free +mbedtls_mpi_init + +mbedtls_sha1 +``` + +Note: the dependency on MPI is because the certificate's serial number is +stored as an MPI in `struct mbedtls_x509write_cert` - the MPI is used purely +as a container for bytes. The depencency is embedded in the public API as +`mbedtls_x509write_crt_set_serial` take an argument of type `mbedtls_mpi *`. + +Note: the direct dependency on SHA1 is in `x509write_crt.c` and makes sense +because it's the only hash that can be used to compute key identifiers for the +Subject Key Identifier and Authority Key Identifier extensions. Replacing that +with an algorithm-agnistic API would or course be easy. + +File by file analysis +--------------------- + +The X.509 library consists of the following C files and associated headers: +``` +x509.c +x509_create.c +x509_crl.c +x509_crt.c +x509_csr.c +x509write_crt.c +x509write_csr.c +``` + +### `x509.c` + +- In `mbedtls_x509_sig_alg_gets()` + call `mbedtls_md_info_from_type()` and `mbedtls_md_get_name()` + to print out information + +### `x509_crl.c` + +- In `mbedtls_x509_crl_parse_file()` + call `mbedtls_pk_load_file()` + to load files if `MBEDTLS_FS_IO` defined + +### `x509_crt.c` + +**Note:** All calls to PK APIs in this file use public (not private) keys. + +- In `x509_profile_check_key()` + call `mbedtls_pk_get_type()` and `mbedtls_pk_get_bitlen()` + +- In `x509_profile_check_key()` + call `mbedtls_pk_ec()` + to get the group id + +- In `x509_crt_parse_der_core()` + call `mbedtls_pk_parse_subpubkey()` + +- In `mbedtls_x509_crt_parse_file()` + call `mbedtls_pk_load_file()` + to load files if `MBEDTLS_FS_IO` defined + +- In `mbedtls_x509_crt_info()` + call `mbedtls_pk_get_name()` and `mbedtls_pk_get_bitlen()` + to print out information + +- In `x509_crt_verifycrl()` + call `mbedtls_md_info_from_type()`, `mbedtls_md()`, `mbedtls_pk_verify_ext()` and `mbedtls_md_get_size()` + to verify CRL signature + +- In `x509_crt_check_signature()` + call `mbedtls_md_info_from_type()`, `mbedtls_md_get_size()`, `mbedtls_md()`, then `mbedtls_pk_can_do()` and `mbedtls_pk_verify_ext()` + to verify certificate signature + +- In `x509_crt_verify_restartable_ca_cb()` + call `mbedtls_pk_get_type()` + to check against profile + +- In `mbedtls_x509_crt_free()` + call `mbedtls_pk_free()` + +### `x509_csr.c` + +**Note:** All calls to PK APIs in this file use public (not private) keys. + +- In `mbedtls_x509_csr_parse_der()` + call `mbedtls_pk_parse_subpubkey()` + +- In `mbedtls_x509_csr_parse_file()` + call `mbedtls_pk_load_file()` + to load files if `MBEDTLS_FS_IO` defined + +- In `mbedtls_x509_csr_info()` + call `mbedtls_pk_get_name()` and `mbedtls_pk_get_bitlen()` + to print out information + +- In `mbedtls_x509_csr_free()` + call `mbedtls_pk_free()` + +### `x509_create.c` + +No call to crypto functions - mostly ASN.1 writing and data conversion. + +### `x509write_crt.c` + +**Note:** Calls to PK APIs in this file are both on public and private keys. + +- In `mbedtls_x509write_crt_init()`, resp. `mbedtls_x509write_crt_free()` + call `mbedtls_mpi_init()`, resp. `mbedtls_mpi_free()` + to manage the serial number + +- In `mbedtls_x509write_crt_set_serial()` + call `mbedtls_mpi_copy()` + +- In `mbedtls_x509write_crt_set_subject_key_identifier()` and `mbedtls_x509write_crt_set_authority_key_identifier()` + call `mbedtls_pk_write_pubkey()` and `mbedtls_sha1_ret()` + +- In `mbedtls_x509write_crt_der()` + call `mbedtls_pk_can_do()` + on a private key (issuer) + to write out correct signature algorithm + +- In `mbedtls_x509write_crt_der()` + call `mbedtls_pk_write_pubkey_der()` + on a public key (subject) + +- In `mbedtls_x509write_crt_der()` + call `mbedtls_md_info_from_type()` and `mbedtls_md()` + to prepare for signing + +- In `mbedtls_x509write_crt_der()` + call `mbedtls_pk_sign()` + on a private key (issuer) + to sign certificate being issued + +### `x509write_csr.c` + +**Note:** All calls for PK APIs in this file are on private (not public) keys + +- In `mbedtls_x509write_csr_der()` + call `mbedtls_pk_write_pubkey_der()` + +- In `mbedtls_x509write_csr_der()` + call `mbedtls_md_info_from_type()` and `mbedtls_md()` + +- In `mbedtls_x509write_csr_der()` + call `mbedtls_pk_sign()` + +- Call `mbedtls_pk_can_do()` + on a private key (writer's) + to write out correct signature algorithm diff --git a/docs/architecture/psa-migration/syms.sh b/docs/architecture/psa-migration/syms.sh new file mode 100755 index 000000000000..5c34b28d1a9c --- /dev/null +++ b/docs/architecture/psa-migration/syms.sh @@ -0,0 +1,58 @@ +#!/bin/sh +# +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Purpose +# +# Show symbols in the X.509 and TLS libraries that are defined in another +# libmbedtlsXXX.a library. This is usually done to list Crypto dependencies. +# +# Usage: +# - build the library with debug symbols and the config you're interested in +# (default, full minus MBEDTLS_USE_PSA_CRYPTO, full, etc.) +# - run this script with the name of your config as the only argument + +set -eu + +# list mbedtls_ symbols of a given type in a static library +syms() { + TYPE="$1" + FILE="$2" + + nm "$FILE" | sed -n "s/[0-9a-f ]*${TYPE} \(mbedtls_.*\)/\1/p" | sort -u +} + +# create listings for the given library +list() { + NAME="$1" + FILE="library/libmbed${NAME}.a" + PREF="${CONFIG}-$NAME" + + syms '[TRrD]' $FILE > ${PREF}-defined + syms U $FILE > ${PREF}-unresolved + + diff ${PREF}-defined ${PREF}-unresolved \ + | sed -n 's/^> //p' > ${PREF}-external + sed 's/mbedtls_\([^_]*\).*/\1/' ${PREF}-external \ + | uniq -c | sort -rn > ${PREF}-modules + + rm ${PREF}-defined ${PREF}-unresolved +} + +CONFIG="${1:-unknown}" + +list x509 +list tls From 1b52d0949412d4a5ba63f936dfa7e77431eb3b4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 29 Sep 2021 12:28:57 +0200 Subject: [PATCH 02/21] Document test strategy for USE_PSA_CRYPTO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note: removed `mbedtls_x509write_crt_set_subject_key()` from the list of things that should be tested, as it's taking public key rather than a keypair. Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/testing.md | 95 ++++++++++++++++++++++ docs/use-psa-crypto.md | 7 +- 2 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 docs/architecture/psa-migration/testing.md diff --git a/docs/architecture/psa-migration/testing.md b/docs/architecture/psa-migration/testing.md new file mode 100644 index 000000000000..754686b404f1 --- /dev/null +++ b/docs/architecture/psa-migration/testing.md @@ -0,0 +1,95 @@ +Testing strategy for `MBEDTLS_USE_PSA_CRYPTO` +============================================= + +This document records the testing strategy used so far in implementing +`MBEDTLS_USE_PSA_CRYPTO`. + + +General considerations +---------------------- + +There needs to be at least one build in `all.sh` that enables +`MBEDTLS_USE_PSA_CRYPTO` and runs the full battery of tests. Currently that's +ensured by the fact that `scripts/config.py full` enables +`MBEDTLS_USE_PSA_CRYPTO`. + +Generally, code review is enough to ensure that PSA APIs are indeed used where +they should be when `MBEDTLS_USE_PSA_CRYPTO` is enabled. + +However, when it comes to TLS, we also have the option of using debug messages +to confirm which code path is taken. This is generaly un-necessary, except when +a decision is made at run-time about whether to use the PSA or legacy code +path. For example, for record protection, currently some ciphers are supported +via PSA while some others aren't, with a run-time fallback. In this case, it's +good to have a debug message checked by the test case to confirm that the +right decision was made at run-time, i. e. that we didn't use the fallback for +ciphers that are supposed to be supported. + + +New APIs meant for application use +---------------------------------- + +For example, `mbedtls_pk_setup_opaque()` is meant to be used by applications +in order to create PK contexts that can then be passed to existing TLS and +X.509 APIs (which remain unchanged). + +In that case, we want: + +- unit testing of the new API and directly-related APIs - for example: + - in `test_suite_pk` we have a new test function `pk_psa_utils` that exercises + `mbedtls_pk_setup_opaque()` and checks that various utility functions + (`mbedtls_pk_get_type()` etc.) work and the functions that are expected to + fail (`mbedtls_pk_verify()` etc) return the expected error. + - in `test_suite_pk` we modified the existing `pk_psa_sign` test function to + check that signature generation works as expected + - in `test_suite_pkwrite` we should have a new test function checking that + exporting (writing out) the public part of the key works as expected and + that exporting the private key fails as expected. +- integration testing of the new API with each existing API which should + accepts a context created this way - for example: + - in `programs/ssl/ssl_client2` a new option `key_opaque` that causes the + new API to be used, and one or more tests in `ssl-opt.sh` using that. + (We should have the same server-side.) + - in `test_suite_x509write` we have a new test function + `x509_csr_check_opaque()` checking integration of the new API with the + existing `mbedtls_x509write_csr_set_key()`. + (We should have something similar for + `mbedtls_x509write_crt_set_issuer_key()`.) + +For some APIs, for example with `mbedtls_ssl_conf_psk_opaque()`, unit testing +does not make sense, so we only have integration testing. + +New APIs meant for internal use +------------------------------- + +For example, `mbedtls_cipher_setup_psa()` is meant to be used by the TLS +layer, but probably not directly by applications. + +In that case, we want: + +- unit testing of the new API and directly-related APIs - for example: + - in `test_suite_cipher`, the existing test functions `auth_crypt_tv` and + `test_vec_crypt` gained a new parameter `use_psa` and corresponding test + cases +- integration testing: + - usually already covered by existing tests for higher-level modules: + - for example simple use of `mbedtls_cipher_setup_psa()` in TLS is already + covered by running the existing TLS tests in a build with + `MBEDTLS_USA_PSA_CRYPTO` enabled + - however if use of the new API in higher layers involves more logic that + use of the old API, specific integrations test may be required + - for example, the logic to fall back from `mbedtls_cipher_setup_psa()` to + `mbedtls_cipher_setup()` in TLS is tested by `run_test_psa` in + `ssl-opt.sh`. + +Internal changes +---------------- + +For example, use of PSA to compute the TLS 1.2 PRF. + +Changes in this category rarely require specific testing, as everything should +be already be covered by running the existing tests in a build with +`MBEDTLS_USE_PSA_CRYPTO` enabled. + +However, if additional logic is involved, or there are run-time decisions about +whether to use the PSA or legacy code paths, specific tests might be in order. diff --git a/docs/use-psa-crypto.md b/docs/use-psa-crypto.md index 6ec2dcaa1b85..1f554e5f4d4b 100644 --- a/docs/use-psa-crypto.md +++ b/docs/use-psa-crypto.md @@ -60,10 +60,9 @@ this is supported on both sides, it's currently only tested client-side); - `mbedtls_x509write_csr_set_key()` to generate a CSR (certificate signature request). -In the TLS and X.509 API, there are two other functions which accept a key or -keypair as a PK context: `mbedtls_x509write_crt_set_subject_key()` and -`mbedtls_x509write_crt_set_issuer_key()`. Use of opaque contexts here probably -works but is so far untested. +In the TLS and X.509 API, there's one other function which accepts a keypair +as a PK context: `mbedtls_x509write_crt_set_issuer_key()`. Use of opaque +contexts here probably works but is so far untested. ### PSA-held (opaque) keys for TLS pre-shared keys (PSK) From b89fd9514637b40814b5b8b86798ea1935c0993e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 30 Sep 2021 11:52:04 +0200 Subject: [PATCH 03/21] Document the general strategy for PSA migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/strategy.md | 256 ++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 docs/architecture/psa-migration/strategy.md diff --git a/docs/architecture/psa-migration/strategy.md b/docs/architecture/psa-migration/strategy.md new file mode 100644 index 000000000000..52819acb9ec2 --- /dev/null +++ b/docs/architecture/psa-migration/strategy.md @@ -0,0 +1,256 @@ +This document explains the strategy that was used so far in starting the +migration to PSA Crypto and mentions future perspectives and open questions. + +Goals +===== + +Several benefits are expected from migrating to PSA Crypto: + +G1. Take advantage of the PSA Crypto driver interface. +G2. Allow isolation of long-term secrets (for example, private keys). +G3. Allow isolation of short-term secrets (for example, TLS sesssion keys). +G4. Have a clean, unified API for Crypto (retire the legacy API). + +Currently, some parts of (G1) and (G2) are implemented when +`MBEDTLS_USE_PSA_CRYPTO` is enabled. For (G2) to take effect, the application +needs to be changed to use new APIs. + +Generally speaking, the numbering above doesn't mean that each goal requires +the preceding ones to be completed - for example it would be possible to +start or even complete (G4) before (G3) is even started. However, (G2) and (G3) +require operations to be done via the PSA Crypto API, which is mostly what (G1) +is about. Also, we can't retire the legacy API (G4) until we no longer rely on +it, which again is mostly (G1). + +So, a solid intermediate goal would be to complete (G1) when +`MBEDTLS_USA_PSA_CRYPTO` is enabled - that is, all crypto operations in X.509 +and TLS would be done via the PSA Crypto API. + +Compile-time options +==================== + +We currently have two compile-time options that are relevant to the migration: + +- `MBEDTLS_PSA_CRYPTO_C` - enabled by default, controls the presence of the PSA + Crypto APIs. +- `MBEDTLS_USE_PSA_CRYPTO` - disabled by default (enabled in "full" config), + controls usage of PSA Crypto APIs to perform operations in X.509 and TLS +(G1 above), as well as the availability of some new APIs (G2 above). + +The reason why `MBEDTLS_USE_PSA_CRYPTO` is optional, and disabled by default, +is mostly to avoid introducing a hard (or even default) dependency of X509 and +TLS and `MBEDTLS_PSA_CRYPTO_C`. This is mostly reasons of code size, and +historically concerns about the maturity of the PSA code (which we might want +to re-evaluate). + +The downside of this approach is that until we feel ready to make +`MBDEDTLS_USE_PSA_CRYPTO` non-optional (always enabled), we have to maintain +two versions of some parts of the code: one using PSA, the other using the +legacy APIs. However, see next section for strategies that can lower that +cost. + +Taking advantage of the existing abstractions layers - or not +============================================================= + +The Crypto library in Mbed TLS currently has 3 abstraction layers that offer +algorithm-agnostic APIs for a class of algorithms: + +- MD for messages digests aka hashes (including HMAC) +- Cipher for symmetric ciphers (included AEAD) +- PK for asymmetric (aka public-key) cryptography (excluding key exchange) + +Note: key exchange (FFDH, ECDH) is not covered by an abstraction layer. + +These abstraction layers typically provide, in addition to the API for crypto +operations, types and numerical identifiers for algorithms (for +example `mbedtls_cipher_mode_t` and its values). The +current strategy is to keep using those identifiers in most of the code, in +particular in existing structures and public APIs, even when +`MBEDTLS_USE_PSA_CRYPTO` is enabled. (This is not an issue for G1, G2, G3 +above, and is only potentially relevant for G4.) + +The are multiple strategies that can be used regarding the place of those +layers in the migration to PSA. + +Silently call to PSA from the abstraction layer +----------------------------------------------- + +- Provide a new definition (conditionally on `USE_PSA_CRYPTO`) of wrapper + functions in the abstraction layer, that calls PSA instead of the legacy +crypto API. +- Upside: changes contained to a single place, no need to change TLS or X.509 + code anywhere. +- Downside: tricky to implement if the PSA implementation is currently done on + top of that layer (dependency loop). + +This strategy is currently used for ECDSA signature verification in the PK +layer, and could be extended to all operations in the PK layer. + +This strategy is not very well suited to the Cipher and MD layers, as the PSA +implementation is currently done on top of those layers. + +Replace calls for each operation +-------------------------------- + +- For every operation that's done through this layer in TLS or X.509, just + replace function call with calls to PSA (conditionally on `USE_PSA_CRYPTO`) +- Upside: conceptually simple, and if the PSA implementation is currently done + on top of that layer, avoids concerns about dependency loops. +- Downside: TLS/X.509 code has to be done for each operation. + +This strategy is currently used for the MD layer. (Currently only a subset of +calling places, but could be extended to all of them.) + +Opt-in use of PSA from the abstraction layer +-------------------------------------------- + +- Provide a new way to set up a context that causes operations on that context + to be done via PSA. +- Upside: changes mostly contained in one place, TLS/X.509 code only needs to + be changed when setting up the context, but not when using it. In + particular, no changes to/duplication of existing public APIs that expect a + key to be passed as a context of this layer (eg, `mbedtls_pk_context`). +- Upside: avoids dependency loop when PSA implemented on top of that layer. +- Downside: when the context is typically set up by the application, requires + changes in application code. + +There are two variants of this strategy: one where using the new setup +function also allows for key isolation (the key is only held by PSA, +supporting both G1 and G2 in that area), and one without isolation (the key is +still stored outsde of PSA most of the time, supporting only G1). + +This strategy, with support for key isolation, is currently used for ECDSA +signature generation in the PK layer - see `mbedtls_pk_setup_opaque()`. This +allows use of PSA-held private ECDSA keys in TLS and X.509 with no change to +the TLS/X.509 code, but a contained change in the application. If could be +extended to other private key operations in the PK layer. + +This strategy, without key isolation, is also currently used in the Cipher +layer - see `mbedtls_cipher_setup_psa()`. This allows use of PSA for cipher +operations in TLS with no change to the application code, and a +contained change in TLS code. (It currently only supports a subset of ciphers, +but could easily be extended to all of them.) + +Note: for private key operations in the PK layer, both the "silent" and the +"opt-in" strategy can apply, and can complement each other, as one provides +support for key isolation, but at the (unavoidable) code of change in +application code, while the other requires no application change to get +support for drivers, but fails to provide isolation support. + +Migrating away from the legacy API +================================== + +This section briefly introduces questions and possible plans towards G4, +mainly as they relate to choices in previous stages. + +The role of the PK/Cipher/MD APIs in user migration +--------------------------------------------------- + +We're currently taking advantage of the existing PK and Cipher layers in order +to reduce the number of places where library code needs to be changed. It's +only natural to consider using the same strategy (with the PK, MD and Cipher +layers) for facilitating migration of application code. + +Note: a necessary first step for that would be to make sure PSA is no longer +implemented of top of the concerned layers + +### Zero-cost compatibility layer? + +The most favourable case is if we can have a zero-cost abstraction (no +runtime, RAM usage or code size penalty), for example just a bunch of +`#define`s, essentialy mapping `mbedtls_` APIs to their `psa_` equivalent. + +Unfortunately that's unlikely fully work. For example, the MD layer uses the +same context type for hashes and HMACs, while the PSA API (rightfully) has +distinct operation types. Similarly, the Cipher layer uses the same context +type for unauthenticated and AEAD ciphers, which again the PSA API +distinguishes. + +It is unclear how much value, if any, a zero-cost compatibility layer that's +incomplete (for example, for MD covering only hashes, or for Cipher covering +only AEAD) or differs significantly from the existing API (for example, +introducing new context types) would provide to users. + +### Low-cost compatibility layers? + +Another possibility is to keep most or all of the existing API for the PK, MD +and Cipher layers, implemented on top of PSA, aiming for the lowest possible +cost. For example, `mbedtls_md_context_t` would be defined as a (tagged) union +of `psa_hash_operation_t` and `psa_mac_operation_t`, then `mbedtls_md_setup()` +would initialize the correct part, and the rest of the functions be simple +wrappers around PSA functions. This would vastly reduce the complexity of the +layers compared to the existing (no need to dispatch through function +pointers, just call the corresponding PSA API). + +Since this would still represent a non-zero cost, not only in terms of code +size, but also in terms of maintainance (testing, etc.) this would probably +be a temporary solution: for example keep the compatibility layers in 4.0 (and +make them optional), but remove them in 5.0. + +Again, this provides the most value to users if we can manage to keep the +existing API unchanged. Their might be conflcits between this goal and that of +reducing the cost, and judgment calls may need to be made. + +Note: when it comes to holding public keys in the PK layer, depending on how +the rest of the code is structured, it may be worth holding the key data in +memory controlled by the PK layer as opposed to a PSA key slot, moving it to a +slot only when needed (see current `ecdsa_verify_wrap` when +`MBEDTLS_USE_PSA_CRYPTO` is defined) For example, when parsing a large +number, N, of X.509 certificates (for example the list of trusted roots), it +might be undesirable to use N PSA key slots for their public keys as long as +the certs are loaded. OTOH, this could also be addressed by merging the "X.509 +parsing on-demand" (#2478), and then the public key data would be held as +bytes in the X.509 CRT structure, and only moved to a PK context / PSA slot +when it's actually used. + +Note: the PK layer actually consists of two relatively distinct parts: crypto +operations, which will be covered by PSA, and parsing/writing (exporting) +from/to various formats, which is currently not fully covered by the PSA +Crypto API. + +### Algorithm identifiers and other identifiers + +It should be easy to provide the user with a bunch of `#define`s for algorithm +identifiers, for example `#define MBEDTLS_MD_SHA256 PSA_ALG_SHA_256`; most of +those would be in the MD, Cipher and PK compatibility layers mentioned above, +but there might be some in other modules that may be worth considering, for +example identifiers for elliptic curves. + +### Lower layers + +Generally speaking, we would retire all of the low-level, non-generic modules, +such as AES, SHA-256, RSA, DHM, ECDH, ECP, bignum, etc, without providing +compatibility APIs for them. People would be encouraged to switch to the PSA +API. (The compatiblity implementation of the existing PK, MD, Cipher APIs +would mostly benefit people who already used those generic APis rather than +the low-level, alg-specific ones.) + +### APIs in TLS and X.509 + +Public APIs in TLS and X.509 may be affected by the migration in at least two +ways: + +1. APIs that rely on a legacy `mbedtls_` crypto type: for example + `mbedtls_ssl_conf_own_cert()` to configure a (certificate and the +associated) private key. Currently the private key is passed as a +`mbedtls_pk_context` object, which would probably change to a `psa_key_id_t`. +Since some users would probably still be using the compatibility PK layer, it +would need a way to easily extract the PSA key ID from the PK context. + +2. APIs the accept list of identifiers: for example + `mbedtls_ssl_conf_curves()` taking a list of `mbedtls_ecp_group_id`s. This +could be changed to accept a list of pairs (`psa_ecc_familiy_t`, size) but we +should probably take this opportunity to move to a identifier independant from +the underlying crypto implementation and use TLS-specific identifiers instead +(based on IANA values or custom enums), as is currently done in the new +`mbedtls_ssl_conf_groups()` API, see #4859). + +Testing +------- + +An question that needs careful consideration when we come around to removing +the low-level crypto APIs and making PK, MD and Cipher optional compatibility +layers is to be sure to preserve testing quality. A lot of the existing test +cases use the low level crypto APIs; we would need to either keep using that +API for tests, or manually migrated test to the PSA Crypto API. Perhaps a +combination of both, perhaps evolving gradually over time. From d9edd56bf802aedb8217c4b36c3f1231bff13913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 30 Sep 2021 15:05:01 +0200 Subject: [PATCH 04/21] Document PSA limitations that could be problems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (WIP: the study of RSA-PSS is incomplete.) Signed-off-by: Manuel Pégourié-Gonnard --- .../psa-migration/psa-limitations.md | 224 ++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 docs/architecture/psa-migration/psa-limitations.md diff --git a/docs/architecture/psa-migration/psa-limitations.md b/docs/architecture/psa-migration/psa-limitations.md new file mode 100644 index 000000000000..05a4d54a2728 --- /dev/null +++ b/docs/architecture/psa-migration/psa-limitations.md @@ -0,0 +1,224 @@ +This document lists current limitations of the PSA Crypto API (as of version +1.1) that may impact our ability to (1) use it for all crypto operations in +TLS and X.509 and (2) support isolation of all long-term secrets in TLS (that +is, goals G1 and G2 in [strategy.md][] in the same directory). + +This is supposed to be a complete list, based on a exhaustive review of crypto +operations done in TLS and X.509 code, but of course it's still possible that +subtle-but-important issues have been missed. The only way to be really sure +is, of course, to actually do the migration work. + +Limitations relevant for G1 (performing crypto operations) +========================================================== + +Restartable ECC operations +-------------------------- + +There is currently no support for that in PSA at all. API design, as well as +implementation, would be non-trivial. + +Currently, `MBEDTLS_USE_PSA_CRYPTO` is simply incompatible with +`MBEDTLS_ECP_RESTARTABLE`. + +Arbitrary parameters for FFDH +----------------------------- + +Currently, the PSA Crypto API can only perform FFDH with a limited set of +well-know parameters (some of them defined in the spec, but implementations +are free to extend that set). + +TLS 1.2 (and earlier) on the other hand have the server send explicit +parameters (P and G) in is ServerKeyExchange message. This has been found to +be suboptimal for security, as it is prohibitively hard for the client to +verify the strength of these parameters. This led to the development of RFC +7919 which allows use of named groups in TLS 1.2 - however as this is only an +extension, servers can still send custom parameters if they don't support the +extension. + +In TLS 1.3 the situation will be simpler: named groups are the only +option, so the current PSA Crypto API is a good match for that. (Not +coincidentally, the groups used by RFC 7919 and TLS 1.3 are part those defined +in the specification.) + +There are several options here: + +1. Implement support for custom FFDH parameters in PSA Crypto: this would pose + non-trivial API design problem, but most importantly seems backwards, as +the crypto community is moving away from custom FFDH parameters. +2. Drop the DHE-RSA and DHE-PSK key exchanges in TLS 1.2 when moving to PSA. +3. Implement RFC 7919, support DHE-RSA and DHE-PSK only in conjunction with it + when moving to PSA. We can modify our server so that it only selects a DHE + ciphersuite if the client offered name FFDH groups; unfortunately +client-side the only option is to offer named groups and break the handshake +if the server didn't take on our offer. This is not fully satisfying, but is +perhaps the least unsatisfying option in terms of result; it's also probably +the one that requires the most work, but it would deliver value beyond PSA +migration by implementing RFC 7919. + +RSA-PSS parameters +------------------ + +RSA-PSS signatures are defined by PKCS#1 v2, re-published as RFC 8017 +(previously RFC 3447). + +As standardized, the signature scheme takes several parameters, in addition to +the hash algorithm potentially used to hash the message being signed: +- a hash algorithm use for the encoding function +- a mask generation function + - most commonly MGF1, which in turn is parametrized by a hash algorithm +- a salt length + +Both the existing `mbedtls_` API and the PSA API support only MGF1 as the +generation function, but there are discrepancy in handling the salt length and +which of the various hash algorithms can differ from each other. + +### API comparison + +- RSA: + - signature: `mbedtls_rsa_rsassa_pss_sign()` + - message hashed externally + - encoding hash = MGF1 hash (from context, or argument = message hash) + - salt length: always using the maximum legal value + - signature: `mbedtls_rsa_rsassa_pss_sign_ext()` + - message hashed externally + - encoding hash = MGF1 hash (from context, or argument = message hash) + - salt length: specified explicitly + - verification: `mbedtls_rsassa_pss_verify()` + - message hashed externally + - encoding hash = MGF1 hash (from context, or argument = message hash) + - salt length: any valid length accepted + - verification: `mbedtls_rsassa_pss_verify_ext()` + - message hashed externally + - encoding hash = MGF1 hash from dedicated argument + - expected salt length: specified explicitly, can specify "ANY" +- PK: + - signature: not supported + - verification: `mbedtls_pk_verify_ext()` + - message hashed externally + - encoding hash = MGF1 hash, specified explicitly + - expected salt length: specified explicitly, can specify "ANY" +- PSA: + - algorithm specification: + - hash alg used for message hashing, encoding and MGF1 + - salt length cannot be specified + - signature generation: + - salt length: always using the maximum legal value + - verification: + - salt length: any valid length accepted + +The RSA/PK API is in principle more flexible than the PSA Crypto API. The +following sub-sections study whether and how this matters in practice. + +### Use in X.509 + +RFC 4055 Section 3.1 defines the encoding of RSA-PSS that's used in X.509. +It allows independently specifying the message hash (also used for encoding +hash), the MGF (and its hash if MGF1 is used), and the salt length (plus an +extra parameter "trailer field" that doesn't vary in practice"). These can be +encoded as part of the key, and of the signature. If both encoding are +presents, all values must match except possibly for the salt length, where the +value from the signature parameters is used. + +In Mbed TLS, RSA-PSS parameters can be parsed and displayed for various +objects (certificates, CRLs, CSRs). During parsing, the following properties +are enforced: +- (the extra "trailer field" parameter must has its default value) +- the mask generation function is MGF1 +- encoding hash = message hashing algorithm (may differ from MGF1 hash) + +When it comes to cryptographic operations, only two things are supported: +- verifying the signature on a certificate from its parent; +- verifying the signature on a CRL from the issuing CA. + +The verification is done using `mbedtls_pk_verify_ext()`. + +Note: since X.509 parsing ensures that message hash = encoding hash, and +`mbedtls_pk_verify_ext()` use encoding hash = mgf1 hash, it looks like all +three hash algorithms must be equal, which would be good news as it would +match a limitation of the PSA API. (TODO: double-check that.) + +Also, since we only use signature verification, the fact that PSA accepts any +valid salt length means that no valid certificate would be wrongly rejected; +however it means that signatures that don't match the announced salt length +would be incorrectly accepted. At first glance, it looks like this doesn't +allow an attacker to forge certificates, so this might be acceptable in +practice, while not fully implementing all the checks in the standard. (TODO: +triple-check that.) + +It is unclear what parameters people use in practice. + +### Use in TLS + +In TLS 1.2 (or lower), RSA-PSS signatures are never used, except via X.509. + +In TLS 1.3, RSA-PSS signatures can be used directly in the protocol (in +addition to indirect use via X.509). It has two sets of three signature +algorithm identifiers (for SHA-256, SHA-384 and SHA-512), depending of what +the OID of the public key is (rsaEncryption or RSASSA-PSS). + +In both cases, it specifies that: +- the mask generation function is MGF1 +- all three hashes are equal +- the length of the salt MUST be equal to the length of the digest algorithm + +When signing, the salt length picked by PSA is the one required by TLS 1.3 +(unless the key is unreasonably small). + +When verifying signatures, again is doesn't look like accepting any salt +length would give an attacker any advantage, but this must be triple-checked +(TODO). + +### Current testing - X509 + +TODO: look at the parameters used by the various test files + +- server9.crt + -HASH + -badsign + -defaults + -bad-saltlen + -bad-mgfhash +- crl-rsa-pss-HASH.pem +- server9.req.HASH + +### Possible course of actions + +TODO - once the previous section has been completed + +Limitations relevant for G2 (isolation of long-term secrets) +============================================================ + +Custom key derivations for mixed-PSK handshake +---------------------------------------------- + +Currently, `MBEDTLS_USE_PSA_CRYPTO` enables the new configuration function +`mbedtls_ssl_conf_psk_opaque()` which allows a PSA-held key to be used for the +(pure) `PSK` key exchange in TLS 1.2. This requires that the derivation of the +Master Secret (MS) be done on the PSA side. To support this, an algorithm +family `PSA_ALG_TLS12_PSK_TO_MS(hash_alg)` was added to PSA Crypto. + +If we want to support key isolation for the "mixed PSK" key exchanges: +DHE-PSK, RSA-PSK, ECDHE-PSK, where the PSK is concatenated with the result of +a DH key agreement (resp. RSA decryption) to form the pre-master secret (PMS) +from which the MS is derived. If the value of the PSK is to remain hidden, we +need the derivation PSK + secondary secret -> MS to be implemented as an +ad-hoc PSA key derivation algorithm. + +Adding this new, TLS-specific, key derivation algorithm to PSA Crypto should +be no harder than it was to add `PSA_ALG_TLS12_PSK_TO_MS()` but still requires +an extension to PSA Crypto. + +Note: looking at RFCs 4279 and 5489, it appears that the structure of the PMS +is always the same: 2-byte length of the secondary secret, secondary secret, +2-byte length of the PSK, PSK. So, a single key derivation algorithm should be +able to cover the 3 key exchanges DHE-PSK, RSA-PSK and ECDHE-PSK. (That's a +minor gain: adding 3 algorithms would not be a blocker anyway.) + +Note: if later we want to also isolate short-term secret (G3), the "secondary +secret" (output of DHE/ECDHE key agreement or RSA decryption) could be a +candidate. This wouldn't be a problem as the PSA key derivation API always +allows inputs from key slots. (Tangent: the hard part in isolating the result +of RSA decryption would be still checking that is has the correct format: +48 bytes, the first two matching the TLS version - note that this is timing +sensitive.) + From b902164cf0e5786926a891da46b8a0daef0d71fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Fri, 1 Oct 2021 13:16:01 +0200 Subject: [PATCH 05/21] Add temporary list of tasks for G1 and G2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Work in progress, some tasks have very explicit definitions and details on how to execute, others much less so; some may need splitting. These documents are temporary anyway, to give a rough idea of the work remaining to reach those goals (both of which we started, but only for some use case so far). Ultimately the result will be actionable and estimated tasks on github. Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/tasks-g1.md | 152 ++++++++++++++++++++ docs/architecture/psa-migration/tasks-g2.md | 80 +++++++++++ 2 files changed, 232 insertions(+) create mode 100644 docs/architecture/psa-migration/tasks-g1.md create mode 100644 docs/architecture/psa-migration/tasks-g2.md diff --git a/docs/architecture/psa-migration/tasks-g1.md b/docs/architecture/psa-migration/tasks-g1.md new file mode 100644 index 000000000000..599a11d3dbd6 --- /dev/null +++ b/docs/architecture/psa-migration/tasks-g1.md @@ -0,0 +1,152 @@ +This document is temporary; it lists tasks to achieve G1 as described in +`strategy.md` while the strategy is being reviewed - once that's done, +corresponding github issues will be created and this document removed. + +For all of the tasks here, no specific testing is expected to be required, +beyond passing the existing tests in a build with `MBEDTLS_USE_PSA_ENABLED`, +see `testing.md`. + +Symmetric crypto +================ + +Hashes +------ + +### Use `psa_hash` in all of X.509 + +Conditionally on `MBEDTLS_USE_PSA_CRYPTO`, replace all remaining calls to +`mbedtls_md()` or `mbedtls_sha1_ret()` by calls `psa_hash` functions, namely: +- replace `mbedtls_md()` in `x509_crt_verifycrl()` in `x509_crt.c` +- replace `mbedtls_md()` in `mbedtls_x509write_crt_der()` in `x509write_crt.c` +- replace `mbedtls_sha1_ret() in + `mbedtls_x509write_crt_set_subject_key_identifier()` in `x509write_crt.c` +- replace `mbedtls_sha1_ret() in + `mbedtls_x509write_crt_set_authority_key_identifier()` in `x509write_crt.c` +- already done in `x509_crt_check_signature()` in `x509_crt.c`, but might + want to replace multi-part with single-part. +- already done in `mbedtls_x509write_csr_der_internal()` in + `x509write_csr.c`, but might want to replace multi-part with single-part. + +HMAC +---- + +### Variable-time HMAC in TLS record protection + +- This is about the calls to `mbedtls_md_hmac_xxx()` in +`mbedtls_ssl_decrypt_buf()` and `mbedtls_ssl_encrypt_buf()`, but excludes the +call in `mbedtls_ssl_cf_hmad()` (which it its own task). +- Might need to change the `transform` structure to hold a PSA context instead + of an MD context. Note: might keep the MD context in parallel until the +constant-time part is done as well. + +TODO: study this better so it can be estimated. + +### Constant-time HMAC in TLS record protection + +This is `mbedtls_ssl_cf_hmac()`. The PSA code might look a bit different as +we'll probably need to store the HMAC key somewhere and compute the ipad/opad +explicitly instead of using (the internals of) the MD layers for that. + +TODO: study this better so it can be estimated. + +Ciphers +------- + +### Use PSA for all cipher operations in TLS + +- extend existing `mbedtls_cipher_setup_psa()` and related code to support + other ciphers than AES that can be used in TLS: ARIA (depends on #4959), +Camellia, ChachaPoly. +- extend unit-testing in `test_suite_cipher` to test those new ciphers as + AES-based cipher are already tested +- remove the fallback mechanism in all places where `cipher_setup_psa()` is + called from TLS code +- expand use of `run_test_psa()` in `ssl-opt.sh` + +Asymmetric crypto +================= + +ECDSA +----- + +### Make `mbedtls_pk_sign()` use PSA for ECDSA operations + +- This is already done with `PK_OPAQUE` contexts, but this task is about doing +it for regulard `ECKEY`/`ECDSA` contexts. +- May share some code (transcoding) with the exist support for `PK_OPAQUE` + contexts + +RSA signature (and verification) +-------------------------------- + +### Make `mbedtls_pk_sign()` use PSA for RSA operations + +- with regular `PK_RSA` context +- only PKCS#1 v1.5 for this task +- similar to what's done for ECDSA, except no need for transcoding (I think) + +### Make `mbedtls_pk_verify()` use PSA for RSA operations + +- with regular `PK_RSA` context +- only PKCS#1 v1.5 for this task +- similar to what's done for ECDSA, except no need for transcoding (I think) + +### Make `mbedtls_pk_verify_ext()` use PSA for RSA operations + +- with regular `PK_RSA` context +- this is for RSA-PSS +- similar to what's done for ECDSA, except no need for transcoding (I think) +- acceptable to enforce that all hashes are equal in the parameters (as + imposed by the PSA API) and reject the signature otherwise +- then need to check if all X.509 tests still pass, and if some don't, make + them depend on `!MBEDTLS_USE_PSA_CRYPTO` + +RISK: see `psa-limitations.md` + +RSA en/decryption +----------------- + +### Make `mbedtls_pk_encrypt()` use PSA for RSA operations + +- with regular `PK_RSA` context + +### Make `mbedtls_pk_decrypt()` use PSA for RSA operations + +- with regular `PK_RSA` context + +ECDH +---- + +### Write remaining utilities for ECDH parsing/writing + +- PSA only provides an API for the operation, need to parse and write + parameters and public keys to/from grp ID + string of bytes +- need to complete what was done in 4a.1 +- testing: positive: extract known-good inputs/outputs from actual handshakes? +- testing: negative: manipulate known-good input to make it invalid + +Note: future task in this section depend on this one, but not on each other. + +### Use PSA for ECDHE in ECDHE-ECDSA and ECDHE-RSA server-side + +- may need to separate branches from other ECDHE-based key exchanges +- only server-side (client-side is already done, can be used for inspiration) + +### Use PSA for ECDH in ECDHE-PSK (all sides and versions) + +- only with non-opaque PSK (support for opaque PSK here is part of G2) + +### Use PSA for ECDH in static-ECDH key exchanges + +- may require additional utility functions to load from cert to PSA + +FFDH +---- + +This may be hard, see `psa-limitations.md` + +EC J-PAKE +--------- + +Use PSA for all EC J-PAKE operations in TLS (both sides). +(TODO: consider how this could be split.) diff --git a/docs/architecture/psa-migration/tasks-g2.md b/docs/architecture/psa-migration/tasks-g2.md new file mode 100644 index 000000000000..72bd37791289 --- /dev/null +++ b/docs/architecture/psa-migration/tasks-g2.md @@ -0,0 +1,80 @@ +This document is temporary; it lists tasks to achieve G2 as described in +`strategy.md` while the strategy is being reviewed - once that's done, +corresponding github issues will be created and this document removed. + +For all of the tasks here, specific testing (integration and unit test depending +on the task) is required, see `testing.md`. + +RSA Signature operations +======================== + +In PK +----- + +### Modify existing `PK_OPAQUE` type to allow for RSA keys + +- the following must work and be tested: `mbedtls_pk_get_type()`, + `mbedtls_pk_get_name()`, `mbedtls_pk_get_bitlen()`, `mbedtls_pk_get_len()`, +`mbedtls_pk_can_do()`. +- most likely adapt `pk_psa_genkey()` in `test_suite_pk.function`. +- all other function (sign, verify, encrypt, decrypt, check pair, debug) will + return `MBEDTLS_ERR_PK_TYPE_MISMATCH` and this will be tested too. + +### Modify `mbedtls_pk_wrap_as_opaque()` to work with RSA. + +- OK to have policy hardcoded on signing with PKCS1v1.5, or allow more if + available at this time + +### Modify `mbedtls_pk_write_pubkey_der()` to work with RSA-opaque. + +- OK to just test that a generated key (with `pk_psa_genkey()`) can be + written, without checking for correctness of the result - this will be +tested as part of another task + +### Make `mbedtls_pk_sign()` work with RSA-opaque. + +- testing may extend `pk_psa_sign()` in `test_suite_pk_function` by adding + selector for ECDSA/RSA. + +In X.509 +-------- + +### Test using RSA-opaque for CSR generation + +- similar to what's already done with ECDSA-opaque + +### Test using opaque keys for Certificate generation + +- similar to what's done with testing CSR generation +- should test both RSA and ECDSA as ECDSA is not tested yet +- might require slight code adaptations, even if unlikely + + +In TLS +------ + +### Test using RSA-opaque for TLS client auth + +- similar to what's already done with ECDSA-opaque + +### Test using RSA-opaque for TLS server auth + +- similar to what's already done with ECDSA-opaque +- key exchanges: ECDHE-RSA and DHE-RSA + +RSA decrypt +=========== + +### Extend `PK_OPAQUE` to allow RSA decryption (PKCS1 v1.5) + +### Test using that in TLS for RSA and RSA-PSK key exchange. + +Support opaque PSKs for "mixed-PSK" key exchanges +================================================= + +See `PSA-limitations.md`. + +Possible split: +- one task to extend PSA (see `PSA-limitations.md`) +- then one task per handshake: DHE-PSK, ECDHE-PSK, RSA-PSK (with tests for + each) From f5ee4b3da4225b0a52fbaf0fd1e4d55d3c97ee67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 21 Oct 2021 13:04:01 +0200 Subject: [PATCH 06/21] Add data about RSA-PSS test files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Data gathered with: for c in server9*.crt; do echo $c; openssl x509 -noout -text -in $c | grep '^ Signature Algorithm: rsassaPss' -A3 | sed '1d'; done for c in crl-rsa-pss-*; do echo $c; openssl crl -noout -text -in $c | grep '^ Signature Algorithm: rsassaPss' -A3 | sed '1d'; done for c in server9.req.*; do echo $c; openssl req -noout -text -in $c | grep '^ Signature Algorithm: rsassaPss' -A3 | sed '1d'; done Unfortunately there is no record of how these files have been generated. Signed-off-by: Manuel Pégourié-Gonnard --- .../psa-migration/psa-limitations.md | 121 ++++++++++++++++-- 1 file changed, 110 insertions(+), 11 deletions(-) diff --git a/docs/architecture/psa-migration/psa-limitations.md b/docs/architecture/psa-migration/psa-limitations.md index 05a4d54a2728..d5d7d07818ee 100644 --- a/docs/architecture/psa-migration/psa-limitations.md +++ b/docs/architecture/psa-migration/psa-limitations.md @@ -122,7 +122,7 @@ value from the signature parameters is used. In Mbed TLS, RSA-PSS parameters can be parsed and displayed for various objects (certificates, CRLs, CSRs). During parsing, the following properties are enforced: -- (the extra "trailer field" parameter must has its default value) +- (the extra "trailer field" parameter must have its default value) - the mask generation function is MGF1 - encoding hash = message hashing algorithm (may differ from MGF1 hash) @@ -147,6 +147,8 @@ triple-check that.) It is unclear what parameters people use in practice. +TODO: look at what OpenSSL and GnuTLS do by default? + ### Use in TLS In TLS 1.2 (or lower), RSA-PSS signatures are never used, except via X.509. @@ -170,16 +172,113 @@ length would give an attacker any advantage, but this must be triple-checked ### Current testing - X509 -TODO: look at the parameters used by the various test files - -- server9.crt - -HASH - -badsign - -defaults - -bad-saltlen - -bad-mgfhash -- crl-rsa-pss-HASH.pem -- server9.req.HASH +TODO: look at hex testing (do we have negative testing of bad trailer field?) + +All test files use the default trailer field of 0xBC. Files with "bad" in the +name are expected to be invalid and rejected in tests. + +**Test certificates:** + +server9-bad-mgfhash.crt (announcing mgf1(sha224), signed with another mgf) + Hash Algorithm: sha256 + Mask Algorithm: mgf1 with sha224 + Salt Length: 0xDE +server9-bad-saltlen.crt (announcing saltlen = 0xDE, signed with another len) + Hash Algorithm: sha256 + Mask Algorithm: mgf1 with sha256 + Salt Length: 0xDE +server9-badsign.crt (one bit flipped in the signature) + Hash Algorithm: sha1 (default) + Mask Algorithm: mgf1 with sha1 (default) + Salt Length: 0xEA +server9-defaults.crt + Hash Algorithm: sha1 (default) + Mask Algorithm: mgf1 with sha1 (default) + Salt Length: 0x14 (default) +server9-sha224.crt + Hash Algorithm: sha224 + Mask Algorithm: mgf1 with sha224 + Salt Length: 0xE2 +server9-sha256.crt + Hash Algorithm: sha256 + Mask Algorithm: mgf1 with sha256 + Salt Length: 0xDE +server9-sha384.crt + Hash Algorithm: sha384 + Mask Algorithm: mgf1 with sha384 + Salt Length: 0xCE +server9-sha512.crt + Hash Algorithm: sha512 + Mask Algorithm: mgf1 with sha512 + Salt Length: 0xBE +server9-with-ca.crt + Hash Algorithm: sha1 (default) + Mask Algorithm: mgf1 with sha1 (default) + Salt Length: 0xEA +server9.crt + Hash Algorithm: sha1 (default) + Mask Algorithm: mgf1 with sha1 (default) + Salt Length: 0xEA + +These certificates are signed with a 2048-bit key. It appears that they are +all using saltlen = keylen - hashlen - 2, except for server9-defaults which is +using saltlen = hashlen. + +**Test CRLs:** + +crl-rsa-pss-sha1-badsign.pem + Hash Algorithm: sha1 (default) + Mask Algorithm: mgf1 with sha1 (default) + Salt Length: 0xEA +crl-rsa-pss-sha1.pem + Hash Algorithm: sha1 (default) + Mask Algorithm: mgf1 with sha1 (default) + Salt Length: 0xEA +crl-rsa-pss-sha224.pem + Hash Algorithm: sha224 + Mask Algorithm: mgf1 with sha224 + Salt Length: 0xE2 +crl-rsa-pss-sha256.pem + Hash Algorithm: sha256 + Mask Algorithm: mgf1 with sha256 + Salt Length: 0xDE +crl-rsa-pss-sha384.pem + Hash Algorithm: sha384 + Mask Algorithm: mgf1 with sha384 + Salt Length: 0xCE +crl-rsa-pss-sha512.pem + Hash Algorithm: sha512 + Mask Algorithm: mgf1 with sha512 + Salt Length: 0xBE + +These CRLs are signed with a 2048-bit key. It appears that they are +all using saltlen = keylen - hashlen - 2. + +**Test CSRs:** + +server9.req.sha1 + Hash Algorithm: sha1 (default) + Mask Algorithm: mgf1 with sha1 (default) + Salt Length: 0x6A +server9.req.sha224 + Hash Algorithm: sha224 + Mask Algorithm: mgf1 with sha224 + Salt Length: 0x62 +server9.req.sha256 + Hash Algorithm: sha256 + Mask Algorithm: mgf1 with sha256 + Salt Length: 0x5E +server9.req.sha384 + Hash Algorithm: sha384 + Mask Algorithm: mgf1 with sha384 + Salt Length: 0x4E +server9.req.sha512 + Hash Algorithm: sha512 + Mask Algorithm: mgf1 with sha512 + Salt Length: 0x3E + +These CSRss are signed with a 2048-bit key. It appears that they are +all using saltlen = keylen - hashlen - 2. ### Possible course of actions From e459be2ed15abb9cd4d4cf0fbc263bf3c6bec96b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 27 Oct 2021 13:25:49 +0200 Subject: [PATCH 07/21] Complete discussion of RSASSA-PSS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update to latest draft of PSA Crypto 1.1.0: back to strict verification by default, but ANY_SALT introduced. Commands used to observe default values of saltlen: openssl genpkey -algorithm rsa-pss -out o.key openssl req -x509 -new -key o.key -subj "/CN=CA" -sha256 -out o.crt certtool --generate-privkey --key-type rsa-pss --outfile g.key certtool --generate-self-signed --load-privkey g.key --outfile g.crt Signed-off-by: Manuel Pégourié-Gonnard --- .../psa-migration/psa-limitations.md | 62 +++++++++++-------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/docs/architecture/psa-migration/psa-limitations.md b/docs/architecture/psa-migration/psa-limitations.md index d5d7d07818ee..85ad28ef998e 100644 --- a/docs/architecture/psa-migration/psa-limitations.md +++ b/docs/architecture/psa-migration/psa-limitations.md @@ -63,14 +63,16 @@ RSA-PSS signatures are defined by PKCS#1 v2, re-published as RFC 8017 As standardized, the signature scheme takes several parameters, in addition to the hash algorithm potentially used to hash the message being signed: -- a hash algorithm use for the encoding function +- a hash algorithm used for the encoding function - a mask generation function - most commonly MGF1, which in turn is parametrized by a hash algorithm - a salt length +- a trailer field - this is universally 0xBC as far as I've seen Both the existing `mbedtls_` API and the PSA API support only MGF1 as the -generation function, but there are discrepancy in handling the salt length and -which of the various hash algorithms can differ from each other. +generation function (and only 0xBC as the trailer field), but there are +discrepancies in handling the salt length and which of the various hash +algorithms can differ from each other. ### API comparison @@ -100,11 +102,11 @@ which of the various hash algorithms can differ from each other. - PSA: - algorithm specification: - hash alg used for message hashing, encoding and MGF1 - - salt length cannot be specified + - salt length can be either "standard" (== hashlen) or "any" - signature generation: - salt length: always using the maximum legal value - verification: - - salt length: any valid length accepted + - salt length: either == hashlen, or any depending on algorithm The RSA/PK API is in principle more flexible than the PSA Crypto API. The following sub-sections study whether and how this matters in practice. @@ -122,7 +124,7 @@ value from the signature parameters is used. In Mbed TLS, RSA-PSS parameters can be parsed and displayed for various objects (certificates, CRLs, CSRs). During parsing, the following properties are enforced: -- (the extra "trailer field" parameter must have its default value) +- the extra "trailer field" parameter must have its default value - the mask generation function is MGF1 - encoding hash = message hashing algorithm (may differ from MGF1 hash) @@ -135,19 +137,12 @@ The verification is done using `mbedtls_pk_verify_ext()`. Note: since X.509 parsing ensures that message hash = encoding hash, and `mbedtls_pk_verify_ext()` use encoding hash = mgf1 hash, it looks like all three hash algorithms must be equal, which would be good news as it would -match a limitation of the PSA API. (TODO: double-check that.) - -Also, since we only use signature verification, the fact that PSA accepts any -valid salt length means that no valid certificate would be wrongly rejected; -however it means that signatures that don't match the announced salt length -would be incorrectly accepted. At first glance, it looks like this doesn't -allow an attacker to forge certificates, so this might be acceptable in -practice, while not fully implementing all the checks in the standard. (TODO: -triple-check that.) +match a limitation of the PSA API. -It is unclear what parameters people use in practice. - -TODO: look at what OpenSSL and GnuTLS do by default? +It is unclear what parameters people use in practice. It looks like by default +OpenSSL picks saltlen = keylen - hashlen - 2 (tested with openssl 1.1.1f). +The `certool` command provided by GnuTLS seems to be picking saltlen = hashlen +by default (tested with GnuTLS 3.6.13). ### Use in TLS @@ -166,16 +161,16 @@ In both cases, it specifies that: When signing, the salt length picked by PSA is the one required by TLS 1.3 (unless the key is unreasonably small). -When verifying signatures, again is doesn't look like accepting any salt -length would give an attacker any advantage, but this must be triple-checked -(TODO). +When verifying signatures, PSA will by default enforce the salt len is the one +required by TLS 1.3. ### Current testing - X509 -TODO: look at hex testing (do we have negative testing of bad trailer field?) +All test files use the default trailer field of 0xBC, as enforced by our +parser. (There's a negative test for that using the +`x509_parse_rsassa_pss_params` test function and hex data.) -All test files use the default trailer field of 0xBC. Files with "bad" in the -name are expected to be invalid and rejected in tests. +Files with "bad" in the name are expected to be invalid and rejected in tests. **Test certificates:** @@ -280,9 +275,22 @@ server9.req.sha512 These CSRss are signed with a 2048-bit key. It appears that they are all using saltlen = keylen - hashlen - 2. -### Possible course of actions - -TODO - once the previous section has been completed +### Possible courses of action + +There's no question about what to do with TLS (any version); the only question +is about X.509 signature verification. Options include: + +1. Doing all verifications with `PSA_ALG_RSA_PSS_ANY_SALT` - while this + wouldn't cause a concrete security issue, this would be non-compliant. +2. Doing verifications with `PSA_ALG_RSA_PSS` when we're lucky and the encoded + saltlen happens to match hashlen, and falling back to `ANY_SALT` otherwise. +Same issue as with the previous point, except more contained. +3. Reject all certificates with saltlen != hashlen. This includes all + certificates generate with OpenSSL using the default parameters, so it's +probably not acceptable. +4. Request an extension to the PSA Crypto API and use one of the above options + in the meantime. Such an extension seems inconvenient and not motivated by +strong security arguments, so it's unclear whether it would be accepted. Limitations relevant for G2 (isolation of long-term secrets) ============================================================ From 7497991356a285801eefabc2ec60c904c95386f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 27 Oct 2021 14:00:08 +0200 Subject: [PATCH 08/21] Expand discussion of goals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/strategy.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/architecture/psa-migration/strategy.md b/docs/architecture/psa-migration/strategy.md index 52819acb9ec2..cb4a1acd4160 100644 --- a/docs/architecture/psa-migration/strategy.md +++ b/docs/architecture/psa-migration/strategy.md @@ -6,21 +6,21 @@ Goals Several benefits are expected from migrating to PSA Crypto: -G1. Take advantage of the PSA Crypto driver interface. +G1. Use PSA Crypto drivers when available. G2. Allow isolation of long-term secrets (for example, private keys). G3. Allow isolation of short-term secrets (for example, TLS sesssion keys). G4. Have a clean, unified API for Crypto (retire the legacy API). +G5. Code size: compile out our implementation when a driver is available. Currently, some parts of (G1) and (G2) are implemented when `MBEDTLS_USE_PSA_CRYPTO` is enabled. For (G2) to take effect, the application needs to be changed to use new APIs. Generally speaking, the numbering above doesn't mean that each goal requires -the preceding ones to be completed - for example it would be possible to -start or even complete (G4) before (G3) is even started. However, (G2) and (G3) -require operations to be done via the PSA Crypto API, which is mostly what (G1) -is about. Also, we can't retire the legacy API (G4) until we no longer rely on -it, which again is mostly (G1). +the preceding ones to be completed, for example G2-G5 could be done in any +order; however they all either depend on G1 or are just much more convenient +if G1 is done before (note that this is not a dependency on G1 being complete, +it's more like each bit of G2-G5 is helped by some speficic bit in G1). So, a solid intermediate goal would be to complete (G1) when `MBEDTLS_USA_PSA_CRYPTO` is enabled - that is, all crypto operations in X.509 From a6c601c079b053b81f054a30480c34e694bae317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 27 Oct 2021 14:12:44 +0200 Subject: [PATCH 09/21] Explain compile-time incompatibilities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/strategy.md | 82 +++++++++++++++++++-- 1 file changed, 76 insertions(+), 6 deletions(-) diff --git a/docs/architecture/psa-migration/strategy.md b/docs/architecture/psa-migration/strategy.md index cb4a1acd4160..a166b27333db 100644 --- a/docs/architecture/psa-migration/strategy.md +++ b/docs/architecture/psa-migration/strategy.md @@ -37,17 +37,87 @@ We currently have two compile-time options that are relevant to the migration: controls usage of PSA Crypto APIs to perform operations in X.509 and TLS (G1 above), as well as the availability of some new APIs (G2 above). -The reason why `MBEDTLS_USE_PSA_CRYPTO` is optional, and disabled by default, -is mostly to avoid introducing a hard (or even default) dependency of X509 and -TLS and `MBEDTLS_PSA_CRYPTO_C`. This is mostly reasons of code size, and -historically concerns about the maturity of the PSA code (which we might want -to re-evaluate). +The reasons why `MBEDTLS_USE_PSA_CRYPTO` is optional and disabled by default +are: +- it's incompatible with `MBEDTLS_ECP_RESTARTABLE`, `MBEDTLS_PSA_CRYPTO_CONFIG` and `MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER`; +- to avoid a hard/default dependency of X509 and TLS and + `MBEDTLS_PSA_CRYPTO_C`, mostly reasons of code size, and historically +concerns about the maturity of the PSA code (which we might want to +re-evaluate). The downside of this approach is that until we feel ready to make `MBDEDTLS_USE_PSA_CRYPTO` non-optional (always enabled), we have to maintain two versions of some parts of the code: one using PSA, the other using the legacy APIs. However, see next section for strategies that can lower that -cost. +cost. The rest of this section explains the reasons for the +incompatibilities mentioned above. + +### `MBEDTLS_ECP_RESTARTABLE` + +Currently this option controls not only the presence of restartable APIs in +the crypto library, but also their use in the TLS and X.509 layers. Since PSA +Crypto does not support restartable operations, there's a clear conflict: the +TLS and X.509 layers can't both use only PSA APIs and get restartable +behaviour. + +Supporting this in PSA is on our roadmap (it's been requested). But it's way +below generalizing support for `MBEDTLS_USE_PSA_CRYPTO` for “mainstream” use +cases on our priority list. So in the medium term `MBEDTLS_ECP_RESTARTABLE` is +incompatible with `MBEDTLS_USE_PSA_CRYPTO`. + +Note: it is possible to make the options compatible at build time simply by +deciding that when `USE_PSA_CRYPTO` is enabled, then `MBEDTLS_ECP_RESTARTABLE` +cease to have any effect on X.509 and TLS: it simply controls the presence of +the APIs in libmbedcrypto. (Or we could split `ECP_RESTARTABLE` into several +options to achieve a similar effect.) This would allow people to use +restartable ECC in non-TLS, non-X509 code (for example firmware verification) +with a build that also uses PSA for TLS and X509), if there is an interest for +that. + +### `MBEDTLS_PSA_CRYPTO_CONFIG` + +X509 and TLS code use `MBEDTLS_xxx` macros to decide whether an algorithm is +supported. This doesn't make `MBEDTLS_USE_PSA_CRYPTO` incompatible with +`MBEDTLS_PSA_CRYPTO_CONFIG` per se, but it makes it incompatible with most +useful uses of `MBEDTLS_PSA_CRYPTO_CONFIG`. The point of +`MBEDTLS_PSA_CRYPTO_CONFIG` is to be able to build a library with support for +an algorithm through a PSA driver only, without building the software +implementation of that algorithm. But then the TLS code would consider the +algorithm unavailable. + +This is tracked in https://github.com/ARMmbed/mbedtls/issues/3674 and +https://github.com/ARMmbed/mbedtls/issues/3677. But now that I look at it with +fresh eyes, I don't think the approach we were planning to use would actually +works. This needs more design effort. + +This is something we need to support eventually, and several partners want it. +I don't know what the priority is for `MBEDTLS_USE_PSA_CRYPTO` between +improving driver support and covering more of the protocol. It seems to me +that it'll be less work overall to first implement a good architecture for +`MBEDTLS_USE_PSA_CRYPTO + MBEDTLS_PSA_CRYPTO_CONFIG` and then extend to more +protocol featues, because implementing that architecture will require changes +to the existing code and the less code there is at this point the better, +whereas extending to more procotol features will require the same amount of +work either way. + +### `MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER` + +When `MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER` is enabled, the library is +built for use with an RPC server that dispatches PSA crypto function calls +from multiple clients. In such a build, all the `psa_xxx` functions that take +would normally take a `psa_key_id_t` as argument instead take a structure +containing both the key id and the client id. And so if e.g. a TLS function +calls `psa_import_key`, it would have to pass this structure, not just the +`psa_key_id_t` key id. + +A solution is to use `mbedtls_svc_key_id_t` throughout instead of +`psa_key_id_t`, and use similar abstractions to define values. That's what we +do in unit tests of PSA crypto itself to support both cases. That abstraction +is more confusing to readers, so the less we use it the better. + +I don't think supporting TLS and an RPC interface in the same build is an +important use case (I don't remember anyone requesting it). So I propose to +ignore it in the design: we just don't intend to support it. Taking advantage of the existing abstractions layers - or not ============================================================= From 09503592207dae6f3a853b55f1d4ce405fd9df27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 27 Oct 2021 14:21:23 +0200 Subject: [PATCH 10/21] Improve "abstraction layers" section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fix inaccuracy about PSA hash implementation - add note about context-less operations - provide summary Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/strategy.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/docs/architecture/psa-migration/strategy.md b/docs/architecture/psa-migration/strategy.md index a166b27333db..d63ad7014501 100644 --- a/docs/architecture/psa-migration/strategy.md +++ b/docs/architecture/psa-migration/strategy.md @@ -156,8 +156,8 @@ crypto API. This strategy is currently used for ECDSA signature verification in the PK layer, and could be extended to all operations in the PK layer. -This strategy is not very well suited to the Cipher and MD layers, as the PSA -implementation is currently done on top of those layers. +This strategy is not very well suited to the Cipher layer, as the PSA +implementation is currently done on top of that layer. Replace calls for each operation -------------------------------- @@ -184,6 +184,9 @@ Opt-in use of PSA from the abstraction layer - Downside: when the context is typically set up by the application, requires changes in application code. +This strategy is not useful when no context is used, for example with the +one-shot function `mbedtls_md()`. + There are two variants of this strategy: one where using the new setup function also allows for key isolation (the key is only held by PSA, supporting both G1 and G2 in that area), and one without isolation (the key is @@ -207,6 +210,16 @@ support for key isolation, but at the (unavoidable) code of change in application code, while the other requires no application change to get support for drivers, but fails to provide isolation support. +Summary +------- + +Stategies currently used with each abstraction layer: + +- PK (for G1): silently call PSA +- PK (for G2): opt-in use of PSA (new key type) +- Cipher (G1): opt-in use of PSA (new setup function) +- MD (G1): replace calls at each call site + Migrating away from the legacy API ================================== From ab1d3084b7c4fe4e44c9fe1a77ad79a374c184a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 17 Jan 2022 10:47:24 +0100 Subject: [PATCH 11/21] Goal 1 tasks are now all reflected on github MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace descriptions with links just to double-check nothing has been forgotten. Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/tasks-g1.md | 96 +++++++-------------- 1 file changed, 29 insertions(+), 67 deletions(-) diff --git a/docs/architecture/psa-migration/tasks-g1.md b/docs/architecture/psa-migration/tasks-g1.md index 599a11d3dbd6..d906bf9ea5ef 100644 --- a/docs/architecture/psa-migration/tasks-g1.md +++ b/docs/architecture/psa-migration/tasks-g1.md @@ -14,54 +14,31 @@ Hashes ### Use `psa_hash` in all of X.509 -Conditionally on `MBEDTLS_USE_PSA_CRYPTO`, replace all remaining calls to -`mbedtls_md()` or `mbedtls_sha1_ret()` by calls `psa_hash` functions, namely: -- replace `mbedtls_md()` in `x509_crt_verifycrl()` in `x509_crt.c` -- replace `mbedtls_md()` in `mbedtls_x509write_crt_der()` in `x509write_crt.c` -- replace `mbedtls_sha1_ret() in - `mbedtls_x509write_crt_set_subject_key_identifier()` in `x509write_crt.c` -- replace `mbedtls_sha1_ret() in - `mbedtls_x509write_crt_set_authority_key_identifier()` in `x509write_crt.c` -- already done in `x509_crt_check_signature()` in `x509_crt.c`, but might - want to replace multi-part with single-part. -- already done in `mbedtls_x509write_csr_der_internal()` in - `x509write_csr.c`, but might want to replace multi-part with single-part. +https://github.com/ARMmbed/mbedtls/issues/5157 HMAC ---- ### Variable-time HMAC in TLS record protection -- This is about the calls to `mbedtls_md_hmac_xxx()` in -`mbedtls_ssl_decrypt_buf()` and `mbedtls_ssl_encrypt_buf()`, but excludes the -call in `mbedtls_ssl_cf_hmad()` (which it its own task). -- Might need to change the `transform` structure to hold a PSA context instead - of an MD context. Note: might keep the MD context in parallel until the -constant-time part is done as well. - -TODO: study this better so it can be estimated. +https://github.com/ARMmbed/mbedtls/issues/5177 ### Constant-time HMAC in TLS record protection -This is `mbedtls_ssl_cf_hmac()`. The PSA code might look a bit different as -we'll probably need to store the HMAC key somewhere and compute the ipad/opad -explicitly instead of using (the internals of) the MD layers for that. +https://github.com/ARMmbed/mbedtls/issues/5178 -TODO: study this better so it can be estimated. Ciphers ------- ### Use PSA for all cipher operations in TLS -- extend existing `mbedtls_cipher_setup_psa()` and related code to support - other ciphers than AES that can be used in TLS: ARIA (depends on #4959), -Camellia, ChachaPoly. -- extend unit-testing in `test_suite_cipher` to test those new ciphers as - AES-based cipher are already tested -- remove the fallback mechanism in all places where `cipher_setup_psa()` is - called from TLS code -- expand use of `run_test_psa()` in `ssl-opt.sh` +https://github.com/ARMmbed/mbedtls/issues/5181 +https://github.com/ARMmbed/mbedtls/issues/5182 +https://github.com/ARMmbed/mbedtls/issues/5203 +https://github.com/ARMmbed/mbedtls/issues/5204 +https://github.com/ARMmbed/mbedtls/issues/5205 +https://github.com/ARMmbed/mbedtls/issues/5206 Asymmetric crypto ================= @@ -71,82 +48,67 @@ ECDSA ### Make `mbedtls_pk_sign()` use PSA for ECDSA operations -- This is already done with `PK_OPAQUE` contexts, but this task is about doing -it for regulard `ECKEY`/`ECDSA` contexts. -- May share some code (transcoding) with the exist support for `PK_OPAQUE` - contexts +https://github.com/ARMmbed/mbedtls/issues/5274 RSA signature (and verification) -------------------------------- ### Make `mbedtls_pk_sign()` use PSA for RSA operations -- with regular `PK_RSA` context -- only PKCS#1 v1.5 for this task -- similar to what's done for ECDSA, except no need for transcoding (I think) +https://github.com/ARMmbed/mbedtls/issues/5162 ### Make `mbedtls_pk_verify()` use PSA for RSA operations -- with regular `PK_RSA` context -- only PKCS#1 v1.5 for this task -- similar to what's done for ECDSA, except no need for transcoding (I think) +https://github.com/ARMmbed/mbedtls/issues/5159 ### Make `mbedtls_pk_verify_ext()` use PSA for RSA operations -- with regular `PK_RSA` context -- this is for RSA-PSS -- similar to what's done for ECDSA, except no need for transcoding (I think) -- acceptable to enforce that all hashes are equal in the parameters (as - imposed by the PSA API) and reject the signature otherwise -- then need to check if all X.509 tests still pass, and if some don't, make - them depend on `!MBEDTLS_USE_PSA_CRYPTO` - -RISK: see `psa-limitations.md` +https://github.com/ARMmbed/mbedtls/issues/5333 (partial) +https://github.com/ARMmbed/mbedtls/issues/5277 (futher) RSA en/decryption ----------------- ### Make `mbedtls_pk_encrypt()` use PSA for RSA operations -- with regular `PK_RSA` context + +https://github.com/ARMmbed/mbedtls/issues/5161 ### Make `mbedtls_pk_decrypt()` use PSA for RSA operations -- with regular `PK_RSA` context +https://github.com/ARMmbed/mbedtls/issues/5160 ECDH ---- -### Write remaining utilities for ECDH parsing/writing +Additional: +https://github.com/ARMmbed/mbedtls/issues/5291 (pre clean-up) +https://github.com/ARMmbed/mbedtls/issues/5321 (TLS 1.3) +https://github.com/ARMmbed/mbedtls/issues/5322 (post clean-up) -- PSA only provides an API for the operation, need to parse and write - parameters and public keys to/from grp ID + string of bytes -- need to complete what was done in 4a.1 -- testing: positive: extract known-good inputs/outputs from actual handshakes? -- testing: negative: manipulate known-good input to make it invalid +### Write remaining utilities for ECDH parsing/writing -Note: future task in this section depend on this one, but not on each other. +(not a task on its own, part of other tasks) ### Use PSA for ECDHE in ECDHE-ECDSA and ECDHE-RSA server-side -- may need to separate branches from other ECDHE-based key exchanges -- only server-side (client-side is already done, can be used for inspiration) +https://github.com/ARMmbed/mbedtls/issues/5317 ### Use PSA for ECDH in ECDHE-PSK (all sides and versions) -- only with non-opaque PSK (support for opaque PSK here is part of G2) +https://github.com/ARMmbed/mbedtls/issues/5318 ### Use PSA for ECDH in static-ECDH key exchanges -- may require additional utility functions to load from cert to PSA +https://github.com/ARMmbed/mbedtls/issues/5319 +https://github.com/ARMmbed/mbedtls/issues/5320 FFDH ---- -This may be hard, see `psa-limitations.md` +https://github.com/ARMmbed/mbedtls/issues/5287 EC J-PAKE --------- -Use PSA for all EC J-PAKE operations in TLS (both sides). -(TODO: consider how this could be split.) +https://github.com/ARMmbed/mbedtls/issues/5275 From 5218774efb6e0ea1f973f4b03fb8c55f84f20050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 17 Jan 2022 11:02:31 +0100 Subject: [PATCH 12/21] Add note about HKDF for TLS 1.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- .../psa-migration/psa-limitations.md | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/docs/architecture/psa-migration/psa-limitations.md b/docs/architecture/psa-migration/psa-limitations.md index 85ad28ef998e..54d1ed8532b4 100644 --- a/docs/architecture/psa-migration/psa-limitations.md +++ b/docs/architecture/psa-migration/psa-limitations.md @@ -292,6 +292,33 @@ probably not acceptable. in the meantime. Such an extension seems inconvenient and not motivated by strong security arguments, so it's unclear whether it would be accepted. +HKDF: Expand not exposed on its own (TLS 1.3) +--------------------------------------------- + +The HKDF function uses and Extract-then-Expand approch, that is: + + HKDF(x, ...) = HKDF-Expand(HKDF-Extract(x, ...), ...) + +Only the full HKDF function is safe in general, however there are cases when +one case safely use the individual Extract and Expand; the TLS 1.3 key +schedule does so. Specifically, looking at the [hierarchy of secrets][13hs] +is seems that Expand and Extract are always chained, so that this hierarchy +can be implemented using only the full HKDF. However, looking at the +derivation of traffic keys (7.3) and the update mechanism (7.2) it appears +that calls to HKDF-Expand are iterated without any intermediated call to +HKDF-Extract : that is, the traffic keys are computed as + + HKDF-Expand(HKDF-Expand(HKDF-Extract(...))) + +(with possibly more than two Expands in a row with update). + +[13hs]: https://datatracker.ietf.org/doc/html/rfc8446#page-93 + +In the short term (early 2022), we'll work around that by re-implementing HKDF +in `ssl_tls13_keys.c` based on the `psa_mac_` APIs (for HMAC). + +In the long term, it is desirable to extend the PSA API. + Limitations relevant for G2 (isolation of long-term secrets) ============================================================ @@ -329,3 +356,16 @@ of RSA decryption would be still checking that is has the correct format: 48 bytes, the first two matching the TLS version - note that this is timing sensitive.) +HKDF: Expand not exposed on its own (TLS 1.3) +--------------------------------------------- + +See the section with the same namw in the G1 part above for background. + +The work-around mentioned there works well enough just for acceleration, but +is not sufficient for key isolation or generally proper key management (it +requires marking keys are usable for HMAC while they should only be used for +key derivation). + +The obvious long-term solution is to make HKDF-Expand available as a new KDF +(in addition to the full HKDF) in PSA (with appropriate warnings in the +documentation). From ec3fd75cbc230cb3f82042d42125c1ace978871a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 17 Jan 2022 11:29:18 +0100 Subject: [PATCH 13/21] Update strategy with late 2021 discussion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unless I missed something, this should now reflect the current strategy. Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/strategy.md | 102 ++++++++++++++------ 1 file changed, 74 insertions(+), 28 deletions(-) diff --git a/docs/architecture/psa-migration/strategy.md b/docs/architecture/psa-migration/strategy.md index d63ad7014501..fe15bc19c876 100644 --- a/docs/architecture/psa-migration/strategy.md +++ b/docs/architecture/psa-migration/strategy.md @@ -39,11 +39,18 @@ We currently have two compile-time options that are relevant to the migration: The reasons why `MBEDTLS_USE_PSA_CRYPTO` is optional and disabled by default are: -- it's incompatible with `MBEDTLS_ECP_RESTARTABLE`, `MBEDTLS_PSA_CRYPTO_CONFIG` and `MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER`; -- to avoid a hard/default dependency of X509 and TLS and - `MBEDTLS_PSA_CRYPTO_C`, mostly reasons of code size, and historically -concerns about the maturity of the PSA code (which we might want to -re-evaluate). +- it's incompatible with `MBEDTLS_ECP_RESTARTABLE`, and `MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER`; +- it does not work well with `MBEDTLS_PSA_CRYPTO_CONFIG` (could compile with + both of them, but then `MBEDTLS_PSA_CRYPTO_CONFIG` won't have the desired +effect) +- to avoid a hard/default dependency of TLS, X.509 and PK on + `MBEDTLS_PSA_CRYPTO_C`, for backards compatibility reasons: + - when `MBEDTLS_PSA_CRYPTO_C` is enabled and used, applications need to call + `psa_crypto_init()` before TLS/X.509 uses PSA functions + - `MBEDTLS_PSA_CRYPTO_C` has a hard depend on `MBEDTLS_ENTROPY_C` but it's + currently possible to compilte TLS and X.509 without `MBEDTLS_ENTROPY_C`. + Also, we can't just auto-enable `MBEDTLS_ENTROPY_C` as it doesn't build + out of the box on all platforms. The downside of this approach is that until we feel ready to make `MBDEDTLS_USE_PSA_CRYPTO` non-optional (always enabled), we have to maintain @@ -52,6 +59,9 @@ legacy APIs. However, see next section for strategies that can lower that cost. The rest of this section explains the reasons for the incompatibilities mentioned above. +In the medium term (writing this in early 2020), we're going to look for ways +to make `MBEDTLS_USE_PSA_CRYPTO` non-optional (always enabled). + ### `MBEDTLS_ECP_RESTARTABLE` Currently this option controls not only the presence of restartable APIs in @@ -66,13 +76,9 @@ cases on our priority list. So in the medium term `MBEDTLS_ECP_RESTARTABLE` is incompatible with `MBEDTLS_USE_PSA_CRYPTO`. Note: it is possible to make the options compatible at build time simply by -deciding that when `USE_PSA_CRYPTO` is enabled, then `MBEDTLS_ECP_RESTARTABLE` -cease to have any effect on X.509 and TLS: it simply controls the presence of -the APIs in libmbedcrypto. (Or we could split `ECP_RESTARTABLE` into several -options to achieve a similar effect.) This would allow people to use -restartable ECC in non-TLS, non-X509 code (for example firmware verification) -with a build that also uses PSA for TLS and X509), if there is an interest for -that. +deciding that when `USE_PSA_CRYPTO` is enabled, PSA APIs are used except if +restartable behaviour was requested at run-time (in addition to enabling +`MBEDTLS_ECP_RESTARTABLE` in the build). ### `MBEDTLS_PSA_CRYPTO_CONFIG` @@ -111,13 +117,36 @@ calls `psa_import_key`, it would have to pass this structure, not just the `psa_key_id_t` key id. A solution is to use `mbedtls_svc_key_id_t` throughout instead of -`psa_key_id_t`, and use similar abstractions to define values. That's what we -do in unit tests of PSA crypto itself to support both cases. That abstraction -is more confusing to readers, so the less we use it the better. - -I don't think supporting TLS and an RPC interface in the same build is an -important use case (I don't remember anyone requesting it). So I propose to -ignore it in the design: we just don't intend to support it. +`psa_key_id_t`, and use similar abstractions to define values. + +That's what we're implemementing in early 2022, see +https://github.com/ARMmbed/mbedtls/issues/5259 + +### Backwars compatibility issues with making it always on + +1. Existing applications may not be calling `psa_crypto_init()` before using + TLS, X.509 or PK. We can try to work around that by calling (the relevant +part of) it ourselves under the hood as needed, but that would likely require +splitting init between the parts that can fail and the parts that can't (see +https://github.com/ARM-software/psa-crypto-api/pull/536 for that). +2. It's currently not possible to enable `MBEDTLS_PSA_CRYPTO_C` in + configurations that don't have `MBEDTLS_ENTROPY_C`, and we can't just +auto-enable the latter, as it won't build or work out of the box on all +platforms. There are two kinds of things we'd need to do if we want to work +around that: + 1. Make it possible to enable the parts of PSA Crypto that don't require an + RNG (typically, public key operations, symmetric crypto, some key +management functions (destroy etc)) in configurations that don't have +`ENTROPY_C`. This requires going through the PSA code base to adjust +dependencies. Risk: there may be annoying dependencies, some of which may be +surprising. + 2. For operations that require an RNG, provide an alternative function + accepting an explicit `f_rng` parameter (see #5238), that would be +available in entropy-less builds. (Then code using those functions still needs +to have one version using it, for entropy-less builds, and one version using +the standard function, for driver support in build with entropy.) + +See https://github.com/ARMmbed/mbedtls/issues/5156 Taking advantage of the existing abstractions layers - or not ============================================================= @@ -153,12 +182,20 @@ crypto API. - Downside: tricky to implement if the PSA implementation is currently done on top of that layer (dependency loop). -This strategy is currently used for ECDSA signature verification in the PK -layer, and could be extended to all operations in the PK layer. +This strategy is currently (late 2021) used for ECDSA signature +verification in the PK layer, and could be extended to all operations in the +PK layer. This strategy is not very well suited to the Cipher layer, as the PSA implementation is currently done on top of that layer. +This strategy will probably be used for some time for the PK layer, while we +figure out what the future of that layer is: parts of it (parse/write, ECDSA +signatures in the format that X.509 & TLS want) are not covered by PSA, so +they will need to keep existing in some way. Also the PK layer is also a good +place for dispatching to either PSA or `mbedtls_xxx_restartable` while that +part is not covered by PSA yet. + Replace calls for each operation -------------------------------- @@ -166,10 +203,14 @@ Replace calls for each operation replace function call with calls to PSA (conditionally on `USE_PSA_CRYPTO`) - Upside: conceptually simple, and if the PSA implementation is currently done on top of that layer, avoids concerns about dependency loops. +- Upside: opens the door to building TLS/X.509 without that layer, saving some + code size. - Downside: TLS/X.509 code has to be done for each operation. -This strategy is currently used for the MD layer. (Currently only a subset of -calling places, but could be extended to all of them.) +This strategy is currently (late 2021) used for the MD layer. (Currently only +a subset of calling places, but will be extended to all of them.) + +In the future (early 2022) we're going to use it for the Cipher layer as well. Opt-in use of PSA from the abstraction layer -------------------------------------------- @@ -192,17 +233,20 @@ function also allows for key isolation (the key is only held by PSA, supporting both G1 and G2 in that area), and one without isolation (the key is still stored outsde of PSA most of the time, supporting only G1). -This strategy, with support for key isolation, is currently used for ECDSA +This strategy, with support for key isolation, is currently (end of 2021) used for ECDSA signature generation in the PK layer - see `mbedtls_pk_setup_opaque()`. This allows use of PSA-held private ECDSA keys in TLS and X.509 with no change to the TLS/X.509 code, but a contained change in the application. If could be -extended to other private key operations in the PK layer. +extended to other private key operations in the PK layer, which is the plan as +of early 2022. This strategy, without key isolation, is also currently used in the Cipher layer - see `mbedtls_cipher_setup_psa()`. This allows use of PSA for cipher operations in TLS with no change to the application code, and a -contained change in TLS code. (It currently only supports a subset of ciphers, -but could easily be extended to all of them.) +contained change in TLS code. (It currently only supports a subset of +ciphers.) However, we'll move to the "Replace calls for each operation" +strategy (early 2022), in the hope of being able to build without this layer +in order to save some code size in the future. Note: for private key operations in the PK layer, both the "silent" and the "opt-in" strategy can apply, and can complement each other, as one provides @@ -217,7 +261,9 @@ Stategies currently used with each abstraction layer: - PK (for G1): silently call PSA - PK (for G2): opt-in use of PSA (new key type) -- Cipher (G1): opt-in use of PSA (new setup function) +- Cipher (G1): + - late 2021: opt-in use of PSA (new setup function) + - early 2022: moving to "replace calls at each call site" - MD (G1): replace calls at each call site Migrating away from the legacy API From 335cbf61daba7f49c22cf1e7d9556ae111e07799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 1 Feb 2022 09:55:45 +0100 Subject: [PATCH 14/21] Remove temporary documents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dependencies-xxx.md documents where merely a support for study, now distilled to strategy.md, psa-limitation.md, and tasks-xx.md and/or github issues. The tasks-g1.md document has now been fully converted to a list of github issues. These documents would quickly become out-of-date and there's little point in updating them, so it's better to remove them. They're still in the github history if anyone wants to have a look. Signed-off-by: Manuel Pégourié-Gonnard --- .../psa-migration/dependencies-tls.md | 563 ------------------ .../psa-migration/dependencies-x509.md | 206 ------- docs/architecture/psa-migration/tasks-g1.md | 114 ---- 3 files changed, 883 deletions(-) delete mode 100644 docs/architecture/psa-migration/dependencies-tls.md delete mode 100644 docs/architecture/psa-migration/dependencies-x509.md delete mode 100644 docs/architecture/psa-migration/tasks-g1.md diff --git a/docs/architecture/psa-migration/dependencies-tls.md b/docs/architecture/psa-migration/dependencies-tls.md deleted file mode 100644 index 74f78d57b070..000000000000 --- a/docs/architecture/psa-migration/dependencies-tls.md +++ /dev/null @@ -1,563 +0,0 @@ -Dependencies of the TLS library on the Crypto library -===================================================== - -This document is part of the technical study on how to port Mbed TLS to PSA -Crypto. It describes the dependencies of libmbedtls.a on libmbedcrypto.a. - -More precisely, it describes what functions from libmbedcrypto.a are called -from libmbedtls.a - other forms of dependencies such as using static inline -functions or types, accessing private struct members, etc., are not listed. - -It is based on Mbed TLS 3.0, excluding experimental support for TLS 1.3, and -also excluding support for restartble ECP operations. - -Non-Crypto dependencies ------------------------ - -The TLS library has a number of dependencies on libmbedcrypto.a that are not -cryptographic, hence are unlikely to be covered by the PSA Crypto API. - -These involve the following modules: - -- threading -- platform - -It also depends on the X.509 library, which is excluded from further analysis -as the focus here is on dependencies on libmbedcrypto.a. - -Crypto dependencies (high-level) --------------------------------- - -The TLS library depends on the following cryptographic modules: - -- cipher -- dhm -- ecdh -- ecjpake -- ecp -- md -- mpi -- pk -- sha256 -- sha512 - -More specifically, calls are made to the following API functions: - -``` -mbedtls_cipher_auth_decrypt_ext -mbedtls_cipher_auth_encrypt_ext -mbedtls_cipher_crypt -mbedtls_cipher_free -mbedtls_cipher_info_from_type -mbedtls_cipher_init -mbedtls_cipher_set_padding_mode -mbedtls_cipher_setkey -mbedtls_cipher_setup - -mbedtls_dhm_calc_secret -mbedtls_dhm_free -mbedtls_dhm_get_bitlen -mbedtls_dhm_get_len -mbedtls_dhm_get_value -mbedtls_dhm_init -mbedtls_dhm_make_params -mbedtls_dhm_make_public -mbedtls_dhm_read_params -mbedtls_dhm_read_public -mbedtls_dhm_set_group - -mbedtls_ecdh_calc_secret -mbedtls_ecdh_free -mbedtls_ecdh_get_params -mbedtls_ecdh_init -mbedtls_ecdh_make_params -mbedtls_ecdh_make_public -mbedtls_ecdh_read_params -mbedtls_ecdh_read_public -mbedtls_ecdh_setup - -mbedtls_ecjpake_check -mbedtls_ecjpake_derive_secret -mbedtls_ecjpake_free -mbedtls_ecjpake_init -mbedtls_ecjpake_read_round_one -mbedtls_ecjpake_read_round_two -mbedtls_ecjpake_set_point_format -mbedtls_ecjpake_setup -mbedtls_ecjpake_write_round_one -mbedtls_ecjpake_write_round_two - -mbedtls_ecp_curve_info_from_grp_id -mbedtls_ecp_curve_info_from_tls_id - -mbedtls_md_clone -mbedtls_md_finish -mbedtls_md_free -mbedtls_md_get_size -mbedtls_md_get_type -mbedtls_md_hmac_finish -mbedtls_md_hmac_reset -mbedtls_md_hmac_starts -mbedtls_md_hmac_update -mbedtls_md_info_from_type -mbedtls_md_init -mbedtls_md_setup -mbedtls_md_starts -mbedtls_md_update - -mbedtls_mpi_bitlen -mbedtls_mpi_free -mbedtls_mpi_read_binary - -mbedtls_pk_can_do -mbedtls_pk_debug -mbedtls_pk_decrypt -mbedtls_pk_encrypt -mbedtls_pk_get_bitlen -mbedtls_pk_sign -mbedtls_pk_sign_restartable -mbedtls_pk_verify -mbedtls_pk_verify_restartable - -mbedtls_sha256_clone -mbedtls_sha256_finish -mbedtls_sha256_free -mbedtls_sha256_init -mbedtls_sha256_starts -mbedtls_sha256_update - -mbedtls_sha512_clone -mbedtls_sha512_finish -mbedtls_sha512_free -mbedtls_sha512_init -mbedtls_sha512_starts -mbedtls_sha512_update -``` - -Note: the direct dependency on MPI functions is in order to manage DHM -parameters, that are currently stored as a pair of MPIs in the -`mbedtls_ssl_config` structure. (The public API uses byte arrays or a -`mbedtls_dhm_context` structure.) - -Note: the direct dependency on ECP APIs is in order to access information; -no crypto operation is done directly via this API, only via the PK and ECDH -APIs. - -Note: the direct dependencies on the SHA-2 modules instead of using the -MD layer is for convenience (and perhaps to save some memory as well) and can -easily be replace by use of a more generic API. - -Key exchanges and other configuration options ---------------------------------------------- - -In the file-level analysis below, many things are only used if certain key -exchanges or other configuration options are enabled. This section sums up -those key exchanges and options. - -Key exchanges: - -- DHE-PSK -- DHE-RSA -- ECDH-ECDSA -- ECDH-RSA -- ECDHE-ECDSA -- ECDHE-PSK -- ECDHE-RSA -- ECJPAKE -- PSK -- RSA -- RSA-PSK - -Protocol: - -- `MBEDTLS_SSL_PROTO_TLS1_2` -- `MBEDTLS_SSL_PROTO_DTLS` -- `MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL` (excluded from this analysis) - -TLS sides: - -- `MBEDTLS_SSL_CLI_C` -- `MBEDTLS_SSL_SRV_C` - -TLS support modules: - -- `MBEDTLS_SSL_CACHE_C` -- `MBEDTLS_SSL_COOKIE_C` -- `MBEDTLS_SSL_TICKET_C` - -Cipher modes: - -- `MBEDTLS_CIPHER_MODE_CBC` -- `MBEDTLS_CIPHER_NULL_CIPHER` -- `MBEDTLS_GCM_C` -- `MBEDTLS_CCM_C` -- `MBEDTLS_CHACHAPOLY_C` - -Hashes: - -- `MBEDTLS_MD5_C` (ciphersuites using HMAC-MD5) -- `MBEDTLS_SHA1_C` (ciphersuites using HMAC-SHA1) -- `MBEDTLS_SHA256_C` -- `MBEDTLS_SHA512_C` - -Other options: - -- `MBEDTLS_X509_CRT_PARSE_C` -- `MBEDTLS_SSL_SESSION_TICKETS` -- `MBEDTLS_SSL_ENCRYPT_THEN_MAC` - - -File-level analysis -------------------- - -The TLS library consists of the following files (excluding TLS 1.3 which is -currently experimental and changing rapidly): - -``` -library/debug.c -library/net_sockets.c -library/ssl_cache.c -library/ssl_ciphersuites.c -library/ssl_cli.c -library/ssl_cookie.c -library/ssl_msg.c -library/ssl_srv.c -library/ssl_ticket.c -library/ssl_tls.c -``` - -The file `net_sockets.c` is excluded from further analysis as it's unrelated. - -**Note:** Calls to `f_rng` in the files below could also be replaced with -direct calls to the global PSA RNG; however these calls are not included in -the current analysis, since the PSA RNG can already be used by setting it -explicitly. - -### `debug.c` - -- In `debug_print_pk()` - call `mbedtls_pk_debug()` - to print info (or "invalid PK context" on failure) - if `MBEDTLS_X509_CRT_PARSE_C` is enabled. - -- In `mbedtls_debug_print_mpi()` - call `mbedtls_mpi_print_mpi()` - -### `ssl_cache.c` - -**Note:** This module is only used server side. - -No call to any crypto API function from this file. - -_Note :_ in the future, work may be required in order to securely store -session secrets in the cache, but it's outside the scope of this analysis. - -### `ssl_ciphersuites.c` - -No call to any crypto API function from this file. - -### `ssl_cookie.c` - -**Note:** this module is only used server-side, only for DTLS. - -- In `mbedtls_ssl_cookie_init()` / `mbedtls_ssl_cookie_free()` - call `mbedtls_md_init()` / `mbedtls_md_free()` - -- In `mbedtls_ssl_cookie_setup()` - call `mbedtls_md_setup()`, `mbedtls_md_info_from_type()` and `mbedtls_md_hmac_starts()` - to set up an HMAC key. - -- In `ssl_cookie_hmac()` - call `mbedtls_md_hmac_reset()`, `mbedtls_md_hmac_update()` and `mbedtls_md_hmac_finish()` - -### `ssl_ticket.c` - -**Note:** This module is only used server-side. - -- In `ssl_ticket_gen_key()` - call `mbedtls_cipher_setkey()` and `mbedtls_cipher_get_key_bitlen()` - -- In `mbedtls_ssl_ticket_setup()` - call `mbedtls_cipher_info_from_type()` and `mbedtls_cipher_setup()` - -- In `mbedtls_ssl_ticket_write()` - call `mbedtls_cipher_auth_encrypt_ext()` - -- In `mbedtls_ssl_ticket_parse()` - call `mbedtls_cipher_auth_decrypt_ext()` - -### `ssl_cli.c` - -**Note:** This module is only used client-side. - -- In `ssl_write_supported_elliptic_curves_ext()` - call `mbedtls_ecp_curve_list()` and `mbedtls_ecp_curve_info_from_grp_id()` - if ECDH, ECDSA or ECJPAKE is enabled - -- In `ssl_write_ecjpake_kkpp_ext()` - call `mbedtls_ecjpake_check()` and `mbedtls_ecjpake_write_round_one()` - if ECJPAKE is enabled - -- In `ssl_parse_supported_point_formats_ext()` - call `mbedtls_ecjpake_set_point_format()` - if ECJPAKE is enabled. - -- In `ssl_validate_ciphersuite()` - call `mbedtls_ecjpake_check()` - if ECJPAKE is enabled. - -- In `ssl_parse_ecjpake_kkpp()` - call `mbedtls_ecjpake_read_round_one()` - if ECJPAKE is enabled. - -- In `ssl_parse_server_dh_params()` - call `mbedtls_dhm_read_params()` and `mbedtls_dhm_get_bitlen()` - if DHE-RSA or DHE-PSK key echange is enabled. - -- In `ssl_check_server_ecdh_params()` - call `mbedtls_ecp_curve_info_from_grp_id()` - if ECDHE-RSA, ECDHE-ECDSA, ECDHE-PSK, ECDH-RSA or ECDH-ECDSA key exchange is enabled. - -- In `ssl_parse_server_ecdh_params()` - call `mbedtls_ecdh_read_params()` - if ECDHE-RSA, ECDHE-ECDSA or ECDHE-PSK is enabled. - -- In `ssl_write_encrypted_pms()` - call `mbedtls_pk_can_do()` and `mbedtls_pk_encrypt()` on peer's public key - if RSA or RSA-PSK key exchange enabled. - -- In `ssl_get_ecdh_params_from_cert()` - call `mbedtls_pk_can_do()` and `mbedtls_pk_ec()` and `mbedtls_ecdh_get_params()` - if ECDH-RSA or ECDH-ECDSA key exchange is enabled - to import public key of peer's cert to ECDH context. - -- In `ssl_parse_server_key_exchange()` - call `mbedtls_ecjpake_read_round_two()` - if ECJPAKE is enabled. - -- In `ssl_parse_server_key_exchange()` - call `mbedtls_pk_can_do()` and `mbedtls_pk_verify_restartable()` - if DHE-RSA, ECDHE-RSA or ECDHE-ECDSA is enabled. - (Note: the hash is computed by `mbedtls_ssl_get_key_exchange_md_tls1_2()`.) - -- In `ssl_write_client_key_exchange()` - call `mbedtls_dhm_make_public()`, `mbedtls_dhm_get_len()` and `mbedtls_dhm_calc_secret()` - if DHE-RSA key exchange is enabled. - -- In `ssl_write_client_key_exchange()` - call `mbedtls_ecdh_make_public()` and `mbedtls_ecdh_calc_secret()` - if ECDHE-RSA, ECDHE-ECDSA, ECDH-RSA or ECDH-ECDSA is enabled. - -- In `ssl_write_client_key_exchange()` - call `mbedtls_dhm_make_public()` and `mbedtls_dhm_get_len()` - if DHE-PSK is enabled. - -- In `ssl_write_client_key_exchange()` - call `mbedtls_ecdh_make_public()` - if ECDHE-PSK is enabled. - -- In `ssl_write_client_key_exchange()` - call `mbedtls_ecjpake_write_round_two()` and `mbedtls_ecjpake_derive_secret()` - if ECJPAKE is enabled. - -- In `ssl_write_certificate_verify()` - call `mbedtls_pk_can_do()` and `mbedtls_pk_sign_restartable()` - if RSA, DHE-RSA, ECDH-RSA, ECDHE-RSA, ECDH-ECDSA or ECDHE-ECDSA is enabled. - (Note: the hash is computed by `calc_verify()`.) - -### `ssl_srv.c` - -**Note:** This module is only used server-side. - -- In `ssl_parse_supported_elliptic_curves()` - call `mbedtls_ecp_curve_info_from_tls_id()` - if ECDH, ECDSA or ECJPAKE is enabled. - -- In `ssl_parse_supported_point_formats()` - call `mbedtls_ecjpake_set_point_format()` - if ECJPAKE is enabled. - -- In `ssl_parse_ecjpake_kkpp()` - call `mbedtls_ecjpake_check()` and `mbedtls_ecjpake_read_round_one()` - if ECJPAKE is enabled. - -- In `ssl_check_key_curve()` to get group ID - call `mbedtls_pk_ec()` - if certificates and ECDSA are enabled. - -- In `ssl_pick_cert()` - call `mbedtls_pk_can_do()` - if certificates are enabled. - -- In `ssl_write_encrypt_then_mac_ext()` - call `mbedtls_cipher_info_from_type()` on ciphersuite info - if EtM is enabled - -- In `ssl_write_ecjpake_kkpp_ext()` - call `mbedtls_ecjpake_write_round_one()` - if ECJPAKE is enabled. - -- In `ssl_get_ecdh_params_from_cert()` - call `mbedtls_pk_can_do()`, `mbedtls_pk_ec()` and `mbedtls_ecdh_get_params()` - if ECDH-RSA or ECDH-ECDSA is enabled, - in order to import own private key to ecdh context. - -- In `ssl_prepare_server_key_exchange()` - call `mbedtls_ecjpake_write_round_two()` - if ECJPAKE is enabled. - -- In `ssl_prepare_server_key_exchange()` - call `mbedtls_dhm_set_group()`, `mbedtls_dhm_make_params()` and `mbedtls_dhm_get_len()` - if DHE-RSA or DHE-PSK key exchange is enabled. - -- In `ssl_prepare_server_key_exchange()` - call `mbedtls_ecdh_setup()` and `mbedtls_ecdh_make_params()` - if ECDHE-RSA, ECDHE-ECDSA or ECDHE-PSK is enabled. - -- In `ssl_prepare_server_key_exchange()` - call `mbedtls_pk_sign()` from `ssl_prepare_server_key_exchange()` - if DHE-RSA, ECDHE-RSA or ECDHE-ECDSA is enabled. - -- In `ssl_parse_client_dh_public()` - call `mbedtls_dhm_read_public()` - if DHE-RSA or DHE-PSK is enabled. - -- In `ssl_decrypt_encrypted_pms()` - call `mbedtls_pk_get_len()`, `mbedtls_pk_can_do()` and `mbedtls_pk_decrypt()` - if RSA or RSA-PSK key exchange is enabled. - -- In `ssl_parse_client_key_exchange()` - call `mbedtls_dhm_calc_secret()` - if DHE-RSA enabled. - (Note: `ssl_parse_client_dh_public()` called first.) - -- In `ssl_parse_client_key_exchange()` - call `mbedtls_ecdh_read_public()` and `mbedtls_ecdh_calc_secret()` - if ECDHE-RSA, ECDHE-ECDSA, ECDH-RSA or ECDH-ECDSA enabled. - -- In `ssl_parse_client_key_exchange()` - call `mbedtls_ecdh_read_public()` - if ECDHE-PSK enabled. - (Note: calling `mbedtls_ssl_psk_derive_premaster()` afterwards.) - -- In `ssl_parse_client_key_exchange()` - call `mbedtls_ecjpake_read_round_two()` and `mbedtls_ecjpake_derive_secret()` - if ECJPAKE enabled. - -- In `ssl_parse_certificate_verify()` - call `mbedtls_pk_can_do()` and `mbedtls_pk_verify()` - if RSA, DHE-RSA, ECDH-RSA, ECDHE-RSA, ECDH-ECDSA or ECDHE-ECDSA enabled. - -### `ssl_tls.c` - -**Note:** This module is used both server-side and client-side. - -- In `tls_prf_generic()` - call `mbedtls_md_init()`, `mbedtls_md_info_from_type()`, `mbedtls_md_get_size()`, `mbedtls_md_setup()`, `mbedtls_md_hmac_starts()`, `mbedtls_md_hmac_update()`, `mbedtls_md_hmac_finish()`, `mbedtls_md_hmac_reset()` and `mbedtls_md_free()` - -- In `mbedtls_ssl_derive_keys()` - call `mbedtls_cipher_info_from_type()`, `mbedtls_cipher_setup_psa()` or `mbedtls_cipher_setup()`, `mbedtls_cipher_setkey()`, and `mbedtls_cipher_set_padding_mode()` - -- In `mbedtls_ssl_derive_keys()`. - call `mbedtls_md_info_from_type()`, `mbedtls_md_setup()`, `mbedtls_md_get_size()` and `mbedtls_md_hmac_starts()` - Note: should be only if CBC/NULL ciphersuites enabled, but is currently unconditional. - -- In `ssl_calc_verify_tls_sha256()` - call `mbedtls_sha256_init()` `mbedtls_sha256_clone()` `mbedtls_sha256_finish()` `mbedtls_sha256_free()` - if SHA256 is enabled. - -- In `ssl_calc_verify_tls_sha384()` - call `mbedtls_sha512_init()` `mbedtls_sha512_clone()` `mbedtls_sha512_finish()` `mbedtls_sha512_free()` - if SHA512 is enabled. - -- In `mbedtls_ssl_psk_derive_premaster()` - call `mbedtls_dhm_calc_secret()` - if DHE-PSK is enabled. - -- In `mbedtls_ssl_psk_derive_premaster()` - call `mbedtls_ecdh_calc_secret()` - if ECDHE-PSK is enabled. - -- In `ssl_encrypt_buf()` - call `mbedtls_cipher_get_cipher_mode()` `mbedtls_md_hmac_update()` `mbedtls_md_hmac_finish()` `mbedtls_md_hmac_reset()` `mbedtls_cipher_crypt()` - if CBC or NULL is enabled. - -- In `ssl_encrypt_buf()` - call `mbedtls_cipher_get_cipher_mode()`, `mbedtls_cipher_auth_encrypt()` - if GCM, CCM or CHACHAPOLY is enabled. - -- In `ssl_decrypt_buf()` - call `mbedtls_cipher_get_cipher_mode()` `mbedtls_md_hmac_update()` `mbedtls_md_hmac_finish()` `mbedtls_md_hmac_reset()` `mbedtls_cipher_crypt()` - if CBC and Encrypt-then-Mac -are enabled. - -- In `mbedtls_ssl_cf_hmac()` - call `mbedtls_md_clone()` - if CBC or NULL is enabled. - -- In `ssl_decrypt_buf()` - call `mbedtls_cipher_get_cipher_mode()`, `mbedtls_cipher_auth_decrypt()` - if GCM, CCM or CHACHAPOLY is enabled. - -- In `mbedtls_ssl_parse_certificate()` - call `mbedtls_pk_can_do()` and `mbedtls_pk_ec()` - to get and check group ID. - -- In `mbedtls_ssl_reset_checksum()`. - call `mbedtls_sha256_starts()` `mbedtls_sha512_starts()` - -- In `ssl_update_checksum_start()`. - call `mbedtls_sha256_update()` `mbedtls_sha512_update()` - -- In `ssl_update_checksum_sha256()` - call `mbedtls_sha256_update()` - if SHA256 is enabled. - -- In `ssl_update_checksum_sha512()` - call `mbedtls_sha512_update()` - if SHA512 is enabled. - -- In `ssl_calc_finished_tls_sha256()` - call `mbedtls_sha256_init()` `mbedtls_sha256_clone()` `mbedtls_sha256_finish()` `mbedtls_sha256_free()` - if SHA256 is enabled. - -- In `ssl_calc_finished_tls_sha512()` - call `mbedtls_sha512_init()` `mbedtls_sha512_clone()` `mbedtls_sha512_finish()` `mbedtls_sha512_free()` - if SHA512 is enabled. - -- In `ssl_handshake_params_init()`. - call `mbedtls_sha256_init()` `mbedtls_sha256_starts()` `mbedtls_sha512_init()` `mbedtls_sha512_starts()` `mbedtls_dhm_init()` `mbedtls_ecdh_init()` `mbedtls_ecjpake_init()` - -- In `ssl_transform_init()`. - call `mbedtls_cipher_init()` `mbedtls_md_init()` - -- In `mbedtls_ssl_set_hs_ecjpake_password()` - call `mbedtls_ecjpake_setup()` - if ECJPAKE is enabled. - -- In `mbedtls_ssl_conf_dh_param_bin()` - call `mbedtls_mpi_read_binary()` and `mbedtls_mpi_free()` - if DHM and SRV are enabled. - -- In `mbedtls_ssl_conf_dh_param_ctx()` - call `mbedtls_dhm_get_value()` and `mbedtls_mpi_free()` - if DHM and SRV are enabled. - -- In `mbedtls_ssl_get_record_expansion()`. - call `mbedtls_cipher_get_cipher_mode()` and `mbedtls_cipher_get_block_size()` - -- In `mbedtls_ssl_transform_free()`. - call `mbedtls_cipher_free()` and `mbedtls_md_free()` - -- In `mbedtls_ssl_handshake_free()`. - call `mbedtls_sha256_free()` `mbedtls_sha512_free()` `mbedtls_dhm_free()` `mbedtls_ecdh_free()` `mbedtls_ecjpake_free()` - -- In `mbedtls_ssl_config_free()` - call `mbedtls_mpi_free()` - if DHM is enabled. - -- In `mbedtls_ssl_sig_from_pk()`. - call `mbedtls_pk_can_do()` - -- In `mbedtls_ssl_get_key_exchange_md_tls1_2()` - call `mbedtls_md_info_from_type()` `mbedtls_md_get_size()` `mbedtls_md_init()` `mbedtls_md_setup()` `mbedtls_md_starts()` `mbedtls_md_update()` `mbedtls_md_update()` `mbedtls_md_finish()` `mbedtls_md_free()` diff --git a/docs/architecture/psa-migration/dependencies-x509.md b/docs/architecture/psa-migration/dependencies-x509.md deleted file mode 100644 index dfbff8304a68..000000000000 --- a/docs/architecture/psa-migration/dependencies-x509.md +++ /dev/null @@ -1,206 +0,0 @@ -Dependencies of the X.509 library on the Crypto library -======================================================= - -This document is part of the technical study on how to port Mbed TLS to PSA -Crypto. It describes the dependencies of libmbedx509.a on libmbedcrypto.a. - -More precisely, it describes what functions from libmbedcrypto.a are called -from libmbedx509.a - other forms of dependencies such as using static inline -functions or types, accessing private struct members, etc., are not listed. - -It is based on Mbed TLS 3.0, excluding support for restartble ECP operations. - -Non-Crypto dependencies ------------------------ - -The X.509 library has a number of dependencies on libmbedcrypto.a that are not -cryptographic, hence are unlikely to be covered by the PSA Crypto API. - -These involve the following modules: - -- asn1 -- oid -- pem -- platform -- threading - -Crypto dependencies (high-level) --------------------------------- - -The X.509 library depends on the following cryptographic modules: - -- pk -- md -- mpi -- sha1 - -More specifically, calls are made to the following API functions: - -``` -mbedtls_pk_can_do -mbedtls_pk_free -mbedtls_pk_get_bitlen -mbedtls_pk_get_name -mbedtls_pk_get_type -mbedtls_pk_load_file -mbedtls_pk_parse_subpubkey -mbedtls_pk_sign -mbedtls_pk_verify_ext -mbedtls_pk_write_pubkey -mbedtls_pk_write_pubkey_der - -mbedtls_md -mbedtls_md_get_name -mbedtls_md_get_size -mbedtls_md_info_from_type - -mbedtls_mpi_copy -mbedtls_mpi_free -mbedtls_mpi_init - -mbedtls_sha1 -``` - -Note: the dependency on MPI is because the certificate's serial number is -stored as an MPI in `struct mbedtls_x509write_cert` - the MPI is used purely -as a container for bytes. The depencency is embedded in the public API as -`mbedtls_x509write_crt_set_serial` take an argument of type `mbedtls_mpi *`. - -Note: the direct dependency on SHA1 is in `x509write_crt.c` and makes sense -because it's the only hash that can be used to compute key identifiers for the -Subject Key Identifier and Authority Key Identifier extensions. Replacing that -with an algorithm-agnistic API would or course be easy. - -File by file analysis ---------------------- - -The X.509 library consists of the following C files and associated headers: -``` -x509.c -x509_create.c -x509_crl.c -x509_crt.c -x509_csr.c -x509write_crt.c -x509write_csr.c -``` - -### `x509.c` - -- In `mbedtls_x509_sig_alg_gets()` - call `mbedtls_md_info_from_type()` and `mbedtls_md_get_name()` - to print out information - -### `x509_crl.c` - -- In `mbedtls_x509_crl_parse_file()` - call `mbedtls_pk_load_file()` - to load files if `MBEDTLS_FS_IO` defined - -### `x509_crt.c` - -**Note:** All calls to PK APIs in this file use public (not private) keys. - -- In `x509_profile_check_key()` - call `mbedtls_pk_get_type()` and `mbedtls_pk_get_bitlen()` - -- In `x509_profile_check_key()` - call `mbedtls_pk_ec()` - to get the group id - -- In `x509_crt_parse_der_core()` - call `mbedtls_pk_parse_subpubkey()` - -- In `mbedtls_x509_crt_parse_file()` - call `mbedtls_pk_load_file()` - to load files if `MBEDTLS_FS_IO` defined - -- In `mbedtls_x509_crt_info()` - call `mbedtls_pk_get_name()` and `mbedtls_pk_get_bitlen()` - to print out information - -- In `x509_crt_verifycrl()` - call `mbedtls_md_info_from_type()`, `mbedtls_md()`, `mbedtls_pk_verify_ext()` and `mbedtls_md_get_size()` - to verify CRL signature - -- In `x509_crt_check_signature()` - call `mbedtls_md_info_from_type()`, `mbedtls_md_get_size()`, `mbedtls_md()`, then `mbedtls_pk_can_do()` and `mbedtls_pk_verify_ext()` - to verify certificate signature - -- In `x509_crt_verify_restartable_ca_cb()` - call `mbedtls_pk_get_type()` - to check against profile - -- In `mbedtls_x509_crt_free()` - call `mbedtls_pk_free()` - -### `x509_csr.c` - -**Note:** All calls to PK APIs in this file use public (not private) keys. - -- In `mbedtls_x509_csr_parse_der()` - call `mbedtls_pk_parse_subpubkey()` - -- In `mbedtls_x509_csr_parse_file()` - call `mbedtls_pk_load_file()` - to load files if `MBEDTLS_FS_IO` defined - -- In `mbedtls_x509_csr_info()` - call `mbedtls_pk_get_name()` and `mbedtls_pk_get_bitlen()` - to print out information - -- In `mbedtls_x509_csr_free()` - call `mbedtls_pk_free()` - -### `x509_create.c` - -No call to crypto functions - mostly ASN.1 writing and data conversion. - -### `x509write_crt.c` - -**Note:** Calls to PK APIs in this file are both on public and private keys. - -- In `mbedtls_x509write_crt_init()`, resp. `mbedtls_x509write_crt_free()` - call `mbedtls_mpi_init()`, resp. `mbedtls_mpi_free()` - to manage the serial number - -- In `mbedtls_x509write_crt_set_serial()` - call `mbedtls_mpi_copy()` - -- In `mbedtls_x509write_crt_set_subject_key_identifier()` and `mbedtls_x509write_crt_set_authority_key_identifier()` - call `mbedtls_pk_write_pubkey()` and `mbedtls_sha1_ret()` - -- In `mbedtls_x509write_crt_der()` - call `mbedtls_pk_can_do()` - on a private key (issuer) - to write out correct signature algorithm - -- In `mbedtls_x509write_crt_der()` - call `mbedtls_pk_write_pubkey_der()` - on a public key (subject) - -- In `mbedtls_x509write_crt_der()` - call `mbedtls_md_info_from_type()` and `mbedtls_md()` - to prepare for signing - -- In `mbedtls_x509write_crt_der()` - call `mbedtls_pk_sign()` - on a private key (issuer) - to sign certificate being issued - -### `x509write_csr.c` - -**Note:** All calls for PK APIs in this file are on private (not public) keys - -- In `mbedtls_x509write_csr_der()` - call `mbedtls_pk_write_pubkey_der()` - -- In `mbedtls_x509write_csr_der()` - call `mbedtls_md_info_from_type()` and `mbedtls_md()` - -- In `mbedtls_x509write_csr_der()` - call `mbedtls_pk_sign()` - -- Call `mbedtls_pk_can_do()` - on a private key (writer's) - to write out correct signature algorithm diff --git a/docs/architecture/psa-migration/tasks-g1.md b/docs/architecture/psa-migration/tasks-g1.md deleted file mode 100644 index d906bf9ea5ef..000000000000 --- a/docs/architecture/psa-migration/tasks-g1.md +++ /dev/null @@ -1,114 +0,0 @@ -This document is temporary; it lists tasks to achieve G1 as described in -`strategy.md` while the strategy is being reviewed - once that's done, -corresponding github issues will be created and this document removed. - -For all of the tasks here, no specific testing is expected to be required, -beyond passing the existing tests in a build with `MBEDTLS_USE_PSA_ENABLED`, -see `testing.md`. - -Symmetric crypto -================ - -Hashes ------- - -### Use `psa_hash` in all of X.509 - -https://github.com/ARMmbed/mbedtls/issues/5157 - -HMAC ----- - -### Variable-time HMAC in TLS record protection - -https://github.com/ARMmbed/mbedtls/issues/5177 - -### Constant-time HMAC in TLS record protection - -https://github.com/ARMmbed/mbedtls/issues/5178 - - -Ciphers -------- - -### Use PSA for all cipher operations in TLS - -https://github.com/ARMmbed/mbedtls/issues/5181 -https://github.com/ARMmbed/mbedtls/issues/5182 -https://github.com/ARMmbed/mbedtls/issues/5203 -https://github.com/ARMmbed/mbedtls/issues/5204 -https://github.com/ARMmbed/mbedtls/issues/5205 -https://github.com/ARMmbed/mbedtls/issues/5206 - -Asymmetric crypto -================= - -ECDSA ------ - -### Make `mbedtls_pk_sign()` use PSA for ECDSA operations - -https://github.com/ARMmbed/mbedtls/issues/5274 - -RSA signature (and verification) --------------------------------- - -### Make `mbedtls_pk_sign()` use PSA for RSA operations - -https://github.com/ARMmbed/mbedtls/issues/5162 - -### Make `mbedtls_pk_verify()` use PSA for RSA operations - -https://github.com/ARMmbed/mbedtls/issues/5159 - -### Make `mbedtls_pk_verify_ext()` use PSA for RSA operations - -https://github.com/ARMmbed/mbedtls/issues/5333 (partial) -https://github.com/ARMmbed/mbedtls/issues/5277 (futher) - -RSA en/decryption ------------------ - -### Make `mbedtls_pk_encrypt()` use PSA for RSA operations - - -https://github.com/ARMmbed/mbedtls/issues/5161 - -### Make `mbedtls_pk_decrypt()` use PSA for RSA operations - -https://github.com/ARMmbed/mbedtls/issues/5160 - -ECDH ----- - -Additional: -https://github.com/ARMmbed/mbedtls/issues/5291 (pre clean-up) -https://github.com/ARMmbed/mbedtls/issues/5321 (TLS 1.3) -https://github.com/ARMmbed/mbedtls/issues/5322 (post clean-up) - -### Write remaining utilities for ECDH parsing/writing - -(not a task on its own, part of other tasks) - -### Use PSA for ECDHE in ECDHE-ECDSA and ECDHE-RSA server-side - -https://github.com/ARMmbed/mbedtls/issues/5317 - -### Use PSA for ECDH in ECDHE-PSK (all sides and versions) - -https://github.com/ARMmbed/mbedtls/issues/5318 - -### Use PSA for ECDH in static-ECDH key exchanges - -https://github.com/ARMmbed/mbedtls/issues/5319 -https://github.com/ARMmbed/mbedtls/issues/5320 - -FFDH ----- - -https://github.com/ARMmbed/mbedtls/issues/5287 - -EC J-PAKE ---------- - -https://github.com/ARMmbed/mbedtls/issues/5275 From 8e559daaa85dbd9afeb659a26b962c633f699bc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 1 Feb 2022 10:26:07 +0100 Subject: [PATCH 15/21] Misc updates to psa-limitations.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- .../psa-migration/psa-limitations.md | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/docs/architecture/psa-migration/psa-limitations.md b/docs/architecture/psa-migration/psa-limitations.md index 54d1ed8532b4..01fd188db4c2 100644 --- a/docs/architecture/psa-migration/psa-limitations.md +++ b/docs/architecture/psa-migration/psa-limitations.md @@ -1,7 +1,7 @@ This document lists current limitations of the PSA Crypto API (as of version 1.1) that may impact our ability to (1) use it for all crypto operations in TLS and X.509 and (2) support isolation of all long-term secrets in TLS (that -is, goals G1 and G2 in [strategy.md][] in the same directory). +is, goals G1 and G2 in [strategy.md](strategy.md) in the same directory). This is supposed to be a complete list, based on a exhaustive review of crypto operations done in TLS and X.509 code, but of course it's still possible that @@ -20,9 +20,25 @@ implementation, would be non-trivial. Currently, `MBEDTLS_USE_PSA_CRYPTO` is simply incompatible with `MBEDTLS_ECP_RESTARTABLE`. +Things that are in the API but not implemented yet +-------------------------------------------------- + +PSA Crypto has an API for FFDH, but it's not implemented in Mbed TLS yet. +(Regarding FFDH, see the next section as well.) See issue [3261][ffdh] on +github. + +[ffdh]: https://github.com/ARMmbed/mbedtls/issues/3261 + +PSA Crypto has an experimental API for EC J-PAKE, but it's not implemented in +Mbed TLS yet. See the [EC J-PAKE follow-up EPIC][ecjp] on github. + +[ecjp]: https://github.com/orgs/ARMmbed/projects/18#column-15836385 + Arbitrary parameters for FFDH ----------------------------- +(See also the first paragraph in the previous section.) + Currently, the PSA Crypto API can only perform FFDH with a limited set of well-know parameters (some of them defined in the spec, but implementations are free to extend that set). @@ -104,7 +120,7 @@ algorithms can differ from each other. - hash alg used for message hashing, encoding and MGF1 - salt length can be either "standard" (== hashlen) or "any" - signature generation: - - salt length: always using the maximum legal value + - salt length: always using the maximum legal value and random salt - verification: - salt length: either == hashlen, or any depending on algorithm @@ -142,7 +158,8 @@ match a limitation of the PSA API. It is unclear what parameters people use in practice. It looks like by default OpenSSL picks saltlen = keylen - hashlen - 2 (tested with openssl 1.1.1f). The `certool` command provided by GnuTLS seems to be picking saltlen = hashlen -by default (tested with GnuTLS 3.6.13). +by default (tested with GnuTLS 3.6.13). FIPS 186-4 recommends saltlen >= +hashlen. ### Use in TLS @@ -317,7 +334,8 @@ HKDF-Extract : that is, the traffic keys are computed as In the short term (early 2022), we'll work around that by re-implementing HKDF in `ssl_tls13_keys.c` based on the `psa_mac_` APIs (for HMAC). -In the long term, it is desirable to extend the PSA API. +In the long term, it is desirable to extend the PSA API. See +https://github.com/ARM-software/psa-crypto-api/issues/539 Limitations relevant for G2 (isolation of long-term secrets) ============================================================ From ce6c0875d1299fee7b7364f77eb1874e9ba7ca5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 1 Feb 2022 10:34:20 +0100 Subject: [PATCH 16/21] Misc updates to strategy.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/strategy.md | 32 ++++++++------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/docs/architecture/psa-migration/strategy.md b/docs/architecture/psa-migration/strategy.md index fe15bc19c876..e508975779a3 100644 --- a/docs/architecture/psa-migration/strategy.md +++ b/docs/architecture/psa-migration/strategy.md @@ -39,7 +39,10 @@ We currently have two compile-time options that are relevant to the migration: The reasons why `MBEDTLS_USE_PSA_CRYPTO` is optional and disabled by default are: -- it's incompatible with `MBEDTLS_ECP_RESTARTABLE`, and `MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER`; +- it's incompatible with `MBEDTLS_ECP_RESTARTABLE`; +- historical: used to be incompatible + `MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER` (fixed early 2022, see + ); - it does not work well with `MBEDTLS_PSA_CRYPTO_CONFIG` (could compile with both of them, but then `MBEDTLS_PSA_CRYPTO_CONFIG` won't have the desired effect) @@ -47,10 +50,13 @@ effect) `MBEDTLS_PSA_CRYPTO_C`, for backards compatibility reasons: - when `MBEDTLS_PSA_CRYPTO_C` is enabled and used, applications need to call `psa_crypto_init()` before TLS/X.509 uses PSA functions - - `MBEDTLS_PSA_CRYPTO_C` has a hard depend on `MBEDTLS_ENTROPY_C` but it's - currently possible to compilte TLS and X.509 without `MBEDTLS_ENTROPY_C`. + - `MBEDTLS_PSA_CRYPTO_C` has a hard depend on `MBEDTLS_ENTROPY_C || + MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` but it's + currently possible to compilte TLS and X.509 without any of the options. Also, we can't just auto-enable `MBEDTLS_ENTROPY_C` as it doesn't build - out of the box on all platforms. + out of the box on all platforms, and even less + `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` as it requires a user-provided RNG + function. The downside of this approach is that until we feel ready to make `MBDEDTLS_USE_PSA_CRYPTO` non-optional (always enabled), we have to maintain @@ -82,6 +88,8 @@ restartable behaviour was requested at run-time (in addition to enabling ### `MBEDTLS_PSA_CRYPTO_CONFIG` +(This section taken from a comment by Gilles.) + X509 and TLS code use `MBEDTLS_xxx` macros to decide whether an algorithm is supported. This doesn't make `MBEDTLS_USE_PSA_CRYPTO` incompatible with `MBEDTLS_PSA_CRYPTO_CONFIG` per se, but it makes it incompatible with most @@ -106,22 +114,6 @@ to the existing code and the less code there is at this point the better, whereas extending to more procotol features will require the same amount of work either way. -### `MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER` - -When `MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER` is enabled, the library is -built for use with an RPC server that dispatches PSA crypto function calls -from multiple clients. In such a build, all the `psa_xxx` functions that take -would normally take a `psa_key_id_t` as argument instead take a structure -containing both the key id and the client id. And so if e.g. a TLS function -calls `psa_import_key`, it would have to pass this structure, not just the -`psa_key_id_t` key id. - -A solution is to use `mbedtls_svc_key_id_t` throughout instead of -`psa_key_id_t`, and use similar abstractions to define values. - -That's what we're implemementing in early 2022, see -https://github.com/ARMmbed/mbedtls/issues/5259 - ### Backwars compatibility issues with making it always on 1. Existing applications may not be calling `psa_crypto_init()` before using From 2467aed96150ca6254f675f2ede6c7412a9d5645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 1 Feb 2022 10:42:30 +0100 Subject: [PATCH 17/21] Misc updates to testing.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/testing.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/architecture/psa-migration/testing.md b/docs/architecture/psa-migration/testing.md index 754686b404f1..6ed294a6cbe7 100644 --- a/docs/architecture/psa-migration/testing.md +++ b/docs/architecture/psa-migration/testing.md @@ -9,9 +9,11 @@ General considerations ---------------------- There needs to be at least one build in `all.sh` that enables -`MBEDTLS_USE_PSA_CRYPTO` and runs the full battery of tests. Currently that's +`MBEDTLS_USE_PSA_CRYPTO` and runs the full battery of tests; currently that's ensured by the fact that `scripts/config.py full` enables -`MBEDTLS_USE_PSA_CRYPTO`. +`MBEDTLS_USE_PSA_CRYPTO`. There needs to be at least one build with +`MBEDTLS_USE_PSA_CRYPTO` disabled (as long as it's optional); currently that's +ensured by the fact that it's disabled in the default config. Generally, code review is enough to ensure that PSA APIs are indeed used where they should be when `MBEDTLS_USE_PSA_CRYPTO` is enabled. @@ -56,8 +58,9 @@ In that case, we want: (We should have something similar for `mbedtls_x509write_crt_set_issuer_key()`.) -For some APIs, for example with `mbedtls_ssl_conf_psk_opaque()`, unit testing -does not make sense, so we only have integration testing. +For some APIs, for example with `mbedtls_ssl_conf_psk_opaque()`, testing in +`test_suite_ssl` was historicaly not possible, so we only have testing in +`ssl-opt.sh`. New APIs meant for internal use ------------------------------- @@ -89,7 +92,8 @@ For example, use of PSA to compute the TLS 1.2 PRF. Changes in this category rarely require specific testing, as everything should be already be covered by running the existing tests in a build with -`MBEDTLS_USE_PSA_CRYPTO` enabled. +`MBEDTLS_USE_PSA_CRYPTO` enabled; however we need to make sure the existing +test have sufficient coveraged, and improve them if necessary. However, if additional logic is involved, or there are run-time decisions about whether to use the PSA or legacy code paths, specific tests might be in order. From 539b9a52f9553e0921b7b74ef245e44c9389ad3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 7 Feb 2022 10:19:08 +0100 Subject: [PATCH 18/21] Fix discussion of RSA-PSS salt length MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/psa-limitations.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/architecture/psa-migration/psa-limitations.md b/docs/architecture/psa-migration/psa-limitations.md index 01fd188db4c2..53dd4a82cd11 100644 --- a/docs/architecture/psa-migration/psa-limitations.md +++ b/docs/architecture/psa-migration/psa-limitations.md @@ -118,11 +118,15 @@ algorithms can differ from each other. - PSA: - algorithm specification: - hash alg used for message hashing, encoding and MGF1 - - salt length can be either "standard" (== hashlen) or "any" + - salt length can be either "standard" (<= hashlen, see note) or "any" - signature generation: - - salt length: always using the maximum legal value and random salt + - salt length: always <= hashlen (see note) and random salt - verification: - - salt length: either == hashlen, or any depending on algorithm + - salt length: either <= hashlen (see note), or any depending on algorithm + +Note: above, "<= hashlen" means that hashlen is used if possible, but if it +doesn't fit because the key is too short, then the maximum lenght that fits is +used. The RSA/PK API is in principle more flexible than the PSA Crypto API. The following sub-sections study whether and how this matters in practice. @@ -158,7 +162,7 @@ match a limitation of the PSA API. It is unclear what parameters people use in practice. It looks like by default OpenSSL picks saltlen = keylen - hashlen - 2 (tested with openssl 1.1.1f). The `certool` command provided by GnuTLS seems to be picking saltlen = hashlen -by default (tested with GnuTLS 3.6.13). FIPS 186-4 recommends saltlen >= +by default (tested with GnuTLS 3.6.13). FIPS 186-4 recommends 0 <= saltlen <= hashlen. ### Use in TLS From 8ebed2121654dc6c0c7fa44760860ee2f9238dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 7 Feb 2022 10:23:49 +0100 Subject: [PATCH 19/21] Fix a few typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- .../psa-migration/psa-limitations.md | 2 +- docs/architecture/psa-migration/strategy.md | 26 +++++++++---------- docs/architecture/psa-migration/testing.md | 6 ++--- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/architecture/psa-migration/psa-limitations.md b/docs/architecture/psa-migration/psa-limitations.md index 53dd4a82cd11..0986f1ba56d1 100644 --- a/docs/architecture/psa-migration/psa-limitations.md +++ b/docs/architecture/psa-migration/psa-limitations.md @@ -381,7 +381,7 @@ sensitive.) HKDF: Expand not exposed on its own (TLS 1.3) --------------------------------------------- -See the section with the same namw in the G1 part above for background. +See the section with the same name in the G1 part above for background. The work-around mentioned there works well enough just for acceleration, but is not sufficient for key isolation or generally proper key management (it diff --git a/docs/architecture/psa-migration/strategy.md b/docs/architecture/psa-migration/strategy.md index e508975779a3..8fb8ce5fea70 100644 --- a/docs/architecture/psa-migration/strategy.md +++ b/docs/architecture/psa-migration/strategy.md @@ -8,7 +8,7 @@ Several benefits are expected from migrating to PSA Crypto: G1. Use PSA Crypto drivers when available. G2. Allow isolation of long-term secrets (for example, private keys). -G3. Allow isolation of short-term secrets (for example, TLS sesssion keys). +G3. Allow isolation of short-term secrets (for example, TLS session keys). G4. Have a clean, unified API for Crypto (retire the legacy API). G5. Code size: compile out our implementation when a driver is available. @@ -20,7 +20,7 @@ Generally speaking, the numbering above doesn't mean that each goal requires the preceding ones to be completed, for example G2-G5 could be done in any order; however they all either depend on G1 or are just much more convenient if G1 is done before (note that this is not a dependency on G1 being complete, -it's more like each bit of G2-G5 is helped by some speficic bit in G1). +it's more like each bit of G2-G5 is helped by some specific bit in G1). So, a solid intermediate goal would be to complete (G1) when `MBEDTLS_USA_PSA_CRYPTO` is enabled - that is, all crypto operations in X.509 @@ -47,7 +47,7 @@ are: both of them, but then `MBEDTLS_PSA_CRYPTO_CONFIG` won't have the desired effect) - to avoid a hard/default dependency of TLS, X.509 and PK on - `MBEDTLS_PSA_CRYPTO_C`, for backards compatibility reasons: + `MBEDTLS_PSA_CRYPTO_C`, for backwards compatibility reasons: - when `MBEDTLS_PSA_CRYPTO_C` is enabled and used, applications need to call `psa_crypto_init()` before TLS/X.509 uses PSA functions - `MBEDTLS_PSA_CRYPTO_C` has a hard depend on `MBEDTLS_ENTROPY_C || @@ -109,12 +109,12 @@ I don't know what the priority is for `MBEDTLS_USE_PSA_CRYPTO` between improving driver support and covering more of the protocol. It seems to me that it'll be less work overall to first implement a good architecture for `MBEDTLS_USE_PSA_CRYPTO + MBEDTLS_PSA_CRYPTO_CONFIG` and then extend to more -protocol featues, because implementing that architecture will require changes +protocol features, because implementing that architecture will require changes to the existing code and the less code there is at this point the better, -whereas extending to more procotol features will require the same amount of +whereas extending to more protocol features will require the same amount of work either way. -### Backwars compatibility issues with making it always on +### Backwards compatibility issues with making it always on 1. Existing applications may not be calling `psa_crypto_init()` before using TLS, X.509 or PK. We can try to work around that by calling (the relevant @@ -223,7 +223,7 @@ one-shot function `mbedtls_md()`. There are two variants of this strategy: one where using the new setup function also allows for key isolation (the key is only held by PSA, supporting both G1 and G2 in that area), and one without isolation (the key is -still stored outsde of PSA most of the time, supporting only G1). +still stored outsede of PSA most of the time, supporting only G1). This strategy, with support for key isolation, is currently (end of 2021) used for ECDSA signature generation in the PK layer - see `mbedtls_pk_setup_opaque()`. This @@ -249,7 +249,7 @@ support for drivers, but fails to provide isolation support. Summary ------- -Stategies currently used with each abstraction layer: +Strategies currently used with each abstraction layer: - PK (for G1): silently call PSA - PK (for G2): opt-in use of PSA (new key type) @@ -279,7 +279,7 @@ implemented of top of the concerned layers The most favourable case is if we can have a zero-cost abstraction (no runtime, RAM usage or code size penalty), for example just a bunch of -`#define`s, essentialy mapping `mbedtls_` APIs to their `psa_` equivalent. +`#define`s, essentially mapping `mbedtls_` APIs to their `psa_` equivalent. Unfortunately that's unlikely fully work. For example, the MD layer uses the same context type for hashes and HMACs, while the PSA API (rightfully) has @@ -304,12 +304,12 @@ layers compared to the existing (no need to dispatch through function pointers, just call the corresponding PSA API). Since this would still represent a non-zero cost, not only in terms of code -size, but also in terms of maintainance (testing, etc.) this would probably +size, but also in terms of maintenance (testing, etc.) this would probably be a temporary solution: for example keep the compatibility layers in 4.0 (and make them optional), but remove them in 5.0. Again, this provides the most value to users if we can manage to keep the -existing API unchanged. Their might be conflcits between this goal and that of +existing API unchanged. Their might be conflicts between this goal and that of reducing the cost, and judgment calls may need to be made. Note: when it comes to holding public keys in the PK layer, depending on how @@ -342,7 +342,7 @@ example identifiers for elliptic curves. Generally speaking, we would retire all of the low-level, non-generic modules, such as AES, SHA-256, RSA, DHM, ECDH, ECP, bignum, etc, without providing compatibility APIs for them. People would be encouraged to switch to the PSA -API. (The compatiblity implementation of the existing PK, MD, Cipher APIs +API. (The compatibility implementation of the existing PK, MD, Cipher APIs would mostly benefit people who already used those generic APis rather than the low-level, alg-specific ones.) @@ -361,7 +361,7 @@ would need a way to easily extract the PSA key ID from the PK context. 2. APIs the accept list of identifiers: for example `mbedtls_ssl_conf_curves()` taking a list of `mbedtls_ecp_group_id`s. This could be changed to accept a list of pairs (`psa_ecc_familiy_t`, size) but we -should probably take this opportunity to move to a identifier independant from +should probably take this opportunity to move to a identifier independent from the underlying crypto implementation and use TLS-specific identifiers instead (based on IANA values or custom enums), as is currently done in the new `mbedtls_ssl_conf_groups()` API, see #4859). diff --git a/docs/architecture/psa-migration/testing.md b/docs/architecture/psa-migration/testing.md index 6ed294a6cbe7..70229ce797b7 100644 --- a/docs/architecture/psa-migration/testing.md +++ b/docs/architecture/psa-migration/testing.md @@ -19,7 +19,7 @@ Generally, code review is enough to ensure that PSA APIs are indeed used where they should be when `MBEDTLS_USE_PSA_CRYPTO` is enabled. However, when it comes to TLS, we also have the option of using debug messages -to confirm which code path is taken. This is generaly un-necessary, except when +to confirm which code path is taken. This is generally unnecessary, except when a decision is made at run-time about whether to use the PSA or legacy code path. For example, for record protection, currently some ciphers are supported via PSA while some others aren't, with a run-time fallback. In this case, it's @@ -59,7 +59,7 @@ In that case, we want: `mbedtls_x509write_crt_set_issuer_key()`.) For some APIs, for example with `mbedtls_ssl_conf_psk_opaque()`, testing in -`test_suite_ssl` was historicaly not possible, so we only have testing in +`test_suite_ssl` was historically not possible, so we only have testing in `ssl-opt.sh`. New APIs meant for internal use @@ -93,7 +93,7 @@ For example, use of PSA to compute the TLS 1.2 PRF. Changes in this category rarely require specific testing, as everything should be already be covered by running the existing tests in a build with `MBEDTLS_USE_PSA_CRYPTO` enabled; however we need to make sure the existing -test have sufficient coveraged, and improve them if necessary. +test have sufficient coverage, and improve them if necessary. However, if additional logic is involved, or there are run-time decisions about whether to use the PSA or legacy code paths, specific tests might be in order. From 80759c4917959f75ceab43e1a854de88e1292219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 Feb 2022 10:33:11 +0100 Subject: [PATCH 20/21] Fix a few more typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/psa-limitations.md | 2 +- docs/architecture/psa-migration/strategy.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/architecture/psa-migration/psa-limitations.md b/docs/architecture/psa-migration/psa-limitations.md index 0986f1ba56d1..f4d357bc3942 100644 --- a/docs/architecture/psa-migration/psa-limitations.md +++ b/docs/architecture/psa-migration/psa-limitations.md @@ -125,7 +125,7 @@ algorithms can differ from each other. - salt length: either <= hashlen (see note), or any depending on algorithm Note: above, "<= hashlen" means that hashlen is used if possible, but if it -doesn't fit because the key is too short, then the maximum lenght that fits is +doesn't fit because the key is too short, then the maximum length that fits is used. The RSA/PK API is in principle more flexible than the PSA Crypto API. The diff --git a/docs/architecture/psa-migration/strategy.md b/docs/architecture/psa-migration/strategy.md index 8fb8ce5fea70..205c6cd2c133 100644 --- a/docs/architecture/psa-migration/strategy.md +++ b/docs/architecture/psa-migration/strategy.md @@ -47,7 +47,7 @@ are: both of them, but then `MBEDTLS_PSA_CRYPTO_CONFIG` won't have the desired effect) - to avoid a hard/default dependency of TLS, X.509 and PK on - `MBEDTLS_PSA_CRYPTO_C`, for backwards compatibility reasons: + `MBEDTLS_PSA_CRYPTO_C`, for backward compatibility reasons: - when `MBEDTLS_PSA_CRYPTO_C` is enabled and used, applications need to call `psa_crypto_init()` before TLS/X.509 uses PSA functions - `MBEDTLS_PSA_CRYPTO_C` has a hard depend on `MBEDTLS_ENTROPY_C || @@ -114,7 +114,7 @@ to the existing code and the less code there is at this point the better, whereas extending to more protocol features will require the same amount of work either way. -### Backwards compatibility issues with making it always on +### Backward compatibility issues with making it always on 1. Existing applications may not be calling `psa_crypto_init()` before using TLS, X.509 or PK. We can try to work around that by calling (the relevant @@ -223,7 +223,7 @@ one-shot function `mbedtls_md()`. There are two variants of this strategy: one where using the new setup function also allows for key isolation (the key is only held by PSA, supporting both G1 and G2 in that area), and one without isolation (the key is -still stored outsede of PSA most of the time, supporting only G1). +still stored outside of PSA most of the time, supporting only G1). This strategy, with support for key isolation, is currently (end of 2021) used for ECDSA signature generation in the PK layer - see `mbedtls_pk_setup_opaque()`. This From 839bb8a238121cbab87f14389bbb79ecf967c29f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 Feb 2022 10:33:41 +0100 Subject: [PATCH 21/21] Fix an inaccuracy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Manuel Pégourié-Gonnard --- docs/architecture/psa-migration/psa-limitations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/psa-migration/psa-limitations.md b/docs/architecture/psa-migration/psa-limitations.md index f4d357bc3942..c60eddc6fbf4 100644 --- a/docs/architecture/psa-migration/psa-limitations.md +++ b/docs/architecture/psa-migration/psa-limitations.md @@ -162,7 +162,7 @@ match a limitation of the PSA API. It is unclear what parameters people use in practice. It looks like by default OpenSSL picks saltlen = keylen - hashlen - 2 (tested with openssl 1.1.1f). The `certool` command provided by GnuTLS seems to be picking saltlen = hashlen -by default (tested with GnuTLS 3.6.13). FIPS 186-4 recommends 0 <= saltlen <= +by default (tested with GnuTLS 3.6.13). FIPS 186-4 requires 0 <= saltlen <= hashlen. ### Use in TLS