#
# Copyright (c) 2023 Linaro Limited
#
# SPDX-License-Identifier: Apache-2.0
#

if(CONFIG_MBEDTLS)

  if(CONFIG_MBEDTLS_BUILTIN)
    # Create an interface library named "mbedTLS":
    # - This is the library other modules/subsystems link against.
    # - It contains some Mbed TLS configuration flags (ex: MBEDTLS_CONFIG_FILE
    #   and TF_PSA_CRYPTO_CONFIG_FILE) which are used in Mbed TLS build, but
    #   which must also be defined when Zephyr code includes headers
    #   from Mbed TLS.
    # - It contains public include directories which are provided by Mbed TLS.
    zephyr_interface_library_named(mbedTLS)

    # Explicitly link zephyr_interface to mbedTLS
    zephyr_link_libraries(mbedTLS)

    target_compile_definitions(mbedTLS INTERFACE
      MBEDTLS_CONFIG_FILE="${CONFIG_MBEDTLS_CONFIG_FILE}"
      TF_PSA_CRYPTO_CONFIG_FILE="${CONFIG_TF_PSA_CRYPTO_CONFIG_FILE}"
    )

    # Some CMake variables that are used in Mbed TLS build
    set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
    set(MBEDTLS_AS_SUBPROJECT ON)
    set(ENABLE_PROGRAMS OFF)
    set(ENABLE_TESTING OFF)
    set(GEN_FILES OFF)
    # Workaround to get rid of a warning generated by the Mbed TLS build system.
    set(CMAKE_INSTALL_LIBDIR "lib" CACHE PATH "")
    set(TF_PSA_CRYPTO_DIR ${ZEPHYR_TF_PSA_CRYPTO_MODULE_DIR})
    set(MLDSA_NATIVE_DIR ${ZEPHYR_MLDSA_NATIVE_MODULE_DIR})

    # Add Mbed TLS (TF-PSA-Crypto is automatically included from there).
    # This creates 3 libraries: mbedtls, mbedx509 and tfpsacrypto.
    add_subdirectory(${ZEPHYR_MBEDTLS_MODULE_DIR} mbedtls)

    foreach(lib mbedtls mbedx509 tfpsacrypto builtin p256-m everest pqcp extras platform utilities)
      # Mbed TLS libraries are normal CMake libraries.
      # To ensure Mbed TLS libraries are including Zephyr include directories and
      # Zephyr compile options we link those libraries with 'zephyr_interface'.
      target_link_libraries(${lib} PRIVATE zephyr_interface)
      # Mbed TLS libraries are external CMake targets (not zephyr_library()),
      # so they miss the automatic add_dependencies on zephyr_generated_headers
      # that zephyr_library() targets get. Without this, generated headers
      # like heap_constants.h may not exist when Mbed TLS sources compile.
      add_dependencies(${lib} zephyr_generated_headers)
    endforeach()

    # Custom macro to tell that a TF-PSA-Crypto source file is being compiled.
    # This is used by Secure Storage.
    target_compile_definitions(tfpsacrypto PRIVATE BUILDING_MBEDTLS_CRYPTO)

    # Add Mbed TLS libraries ("tfpsacrypto" and "mbedx509" are linked to "mbedtls")
    # to ZEPHYR_LIBS list.
    zephyr_append_cmake_library(mbedtls)

    # Add Mbed TLS public include directories to the "mbedTLS" interface library.
    target_include_directories(mbedTLS INTERFACE
      $<TARGET_PROPERTY:mbedtls,INTERFACE_INCLUDE_DIRECTORIES>
    )

    # Add local include directories to the "mbedTLS" interface library.
    target_include_directories(mbedTLS INTERFACE
      ${CMAKE_CURRENT_LIST_DIR}/configs
      ${CMAKE_CURRENT_LIST_DIR}/include
    )

    # Add some support for legacy crypto that unfortunately is still required
    # in some scenarios.
    include(${CMAKE_CURRENT_LIST_DIR}/legacy_support.cmake)

    # Add another library to provide Zephyr-specific support
    zephyr_library()
    zephyr_library_sources(
      ${CMAKE_CURRENT_LIST_DIR}/zephyr_init.c
      ${CMAKE_CURRENT_LIST_DIR}/zephyr_entropy.c
      $<$<BOOL:${CONFIG_MBEDTLS_DEBUG}>:${CMAKE_CURRENT_LIST_DIR}/debug.c>
      $<$<BOOL:${CONFIG_MBEDTLS_SHELL}>:${CMAKE_CURRENT_LIST_DIR}/shell.c>
    )
    zephyr_library_link_libraries(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}
      gcc
      )
    # Lib mbedtls_external depends on libgcc (I assume?) so to allow
    # mbedtls_external to link with gcc we need to ensure it is placed
    # after mbedtls_external on the linkers command line.
  endif()

  if(CONFIG_MBEDTLS_TLS_VERSION_1_2 OR CONFIG_MBEDTLS_TLS_VERSION_1_3)
    if(NOT CONFIG_MBEDTLS_HAVE_TIME_DATE)
      message(WARNING "
      The option CONFIG_MBEDTLS_HAVE_TIME_DATE is required for proper
      certificate validation. If it is not enabled, certificates will
      not be checked for expiration or validity dates, which may lead
      to security vulnerabilities.
      ")
    endif()
  endif()

endif()
