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] 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 0000000000..74f78d57b0 --- /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 0000000000..dfbff8304a --- /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 0000000000..5c34b28d1a --- /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