1# Copyright (c) 2019 - 2023 Linaro
2# Copyright (c) 2020 - 2023 Nordic Semiconductor ASA
3#
4# SPDX-License-Identifier: Apache-2.0
5
6# List of all partitions supported by TF-M
7# Name must match name in 'trusted-firmware-m/tools/tfm_manifest_list.yaml'
8set(TFM_VALID_PARTITIONS
9  TFM_PARTITION_NS_AGENT_MAILBOX
10  TFM_PARTITION_PROTECTED_STORAGE
11  TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
12  TFM_PARTITION_CRYPTO
13  TFM_PARTITION_PLATFORM
14  TFM_PARTITION_INITIAL_ATTESTATION
15  TFM_PARTITION_FIRMWARE_UPDATE
16  )
17
18if (CONFIG_BUILD_WITH_TFM)
19  # PSA API awareness for the Non-Secure application
20  target_compile_definitions(app PRIVATE "TFM_PSA_API")
21  if (CONFIG_TFM_SFN)
22    list(APPEND TFM_CMAKE_ARGS -DCONFIG_TFM_SPM_BACKEND="SFN")
23  else() # CONFIG_TFM_IPC
24    list(APPEND TFM_CMAKE_ARGS -DCONFIG_TFM_SPM_BACKEND="IPC")
25  endif()
26  if (CONFIG_TFM_REGRESSION_S)
27    list(APPEND TFM_CMAKE_ARGS -DTEST_S=ON)
28    list(APPEND TFM_CMAKE_ARGS -DTFM_S_REG_TEST:BOOL=ON)
29  endif()
30  if (CONFIG_TFM_REGRESSION_NS)
31    list(APPEND TFM_CMAKE_ARGS -DTEST_NS=ON)
32    list(APPEND TFM_CMAKE_ARGS -DTFM_NS_REG_TEST:BOOL=ON)
33  endif()
34  if (CONFIG_TFM_BL2)
35    list(APPEND TFM_CMAKE_ARGS -DBL2=TRUE)
36    list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_IMAGE_VERSION_S=${CONFIG_TFM_IMAGE_VERSION_S})
37    list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_IMAGE_VERSION_NS=${CONFIG_TFM_IMAGE_VERSION_NS})
38    list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_SIGNATURE_TYPE=${CONFIG_TFM_MCUBOOT_SIGNATURE_TYPE})
39
40    # TF-M's config/check_config.cmake requires MCUBOOT_BUILTIN_KEY=OFF for RSA
41    # and MCUBOOT_USE_PSA_CRYPTO for EC-P. The others are dependencies needed
42    # for either the build or the boot to succeed.
43    if (${CONFIG_TFM_MCUBOOT_SIGNATURE_TYPE} MATCHES "^RSA")
44      list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_BUILTIN_KEY=OFF)
45      list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_HW_KEY=ON)
46    elseif (${CONFIG_TFM_MCUBOOT_SIGNATURE_TYPE} MATCHES "^EC-P")
47      list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_USE_PSA_CRYPTO=ON)
48      list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_BUILTIN_KEY=ON)
49      list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_HW_KEY=OFF)
50    endif()
51
52    foreach(SUFFIX IN ITEMS "S" "NS")
53      string(CONFIGURE ${CONFIG_TFM_KEY_FILE_${SUFFIX}} CONFIG_TFM_KEY_FILE_${SUFFIX})
54      list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_KEY_${SUFFIX}=${CONFIG_TFM_KEY_FILE_${SUFFIX}})
55    endforeach()
56
57  else()
58    list(APPEND TFM_CMAKE_ARGS -DBL2=FALSE)
59  endif()
60  if (CONFIG_TFM_ISOLATION_LEVEL)
61    list(APPEND TFM_CMAKE_ARGS -DTFM_ISOLATION_LEVEL=${CONFIG_TFM_ISOLATION_LEVEL})
62  endif()
63  if (CONFIG_TFM_ITS_NUM_ASSETS_OVERRIDE)
64    list(APPEND TFM_CMAKE_ARGS -DITS_NUM_ASSETS=${CONFIG_TFM_ITS_NUM_ASSETS})
65  endif()
66  if (CONFIG_TFM_ITS_MAX_ASSET_SIZE_OVERRIDE)
67    list(APPEND TFM_CMAKE_ARGS -DITS_MAX_ASSET_SIZE=${CONFIG_TFM_ITS_MAX_ASSET_SIZE})
68  endif()
69  if (CONFIG_TFM_PROFILE)
70    list(APPEND TFM_CMAKE_ARGS -DTFM_PROFILE=${CONFIG_TFM_PROFILE})
71  endif()
72  if (CONFIG_TFM_CMAKE_BUILD_TYPE_RELEASE)
73    set(TFM_CMAKE_BUILD_TYPE "Release")
74  elseif (CONFIG_TFM_CMAKE_BUILD_TYPE_MINSIZEREL)
75    set(TFM_CMAKE_BUILD_TYPE "MinSizeRel")
76  elseif (CONFIG_TFM_CMAKE_BUILD_TYPE_DEBUG)
77    set(TFM_CMAKE_BUILD_TYPE "Debug")
78  else ()
79    set(TFM_CMAKE_BUILD_TYPE "RelWithDebInfo")
80  endif()
81  if (DEFINED CONFIG_TFM_MCUBOOT_IMAGE_NUMBER)
82    list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_IMAGE_NUMBER=${CONFIG_TFM_MCUBOOT_IMAGE_NUMBER})
83  endif()
84
85  if (CONFIG_TFM_DUMMY_PROVISIONING)
86    list(APPEND TFM_CMAKE_ARGS -DTFM_DUMMY_PROVISIONING=ON)
87  else()
88    list(APPEND TFM_CMAKE_ARGS -DTFM_DUMMY_PROVISIONING=OFF)
89  endif()
90
91  if (CONFIG_TFM_EXCEPTION_INFO_DUMP)
92    list(APPEND TFM_CMAKE_ARGS -DTFM_EXCEPTION_INFO_DUMP=ON)
93  else()
94    list(APPEND TFM_CMAKE_ARGS -DTFM_EXCEPTION_INFO_DUMP=OFF)
95  endif()
96
97  if (CONFIG_TFM_BL2)
98    if (CONFIG_TFM_BL2_LOG_LEVEL_DEBUG)
99      set(TFM_BL2_LOG_LEVEL "DEBUG")
100    elseif (CONFIG_TFM_BL2_LOG_LEVEL_INFO)
101      set(TFM_BL2_LOG_LEVEL "INFO")
102    elseif (CONFIG_TFM_BL2_LOG_LEVEL_WARNING)
103      set(TFM_BL2_LOG_LEVEL "WARNING")
104    elseif (CONFIG_TFM_BL2_LOG_LEVEL_ERROR)
105      set(TFM_BL2_LOG_LEVEL "ERROR")
106    elseif (CONFIG_TFM_BL2_LOG_LEVEL_OFF OR CONFIG_TFM_LOG_LEVEL_SILENCE)
107      set(TFM_BL2_LOG_LEVEL "OFF")
108    endif()
109
110    if (DEFINED TFM_BL2_LOG_LEVEL)
111      # BL2 uses MCUBOOT_LOG_LEVEL configuration
112      list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_LOG_LEVEL=${TFM_BL2_LOG_LEVEL})
113    endif()
114  endif()
115
116  if (CONFIG_TFM_PARTITION_LOG_LEVEL_DEBUG)
117    set(TFM_PARTITION_LOG_LEVEL "TFM_PARTITION_LOG_LEVEL_DEBUG")
118  elseif (CONFIG_TFM_PARTITION_LOG_LEVEL_INFO)
119    set(TFM_PARTITION_LOG_LEVEL "TFM_PARTITION_LOG_LEVEL_INFO")
120  elseif (CONFIG_TFM_PARTITION_LOG_LEVEL_ERROR)
121    set(TFM_PARTITION_LOG_LEVEL "TFM_PARTITION_LOG_LEVEL_ERROR")
122  elseif (CONFIG_TFM_PARTITION_LOG_LEVEL_SILENCE OR CONFIG_TFM_LOG_LEVEL_SILENCE)
123    set(TFM_PARTITION_LOG_LEVEL "TFM_PARTITION_LOG_LEVEL_SILENCE")
124  endif()
125
126  if (DEFINED TFM_PARTITION_LOG_LEVEL)
127    list(APPEND TFM_CMAKE_ARGS -DTFM_PARTITION_LOG_LEVEL=${TFM_PARTITION_LOG_LEVEL})
128  endif()
129
130  if (CONFIG_TFM_SPM_LOG_LEVEL_DEBUG)
131    set(TFM_SPM_LOG_LEVEL "TFM_SPM_LOG_LEVEL_DEBUG")
132  elseif (CONFIG_TFM_SPM_LOG_LEVEL_INFO)
133    set(TFM_SPM_LOG_LEVEL "TFM_SPM_LOG_LEVEL_INFO")
134  elseif (CONFIG_TFM_SPM_LOG_LEVEL_ERROR)
135    set(TFM_SPM_LOG_LEVEL "TFM_SPM_LOG_LEVEL_ERROR")
136  elseif (CONFIG_TFM_SPM_LOG_LEVEL_SILENCE OR CONFIG_TFM_LOG_LEVEL_SILENCE)
137    set(TFM_SPM_LOG_LEVEL "TFM_SPM_LOG_LEVEL_SILENCE")
138  endif()
139
140  if (DEFINED TFM_SPM_LOG_LEVEL)
141    list(APPEND TFM_CMAKE_ARGS -DTFM_SPM_LOG_LEVEL=${TFM_SPM_LOG_LEVEL})
142  endif()
143
144  # Enable TFM partitions as specified in Kconfig
145  foreach(partition ${TFM_VALID_PARTITIONS})
146    if (CONFIG_${partition})
147      # list(APPEND TFM_ENABLED_PARTITIONS_ARG ${partition})
148      set(val "ON")
149    else()
150      set(val "OFF")
151    endif()
152    list(APPEND TFM_CMAKE_ARGS -D${partition}=${val})
153  endforeach()
154
155  set(TFM_BINARY_DIR ${CMAKE_BINARY_DIR}/tfm)
156
157  set(TFM_INTERFACE_SOURCE_DIR   ${TFM_BINARY_DIR}/api_ns/interface/src)
158  set(TFM_INTERFACE_INCLUDE_DIR  ${TFM_BINARY_DIR}/api_ns/interface/include)
159  set(TFM_INTERFACE_LIB_DIR      ${TFM_BINARY_DIR}/api_ns/interface/lib)
160
161  if(CONFIG_TFM_BL2)
162    set(BL2_ELF_FILE ${TFM_BINARY_DIR}/bin/bl2.elf)
163    set(BL2_BIN_FILE ${TFM_BINARY_DIR}/bin/bl2.bin)
164    set(BL2_HEX_FILE ${TFM_BINARY_DIR}/bin/bl2.hex)
165  endif()
166  set(TFM_S_ELF_FILE ${TFM_BINARY_DIR}/bin/tfm_s.elf)
167  set(TFM_S_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_s.bin)
168  set(TFM_S_HEX_FILE ${TFM_BINARY_DIR}/bin/tfm_s.hex)
169  set(TFM_NS_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_ns.bin)
170  set(TFM_NS_HEX_FILE ${CMAKE_BINARY_DIR}/tfm_ns/bin/tfm_ns.hex)
171  set(TFM_S_SIGNED_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_s_signed.bin)
172  set(TFM_NS_SIGNED_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_ns_signed.bin)
173  set(TFM_S_NS_SIGNED_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_s_ns_signed.bin)
174
175  set(BUILD_BYPRODUCTS
176    ${PSA_TEST_VAL_FILE}
177    ${PSA_TEST_PAL_FILE}
178    ${PSA_TEST_COMBINE_FILE}
179    ${BL2_ELF_FILE}
180    ${BL2_BIN_FILE}
181    ${BL2_HEX_FILE}
182    ${TFM_S_ELF_FILE}
183    ${TFM_S_BIN_FILE}
184    ${TFM_S_HEX_FILE}
185    ${TFM_S_SIGNED_BIN_FILE}
186    ${TFM_S_NS_SIGNED_BIN_FILE}
187
188    ${TFM_INTERFACE_LIB_DIR}/s_veneers.o
189
190    ${TFM_INTERFACE_SOURCE_DIR}/tfm_attest_api.c
191    ${TFM_INTERFACE_SOURCE_DIR}/tfm_crypto_api.c
192    ${TFM_INTERFACE_SOURCE_DIR}/tfm_fwu_api.c
193    ${TFM_INTERFACE_SOURCE_DIR}/tfm_its_api.c
194    ${TFM_INTERFACE_SOURCE_DIR}/tfm_platform_api.c
195    ${TFM_INTERFACE_SOURCE_DIR}/tfm_ps_api.c
196    ${TFM_INTERFACE_SOURCE_DIR}/tfm_tz_psa_ns_api.c
197
198    # Specific to nordic platform
199    ${TFM_INTERFACE_SOURCE_DIR}/tfm_ioctl_core_ns_api.c
200    )
201
202  # Get the toolchain variant
203  # TODO: Add support for cross-compile toolchain variant
204  # TODO: Enforce GCC version check against TF-M compiler requirements
205  if(${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "zephyr")
206    set(TFM_TOOLCHAIN_FILE "toolchain_GNUARM.cmake")
207    set(TFM_TOOLCHAIN_PREFIX "arm-zephyr-eabi")
208    set(TFM_TOOLCHAIN_PATH ${ZEPHYR_SDK_INSTALL_DIR}/arm-zephyr-eabi/bin)
209  elseif(${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "gnuarmemb")
210    set(TFM_TOOLCHAIN_FILE "toolchain_GNUARM.cmake")
211    set(TFM_TOOLCHAIN_PREFIX "arm-none-eabi")
212    set(TFM_TOOLCHAIN_PATH ${GNUARMEMB_TOOLCHAIN_PATH}/bin)
213  elseif(${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "xtools")
214    set(TFM_TOOLCHAIN_FILE "toolchain_GNUARM.cmake")
215    set(TFM_TOOLCHAIN_PREFIX "arm-zephyr-eabi")
216    set(TFM_TOOLCHAIN_PATH ${XTOOLS_TOOLCHAIN_PATH}/arm-zephyr-eabi/bin)
217  else()
218    message(FATAL_ERROR "Unsupported ZEPHYR_TOOLCHAIN_VARIANT: ${ZEPHYR_TOOLCHAIN_VARIANT}")
219  endif()
220
221  if (CONFIG_TFM_PARTITION_INITIAL_ATTESTATION AND CONFIG_TFM_QCBOR_PATH STREQUAL "")
222    # TODO: Remove this when QCBOR licensing issues w/t_cose have been resolved,
223    # or only allow it when 'QCBOR_PATH' is set to a local path where QCBOR has
224    # been manually downloaded by the user before starting the build.
225    message(FATAL_ERROR "CONFIG_TFM_PARTITION_INITIAL_ATTESTATION is not available "
226      "with TF-M due to licensing issues with a dependent library. This "
227      "restriction will be removed once licensing issues have been resolved."
228      )
229  endif()
230
231  string(REPLACE "toolchain" "toolchain_ns" TFM_TOOLCHAIN_NS_FILE ${TFM_TOOLCHAIN_FILE})
232
233  if(CONFIG_BOARD_LPCXPRESSO55S69_LPC55S69_CPU0_NS)
234    # Supply path to NXP HAL sources used for TF-M build
235    set(TFM_PLATFORM_NXP_HAL_FILE_PATH ${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/platform/ext/target/nxp/)
236    list(APPEND TFM_CMAKE_ARGS -DTFM_PLATFORM_NXP_HAL_FILE_PATH=${TFM_PLATFORM_NXP_HAL_FILE_PATH})
237  endif()
238
239  if(CONFIG_TFM_BL2 AND CONFIG_TFM_MCUBOOT_PATH_LOCAL)
240    # Supply path to MCUboot for TF-M build
241    list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_PATH=${ZEPHYR_MCUBOOT_MODULE_DIR})
242  endif()
243
244  if(CONFIG_TFM_MCUBOOT_DATA_SHARING)
245    list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_DATA_SHARING=ON)
246  endif()
247
248  if(CONFIG_FPU AND CONFIG_FP_HARDABI)
249    list(APPEND TFM_CMAKE_ARGS -DCONFIG_TFM_ENABLE_FP=ON)
250    # Note: This is not a cmake option in TF-M.
251    # This should be specified by the platform in preload.cmake
252    # This works as a workaround for the platforms that do not have this.
253    list(APPEND TFM_CMAKE_ARGS -DCONFIG_TFM_FP_ARCH=${FPU_FOR_${GCC_M_CPU}})
254  else()
255    list(APPEND TFM_CMAKE_ARGS -DCONFIG_TFM_ENABLE_FP=OFF)
256  endif()
257
258  list(APPEND TFM_CMAKE_ARGS -DTFM_TESTS_REVISION_CHECKS=OFF)
259
260  file(MAKE_DIRECTORY ${TFM_BINARY_DIR})
261  add_custom_target(tfm_cmake
262    DEPENDS ${TFM_BINARY_DIR}/CMakeCache.txt
263  )
264  add_custom_command(
265    OUTPUT ${TFM_BINARY_DIR}/CMakeCache.txt
266    COMMAND ${CMAKE_COMMAND}
267      -G${CMAKE_GENERATOR}
268      -DTFM_TOOLCHAIN_FILE=${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/${TFM_TOOLCHAIN_FILE}
269      -DCROSS_COMPILE=${TFM_TOOLCHAIN_PATH}/${TFM_TOOLCHAIN_PREFIX}
270      -DCMAKE_BUILD_TYPE=${TFM_CMAKE_BUILD_TYPE}
271      -DTFM_PLATFORM=${CONFIG_TFM_BOARD}
272      -DCONFIG_TFM_BUILD_LOG_QUIET=ON
273      -DCONFIG_TFM_MEMORY_USAGE_QUIET=OFF
274      -DPython3_EXECUTABLE=${Python3_EXECUTABLE}
275      ${TFM_CMAKE_ARGS}
276      $<GENEX_EVAL:$<TARGET_PROPERTY:zephyr_property_target,TFM_CMAKE_OPTIONS>>
277      -DMBEDCRYPTO_PATH=$<IF:$<BOOL:$<TARGET_PROPERTY:zephyr_property_target,TFM_MBEDCRYPTO_PATH>>,$<TARGET_PROPERTY:zephyr_property_target,TFM_MBEDCRYPTO_PATH>,${ZEPHYR_MBEDTLS_MODULE_DIR}>
278      -DCMSIS_PATH=${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/platform/ext/cmsis
279      ${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}
280    WORKING_DIRECTORY ${TFM_BINARY_DIR}
281    COMMAND_EXPAND_LISTS
282  )
283
284  include(ExternalProject)
285
286  if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows)
287    # Set number of parallel jobs for TF-M build to 1.
288    # In some circumstances it has been experienced that building TF-M with
289    # multiple parallel jobs then `permission denied` may occur. Root cause on
290    # Windows has not been identified but current suspicion is around folder /
291    # file lock mechanism. To ensure correct behaviour in all cases, limit
292    # number of parallel jobs to 1.
293    set(PARALLEL_JOBS -j 1)
294  else()
295	# Leave PARALLEL_JOBS unset and use the default number of
296	# threads. Which is num_cores+2 on Ninja and MAKEFLAGS with Make.
297  endif()
298
299  ExternalProject_Add(
300    tfm
301    SOURCE_DIR ${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}
302    BINARY_DIR ${TFM_BINARY_DIR}
303    CONFIGURE_COMMAND ""
304    BUILD_COMMAND ${CMAKE_COMMAND} --build . ${PARALLEL_JOBS}
305    INSTALL_COMMAND ${CMAKE_COMMAND} --install .
306    BUILD_ALWAYS True
307    USES_TERMINAL_BUILD True
308    DEPENDS tfm_cmake
309    BUILD_BYPRODUCTS ${BUILD_BYPRODUCTS}
310  )
311
312  # Set TFM binary directory as target property on 'tfm'
313  # This is the root of all TFM build artifacts.
314  set_target_properties(tfm PROPERTIES TFM_BINARY_DIR ${TFM_BINARY_DIR})
315
316  # Set TFM toolchain properties on 'tfm'
317  set_target_properties(tfm PROPERTIES TFM_TOOLCHAIN_NS_FILE ${TFM_TOOLCHAIN_NS_FILE})
318  set_target_properties(tfm PROPERTIES TFM_TOOLCHAIN_PREFIX  ${TFM_TOOLCHAIN_PREFIX})
319  set_target_properties(tfm PROPERTIES TFM_TOOLCHAIN_PATH    ${TFM_TOOLCHAIN_PATH})
320
321  # Set BL2 (MCUboot) executable file paths as target properties on 'tfm'
322  # These files are produced by the TFM build system.
323  if(CONFIG_TFM_BL2)
324    set_target_properties(tfm PROPERTIES
325      BL2_ELF_FILE ${BL2_ELF_FILE}
326      BL2_BIN_FILE ${BL2_BIN_FILE}
327      BL2_HEX_FILE ${BL2_HEX_FILE}
328      )
329  endif()
330
331  # Set TFM S/NS executable file paths as target properties on 'tfm'
332  # These files are produced by the TFM build system.
333  # Note that the Nonsecure FW is replaced by the Zephyr app in regular Zephyr
334  # builds.
335  set_target_properties(tfm PROPERTIES
336    TFM_S_ELF_FILE ${TFM_S_ELF_FILE}
337    TFM_S_BIN_FILE ${TFM_S_BIN_FILE} # TFM Secure FW (unsigned)
338    TFM_S_HEX_FILE ${TFM_S_HEX_FILE} # TFM Secure FW (unsigned)
339    TFM_NS_BIN_FILE ${TFM_NS_BIN_FILE} # TFM Nonsecure FW (unsigned)
340    TFM_NS_HEX_FILE ${TFM_NS_HEX_FILE} # TFM Nonsecure FW (unsigned)
341    TFM_S_SIGNED_BIN_FILE ${TFM_S_SIGNED_BIN_FILE} # TFM Secure FW (signed)
342    TFM_NS_SIGNED_BIN_FILE ${TFM_NS_SIGNED_BIN_FILE} # TFM Nonsecure FW (signed)
343    TFM_S_NS_SIGNED_BIN_FILE ${TFM_S_NS_SIGNED_BIN_FILE} # Merged TFM Secure/Nonsecure FW (signed)
344    )
345
346  zephyr_library_named(tfm_api)
347
348  zephyr_library_sources(
349    src/zephyr_tfm_log.c
350    interface/interface.c
351    )
352
353  # A dependency on tfm_s.hex for zephyr.elf will not cause a Zephyr re-link when
354  # tfm_s.hex is updated, as the hex is not a direct input on the executable.
355  # Instead we establish a source file dependency which ensures that tfm_api is
356  # updated when there are changes in tfm itself, this again will trigger an re-link
357  # of Zephyr.elf.
358  set_property(SOURCE interface/interface.c APPEND PROPERTY OBJECT_DEPENDS ${TFM_S_HEX_FILE})
359
360  # Non-Secure interface to request system reboot
361  if (CONFIG_TFM_PARTITION_PLATFORM AND NOT CONFIG_TFM_PARTITION_PLATFORM_CUSTOM_REBOOT)
362    zephyr_library_sources(src/reboot.c)
363  endif()
364
365  zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_PLATFORM                 ${TFM_INTERFACE_SOURCE_DIR}/tfm_platform_api.c)
366  zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_PROTECTED_STORAGE        ${TFM_INTERFACE_SOURCE_DIR}/tfm_ps_api.c)
367  zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_INTERNAL_TRUSTED_STORAGE ${TFM_INTERFACE_SOURCE_DIR}/tfm_its_api.c)
368  zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_CRYPTO                   ${TFM_INTERFACE_SOURCE_DIR}/tfm_crypto_api.c)
369  zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_INITIAL_ATTESTATION      ${TFM_INTERFACE_SOURCE_DIR}/tfm_attest_api.c)
370  zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_FIRMWARE_UPDATE          ${TFM_INTERFACE_SOURCE_DIR}/tfm_fwu_api.c)
371
372  zephyr_library_sources(${TFM_INTERFACE_SOURCE_DIR}/tfm_tz_psa_ns_api.c)
373
374  if(CONFIG_SOC_FAMILY_NORDIC_NRF)
375    zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_PLATFORM               ${TFM_INTERFACE_SOURCE_DIR}/tfm_ioctl_core_ns_api.c)
376  endif()
377
378  target_include_directories(tfm_api PUBLIC
379    ${TFM_INTERFACE_INCLUDE_DIR}
380    ${TFM_INTERFACE_INCLUDE_DIR}/crypto_keys
381    ${ZEPHYR_BASE}/modules/mbedtls/configs
382    )
383  # Pass down the MbedTLS configuration file to use.
384  target_compile_definitions(tfm_api PUBLIC
385    MBEDTLS_CONFIG_FILE="${CONFIG_MBEDTLS_CFG_FILE}"
386    )
387
388  zephyr_library_link_libraries(
389    ${TFM_INTERFACE_LIB_DIR}/s_veneers.o
390    )
391
392  # To ensure that generated include files are created before they are used.
393  add_dependencies(zephyr_interface tfm)
394
395  if (CONFIG_TFM_BL2)
396    set(PREPROCESSED_FILE_S "${TFM_BINARY_DIR}/bl2/ext/mcuboot/CMakeFiles/signing_layout_s.dir/signing_layout_s.o")
397    set(PREPROCESSED_FILE_S_NS "${TFM_BINARY_DIR}/bl2/ext/mcuboot/CMakeFiles/signing_layout_s.dir/signing_layout_s_ns.o")
398    set(PREPROCESSED_FILE_NS "${TFM_BINARY_DIR}/bl2/ext/mcuboot/CMakeFiles/signing_layout_ns.dir/signing_layout_ns.o")
399    set(TFM_MCUBOOT_DIR "${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/bl2/ext/mcuboot")
400  endif()
401
402  # Configure which format (full or hash) to include the public key in
403  # the image manifest
404  if(NOT DEFINED TFM_PUBLIC_KEY_FORMAT)
405    set(TFM_PUBLIC_KEY_FORMAT "full")
406  endif()
407
408  if(DEFINED TFM_HEX_BASE_ADDRESS_S)
409    set(HEX_ADDR_ARGS_S "--hex-addr=${TFM_HEX_BASE_ADDRESS_S}")
410  endif()
411
412  if(DEFINED TFM_HEX_BASE_ADDRESS_NS)
413    set(HEX_ADDR_ARGS_NS "--hex-addr=${TFM_HEX_BASE_ADDRESS_NS}")
414  endif()
415
416  function(tfm_sign OUT_ARG SUFFIX PAD INPUT_FILE OUTPUT_FILE)
417    if(PAD)
418      set(pad_args --pad --pad-header)
419    endif()
420    # Secure + Non-secure images are signed the same way as a secure only
421    # build, but with a different layout file.
422    set(layout_file ${PREPROCESSED_FILE_${SUFFIX}})
423    if(SUFFIX STREQUAL "S_NS")
424      set(SUFFIX "S")
425    endif()
426    set (${OUT_ARG}
427      # Add the MCUBoot script to the path so that if there is a version of imgtool in there then
428      # it gets used over the system imgtool. Used so that imgtool from upstream
429      # mcuboot is preferred over system imgtool
430      ${CMAKE_COMMAND} -E env PYTHONPATH=${ZEPHYR_MCUBOOT_MODULE_DIR}/scripts
431      ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/wrapper/wrapper.py
432      --layout ${layout_file}
433      -k ${CONFIG_TFM_KEY_FILE_${SUFFIX}}
434      --public-key-format ${TFM_PUBLIC_KEY_FORMAT}
435      --align 1
436      -v ${CONFIG_TFM_IMAGE_VERSION_${SUFFIX}}
437      ${pad_args}
438      ${HEX_ADDR_ARGS_${SUFFIX}}
439      ${ADD_${SUFFIX}_IMAGE_MIN_VER}
440      -s ${CONFIG_TFM_IMAGE_SECURITY_COUNTER}
441      --measured-boot-record
442      -H ${CONFIG_ROM_START_OFFSET}
443      ${INPUT_FILE}
444      ${OUTPUT_FILE}
445      PARENT_SCOPE)
446  endfunction()
447
448  set(MERGED_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_merged.hex)
449  set(S_NS_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_zephyr_ns.hex)
450  set(S_NS_SIGNED_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_zephyr_ns_signed.hex)
451  set(NS_SIGNED_FILE ${CMAKE_BINARY_DIR}/zephyr/zephyr_ns_signed.hex)
452  set(S_SIGNED_FILE ${CMAKE_BINARY_DIR}/zephyr/tfm_s_signed.hex)
453
454  if (CONFIG_TFM_USE_NS_APP)
455    # Use the TF-M NS binary as the Non-Secure application firmware image
456    set(NS_APP_FILE $<TARGET_PROPERTY:tfm,TFM_NS_HEX_FILE>)
457  else()
458    # Use the Zephyr binary as the Non-Secure application firmware image
459    set(NS_APP_FILE ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_HEX_NAME})
460  endif()
461
462  if (NOT CONFIG_TFM_BL2)
463    # Merge tfm_s and zephyr (NS) image to a single binary.
464    set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
465      COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py
466        -o ${MERGED_FILE}
467        $<TARGET_PROPERTY:tfm,TFM_S_HEX_FILE>
468        ${NS_APP_FILE}
469    )
470
471    set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts
472      ${MERGED_FILE}
473    )
474
475  elseif(CONFIG_TFM_MCUBOOT_IMAGE_NUMBER STREQUAL "1")
476    tfm_sign(sign_cmd S_NS TRUE ${S_NS_FILE} ${S_NS_SIGNED_FILE})
477
478    set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
479      COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py
480        -o ${S_NS_FILE}
481        $<TARGET_PROPERTY:tfm,TFM_S_HEX_FILE>
482        ${NS_APP_FILE}
483
484      COMMAND ${sign_cmd}
485
486      COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py
487        -o ${MERGED_FILE}
488        $<TARGET_PROPERTY:tfm,BL2_HEX_FILE>
489        ${S_NS_SIGNED_FILE}
490    )
491
492    set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts
493      ${S_NS_FILE}
494      ${S_NS_SIGNED_FILE}
495      ${MERGED_FILE}
496    )
497
498  else()
499    if (CONFIG_TFM_USE_NS_APP)
500      tfm_sign(sign_cmd_ns NS TRUE ${NS_APP_FILE} ${NS_SIGNED_FILE})
501    else()
502      tfm_sign(sign_cmd_ns NS FALSE ${NS_APP_FILE} ${NS_SIGNED_FILE})
503    endif()
504
505    tfm_sign(sign_cmd_s S TRUE $<TARGET_PROPERTY:tfm,TFM_S_HEX_FILE> ${S_SIGNED_FILE})
506
507    #Create and sign for concatenated binary image, should align with the TF-M BL2
508    set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
509      COMMAND ${sign_cmd_ns}
510      COMMAND ${sign_cmd_s}
511
512      COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py
513        -o ${MERGED_FILE}
514        $<TARGET_PROPERTY:tfm,BL2_HEX_FILE>
515        ${S_SIGNED_FILE}
516        ${NS_SIGNED_FILE}
517    )
518
519    set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts
520      ${S_SIGNED_FILE}
521      ${NS_SIGNED_FILE}
522      ${MERGED_FILE}
523    )
524  endif()
525
526  if(CONFIG_TFM_DUMMY_PROVISIONING)
527    message(WARNING
528      "TFM_DUMMY_PROVISIONING is enabled:
529      The device will be provisioned using dummy keys and is NOT secure!
530      This is not suitable for production"
531      )
532  endif()
533
534endif() # CONFIG_BUILD_WITH_TFM
535