Aws freertos "cryptoauthlib.h" not being detected

Hi,
I am currently trying to implement atecc libraries such as “cryptoauthlib.h” into my project but the the header file is not being detected as the output after building is:

fatal error: cryptoauthlib.h: No such file or directory

The file is currently under freertos/vendors/microchip/secure_elements/lib/cryptoauthlib.h

Here is the project hierarchy:

-freertos
-fsonet_lib
    -CMakeLists.txt
    -src
    -include
-src
    -main.c
-CMakeLists.txt

Here are the contents of the CMakeLists.txt in fsonet_lib:

# include paths of this components.
set(COMPONENT_ADD_INCLUDEDIRS include)

# source files of this components.
set(COMPONENT_SRCDIRS src)
# Alternatively, use COMPONENT_SRCS to specify source files explicitly
# set(COMPONENT_SRCS src)

# add this components, this will define a CMake library target.
register_component()

# standard CMake function can be used to specify dependencies. ${COMPONENT_TARGET} is defined
# from esp-idf when you call register_component, by default it's idf_component_<folder_name>.
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::core_mqtt)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::mqtt)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::mqtt_demo_helpers)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::core_json)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::core_mqtt_demo_dependencies)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::common)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::crypto)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::dev_mode_key_provisioning)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::kernel)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::ota)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::pkcs11)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::pkcs11_implementation)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::pkcs11_helpers)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::pkcs11_utils)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::platform)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::secure_sockets)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::transport_interface_secure_sockets)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::serializer)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::shadow)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::device_shadow)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::device_shadow_demo_dependencies)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::tls)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::wifi)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::common_io)

include_directories(${COMPONENT_TARGET} PRIVATE BEFORE fsonet-configs)

Here is the CMakelists.txt at the highest level of the repository:

cmake_minimum_required(VERSION 3.13)

project(fsonet)

add_executable(my_app src/main.c)

# Tell IDF build to link against this target.
set(IDF_PROJECT_EXECUTABLE my_app)
set(CMAKE_EXECUTABLE_SUFFIX ".elf")

# Add some extra components. IDF_EXTRA_COMPONENT_DIRS is an variable used by ESP-IDF
# to collect extra components.
get_filename_component(
    EXTRA_COMPONENT_DIRS
    "fsonet_lib" ABSOLUTE
)
list(APPEND IDF_EXTRA_COMPONENT_DIRS ${EXTRA_COMPONENT_DIRS})

# As of now there's no offical way to redefine config files outside of FreeRTOS source tree.
# This is a temporary approach to inject an include path so that this takes precedence over the
# config file directory inside FreeRTOS.
include_directories(BEFORE fsonet-configs)

#Set sdkconfig
set(IDF_SDKCONFIG_DEFAULTS "${CMAKE_CURRENT_LIST_DIR}/fsonet-configs/sdkconfig.defaults")

# Add freertos as an subdirectory. AFR_BOARD tells which board to target.
set(AFR_BOARD espressif.esp32_plus_ecc608a_devkitc CACHE INTERNAL "")
add_subdirectory(freertos)

# Link against the mqtt demo so that we can use it. Dependencies of this demo are transitively
# linked.
target_link_libraries(my_app PRIVATE AFR::demo_core_mqtt)
target_link_libraries(my_app PRIVATE AFR::demo_device_shadow)
target_link_libraries(my_app PRIVATE AFR::demo_ota)
target_link_libraries(my_app PRIVATE AFR::shadow)
target_link_libraries(my_app PRIVATE AFR::pkcs11_ecc608a)
#target_link_libraries(my_app PRIVATE AFR::common_io)
include_directories(my_app PRIVATE fsonet-configs)
#include_directories(my_app PRIVATE "amazon-freertos/demos/network_manager")
include_directories(my_app PRIVATE "amazon-freertos/demos/dev_mode_key_provisioning/include")


#Linking esp-idf libraries
set(esp_idf_dir "${CMAKE_CURRENT_LIST_DIR}/freertos/vendors/espressif/esp-idf")
set(IDF_TARGET esp32)
set(ENV{IDF_PATH} ${esp_idf_dir})
include(${esp_idf_dir}/tools/cmake/idf_functions.cmake)
add_subdirectory(${esp_idf_dir})
set(IDF_TOOLCHAIN_FILE ${CMAKE_TOOLCHAIN_FILE})

set(mchp_dir "${CMAKE_CURRENT_LIST_DIR}/freertos/vendors/microchip")
set(ecc608_dir "${mchp_dir}/secure_elements")
include_directories(my_app PRIVATE mchp_dir)
include_directories(my_app PRIVATE ecc608_dir)

Am i missing anything in my CMakeLists.txt ?

It looks like the problem is with the last four lines of your root CMakeLists.txt file. You have the following:

set(mchp_dir "${CMAKE_CURRENT_LIST_DIR}/freertos/vendors/microchip")
set(ecc608_dir "${mchp_dir}/secure_elements")
include_directories(my_app PRIVATE mchp_dir)
include_directories(my_app PRIVATE ecc608_dir)

There are two issues with this:

  1. The header file that you are attempting to include is in the “lib” subdirectory of the “secure_elements” folder. Your include_directories calls are not including this path.
  2. In your include_directories calls, you need to dereference your CMake variables to access the string data. What you currently have adds “…/mchp_dir” and “…/ecc608_dir” to the include path.

With that in mind, you should be able to include the “cryptoauthlib.h” header file if you replace those four lines with the following code:

set(mchp_dir "${CMAKE_CURRENT_LIST_DIR}/freertos/vendors/microchip")
include_directories(my_app PRIVATE "${mchp_dir}/secure_elements/lib")

If you need the other two directories added to your include path, then you can add those in a similar manner.

Thank you for the response @yanjos, however, I am still getting the same error after attempting your suggestive solution. Is there something I am missing here ?

When you attempt to build the project, you should see the CMake target that is being built, along with the command to build it.

Can you share the name of the target that is failing to build? Also, can you check the include path to see if the directory containing the missing header file is in there or not?

So the target that fails to build is actually my own component called “fsonet_lib”. I added it as an extra component of esp-idf using the following command

get_filename_component(
    EXTRA_COMPONENT_DIRS
    "fsonet_lib" ABSOLUTE
)
list(APPEND IDF_EXTRA_COMPONENT_DIRS ${EXTRA_COMPONENT_DIRS})

This directory contains an include folder with header files that include the “cryptoauthlib.h” header file. It also does not look like the directory containing the header file is in the include paths.

I believe that calling “get_filename_component” adds a dependency to your main application on this “fsonet_lib” component. This does not add the include paths of the main application to this “fsonet_lib” component.

Have you tried to add the required include directories to the “fsonet_lib” component? There may be a way that is more aligned with esp-idf, but you should be able to do this by using the CMake “target_include_directories” function. Inside of the fsonet_lib CMakeLists.txt file, it should look something like:

set(mchp_dir "${PROJECT_SOURCE_DIR}/freertos/vendors/microchip")
target_include_directories(${COMPONENT_TARGET} PRIVATE "${mchp_dir}/secure_elements/lib")

You can see the CMake documentation on this command here.

1 Like

Hi @yanjos,

Your solution worked! I was able to build successfully with no errors. Thank you for your help it is very much appreciated.

Hi @yanjos,

New update, I was able to include the files and build without any error however, I tried using functions from these libraries and I get undefined reference as an error
Examples of such:

freertos/esp-idf/fsonet_lib/libfsonet_lib.a(app_crypto_test.c.obj):(.literal.atecc_init+0x0): undefined reference to `atcab_init'

Seems like there is a path to the header files but not the C files. Is there anything I am missing in my CMakeLists.txt that can fix this ?

In this case, it means that you have the header files in your include path but you aren’t linking with the built C files. There are two approaches to resolving this:

  1. Link your target that requires the C files to a target that defines them.
  2. Add the source files directly to the target that requires them.

I’d recommend option 1. This approach allows other components to link to the files in case they also require them. I’m not aware of a premade target for this that you could use. You could create a target that defines the relevant source files and include paths, and then link your target to this one.

Hi @yanjos

So i was able to create a target that defines all these C objects however some of these files are dependent on other drivers/libraries

Here is my new CMakeLists.txt in fsonet_lib

# include paths of this components.
set(COMPONENT_ADD_INCLUDEDIRS include)

# source files of this components.
set(COMPONENT_SRCDIRS src)
# Alternatively, use COMPONENT_SRCS to specify source files explicitly
# set(COMPONENT_SRCS src)

# add this components, this will define a CMake library target.
register_component()

# standard CMake function can be used to specify dependencies. ${COMPONENT_TARGET} is defined
# from esp-idf when you call register_component, by default it's idf_component_<folder_name>.
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::core_mqtt)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::mqtt)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::mqtt_demo_helpers)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::core_json)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::core_mqtt_demo_dependencies)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::common)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::crypto)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::dev_mode_key_provisioning)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::kernel)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::ota)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::pkcs11)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::pkcs11_implementation)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::pkcs11_helpers)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::pkcs11_utils)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::platform)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::secure_sockets)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::transport_interface_secure_sockets)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::serializer)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::shadow)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::device_shadow)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::device_shadow_demo_dependencies)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::tls)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::wifi)
target_link_libraries(${COMPONENT_TARGET} PRIVATE AFR::common_io)

include_directories(${COMPONENT_TARGET} PRIVATE BEFORE fsonet-configs)

#Secure element
set(mchp_dir "${CMAKE_CURRENT_LIST_DIR}/../freertos/vendors/microchip")
target_include_directories(${COMPONENT_TARGET} PRIVATE "${mchp_dir}/secure_elements/lib")
target_include_directories(${COMPONENT_TARGET} PRIVATE "${mchp_dir}/secure_elements/lib/atcacert")
target_include_directories(${COMPONENT_TARGET} PRIVATE "${mchp_dir}/secure_elements/lib/basic")
target_include_directories(${COMPONENT_TARGET} PRIVATE "${mchp_dir}/secure_elements/lib/crypto")
target_include_directories(${COMPONENT_TARGET} PRIVATE "${mchp_dir}/secure_elements/lib/hal")
target_include_directories(${COMPONENT_TARGET} PRIVATE "${mchp_dir}/secure_elements/lib/host")
target_include_directories(${COMPONENT_TARGET} PRIVATE "${mchp_dir}/secure_elements/lib/jwt")
target_include_directories(${COMPONENT_TARGET} PRIVATE "${mchp_dir}/secure_elements/lib/mbedtls")
target_include_directories(${COMPONENT_TARGET} PRIVATE "${mchp_dir}/secure_elements/lib/pkcs11")

add_library(
    atecc_lib STATIC
)
target_sources(
    atecc_lib
    PRIVATE
        "${mchp_dir}/secure_elements/lib/atcacert/atcacert_client.c"
        "${mchp_dir}/secure_elements/lib/atcacert/atcacert_date.c"
        "${mchp_dir}/secure_elements/lib/atcacert/atcacert_def.c"
        "${mchp_dir}/secure_elements/lib/atcacert/atcacert_der.c"
        "${mchp_dir}/secure_elements/lib/atcacert/atcacert_host_hw.c"
        "${mchp_dir}/secure_elements/lib/atcacert/atcacert_host_sw.c"
        "${mchp_dir}/secure_elements/lib/atcacert/atcacert_pem.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_aes_cbc.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_aes_cmac.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_aes_ctr.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_aes_gcm.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_aes.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_checkmac.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_counter.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_derivekey.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_ecdh.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_gendig.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_genkey.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_hmac.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_info.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_kdf.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_lock.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_mac.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_nonce.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_privwrite.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_random.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_read.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_secureboot.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_sha.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_sign.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_updateextra.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_verify.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic_write.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_basic.c"
        "${mchp_dir}/secure_elements/lib/basic/atca_helpers.c"
        "${mchp_dir}/secure_elements/lib/crypto/hashes/sha1_routines.c"
        "${mchp_dir}/secure_elements/lib/crypto/hashes/sha2_routines.c"
        "${mchp_dir}/secure_elements/lib/crypto/atca_crypto_sw_ecdsa.c"
        "${mchp_dir}/secure_elements/lib/crypto/atca_crypto_sw_rand.c"
        "${mchp_dir}/secure_elements/lib/crypto/atca_crypto_sw_sha1.c"
        "${mchp_dir}/secure_elements/lib/crypto/atca_crypto_sw_sha2.c"
        "${mchp_dir}/secure_elements/lib/hal/atca_hal.c"
        "${mchp_dir}/secure_elements/lib/hal/hal_esp32_i2c.c"
        "${mchp_dir}/secure_elements/lib/hal/hal_esp32_timer.c"
        "${mchp_dir}/secure_elements/lib/hal/hal_freertos.c"
        "${mchp_dir}/secure_elements/lib/host/atca_host.c"
        "${mchp_dir}/secure_elements/lib/jwt/atca_jwt.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_attrib.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_cert.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_config.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_debug.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_digest.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_find.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_info.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_init.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_key.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_main.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_mech.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_object.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_os.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_session.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_signature.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_slot.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_token.c"
        "${mchp_dir}/secure_elements/lib/pkcs11/pkcs11_util.c"
        "${mchp_dir}/secure_elements/lib/atca_cfgs.c"
        "${mchp_dir}/secure_elements/lib/atca_command.c"
        "${mchp_dir}/secure_elements/lib/atca_device.c"
        "${mchp_dir}/secure_elements/lib/atca_execution.c"
        "${mchp_dir}/secure_elements/lib/atca_iface.c"
)
target_include_directories(
    atecc_lib
    PRIVATE
        "${mchp_dir}/secure_elements/lib"
        "${mchp_dir}/secure_elements/lib/atcacert"
        "${mchp_dir}/secure_elements/lib/basic"
        "${mchp_dir}/secure_elements/lib/crypto"
        "${mchp_dir}/secure_elements/lib/hal"
        "${mchp_dir}/secure_elements/lib/host"
        "${mchp_dir}/secure_elements/lib/jwt"
        "${mchp_dir}/secure_elements/lib/mbedtls"
        "${mchp_dir}/secure_elements/lib/pkcs11"
)

target_link_libraries(${COMPONENT_TARGET} PRIVATE atecc_lib)

The error I get now is

/freertos/vendors/microchip/secure_elements/lib/hal/hal_esp32_i2c.c:18:24: fatal error: driver/i2c.h: No such file or directory
compilation terminated.
make[2]: *** [freertos/esp-idf/fsonet_lib/CMakeFiles/atecc_lib.dir/build.make:609: freertos/esp-idf/fsonet_lib/CMakeFiles/atecc_lib.dir/__/freertos/vendors/microchip/secure_elements/lib/hal/hal_esp32_i2c.c.obj] Error 1
make[1]: *** [CMakeFiles/Makefile2:5953: freertos/esp-idf/fsonet_lib/CMakeFiles/atecc_lib.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....

It appears that the file hal_esp32_i2c.c needs driver/i2c.h file from esp-idf to function. Do you have a suggestion on how to link esp-idf vendor to the target as I have not been successful with this ?

On another note, do you know what version of the cryptoauthlib library aws freertos is using because currently v3.2 (the current/newest version) has an error with hal_esp32 libraries making atecc608 and esp32 implementation impossible and causes errors.

For questions specific to the microchip library or the esp32 platform, you may want to consider asking questions in the respective vendor subsections of this forum. There may be others that have encountered these problems and could give you more detailed assistance.

I found a header file that looks like it’s what you need:

Can you elaborate on what you mean by linking esp-idf vendor the target?

I’m unsure of the exact version that we are using, but I believe it is a version before v3.2. The last time these files were updated was 14 months ago. This is before the v3.2 release from what I can tell.

So one of the files hal_esp32_i2c.c is reliant on esp-idf’s i2c driver. Since I created my own target it would not detect the i2c driver unless I link esp-idf to the new target I created. Since my own component had paths to esp-idf, I included that file in my own component as a work around and it works. But all is good and working now so thank you for your time it is much appreciated!

I’m glad to hear that it’s working now.

If I understand correctly, then there should be at least two ways to link your target to the esp-idf i2c drivers.

To be clear, I’ll be referring to CMake targets and to esp-idf components as separate things. CMake targets refers to the bundle of include paths and source files created with the CMake “add_library” command. I’ll refer to esp-idf components as the bundle of include paths and source files that is created with the “register_component()” command.

The first approach would be to define your source code and includes as an esp-idf component instead of a CMake target. Then link together the two components according to the Espressif documentation. This can be done with these commands (replace content within the brackets with the name):

    set(COMPONENT_REQUIRES <esp-idf-component-name>)
    or
    set(COMPONENT_PRIV_REQUIRES <esp-idf-component-name>)

The second approach is to link your custom CMake target to the esp-idf component by name. This is assuming that there is an esp-idf component that defines the source files and include files for the driver. I believe that the default name for the CMake target of esp-idf components is in this format:
“idf_component_<folder_name>”

You can use the standard “target_link_libraries” function in CMake to link with this target.