1idf_build_get_property(idf_target IDF_TARGET)
2idf_build_get_property(python PYTHON)
3
4if(NOT ${IDF_TARGET} STREQUAL "linux")
5set(priv_requires soc esp_hw_support)
6
7if(NOT BOOTLOADER_BUILD)
8    list(APPEND priv_requires esp_pm)
9endif()
10endif()
11
12set(mbedtls_srcs "")
13set(mbedtls_include_dirs "port/include" "mbedtls/include" "mbedtls/library")
14
15if(CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL)
16    list(APPEND mbedtls_include_dirs "port/mbedtls_rom")
17endif()
18
19if(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE)
20    list(APPEND mbedtls_srcs "esp_crt_bundle/esp_crt_bundle.c")
21    list(APPEND mbedtls_include_dirs "esp_crt_bundle/include")
22endif()
23
24idf_component_register(SRCS "${mbedtls_srcs}"
25    INCLUDE_DIRS "${mbedtls_include_dirs}"
26    PRIV_REQUIRES "${priv_requires}"
27    )
28
29# Determine the type of mbedtls component library
30if(mbedtls_srcs STREQUAL "")
31    # For no sources in component library we must use "INTERFACE"
32    set(linkage_type INTERFACE)
33else()
34    set(linkage_type PUBLIC)
35endif()
36
37
38if(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE)
39    set(bundle_name "x509_crt_bundle")
40    set(DEFAULT_CRT_DIR ${COMPONENT_DIR}/esp_crt_bundle)
41
42    # Generate custom certificate bundle using the generate_cert_bundle utility
43    set(GENERATE_CERT_BUNDLEPY ${python} ${COMPONENT_DIR}/esp_crt_bundle/gen_crt_bundle.py)
44
45    if(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL)
46        list(APPEND crt_paths ${DEFAULT_CRT_DIR}/cacrt_all.pem ${DEFAULT_CRT_DIR}/cacrt_local.pem)
47    elseif(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN)
48        list(APPEND crt_paths ${DEFAULT_CRT_DIR}/cacrt_all.pem ${DEFAULT_CRT_DIR}/cacrt_local.pem)
49        list(APPEND args --filter ${DEFAULT_CRT_DIR}/cmn_crt_authorities.csv)
50    endif()
51
52    if(CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE)
53        get_filename_component(custom_bundle_path
54        ${CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH} ABSOLUTE BASE_DIR "${project_dir}")
55        list(APPEND crt_paths ${custom_bundle_path})
56
57    endif()
58    list(APPEND args --input ${crt_paths} -q)
59
60    get_filename_component(crt_bundle
61        ${bundle_name}
62        ABSOLUTE BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
63
64    # Generate bundle according to config
65    add_custom_command(OUTPUT ${crt_bundle}
66        COMMAND ${GENERATE_CERT_BUNDLEPY} ${args}
67        DEPENDS ${custom_bundle_path}
68        VERBATIM)
69
70    add_custom_target(custom_bundle DEPENDS ${cert_bundle})
71    add_dependencies(${COMPONENT_LIB} custom_bundle)
72
73
74    target_add_binary_data(${COMPONENT_LIB} ${crt_bundle} BINARY)
75    set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
76        APPEND PROPERTY ADDITIONAL_CLEAN_FILES
77        "${crt_bundle}")
78endif()
79
80
81# Only build mbedtls libraries
82set(ENABLE_TESTING CACHE BOOL OFF)
83set(ENABLE_PROGRAMS CACHE BOOL OFF)
84
85# Use pre-generated source files in mbedtls repository
86set(GEN_FILES CACHE BOOL OFF)
87
88# Make sure mbedtls finds the same Python interpreter as IDF uses
89idf_build_get_property(python PYTHON)
90set(Python3_EXECUTABLE ${python})
91
92# Needed to for include_next includes to work from within mbedtls
93set(include_dirs "${COMPONENT_DIR}/port/include")
94
95if(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE)
96    list(APPEND include_dirs "${COMPONENT_DIR}/esp_crt_bundle/include")
97endif()
98
99include_directories(${include_dirs})
100
101# Needed to for mbedtls_rom includes to work from within mbedtls
102if(CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL)
103    include_directories("${COMPONENT_DIR}/port/mbedtls_rom")
104endif()
105
106# Import mbedtls library targets
107add_subdirectory(mbedtls)
108
109# Use port specific implementation of net_socket.c instead of one from mbedtls
110get_target_property(src_tls mbedtls SOURCES)
111list(REMOVE_ITEM src_tls net_sockets.c)
112set_property(TARGET mbedtls PROPERTY SOURCES ${src_tls})
113
114if(CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1)
115get_target_property(src_tls mbedtls SOURCES)
116list(REMOVE_ITEM src_tls ssl_ciphersuites.c ssl_cli.c ssl_tls.c)
117set_property(TARGET mbedtls PROPERTY SOURCES ${src_tls})
118
119get_target_property(src_crypto mbedcrypto SOURCES)
120list(REMOVE_ITEM src_crypto cipher_wrap.c ecdsa.c ecp.c ecp_curves.c oid.c pk_wrap.c)
121set_property(TARGET mbedcrypto PROPERTY SOURCES ${src_crypto})
122
123get_target_property(src_x509 mbedx509 SOURCES)
124list(REMOVE_ITEM src_x509 x509_crt.c)
125set_property(TARGET mbedx509 PROPERTY SOURCES ${src_x509})
126endif()
127
128# Core libraries from the mbedTLS project
129set(mbedtls_targets mbedtls mbedcrypto mbedx509)
130# 3rd party libraries from the mbedTLS project
131list(APPEND mbedtls_targets everest p256m)
132
133set(mbedtls_target_sources "${COMPONENT_DIR}/port/mbedtls_debug.c"
134                           "${COMPONENT_DIR}/port/esp_platform_time.c")
135
136if(CONFIG_MBEDTLS_DYNAMIC_BUFFER)
137set(mbedtls_target_sources ${mbedtls_target_sources}
138                           "${COMPONENT_DIR}/port/dynamic/esp_mbedtls_dynamic_impl.c"
139                           "${COMPONENT_DIR}/port/dynamic/esp_ssl_cli.c"
140                           "${COMPONENT_DIR}/port/dynamic/esp_ssl_srv.c"
141                           "${COMPONENT_DIR}/port/dynamic/esp_ssl_tls.c")
142endif()
143
144if(${IDF_TARGET} STREQUAL "linux")
145set(mbedtls_target_sources ${mbedtls_target_sources} "${COMPONENT_DIR}/port/net_sockets.c")
146endif()
147
148# While updating to MbedTLS release/v3.4.0, building mbedtls/library/psa_crypto.c
149# clang produces an unreachable-code warning.
150if(CMAKE_C_COMPILER_ID MATCHES "Clang")
151    target_compile_options(mbedcrypto PRIVATE "-Wno-unreachable-code")
152endif()
153
154# net_sockets.c should only be compiled if BSD socket functions are available.
155# Do this by checking if lwip component is included into the build.
156idf_build_get_property(build_components BUILD_COMPONENTS)
157if(lwip IN_LIST build_components)
158    list(APPEND mbedtls_target_sources "${COMPONENT_DIR}/port/net_sockets.c")
159    idf_component_get_property(lwip_lib lwip COMPONENT_LIB)
160    target_link_libraries(${COMPONENT_LIB} ${linkage_type} ${lwip_lib})
161endif()
162
163# Add port files to mbedtls targets
164target_sources(mbedtls PRIVATE ${mbedtls_target_sources})
165
166# Choose perihperal type
167
168if(CONFIG_SOC_SHA_SUPPORTED)
169    if(CONFIG_SOC_SHA_SUPPORT_DMA)
170        set(SHA_PERIPHERAL_TYPE "dma")
171    elseif(CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG)
172        set(SHA_PERIPHERAL_TYPE "parallel_engine")
173    else()
174        set(SHA_PERIPHERAL_TYPE "block")
175    endif()
176endif()
177
178if(CONFIG_SOC_AES_SUPPORTED)
179    if(CONFIG_SOC_AES_SUPPORT_DMA)
180        set(AES_PERIPHERAL_TYPE "dma")
181    else()
182        set(AES_PERIPHERAL_TYPE "block")
183    endif()
184endif()
185
186if(SHA_PERIPHERAL_TYPE STREQUAL "dma")
187    target_include_directories(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/sha/dma/include")
188
189    if(NOT CONFIG_SOC_SHA_GDMA)
190        set(SHA_DMA_SRCS "${COMPONENT_DIR}/port/sha/dma/esp_sha_crypto_dma_impl.c")
191    else()
192        set(SHA_DMA_SRCS "${COMPONENT_DIR}/port/sha/dma/esp_sha_gdma_impl.c")
193
194    endif()
195    target_sources(mbedcrypto PRIVATE  "${SHA_DMA_SRCS}")
196endif()
197
198if(AES_PERIPHERAL_TYPE STREQUAL "dma")
199    if(NOT CONFIG_SOC_AES_GDMA)
200        set(AES_DMA_SRCS "${COMPONENT_DIR}/port/aes/dma/esp_aes_crypto_dma_impl.c")
201    else()
202        set(AES_DMA_SRCS "${COMPONENT_DIR}/port/aes/dma/esp_aes_gdma_impl.c"
203                         "${COMPONENT_DIR}/port/crypto_shared_gdma/esp_crypto_shared_gdma.c")
204    endif()
205
206    target_include_directories(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/aes/dma/include")
207    target_sources(mbedcrypto PRIVATE  "${AES_DMA_SRCS}")
208endif()
209
210
211target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c"
212                                  "${COMPONENT_DIR}/port/esp_mem.c"
213                                  "${COMPONENT_DIR}/port/esp_timing.c"
214)
215
216if(CONFIG_SOC_AES_SUPPORTED)
217    target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/aes/esp_aes_xts.c"
218                                  "${COMPONENT_DIR}/port/aes/esp_aes_common.c"
219                                  "${COMPONENT_DIR}/port/aes/${AES_PERIPHERAL_TYPE}/esp_aes.c"
220    )
221endif()
222
223if(CONFIG_SOC_SHA_SUPPORTED)
224    target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/sha/esp_sha.c"
225                                    "${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/sha.c"
226    )
227endif()
228
229# CONFIG_ESP_TLS_USE_DS_PERIPHERAL can be enabled only for the supported targets.
230if(CONFIG_ESP_TLS_USE_DS_PERIPHERAL)
231    target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_ds/esp_rsa_sign_alt.c")
232endif()
233
234# Note: some mbedTLS hardware acceleration can be enabled/disabled by config.
235#
236# We don't need to filter aes.c as this uses a different prefix (esp_aes_x) and the
237# config option only changes the prefixes in the header so mbedtls_aes_x compiles to esp_aes_x
238#
239# The other port-specific files don't override internal mbedTLS functions, they just add new functions.
240
241if(CONFIG_MBEDTLS_HARDWARE_MPI)
242    target_sources(mbedcrypto PRIVATE  "${COMPONENT_DIR}/port/esp_bignum.c"
243                                       "${COMPONENT_DIR}/port/${idf_target}/bignum.c"
244    )
245endif()
246
247if(CONFIG_MBEDTLS_HARDWARE_SHA)
248    target_sources(mbedcrypto PRIVATE  "${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/esp_sha1.c"
249                                       "${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/esp_sha256.c"
250                                       "${COMPONENT_DIR}/port/sha/${SHA_PERIPHERAL_TYPE}/esp_sha512.c"
251    )
252endif()
253
254if(CONFIG_MBEDTLS_HARDWARE_GCM OR CONFIG_MBEDTLS_HARDWARE_AES)
255    target_sources(mbedcrypto PRIVATE  "${COMPONENT_DIR}/port/aes/esp_aes_gcm.c")
256endif()
257
258if(CONFIG_MBEDTLS_HARDWARE_ECC)
259    target_sources(mbedcrypto PRIVATE  "${COMPONENT_DIR}/port/ecc/esp_ecc.c"
260                                       "${COMPONENT_DIR}/port/ecc/ecc_alt.c")
261endif()
262
263if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN OR CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY)
264    target_sources(mbedcrypto PRIVATE  "${COMPONENT_DIR}/port/ecdsa/ecdsa_alt.c")
265
266    if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN)
267        target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_sign")
268        target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_sign_restartable")
269        target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_write_signature")
270        target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_write_signature_restartable")
271    endif()
272
273    if(CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY)
274        target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_verify")
275        target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_verify_restartable")
276        target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_read_signature")
277        target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_read_signature_restartable")
278    endif()
279endif()
280
281if(CONFIG_MBEDTLS_ROM_MD5)
282    target_sources(mbedcrypto PRIVATE  "${COMPONENT_DIR}/port/md/esp_md.c")
283endif()
284
285if(CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL)
286    target_sources(mbedcrypto PRIVATE  "${COMPONENT_DIR}/port/mbedtls_rom/mbedtls_rom_osi.c")
287    target_link_libraries(${COMPONENT_LIB} PRIVATE "-u mbedtls_rom_osi_functions_init")
288endif()
289
290foreach(target ${mbedtls_targets})
291    target_compile_definitions(${target} PUBLIC -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h")
292endforeach()
293
294if(CONFIG_MBEDTLS_DYNAMIC_BUFFER)
295    set(WRAP_FUNCTIONS
296        mbedtls_ssl_write_client_hello
297        mbedtls_ssl_handshake_client_step
298        mbedtls_ssl_handshake_server_step
299        mbedtls_ssl_read
300        mbedtls_ssl_write
301        mbedtls_ssl_session_reset
302        mbedtls_ssl_free
303        mbedtls_ssl_setup
304        mbedtls_ssl_send_alert_message
305        mbedtls_ssl_close_notify)
306
307    foreach(wrap ${WRAP_FUNCTIONS})
308        target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=${wrap}")
309    endforeach()
310endif()
311
312set_property(TARGET mbedcrypto APPEND PROPERTY LINK_INTERFACE_LIBRARIES mbedtls)
313
314if(CONFIG_PM_ENABLE)
315    target_link_libraries(mbedcrypto PRIVATE idf::esp_pm)
316endif()
317
318if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN OR CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY)
319    target_link_libraries(mbedcrypto PRIVATE idf::efuse)
320endif()
321
322target_link_libraries(${COMPONENT_LIB} ${linkage_type} ${mbedtls_targets})
323
324if(CONFIG_ESP_TLS_USE_DS_PERIPHERAL)
325    # The linker seems to be unable to resolve all the dependencies without increasing this
326    set_property(TARGET mbedcrypto APPEND PROPERTY LINK_INTERFACE_MULTIPLICITY 6)
327endif()
328
329# Additional optional dependencies for the mbedcrypto library
330function(mbedcrypto_optional_deps component_name)
331    idf_build_get_property(components BUILD_COMPONENTS)
332    if(${component_name} IN_LIST components)
333        idf_component_get_property(lib_name ${component_name} COMPONENT_LIB)
334        target_link_libraries(mbedcrypto PRIVATE ${lib_name})
335    endif()
336endfunction()
337
338if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN_CONSTANT_TIME_CM)
339    mbedcrypto_optional_deps(esp_timer idf::esp_timer)
340endif()
341
342# Link esp-cryptoauthlib to mbedtls
343if(CONFIG_ATCA_MBEDTLS_ECDSA)
344    idf_component_optional_requires(PRIVATE espressif__esp-cryptoauthlib esp-cryptoauthlib)
345endif()
346