1# Copyright (c) 2019, 2020 Linaro
2# Copyright (c) 2020, 2021 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/config/config_default.cmake'
8set(TFM_VALID_PARTITIONS
9  TFM_PARTITION_PROTECTED_STORAGE
10  TFM_PARTITION_INTERNAL_TRUSTED_STORAGE
11  TFM_PARTITION_CRYPTO
12  TFM_PARTITION_INITIAL_ATTESTATION
13  TFM_PARTITION_PLATFORM
14  TFM_PARTITION_AUDIT_LOG
15  )
16
17# List of all crypto modules that can be enabled/disabled
18# Corresponds to the *_MODULE_DISABLED configs in 'trusted-firmware-m/config/config_default.cmake'
19set(TFM_CRYPTO_MODULES
20  CRYPTO_RNG_MODULE
21  CRYPTO_KEY_MODULE
22  CRYPTO_AEAD_MODULE
23  CRYPTO_MAC_MODULE
24  CRYPTO_HASH_MODULE
25  CRYPTO_CIPHER_MODULE
26  CRYPTO_GENERATOR_MODULE
27  CRYPTO_ASYMMETRIC_MODULE
28  CRYPTO_KEY_DERIVATION_MODULE
29  )
30
31
32if (CONFIG_BUILD_WITH_TFM)
33  if (CONFIG_TFM_IPC)
34    list(APPEND TFM_CMAKE_ARGS -DTFM_PSA_API=ON)
35    # PSA API awareness for the Non-Secure application
36    target_compile_definitions(app PRIVATE "TFM_PSA_API")
37  endif()
38  if (CONFIG_TFM_REGRESSION_S)
39    list(APPEND TFM_CMAKE_ARGS -DTEST_S=ON)
40  endif()
41  if (CONFIG_TFM_REGRESSION_NS)
42    list(APPEND TFM_CMAKE_ARGS -DTEST_NS=ON)
43  endif()
44  if (CONFIG_TFM_BL2)
45    list(APPEND TFM_CMAKE_ARGS -DBL2=TRUE)
46  else()
47    list(APPEND TFM_CMAKE_ARGS -DBL2=FALSE)
48  endif()
49  if (CONFIG_TFM_ISOLATION_LEVEL)
50    list(APPEND TFM_CMAKE_ARGS -DTFM_ISOLATION_LEVEL=${CONFIG_TFM_ISOLATION_LEVEL})
51  endif()
52  if (CONFIG_TFM_PROFILE)
53    list(APPEND TFM_CMAKE_ARGS -DTFM_PROFILE=${CONFIG_TFM_PROFILE})
54  endif()
55  if (CONFIG_TFM_PSA_TEST_CRYPTO)
56    set(TFM_PSA_TEST_SUITE CRYPTO)
57  elseif (CONFIG_TFM_PSA_TEST_PROTECTED_STORAGE)
58    set(TFM_PSA_TEST_SUITE PROTECTED_STORAGE)
59  elseif (CONFIG_TFM_PSA_TEST_INTERNAL_TRUSTED_STORAGE)
60    set(TFM_PSA_TEST_SUITE INTERNAL_TRUSTED_STORAGE)
61  elseif (CONFIG_TFM_PSA_TEST_STORAGE)
62    set(TFM_PSA_TEST_SUITE STORAGE)
63  elseif (CONFIG_TFM_PSA_TEST_INITIAL_ATTESTATION)
64    set(TFM_PSA_TEST_SUITE INITIAL_ATTESTATION)
65  endif()
66  if (DEFINED TFM_PSA_TEST_SUITE)
67    list(APPEND TFM_CMAKE_ARGS -DTEST_PSA_API=${TFM_PSA_TEST_SUITE})
68  endif()
69  if (CONFIG_TFM_CMAKE_BUILD_TYPE_RELEASE)
70    set(TFM_CMAKE_BUILD_TYPE "Release")
71  elseif (CONFIG_TFM_CMAKE_BUILD_TYPE_MINSIZEREL)
72    set(TFM_CMAKE_BUILD_TYPE "MinSizeRel")
73  elseif (CONFIG_TFM_CMAKE_BUILD_TYPE_DEBUG)
74    set(TFM_CMAKE_BUILD_TYPE "Debug")
75  else ()
76    set(TFM_CMAKE_BUILD_TYPE "RelWithDebInfo")
77  endif()
78  if (DEFINED CONFIG_TFM_MCUBOOT_IMAGE_NUMBER)
79    list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_IMAGE_NUMBER=${CONFIG_TFM_MCUBOOT_IMAGE_NUMBER})
80  endif()
81
82  # Enable TFM partitions as specified in Kconfig
83  foreach(partition ${TFM_VALID_PARTITIONS})
84    if (CONFIG_${partition})
85      # list(APPEND TFM_ENABLED_PARTITIONS_ARG ${partition})
86      set(val "ON")
87    else()
88      set(val "OFF")
89    endif()
90    list(APPEND TFM_CMAKE_ARGS -D${partition}=${val})
91  endforeach()
92
93  # Enable TFM crypto modules as specified in Kconfig
94  foreach(module ${TFM_CRYPTO_MODULES})
95    if (CONFIG_TFM_${module}_ENABLED)
96      # list(APPEND TFM_ENABLED_CRYPTO_MODULES_ARG ${module})
97      set(val "FALSE")
98    else()
99      set(val "TRUE")
100    endif()
101    list(APPEND TFM_CMAKE_ARGS -D${module}_DISABLED=${val})
102  endforeach()
103
104  set(TFM_BINARY_DIR ${CMAKE_BINARY_DIR}/tfm)
105
106  set(VENEERS_FILE ${TFM_BINARY_DIR}/secure_fw/s_veneers.o)
107  set(TFM_API_NS_PATH ${TFM_BINARY_DIR}/app/libtfm_api_ns.a)
108  set(TFM_GENERATED_INCLUDES ${TFM_BINARY_DIR}/generated/interface/include)
109  set(PLATFORM_NS_FILE ${TFM_BINARY_DIR}/platform/libplatform_ns.a)
110
111  if (TFM_PSA_TEST_SUITE)
112    set(PSA_TEST_VAL_FILE ${TFM_BINARY_DIR}/app/psa_api_tests/val/val_nspe.a)
113    set(PSA_TEST_PAL_FILE ${TFM_BINARY_DIR}/app/psa_api_tests/platform/pal_nspe.a)
114    set(COMBINE_DIR_STORAGE storage)
115    set(COMBINE_DIR_PROTECTED_STORAGE storage)
116    set(COMBINE_DIR_INTERNAL_TRUSTED_STORAGE storage)
117    set(COMBINE_DIR_CRYPTO crypto)
118    set(COMBINE_DIR_INITIAL_ATTESTATION initial_attestation)
119    set(PSA_TEST_COMBINE_FILE ${TFM_BINARY_DIR}/app/psa_api_tests/dev_apis/${COMBINE_DIR_${TFM_PSA_TEST_SUITE}}/test_combine.a)
120  endif()
121
122  if(CONFIG_TFM_BL2)
123    set(BL2_BIN_FILE ${TFM_BINARY_DIR}/bin/bl2.bin)
124    set(BL2_HEX_FILE ${TFM_BINARY_DIR}/bin/bl2.hex)
125  endif()
126  set(TFM_S_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_s.bin)
127  set(TFM_S_HEX_FILE ${TFM_BINARY_DIR}/bin/tfm_s.hex)
128  set(TFM_NS_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_ns.bin)
129  set(TFM_NS_HEX_FILE ${TFM_BINARY_DIR}/bin/tfm_ns.hex)
130  set(TFM_S_SIGNED_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_s_signed.bin)
131  set(TFM_NS_SIGNED_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_ns_signed.bin)
132  set(TFM_S_NS_SIGNED_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_s_ns_signed.bin)
133
134  set(BUILD_BYPRODUCTS
135    ${VENEERS_FILE}
136    ${TFM_API_NS_PATH}
137    ${TFM_GENERATED_INCLUDES}/psa_manifest/sid.h
138    ${PSA_TEST_VAL_FILE}
139    ${PSA_TEST_PAL_FILE}
140    ${PSA_TEST_COMBINE_FILE}
141    ${PLATFORM_NS_FILE}
142    ${BL2_BIN_FILE}
143    ${BL2_HEX_FILE}
144    ${TFM_S_BIN_FILE}
145    ${TFM_S_HEX_FILE}
146    ${TFM_NS_BIN_FILE}
147    ${TFM_NS_HEX_FILE}
148    ${TFM_S_SIGNED_BIN_FILE}
149    ${TFM_NS_SIGNED_BIN_FILE}
150    ${TFM_S_NS_SIGNED_BIN_FILE}
151    )
152
153  # Get the toolchain variant
154  # TODO: Add support for cross-compile toolchain variant
155  # TODO: Enforce GCC version check against TF-M compiler requirements
156  if(${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "zephyr")
157    set(TFM_TOOLCHAIN_FILE "trusted-firmware-m/toolchain_GNUARM.cmake")
158    set(TFM_TOOLCHAIN_PREFIX "arm-zephyr-eabi")
159    set(TFM_TOOLCHAIN_PATH ${ZEPHYR_SDK_INSTALL_DIR}/arm-zephyr-eabi/bin)
160  elseif(${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "gnuarmemb")
161    set(TFM_TOOLCHAIN_FILE "trusted-firmware-m/toolchain_GNUARM.cmake")
162    set(TFM_TOOLCHAIN_PREFIX "arm-none-eabi")
163    set(TFM_TOOLCHAIN_PATH ${GNUARMEMB_TOOLCHAIN_PATH}/bin)
164  elseif(${ZEPHYR_TOOLCHAIN_VARIANT} STREQUAL "xtools")
165    set(TFM_TOOLCHAIN_FILE "trusted-firmware-m/toolchain_GNUARM.cmake")
166    set(TFM_TOOLCHAIN_PREFIX "arm-zephyr-eabi")
167    set(TFM_TOOLCHAIN_PATH ${XTOOLS_TOOLCHAIN_PATH}/arm-zephyr-eabi/bin)
168  else()
169    message(FATAL_ERROR "Unsupported ZEPHYR_TOOLCHAIN_VARIANT: ${ZEPHYR_TOOLCHAIN_VARIANT}")
170  endif()
171
172  if(CONFIG_BOARD_LPCXPRESSO55S69_CPU0)
173    # Supply path to NXP HAL sources used for TF-M build
174    set(TFM_PLATFORM_NXP_HAL_FILE_PATH ${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/trusted-firmware-m/platform/ext/target/nxp/)
175    list(APPEND TFM_CMAKE_ARGS -DTFM_PLATFORM_NXP_HAL_FILE_PATH=${TFM_PLATFORM_NXP_HAL_FILE_PATH})
176  endif()
177
178  if(CONFIG_TFM_BL2 AND CONFIG_TFM_MCUBOOT_PATH_LOCAL)
179    # Supply path to MCUboot for TF-M build
180    list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_PATH=${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/../../../bootloader/mcuboot)
181  endif()
182
183  file(MAKE_DIRECTORY ${TFM_BINARY_DIR})
184  add_custom_target(tfm_cmake
185    DEPENDS ${TFM_BINARY_DIR}/CMakeCache.txt
186  )
187  add_custom_command(
188    OUTPUT ${TFM_BINARY_DIR}/CMakeCache.txt
189    COMMAND ${CMAKE_COMMAND}
190      -G${CMAKE_GENERATOR}
191      -DTFM_TOOLCHAIN_FILE=${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/${TFM_TOOLCHAIN_FILE}
192      -DTFM_PLATFORM=${TFM_BOARD}
193      -DCROSS_COMPILE=${TFM_TOOLCHAIN_PATH}/${TFM_TOOLCHAIN_PREFIX}
194      -DCMAKE_BUILD_TYPE=${TFM_CMAKE_BUILD_TYPE}
195      -DTFM_PLATFORM=${CONFIG_TFM_BOARD}
196      ${TFM_CMAKE_ARGS}
197      $<GENEX_EVAL:$<TARGET_PROPERTY:zephyr_property_target,TFM_CMAKE_OPTIONS>>
198      -DTFM_TEST_REPO_PATH=${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/tf-m-tests
199      -DMBEDCRYPTO_PATH=$<IF:$<BOOL:$<TARGET_PROPERTY:zephyr_property_target,TFM_MBEDCRYPTO_PATH>>,$<TARGET_PROPERTY:zephyr_property_target,TFM_MBEDCRYPTO_PATH>,${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/../../crypto/mbedtls/mbedtls>
200      -DPSA_ARCH_TESTS_PATH=${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/psa-arch-tests
201      ${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/trusted-firmware-m
202    WORKING_DIRECTORY ${TFM_BINARY_DIR}
203    COMMAND_EXPAND_LISTS
204  )
205
206  include(ExternalProject)
207
208  ExternalProject_Add(
209    tfm
210    SOURCE_DIR ${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/trusted-firmware-m
211    BINARY_DIR ${TFM_BINARY_DIR}
212    CONFIGURE_COMMAND ""
213    BUILD_COMMAND ${CMAKE_COMMAND} --build .
214    INSTALL_COMMAND ${CMAKE_COMMAND} --install .
215    BUILD_ALWAYS True
216    USES_TERMINAL_BUILD True
217    DEPENDS tfm_cmake
218    BUILD_BYPRODUCTS ${BUILD_BYPRODUCTS}
219  )
220
221  # Set BL2 (MCUboot) executable file paths as target properties on 'tfm'
222  # These files are produced by the TFM build system.
223  if(CONFIG_TFM_BL2)
224    set_target_properties(tfm PROPERTIES
225      BL2_BIN_FILE ${BL2_BIN_FILE}
226      BL2_HEX_FILE ${BL2_HEX_FILE}
227      )
228  endif()
229
230  # Set TFM S/NS executable file paths as target properties on 'tfm'
231  # These files are produced by the TFM build system.
232  # Note that the Nonsecure FW is replaced by the Zephyr app in regular Zephyr
233  # builds.
234  set_target_properties(tfm PROPERTIES
235    TFM_S_BIN_FILE ${TFM_S_BIN_FILE} # TFM Secure FW (unsigned)
236    TFM_S_HEX_FILE ${TFM_S_HEX_FILE} # TFM Secure FW (unsigned)
237    TFM_NS_BIN_FILE ${TFM_NS_BIN_FILE} # TFM Nonsecure FW (unsigned)
238    TFM_NS_HEX_FILE ${TFM_NS_HEX_FILE} # TFM Nonsecure FW (unsigned)
239    TFM_S_SIGNED_BIN_FILE ${TFM_S_SIGNED_BIN_FILE} # TFM Secure FW (signed)
240    TFM_NS_SIGNED_BIN_FILE ${TFM_NS_SIGNED_BIN_FILE} # TFM Nonsecure FW (signed)
241    TFM_S_NS_SIGNED_BIN_FILE ${TFM_S_NS_SIGNED_BIN_FILE} # Merged TFM Secure/Nonsecure FW (signed)
242    )
243
244  zephyr_library_named(tfm_api)
245
246  zephyr_library_sources(
247    src/zephyr_tfm_log.c
248    interface/interface.c
249    )
250  # Non-Secure interface to request system reboot
251  zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_PLATFORM src/reboot.c)
252  zephyr_library_sources_ifndef(CONFIG_TFM_PSA_TEST_NONE src/zephyr_tfm_psa_test.c)
253
254  zephyr_include_directories(
255    ${TFM_GENERATED_INCLUDES}
256    )
257
258  target_include_directories(tfm_api PRIVATE
259    ${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/trusted-firmware-m/interface/include
260    )
261
262  zephyr_library_link_libraries(
263    ${PSA_TEST_VAL_FILE}
264    ${PSA_TEST_PAL_FILE}
265    ${PSA_TEST_COMBINE_FILE}
266    ${PLATFORM_NS_FILE}
267    ${TFM_API_NS_PATH}
268    ${VENEERS_FILE}
269    )
270
271  # To ensure that generated include files are created before they are used.
272  add_dependencies(zephyr_interface tfm)
273
274  # Set default image versions if not defined elsewhere
275  if (NOT DEFINED TFM_IMAGE_VERSION_S)
276    set(TFM_IMAGE_VERSION_S 0.0.0+0)
277  endif()
278
279  if (NOT DEFINED TFM_IMAGE_VERSION_NS)
280    set(TFM_IMAGE_VERSION_NS 0.0.0+0)
281  endif()
282
283  if (CONFIG_TFM_BL2)
284    set(PREPROCESSED_FILE_S "${CMAKE_BINARY_DIR}/tfm/bl2/ext/mcuboot/CMakeFiles/signing_layout_s.dir/signing_layout_s.o")
285    set(PREPROCESSED_FILE_NS "${CMAKE_BINARY_DIR}/tfm/bl2/ext/mcuboot/CMakeFiles/signing_layout_ns.dir/signing_layout_ns.o")
286    set(TFM_MCUBOOT_DIR "${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/trusted-firmware-m/bl2/ext/mcuboot")
287  endif()
288
289  # Configure which format (full or hash) to include the public key in
290  # the image manifest
291  if(NOT DEFINED TFM_PUBLIC_KEY_FORMAT)
292    set(TFM_PUBLIC_KEY_FORMAT "full")
293  endif()
294
295  if(DEFINED TFM_HEX_BASE_ADDRESS_S)
296    set(HEX_ADDR_ARGS_S "--hex-addr=${TFM_HEX_BASE_ADDRESS_S}")
297  endif()
298
299  if(DEFINED TFM_HEX_BASE_ADDRESS_NS)
300    set(HEX_ADDR_ARGS_NS "--hex-addr=${TFM_HEX_BASE_ADDRESS_NS}")
301  endif()
302
303  function(tfm_sign OUT_ARG SUFFIX PAD INPUT_FILE OUTPUT_FILE)
304    if(PAD)
305      set(pad_args --pad --pad-header)
306    endif()
307    set (${OUT_ARG}
308      ${PYTHON_EXECUTABLE} ${TFM_MCUBOOT_DIR}/scripts/wrapper/wrapper.py
309      --layout ${PREPROCESSED_FILE_${SUFFIX}}
310      -k ${CONFIG_TFM_KEY_FILE_${SUFFIX}}
311      --public-key-format ${TFM_PUBLIC_KEY_FORMAT}
312      --align 1
313      -v ${TFM_IMAGE_VERSION_${SUFFIX}}
314      ${pad_args}
315      ${HEX_ADDR_ARGS_${SUFFIX}}
316      ${ADD_${SUFFIX}_IMAGE_MIN_VER}
317      -s auto
318      -H ${CONFIG_ROM_START_OFFSET}
319      ${INPUT_FILE}
320      ${OUTPUT_FILE}
321      PARENT_SCOPE)
322  endfunction()
323
324  set(MERGED_FILE ${CMAKE_BINARY_DIR}/tfm_merged.hex)
325  set(S_NS_FILE ${CMAKE_BINARY_DIR}/tfm_s_zephyr_ns.hex)
326  set(S_NS_SIGNED_FILE ${CMAKE_BINARY_DIR}/tfm_s_zephyr_ns_signed.hex)
327  set(NS_SIGNED_FILE ${CMAKE_BINARY_DIR}/zephyr_ns_signed.hex)
328  set(S_SIGNED_FILE ${CMAKE_BINARY_DIR}/tfm_s_signed.hex)
329
330  if (CONFIG_TFM_REGRESSION_NS)
331    # Use the TF-M NS binary as the Non-Secure application firmware image
332    set(NS_APP_FILE $<TARGET_PROPERTY:tfm,TFM_NS_HEX_FILE>)
333  else()
334    # Use the Zephyr binary as the Non-Secure application firmware image
335    set(NS_APP_FILE ${CMAKE_BINARY_DIR}/zephyr/${KERNEL_HEX_NAME})
336  endif()
337
338  if (NOT CONFIG_TFM_BL2)
339    # Merge tfm_s and zephyr (NS) image to a single binary.
340    set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
341      COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/mergehex.py
342        -o ${MERGED_FILE}
343        $<TARGET_PROPERTY:tfm,TFM_S_HEX_FILE>
344        ${NS_APP_FILE}
345    )
346
347    set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts
348      ${MERGED_FILE}
349    )
350
351  elseif(CONFIG_TFM_MCUBOOT_IMAGE_NUMBER STREQUAL "1")
352    tfm_sign(sign_cmd NS TRUE ${S_NS_FILE} ${S_NS_SIGNED_FILE})
353
354    set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
355      COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/mergehex.py
356        -o ${S_NS_FILE}
357        $<TARGET_PROPERTY:tfm,TFM_S_HEX_FILE>
358        ${NS_APP_FILE}
359
360      COMMAND ${sign_cmd}
361
362      COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/mergehex.py
363        -o ${MERGED_FILE}
364        $<TARGET_PROPERTY:tfm,BL2_HEX_FILE>
365        ${S_NS_SIGNED_FILE}
366    )
367
368    set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts
369      ${S_NS_FILE}
370      ${S_NS_SIGNED_FILE}
371      ${MERGED_FILE}
372    )
373
374  else()
375    if (CONFIG_TFM_REGRESSION_NS)
376      tfm_sign(sign_cmd_ns NS TRUE ${NS_APP_FILE} ${NS_SIGNED_FILE})
377    else()
378      tfm_sign(sign_cmd_ns NS FALSE ${NS_APP_FILE} ${NS_SIGNED_FILE})
379    endif()
380
381    tfm_sign(sign_cmd_s S TRUE $<TARGET_PROPERTY:tfm,TFM_S_HEX_FILE> ${S_SIGNED_FILE})
382
383    #Create and sign for concatenated binary image, should align with the TF-M BL2
384    set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
385      COMMAND ${sign_cmd_ns}
386      COMMAND ${sign_cmd_s}
387
388      COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/mergehex.py
389        -o ${MERGED_FILE}
390        $<TARGET_PROPERTY:tfm,BL2_HEX_FILE>
391        ${S_SIGNED_FILE}
392        ${NS_SIGNED_FILE}
393    )
394
395    set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts
396      ${S_SIGNED_FILE}
397      ${NS_SIGNED_FILE}
398      ${MERGED_FILE}
399    )
400  endif()
401endif()
402