mbedtls/docs/architecture/psa-migration/dependencies-tls.md
Manuel Pégourié-Gonnard 0d0a104b2d Add study for TLS/X.509 dependencies on crypto
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 <manuel.pegourie-gonnard@arm.com>
2022-01-18 09:13:00 +01:00

16 KiB

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.

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