ADAC: Authenticated Debug Access Control
The commit adds the impelementation of ADAC protocol towards the
target side.
Following components are part of the commit:-
Core : ADAC protocol core
SDA : Secure Debug Agent
The commit also demonstrates the porting of a platform from
trusted-firmware-m. Corstone1000 platform is used for the purpose.
Change-Id: I50b93f9e48789cf5927736b4d1cb35b9a47c38db
Signed-off-by: Satish Kumar <satish.kumar01@arm.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..d28eed1
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2021 Arm Limited. All rights reserved.
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+cmake_minimum_required(VERSION 3.15)
+
+get_filename_component(PSA_ADAC_ROOT ${CMAKE_CURRENT_SOURCE_DIR} ABSOLUTE)
+get_filename_component(PSA_ADAC_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} ABSOLUTE)
+
+if (NOT DEFINED PSA_ADAC_TARGET)
+ Message(FATAL_ERROR "PSA_ADAC_TARGET not defined.")
+endif()
+
+get_filename_component(PSA_ADAC_TARGET_PATH ${CMAKE_CURRENT_SOURCE_DIR}/target/${PSA_ADAC_TARGET} ABSOLUTE)
+
+if (NOT EXISTS ${PSA_ADAC_TARGET_PATH})
+ Message(FATAL_ERROR "Target ${PSA_ADAC_TARGET_PATH} not supported.")
+endif()
+
+if (NOT DEFINED PSA_ADAC_MBEDTLS_INCLUDE)
+ Message(FATAL_ERROR "PSA_ADAC_MBEDTLS_INCLUDE not defined.")
+endif()
+
+if (NOT EXISTS ${PSA_ADAC_MBEDTLS_INCLUDE})
+ Message(FATAL_ERROR "Does not exist: ${PSA_ADAC_MBEDTLS_INCLUDE}")
+endif()
+
+
+get_filename_component(PSA_ADAC_INSTALL_PATH ${CMAKE_CURRENT_BINARY_DIR}/install ABSOLUTE)
+
+# NOTE: cmake config priority is bottom to top, so dont change the order of
+# below includes
+include(${PSA_ADAC_TARGET_PATH}/config.cmake)
+include(${PSA_ADAC_ROOT}/cmake/psa_adac.cmake)
+
+if (${PSA_ADAC_TOOLCHAIN})
+ include(${PSA_ADAC_ROOT}/cmake/toolchain.cmake)
+endif()
+
+project(${PSA_ADAC_TARGET}-psa-adac LANGUAGES C ASM)
+
+if (${PSA_ADAC_TOOLCHAIN})
+ arm_toolchain_reload_compiler()
+endif()
+
+add_library(${PROJECT_NAME} STATIC)
+
+add_subdirectory(${PSA_ADAC_ROOT}/psa-adac/core adac_core)
+add_subdirectory(${PSA_ADAC_ROOT}/psa-adac/sda adac_sda)
+add_subdirectory(${PSA_ADAC_TARGET_PATH} adac_platform)
+
+target_link_libraries(${PROJECT_NAME}
+ PUBLIC
+ psa_adac_core
+ psa_adac_sda
+)
+
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.a"
+ DESTINATION ${PSA_ADAC_INSTALL_PATH}/lib
+)
diff --git a/cmake/psa_adac.cmake b/cmake/psa_adac.cmake
new file mode 100644
index 0000000..54c5c5d
--- /dev/null
+++ b/cmake/psa_adac.cmake
@@ -0,0 +1,55 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+
+list(APPEND CMAKE_MODULE_PATH ${PSA_ADAC_ROOT}/cmake)
+
+set(PSA_ADAC_TOOLCHAIN TRUE CACHE BOOL "Whether to use psa-adac toolchain.")
+
+set(PSA_ADAC_EC_P256 On CACHE BOOL "Enable support for ECDSA P-256")
+set(PSA_ADAC_EC_P521 On CACHE BOOL "Enable support for ECDSA P-521")
+set(PSA_ADAC_RSA3072 On CACHE BOOL "Enable support for RSA 3072")
+set(PSA_ADAC_RSA4096 On CACHE BOOL "Enable support for RSA 4096")
+set(PSA_ADAC_ED25519 Off CACHE BOOL "Enable support for EdDSA Ed25519")
+set(PSA_ADAC_ED448 Off CACHE BOOL "Enable support for EdDSA Ed448")
+set(PSA_ADAC_SM2SM3 Off CACHE BOOL "Enable support for SM2/SM3")
+set(PSA_ADAC_CMAC On CACHE BOOL "Enable support for CMAC AES-128")
+set(PSA_ADAC_HMAC On CACHE BOOL "Enable support for HMAC SHA-256")
+set(PSA_ADAC_HW_CRYPTO Off CACHE BOOL "Support for hardware cryptography")
+set(PSA_ADAC_DEBUG Off CACHE BOOL "Enable debug")
+set(PSA_ADAC_QUIET Off CACHE BOOL "Disable console output")
+set(PSA_ADAC_QEMU Off CACHE BOOL "The image will be built to run on QEMU")
+set(PSA_ADAC_MINIMUM_SIZE_CONFIG Off CACHE BOOL "Size-optimized build (reduced features)")
+
+if (CMAKE_BUILD_TYPE STREQUAL "Debug")
+ set(PSA_ADAC_DEBUG On)
+ set(PSA_ADAC_TRACE Off)
+elseif (CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
+ set(PSA_ADAC_QUIET On)
+ set(PSA_ADAC_DEBUG Off)
+endif ()
+
+if (ROM_POC) # TODO: this is just for transition, remove soon
+ set(PSA_ADAC_MINIMUM_SIZE_CONFIG On)
+endif ()
+
+if (PSA_ADAC_MINIMUM_SIZE_CONFIG AND NOT (PLATFORM_NAME STREQUAL "native"))
+ # set(PSA_ADAC_EC_P256 On)
+ set(PSA_ADAC_EC_P521 Off)
+ set(PSA_ADAC_RSA3072 Off)
+ set(PSA_ADAC_RSA4096 Off)
+ set(PSA_ADAC_ED25519 Off)
+ set(PSA_ADAC_ED448 Off)
+ set(PSA_ADAC_SM2SM3 Off)
+ set(PSA_ADAC_CMAC Off)
+ set(PSA_ADAC_HMAC Off)
+endif ()
+
+find_program(CCACHE_PROGRAM ccache)
+if (CCACHE_PROGRAM)
+ set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
+endif ()
diff --git a/cmake/set_extensions.cmake b/cmake/set_extensions.cmake
new file mode 100644
index 0000000..2753337
--- /dev/null
+++ b/cmake/set_extensions.cmake
@@ -0,0 +1,12 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+set(CMAKE_C_OUTPUT_EXTENSION ".o")
+set(CMAKE_C_OUTPUT_EXTENSION_REPLACE 1)
+
+set(CMAKE_ASM_OUTPUT_EXTENSION ".o")
+set(CMAKE_ASM_OUTPUT_EXTENSION_REPLACE 1)
diff --git a/cmake/toolchain.cmake b/cmake/toolchain.cmake
new file mode 100644
index 0000000..3f01947
--- /dev/null
+++ b/cmake/toolchain.cmake
@@ -0,0 +1,52 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+set(CMAKE_C_COMPILER_FORCED true)
+set(CROSS_COMPILE arm-none-eabi CACHE STRING "Cross-compilation triplet")
+
+if (NOT (COMPILER))
+ set(COMPILER "GNUARM")
+endif ()
+
+if (COMPILER STREQUAL "GNUARM")
+
+ include(${PSA_ADAC_ROOT}/cmake/toolchain_GNUARM.cmake)
+
+ if (CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
+ add_compile_options(-flto -Os)
+ add_link_options(-Wl,--as-needed -flto -flto-partition=none -Os -ffunction-sections -fuse-linker-plugin)
+ add_compile_options($<$<COMPILE_LANGUAGE:C>:-DNDEBUG>)
+ endif ()
+
+elseif(COMPILER STREQUAL "ARMCLANG")
+
+ include(${PSA_ADAC_ROOT}/cmake/toolchain_ARMCLANG.cmake)
+
+ if (CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
+ add_compile_options($<$<COMPILE_LANGUAGE:C>:-Oz>)
+ # # Can't enable LTO for all targets because static libraries (like mbedcrypto)
+ # # are not supported.
+ # add_compile_options(-flto)
+ # add_link_options(--lto)
+ add_compile_options($<$<COMPILE_LANGUAGE:C>:-DNDEBUG>)
+ endif ()
+
+elseif(COMPILER STREQUAL "IARARM")
+
+ include(${PSA_ADAC_ROOT}/cmake/toolchain_IARARM.cmake)
+
+ if (CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
+ add_compile_options(--mfc)
+ add_link_options(--vfe)
+ add_compile_options($<$<COMPILE_LANGUAGE:C>:-DNDEBUG>)
+ endif()
+
+else()
+
+ message(FATAL_ERROR "\nValid values for COMPILER are 'GNUARM' (default), 'ARMCLANG' and 'IARARM'\n")
+
+endif()
diff --git a/cmake/toolchain_ARMCLANG.cmake b/cmake/toolchain_ARMCLANG.cmake
new file mode 100644
index 0000000..8fef6fa
--- /dev/null
+++ b/cmake/toolchain_ARMCLANG.cmake
@@ -0,0 +1,218 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+cmake_minimum_required(VERSION 3.15)
+
+SET(CMAKE_SYSTEM_NAME Generic)
+
+set(CMAKE_C_COMPILER armclang)
+set(CMAKE_ASM_COMPILER armasm)
+
+set(LINKER_VENEER_OUTPUT_FLAG --import_cmse_lib_out=)
+set(COMPILER_CMSE_FLAG $<$<COMPILE_LANGUAGE:C>:-mcmse>)
+
+# This variable name is a bit of a misnomer. The file it is set to is included
+# at a particular step in the compiler initialisation. It is used here to
+# configure the extensions for object files. Despite the name, it also works
+# with the Ninja generator.
+set(CMAKE_USER_MAKE_RULES_OVERRIDE ${CMAKE_CURRENT_LIST_DIR}/set_extensions.cmake)
+
+macro(arm_toolchain_reset_compiler_flags)
+ set_property(DIRECTORY PROPERTY COMPILE_OPTIONS "")
+ string(REGEX REPLACE "\\+nodsp" ".no_dsp" CMAKE_ASM_CPU_FLAG "${CMAKE_SYSTEM_PROCESSOR}")
+
+ add_compile_options(
+ $<$<COMPILE_LANGUAGE:C>:-Wno-ignored-optimization-argument>
+ $<$<COMPILE_LANGUAGE:C>:-Wno-unused-command-line-argument>
+ $<$<COMPILE_LANGUAGE:C>:-Wall>
+ # Don't error when the MBEDTLS_NULL_ENTROPY warning is shown
+ $<$<COMPILE_LANGUAGE:C>:-Wno-error=cpp>
+ $<$<COMPILE_LANGUAGE:C>:-c>
+ $<$<COMPILE_LANGUAGE:C>:-fdata-sections>
+ $<$<COMPILE_LANGUAGE:C>:-ffunction-sections>
+ $<$<COMPILE_LANGUAGE:C>:-fno-builtin>
+ $<$<COMPILE_LANGUAGE:C>:-fshort-enums>
+ $<$<COMPILE_LANGUAGE:C>:-fshort-wchar>
+ $<$<COMPILE_LANGUAGE:C>:-funsigned-char>
+ $<$<COMPILE_LANGUAGE:C>:-masm=auto>
+ $<$<COMPILE_LANGUAGE:C>:-nostdlib>
+ $<$<COMPILE_LANGUAGE:C>:-std=c99>
+ $<$<AND:$<COMPILE_LANGUAGE:C>,$<NOT:$<BOOL:${ARM_SYSTEM_FP}>>>:-mfpu=none>
+ $<$<AND:$<COMPILE_LANGUAGE:ASM>,$<NOT:$<BOOL:${ARM_SYSTEM_FP}>>>:--fpu=none>
+ $<$<COMPILE_LANGUAGE:ASM>:--cpu=${CMAKE_ASM_CPU_FLAG}>
+ )
+endmacro()
+
+macro(arm_toolchain_reset_linker_flags)
+ set_property(DIRECTORY PROPERTY LINK_OPTIONS "")
+
+ add_link_options(
+ --info=summarysizes,sizes,totals,unused,veneers
+ --strict
+ --symbols
+ --xref
+ # Suppress link warnings that are consistant (and therefore hopefully
+ # harmless)
+ # https://developer.arm.com/documentation/100074/0608/linker-errors-and-warnings/list-of-the-armlink-error-and-warning-messages
+ # Empty region description
+ --diag_suppress=6312
+ # Ns section matches pattern
+ --diag_suppress=6314
+ # Duplicate input files
+ --diag_suppress=6304
+ $<$<NOT:$<BOOL:${ARM_SYSTEM_FP}>>:--fpu=softvfp>
+ )
+endmacro()
+
+macro(arm_toolchain_set_processor_arch)
+ set(CMAKE_SYSTEM_PROCESSOR ${ARM_SYSTEM_PROCESSOR})
+ set(CMAKE_SYSTEM_ARCHITECTURE ${ARM_SYSTEM_ARCHITECTURE})
+
+ set(CMAKE_C_COMPILER_TARGET arm-${CROSS_COMPILE})
+ set(CMAKE_ASM_COMPILER_TARGET arm-${CROSS_COMPILE})
+
+ if (DEFINED ARM_SYSTEM_DSP)
+ if(NOT ARM_SYSTEM_DSP)
+ string(APPEND CMAKE_SYSTEM_PROCESSOR "+nodsp")
+ endif()
+
+ # Cmake's ARMClang support has several issues with compiler validation. To
+ # avoid these, we set the list of supported -mcpu and -march variables to
+ # the ones we intend to use so that the validation will never fail.
+ include(Compiler/ARMClang)
+ set(CMAKE_C_COMPILER_PROCESSOR_LIST ${CMAKE_SYSTEM_PROCESSOR})
+ set(CMAKE_C_COMPILER_ARCH_LIST ${CMAKE_SYSTEM_PROCESSOR})
+ set(CMAKE_ASM_COMPILER_PROCESSOR_LIST ${CMAKE_SYSTEM_PROCESSOR})
+ set(CMAKE_ASM_COMPILER_ARCH_LIST ${CMAKE_SYSTEM_PROCESSOR})
+ endif()
+endmacro()
+
+macro(arm_toolchain_reload_compiler)
+ arm_toolchain_set_processor_arch()
+ arm_toolchain_reset_compiler_flags()
+ arm_toolchain_reset_linker_flags()
+
+ unset(CMAKE_C_FLAGS_INIT)
+ unset(CMAKE_C_LINK_FLAGS)
+ unset(CMAKE_ASM_FLAGS_INIT)
+ unset(CMAKE_ASM_LINK_FLAGS)
+ unset(__mcpu_flag_set)
+ unset(__march_flag_set)
+
+ include(Compiler/ARMClang)
+ __compiler_armclang(C)
+ include(Compiler/ARMCC)
+ __compiler_armcc(ASM)
+
+ # Cmake's armclang support will set either mcpu or march, but march gives
+ # better code size so we manually set it.
+ set(CMAKE_C_FLAGS "-march=${CMAKE_SYSTEM_ARCHITECTURE}")
+ set(CMAKE_ASM_FLAGS ${CMAKE_ASM_FLAGS_INIT})
+
+ set(CMAKE_C_LINK_FLAGS "--cpu=${CMAKE_SYSTEM_PROCESSOR}")
+ set(CMAKE_ASM_LINK_FLAGS "--cpu=${CMAKE_SYSTEM_PROCESSOR}")
+ # But armlink doesn't support this +dsp syntax
+ string(REGEX REPLACE "\\+nodsp" "" CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS}")
+ string(REGEX REPLACE "\\+nodsp" "" CMAKE_ASM_LINK_FLAGS "${CMAKE_ASM_LINK_FLAGS}")
+ # And uses different syntax for +nofp
+ string(REGEX REPLACE "\\+nofp" ".no_fp" CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS}")
+ string(REGEX REPLACE "\\+nofp" ".no_fp" CMAKE_ASM_LINK_FLAGS "${CMAKE_ASM_LINK_FLAGS}")
+
+ # Workaround for issues with --depend-single-line with armasm and Ninja
+ if (CMAKE_GENERATOR STREQUAL "Ninja")
+ set( CMAKE_DEPFILE_FLAGS_ASM "--depend=<OBJECT>.d")
+ endif()
+
+ set(CMAKE_C_FLAGS_MINSIZEREL "-Oz -DNDEBUG")
+endmacro()
+
+# Configure environment for the compiler setup run by cmake at the first
+# `project` call in <tfm_root>/CMakeLists.txt. After this mandatory setup is
+# done, all further compiler setup is done via arm_toolchain_reload_compiler()
+arm_toolchain_set_processor_arch()
+arm_toolchain_reset_compiler_flags()
+arm_toolchain_reset_linker_flags()
+
+# Behaviour for handling scatter files is so wildly divergent between compilers
+# that this macro is required.
+macro(target_add_scatter_file target)
+ target_link_options(${target}
+ PRIVATE
+ --scatter=$<TARGET_OBJECTS:${target}_scatter>
+ )
+
+ add_dependencies(${target}
+ ${target}_scatter
+ )
+
+ add_library(${target}_scatter OBJECT)
+ foreach(scatter_file ${ARGN})
+ target_sources(${target}_scatter
+ PRIVATE
+ ${scatter_file}
+ )
+ # Cmake cannot use generator expressions in the
+ # set_source_file_properties command, so instead we just parse the regex
+ # for the filename and set the property on all files, regardless of if
+ # the generator expression would evaluate to true or not.
+ string(REGEX REPLACE ".*>:(.*)>$" "\\1" SCATTER_FILE_PATH "${scatter_file}")
+ set_source_files_properties(${SCATTER_FILE_PATH}
+ PROPERTIES
+ LANGUAGE C
+ )
+ endforeach()
+
+ target_link_libraries(${target}_scatter
+ platform_region_defs
+ )
+
+ target_compile_options(${target}_scatter
+ PRIVATE
+ -E
+ -xc
+ )
+endmacro()
+
+macro(add_convert_to_bin_target target)
+ get_target_property(bin_dir ${target} RUNTIME_OUTPUT_DIRECTORY)
+
+ add_custom_target(${target}_bin
+ SOURCES ${bin_dir}/${target}.bin
+ )
+ add_custom_command(OUTPUT ${bin_dir}/${target}.bin
+ DEPENDS ${target}
+ COMMAND fromelf
+ --bincombined $<TARGET_FILE:${target}>
+ --output=${bin_dir}/${target}.bin
+ )
+
+ add_custom_target(${target}_elf
+ SOURCES ${bin_dir}/${target}.elf
+ )
+ add_custom_command(OUTPUT ${bin_dir}/${target}.elf
+ DEPENDS ${target}
+ COMMAND fromelf
+ --elf $<TARGET_FILE:${target}>
+ --output=${bin_dir}/${target}.elf
+ )
+
+ add_custom_target(${target}_hex
+ SOURCES ${bin_dir}/${target}.hex
+ )
+ add_custom_command(OUTPUT ${bin_dir}/${target}.hex
+ DEPENDS ${target}
+ COMMAND fromelf
+ --i32combined $<TARGET_FILE:${target}>
+ --output=${bin_dir}/${target}.hex
+ )
+
+ add_custom_target(${target}_binaries
+ ALL
+ DEPENDS ${target}_bin
+ DEPENDS ${target}_elf
+ DEPENDS ${target}_hex
+ )
+endmacro()
diff --git a/cmake/toolchain_GNUARM.cmake b/cmake/toolchain_GNUARM.cmake
new file mode 100644
index 0000000..fc6fe4c
--- /dev/null
+++ b/cmake/toolchain_GNUARM.cmake
@@ -0,0 +1,176 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+set(CMAKE_SYSTEM_NAME Generic)
+
+find_program(CMAKE_C_COMPILER ${CROSS_COMPILE}-gcc)
+set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
+
+#set(CMAKE_C_COMPILER ${CROSS_COMPILE}-gcc)
+#set(CMAKE_ASM_COMPILER ${CROSS_COMPILE}-gcc)
+set(CMAKE_AR ${CROSS_COMPILE}-gcc-ar)
+set(CMAKE_RANLIB ${CROSS_COMPILE}-gcc-ranlib)
+
+set(LINKER_VENEER_OUTPUT_FLAG -Wl,--cmse-implib,--out-implib=)
+set(COMPILER_CMSE_FLAG -mcmse)
+
+# This variable name is a bit of a misnomer. The file it is set to is included
+# at a particular step in the compiler initialisation. It is used here to
+# configure the extensions for object files. Despite the name, it also works
+# with the Ninja generator.
+set(CMAKE_USER_MAKE_RULES_OVERRIDE ${CMAKE_CURRENT_LIST_DIR}/set_extensions.cmake)
+
+macro(arm_toolchain_reset_compiler_flags)
+ set_property(DIRECTORY PROPERTY COMPILE_OPTIONS "")
+
+ add_compile_options(
+ --specs=nano.specs
+ -Wall
+ -Wno-format
+ -Wno-return-type
+ -Wno-unused-but-set-variable
+ -c
+ -fdata-sections
+ -ffunction-sections
+ -fno-builtin
+ -fshort-enums
+ -funsigned-char
+ -mthumb
+ -nostdlib
+ -std=c99
+ $<$<NOT:$<BOOL:${ARM_SYSTEM_FP}>>:-msoft-float>
+ )
+endmacro()
+
+macro(arm_toolchain_reset_linker_flags)
+ set_property(DIRECTORY PROPERTY LINK_OPTIONS "")
+
+ add_link_options(
+ --entry=Reset_Handler
+ --specs=nano.specs
+ LINKER:-check-sections
+ LINKER:-fatal-warnings
+ LINKER:--gc-sections
+ LINKER:--no-wchar-size-warning
+ LINKER:--print-memory-usage
+ LINKER:-Map=$<TARGET_FILE_BASE_NAME:$<TARGET_PROPERTY:NAME>>.map
+ LINKER:--cref
+ )
+endmacro()
+
+macro(arm_toolchain_set_processor_arch)
+ set(CMAKE_SYSTEM_PROCESSOR ${ARM_SYSTEM_PROCESSOR})
+ set(CMAKE_SYSTEM_ARCHITECTURE ${ARM_SYSTEM_ARCHITECTURE})
+
+ if (DEFINED ARM_SYSTEM_DSP)
+ if(NOT ARM_SYSTEM_DSP)
+ string(APPEND CMAKE_SYSTEM_PROCESSOR "+nodsp")
+ endif()
+ endif()
+endmacro()
+
+macro(arm_toolchain_reload_compiler)
+ arm_toolchain_set_processor_arch()
+ arm_toolchain_reset_compiler_flags()
+ arm_toolchain_reset_linker_flags()
+
+ unset(CMAKE_C_FLAGS_INIT)
+ unset(CMAKE_ASM_FLAGS_INIT)
+
+ set(CMAKE_C_FLAGS_INIT "-mcpu=${CMAKE_SYSTEM_PROCESSOR}")
+ set(CMAKE_ASM_FLAGS_INIT "-mcpu=${CMAKE_SYSTEM_PROCESSOR}")
+ set(CMAKE_C_LINK_FLAGS "-mcpu=${CMAKE_SYSTEM_PROCESSOR}")
+ set(CMAKE_ASM_LINK_FLAGS "-mcpu=${CMAKE_SYSTEM_PROCESSOR}")
+
+ set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS_INIT})
+ set(CMAKE_ASM_FLAGS ${CMAKE_ASM_FLAGS_INIT})
+endmacro()
+
+# Configure environment for the compiler setup run by cmake at the first
+# `project` call in <tfm_root>/CMakeLists.txt. After this mandatory setup is
+# done, all further compiler setup is done via arm_toolchain_reload_compiler()
+arm_toolchain_reload_compiler()
+
+macro(target_add_scatter_file target)
+ target_link_options(${target}
+ PRIVATE
+ -T $<TARGET_OBJECTS:${target}_scatter>
+ )
+
+ add_dependencies(${target}
+ ${target}_scatter
+ )
+
+ add_library(${target}_scatter OBJECT)
+ foreach(scatter_file ${ARGN})
+ target_sources(${target}_scatter
+ PRIVATE
+ ${scatter_file}
+ )
+ # Cmake cannot use generator expressions in the
+ # set_source_file_properties command, so instead we just parse the regex
+ # for the filename and set the property on all files, regardless of if
+ # the generator expression would evaluate to true or not.
+ string(REGEX REPLACE ".*>:(.*)>$" "\\1" SCATTER_FILE_PATH "${scatter_file}")
+ set_source_files_properties(${SCATTER_FILE_PATH}
+ PROPERTIES
+ LANGUAGE C
+ )
+ endforeach()
+
+ target_link_libraries(${target}_scatter
+ platform_region_defs
+ )
+
+ target_compile_options(${target}_scatter
+ PRIVATE
+ -E
+ -P
+ -xc
+ )
+endmacro()
+
+macro(add_convert_to_bin_target target)
+ get_target_property(bin_dir ${target} RUNTIME_OUTPUT_DIRECTORY)
+
+ add_custom_target(${target}_bin
+ SOURCES ${bin_dir}/${target}.bin
+ )
+ add_custom_command(OUTPUT ${bin_dir}/${target}.bin
+ DEPENDS ${target}
+ COMMAND ${CMAKE_OBJCOPY}
+ -O binary $<TARGET_FILE:${target}>
+ ${bin_dir}/${target}.bin
+ )
+
+ add_custom_target(${target}_elf
+ SOURCES ${bin_dir}/${target}.elf
+ )
+ add_custom_command(OUTPUT ${bin_dir}/${target}.elf
+ DEPENDS ${target}
+ COMMAND ${CMAKE_OBJCOPY}
+ -O elf32-littlearm $<TARGET_FILE:${target}>
+ ${bin_dir}/${target}.elf
+ )
+
+ add_custom_target(${target}_hex
+ SOURCES ${bin_dir}/${target}.hex
+ )
+ add_custom_command(OUTPUT ${bin_dir}/${target}.hex
+ DEPENDS ${target}
+ COMMAND ${CMAKE_OBJCOPY}
+ -O ihex $<TARGET_FILE:${target}>
+ ${bin_dir}/${target}.hex
+ )
+
+ add_custom_target(${target}_binaries
+ ALL
+ DEPENDS ${target}_bin
+ DEPENDS ${target}_elf
+ DEPENDS ${target}_hex
+ )
+endmacro()
diff --git a/cmake/toolchain_IARARM.cmake b/cmake/toolchain_IARARM.cmake
new file mode 100644
index 0000000..48e34f9
--- /dev/null
+++ b/cmake/toolchain_IARARM.cmake
@@ -0,0 +1,178 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, IAR Systems AB. All rights reserved.
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+cmake_minimum_required(VERSION 3.15)
+
+SET(CMAKE_SYSTEM_NAME Generic)
+set(CMAKE_SYSTEM_PROCESSOR ${ARM_SYSTEM_PROCESSOR})
+set(CMAKE_SYSTEM_ARCHITECTURE ${ARM_SYSTEM_ARCHITECTURE})
+
+if(CROSS_COMPILE)
+ set(CMAKE_C_COMPILER_TARGET arm-${CROSS_COMPILE})
+ set(CMAKE_ASM_COMPILER_TARGET arm-${CROSS_COMPILE})
+else()
+ set(CMAKE_C_COMPILER_TARGET arm-arm-none-eabi)
+ set(CMAKE_ASM_COMPILER_TARGET arm-arm-none-eabi)
+endif()
+
+set(CMAKE_C_COMPILER iccarm)
+set(CMAKE_ASM_COMPILER iasmarm)
+
+set(LINKER_VENEER_OUTPUT_FLAG --import_cmse_lib_out= )
+set(COMPILER_CMSE_FLAG --cmse)
+
+# This variable name is a bit of a misnomer. The file it is set to is included
+# at a particular step in the compiler initialisation. It is used here to
+# configure the extensions for object files. Despite the name, it also works
+# with the Ninja generator.
+set(CMAKE_USER_MAKE_RULES_OVERRIDE ${CMAKE_CURRENT_LIST_DIR}/set_extensions.cmake)
+
+macro(arm_toolchain_reset_compiler_flags)
+ set_property(DIRECTORY PROPERTY COMPILE_OPTIONS "")
+
+ add_compile_options(
+ $<$<COMPILE_LANGUAGE:C,CXX>:-e>
+ $<$<COMPILE_LANGUAGE:C,CXX>:--dlib_config=full>
+ $<$<COMPILE_LANGUAGE:C,CXX>:--vla>
+ $<$<COMPILE_LANGUAGE:C,CXX>:--silent>
+ $<$<COMPILE_LANGUAGE:C,CXX>:-DNO_TYPEOF>
+ $<$<COMPILE_LANGUAGE:C,CXX>:-D_NO_DEFINITIONS_IN_HEADER_FILES>
+ $<$<COMPILE_LANGUAGE:C,CXX>:--diag_suppress=Pe546,Pe940,Pa082,Pa084>
+ )
+endmacro()
+
+macro(arm_toolchain_reset_linker_flags)
+ set_property(DIRECTORY PROPERTY LINK_OPTIONS "")
+
+ add_link_options(
+ --silent
+ --semihosting
+ --redirect __write=__write_buffered
+ )
+endmacro()
+
+macro(arm_toolchain_set_processor_arch)
+ if(${ARM_SYSTEM_PROCESSOR} STREQUAL "cortex-m0plus")
+ set(CMAKE_SYSTEM_PROCESSOR Cortex-M0+)
+ else()
+ set(CMAKE_SYSTEM_PROCESSOR ${ARM_SYSTEM_PROCESSOR})
+ endif()
+ set(CMAKE_SYSTEM_ARCHITECTURE ${ARM_SYSTEM_ARCHITECTURE})
+
+ if (DEFINED ARM_SYSTEM_DSP)
+ if(NOT ARM_SYSTEM_DSP)
+ string(APPEND CMAKE_SYSTEM_PROCESSOR ".no_dsp")
+ endif()
+ endif()
+endmacro()
+
+macro(arm_toolchain_reload_compiler)
+ arm_toolchain_set_processor_arch()
+ arm_toolchain_reset_compiler_flags()
+ arm_toolchain_reset_linker_flags()
+
+ unset(CMAKE_C_FLAGS_INIT)
+ unset(CMAKE_C_LINK_FLAGS)
+ unset(CMAKE_ASM_FLAGS_INIT)
+ unset(CMAKE_ASM_LINK_FLAGS)
+
+ set(CMAKE_C_FLAGS_INIT "--cpu ${CMAKE_SYSTEM_PROCESSOR}")
+ set(CMAKE_ASM_FLAGS_INIT "--cpu ${CMAKE_SYSTEM_PROCESSOR}")
+ set(CMAKE_C_LINK_FLAGS "--cpu ${CMAKE_SYSTEM_PROCESSOR}")
+ set(CMAKE_ASM_LINK_FLAGS "--cpu ${CMAKE_SYSTEM_PROCESSOR}")
+
+ set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS_INIT})
+ set(CMAKE_ASM_FLAGS ${CMAKE_ASM_FLAGS_INIT})
+endmacro()
+
+# Configure environment for the compiler setup run by cmake at the first
+# `project` call in <tfm_root>/CMakeLists.txt. After this mandatory setup is
+# done, all further compiler setup is done via arm_toolchain_reload_compiler()
+arm_toolchain_reload_compiler()
+
+# Behaviour for handling scatter files is so wildly divergent between compilers
+# that this macro is required.
+macro(target_add_scatter_file target)
+ target_link_options(${target}
+ PRIVATE
+ --config $<TARGET_OBJECTS:${target}_scatter>
+ )
+ add_dependencies(${target}
+ ${target}_scatter
+ )
+
+ add_library(${target}_scatter OBJECT)
+ foreach(scatter_file ${ARGN})
+ target_sources(${target}_scatter
+ PRIVATE
+ ${scatter_file}
+ )
+ # Cmake cannot use generator expressions in the
+ # set_source_file_properties command, so instead we just parse the regex
+ # for the filename and set the property on all files, regardless of if
+ # the generator expression would evaluate to true or not.
+ string(REGEX REPLACE ".*>:(.*)>$" "\\1" SCATTER_FILE_PATH "${scatter_file}")
+ set_source_files_properties(${SCATTER_FILE_PATH}
+ PROPERTIES
+ LANGUAGE C
+ )
+ endforeach()
+
+ target_link_libraries(${target}_scatter
+ platform_region_defs
+ )
+
+ target_compile_options(${target}_scatter
+ PRIVATE
+ --preprocess=sn $<TARGET_OBJECTS:${target}_scatter>
+ )
+endmacro()
+
+macro(add_convert_to_bin_target target)
+ get_target_property(bin_dir ${target} RUNTIME_OUTPUT_DIRECTORY)
+
+ add_custom_target(${target}_bin
+ SOURCES ${bin_dir}/${target}.bin
+ )
+ add_custom_command(OUTPUT ${bin_dir}/${target}.bin
+ DEPENDS ${target}
+ COMMAND ielftool
+ --silent
+ --bin $<TARGET_FILE:${target}>
+ ${bin_dir}/${target}.bin
+ )
+
+ add_custom_target(${target}_elf
+ SOURCES ${bin_dir}/${target}.elf
+ )
+ add_custom_command(OUTPUT ${bin_dir}/${target}.elf
+ DEPENDS ${target}
+ COMMAND ielftool
+ --silent
+ $<TARGET_FILE:${target}>
+ ${bin_dir}/${target}.elf
+ )
+
+ add_custom_target(${target}_hex
+ SOURCES ${bin_dir}/${target}.hex
+ )
+ add_custom_command(OUTPUT ${bin_dir}/${target}.hex
+ DEPENDS ${target}
+ COMMAND ielftool
+ --silent
+ --ihex $<TARGET_FILE:${target}>
+ ${bin_dir}/${target}.hex
+ )
+
+ add_custom_target(${target}_binaries
+ ALL
+ DEPENDS ${target}_bin
+ DEPENDS ${target}_elf
+ DEPENDS ${target}_hex
+ )
+endmacro()
diff --git a/dco.txt b/dco.txt
new file mode 100644
index 0000000..8201f99
--- /dev/null
+++ b/dco.txt
@@ -0,0 +1,37 @@
+Developer Certificate of Origin
+Version 1.1
+
+Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
+1 Letterman Drive
+Suite D4700
+San Francisco, CA, 94129
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+
+Developer's Certificate of Origin 1.1
+
+By making a contribution to this project, I certify that:
+
+(a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+(b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+(c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+(d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
diff --git a/license.rst b/license.rst
new file mode 100644
index 0000000..2f703d5
--- /dev/null
+++ b/license.rst
@@ -0,0 +1,36 @@
+Copyright (c) 2017-2019, Arm Limited. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+- Neither the name of ARM nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior
+ written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+---
+
+.. note::
+ Individual files contain the following tag instead of the full license text.
+
+
+
+ SPDX-License-Identifier: BSD-3-Clause
+
+This enables machine processing of license information based on the SPDX
+License Identifiers that are here available: http://spdx.org/licenses/
diff --git a/psa-adac/core/CMakeLists.txt b/psa-adac/core/CMakeLists.txt
new file mode 100644
index 0000000..13da7a4
--- /dev/null
+++ b/psa-adac/core/CMakeLists.txt
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2020 Arm Limited. All rights reserved.
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+add_library(psa_adac_core STATIC)
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/psa_adac_config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/include/psa_adac_config.h)
+
+target_include_directories(psa_adac_core
+ PUBLIC
+ ${PSA_ADAC_ROOT}/psa-adac/core/include
+ PRIVATE
+ ${PSA_ADAC_MBEDTLS_INCLUDE}
+ ${PSA_ADAC_ROOT}/transport_layer/include
+)
+
+list(APPEND PSA_ADAC_CORE_SRC
+ ${PSA_ADAC_ROOT}/psa-adac/core/src/adac_certificate.c
+ ${PSA_ADAC_ROOT}/psa-adac/core/src/adac_crypto.c
+ ${PSA_ADAC_ROOT}/psa-adac/core/src/adac_token.c)
+
+target_sources(psa_adac_core
+ PRIVATE
+ ${PSA_ADAC_CORE_SRC}
+)
+
+target_link_libraries(psa_adac_core
+ PRIVATE
+ ${PROJECT_NAME}
+)
+
+install(DIRECTORY
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/
+ DESTINATION ${PSA_ADAC_INSTALL_PATH}/include
+)
diff --git a/psa-adac/core/adac_core.dox b/psa-adac/core/adac_core.dox
new file mode 100644
index 0000000..757750d
--- /dev/null
+++ b/psa-adac/core/adac_core.dox
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/** \defgroup adac-core ADAC Core
+ */
+
+/** \defgroup adac-crypto-api ADAC Cryptographic Interface
+ */
+
+/** \defgroup adac-crypto ADAC Cryptosystems
+ */
+
+/** \defgroup rsa3072 RSA 3072-bit key support
+ \ingroup adac-crypto
+ */
+
+/** \defgroup rsa4096 RSA 4096-bit key support
+ \ingroup adac-crypto
+ */
+
+/** \defgroup ecdsap256 ECDSA P-256 support
+ \ingroup adac-crypto
+ */
+
+/** \defgroup ecdsap521 ECDSA P-521 support
+ \ingroup adac-crypto
+ */
+
+/** \defgroup ed25519 EdDSA Ed25519 support
+ \ingroup adac-crypto
+ */
+
+/** \defgroup ed448 EdDSA Ed448 support
+ \ingroup adac-crypto
+ */
+
+/** \defgroup sm2sm3 SM2/SM3 support
+ \ingroup adac-crypto
+ */
+
+/** \defgroup cmac CMAC AES support
+ \ingroup adac-crypto
+ */
+
+/** \defgroup hmac HMAC SHA-256 support
+ \ingroup adac-crypto
+ */
+
diff --git a/psa-adac/core/include/psa_adac.h b/psa-adac/core/include/psa_adac.h
new file mode 100644
index 0000000..1569e99
--- /dev/null
+++ b/psa-adac/core/include/psa_adac.h
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * \file
+ * \brief ADAC Core
+ */
+
+#ifndef PSA_ADAC_H
+#define PSA_ADAC_H
+
+#include <stdint.h>
+#include <psa/crypto.h>
+
+/** \addtogroup adac-core
+ * @{
+ */
+
+#define ROUND_TO_WORD(x) (((size_t)x + 3) & ~0x03UL)
+
+/** \brief Key options
+ *
+ */
+typedef enum {
+ ECDSA_P256_SHA256 = 0x01, /**< EC key using P-256 curve, ECDSA signature with SHA-256 */
+ ECDSA_P521_SHA512 = 0x02, /**< EC key using P-521 curve, ECDSA signature with SHA-512 */
+ RSA_3072_SHA256 = 0x03, /**< 3072-bit RSA key, RSA signature with SHA-256 */
+ RSA_4096_SHA256 = 0x04, /**< 4096-bit RSA key, RSA signature with SHA-256 */
+ ED_25519_SHA512 = 0x05, /**< EC key using Curve25519, EdDSA signature with SHA-512 */
+ ED_448_SHAKE256 = 0x06, /**< EC key using Curve448, EdDSA signature with SHAKE-256 */
+ SM_SM2_SM3 = 0x07, /**< EC key using SM2, ECDSA/SM signature with SM3 */
+ CMAC_AES = 0x08, /**< AES-128 key, CMAC MAC */
+ HMAC_SHA256 = 0x09 /**< 256-bit key, HMAC-SHA-256 MAC */
+} key_options_t;
+
+/**
+ *
+ */
+typedef enum {
+ PSA_BINARY_TOKEN = 0x0200,
+ PSA_BINARY_CRT = 0x0201,
+ PSA_X509_CRT = 0x0202
+} type_id_t;
+
+/** \brief Version type
+ *
+ */
+typedef struct {
+ uint8_t major;
+ uint8_t minor;
+} psa_version_t;
+
+/** \brief TLV type for extensions
+ *
+ */
+typedef struct {
+ uint16_t _reserved; //!< Must be set to zero.
+ uint16_t type_id;
+ uint32_t length_in_bytes;
+ uint8_t value[];
+} psa_tlv_t;
+
+/** \brief Command protocol request packet
+ *
+ */
+typedef struct {
+ uint16_t _reserved; //!< Must be set to zero.
+ uint16_t command;
+ uint32_t data_count;
+ uint32_t data[];
+} request_packet_t;
+
+/** \brief Command protocol response packet
+ *
+ */
+typedef struct {
+ uint16_t _reserved; //!< Must be set to zero.
+ uint16_t status;
+ uint32_t data_count;
+ uint32_t data[];
+} response_packet_t;
+
+/** \brief Commands
+ *
+ */
+typedef enum {
+ SDP_DISCOVERY_CMD = 0x01, /**< `Discovery` command */
+ SDP_AUTH_START_CMD = 0x02, /**< `Start Authentication` command */
+ SDP_AUTH_RESPONSE_CMD = 0x03, /**< `Authentication Response` command */
+ SDP_RESUME_BOOT_CMD = 0x05, /**< `Resume Boot` command */
+ SDP_LOCK_DEBUG_CMD = 0x06 /**< `Lock Debug` command */
+} sdp_commands_t;
+
+/** \brief Status codes
+ *
+ */
+typedef enum {
+ SDP_SUCCESS = 0x0000,
+ SDP_FAILURE = 0x0001,
+ SDP_NEED_MORE_DATA = 0x0002,
+ SDP_UNSUPPORTED = 0x0003,
+ SDP_INVALID_COMMAND = 0x7FFF
+} sdp_status_t;
+
+/** \brief Certification roles
+ *
+ */
+typedef enum {
+ SDP_CRT_ROLE_ROOT = 0x01, /**< Root Certification Authority Certificate */
+ SDP_CRT_ROLE_INT = 0x02, /**< Intermediate Certification Authority Certificate */
+ SDP_CRT_ROLE_LEAF = 0x03 /**< Leaf Certificate */
+} certificate_role_t;
+
+/** \brief Certificate header
+ *
+ */
+typedef struct {
+ psa_version_t format_version;
+ uint8_t signature_type;
+ uint8_t key_type;
+ uint8_t role;
+ uint8_t usage;
+ uint16_t _reserved; //!< Must be set to zero.
+ uint16_t lifecycle;
+ uint16_t custom_constraint;
+ uint32_t extensions_bytes;
+ uint32_t soc_class;
+ uint8_t soc_id[16];
+ uint8_t permissions_mask[16];
+} certificate_header_t;
+
+/** \brief Token header
+ *
+ */
+typedef struct {
+ psa_version_t format_version;
+ uint8_t signature_type;
+ uint8_t _reserved; //!< Must be set to zero.
+ uint32_t extensions_bytes;
+ uint8_t requested_permissions[16];
+} token_header_t;
+
+#define CHALLENGE_SIZE 32
+#define MAX_EXTENSIONS 16
+
+/** \brief Authentication challenge
+ *
+ */
+typedef struct {
+ psa_version_t format_version;
+ uint16_t _reserved;
+ uint8_t challenge_vector[32];
+} psa_auth_challenge_t;
+
+typedef struct {
+ uint8_t *content;
+ size_t size;
+ size_t max;
+ uint8_t key_type;
+} validation_context_t;
+
+/** \brief Library initialization
+ *
+ */
+psa_status_t psa_adac_init();
+
+/**
+ *
+ */
+psa_status_t psa_adac_context_load_key(validation_context_t *context, uint8_t key_type, uint8_t *key, size_t key_size);
+
+// Do sanity checks to insure memory safety
+psa_status_t psa_adac_certificate_sanity_check(uint8_t *crt, size_t crt_size);
+
+/**
+ *
+ */
+psa_status_t psa_adac_extract_public_key(uint8_t *crt, size_t crt_size, uint8_t *key_type,
+ uint8_t **pubkey, size_t *pubkey_size);
+
+/**
+ *
+ */
+psa_status_t psa_adac_update_context(uint8_t *crt, size_t crt_size, validation_context_t *context);
+
+/**
+ *
+ */
+psa_status_t psa_adac_certificate_verify_sig(uint8_t *crt, size_t crt_size,
+ uint8_t key_type, uint8_t *key, size_t key_size);
+
+/**
+ *
+ */
+psa_status_t psa_adac_token_verify_info(uint8_t token[], size_t token_size, uint8_t **sig, size_t *sig_size,
+ size_t *tbs_size, size_t *_body_size,
+ psa_algorithm_t *hash_algo, psa_algorithm_t *sig_algo);
+/**
+ *
+ */
+psa_status_t psa_adac_verify_token_signature(uint8_t *token, size_t token_size, uint8_t *challenge,
+ size_t challenge_size, uint8_t key_type, uint8_t *key, size_t key_size);
+/**
+ *
+ */
+psa_status_t psa_adac_verify_certificate_rotpk(uint8_t *crt, size_t crt_size, psa_algorithm_t alg,
+ uint8_t **rotpk, size_t *rotpk_size, size_t rotpk_count);
+
+/**@}*/
+
+#endif // PSA_ADAC_H
diff --git a/psa-adac/core/include/psa_adac_config.h.in b/psa-adac/core/include/psa_adac_config.h.in
new file mode 100644
index 0000000..1d47cdd
--- /dev/null
+++ b/psa-adac/core/include/psa_adac_config.h.in
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#cmakedefine PSA_ADAC_DEBUG
+#cmakedefine PSA_ADAC_TRACE
+#cmakedefine PSA_ADAC_QEMU
+#cmakedefine PSA_ADAC_QUIET
+#cmakedefine PSA_ADAC_MINIMUM_SIZE_CONFIG
+
+#cmakedefine PSA_ADAC_EC_P256
+#cmakedefine PSA_ADAC_EC_P521
+#cmakedefine PSA_ADAC_RSA3072
+#cmakedefine PSA_ADAC_RSA4096
+#cmakedefine PSA_ADAC_ED25519
+#cmakedefine PSA_ADAC_ED448
+#cmakedefine PSA_ADAC_SM2SM3
+#cmakedefine PSA_ADAC_HMAC
+#cmakedefine PSA_ADAC_CMAC
+#cmakedefine PSA_ADAC_HW_CRYPTO
+#cmakedefine PSA_ADAC_USE_CRYPTOCELL
+
+#cmakedefine CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}"
diff --git a/psa-adac/core/include/psa_adac_crypto_api.h b/psa-adac/core/include/psa_adac_crypto_api.h
new file mode 100644
index 0000000..5458832
--- /dev/null
+++ b/psa-adac/core/include/psa_adac_crypto_api.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PSA_ADAC_PSA_CRYPTO_API_H
+#define PSA_ADAC_PSA_CRYPTO_API_H
+
+#include <psa/crypto.h>
+
+/** \addtogroup adac-crypto-api
+ * @{
+ */
+
+/** \brief ADAC cryptographic back-end initialization
+ *
+ * This function will be called by ADAC library.
+ */
+psa_status_t psa_adac_crypto_init();
+
+/** \brief Generate challenge
+ *
+ * \param[out] output Output buffer for the challenge.
+ * \param output_size Number of bytes to generate and output.
+ */
+psa_status_t psa_adac_generate_challenge(uint8_t *output, size_t output_size);
+
+/** \brief Compute the hash of a message
+ *
+ * \param alg The hash algorithm to compute.
+ * \param[in] input Buffer containing the message to hash.
+ * \param input_size Size of the \p input buffer in bytes.
+ * \param[out] hash Buffer where the hash is to be written.
+ * \param hash_size Size of the \p hash buffer in bytes.
+ * \param[out] hash_length On success, the length of the hash in bytes.
+ *
+ * \retval PSA_SUCCESS
+ * Success.
+ * \retval PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported (or unknown hash algorithm).
+ * \retval PSA_ERROR_INVALID_ARGUMENT
+ * \retval PSA_ERROR_HARDWARE_FAILURE
+ */
+psa_status_t psa_adac_hash(psa_algorithm_t alg, const uint8_t *input, size_t input_size,
+ uint8_t *hash, size_t hash_size, size_t *hash_length);
+
+/** \brief Compute the hash of a message composed of multiple parts
+ *
+ * \param alg The hash algorithm to compute.
+ * \param[in] inputs Array of buffers containing the message to hash.
+ * \param[in] input_sizes Array of size of the \p inputs buffers in bytes.
+ * \param input_count Number of entries in \p inputs and \p input_sizes.
+ * \param[out] hash Buffer where the hash is to be written.
+ * \param hash_size Size of the \p hash buffer in bytes.
+ * \param[out] hash_length On success, the length of the hash in bytes.
+ *
+ * \retval PSA_SUCCESS
+ * Success.
+ * \retval PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported (or unknown hash algorithm).
+ * \retval PSA_ERROR_INVALID_ARGUMENT
+ * \retval PSA_ERROR_HARDWARE_FAILURE
+ */
+psa_status_t psa_adac_hash_multiple(psa_algorithm_t alg,
+ const uint8_t *inputs[], size_t input_sizes[], size_t input_count,
+ uint8_t hash[], size_t hash_size, size_t *hash_length);
+
+/** \brief Compute the hash of a message and compare it with an expected value.
+ *
+ * \param alg The hash algorithm to compute.
+ * \param[in] input Buffer containing the message to hash.
+ * \param input_size Size of the \p input buffer in bytes.
+ * \param[out] hash Buffer containing the expected hash value.
+ * \param hash_size Size of the \p hash buffer in bytes.
+ *
+ * \retval PSA_SUCCESS
+ * The expected hash is identical to the actual hash of the input.
+ * \retval PSA_ERROR_INVALID_SIGNATURE
+ * The hash of the message was calculated successfully, but it
+ * differs from the expected hash.
+ * \retval PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported (or unknown hash algorithm).
+ * \retval PSA_ERROR_INVALID_ARGUMENT
+ * \retval PSA_ERROR_HARDWARE_FAILURE
+ */
+psa_status_t psa_adac_hash_verify(psa_algorithm_t alg, const uint8_t input[], size_t input_size,
+ uint8_t hash[], size_t hash_size);
+
+/** \brief Compute the hash of a message and compare it with a list of expected values
+ *
+ */
+psa_status_t psa_adac_hash_verify_multiple(psa_algorithm_t alg, const uint8_t input[], size_t input_length,
+ uint8_t *hash[], size_t hash_size[], size_t hash_count);
+
+/** \brief Verify a signature
+ *
+ */
+psa_status_t psa_adac_verify_signature(uint8_t key_type, uint8_t *key, size_t key_size, psa_algorithm_t hash_algo,
+ const uint8_t *inputs[], size_t input_sizes[], size_t input_count,
+ psa_algorithm_t sig_algo, uint8_t *sig, size_t sig_size);
+
+/** \brief Verify a message authentication code
+ *
+ */
+psa_status_t psa_adac_mac_verify(psa_algorithm_t alg, const uint8_t *inputs[], size_t input_sizes[], size_t input_count,
+ const uint8_t key[], size_t key_size, uint8_t mac[], size_t mac_size);
+
+/** \brief Derive key
+ *
+ */
+psa_status_t psa_adac_derive_key(uint8_t *crt, size_t crt_size, uint8_t key_type, uint8_t *key, size_t key_size);
+
+/**@}*/
+
+#endif //PSA_ADAC_PSA_CRYPTO_API_H
diff --git a/psa-adac/core/include/psa_adac_cryptosystems.h b/psa-adac/core/include/psa_adac_cryptosystems.h
new file mode 100644
index 0000000..f694469
--- /dev/null
+++ b/psa-adac/core/include/psa_adac_cryptosystems.h
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * \file
+ *
+ * Defines certificate and token structures for supported cryptosystems.
+ */
+
+#ifndef PSA_ADAC_CRYPTOSYSTEMS_H
+#define PSA_ADAC_CRYPTOSYSTEMS_H
+
+#include <psa/crypto.h>
+
+#ifdef PSA_ADAC_EC_P256
+
+/** \addtogroup ecdsap256
+ * @{
+ */
+
+#define ECDSA_P256_PUBLIC_KEY_SIZE 64
+#define ECDSA_P256_SIGNATURE_SIZE 64
+#define ECDSA_P256_HASH_SIZE 32
+#define ECDSA_P256_HASH_ALGORITHM PSA_ALG_SHA_256
+#define ECDSA_P256_SIGN_ALGORITHM PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)
+
+/** \brief ADAC certificate structure for ECDSA with P-256 curve cryptosystem
+ */
+typedef struct {
+ certificate_header_t header;
+ uint8_t pubkey[ECDSA_P256_PUBLIC_KEY_SIZE]; // P-256 public key
+ uint8_t extensions_hash[ECDSA_P256_HASH_SIZE]; // SHA-256 hash
+ uint8_t signature[ECDSA_P256_SIGNATURE_SIZE]; // P-256 with SHA-256 signature
+ uint32_t extensions[];
+} certificate_p256_p256_t;
+
+/** \brief ADAC token structure for ECDSA with P-256 curve cryptosystem
+ */
+typedef struct {
+ token_header_t header;
+ uint8_t extensions_hash[ECDSA_P256_HASH_SIZE]; // SHA-256 hash
+ uint8_t signature[ECDSA_P256_SIGNATURE_SIZE]; // P-256 with SHA-256 signature
+ uint32_t extensions[];
+} token_p256_t;
+
+/**@}*/
+
+#endif // PSA_ADAC_EC_P256
+
+#ifdef PSA_ADAC_EC_P521
+
+/** \addtogroup ecdsap521
+ * @{
+ */
+
+#define ECDSA_P521_PUBLIC_KEY_SIZE 132
+#define ECDSA_P521_SIGNATURE_SIZE 132
+#define ECDSA_P521_HASH_SIZE 64
+#define ECDSA_P521_HASH_ALGORITHM PSA_ALG_SHA_512
+#define ECDSA_P521_SIGN_ALGORITHM PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_512)
+
+/** \brief ADAC certificate structure for ECDSA with P-521 curve cryptosystem
+ */
+typedef struct {
+ certificate_header_t header;
+ uint8_t pubkey[ROUND_TO_WORD(ECDSA_P521_PUBLIC_KEY_SIZE)]; // P-521 public key
+ uint8_t extensions_hash[ECDSA_P521_HASH_SIZE]; // SHA-512 hash
+ uint8_t signature[ROUND_TO_WORD(ECDSA_P521_SIGNATURE_SIZE)]; // P-521 with SHA-512 signature
+ uint32_t extensions[];
+} certificate_p521_p521_t;
+
+/** \brief ADAC token structure for ECDSA with P-521 curve cryptosystem
+ */
+typedef struct {
+ token_header_t header;
+ uint8_t extensions_hash[ECDSA_P521_HASH_SIZE]; // SHA-512 hash
+ uint8_t signature[ECDSA_P521_SIGNATURE_SIZE]; // P-521 with SHA-512 signature
+ uint32_t extensions[];
+} token_p521_t;
+
+/**@}*/
+
+#endif // PSA_ADAC_EC_P521
+
+#ifdef PSA_ADAC_RSA3072
+
+/** \addtogroup rsa3072
+ * @{
+ */
+
+#define RSA_3072_PUBLIC_KEY_SIZE 384
+#define RSA_3072_SIGNATURE_SIZE 384
+#define RSA_3072_HASH_SIZE 32
+#define RSA_3072_HASH_ALGORITHM PSA_ALG_SHA_256
+#define RSA_3072_SIGN_ALGORITHM PSA_ALG_RSA_PSS(PSA_ALG_SHA_256)
+
+/** \brief ADAC certificate structure for RSA 3072-bit key cryptosystem
+ */
+typedef struct {
+ certificate_header_t header;
+ uint8_t pubkey[RSA_3072_PUBLIC_KEY_SIZE]; // RSA 3072-bit public key
+ uint8_t extensions_hash[RSA_3072_HASH_SIZE]; // SHA-256 hash
+ uint8_t signature[RSA_3072_SIGNATURE_SIZE]; // RSA with SHA-256 signature
+ uint32_t extensions[];
+} certificate_rsa3072_rsa3072_t;
+
+/** \brief ADAC token structure for RSA 3072-bit key cryptosystem
+ */
+typedef struct {
+ token_header_t header;
+ uint8_t extensions_hash[RSA_3072_HASH_SIZE]; // SHA-256 hash
+ uint8_t signature[RSA_3072_SIGNATURE_SIZE]; // RSA with SHA-256 signature
+ uint32_t extensions[];
+} token_rsa3072_t;
+
+/**@}*/
+
+#endif // PSA_ADAC_RSA3072
+
+#ifdef PSA_ADAC_RSA4096
+
+/** \addtogroup rsa4096
+ * @{
+ */
+
+#define RSA_4096_PUBLIC_KEY_SIZE 512
+#define RSA_4096_SIGNATURE_SIZE 512
+#define RSA_4096_HASH_SIZE 32
+#define RSA_4096_HASH_ALGORITHM PSA_ALG_SHA_256
+#define RSA_4096_SIGN_ALGORITHM PSA_ALG_RSA_PSS(PSA_ALG_SHA_256)
+
+/** \brief ADAC certificate structure for RSA 4096-bit key cryptosystem
+ */
+typedef struct {
+ certificate_header_t header;
+ uint8_t pubkey[RSA_4096_PUBLIC_KEY_SIZE]; // RSA 4096-bit public key
+ uint8_t extensions_hash[RSA_4096_HASH_SIZE]; // SHA-256 hash
+ uint8_t signature[RSA_4096_SIGNATURE_SIZE]; // RSA with SHA-256 signature
+ uint32_t extensions[];
+} certificate_rsa4096_rsa4096_t;
+
+/** \brief ADAC token structure for RSA 4096-bit key cryptosystem
+ */
+typedef struct {
+ token_header_t header;
+ uint8_t extensions_hash[RSA_4096_HASH_SIZE]; // SHA-256 hash
+ uint8_t signature[RSA_4096_SIGNATURE_SIZE]; // RSA with SHA-256 signature
+ uint32_t extensions[];
+} token_rsa4096_t;
+
+/**@}*/
+
+#endif // PSA_ADAC_RSA4096
+
+#ifdef PSA_ADAC_ED25519
+
+/** \addtogroup ed25519
+ * @{
+ */
+
+/** \brief ADAC certificate structure for EdDSA with Curve25519 curve cryptosystem
+ */
+#define PSA_ALG_ED25519 (PSA_ALG_VENDOR_FLAG & 0x1)
+#define EDDSA_ED25519_PUBLIC_KEY_SIZE 32
+#define EDDSA_ED25519_SIGNATURE_SIZE 64
+#define EDDSA_ED25519_HASH_SIZE 64
+#define EDDSA_ED25519_HASH_ALGORITHM PSA_ALG_SHA_512
+#define EDDSA_ED25519_SIGN_ALGORITHM PSA_ALG_ED25519 // Non-standard
+
+/** \brief ADAC certificate structure for EdDSA with Curve25519 curve cryptosystem
+ */
+typedef struct {
+ certificate_header_t header;
+ uint8_t pubkey[ROUND_TO_WORD(EDDSA_ED25519_PUBLIC_KEY_SIZE)];
+ uint8_t extensions_hash[EDDSA_ED25519_HASH_SIZE];
+ uint8_t signature[ROUND_TO_WORD(EDDSA_ED25519_SIGNATURE_SIZE)];
+ uint32_t extensions[];
+} certificate_ed255_ed255_t;
+
+
+/** \brief ADAC token structure for EdDSA with Curve25519 curve cryptosystem
+ */
+typedef struct {
+ token_header_t header;
+ uint8_t extensions_hash[EDDSA_ED25519_HASH_SIZE]; // SHA-512 hash
+ uint8_t signature[EDDSA_ED25519_SIGNATURE_SIZE]; // Ed25519 signature
+ uint32_t extensions[];
+} token_ed255_t;
+
+/**@}*/
+
+#endif // PSA_ADAC_ED25519
+
+#ifdef PSA_ADAC_ED448
+
+/** \addtogroup ed448
+ * @{
+ */
+
+#define PSA_ALG_ED448 (PSA_ALG_VENDOR_FLAG & 0x2)
+#define PSA_ALG_SHAKE256 (PSA_ALG_VENDOR_FLAG & 0x3)
+#define EDDSA_ED448_PUBLIC_KEY_SIZE 57
+#define EDDSA_ED448_SIGNATURE_SIZE 114
+#define EDDSA_ED448_HASH_SIZE 64
+#define EDDSA_ED448_HASH_ALGORITHM PSA_ALG_SHAKE256 // Non-standard
+#define EDDSA_ED448_SIGN_ALGORITHM PSA_ALG_ED448 // Non-standard
+
+/** \brief ADAC certificate structure for EdDSA with Curve448 curve cryptosystem
+ */
+typedef struct {
+ certificate_header_t header;
+ uint8_t pubkey[ROUND_TO_WORD(EDDSA_ED448_PUBLIC_KEY_SIZE)];
+ uint8_t extensions_hash[EDDSA_ED448_HASH_SIZE];
+ uint8_t signature[ROUND_TO_WORD(EDDSA_ED448_SIGNATURE_SIZE)];
+ uint32_t extensions[];
+} certificate_ed448_ed448_t;
+
+/** \brief ADAC token structure for EdDSA with Curve448 curve cryptosystem
+ */
+typedef struct {
+ token_header_t header;
+ uint8_t extensions_hash[EDDSA_ED448_HASH_SIZE]; // SHAKE256 hash
+ uint8_t signature[ROUND_TO_WORD(EDDSA_ED448_SIGNATURE_SIZE)]; // Ed448 signature
+ uint32_t extensions[];
+} token_ed448_t;
+
+/**@}*/
+
+#endif // PSA_ADAC_ED448
+
+#ifdef PSA_ADAC_SM2
+
+/** \addtogroup sm2sm3
+ * @{
+ */
+
+#define PSA_ALG_SM2 (PSA_ALG_VENDOR_FLAG & 0x4)
+#define PSA_ALG_SM3 (PSA_ALG_VENDOR_FLAG & 0x5)
+#define SM2_SM3_PUBLIC_KEY_SIZE 64
+#define SM2_SM3_SIGNATURE_SIZE 64
+#define SM2_SM3_HASH_SIZE 32
+#define SM2_SM3_HASH_ALGORITHM PSA_ALG_SM3
+#define SM2_SM3_SIGN_ALGORITHM PSA_ALG_SM2
+
+/** \brief ADAC certificate structure for SM2 cryptosystem
+ */
+typedef struct {
+ certificate_header_t header;
+ uint8_t pubkey[SM2_SM3_PUBLIC_KEY_SIZE]; // SM2 public key
+ uint8_t extensions_hash[SM2_SM3_HASH_SIZE]; // SM3 hash
+ uint8_t signature[SM2_SM3_SIGNATURE_SIZE]; // SM2 with SM3 signature
+ uint32_t extensions[];
+} certificate_sm2sm3_sm2sm3_t;
+
+/** \brief ADAC token structure for SM2 cryptosystem
+ */
+typedef struct {
+ token_header_t header;
+ uint8_t extensions_hash[SM2_SM3_HASH_SIZE]; // SM3 hash
+ uint8_t signature[SM2_SM3_SIGNATURE_SIZE]; // SM2 with SM3 signature
+ uint32_t extensions[];
+} token_sm2sm3_t;
+
+/**@}*/
+
+#endif // PSA_ADAC_SM2
+
+#ifdef PSA_ADAC_CMAC
+
+/** \addtogroup cmac
+ * @{
+ */
+
+#define CMAC_PUBLIC_KEY_SIZE 16
+#define CMAC_SIGNATURE_SIZE 16
+#define CMAC_HASH_SIZE 16
+#define CMAC_HASH_ALGORITHM PSA_ALG_CMAC
+#define CMAC_SIGN_ALGORITHM PSA_ALG_CMAC
+
+/** \brief ADAC certificate structure for CMAC with AES-128 cryptosystem
+ */
+typedef struct {
+ certificate_header_t header;
+ uint8_t pubkey[CMAC_PUBLIC_KEY_SIZE]; // Nonce
+ uint8_t extensions_hash[CMAC_HASH_SIZE]; // CMAC
+ uint8_t signature[CMAC_SIGNATURE_SIZE]; // CMAC
+ uint32_t extensions[];
+} certificate_cmac_cmac_t;
+
+/** \brief ADAC token structure for CMAC with AES-128 cryptosystem
+ */
+typedef struct {
+ token_header_t header;
+ uint8_t extensions_hash[CMAC_HASH_SIZE]; // CMAC
+ uint8_t signature[CMAC_SIGNATURE_SIZE]; // CMAC
+ uint32_t extensions[];
+} token_cmac_t;
+
+/**@}*/
+
+#endif // PSA_ADAC_CMAC
+
+#ifdef PSA_ADAC_HMAC
+
+/** \addtogroup hmac
+ * @{
+ */
+
+#define HMAC_PUBLIC_KEY_SIZE 32
+#define HMAC_SIGNATURE_SIZE 32
+#define HMAC_HASH_SIZE 32
+#define HMAC_HASH_ALGORITHM PSA_ALG_SHA_256
+#define HMAC_SIGN_ALGORITHM PSA_ALG_HMAC(PSA_ALG_SHA_256)
+
+/** \brief ADAC certificate structure for HMAC with SHA-256 cryptosystem
+ */
+typedef struct {
+ certificate_header_t header;
+ uint8_t pubkey[HMAC_PUBLIC_KEY_SIZE]; // Nonce
+ uint8_t extensions_hash[HMAC_HASH_SIZE]; // SHA-256 hash
+ uint8_t signature[HMAC_SIGNATURE_SIZE]; // HMAC
+ uint32_t extensions[];
+} certificate_hmac_hmac_t;
+
+/** \brief ADAC token structure for HMAC with SHA-256 cryptosystem
+ */
+typedef struct {
+ token_header_t header;
+ uint8_t extensions_hash[HMAC_HASH_SIZE]; // SHA-256 Hash
+ uint8_t signature[HMAC_SIGNATURE_SIZE]; // HMAC-SHA-256
+ uint32_t extensions[];
+} token_hmac_t;
+
+/**@}*/
+
+#endif // PSA_ADAC_HMAC
+
+#endif //PSA_ADAC_CRYPTOSYSTEMS_H
diff --git a/psa-adac/core/include/psa_adac_debug.h b/psa-adac/core/include/psa_adac_debug.h
new file mode 100644
index 0000000..89fc152
--- /dev/null
+++ b/psa-adac/core/include/psa_adac_debug.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PSA_ADAC_DEBUG_H
+#define PSA_ADAC_DEBUG_H
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <psa_adac_config.h>
+
+#define PSA_ADAC_LOG_LVL_NONE 50
+#define PSA_ADAC_LOG_LVL_ERROR 40
+#define PSA_ADAC_LOG_LVL_WARN 30
+#define PSA_ADAC_LOG_LVL_INFO 20
+#define PSA_ADAC_LOG_LVL_DEBUG 10
+#define PSA_ADAC_LOG_LVL_TRACE 0
+#ifndef PSA_ADAC_LOG_PRINT
+#define PSA_ADAC_LOG_PRINT printf
+#endif
+#ifdef PSA_ADAC_QUIET
+#define PSA_ADAC_LOG_LEVEL PSA_ADAC_LOG_LVL_NONE
+#define PSA_ADAC_LOG_PRINTF(...)
+#define PSA_ADAC_LOG_SPRINTF(var, format, ...)
+#else
+#define PSA_ADAC_LOG_PRINTF(...) printf(__VA_ARGS__)
+#define PSA_ADAC_LOG_SPRINTF(var, format, ...) \
+ sprintf(var, format, __VA_ARGS__)
+#if defined(PSA_ADAC_TRACE)
+#define PSA_ADAC_LOG_LEVEL PSA_ADAC_LOG_LVL_TRACE
+#elif defined(PSA_ADAC_DEBUG) || defined(DEBUG) || !defined(NDEBUG)
+#define PSA_ADAC_LOG_LEVEL PSA_ADAC_LOG_LVL_DEBUG
+#else
+#define PSA_ADAC_LOG_LEVEL PSA_ADAC_LOG_LVL_INFO
+#endif
+#endif
+
+#define PSA_ADAC_LOG_FUNC_AND_LEVEL(_level, _who) \
+ PSA_ADAC_LOG_PRINT("%-30.30s:% 5d : %-5.5s : %-10.10s : ", __func__, __LINE__, _level, _who)
+
+#define PSA_ADAC_LOG_PRINT_LINE(_who, _level, _format, ...) \
+ PSA_ADAC_LOG_PRINT("%-30.30s:% 5d : %-5.5s : %-10.10s : "_format, __func__, __LINE__, _who, _level, ##__VA_ARGS__)
+
+#if PSA_ADAC_LOG_LEVEL <= PSA_ADAC_LOG_LVL_ERROR
+#define PSA_ADAC_LOG_ERR(_who, _format, ...) PSA_ADAC_LOG_PRINT_LINE("error", _who, _format, ##__VA_ARGS__)
+#else
+#define PSA_ADAC_LOG_ERR(_who, _format, ...) do{} while(0)
+#endif
+
+#if PSA_ADAC_LOG_LEVEL <= PSA_ADAC_LOG_LVL_WARN
+#define PSA_ADAC_LOG_WARN(_who, _format, ...) PSA_ADAC_LOG_PRINT_LINE("warn", _who, _format, ##__VA_ARGS__)
+#else
+#define PSA_ADAC_LOG_WARN(_who, _format, ...) do{} while(0)
+#endif
+
+#if PSA_ADAC_LOG_LEVEL <= PSA_ADAC_LOG_LVL_INFO
+#define PSA_ADAC_LOG_INFO(_who, _format, ...) PSA_ADAC_LOG_PRINT_LINE("info", _who, _format, ##__VA_ARGS__)
+#else
+#define PSA_ADAC_LOG_INFO(_who, _format, ...) do{} while(0)
+#endif
+
+#if PSA_ADAC_LOG_LEVEL <= PSA_ADAC_LOG_LVL_DEBUG
+#define PSA_ADAC_LOG_DEBUG(_who, _format, ...) PSA_ADAC_LOG_PRINT_LINE("debug", _who, _format, ##__VA_ARGS__)
+#define PSA_ADAC_LOG_DUMP(_who, _label, _buff, _size) \
+ do { \
+ uint32_t _i = 0, _j = 0, _k = 0; \
+ for (_i = 0; _i * 16 + _j < _size; _i++, _j = 0) { \
+ char _tmp[256] = {0}; \
+ for (_j = 0, _k = 0; _i * 16 + _j < _size && _j < 16; _j++) { \
+ _k += sprintf(_tmp + _k, "%02x", ((uint8_t *)_buff)[_i * 16 + _j]); \
+ } \
+ PSA_ADAC_LOG_FUNC_AND_LEVEL("debug", _who); \
+ PSA_ADAC_LOG_PRINT("%-10.10s %04x: %s\n", _label, _i * 16, _tmp); \
+ } \
+ } while(0)
+#else
+#define PSA_ADAC_LOG_DEBUG(_who, _format, ...) do{} while(0)
+#define PSA_ADAC_LOG_DUMP(_who, _label, _buff, _size) do{} while(0)
+#endif
+
+#if PSA_ADAC_LOG_LEVEL <= PSA_ADAC_LOG_LVL_TRACE
+#define PSA_ADAC_LOG_TRACE(_who, _format, ...) PSA_ADAC_LOG_PRINT_LINE("trace", _who, _format, ##__VA_ARGS__)
+#define PSA_ADAC_LOG_TDUMP(_who, _label, _buff, _size) \
+ do { \
+ uint32_t _i = 0, _j = 0, _k = 0; \
+ for (_i = 0; _i * 16 + _j < _size; _i++, _j = 0) { \
+ char _tmp[256] = {0}; \
+ for (_j = 0, _k = 0; _i * 16 + _j < _size && _j < 16; _j++) { \
+ _k += sprintf(_tmp + _k, "%02x", ((uint8_t *)_buff)[_i * 16 + _j]); \
+ } \
+ PSA_ADAC_LOG_FUNC_AND_LEVEL("trace", _who); \
+ PSA_ADAC_LOG_PRINT("%-10.10s %04x: %s\n", _label, _i * 16, _tmp); \
+ } \
+ } while(0)
+#else
+#define PSA_ADAC_LOG_TRACE(_who, _format, ...) do{} while(0)
+#define PSA_ADAC_LOG_TDUMP(_who, _label, _buff, _size) do{} while(0)
+#endif
+
+#define PSA_ADAC_ASSERT_ERROR(_cmd, _exp, _error) \
+ do { \
+ int _res = 0; \
+ if ((_res = (int)(_cmd)) != _exp) { \
+ PSA_ADAC_LOG_ERR(ENTITY_NAME, "failed to run[%s] res[%d] returning[%s]\n", #_cmd, _res, #_error); \
+ res = _error; \
+ goto bail; \
+ } \
+ } while (0)
+
+#define PSA_ADAC_ASSERT(_cmd, _exp) \
+ do { \
+ if ((res = (_cmd)) != _exp) { \
+ PSA_ADAC_LOG_ERR(ENTITY_NAME, "failed to run[%s] res[%d]\n", #_cmd, res); \
+ goto bail; \
+ } \
+ } while (0)
+
+#endif //PSA_ADAC_DEBUG_H
diff --git a/psa-adac/core/src/adac_certificate.c b/psa-adac/core/src/adac_certificate.c
new file mode 100644
index 0000000..3827329
--- /dev/null
+++ b/psa-adac/core/src/adac_certificate.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <psa_adac_config.h>
+
+#include <psa_adac.h>
+#include <psa_adac_crypto_api.h>
+#include <psa_adac_cryptosystems.h>
+#include <psa_adac_debug.h>
+#include <stdio.h>
+
+psa_status_t psa_adac_certificate_sanity_check(uint8_t *crt, size_t crt_size) {
+ certificate_header_t *h_crt = (certificate_header_t *) crt;
+ psa_status_t r = PSA_SUCCESS;
+
+ if ((crt == NULL) || (sizeof(certificate_header_t) > crt_size)) {
+ r = PSA_ERROR_INVALID_ARGUMENT;
+ } else {
+ size_t body_size = 0;
+
+ if ((h_crt->key_type == ECDSA_P256_SHA256) && (h_crt->signature_type == ECDSA_P256_SHA256)) {
+#ifdef PSA_ADAC_EC_P256
+ body_size = sizeof(certificate_p256_p256_t);
+#endif
+ } else if ((h_crt->key_type == ECDSA_P521_SHA512) && (h_crt->signature_type == ECDSA_P521_SHA512)) {
+#ifdef PSA_ADAC_EC_P521
+ body_size = sizeof(certificate_p521_p521_t);
+#endif
+ } else if ((h_crt->key_type == RSA_3072_SHA256) && (h_crt->signature_type == RSA_3072_SHA256)) {
+#ifdef PSA_ADAC_RSA3072
+ body_size = sizeof(certificate_rsa3072_rsa3072_t);
+#endif
+ } else if ((h_crt->key_type == RSA_4096_SHA256) && (h_crt->signature_type == RSA_4096_SHA256)) {
+#ifdef PSA_ADAC_RSA4096
+ body_size = sizeof(certificate_rsa4096_rsa4096_t);
+#endif
+ } else if ((h_crt->key_type == ED_25519_SHA512) && (h_crt->signature_type == ED_25519_SHA512)) {
+#ifdef PSA_ADAC_ED25519
+ body_size = sizeof(certificate_ed255_ed255_t);
+#endif
+ } else if ((h_crt->key_type == ED_448_SHAKE256) && (h_crt->signature_type == ED_448_SHAKE256)) {
+#ifdef PSA_ADAC_ED448
+ body_size = sizeof(certificate_ed448_ed448_t);
+#endif
+ } else if ((h_crt->key_type == SM_SM2_SM3) && (h_crt->signature_type == SM_SM2_SM3)) {
+#ifdef PSA_ADAC_SM2
+ body_size = sizeof(certificate_sm2sm3_sm2sm3_t);
+#endif
+ } else if ((h_crt->key_type == CMAC_AES) && (h_crt->signature_type == CMAC_AES)) {
+#ifdef PSA_ADAC_CMAC
+ body_size = sizeof(certificate_cmac_cmac_t);
+#endif
+ } else if ((h_crt->key_type == HMAC_SHA256) && (h_crt->signature_type == HMAC_SHA256)) {
+#ifdef PSA_ADAC_HMAC
+ body_size = sizeof(certificate_hmac_hmac_t);
+#endif
+ } else {
+ body_size = 0; /* [misra-c2012-15.7] */
+ }
+
+ if (body_size == 0UL) {
+ r = PSA_ERROR_NOT_SUPPORTED;
+ } else {
+ size_t exts_size = ROUND_TO_WORD(h_crt->extensions_bytes);
+ if ((body_size + exts_size) != crt_size) {
+ // Inconsistent size
+ r = PSA_ERROR_INVALID_ARGUMENT;
+ }
+ }
+ }
+
+ return r;
+}
+
+psa_status_t psa_adac_certificate_verify_extensions(uint8_t *exts, size_t exts_size, psa_algorithm_t hash_algo,
+ uint8_t key_type, uint8_t *key, size_t key_size,
+ uint8_t *hash, size_t hash_size) {
+ psa_status_t r = PSA_ERROR_NOT_SUPPORTED;
+
+ if ((hash_algo == PSA_ALG_SHA_256) || (hash_algo == PSA_ALG_SHA_512)) {
+ r = psa_adac_hash_verify(hash_algo, exts, exts_size, hash, hash_size);
+ } else if ((hash_algo == PSA_ALG_CMAC) && (key_type == CMAC_AES)) {
+#if defined(PSA_ADAC_CMAC)
+ r = psa_adac_mac_verify(hash_algo, (const uint8_t **) &exts, &exts_size, 1, key, key_size, hash, hash_size);
+#else
+ key;
+ key_size;
+#endif
+ } else {
+ r = PSA_ERROR_NOT_SUPPORTED; /* [misra-c2012-15.7] */
+ }
+
+ return r;
+}
+
+psa_status_t psa_adac_certificate_verify_sig(uint8_t *crt, size_t crt_size,
+ uint8_t key_type, uint8_t *key, size_t key_size) {
+ certificate_header_t *h_crt = (certificate_header_t *) crt;
+ uint8_t *sig = NULL;
+ uint8_t *ext = NULL;
+ uint8_t *ext_hash = NULL;
+ psa_status_t r = PSA_SUCCESS;
+ psa_algorithm_t sig_algo = 0;
+ psa_algorithm_t hash_algo = 0;
+ size_t hash_size = 0;
+ size_t sig_size = 0;
+ size_t tbs_size = 0;
+ size_t body_size = 0;
+
+ if ((crt == NULL) || (key == NULL) || (crt_size <= 0UL) || (key_size <= 0UL)) {
+ PSA_ADAC_LOG_ERR("crt", "Invalid arguments\n");
+ r = PSA_ERROR_INVALID_ARGUMENT;
+ } else if ((h_crt->key_type != key_type) || (h_crt->signature_type != key_type)) {
+ PSA_ADAC_LOG_ERR("crt", "Types mismatch\n");
+ r = PSA_ERROR_NOT_SUPPORTED;
+ } else if ((h_crt->key_type == ECDSA_P256_SHA256) && (h_crt->signature_type == ECDSA_P256_SHA256)) {
+#ifdef PSA_ADAC_EC_P256
+ certificate_p256_p256_t *s_crt = (certificate_p256_p256_t *) crt;
+ sig = s_crt->signature;
+ sig_algo = ECDSA_P256_SIGN_ALGORITHM;
+ sig_size = sizeof(s_crt->signature);
+ tbs_size = offsetof(certificate_p256_p256_t, signature);
+ body_size = sizeof(certificate_p256_p256_t);
+ ext = (uint8_t *) s_crt->extensions;
+ ext_hash = s_crt->extensions_hash;
+ hash_size = sizeof(s_crt->extensions_hash);
+ hash_algo = ECDSA_P256_HASH_ALGORITHM;
+#else
+ r = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if ((h_crt->key_type == ECDSA_P521_SHA512) && (h_crt->signature_type == ECDSA_P521_SHA512)) {
+#ifdef PSA_ADAC_EC_P521
+ certificate_p521_p521_t *s_crt = (certificate_p521_p521_t *) crt;
+ sig = s_crt->signature;
+ sig_algo = ECDSA_P521_SIGN_ALGORITHM;
+ sig_size = sizeof(s_crt->signature);
+ tbs_size = offsetof(certificate_p521_p521_t, signature);
+ body_size = sizeof(certificate_p521_p521_t);
+ ext = (uint8_t *) s_crt->extensions;
+ ext_hash = s_crt->extensions_hash;
+ hash_size = sizeof(s_crt->extensions_hash);
+ hash_algo = ECDSA_P521_HASH_ALGORITHM;
+#else
+ r = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if ((h_crt->key_type == RSA_3072_SHA256) && (h_crt->signature_type == RSA_3072_SHA256)) {
+#ifdef PSA_ADAC_RSA3072
+ certificate_rsa3072_rsa3072_t *s_crt = (certificate_rsa3072_rsa3072_t *) crt;
+ sig = s_crt->signature;
+ sig_algo = RSA_3072_SIGN_ALGORITHM;
+ sig_size = sizeof(s_crt->signature);
+ tbs_size = offsetof(certificate_rsa3072_rsa3072_t, signature);
+ body_size = sizeof(certificate_rsa3072_rsa3072_t);
+ ext = (uint8_t *) s_crt->extensions;
+ ext_hash = s_crt->extensions_hash;
+ hash_size = sizeof(s_crt->extensions_hash);
+ hash_algo = RSA_3072_HASH_ALGORITHM;
+#else
+ r = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if ((h_crt->key_type == RSA_4096_SHA256) && (h_crt->signature_type == RSA_4096_SHA256)) {
+#ifdef PSA_ADAC_RSA4096
+ certificate_rsa4096_rsa4096_t *s_crt = (certificate_rsa4096_rsa4096_t *) crt;
+ sig = s_crt->signature;
+ sig_algo = RSA_4096_SIGN_ALGORITHM;
+ sig_size = sizeof(s_crt->signature);
+ tbs_size = offsetof(certificate_rsa4096_rsa4096_t, signature);
+ body_size = sizeof(certificate_rsa4096_rsa4096_t);
+ ext = (uint8_t *) s_crt->extensions;
+ ext_hash = s_crt->extensions_hash;
+ hash_size = sizeof(s_crt->extensions_hash);
+ hash_algo = RSA_4096_HASH_ALGORITHM;
+#else
+ r = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if ((h_crt->key_type == ED_25519_SHA512) && (h_crt->signature_type == ED_25519_SHA512)) {
+#ifdef PSA_ADAC_ED25519
+ certificate_ed255_ed255_t *s_crt = (certificate_ed255_ed255_t *) crt;
+ sig = s_crt->signature;
+ sig_algo = EDDSA_ED25519_SIGN_ALGORITHM;
+ sig_size = sizeof(s_crt->signature);
+ tbs_size = offsetof(certificate_ed255_ed255_t, signature);
+ body_size = sizeof(certificate_ed255_ed255_t);
+ ext = (uint8_t *) s_crt->extensions;
+ ext_hash = s_crt->extensions_hash;
+ hash_size = sizeof(s_crt->extensions_hash);
+ hash_algo = EDDSA_ED25519_HASH_ALGORITHM;
+ // TODO
+#endif
+ r = PSA_ERROR_NOT_SUPPORTED;
+ } else if ((h_crt->key_type == ED_448_SHAKE256) && (h_crt->signature_type == ED_448_SHAKE256)) {
+#ifdef PSA_ADAC_ED448
+ certificate_ed448_ed448_t *s_crt = (certificate_ed448_ed448_t *) crt;
+ sig = s_crt->signature;
+ sig_algo = EDDSA_ED448_SIGN_ALGORITHM;
+ sig_size = sizeof(s_crt->signature);
+ tbs_size = offsetof(certificate_ed448_ed448_t, signature);
+ body_size = sizeof(certificate_ed448_ed448_t);
+ ext = (uint8_t *) s_crt->extensions;
+ ext_hash = s_crt->extensions_hash;
+ hash_size = sizeof(s_crt->extensions_hash);
+ hash_algo = EDDSA_ED448_HASH_ALGORITHM;
+ // TODO
+#endif
+ r = PSA_ERROR_NOT_SUPPORTED;
+ } else if ((h_crt->key_type == SM_SM2_SM3) && (h_crt->signature_type == SM_SM2_SM3)) {
+#ifdef PSA_ADAC_SM2
+ certificate_sm2sm3_sm2sm3_t *s_crt = (certificate_sm2sm3_sm2sm3_t *) crt;
+ sig = s_crt->signature;
+ sig_algo = SM2_SM3_SIGN_ALGORITHM;
+ sig_size = sizeof(s_crt->signature);
+ tbs_size = offsetof(certificate_sm2sm3_sm2sm3_t, signature);
+ body_size = sizeof(certificate_sm2sm3_sm2sm3_t);
+ ext = (uint8_t *) s_crt->extensions;
+ ext_hash = s_crt->extensions_hash;
+ hash_size = sizeof(s_crt->extensions_hash);
+ hash_algo = SM2_SM3_HASH_ALGORITHM;
+ // TODO
+#endif
+ r = PSA_ERROR_NOT_SUPPORTED;
+ } else if ((h_crt->key_type == CMAC_AES) && (h_crt->signature_type == CMAC_AES)) {
+#ifdef PSA_ADAC_CMAC
+ certificate_cmac_cmac_t *s_crt = (certificate_cmac_cmac_t *) crt;
+ sig = s_crt->signature;
+ sig_algo = CMAC_SIGN_ALGORITHM;
+ sig_size = sizeof(s_crt->signature);
+ tbs_size = offsetof(certificate_cmac_cmac_t, signature);
+ body_size = sizeof(certificate_cmac_cmac_t);
+ ext = (uint8_t *) s_crt->extensions;
+ ext_hash = s_crt->extensions_hash;
+ hash_size = sizeof(s_crt->extensions_hash);
+ hash_algo = CMAC_HASH_ALGORITHM;
+#else
+ r = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if ((h_crt->key_type == HMAC_SHA256) && (h_crt->signature_type == HMAC_SHA256)) {
+#ifdef PSA_ADAC_HMAC
+ certificate_hmac_hmac_t *s_crt = (certificate_hmac_hmac_t *) crt;
+ sig = s_crt->signature;
+ sig_algo = HMAC_SIGN_ALGORITHM;
+ sig_size = sizeof(s_crt->signature);
+ tbs_size = offsetof(certificate_hmac_hmac_t, signature);
+ body_size = sizeof(certificate_hmac_hmac_t);
+ ext = (uint8_t *) s_crt->extensions;
+ ext_hash = s_crt->extensions_hash;
+ hash_size = sizeof(s_crt->extensions_hash);
+ hash_algo = HMAC_HASH_ALGORITHM;
+#else
+ r = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else {
+ PSA_ADAC_LOG_ERR("crt", "Unsupported certificate type\n");
+ r = PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ if (PSA_SUCCESS == r) {
+ size_t exts_size = ROUND_TO_WORD(h_crt->extensions_bytes);
+ if (exts_size > 0UL) {
+ if ((body_size + exts_size) != crt_size) {
+ // Inconsistent size
+ r = PSA_ERROR_INVALID_ARGUMENT;
+ } else {
+ r = psa_adac_certificate_verify_extensions(ext, exts_size, hash_algo, key_type,
+ key, key_size, ext_hash, hash_size);
+ if (r != PSA_SUCCESS) {
+ // Hash does not match
+ }
+ }
+ } else {
+ // TODO: Check all zeros
+ }
+ }
+
+ if (PSA_SUCCESS == r) {
+ PSA_ADAC_LOG_TRACE("crt", "Starting signature verification (%d)\n", sig_size);
+ r = psa_adac_verify_signature(key_type, key, key_size, hash_algo, (const uint8_t **) &crt, &tbs_size, 1,
+ sig_algo, sig, sig_size);
+ PSA_ADAC_LOG_DEBUG("crt", "Signature verification: %s\n", (r == PSA_SUCCESS) ? "success" : "failure");
+ }
+
+ return r;
+}
diff --git a/psa-adac/core/src/adac_crypto.c b/psa-adac/core/src/adac_crypto.c
new file mode 100644
index 0000000..7b0c30b
--- /dev/null
+++ b/psa-adac/core/src/adac_crypto.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <psa_adac_config.h>
+
+#include <psa_adac.h>
+#include <psa_adac_crypto_api.h>
+#include <psa_adac_cryptosystems.h>
+#include <psa_adac_debug.h>
+#include "platform/platform.h"
+
+#include <string.h>
+
+void psa_adac_platform_init();
+
+psa_status_t psa_adac_crypto_init();
+
+psa_status_t psa_adac_init() {
+ static uint8_t psa_adac_init_done = 0;
+ psa_status_t ret = PSA_SUCCESS;
+
+ if (psa_adac_init_done == 0UL) {
+ psa_adac_platform_init();
+ ret = psa_adac_crypto_init();
+ psa_adac_init_done = 1;
+ }
+
+ return ret;
+}
+
+psa_status_t psa_adac_extract_public_key(uint8_t *crt, size_t crt_size, uint8_t *key_type,
+ uint8_t **pubkey, size_t *pubkey_size) {
+ certificate_header_t *header = (certificate_header_t *) crt;
+ size_t ext_bytes = 0;
+ size_t body_size = 0;
+ psa_status_t ret = PSA_SUCCESS;
+
+ if ((crt_size < sizeof(certificate_header_t)) || (key_type == NULL) ||
+ (pubkey == NULL) || (pubkey_size == NULL)) {
+ ret = PSA_ERROR_INVALID_ARGUMENT;
+ } else if ((header->key_type == ECDSA_P256_SHA256) && (header->signature_type == ECDSA_P256_SHA256)) {
+#ifdef PSA_ADAC_EC_P256
+ certificate_p256_p256_t *certificate = (certificate_p256_p256_t *) crt;
+ body_size = sizeof(certificate_p256_p256_t);
+ ext_bytes = certificate->header.extensions_bytes;
+ *pubkey = certificate->pubkey;
+ *pubkey_size = sizeof(certificate->pubkey);
+#else
+ ret = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if ((header->key_type == ECDSA_P521_SHA512) && (header->signature_type == ECDSA_P521_SHA512)) {
+#ifdef PSA_ADAC_EC_P521
+ certificate_p521_p521_t *certificate = (certificate_p521_p521_t *) crt;
+ body_size = sizeof(certificate_p521_p521_t);
+ ext_bytes = certificate->header.extensions_bytes;
+ *pubkey = certificate->pubkey;
+ *pubkey_size = sizeof(certificate->pubkey);
+#else
+ ret = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if ((header->key_type == ED_25519_SHA512) && (header->signature_type == ED_25519_SHA512)) {
+#ifdef PSA_ADAC_ED25519
+ certificate_ed255_ed255_t *certificate = (certificate_ed255_ed255_t *) crt;
+ body_size = sizeof(certificate_ed255_ed255_t);
+ ext_words = certificate->header.extensions_bytes;
+ *pubkey = certificate->pubkey;
+ *pubkey_size = sizeof(certificate->pubkey);
+#else
+ ret = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if ((header->key_type == ED_448_SHAKE256) && (header->signature_type == ED_448_SHAKE256)) {
+#ifdef PSA_ADAC_ED448
+ certificate_ed448_ed448_t *certificate = (certificate_ed448_ed448_t *) crt;
+ body_size = sizeof(certificate_ed448_ed448_t);
+ ext_words = certificate->header.extensions_bytes;
+ *pubkey = certificate->pubkey;
+ *pubkey_size = sizeof(certificate->pubkey);
+#else
+ ret = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if ((header->key_type == RSA_3072_SHA256) && (header->signature_type == RSA_3072_SHA256)) {
+#ifdef PSA_ADAC_RSA3072
+ certificate_rsa3072_rsa3072_t *certificate = (certificate_rsa3072_rsa3072_t *) crt;
+ body_size = sizeof(certificate_rsa3072_rsa3072_t);
+ ext_bytes = certificate->header.extensions_bytes;
+ *pubkey = certificate->pubkey;
+ *pubkey_size = sizeof(certificate->pubkey);
+#else
+ ret = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if ((header->key_type == RSA_4096_SHA256) && (header->signature_type == RSA_4096_SHA256)) {
+#ifdef PSA_ADAC_RSA4096
+ certificate_rsa4096_rsa4096_t *certificate = (certificate_rsa4096_rsa4096_t *) crt;
+ body_size = sizeof(certificate_rsa4096_rsa4096_t);
+ ext_bytes = certificate->header.extensions_bytes;
+ *pubkey = certificate->pubkey;
+ *pubkey_size = sizeof(certificate->pubkey);
+#else
+ ret = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else {
+ ret = PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ if (PSA_SUCCESS == ret) {
+ *key_type = header->key_type;
+
+ if ((ROUND_TO_WORD(ext_bytes) + body_size) != crt_size) {
+ PSA_ADAC_LOG_ERR("crypto", "Inconsistent certificate size\n");
+ // Inconsistent certificate size
+ ret = PSA_ERROR_INVALID_ARGUMENT;
+ }
+ }
+
+ return ret;
+}
+
+psa_status_t psa_adac_verify_certificate_rotpk(uint8_t *crt, size_t crt_size, psa_algorithm_t alg,
+ uint8_t **rotpk, size_t *rotpk_size, size_t rotpk_count) {
+ size_t pubkey_size;
+ uint8_t key_type;
+ uint8_t *pubkey = NULL;
+
+ psa_status_t ret = psa_adac_extract_public_key(crt, crt_size, &key_type, &pubkey, &pubkey_size);
+ if (ret == PSA_SUCCESS) {
+ ret = psa_adac_hash_verify_multiple(alg, pubkey, pubkey_size, rotpk, rotpk_size, rotpk_count);
+ }
+
+ PSA_ADAC_LOG_TRACE("auth_rotpk", "ROTPK Certificate verification %s\n",
+ (ret == PSA_SUCCESS) ? "successful" : "failed");
+ return ret;
+}
+
+psa_status_t psa_adac_context_load_key(validation_context_t *context, uint8_t key_type, uint8_t *key, size_t key_size) {
+ psa_status_t ret = PSA_ERROR_INSUFFICIENT_MEMORY;
+ if (context->max >= key_size) {
+ (void) memcpy(context->content, key, key_size);
+ context->key_type = key_type;
+ context->size = key_size;
+ ret = PSA_SUCCESS;
+ }
+ return ret;
+}
+
+psa_status_t psa_adac_update_context(uint8_t *crt, size_t crt_size, validation_context_t *ctx) {
+ psa_status_t ret;
+
+ if ((ctx->key_type == CMAC_AES) || (ctx->key_type == HMAC_SHA256)) {
+#if defined(PSA_ADAC_CMAC) || defined(PSA_ADAC_HMAC)
+ ret = psa_adac_derive_key(crt, crt_size, ctx->key_type, ctx->content, ctx->size);
+#else
+ ret = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else {
+ size_t key_size;
+ uint8_t key_type;
+ uint8_t *key = NULL;
+
+ ret = psa_adac_extract_public_key(crt, crt_size, &key_type, &key, &key_size);
+ if (PSA_SUCCESS == ret) {
+ ret = psa_adac_context_load_key(ctx, key_type, key, key_size);
+ }
+ }
+
+ return ret;
+}
diff --git a/psa-adac/core/src/adac_crypto.h b/psa-adac/core/src/adac_crypto.h
new file mode 100644
index 0000000..7b594d2
--- /dev/null
+++ b/psa-adac/core/src/adac_crypto.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PSA_ADAC_CRYPTO_H
+#define PSA_ADAC_CRYPTO_H
+
+#include <psa/crypto.h>
+
+psa_status_t load_rsa_3072_public_key(uint8_t *key, size_t key_size, psa_key_handle_t *handle);
+psa_status_t load_rsa_4096_public_key(uint8_t *key, size_t key_size, psa_key_handle_t *handle);
+psa_status_t load_ecdsa_p256_public_key(uint8_t *key, size_t key_size, psa_key_handle_t *handle);
+psa_status_t load_ecdsa_p521_public_key(uint8_t *key, size_t key_size, psa_key_handle_t *handle);
+
+#endif // PSA_ADAC_CRYPTO_H
diff --git a/psa-adac/core/src/adac_token.c b/psa-adac/core/src/adac_token.c
new file mode 100755
index 0000000..e5c1df0
--- /dev/null
+++ b/psa-adac/core/src/adac_token.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <psa_adac_config.h>
+
+#include <psa_adac.h>
+#include <psa_adac_crypto_api.h>
+#include <psa_adac_cryptosystems.h>
+#include <psa_adac_debug.h>
+
+#include <stdlib.h>
+
+psa_status_t psa_adac_token_verify_info(uint8_t token[], size_t token_size, uint8_t **sig, size_t *sig_size,
+ size_t *tbs_size, size_t *body_size, psa_algorithm_t *hash_algo,
+ psa_algorithm_t *sig_algo) {
+ token_header_t *header = (token_header_t *) token;
+ size_t ext_hash_size = 0;
+ size_t _body_size = 0;
+ size_t _tbs_size = 0;
+ size_t _sig_size = 0;
+ psa_algorithm_t _hash_algo = 0;
+ psa_algorithm_t _sig_algo = 0;
+ uint8_t *exts = NULL;
+ uint8_t *ext_hash = NULL;
+ uint8_t *_sig = NULL;
+ psa_status_t ret = PSA_SUCCESS;
+
+ if (header->signature_type == ECDSA_P256_SHA256) {
+#ifdef PSA_ADAC_EC_P256
+ token_p256_t *_token = (token_p256_t *) token;
+ _body_size = sizeof(token_p256_t);
+ _tbs_size = offsetof(token_p256_t, signature);
+ _sig_size = sizeof(_token->signature);
+ _sig = _token->signature;
+ _hash_algo = ECDSA_P256_HASH_ALGORITHM;
+ _sig_algo = ECDSA_P256_SIGN_ALGORITHM;
+ ext_hash_size = sizeof(_token->extensions_hash);
+ ext_hash = _token->extensions_hash;
+ exts = (uint8_t *) _token->extensions;
+#else
+ ret = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if (header->signature_type == ECDSA_P521_SHA512) {
+#ifdef PSA_ADAC_EC_P521
+ token_p521_t *_token = (token_p521_t *) token;
+ _body_size = sizeof(token_p521_t);
+ _tbs_size = offsetof(token_p521_t, signature);
+ _sig_size = sizeof(_token->signature);
+ _sig = _token->signature;
+ _hash_algo = ECDSA_P521_HASH_ALGORITHM;
+ _sig_algo = ECDSA_P521_SIGN_ALGORITHM;
+ ext_hash_size = sizeof(_token->extensions_hash);
+ ext_hash = _token->extensions_hash;
+ exts = (uint8_t *) _token->extensions;
+#else
+ ret = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if (header->signature_type == RSA_3072_SHA256) {
+#ifdef PSA_ADAC_RSA3072
+ token_rsa3072_t *_token = (token_rsa3072_t *) token;
+ _body_size = sizeof(token_rsa3072_t);
+ _tbs_size = offsetof(token_rsa3072_t, signature);
+ _sig_size = sizeof(_token->signature);
+ _sig = _token->signature;
+ _hash_algo = RSA_3072_HASH_ALGORITHM;
+ _sig_algo = RSA_3072_SIGN_ALGORITHM;
+ ext_hash_size = sizeof(_token->extensions_hash);
+ ext_hash = _token->extensions_hash;
+ exts = (uint8_t *) _token->extensions;
+#else
+ ret = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if (header->signature_type == RSA_4096_SHA256) {
+#ifdef PSA_ADAC_RSA4096
+ token_rsa4096_t *_token = (token_rsa4096_t *) token;
+ _body_size = sizeof(token_rsa4096_t);
+ _tbs_size = offsetof(token_rsa4096_t, signature);
+ _sig_size = sizeof(_token->signature);
+ _sig = _token->signature;
+ _hash_algo = RSA_4096_HASH_ALGORITHM;
+ _sig_algo = RSA_4096_SIGN_ALGORITHM;
+ ext_hash_size = sizeof(_token->extensions_hash);
+ ext_hash = _token->extensions_hash;
+ exts = (uint8_t *) _token->extensions;
+#else
+ ret = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if (header->signature_type == ED_25519_SHA512) {
+#ifdef PSA_ADAC_ED25519
+ // TODO
+ token_ed255_t *_token = (token_ed255_t *) token;
+ _body_size = sizeof(token_ed255_t);
+ _tbs_size = offsetof(token_ed255_t, signature);
+ _sig_size = sizeof(_token->signature);
+ _sig = _token->signature;
+ _hash_algo = EDDSA_ED25519_HASH_ALGORITHM;
+ ext_hash_size = sizeof(_token->extensions_hash);
+ ext_hash = _token->extensions_hash;
+ exts = (uint8_t *) _token->extensions;
+#else
+ ret = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if (header->signature_type == ED_448_SHAKE256) {
+#ifdef PSA_ADAC_ED448
+ // TODO
+ token_ed448_t *_token = (token_ed448_t *) token;
+ _body_size = sizeof(token_ed448_t);
+ _tbs_size = offsetof(token_ed448_t, signature);
+ _sig_size = sizeof(_token->signature);
+ _sig = _token->signature;
+ _hash_algo = EDDSA_ED448_HASH_ALGORITHM;
+ ext_hash_size = sizeof(_token->extensions_hash);
+ ext_hash = _token->extensions_hash;
+ exts = (uint8_t *) _token->extensions;
+#else
+ ret = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if (header->signature_type == SM_SM2_SM3) {
+#ifdef PSA_ADAC_SM2
+ // TODO
+ token_sm2sm3_t *_token = (token_sm2sm3_t *) token;
+ _body_size = sizeof(token_sm2sm3_t);
+ _tbs_size = offsetof(token_sm2sm3_t, signature);
+ _sig_size = sizeof(_token->signature);
+ _sig = _token->signature;
+ _hash_algo = SM2_SM3_HASH_ALGORITHM;
+ _sig_algo = SM2_SM3_SIGN_ALGORITHM;
+ ext_hash_size = sizeof(_token->extensions_hash);
+ ext_hash = _token->extensions_hash;
+ exts = (uint8_t *) _token->extensions;
+#else
+ ret = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if (header->signature_type == CMAC_AES) {
+#ifdef PSA_ADAC_CMAC
+ token_cmac_t *_token = (token_cmac_t *) token;
+ _body_size = sizeof(token_cmac_t);
+ _tbs_size = offsetof(token_cmac_t, signature);
+ _sig_size = sizeof(_token->signature);
+ _sig = _token->signature;
+ _hash_algo = CMAC_HASH_ALGORITHM;
+ _sig_algo = CMAC_SIGN_ALGORITHM;
+ ext_hash_size = sizeof(_token->extensions_hash);
+ ext_hash = _token->extensions_hash;
+ exts = (uint8_t *) _token->extensions;
+#else
+ ret = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else if (header->signature_type == HMAC_SHA256) {
+#ifdef PSA_ADAC_HMAC
+ token_hmac_t *_token = (token_hmac_t *) token;
+ _body_size = sizeof(token_hmac_t);
+ _tbs_size = offsetof(token_hmac_t, signature);
+ _sig_size = sizeof(_token->signature);
+ _sig = _token->signature;
+ _hash_algo = HMAC_HASH_ALGORITHM;
+ _sig_algo = HMAC_SIGN_ALGORITHM;
+ ext_hash_size = sizeof(_token->extensions_hash);
+ ext_hash = _token->extensions_hash;
+ exts = (uint8_t *) _token->extensions;
+#else
+ ret = PSA_ERROR_NOT_SUPPORTED;
+#endif
+ } else {
+ ret = PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ if (PSA_SUCCESS == ret) {
+ size_t exts_size = ROUND_TO_WORD(header->extensions_bytes);
+ if ((_body_size + exts_size) != token_size) {
+ PSA_ADAC_LOG_ERR("token", "Size inconsistency %zu + %zu != %zu\n", _body_size, exts_size, token_size);
+ ret = PSA_ERROR_INVALID_ARGUMENT;
+ } else {
+ if (exts_size > 0UL) {
+ // FIXME: PSA_ALG_CMAC
+ if (psa_adac_hash_verify(_hash_algo, exts, exts_size, ext_hash, ext_hash_size) != PSA_SUCCESS) {
+ PSA_ADAC_LOG_ERR("token", "Token extension hash does not match\n");
+ ret = PSA_ERROR_INVALID_SIGNATURE;
+ } else {
+ // FIXME: Check for 0s
+ }
+ }
+ }
+ }
+
+ if (PSA_SUCCESS == ret) {
+ *body_size = _body_size;
+ *hash_algo = _hash_algo;
+ *sig_algo = _sig_algo;
+ *sig_size = _sig_size;
+ *tbs_size = _tbs_size;
+ *sig = _sig;
+ }
+
+ return ret;
+}
+
+psa_status_t psa_adac_verify_token_signature(uint8_t *token, size_t token_size, uint8_t *challenge,
+ size_t challenge_size, uint8_t key_type, uint8_t *key, size_t key_size) {
+ uint8_t *sig;
+ size_t sig_size;
+ size_t body_size;
+ size_t tbs_size;
+ psa_algorithm_t hash_algo;
+ psa_algorithm_t sig_algo;
+
+ psa_status_t ret = psa_adac_token_verify_info(token, token_size, &sig, &sig_size, &tbs_size,
+ &body_size, &hash_algo, &sig_algo);
+
+ if (ret != PSA_SUCCESS) {
+ PSA_ADAC_LOG_ERR("token", "Unsupported token signature format\n");
+ } else {
+ const uint8_t *parts[2] = {(uint8_t *) token, challenge};
+ size_t part_sizes[2] = {tbs_size, challenge_size};
+ ret = psa_adac_verify_signature(key_type, key, key_size, hash_algo, parts, part_sizes, 2,
+ sig_algo, sig, sig_size);
+ }
+
+ PSA_ADAC_LOG_DEBUG("token", "Signature verification (%d): %s\n", ret, (ret == PSA_SUCCESS) ? "success" : "failure");
+
+ return ret;
+}
diff --git a/psa-adac/sda/CMakeLists.txt b/psa-adac/sda/CMakeLists.txt
new file mode 100644
index 0000000..e1d21fc
--- /dev/null
+++ b/psa-adac/sda/CMakeLists.txt
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2020 Arm Limited. All rights reserved.
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+add_library(psa_adac_sda STATIC)
+
+target_include_directories(psa_adac_sda
+ PUBLIC
+ ${PSA_ADAC_ROOT}/psa-adac/sda/include
+ PRIVATE
+ ${PSA_ADAC_MBEDTLS_INCLUDE}
+
+)
+
+list(APPEND PSA_ADAC_SDA_SRC
+ ${PSA_ADAC_ROOT}/psa-adac/sda/src/psa_adac_sda.c
+)
+
+target_sources(psa_adac_sda
+ PUBLIC
+ ${PSA_ADAC_SDA_SRC}
+)
+
+target_link_libraries(psa_adac_sda
+ PRIVATE
+ psa_adac_core
+ ${PROJECT_NAME}
+)
+
+install(DIRECTORY
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/
+ DESTINATION ${PSA_ADAC_INSTALL_PATH}/include
+)
diff --git a/psa-adac/sda/adac_sda.dox b/psa-adac/sda/adac_sda.dox
new file mode 100644
index 0000000..056d287
--- /dev/null
+++ b/psa-adac/sda/adac_sda.dox
@@ -0,0 +1,7 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/** \defgroup adac-sda ADAC Secure Debug Authenticator
+ */
diff --git a/psa-adac/sda/include/psa_adac_sda.h b/psa-adac/sda/include/psa_adac_sda.h
new file mode 100644
index 0000000..1184502
--- /dev/null
+++ b/psa-adac/sda/include/psa_adac_sda.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PSA_ADAC_SDA_H
+#define PSA_ADAC_SDA_H
+
+#include <psa/crypto.h>
+#include <psa_adac.h>
+
+/** \addtogroup adac-sda
+ * @{
+ */
+
+typedef struct {
+ psa_algorithm_t rotpk_algo;
+ uint8_t **rotpk;
+ size_t *rotpk_size;
+ uint8_t *rotpk_type;
+ size_t rotpk_count;
+} rotpk_context_t;
+
+typedef enum {
+ AUTH_INIT,
+ AUTH_CHALLENGE,
+ AUTH_ROT_META,
+ AUTH_ROOT,
+ AUTH_CHAIN,
+ AUTH_LEAF,
+ AUTH_TOKEN,
+ AUTH_SUCCESS,
+ AUTH_FAILURE
+} authentication_state_t;
+
+#include <platform/msg_interface.h>
+
+typedef struct {
+ uint8_t permissions_mask[16];
+ psa_auth_challenge_t challenge;
+ rotpk_context_t rotpk_ctx;
+ validation_context_t context;
+ authentication_state_t state;
+#ifndef PSA_ADAC_AUTHENTICATOR_IMPLICIT_TRANSPORT
+ target_msg_interface_t msg_interface;
+ void *msg_ctx;
+#endif
+} authentication_context_t;
+
+/** \brief Initialize authentication context
+ */
+void authentication_context_init(authentication_context_t *auth_ctx, uint8_t *buffer, size_t size,
+ psa_algorithm_t rotpk_algo, uint8_t **rotpk, size_t *rotpk_size,
+ uint8_t *rotpk_type, size_t rotpk_count);
+
+/**
+ */
+response_packet_t *authentication_discovery(authentication_context_t *auth_ctx, request_packet_t *request);
+
+/**
+ */
+response_packet_t *authentication_start(authentication_context_t *auth_ctx, request_packet_t *request);
+
+/**
+ */
+response_packet_t *authentication_response(authentication_context_t *auth_ctx, request_packet_t *request);
+
+#ifndef PSA_ADAC_AUTHENTICATOR_IMPLICIT_TRANSPORT
+void authentication_context_set_transport(authentication_context_t *auth_ctx,
+ target_msg_interface_t msg_interface, void *msg_ctx);
+#endif
+
+/**
+ */
+int authentication_handle(authentication_context_t *auth_ctx);
+
+/**@}*/
+
+#endif //PSA_ADAC_SDA_H
diff --git a/psa-adac/sda/src/psa_adac_sda.c b/psa-adac/sda/src/psa_adac_sda.c
new file mode 100644
index 0000000..06f7c70
--- /dev/null
+++ b/psa-adac/sda/src/psa_adac_sda.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <psa_adac_sda.h>
+#include <platform/msg_interface.h>
+
+#include <psa_adac.h>
+#include <psa_adac_crypto_api.h>
+#include <psa_adac_cryptosystems.h>
+#include <psa_adac_debug.h>
+
+#include <string.h>
+
+#ifdef PSA_ADAC_AUTHENTICATOR_IMPLICIT_TRANSPORT
+
+static inline request_packet_t *authenticator_request_packet_receive(authentication_context_t *auth_ctx) {
+ (void) auth_ctx; // misra-c2012-2.7
+ return request_packet_receive();
+}
+
+static inline int authenticator_request_packet_release(authentication_context_t *auth_ctx, request_packet_t *packet) {
+ (void) auth_ctx; // misra-c2012-2.7
+ return request_packet_release(packet);
+}
+
+static inline int authenticator_response_packet_release(authentication_context_t *auth_ctx, response_packet_t *packet) {
+ (void) auth_ctx; // misra-c2012-2.7
+ return response_packet_release(packet);
+}
+
+static inline response_packet_t *authenticator_response_packet_build(authentication_context_t *auth_ctx,
+ uint16_t status, uint8_t *data, size_t data_size) {
+ (void) auth_ctx; // misra-c2012-2.7
+ return response_packet_build(status, data, data_size);
+}
+
+static inline response_packet_t *authenticator_response_packet_lock(authentication_context_t *auth_ctx,
+ size_t *max_data_size) {
+ (void) auth_ctx; // misra-c2012-2.7
+ return response_packet_lock(max_data_size);
+}
+
+static inline int authenticator_response_packet_send(authentication_context_t *auth_ctx, response_packet_t *packet) {
+ (void) auth_ctx; // misra-c2012-2.7
+ return response_packet_send(packet);
+}
+
+#endif
+
+int authenticator_send_response(authentication_context_t *auth_ctx, response_packet_t *response) {
+ int r = 1;
+ if (response != NULL) {
+ if (authenticator_response_packet_send(auth_ctx, response) == 0) {
+ r = 0;
+ }
+ (void) authenticator_response_packet_release(auth_ctx, response);
+ }
+ return r;
+}
+
+response_packet_t *authentication_discovery(authentication_context_t *auth_ctx, request_packet_t *request) {
+ (void) authenticator_request_packet_release(auth_ctx, request);
+ PSA_ADAC_LOG_DEBUG("auth", "Discovery\n");
+
+ size_t max = 0;
+ response_packet_t *r = authenticator_response_packet_lock(auth_ctx, &max);
+ if (r != NULL) {
+ size_t size = psa_adac_platform_discovery((uint8_t *) r->data, max);
+ while (((size % 4UL) != 0UL) && (size < max)) {
+ ((uint8_t *) r->data)[size] = 0x0;
+ size += 1UL;
+ }
+ r->data_count = size >> 2;
+ r->status = 0x0;
+ }
+ return r;
+}
+
+response_packet_t *authentication_start(authentication_context_t *auth_ctx, request_packet_t *request) {
+ (void) authenticator_request_packet_release(auth_ctx, request);
+ PSA_ADAC_LOG_DEBUG("auth", "Starting authentication\n");
+ auth_ctx->state = AUTH_CHALLENGE;
+
+ PSA_ADAC_LOG_DEBUG("auth", "Generating challenge (%d)\n", CHALLENGE_SIZE);
+ auth_ctx->challenge.format_version.major = 0x01;
+ auth_ctx->challenge.format_version.minor = 0x00;
+ auth_ctx->challenge._reserved = 0x00;
+ psa_adac_generate_challenge(auth_ctx->challenge.challenge_vector, sizeof(auth_ctx->challenge.challenge_vector));
+ response_packet_t *response = authenticator_response_packet_build(auth_ctx, 0x0, (uint8_t *) &auth_ctx->challenge,
+ sizeof(auth_ctx->challenge));
+ return response;
+}
+
+int is_hashed_rotpk_entry(uint8_t key_type, psa_algorithm_t algo, size_t rotpk_size) {
+ int ret = 1;
+ if ((key_type == CMAC_AES) || (key_type == HMAC_SHA256)) {
+ ret = 0;
+ }
+
+ if (algo == PSA_ALG_SHA_256) {
+ if (rotpk_size != 32UL) {
+ ret = 0;
+ }
+ }
+ /* TODO: PSA_HASH_SIZE remove in mbedtls new version
+ {
+ if (rotpk_size != PSA_HASH_SIZE(algo)) {
+ ret = 0;
+ }
+ }
+ */
+
+ return ret;
+}
+
+psa_status_t psa_adac_certificate_check(uint8_t *crt, size_t crt_size, rotpk_context_t *rotpk_ctx,
+ validation_context_t *context, int is_root) {
+ certificate_header_t *header = (certificate_header_t *) crt;
+ psa_status_t r = psa_adac_certificate_sanity_check(crt, crt_size);
+
+ if (PSA_SUCCESS != r) {
+ // Certificate failed sanity check
+ } else if (is_root != 0) {
+ int found = 0;
+ for (int i = 0; (i < rotpk_ctx->rotpk_count) && (!found); i++) {
+ if ((rotpk_ctx->rotpk_type[i] != header->key_type) ||
+ (rotpk_ctx->rotpk_type[i] != header->signature_type)) {
+ continue;
+ }
+ if (is_hashed_rotpk_entry(rotpk_ctx->rotpk_type[i], rotpk_ctx->rotpk_algo, rotpk_ctx->rotpk_size[i]) != 0) {
+ size_t pubkey_size;
+ uint8_t key_type;
+ uint8_t *pubkey = NULL;
+
+ if ((PSA_SUCCESS != psa_adac_extract_public_key(crt, crt_size, &key_type, &pubkey, &pubkey_size)) ||
+ (PSA_SUCCESS != psa_adac_hash_verify(rotpk_ctx->rotpk_algo, pubkey, pubkey_size,
+ rotpk_ctx->rotpk[i], rotpk_ctx->rotpk_size[i])) ||
+ (PSA_SUCCESS != psa_adac_context_load_key(context, key_type, pubkey, pubkey_size)) ||
+ (PSA_SUCCESS != psa_adac_certificate_verify_sig(crt, crt_size, context->key_type,
+ context->content, context->size))) {
+ continue;
+ }
+ found = 1;
+ } else {
+ if ((PSA_SUCCESS != psa_adac_context_load_key(context, rotpk_ctx->rotpk_type[i], rotpk_ctx->rotpk[i],
+ rotpk_ctx->rotpk_size[i])) ||
+ (PSA_SUCCESS != psa_adac_certificate_verify_sig(crt, crt_size, context->key_type,
+ context->content, context->size)) ||
+ (PSA_SUCCESS != psa_adac_update_context(crt, crt_size, context))) {
+ continue;
+ }
+ found = 1;
+ }
+ }
+
+ r = found ? PSA_SUCCESS : PSA_ERROR_DOES_NOT_EXIST;
+ } else {
+ r = psa_adac_certificate_verify_sig(crt, crt_size, context->key_type,
+ context->content, context->size);
+ if (PSA_SUCCESS == r) {
+ r = psa_adac_update_context(crt, crt_size, context);
+ }
+ }
+
+ return r;
+}
+
+psa_status_t certificate_check(authentication_context_t *ctx, uint8_t *crt, size_t crt_size, int is_root) {
+ psa_status_t r = psa_adac_certificate_check(crt, crt_size, &(ctx->rotpk_ctx), &(ctx->context), is_root);
+ if (PSA_SUCCESS != r) {
+ PSA_ADAC_LOG_ERR("auth", "Error validating %s\n", is_root ? "root certificate" : "certificate");
+ } else {
+ r = psa_adac_platform_check_certificate(crt, crt_size);
+ if (PSA_SUCCESS != r) {
+ PSA_ADAC_LOG_ERR("auth", "Certificate rejected by platform\n");
+ }
+ }
+
+ return r;
+}
+
+psa_status_t authentication_crt(authentication_context_t *auth_ctx, uint8_t *crt, size_t crt_size) {
+ psa_status_t r = SDP_FAILURE;
+ certificate_header_t *header = (certificate_header_t *) crt;
+
+ if (header->role == SDP_CRT_ROLE_ROOT) {
+ if ((auth_ctx->state != AUTH_CHALLENGE) && (auth_ctx->state != AUTH_ROT_META)) {
+ PSA_ADAC_LOG_ERR("auth", "State inconsistent with receiving a root certificate\n");
+
+ } else if (PSA_SUCCESS == certificate_check(auth_ctx, crt, crt_size, 1)) {
+ auth_ctx->state = AUTH_ROOT;
+ r = SDP_NEED_MORE_DATA;
+
+ for (size_t i = 0; i < sizeof(auth_ctx->permissions_mask); i++) {
+ auth_ctx->permissions_mask[i] &= header->permissions_mask[i];
+ }
+ } else {
+ r = SDP_FAILURE; /* [misra-c2012-15.7] */
+ }
+ } else if ((header->role == SDP_CRT_ROLE_INT) || (header->role == SDP_CRT_ROLE_LEAF)) {
+ if ((auth_ctx->state != AUTH_ROOT) && (auth_ctx->state != AUTH_CHAIN)) {
+ PSA_ADAC_LOG_ERR("auth", "State inconsistent with receiving an intermediate or leaf certificate\n");
+ } else if (PSA_SUCCESS == certificate_check(auth_ctx, crt, crt_size, 0)) {
+ auth_ctx->state = (header->role == SDP_CRT_ROLE_INT) ? AUTH_CHAIN : AUTH_LEAF;
+ r = SDP_NEED_MORE_DATA;
+
+ for (size_t i = 0; i < sizeof(auth_ctx->permissions_mask); i++) {
+ auth_ctx->permissions_mask[i] &= header->permissions_mask[i];
+ }
+ } else {
+ r = SDP_FAILURE; /* [misra-c2012-15.7] */
+ }
+ } else {
+ PSA_ADAC_LOG_ERR("auth_crt", "Inconsistent certificate role\n");
+ }
+
+ if (r == SDP_FAILURE) {
+ PSA_ADAC_LOG_ERR("auth_crt", "Authentication failure\n");
+ auth_ctx->state = AUTH_FAILURE;
+ }
+ return r;
+}
+
+psa_status_t authentication_token(authentication_context_t *auth_ctx, uint8_t *token, size_t token_size) {
+ size_t sig_size;
+ size_t body_size;
+ size_t tbs_size;
+ psa_algorithm_t hash_algo;
+ psa_algorithm_t sig_algo;
+ psa_status_t r = SDP_FAILURE;
+ uint8_t *sig;
+
+ if ((auth_ctx->state != AUTH_ROOT) && (auth_ctx->state != AUTH_LEAF)) {
+ PSA_ADAC_LOG_ERR("auth", "State inconsistent with receiving a token\n");
+ } else if (PSA_SUCCESS != psa_adac_token_verify_info(token, token_size, &sig, &sig_size, &tbs_size,
+ &body_size, &hash_algo, &sig_algo)) {
+ PSA_ADAC_LOG_ERR("auth", "Error checking token\n");
+ } else if (PSA_SUCCESS != psa_adac_platform_check_token(token, token_size)) {
+ PSA_ADAC_LOG_ERR("auth", "Token rejected by platform\n");
+ } else if (PSA_SUCCESS !=
+ psa_adac_verify_token_signature(token, token_size, auth_ctx->challenge.challenge_vector,
+ sizeof(auth_ctx->challenge.challenge_vector),
+ auth_ctx->context.key_type, auth_ctx->context.content,
+ auth_ctx->context.size)) {
+ PSA_ADAC_LOG_ERR("auth", "Invalid token signature\n");
+ } else {
+ PSA_ADAC_LOG_INFO("auth", "Authentication successful\n");
+ token_header_t *header = (token_header_t *) token;
+ for (size_t i = 0; i < sizeof(auth_ctx->permissions_mask); i++) {
+ auth_ctx->permissions_mask[i] &= header->requested_permissions[i];
+ }
+
+ // Should it be allowed to fail?
+ psa_adac_apply_permissions(auth_ctx->permissions_mask);
+
+ r = SDP_SUCCESS;
+ auth_ctx->state = AUTH_SUCCESS;
+ }
+
+ if (r == SDP_FAILURE) {
+ auth_ctx->state = AUTH_FAILURE;
+ }
+ return r;
+}
+
+response_packet_t *authentication_response(authentication_context_t *auth_ctx, request_packet_t *request) {
+ PSA_ADAC_LOG_DEBUG("auth", "Received Authentication Response (%d)\n", request->data_count * 4);
+ psa_tlv_t *fragment = (psa_tlv_t *) &request->data;
+ psa_status_t r = SDP_FAILURE;
+
+ if ((request->data_count < 1) || (((request->data_count * 4) - 4) < fragment->length_in_bytes)) {
+ auth_ctx->state = AUTH_FAILURE;
+ } else if (fragment->type_id == PSA_BINARY_CRT) { // TODO: Add support for RoT Metadata fragment
+ if ((auth_ctx->state != AUTH_CHALLENGE) && (auth_ctx->state != AUTH_ROT_META) &&
+ (auth_ctx->state != AUTH_ROOT) && (auth_ctx->state != AUTH_CHAIN)) {
+ auth_ctx->state = AUTH_FAILURE;
+ PSA_ADAC_LOG_DEBUG("auth", "State inconsistent with receiving a certificate\n");
+ } else if (fragment->length_in_bytes <= sizeof(certificate_header_t)) {
+ auth_ctx->state = AUTH_FAILURE;
+ PSA_ADAC_LOG_DEBUG("auth", "Size inconsistent with certificate\n");
+ } else {
+ PSA_ADAC_LOG_TRACE("auth", "Received a certificate\n");
+ r = authentication_crt(auth_ctx, fragment->value, fragment->length_in_bytes);
+ }
+ } else if (fragment->type_id == PSA_BINARY_TOKEN) {
+ if ((auth_ctx->state != AUTH_ROOT) && (auth_ctx->state != AUTH_LEAF)) {
+ PSA_ADAC_LOG_DEBUG("auth", "State inconsistent with receiving a token\n");
+ } else if (fragment->length_in_bytes <= sizeof(token_header_t)) {
+ auth_ctx->state = AUTH_FAILURE;
+ PSA_ADAC_LOG_DEBUG("auth", "Size inconsistent with token\n");
+ } else {
+ PSA_ADAC_LOG_TRACE("auth", "Received a token\n");
+ r = authentication_token(auth_ctx, fragment->value, fragment->length_in_bytes);
+ }
+ } else {
+ PSA_ADAC_LOG_WARN("auth", "Received neither a certificate nor a token\n");
+ }
+
+ (void) authenticator_request_packet_release(auth_ctx, request);
+ return authenticator_response_packet_build(auth_ctx, r, NULL, 0);
+}
+
+void authentication_context_init(authentication_context_t *auth_ctx, uint8_t *buffer, size_t size,
+ psa_algorithm_t rotpk_algo, uint8_t **rotpk, size_t *rotpk_size,
+ uint8_t *rotpk_type, size_t rotpk_count) {
+ for (size_t i = 0UL; i < sizeof(auth_ctx->permissions_mask); i++) {
+ auth_ctx->permissions_mask[i] = 0xFF;
+ }
+
+ auth_ctx->rotpk_ctx.rotpk = rotpk;
+ auth_ctx->rotpk_ctx.rotpk_algo = rotpk_algo;
+ auth_ctx->rotpk_ctx.rotpk_size = rotpk_size;
+ auth_ctx->rotpk_ctx.rotpk_type = rotpk_type;
+ auth_ctx->rotpk_ctx.rotpk_count = rotpk_count;
+
+ auth_ctx->context.content = buffer;
+ auth_ctx->context.max = size;
+ auth_ctx->context.size = 0;
+
+ auth_ctx->state = AUTH_INIT;
+}
+
+int authentication_handle(authentication_context_t *auth_ctx) {
+ int done = 0;
+ request_packet_t *request;
+
+ PSA_ADAC_LOG_INFO("auth", "Starting authentication loop\n");
+ while (done == 0) {
+ request = authenticator_request_packet_receive(auth_ctx);
+ if (NULL == request) {
+ break;
+ }
+
+ PSA_ADAC_LOG_DEBUG("auth", "Receiving request %x\n", request->command);
+
+ int ret;
+ response_packet_t *response;
+ switch (request->command) {
+ case SDP_DISCOVERY_CMD:
+ response = authentication_discovery(auth_ctx, request);
+ ret = authenticator_send_response(auth_ctx, response);
+ break;
+
+ case SDP_AUTH_START_CMD:
+ response = authentication_start(auth_ctx, request);
+ ret = authenticator_send_response(auth_ctx, response);
+ break;
+
+ case SDP_AUTH_RESPONSE_CMD:
+ response = authentication_response(auth_ctx, request);
+ ret = authenticator_send_response(auth_ctx, response);
+ break;
+
+ // Send success status but otherwise do nothing.
+ case SDP_LOCK_DEBUG_CMD:
+ PSA_ADAC_LOG_DEBUG("auth", "Lock debug\n");
+ (void) authenticator_request_packet_release(auth_ctx, request);
+ psa_adac_platform_lock();
+ response = authenticator_response_packet_build(auth_ctx, SDP_SUCCESS, NULL, 0);
+ ret = authenticator_send_response(auth_ctx, response);
+ break;
+
+ // Send success status and terminate command loop.
+ case SDP_RESUME_BOOT_CMD:
+ PSA_ADAC_LOG_DEBUG("auth", "Resuming \"boot\"\n");
+ (void) authenticator_request_packet_release(auth_ctx, request);
+ response = authenticator_response_packet_build(auth_ctx, SDP_SUCCESS, NULL, 0);
+ ret = authenticator_send_response(auth_ctx, response);
+ done = 1;
+ break;
+
+ default:
+ PSA_ADAC_LOG_ERR("auth", "Unknown command: %04x\n", request->command);
+ (void) authenticator_request_packet_release(auth_ctx, request);
+ response = authenticator_response_packet_build(auth_ctx, SDP_INVALID_COMMAND, NULL, 0);
+ ret = authenticator_send_response(auth_ctx, response);
+ break;
+ }
+
+ if (ret != 0) {
+ PSA_ADAC_LOG_ERR("auth", "Error sending response: %04x\n", ret);
+ }
+
+ if ((auth_ctx->state == AUTH_SUCCESS) || (auth_ctx->state == AUTH_FAILURE)) {
+ done = 1;
+ }
+ }
+
+ PSA_ADAC_LOG_INFO("auth", "Ending authentication loop\n");
+
+ return done;
+}
diff --git a/readme.rst b/readme.rst
new file mode 100644
index 0000000..aa30eb4
--- /dev/null
+++ b/readme.rst
@@ -0,0 +1,189 @@
+##################################
+Authenticated Debug Access Control
+##################################
+
+************
+Introduction
+************
+
+Introducing security in debug is about making sure that only authorized people
+have access to select parts of firmware and hardware. The Trusted Firmware-M
+software implementation contained in this project is designed to be a
+reference implementation.
+
+ADAC aims at making sure that debug capabilities do not become attack vectors.
+Debug security cannot be an afterthought when designing an SoC and the kind of
+debug solution needed is driven by the threat models for the device use case.
+
+The ADAC architecture is designed to be flexible to meet varying vendor needs,
+adaptable to work with many different hardware and software components, and
+scalable from small embedded or IoT systems to complex server environments.
+At the same time, it strives to be simple and resilient against attack.
+
+`Authenticated Debug Access Control`_ (ADAC).
+
+**********
+Components
+**********
+
+The repository contains software componenets, of the ADAC protocol, towards
+the target side. The following components are included in this repo:
+
+* Secure Debug Authenticator (SDA)
+* ADAC protocol core
+* Supported target platforms
+ * trusted-firmware-m: dipdha platform
+* Transport layer
+ * `SDC-600 Secure Debug Channel`_
+
+********************
+Directory structures
+********************
+
+- psa-adac
+ - core
+ - sda
+- target
+ - target name
+ - files implementing platform interface of psa-adac/core and psa-adac/sda
+ - psa_adac_platform.h: place where platform specific incoming and outgoing calls can be declared
+- transport
+ - files implementing transport interface of psa-adac/core and psa-adac/sda
+ - various implementations of transport layer for communication with the host can be hosted here
+- template_hal_files
+ - template files for hal api definitions
+
+
+************************
+Integration instructions
+************************
+
+Build options
+=============
+
+Build from the adac repository
+----------------------------------
+
+Configure:
+
+.. code-block::
+
+ cmake -B <build_dir> -S . -DCMAKE_BUILD_TYPE=Debug -DPSA_ADAC_TARGET=<target_name> -DPSA_ADAC_MBEDTLS_INCLUDE=<path to mbedtls include>
+
+Build and install:
+
+.. code-block::
+
+ cmake --build <build_dir> -- install
+
+Static library will be installation at:
+
+.. code-block::
+
+ <build_dir>/install/lib/lib_<target_name>.a
+
+Build as cmake target
+---------------------
+
+.. code-block::
+
+ add_subdirectory(${PLATFORM_PSA_ADAC_SOURCE_PATH} ${PLATFORM_PSA_ADAC_BUILD_PATH})
+ target_link_libraries(<target_name>-psa-adac
+ PRIVATE
+ <caller of adac entry point>
+ )
+
+Configuration variables
+=======================
+
+PSA_ADAC_TOOLCHAIN
+------------------
+When OFF, the build will not include toolchain files from the
+adac repository. User can decide to choose the toolchain configuration from the
+adac repository or can also provide its own toolchain configuration files.
+
+PSA_ADAC_TARGET
+---------------
+Name of the target. Support for the target should exist inside
+the ./target/ directory.
+
+PSA_ADAC_MBEDTLS_INCLUDE
+------------------------
+Path to mbedtls include directory (`MBEDTLS Repository`_)
+
+.. code-block::
+
+ <mbedtls>/include
+
+
+HAL integration
+===============
+
+psa-adac/sda and psa-adac/core depends on the following inteface:
+
+platform.h
+----------
+Defines the interface to the platform. A template file for the inteface
+can be found inside template directory.
+
+psa_adac_crypto_api.h
+---------------------
+Defines the interface to the cryptographic supported required
+by the adac protocol implementation.
+
+A target should provide the implementation of these HAL APIs. An example for platform.h
+api implementation can be find inside corstone1000 target directory. And example for
+crypto api implementaion can be find inside `Trusted-Firmware-M`_ repository. Further
+such integration of crypto apis, based on software (ex: mbedtls) as well as based on
+hardware accelerattion, can also be hosted as part of this repository.
+
+msg_interface.h
+---------------
+Defines the interface to the transport layer. The transport layer supports the communication
+between host and the target. The file, msg_interface.h, only contains the interface used
+by the target, i.e. psa-adac/core and psa-adac/sda. Various implementation of transport
+layer can be hosted inside ./trasport/ directory. For ex: corstone1000 uses transport based
+on SDC600 COMPORT.
+
+Integration to the secure debug workflow
+========================================
+
+The entry function definition to start the secure debug flow and any other dependency,
+a target is free to declare such apis inside the file: psa_adac_platform.h
+
+Corstone1000 psa_adac_platform.h is one such example.
+
+
+Target examples
+===============
+
+Build instructions for Corstone1000 platform inside trusted-firmware-m
+----------------------------------------------------------------------
+
+Configure:
+
+.. code-block::
+
+ cmake -B <build_dir> -S . -DCMAKE_BUILD_TYPE=Debug -DPSA_ADAC_TARGET=trusted-firmware-m -DTFM_PLATFORM=arm/corstone1000 -DPSA_ADAC_MBEDTLS_INCLUDE=<mbedtls>/include
+
+Build and install:
+
+.. code-block::
+
+ cmake --build <build_dir> -- install
+
+Build library:
+
+.. code-block::
+
+ build/install/lib/libtrusted-firmware-m-psa-adac.a
+
+The library generated contains secure debug support for Corstone1000 platform
+which can be linked to Corstone1000's trusted-firmware-m build.
+
+.. _Authenticated Debug Access Control: https://developer.arm.com/documentation/den0101/latest
+.. _SDC-600 Secure Debug Channel: https://www.arm.com/products/silicon-ip-system/coresight-debug-trace/sdc-600
+.. _MBEDTLS Repository: https://github.com/ARMmbed/mbedtls.git
+.. _Trusted-Firmware-M : https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git/
+
+*Copyright (c) 2021, Arm Limited. All rights reserved.*
diff --git a/target/trusted-firmware-m/CMakeLists.txt b/target/trusted-firmware-m/CMakeLists.txt
new file mode 100644
index 0000000..4ea1c38
--- /dev/null
+++ b/target/trusted-firmware-m/CMakeLists.txt
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2021 Arm Limited. All rights reserved.
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+target_include_directories(${PROJECT_NAME}
+ PRIVATE
+ ${PSA_ADAC_MBEDTLS_INCLUDE}
+)
+
+set(MBEDTLS_CONFIG_FILE "${CMAKE_CURRENT_SOURCE_DIR}/authenticator-crypto-config.h")
+
+add_compile_options($<$<COMPILE_LANGUAGE:C>:-DMBEDTLS_CONFIG_FILE="${MBEDTLS_CONFIG_FILE}">)
+
+target_compile_definitions(${PROJECT_NAME}
+ PUBLIC
+ TRUSTED_FIRMWARE_M_PSA_ADAC
+)
+
+add_subdirectory(${TFM_PLATFORM_PATH})
diff --git a/target/trusted-firmware-m/authenticator-crypto-config.h b/target/trusted-firmware-m/authenticator-crypto-config.h
new file mode 100644
index 0000000..ab2f1c6
--- /dev/null
+++ b/target/trusted-firmware-m/authenticator-crypto-config.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+
+#ifndef AUTHENTICATOR_CRYPTO_CONFIG_H
+#define AUTHENTICATOR_CRYPTO_CONFIG_H
+
+#include <psa_adac_config.h>
+
+#define MBEDTLS_PSA_CRYPTO_C
+
+/* System support */
+#define MBEDTLS_PLATFORM_C
+#define MBEDTLS_PLATFORM_MEMORY
+#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
+#define MBEDTLS_NO_PLATFORM_ENTROPY
+#define MBEDTLS_ENTROPY_HARDWARE_ALT
+#define MBEDTLS_HAVE_ASM
+
+#define MBEDTLS_PLATFORM_EXIT_ALT
+#define MBEDTLS_PLATFORM_PRINTF_ALT
+
+#if defined(PSA_ADAC_RSA3072) || defined(PSA_ADAC_RSA4096)
+#define MBEDTLS_RSA_C
+#define MBEDTLS_PKCS1_V21
+#define MBEDTLS_OID_C
+#define MBEDTLS_BIGNUM_C
+#define MBEDTLS_PK_PARSE_C
+#define MBEDTLS_PK_C
+
+/* Support RSA key sizes up to 4096 bit */
+#define MBEDTLS_MPI_MAX_SIZE 512
+#endif
+
+/* PSA ADAC */
+#if defined(PSA_ADAC_EC_P256) || defined(PSA_ADAC_EC_P521)
+#define MBEDTLS_ECDSA_C
+#define MBEDTLS_ECP_C
+#define MBEDTLS_ASN1_PARSE_C
+#define MBEDTLS_ASN1_WRITE_C
+#ifndef MBEDTLS_BIGNUM_C
+#define MBEDTLS_BIGNUM_C
+#endif
+#ifndef MBEDTLS_PK_C
+#define MBEDTLS_PK_C
+#endif
+#if defined(PSA_ADAC_EC_P256)
+#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#endif
+#if defined(PSA_ADAC_EC_P521)
+#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
+#endif
+#endif
+
+/* Needed by PSA Crypto API Implementation */
+#define MBEDTLS_CTR_DRBG_C
+#define MBEDTLS_ENTROPY_C
+#define MBEDTLS_AES_C
+#define MBEDTLS_AES_ROM_TABLES
+#define MBEDTLS_AES_FEWER_TABLES
+
+#define MBEDTLS_MD_C
+#define MBEDTLS_SHA224_C
+#define MBEDTLS_SHA256_C
+#define MBEDTLS_SHA256_SMALLER
+#if defined(PSA_ADAC_EC_P521) || defined(PSA_ADAC_ED25519)
+#define MBEDTLS_SHA512_C
+#define MBEDTLS_SHA512_SMALLER
+#else
+#define MBEDTLS_ENTROPY_FORCE_SHA256
+#endif
+
+#ifdef PSA_ADAC_USE_CRYPTOCELL
+#define MBEDTLS_AES_ALT
+#define MBEDTLS_SHA256_ALT
+#define MBEDTLS_ENTROPY_HARDWARE_ALT
+#else
+#define MBEDTLS_CIPHER_C
+#endif
+
+#ifdef PSA_ADAC_CMAC
+#define MBEDTLS_CMAC_C
+#ifndef MBEDTLS_CIPHER_C
+#define MBEDTLS_CIPHER_C
+#endif
+#endif
+
+#ifdef PSA_ADAC_HMAC
+#define MBEDTLS_HKDF_C
+#endif
+
+#include "mbedtls/check_config.h"
+
+#endif /* AUTHENTICATOR_CRYPTO_CONFIG_H */
diff --git a/target/trusted-firmware-m/config.cmake b/target/trusted-firmware-m/config.cmake
new file mode 100644
index 0000000..5d6de1b
--- /dev/null
+++ b/target/trusted-firmware-m/config.cmake
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2021 Arm Limited. All rights reserved.
+# SPDX-License-Identifier: BSD-3-Clause
+#
+if (NOT DEFINED TFM_PLATFORM)
+ Message(FATAL_ERROR "TFM_PLATFORM not defined.")
+endif()
+
+get_filename_component(TFM_PLATFORM_PATH ${CMAKE_CURRENT_SOURCE_DIR}/target/trusted-firmware-m/platform/${TFM_PLATFORM} ABSOLUTE)
+
+if (NOT EXISTS ${TFM_PLATFORM_PATH})
+ Message(FATAL_ERROR "Platform ${TFM_PLATFORM} not supported.")
+endif()
+
+include(${TFM_PLATFORM_PATH}/config.cmake)
+
+set(PSA_ADAC_QUIET OFF CACHE BOOL "The image will be built to run on QEMU")
+set(PSA_ADAC_DEBUG ON CACHE BOOL "Enable debug")
diff --git a/target/trusted-firmware-m/platform/arm/corstone1000/CMakeLists.txt b/target/trusted-firmware-m/platform/arm/corstone1000/CMakeLists.txt
new file mode 100644
index 0000000..6dc8d86
--- /dev/null
+++ b/target/trusted-firmware-m/platform/arm/corstone1000/CMakeLists.txt
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2021 Arm Limited. All rights reserved.
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+target_sources(${PROJECT_NAME}
+ PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}/corstone1000.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/demo-discovery.c
+ ${PSA_ADAC_ROOT}/transport_layer/transports/static_buffer_msg.c
+ ${PSA_ADAC_ROOT}/transport_layer/transports/sdc-600/sdc-600.c
+ ${PSA_ADAC_ROOT}/transport_layer/transports/sdc-600/int_com_port_driver.c
+)
+
+target_include_directories(${PROJECT_NAME}
+ PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${PSA_ADAC_MBEDTLS_INCLUDE}
+ ${PSA_ADAC_ROOT}/transport_layer/transports
+)
+
+install(FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/psa_adac_platform.h
+ DESTINATION ${PSA_ADAC_INSTALL_PATH}/include
+)
diff --git a/target/trusted-firmware-m/platform/arm/corstone1000/config.cmake b/target/trusted-firmware-m/platform/arm/corstone1000/config.cmake
new file mode 100644
index 0000000..c4185c7
--- /dev/null
+++ b/target/trusted-firmware-m/platform/arm/corstone1000/config.cmake
@@ -0,0 +1,14 @@
+#
+# Copyright (c) 2021 Arm Limited. All rights reserved.
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+set(ARM_SYSTEM_PROCESSOR cortex-m0plus)
+set(ARM_SYSTEM_ARCHITECTURE armv6-m)
+set(ARM_SYSTEM_FP OFF)
+
+set(PSA_ADAC_EC_P256 ON CACHE BOOL "Enable support for ECDSA P-256")
+set(PSA_ADAC_EC_P521 OFF CACHE BOOL "Enable support for ECDSA P-521")
+set(PSA_ADAC_HW_CRYPTO ON CACHE BOOL "Support for hardware cryptography")
+
+set(PSA_ADAC_USE_CRYPTOCELL On)
diff --git a/target/trusted-firmware-m/platform/arm/corstone1000/corstone1000.c b/target/trusted-firmware-m/platform/arm/corstone1000/corstone1000.c
new file mode 100644
index 0000000..c0f5277
--- /dev/null
+++ b/target/trusted-firmware-m/platform/arm/corstone1000/corstone1000.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <psa_adac_config.h>
+#include <psa_adac_debug.h>
+#include <psa_adac_sda.h>
+#include <platform/platform.h>
+#include <platform/msg_interface.h>
+
+#include "demo-anchors.h"
+
+#include <string.h>
+
+void psa_adac_platform_init() {
+}
+
+extern uint8_t discovery_template[];
+extern size_t discovery_template_len;
+
+size_t psa_adac_platform_discovery(uint8_t *reply, size_t reply_size) {
+ if (reply_size >= discovery_template_len) {
+ memcpy(reply, discovery_template, discovery_template_len);
+ return discovery_template_len;
+ }
+ return 0;
+}
+
+void psa_adac_platform_lock() {
+ // TODO: Code me
+}
+
+int psa_adac_platform_check_token(uint8_t *token, size_t token_size) {
+ // TODO: Code me
+ return 0;
+}
+
+int psa_adac_platform_check_certificate(uint8_t *crt, size_t crt_size) {
+ // TODO: Code me
+ return 0;
+}
+
+int psa_adac_apply_permissions(uint8_t permissions_mask[16])
+{
+ PSA_ADAC_LOG_INFO("platform", "\r\n");
+
+ int ret = psa_adac_to_tfm_apply_permissions(permissions_mask);
+ if (ret) {
+ PSA_ADAC_LOG_INFO("platform", "psa_adac_to_tfm_apply_permissions failed\n\r");
+ return ret;
+ }
+
+ PSA_ADAC_LOG_INFO("platform",
+ "\n\rPlatform unlcoked for the secure debug %s\n");
+ return ret;
+}
+
+uint8_t buffer[512];
+uint8_t messages[512];
+
+int tfm_to_psa_adac_corstone1000_secure_debug(uint8_t *secure_debug_roptpk, uint32_t len)
+{
+ authentication_context_t auth_ctx;
+ int ret = -1;
+
+ if (psa_adac_detect_debug_request()) {
+ PSA_ADAC_LOG_INFO("main", "%s:%d Connection establised\r\n", __func__, __LINE__);
+
+ msg_interface_init(NULL, messages, sizeof(messages));
+
+ psa_adac_init();
+ psa_adac_acknowledge_debug_request();
+
+ rotpk_anchors[0] = secure_debug_roptpk;
+ rotpk_anchors_size[0] = len;
+ authentication_context_init(&auth_ctx, buffer, sizeof(buffer), ROTPK_ANCHOR_ALG,
+ rotpk_anchors, rotpk_anchors_size, rotpk_anchors_type,
+ rotpk_anchors_length);
+#ifndef PSA_ADAC_QUIET
+ PSA_ADAC_LOG_INFO("main", "Starting authentication.\r\n");
+#endif
+ authentication_handle(&auth_ctx);
+
+ PSA_ADAC_LOG_INFO("main", "\r\n\r\n\r\nAuthentication is a %s\r\r\r\n\n\n",
+ auth_ctx.state == AUTH_SUCCESS ? "success" : "failure");
+
+ if (auth_ctx.state == AUTH_SUCCESS) {
+ ret = 0;
+ }
+
+ msg_interface_free(NULL);
+ } else {
+ PSA_ADAC_LOG_INFO("main", "%s:%d No secure debug connection.\r\n", __func__, __LINE__);
+ }
+
+ return ret;
+}
+
+void platform_init() {
+}
diff --git a/target/trusted-firmware-m/platform/arm/corstone1000/demo-anchors.h b/target/trusted-firmware-m/platform/arm/corstone1000/demo-anchors.h
new file mode 100644
index 0000000..8a31faf
--- /dev/null
+++ b/target/trusted-firmware-m/platform/arm/corstone1000/demo-anchors.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <psa_adac_config.h>
+
+#define ROTPK_ANCHOR_ALG PSA_ALG_SHA_256
+
+static uint8_t *rotpk_anchors[1];
+
+static size_t rotpk_anchors_size[1];
+
+static uint8_t rotpk_anchors_type[] = {
+ ECDSA_P256_SHA256,
+};
+
+static size_t rotpk_anchors_length = sizeof(rotpk_anchors) / sizeof(uint8_t *);
diff --git a/target/trusted-firmware-m/platform/arm/corstone1000/demo-discovery.c b/target/trusted-firmware-m/platform/arm/corstone1000/demo-discovery.c
new file mode 100644
index 0000000..d2680c3
--- /dev/null
+++ b/target/trusted-firmware-m/platform/arm/corstone1000/demo-discovery.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "psa_adac.h"
+#include "psa_adac_config.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef PSA_ADAC_EC_P256
+#define EC_P256_CNT 1
+#define EC_P256_VAL ECDSA_P256_SHA256,
+#else
+#define EC_P256_CNT 0
+#define EC_P256_VAL
+#endif
+
+#ifdef PSA_ADAC_EC_P521
+#define EC_P521_CNT 1
+#define EC_P521_VAL ECDSA_P521_SHA512,
+#else
+#define EC_P521_CNT 0
+#define EC_P521_VAL
+#endif
+
+#ifdef PSA_ADAC_RSA3072
+#define RSA3072_CNT 1
+#define RSA3072_VAL RSA_3072_SHA256,
+#else
+#define RSA3072_CNT 0
+#define RSA3072_VAL
+#endif
+
+
+#ifdef PSA_ADAC_RSA4096
+#define RSA4096_CNT 1
+#define RSA4096_VAL RSA_4096_SHA256,
+#else
+#define RSA4096_CNT 0
+#define RSA4096_VAL
+#endif
+
+#ifdef PSA_ADAC_ED25519
+#define ED25519_CNT 1
+#define ED25519_VAL ED_25519_SHA512,
+#else
+#define ED25519_CNT 0
+#define ED25519_VAL
+#endif
+
+#ifdef PSA_ADAC_ED448
+#define ED448_CNT 1
+#define ED448_VAL ED_448_SHAKE256,
+#else
+#define ED448_CNT 0
+#define ED448_VAL
+#endif
+
+#ifdef PSA_ADAC_SM2SM3
+#define SM2SM3_CNT 1
+#define SM2SM3_VAL SM_SM2_SM3,
+#else
+#define SM2SM3_CNT 0
+#define SM2SM3_VAL
+#endif
+
+#ifdef PSA_ADAC_HMAC
+#define HMAC_CNT 1
+#define HMAC_VAL CMAC_AES,
+#else
+#define HMAC_CNT 0
+#define HMAC_VAL
+#endif
+
+#ifdef PSA_ADAC_CMAC
+#define CMAC_CNT 1
+#define CMAC_VAL HMAC_SHA256,
+#else
+#define CMAC_CNT 0
+#define CMAC_VAL
+#endif
+
+#define CRYPTO_CNT EC_P256_CNT + EC_P521_CNT + RSA3072_CNT + RSA4096_CNT + \
+ ED25519_CNT + ED448_CNT + SM2SM3_CNT + HMAC_CNT + CMAC_CNT
+#define CRYPTO_VALS EC_P256_VAL EC_P521_VAL RSA3072_VAL RSA4096_VAL \
+ ED25519_VAL ED448_VAL SM2SM3_VAL HMAC_VAL CMAC_VAL
+
+uint8_t discovery_template[] = {
+ // @+00 (12 bytes) psa_auth_version: 1.0
+ 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00,
+ // @+12 (12 bytes) vendor_id: {0x04, 0x3B} => 0x023B ("ARM Ltd.")
+ 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x04, 0x3B, 0x00, 0x00,
+ // @+24 (12 bytes) soc_class: [0x00, 0x00, 0x00, 0x00]
+ 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ // @+36 (24 bytes) soc_id: [0x00] * 16
+ 0x00, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // @+60 (12 bytes) psa_lifecycle: PSA_LIFECYCLE_SECURED
+ 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x00, 0x00,
+ // @+72 (12 bytes) token_formats: [{0x00, 0x02} (token_psa_debug)]
+ 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x00,
+ // @+84 (12 bytes) cert_formats: [{0x01, 0x02} (cert_psa_debug)]
+ 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00,
+ 0x01, 0x02, 0x00, 0x00,
+ // @+96 (8 + X bytes) cryptosystems: [...]
+ 0x00, 0x00, 0x02, 0x01, CRYPTO_CNT, 0x00, 0x00, 0x00,
+ CRYPTO_VALS
+};
+
+size_t discovery_template_len = sizeof(discovery_template);
diff --git a/target/trusted-firmware-m/platform/arm/corstone1000/include/platform/msg_interface.h b/target/trusted-firmware-m/platform/arm/corstone1000/include/platform/msg_interface.h
new file mode 100644
index 0000000..4713985
--- /dev/null
+++ b/target/trusted-firmware-m/platform/arm/corstone1000/include/platform/msg_interface.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PSA_ADAC_MSG_INTERFACE_H
+#define PSA_ADAC_MSG_INTERFACE_H
+
+#include <psa_adac.h>
+#include <platform/platform.h>
+#include <stddef.h>
+
+#if defined(PSA_ADAC_AUTHENTICATOR_IMPLICIT_TRANSPORT)
+
+int msg_interface_init(void *ctx, uint8_t buffer[], size_t size);
+int msg_interface_free(void *ctx);
+
+request_packet_t *request_packet_lock(size_t *max_data_size);
+response_packet_t *response_packet_lock(size_t *max_data_size);
+int response_packet_release(response_packet_t *packet);
+int request_packet_release(request_packet_t *packet);
+
+request_packet_t *request_packet_receive();
+response_packet_t *response_packet_build(uint16_t status, uint8_t *data, size_t data_size);
+int response_packet_send(response_packet_t *packet);
+
+#else
+
+#error "Explicit Transport API Currently not defined"
+
+/* This is a very early draft */
+
+typedef int (*msg_interface_init_t)(void *ctx, uint8_t buffer[], size_t size);
+typedef int (*msg_interface_free_t)(void *ctx);
+
+/* Target */
+typedef request_packet_t *(*request_packet_receive_t)(void *ctx);
+typedef int (*request_packet_release_t)(void *ctx, request_packet_t * packet);
+typedef response_packet_t *(*response_packet_lock_t)(void *ctx, size_t *max_data_size);
+typedef response_packet_t *(*response_packet_build_t)(void *ctx, uint16_t status, uint8_t *data, size_t data_size);
+typedef int (*response_packet_send_t)(void *ctx, response_packet_t *packet);
+
+typedef struct {
+ msg_interface_init_t msg_interface_init;
+ msg_interface_free_t msg_interface_free;
+ request_packet_receive_t request_packet_receive;
+ request_packet_release_t request_packet_release;
+ response_packet_lock_t response_packet_lock;
+ response_packet_build_t response_packet_build;
+ response_packet_send_t response_packet_send;
+ response_packet_release_t response_packet_release;
+} target_msg_interface_t;
+#endif
+
+#endif //PSA_ADAC_MSG_INTERFACE_H
diff --git a/target/trusted-firmware-m/platform/arm/corstone1000/include/platform/platform.h b/target/trusted-firmware-m/platform/arm/corstone1000/include/platform/platform.h
new file mode 100644
index 0000000..6e072af
--- /dev/null
+++ b/target/trusted-firmware-m/platform/arm/corstone1000/include/platform/platform.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PSA_ADAC_PLATFORM_H
+#define PSA_ADAC_PLATFORM_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+#ifdef PSA_ADAC_PLATFORM_CONFIG_FILE
+#include PSA_ADAC_PLATFORM_CONFIG_FILE
+#else
+#include <psa_adac_platform.h>
+#endif
+
+#ifndef PSA_ADAC_PLATFORM_BANNER
+#define PSA_ADAC_PLATFORM_BANNER "PSA ADAC "
+#endif
+
+void platform_init();
+
+void psa_adac_platform_lock();
+void psa_adac_platform_init();
+int psa_adac_detect_debug_request();
+void psa_adac_acknowledge_debug_request();
+
+size_t psa_adac_platform_discovery(uint8_t *reply, size_t reply_size);
+
+int psa_adac_platform_check_token(uint8_t *token, size_t token_size);
+int psa_adac_platform_check_certificate(uint8_t *crt, size_t crt_size);
+int psa_adac_apply_permissions(uint8_t permissions_mask[16]);
+
+#endif //PSA_ADAC_PLATFORM_H
diff --git a/target/trusted-firmware-m/platform/arm/corstone1000/include/psa_adac_platform.h b/target/trusted-firmware-m/platform/arm/corstone1000/include/psa_adac_platform.h
new file mode 100644
index 0000000..87f9d4f
--- /dev/null
+++ b/target/trusted-firmware-m/platform/arm/corstone1000/include/psa_adac_platform.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2021 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PSA_ADAC_TRUSTED_FIRMWARE_M_CORSTONE1000__PSA_ADAC_PLATFORM_H
+#define PSA_ADAC_TRUSTED_FIRMWARE_M_CORSTONE1000_PSA_ADAC_PLATFORM_H
+
+#include <psa_adac_config.h>
+
+#define PSA_ADAC_PLATFORM_BANNER "PSA ADAC: Tresuted-Firmware-M Dipda platform."
+#define PSA_ADAC_AUTHENTICATOR_IMPLICIT_TRANSPORT
+
+/*
+ * From tf-m to psa-adac.
+ * Call to this function will wait for host debugger to initiate the
+ * secure debug connection and will perform the secure debug authentication
+ * proces.
+ */
+int tfm_to_psa_adac_corstone1000_secure_debug(uint8_t *secure_debug_rotpk, uint32_t len);
+
+/*
+ * From psa-adac to tfm
+ * The platform code in the tf-m can use this function to apply
+ * secure debug permissions.
+ */
+int psa_adac_to_tfm_apply_permissions(uint8_t permissions_mask[16]);
+
+
+#endif //PSA_ADAC_TRUSTED_FIRMWARE_M_CORSTONE1000_PSA_ADAC_PLATFORM_H
diff --git a/target/trusted-firmware-m/platform/arm/corstone1000/int_com_port_config.h b/target/trusted-firmware-m/platform/arm/corstone1000/int_com_port_config.h
new file mode 100644
index 0000000..73507d0
--- /dev/null
+++ b/target/trusted-firmware-m/platform/arm/corstone1000/int_com_port_config.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef _HAL_H
+#define _HAL_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define HAL_SOCID_SIZE (32)
+
+#define SE_HOST_ACCESS 0x60000000
+#define SE_APBCOM_BASE (SE_HOST_ACCESS + 0x1B900000)
+
+#define HAL_APBCOM_BASE SE_APBCOM_BASE
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HAL_H */
+
+
+
diff --git a/template_hal_files/psa_adac_crypto_api_impl.c b/template_hal_files/psa_adac_crypto_api_impl.c
new file mode 100644
index 0000000..edd602c
--- /dev/null
+++ b/template_hal_files/psa_adac_crypto_api_impl.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <psa/crypto.h>
+#include "psa_adac_config.h"
+#include "psa_adac_debug.h"
+#include "psa_adac.h"
+
+/** \addtogroup adac-crypto-api
+ * @{
+ */
+
+/** \brief ADAC cryptographic back-end initialization
+ *
+ * This function will be called by ADAC library.
+ */
+psa_status_t psa_adac_crypto_init()
+{
+ // Code me
+}
+
+/** \brief Generate challenge
+ *
+ * \param[out] output Output buffer for the challenge.
+ * \param output_size Number of bytes to generate and output.
+ */
+psa_status_t psa_adac_generate_challenge(uint8_t *output, size_t output_size);
+{
+ // Code me
+}
+
+/** \brief Compute the hash of a message
+ *
+ * \param alg The hash algorithm to compute.
+ * \param[in] input Buffer containing the message to hash.
+ * \param input_size Size of the \p input buffer in bytes.
+ * \param[out] hash Buffer where the hash is to be written.
+ * \param hash_size Size of the \p hash buffer in bytes.
+ * \param[out] hash_length On success, the length of the hash in bytes.
+ *
+ * \retval PSA_SUCCESS
+ * Success.
+ * \retval PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported (or unknown hash algorithm).
+ * \retval PSA_ERROR_INVALID_ARGUMENT
+ * \retval PSA_ERROR_HARDWARE_FAILURE
+ */
+psa_status_t psa_adac_hash(psa_algorithm_t alg, const uint8_t *input, size_t input_size,
+ uint8_t *hash, size_t hash_size, size_t *hash_length)
+{
+ // Code me
+}
+
+/** \brief Compute the hash of a message composed of multiple parts
+ *
+ * \param alg The hash algorithm to compute.
+ * \param[in] inputs Array of buffers containing the message to hash.
+ * \param[in] input_sizes Array of size of the \p inputs buffers in bytes.
+ * \param input_count Number of entries in \p inputs and \p input_sizes.
+ * \param[out] hash Buffer where the hash is to be written.
+ * \param hash_size Size of the \p hash buffer in bytes.
+ * \param[out] hash_length On success, the length of the hash in bytes.
+ *
+ * \retval PSA_SUCCESS
+ * Success.
+ * \retval PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported (or unknown hash algorithm).
+ * \retval PSA_ERROR_INVALID_ARGUMENT
+ * \retval PSA_ERROR_HARDWARE_FAILURE
+ */
+psa_status_t psa_adac_hash_multiple(psa_algorithm_t alg,
+ const uint8_t *inputs[], size_t input_sizes[], size_t input_count,
+ uint8_t hash[], size_t hash_size, size_t *hash_length)
+{
+ // Code me
+}
+
+/** \brief Compute the hash of a message and compare it with an expected value.
+ *
+ * \param alg The hash algorithm to compute.
+ * \param[in] input Buffer containing the message to hash.
+ * \param input_size Size of the \p input buffer in bytes.
+ * \param[out] hash Buffer containing the expected hash value.
+ * \param hash_size Size of the \p hash buffer in bytes.
+ *
+ * \retval PSA_SUCCESS
+ * The expected hash is identical to the actual hash of the input.
+ * \retval PSA_ERROR_INVALID_SIGNATURE
+ * The hash of the message was calculated successfully, but it
+ * differs from the expected hash.
+ * \retval PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported (or unknown hash algorithm).
+ * \retval PSA_ERROR_INVALID_ARGUMENT
+ * \retval PSA_ERROR_HARDWARE_FAILURE
+ */
+psa_status_t psa_adac_hash_verify(psa_algorithm_t alg, const uint8_t input[], size_t input_size,
+ uint8_t hash[], size_t hash_size)
+{
+ // Code me
+}
+
+/** \brief Compute the hash of a message and compare it with a list of expected values
+ *
+ */
+psa_status_t psa_adac_hash_verify_multiple(psa_algorithm_t alg, const uint8_t input[], size_t input_length,
+ uint8_t *hash[], size_t hash_size[], size_t hash_count)
+{
+ // Code me
+}
+
+/** \brief Verify a signature
+ *
+ */
+psa_status_t psa_adac_verify_signature(uint8_t key_type, uint8_t *key, size_t key_size, psa_algorithm_t hash_algo,
+ const uint8_t *inputs[], size_t input_sizes[], size_t input_count,
+ psa_algorithm_t sig_algo, uint8_t *sig, size_t sig_size)
+{
+ // Code me
+}
+
+/** \brief Verify a message authentication code
+ *
+ */
+psa_status_t psa_adac_mac_verify(psa_algorithm_t alg, const uint8_t *inputs[], size_t input_sizes[], size_t input_count,
+ const uint8_t key[], size_t key_size, uint8_t mac[], size_t mac_size)
+{
+ // Code me
+}
+
+/** \brief Derive key
+ *
+ */
+psa_status_t psa_adac_derive_key(uint8_t *crt, size_t crt_size, uint8_t key_type, uint8_t *key, size_t key_size)
+{
+ // Code me
+}
+
+/**@}*/
+
+#endif //PSA_ADAC_PSA_CRYPTO_API_H
diff --git a/template_hal_files/target_name.c b/template_hal_files/target_name.c
new file mode 100644
index 0000000..0bc2ebc
--- /dev/null
+++ b/template_hal_files/target_name.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <psa_adac_config.h>
+#include <psa_adac_debug.h>
+#include <psa_adac_sda.h>
+#include <platform/platform.h>
+#include <platform/msg_interface.h>
+
+void psa_adac_platform_init()
+{
+ // TODO: Code me
+}
+
+size_t psa_adac_platform_discovery(uint8_t *reply, size_t reply_size)
+{
+ // TODO: Code me
+}
+
+void psa_adac_platform_lock()
+{
+ // TODO: Code me
+}
+
+int psa_adac_platform_check_token(uint8_t *token, size_t token_size)
+{
+ // TODO: Code me
+}
+
+int psa_adac_platform_check_certificate(uint8_t *crt, size_t crt_size)
+{
+ // TODO: Code me
+}
+
+int psa_adac_apply_permissions(uint8_t permissions_mask[16])
+{
+ // TODO: Code me
+}
+
+void platform_init()
+{
+ // TODO: Code me
+}
diff --git a/template_hal_files/trasport_layer.c b/template_hal_files/trasport_layer.c
new file mode 100644
index 0000000..d5540b2
--- /dev/null
+++ b/template_hal_files/trasport_layer.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <psa_adac_debug.h>
+#include <platform/msg_interface.h>
+
+#include <platform/platform.h>
+
+int psa_adac_detect_debug_request()
+{
+ // Code me
+}
+
+void psa_adac_acknowledge_debug_request()
+{
+ // Code me
+}
+
+int msg_interface_init(void *ctx, uint8_t buffer[], size_t buffer_size)
+{
+ // Code me
+}
+
+int msg_interface_free(void *ctx)
+{
+ // Code me
+}
+
+int request_packet_send()
+{
+ // Code me
+}
+
+request_packet_t *request_packet_receive(void *ctx)
+{
+ // Code me
+}
+
+int response_packet_send(response_packet_t *p)
+{
+ // Code me
+}
+
+response_packet_t *response_packet_receive()
+{
+ // Code me
+}
diff --git a/transport_layer/transports/sdc-600/int_com_port_def.h b/transport_layer/transports/sdc-600/int_com_port_def.h
new file mode 100644
index 0000000..67136ce
--- /dev/null
+++ b/transport_layer/transports/sdc-600/int_com_port_def.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2016-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef _COM_PORT_DEF_H_
+#define _COM_PORT_DEF_H_
+
+#include "int_com_port_hal.h"
+
+/* internal apbcom variant */
+#define APBCOM_REG_VIDR 0xD00
+#define APBCOM_REG_FIDTXR 0xD08
+#define APBCOM_REG_FIDRXR 0xD0C
+#define APBCOM_REG_ICSR 0xD10
+#define APBCOM_REG_DR 0xD20
+#define APBCOM_REG_SR 0xD2C
+#define APBCOM_REG_DBR 0xD30
+#define APBCOM_REG_SR_ALIAS 0xD3C
+
+#define APBCOM_REG_ITSTATUS 0xEFC
+#define APBCOM_REG_ITCTRL 0 0xF00
+#define APBCOM_REG_CLAIMSET 0xFA0
+#define APBCOM_REG_CLAIMCLR 0xFA4
+#define APBCOM_REG_AUTHSTATUS 0xFB8
+#define APBCOM_REG_DEVARCH 0xFBC
+#define APBCOM_REG_DEVID 0xFC8
+#define APBCOM_REG_PIDR4 0xFD0
+#define APBCOM_REG_PIDR0 0xFE0
+#define APBCOM_REG_PIDR1 0xFE4
+#define APBCOM_REG_PIDR2 0xFE8
+#define APBCOM_REG_PIDR3 0xFEC
+#define APBCOM_REG_CIDR0 0xFF0
+#define APBCOM_REG_CIDR1 0xFF4
+#define APBCOM_REG_CIDR2 0xFF8
+#define APBCOM_REG_CIDR3 0xFFC
+
+/* status register */
+#define SR_TXS_OFFSET 0
+#define SR_TXS_LEN 8
+#define SR_TXOE_OFFSET 13
+#define SR_TXOE_LEN 1
+#define SR_TXLE_OFFSET 14
+#define SR_TXLE_LEN 1
+#define SR_RXF_OFFSET 16
+#define SR_RXF_LEN 8
+#define SR_RXLE_OFFSET 30
+#define SR_RXLE_LEN 1
+
+#define APBCOM_ADDR(_a) \
+ ((unsigned int)(HAL_APBCOM_BASE + _a))
+
+#define APBCOM_READ_WORD(_a) \
+ *((volatile unsigned int*)(APBCOM_ADDR(_a)))
+
+#define APBCOM_WRITE_WORD(_a, _val) \
+ *((unsigned int*)(APBCOM_ADDR(_a))) = *(uint32_t*)_val
+
+#define APBCOM_READ_FEILD(_a, _offset, _len) \
+ ((APBCOM_READ_WORD(_a) & (((1 << (_len)) - 1) << _offset)) >> _offset)
+
+#define APBCOM_GET_FEILD(_val, _offset, _len) \
+ (((_val) & (((1 << (_len)) - 1) << _offset)) >> _offset)
+
+// Flags bytes
+#define FLAG_IDR 0xA0
+#define FLAG_IDA 0xA1
+#define FLAG_LPH1RA 0xA6
+#define FLAG_LPH1RL 0xA7
+#define FLAG_LPH2RA 0xA8
+#define FLAG_LPH2RL 0xA9
+#define FLAG_LPH2RR 0xAA
+#define FLAG_START 0xAC
+#define FLAG_END 0xAD
+#define FLAG_ESC 0xAE
+#define FLAG__NULL 0xAF
+
+// Reboot types
+enum ResetType {
+ NONE,
+ nSRSTReset,
+ COMPortReset
+};
+
+static inline const char* apbcomflagToStr(uint8_t flag)
+{
+#define FLAG_TO_STR(_a) case _a: return #_a
+ switch (flag) {
+ FLAG_TO_STR(FLAG_IDR );
+ FLAG_TO_STR(FLAG_IDA );
+ FLAG_TO_STR(FLAG_LPH1RA );
+ FLAG_TO_STR(FLAG_LPH1RL );
+ FLAG_TO_STR(FLAG_LPH2RA );
+ FLAG_TO_STR(FLAG_LPH2RL );
+ FLAG_TO_STR(FLAG_LPH2RR );
+ FLAG_TO_STR(FLAG_START );
+ FLAG_TO_STR(FLAG_END );
+ FLAG_TO_STR(FLAG_ESC );
+ FLAG_TO_STR(FLAG__NULL );
+ default: return "other";
+ }
+#undef FLAG_TO_STR
+}
+#endif /* _COM_PORT_DEF_H_ */
diff --git a/transport_layer/transports/sdc-600/int_com_port_driver.c b/transport_layer/transports/sdc-600/int_com_port_driver.c
new file mode 100644
index 0000000..3b7b679
--- /dev/null
+++ b/transport_layer/transports/sdc-600/int_com_port_driver.c
@@ -0,0 +1,483 @@
+/*
+ * Copyright (c) 2016-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "sdc600_types.h"
+#include "sdc600_log.h"
+
+#include "int_com_port_driver.h"
+#include "int_com_port_def.h"
+
+/******************************************************************************************************
+ *
+ * Macros
+ *
+ ******************************************************************************************************/
+#define ENTITY_NAME "ICPD"
+
+#define BLOCKED true
+#define NOT_BLOCKED false
+
+#define SKIP_ERROR_CHECK true
+#define ERROR_CHECK false
+
+#define ICPD_ASSERT(_cmd, _exp, _error) \
+ do { \
+ int _res = 0; \
+ if (SDC600_TRACE) SDC600_LOG_DEBUG(ENTITY_NAME, "running[%s]\n", #_cmd); \
+ if ((_res = (int)(_cmd)) != _exp) \
+ { \
+ SDC600_LOG_ERR(ENTITY_NAME, "failed to run[%s] res[%d]\n", #_cmd, _res); \
+ res = _error; \
+ goto bail; \
+ } \
+ } while (0)
+
+#define ICPD_ASSERT_PASS(_cmd, _exp) \
+ do { \
+ int _res = 0; \
+ if (SDC600_TRACE) SDC600_LOG_DEBUG(ENTITY_NAME, "running[%s]\n", #_cmd); \
+ if ((_res = (int)(_cmd)) != _exp) \
+ { \
+ SDC600_LOG_ERR(ENTITY_NAME, "failed to run[%s] res[%d]\n", #_cmd, _res); \
+ goto bail; \
+ } \
+ } while (0)
+
+/******************************************************************************************************
+ *
+ * Static declarations
+ *
+ ******************************************************************************************************/
+static icpd_rx_rc_t IComPortRxInt(uint8_t startFlag,
+ uint8_t *RxBuffer,
+ size_t RxBufferLength,
+ size_t *ActualLength);
+
+static icpd_rx_rc_t IComPortReadByte(uint8_t *byte, bool_t isBlocked, bool_t isSkipErrorsCheck);
+
+static bool_t IComPortIsFlag(uint8_t buffer, uint8_t flag);
+
+static icpd_tx_rc_t IComSendByte(uint8_t byte);
+
+static icpd_tx_rc_t IComPortTxInt(uint8_t startFlag,
+ uint8_t *TxBuffer,
+ size_t TxBufferLength,
+ size_t *actualLength);
+
+/******************************************************************************************************
+ *
+ * variables
+ *
+ ******************************************************************************************************/
+bool_t gIsComPortInited = false;
+
+/******************************************************************************************************
+ *
+ * private
+ *
+ ******************************************************************************************************/
+static icpd_rx_rc_t IComPortReadByte(uint8_t *byte, bool_t isBlocked, bool_t isSkipErrorsCheck) {
+ icpd_rx_rc_t res = ICPD_RX_SUCCESS;
+
+ bool_t txOverflow = false;
+ uint8_t rxData = 0;
+ uint32_t sr = 0;
+
+ do {
+ sr = APBCOM_READ_WORD(APBCOM_REG_SR);
+
+ if (isSkipErrorsCheck == ERROR_CHECK) {
+
+ // SDC600_LOG_DEBUG(ENTITY_NAME, "SR[0x%08x]\n", sr);
+
+ txOverflow = APBCOM_GET_FEILD(sr, SR_TXOE_OFFSET, SR_TXOE_LEN) > 0;
+ if (txOverflow) {
+ SDC600_LOG_ERR(ENTITY_NAME, "buffer overflow detected [%u]\n", txOverflow);
+ res = ICPD_RX_BUFFER_OVERFLOW;
+ goto bail;
+ }
+
+ }
+
+ rxData = APBCOM_GET_FEILD(sr, SR_RXF_OFFSET, SR_RXF_LEN);
+ if (rxData > 0) {
+ break;
+ }
+
+ } while (isBlocked);
+
+ /* this driver is hard coded to work with fifo size 1 */
+ *byte = APBCOM_READ_WORD(APBCOM_REG_DR) & 0xFF;
+
+ bail:
+ return res;
+}
+
+static bool_t IComPortIsFlag(uint8_t byte, uint8_t flag) {
+
+ SDC600_LOG_DEBUG(ENTITY_NAME, "expecting flag[%s]\n", apbcomflagToStr(flag));
+
+ if (byte == flag) {
+ SDC600_LOG_DEBUG(ENTITY_NAME, "flag[%s] found\n", apbcomflagToStr(flag));
+ return true;
+ }
+
+ SDC600_LOG_DEBUG(ENTITY_NAME, "flag[%s] not found\n", apbcomflagToStr(flag));
+
+ return false;
+}
+
+static icpd_tx_rc_t IComSendByte(uint8_t byte) {
+ icpd_tx_rc_t res = ICPD_TX_SUCCESS;
+ uint8_t txFifoFreeSapceInBytes = 0;
+
+ const uint32_t MAX_NUM_OF_RETRIES = 50000;
+ uint32_t numOfRetries = 0;
+ uint32_t sr = 0;
+
+
+ while (numOfRetries++ < MAX_NUM_OF_RETRIES) {
+ sr = APBCOM_READ_WORD(APBCOM_REG_SR);
+
+ if (APBCOM_GET_FEILD(sr, SR_TXLE_OFFSET, SR_TXLE_LEN) > 0) {
+ SDC600_LOG_ERR(ENTITY_NAME, "link error detected\n");
+ res = ICPD_TX_DISCONNECT;
+ goto bail;
+ }
+
+ if (APBCOM_GET_FEILD(sr, SR_TXOE_OFFSET, SR_TXOE_LEN) > 0) {
+ SDC600_LOG_ERR(ENTITY_NAME, "overflow detected\n");
+ res = ICPD_TX_FAIL;
+ goto bail;
+ }
+
+ txFifoFreeSapceInBytes = APBCOM_GET_FEILD(sr, SR_TXS_OFFSET, SR_TXS_LEN);
+ if (txFifoFreeSapceInBytes > 0) {
+ break;
+ }
+ }
+
+ if (numOfRetries >= MAX_NUM_OF_RETRIES) {
+ SDC600_LOG_ERR(ENTITY_NAME, "write operation timed out\n");
+ res = ICPD_TX_TIMEOUT;
+ goto bail;
+ }
+
+ uint8_t txData[4] = {byte, FLAG__NULL, FLAG__NULL, FLAG__NULL};
+ APBCOM_WRITE_WORD(APBCOM_REG_DBR, txData);
+
+ bail:
+ return res;
+}
+
+static icpd_tx_rc_t IComPortTxInt(uint8_t startFlag, uint8_t *TxBuffer, size_t TxBufferLength, size_t *actualLength) {
+ icpd_tx_rc_t res = ICPD_TX_SUCCESS;
+ size_t input_index = 0, output_index = 0;
+
+ SDC600_LOG_BUF(" <----- ", TxBuffer, TxBufferLength, "data_to_send");
+
+ res = IComSendByte(startFlag);
+ if (res != ICPD_TX_SUCCESS) {
+ SDC600_LOG_ERR(ENTITY_NAME, "failed to send byte num[%u][0x%02x]\n", output_index, startFlag);
+ goto bail;
+ }
+ ++output_index;
+
+ /* send all bytes */
+ for (input_index = 0; input_index < TxBufferLength; ++input_index, ++output_index) {
+ uint8_t current = TxBuffer[input_index];
+
+ /* Each Message byte that matches one of the Flag bytes is
+ * immediately preceded by the ESC Flag byte, and bit [7] of the Message byte is inverted. */
+ if (current >= 0xA0 && current < 0xC0) {
+ res = IComSendByte(FLAG_ESC);
+ if (res != ICPD_TX_SUCCESS) {
+ SDC600_LOG_ERR(ENTITY_NAME, "failed to send byte num[%u][0x%02x]\n", output_index, FLAG_ESC);
+ goto bail;
+ }
+ ++output_index;
+ current = current & ~0x80UL;
+ }
+ res = IComSendByte(current);
+ if (res != ICPD_TX_SUCCESS) {
+ SDC600_LOG_ERR(ENTITY_NAME, "failed to send byte num[%u][0x%02x]\n", output_index, current);
+ goto bail;
+ }
+ }
+
+ res = IComSendByte(FLAG_END);
+ if (res != ICPD_TX_SUCCESS) {
+ SDC600_LOG_ERR(ENTITY_NAME, "failed to send byte num[%u][0x%02x]\n", output_index, FLAG_END);
+ goto bail;
+ }
+ ++output_index;
+
+ if(actualLength !=NULL) {
+ *actualLength = output_index;
+ }
+
+bail:
+ return res;
+
+}
+
+static icpd_rx_rc_t IComPortRxInt(uint8_t startFlag, uint8_t *RxBuffer, size_t RxBufferLength, size_t *ActualLength) {
+ icpd_rx_rc_t res = ICPD_RX_SUCCESS;
+
+ uint8_t readByte = 0;
+ bool_t isDone = false;
+ uint16_t buffer_idx = 0;
+ bool_t isStartRecv = false;
+ bool_t isEndRecv = false;
+ bool_t isEscRecv = false;
+
+ ICPD_ASSERT(gIsComPortInited == true, true, ICPD_RX_FAIL);
+
+ while (isDone == false) {
+ /* if this fails it means the buffer is empty */
+ res = IComPortReadByte(&readByte, BLOCKED, ERROR_CHECK);
+ if (res != ICPD_RX_SUCCESS) {
+ SDC600_LOG_ERR(ENTITY_NAME, "IComPortReadBuffer failed with code: %d\n", res);
+ goto bail;
+ }
+
+ /* com port is 1 byte fifo width */
+ if (readByte == FLAG_END) {
+ isDone = true;
+ isEndRecv = true;
+ continue;
+ } else if (readByte == FLAG__NULL) {
+ continue;
+ } else if (readByte == FLAG_ESC) {
+ isEscRecv = true;
+ } else if (readByte == startFlag) {
+ buffer_idx = 0;
+ isStartRecv = true;
+ } else {
+ if (isEscRecv == true) {
+ readByte |= 0x80UL;
+ isEscRecv = false;
+ }
+
+ if (buffer_idx >= RxBufferLength) {
+ SDC600_LOG_ERR(ENTITY_NAME, "RxBufferLength[%u] buffer_idx[%u]\n", (uint32_t) RxBufferLength,
+ buffer_idx);
+ res = ICPD_RX_BUFFER_OVERFLOW;
+ goto bail;
+ }
+
+ RxBuffer[buffer_idx] = readByte;
+
+ buffer_idx += 1;
+ *ActualLength = buffer_idx;
+ }
+ }
+
+ SDC600_LOG_BUF(" -----> ", RxBuffer, *ActualLength, "data_recv");
+
+ bail:
+
+ if (res == ICPD_RX_SUCCESS) {
+ if (isStartRecv ^ isEndRecv)
+ res = ICPD_RX_PROT_ERROR;
+ }
+
+ return res;
+
+}
+
+/******************************************************************************************************
+ *
+ * public
+ *
+ ******************************************************************************************************/
+/**
+ * This function is called by the Secure Debug Handler to initiate the Internal COM port
+ * driver and the COM port link. The Internal COM port driver checks if there is any
+ * RX symbol in the Internal COM Port FIFO to find if the debugger platform is connected
+ * and check if link is established by the External COM Port (LPH2RA symbol in the Internal
+ * COM Port FIFO).
+ *
+ * Once the driver detects LPH2RA, the driver transmits LPH2RA to the debugger, establishes
+ * the link to the external COM port and waits for IDA command. Once received, the driver
+ * responds with the high level protocol provided value.
+ *
+ * @param IDBuffer [in]
+ * @param IDBufferLength [in]
+ * @return
+ */
+icpd_rc_t IComPortInit(uint8_t *IDBuffer, size_t IDBufferLength) {
+ icpd_rc_t res = ICPD_SUCCESS;
+ uint8_t readByte;
+
+#ifdef PROFILE_ENABLED
+ ICPD_ASSERT(IDBuffer != NULL, true, ICPD_FAIL);
+
+ {
+ volatile uint32_t *SYST_CSR = 0xE000E010;
+ volatile uint32_t *SYST_RVR = 0xE000E014;
+ volatile uint32_t *SYST_CVR = 0xE000E018;
+ {
+
+ /* enable systick */
+
+ *SYST_CSR = 5;
+ *SYST_RVR = 0x00ffffff;
+
+ }
+ {
+ uint32_t sr;
+ uint32_t var;
+ uint32_t time = *SYST_CVR;
+
+ for (var = 0; var < 1000; ++var) {
+ sr = APBCOM_READ_WORD(APBCOM_REG_SR);
+ }
+
+ SDC600_LOG_ERR(ENTITY_NAME, "SR tick[%u]\n", time - *SYST_CVR);
+ }
+ {
+ uint32_t sr;
+ uint32_t var;
+ uint32_t time = *SYST_CVR;
+
+ uint8_t txData[4] = { FLAG__NULL, FLAG__NULL, FLAG__NULL, FLAG__NULL };
+ for (var = 0; var < 1000; ++var) {
+ APBCOM_WRITE_WORD(APBCOM_REG_DR, txData);
+ }
+
+ SDC600_LOG_ERR(ENTITY_NAME, "DR tick[%u]\n", time - *SYST_CVR);
+ }
+ }
+#endif
+
+ // 1. The Internal COM Port device HW detects the status of the LINKEST signal.
+ // If it is set to 1 the HW inserts LPH2RA flag to the Internal COM Port's RX FIFO,
+ // otherwise the RX FIFO remains empty. If LPH2RA symbol is inserted to the RX FIFO
+ // then the Internal COM Port device interrupts its driver (in the boot case, interrupts
+ // are not enabled). Note: if the Internal COM Port CPU is asleep,
+ // this interrupt is assumed to wake it up.
+
+ // 2. Driver checks if the RX FIFO is not empty (RXF field of the Status register is not 0).
+ // 3. If no symbol found (FIFO is empty or FIFO returned value is NULL),
+ // return with Debugger not connected status.
+
+ // 4. If the driver reads a LPH2RA flag then it knows that the debugger
+ // may be connected as the link from the External COM Port is set.
+ // Driver goes to step 6 below.
+
+ // 5. If the read symbol from the FIFO is anything else (garbage, leftover
+ // from previous attempts), the driver drops it and returns to step 2 above.
+
+ /* FIXME: BLOCKED reading is active: if platform has a support to reset from
+ * the host, BLOCKED reading can be removed from NOT_BLOCKED. */
+ SDC600_LOG_WARN("init", "%s: Blocked reading of LPH2RA is active.\r\n", __func__);
+ SDC600_LOG_WARN("init", "%s: Blocked reading LPH2RA\r\n", __func__);
+ ICPD_ASSERT(IComPortReadByte(&readByte, BLOCKED, SKIP_ERROR_CHECK), ICPD_RX_SUCCESS, ICPD_FAIL);
+ ICPD_ASSERT(IComPortIsFlag(readByte, FLAG_LPH2RA), true, ICPD_DEBUGGER_NOT_CONNECTED);
+ SDC600_LOG_INFO("init", "%s: LPH2RA received\r\n", __func__);
+
+ // Set the link back to the debugger:
+ // 6. The Internal COM Port device driver writes LPH2RA flag to the Internal COM Port device TX.
+ ICPD_ASSERT(IComSendByte(FLAG_LPH2RA), ICPD_TX_SUCCESS, ICPD_FAIL);
+
+ /* TODO implement a timeout */
+ // Wait for External COM Port driver check of the debugged system protocol:
+ /**
+ * 7. Driver polls and reads a byte from the Internal COM Port FIFO.
+ * After timeout the driver returns with Debugger not connected
+ * status.
+ */
+ ICPD_ASSERT(IComPortReadByte(&readByte, BLOCKED, SKIP_ERROR_CHECK), ICPD_RX_SUCCESS, ICPD_DEBUGGER_NOT_CONNECTED);
+
+ /**
+ * 8. If the driver reads an IDR flag then it goes to step 10 below.
+ * Otherwise it returns with unexpected symbol received ststus.
+ */
+ if (IComPortIsFlag(readByte, FLAG_IDR) == true) {
+ size_t actualLength = 0;
+
+ /**
+ * IDR was detected
+ * 9. The driver responds and transmits to the debugger with
+ * Identification response message from the IDBuffer.
+ * Note: this response message format has a special format. It
+ * starts with IDA flag, followed by 6 bytes of debugged system
+ * ID hex value, and an END flag. If any of the platform ID
+ * bytes has MS bits value of 101b then the transmit driver must
+ * send an ESC flag following a flip of the MS bit of the byte
+ * to transmit.
+ * 10. Return with success code.
+ */
+ ICPD_ASSERT_PASS(
+ IComPortTxInt(FLAG_IDA, IDBuffer, IDBufferLength, &actualLength),
+ ICPD_TX_SUCCESS);
+
+ gIsComPortInited = true;
+ } else {
+ res = ICPD_FAIL;
+ goto bail;
+ }
+
+ bail:
+ return res;
+}
+
+/**
+ * At its receive side, the Internal COM port driver receives from the SDC-600 Internal
+ * COM port receiver a protocol message (which is stuffed by the required ESC flag bytes)
+ * that starts with START of message and ends with END of message flags. The receive side
+ * of the driver strips off the START and END of message flags and writes just the message
+ * content to the buffer it received from the Secure Debug Handler. While receiving, when
+ * the receiver detects ESC flag it drops it and replace the following received byte to
+ * its original value by flipping the MS bit.
+ *
+ * In case the receiver detects a message that does not start with START it
+ * drops it and reports an RX error.
+ * In case the receiver detects a LPH2RL flag it drops it and reports link
+ * dropper RX error.
+ * In case the receiver detects a message that starts with START but it filled
+ * the receive buffer to its end prior to the detection of END, it drops it
+ * and reports an RX error.
+ *
+ * @param RxBuffer [out]
+ * @param RxBufferLength [in]
+ * @param ActualLength [out]
+ * @return
+ */
+icpd_rx_rc_t IComPortRx(uint8_t *RxBuffer, size_t RxBufferLength, size_t *ActualLength) {
+ return IComPortRxInt(FLAG_START, RxBuffer, RxBufferLength, ActualLength);
+}
+
+/**
+ * The transmit side of the driver receives from the Secure Debug Handler a message
+ * to transmit in the provided buffer. The transmitter is transparent to the caller
+ * and the provided buffer may include any byte values (including values that are
+ * SDC-600 flag bytes). The IComPortTx provides transparent transmit interface.
+ *
+ * The IComPortTx function is responsible to inject to the Internal COM Port transmit
+ * FIFO HW a START flag, followed by the message bytes from the buffer and at the end
+ * it is responsible to inject to the transmit HW an END flag. While transmitting any
+ * byte from the buffer, the driver must detect if it is one of the SDC-600 COM Port
+ * flag values (bytes with an upper 3 bits of b101 are classified as Flag bytes).
+ * In such case the driver must inject ESC flag to the transmitter and flips the MS
+ * bit of the byte and transmits the modified byte.
+ * At the end of transmission of the buffer the IComPortTx function is responsible to
+ * inject to the External COM Port transmit FIFO HW an END flag.
+ *
+ * @param TxBuffer [in]
+ * @param TxBufferLength [in]
+ * @param ActualLength [out]
+ * @return
+ */
+icpd_tx_rc_t IComPortTx(uint8_t *TxBuffer, size_t TxBufferLength, size_t *ActualLength) {
+ return IComPortTxInt(FLAG_START, TxBuffer, TxBufferLength, ActualLength);
+}
diff --git a/transport_layer/transports/sdc-600/int_com_port_driver.h b/transport_layer/transports/sdc-600/int_com_port_driver.h
new file mode 100644
index 0000000..6aba4da
--- /dev/null
+++ b/transport_layer/transports/sdc-600/int_com_port_driver.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2016-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef INT_COM_PORT_DRIVER_H_
+#define INT_COM_PORT_DRIVER_H_
+
+#include <stdint.h>
+#include <stddef.h>
+
+typedef enum icpd_rc_t {
+ ICPD_SUCCESS,
+ ICPD_DEBUGGER_NOT_CONNECTED,
+ ICPD_FAIL,
+} icpd_rc_t;
+
+typedef enum icpd_rx_rc_t {
+ ICPD_RX_SUCCESS,
+ ICPD_RX_PROT_ERROR,
+ ICPD_RX_BUFFER_OVERFLOW,
+ ICPD_RX_DISCONNECT,
+ ICPD_RX_FAIL,
+} icpd_rx_rc_t;
+
+typedef enum icpd_tx_rc_t {
+ ICPD_TX_SUCCESS,
+ ICPD_TX_TIMEOUT,
+ ICPD_TX_DISCONNECT,
+ ICPD_TX_FAIL,
+} icpd_tx_rc_t;
+
+/**
+ * This function is called by the Secure Debug Handler to initiate the Internal COM port
+ * driver and the COM port link. The Internal COM port driver checks if there is any
+ * RX symbol in the Internal COM Port FIFO to find if the debugger platform is connected
+ * and check if link is established by the External COM Port (LPH2RA symbol in the Internal
+ * COM Port FIFO).
+ *
+ * Once the driver detects LPH2RA, the driver transmits LPH2RA to the debugger, establishes
+ * the link to the external COM port and waits for IDA command. Once received, the driver
+ * responds with the high level protocol provided value.
+ *
+ * @param IDBuffer [in]
+ * @param IDBufferLength [in]
+ * @return
+ */
+icpd_rc_t IComPortInit(uint8_t *IDBuffer, size_t IDBufferLength);
+
+/**
+ * At its receive side, the Internal COM port driver receives from the SDC-600 Internal
+ * COM port receiver a protocol message (which is stuffed by the required ESC flag bytes)
+ * that starts with START of message and ends with END of message flags. The receive side
+ * of the driver strips off the START and END of message flags and writes just the message
+ * content to the buffer it received from the Secure Debug Handler. While receiving, when
+ * the receiver detects ESC flag it drops it and replace the following received byte to
+ * its original value by flipping the MS bit.
+ *
+ * In case the receiver detects a message that does not start with START it
+ * drops it and reports an RX error.
+ * In case the receiver detects a LPH2RL flag it drops it and reports link
+ * dropper RX error.
+ * In case the receiver detects a message that starts with START but it filled
+ * the receive buffer to its end prior to the detection of END, it drops it
+ * and reports an RX error.
+ *
+ * @param RxBuffer [out]
+ * @param RxBufferLength [in]
+ * @param ActualLength [out]
+ * @return
+ */
+icpd_rx_rc_t IComPortRx(uint8_t *RxBuffer, size_t RxBufferLength, size_t *ActualLength);
+
+/**
+ * The transmit side of the driver receives from the Secure Debug Handler a message
+ * to transmit in the provided buffer. The transmitter is transparent to the caller
+ * and the provided buffer may include any byte values (including values that are
+ * SDC-600 flag bytes). The IComPortTx provides transparent transmit interface.
+ *
+ * The IComPortTx function is responsible to inject to the Internal COM Port transmit
+ * FIFO HW a START flag, followed by the message bytes from the buffer and at the end
+ * it is responsible to inject to the transmit HW an END flag. While transmitting any
+ * byte from the buffer, the driver must detect if it is one of the SDC-600 COM Port
+ * flag values (bytes with an upper 3 bits of b101 are classified as Flag bytes).
+ * In such case the driver must inject ESC flag to the transmitter and flips the MS
+ * bit of the byte and transmits the modified byte.
+ * At the end of transmission of the buffer the IComPortTx function is responsible to
+ * inject to the External COM Port transmit FIFO HW an END flag.
+ *
+ * @param TxBuffer [in]
+ * @param TxBufferLength [in]
+ * @param ActualLength [out]
+ * @return
+ */
+icpd_tx_rc_t IComPortTx(uint8_t *TxBuffer, size_t TxBufferLength, size_t *ActualLength);
+
+#endif /* INT_COM_PORT_DRIVER_H_ */
diff --git a/transport_layer/transports/sdc-600/int_com_port_hal.h b/transport_layer/transports/sdc-600/int_com_port_hal.h
new file mode 100644
index 0000000..3313be6
--- /dev/null
+++ b/transport_layer/transports/sdc-600/int_com_port_hal.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef _INT_COM_PORT_HAL_API_H
+#define _INT_COM_PORT_HAL_API_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! @file
+@brief This file contains the Hardware Abstraction API definition.
+ */
+
+/*
+ * Include platform-specific hardware abstraction layer implementation header
+ */
+#include "int_com_port_config.h"
+
+/* Mandatory implementation definitions */
+#ifndef HAL_SOCID_SIZE
+#error "HAL_SOCID_SIZE needs to be defined by the platform's hal.h"
+#endif
+
+#ifndef HAL_APBCOM_BASE
+#error "HAL_APBCOM_BASE needs to be defined by the platform's hal.h"
+#endif /* HAL_APBCOM_BASE */
+
+/* Optional implementation definitions */
+#ifndef HAL_OK
+#define HAL_OK 0
+#endif
+
+#ifndef HAL_FAIL
+#define HAL_FAIL 1UL
+#endif
+
+typedef uint32_t hal_socid_t[HAL_SOCID_SIZE / 4];
+
+typedef uint32_t hal_status_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _INT_COM_PORT_HAL_API_H */
+
+
+
diff --git a/transport_layer/transports/sdc-600/sdc-600.c b/transport_layer/transports/sdc-600/sdc-600.c
new file mode 100644
index 0000000..4c0c644
--- /dev/null
+++ b/transport_layer/transports/sdc-600/sdc-600.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <psa_adac_debug.h>
+#include <platform/msg_interface.h>
+#include "static_buffer_msg.h"
+
+#include "int_com_port_driver.h"
+
+#include <stdio.h>
+
+#include <platform/platform.h>
+
+#ifndef PSA_ADAC_AUTHENTICATOR_IMPLICIT_TRANSPORT
+#error "Unsupported environment"
+#endif
+
+#ifndef SDC600_BASE
+#define SDC600_BASE (0x50002000)
+#endif
+#define SDC600 ((SDC600_Type *)SDC600_BASE)
+
+//! PSA Debug Access Control protocol ID: 'PSADBG'
+static const char APBCOM_ID[6] = {0x50, 0x53, 0x41, 0x44, 0x42, 0x47};
+
+int psa_adac_detect_debug_request() {
+ int rc = 0;
+
+ // Initialize the IComPort driver.
+ icpd_rc_t r = IComPortInit((uint8_t *) APBCOM_ID, sizeof(APBCOM_ID));
+
+ switch (r) {
+ case ICPD_SUCCESS:
+ rc = 1;
+ PSA_ADAC_LOG_INFO("sdc-600", "IComPortInit: Success\n");
+ break;
+
+ case ICPD_DEBUGGER_NOT_CONNECTED:
+ PSA_ADAC_LOG_INFO("sdc-600", "IComPortInit: Debugger not connected\n");
+ break;
+
+ case ICPD_FAIL:
+ PSA_ADAC_LOG_INFO("sdc-600", "IComPortInit: Failure\n");
+ }
+
+ return rc;
+}
+
+void psa_adac_acknowledge_debug_request() {
+ // Nothing
+}
+
+int msg_interface_init(void *ctx, uint8_t buffer[], size_t buffer_size) {
+ return psa_adac_static_buffer_msg_init(buffer, buffer_size);
+}
+
+int msg_interface_free(void *ctx) {
+ return psa_adac_static_buffer_msg_release();
+}
+
+int request_packet_send() {
+ return -1;
+}
+
+request_packet_t *request_packet_receive(void *ctx) {
+ size_t max = 0, length = 0;
+ request_packet_t *r = request_packet_lock(&max);
+ if (r != NULL) {
+ if (IComPortRx((uint8_t *) r, max, &length) == ICPD_RX_SUCCESS) {
+ PSA_ADAC_LOG_DEBUG("request_packet_receive", "Received message of length %d\n", length);
+ return r;
+ }
+ PSA_ADAC_LOG_DEBUG("request_packet_receive", "Error Receiving Request\n");
+ request_packet_release(r);
+ } else {
+ PSA_ADAC_LOG_DEBUG("request_packet_receive", "Error locking Request\n");
+ }
+ return NULL;
+}
+
+int response_packet_send(response_packet_t *p) {
+ response_packet_t *packet = psa_adac_static_buffer_msg_get_response();
+ return (IComPortTx((uint8_t *) packet,
+ sizeof(response_packet_t) + packet->data_count * sizeof(uint32_t),
+ NULL) == ICPD_TX_SUCCESS ? 0 : -1);
+}
+
+response_packet_t *response_packet_receive() {
+ return NULL;
+}
diff --git a/transport_layer/transports/sdc-600/sdc600_log.h b/transport_layer/transports/sdc-600/sdc600_log.h
new file mode 100644
index 0000000..b4913bf
--- /dev/null
+++ b/transport_layer/transports/sdc-600/sdc600_log.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef SDC600_LOG_H_
+#define SDC600_LOG_H_
+
+#include "psa_adac_debug.h"
+#include <stdio.h>
+#include <stddef.h>
+#include <stdint.h>
+
+// Map SDC600 log macros to PSA_ADAC log macros.
+
+#define SDC600_TRACE 0
+
+#define SDC600_LOG_FUNC_AND_LEVEL(_level, _who) PSA_ADAC_LOG_FUNC_AND_LEVEL(_level, _who)
+
+#define SDC600_LOG_PRINT_LINE(_who, _level, _format, ...) PSA_ADAC_LOG_PRINT_LINE(_who, _level, _format, ##__VA_ARGS__)
+
+#define DEBUG_REG(_a) \
+ SDC600_LOG_DEBUG("TEST", "%s: [secure][%p] = [0x%08x]; [non-secure][%p] = [0x%08x]\n", \
+ #_a, \
+ (uint32_t *)APBCOM_ADDR(_a), \
+ (uint32_t)APBCOM_READ_WORD(_a), \
+ (uint32_t *)APBCOM_ADDR(_a - 0x10000000), \
+ (uint32_t)APBCOM_READ_WORD(_a - 0x10000000));
+
+#define SDC600_LOG_ERR(_who, _format, ...) PSA_ADAC_LOG_ERR(_who, _format, ##__VA_ARGS__)
+
+#define SDC600_LOG_WARN(_who, _format, ...) PSA_ADAC_LOG_WARN(_who, _format, ##__VA_ARGS__)
+
+#define SDC600_LOG_INFO(_who, _format, ...) PSA_ADAC_LOG_INFO(_who, _format, ##__VA_ARGS__)
+
+#define SDC600_LOG_DEBUG(_who, _format, ...) PSA_ADAC_LOG_DEBUG(_who, _format, ##__VA_ARGS__)
+
+#define SDC600_LOG_BUF(_who, _buff, _size, _label) PSA_ADAC_LOG_DUMP(_who, _label, _buff, _size)
+
+#define SDC600_ASSERT_ERROR(_cmd, _exp, _error) \
+ do { \
+ int _res = 0; \
+ if (SDC600_TRACE) SDC600_LOG_DEBUG(ENTITY_NAME, "running[%s]\n", #_cmd); \
+ if ((_res = (int)(_cmd)) != _exp) \
+ { \
+ SDC600_LOG_ERR(ENTITY_NAME, "failed to run[%s] res[%d] returning[0x%08x]\n", #_cmd, _res, _error); \
+ res = _error; \
+ goto bail; \
+ } \
+ } while (0)
+
+#define SDC600_ASSERT(_cmd, _exp) \
+ do { \
+ int _res = 0; \
+ if (SDC600_TRACE) SDC600_LOG_DEBUG(ENTITY_NAME, "running[%s]\n", #_cmd); \
+ if ((_res = (int)(_cmd)) != _exp) \
+ { \
+ SDC600_LOG_ERR(ENTITY_NAME, "failed to run[%s] res[%d]\n", #_cmd, _res); \
+ res = _res; \
+ goto bail; \
+ } \
+ } while (0)
+
+#endif /* SDC600_LOG_H_ */
diff --git a/transport_layer/transports/sdc-600/sdc600_types.h b/transport_layer/transports/sdc-600/sdc600_types.h
new file mode 100644
index 0000000..10378d1
--- /dev/null
+++ b/transport_layer/transports/sdc-600/sdc600_types.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2016-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef SDC600_TYPES_H_
+#define SDC600_TYPES_H_
+
+#include "stdint.h"
+
+typedef enum bool_t {
+ false,
+ true,
+} bool_t;
+
+#endif /* SDC600_TYPES_H_ */
diff --git a/transport_layer/transports/static_buffer_msg.c b/transport_layer/transports/static_buffer_msg.c
new file mode 100644
index 0000000..d159a4a
--- /dev/null
+++ b/transport_layer/transports/static_buffer_msg.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "static_buffer_msg.h"
+
+#include <string.h>
+
+// TODO: Enforce alignment and sizes on 4 bytes
+
+enum {
+ BUFFER_UNINITIALIZED = 0,
+ BUFFER_EMPTY,
+ BUFFER_REQUEST,
+ BUFFER_RESPONSE
+};
+
+static size_t psa_adac_static_buffer_size = 0;
+static uint8_t *psa_adac_static_buffer_pointer = NULL;
+static uint8_t psa_adac_static_buffer_status = BUFFER_UNINITIALIZED;
+
+int psa_adac_static_buffer_msg_init(uint8_t *buffer, size_t size) {
+ int ret = -1;
+ if (psa_adac_static_buffer_status == BUFFER_UNINITIALIZED) {
+ psa_adac_static_buffer_size = size;
+ psa_adac_static_buffer_pointer = buffer;
+ psa_adac_static_buffer_status = BUFFER_EMPTY;
+ ret = 0;
+ }
+
+ return ret;
+}
+
+int psa_adac_static_buffer_msg_release() {
+ int ret = -1;
+ if (psa_adac_static_buffer_status == BUFFER_EMPTY) {
+ psa_adac_static_buffer_size = 0;
+ psa_adac_static_buffer_pointer = NULL;
+ psa_adac_static_buffer_status = BUFFER_UNINITIALIZED;
+ ret = 0;
+ }
+
+ return ret;
+}
+
+request_packet_t *psa_adac_static_buffer_msg_get_request() {
+ // TODO: Check consistency
+ return (request_packet_t *) psa_adac_static_buffer_pointer;
+}
+
+response_packet_t *psa_adac_static_buffer_msg_get_response() {
+ // TODO: Check consistency
+ return (response_packet_t *) psa_adac_static_buffer_pointer;
+
+}
+
+request_packet_t *request_packet_build(uint16_t command, uint8_t *data, size_t data_size) {
+ request_packet_t *request = NULL;
+ if ((psa_adac_static_buffer_status == BUFFER_EMPTY) &&
+ (data_size <= (psa_adac_static_buffer_size - sizeof(request_packet_t)))) {
+ request = (request_packet_t *) psa_adac_static_buffer_pointer;
+ request->command = command;
+ request->data_count = data_size / 4UL;
+ (void) memcpy((void *) request->data, (void *) data, data_size);
+ // TODO: Fill with 0s
+ psa_adac_static_buffer_status = BUFFER_REQUEST;
+ }
+
+ return request;
+}
+
+request_packet_t *request_packet_lock(size_t *max_data_size) {
+ request_packet_t *request = NULL;
+ if (psa_adac_static_buffer_status == BUFFER_EMPTY) {
+ if (max_data_size != NULL) {
+ *max_data_size = psa_adac_static_buffer_size - sizeof(response_packet_t);
+ }
+
+ request = (request_packet_t *) psa_adac_static_buffer_pointer;
+ psa_adac_static_buffer_status = BUFFER_REQUEST;
+ }
+
+ return request;
+}
+
+int request_packet_release(request_packet_t *packet) {
+ int ret = -1;
+ if (psa_adac_static_buffer_status == BUFFER_REQUEST) {
+ psa_adac_static_buffer_status = BUFFER_EMPTY;
+ ret = 0;
+ }
+
+ return ret;
+}
+
+response_packet_t *response_packet_build(uint16_t status, uint8_t *data, size_t data_size) {
+ response_packet_t *response = NULL;
+ if ((psa_adac_static_buffer_status == BUFFER_EMPTY) &&
+ (data_size <= (psa_adac_static_buffer_size - sizeof(response_packet_t)))) {
+ response = (response_packet_t *) psa_adac_static_buffer_pointer;
+ response->status = status;
+ response->data_count = data_size / 4UL;
+ (void) memcpy((void *) response->data, (void *) data, data_size);
+ // TODO: Fill with 0s
+ psa_adac_static_buffer_status = BUFFER_RESPONSE;
+ }
+
+ return response;
+}
+
+response_packet_t *response_packet_lock(size_t *max_data_size) {
+ response_packet_t *response = NULL;
+ if (psa_adac_static_buffer_status == BUFFER_EMPTY) {
+ if (max_data_size != NULL) {
+ *max_data_size = psa_adac_static_buffer_size - sizeof(response_packet_t);
+ }
+ response = (response_packet_t *) psa_adac_static_buffer_pointer;
+ psa_adac_static_buffer_status = BUFFER_RESPONSE;
+ }
+
+ return response;
+}
+
+int response_packet_release(response_packet_t *packet) {
+ int ret = -1;
+ if (psa_adac_static_buffer_status == BUFFER_RESPONSE) {
+ psa_adac_static_buffer_status = BUFFER_EMPTY;
+ ret = 0;
+ }
+
+ return ret;
+}
diff --git a/transport_layer/transports/static_buffer_msg.h b/transport_layer/transports/static_buffer_msg.h
new file mode 100644
index 0000000..2064c46
--- /dev/null
+++ b/transport_layer/transports/static_buffer_msg.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PSA_ADAC_STATIC_BUFFER_MSG_H
+#define PSA_ADAC_STATIC_BUFFER_MSG_H
+
+#include <psa_adac.h>
+
+#include <stddef.h>
+#include <stdint.h>
+
+int psa_adac_static_buffer_msg_init(uint8_t *buffer, size_t size);
+int psa_adac_static_buffer_msg_release();
+
+request_packet_t *psa_adac_static_buffer_msg_get_request();
+response_packet_t *psa_adac_static_buffer_msg_get_response();
+
+#endif //PSA_ADAC_STATIC_BUFFER_MSG_H