modules: mbedtls: build MbedTLS as three libraries

Previously, Zephyr's mbedtls module's cmake build created a single static
library, rather than the collection of libraries (mbedtls, mbedcrypto,
and mbedx509) that upstream mbedTLS cmake provides.

To give better control at link time to choose the required libraries to
link, this commit updates the Zephyr MbedTLS module to also define a
collection of libraries rather than a single static MbedTLS library.

One benefit of the three library approach is that if mbedTLS is used in
Zephyr in the the non-secure application in addition to TFM's PSA Crypto
API on the secure side with TF-M, PSA API calls on the non-secure side
will be redirected to the TFM PSA implementation, and the mbedcrypto
library will only be linked to the secure (TF-M) binary, with the mbedtls
and mbedx509 libraries linked against the non-secure (Zephyr) binary,
enabling TLS calls to PSA crypto to be redirected to mbedcrypto in the
secure partition and avoiding function duplication in the non-secure
binary.

Signed-off-by: Rajkumar Kanagaraj <rajkumar.kanagaraj@linaro.org>
diff --git a/modules/mbedtls/CMakeLists.txt b/modules/mbedtls/CMakeLists.txt
index fbfa187..09017a5 100644
--- a/modules/mbedtls/CMakeLists.txt
+++ b/modules/mbedtls/CMakeLists.txt
@@ -1,71 +1,203 @@
+#
+# Copyright (c) 2023 Linaro Limited
+#
+# SPDX-License-Identifier: Apache-2.0
+#
 if(CONFIG_MBEDTLS)
 zephyr_interface_library_named(mbedTLS)
 
-if(CONFIG_MBEDTLS_BUILTIN)
-  target_compile_definitions(mbedTLS INTERFACE
-    MBEDTLS_CONFIG_FILE="${CONFIG_MBEDTLS_CFG_FILE}"
-  )
+  if(CONFIG_MBEDTLS_BUILTIN)
+    if(CONFIG_MBEDTLS_ZEPHYR_ENTROPY AND NOT CONFIG_ENTROPY_HAS_DRIVER)
+      message(WARNING "No entropy device on the system, using fake entropy source!")
+    endif()
 
-  target_include_directories(mbedTLS INTERFACE
-    ${ZEPHYR_CURRENT_MODULE_DIR}/include
-    # mbedTLS v3.1.0 has psa_crypto_cipher.c including an internal header using <>.
-    # This line ensures the header can be found in Zephyr.
-    # When updating to mbedTLS > v3.1.0, please check if this has been corrected,
-    # and if so remove this include path.
-    ${ZEPHYR_CURRENT_MODULE_DIR}/library
-    configs
-    include
-  )
-
-  zephyr_library()
-
-  file(GLOB
-    mbedtls_sources # This is an output parameter
-      ${ZEPHYR_CURRENT_MODULE_DIR}/library/*.c
+    # Add the config-file entry point
+    target_compile_definitions(mbedTLS INTERFACE
+        MBEDTLS_CONFIG_FILE="${CONFIG_MBEDTLS_CFG_FILE}"
     )
 
-  if(CONFIG_MBEDTLS_DEBUG_EXTRACT_BASENAME_AT_BUILDTIME)
-    zephyr_cc_option(-fmacro-prefix-map=${ZEPHYR_CURRENT_MODULE_DIR}/library/=)
-  endif()
+    # Add regular includes
+    target_include_directories(mbedTLS INTERFACE
+        ${ZEPHYR_CURRENT_MODULE_DIR}/include
+        configs
+        include
+    )
 
-  zephyr_library_sources(
-    zephyr_init.c
-    ${mbedtls_sources}
-  )
+    # Add base library with files required by all drivers/backends.
+    zephyr_library_named(mbedTLSBase)
 
-  zephyr_library_sources_ifdef(CONFIG_MBEDTLS_DEBUG debug.c)
-  zephyr_library_sources_ifdef(CONFIG_MBEDTLS_SHELL shell.c)
+    # Base mbed TLS files
+    list(APPEND mbedtls_base_src
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/asn1parse.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/asn1write.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/base64.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/bignum.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/bignum_core.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/bignum_mod.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/bignum_mod_raw.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/nist_kw.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/oid.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/padlock.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/platform.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/platform_util.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/version.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/constant_time.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/aes.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/aesni.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/aria.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/camellia.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ccm.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/chacha20.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/chachapoly.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/cipher.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/cipher_wrap.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/cmac.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/code_share.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ctr_drbg.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/debug.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/des.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/dhm.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecdh.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecdsa.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecjpake.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecp.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecp_curves.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/entropy.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/entropy_poll.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/error.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/gcm.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/hash_info.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/hkdf.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/hmac_drbg.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/lmots.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/lms.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/md5.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/md.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/memory_buffer_alloc.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/mps_reader.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/mps_trace.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/poly1305.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ripemd160.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/rsa_alt_helpers.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/rsa.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/sha1.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/sha256.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/sha512.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/threading.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/timing.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/version_features.c
+      zephyr_init.c
+    )
 
-  # mbedTLS v3.1.0 is having unused variables and functions in /library/ssl_msg.c
-  # To avoid compilation warnings, which are treated as errors in CI, we disable unused variables and functions.
-  # Please check when mbedTLS is updated to version >v3.1.0 if those flags are still needed.
-  # If mbedTLS has fixed the mentioned issue, then please remove the flags.
-  set_source_files_properties(${ZEPHYR_CURRENT_MODULE_DIR}/library/ssl_msg.c
-      PROPERTIES COMPILE_OPTIONS "-Wno-unused-variable;-Wno-unused-function")
+    zephyr_library_sources(${mbedtls_base_src})
 
-  zephyr_library_app_memory(k_mbedtls_partition)
-  if(CONFIG_ARCH_POSIX AND CONFIG_ASAN AND NOT CONFIG_64BIT)
-    # i386 assembly code used in MBEDTLS does not compile with size optimization
-    # if address sanitizer is enabled, as such switch default optimization level
-    # to speed
-    set_property(SOURCE ${ZEPHYR_CURRENT_MODULE_DIR}/mbedtls/library/bignum.c APPEND PROPERTY COMPILE_OPTIONS
-        "${OPTIMIZE_FOR_SPEED_FLAG}")
-  endif ()
+    zephyr_library_sources_ifdef(CONFIG_MBEDTLS_DEBUG debug.c)
+    zephyr_library_sources_ifdef(CONFIG_MBEDTLS_SHELL shell.c)
 
-  if(CONFIG_MBEDTLS_ZEPHYR_ENTROPY AND NOT CONFIG_ENTROPY_HAS_DRIVER)
-    message(WARNING "No entropy device on the system, using fake entropy source!")
-  endif()
+    zephyr_library_app_memory(k_mbedtls_partition)
+    if(CONFIG_ARCH_POSIX AND CONFIG_ASAN AND NOT CONFIG_64BIT)
+      # i386 assembly code used in MBEDTLS does not compile with size optimization
+      # if address sanitizer is enabled, as such switch default optimization level
+      # to speed
+      set_property(SOURCE ${ZEPHYR_CURRENT_MODULE_DIR}/mbedtls/library/bignum.c APPEND PROPERTY COMPILE_OPTIONS
+          "${OPTIMIZE_FOR_SPEED_FLAG}")
+    endif ()
 
-  zephyr_library_link_libraries(mbedTLS)
+    zephyr_library_link_libraries(mbedTLS)
+
+    zephyr_library_named(mbedTLSCrypto)
+
+    if (MBEDTLS_USE_PSA_CRYPTO)
+      list(APPEND crypto_source
+        ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_aead.c
+        ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_cipher.c
+        ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_driver_wrappers.c
+        ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_ecp.c
+        ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_hash.c
+        ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_mac.c
+        ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_rsa.c
+        ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_se.c
+        ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_slot_management.c
+        ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_storage.c
+        ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_its_file.c
+      )
+    endif()
+
+    if (NOT CONFIG_BUILD_WITH_TFM)
+      list(APPEND crypto_source
+        ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto.c
+        ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_client.c
+      )
+    endif()
+
+    list(APPEND crypto_source
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/pem.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/pkcs12.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/pkcs5.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/pkparse.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/pkwrite.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/pk.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/pk_wrap.c
+    )
+
+    zephyr_library_sources(${crypto_source})
+
+    zephyr_library_link_libraries(mbedTLS)
+
+    zephyr_library_link_libraries_ifdef(CONFIG_BUILD_WITH_TFM tfm_api)
+
+    zephyr_library_named(mbedTLSX509)
+
+    list(APPEND x509_source
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/x509.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/x509_create.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/x509_crl.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/x509_crt.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/x509_csr.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/x509write_crt.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/x509write_csr.c
+    )
+
+    zephyr_library_sources(${x509_source})
+
+    zephyr_library_link_libraries(mbedTLS)
+
+    zephyr_library()
+
+    list(APPEND mbedtls_source
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/net_sockets.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ssl_cache.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ssl_ciphersuites.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ssl_client.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ssl_cookie.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ssl_debug_helpers_generated.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ssl_msg.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ssl_ticket.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ssl_tls12_client.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ssl_tls12_server.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ssl_tls13_client.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ssl_tls13_generic.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ssl_tls13_keys.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ssl_tls13_server.c
+      ${ZEPHYR_CURRENT_MODULE_DIR}/library/ssl_tls.c
+    )
+
+    zephyr_library_sources(${mbedtls_source})
+
+    zephyr_library_link_libraries(
+      mbedTLSX509
+      mbedTLSCrypto
+      mbedTLSBase
+      mbedTLS
+    )
+
 elseif (CONFIG_MBEDTLS_LIBRARY)
 
   # NB: CONFIG_MBEDTLS_LIBRARY is not regression tested and is
   # therefore susceptible to bit rot
-
   target_include_directories(mbedTLS INTERFACE
     ${CONFIG_MBEDTLS_INSTALL_PATH}
   )
-
   zephyr_link_libraries(
     mbedtls_external
     -L${CONFIG_MBEDTLS_INSTALL_PATH}