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