mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2026-03-20 11:11:08 +01:00
Remove tf-psa-crypto directory
Signed-off-by: Ronald Cron <ronald.cron@arm.com>
This commit is contained in:
1
tf-psa-crypto/.gitignore
vendored
1
tf-psa-crypto/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
Makefile
|
||||
@@ -1,525 +0,0 @@
|
||||
#
|
||||
# CMake build system design considerations:
|
||||
#
|
||||
# - Include directories:
|
||||
# + Do not define include directories globally using the include_directories
|
||||
# command but rather at the target level using the
|
||||
# target_include_directories command. That way, it is easier to guarantee
|
||||
# that targets are built using the proper list of include directories.
|
||||
# + Use the PUBLIC and PRIVATE keywords to specify the scope of include
|
||||
# directories. That way, a target linking to a library (using the
|
||||
# target_link_libraries command) inherits from the library PUBLIC include
|
||||
# directories and not from the PRIVATE ones.
|
||||
# - TF_PSA_CRYPTO_TARGET_PREFIX: CMake targets are designed to be alterable by
|
||||
# calling CMake in order to avoid target name clashes, via the use of
|
||||
# TF_PSA_CRYPTO_TARGET_PREFIX. The value of this variable is prefixed to the
|
||||
# tfpsacrypto and tfpsacrypto-apidoc targets.
|
||||
#
|
||||
|
||||
# We specify a minimum requirement of 3.10.2, but for now use 3.5.1 here
|
||||
# until our infrastructure catches up.
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
# Include convenience functions for printing properties and variables, like
|
||||
# cmake_print_properties(), cmake_print_variables().
|
||||
include(CMakePrintHelpers)
|
||||
|
||||
# https://cmake.org/cmake/help/latest/policy/CMP0011.html
|
||||
# Setting this policy is required in CMake >= 3.18.0, otherwise a warning is generated. The OLD
|
||||
# policy setting is deprecated, and will be removed in future versions.
|
||||
cmake_policy(SET CMP0011 NEW)
|
||||
# https://cmake.org/cmake/help/latest/policy/CMP0012.html
|
||||
# Setting the CMP0012 policy to NEW is required for FindPython3 to work with CMake 3.18.2
|
||||
# (there is a bug in this particular version), otherwise, setting the CMP0012 policy is required
|
||||
# for CMake versions >= 3.18.3 otherwise a deprecated warning is generated. The OLD policy setting
|
||||
# is deprecated and will be removed in future versions.
|
||||
cmake_policy(SET CMP0012 NEW)
|
||||
|
||||
set(TF_PSA_CRYPTO_VERSION 0.1.0)
|
||||
set(TF_PSA_CRYPTO_SOVERSION 0)
|
||||
|
||||
if(TEST_CPP)
|
||||
project("TF-PSA-Crypto"
|
||||
LANGUAGES C CXX
|
||||
VERSION ${TF_PSA_CRYPTO_VERSION}
|
||||
)
|
||||
else()
|
||||
project("TF-PSA-Crypto"
|
||||
LANGUAGES C
|
||||
VERSION ${TF_PSA_CRYPTO_VERSION}
|
||||
)
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# Determine if TF-PSA-Crypto is being built as a subproject using add_subdirectory()
|
||||
if(NOT DEFINED TF_PSA_CRYPTO_AS_SUBPROJECT)
|
||||
set(TF_PSA_CRYPTO_AS_SUBPROJECT ON)
|
||||
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
set(TF_PSA_CRYPTO_AS_SUBPROJECT OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Set the project, Mbed TLS and framework root directory.
|
||||
set(TF_PSA_CRYPTO_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(MBEDTLS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..)
|
||||
set(TF_PSA_CRYPTO_FRAMEWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../framework)
|
||||
|
||||
# Put the version numbers into relevant files
|
||||
set(version_number_files
|
||||
doxygen/input/doc_mainpage.h
|
||||
doxygen/tfpsacrypto.doxyfile)
|
||||
foreach(file ${version_number_files})
|
||||
configure_file(${file}.in
|
||||
${TF_PSA_CRYPTO_DIR}/${file})
|
||||
endforeach(file)
|
||||
|
||||
ADD_CUSTOM_TARGET(${TF_PSA_CRYPTO_TARGET_PREFIX}tfpsacrypto-apidoc
|
||||
COMMAND doxygen tfpsacrypto.doxyfile
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doxygen)
|
||||
|
||||
option(ENABLE_PROGRAMS "Build TF-PSA-Crypto programs." ON)
|
||||
|
||||
option(TF_PSA_CRYPTO_FATAL_WARNINGS "Compiler warnings treated as errors" ON)
|
||||
if(CMAKE_HOST_WIN32)
|
||||
# N.B. The comment on the next line is significant! If you change it,
|
||||
# edit the sed command in prepare_release.sh that modifies
|
||||
# CMakeLists.txt.
|
||||
option(GEN_FILES "Generate the auto-generated files as needed" OFF) # off in development
|
||||
else()
|
||||
option(GEN_FILES "Generate the auto-generated files as needed" ON)
|
||||
endif()
|
||||
|
||||
# Support for package config and install to be added later.
|
||||
option(DISABLE_PACKAGE_CONFIG_AND_INSTALL "Disable package configuration, target export and installation" ${TF_PSA_CRYPTO_AS_SUBPROJECT})
|
||||
|
||||
if (CMAKE_C_SIMULATE_ID)
|
||||
set(COMPILER_ID ${CMAKE_C_SIMULATE_ID})
|
||||
else()
|
||||
set(COMPILER_ID ${CMAKE_C_COMPILER_ID})
|
||||
endif(CMAKE_C_SIMULATE_ID)
|
||||
|
||||
string(REGEX MATCH "Clang" CMAKE_COMPILER_IS_CLANG "${COMPILER_ID}")
|
||||
string(REGEX MATCH "GNU" CMAKE_COMPILER_IS_GNU "${COMPILER_ID}")
|
||||
string(REGEX MATCH "IAR" CMAKE_COMPILER_IS_IAR "${COMPILER_ID}")
|
||||
string(REGEX MATCH "MSVC" CMAKE_COMPILER_IS_MSVC "${COMPILER_ID}")
|
||||
|
||||
# the test suites currently have compile errors with MSVC
|
||||
if(CMAKE_COMPILER_IS_MSVC)
|
||||
option(ENABLE_TESTING "Build TF-PSA-Crypto tests." OFF)
|
||||
else()
|
||||
option(ENABLE_TESTING "Build TF-PSA-Crypto tests." ON)
|
||||
endif()
|
||||
|
||||
option(USE_STATIC_TF_PSA_CRYPTO_LIBRARY "Build TF-PSA-Crypto static library." ON)
|
||||
option(USE_SHARED_TF_PSA_CRYPTO_LIBRARY "Build TF-PSA-Crypto shared library." OFF)
|
||||
option(LINK_WITH_PTHREAD "Explicitly link Mbed TLS library to pthread." OFF)
|
||||
option(LINK_WITH_TRUSTED_STORAGE "Explicitly link Mbed TLS library to trusted_storage." OFF)
|
||||
|
||||
set(tfpsacrypto_target "${TF_PSA_CRYPTO_TARGET_PREFIX}tfpsacrypto")
|
||||
if (USE_STATIC_TF_PSA_CRYPTO_LIBRARY)
|
||||
set(tfpsacrypto_static_target ${tfpsacrypto_target})
|
||||
endif()
|
||||
if(USE_STATIC_TF_PSA_CRYPTO_LIBRARY AND USE_SHARED_TF_PSA_CRYPTO_LIBRARY)
|
||||
string(APPEND tfpsacrypto_static_target "_static")
|
||||
endif()
|
||||
|
||||
# Warning string - created as a list for compatibility with CMake 2.8
|
||||
set(CTR_DRBG_128_BIT_KEY_WARN_L1 "**** WARNING! MBEDTLS_CTR_DRBG_USE_128_BIT_KEY defined!\n")
|
||||
set(CTR_DRBG_128_BIT_KEY_WARN_L2 "**** Using 128-bit keys for CTR_DRBG limits the security of generated\n")
|
||||
set(CTR_DRBG_128_BIT_KEY_WARN_L3 "**** keys and operations that use random values generated to 128-bit security\n")
|
||||
|
||||
set(CTR_DRBG_128_BIT_KEY_WARNING "${WARNING_BORDER}"
|
||||
"${CTR_DRBG_128_BIT_KEY_WARN_L1}"
|
||||
"${CTR_DRBG_128_BIT_KEY_WARN_L2}"
|
||||
"${CTR_DRBG_128_BIT_KEY_WARN_L3}"
|
||||
"${WARNING_BORDER}")
|
||||
|
||||
# Python 3 is only needed here to check for configuration warnings.
|
||||
if(NOT CMAKE_VERSION VERSION_LESS 3.15.0)
|
||||
set(Python3_FIND_STRATEGY LOCATION)
|
||||
find_package(Python3 COMPONENTS Interpreter)
|
||||
if(Python3_Interpreter_FOUND)
|
||||
set(TF_PSA_CRYPTO_PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
|
||||
endif()
|
||||
else()
|
||||
find_package(PythonInterp 3)
|
||||
if(PYTHONINTERP_FOUND)
|
||||
set(TF_PSA_CRYPTO_PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(TF_PSA_CRYPTO_PYTHON_EXECUTABLE)
|
||||
# If 128-bit keys are configured for CTR_DRBG, display an appropriate warning
|
||||
execute_process(
|
||||
COMMAND
|
||||
${TF_PSA_CRYPTO_PYTHON_EXECUTABLE} ${TF_PSA_CRYPTO_DIR}/scripts/config.py
|
||||
-f ${TF_PSA_CRYPTO_DIR}/include/psa/crypto_config.h
|
||||
get MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
|
||||
RESULT_VARIABLE
|
||||
result
|
||||
)
|
||||
if(${result} EQUAL 0)
|
||||
message(WARNING ${CTR_DRBG_128_BIT_KEY_WARNING})
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
# We now potentially need to link all executables against PThreads, if available
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
||||
find_package(Threads)
|
||||
|
||||
# If this is the root project add longer list of available CMAKE_BUILD_TYPE values
|
||||
if(NOT TF_PSA_CRYPTO_AS_SUBPROJECT)
|
||||
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}
|
||||
CACHE STRING "Choose the type of build: None Debug Release Coverage ASan ASanDbg MemSan MemSanDbg Check CheckFull TSan TSanDbg"
|
||||
FORCE)
|
||||
endif()
|
||||
|
||||
# Make TF_PSA_CRYPTO_CONFIG_FILE and TF_PSA_CRYPTO_USER_CONFIG_FILE into PATHs
|
||||
set(TF_PSA_CRYPTO_CONFIG_FILE "" CACHE FILEPATH "TF-PSA-Crypto config file (overrides default).")
|
||||
set(TF_PSA_CRYPTO_USER_CONFIG_FILE "" CACHE FILEPATH "TF-PSA-Crypto user config file (appended to default).")
|
||||
|
||||
# Create a symbolic link from ${base_name} in the binary directory
|
||||
# to the corresponding path in the source directory.
|
||||
# Note: Copies the file(s) on Windows.
|
||||
function(link_to_source base_name)
|
||||
set(link "${CMAKE_CURRENT_BINARY_DIR}/${base_name}")
|
||||
set(target "${CMAKE_CURRENT_SOURCE_DIR}/${base_name}")
|
||||
|
||||
# Linking to non-existent file is not desirable. At best you will have a
|
||||
# dangling link, but when building in tree, this can create a symbolic link
|
||||
# to itself.
|
||||
if (EXISTS ${target} AND NOT EXISTS ${link})
|
||||
if (CMAKE_HOST_UNIX)
|
||||
execute_process(COMMAND ln -s ${target} ${link}
|
||||
RESULT_VARIABLE result
|
||||
ERROR_VARIABLE output)
|
||||
|
||||
if (NOT ${result} EQUAL 0)
|
||||
message(FATAL_ERROR "Could not create symbolic link for: ${target} --> ${output}")
|
||||
endif()
|
||||
else()
|
||||
if (IS_DIRECTORY ${target})
|
||||
file(GLOB_RECURSE files FOLLOW_SYMLINKS LIST_DIRECTORIES false RELATIVE ${target} "${target}/*")
|
||||
foreach(file IN LISTS files)
|
||||
configure_file("${target}/${file}" "${link}/${file}" COPYONLY)
|
||||
endforeach(file)
|
||||
else()
|
||||
configure_file(${target} ${link} COPYONLY)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endfunction(link_to_source)
|
||||
|
||||
# Get the filename without the final extension (i.e. convert "a.b.c" to "a.b")
|
||||
function(get_name_without_last_ext dest_var full_name)
|
||||
# Split into a list on '.' (but a cmake list is just a ';'-separated string)
|
||||
string(REPLACE "." ";" ext_parts "${full_name}")
|
||||
# Remove the last item if there are more than one
|
||||
list(LENGTH ext_parts ext_parts_len)
|
||||
if (${ext_parts_len} GREATER "1")
|
||||
math(EXPR ext_parts_last_item "${ext_parts_len} - 1")
|
||||
list(REMOVE_AT ext_parts ${ext_parts_last_item})
|
||||
endif()
|
||||
# Convert back to a string by replacing separators with '.'
|
||||
string(REPLACE ";" "." no_ext_name "${ext_parts}")
|
||||
# Copy into the desired variable
|
||||
set(${dest_var} ${no_ext_name} PARENT_SCOPE)
|
||||
endfunction(get_name_without_last_ext)
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
|
||||
function(set_base_compile_options target)
|
||||
if(CMAKE_COMPILER_IS_GNU)
|
||||
set_gnu_base_compile_options(${target})
|
||||
elseif(CMAKE_COMPILER_IS_CLANG)
|
||||
set_clang_base_compile_options(${target})
|
||||
elseif(CMAKE_COMPILER_IS_IAR)
|
||||
set_iar_base_compile_options(${target})
|
||||
elseif(CMAKE_COMPILER_IS_MSVC)
|
||||
set_msvc_base_compile_options(${target})
|
||||
endif()
|
||||
endfunction(set_base_compile_options)
|
||||
|
||||
function(set_gnu_base_compile_options target)
|
||||
# some warnings we want are not available with old GCC versions
|
||||
# note: starting with CMake 2.8 we could use CMAKE_C_COMPILER_VERSION
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
||||
OUTPUT_VARIABLE GCC_VERSION)
|
||||
target_compile_options(${target} PRIVATE -Wall -Wextra -Wwrite-strings -Wmissing-prototypes)
|
||||
if (GCC_VERSION VERSION_GREATER 3.0 OR GCC_VERSION VERSION_EQUAL 3.0)
|
||||
target_compile_options(${target} PRIVATE -Wformat=2 -Wno-format-nonliteral)
|
||||
endif()
|
||||
if (GCC_VERSION VERSION_GREATER 4.3 OR GCC_VERSION VERSION_EQUAL 4.3)
|
||||
target_compile_options(${target} PRIVATE -Wvla)
|
||||
endif()
|
||||
if (GCC_VERSION VERSION_GREATER 4.5 OR GCC_VERSION VERSION_EQUAL 4.5)
|
||||
target_compile_options(${target} PRIVATE -Wlogical-op)
|
||||
endif()
|
||||
if (GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
|
||||
target_compile_options(${target} PRIVATE -Wshadow)
|
||||
endif()
|
||||
if (GCC_VERSION VERSION_GREATER 5.0)
|
||||
CHECK_C_COMPILER_FLAG("-Wformat-signedness" C_COMPILER_SUPPORTS_WFORMAT_SIGNEDNESS)
|
||||
if(C_COMPILER_SUPPORTS_WFORMAT_SIGNEDNESS)
|
||||
target_compile_options(${target} PRIVATE -Wformat-signedness)
|
||||
endif()
|
||||
endif()
|
||||
if (GCC_VERSION VERSION_GREATER 7.0 OR GCC_VERSION VERSION_EQUAL 7.0)
|
||||
target_compile_options(${target} PRIVATE -Wformat-overflow=2 -Wformat-truncation)
|
||||
endif()
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:Release>:-O2>)
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:Debug>:-O0 -g3>)
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:Coverage>:-O0 -g3 --coverage>)
|
||||
set_target_properties(${target} PROPERTIES LINK_FLAGS_COVERAGE "--coverage")
|
||||
# Old GCC versions hit a performance problem with test_suite_pkwrite
|
||||
# "Private keey write check EC" tests when building with Asan+UBSan
|
||||
# and -O3: those tests take more than 100x time than normal, with
|
||||
# test_suite_pkwrite taking >3h on the CI. Observed with GCC 5.4 on
|
||||
# Ubuntu 16.04 x86_64 and GCC 6.5 on Ubuntu 18.04 x86_64.
|
||||
# GCC 7.5 and above on Ubuntu 18.04 appear fine.
|
||||
# To avoid the performance problem, we use -O2 when GCC version is lower than 7.0.
|
||||
# It doesn't slow down much even with modern compiler versions.
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:ASan>:-fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all>)
|
||||
if (GCC_VERSION VERSION_LESS 7.0)
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:ASan>:-O2>)
|
||||
else()
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:ASan>:-O3>)
|
||||
endif()
|
||||
set_target_properties(${target} PROPERTIES LINK_FLAGS_ASAN "-fsanitize=address -fsanitize=undefined")
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:ASanDbg>:-fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls>)
|
||||
set_target_properties(${target} PROPERTIES LINK_FLAGS_ASANDBG "-fsanitize=address -fsanitize=undefined")
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:TSan>:-fsanitize=thread -O3>)
|
||||
set_target_properties(${target} PROPERTIES LINK_FLAGS_TSAN "-fsanitize=thread")
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:TSanDbg>:-fsanitize=thread -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls>)
|
||||
set_target_properties(${target} PROPERTIES LINK_FLAGS_TSANDBG "-fsanitize=thread")
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:Check>:-Os>)
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:CheckFull>:-Os -Wcast-qual>)
|
||||
|
||||
if(TF_PSA_CRYPTO_FATAL_WARNINGS)
|
||||
target_compile_options(${target} PRIVATE -Werror)
|
||||
endif(TF_PSA_CRYPTO_FATAL_WARNINGS)
|
||||
endfunction(set_gnu_base_compile_options)
|
||||
|
||||
function(set_clang_base_compile_options target)
|
||||
target_compile_options(${target} PRIVATE -Wall -Wextra -Wwrite-strings -Wmissing-prototypes -Wpointer-arith -Wimplicit-fallthrough -Wshadow -Wvla -Wformat=2 -Wno-format-nonliteral)
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:Release>:-O2>)
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:Debug>:-O0 -g3>)
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:Coverage>:-O0 -g3 --coverage>)
|
||||
set_target_properties(${target} PROPERTIES LINK_FLAGS_COVERAGE "--coverage")
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:ASan>:-fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O3>)
|
||||
set_target_properties(${target} PROPERTIES LINK_FLAGS_ASAN "-fsanitize=address -fsanitize=undefined")
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:ASanDbg>:-fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls>)
|
||||
set_target_properties(${target} PROPERTIES LINK_FLAGS_ASANDBG "-fsanitize=address -fsanitize=undefined")
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:MemSan>:-fsanitize=memory>)
|
||||
set_target_properties(${target} PROPERTIES LINK_FLAGS_MEMSAN "-fsanitize=memory")
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:MemSanDbg>:-fsanitize=memory -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2>)
|
||||
set_target_properties(${target} PROPERTIES LINK_FLAGS_MEMSANDBG "-fsanitize=memory")
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:TSan>:-fsanitize=thread -O3>)
|
||||
set_target_properties(${target} PROPERTIES LINK_FLAGS_TSAN "-fsanitize=thread")
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:TSanDbg>:-fsanitize=thread -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls>)
|
||||
set_target_properties(${target} PROPERTIES LINK_FLAGS_TSANDBG "-fsanitize=thread")
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:Check>:-Os>)
|
||||
|
||||
if(MBEDTLS_FATAL_WARNINGS)
|
||||
target_compile_options(${target} PRIVATE -Werror)
|
||||
endif(MBEDTLS_FATAL_WARNINGS)
|
||||
endfunction(set_clang_base_compile_options)
|
||||
|
||||
function(set_iar_base_compile_options target)
|
||||
target_compile_options(${target} PRIVATE --warn_about_c_style_casts)
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:Release>:-Ohz>)
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:Debug>:--debug -On>)
|
||||
|
||||
if(MBEDTLS_FATAL_WARNINGS)
|
||||
target_compile_options(${target} PRIVATE --warnings_are_errors)
|
||||
endif(MBEDTLS_FATAL_WARNINGS)
|
||||
endfunction(set_iar_base_compile_options)
|
||||
|
||||
function(set_msvc_base_compile_options target)
|
||||
# Strictest warnings, UTF-8 source and execution charset
|
||||
target_compile_options(${target} PRIVATE /W3 /utf-8)
|
||||
|
||||
if(MBEDTLS_FATAL_WARNINGS)
|
||||
target_compile_options(${target} PRIVATE /WX)
|
||||
endif(MBEDTLS_FATAL_WARNINGS)
|
||||
endfunction(set_msvc_base_compile_options)
|
||||
|
||||
function(set_config_files_compile_definitions target)
|
||||
# Pass-through MBEDTLS_CONFIG_FILE, MBEDTLS_USER_CONFIG_FILE,
|
||||
# TF_PSA_CRYPTO_CONFIG_FILE and TF_PSA_CRYPTO_USER_CONFIG_FILE
|
||||
if(MBEDTLS_CONFIG_FILE)
|
||||
target_compile_definitions(${target}
|
||||
PUBLIC MBEDTLS_CONFIG_FILE="${MBEDTLS_CONFIG_FILE}")
|
||||
endif()
|
||||
if(MBEDTLS_USER_CONFIG_FILE)
|
||||
target_compile_definitions(${target}
|
||||
PUBLIC MBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}")
|
||||
endif()
|
||||
if(TF_PSA_CRYPTO_CONFIG_FILE)
|
||||
target_compile_definitions(${target}
|
||||
PUBLIC TF_PSA_CRYPTO_CONFIG_FILE="${TF_PSA_CRYPTO_CONFIG_FILE}")
|
||||
endif()
|
||||
if(TF_PSA_CRYPTO_USER_CONFIG_FILE)
|
||||
target_compile_definitions(${target}
|
||||
PUBLIC TF_PSA_CRYPTO_USER_CONFIG_FILE="${TF_PSA_CRYPTO_USER_CONFIG_FILE}")
|
||||
endif()
|
||||
endfunction(set_config_files_compile_definitions)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Check" AND TEST_CPP)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
if(CMAKE_COMPILER_IS_CLANG OR CMAKE_COMPILER_IS_GNU)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT EXISTS "${TF_PSA_CRYPTO_FRAMEWORK_DIR}/CMakeLists.txt")
|
||||
message(FATAL_ERROR "${TF_PSA_CRYPTO_FRAMEWORK_DIR}/CMakeLists.txt not found. Run `git submodule update --init` from the source tree to fetch the submodule contents.")
|
||||
endif()
|
||||
|
||||
add_subdirectory(include)
|
||||
add_subdirectory(core)
|
||||
add_subdirectory(drivers)
|
||||
add_subdirectory(pkgconfig)
|
||||
|
||||
#
|
||||
# The C files in tests/src directory contain test code shared among test suites
|
||||
# and programs. This shared test code is compiled and linked to test suites and
|
||||
# programs objects as a set of compiled objects. The compiled objects are NOT
|
||||
# built into a library that the test suite and program objects would link
|
||||
# against as they link against the tfpsacrypto library. The reason is that such
|
||||
# library is expected to have mutual dependencies with the aforementioned
|
||||
# library and that there is as of today no portable way of handling such
|
||||
# dependencies (only toolchain specific solutions).
|
||||
#
|
||||
# Thus the below definition of the `tf_psa_crypto_test` CMake library of
|
||||
# objects target. This library of objects is used by tests and programs CMake
|
||||
# files to define the test executables.
|
||||
#
|
||||
if(ENABLE_TESTING OR ENABLE_PROGRAMS)
|
||||
file(GLOB TF_PSA_CRYPTO_TEST_FILES
|
||||
${TF_PSA_CRYPTO_FRAMEWORK_DIR}/tests/src/*.c
|
||||
${TF_PSA_CRYPTO_FRAMEWORK_DIR}/tests/src/drivers/*.c
|
||||
tests/src/*.c)
|
||||
add_library(tf_psa_crypto_test OBJECT ${TF_PSA_CRYPTO_TEST_FILES})
|
||||
set_base_compile_options(tf_psa_crypto_test)
|
||||
if(GEN_FILES)
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${TF_PSA_CRYPTO_FRAMEWORK_DIR}/tests/include/test/test_keys.h
|
||||
COMMAND
|
||||
"${TF_PSA_CRYPTO_PYTHON_EXECUTABLE}"
|
||||
"${TF_PSA_CRYPTO_FRAMEWORK_DIR}/scripts/generate_test_keys.py"
|
||||
"--output"
|
||||
"${TF_PSA_CRYPTO_FRAMEWORK_DIR}/tests/include/test/test_keys.h"
|
||||
DEPENDS
|
||||
${TF_PSA_CRYPTO_FRAMEWORK_DIR}/scripts/generate_test_keys.py
|
||||
)
|
||||
add_custom_target(tf_psa_crypto_test_keys_header
|
||||
DEPENDS ${TF_PSA_CRYPTO_FRAMEWORK_DIR}/tests/include/test/test_keys.h)
|
||||
add_dependencies(tf_psa_crypto_test tf_psa_crypto_test_keys_header)
|
||||
endif()
|
||||
|
||||
file(WRITE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/seedfile
|
||||
"This is a seedfile that contains 64 bytes ......................"
|
||||
)
|
||||
|
||||
target_include_directories(tf_psa_crypto_test
|
||||
PRIVATE ${TF_PSA_CRYPTO_FRAMEWORK_DIR}/tests/include
|
||||
PRIVATE tests/include
|
||||
PRIVATE include
|
||||
PRIVATE drivers/builtin/include
|
||||
PRIVATE drivers/everest/include
|
||||
PRIVATE core
|
||||
PRIVATE drivers/builtin/src)
|
||||
# Request C11, needed for memory poisoning tests
|
||||
set_target_properties(tf_psa_crypto_test PROPERTIES C_STANDARD 11)
|
||||
set_config_files_compile_definitions(tf_psa_crypto_test)
|
||||
endif()
|
||||
|
||||
if(ENABLE_PROGRAMS)
|
||||
add_subdirectory(programs)
|
||||
endif()
|
||||
|
||||
if(ENABLE_TESTING)
|
||||
enable_testing()
|
||||
|
||||
add_subdirectory(tests)
|
||||
|
||||
# additional convenience targets for Unix only
|
||||
if(UNIX AND (NOT TF_PSA_CRYPTO_AS_SUBPROJECT))
|
||||
# For coverage testing:
|
||||
# 1. Build with:
|
||||
# cmake -D CMAKE_BUILD_TYPE=Coverage /path/to/source && make
|
||||
# 2. Run the relevant tests for the part of the code you're interested in.
|
||||
# For the reference coverage measurement, see
|
||||
# tests/scripts/basic-build-test.sh
|
||||
# 3. Run scripts/lcov.sh to generate an HTML report.
|
||||
ADD_CUSTOM_TARGET(lcov
|
||||
COMMAND ${MBEDTLS_DIR}/scripts/lcov.sh
|
||||
)
|
||||
|
||||
ADD_CUSTOM_TARGET(memcheck
|
||||
COMMAND sed -i.bak s+/usr/bin/valgrind+`which valgrind`+ DartConfiguration.tcl
|
||||
COMMAND ctest -O memcheck.log -D ExperimentalMemCheck
|
||||
COMMAND tail -n1 memcheck.log | grep 'Memory checking results:' > /dev/null
|
||||
COMMAND rm -f memcheck.log
|
||||
COMMAND mv DartConfiguration.tcl.bak DartConfiguration.tcl
|
||||
)
|
||||
endif()
|
||||
|
||||
# Make scripts needed for testing available in an out-of-source build.
|
||||
if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
link_to_source(scripts)
|
||||
# Copy (don't link) DartConfiguration.tcl, needed for memcheck, to
|
||||
# keep things simple with the sed commands in the memcheck target.
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/DartConfiguration.tcl
|
||||
${CMAKE_CURRENT_BINARY_DIR}/DartConfiguration.tcl COPYONLY)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT DISABLE_PACKAGE_CONFIG_AND_INSTALL)
|
||||
configure_package_config_file(
|
||||
"cmake/TF-PSA-CryptoConfig.cmake.in"
|
||||
"cmake/TF-PSA-CryptoConfig.cmake"
|
||||
INSTALL_DESTINATION "cmake")
|
||||
|
||||
write_basic_package_version_file(
|
||||
"cmake/TF-PSA-CryptoConfigVersion.cmake"
|
||||
COMPATIBILITY SameMajorVersion
|
||||
VERSION 0.1.0)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/TF-PSA-CryptoConfig.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake/TF-PSA-CryptoConfigVersion.cmake"
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/TF-PSA-Crypto")
|
||||
|
||||
export(
|
||||
EXPORT TF-PSA-CryptoTargets
|
||||
NAMESPACE TF-PSA-Crypto::
|
||||
FILE "cmake/TF-PSA-CryptoTargets.cmake")
|
||||
|
||||
install(
|
||||
EXPORT TF-PSA-CryptoTargets
|
||||
NAMESPACE TF-PSA-Crypto::
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/TF-PSA-Crypto"
|
||||
FILE "TF-PSA-CryptoTargets.cmake")
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.15 OR CMAKE_VERSION VERSION_EQUAL 3.15)
|
||||
# Do not export the package by default
|
||||
cmake_policy(SET CMP0090 NEW)
|
||||
|
||||
# Make this package visible to the system
|
||||
export(PACKAGE TF-PSA-Crypto)
|
||||
endif()
|
||||
endif()
|
||||
@@ -1,4 +0,0 @@
|
||||
Site: localhost
|
||||
BuildName: Mbed TLS-test
|
||||
CoverageCommand: /usr/bin/gcov
|
||||
MemoryCheckCommand: /usr/bin/valgrind
|
||||
1
tf-psa-crypto/cmake/.gitignore
vendored
1
tf-psa-crypto/cmake/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
TF-PSA-CryptoConfig.cmake
|
||||
@@ -1,3 +0,0 @@
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/TF-PSA-CryptoTargets.cmake")
|
||||
4
tf-psa-crypto/core/.gitignore
vendored
4
tf-psa-crypto/core/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
###START_GENERATED_FILES###
|
||||
/psa_crypto_driver_wrappers.h
|
||||
/psa_crypto_driver_wrappers_no_static.c
|
||||
###END_GENERATED_FILES###
|
||||
@@ -1,157 +0,0 @@
|
||||
set(src_crypto
|
||||
psa_crypto.c
|
||||
psa_crypto_client.c
|
||||
psa_crypto_driver_wrappers_no_static.c
|
||||
psa_crypto_se.c
|
||||
psa_crypto_slot_management.c
|
||||
psa_crypto_storage.c
|
||||
psa_its_file.c
|
||||
)
|
||||
|
||||
if(GEN_FILES)
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${CMAKE_CURRENT_BINARY_DIR}/psa_crypto_driver_wrappers.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/psa_crypto_driver_wrappers_no_static.c
|
||||
COMMAND
|
||||
${TF_PSA_CRYPTO_PYTHON_EXECUTABLE}
|
||||
${TF_PSA_CRYPTO_DIR}/scripts/generate_driver_wrappers.py
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS
|
||||
${TF_PSA_CRYPTO_DIR}/scripts/generate_driver_wrappers.py
|
||||
${TF_PSA_CRYPTO_DIR}/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja
|
||||
${TF_PSA_CRYPTO_DIR}/scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja
|
||||
)
|
||||
else()
|
||||
link_to_source(psa_crypto_driver_wrappers.h)
|
||||
link_to_source(psa_crypto_driver_wrappers_no_static.c)
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
set(LIBS_C_FLAGS -Wmissing-declarations -Wmissing-prototypes)
|
||||
endif(CMAKE_COMPILER_IS_GNUCC)
|
||||
|
||||
if(CMAKE_COMPILER_IS_CLANG)
|
||||
set(LIBS_C_FLAGS -Wmissing-declarations -Wmissing-prototypes -Wdocumentation -Wno-documentation-deprecated-sync -Wunreachable-code)
|
||||
endif(CMAKE_COMPILER_IS_CLANG)
|
||||
|
||||
if(CMAKE_COMPILER_IS_MSVC)
|
||||
option(MSVC_STATIC_RUNTIME "Build the libraries with /MT compiler flag" OFF)
|
||||
if(MSVC_STATIC_RUNTIME)
|
||||
foreach(flag_var
|
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_C_FLAGS_CHECK)
|
||||
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
||||
endforeach(flag_var)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang")
|
||||
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
|
||||
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
||||
endif()
|
||||
|
||||
if(LINK_WITH_PTHREAD)
|
||||
set(libs ${libs} ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
|
||||
if(LINK_WITH_TRUSTED_STORAGE)
|
||||
set(libs ${libs} trusted_storage)
|
||||
endif()
|
||||
|
||||
if (NOT USE_STATIC_TF_PSA_CRYPTO_LIBRARY AND NOT USE_SHARED_TF_PSA_CRYPTO_LIBRARY)
|
||||
message(FATAL_ERROR "Need to choose static or shared TF-PSA-Crypto build!")
|
||||
endif(NOT USE_STATIC_TF_PSA_CRYPTO_LIBRARY AND NOT USE_SHARED_TF_PSA_CRYPTO_LIBRARY)
|
||||
|
||||
set(tfpsacrypto_target "${TF_PSA_CRYPTO_TARGET_PREFIX}tfpsacrypto")
|
||||
set(builtin_target "${TF_PSA_CRYPTO_TARGET_PREFIX}builtin")
|
||||
|
||||
if (USE_STATIC_TF_PSA_CRYPTO_LIBRARY)
|
||||
set(tfpsacrypto_static_target ${tfpsacrypto_target})
|
||||
set(builtin_static_target ${builtin_target})
|
||||
endif()
|
||||
|
||||
set(target_libraries ${tfpsacrypto_target})
|
||||
|
||||
if(USE_STATIC_TF_PSA_CRYPTO_LIBRARY AND USE_SHARED_TF_PSA_CRYPTO_LIBRARY)
|
||||
string(APPEND tfpsacrypto_static_target "_static")
|
||||
string(APPEND builtin_static_target "_static")
|
||||
|
||||
list(APPEND target_libraries
|
||||
${tfpsacrypto_static_target})
|
||||
endif()
|
||||
|
||||
set(p256m_target "${TF_PSA_CRYPTO_TARGET_PREFIX}p256m")
|
||||
set(everest_target "${TF_PSA_CRYPTO_TARGET_PREFIX}everest")
|
||||
|
||||
if(USE_STATIC_TF_PSA_CRYPTO_LIBRARY)
|
||||
add_library(${tfpsacrypto_static_target} STATIC ${src_crypto})
|
||||
set_base_compile_options(${tfpsacrypto_static_target})
|
||||
target_compile_options(${tfpsacrypto_static_target} PRIVATE ${LIBS_C_FLAGS})
|
||||
set_target_properties(${tfpsacrypto_static_target} PROPERTIES OUTPUT_NAME tfpsacrypto)
|
||||
target_link_libraries(${tfpsacrypto_static_target} PUBLIC ${libs})
|
||||
|
||||
target_link_libraries(${tfpsacrypto_static_target} PUBLIC ${builtin_static_target})
|
||||
|
||||
if(TARGET ${everest_target})
|
||||
target_link_libraries(${tfpsacrypto_static_target} PUBLIC ${everest_target})
|
||||
endif()
|
||||
|
||||
if(TARGET ${p256m_target})
|
||||
target_link_libraries(${tfpsacrypto_static_target} PUBLIC ${p256m_target})
|
||||
endif()
|
||||
endif(USE_STATIC_TF_PSA_CRYPTO_LIBRARY)
|
||||
|
||||
if(USE_SHARED_TF_PSA_CRYPTO_LIBRARY)
|
||||
set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR})
|
||||
add_library(${tfpsacrypto_target} SHARED ${src_crypto})
|
||||
set_base_compile_options(${tfpsacrypto_target})
|
||||
target_compile_options(${tfpsacrypto_target} PRIVATE ${LIBS_C_FLAGS})
|
||||
set_target_properties(${tfpsacrypto_target} PROPERTIES VERSION 4.0.0 SOVERSION 16)
|
||||
target_link_libraries(${tfpsacrypto_target} PUBLIC ${libs})
|
||||
|
||||
target_link_libraries(${tfpsacrypto_target} PUBLIC ${builtin_target})
|
||||
|
||||
if(TARGET ${everest_target})
|
||||
target_link_libraries(${tfpsacrypto_target} PUBLIC ${everest_target})
|
||||
endif()
|
||||
|
||||
if(TARGET ${p256m_target})
|
||||
target_link_libraries(${tfpsacrypto_target} PUBLIC ${p256m_target})
|
||||
endif()
|
||||
endif(USE_SHARED_TF_PSA_CRYPTO_LIBRARY)
|
||||
|
||||
foreach(target IN LISTS target_libraries)
|
||||
add_library(TF-PSA-Crypto::${target} ALIAS ${target}) # add_subdirectory support
|
||||
# Include public header files include/, drivers/builtin/include/ and
|
||||
# ${MBEDTLS_DIR}/include/ as we still need it. Include private header files
|
||||
# from core/ and drivers/builtin/src/.
|
||||
target_include_directories(${target}
|
||||
PUBLIC $<BUILD_INTERFACE:${TF_PSA_CRYPTO_DIR}/include/>
|
||||
$<BUILD_INTERFACE:${TF_PSA_CRYPTO_DIR}/drivers/builtin/include/>
|
||||
$<INSTALL_INTERFACE:include/>
|
||||
PRIVATE ${TF_PSA_CRYPTO_DIR}/core
|
||||
${TF_PSA_CRYPTO_DIR}/drivers/builtin/src
|
||||
# Needed to include psa_crypto_driver_wrappers.h
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
set_config_files_compile_definitions(${target})
|
||||
install(
|
||||
TARGETS ${target}
|
||||
EXPORT MbedTLSTargets
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
|
||||
install(
|
||||
TARGETS ${target}
|
||||
EXPORT TF-PSA-CryptoTargets
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
|
||||
endforeach(target)
|
||||
@@ -1,684 +0,0 @@
|
||||
/**
|
||||
* \file alignment.h
|
||||
*
|
||||
* \brief Utility code for dealing with unaligned memory accesses
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_LIBRARY_ALIGNMENT_H
|
||||
#define MBEDTLS_LIBRARY_ALIGNMENT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS for architectures where unaligned memory
|
||||
* accesses are known to be efficient.
|
||||
*
|
||||
* All functions defined here will behave correctly regardless, but might be less
|
||||
* efficient when this is not defined.
|
||||
*/
|
||||
#if defined(__ARM_FEATURE_UNALIGNED) \
|
||||
|| defined(MBEDTLS_ARCH_IS_X86) || defined(MBEDTLS_ARCH_IS_X64) \
|
||||
|| defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
|
||||
/*
|
||||
* __ARM_FEATURE_UNALIGNED is defined where appropriate by armcc, gcc 7, clang 9
|
||||
* (and later versions) for Arm v7 and later; all x86 platforms should have
|
||||
* efficient unaligned access.
|
||||
*
|
||||
* https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#alignment
|
||||
* specifies that on Windows-on-Arm64, unaligned access is safe (except for uncached
|
||||
* device memory).
|
||||
*/
|
||||
#define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS
|
||||
#endif
|
||||
|
||||
#if defined(__IAR_SYSTEMS_ICC__) && \
|
||||
(defined(MBEDTLS_ARCH_IS_ARM64) || defined(MBEDTLS_ARCH_IS_ARM32) \
|
||||
|| defined(__ICCRX__) || defined(__ICCRL78__) || defined(__ICCRISCV__))
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
#define MBEDTLS_POP_IAR_LANGUAGE_PRAGMA
|
||||
/* IAR recommend this technique for accessing unaligned data in
|
||||
* https://www.iar.com/knowledge/support/technical-notes/compiler/accessing-unaligned-data
|
||||
* This results in a single load / store instruction (if unaligned access is supported).
|
||||
* According to that document, this is only supported on certain architectures.
|
||||
*/
|
||||
#define UINT_UNALIGNED
|
||||
typedef uint16_t __packed mbedtls_uint16_unaligned_t;
|
||||
typedef uint32_t __packed mbedtls_uint32_unaligned_t;
|
||||
typedef uint64_t __packed mbedtls_uint64_unaligned_t;
|
||||
#elif defined(MBEDTLS_COMPILER_IS_GCC) && (MBEDTLS_GCC_VERSION >= 40504) && \
|
||||
((MBEDTLS_GCC_VERSION < 60300) || (!defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)))
|
||||
/*
|
||||
* gcc may generate a branch to memcpy for calls like `memcpy(dest, src, 4)` rather than
|
||||
* generating some LDR or LDRB instructions (similar for stores).
|
||||
*
|
||||
* This is architecture dependent: x86-64 seems fine even with old gcc; 32-bit Arm
|
||||
* is affected. To keep it simple, we enable for all architectures.
|
||||
*
|
||||
* For versions of gcc < 5.4.0 this issue always happens.
|
||||
* For gcc < 6.3.0, this issue happens at -O0
|
||||
* For all versions, this issue happens iff unaligned access is not supported.
|
||||
*
|
||||
* For gcc 4.x, this implementation will generate byte-by-byte loads even if unaligned access is
|
||||
* supported, which is correct but not optimal.
|
||||
*
|
||||
* For performance (and code size, in some cases), we want to avoid the branch and just generate
|
||||
* some inline load/store instructions since the access is small and constant-size.
|
||||
*
|
||||
* The manual states:
|
||||
* "The packed attribute specifies that a variable or structure field should have the smallest
|
||||
* possible alignment—one byte for a variable"
|
||||
* https://gcc.gnu.org/onlinedocs/gcc-4.5.4/gcc/Variable-Attributes.html
|
||||
*
|
||||
* Previous implementations used __attribute__((__aligned__(1)), but had issues with a gcc bug:
|
||||
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94662
|
||||
*
|
||||
* Tested with several versions of GCC from 4.5.0 up to 13.2.0
|
||||
* We don't enable for older than 4.5.0 as this has not been tested.
|
||||
*/
|
||||
#define UINT_UNALIGNED_STRUCT
|
||||
typedef struct {
|
||||
uint16_t x;
|
||||
} __attribute__((packed)) mbedtls_uint16_unaligned_t;
|
||||
typedef struct {
|
||||
uint32_t x;
|
||||
} __attribute__((packed)) mbedtls_uint32_unaligned_t;
|
||||
typedef struct {
|
||||
uint64_t x;
|
||||
} __attribute__((packed)) mbedtls_uint64_unaligned_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We try to force mbedtls_(get|put)_unaligned_uintXX to be always inline, because this results
|
||||
* in code that is both smaller and faster. IAR and gcc both benefit from this when optimising
|
||||
* for size.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Read the unsigned 16 bits integer from the given address, which need not
|
||||
* be aligned.
|
||||
*
|
||||
* \param p pointer to 2 bytes of data
|
||||
* \return Data at the given address
|
||||
*/
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma inline = forced
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
static inline uint16_t mbedtls_get_unaligned_uint16(const void *p)
|
||||
{
|
||||
uint16_t r;
|
||||
#if defined(UINT_UNALIGNED)
|
||||
mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
|
||||
r = *p16;
|
||||
#elif defined(UINT_UNALIGNED_STRUCT)
|
||||
mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
|
||||
r = p16->x;
|
||||
#else
|
||||
memcpy(&r, p, sizeof(r));
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the unsigned 16 bits integer to the given address, which need not
|
||||
* be aligned.
|
||||
*
|
||||
* \param p pointer to 2 bytes of data
|
||||
* \param x data to write
|
||||
*/
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma inline = forced
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
static inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x)
|
||||
{
|
||||
#if defined(UINT_UNALIGNED)
|
||||
mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
|
||||
*p16 = x;
|
||||
#elif defined(UINT_UNALIGNED_STRUCT)
|
||||
mbedtls_uint16_unaligned_t *p16 = (mbedtls_uint16_unaligned_t *) p;
|
||||
p16->x = x;
|
||||
#else
|
||||
memcpy(p, &x, sizeof(x));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the unsigned 32 bits integer from the given address, which need not
|
||||
* be aligned.
|
||||
*
|
||||
* \param p pointer to 4 bytes of data
|
||||
* \return Data at the given address
|
||||
*/
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma inline = forced
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
static inline uint32_t mbedtls_get_unaligned_uint32(const void *p)
|
||||
{
|
||||
uint32_t r;
|
||||
#if defined(UINT_UNALIGNED)
|
||||
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
|
||||
r = *p32;
|
||||
#elif defined(UINT_UNALIGNED_STRUCT)
|
||||
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
|
||||
r = p32->x;
|
||||
#else
|
||||
memcpy(&r, p, sizeof(r));
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the unsigned 32 bits integer to the given address, which need not
|
||||
* be aligned.
|
||||
*
|
||||
* \param p pointer to 4 bytes of data
|
||||
* \param x data to write
|
||||
*/
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma inline = forced
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
static inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x)
|
||||
{
|
||||
#if defined(UINT_UNALIGNED)
|
||||
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
|
||||
*p32 = x;
|
||||
#elif defined(UINT_UNALIGNED_STRUCT)
|
||||
mbedtls_uint32_unaligned_t *p32 = (mbedtls_uint32_unaligned_t *) p;
|
||||
p32->x = x;
|
||||
#else
|
||||
memcpy(p, &x, sizeof(x));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the unsigned 64 bits integer from the given address, which need not
|
||||
* be aligned.
|
||||
*
|
||||
* \param p pointer to 8 bytes of data
|
||||
* \return Data at the given address
|
||||
*/
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma inline = forced
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
static inline uint64_t mbedtls_get_unaligned_uint64(const void *p)
|
||||
{
|
||||
uint64_t r;
|
||||
#if defined(UINT_UNALIGNED)
|
||||
mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
|
||||
r = *p64;
|
||||
#elif defined(UINT_UNALIGNED_STRUCT)
|
||||
mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
|
||||
r = p64->x;
|
||||
#else
|
||||
memcpy(&r, p, sizeof(r));
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the unsigned 64 bits integer to the given address, which need not
|
||||
* be aligned.
|
||||
*
|
||||
* \param p pointer to 8 bytes of data
|
||||
* \param x data to write
|
||||
*/
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma inline = forced
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
static inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x)
|
||||
{
|
||||
#if defined(UINT_UNALIGNED)
|
||||
mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
|
||||
*p64 = x;
|
||||
#elif defined(UINT_UNALIGNED_STRUCT)
|
||||
mbedtls_uint64_unaligned_t *p64 = (mbedtls_uint64_unaligned_t *) p;
|
||||
p64->x = x;
|
||||
#else
|
||||
memcpy(p, &x, sizeof(x));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_POP_IAR_LANGUAGE_PRAGMA)
|
||||
#pragma language=restore
|
||||
#endif
|
||||
|
||||
/** Byte Reading Macros
|
||||
*
|
||||
* Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th
|
||||
* byte from x, where byte 0 is the least significant byte.
|
||||
*/
|
||||
#define MBEDTLS_BYTE_0(x) ((uint8_t) ((x) & 0xff))
|
||||
#define MBEDTLS_BYTE_1(x) ((uint8_t) (((x) >> 8) & 0xff))
|
||||
#define MBEDTLS_BYTE_2(x) ((uint8_t) (((x) >> 16) & 0xff))
|
||||
#define MBEDTLS_BYTE_3(x) ((uint8_t) (((x) >> 24) & 0xff))
|
||||
#define MBEDTLS_BYTE_4(x) ((uint8_t) (((x) >> 32) & 0xff))
|
||||
#define MBEDTLS_BYTE_5(x) ((uint8_t) (((x) >> 40) & 0xff))
|
||||
#define MBEDTLS_BYTE_6(x) ((uint8_t) (((x) >> 48) & 0xff))
|
||||
#define MBEDTLS_BYTE_7(x) ((uint8_t) (((x) >> 56) & 0xff))
|
||||
|
||||
/*
|
||||
* Detect GCC built-in byteswap routines
|
||||
*/
|
||||
#if defined(__GNUC__) && defined(__GNUC_PREREQ)
|
||||
#if __GNUC_PREREQ(4, 8)
|
||||
#define MBEDTLS_BSWAP16 __builtin_bswap16
|
||||
#endif /* __GNUC_PREREQ(4,8) */
|
||||
#if __GNUC_PREREQ(4, 3)
|
||||
#define MBEDTLS_BSWAP32 __builtin_bswap32
|
||||
#define MBEDTLS_BSWAP64 __builtin_bswap64
|
||||
#endif /* __GNUC_PREREQ(4,3) */
|
||||
#endif /* defined(__GNUC__) && defined(__GNUC_PREREQ) */
|
||||
|
||||
/*
|
||||
* Detect Clang built-in byteswap routines
|
||||
*/
|
||||
#if defined(__clang__) && defined(__has_builtin)
|
||||
#if __has_builtin(__builtin_bswap16) && !defined(MBEDTLS_BSWAP16)
|
||||
#define MBEDTLS_BSWAP16 __builtin_bswap16
|
||||
#endif /* __has_builtin(__builtin_bswap16) */
|
||||
#if __has_builtin(__builtin_bswap32) && !defined(MBEDTLS_BSWAP32)
|
||||
#define MBEDTLS_BSWAP32 __builtin_bswap32
|
||||
#endif /* __has_builtin(__builtin_bswap32) */
|
||||
#if __has_builtin(__builtin_bswap64) && !defined(MBEDTLS_BSWAP64)
|
||||
#define MBEDTLS_BSWAP64 __builtin_bswap64
|
||||
#endif /* __has_builtin(__builtin_bswap64) */
|
||||
#endif /* defined(__clang__) && defined(__has_builtin) */
|
||||
|
||||
/*
|
||||
* Detect MSVC built-in byteswap routines
|
||||
*/
|
||||
#if defined(_MSC_VER)
|
||||
#if !defined(MBEDTLS_BSWAP16)
|
||||
#define MBEDTLS_BSWAP16 _byteswap_ushort
|
||||
#endif
|
||||
#if !defined(MBEDTLS_BSWAP32)
|
||||
#define MBEDTLS_BSWAP32 _byteswap_ulong
|
||||
#endif
|
||||
#if !defined(MBEDTLS_BSWAP64)
|
||||
#define MBEDTLS_BSWAP64 _byteswap_uint64
|
||||
#endif
|
||||
#endif /* defined(_MSC_VER) */
|
||||
|
||||
/* Detect armcc built-in byteswap routine */
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 410000) && !defined(MBEDTLS_BSWAP32)
|
||||
#if defined(__ARM_ACLE) /* ARM Compiler 6 - earlier versions don't need a header */
|
||||
#include <arm_acle.h>
|
||||
#endif
|
||||
#define MBEDTLS_BSWAP32 __rev
|
||||
#endif
|
||||
|
||||
/* Detect IAR built-in byteswap routine */
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#if defined(__ARM_ACLE)
|
||||
#include <arm_acle.h>
|
||||
#define MBEDTLS_BSWAP16(x) ((uint16_t) __rev16((uint32_t) (x)))
|
||||
#define MBEDTLS_BSWAP32 __rev
|
||||
#define MBEDTLS_BSWAP64 __revll
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Where compiler built-ins are not present, fall back to C code that the
|
||||
* compiler may be able to detect and transform into the relevant bswap or
|
||||
* similar instruction.
|
||||
*/
|
||||
#if !defined(MBEDTLS_BSWAP16)
|
||||
static inline uint16_t mbedtls_bswap16(uint16_t x)
|
||||
{
|
||||
return
|
||||
(x & 0x00ff) << 8 |
|
||||
(x & 0xff00) >> 8;
|
||||
}
|
||||
#define MBEDTLS_BSWAP16 mbedtls_bswap16
|
||||
#endif /* !defined(MBEDTLS_BSWAP16) */
|
||||
|
||||
#if !defined(MBEDTLS_BSWAP32)
|
||||
static inline uint32_t mbedtls_bswap32(uint32_t x)
|
||||
{
|
||||
return
|
||||
(x & 0x000000ff) << 24 |
|
||||
(x & 0x0000ff00) << 8 |
|
||||
(x & 0x00ff0000) >> 8 |
|
||||
(x & 0xff000000) >> 24;
|
||||
}
|
||||
#define MBEDTLS_BSWAP32 mbedtls_bswap32
|
||||
#endif /* !defined(MBEDTLS_BSWAP32) */
|
||||
|
||||
#if !defined(MBEDTLS_BSWAP64)
|
||||
static inline uint64_t mbedtls_bswap64(uint64_t x)
|
||||
{
|
||||
return
|
||||
(x & 0x00000000000000ffULL) << 56 |
|
||||
(x & 0x000000000000ff00ULL) << 40 |
|
||||
(x & 0x0000000000ff0000ULL) << 24 |
|
||||
(x & 0x00000000ff000000ULL) << 8 |
|
||||
(x & 0x000000ff00000000ULL) >> 8 |
|
||||
(x & 0x0000ff0000000000ULL) >> 24 |
|
||||
(x & 0x00ff000000000000ULL) >> 40 |
|
||||
(x & 0xff00000000000000ULL) >> 56;
|
||||
}
|
||||
#define MBEDTLS_BSWAP64 mbedtls_bswap64
|
||||
#endif /* !defined(MBEDTLS_BSWAP64) */
|
||||
|
||||
#if !defined(__BYTE_ORDER__)
|
||||
|
||||
#if defined(__LITTLE_ENDIAN__)
|
||||
/* IAR defines __xxx_ENDIAN__, but not __BYTE_ORDER__ */
|
||||
#define MBEDTLS_IS_BIG_ENDIAN 0
|
||||
#elif defined(__BIG_ENDIAN__)
|
||||
#define MBEDTLS_IS_BIG_ENDIAN 1
|
||||
#else
|
||||
static const uint16_t mbedtls_byte_order_detector = { 0x100 };
|
||||
#define MBEDTLS_IS_BIG_ENDIAN (*((unsigned char *) (&mbedtls_byte_order_detector)) == 0x01)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#if (__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__)
|
||||
#define MBEDTLS_IS_BIG_ENDIAN 1
|
||||
#else
|
||||
#define MBEDTLS_IS_BIG_ENDIAN 0
|
||||
#endif
|
||||
|
||||
#endif /* !defined(__BYTE_ORDER__) */
|
||||
|
||||
/**
|
||||
* Get the unsigned 32 bits integer corresponding to four bytes in
|
||||
* big-endian order (MSB first).
|
||||
*
|
||||
* \param data Base address of the memory to get the four bytes from.
|
||||
* \param offset Offset from \p data of the first and most significant
|
||||
* byte of the four bytes to build the 32 bits unsigned
|
||||
* integer from.
|
||||
*/
|
||||
#define MBEDTLS_GET_UINT32_BE(data, offset) \
|
||||
((MBEDTLS_IS_BIG_ENDIAN) \
|
||||
? mbedtls_get_unaligned_uint32((data) + (offset)) \
|
||||
: MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Put in memory a 32 bits unsigned integer in big-endian order.
|
||||
*
|
||||
* \param n 32 bits unsigned integer to put in memory.
|
||||
* \param data Base address of the memory where to put the 32
|
||||
* bits unsigned integer in.
|
||||
* \param offset Offset from \p data where to put the most significant
|
||||
* byte of the 32 bits unsigned integer \p n.
|
||||
*/
|
||||
#define MBEDTLS_PUT_UINT32_BE(n, data, offset) \
|
||||
{ \
|
||||
if (MBEDTLS_IS_BIG_ENDIAN) \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint32((data) + (offset), (uint32_t) (n)); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t) (n))); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unsigned 32 bits integer corresponding to four bytes in
|
||||
* little-endian order (LSB first).
|
||||
*
|
||||
* \param data Base address of the memory to get the four bytes from.
|
||||
* \param offset Offset from \p data of the first and least significant
|
||||
* byte of the four bytes to build the 32 bits unsigned
|
||||
* integer from.
|
||||
*/
|
||||
#define MBEDTLS_GET_UINT32_LE(data, offset) \
|
||||
((MBEDTLS_IS_BIG_ENDIAN) \
|
||||
? MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \
|
||||
: mbedtls_get_unaligned_uint32((data) + (offset)) \
|
||||
)
|
||||
|
||||
|
||||
/**
|
||||
* Put in memory a 32 bits unsigned integer in little-endian order.
|
||||
*
|
||||
* \param n 32 bits unsigned integer to put in memory.
|
||||
* \param data Base address of the memory where to put the 32
|
||||
* bits unsigned integer in.
|
||||
* \param offset Offset from \p data where to put the least significant
|
||||
* byte of the 32 bits unsigned integer \p n.
|
||||
*/
|
||||
#define MBEDTLS_PUT_UINT32_LE(n, data, offset) \
|
||||
{ \
|
||||
if (MBEDTLS_IS_BIG_ENDIAN) \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t) (n))); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint32((data) + (offset), ((uint32_t) (n))); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unsigned 16 bits integer corresponding to two bytes in
|
||||
* little-endian order (LSB first).
|
||||
*
|
||||
* \param data Base address of the memory to get the two bytes from.
|
||||
* \param offset Offset from \p data of the first and least significant
|
||||
* byte of the two bytes to build the 16 bits unsigned
|
||||
* integer from.
|
||||
*/
|
||||
#define MBEDTLS_GET_UINT16_LE(data, offset) \
|
||||
((MBEDTLS_IS_BIG_ENDIAN) \
|
||||
? MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \
|
||||
: mbedtls_get_unaligned_uint16((data) + (offset)) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Put in memory a 16 bits unsigned integer in little-endian order.
|
||||
*
|
||||
* \param n 16 bits unsigned integer to put in memory.
|
||||
* \param data Base address of the memory where to put the 16
|
||||
* bits unsigned integer in.
|
||||
* \param offset Offset from \p data where to put the least significant
|
||||
* byte of the 16 bits unsigned integer \p n.
|
||||
*/
|
||||
#define MBEDTLS_PUT_UINT16_LE(n, data, offset) \
|
||||
{ \
|
||||
if (MBEDTLS_IS_BIG_ENDIAN) \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t) (n))); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unsigned 16 bits integer corresponding to two bytes in
|
||||
* big-endian order (MSB first).
|
||||
*
|
||||
* \param data Base address of the memory to get the two bytes from.
|
||||
* \param offset Offset from \p data of the first and most significant
|
||||
* byte of the two bytes to build the 16 bits unsigned
|
||||
* integer from.
|
||||
*/
|
||||
#define MBEDTLS_GET_UINT16_BE(data, offset) \
|
||||
((MBEDTLS_IS_BIG_ENDIAN) \
|
||||
? mbedtls_get_unaligned_uint16((data) + (offset)) \
|
||||
: MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Put in memory a 16 bits unsigned integer in big-endian order.
|
||||
*
|
||||
* \param n 16 bits unsigned integer to put in memory.
|
||||
* \param data Base address of the memory where to put the 16
|
||||
* bits unsigned integer in.
|
||||
* \param offset Offset from \p data where to put the most significant
|
||||
* byte of the 16 bits unsigned integer \p n.
|
||||
*/
|
||||
#define MBEDTLS_PUT_UINT16_BE(n, data, offset) \
|
||||
{ \
|
||||
if (MBEDTLS_IS_BIG_ENDIAN) \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t) (n))); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unsigned 24 bits integer corresponding to three bytes in
|
||||
* big-endian order (MSB first).
|
||||
*
|
||||
* \param data Base address of the memory to get the three bytes from.
|
||||
* \param offset Offset from \p data of the first and most significant
|
||||
* byte of the three bytes to build the 24 bits unsigned
|
||||
* integer from.
|
||||
*/
|
||||
#define MBEDTLS_GET_UINT24_BE(data, offset) \
|
||||
( \
|
||||
((uint32_t) (data)[(offset)] << 16) \
|
||||
| ((uint32_t) (data)[(offset) + 1] << 8) \
|
||||
| ((uint32_t) (data)[(offset) + 2]) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Put in memory a 24 bits unsigned integer in big-endian order.
|
||||
*
|
||||
* \param n 24 bits unsigned integer to put in memory.
|
||||
* \param data Base address of the memory where to put the 24
|
||||
* bits unsigned integer in.
|
||||
* \param offset Offset from \p data where to put the most significant
|
||||
* byte of the 24 bits unsigned integer \p n.
|
||||
*/
|
||||
#define MBEDTLS_PUT_UINT24_BE(n, data, offset) \
|
||||
{ \
|
||||
(data)[(offset)] = MBEDTLS_BYTE_2(n); \
|
||||
(data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \
|
||||
(data)[(offset) + 2] = MBEDTLS_BYTE_0(n); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unsigned 24 bits integer corresponding to three bytes in
|
||||
* little-endian order (LSB first).
|
||||
*
|
||||
* \param data Base address of the memory to get the three bytes from.
|
||||
* \param offset Offset from \p data of the first and least significant
|
||||
* byte of the three bytes to build the 24 bits unsigned
|
||||
* integer from.
|
||||
*/
|
||||
#define MBEDTLS_GET_UINT24_LE(data, offset) \
|
||||
( \
|
||||
((uint32_t) (data)[(offset)]) \
|
||||
| ((uint32_t) (data)[(offset) + 1] << 8) \
|
||||
| ((uint32_t) (data)[(offset) + 2] << 16) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Put in memory a 24 bits unsigned integer in little-endian order.
|
||||
*
|
||||
* \param n 24 bits unsigned integer to put in memory.
|
||||
* \param data Base address of the memory where to put the 24
|
||||
* bits unsigned integer in.
|
||||
* \param offset Offset from \p data where to put the least significant
|
||||
* byte of the 24 bits unsigned integer \p n.
|
||||
*/
|
||||
#define MBEDTLS_PUT_UINT24_LE(n, data, offset) \
|
||||
{ \
|
||||
(data)[(offset)] = MBEDTLS_BYTE_0(n); \
|
||||
(data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \
|
||||
(data)[(offset) + 2] = MBEDTLS_BYTE_2(n); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unsigned 64 bits integer corresponding to eight bytes in
|
||||
* big-endian order (MSB first).
|
||||
*
|
||||
* \param data Base address of the memory to get the eight bytes from.
|
||||
* \param offset Offset from \p data of the first and most significant
|
||||
* byte of the eight bytes to build the 64 bits unsigned
|
||||
* integer from.
|
||||
*/
|
||||
#define MBEDTLS_GET_UINT64_BE(data, offset) \
|
||||
((MBEDTLS_IS_BIG_ENDIAN) \
|
||||
? mbedtls_get_unaligned_uint64((data) + (offset)) \
|
||||
: MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Put in memory a 64 bits unsigned integer in big-endian order.
|
||||
*
|
||||
* \param n 64 bits unsigned integer to put in memory.
|
||||
* \param data Base address of the memory where to put the 64
|
||||
* bits unsigned integer in.
|
||||
* \param offset Offset from \p data where to put the most significant
|
||||
* byte of the 64 bits unsigned integer \p n.
|
||||
*/
|
||||
#define MBEDTLS_PUT_UINT64_BE(n, data, offset) \
|
||||
{ \
|
||||
if (MBEDTLS_IS_BIG_ENDIAN) \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t) (n))); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unsigned 64 bits integer corresponding to eight bytes in
|
||||
* little-endian order (LSB first).
|
||||
*
|
||||
* \param data Base address of the memory to get the eight bytes from.
|
||||
* \param offset Offset from \p data of the first and least significant
|
||||
* byte of the eight bytes to build the 64 bits unsigned
|
||||
* integer from.
|
||||
*/
|
||||
#define MBEDTLS_GET_UINT64_LE(data, offset) \
|
||||
((MBEDTLS_IS_BIG_ENDIAN) \
|
||||
? MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \
|
||||
: mbedtls_get_unaligned_uint64((data) + (offset)) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Put in memory a 64 bits unsigned integer in little-endian order.
|
||||
*
|
||||
* \param n 64 bits unsigned integer to put in memory.
|
||||
* \param data Base address of the memory where to put the 64
|
||||
* bits unsigned integer in.
|
||||
* \param offset Offset from \p data where to put the least significant
|
||||
* byte of the 64 bits unsigned integer \p n.
|
||||
*/
|
||||
#define MBEDTLS_PUT_UINT64_LE(n, data, offset) \
|
||||
{ \
|
||||
if (MBEDTLS_IS_BIG_ENDIAN) \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t) (n))); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_LIBRARY_ALIGNMENT_H */
|
||||
@@ -1,437 +0,0 @@
|
||||
/**
|
||||
* \file common.h
|
||||
*
|
||||
* \brief Utility macros for internal use in the library
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_LIBRARY_COMMON_H
|
||||
#define MBEDTLS_LIBRARY_COMMON_H
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
#include "alignment.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(__ARM_NEON)
|
||||
#include <arm_neon.h>
|
||||
#define MBEDTLS_HAVE_NEON_INTRINSICS
|
||||
#elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
|
||||
#include <arm64_neon.h>
|
||||
#define MBEDTLS_HAVE_NEON_INTRINSICS
|
||||
#endif
|
||||
|
||||
/** Helper to define a function as static except when building invasive tests.
|
||||
*
|
||||
* If a function is only used inside its own source file and should be
|
||||
* declared `static` to allow the compiler to optimize for code size,
|
||||
* but that function has unit tests, define it with
|
||||
* ```
|
||||
* MBEDTLS_STATIC_TESTABLE int mbedtls_foo(...) { ... }
|
||||
* ```
|
||||
* and declare it in a header in the `library/` directory with
|
||||
* ```
|
||||
* #if defined(MBEDTLS_TEST_HOOKS)
|
||||
* int mbedtls_foo(...);
|
||||
* #endif
|
||||
* ```
|
||||
*/
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
#define MBEDTLS_STATIC_TESTABLE
|
||||
#else
|
||||
#define MBEDTLS_STATIC_TESTABLE static
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
extern void (*mbedtls_test_hook_test_fail)(const char *test, int line, const char *file);
|
||||
#define MBEDTLS_TEST_HOOK_TEST_ASSERT(TEST) \
|
||||
do { \
|
||||
if ((!(TEST)) && ((*mbedtls_test_hook_test_fail) != NULL)) \
|
||||
{ \
|
||||
(*mbedtls_test_hook_test_fail)( #TEST, __LINE__, __FILE__); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define MBEDTLS_TEST_HOOK_TEST_ASSERT(TEST)
|
||||
#endif /* defined(MBEDTLS_TEST_HOOKS) */
|
||||
|
||||
/** \def ARRAY_LENGTH
|
||||
* Return the number of elements of a static or stack array.
|
||||
*
|
||||
* \param array A value of array (not pointer) type.
|
||||
*
|
||||
* \return The number of elements of the array.
|
||||
*/
|
||||
/* A correct implementation of ARRAY_LENGTH, but which silently gives
|
||||
* a nonsensical result if called with a pointer rather than an array. */
|
||||
#define ARRAY_LENGTH_UNSAFE(array) \
|
||||
(sizeof(array) / sizeof(*(array)))
|
||||
|
||||
#if defined(__GNUC__)
|
||||
/* Test if arg and &(arg)[0] have the same type. This is true if arg is
|
||||
* an array but not if it's a pointer. */
|
||||
#define IS_ARRAY_NOT_POINTER(arg) \
|
||||
(!__builtin_types_compatible_p(__typeof__(arg), \
|
||||
__typeof__(&(arg)[0])))
|
||||
/* A compile-time constant with the value 0. If `const_expr` is not a
|
||||
* compile-time constant with a nonzero value, cause a compile-time error. */
|
||||
#define STATIC_ASSERT_EXPR(const_expr) \
|
||||
(0 && sizeof(struct { unsigned int STATIC_ASSERT : 1 - 2 * !(const_expr); }))
|
||||
|
||||
/* Return the scalar value `value` (possibly promoted). This is a compile-time
|
||||
* constant if `value` is. `condition` must be a compile-time constant.
|
||||
* If `condition` is false, arrange to cause a compile-time error. */
|
||||
#define STATIC_ASSERT_THEN_RETURN(condition, value) \
|
||||
(STATIC_ASSERT_EXPR(condition) ? 0 : (value))
|
||||
|
||||
#define ARRAY_LENGTH(array) \
|
||||
(STATIC_ASSERT_THEN_RETURN(IS_ARRAY_NOT_POINTER(array), \
|
||||
ARRAY_LENGTH_UNSAFE(array)))
|
||||
|
||||
#else
|
||||
/* If we aren't sure the compiler supports our non-standard tricks,
|
||||
* fall back to the unsafe implementation. */
|
||||
#define ARRAY_LENGTH(array) ARRAY_LENGTH_UNSAFE(array)
|
||||
#endif
|
||||
/** Allow library to access its structs' private members.
|
||||
*
|
||||
* Although structs defined in header files are publicly available,
|
||||
* their members are private and should not be accessed by the user.
|
||||
*/
|
||||
#define MBEDTLS_ALLOW_PRIVATE_ACCESS
|
||||
|
||||
/**
|
||||
* \brief Securely zeroize a buffer then free it.
|
||||
*
|
||||
* Similar to making consecutive calls to
|
||||
* \c mbedtls_platform_zeroize() and \c mbedtls_free(), but has
|
||||
* code size savings, and potential for optimisation in the future.
|
||||
*
|
||||
* Guaranteed to be a no-op if \p buf is \c NULL and \p len is 0.
|
||||
*
|
||||
* \param buf Buffer to be zeroized then freed.
|
||||
* \param len Length of the buffer in bytes
|
||||
*/
|
||||
void mbedtls_zeroize_and_free(void *buf, size_t len);
|
||||
|
||||
/** Return an offset into a buffer.
|
||||
*
|
||||
* This is just the addition of an offset to a pointer, except that this
|
||||
* function also accepts an offset of 0 into a buffer whose pointer is null.
|
||||
* (`p + n` has undefined behavior when `p` is null, even when `n == 0`.
|
||||
* A null pointer is a valid buffer pointer when the size is 0, for example
|
||||
* as the result of `malloc(0)` on some platforms.)
|
||||
*
|
||||
* \param p Pointer to a buffer of at least n bytes.
|
||||
* This may be \p NULL if \p n is zero.
|
||||
* \param n An offset in bytes.
|
||||
* \return Pointer to offset \p n in the buffer \p p.
|
||||
* Note that this is only a valid pointer if the size of the
|
||||
* buffer is at least \p n + 1.
|
||||
*/
|
||||
static inline unsigned char *mbedtls_buffer_offset(
|
||||
unsigned char *p, size_t n)
|
||||
{
|
||||
return p == NULL ? NULL : p + n;
|
||||
}
|
||||
|
||||
/** Return an offset into a read-only buffer.
|
||||
*
|
||||
* Similar to mbedtls_buffer_offset(), but for const pointers.
|
||||
*
|
||||
* \param p Pointer to a buffer of at least n bytes.
|
||||
* This may be \p NULL if \p n is zero.
|
||||
* \param n An offset in bytes.
|
||||
* \return Pointer to offset \p n in the buffer \p p.
|
||||
* Note that this is only a valid pointer if the size of the
|
||||
* buffer is at least \p n + 1.
|
||||
*/
|
||||
static inline const unsigned char *mbedtls_buffer_offset_const(
|
||||
const unsigned char *p, size_t n)
|
||||
{
|
||||
return p == NULL ? NULL : p + n;
|
||||
}
|
||||
|
||||
/* Always inline mbedtls_xor() for similar reasons as mbedtls_xor_no_simd(). */
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma inline = forced
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
/**
|
||||
* Perform a fast block XOR operation, such that
|
||||
* r[i] = a[i] ^ b[i] where 0 <= i < n
|
||||
*
|
||||
* \param r Pointer to result (buffer of at least \p n bytes). \p r
|
||||
* may be equal to either \p a or \p b, but behaviour when
|
||||
* it overlaps in other ways is undefined.
|
||||
* \param a Pointer to input (buffer of at least \p n bytes)
|
||||
* \param b Pointer to input (buffer of at least \p n bytes)
|
||||
* \param n Number of bytes to process.
|
||||
*
|
||||
* \note Depending on the situation, it may be faster to use either mbedtls_xor() or
|
||||
* mbedtls_xor_no_simd() (these are functionally equivalent).
|
||||
* If the result is used immediately after the xor operation in non-SIMD code (e.g, in
|
||||
* AES-CBC), there may be additional latency to transfer the data from SIMD to scalar
|
||||
* registers, and in this case, mbedtls_xor_no_simd() may be faster. In other cases where
|
||||
* the result is not used immediately (e.g., in AES-CTR), mbedtls_xor() may be faster.
|
||||
* For targets without SIMD support, they will behave the same.
|
||||
*/
|
||||
static inline void mbedtls_xor(unsigned char *r,
|
||||
const unsigned char *a,
|
||||
const unsigned char *b,
|
||||
size_t n)
|
||||
{
|
||||
size_t i = 0;
|
||||
#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
|
||||
#if defined(MBEDTLS_HAVE_NEON_INTRINSICS) && \
|
||||
(!(defined(MBEDTLS_COMPILER_IS_GCC) && MBEDTLS_GCC_VERSION < 70300))
|
||||
/* Old GCC versions generate a warning here, so disable the NEON path for these compilers */
|
||||
for (; (i + 16) <= n; i += 16) {
|
||||
uint8x16_t v1 = vld1q_u8(a + i);
|
||||
uint8x16_t v2 = vld1q_u8(b + i);
|
||||
uint8x16_t x = veorq_u8(v1, v2);
|
||||
vst1q_u8(r + i, x);
|
||||
}
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
/* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case
|
||||
* where n is a constant multiple of 16.
|
||||
* For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time
|
||||
* constant, and is a very small perf regression if n is not a compile-time constant. */
|
||||
if (n % 16 == 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#elif defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64)
|
||||
/* This codepath probably only makes sense on architectures with 64-bit registers */
|
||||
for (; (i + 8) <= n; i += 8) {
|
||||
uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i);
|
||||
mbedtls_put_unaligned_uint64(r + i, x);
|
||||
}
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
if (n % 8 == 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
for (; (i + 4) <= n; i += 4) {
|
||||
uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i);
|
||||
mbedtls_put_unaligned_uint32(r + i, x);
|
||||
}
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
if (n % 4 == 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
for (; i < n; i++) {
|
||||
r[i] = a[i] ^ b[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Always inline mbedtls_xor_no_simd() as we see significant perf regressions when it does not get
|
||||
* inlined (e.g., observed about 3x perf difference in gcm_mult_largetable with gcc 7 - 12) */
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#pragma inline = forced
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__((always_inline))
|
||||
#endif
|
||||
/**
|
||||
* Perform a fast block XOR operation, such that
|
||||
* r[i] = a[i] ^ b[i] where 0 <= i < n
|
||||
*
|
||||
* In some situations, this can perform better than mbedtls_xor() (e.g., it's about 5%
|
||||
* better in AES-CBC).
|
||||
*
|
||||
* \param r Pointer to result (buffer of at least \p n bytes). \p r
|
||||
* may be equal to either \p a or \p b, but behaviour when
|
||||
* it overlaps in other ways is undefined.
|
||||
* \param a Pointer to input (buffer of at least \p n bytes)
|
||||
* \param b Pointer to input (buffer of at least \p n bytes)
|
||||
* \param n Number of bytes to process.
|
||||
*
|
||||
* \note Depending on the situation, it may be faster to use either mbedtls_xor() or
|
||||
* mbedtls_xor_no_simd() (these are functionally equivalent).
|
||||
* If the result is used immediately after the xor operation in non-SIMD code (e.g, in
|
||||
* AES-CBC), there may be additional latency to transfer the data from SIMD to scalar
|
||||
* registers, and in this case, mbedtls_xor_no_simd() may be faster. In other cases where
|
||||
* the result is not used immediately (e.g., in AES-CTR), mbedtls_xor() may be faster.
|
||||
* For targets without SIMD support, they will behave the same.
|
||||
*/
|
||||
static inline void mbedtls_xor_no_simd(unsigned char *r,
|
||||
const unsigned char *a,
|
||||
const unsigned char *b,
|
||||
size_t n)
|
||||
{
|
||||
size_t i = 0;
|
||||
#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
|
||||
#if defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64)
|
||||
/* This codepath probably only makes sense on architectures with 64-bit registers */
|
||||
for (; (i + 8) <= n; i += 8) {
|
||||
uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i);
|
||||
mbedtls_put_unaligned_uint64(r + i, x);
|
||||
}
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
/* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case
|
||||
* where n is a constant multiple of 8.
|
||||
* For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time
|
||||
* constant, and is a very small perf regression if n is not a compile-time constant. */
|
||||
if (n % 8 == 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
for (; (i + 4) <= n; i += 4) {
|
||||
uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i);
|
||||
mbedtls_put_unaligned_uint32(r + i, x);
|
||||
}
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
if (n % 4 == 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
for (; i < n; i++) {
|
||||
r[i] = a[i] ^ b[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Fix MSVC C99 compatible issue
|
||||
* MSVC support __func__ from visual studio 2015( 1900 )
|
||||
* Use MSVC predefine macro to avoid name check fail.
|
||||
*/
|
||||
#if (defined(_MSC_VER) && (_MSC_VER <= 1900))
|
||||
#define /*no-check-names*/ __func__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
/* Define `asm` for compilers which don't define it. */
|
||||
/* *INDENT-OFF* */
|
||||
#ifndef asm
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
#define asm __asm
|
||||
#else
|
||||
#define asm __asm__
|
||||
#endif
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/*
|
||||
* Define the constraint used for read-only pointer operands to aarch64 asm.
|
||||
*
|
||||
* This is normally the usual "r", but for aarch64_32 (aka ILP32,
|
||||
* as found in watchos), "p" is required to avoid warnings from clang.
|
||||
*
|
||||
* Note that clang does not recognise '+p' or '=p', and armclang
|
||||
* does not recognise 'p' at all. Therefore, to update a pointer from
|
||||
* aarch64 assembly, it is necessary to use something like:
|
||||
*
|
||||
* uintptr_t uptr = (uintptr_t) ptr;
|
||||
* asm( "ldr x4, [%x0], #8" ... : "+r" (uptr) : : )
|
||||
* ptr = (void*) uptr;
|
||||
*
|
||||
* Note that the "x" in "%x0" is neccessary; writing "%0" will cause warnings.
|
||||
*/
|
||||
#if defined(__aarch64__) && defined(MBEDTLS_HAVE_ASM)
|
||||
#if UINTPTR_MAX == 0xfffffffful
|
||||
/* ILP32: Specify the pointer operand slightly differently, as per #7787. */
|
||||
#define MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT "p"
|
||||
#elif UINTPTR_MAX == 0xfffffffffffffffful
|
||||
/* Normal case (64-bit pointers): use "r" as the constraint for pointer operands to asm */
|
||||
#define MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT "r"
|
||||
#else
|
||||
#error "Unrecognised pointer size for aarch64"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Always provide a static assert macro, so it can be used unconditionally.
|
||||
* It does nothing on systems where we don't know how to define a static assert.
|
||||
*/
|
||||
/* Can't use the C11-style `defined(static_assert)` on FreeBSD, since it
|
||||
* defines static_assert even with -std=c99, but then complains about it.
|
||||
*/
|
||||
#if defined(static_assert) && !defined(__FreeBSD__)
|
||||
#define MBEDTLS_STATIC_ASSERT(expr, msg) static_assert(expr, msg)
|
||||
#else
|
||||
/* Make sure `MBEDTLS_STATIC_ASSERT(expr, msg);` is valid both inside and
|
||||
* outside a function. We choose a struct declaration, which can be repeated
|
||||
* any number of times and does not need a matching definition. */
|
||||
#define MBEDTLS_STATIC_ASSERT(expr, msg) \
|
||||
struct ISO_C_does_not_allow_extra_semicolon_outside_of_a_function
|
||||
#endif
|
||||
|
||||
#if defined(__has_builtin)
|
||||
#define MBEDTLS_HAS_BUILTIN(x) __has_builtin(x)
|
||||
#else
|
||||
#define MBEDTLS_HAS_BUILTIN(x) 0
|
||||
#endif
|
||||
|
||||
/* Define compiler branch hints */
|
||||
#if MBEDTLS_HAS_BUILTIN(__builtin_expect)
|
||||
#define MBEDTLS_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
#define MBEDTLS_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
#else
|
||||
#define MBEDTLS_LIKELY(x) x
|
||||
#define MBEDTLS_UNLIKELY(x) x
|
||||
#endif
|
||||
|
||||
/* MBEDTLS_ASSUME may be used to provide additional information to the compiler
|
||||
* which can result in smaller code-size. */
|
||||
#if MBEDTLS_HAS_BUILTIN(__builtin_assume)
|
||||
/* clang provides __builtin_assume */
|
||||
#define MBEDTLS_ASSUME(x) __builtin_assume(x)
|
||||
#elif MBEDTLS_HAS_BUILTIN(__builtin_unreachable)
|
||||
/* gcc and IAR can use __builtin_unreachable */
|
||||
#define MBEDTLS_ASSUME(x) do { if (!(x)) __builtin_unreachable(); } while (0)
|
||||
#elif defined(_MSC_VER)
|
||||
/* Supported by MSVC since VS 2005 */
|
||||
#define MBEDTLS_ASSUME(x) __assume(x)
|
||||
#else
|
||||
#define MBEDTLS_ASSUME(x) do { } while (0)
|
||||
#endif
|
||||
|
||||
/* For gcc -Os, override with -O2 for a given function.
|
||||
*
|
||||
* This will not affect behaviour for other optimisation settings, e.g. -O0.
|
||||
*/
|
||||
#if defined(MBEDTLS_COMPILER_IS_GCC) && defined(__OPTIMIZE_SIZE__)
|
||||
#define MBEDTLS_OPTIMIZE_FOR_PERFORMANCE __attribute__((optimize("-O2")))
|
||||
#else
|
||||
#define MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
|
||||
#endif
|
||||
|
||||
/* Suppress compiler warnings for unused functions and variables. */
|
||||
#if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__has_attribute)
|
||||
# if __has_attribute(unused)
|
||||
# define MBEDTLS_MAYBE_UNUSED __attribute__((unused))
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__GNUC__)
|
||||
# define MBEDTLS_MAYBE_UNUSED __attribute__((unused))
|
||||
#endif
|
||||
#if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__IAR_SYSTEMS_ICC__) && defined(__VER__)
|
||||
/* IAR does support __attribute__((unused)), but only if the -e flag (extended language support)
|
||||
* is given; the pragma always works.
|
||||
* Unfortunately the pragma affects the rest of the file where it is used, but this is harmless.
|
||||
* Check for version 5.2 or later - this pragma may be supported by earlier versions, but I wasn't
|
||||
* able to find documentation).
|
||||
*/
|
||||
# if (__VER__ >= 5020000)
|
||||
# define MBEDTLS_MAYBE_UNUSED _Pragma("diag_suppress=Pe177")
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(MBEDTLS_MAYBE_UNUSED) && defined(_MSC_VER)
|
||||
# define MBEDTLS_MAYBE_UNUSED __pragma(warning(suppress:4189))
|
||||
#endif
|
||||
#if !defined(MBEDTLS_MAYBE_UNUSED)
|
||||
# define MBEDTLS_MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_LIBRARY_COMMON_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* PSA crypto client code
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
|
||||
|
||||
#include <string.h>
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
void psa_reset_key_attributes(psa_key_attributes_t *attributes)
|
||||
{
|
||||
memset(attributes, 0, sizeof(*attributes));
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,52 +0,0 @@
|
||||
/**
|
||||
* \file psa_crypto_core_common.h
|
||||
*
|
||||
* \brief Utility macros for internal use in the PSA cryptography core.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_CORE_COMMON_H
|
||||
#define PSA_CRYPTO_CORE_COMMON_H
|
||||
|
||||
/** Return an offset into a buffer.
|
||||
*
|
||||
* This is just the addition of an offset to a pointer, except that this
|
||||
* function also accepts an offset of 0 into a buffer whose pointer is null.
|
||||
* (`p + n` has undefined behavior when `p` is null, even when `n == 0`.
|
||||
* A null pointer is a valid buffer pointer when the size is 0, for example
|
||||
* as the result of `malloc(0)` on some platforms.)
|
||||
*
|
||||
* \param p Pointer to a buffer of at least n bytes.
|
||||
* This may be \p NULL if \p n is zero.
|
||||
* \param n An offset in bytes.
|
||||
* \return Pointer to offset \p n in the buffer \p p.
|
||||
* Note that this is only a valid pointer if the size of the
|
||||
* buffer is at least \p n + 1.
|
||||
*/
|
||||
static inline unsigned char *psa_crypto_buffer_offset(
|
||||
unsigned char *p, size_t n)
|
||||
{
|
||||
return p == NULL ? NULL : p + n;
|
||||
}
|
||||
|
||||
/** Return an offset into a read-only buffer.
|
||||
*
|
||||
* Similar to mbedtls_buffer_offset(), but for const pointers.
|
||||
*
|
||||
* \param p Pointer to a buffer of at least n bytes.
|
||||
* This may be \p NULL if \p n is zero.
|
||||
* \param n An offset in bytes.
|
||||
* \return Pointer to offset \p n in the buffer \p p.
|
||||
* Note that this is only a valid pointer if the size of the
|
||||
* buffer is at least \p n + 1.
|
||||
*/
|
||||
static inline const unsigned char *psa_crypto_buffer_offset_const(
|
||||
const unsigned char *p, size_t n)
|
||||
{
|
||||
return p == NULL ? NULL : p + n;
|
||||
}
|
||||
|
||||
#endif /* PSA_CRYPTO_CORE_COMMON_H */
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Function signatures for functionality that can be provided by
|
||||
* cryptographic accelerators.
|
||||
*/
|
||||
/* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_DRIVER_WRAPPERS_NO_STATIC_H
|
||||
#define PSA_CRYPTO_DRIVER_WRAPPERS_NO_STATIC_H
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa/crypto_driver_common.h"
|
||||
|
||||
psa_status_t psa_driver_wrapper_export_public_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer, size_t key_buffer_size,
|
||||
uint8_t *data, size_t data_size, size_t *data_length);
|
||||
|
||||
psa_status_t psa_driver_wrapper_get_key_buffer_size(
|
||||
const psa_key_attributes_t *attributes,
|
||||
size_t *key_buffer_size);
|
||||
|
||||
psa_status_t psa_driver_wrapper_get_builtin_key(
|
||||
psa_drv_slot_number_t slot_number,
|
||||
psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length);
|
||||
|
||||
#endif /* PSA_CRYPTO_DRIVER_WRAPPERS_NO_STATIC_H */
|
||||
|
||||
/* End of automatically generated file. */
|
||||
@@ -1,85 +0,0 @@
|
||||
/**
|
||||
* \file psa_crypto_invasive.h
|
||||
*
|
||||
* \brief PSA cryptography module: invasive interfaces for test only.
|
||||
*
|
||||
* The interfaces in this file are intended for testing purposes only.
|
||||
* They MUST NOT be made available to clients over IPC in integrations
|
||||
* with isolation, and they SHOULD NOT be made available in library
|
||||
* integrations except when building the library for testing.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_INVASIVE_H
|
||||
#define PSA_CRYPTO_INVASIVE_H
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "common.h"
|
||||
|
||||
#include "mbedtls/entropy.h"
|
||||
|
||||
#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
|
||||
/** \brief Configure entropy sources.
|
||||
*
|
||||
* This function may only be called before a call to psa_crypto_init(),
|
||||
* or after a call to mbedtls_psa_crypto_free() and before any
|
||||
* subsequent call to psa_crypto_init().
|
||||
*
|
||||
* This function is only intended for test purposes. The functionality
|
||||
* it provides is also useful for system integrators, but
|
||||
* system integrators should configure entropy drivers instead of
|
||||
* breaking through to the Mbed TLS API.
|
||||
*
|
||||
* \param entropy_init Function to initialize the entropy context
|
||||
* and set up the desired entropy sources.
|
||||
* It is called by psa_crypto_init().
|
||||
* By default this is mbedtls_entropy_init().
|
||||
* This function cannot report failures directly.
|
||||
* To indicate a failure, set the entropy context
|
||||
* to a state where mbedtls_entropy_func() will
|
||||
* return an error.
|
||||
* \param entropy_free Function to free the entropy context
|
||||
* and associated resources.
|
||||
* It is called by mbedtls_psa_crypto_free().
|
||||
* By default this is mbedtls_entropy_free().
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||
* The caller does not have the permission to configure
|
||||
* entropy sources.
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The library has already been initialized.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
|
||||
void (* entropy_init)(mbedtls_entropy_context *ctx),
|
||||
void (* entropy_free)(mbedtls_entropy_context *ctx));
|
||||
#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
psa_status_t psa_mac_key_can_do(
|
||||
psa_algorithm_t algorithm,
|
||||
psa_key_type_t key_type);
|
||||
|
||||
psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len,
|
||||
uint8_t *input_copy, size_t input_copy_len);
|
||||
|
||||
psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_copy_len,
|
||||
uint8_t *output, size_t output_len);
|
||||
|
||||
/*
|
||||
* Test hooks to use for memory unpoisoning/poisoning in copy functions.
|
||||
*/
|
||||
extern void (*psa_input_pre_copy_hook)(const uint8_t *input, size_t input_len);
|
||||
extern void (*psa_input_post_copy_hook)(const uint8_t *input, size_t input_len);
|
||||
extern void (*psa_output_pre_copy_hook)(const uint8_t *output, size_t output_len);
|
||||
extern void (*psa_output_post_copy_hook)(const uint8_t *output, size_t output_len);
|
||||
|
||||
#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
#endif /* PSA_CRYPTO_INVASIVE_H */
|
||||
@@ -1,131 +0,0 @@
|
||||
/** \file psa_crypto_its.h
|
||||
* \brief Interface of trusted storage that crypto is built on.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_ITS_H
|
||||
#define PSA_CRYPTO_ITS_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <psa/crypto_types.h>
|
||||
#include <psa/crypto_values.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief Flags used when creating a data entry
|
||||
*/
|
||||
typedef uint32_t psa_storage_create_flags_t;
|
||||
|
||||
/** \brief A type for UIDs used for identifying data
|
||||
*/
|
||||
typedef uint64_t psa_storage_uid_t;
|
||||
|
||||
#define PSA_STORAGE_FLAG_NONE 0 /**< No flags to pass */
|
||||
#define PSA_STORAGE_FLAG_WRITE_ONCE (1 << 0) /**< The data associated with the uid will not be able to be modified or deleted. Intended to be used to set bits in `psa_storage_create_flags_t`*/
|
||||
|
||||
/**
|
||||
* \brief A container for metadata associated with a specific uid
|
||||
*/
|
||||
struct psa_storage_info_t {
|
||||
uint32_t size; /**< The size of the data associated with a uid **/
|
||||
psa_storage_create_flags_t flags; /**< The flags set when the uid was created **/
|
||||
};
|
||||
|
||||
/** Flag indicating that \ref psa_storage_create and \ref psa_storage_set_extended are supported */
|
||||
#define PSA_STORAGE_SUPPORT_SET_EXTENDED (1 << 0)
|
||||
|
||||
#define PSA_ITS_API_VERSION_MAJOR 1 /**< The major version number of the PSA ITS API. It will be incremented on significant updates that may include breaking changes */
|
||||
#define PSA_ITS_API_VERSION_MINOR 1 /**< The minor version number of the PSA ITS API. It will be incremented in small updates that are unlikely to include breaking changes */
|
||||
|
||||
/**
|
||||
* \brief create a new or modify an existing uid/value pair
|
||||
*
|
||||
* \param[in] uid the identifier for the data
|
||||
* \param[in] data_length The size in bytes of the data in `p_data`
|
||||
* \param[in] p_data A buffer containing the data
|
||||
* \param[in] create_flags The flags that the data will be stored with
|
||||
*
|
||||
* \return A status indicating the success/failure of the operation
|
||||
*
|
||||
* \retval #PSA_SUCCESS The operation completed successfully
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED The operation failed because the provided `uid` value was already created with PSA_STORAGE_FLAG_WRITE_ONCE
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED The operation failed because one or more of the flags provided in `create_flags` is not supported or is not valid
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE The operation failed because there was insufficient space on the storage medium
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_data`)
|
||||
* is invalid, for example is `NULL` or references memory the caller cannot access
|
||||
*/
|
||||
psa_status_t psa_its_set(psa_storage_uid_t uid,
|
||||
uint32_t data_length,
|
||||
const void *p_data,
|
||||
psa_storage_create_flags_t create_flags);
|
||||
|
||||
/**
|
||||
* \brief Retrieve the value associated with a provided uid
|
||||
*
|
||||
* \param[in] uid The uid value
|
||||
* \param[in] data_offset The starting offset of the data requested
|
||||
* \param[in] data_length the amount of data requested (and the minimum allocated size of the `p_data` buffer)
|
||||
* \param[out] p_data The buffer where the data will be placed upon successful completion
|
||||
* \param[out] p_data_length The amount of data returned in the p_data buffer
|
||||
*
|
||||
*
|
||||
* \return A status indicating the success/failure of the operation
|
||||
*
|
||||
* \retval #PSA_SUCCESS The operation completed successfully
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided `uid` value was not found in the storage
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT The operation failed because stored data has been corrupted
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_data`, `p_data_length`)
|
||||
* is invalid. For example is `NULL` or references memory the caller cannot access.
|
||||
* In addition, this can also happen if an invalid offset was provided.
|
||||
*/
|
||||
psa_status_t psa_its_get(psa_storage_uid_t uid,
|
||||
uint32_t data_offset,
|
||||
uint32_t data_length,
|
||||
void *p_data,
|
||||
size_t *p_data_length);
|
||||
|
||||
/**
|
||||
* \brief Retrieve the metadata about the provided uid
|
||||
*
|
||||
* \param[in] uid The uid value
|
||||
* \param[out] p_info A pointer to the `psa_storage_info_t` struct that will be populated with the metadata
|
||||
*
|
||||
* \return A status indicating the success/failure of the operation
|
||||
*
|
||||
* \retval #PSA_SUCCESS The operation completed successfully
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided uid value was not found in the storage
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT The operation failed because stored data has been corrupted
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_info`)
|
||||
* is invalid, for example is `NULL` or references memory the caller cannot access
|
||||
*/
|
||||
psa_status_t psa_its_get_info(psa_storage_uid_t uid,
|
||||
struct psa_storage_info_t *p_info);
|
||||
|
||||
/**
|
||||
* \brief Remove the provided key and its associated data from the storage
|
||||
*
|
||||
* \param[in] uid The uid value
|
||||
*
|
||||
* \return A status indicating the success/failure of the operation
|
||||
*
|
||||
* \retval #PSA_SUCCESS The operation completed successfully
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided key value was not found in the storage
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED The operation failed because the provided key value was created with PSA_STORAGE_FLAG_WRITE_ONCE
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
|
||||
*/
|
||||
psa_status_t psa_its_remove(psa_storage_uid_t uid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTO_ITS_H */
|
||||
@@ -1,126 +0,0 @@
|
||||
/** \file psa_crypto_random_impl.h
|
||||
*
|
||||
* \brief PSA crypto random generator implementation abstraction.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_RANDOM_IMPL_H
|
||||
#define PSA_CRYPTO_RANDOM_IMPL_H
|
||||
|
||||
#include "psa_util_internal.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
|
||||
|
||||
typedef mbedtls_psa_external_random_context_t mbedtls_psa_random_context_t;
|
||||
|
||||
#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
|
||||
|
||||
#include "mbedtls/entropy.h"
|
||||
|
||||
/* Choose a DRBG based on configuration and availability */
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#undef MBEDTLS_PSA_HMAC_DRBG_MD_TYPE
|
||||
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
|
||||
#include "mbedtls/hmac_drbg.h"
|
||||
#if defined(PSA_WANT_ALG_SHA_512) && defined(PSA_WANT_ALG_SHA_256)
|
||||
#include <limits.h>
|
||||
#if SIZE_MAX > 0xffffffff
|
||||
/* Looks like a 64-bit system, so prefer SHA-512. */
|
||||
#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA512
|
||||
#else
|
||||
/* Looks like a 32-bit system, so prefer SHA-256. */
|
||||
#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256
|
||||
#endif
|
||||
#elif defined(PSA_WANT_ALG_SHA_512)
|
||||
#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA512
|
||||
#elif defined(PSA_WANT_ALG_SHA_256)
|
||||
#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256
|
||||
#else
|
||||
#error "No hash algorithm available for HMAC_DBRG."
|
||||
#endif
|
||||
|
||||
#else /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
|
||||
|
||||
#error "No DRBG module available for the psa_crypto module."
|
||||
|
||||
#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C*/
|
||||
|
||||
/* The maximum number of bytes that mbedtls_psa_get_random() is expected to return. */
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
#define MBEDTLS_PSA_RANDOM_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
typedef mbedtls_ctr_drbg_context mbedtls_psa_drbg_context_t;
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
typedef mbedtls_hmac_drbg_context mbedtls_psa_drbg_context_t;
|
||||
#endif /* !MBEDTLS_CTR_DRBG_C && !MBEDTLS_HMAC_DRBG_C */
|
||||
|
||||
typedef struct {
|
||||
void (* entropy_init)(mbedtls_entropy_context *ctx);
|
||||
void (* entropy_free)(mbedtls_entropy_context *ctx);
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_psa_drbg_context_t drbg;
|
||||
} mbedtls_psa_random_context_t;
|
||||
|
||||
/** Initialize the PSA DRBG.
|
||||
*
|
||||
* \param p_rng Pointer to the Mbed TLS DRBG state.
|
||||
*/
|
||||
static inline void mbedtls_psa_drbg_init(mbedtls_psa_drbg_context_t *p_rng)
|
||||
{
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
mbedtls_ctr_drbg_init(p_rng);
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
mbedtls_hmac_drbg_init(p_rng);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Deinitialize the PSA DRBG.
|
||||
*
|
||||
* \param p_rng Pointer to the Mbed TLS DRBG state.
|
||||
*/
|
||||
static inline void mbedtls_psa_drbg_free(mbedtls_psa_drbg_context_t *p_rng)
|
||||
{
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
mbedtls_ctr_drbg_free(p_rng);
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
mbedtls_hmac_drbg_free(p_rng);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Seed the PSA DRBG.
|
||||
*
|
||||
* \param entropy An entropy context to read the seed from.
|
||||
* \param custom The personalization string.
|
||||
* This can be \c NULL, in which case the personalization
|
||||
* string is empty regardless of the value of \p len.
|
||||
* \param len The length of the personalization string.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An Mbed TLS error code (\c MBEDTLS_ERR_xxx) on failure.
|
||||
*/
|
||||
static inline int mbedtls_psa_drbg_seed(mbedtls_psa_drbg_context_t *drbg_ctx,
|
||||
mbedtls_entropy_context *entropy,
|
||||
const unsigned char *custom, size_t len)
|
||||
{
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
return mbedtls_ctr_drbg_seed(drbg_ctx, mbedtls_entropy_func, entropy, custom, len);
|
||||
#elif defined(MBEDTLS_HMAC_DRBG_C)
|
||||
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE);
|
||||
return mbedtls_hmac_drbg_seed(drbg_ctx, md_info, mbedtls_entropy_func, entropy, custom, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
|
||||
|
||||
#endif /* PSA_CRYPTO_RANDOM_IMPL_H */
|
||||
@@ -1,373 +0,0 @@
|
||||
/*
|
||||
* PSA crypto support for secure element drivers
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "psa/crypto_se_driver.h"
|
||||
|
||||
#include "psa_crypto_se.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_ITS_FILE_C)
|
||||
#include "psa_crypto_its.h"
|
||||
#else /* Native ITS implementation */
|
||||
#include "psa/error.h"
|
||||
#include "psa/internal_trusted_storage.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Driver lookup */
|
||||
/****************************************************************/
|
||||
|
||||
/* This structure is identical to psa_drv_se_context_t declared in
|
||||
* `crypto_se_driver.h`, except that some parts are writable here
|
||||
* (non-const, or pointer to non-const). */
|
||||
typedef struct {
|
||||
void *persistent_data;
|
||||
size_t persistent_data_size;
|
||||
uintptr_t transient_data;
|
||||
} psa_drv_se_internal_context_t;
|
||||
|
||||
struct psa_se_drv_table_entry_s {
|
||||
psa_key_location_t location;
|
||||
const psa_drv_se_t *methods;
|
||||
union {
|
||||
psa_drv_se_internal_context_t internal;
|
||||
psa_drv_se_context_t context;
|
||||
} u;
|
||||
};
|
||||
|
||||
static psa_se_drv_table_entry_t driver_table[PSA_MAX_SE_DRIVERS];
|
||||
|
||||
psa_se_drv_table_entry_t *psa_get_se_driver_entry(
|
||||
psa_key_lifetime_t lifetime)
|
||||
{
|
||||
size_t i;
|
||||
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(lifetime);
|
||||
/* In the driver table, location=0 means an entry that isn't used.
|
||||
* No driver has a location of 0 because it's a reserved value
|
||||
* (which designates transparent keys). Make sure we never return
|
||||
* a driver entry for location 0. */
|
||||
if (location == 0) {
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) {
|
||||
if (driver_table[i].location == location) {
|
||||
return &driver_table[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const psa_drv_se_t *psa_get_se_driver_methods(
|
||||
const psa_se_drv_table_entry_t *driver)
|
||||
{
|
||||
return driver->methods;
|
||||
}
|
||||
|
||||
psa_drv_se_context_t *psa_get_se_driver_context(
|
||||
psa_se_drv_table_entry_t *driver)
|
||||
{
|
||||
return &driver->u.context;
|
||||
}
|
||||
|
||||
int psa_get_se_driver(psa_key_lifetime_t lifetime,
|
||||
const psa_drv_se_t **p_methods,
|
||||
psa_drv_se_context_t **p_drv_context)
|
||||
{
|
||||
psa_se_drv_table_entry_t *driver = psa_get_se_driver_entry(lifetime);
|
||||
if (p_methods != NULL) {
|
||||
*p_methods = (driver ? driver->methods : NULL);
|
||||
}
|
||||
if (p_drv_context != NULL) {
|
||||
*p_drv_context = (driver ? &driver->u.context : NULL);
|
||||
}
|
||||
return driver != NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Persistent data management */
|
||||
/****************************************************************/
|
||||
|
||||
static psa_status_t psa_get_se_driver_its_file_uid(
|
||||
const psa_se_drv_table_entry_t *driver,
|
||||
psa_storage_uid_t *uid)
|
||||
{
|
||||
if (driver->location > PSA_MAX_SE_LOCATION) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* ITS file sizes are limited to 32 bits. */
|
||||
if (driver->u.internal.persistent_data_size > UINT32_MAX) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* See the documentation of PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE. */
|
||||
*uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + driver->location;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_load_se_persistent_data(
|
||||
const psa_se_drv_table_entry_t *driver)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_storage_uid_t uid;
|
||||
size_t length;
|
||||
|
||||
status = psa_get_se_driver_its_file_uid(driver, &uid);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Read the amount of persistent data that the driver requests.
|
||||
* If the data in storage is larger, it is truncated. If the data
|
||||
* in storage is smaller, silently keep what is already at the end
|
||||
* of the output buffer. */
|
||||
/* psa_get_se_driver_its_file_uid ensures that the size_t
|
||||
* persistent_data_size is in range, but compilers don't know that,
|
||||
* so cast to reassure them. */
|
||||
return psa_its_get(uid, 0,
|
||||
(uint32_t) driver->u.internal.persistent_data_size,
|
||||
driver->u.internal.persistent_data,
|
||||
&length);
|
||||
}
|
||||
|
||||
psa_status_t psa_save_se_persistent_data(
|
||||
const psa_se_drv_table_entry_t *driver)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_storage_uid_t uid;
|
||||
|
||||
status = psa_get_se_driver_its_file_uid(driver, &uid);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* psa_get_se_driver_its_file_uid ensures that the size_t
|
||||
* persistent_data_size is in range, but compilers don't know that,
|
||||
* so cast to reassure them. */
|
||||
return psa_its_set(uid,
|
||||
(uint32_t) driver->u.internal.persistent_data_size,
|
||||
driver->u.internal.persistent_data,
|
||||
0);
|
||||
}
|
||||
|
||||
psa_status_t psa_destroy_se_persistent_data(psa_key_location_t location)
|
||||
{
|
||||
psa_storage_uid_t uid;
|
||||
if (location > PSA_MAX_SE_LOCATION) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + location;
|
||||
return psa_its_remove(uid);
|
||||
}
|
||||
|
||||
psa_status_t psa_find_se_slot_for_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_creation_method_t method,
|
||||
psa_se_drv_table_entry_t *driver,
|
||||
psa_key_slot_number_t *slot_number)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_location_t key_location =
|
||||
PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(attributes));
|
||||
|
||||
/* If the location is wrong, it's a bug in the library. */
|
||||
if (driver->location != key_location) {
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
|
||||
/* If the driver doesn't support key creation in any way, give up now. */
|
||||
if (driver->methods->key_management == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (psa_get_key_slot_number(attributes, slot_number) == PSA_SUCCESS) {
|
||||
/* The application wants to use a specific slot. Allow it if
|
||||
* the driver supports it. On a system with isolation,
|
||||
* the crypto service must check that the application is
|
||||
* permitted to request this slot. */
|
||||
psa_drv_se_validate_slot_number_t p_validate_slot_number =
|
||||
driver->methods->key_management->p_validate_slot_number;
|
||||
if (p_validate_slot_number == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
status = p_validate_slot_number(&driver->u.context,
|
||||
driver->u.internal.persistent_data,
|
||||
attributes, method,
|
||||
*slot_number);
|
||||
} else if (method == PSA_KEY_CREATION_REGISTER) {
|
||||
/* The application didn't specify a slot number. This doesn't
|
||||
* make sense when registering a slot. */
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
} else {
|
||||
/* The application didn't tell us which slot to use. Let the driver
|
||||
* choose. This is the normal case. */
|
||||
psa_drv_se_allocate_key_t p_allocate =
|
||||
driver->methods->key_management->p_allocate;
|
||||
if (p_allocate == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
status = p_allocate(&driver->u.context,
|
||||
driver->u.internal.persistent_data,
|
||||
attributes, method,
|
||||
slot_number);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_destroy_se_key(psa_se_drv_table_entry_t *driver,
|
||||
psa_key_slot_number_t slot_number)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_status_t storage_status;
|
||||
/* Normally a missing method would mean that the action is not
|
||||
* supported. But psa_destroy_key() is not supposed to return
|
||||
* PSA_ERROR_NOT_SUPPORTED: if you can create a key, you should
|
||||
* be able to destroy it. The only use case for a driver that
|
||||
* does not have a way to destroy keys at all is if the keys are
|
||||
* locked in a read-only state: we can use the keys but not
|
||||
* destroy them. Hence, if the driver doesn't support destroying
|
||||
* keys, it's really a lack of permission. */
|
||||
if (driver->methods->key_management == NULL ||
|
||||
driver->methods->key_management->p_destroy == NULL) {
|
||||
return PSA_ERROR_NOT_PERMITTED;
|
||||
}
|
||||
status = driver->methods->key_management->p_destroy(
|
||||
&driver->u.context,
|
||||
driver->u.internal.persistent_data,
|
||||
slot_number);
|
||||
storage_status = psa_save_se_persistent_data(driver);
|
||||
return status == PSA_SUCCESS ? storage_status : status;
|
||||
}
|
||||
|
||||
psa_status_t psa_init_all_se_drivers(void)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) {
|
||||
psa_se_drv_table_entry_t *driver = &driver_table[i];
|
||||
if (driver->location == 0) {
|
||||
continue; /* skipping unused entry */
|
||||
}
|
||||
const psa_drv_se_t *methods = psa_get_se_driver_methods(driver);
|
||||
if (methods->p_init != NULL) {
|
||||
psa_status_t status = methods->p_init(
|
||||
&driver->u.context,
|
||||
driver->u.internal.persistent_data,
|
||||
driver->location);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
status = psa_save_se_persistent_data(driver);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Driver registration */
|
||||
/****************************************************************/
|
||||
|
||||
psa_status_t psa_register_se_driver(
|
||||
psa_key_location_t location,
|
||||
const psa_drv_se_t *methods)
|
||||
{
|
||||
size_t i;
|
||||
psa_status_t status;
|
||||
|
||||
if (methods->hal_version != PSA_DRV_SE_HAL_VERSION) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
/* Driver table entries are 0-initialized. 0 is not a valid driver
|
||||
* location because it means a transparent key. */
|
||||
MBEDTLS_STATIC_ASSERT(PSA_KEY_LOCATION_LOCAL_STORAGE == 0,
|
||||
"Secure element support requires 0 to mean a local key");
|
||||
|
||||
if (location == PSA_KEY_LOCATION_LOCAL_STORAGE) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
if (location > PSA_MAX_SE_LOCATION) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) {
|
||||
if (driver_table[i].location == 0) {
|
||||
break;
|
||||
}
|
||||
/* Check that location isn't already in use up to the first free
|
||||
* entry. Since entries are created in order and never deleted,
|
||||
* there can't be a used entry after the first free entry. */
|
||||
if (driver_table[i].location == location) {
|
||||
return PSA_ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
}
|
||||
if (i == PSA_MAX_SE_DRIVERS) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
driver_table[i].location = location;
|
||||
driver_table[i].methods = methods;
|
||||
driver_table[i].u.internal.persistent_data_size =
|
||||
methods->persistent_data_size;
|
||||
|
||||
if (methods->persistent_data_size != 0) {
|
||||
driver_table[i].u.internal.persistent_data =
|
||||
mbedtls_calloc(1, methods->persistent_data_size);
|
||||
if (driver_table[i].u.internal.persistent_data == NULL) {
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
/* Load the driver's persistent data. On first use, the persistent
|
||||
* data does not exist in storage, and is initialized to
|
||||
* all-bits-zero by the calloc call just above. */
|
||||
status = psa_load_se_persistent_data(&driver_table[i]);
|
||||
if (status != PSA_SUCCESS && status != PSA_ERROR_DOES_NOT_EXIST) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
|
||||
error:
|
||||
memset(&driver_table[i], 0, sizeof(driver_table[i]));
|
||||
return status;
|
||||
}
|
||||
|
||||
void psa_unregister_all_se_drivers(void)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < PSA_MAX_SE_DRIVERS; i++) {
|
||||
if (driver_table[i].u.internal.persistent_data != NULL) {
|
||||
mbedtls_free(driver_table[i].u.internal.persistent_data);
|
||||
}
|
||||
}
|
||||
memset(driver_table, 0, sizeof(driver_table));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* The end */
|
||||
/****************************************************************/
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
@@ -1,185 +0,0 @@
|
||||
/*
|
||||
* PSA crypto support for secure element drivers
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_SE_H
|
||||
#define PSA_CRYPTO_SE_H
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa/crypto_se_driver.h"
|
||||
|
||||
/** The maximum location value that this implementation supports
|
||||
* for a secure element.
|
||||
*
|
||||
* This is not a characteristic that each PSA implementation has, but a
|
||||
* limitation of the current implementation due to the constraints imposed
|
||||
* by storage. See #PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE.
|
||||
*
|
||||
* The minimum location value for a secure element is 1, like on any
|
||||
* PSA implementation (0 means a transparent key).
|
||||
*/
|
||||
#define PSA_MAX_SE_LOCATION 255
|
||||
|
||||
/** The base of the range of ITS file identifiers for secure element
|
||||
* driver persistent data.
|
||||
*
|
||||
* We use a slice of the implementation reserved range 0xffff0000..0xffffffff,
|
||||
* specifically the range 0xfffffe00..0xfffffeff. The length of this range
|
||||
* drives the value of #PSA_MAX_SE_LOCATION. The identifier 0xfffffe00 is
|
||||
* actually not used since it corresponds to #PSA_KEY_LOCATION_LOCAL_STORAGE
|
||||
* which doesn't have a driver.
|
||||
*/
|
||||
#define PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE ((psa_key_id_t) 0xfffffe00)
|
||||
|
||||
/** The maximum number of registered secure element driver locations. */
|
||||
#define PSA_MAX_SE_DRIVERS 4
|
||||
|
||||
/** Unregister all secure element drivers.
|
||||
*
|
||||
* \warning Do not call this function while the library is in the initialized
|
||||
* state. This function is only intended to be called at the end
|
||||
* of mbedtls_psa_crypto_free().
|
||||
*/
|
||||
void psa_unregister_all_se_drivers(void);
|
||||
|
||||
/** Initialize all secure element drivers.
|
||||
*
|
||||
* Called from psa_crypto_init().
|
||||
*/
|
||||
psa_status_t psa_init_all_se_drivers(void);
|
||||
|
||||
/** A structure that describes a registered secure element driver.
|
||||
*
|
||||
* A secure element driver table entry contains a pointer to the
|
||||
* driver's method table as well as the driver context structure.
|
||||
*/
|
||||
typedef struct psa_se_drv_table_entry_s psa_se_drv_table_entry_t;
|
||||
|
||||
/** Return the secure element driver information for a lifetime value.
|
||||
*
|
||||
* \param lifetime The lifetime value to query.
|
||||
* \param[out] p_methods On output, if there is a driver,
|
||||
* \c *methods points to its method table.
|
||||
* Otherwise \c *methods is \c NULL.
|
||||
* \param[out] p_drv_context On output, if there is a driver,
|
||||
* \c *drv_context points to its context
|
||||
* structure.
|
||||
* Otherwise \c *drv_context is \c NULL.
|
||||
*
|
||||
* \retval 1
|
||||
* \p lifetime corresponds to a registered driver.
|
||||
* \retval 0
|
||||
* \p lifetime does not correspond to a registered driver.
|
||||
*/
|
||||
int psa_get_se_driver(psa_key_lifetime_t lifetime,
|
||||
const psa_drv_se_t **p_methods,
|
||||
psa_drv_se_context_t **p_drv_context);
|
||||
|
||||
/** Return the secure element driver table entry for a lifetime value.
|
||||
*
|
||||
* \param lifetime The lifetime value to query.
|
||||
*
|
||||
* \return The driver table entry for \p lifetime, or
|
||||
* \p NULL if \p lifetime does not correspond to a registered driver.
|
||||
*/
|
||||
psa_se_drv_table_entry_t *psa_get_se_driver_entry(
|
||||
psa_key_lifetime_t lifetime);
|
||||
|
||||
/** Return the method table for a secure element driver.
|
||||
*
|
||||
* \param[in] driver The driver table entry to access, or \c NULL.
|
||||
*
|
||||
* \return The driver's method table.
|
||||
* \c NULL if \p driver is \c NULL.
|
||||
*/
|
||||
const psa_drv_se_t *psa_get_se_driver_methods(
|
||||
const psa_se_drv_table_entry_t *driver);
|
||||
|
||||
/** Return the context of a secure element driver.
|
||||
*
|
||||
* \param[in] driver The driver table entry to access, or \c NULL.
|
||||
*
|
||||
* \return A pointer to the driver context.
|
||||
* \c NULL if \p driver is \c NULL.
|
||||
*/
|
||||
psa_drv_se_context_t *psa_get_se_driver_context(
|
||||
psa_se_drv_table_entry_t *driver);
|
||||
|
||||
/** Find a free slot for a key that is to be created.
|
||||
*
|
||||
* This function calls the relevant method in the driver to find a suitable
|
||||
* slot for a key with the given attributes.
|
||||
*
|
||||
* \param[in] attributes Metadata about the key that is about to be created.
|
||||
* \param[in] driver The driver table entry to query.
|
||||
* \param[out] slot_number On success, a slot number that is free in this
|
||||
* secure element.
|
||||
*/
|
||||
psa_status_t psa_find_se_slot_for_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_creation_method_t method,
|
||||
psa_se_drv_table_entry_t *driver,
|
||||
psa_key_slot_number_t *slot_number);
|
||||
|
||||
/** Destroy a key in a secure element.
|
||||
*
|
||||
* This function calls the relevant driver method to destroy a key
|
||||
* and updates the driver's persistent data.
|
||||
*/
|
||||
psa_status_t psa_destroy_se_key(psa_se_drv_table_entry_t *driver,
|
||||
psa_key_slot_number_t slot_number);
|
||||
|
||||
/** Load the persistent data of a secure element driver.
|
||||
*
|
||||
* \param driver The driver table entry containing the persistent
|
||||
* data to load from storage.
|
||||
*
|
||||
* \return #PSA_SUCCESS
|
||||
* \return #PSA_ERROR_NOT_SUPPORTED
|
||||
* \return #PSA_ERROR_DOES_NOT_EXIST
|
||||
* \return #PSA_ERROR_STORAGE_FAILURE
|
||||
* \return #PSA_ERROR_DATA_CORRUPT
|
||||
* \return #PSA_ERROR_INVALID_ARGUMENT
|
||||
*/
|
||||
psa_status_t psa_load_se_persistent_data(
|
||||
const psa_se_drv_table_entry_t *driver);
|
||||
|
||||
/** Save the persistent data of a secure element driver.
|
||||
*
|
||||
* \param[in] driver The driver table entry containing the persistent
|
||||
* data to save to storage.
|
||||
*
|
||||
* \return #PSA_SUCCESS
|
||||
* \return #PSA_ERROR_NOT_SUPPORTED
|
||||
* \return #PSA_ERROR_NOT_PERMITTED
|
||||
* \return #PSA_ERROR_NOT_SUPPORTED
|
||||
* \return #PSA_ERROR_INSUFFICIENT_STORAGE
|
||||
* \return #PSA_ERROR_STORAGE_FAILURE
|
||||
* \return #PSA_ERROR_INVALID_ARGUMENT
|
||||
*/
|
||||
psa_status_t psa_save_se_persistent_data(
|
||||
const psa_se_drv_table_entry_t *driver);
|
||||
|
||||
/** Destroy the persistent data of a secure element driver.
|
||||
*
|
||||
* This is currently only used for testing.
|
||||
*
|
||||
* \param[in] location The location identifier for the driver whose
|
||||
* persistent data is to be erased.
|
||||
*/
|
||||
psa_status_t psa_destroy_se_persistent_data(psa_key_location_t location);
|
||||
|
||||
|
||||
/** The storage representation of a key whose data is in a secure element.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t slot_number[sizeof(psa_key_slot_number_t)];
|
||||
} psa_se_key_data_storage_t;
|
||||
|
||||
#endif /* PSA_CRYPTO_SE_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,344 +0,0 @@
|
||||
/*
|
||||
* PSA crypto layer on top of Mbed TLS crypto
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_SLOT_MANAGEMENT_H
|
||||
#define PSA_CRYPTO_SLOT_MANAGEMENT_H
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_se.h"
|
||||
|
||||
/** Range of volatile key identifiers.
|
||||
*
|
||||
* The first #MBEDTLS_PSA_KEY_SLOT_COUNT identifiers of the implementation
|
||||
* range of key identifiers are reserved for volatile key identifiers.
|
||||
*
|
||||
* If \c id is a a volatile key identifier, #PSA_KEY_ID_VOLATILE_MIN - \c id
|
||||
* indicates the key slot containing the volatile key definition. See
|
||||
* psa_crypto_slot_management.c for details.
|
||||
*/
|
||||
|
||||
/** The minimum value for a volatile key identifier.
|
||||
*/
|
||||
#define PSA_KEY_ID_VOLATILE_MIN PSA_KEY_ID_VENDOR_MIN
|
||||
|
||||
/** The maximum value for a volatile key identifier.
|
||||
*/
|
||||
#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
|
||||
#define PSA_KEY_ID_VOLATILE_MAX (MBEDTLS_PSA_KEY_ID_BUILTIN_MIN - 1)
|
||||
#else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
|
||||
#define PSA_KEY_ID_VOLATILE_MAX \
|
||||
(PSA_KEY_ID_VOLATILE_MIN + MBEDTLS_PSA_KEY_SLOT_COUNT - 1)
|
||||
#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
|
||||
|
||||
/** Test whether a key identifier is a volatile key identifier.
|
||||
*
|
||||
* \param key_id Key identifier to test.
|
||||
*
|
||||
* \retval 1
|
||||
* The key identifier is a volatile key identifier.
|
||||
* \retval 0
|
||||
* The key identifier is not a volatile key identifier.
|
||||
*/
|
||||
static inline int psa_key_id_is_volatile(psa_key_id_t key_id)
|
||||
{
|
||||
return (key_id >= PSA_KEY_ID_VOLATILE_MIN) &&
|
||||
(key_id <= PSA_KEY_ID_VOLATILE_MAX);
|
||||
}
|
||||
|
||||
/** Get the description of a key given its identifier and lock it.
|
||||
*
|
||||
* The descriptions of volatile keys and loaded persistent keys are stored in
|
||||
* key slots. This function returns a pointer to the key slot containing the
|
||||
* description of a key given its identifier.
|
||||
*
|
||||
* In case of a persistent key, the function loads the description of the key
|
||||
* into a key slot if not already done.
|
||||
*
|
||||
* On success, the returned key slot has been registered for reading.
|
||||
* It is the responsibility of the caller to call psa_unregister_read(slot)
|
||||
* when they have finished reading the contents of the slot.
|
||||
*
|
||||
* On failure, `*p_slot` is set to NULL. This ensures that it is always valid
|
||||
* to call psa_unregister_read on the returned slot.
|
||||
*
|
||||
* \param key Key identifier to query.
|
||||
* \param[out] p_slot On success, `*p_slot` contains a pointer to the
|
||||
* key slot containing the description of the key
|
||||
* identified by \p key.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* \p *p_slot contains a pointer to the key slot containing the
|
||||
* description of the key identified by \p key.
|
||||
* The key slot counter has been incremented.
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The library has not been initialized.
|
||||
* \retval #PSA_ERROR_INVALID_HANDLE
|
||||
* \p key is not a valid key identifier.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* \p key is a persistent key identifier. The implementation does not
|
||||
* have sufficient resources to load the persistent key. This can be
|
||||
* due to a lack of empty key slot, or available memory.
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST
|
||||
* There is no key with key identifier \p key.
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
*/
|
||||
psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key,
|
||||
psa_key_slot_t **p_slot);
|
||||
|
||||
/** Initialize the key slot structures.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Currently this function always succeeds.
|
||||
*/
|
||||
psa_status_t psa_initialize_key_slots(void);
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
|
||||
/* Allow test code to customize the key slice length. We use this in tests
|
||||
* that exhaust the key store to reach a full key store in reasonable time
|
||||
* and memory.
|
||||
*
|
||||
* The length of each slice must be between 1 and
|
||||
* (1 << KEY_ID_SLOT_INDEX_WIDTH) inclusive.
|
||||
*
|
||||
* The length for a given slice index must not change while
|
||||
* the key store is initialized.
|
||||
*/
|
||||
extern size_t (*mbedtls_test_hook_psa_volatile_key_slice_length)(
|
||||
size_t slice_idx);
|
||||
|
||||
/* The number of volatile key slices. */
|
||||
size_t psa_key_slot_volatile_slice_count(void);
|
||||
#endif
|
||||
|
||||
/** Delete all data from key slots in memory.
|
||||
* This function is not thread safe, it wipes every key slot regardless of
|
||||
* state and reader count. It should only be called when no slot is in use.
|
||||
*
|
||||
* This does not affect persistent storage. */
|
||||
void psa_wipe_all_key_slots(void);
|
||||
|
||||
/** Find a free key slot and reserve it to be filled with a key.
|
||||
*
|
||||
* This function finds a key slot that is free,
|
||||
* sets its state to PSA_SLOT_FILLING and then returns the slot.
|
||||
*
|
||||
* On success, the key slot's state is PSA_SLOT_FILLING.
|
||||
* It is the responsibility of the caller to change the slot's state to
|
||||
* PSA_SLOT_EMPTY/FULL once key creation has finished.
|
||||
*
|
||||
* If multi-threading is enabled, the caller must hold the
|
||||
* global key slot mutex.
|
||||
*
|
||||
* \param[out] volatile_key_id - If null, reserve a cache slot for
|
||||
* a persistent or built-in key.
|
||||
* - If non-null, allocate a slot for
|
||||
* a volatile key. On success,
|
||||
* \p *volatile_key_id is the
|
||||
* identifier corresponding to the
|
||||
* returned slot. It is the caller's
|
||||
* responsibility to set this key identifier
|
||||
* in the attributes.
|
||||
* \param[out] p_slot On success, a pointer to the slot.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* There were no free key slots.
|
||||
* When #MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, there was not
|
||||
* enough memory to allocate more slots.
|
||||
* \retval #PSA_ERROR_BAD_STATE \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
* This function attempted to operate on a key slot which was in an
|
||||
* unexpected state.
|
||||
*/
|
||||
psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id,
|
||||
psa_key_slot_t **p_slot);
|
||||
|
||||
#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
|
||||
/** Return a key slot to the free list.
|
||||
*
|
||||
* Call this function when a slot obtained from psa_reserve_free_key_slot()
|
||||
* is no longer in use.
|
||||
*
|
||||
* If multi-threading is enabled, the caller must hold the
|
||||
* global key slot mutex.
|
||||
*
|
||||
* \param slice_idx The slice containing the slot.
|
||||
* This is `slot->slice_index` when the slot
|
||||
* is obtained from psa_reserve_free_key_slot().
|
||||
* \param slot The key slot.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
* This function attempted to operate on a key slot which was in an
|
||||
* unexpected state.
|
||||
*/
|
||||
psa_status_t psa_free_key_slot(size_t slice_idx,
|
||||
psa_key_slot_t *slot);
|
||||
#endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
|
||||
|
||||
/** Change the state of a key slot.
|
||||
*
|
||||
* This function changes the state of the key slot from expected_state to
|
||||
* new state. If the state of the slot was not expected_state, the state is
|
||||
* unchanged.
|
||||
*
|
||||
* If multi-threading is enabled, the caller must hold the
|
||||
* global key slot mutex.
|
||||
*
|
||||
* \param[in] slot The key slot.
|
||||
* \param[in] expected_state The current state of the slot.
|
||||
* \param[in] new_state The new state of the slot.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
The key slot's state variable is new_state.
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
* The slot's state was not expected_state.
|
||||
*/
|
||||
static inline psa_status_t psa_key_slot_state_transition(
|
||||
psa_key_slot_t *slot, psa_key_slot_state_t expected_state,
|
||||
psa_key_slot_state_t new_state)
|
||||
{
|
||||
if (slot->state != expected_state) {
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
slot->state = new_state;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/** Register as a reader of a key slot.
|
||||
*
|
||||
* This function increments the key slot registered reader counter by one.
|
||||
* If multi-threading is enabled, the caller must hold the
|
||||
* global key slot mutex.
|
||||
*
|
||||
* \param[in] slot The key slot.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
The key slot registered reader counter was incremented.
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
* The reader counter already reached its maximum value and was not
|
||||
* increased, or the slot's state was not PSA_SLOT_FULL.
|
||||
*/
|
||||
static inline psa_status_t psa_register_read(psa_key_slot_t *slot)
|
||||
{
|
||||
if ((slot->state != PSA_SLOT_FULL) ||
|
||||
(slot->var.occupied.registered_readers >= SIZE_MAX)) {
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
slot->var.occupied.registered_readers++;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/** Unregister from reading a key slot.
|
||||
*
|
||||
* This function decrements the key slot registered reader counter by one.
|
||||
* If the state of the slot is PSA_SLOT_PENDING_DELETION,
|
||||
* and there is only one registered reader (the caller),
|
||||
* this function will call psa_wipe_key_slot().
|
||||
* If multi-threading is enabled, the caller must hold the
|
||||
* global key slot mutex.
|
||||
*
|
||||
* \note To ease the handling of errors in retrieving a key slot
|
||||
* a NULL input pointer is valid, and the function returns
|
||||
* successfully without doing anything in that case.
|
||||
*
|
||||
* \param[in] slot The key slot.
|
||||
* \retval #PSA_SUCCESS
|
||||
* \p slot is NULL or the key slot reader counter has been
|
||||
* decremented (and potentially wiped) successfully.
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
* The slot's state was neither PSA_SLOT_FULL nor
|
||||
* PSA_SLOT_PENDING_DELETION.
|
||||
* Or a wipe was attempted and the slot's state was not
|
||||
* PSA_SLOT_PENDING_DELETION.
|
||||
* Or registered_readers was equal to 0.
|
||||
*/
|
||||
psa_status_t psa_unregister_read(psa_key_slot_t *slot);
|
||||
|
||||
/** Wrap a call to psa_unregister_read in the global key slot mutex.
|
||||
*
|
||||
* If threading is disabled, this simply calls psa_unregister_read.
|
||||
*
|
||||
* \note To ease the handling of errors in retrieving a key slot
|
||||
* a NULL input pointer is valid, and the function returns
|
||||
* successfully without doing anything in that case.
|
||||
*
|
||||
* \param[in] slot The key slot.
|
||||
* \retval #PSA_SUCCESS
|
||||
* \p slot is NULL or the key slot reader counter has been
|
||||
* decremented (and potentially wiped) successfully.
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
* The slot's state was neither PSA_SLOT_FULL nor
|
||||
* PSA_SLOT_PENDING_DELETION.
|
||||
* Or a wipe was attempted and the slot's state was not
|
||||
* PSA_SLOT_PENDING_DELETION.
|
||||
* Or registered_readers was equal to 0.
|
||||
*/
|
||||
psa_status_t psa_unregister_read_under_mutex(psa_key_slot_t *slot);
|
||||
|
||||
/** Test whether a lifetime designates a key in an external cryptoprocessor.
|
||||
*
|
||||
* \param lifetime The lifetime to test.
|
||||
*
|
||||
* \retval 1
|
||||
* The lifetime designates an external key. There should be a
|
||||
* registered driver for this lifetime, otherwise the key cannot
|
||||
* be created or manipulated.
|
||||
* \retval 0
|
||||
* The lifetime designates a key that is volatile or in internal
|
||||
* storage.
|
||||
*/
|
||||
static inline int psa_key_lifetime_is_external(psa_key_lifetime_t lifetime)
|
||||
{
|
||||
return PSA_KEY_LIFETIME_GET_LOCATION(lifetime)
|
||||
!= PSA_KEY_LOCATION_LOCAL_STORAGE;
|
||||
}
|
||||
|
||||
/** Validate a key's location.
|
||||
*
|
||||
* This function checks whether the key's attributes point to a location that
|
||||
* is known to the PSA Core, and returns the driver function table if the key
|
||||
* is to be found in an external location.
|
||||
*
|
||||
* \param[in] lifetime The key lifetime attribute.
|
||||
* \param[out] p_drv On success, when a key is located in external
|
||||
* storage, returns a pointer to the driver table
|
||||
* associated with the key's storage location.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
|
||||
*/
|
||||
psa_status_t psa_validate_key_location(psa_key_lifetime_t lifetime,
|
||||
psa_se_drv_table_entry_t **p_drv);
|
||||
|
||||
/** Validate the persistence of a key.
|
||||
*
|
||||
* \param[in] lifetime The key lifetime attribute.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED The key is persistent but persistent keys
|
||||
* are not supported.
|
||||
*/
|
||||
psa_status_t psa_validate_key_persistence(psa_key_lifetime_t lifetime);
|
||||
|
||||
/** Validate a key identifier.
|
||||
*
|
||||
* \param[in] key The key identifier.
|
||||
* \param[in] vendor_ok Non-zero to indicate that key identifiers in the
|
||||
* vendor range are allowed, volatile key identifiers
|
||||
* excepted \c 0 otherwise.
|
||||
*
|
||||
* \retval <> 0 if the key identifier is valid, 0 otherwise.
|
||||
*/
|
||||
int psa_is_valid_key_id(mbedtls_svc_key_id_t key, int vendor_ok);
|
||||
|
||||
#endif /* PSA_CRYPTO_SLOT_MANAGEMENT_H */
|
||||
@@ -1,481 +0,0 @@
|
||||
/*
|
||||
* PSA persistent key storage
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_storage.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_ITS_FILE_C)
|
||||
#include "psa_crypto_its.h"
|
||||
#else /* Native ITS implementation */
|
||||
#include "psa/error.h"
|
||||
#include "psa/internal_trusted_storage.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Key storage */
|
||||
/****************************************************************/
|
||||
|
||||
/* Determine a file name (ITS file identifier) for the given key identifier.
|
||||
* The file name must be distinct from any file that is used for a purpose
|
||||
* other than storing a key. Currently, the only such file is the random seed
|
||||
* file whose name is PSA_CRYPTO_ITS_RANDOM_SEED_UID and whose value is
|
||||
* 0xFFFFFF52. */
|
||||
static psa_storage_uid_t psa_its_identifier_of_slot(mbedtls_svc_key_id_t key)
|
||||
{
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
|
||||
/* Encode the owner in the upper 32 bits. This means that if
|
||||
* owner values are nonzero (as they are on a PSA platform),
|
||||
* no key file will ever have a value less than 0x100000000, so
|
||||
* the whole range 0..0xffffffff is available for non-key files. */
|
||||
uint32_t unsigned_owner_id = MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(key);
|
||||
return ((uint64_t) unsigned_owner_id << 32) |
|
||||
MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key);
|
||||
#else
|
||||
/* Use the key id directly as a file name.
|
||||
* psa_is_key_id_valid() in psa_crypto_slot_management.c
|
||||
* is responsible for ensuring that key identifiers do not have a
|
||||
* value that is reserved for non-key files. */
|
||||
return key;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Load persistent data for the given key slot number.
|
||||
*
|
||||
* This function reads data from a storage backend and returns the data in a
|
||||
* buffer.
|
||||
*
|
||||
* \param key Persistent identifier of the key to be loaded. This
|
||||
* should be an occupied storage location.
|
||||
* \param[out] data Buffer where the data is to be written.
|
||||
* \param data_size Size of the \c data buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
|
||||
*/
|
||||
static psa_status_t psa_crypto_storage_load(
|
||||
const mbedtls_svc_key_id_t key, uint8_t *data, size_t data_size)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
|
||||
struct psa_storage_info_t data_identifier_info;
|
||||
size_t data_length = 0;
|
||||
|
||||
status = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_its_get(data_identifier, 0, (uint32_t) data_size, data, &data_length);
|
||||
if (data_size != data_length) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key)
|
||||
{
|
||||
psa_status_t ret;
|
||||
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
|
||||
struct psa_storage_info_t data_identifier_info;
|
||||
|
||||
ret = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
|
||||
if (ret == PSA_ERROR_DOES_NOT_EXIST) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Store persistent data for the given key slot number.
|
||||
*
|
||||
* This function stores the given data buffer to a persistent storage.
|
||||
*
|
||||
* \param key Persistent identifier of the key to be stored. This
|
||||
* should be an unoccupied storage location.
|
||||
* \param[in] data Buffer containing the data to be stored.
|
||||
* \param data_length The number of bytes
|
||||
* that make up the data.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
|
||||
* \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
*/
|
||||
static psa_status_t psa_crypto_storage_store(const mbedtls_svc_key_id_t key,
|
||||
const uint8_t *data,
|
||||
size_t data_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
|
||||
struct psa_storage_info_t data_identifier_info;
|
||||
|
||||
if (psa_is_key_present_in_storage(key) == 1) {
|
||||
return PSA_ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
status = psa_its_set(data_identifier, (uint32_t) data_length, data, 0);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
status = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (data_identifier_info.size != data_length) {
|
||||
status = PSA_ERROR_DATA_INVALID;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (status != PSA_SUCCESS) {
|
||||
/* Remove the file in case we managed to create it but something
|
||||
* went wrong. It's ok if the file doesn't exist. If the file exists
|
||||
* but the removal fails, we're already reporting an error so there's
|
||||
* nothing else we can do. */
|
||||
(void) psa_its_remove(data_identifier);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_destroy_persistent_key(const mbedtls_svc_key_id_t key)
|
||||
{
|
||||
psa_status_t ret;
|
||||
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
|
||||
struct psa_storage_info_t data_identifier_info;
|
||||
|
||||
ret = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
if (ret == PSA_ERROR_DOES_NOT_EXIST) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
if (psa_its_remove(data_identifier) != PSA_SUCCESS) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
ret = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
if (ret != PSA_ERROR_DOES_NOT_EXIST) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get data length for given key slot number.
|
||||
*
|
||||
* \param key Persistent identifier whose stored data length
|
||||
* is to be obtained.
|
||||
* \param[out] data_length The number of bytes that make up the data.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
*/
|
||||
static psa_status_t psa_crypto_storage_get_data_length(
|
||||
const mbedtls_svc_key_id_t key,
|
||||
size_t *data_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
|
||||
struct psa_storage_info_t data_identifier_info;
|
||||
|
||||
status = psa_its_get_info(data_identifier, &data_identifier_info);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
*data_length = (size_t) data_identifier_info.size;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Persistent key storage magic header.
|
||||
*/
|
||||
#define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY"
|
||||
#define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH (sizeof(PSA_KEY_STORAGE_MAGIC_HEADER))
|
||||
|
||||
typedef struct {
|
||||
uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH];
|
||||
uint8_t version[4];
|
||||
uint8_t lifetime[sizeof(psa_key_lifetime_t)];
|
||||
uint8_t type[2];
|
||||
uint8_t bits[2];
|
||||
uint8_t policy[sizeof(psa_key_policy_t)];
|
||||
uint8_t data_len[4];
|
||||
uint8_t key_data[];
|
||||
} psa_persistent_key_storage_format;
|
||||
|
||||
void psa_format_key_data_for_storage(const uint8_t *data,
|
||||
const size_t data_length,
|
||||
const psa_key_attributes_t *attr,
|
||||
uint8_t *storage_data)
|
||||
{
|
||||
psa_persistent_key_storage_format *storage_format =
|
||||
(psa_persistent_key_storage_format *) storage_data;
|
||||
|
||||
memcpy(storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER,
|
||||
PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH);
|
||||
MBEDTLS_PUT_UINT32_LE(0, storage_format->version, 0);
|
||||
MBEDTLS_PUT_UINT32_LE(attr->lifetime, storage_format->lifetime, 0);
|
||||
MBEDTLS_PUT_UINT16_LE((uint16_t) attr->type, storage_format->type, 0);
|
||||
MBEDTLS_PUT_UINT16_LE((uint16_t) attr->bits, storage_format->bits, 0);
|
||||
MBEDTLS_PUT_UINT32_LE(attr->policy.usage, storage_format->policy, 0);
|
||||
MBEDTLS_PUT_UINT32_LE(attr->policy.alg, storage_format->policy, sizeof(uint32_t));
|
||||
MBEDTLS_PUT_UINT32_LE(attr->policy.alg2, storage_format->policy, 2 * sizeof(uint32_t));
|
||||
MBEDTLS_PUT_UINT32_LE(data_length, storage_format->data_len, 0);
|
||||
memcpy(storage_format->key_data, data, data_length);
|
||||
}
|
||||
|
||||
static psa_status_t check_magic_header(const uint8_t *data)
|
||||
{
|
||||
if (memcmp(data, PSA_KEY_STORAGE_MAGIC_HEADER,
|
||||
PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH) != 0) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data,
|
||||
size_t storage_data_length,
|
||||
uint8_t **key_data,
|
||||
size_t *key_data_length,
|
||||
psa_key_attributes_t *attr)
|
||||
{
|
||||
psa_status_t status;
|
||||
const psa_persistent_key_storage_format *storage_format =
|
||||
(const psa_persistent_key_storage_format *) storage_data;
|
||||
uint32_t version;
|
||||
|
||||
if (storage_data_length < sizeof(*storage_format)) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
status = check_magic_header(storage_data);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
version = MBEDTLS_GET_UINT32_LE(storage_format->version, 0);
|
||||
if (version != 0) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
*key_data_length = MBEDTLS_GET_UINT32_LE(storage_format->data_len, 0);
|
||||
if (*key_data_length > (storage_data_length - sizeof(*storage_format)) ||
|
||||
*key_data_length > PSA_CRYPTO_MAX_STORAGE_SIZE) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
|
||||
if (*key_data_length == 0) {
|
||||
*key_data = NULL;
|
||||
} else {
|
||||
*key_data = mbedtls_calloc(1, *key_data_length);
|
||||
if (*key_data == NULL) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
memcpy(*key_data, storage_format->key_data, *key_data_length);
|
||||
}
|
||||
|
||||
attr->lifetime = MBEDTLS_GET_UINT32_LE(storage_format->lifetime, 0);
|
||||
attr->type = MBEDTLS_GET_UINT16_LE(storage_format->type, 0);
|
||||
attr->bits = MBEDTLS_GET_UINT16_LE(storage_format->bits, 0);
|
||||
attr->policy.usage = MBEDTLS_GET_UINT32_LE(storage_format->policy, 0);
|
||||
attr->policy.alg = MBEDTLS_GET_UINT32_LE(storage_format->policy, sizeof(uint32_t));
|
||||
attr->policy.alg2 = MBEDTLS_GET_UINT32_LE(storage_format->policy, 2 * sizeof(uint32_t));
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_save_persistent_key(const psa_key_attributes_t *attr,
|
||||
const uint8_t *data,
|
||||
const size_t data_length)
|
||||
{
|
||||
size_t storage_data_length;
|
||||
uint8_t *storage_data;
|
||||
psa_status_t status;
|
||||
|
||||
/* All keys saved to persistent storage always have a key context */
|
||||
if (data == NULL || data_length == 0) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (data_length > PSA_CRYPTO_MAX_STORAGE_SIZE) {
|
||||
return PSA_ERROR_INSUFFICIENT_STORAGE;
|
||||
}
|
||||
storage_data_length = data_length + sizeof(psa_persistent_key_storage_format);
|
||||
|
||||
storage_data = mbedtls_calloc(1, storage_data_length);
|
||||
if (storage_data == NULL) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
psa_format_key_data_for_storage(data, data_length, attr, storage_data);
|
||||
|
||||
status = psa_crypto_storage_store(attr->id,
|
||||
storage_data, storage_data_length);
|
||||
|
||||
mbedtls_zeroize_and_free(storage_data, storage_data_length);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void psa_free_persistent_key_data(uint8_t *key_data, size_t key_data_length)
|
||||
{
|
||||
mbedtls_zeroize_and_free(key_data, key_data_length);
|
||||
}
|
||||
|
||||
psa_status_t psa_load_persistent_key(psa_key_attributes_t *attr,
|
||||
uint8_t **data,
|
||||
size_t *data_length)
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
uint8_t *loaded_data;
|
||||
size_t storage_data_length = 0;
|
||||
mbedtls_svc_key_id_t key = attr->id;
|
||||
|
||||
status = psa_crypto_storage_get_data_length(key, &storage_data_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
loaded_data = mbedtls_calloc(1, storage_data_length);
|
||||
|
||||
if (loaded_data == NULL) {
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
status = psa_crypto_storage_load(key, loaded_data, storage_data_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_parse_key_data_from_storage(loaded_data, storage_data_length,
|
||||
data, data_length, attr);
|
||||
|
||||
/* All keys saved to persistent storage always have a key context */
|
||||
if (status == PSA_SUCCESS &&
|
||||
(*data == NULL || *data_length == 0)) {
|
||||
status = PSA_ERROR_STORAGE_FAILURE;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_zeroize_and_free(loaded_data, storage_data_length);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Transactions */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
|
||||
|
||||
psa_crypto_transaction_t psa_crypto_transaction;
|
||||
|
||||
psa_status_t psa_crypto_save_transaction(void)
|
||||
{
|
||||
struct psa_storage_info_t p_info;
|
||||
psa_status_t status;
|
||||
status = psa_its_get_info(PSA_CRYPTO_ITS_TRANSACTION_UID, &p_info);
|
||||
if (status == PSA_SUCCESS) {
|
||||
/* This shouldn't happen: we're trying to start a transaction while
|
||||
* there is still a transaction that hasn't been replayed. */
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
} else if (status != PSA_ERROR_DOES_NOT_EXIST) {
|
||||
return status;
|
||||
}
|
||||
return psa_its_set(PSA_CRYPTO_ITS_TRANSACTION_UID,
|
||||
sizeof(psa_crypto_transaction),
|
||||
&psa_crypto_transaction,
|
||||
0);
|
||||
}
|
||||
|
||||
psa_status_t psa_crypto_load_transaction(void)
|
||||
{
|
||||
psa_status_t status;
|
||||
size_t length;
|
||||
status = psa_its_get(PSA_CRYPTO_ITS_TRANSACTION_UID, 0,
|
||||
sizeof(psa_crypto_transaction),
|
||||
&psa_crypto_transaction, &length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
if (length != sizeof(psa_crypto_transaction)) {
|
||||
return PSA_ERROR_DATA_INVALID;
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_crypto_stop_transaction(void)
|
||||
{
|
||||
psa_status_t status = psa_its_remove(PSA_CRYPTO_ITS_TRANSACTION_UID);
|
||||
/* Whether or not updating the storage succeeded, the transaction is
|
||||
* finished now. It's too late to go back, so zero out the in-memory
|
||||
* data. */
|
||||
memset(&psa_crypto_transaction, 0, sizeof(psa_crypto_transaction));
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Random generator state */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
|
||||
psa_status_t mbedtls_psa_storage_inject_entropy(const unsigned char *seed,
|
||||
size_t seed_size)
|
||||
{
|
||||
psa_status_t status;
|
||||
struct psa_storage_info_t p_info;
|
||||
|
||||
status = psa_its_get_info(PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info);
|
||||
|
||||
if (PSA_ERROR_DOES_NOT_EXIST == status) { /* No seed exists */
|
||||
status = psa_its_set(PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0);
|
||||
} else if (PSA_SUCCESS == status) {
|
||||
/* You should not be here. Seed needs to be injected only once */
|
||||
status = PSA_ERROR_NOT_PERMITTED;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* The end */
|
||||
/****************************************************************/
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
||||
@@ -1,392 +0,0 @@
|
||||
/**
|
||||
* \file psa_crypto_storage.h
|
||||
*
|
||||
* \brief PSA cryptography module: Mbed TLS key storage
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_STORAGE_H
|
||||
#define PSA_CRYPTO_STORAGE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa/crypto_se_driver.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Limit the maximum key size in storage. */
|
||||
#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS)
|
||||
/* Reflect the maximum size for the key buffer. */
|
||||
#define PSA_CRYPTO_MAX_STORAGE_SIZE (MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE)
|
||||
#else
|
||||
/* Just set an upper boundary but it should have no effect since the key size
|
||||
* is limited in memory. */
|
||||
#define PSA_CRYPTO_MAX_STORAGE_SIZE (PSA_BITS_TO_BYTES(PSA_MAX_KEY_BITS))
|
||||
#endif
|
||||
|
||||
/* Sanity check: a file size must fit in 32 bits. Allow a generous
|
||||
* 64kB of metadata. */
|
||||
#if PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000
|
||||
#error "PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000"
|
||||
#endif
|
||||
|
||||
/** The maximum permitted persistent slot number.
|
||||
*
|
||||
* In Mbed Crypto 0.1.0b:
|
||||
* - Using the file backend, all key ids are ok except 0.
|
||||
* - Using the ITS backend, all key ids are ok except 0xFFFFFF52
|
||||
* (#PSA_CRYPTO_ITS_RANDOM_SEED_UID) for which the file contains the
|
||||
* device's random seed (if this feature is enabled).
|
||||
* - Only key ids from 1 to #MBEDTLS_PSA_KEY_SLOT_COUNT are actually used.
|
||||
*
|
||||
* Since we need to preserve the random seed, avoid using that key slot.
|
||||
* Reserve a whole range of key slots just in case something else comes up.
|
||||
*
|
||||
* This limitation will probably become moot when we implement client
|
||||
* separation for key storage.
|
||||
*/
|
||||
#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER PSA_KEY_ID_VENDOR_MAX
|
||||
|
||||
/**
|
||||
* \brief Checks if persistent data is stored for the given key slot number
|
||||
*
|
||||
* This function checks if any key data or metadata exists for the key slot in
|
||||
* the persistent storage.
|
||||
*
|
||||
* \param key Persistent identifier to check.
|
||||
*
|
||||
* \retval 0
|
||||
* No persistent data present for slot number
|
||||
* \retval 1
|
||||
* Persistent data present for slot number
|
||||
*/
|
||||
int psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key);
|
||||
|
||||
/**
|
||||
* \brief Format key data and metadata and save to a location for given key
|
||||
* slot.
|
||||
*
|
||||
* This function formats the key data and metadata and saves it to a
|
||||
* persistent storage backend. The storage location corresponding to the
|
||||
* key slot must be empty, otherwise this function will fail. This function
|
||||
* should be called after loading the key into an internal slot to ensure the
|
||||
* persistent key is not saved into a storage location corresponding to an
|
||||
* already occupied non-persistent key, as well as ensuring the key data is
|
||||
* validated.
|
||||
*
|
||||
* Note: This function will only succeed for key buffers which are not
|
||||
* empty. If passed a NULL pointer or zero-length, the function will fail
|
||||
* with #PSA_ERROR_INVALID_ARGUMENT.
|
||||
*
|
||||
* \param[in] attr The attributes of the key to save.
|
||||
* The key identifier field in the attributes
|
||||
* determines the key's location.
|
||||
* \param[in] data Buffer containing the key data.
|
||||
* \param data_length The number of bytes that make up the key data.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
*/
|
||||
psa_status_t psa_save_persistent_key(const psa_key_attributes_t *attr,
|
||||
const uint8_t *data,
|
||||
const size_t data_length);
|
||||
|
||||
/**
|
||||
* \brief Parses key data and metadata and load persistent key for given
|
||||
* key slot number.
|
||||
*
|
||||
* This function reads from a storage backend, parses the key data and
|
||||
* metadata and writes them to the appropriate output parameters.
|
||||
*
|
||||
* Note: This function allocates a buffer and returns a pointer to it through
|
||||
* the data parameter. On successful return, the pointer is guaranteed to be
|
||||
* valid and the buffer contains at least one byte of data.
|
||||
* psa_free_persistent_key_data() must be called on the data buffer
|
||||
* afterwards to zeroize and free this buffer.
|
||||
*
|
||||
* \param[in,out] attr On input, the key identifier field identifies
|
||||
* the key to load. Other fields are ignored.
|
||||
* On success, the attribute structure contains
|
||||
* the key metadata that was loaded from storage.
|
||||
* \param[out] data Pointer to an allocated key data buffer on return.
|
||||
* \param[out] data_length The number of bytes that make up the key data.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
|
||||
*/
|
||||
psa_status_t psa_load_persistent_key(psa_key_attributes_t *attr,
|
||||
uint8_t **data,
|
||||
size_t *data_length);
|
||||
|
||||
/**
|
||||
* \brief Remove persistent data for the given key slot number.
|
||||
*
|
||||
* \param key Persistent identifier of the key to remove
|
||||
* from persistent storage.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The key was successfully removed,
|
||||
* or the key did not exist.
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
*/
|
||||
psa_status_t psa_destroy_persistent_key(const mbedtls_svc_key_id_t key);
|
||||
|
||||
/**
|
||||
* \brief Free the temporary buffer allocated by psa_load_persistent_key().
|
||||
*
|
||||
* This function must be called at some point after psa_load_persistent_key()
|
||||
* to zeroize and free the memory allocated to the buffer in that function.
|
||||
*
|
||||
* \param key_data Buffer for the key data.
|
||||
* \param key_data_length Size of the key data buffer.
|
||||
*
|
||||
*/
|
||||
void psa_free_persistent_key_data(uint8_t *key_data, size_t key_data_length);
|
||||
|
||||
/**
|
||||
* \brief Formats key data and metadata for persistent storage
|
||||
*
|
||||
* \param[in] data Buffer containing the key data.
|
||||
* \param data_length Length of the key data buffer.
|
||||
* \param[in] attr The core attributes of the key.
|
||||
* \param[out] storage_data Output buffer for the formatted data.
|
||||
*
|
||||
*/
|
||||
void psa_format_key_data_for_storage(const uint8_t *data,
|
||||
const size_t data_length,
|
||||
const psa_key_attributes_t *attr,
|
||||
uint8_t *storage_data);
|
||||
|
||||
/**
|
||||
* \brief Parses persistent storage data into key data and metadata
|
||||
*
|
||||
* \param[in] storage_data Buffer for the storage data.
|
||||
* \param storage_data_length Length of the storage data buffer
|
||||
* \param[out] key_data On output, pointer to a newly allocated buffer
|
||||
* containing the key data. This must be freed
|
||||
* using psa_free_persistent_key_data()
|
||||
* \param[out] key_data_length Length of the key data buffer
|
||||
* \param[out] attr On success, the attribute structure is filled
|
||||
* with the loaded key metadata.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
*/
|
||||
psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data,
|
||||
size_t storage_data_length,
|
||||
uint8_t **key_data,
|
||||
size_t *key_data_length,
|
||||
psa_key_attributes_t *attr);
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
/** This symbol is defined if transaction support is required. */
|
||||
#define PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS 1
|
||||
#endif
|
||||
|
||||
#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
|
||||
|
||||
/** The type of transaction that is in progress.
|
||||
*/
|
||||
/* This is an integer type rather than an enum for two reasons: to support
|
||||
* unknown values when loading a transaction file, and to ensure that the
|
||||
* type has a known size.
|
||||
*/
|
||||
typedef uint16_t psa_crypto_transaction_type_t;
|
||||
|
||||
/** No transaction is in progress.
|
||||
*
|
||||
* This has the value 0, so zero-initialization sets a transaction's type to
|
||||
* this value.
|
||||
*/
|
||||
#define PSA_CRYPTO_TRANSACTION_NONE ((psa_crypto_transaction_type_t) 0x0000)
|
||||
|
||||
/** A key creation transaction.
|
||||
*
|
||||
* This is only used for keys in an external cryptoprocessor (secure element).
|
||||
* Keys in RAM or in internal storage are created atomically in storage
|
||||
* (simple file creation), so they do not need a transaction mechanism.
|
||||
*/
|
||||
#define PSA_CRYPTO_TRANSACTION_CREATE_KEY ((psa_crypto_transaction_type_t) 0x0001)
|
||||
|
||||
/** A key destruction transaction.
|
||||
*
|
||||
* This is only used for keys in an external cryptoprocessor (secure element).
|
||||
* Keys in RAM or in internal storage are destroyed atomically in storage
|
||||
* (simple file deletion), so they do not need a transaction mechanism.
|
||||
*/
|
||||
#define PSA_CRYPTO_TRANSACTION_DESTROY_KEY ((psa_crypto_transaction_type_t) 0x0002)
|
||||
|
||||
/** Transaction data.
|
||||
*
|
||||
* This type is designed to be serialized by writing the memory representation
|
||||
* and reading it back on the same device.
|
||||
*
|
||||
* \note The transaction mechanism is not thread-safe. There can only be one
|
||||
* single active transaction at a time.
|
||||
* The transaction object is #psa_crypto_transaction.
|
||||
*
|
||||
* \note If an API call starts a transaction, it must complete this transaction
|
||||
* before returning to the application.
|
||||
*
|
||||
* The lifetime of a transaction is the following (note that only one
|
||||
* transaction may be active at a time):
|
||||
*
|
||||
* -# Call psa_crypto_prepare_transaction() to initialize the transaction
|
||||
* object in memory and declare the type of transaction that is starting.
|
||||
* -# Fill in the type-specific fields of #psa_crypto_transaction.
|
||||
* -# Call psa_crypto_save_transaction() to start the transaction. This
|
||||
* saves the transaction data to internal storage.
|
||||
* -# Perform the work of the transaction by modifying files, contacting
|
||||
* external entities, or whatever needs doing. Note that the transaction
|
||||
* may be interrupted by a power failure, so you need to have a way
|
||||
* recover from interruptions either by undoing what has been done
|
||||
* so far or by resuming where you left off.
|
||||
* -# If there are intermediate stages in the transaction, update
|
||||
* the fields of #psa_crypto_transaction and call
|
||||
* psa_crypto_save_transaction() again when each stage is reached.
|
||||
* -# When the transaction is over, call psa_crypto_stop_transaction() to
|
||||
* remove the transaction data in storage and in memory.
|
||||
*
|
||||
* If the system crashes while a transaction is in progress, psa_crypto_init()
|
||||
* calls psa_crypto_load_transaction() and takes care of completing or
|
||||
* rewinding the transaction. This is done in psa_crypto_recover_transaction()
|
||||
* in psa_crypto.c. If you add a new type of transaction, be
|
||||
* sure to add code for it in psa_crypto_recover_transaction().
|
||||
*/
|
||||
typedef union {
|
||||
/* Each element of this union must have the following properties
|
||||
* to facilitate serialization and deserialization:
|
||||
*
|
||||
* - The element is a struct.
|
||||
* - The first field of the struct is `psa_crypto_transaction_type_t type`.
|
||||
* - Elements of the struct are arranged such a way that there is
|
||||
* no padding.
|
||||
*/
|
||||
struct psa_crypto_transaction_unknown_s {
|
||||
psa_crypto_transaction_type_t type;
|
||||
uint16_t unused1;
|
||||
uint32_t unused2;
|
||||
uint64_t unused3;
|
||||
uint64_t unused4;
|
||||
} unknown;
|
||||
/* ::type is #PSA_CRYPTO_TRANSACTION_CREATE_KEY or
|
||||
* #PSA_CRYPTO_TRANSACTION_DESTROY_KEY. */
|
||||
struct psa_crypto_transaction_key_s {
|
||||
psa_crypto_transaction_type_t type;
|
||||
uint16_t unused1;
|
||||
psa_key_lifetime_t lifetime;
|
||||
psa_key_slot_number_t slot;
|
||||
mbedtls_svc_key_id_t id;
|
||||
} key;
|
||||
} psa_crypto_transaction_t;
|
||||
|
||||
/** The single active transaction.
|
||||
*/
|
||||
extern psa_crypto_transaction_t psa_crypto_transaction;
|
||||
|
||||
/** Prepare for a transaction.
|
||||
*
|
||||
* There must not be an ongoing transaction.
|
||||
*
|
||||
* \param type The type of transaction to start.
|
||||
*/
|
||||
static inline void psa_crypto_prepare_transaction(
|
||||
psa_crypto_transaction_type_t type)
|
||||
{
|
||||
psa_crypto_transaction.unknown.type = type;
|
||||
}
|
||||
|
||||
/** Save the transaction data to storage.
|
||||
*
|
||||
* You may call this function multiple times during a transaction to
|
||||
* atomically update the transaction state.
|
||||
*
|
||||
* \retval #PSA_SUCCESS \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
*/
|
||||
psa_status_t psa_crypto_save_transaction(void);
|
||||
|
||||
/** Load the transaction data from storage, if any.
|
||||
*
|
||||
* This function is meant to be called from psa_crypto_init() to recover
|
||||
* in case a transaction was interrupted by a system crash.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The data about the ongoing transaction has been loaded to
|
||||
* #psa_crypto_transaction.
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST
|
||||
* There is no ongoing transaction.
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_INVALID \emptydescription
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
|
||||
*/
|
||||
psa_status_t psa_crypto_load_transaction(void);
|
||||
|
||||
/** Indicate that the current transaction is finished.
|
||||
*
|
||||
* Call this function at the very end of transaction processing.
|
||||
* This function does not "commit" or "abort" the transaction: the storage
|
||||
* subsystem has no concept of "commit" and "abort", just saving and
|
||||
* removing the transaction information in storage.
|
||||
*
|
||||
* This function erases the transaction data in storage (if any) and
|
||||
* resets the transaction data in memory.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* There was transaction data in storage.
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST
|
||||
* There was no transaction data in storage.
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE
|
||||
* It was impossible to determine whether there was transaction data
|
||||
* in storage, or the transaction data could not be erased.
|
||||
*/
|
||||
psa_status_t psa_crypto_stop_transaction(void);
|
||||
|
||||
/** The ITS file identifier for the transaction data.
|
||||
*
|
||||
* 0xffffffNN = special file; 0x74 = 't' for transaction.
|
||||
*/
|
||||
#define PSA_CRYPTO_ITS_TRANSACTION_UID ((psa_key_id_t) 0xffffff74)
|
||||
|
||||
#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
|
||||
|
||||
#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
|
||||
/** Backend side of mbedtls_psa_inject_entropy().
|
||||
*
|
||||
* This function stores the supplied data into the entropy seed file.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||
* The entropy seed file already exists.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_storage_inject_entropy(const unsigned char *seed,
|
||||
size_t seed_size);
|
||||
#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTO_STORAGE_H */
|
||||
@@ -1,254 +0,0 @@
|
||||
/*
|
||||
* PSA ITS simulator over stdio files.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_ITS_FILE_C)
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "psa_crypto_its.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(PSA_ITS_STORAGE_PREFIX)
|
||||
#define PSA_ITS_STORAGE_PREFIX ""
|
||||
#endif
|
||||
|
||||
#define PSA_ITS_STORAGE_FILENAME_PATTERN "%08x%08x"
|
||||
#define PSA_ITS_STORAGE_SUFFIX ".psa_its"
|
||||
#define PSA_ITS_STORAGE_FILENAME_LENGTH \
|
||||
(sizeof(PSA_ITS_STORAGE_PREFIX) - 1 + /*prefix without terminating 0*/ \
|
||||
16 + /*UID (64-bit number in hex)*/ \
|
||||
sizeof(PSA_ITS_STORAGE_SUFFIX) - 1 + /*suffix without terminating 0*/ \
|
||||
1 /*terminating null byte*/)
|
||||
#define PSA_ITS_STORAGE_TEMP \
|
||||
PSA_ITS_STORAGE_PREFIX "tempfile" PSA_ITS_STORAGE_SUFFIX
|
||||
|
||||
/* The maximum value of psa_storage_info_t.size */
|
||||
#define PSA_ITS_MAX_SIZE 0xffffffff
|
||||
|
||||
#define PSA_ITS_MAGIC_STRING "PSA\0ITS\0"
|
||||
#define PSA_ITS_MAGIC_LENGTH 8
|
||||
|
||||
/* As rename fails on Windows if the new filepath already exists,
|
||||
* use MoveFileExA with the MOVEFILE_REPLACE_EXISTING flag instead.
|
||||
* Returns 0 on success, nonzero on failure. */
|
||||
#if defined(_WIN32)
|
||||
#define rename_replace_existing(oldpath, newpath) \
|
||||
(!MoveFileExA(oldpath, newpath, MOVEFILE_REPLACE_EXISTING))
|
||||
#else
|
||||
#define rename_replace_existing(oldpath, newpath) rename(oldpath, newpath)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t magic[PSA_ITS_MAGIC_LENGTH];
|
||||
uint8_t size[sizeof(uint32_t)];
|
||||
uint8_t flags[sizeof(psa_storage_create_flags_t)];
|
||||
} psa_its_file_header_t;
|
||||
|
||||
static void psa_its_fill_filename(psa_storage_uid_t uid, char *filename)
|
||||
{
|
||||
/* Break up the UID into two 32-bit pieces so as not to rely on
|
||||
* long long support in snprintf. */
|
||||
mbedtls_snprintf(filename, PSA_ITS_STORAGE_FILENAME_LENGTH,
|
||||
"%s" PSA_ITS_STORAGE_FILENAME_PATTERN "%s",
|
||||
PSA_ITS_STORAGE_PREFIX,
|
||||
(unsigned) (uid >> 32),
|
||||
(unsigned) (uid & 0xffffffff),
|
||||
PSA_ITS_STORAGE_SUFFIX);
|
||||
}
|
||||
|
||||
static psa_status_t psa_its_read_file(psa_storage_uid_t uid,
|
||||
struct psa_storage_info_t *p_info,
|
||||
FILE **p_stream)
|
||||
{
|
||||
char filename[PSA_ITS_STORAGE_FILENAME_LENGTH];
|
||||
psa_its_file_header_t header;
|
||||
size_t n;
|
||||
|
||||
*p_stream = NULL;
|
||||
psa_its_fill_filename(uid, filename);
|
||||
*p_stream = fopen(filename, "rb");
|
||||
if (*p_stream == NULL) {
|
||||
return PSA_ERROR_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
/* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
|
||||
mbedtls_setbuf(*p_stream, NULL);
|
||||
|
||||
n = fread(&header, 1, sizeof(header), *p_stream);
|
||||
if (n != sizeof(header)) {
|
||||
return PSA_ERROR_DATA_CORRUPT;
|
||||
}
|
||||
if (memcmp(header.magic, PSA_ITS_MAGIC_STRING,
|
||||
PSA_ITS_MAGIC_LENGTH) != 0) {
|
||||
return PSA_ERROR_DATA_CORRUPT;
|
||||
}
|
||||
|
||||
p_info->size = MBEDTLS_GET_UINT32_LE(header.size, 0);
|
||||
p_info->flags = MBEDTLS_GET_UINT32_LE(header.flags, 0);
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_its_get_info(psa_storage_uid_t uid,
|
||||
struct psa_storage_info_t *p_info)
|
||||
{
|
||||
psa_status_t status;
|
||||
FILE *stream = NULL;
|
||||
status = psa_its_read_file(uid, p_info, &stream);
|
||||
if (stream != NULL) {
|
||||
fclose(stream);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_its_get(psa_storage_uid_t uid,
|
||||
uint32_t data_offset,
|
||||
uint32_t data_length,
|
||||
void *p_data,
|
||||
size_t *p_data_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
FILE *stream = NULL;
|
||||
size_t n;
|
||||
struct psa_storage_info_t info;
|
||||
|
||||
status = psa_its_read_file(uid, &info, &stream);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
if (data_offset + data_length < data_offset) {
|
||||
goto exit;
|
||||
}
|
||||
#if SIZE_MAX < 0xffffffff
|
||||
if (data_offset + data_length > SIZE_MAX) {
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
if (data_offset + data_length > info.size) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = PSA_ERROR_STORAGE_FAILURE;
|
||||
#if LONG_MAX < 0xffffffff
|
||||
while (data_offset > LONG_MAX) {
|
||||
if (fseek(stream, LONG_MAX, SEEK_CUR) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
data_offset -= LONG_MAX;
|
||||
}
|
||||
#endif
|
||||
if (fseek(stream, data_offset, SEEK_CUR) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
n = fread(p_data, 1, data_length, stream);
|
||||
if (n != data_length) {
|
||||
goto exit;
|
||||
}
|
||||
status = PSA_SUCCESS;
|
||||
if (p_data_length != NULL) {
|
||||
*p_data_length = n;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (stream != NULL) {
|
||||
fclose(stream);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_its_set(psa_storage_uid_t uid,
|
||||
uint32_t data_length,
|
||||
const void *p_data,
|
||||
psa_storage_create_flags_t create_flags)
|
||||
{
|
||||
if (uid == 0) {
|
||||
return PSA_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
psa_status_t status = PSA_ERROR_STORAGE_FAILURE;
|
||||
char filename[PSA_ITS_STORAGE_FILENAME_LENGTH];
|
||||
FILE *stream = NULL;
|
||||
psa_its_file_header_t header;
|
||||
size_t n;
|
||||
|
||||
memcpy(header.magic, PSA_ITS_MAGIC_STRING, PSA_ITS_MAGIC_LENGTH);
|
||||
MBEDTLS_PUT_UINT32_LE(data_length, header.size, 0);
|
||||
MBEDTLS_PUT_UINT32_LE(create_flags, header.flags, 0);
|
||||
|
||||
psa_its_fill_filename(uid, filename);
|
||||
stream = fopen(PSA_ITS_STORAGE_TEMP, "wb");
|
||||
|
||||
if (stream == NULL) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
|
||||
mbedtls_setbuf(stream, NULL);
|
||||
|
||||
status = PSA_ERROR_INSUFFICIENT_STORAGE;
|
||||
n = fwrite(&header, 1, sizeof(header), stream);
|
||||
if (n != sizeof(header)) {
|
||||
goto exit;
|
||||
}
|
||||
if (data_length != 0) {
|
||||
n = fwrite(p_data, 1, data_length, stream);
|
||||
if (n != data_length) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
status = PSA_SUCCESS;
|
||||
|
||||
exit:
|
||||
if (stream != NULL) {
|
||||
int ret = fclose(stream);
|
||||
if (status == PSA_SUCCESS && ret != 0) {
|
||||
status = PSA_ERROR_INSUFFICIENT_STORAGE;
|
||||
}
|
||||
}
|
||||
if (status == PSA_SUCCESS) {
|
||||
if (rename_replace_existing(PSA_ITS_STORAGE_TEMP, filename) != 0) {
|
||||
status = PSA_ERROR_STORAGE_FAILURE;
|
||||
}
|
||||
}
|
||||
/* The temporary file may still exist, but only in failure cases where
|
||||
* we're already reporting an error. So there's nothing we can do on
|
||||
* failure. If the function succeeded, and in some error cases, the
|
||||
* temporary file doesn't exist and so remove() is expected to fail.
|
||||
* Thus we just ignore the return status of remove(). */
|
||||
(void) remove(PSA_ITS_STORAGE_TEMP);
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_its_remove(psa_storage_uid_t uid)
|
||||
{
|
||||
char filename[PSA_ITS_STORAGE_FILENAME_LENGTH];
|
||||
FILE *stream;
|
||||
psa_its_fill_filename(uid, filename);
|
||||
stream = fopen(filename, "rb");
|
||||
if (stream == NULL) {
|
||||
return PSA_ERROR_DOES_NOT_EXIST;
|
||||
}
|
||||
fclose(stream);
|
||||
if (remove(filename) != 0) {
|
||||
return PSA_ERROR_STORAGE_FAILURE;
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_PSA_ITS_FILE_C */
|
||||
@@ -1,467 +0,0 @@
|
||||
Mbed TLS storage specification
|
||||
=================================
|
||||
|
||||
This document specifies how Mbed TLS uses storage.
|
||||
Key storage was originally introduced in a product called Mbed Crypto, which was re-distributed via Mbed TLS and has since been merged into Mbed TLS.
|
||||
This document contains historical information both from before and after this merge.
|
||||
|
||||
Mbed Crypto may be upgraded on an existing device with the storage preserved. Therefore:
|
||||
|
||||
1. Any change may break existing installations and may require an upgrade path.
|
||||
1. This document retains historical information about all past released versions. Do not remove information from this document unless it has always been incorrect or it is about a version that you are sure was never released.
|
||||
|
||||
Mbed Crypto 0.1.0
|
||||
-----------------
|
||||
|
||||
Tags: mbedcrypto-0.1.0b, mbedcrypto-0.1.0b2
|
||||
|
||||
Released in November 2018. <br>
|
||||
Integrated in Mbed OS 5.11.
|
||||
|
||||
Supported backends:
|
||||
|
||||
* [PSA ITS](#file-namespace-on-its-for-0.1.0)
|
||||
* [C stdio](#file-namespace-on-stdio-for-0.1.0)
|
||||
|
||||
Supported features:
|
||||
|
||||
* [Persistent transparent keys](#key-file-format-for-0.1.0) designated by a [slot number](#key-names-for-0.1.0).
|
||||
* [Nonvolatile random seed](#nonvolatile-random-seed-file-format-for-0.1.0) on ITS only.
|
||||
|
||||
This is a beta release, and we do not promise backward compatibility, with one exception:
|
||||
|
||||
> On Mbed OS, if a device has a nonvolatile random seed file produced with Mbed OS 5.11.x and is upgraded to a later version of Mbed OS, the nonvolatile random seed file is preserved or upgraded.
|
||||
|
||||
We do not make any promises regarding key storage, or regarding the nonvolatile random seed file on other platforms.
|
||||
|
||||
### Key names for 0.1.0
|
||||
|
||||
Information about each key is stored in a dedicated file whose name is constructed from the key identifier. The way in which the file name is constructed depends on the storage backend. The content of the file is described [below](#key-file-format-for-0.1.0).
|
||||
|
||||
The valid values for a key identifier are the range from 1 to 0xfffeffff. This limitation on the range is not documented in user-facing documentation: according to the user-facing documentation, arbitrary 32-bit values are valid.
|
||||
|
||||
The code uses the following constant in an internal header (note that despite the name, this value is actually one plus the maximum permitted value):
|
||||
|
||||
#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER 0xffff0000
|
||||
|
||||
There is a shared namespace for all callers.
|
||||
|
||||
### Key file format for 0.1.0
|
||||
|
||||
All integers are encoded in little-endian order in 8-bit bytes.
|
||||
|
||||
The layout of a key file is:
|
||||
|
||||
* magic (8 bytes): `"PSA\0KEY\0"`
|
||||
* version (4 bytes): 0
|
||||
* type (4 bytes): `psa_key_type_t` value
|
||||
* policy usage flags (4 bytes): `psa_key_usage_t` value
|
||||
* policy usage algorithm (4 bytes): `psa_algorithm_t` value
|
||||
* key material length (4 bytes)
|
||||
* key material: output of `psa_export_key`
|
||||
* Any trailing data is rejected on load.
|
||||
|
||||
### Nonvolatile random seed file format for 0.1.0
|
||||
|
||||
The nonvolatile random seed file contains a seed for the random generator. If present, it is rewritten at each boot as part of the random generator initialization.
|
||||
|
||||
The file format is just the seed as a byte string with no metadata or encoding of any kind.
|
||||
|
||||
### File namespace on ITS for 0.1.0
|
||||
|
||||
Assumption: ITS provides a 32-bit file identifier namespace. The Crypto service can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
|
||||
|
||||
* File 0: unused.
|
||||
* Files 1 through 0xfffeffff: [content](#key-file-format-for-0.1.0) of the [key whose identifier is the file identifier](#key-names-for-0.1.0).
|
||||
* File 0xffffff52 (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`): [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-0.1.0).
|
||||
* Files 0xffff0000 through 0xffffff51, 0xffffff53 through 0xffffffff: unused.
|
||||
|
||||
### File namespace on stdio for 0.1.0
|
||||
|
||||
Assumption: C stdio, allowing names containing lowercase letters, digits and underscores, of length up to 23.
|
||||
|
||||
An undocumented build-time configuration value `CRYPTO_STORAGE_FILE_LOCATION` allows storing the key files in a directory other than the current directory. This value is simply prepended to the file name (so it must end with a directory separator to put the keys in a different directory).
|
||||
|
||||
* `CRYPTO_STORAGE_FILE_LOCATION "psa_key_slot_0"`: used as a temporary file. Must be writable. May be overwritten or deleted if present.
|
||||
* `sprintf(CRYPTO_STORAGE_FILE_LOCATION "psa_key_slot_%lu", key_id)` [content](#key-file-format-for-0.1.0) of the [key whose identifier](#key-names-for-0.1.0) is `key_id`.
|
||||
* Other files: unused.
|
||||
|
||||
Mbed Crypto 1.0.0
|
||||
-----------------
|
||||
|
||||
Tags: mbedcrypto-1.0.0d4, mbedcrypto-1.0.0
|
||||
|
||||
Released in February 2019. <br>
|
||||
Integrated in Mbed OS 5.12.
|
||||
|
||||
Supported integrations:
|
||||
|
||||
* [PSA platform](#file-namespace-on-a-psa-platform-for-1.0.0)
|
||||
* [library using PSA ITS](#file-namespace-on-its-as-a-library-for-1.0.0)
|
||||
* [library using C stdio](#file-namespace-on-stdio-for-1.0.0)
|
||||
|
||||
Supported features:
|
||||
|
||||
* [Persistent transparent keys](#key-file-format-for-1.0.0) designated by a [key identifier and owner](#key-names-for-1.0.0).
|
||||
* [Nonvolatile random seed](#nonvolatile-random-seed-file-format-for-1.0.0) on ITS only.
|
||||
|
||||
Backward compatibility commitments: TBD
|
||||
|
||||
### Key names for 1.0.0
|
||||
|
||||
Information about each key is stored in a dedicated file designated by the key identifier. In integrations where there is no concept of key owner (in particular, in library integrations), the key identifier is exactly the key identifier as defined in the PSA Cryptography API specification (`psa_key_id_t`). In integrations where there is a concept of key owner (integration into a service for example), the key identifier is made of an owner identifier (its semantics and type are integration specific) and of the key identifier (`psa_key_id_t`) from the key owner point of view.
|
||||
|
||||
The way in which the file name is constructed from the key identifier depends on the storage backend. The content of the file is described [below](#key-file-format-for-1.0.0).
|
||||
|
||||
* Library integration: the key file name is just the key identifier as defined in the PSA crypto specification. This is a 32-bit value.
|
||||
* PSA service integration: the key file name is `(uint64_t)owner_uid << 32 | key_id` where `key_id` is the key identifier from the owner point of view and `owner_uid` (of type `int32_t`) is the calling partition identifier provided to the server by the partition manager. This is a 64-bit value.
|
||||
|
||||
### Key file format for 1.0.0
|
||||
|
||||
The layout is identical to [0.1.0](#key-file-format-for-0.1.0) so far. However note that the encoding of key types, algorithms and key material has changed, therefore the storage format is not compatible (despite using the same value in the version field so far).
|
||||
|
||||
### Nonvolatile random seed file format for 1.0.0
|
||||
|
||||
The nonvolatile random seed file contains a seed for the random generator. If present, it is rewritten at each boot as part of the random generator initialization.
|
||||
|
||||
The file format is just the seed as a byte string with no metadata or encoding of any kind.
|
||||
|
||||
This is unchanged since [the feature was introduced in Mbed Crypto 0.1.0](#nonvolatile-random-seed-file-format-for-0.1.0).
|
||||
|
||||
### File namespace on a PSA platform for 1.0.0
|
||||
|
||||
Assumption: ITS provides a 64-bit file identifier namespace. The Crypto service can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
|
||||
|
||||
Assumption: the owner identifier is a nonzero value of type `int32_t`.
|
||||
|
||||
* Files 0 through 0xffffff51, 0xffffff53 through 0xffffffff: unused, reserved for internal use of the crypto library or crypto service.
|
||||
* File 0xffffff52 (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`): [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-0.1.0).
|
||||
* Files 0x100000000 through 0xffffffffffff: [content](#key-file-format-for-1.0.0) of the [key whose identifier is the file identifier](#key-names-for-1.0.0). The upper 32 bits determine the owner.
|
||||
|
||||
### File namespace on ITS as a library for 1.0.0
|
||||
|
||||
Assumption: ITS provides a 64-bit file identifier namespace. The entity using the crypto library can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
|
||||
|
||||
This is a library integration, so there is no owner. The key file identifier is identical to the key identifier.
|
||||
|
||||
* File 0: unused.
|
||||
* Files 1 through 0xfffeffff: [content](#key-file-format-for-1.0.0) of the [key whose identifier is the file identifier](#key-names-for-1.0.0).
|
||||
* File 0xffffff52 (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`): [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-1.0.0).
|
||||
* Files 0xffff0000 through 0xffffff51, 0xffffff53 through 0xffffffff, 0x100000000 through 0xffffffffffffffff: unused.
|
||||
|
||||
### File namespace on stdio for 1.0.0
|
||||
|
||||
This is a library integration, so there is no owner. The key file identifier is identical to the key identifier.
|
||||
|
||||
[Identical to 0.1.0](#file-namespace-on-stdio-for-0.1.0).
|
||||
|
||||
### Upgrade from 0.1.0 to 1.0.0.
|
||||
|
||||
* Delete files 1 through 0xfffeffff, which contain keys in a format that is no longer supported.
|
||||
|
||||
### Suggested changes to make before 1.0.0
|
||||
|
||||
The library integration and the PSA platform integration use different sets of file names. This is annoyingly non-uniform. For example, if we want to store non-key files, we have room in different ranges (0 through 0xffffffff on a PSA platform, 0xffff0000 through 0xffffffffffffffff in a library integration).
|
||||
|
||||
It would simplify things to always have a 32-bit owner, with a nonzero value, and thus reserve the range 0–0xffffffff for internal library use.
|
||||
|
||||
Mbed Crypto 1.1.0
|
||||
-----------------
|
||||
|
||||
Tags: mbedcrypto-1.1.0
|
||||
|
||||
Released in early June 2019. <br>
|
||||
Integrated in Mbed OS 5.13.
|
||||
|
||||
Changes since [1.0.0](#mbed-crypto-1.0.0):
|
||||
|
||||
* The stdio backend for storage has been replaced by an implementation of [PSA ITS over stdio](#file-namespace-on-stdio-for-1.1.0).
|
||||
* [Some changes in the key file format](#key-file-format-for-1.1.0).
|
||||
|
||||
### File namespace on stdio for 1.1.0
|
||||
|
||||
Assumption: C stdio, allowing names containing lowercase letters, digits and underscores, of length up to 23.
|
||||
|
||||
An undocumented build-time configuration value `PSA_ITS_STORAGE_PREFIX` allows storing the key files in a directory other than the current directory. This value is simply prepended to the file name (so it must end with a directory separator to put the keys in a different directory).
|
||||
|
||||
* `PSA_ITS_STORAGE_PREFIX "tempfile.psa_its"`: used as a temporary file. Must be writable. May be overwritten or deleted if present.
|
||||
* `sprintf(PSA_ITS_STORAGE_PREFIX "%016llx.psa_its", key_id)`: a key or non-key file. The `key_id` in the name is the 64-bit file identifier, which is the [key identifier](#key-names-for-mbed-tls-2.25.0) for a key file or some reserved identifier for a non-key file (currently: only the [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-1.0.0)). The contents of the file are:
|
||||
* Magic header (8 bytes): `"PSA\0ITS\0"`
|
||||
* File contents.
|
||||
|
||||
### Key file format for 1.1.0
|
||||
|
||||
The key file format is identical to [1.0.0](#key-file-format-for-1.0.0), except for the following changes:
|
||||
|
||||
* A new policy field, marked as [NEW:1.1.0] below.
|
||||
* The encoding of key types, algorithms and key material has changed, therefore the storage format is not compatible (despite using the same value in the version field so far).
|
||||
|
||||
A self-contained description of the file layout follows.
|
||||
|
||||
All integers are encoded in little-endian order in 8-bit bytes.
|
||||
|
||||
The layout of a key file is:
|
||||
|
||||
* magic (8 bytes): `"PSA\0KEY\0"`
|
||||
* version (4 bytes): 0
|
||||
* type (4 bytes): `psa_key_type_t` value
|
||||
* policy usage flags (4 bytes): `psa_key_usage_t` value
|
||||
* policy usage algorithm (4 bytes): `psa_algorithm_t` value
|
||||
* policy enrollment algorithm (4 bytes): `psa_algorithm_t` value [NEW:1.1.0]
|
||||
* key material length (4 bytes)
|
||||
* key material: output of `psa_export_key`
|
||||
* Any trailing data is rejected on load.
|
||||
|
||||
Mbed Crypto TBD
|
||||
---------------
|
||||
|
||||
Tags: TBD
|
||||
|
||||
Released in TBD 2019. <br>
|
||||
Integrated in Mbed OS TBD.
|
||||
|
||||
### Changes introduced in TBD
|
||||
|
||||
* The layout of a key file now has a lifetime field before the type field.
|
||||
* Key files can store references to keys in a secure element. In such key files, the key material contains the slot number.
|
||||
|
||||
### File namespace on a PSA platform on TBD
|
||||
|
||||
Assumption: ITS provides a 64-bit file identifier namespace. The Crypto service can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
|
||||
|
||||
Assumption: the owner identifier is a nonzero value of type `int32_t`.
|
||||
|
||||
* Files 0 through 0xfffeffff: unused.
|
||||
* Files 0xffff0000 through 0xffffffff: reserved for internal use of the crypto library or crypto service. See [non-key files](#non-key-files-on-tbd).
|
||||
* Files 0x100000000 through 0xffffffffffff: [content](#key-file-format-for-1.0.0) of the [key whose identifier is the file identifier](#key-names-for-1.0.0). The upper 32 bits determine the owner.
|
||||
|
||||
### File namespace on ITS as a library on TBD
|
||||
|
||||
Assumption: ITS provides a 64-bit file identifier namespace. The entity using the crypto library can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
|
||||
|
||||
This is a library integration, so there is no owner. The key file identifier is identical to the key identifier.
|
||||
|
||||
* File 0: unused.
|
||||
* Files 1 through 0xfffeffff: [content](#key-file-format-for-1.0.0) of the [key whose identifier is the file identifier](#key-names-for-1.0.0).
|
||||
* Files 0xffff0000 through 0xffffffff: reserved for internal use of the crypto library or crypto service. See [non-key files](#non-key-files-on-tbd).
|
||||
* Files 0x100000000 through 0xffffffffffffffff: unused.
|
||||
|
||||
### Non-key files on TBD
|
||||
|
||||
File identifiers in the range 0xffff0000 through 0xffffffff are reserved for internal use in Mbed Crypto.
|
||||
|
||||
* Files 0xfffffe02 through 0xfffffeff (`PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + lifetime`): secure element driver storage. The content of the file is the secure element driver's persistent data.
|
||||
* File 0xffffff52 (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`): [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-1.0.0).
|
||||
* File 0xffffff54 (`PSA_CRYPTO_ITS_TRANSACTION_UID`): [transaction file](#transaction-file-format-for-tbd).
|
||||
* Other files are unused and reserved for future use.
|
||||
|
||||
### Key file format for TBD
|
||||
|
||||
All integers are encoded in little-endian order in 8-bit bytes except where otherwise indicated.
|
||||
|
||||
The layout of a key file is:
|
||||
|
||||
* magic (8 bytes): `"PSA\0KEY\0"`.
|
||||
* version (4 bytes): 0.
|
||||
* lifetime (4 bytes): `psa_key_lifetime_t` value.
|
||||
* type (4 bytes): `psa_key_type_t` value.
|
||||
* policy usage flags (4 bytes): `psa_key_usage_t` value.
|
||||
* policy usage algorithm (4 bytes): `psa_algorithm_t` value.
|
||||
* policy enrollment algorithm (4 bytes): `psa_algorithm_t` value.
|
||||
* key material length (4 bytes).
|
||||
* key material:
|
||||
* For a transparent key: output of `psa_export_key`.
|
||||
* For an opaque key (unified driver interface): driver-specific opaque key blob.
|
||||
* For an opaque key (key in a secure element): slot number (8 bytes), in platform endianness.
|
||||
* Any trailing data is rejected on load.
|
||||
|
||||
### Transaction file format for TBD
|
||||
|
||||
The transaction file contains data about an ongoing action that cannot be completed atomically. It exists only if there is an ongoing transaction.
|
||||
|
||||
All integers are encoded in platform endianness.
|
||||
|
||||
All currently existing transactions concern a key in a secure element.
|
||||
|
||||
The layout of a transaction file is:
|
||||
|
||||
* type (2 bytes): the [transaction type](#transaction-types-on-tbd).
|
||||
* unused (2 bytes)
|
||||
* lifetime (4 bytes): `psa_key_lifetime_t` value that corresponds to a key in a secure element.
|
||||
* slot number (8 bytes): `psa_key_slot_number_t` value. This is the unique designation of the key for the secure element driver.
|
||||
* key identifier (4 bytes in a library integration, 8 bytes on a PSA platform): the internal representation of the key identifier. On a PSA platform, this encodes the key owner in the same way as [in file identifiers for key files](#file-namespace-on-a-psa-platform-on-tbd)).
|
||||
|
||||
#### Transaction types on TBD
|
||||
|
||||
* 0x0001: key creation. The following locations may or may not contain data about the key that is being created:
|
||||
* The slot in the secure element designated by the slot number.
|
||||
* The file containing the key metadata designated by the key identifier.
|
||||
* The driver persistent data.
|
||||
* 0x0002: key destruction. The following locations may or may not still contain data about the key that is being destroyed:
|
||||
* The slot in the secure element designated by the slot number.
|
||||
* The file containing the key metadata designated by the key identifier.
|
||||
* The driver persistent data.
|
||||
|
||||
Mbed Crypto TBD
|
||||
---------------
|
||||
|
||||
Tags: TBD
|
||||
|
||||
Released in TBD 2020. <br>
|
||||
Integrated in Mbed OS TBD.
|
||||
|
||||
### Changes introduced in TBD
|
||||
|
||||
* The type field has been split into a type and a bits field of 2 bytes each.
|
||||
|
||||
### Key file format for TBD
|
||||
|
||||
All integers are encoded in little-endian order in 8-bit bytes except where otherwise indicated.
|
||||
|
||||
The layout of a key file is:
|
||||
|
||||
* magic (8 bytes): `"PSA\0KEY\0"`.
|
||||
* version (4 bytes): 0.
|
||||
* lifetime (4 bytes): `psa_key_lifetime_t` value.
|
||||
* type (2 bytes): `psa_key_type_t` value.
|
||||
* bits (2 bytes): `psa_key_bits_t` value.
|
||||
* policy usage flags (4 bytes): `psa_key_usage_t` value.
|
||||
* policy usage algorithm (4 bytes): `psa_algorithm_t` value.
|
||||
* policy enrollment algorithm (4 bytes): `psa_algorithm_t` value.
|
||||
* key material length (4 bytes).
|
||||
* key material:
|
||||
* For a transparent key: output of `psa_export_key`.
|
||||
* For an opaque key (unified driver interface): driver-specific opaque key blob.
|
||||
* For an opaque key (key in a secure element): slot number (8 bytes), in platform endianness.
|
||||
* Any trailing data is rejected on load.
|
||||
|
||||
Mbed TLS 2.25.0
|
||||
---------------
|
||||
|
||||
Tags: `mbedtls-2.25.0`, `mbedtls-2.26.0`, `mbedtls-2.27.0`, `mbedtls-2.28.0`, `mbedtls-3.0.0`, `mbedtls-3.1.0`
|
||||
|
||||
First released in December 2020.
|
||||
|
||||
Note: this is the first version that is officially supported. The version number is still 0.
|
||||
|
||||
Backward compatibility commitments: we promise backward compatibility for stored keys when Mbed TLS is upgraded from x to y if x >= 2.25 and y < 4. See [`BRANCHES.md`](../../BRANCHES.md) for more details.
|
||||
|
||||
Supported integrations:
|
||||
|
||||
* [PSA platform](#file-namespace-on-a-psa-platform-on-mbed-tls-2.25.0)
|
||||
* [library using PSA ITS](#file-namespace-on-its-as-a-library-on-mbed-tls-2.25.0)
|
||||
* [library using C stdio](#file-namespace-on-stdio-for-mbed-tls-2.25.0)
|
||||
|
||||
Supported features:
|
||||
|
||||
* [Persistent keys](#key-file-format-for-mbed-tls-2.25.0) designated by a [key identifier and owner](#key-names-for-mbed-tls-2.25.0). Keys can be:
|
||||
* Transparent, stored in the export format.
|
||||
* Opaque, using the PSA driver interface with statically registered drivers. The driver determines the content of the opaque key blob.
|
||||
* Opaque, using the deprecated secure element interface with dynamically registered drivers (`MBEDTLS_PSA_CRYPTO_SE_C`). The driver picks a slot number which is stored in the place of the key material.
|
||||
* [Nonvolatile random seed](#nonvolatile-random-seed-file-format-for-mbed-tls-2.25.0) on ITS only.
|
||||
|
||||
### Changes introduced in Mbed TLS 2.25.0
|
||||
|
||||
* The numerical encodings of `psa_key_type_t`, `psa_key_usage_t` and `psa_algorithm_t` have changed.
|
||||
|
||||
### File namespace on a PSA platform on Mbed TLS 2.25.0
|
||||
|
||||
Assumption: ITS provides a 64-bit file identifier namespace. The Crypto service can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
|
||||
|
||||
Assumption: the owner identifier is a nonzero value of type `int32_t`.
|
||||
|
||||
* Files 0 through 0xfffeffff: unused.
|
||||
* Files 0xffff0000 through 0xffffffff: reserved for internal use of the crypto library or crypto service. See [non-key files](#non-key-files-on-mbed-tls-2.25.0).
|
||||
* Files 0x100000000 through 0xffffffffffff: [content](#key-file-format-for-mbed-tls-2.25.0) of the [key whose identifier is the file identifier](#key-names-for-mbed-tls-2.25.0). The upper 32 bits determine the owner.
|
||||
|
||||
### File namespace on ITS as a library on Mbed TLS 2.25.0
|
||||
|
||||
Assumption: ITS provides a 64-bit file identifier namespace. The entity using the crypto library can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
|
||||
|
||||
This is a library integration, so there is no owner. The key file identifier is identical to the key identifier.
|
||||
|
||||
* File 0: unused.
|
||||
* Files 1 through 0xfffeffff: [content](#key-file-format-for-mbed-tls-2.25.0) of the [key whose identifier is the file identifier](#key-names-for-mbed-tls-2.25.0).
|
||||
* Files 0xffff0000 through 0xffffffff: reserved for internal use of the crypto library or crypto service. See [non-key files](#non-key-files-on-mbed-tls-2.25.0).
|
||||
* Files 0x100000000 through 0xffffffffffffffff: unused.
|
||||
|
||||
### File namespace on stdio for Mbed TLS 2.25.0
|
||||
|
||||
Assumption: C stdio, allowing names containing lowercase letters, digits and underscores, of length up to 23.
|
||||
|
||||
An undocumented build-time configuration value `PSA_ITS_STORAGE_PREFIX` allows storing the key files in a directory other than the current directory. This value is simply prepended to the file name (so it must end with a directory separator to put the keys in a different directory).
|
||||
|
||||
* `PSA_ITS_STORAGE_PREFIX "tempfile.psa_its"`: used as a temporary file. Must be writable. May be overwritten or deleted if present.
|
||||
* `sprintf(PSA_ITS_STORAGE_PREFIX "%016llx.psa_its", key_id)`: a key or non-key file. The `key_id` in the name is the 64-bit file identifier, which is the [key identifier](#key-names-for-mbed-tls-2.25.0) for a key file or some reserved identifier for a [non-key file](#non-key-files-on-mbed-tls-2.25.0). The contents of the file are:
|
||||
* Magic header (8 bytes): `"PSA\0ITS\0"`
|
||||
* File contents.
|
||||
|
||||
### Key names for Mbed TLS 2.25.0
|
||||
|
||||
Information about each key is stored in a dedicated file designated by the key identifier. In integrations where there is no concept of key owner (in particular, in library integrations), the key identifier is exactly the key identifier as defined in the PSA Cryptography API specification (`psa_key_id_t`). In integrations where there is a concept of key owner (integration into a service for example), the key identifier is made of an owner identifier (its semantics and type are integration specific) and of the key identifier (`psa_key_id_t`) from the key owner point of view.
|
||||
|
||||
The way in which the file name is constructed from the key identifier depends on the storage backend. The content of the file is described [below](#key-file-format-for-mbed-tls-2.25.0).
|
||||
|
||||
* Library integration: the key file name is just the key identifier as defined in the PSA crypto specification. This is a 32-bit value which must be in the range 0x00000001..0x3fffffff (`PSA_KEY_ID_USER_MIN`..`PSA_KEY_ID_USER_MAX`).
|
||||
* PSA service integration: the key file name is `(uint64_t)owner_uid << 32 | key_id` where `key_id` is the key identifier from the owner point of view and `owner_uid` (of type `int32_t`) is the calling partition identifier provided to the server by the partition manager. This is a 64-bit value.
|
||||
|
||||
### Key file format for Mbed TLS 2.25.0
|
||||
|
||||
All integers are encoded in little-endian order in 8-bit bytes except where otherwise indicated.
|
||||
|
||||
The layout of a key file is:
|
||||
|
||||
* magic (8 bytes): `"PSA\0KEY\0"`.
|
||||
* version (4 bytes): 0.
|
||||
* lifetime (4 bytes): `psa_key_lifetime_t` value.
|
||||
* type (2 bytes): `psa_key_type_t` value.
|
||||
* bits (2 bytes): `psa_key_bits_t` value.
|
||||
* policy usage flags (4 bytes): `psa_key_usage_t` value.
|
||||
* policy usage algorithm (4 bytes): `psa_algorithm_t` value.
|
||||
* policy enrollment algorithm (4 bytes): `psa_algorithm_t` value.
|
||||
* key material length (4 bytes).
|
||||
* key material:
|
||||
* For a transparent key: output of `psa_export_key`.
|
||||
* For an opaque key (unified driver interface): driver-specific opaque key blob.
|
||||
* For an opaque key (key in a dynamic secure element): slot number (8 bytes), in platform endianness.
|
||||
* Any trailing data is rejected on load.
|
||||
|
||||
### Non-key files on Mbed TLS 2.25.0
|
||||
|
||||
File identifiers that are outside the range of persistent key identifiers are reserved for internal use by the library. The only identifiers currently in use have the owner id (top 32 bits) set to 0.
|
||||
|
||||
* Files 0xfffffe02 through 0xfffffeff (`PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + lifetime`): dynamic secure element driver storage. The content of the file is the secure element driver's persistent data.
|
||||
* File 0xffffff52 (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`): [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-mbed-tls-2.25.0).
|
||||
* File 0xffffff54 (`PSA_CRYPTO_ITS_TRANSACTION_UID`): [transaction file](#transaction-file-format-for-mbed-tls-2.25.0).
|
||||
* Other files are unused and reserved for future use.
|
||||
|
||||
### Nonvolatile random seed file format for Mbed TLS 2.25.0
|
||||
|
||||
[Identical to Mbed Crypto 0.1.0](#nonvolatile-random-seed-file-format-for-0.1.0).
|
||||
|
||||
### Transaction file format for Mbed TLS 2.25.0
|
||||
|
||||
The transaction file contains data about an ongoing action that cannot be completed atomically. It exists only if there is an ongoing transaction.
|
||||
|
||||
All integers are encoded in platform endianness.
|
||||
|
||||
All currently existing transactions concern a key in a dynamic secure element.
|
||||
|
||||
The layout of a transaction file is:
|
||||
|
||||
* type (2 bytes): the [transaction type](#transaction-types-on-mbed-tls-2.25.0).
|
||||
* unused (2 bytes)
|
||||
* lifetime (4 bytes): `psa_key_lifetime_t` value that corresponds to a key in a secure element.
|
||||
* slot number (8 bytes): `psa_key_slot_number_t` value. This is the unique designation of the key for the secure element driver.
|
||||
* key identifier (4 bytes in a library integration, 8 bytes on a PSA platform): the internal representation of the key identifier. On a PSA platform, this encodes the key owner in the same way as [in file identifiers for key files](#file-namespace-on-a-psa-platform-on-mbed-tls-2.25.0)).
|
||||
|
||||
#### Transaction types on Mbed TLS 2.25.0
|
||||
|
||||
* 0x0001: key creation. The following locations may or may not contain data about the key that is being created:
|
||||
* The slot in the secure element designated by the slot number.
|
||||
* The file containing the key metadata designated by the key identifier.
|
||||
* The driver persistent data.
|
||||
* 0x0002: key destruction. The following locations may or may not still contain data about the key that is being destroyed:
|
||||
* The slot in the secure element designated by the slot number.
|
||||
* The file containing the key metadata designated by the key identifier.
|
||||
* The driver persistent data.
|
||||
@@ -1,173 +0,0 @@
|
||||
PSA Cryptography API implementation and PSA driver interface
|
||||
===========================================================
|
||||
|
||||
## Introduction
|
||||
|
||||
The [PSA Cryptography API specification](https://armmbed.github.io/mbed-crypto/psa/#application-programming-interface) defines an interface to cryptographic operations for which the Mbed TLS library provides a reference implementation. The PSA Cryptography API specification is complemented by the PSA driver interface specification which defines an interface for cryptoprocessor drivers.
|
||||
|
||||
This document describes the high level organization of the Mbed TLS PSA Cryptography API implementation which is tightly related to the PSA driver interface.
|
||||
|
||||
## High level organization of the Mbed TLS PSA Cryptography API implementation
|
||||
In one sentence, the Mbed TLS PSA Cryptography API implementation is made of a core and PSA drivers as defined in the PSA driver interface. The key point is that software cryptographic operations are organized as PSA drivers: they interact with the core through the PSA driver interface.
|
||||
|
||||
### Rationale
|
||||
|
||||
* Addressing software and hardware cryptographic implementations through the same C interface reduces the core code size and its call graph complexity. The core and its dispatching to software and hardware implementations are consequently easier to test and validate.
|
||||
* The organization of the software cryptographic implementations in drivers promotes modularization of those implementations.
|
||||
* As hardware capabilities, software cryptographic functionalities can be described by a JSON driver description file as defined in the PSA driver interface.
|
||||
* Along with JSON driver description files, the PSA driver specification defines the deliverables for a driver to be included into the Mbed TLS PSA Cryptography implementation. This provides a natural framework to integrate third party or alternative software implementations of cryptographic operations.
|
||||
|
||||
## The Mbed TLS PSA Cryptography API implementation core
|
||||
|
||||
The core implements all the APIs as defined in the PSA Cryptography API specification but does not perform on its own any cryptographic operation. The core relies on PSA drivers to actually
|
||||
perform the cryptographic operations. The core is responsible for:
|
||||
|
||||
* the key store.
|
||||
* checking PSA API arguments and translating them into valid arguments for the necessary calls to the PSA driver interface.
|
||||
* dispatching the cryptographic operations to the appropriate PSA drivers.
|
||||
|
||||
The sketch of an Mbed TLS PSA cryptographic API implementation is thus:
|
||||
```C
|
||||
psa_status_t psa_api( ... )
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
/* Pre driver interface call processing: validation of arguments, building
|
||||
* of arguments for the call to the driver interface, ... */
|
||||
|
||||
...
|
||||
|
||||
/* Call to the driver interface */
|
||||
status = psa_driver_wrapper_<entry_point>( ... );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
/* Post driver interface call processing: validation of the values returned
|
||||
* by the driver, finalization of the values to return to the caller,
|
||||
* clean-up in case of error ... */
|
||||
}
|
||||
```
|
||||
The code of most PSA APIs is expected to match precisely the above layout. However, it is likely that the code structure of some APIs will be more complicated with several calls to the driver interface, mainly to encompass a larger variety of hardware designs. For example, to encompass hardware accelerators that are capable of verifying a MAC and those that are only capable of computing a MAC, the psa_mac_verify() API could call first psa_driver_wrapper_mac_verify() and then fallback to psa_driver_wrapper_mac_compute().
|
||||
|
||||
The implementations of `psa_driver_wrapper_<entry_point>` functions are generated by the build system based on the JSON driver description files of the various PSA drivers making up the Mbed TLS PSA Cryptography API implementation. The implementations are splited into two parts. The static ones are generated in a psa_crypto_driver_wrappers.h header file, the non-static ones are generated in a psa_crypto_driver_wrappers_no_static.c C file and the function prototypes declared in a psa_crypto_driver_wrappers_no_static.h header file.
|
||||
|
||||
The psa_driver_wrapper_<entry_point>() functions dispatch cryptographic operations to accelerator drivers, secure element drivers as well as to the software implementations of cryptographic operations.
|
||||
|
||||
Note that the implementation allows to build the library with only a C compiler by shipping a generated file corresponding to a pure software implementation. The driver entry points and their code in this generated file are guarded by pre-processor directives based on PSA_WANT_xyz macros (see [Conditional inclusion of cryptographic mechanism through the PSA API in Mbed TLS](psa-conditional-inclusion-c.html). That way, it is possible to compile and include in the library only the desired cryptographic operations.
|
||||
|
||||
### Key creation
|
||||
|
||||
Key creation implementation in Mbed TLS PSA core is articulated around three internal functions: psa_start_key_creation(), psa_finish_key_creation() and psa_fail_key_creation(). Implementations of key creation PSA APIs, namely psa_import_key(), psa_generate_key(), psa_key_derivation_output_key() and psa_copy_key() go by the following sequence:
|
||||
1. Check the input parameters.
|
||||
2. Call psa_start_key_creation() that allocates a key slot, prepares it with the specified key attributes, and in case of a volatile key assign it a volatile key identifier.
|
||||
3. Generate or copy the key material into the key slot. This entails the allocation of the buffer to store the key material.
|
||||
4. Call psa_finish_key_creation() that mostly saves persistent keys into persistent storage.
|
||||
|
||||
In case of any error occurring at step 3 or 4, psa_fail_key_creation() is called. It wipes and cleans the slot especially the key material: reset to zero of the RAM memory that contained the key material, free the allocated buffer.
|
||||
|
||||
|
||||
## Mbed TLS PSA Cryptography API implementation drivers
|
||||
|
||||
A driver of the Mbed TLS PSA Cryptography API implementation (Mbed TLS PSA driver in the following) is a driver in the sense that it is compliant with the PSA driver interface specification. But it is not an actual driver that drives some hardware. It implements cryptographic operations purely in software.
|
||||
|
||||
An Mbed TLS PSA driver C file is named psa_crypto_<driver_name>.c and its associated header file psa_crypto_<driver_name>.h. The functions implementing a driver entry point as defined in the PSA driver interface specification are named as mbedtls_psa_<driver name>_<entry point>(). As an example, the psa_crypto_rsa.c and psa_crypto_rsa.h are the files containing the Mbed TLS PSA driver implementing RSA cryptographic operations. This RSA driver implements among other entry points the "import_key" entry point. The function implementing this entry point is named mbedtls_psa_rsa_import_key().
|
||||
|
||||
## How to implement a new cryptographic mechanism
|
||||
|
||||
Summary of files to modify when adding a new algorithm or key type:
|
||||
|
||||
* [ ] PSA Crypto API draft, if not already done — [PSA standardization](#psa-standardization)
|
||||
* [ ] `include/psa/crypto_values.h` or `include/psa/crypto_extra.h` — [New functions and macros](#new-functions-and-macros)
|
||||
* [ ] `include/psa/crypto_config.h`, `tests/configs/crypto_config_test_driver_extension.h` — [Preprocessor symbols](#preprocessor-symbols)
|
||||
* Occasionally `library/check_crypto_config.h` — [Preprocessor symbols](#preprocessor-symbols)
|
||||
* [ ] `include/mbedtls/config_psa.h` — [Preprocessor symbols](#preprocessor-symbols)
|
||||
* [ ] `library/psa_crypto.c`, `library/psa_crypto_*.[hc]` — [Implementation of the mechanisms](#implementation-of-the-mechanisms)
|
||||
* [ ] `include/psa/crypto_builtin_*.h` — [Translucent data structures](#translucent-data-structures)
|
||||
* [ ] `tests/suites/test_suite_psa_crypto_metadata.data` — [New functions and macros](#new-functions-and-macros)
|
||||
* (If adding `PSA_IS_xxx`) `tests/suites/test_suite_psa_crypto_metadata.function` — [New functions and macros](#new-functions-and-macros)
|
||||
* [ ] `tests/suites/test_suite_psa_crypto*.data`, `tests/suites/test_suite_psa_crypto*.function` — [Unit tests](#unit-tests)
|
||||
* [ ] `framework/scripts/mbedtls_framework/crypto_knowledge.py`, `framework/scripts/mbedtls_framework/asymmetric_key_data.py` — [Unit tests](#unit-tests)
|
||||
* [ ] `ChangeLog.d/*.txt` — changelog entry
|
||||
|
||||
Summary of files to modify when adding new API functions:
|
||||
|
||||
* [ ] `include/psa/crypto.h` and `include/psa/crypto_sizes.h`, or `include/psa/crypto_extra.h` — [New functions and macros](#new-functions-and-macros)
|
||||
* [ ] `library/psa_crypto.c`, `scripts/data_files/driver_templates/*.jinja` — [Implementation of the mechanisms](#implementation-of-the-mechanisms)
|
||||
* [ ] If adding stateful functions: `include/psa/crypto_struct.h`, `include/psa/crypto_builtin_*.h`, `include/psa/crypto_driver_contexts_*.h` — [Translucent data structures](#translucent-data-structures)
|
||||
* [ ] `tests/suites/test_suite_psa_crypto.data`, `tests/suites/test_suite_psa_crypto.function`, `tests/suites/test_suite_psa_crypto_driver_wrappers.*` — [Unit tests](#unit-tests)
|
||||
|
||||
Note that this is just a basic guide. In some cases, you won't need to change all the files listed here. In some cases, you may need to change other files.
|
||||
|
||||
### PSA standardization
|
||||
|
||||
Typically, if there's enough demand for a cryptographic mechanism in Mbed TLS, there's enough demand for it to be part of the official PSA Cryptography specification. Therefore the first step before implementing a new mechanism should be to approach the PSA Cryptography working group in Arm for standardization.
|
||||
|
||||
At the time of writing, all cryptographic mechanisms that are accessible through `psa_xxx` APIs in in Mbed TLS are current or upcoming PSA standards. Mbed TLS implements some extensions to the PSA API that offer extra integration customization or extra key policies.
|
||||
|
||||
Mbed TLS routinely implements cryptographic mechanisms that are not yet part of a published PSA standard, but that are scheduled to be part of a future version of the standard. The Mbed TLS implementation validates the feasibility of the upcoming PSA standard. The PSA Cryptography working group and the Mbed TLS development team communicate during the elaboration of the new interfaces.
|
||||
|
||||
### New functions and macros
|
||||
|
||||
If a mechanism requires new functions, they should follow the design guidelines in the PSA Cryptography API specification.
|
||||
|
||||
Functions that are part of the current or upcoming API are declared in `include/psa/crypto.h`, apart from structure accessors defined in `include/psa/crypto_struct.h`. Functions that have output buffers have associated sufficient-output-size macros in `include/psa/crypto_sizes.h`.
|
||||
|
||||
Constants (algorithm identifiers, key type identifiers, etc.) and associated destructor macros (e.g. `PSA_IS_xxx()`) are defined in `include/psa/crypto_values.h`.
|
||||
|
||||
Functions and macros that are not intended for standardization, or that are at a stage where the draft standard might still evolve significantly, are declared in `include/psa/crypto_extra.h`.
|
||||
|
||||
The PSA Cryptography API specification defines both names and values for certain kinds of constants: algorithms (`PSA_ALG_xxx`), key types (`PSA_KEY_TYPE_xxx`), ECC curve families (`PSA_ECC_FAMILY_xxx`), DH group families (`PSA_DH_FAMILY_xxx`). If Mbed TLS defines an algorithm or a key type that is not part of a current or upcoming PSA standard, pick a value with the `VENDOR` flag set. If Mbed TLS defines an ECC curve or DH group family that is not part of a current or upcoming PSA standard, define a vendor key type and use the family identifier only with this vendor key type.
|
||||
|
||||
New constants must have a test case in `tests/suites/test_suite_psa_crypto_metadata.data` that verifies that `PSA_IS_xxx` macros behave properly with the new constant. New `PSA_IS_xxx` macros must be declared in `tests/suites/test_suite_psa_crypto_metadata.function`.
|
||||
|
||||
### Preprocessor symbols
|
||||
|
||||
Each cryptographic mechanism is optional and can be selected by the application at build time. For each feature `PSA_ttt_xxx`:
|
||||
|
||||
* The feature is available to applications when the preprocessor symbol `PSA_WANT_ttt_xxx` is defined. These symbols are set in the application configuration file `include/psa/crypto_config.h` (or `MBEDTLS_PSA_CRYPTO_CONFIG_FILE`, plus `MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE`), with code in `include/mbedtls/config_psa.h` deducing the necessary underlying `MBEDTLS_xxx` symbols.
|
||||
* For transparent keys (keys that are not in a secure element), the feature is implemented by Mbed TLS if `MBEDTLS_PSA_BUILTIN_ttt_xxx` is defined, and by an accelerator driver if `MBEDTLS_PSA_ACCEL_ttt_xxx` is defined. `MBEDTLS_PSA_BUILTIN_ttt_xxx` constants are set in `include/mbedtls/config_psa.h` based on the application requests `PSA_WANT_ttt_xxx` and the accelerator driver declarations `MBEDTLS_PSA_ACCEL_ttt_xxx`.
|
||||
* For the testing of the driver dispatch code, `tests/configs/crypto_config_test_driver_extension.h` sets additional `MBEDTLS_PSA_ACCEL_xxx` symbols.
|
||||
|
||||
For more details, see *[Conditional inclusion of cryptographic mechanism through the PSA API in Mbed TLS](../proposed/psa-conditional-inclusion-c.html)*.
|
||||
|
||||
Some mechanisms require other mechanisms. For example, you can't do GCM without a block cipher, or RSA-PSS without RSA keys. When mechanism A requires mechanism B, `include/mbedtls/config_psa.h` ensures that B is enabled whenever A is enabled. When mechanism A requires at least one of a set {B1, B2, B3, ...} but there is no particular reason why enabling A would enable any of the specific Bi's, it's up to the application to choose Bi's and the file `library/check_crypto_config.h` contains compile-time constraints to ensure that at least one Bi is enabled.
|
||||
|
||||
### Implementation of the mechanisms
|
||||
|
||||
The general structure of a cryptographic operation function is:
|
||||
|
||||
1. API function defined in `library/psa_crypto.c`. The entry point performs generic checks that don't depend on whether the mechanism is implemented in software or in a driver and looks up keys in the key store.
|
||||
2. Driver dispatch code in `scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja`, `scripts/data_files/driver_templates/psa_crypto_driver_wrappers_no_static.c.jinja` or files included from there.
|
||||
3. Built-in implementation in `library/psa_crypto_*.c` (with function declarations in the corresponding `.h` file). These files typically contain the implementation of modes of operation over basic building blocks that are defined elsewhere. For example, HMAC is implemented in `library/psa_crypto_mac.c` but the underlying hash functions are implemented in `library/sha*.c` and `library/md*.c`.
|
||||
4. Basic cryptographic building blocks in `library/*.c`.
|
||||
|
||||
When implementing a new algorithm or key type, there are typically things to change in `library/crypto.c` (e.g. buffer size calculations, algorithm/key-type compatibility) and in the built-in implementation, but not in the driver dispatch code.
|
||||
|
||||
### Translucent data structures
|
||||
|
||||
Some mechanisms require state to be kept between function calls. Keys and key-like data is kept in the key store, which PSA manages internally. Other state, for example the state of multipart operations, is kept in structures allocated by the caller.
|
||||
|
||||
The size of operation structures needs to be known at compile time, since callers may allocate them on the stack. Therefore these structures are defined in a public header: `include/psa/crypto_struct.h` for the parts that are independent of the underlying implementation, `include/psa/crypto_builtin_*` for parts that are specific to the Mbed TLS built-in implementation, `include/psa/crypto_driver_*.h` for structures implemented by drivers.
|
||||
|
||||
### Unit tests
|
||||
|
||||
A number of unit tests are automatically generated by `framework/scripts/generate_psa_tests.py` based on the algorithms and key types declared in `include/psa/crypto_values.h` and `include/psa/crypto_extra.h`:
|
||||
|
||||
* Attempt to create a key with a key type that is not supported.
|
||||
* Attempt to perform an operation with a combination of key type and algorithm that is not valid or not supported.
|
||||
* Storage and retrieval of a persistent key.
|
||||
|
||||
When adding a new key type or algorithm:
|
||||
|
||||
* `framework/scripts/mbedtls_framework/crypto_knowledge.py` contains knowledge about the compatibility of key types, key sizes and algorithms.
|
||||
* `framework/scripts/mbedtls_framework/asymmetric_key_data.py` contains valid key data for asymmetric key types.
|
||||
|
||||
Other things need to be tested manually, either in `tests/suites/test_sutie_psa_crypto.data` or in another file. For example (this is not an exhaustive list):
|
||||
|
||||
* Known answer tests.
|
||||
* Potential edge cases (e.g. data less/equal/more than the block size, number equal to zero in asymmetric cryptography).
|
||||
* Tests with invalid keys (e.g. wrong size or format).
|
||||
* Tests with invalid data (e.g. wrong size or format, output buffer too small, invalid padding).
|
||||
* For new functions: incorrect function call sequence, driver dispatch (in `tests/suites/test_suite_psa_crypto_driver_wrappers.*`).
|
||||
* For key derivation algorithms: variation on the sequence of input steps, variation on the output size.
|
||||
|
||||
@@ -1,214 +0,0 @@
|
||||
PSA key store design
|
||||
====================
|
||||
|
||||
## Introduction
|
||||
|
||||
This document describes the architecture of the key storage in memory in the Mbed TLS and TF-PSA-Crypto implementation of the PSA Cryptography API.
|
||||
|
||||
In the PSA Cryptography API, cryptographic operations access key materials via a key identifier (key ID for short). Applications must first create a key object, which allocates storage in memory for the key material and metadata. This storage is under the control of the library and may be located in a different memory space such as a trusted execution environment or a secure element.
|
||||
|
||||
The storage of persistent keys is out of scope of this document. See the [Mbed Crypto storage specification](mbed-crypto-storage-specification.md).
|
||||
|
||||
## Key slot management interface
|
||||
|
||||
### Key store and key slots
|
||||
|
||||
The **key store** consists of a collection of **key slots**. Each key slot contains the metadata for one key, as well as the key material or a reference to the key material.
|
||||
|
||||
A key slot has the type `psa_key_slot_t`. The key store is a global object which is private inside `psa_crypto_slot_management.c`.
|
||||
|
||||
### Key slot entry points
|
||||
|
||||
The following operations allocate a key slot by calling `psa_reserve_free_key_slot()`:
|
||||
|
||||
* **Creating** a key object, through means such as import, random generation, deterministic derivation, copy, or registration of an existing key that is stored in protected hardware (secure element, hardware unique key (HUK)).
|
||||
* **Loading** a persistent key from storage, or loading a built-in key. This is done through `psa_get_and_lock_key_slot()`, which calls `psa_reserve_free_key_slot()` and loads the key if applicable.
|
||||
|
||||
The following operations free a key slot by calling `psa_wipe_key_slot()` and, if applicable, `psa_free_key_slot()`:
|
||||
|
||||
* **Destroying** a key.
|
||||
* **Purging** a persistent key from memory, either explicitly at the application's request or to free memory.
|
||||
|
||||
Deinitializing the PSA Crypto subsystem with `mbedtls_psa_crypto_free()` destroys all volatile keys and purges all persistent keys.
|
||||
|
||||
The library accesses key slots in the following scenarios:
|
||||
|
||||
* while the key is being created or loaded;
|
||||
* while the key is being destroyed or purged;
|
||||
* while the key metadata or key material is being accessed.
|
||||
|
||||
### Key slot states
|
||||
|
||||
The state of a key slot is indicated by its `state` field of type `psa_key_slot_state_t`, which can be:
|
||||
|
||||
* `PSA_SLOT_EMPTY`: a slot that occupies memory but does not currently contain a key.
|
||||
* `PSA_SLOT_FILLING`: a slot that is being filled to create or load a key.
|
||||
* `PSA_SLOT_FULL`: a slot containing a key.
|
||||
* `PSA_SLOT_PENDING_DELETION`: a slot whose key is being destroy or purged.
|
||||
|
||||
These states are mostly useful for concurrency. See [Concurrency](#concurrency) below and [key slot states in the PSA thread safety specification](psa-thread-safety/psa-thread-safety.md#key-slot-states).
|
||||
|
||||
#### Concurrency
|
||||
|
||||
In a multithreaded environment, since Mbed TLS 3.6.0, each key slot is protected by a reader-writer lock. (In earlier versions, the key store was not thread-safe.) The lock is controlled by a single global mutex `mbedtls_threading_psa_globaldata_mutex`. The concurrency state of the slot is indicated by the state and the `registered_readers` field:
|
||||
|
||||
* `EMPTY` or `FULL` state, `registered_readers == 0`: the slot is not in use by any thread.
|
||||
* `FULL` state, `registered_readers != 0`: the slot is being read.
|
||||
* `FILLING` or `PENDING_DELETION` state: the slot is being written.
|
||||
|
||||
For more information, see [PSA thread safety](psa-thread-safety/psa-thread-safety.md).
|
||||
|
||||
Note that a slot must not be moved in memory while it is being read or written.
|
||||
|
||||
## Key slot management implementations
|
||||
|
||||
### Key store implementation variants
|
||||
|
||||
There are three variants of the key store implementation, responding to different needs.
|
||||
|
||||
* Hybrid key store ([static key slots](#static-key-store) with dynamic key data): the key store is a statically allocated array of slots, of size `MBEDTLS_PSA_KEY_SLOT_COUNT`. Key material is allocated on the heap. This is the historical implementation. It remains the default in the Mbed TLS 3.6 long-time support (LTS) branch when using a handwritten `mbedtls_config.h`, as is common on resource-constrained platforms, because the alternatives have tradeoffs (key size limit and larger RAM usage at rest for the static key store, larger code size and more risk due to code complexity for the dynamic key store).
|
||||
* Fully [static key store](#static-key-store) (since Mbed TLS 3.6.3): the key store is a statically allocated array of slots, of size `MBEDTLS_PSA_KEY_SLOT_COUNT`. Each key slot contains the key representation directly, and the key representation must be no more than `MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE` bytes. This is intended for very constrained devices that do not have a heap.
|
||||
* [Dynamic key store](#dynamic-key-store) (since Mbed TLS 3.6.1): the key store is dynamically allocated as multiple slices on the heap, with a size that adjusts to the application's usage. Key material is allocated on the heap. Compared to the hybrid key store, the code size and RAM consumption are larger. This is intended for higher-end devices where applications are not expected to have a highly predicatable resource usage. This is the default implementation when using the default `mbedtls_config.h` file, as is common on platforms such as Linux, starting with Mbed TLS 3.6.1.
|
||||
|
||||
#### Future improvement: merging the key store variants
|
||||
|
||||
In the future, we may reduce the number of key store variants to just two, perhaps even one.
|
||||
|
||||
We introduced the variants other than the hybrid key store in a patch release of a long-time support version. As a consequence, we wanted to minimize making changes to the default build (when not using the supplied `mbedtls_config.h`, as explained above), to minimize the risk of bugs and the increase in code size. These considerations will not apply in future major or minor releases, so the default key store can change later.
|
||||
|
||||
The static key store could become a runtime decision, where only keys larger than some threshold require the use of heap memory. The reasons not to do this in Mbed TLS 3.6.x are that this increases complexity somewhat (slightly more code size, and more risk), and this changes the RAM usage profile somewhat.
|
||||
|
||||
A major constraint on the design of the dynamic key store is the need to preserve slot pointers while a slot may be accessed by another thread (see [“Concurrency”](#concurrency)). With the concurrency primitives available in Mbed TLS 3.x, it is very hard to move a key slot in memory, because there could be an indefinite wait until some other thread has finished accessing the slot. This pushed towards the slice-based organisation described below, where each slice is allocated for the long term. In particular, slices cannot be compacted (compacting would be moving slots out of a sparsely-used slice to free it). Better concurrency primitives (e.g. condition variables or semaphores), together with a `realloc()` primitive, could allow freeing unused memory more aggressively, which could make the dynamic key store not detrimental in RAM usage compared to the historical hybrid key store.
|
||||
|
||||
#### Slice abstraction
|
||||
|
||||
Some parts of the key slot management code use **key slices** as an abstraction. A key slice is an array of key slots. Key slices are identified by an index which is a small non-negative integer.
|
||||
|
||||
* With a [static key store](#static-key-store), there is a single, statically allocated slice, with the index 0.
|
||||
* With a [dynamic key store](#dynamic-key-store), there is statically allocated array of pointers to key slices. The index of a slice is the index in that array. The slices are allocated on the heap as needed.
|
||||
|
||||
#### Key identifiers and slot location
|
||||
|
||||
When creating a volatile key, the slice containing the slot and index of the slot in its slice determine the key identifier. When accessing a volatile key, the slice and the slot index in the slice are calculated from the key identifier. The encoding of the slot location in the volatile key identifier is different for a [static](#volatile-key-identifiers-in-the-static-key-store) or [dynamic](#volatile-key-identifiers-in-the-dynamic-key-store) key store.
|
||||
|
||||
### Static key store
|
||||
|
||||
The static key store is the historical implementation. The key store is a statically allocated array of slots, of size `MBEDTLS_PSA_KEY_SLOT_COUNT`. This value is an upper bound for the total number of volatile keys plus loaded keys.
|
||||
|
||||
Since Mbed TLS 3.6.3, there are two variants for the static key store: a hybrid variant (default), and a fully-static variant enabled by the configuration option `MBEDTLS_PSA_STATIC_KEY_SLOTS`. The two variants have the same key store management: the only difference is in how the memory for key data is managed. With fully static key slots, the key data is directly inside the slot, and limited to `MBEDTLS_PSA_KEY_SLOT_BUFFER_SIZE` bytes. With the hybrid key store, the slot contains a pointer to the key data, which is allocated on the heap.
|
||||
|
||||
#### Volatile key identifiers in the static key store
|
||||
|
||||
For easy lookup, a volatile key whose index is `id` is stored at the index `id - PSA_KEY_ID_VOLATILE_MIN`.
|
||||
|
||||
#### Key creation with a static key store
|
||||
|
||||
To create a key, `psa_reserve_free_key_slot()` searches the key slot array until it finds one that is empty. If there are none, the code looks for a persistent key that can be purged (see [“Persistent key cache”](#persistent-key-cache)), and purges it. If no slot is free and no slot contains a purgeable key, the key creation fails.
|
||||
|
||||
#### Freeing a key slot with a static key store
|
||||
|
||||
With a static key store, `psa_wipe_key_slot()` destroys or purges a key by freeing any associated resources, then setting the key slot to the empty state. The slot is then ready for reuse.
|
||||
|
||||
### Dynamic key store
|
||||
|
||||
The dynamic key store allows a large number of keys, at the expense of more complex memory management.
|
||||
|
||||
The dynamic key store was added in Mbed TLS 3.6.1. It is enabled by `MBEDTLS_PSA_KEY_STORE_DYNAMIC`, which is enabled by default since Mbed TLS 3.6.1.
|
||||
|
||||
#### Dynamic key slot performance characteristics
|
||||
|
||||
Key management and key access have $O(1)$ amortized performance, and mostly $O(1)$ performance for actions involving keys. More precisely:
|
||||
|
||||
* Access to an existing volatile key takes $O(1)$ time.
|
||||
* Access to a persistent key (including creation and destruction) takes time that is linear in `MBEDTLS_PSA_KEY_SLOT_COUNT`.
|
||||
* Allocating a key takes amortized $O(1)$ time. Usually the time is $O(s)$ where $s$ is the number of slices (which is a hard-coded value less than $30$), but when creating $k$ volatile keys, at most $\log(k)$ creations will involve calls to `calloc()`, totalling $O(k)$ memory.
|
||||
* Destroying a volatile key takes $O(1)$ time as of Mbed TLS 3.6.1. Later improvements to memory consumption are likely to involve calls to `free()` which may total $O(k)$ memory where $k$ is the maximum number of volatile keys.
|
||||
|
||||
#### Key slices in the dynamic key store
|
||||
|
||||
The key slot is organized in slices, which are dynamically arrays of key slot. The number of slices is determined at compile time. The key store contains a static array of pointers to slices.
|
||||
|
||||
Volatile keys and loaded keys (persistent or built-in) are stored in separate slices.
|
||||
Key slices number 0 to `KEY_SLOT_VOLATILE_SLICE_COUNT - 1` contain only volatile keys.
|
||||
One key slice contains only loaded keys: that key slice is thus the cache slice. See [“Persistent key cache”](persistent-key-cache) for how the cache is managed.
|
||||
|
||||
#### Volatile key identifiers in the dynamic key store
|
||||
|
||||
A volatile key identifier encodes the slice index and the slot index at separate bit positions. That is, `key_id = BASE | slice_index | slot_index` where the bits set in `BASE`, `slice_index` and `slot_index` do not overlap.
|
||||
|
||||
#### From key slot to key slice
|
||||
|
||||
Some parts of the slot management code need to determine which key slice contains a key slot when given a pointer to the key slot. In principle, the key slice is uniquely determined from the key identifier which is located in the slot:
|
||||
|
||||
* for a volatile key identifier, the [slice index is encoded in the key identifier](#volatile-key-identifiers-in-the-dynamic-key-store);
|
||||
* for a persistent key identifier or built-in key identifier, [the slot is in the sole cache slice](#key-slices-in-the-dynamic-key-store).
|
||||
|
||||
Nonetheless, we store the slice index as a field in the slot, for two reasons:
|
||||
|
||||
* It is more robust in case the slice assignment becomes more complex in the future or is somehow buggy.
|
||||
* It allows the slot to slice correspondence to work even if the key identifier field has not been filled yet or has been wiped. The implementation in Mbed TLS 3.6.1 requires this because `psa_wipe_key_slot()` wipes the slot, then calls `psa_free_key_slot()`, which needs to determine the slice. Keeping the slice index as a separate field allows us to better separate the concerns of key liveness and slot liveness. A redesign of the internal interfaces could improve this, but would be too disruptive in the 3.6 LTS branch.
|
||||
|
||||
#### Length of the volatile key slices
|
||||
|
||||
The volatile key slices have exponentially increasing length: each slice is twice as long as the previous one. Thus if the length of slice 0 is `B` and there are `N` slices, then there are `B * (2^N - 1)` slots.
|
||||
|
||||
As of Mbed TLS 3.6.1, the maximum number of volatile key slots is less than the theoretical maximum of 2^30 - 2^16 (0x10000000..0x7ffeffff, the largest range of key identifiers reserved for the PSA Crypto implementation that does not overlap the range for built-in keys). The reason is that we limit the slot index to 2^25-1 so that the [encoding of volatile key identifiers](#volatile-key-identifiers-in-the-dynamic-key-store) has 25 bits for the slot index.
|
||||
|
||||
When `MBEDTLS_TEST_HOOKS` is enabled, the length of key slices can be overridden. We use this in tests that need to fill the key store.
|
||||
|
||||
#### Free list
|
||||
|
||||
Each volatile key slice has a **free list**. This is a linked list of all the slots in the slice that are free. The global data contains a static array of free list heads, i.e. the index of a free slot in the slice. Each free slot contains the index of the next free slot in that slice's free list. The end of the list is indicated by an index that is larger than the length of the slice. If the list is empty, the head contains an index that is larger than the length.
|
||||
|
||||
As a small optimization, a free slot does not actually contain the index of the next slot, but the index of the next free slot on the list _relative to the next slot in the array_. For example, 0 indicates that the next free slot is the slot immediately after the current slot. This fact is the reason for the encoding: a slice freshly obtained from `calloc` has all of its slots in the free list in order. The value 1 indicates that there is one element between this slot and the next free slot. The next element of the free list can come before the current slot: -2 indicates that it's the slot immediately before, -3 is two slots before, and so on (-1 is impossible). In general, the absolute index of the next slot after slot `i` in the free list is `i + 1 slice[i].next_free_relative_to_next`.
|
||||
|
||||
#### Dynamic key slot allocation
|
||||
|
||||
To create a volatile key, `psa_reserve_free_key_slot()` searches the free lists of each allocated slice until it finds a slice that is not full. If all allocated slices are full, the code allocates a new slice at the lowest possible slice index. If all possible slices are already allocated and full, the key creation fails.
|
||||
|
||||
The newly allocated slot is removed from the slice's free list.
|
||||
|
||||
We only allocate a slice of size `B * 2^k` if there are already `B * (2^k - 1)` occupied slots. Thus the memory overhead is at most `B` slots plus the number of occupied slots, i.e. the memory consumption for slots is at most twice the required memory plus a small constant overhead.
|
||||
|
||||
#### Dynamic key slot deallocation
|
||||
|
||||
When destroying a volatile key, `psa_wipe_key_slot()` calls `psa_free_key_slot()`. This function adds the newly freed slot to the head of the free list.
|
||||
|
||||
##### Future improvement: slice deallocation
|
||||
|
||||
As of Mbed TLS 3.6.1, `psa_free_key_slot()` does not deallocate slices. Thus the memory consumption for slots never decreases (except when the PSA crypto subsystem is deinitialized). Freeing key slices intelligently would be a desirable improvement.
|
||||
|
||||
We should not free a key slice as soon as it becomes empty, because that would cause large allocations and deallocations if there are slices full of long-lived keys, and then one slice keeps being allocate and deallocated for the occasional short-lived keys. Rather, there should be some hysteresis, e.g. only deallocate a slice if there are at least T free slots in the previous slice. [#9435](https://github.com/Mbed-TLS/mbedtls/issues/9435)
|
||||
|
||||
Note that currently, the slice array contains one sequence of allocated slices followed by one sequence of unallocated slices. Mixing allocated and unallocated slices may make some parts of the code a little more complex, and should be tested thoroughly.
|
||||
|
||||
### Persistent key cache
|
||||
|
||||
Persistent keys and built-in keys need to be loaded into the in-memory key store each time they are accessed:
|
||||
|
||||
* while creating them;
|
||||
* to access their metadata;
|
||||
* to start performing an operation with the key;
|
||||
* when destroying the key.
|
||||
|
||||
To avoid frequent storage access, we cache persistent keys in memory. This cache also applies to built-in keys.
|
||||
|
||||
With the [static key store](#static-key-store), a non-empty slot can contain either a volatile key or a cache entry for a persistent or built-in key. With the [dynamic key store](#dynamic-key-store), volatile keys and cached keys are placed in separate [slices](#key-slices-in-the-dynamic-key-store).
|
||||
|
||||
The persistent key cache is a fixed-size array of `MBEDTLS_PSA_KEY_SLOT_COUNT` slots. In the static key store, this array is shared with volatile keys. In the dynamic key store, the cache is a separate array that does not contain volatile keys.
|
||||
|
||||
#### Accessing a persistent key
|
||||
|
||||
`psa_get_and_lock_key_slot()` automatically loads persistent and built-in keys if the specified key identifier is in the corresponding range. To that effect, it traverses the key cache to see if a key with the given identifier is already loaded. If not, it loads the key. This cache walk takes time that is proportional to the cache size.
|
||||
|
||||
#### Cache eviction
|
||||
|
||||
A key slot must be allocated in the cache slice:
|
||||
|
||||
* to create a volatile key (static key store only);
|
||||
* to create a persistent key;
|
||||
* to load a persistent or built-in key.
|
||||
|
||||
If the cache slice is full, the code will try to evict an entry. Only slots that do not have readers can be evicted (see [“Concurrency”](#concurrency)). In the static key store, slots containing volatile keys cannot be evicted.
|
||||
|
||||
As of Mbed TLS 3.6.1, there is no tracking of a key's usage frequency or age. The slot eviction code picks the first evictable slot it finds in its traversal order. We have not reasoned about or experimented with different strategies.
|
||||
@@ -1,685 +0,0 @@
|
||||
PSA API functions and shared memory
|
||||
===================================
|
||||
|
||||
## Introduction
|
||||
|
||||
This document discusses the security architecture of systems where PSA API functions might receive arguments that are in memory that is shared with an untrusted process. On such systems, the untrusted process might access a shared memory buffer while the cryptography library is using it, and thus cause unexpected behavior in the cryptography code.
|
||||
|
||||
### Core assumptions
|
||||
|
||||
We assume the following scope limitations:
|
||||
|
||||
* Only PSA Crypto API functions are in scope (including Mbed TLS extensions to the official API specification). Legacy crypto, X.509, TLS, or any other function which is not called `psa_xxx` is out of scope.
|
||||
* We only consider [input buffers](https://arm-software.github.io/psa-api/crypto/1.1/overview/conventions.html#input-buffer-sizes) and [output buffers](https://arm-software.github.io/psa-api/crypto/1.1/overview/conventions.html#output-buffer-sizes). Any other data is assumed to be in non-shared memory.
|
||||
|
||||
## System architecture discussion
|
||||
|
||||
### Architecture overview
|
||||
|
||||
We consider a system that has memory separation between partitions: a partition can't access another partition's memory directly. Partitions are meant to be isolated from each other: a partition may only affect the integrity of another partition via well-defined system interfaces. For example, this can be a Unix/POSIX-like system that isolates processes, or isolation between the secure world and the non-secure world relying on a mechanism such as TrustZone, or isolation between secure-world applications on such a system.
|
||||
|
||||
More precisely, we consider such a system where our PSA Crypto implementation is running inside one partition, called the **crypto service**. The crypto service receives remote procedure calls (RPC) from other partitions, validates their arguments (e.g. validation of key identifier ownership), and calls a PSA Crypto API function. This document is concerned with environments where the arguments passed to a PSA Crypto API function may be in shared memory (as opposed to environments where the inputs are always copied into memory that is solely accessible by the crypto service before calling the API function, and likewise with output buffers after the function returns).
|
||||
|
||||
When the data is accessible to another partition, there is a risk that this other partition will access it while the crypto implementation is working. Although this could be prevented by suspending the whole system while crypto is working, such a limitation is rarely desirable and most systems don't offer a way to do it. (Even systems that have absolute thread priorities, and where crypto has a higher priority than any untrusted partition, may be vulnerable due to having multiple cores or asynchronous data transfers with peripherals.)
|
||||
|
||||
The crypto service must guarantee that it behaves as if the rest of the world was suspended while it is executed. A behavior that is only possible if an untrusted entity accesses a buffer while the crypto service is processing the data is a security violation.
|
||||
|
||||
### Risks and vulnerabilities
|
||||
|
||||
We consider a security architecture with two or three entities:
|
||||
|
||||
* a crypto service, which offers PSA crypto API calls over RPC (remote procedure call) using shared memory for some input or output arguments;
|
||||
* a client of the crypto service, which makes a RPC to the crypto service;
|
||||
* in some scenarios, a client of the client, which makes a RPC to the crypto client which re-shares the memory with the crypto service.
|
||||
|
||||
The behavior of RPC is defined for in terms of values of inputs and outputs. This models an ideal world where the content of input and output buffers is not accessible outside the crypto service while it is processing an RPC. It is a security violation if the crypto service behaves in a way that cannot be achieved by setting the inputs before the RPC call, and reading the outputs after the RPC call is finished.
|
||||
|
||||
#### Read-read inconsistency
|
||||
|
||||
If an input argument is in shared memory, there is a risk of a **read-read inconsistency**:
|
||||
|
||||
1. The crypto code reads part of the input and validates it, or injects it into a calculation.
|
||||
2. The client (or client's client) modifies the input.
|
||||
3. The crypto code reads the same part again, and performs an action which would be impossible if the input had had the same value all along.
|
||||
|
||||
Vulnerability example (parsing): suppose the input contains data with a type-length-value or length-value encoding (for example, importing an RSA key). The crypto code reads the length field and checks that it fits within the buffer. (This could be the length of the overall data, or the length of an embedded field) Later, the crypto code reads the length again and uses it without validation. A malicious client can modify the length field in the shared memory between the two reads and thus cause a buffer overread on the second read.
|
||||
|
||||
Vulnerability example (dual processing): consider an RPC to perform authenticated encryption, using a mechanism with an encrypt-and-MAC structure. The authenticated encryption implementation separately calculates the ciphertext and the MAC from the plaintext. A client sets the plaintext input to `"PPPP"`, then starts the RPC call, then changes the input buffer to `"QQQQ"` while the crypto service is working.
|
||||
|
||||
* Any of `enc("PPPP")+mac("PPPP")`, `enc("PPQQ")+mac("PPQQ")` or `enc("QQQQ")+mac("QQQQ")` are valid outputs: they are outputs that can be produced by this authenticated encryption RPC.
|
||||
* If the authenticated encryption calculates the ciphertext before the client changes the output buffer and calculates the MAC after that change, reading the input buffer again each time, the output will be `enc("PPPP")+mac("QQQQ")`. There is no input that can lead to this output, hence this behavior violates the security guarantees of the crypto service.
|
||||
|
||||
#### Write-read inconsistency
|
||||
|
||||
If an output argument is in shared memory, there is a risk of a **write-read inconsistency**:
|
||||
|
||||
1. The crypto code writes some intermediate data into the output buffer.
|
||||
2. The client (or client's client) modifies the intermediate data.
|
||||
3. The crypto code reads the intermediate data back and continues the calculation, leading to an outcome that would not be possible if the intermediate data had not been modified.
|
||||
|
||||
Vulnerability example: suppose that an RSA signature function works by formatting the data in place in the output buffer, then applying the RSA private-key operation in place. (This is how `mbedtls_rsa_pkcs1_sign` works.) A malicious client may write badly formatted data into the buffer, so that the private-key operation is not a valid signature (e.g. it could be a decryption), violating the RSA key's usage policy.
|
||||
|
||||
Vulnerability example with chained calls: we consider the same RSA signature operation as before. In this example, we additionally assume that the data to sign comes from an attestation application which signs some data on behalf of a final client: the key and the data to sign are under the attestation application's control, and the final client must not be able to obtain arbitrary signatures. The final client shares an output buffer for the signature with the attestation application, and the attestation application re-shares this buffer with the crypto service. A malicious final client can modify the intermediate data and thus sign arbitrary data.
|
||||
|
||||
#### Write-write disclosure
|
||||
|
||||
If an output argument is in shared memory, there is a risk of a **write-write disclosure**:
|
||||
|
||||
1. The crypto code writes some intermediate data into the output buffer. This intermediate data must remain confidential.
|
||||
2. The client (or client's client) reads the intermediate data.
|
||||
3. The crypto code overwrites the intermediate data.
|
||||
|
||||
Vulnerability example with chained calls (temporary exposure): an application encrypts some data, and lets its clients store the ciphertext. Clients may not have access to the plaintext. To save memory, when it calls the crypto service, it passes an output buffer that is in the final client's memory. Suppose the encryption mechanism works by copying its input to the output buffer then encrypting in place (for example, to simplify considerations related to overlap, or because the implementation relies on a low-level API that works in place). In this scenario, the plaintext is exposed to the final client while the encryption in progress, which violates the confidentiality of the plaintext.
|
||||
|
||||
Vulnerability example with chained calls (backtrack): we consider a provisioning application that provides a data encryption service on behalf of multiple clients, using a single shared key. Clients are not allowed to access each other's data. The provisioning application isolates clients by including the client identity in the associated data. Suppose that an AEAD decryption function processes the ciphertext incrementally by simultaneously writing the plaintext to the output buffer and calculating the tag. (This is how AEAD decryption usually works.) At the end, if the tag is wrong, the decryption function wipes the output buffer. Assume that the output buffer for the plaintext is shared from the client to the provisioning application, which re-shares it with the crypto service. A malicious client can read another client (the victim)'s encrypted data by passing the ciphertext to the provisioning application, which will attempt to decrypt it with associated data identifying the requesting client. Although the operation will fail beacuse the tag is wrong, the malicious client still reads the victim plaintext.
|
||||
|
||||
#### Write-read feedback
|
||||
|
||||
If a function both has an input argument and an output argument in shared memory, and processes its input incrementally to emit output incrementally, the following sequence of events is possible:
|
||||
|
||||
1. The crypto code processes part of the input and writes the corresponding part of the output.
|
||||
2. The client reads the early output and uses that to calculate the next part of the input.
|
||||
3. The crypto code processes the rest of the input.
|
||||
|
||||
There are cryptographic mechanisms for which this breaks security properties. An example is [CBC encryption](https://link.springer.com/content/pdf/10.1007/3-540-45708-9_2.pdf): if the client can choose the content of a plaintext block after seeing the immediately preceding ciphertext block, this gives the client a decryption oracle. This is a security violation if the key policy only allowed the client to encrypt, not to decrypt.
|
||||
|
||||
TODO: is this a risk we want to take into account? Although this extends the possible behaviors of the one-shot interface, the client can do the same thing legitimately with the multipart interface.
|
||||
|
||||
### Possible countermeasures
|
||||
|
||||
In this section, we briefly discuss generic countermeasures.
|
||||
|
||||
#### Copying
|
||||
|
||||
Copying is a valid countermeasure. It is conceptually simple. However, it is often unattractive because it requires additional memory and time.
|
||||
|
||||
Note that although copying is very easy to write into a program, there is a risk that a compiler (especially with whole-program optimization) may optimize the copy away, if it does not understand that copies between shared memory and non-shared memory are semantically meaningful.
|
||||
|
||||
Example: the PSA Firmware Framework 1.0 forbids shared memory between partitions. This restriction is lifted in version 1.1 due to concerns over RAM usage.
|
||||
|
||||
#### Careful accesses
|
||||
|
||||
The following rules guarantee that shared memory cannot result in a security violation other than [write-read feedback](#write-read-feedback):
|
||||
|
||||
* Never read the same input twice at the same index.
|
||||
* Never read back from an output.
|
||||
* Never write to the output twice at the same index.
|
||||
* This rule can usefully be relaxed in many circumstances. It is ok to write data that is independent of the inputs (and not otherwise confidential), then overwrite it. For example, it is ok to zero the output buffer before starting to process the input.
|
||||
|
||||
These rules are very difficult to enforce.
|
||||
|
||||
Example: these are the rules that a GlobalPlatform TEE Trusted Application (application running on the secure side of TrustZone on Cortex-A) must follow.
|
||||
|
||||
## Protection requirements
|
||||
|
||||
### Responsibility for protection
|
||||
|
||||
A call to a crypto service to perform a crypto operation involves the following components:
|
||||
|
||||
1. The remote procedure call framework provided by the operating system.
|
||||
2. The code of the crypto service.
|
||||
3. The code of the PSA Crypto dispatch layer (also known as the core), which is provided by Mbed TLS.
|
||||
4. The driver implementing the cryptographic mechanism, which may be provided by Mbed TLS (built-in driver) or by a third-party driver.
|
||||
|
||||
The [PSA Crypto API specification](https://arm-software.github.io/psa-api/crypto/1.1/overview/conventions.html#stability-of-parameters) puts the responsibility for protection on the implementation of the PSA Crypto API, i.e. (3) or (4).
|
||||
|
||||
> In an environment with multiple threads or with shared memory, the implementation carefully accesses non-overlapping buffer parameters in order to prevent any security risk resulting from the content of the buffer being modified or observed during the execution of the function. (...)
|
||||
|
||||
In Mbed TLS 2.x and 3.x up to and including 3.5.0, there is no defense against buffers in shared memory. The responsibility shifts to (1) or (2), but this is not documented.
|
||||
|
||||
In the remainder of this chapter, we will discuss how to implement this high-level requirement where it belongs: inside the implementation of the PSA Crypto API. Note that this allows two possible levels: in the dispatch layer (independently of the implementation of each mechanism) or in the driver (specific to each implementation).
|
||||
|
||||
#### Protection in the dispatch layer
|
||||
|
||||
The dispatch layer has no control over how the driver layer will access buffers. Therefore the only possible protection at this layer method is to ensure that drivers have no access to shared memory. This means that any buffer located in shared memory must be copied into or out of a buffer in memory owned by the crypto service (heap or stack). This adds inefficiency, mostly in terms of RAM usage.
|
||||
|
||||
For buffers with a small static size limit, this is something we often do for convenience, especially with output buffers. However, as of Mbed TLS 3.5.0, it is not done systematically.
|
||||
|
||||
It is ok to skip the copy if it is known for sure that a buffer is not in shared memory. However, the location of the buffer is not under the control of Mbed TLS. This means skipping the copy would have to be a compile-time or run-time option which has to be set by the application using Mbed TLS. This is both an additional maintenance cost (more code to analyze, more testing burden), and a residual security risk in case the party who is responsible for setting this option does not set it correctly. As a consequence, Mbed TLS will not offer this configurability unless there is a compelling argument.
|
||||
|
||||
#### Protection in the driver layer
|
||||
|
||||
Putting the responsibility for protection in the driver layer increases the overall amount of work since there are more driver implementations than dispatch implementations. (This is true even inside Mbed TLS: almost all API functions have multiple underlying implementations, one for each algorithm.) It also increases the risk to the ecosystem since some drivers might not protect correctly. Therefore having drivers be responsible for protection is only a good choice if there is a definite benefit to it, compared to allocating an internal buffer and copying. An expected benefit in some cases is that there are practical protection methods other than copying.
|
||||
|
||||
Some cryptographic mechanisms are naturally implemented by processing the input in a single pass, with a low risk of ever reading the same byte twice, and by writing the final output directly into the output buffer. For such mechanism, it is sensible to mandate that drivers respect these rules.
|
||||
|
||||
In the next section, we will analyze how susceptible various cryptographic mechanisms are to shared memory vulnerabilities.
|
||||
|
||||
### Susceptibility of different mechanisms
|
||||
|
||||
#### Operations involving small buffers
|
||||
|
||||
For operations involving **small buffers**, the cost of copying is low. For many of those, the risk of not copying is high:
|
||||
|
||||
* Any parsing of formatted data has a high risk of [read-read inconsistency](#read-read-inconsistency).
|
||||
* An internal review shows that for RSA operations, it is natural for an implementation to have a [write-read inconsistency](#write-read-inconsistency) or a [write-write disclosure](#write-write-disclosure).
|
||||
|
||||
Note that in this context, a “small buffer” is one with a size limit that is known at compile time, and small enough that copying the data is not prohibitive. For example, an RSA key fits in a small buffer. A hash input is not a small buffer, even if it happens to be only a few bytes long in one particular call.
|
||||
|
||||
The following buffers are considered small buffers:
|
||||
|
||||
* Any input or output directly related to asymmetric cryptography (signature, encryption/decryption, key exchange, PAKE), including key import and export.
|
||||
* Note that this does not include inputs or outputs that are not processed by an asymmetric primitives, for example the message input to `psa_sign_message` or `psa_verify_message`.
|
||||
* Cooked key derivation output.
|
||||
* The output of a hash or MAC operation.
|
||||
|
||||
**Design decision: the dispatch layer shall copy all small buffers**.
|
||||
|
||||
#### Symmetric cryptography inputs with small output
|
||||
|
||||
Message inputs to hash, MAC and key derivation operations are at a low risk of [read-read inconsistency](#read-read-inconsistency) because they are unformatted data, and for all specified algorithms, it is natural to process the input one byte at a time.
|
||||
|
||||
**Design decision: require symmetric cryptography drivers to read their input without a risk of read-read inconsistency**.
|
||||
|
||||
TODO: what about IV/nonce inputs? They are typically small, but don't necessarily have a static size limit (e.g. GCM recommends a 12-byte nonce, but also allows large nonces).
|
||||
|
||||
#### Key derivation outputs
|
||||
|
||||
Key derivation typically emits its output as a stream, with no error condition detected after setup other than operational failures (e.g. communication failure with an accelerator) or running out of data to emit (which can easily be checked before emitting any data, since the data size is known in advance).
|
||||
|
||||
(Note that this is about raw byte output, not about cooked key derivation, i.e. deriving a structured key, which is considered a [small buffer](#operations-involving-small-buffers).)
|
||||
|
||||
**Design decision: require key derivation drivers to emit their output without reading back from the output buffer**.
|
||||
|
||||
#### Cipher and AEAD
|
||||
|
||||
AEAD decryption is at risk of [write-write disclosure](#write-write-disclosure) when the tag does not match.
|
||||
|
||||
AEAD encryption and decryption are at risk of [read-read inconsistency](#read-read-inconsistency) if they process the input multiple times, which is natural in a number of cases:
|
||||
|
||||
* when encrypting with an encrypt-and-authenticate or authenticate-then-encrypt structure (one read to calculate the authentication tag and another read to encrypt);
|
||||
* when decrypting with an encrypt-then-authenticate structure (one read to decrypt and one read to calculate the authentication tag);
|
||||
* with SIV modes (not yet present in the PSA API, but likely to come one day) (one full pass to calculate the IV, then another full pass for the core authenticated encryption);
|
||||
|
||||
Cipher and AEAD outputs are at risk of [write-read inconsistency](#write-read-inconsistency) and [write-write disclosure](#write-write-disclosure) if they are implemented by copying the input into the output buffer with `memmove`, then processing the data in place. In particular, this approach makes it easy to fully support overlapping, since `memmove` will take care of overlapping cases correctly, which is otherwise hard to do portably (C99 does not offer an efficient, portable way to check whether two buffers overlap).
|
||||
|
||||
**Design decision: the dispatch layer shall allocate an intermediate buffer for cipher and AEAD plaintext/ciphertext inputs and outputs**.
|
||||
|
||||
Note that this can be a single buffer for the input and the output if the driver supports in-place operation (which it is supposed to, since it is supposed to support arbitrary overlap, although this is not always the case in Mbed TLS, a [known issue](https://github.com/Mbed-TLS/mbedtls/issues/3266)). A side benefit of doing this intermediate copy is that overlap will be supported.
|
||||
|
||||
For all currently implemented AEAD modes, the associated data is only processed once to calculate an intermediate value of the authentication tag.
|
||||
|
||||
**Design decision: for now, require AEAD drivers to read the additional data without a risk of read-read inconsistency**. Make a note to revisit this when we start supporting an SIV mode, at which point the dispatch layer shall copy the input for modes that are not known to be low-risk.
|
||||
|
||||
#### Message signature
|
||||
|
||||
For signature algorithms with a hash-and-sign framework, the input to sign/verify-message is passed to a hash, and thus can follow the same rules as [symmetric cryptography inputs with small output](#symmetric-cryptography-inputs-with-small-output). This is also true for `PSA_ALG_RSA_PKCS1V15_SIGN_RAW`, which is the only non-hash-and-sign signature mechanism implemented in Mbed TLS 3.5. This is not true for PureEdDSA (`#PSA_ALG_PURE_EDDSA`), which is not yet implemented: [PureEdDSA signature](https://www.rfc-editor.org/rfc/rfc8032#section-5.1.6) processes the message twice. (However, PureEdDSA verification only processes the message once.)
|
||||
|
||||
**Design decision: for now, require sign/verify-message drivers to read their input without a risk of read-read inconsistency**. Make a note to revisit this when we start supporting PureEdDSA, at which point the dispatch layer shall copy the input for algorithms such as PureEdDSA that are not known to be low-risk.
|
||||
|
||||
## Design of shared memory protection
|
||||
|
||||
This section explains how Mbed TLS implements the shared memory protection strategy summarized below.
|
||||
|
||||
### Shared memory protection strategy
|
||||
|
||||
* The core (dispatch layer) shall make a copy of the following buffers, so that drivers do not receive arguments that are in shared memory:
|
||||
* Any input or output from asymmetric cryptography (signature, encryption/decryption, key exchange, PAKE), including key import and export.
|
||||
* Plaintext/ciphertext inputs and outputs for cipher and AEAD.
|
||||
* The output of a hash or MAC operation.
|
||||
* Cooked key derivation output.
|
||||
|
||||
* A document shall explain the requirements on drivers for arguments whose access needs to be protected:
|
||||
* Hash and MAC input.
|
||||
* Cipher/AEAD IV/nonce (to be confirmed).
|
||||
* AEAD associated data (to be confirmed).
|
||||
* Key derivation input (excluding key agreement).
|
||||
* Raw key derivation output (excluding cooked key derivation output).
|
||||
|
||||
* The built-in implementations of cryptographic mechanisms with arguments whose access needs to be protected shall protect those arguments.
|
||||
|
||||
Justification: see “[Susceptibility of different mechanisms](#susceptibility-of-different-mechanisms)”.
|
||||
|
||||
### Implementation of copying
|
||||
|
||||
Copy what needs copying. This is broadly straightforward, however there are a few things to consider.
|
||||
|
||||
#### Compiler optimization of copies
|
||||
|
||||
It is unclear whether the compiler will attempt to optimize away copying operations.
|
||||
|
||||
Once the copying code is implemented, it should be evaluated to see whether compiler optimization is a problem. Specifically, for the major compilers supported by Mbed TLS:
|
||||
* Write a small program that uses a PSA function which copies inputs or outputs.
|
||||
* Build the program with link-time optimization / full-program optimization enabled (e.g. `-flto` with `gcc`). Try also enabling the most extreme optimization options such as `-Ofast` (`gcc`) and `-Oz` (`clang`).
|
||||
* Inspect the generated code with `objdump` or a similar tool to see if copying operations are preserved.
|
||||
|
||||
If copying behaviour is preserved by all major compilers then assume that compiler optimization is not a problem.
|
||||
|
||||
If copying behaviour is optimized away by the compiler, further investigation is needed. Experiment with using the `volatile` keyword to force the compiler not to optimize accesses to the copied buffers. If the `volatile` keyword is not sufficient, we may be able to use compiler or target-specific techniques to prevent optimization, for example memory barriers or empty `asm` blocks. These may be implemented and verified for important platforms while retaining a C implementation that is likely to be correct on most platforms as a fallback - the same approach taken by the constant-time module.
|
||||
|
||||
**Open questions: Will the compiler optimize away copies? If so, can it be prevented from doing so in a portable way?**
|
||||
|
||||
#### Copying code
|
||||
|
||||
We may either copy buffers on an ad-hoc basis using `memcpy()` in each PSA function, or use a unified set of functions for copying input and output data. The advantages of the latter are obvious:
|
||||
|
||||
* Any test hooks need only be added in one place.
|
||||
* Copying code must only be reviewed for correctness in one place, rather than in all functions where it occurs.
|
||||
* Copy bypass is simpler as we can just replace these functions with no-ops in a single place.
|
||||
* Any complexity needed to prevent the compiler optimizing copies away does not have to be duplicated.
|
||||
|
||||
On the other hand, the only advantage of ad-hoc copying is slightly greater flexibility.
|
||||
|
||||
**Design decision: Create a unified set of functions for copying input and output data.**
|
||||
|
||||
#### Copying in multipart APIs
|
||||
|
||||
Multipart APIs may follow one of 2 possible approaches for copying of input:
|
||||
|
||||
##### 1. Allocate a buffer and copy input on each call to `update()`
|
||||
|
||||
This is simple and mirrors the approach for one-shot APIs nicely. However, allocating memory in the middle of a multi-part operation is likely to be bad for performance. Multipart APIs are designed in part for systems that do not have time to perform an operation at once, so introducing poor performance may be a problem here.
|
||||
|
||||
**Open question: Does memory allocation in `update()` cause a performance problem? If so, to what extent?**
|
||||
|
||||
##### 2. Allocate a buffer at the start of the operation and subdivide calls to `update()`
|
||||
|
||||
In this approach, input and output buffers are allocated at the start of the operation that are large enough to hold the expected average call to `update()`. When `update()` is called with larger buffers than these, the PSA API layer makes multiple calls to the driver, chopping the input into chunks of the temporary buffer size and filling the output from the results until the operation is finished.
|
||||
|
||||
This would be more complicated than approach (1) and introduces some extra issues. For example, if one of the intermediate calls to the driver's `update()` returns an error, it is not possible for the driver's state to be rolled back to before the first call to `update()`. It is unclear how this could be solved.
|
||||
|
||||
However, this approach would reduce memory usage in some cases and prevent memory allocation during an operation. Additionally, since the input and output buffers would be fixed-size it would be possible to allocate them statically, avoiding the need for any dynamic memory allocation at all.
|
||||
|
||||
**Design decision: Initially use approach (1) and treat approach (2) as an optimization to be done if necessary.**
|
||||
|
||||
### Validation of copying
|
||||
|
||||
#### Validation of copying by review
|
||||
|
||||
This is fairly self-explanatory. Review all functions that use shared memory and ensure that they each copy memory. This is the simplest strategy to implement but is less reliable than automated validation.
|
||||
|
||||
#### Validation of copying with memory pools
|
||||
|
||||
Proposed general idea: have tests where the test code calling API functions allocates memory in a certain pool, and code in the library allocates memory in a different pool. Test drivers check that needs-copying arguments are within the library pool, not within the test pool.
|
||||
|
||||
#### Validation of copying by memory poisoning
|
||||
|
||||
Proposed general idea: in test code, “poison” the memory area used by input and output parameters that must be copied. Poisoning means something that prevents accessing memory while it is poisoned. This could be via memory protection (allocate with `mmap` then disable access with `mprotect`), or some kind of poisoning for an analyzer such as MSan or Valgrind.
|
||||
|
||||
In the library, the code that does the copying temporarily unpoisons the memory by calling a test hook.
|
||||
|
||||
```c
|
||||
static void copy_to_user(void *copy_buffer, void *const input_buffer, size_t length) {
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
if (memory_poison_hook != NULL) {
|
||||
memory_poison_hook(copy_buffer, length);
|
||||
}
|
||||
#endif
|
||||
memcpy(copy_buffer, input_buffer, length);
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
if (memory_unpoison_hook != NULL) {
|
||||
memory_unpoison_hook(copy_buffer, length);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
```
|
||||
The reason to poison the memory before calling the library, rather than after the copy-in (and symmetrically for output buffers) is so that the test will fail if we forget to copy, or we copy the wrong thing. This would not be the case if we relied on the library's copy function to do the poisoning: that would only validate that the driver code does not access the memory on the condition that the copy is done as expected.
|
||||
|
||||
##### Options for implementing poisoning
|
||||
|
||||
There are several different ways that poisoning could be implemented:
|
||||
|
||||
1. Using Valgrind's memcheck tool. Valgrind provides a macro `VALGRIND_MAKE_MEM_NO_ACCESS` that allows manual memory poisoning. Valgrind memory poisoning is already used for constant-flow testing in Mbed TLS.
|
||||
2. Using Memory Sanitizer (MSan), which allows us to mark memory as uninitialized. This is also used for constant-flow testing. It is suitable for input buffers only, since it allows us to detect when a poisoned buffer is read but not when it is written.
|
||||
3. Using Address Sanitizer (ASan). This provides `ASAN_POISON_MEMORY_REGION` which marks memory as inaccessible.
|
||||
4. Allocating buffers separate pages and calling `mprotect()` to set pages as inaccessible. This has the disadvantage that we will have to manually ensure that buffers sit in their own pages, which likely means making a copy.
|
||||
5. Filling buffers with random data, keeping a copy of the original. For input buffers, keep a copy of the original and copy it back once the PSA function returns. For output buffers, fill them with random data and keep a separate copy of it. In the memory poisoning hooks, compare the copy of random data with the original to ensure that the output buffer has not been written directly.
|
||||
|
||||
Approach (2) is insufficient for the full testing we require as we need to be able to check both input and output buffers.
|
||||
|
||||
Approach (5) is simple and requires no extra tooling. It is likely to have good performance as it does not use any sanitizers. However, it requires the memory poisoning test hooks to maintain extra copies of the buffers, which seems difficult to implement in practice. Additionally, it does not precisely test the property we want to validate, so we are relying on the tests to fail if given random data as input. It is possible (if unlikely) that the PSA function will access the poisoned buffer without causing the test to fail. This becomes more likely when we consider test cases that call PSA functions on incorrect inputs to check that the correct error is returned. For these reasons, this memory poisoning approach seems unsuitable.
|
||||
|
||||
All three remaining approaches are suitable for our purposes. However, approach (4) is more complex than the other two. To implement it, we would need to allocate poisoned buffers in separate memory pages. They would require special handling and test code would likely have to be designed around this special handling.
|
||||
|
||||
Meanwhile, approaches (1) and (3) are much more convenient. We are simply required to call a special macro on some buffer that was allocated by us and the sanitizer takes care of everything else. Of these two, ASan appears to have a limitation related to buffer alignment. From code comments quoted in [the documentation](https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning):
|
||||
|
||||
> This function is not guaranteed to poison the whole region - it may poison only subregion of [addr, addr+size) due to ASan alignment restrictions.
|
||||
|
||||
Specifically, ASan will round the buffer size down to 8 bytes before poisoning due to details of its implementation. For more information on this, see [Microsoft documentation of this feature](https://learn.microsoft.com/en-us/cpp/sanitizers/asan-runtime?view=msvc-170#alignment-requirements-for-addresssanitizer-poisoning).
|
||||
|
||||
It should be possible to work around this by manually rounding buffer lengths up to the nearest multiple of 8 in the poisoning function, although it's remotely possible that this will cause other problems. Valgrind does not appear to have this limitation (unless Valgrind is simply more poorly documented). However, running tests under Valgrind causes a much greater slowdown compared with ASan. As a result, it would be beneficial to implement support for both Valgrind and ASan, to give the extra flexibility to choose either performance or accuracy as required. This should be simple as both have very similar memory poisoning interfaces.
|
||||
|
||||
**Design decision: Implement memory poisoning tests with both Valgrind's memcheck and ASan manual poisoning.**
|
||||
|
||||
##### Validation with new tests
|
||||
|
||||
Validation with newly created tests would be simpler to implement than using existing tests, since the tests can be written to take into account memory poisoning. It is also possible to build such a testsuite using existing tests as a starting point - `mbedtls_test_psa_exercise_key` is a test helper that already exercises many PSA operations on a key. This would need to be extended to cover operations without keys (e.g. hashes) and multipart operations, but it provides a good base from which to build all of the required testing.
|
||||
|
||||
Additionally, we can ensure that all functions are exercised by automatically generating test data files.
|
||||
|
||||
##### Validation with existing tests
|
||||
|
||||
An alternative approach would be to integrate memory poisoning validation with existing tests. This has two main advantages:
|
||||
|
||||
* All of the tests are written already, potentially saving development time.
|
||||
* The code coverage of these tests is greater than would be achievable writing new tests from scratch. In practice this advantage is small as buffer copying will take place in the dispatch layer. The tests are therefore independent of the values of parameters passed to the driver, so extra coverage in these parameters does not gain anything.
|
||||
|
||||
It may be possible to transparently implement memory poisoning so that existing tests can work without modification. This would be achieved by replacing the implementation of `malloc()` with one that allocates poisoned buffers. However, there are some difficulties with this:
|
||||
|
||||
* Not all buffers allocated by tests are used as inputs and outputs to PSA functions being tested.
|
||||
* Those buffers that are inputs to a PSA function need to be unpoisoned right up until the function is called, so that they can be filled with input data.
|
||||
* Those buffers that are outputs from a PSA function need to be unpoisoned straight after the function returns, so that they can be read to check the output is correct.
|
||||
|
||||
These issues may be solved by creating some kind of test wrapper around every PSA function call that poisons the memory. However, it is unclear how straightforward this will be in practice. If this is simple to achieve, the extra coverage and time saved on new tests will be a benefit. If not, writing new tests is the best strategy.
|
||||
|
||||
**Design decision: Add memory poisoning transparently to existing tests.**
|
||||
|
||||
#### Discussion of copying validation
|
||||
|
||||
Of all discussed approaches, validation by memory poisoning appears as the best. This is because it:
|
||||
|
||||
* Does not require complex linking against different versions of `malloc()` (as is the case with the memory pool approach).
|
||||
* Allows automated testing (unlike the review approach).
|
||||
|
||||
**Design decision: Use a memory poisoning approach to validate copying.**
|
||||
|
||||
### Shared memory protection requirements
|
||||
|
||||
TODO: write document and reference it here.
|
||||
|
||||
### Validation of careful access for built-in drivers
|
||||
|
||||
For PSA functions whose inputs and outputs are not copied, it is important that we validate that the builtin drivers are correctly accessing their inputs and outputs so as not to cause a security issue. Specifically, we must check that each memory location in a shared buffer is not accessed more than once by a driver function. In this section we examine various possible methods for performing this validation.
|
||||
|
||||
Note: We are focusing on read-read inconsistencies for now, as most of the cases where we aren't copying are inputs.
|
||||
|
||||
#### Review
|
||||
|
||||
As with validation of copying, the simplest method of validation we can implement is careful code review. This is the least desirable method of validation for several reasons:
|
||||
|
||||
1. It is tedious for the reviewers.
|
||||
2. Reviewers are prone to make mistakes (especially when performing tedious tasks).
|
||||
3. It requires engineering time linear in the number of PSA functions to be tested.
|
||||
4. It cannot assure the quality of third-party drivers, whereas automated tests can be ported to any driver implementation in principle.
|
||||
|
||||
If all other approaches turn out to be prohibitively difficult, code review exists as a fallback option. However, it should be understood that this is far from ideal.
|
||||
|
||||
#### Tests using `mprotect()`
|
||||
|
||||
Checking that a memory location is not accessed more than once may be achieved by using `mprotect()` on a Linux system to cause a segmentation fault whenever a memory access happens. Tests based on this approach are sketched below.
|
||||
|
||||
##### Linux mprotect+ptrace
|
||||
|
||||
Idea: call `mmap` to allocate memory for arguments and `mprotect` to deny or reenable access. Use `ptrace` from a parent process to react to SIGSEGV from a denied access. On SIGSEGV happening in the faulting region:
|
||||
|
||||
1. Use `ptrace` to execute a `mprotect` system call in the child to enable access. TODO: How? `ptrace` can modify registers and memory in the child, which includes changing parameters of a syscall that's about to be executed, but not directly cause the child process to execute a syscall that it wasn't about to execute.
|
||||
2. Use `ptrace` with `PTRACE_SINGLESTEP` to re-execute the failed load/store instrution.
|
||||
3. Use `ptrace` to execute a `mprotect` system call in the child to disable access.
|
||||
4. Use `PTRACE_CONT` to resume the child execution.
|
||||
|
||||
Record the addresses that are accessed. Mark the test as failed if the same address is read twice.
|
||||
|
||||
##### Debugger + mprotect
|
||||
|
||||
Idea: call `mmap` to allocate memory for arguments and `mprotect` to deny or reenable access. Use a debugger to handle SIGSEGV (Gdb: set signal catchpoint). If the segfault was due to accessing the protected region:
|
||||
|
||||
1. Execute `mprotect` to allow access.
|
||||
2. Single-step the load/store instruction.
|
||||
3. Execute `mprotect` to disable access.
|
||||
4. Continue execution.
|
||||
|
||||
Record the addresses that are accessed. Mark the test as failed if the same address is read twice. This part might be hard to do in the gdb language, so we may want to just log the addresses and then use a separate program to analyze the logs, or do the gdb tasks from Python.
|
||||
|
||||
#### Instrumentation (Valgrind)
|
||||
|
||||
An alternative approach is to use a dynamic instrumentation tool (the most obvious being Valgrind) to trace memory accesses and check that each of the important memory addresses is accessed no more than once.
|
||||
|
||||
Valgrind has no tool specifically that checks the property that we are looking for. However, it is possible to generate a memory trace with Valgrind using the following:
|
||||
|
||||
```
|
||||
valgrind --tool=lackey --trace-mem=yes --log-file=logfile ./myprogram
|
||||
```
|
||||
This will execute `myprogram` and dump a record of every memory access to `logfile`, with its address and data width. If `myprogram` is a test that does the following:
|
||||
|
||||
1. Set up input and output buffers for a PSA function call.
|
||||
2. Leak the start and end address of each buffer via `print()`.
|
||||
3. Write data into the input buffer exactly once.
|
||||
4. Call the PSA function.
|
||||
5. Read data from the output buffer exactly once.
|
||||
|
||||
Then it should be possible to parse the output from the program and from Valgrind and check that each location was accessed exactly twice: once by the program's setup and once by the PSA function.
|
||||
|
||||
#### Fixed Virtual Platform testing
|
||||
|
||||
It may be possible to measure double accesses by running tests on a Fixed Virtual Platform such as Corstone 310 ecosystem FVP, available [here](https://developer.arm.com/downloads/-/arm-ecosystem-fvps). There exists a pre-packaged example program for the Corstone 310 FVP available as part of the Open IoT SDK [here](https://git.gitlab.arm.com/iot/open-iot-sdk/examples/sdk-examples/-/tree/main/examples/mbedtls/cmsis-rtx/corstone-310) that could provide a starting point for a set of tests.
|
||||
|
||||
Running on an FVP allows two approaches to careful-access testing:
|
||||
|
||||
* Convenient scripted use of a debugger with [Iris](https://developer.arm.com/documentation/101196/latest/). This allows memory watchpoints to be set, perhaps more flexibly than with GDB.
|
||||
* Tracing of all memory accesses with [Tarmac Trace](https://developer.arm.com/documentation/100964/1123/Plug-ins-for-Fast-Models/TarmacTrace). To validate the single-access properties, the [processor memory access trace source](https://developer.arm.com/documentation/100964/1123/Plug-ins-for-Fast-Models/TarmacTrace/Processor-memory-access-trace) can be used to output all memory accesses happening on the FVP. This output can then be easily parsed and processed to ensure that the input and output buffers are accessed only once. The addresses of buffers can either be leaked by the program through printing to the serial port or set to fixed values in the FVP's linker script.
|
||||
|
||||
#### Discussion of careful-access validation
|
||||
|
||||
The best approach for validating the correctness of memory accesses is an open question that requires further investigation. To answer this question, each of the test strategies discussed above must be prototyped as follows:
|
||||
|
||||
1. Take 1-2 days to create a basic prototype of a test that uses the approach.
|
||||
2. Document the prototype - write a short guide that can be followed to arrive at the same prototype.
|
||||
3. Evaluate the prototype according to its usefulness. The criteria of evaluation should include:
|
||||
* Ease of implementation - Was the prototype simple to implement? Having implemented it, is it simple to extend it to do all of the required testing?
|
||||
* Flexibility - Could the prototype be extended to cover other careful-access testing that may be needed in future?
|
||||
* Performance - Does the test method perform well? Will it cause significant slowdown to CI jobs?
|
||||
* Ease of reproduction - Does the prototype require a particular platform or tool to be set up? How easy would it be for an external user to run the prototype?
|
||||
* Comprehensibility - Accounting for the lower code quality of a prototype, would developers unfamiliar with the tests based on the prototype be able to understand them easily?
|
||||
* Portability - How well can this approach be ported to multiple platforms? This would allow us to ensure that there are no double-accesses due to a bug that only affects a specific target.
|
||||
|
||||
Once each prototype is complete, choose the best approach to implement the careful-access testing. Implement tests using this approach for each of the PSA interfaces that require careful-access testing:
|
||||
|
||||
* Hash
|
||||
* MAC
|
||||
* AEAD (additional data only)
|
||||
* Key derivation
|
||||
* Asymmetric signature (input only)
|
||||
|
||||
##### New vs existing tests
|
||||
|
||||
Most of the test methods discussed above need extra setup. Some require leaking of buffer bounds, predictable memory access patterns or allocation of special buffers. FVP testing even requires the tests to be run on a non-host target.
|
||||
|
||||
With this complexity in mind it does not seem feasible to run careful-access tests using existing testsuites. Instead, new tests should be written that exercise the drivers in the required way. Fortunately, the only interfaces that need testing are hash, MAC, AEAD (testing over AD only), Key derivation and Asymmetric signature, which limits the number of new tests that must be written.
|
||||
|
||||
#### Validation of validation for careful-access
|
||||
|
||||
In order to ensure that the careful-access validation works, it is necessary to write tests to check that we can correctly detect careful-access violations when they occur. To do this, write a test function that:
|
||||
|
||||
* Reads its input multiple times at the same location.
|
||||
* Writes to its output multiple times at the same location.
|
||||
|
||||
Then, write a careful-access test for this function and ensure that it fails.
|
||||
|
||||
## Analysis of argument protection in built-in drivers
|
||||
|
||||
TODO: analyze the built-in implementations of mechanisms for which there is a requirement on drivers. By code inspection, how satisfied are we that they meet the requirement?
|
||||
|
||||
## Copy bypass
|
||||
|
||||
For efficiency, we are likely to want mechanisms to bypass the copy and process buffers directly in builds that are not affected by shared memory considerations.
|
||||
|
||||
Expand this section to document any mechanisms that bypass the copy.
|
||||
|
||||
Make sure that such mechanisms preserve the guarantees when buffers overlap.
|
||||
|
||||
## Detailed design
|
||||
|
||||
### Implementation by module
|
||||
|
||||
Module | Input protection strategy | Output protection strategy | Notes
|
||||
---|---|---|---
|
||||
Hash and MAC | Careful access | Careful access | Low risk of multiple-access as the input and output are raw unformatted data.
|
||||
Cipher | Copying | Copying |
|
||||
AEAD | Copying (careful access for additional data) | Copying |
|
||||
Key derivation | Careful access | Careful access |
|
||||
Asymmetric signature | Careful access | Copying | Inputs to signatures are passed to a hash. This will no longer hold once PureEdDSA support is implemented.
|
||||
Asymmetric encryption | Copying | Copying |
|
||||
Key agreement | Copying | Copying |
|
||||
PAKE | Copying | Copying |
|
||||
Key import / export | Copying | Copying | Keys may be imported and exported in DER format, which is a structured format and therefore susceptible to read-read inconsistencies and potentially write-read inconsistencies.
|
||||
|
||||
### Copying functions
|
||||
|
||||
As discussed in [Copying code](#copying-code), it is simpler to use a single unified API for copying. Therefore, we create the following functions:
|
||||
|
||||
* `psa_crypto_copy_input(const uint8_t *input, size_t input_length, uint8_t *input_copy, size_t input_copy_length)`
|
||||
* `psa_crypto_copy_output(const uint8_t *output_copy, size_t output_copy_length, uint8_t *output, size_t output_length)`
|
||||
|
||||
These seem to be a repeat of the same function, however it is useful to retain two separate functions for input and output parameters so that we can use different test hooks in each when using memory poisoning for tests.
|
||||
|
||||
Given that the majority of functions will be allocating memory on the heap to copy, it is helpful to build convenience functions that allocate the memory as well.
|
||||
|
||||
In order to keep track of allocated copies on the heap, we can create new structs:
|
||||
|
||||
```c
|
||||
typedef struct psa_crypto_local_input_s {
|
||||
uint8_t *buffer;
|
||||
size_t length;
|
||||
} psa_crypto_local_input_t;
|
||||
|
||||
typedef struct psa_crypto_local_output_s {
|
||||
uint8_t *original;
|
||||
uint8_t *buffer;
|
||||
size_t length;
|
||||
} psa_crypto_local_output_t;
|
||||
```
|
||||
|
||||
These may be used to keep track of input and output copies' state, and ensure that their length is always stored with them. In the case of output copies, we keep a pointer to the original buffer so that it is easy to perform a writeback to the original once we have finished outputting.
|
||||
|
||||
With these structs we may create 2 pairs of functions, one pair for input copies:
|
||||
|
||||
```c
|
||||
psa_status_t psa_crypto_local_input_alloc(const uint8_t *input, size_t input_len,
|
||||
psa_crypto_local_input_t *local_input);
|
||||
|
||||
void psa_crypto_local_input_free(psa_crypto_local_input_t *local_input);
|
||||
```
|
||||
|
||||
* `psa_crypto_local_input_alloc()` calls `calloc()` to allocate a new buffer of length `input_len`, copies the contents across from `input`. It then stores `input_len` and the pointer to the copy in the struct `local_input`.
|
||||
* `psa_crypto_local_input_free()` calls `free()` on the local input that is referred to by `local_input` and sets the pointer in the struct to `NULL`.
|
||||
|
||||
We also create a pair of functions for output copies:
|
||||
|
||||
```c
|
||||
psa_status_t psa_crypto_local_output_alloc(uint8_t *output, size_t output_len,
|
||||
psa_crypto_local_output_t *local_output);
|
||||
|
||||
psa_status_t psa_crypto_local_output_free(psa_crypto_local_output_t *local_output);
|
||||
```
|
||||
|
||||
* `psa_crypto_local_output_alloc()` calls `calloc()` to allocate a new buffer of length `output_len` and stores `output_len` and the pointer to the buffer in the struct `local_output`. It also stores a pointer to `output` in `local_output->original`.
|
||||
* `psa_crypto_local_output_free()` copies the contents of the output buffer `local_output->buffer` into the buffer `local_output->original`, calls `free()` on `local_output->buffer` and sets it to `NULL`.
|
||||
|
||||
Some PSA functions may not use these convenience functions as they may have local optimizations that reduce memory usage. For example, ciphers may be able to use a single intermediate buffer for both input and output.
|
||||
|
||||
In order to abstract the management of the copy state further, to make it simpler to add, we create the following 6 convenience macros:
|
||||
|
||||
For inputs:
|
||||
|
||||
* `LOCAL_INPUT_DECLARE(input, input_copy_name)`, which declares and initializes a `psa_crypto_local_input_t` and a pointer with the name `input_copy_name` in the current scope.
|
||||
* `LOCAL_INPUT_ALLOC(input, input_size, input_copy)`, which tries to allocate an input using `psa_crypto_local_input_alloc()`. On failure, it sets an error code and jumps to an exit label. On success, it sets `input_copy` to point to the copy of the buffer.
|
||||
* `LOCAL_INPUT_FREE(input, input_copy)`, which frees the input copy using `psa_crypto_local_input_free()` and sets `input_copy` to `NULL`.
|
||||
|
||||
For outputs:
|
||||
|
||||
* `LOCAL_OUTPUT_DECLARE(output, output_copy_name)`, analogous to `LOCAL_INPUT_DECLARE()` for `psa_crypto_local_output_t`.
|
||||
* `LOCAL_OUTPUT_ALLOC(output, output_size, output_copy)`, analogous to `LOCAL_INPUT_ALLOC()` for outputs, calling `psa_crypto_local_output_alloc()`.
|
||||
* `LOCAL_OUTPUT_FREE(output, output_copy)`, analogous to `LOCAL_INPUT_FREE()` for outputs. If the `psa_crypto_local_output_t` is in an invalid state (the copy pointer is valid, but the original pointer is `NULL`) this macro sets an error status.
|
||||
|
||||
These macros allow PSA functions to have copying added while keeping the code mostly unmodified. Consider a hypothetical PSA function:
|
||||
|
||||
```c
|
||||
psa_status_t psa_foo(const uint8_t *input, size_t input_length,
|
||||
uint8_t *output, size_t output_size, size_t *output_length)
|
||||
{
|
||||
/* Do some operation on input and output */
|
||||
}
|
||||
```
|
||||
|
||||
By changing the name of the input and output parameters, we can retain the original variable name as the name of the local copy while using a new name (e.g. with the suffix `_external`) for the original buffer. This allows copying to be added near-seamlessly as follows:
|
||||
|
||||
```c
|
||||
psa_status_t psa_foo(const uint8_t *input_external, size_t input_length,
|
||||
uint8_t *output_external, size_t output_size, size_t *output_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
LOCAL_INPUT_DECLARE(input_external, input);
|
||||
LOCAL_OUTPUT_DECLARE(output_external, output);
|
||||
|
||||
LOCAL_INPUT_ALLOC(input_external, input);
|
||||
LOCAL_OUTPUT_ALLOC(output_external, output);
|
||||
|
||||
/* Do some operation on input and output */
|
||||
|
||||
exit:
|
||||
LOCAL_INPUT_FREE(input_external, input);
|
||||
LOCAL_OUTPUT_FREE(output_external, output);
|
||||
}
|
||||
```
|
||||
|
||||
A second advantage of using macros for the copying (other than simple convenience) is that it allows copying to be easily disabled by defining alternate macros that function as no-ops. Since buffer copying is specific to systems where shared memory is passed to PSA functions, it is useful to be able to disable it where it is not needed, to save code size.
|
||||
|
||||
To this end, the macros above are defined conditionally on a new config option, `MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS`, which may be set whenever PSA functions are assumed to have exclusive access to their input and output buffers. When `MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS` is set, the macros do not perform copying.
|
||||
|
||||
### Implementation of copying validation
|
||||
|
||||
As discussed in the [design exploration of copying validation](#validation-of-copying), the best strategy for validation of copies appears to be validation by memory poisoning, implemented using Valgrind and ASan.
|
||||
|
||||
To perform memory poisoning, we must implement the functions alluded to in [Validation of copying by memory poisoning](#validation-of-copying-by-memory-poisoning):
|
||||
```c
|
||||
void mbedtls_test_memory_poison(const unsigned char *ptr, size_t size);
|
||||
void mbedtls_test_memory_unpoison(const unsigned char *ptr, size_t size);
|
||||
```
|
||||
This should poison or unpoison the given buffer, respectively.
|
||||
|
||||
* `mbedtls_test_memory_poison()` is equivalent to calling `VALGRIND_MAKE_MEM_NOACCESS(ptr, size)` or `ASAN_POISON_MEMORY_REGION(ptr, size)`.
|
||||
* `mbedtls_test_memory_unpoison()` is equivalent to calling `VALGRIND_MAKE_MEM_DEFINED(ptr, size)` or `ASAN_UNPOISON_MEMORY_REGION(ptr, size)`.
|
||||
|
||||
The PSA copying function must then have test hooks implemented as outlined in [Validation of copying by memory poisoning](#validation-of-copying-by-memory-poisoning).
|
||||
|
||||
As discussed in [the design exploration](#validation-with-existing-tests), the preferred approach for implementing copy-testing is to implement it transparently using existing tests. This is specified in more detail below.
|
||||
|
||||
#### Transparent allocation-based memory poisoning
|
||||
|
||||
In order to implement transparent memory poisoning we require a wrapper around all PSA function calls that poisons any input and output buffers.
|
||||
|
||||
The easiest way to do this is to create wrapper functions that poison the memory and then `#define` PSA function names to be wrapped versions of themselves. For example, to replace `psa_aead_update()`:
|
||||
```c
|
||||
psa_status_t mem_poison_psa_aead_update(psa_aead_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
mbedtls_test_memory_poison(input, input_length);
|
||||
mbedtls_test_memory_poison(output, output_size);
|
||||
psa_status_t status = psa_aead_update(operation, input, input_length,
|
||||
output, output_size, output_length);
|
||||
mbedtls_test_memory_unpoison(input, input_length);
|
||||
mbedtls_test_memory_unpoison(output, output_size);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#define psa_aead_update(...) mem_poison_psa_aead_update(__VA_ARGS__)
|
||||
```
|
||||
|
||||
There now exists a more generic mechanism for making exactly this kind of transformation - the PSA test wrappers, which exist in the files `tests/include/test/psa_test_wrappers.h` and `tests/src/psa_test_wrappers.c`. These are wrappers around all PSA functions that allow testing code to be inserted at the start and end of a PSA function call.
|
||||
|
||||
The test wrappers are generated by a script, although they are not automatically generated as part of the build process. Instead, they are checked into source control and must be manually updated when functions change by running `framework/scripts/generate_psa_wrappers.py`.
|
||||
|
||||
Poisoning code is added to these test wrappers where relevant in order to pre-poison and post-unpoison the parameters to the functions.
|
||||
|
||||
#### Configuration of poisoning tests
|
||||
|
||||
Since the memory poisoning tests will require the use of interfaces specific to the sanitizers used to poison memory, they must only be enabled when we are building with ASan or Valgrind. For now, we can auto-detect ASan at compile-time and set an option: `MBEDTLS_TEST_MEMORY_CAN_POISON`. When this option is enabled, we build with memory-poisoning support. This enables transparent testing with ASan without needing any extra configuration options.
|
||||
|
||||
Auto-detection and memory-poisoning with Valgrind is left for future work.
|
||||
|
||||
#### Validation of validation for copying
|
||||
|
||||
To make sure that we can correctly detect functions that access their input/output buffers rather than the copies, it would be best to write a test function that misbehaves and test it with memory poisoning. Specifically, the function should:
|
||||
|
||||
* Read its input buffer and after calling the input-buffer-copying function to create a local copy of its input.
|
||||
* Write to its output buffer before and after calling the output-buffer-copying function to copy-back its output.
|
||||
|
||||
Then, we could write a test that uses this function with memory poisoning and ensure that it fails. Since we are expecting a failure due to memory-poisoning, we would run this test separately from the rest of the memory-poisoning testing.
|
||||
|
||||
This testing is implemented in `programs/test/metatest.c`, which is a program designed to check that test failures happen correctly. It may be run via the script `tests/scripts/run-metatests.sh`.
|
||||
@@ -1,536 +0,0 @@
|
||||
# PSA storage resilience design
|
||||
|
||||
## Introduction
|
||||
|
||||
The PSA crypto subsystem includes a persistent key store. It is possible to create a persistent key and read it back later. This must work even if the underlying storage exhibits non-nominal behavior. In this document, _resilience_ means correct behavior of the key store even under if the underlying platform behaves in a non-nominal, but still partially controlled way.
|
||||
|
||||
At this point, we are only concerned about one specific form of resilience: to a system crash or power loss. That is, we assume that the underlying platform behaves nominally, except that occasionally it may restart. In the field, this can happen due to a sudden loss of power.
|
||||
|
||||
This document explores the problem space, defines a library design and a test design.
|
||||
|
||||
## Resilience goals for API functions
|
||||
|
||||
**Goal: PSA Crypto API functions are atomic and committing.**
|
||||
|
||||
_Atomic_ means that when an application calls an API function, as far as the application is concerned, at any given point in time, the system is either in a state where the function has not started yet, or in a state where the function has returned. The application never needs to worry about an intermediate state.
|
||||
|
||||
_Committing_ means that when a function returns, the data has been written to the persistent storage. As a consequence, if the system restarts during a sequence of storage modifications $M_1, M_2, \ldots, M_n$, we know that when the system restarts, a prefix of the sequence has been performed. For example, there will never be a situation where $M_2$ has been performed but not $M_1$.
|
||||
|
||||
The committing property is important not only for sequences of operations, but also when reporting the result of an operation to an external system. For example, if a key creation function in the PSA Crypto API reports to the application that a key has been created, and the application reports to a server that the key has been created, it is guaranteed that the key exists even if the system restarts.
|
||||
|
||||
## Assumptions on the underlying file storage
|
||||
|
||||
PSA relies on a PSA ITS (Internal Trusted Storage) interface, which exposes a simple API. There are two functions to modify files:
|
||||
|
||||
* `set()` writes a whole file (either creating it, or replacing the previous content).
|
||||
* `remove()` removes a file (returning a specific error code if the file does not exist).
|
||||
|
||||
**Assumption: the underlying ITS functions are atomic and committing.**
|
||||
|
||||
Since the underlying functions are atomic, the content of a file is always a version that was previously passed to `set()`. We do not try to handle the case where a file might be partially written.
|
||||
|
||||
## Overview of API functions
|
||||
|
||||
For a transparent key, all key management operations (creation or destruction) on persistent keys rely on a single call to the underlying storage (`set()` for a key creation, `remove()` for a key destruction). This also holds for an opaque key stored in a secure element that does not have its own key store: in this case, the core stores a wrapped (i.e. encrypted) copy of the key material, but this does not impact how the core interacts with the storage. Other API functions do not modify the storage.
|
||||
|
||||
The following case requires extra work related to resilience:
|
||||
|
||||
* [Key management for stateful secure element keys](#designing-key-management-for-secure-element-keys).
|
||||
|
||||
As a consequence, apart from the listed cases, the API calls inherit directly from the [resilience properties of the underyling storage](#assumptions-on-the-underlying-file-storage). We do not need to take any special precautions in the library design, and we do not need to perform any testing of resilience for transparent keys.
|
||||
|
||||
(This section was last updated for Mbed TLS 3.4.0 implementing PSA Crypto API 1.1.)
|
||||
|
||||
## Designing key management for secure element keys
|
||||
|
||||
In this section, we use “(stateful) secure element key” to mean a key stored in a stateful secure element, i.e. a secure element that stores keys. This excludes keys in a stateleess secure element for which the core stores a wrapped copy of the key. We study the problem of how key management in stateful secure elements interacts with storage and explore the design space.
|
||||
|
||||
### Assumptions on stateful secure elements
|
||||
|
||||
**Assumption: driver calls for key management in stateful secure elements are atomic and committing.**
|
||||
|
||||
(For stateless secure elements, this assumption is vacuously true.)
|
||||
|
||||
### Dual management of keys: the problem
|
||||
|
||||
For a secure element key, key management requires a commitment on both sites. For example, consider a successful key creation operation:
|
||||
|
||||
1. The core sends a request to the secure element to create a key.
|
||||
2. The secure element modifies its key store to create the key.
|
||||
3. The secure element reports to the core that the key has been created.
|
||||
4. The core reports to the application that the key has been created.
|
||||
|
||||
If the core loses power between steps 1 and 2, the key does not exist yet. This is fine from an application's perspective since the core has not committed to the key's existence, but the core needs to take care not to leave resources in storage that are related to the non-existent key. If the core loses power between steps 2 and 3, the key exists in the secure element. From an application's perspective, the core may either report that the key exists or that it does not exist, but in the latter case, the core needs to free the key in the secure element, to avoid leaving behind inaccessible resources.
|
||||
|
||||
As a consequence, the content of the storage cannot remain the same between the end of step 1 and the end of step 3, since the core must behave differently depending on whether step 2 has taken place.
|
||||
|
||||
Accomplishing a transaction across system boundaries is a well-known problem in database management, with a well-known solution: two-phase commit.
|
||||
|
||||
### Overview of two-phase commit with stateful secure elements
|
||||
|
||||
With a key in a stateful secure element, a successful creation process goes as follows (see [“Key management in a secure element with storage” in the driver interface specification](../../proposed/psa-driver-interface.html#key-management-in-a-secure-element-with-storage)):
|
||||
|
||||
1. The core calls the driver's `"allocate_key"` entry point.
|
||||
2. The driver allocates a unique identifier _D_ for the key. This is unrelated to the key identifier _A_ used by the application interface. This step must not modify the state of the secure element.
|
||||
3. The core updates the storage to indicate that key identifier _A_ has the identifier _D_ in the driver, and that _A_ is in a half-created state.
|
||||
4. The core calls the driver's key creation entry point, passing it the driver's chosen identifier _D_.
|
||||
5. The driver creates the key in the secure element. When this happens, it concludes the voting phase of the two-phase commit: effectively, the secure element decides to commit. (It is however possible to revert this commitment by giving the secure element the order to destroy the key.)
|
||||
6. The core updates the storage to indicate that _A_ is now in a fully created state. This concludes the commit phase of the two-phase commit.
|
||||
|
||||
If there is a loss of power:
|
||||
|
||||
* Before step 3: the system state has not changed at all. As far as the world is concerned, the key creation attempt never happened.
|
||||
* Between step 3 and step 6: upon restart, the core needs to find out whether the secure element completed step 5 or not, and reconcile the state of the storage with the state of the secure element.
|
||||
* After step 6: the key has been created successfully.
|
||||
|
||||
Key destruction goes as follows:
|
||||
|
||||
1. The core updates the storage indicating that the key is being destroyed.
|
||||
2. The core calls the driver's `"destroy_key"` entry point.
|
||||
3. The secure element destroys the key.
|
||||
4. The core updates the storage to indicate that the key has been destroyed.
|
||||
|
||||
If there is a loss of power:
|
||||
|
||||
* Before step 1: the system state has not changed at all. As far as the world is concerned, the key destruction attempt never happened.
|
||||
* Between step 1 and step 4: upon restart, the core needs to find out whether the secure element completed step 3 or not, and reconcile the state of the storage with the state of the secure element.
|
||||
* After step 4: the key has been destroyed successfully.
|
||||
|
||||
In both cases, upon restart, the core needs to perform a transaction recovery. When a power loss happens, the core decides whether to commit or abort the transaction.
|
||||
|
||||
Note that the analysis in this section assumes that the driver does not update its persistent state during a key management operation (or at least not in a way that is influences the key management process — for example, it might renew an authorization token).
|
||||
|
||||
### Optimization considerations for transactions
|
||||
|
||||
We assume that power failures are rare. Therefore we will primarily optimize for the normal case. Transaction recovery needs to be practical, but does not have to be fully optimized.
|
||||
|
||||
The main quantity we will optimize for is the number of storage updates in the nominal case. This is good for performance because storage writes are likely to dominate the runtime in some hardware configurations where storage writes are slow and communication with the secure element is fast, for key management operations that require a small amount of computation. In addition, minimizing the number of storage updates is good for the longevity of flash media.
|
||||
|
||||
#### Information available during recovery
|
||||
|
||||
The PSA ITS API does not support enumerating files in storage: an ITS call can only access one file identifier. Therefore transaction recovery cannot be done by traversing files whose name is or encodes the key identifier. It must start by traversing a small number of files whose names are independent of the key identifiers involved.
|
||||
|
||||
#### Minimum effort for a transaction
|
||||
|
||||
Per the [assumptions on the underlying file storage](#assumptions-on-the-underlying-file-storage), each atomic operation in the internal storage concerns a single file: either removing it, or setting its content. Furthermore there is no way to enumerate the files in storage.
|
||||
|
||||
A key creation function must transform the internal storage from a state where file `id` does not exist, to a state where file `id` exists and has its desired final content (containing the key attributes and the driver's key identifier). The situation is similar with key destruction, except that the initial and final states are exchanged. Neither the initial state nor the final state reference `id` otherwise.
|
||||
|
||||
For a key that is not in a stateful element, the transaction consists of a single write operation. As discussed previously, this is not possible with a stateful secure element because the state of the internal storage needs to change both before and after the state change in the secure element. No other single-write algorithm works.
|
||||
|
||||
If there is a power failure around the time of changing the state of the secure element, there must be information in the internal storage that indicates that key `id` has a transaction in progress. The file `id` cannot be used for this purpose because there is no way to enumerate all keys (and even if there was, it would not be practical). Therefore the transaction will need to modify some other file `t` with a fixed name (a name that doesn't depend on the key). Since the final system state should be identical to the initial state except for the file `id`, the minimum number of storage operations for a transaction is 3:
|
||||
|
||||
* Write (create or update) a file `t` referencing `id`.
|
||||
* Write the final state of `id`.
|
||||
* Restore `t` to its initial state.
|
||||
|
||||
The strategies discussed in the [overview above](#overview-of-two-phase-commit-with-stateful-secure-elements) follow this pattern, with `t` being the file containing the transaction list that the recovery consults. We have just proved that this pattern is optimal.
|
||||
|
||||
Note that this pattern requires the state of `id` to be modified only once. In particular, if a key management involves writing an intermediate state for `id` before modifying the secure element state and writing a different state after that, this will require a total of 4 updates to internal storage. Since we want to minimize the number of storage updates, we will not explore designs that involved updating `id` twice or more.
|
||||
|
||||
### Recovery strategies
|
||||
|
||||
When the core starts, it needs to know about transaction(s) that need to be resumed. This information will be stored in a persistent “transaction list”, with one entry per key. In this section, we explore recovery strategies, and we determine what the transaction list needs to contain as well as when it needs to be updated. Other sections will explore the format of the transaction list, as well as how many keys it needs to contain.
|
||||
|
||||
#### Exploring the recovery decision tree
|
||||
|
||||
There are four cases for recovery when a transaction is in progress. In each case, the core can either decide to commit the transaction (which may require replaying the interrupted part) or abort it (which may require a rewind in the secure element). It may call the secure element driver's `"get_key_attributes"` entry point to find out whether the key is present.
|
||||
|
||||
* Key creation, key not present in the secure element:
|
||||
* Committing means replaying the driver call in the key creation. This requires all the input, for example the data to import. This seems impractical in general. Also, the second driver call require a new call to `"allocate_key"` which will in general changing the key's driver identifier, which complicates state management in the core. Given the likely complexity, we exclude this strategy.
|
||||
* Aborting means removing any trace of the key creation.
|
||||
* Key creation, key present in the secure element:
|
||||
* Committing means finishing the update of the core's persistent state, as would have been done if the transaction had not been interrupted.
|
||||
* Aborting means destroying the key in the secure element and removing any local storage used for that key.
|
||||
* Key destruction, key not present in the secure element:
|
||||
* Committing means finishing the update of the core's persistent state, as would have been done if the transaction had not been interrupted, by removing any remaining local storage used for that key.
|
||||
* Aborting would mean re-creating the key in the secure element, which is impossible in general since the key material is no longer present.
|
||||
* Key destruction, key present in the secure element:
|
||||
* Committing means finishing the update of the core's persistent state, as would have been done if the transaction had not been interrupted, by removing any remaining local storage used for that key and destroying the key in the secure element.
|
||||
* Aborting means keeping the key. This requires no action on the secure element, and is only practical locally if the local storage is intact.
|
||||
|
||||
#### Comparing recovery strategies
|
||||
|
||||
From the analysis above, assuming that all keys are treated in the same way, there are 4 possible strategies.
|
||||
|
||||
* [Always follow the state of the secure element](#exploring-the-follow-the-secure-element-strategy). This requires the secure element driver to have a `"get_key_attributes"` entry point. Recovery means resuming the operation where it left off. For key creation, this means that the key metadata needs to be saved before calling the secure element's key creation entry point.
|
||||
* Minimize the information processing: [always destroy the key](#exploring-the-always-destroy-strategy), i.e. abort all key creations and commit all key destructions. This does not require querying the state of the secure element. This does not require any special precautions to preserve information about the key during the transaction. It simplifies recovery in that the recovery process might not even need to know whether it's recovering a key creation or a key destruction.
|
||||
* Follow the state of the secure element for key creation, but always go ahead with key destruction. This requires the secure element driver to have a `"get_key_attributes"` entry point. Compared to always following the state of the secure element, this has the advantage of maximizing the chance that a command to destroy key material is effective. Compared to always destroying the key, this has a performance advantage if a key creation is interrupted. These do not seem like decisive advantages, so we will not consider this strategy further.
|
||||
* Always abort key creation, but follow the state of the secure element for key destruction. I can't think of a good reason to choose this strategy.
|
||||
|
||||
Requiring the driver to have a `"get_key_attributes"` entry point is potentially problematic because some secure elements don't have room to store key attributes: a key slot always exists, and it's up to the user to remember what, if anything, they put in it. The driver has to remember anyway, so that it can find a free slot when creating a key. But with a recovery strategy that doesn't involve a `"get_key_attributes"` entry point, the driver design is easier: the driver doesn't need to protect the information about slots in use against a power failure, the core takes care of that.
|
||||
|
||||
#### Exploring the follow-the-secure-element strategy
|
||||
|
||||
Each entry in the transaction list contains the API key identifier, the key lifetime (or at least the location), the driver key identifier (not constant-size), and an indication of whether the key is being created or destroyed.
|
||||
|
||||
For key creation, we have all the information to store in the key file once the `"allocate_key"` call returns. We must store all the information that will go in the key file before calling the driver's key creation entry point. Therefore the normal sequence of operations is:
|
||||
|
||||
1. Call the driver's `"allocate_key"` entry point.
|
||||
2. Add the key to the transaction list, indicating that it is being created.
|
||||
3. Write the key file.
|
||||
4. Call the driver's key creation entry point.
|
||||
5. Remove the key from the transaction list.
|
||||
|
||||
During recovery, for each key in the transaction list that was being created:
|
||||
|
||||
* If the key exists in the secure element, just remove it from the transaction list.
|
||||
* If the key does not exist in the secure element, first remove the key file if it is present, then remove the key from the transaction list.
|
||||
|
||||
For key destruction, we need to preserve the key file until after the key has been destroyed. Therefore the normal sequence of operations is:
|
||||
|
||||
1. Add the key to the transaction list, indicating that it is being destroyed.
|
||||
2. Call the driver's `"destroy_key"` entry point.
|
||||
3. Remove the key file.
|
||||
4. Remove the key from the transaction list.
|
||||
|
||||
During recovery, for each key in the transaction list that was being created:
|
||||
|
||||
* If the key exists in the secure element, call the driver's `"destroy_key"` entry point, then remove the key file, and finally remote the key from the transaction lits.
|
||||
* If the key does not exist in the secure element, remove the key file if it is still present, then remove the key from the transaction list.
|
||||
|
||||
#### Exploring the always-destroy strategy
|
||||
|
||||
Each entry in the transaction list contains the API key identifier, the key lifetime (or at least the location), and the driver key identifier (not constant-size).
|
||||
|
||||
For key creation, we do not need to store the key's metadata until it has been created in the secure element. Therefore the normal sequence of operations is:
|
||||
|
||||
1. Call the driver's `"allocate_key"` entry point.
|
||||
2. Add the key to the transaction list.
|
||||
3. Call the driver's key creation entry point.
|
||||
4. Write the key file.
|
||||
5. Remove the key from the transaction list.
|
||||
|
||||
For key destruction, we can remove the key file before contacting the secure element. Therefore the normal sequence of operations is:
|
||||
|
||||
1. Add the key to the transaction list.
|
||||
2. Remove the key file.
|
||||
3. Call the driver's `"destroy_key"` entry point.
|
||||
4. Remove the key from the transaction list.
|
||||
|
||||
Recovery means removing all traces of all keys on the transaction list. This means following the destruction process, starting after the point where the key has been added to the transaction list, and ignoring any failure of a removal action if the item to remove does not exist:
|
||||
|
||||
1. Remove the key file, treating `DOES_NOT_EXIST` as a success.
|
||||
2. Call the driver's `"destroy_key"` entry point, treating `DOES_NOT_EXIST` as a success.
|
||||
3. Remove the key from the transaction list.
|
||||
|
||||
#### Always-destroy strategy with a simpler transaction file
|
||||
|
||||
We can modify the [always-destroy strategy](#exploring-the-always-destroy-strategy) to make the transaction file simpler: if we ensure that the key file always exists if the key exists in the secure element, then the transaction list does not need to include the driver key identifier: it can be read from the key file.
|
||||
|
||||
For key creation, we need to store the key's metadata before creating in the secure element. Therefore the normal sequence of operations is:
|
||||
|
||||
1. Call the driver's `"allocate_key"` entry point.
|
||||
2. Add the key to the transaction list.
|
||||
3. Write the key file.
|
||||
4. Call the driver's key creation entry point.
|
||||
5. Remove the key from the transaction list.
|
||||
|
||||
For key destruction, we need to contact the secure element before removing the key file. Therefore the normal sequence of operations is:
|
||||
|
||||
1. Add the key to the transaction list.
|
||||
2. Call the driver's `"destroy_key"` entry point.
|
||||
3. Remove the key file.
|
||||
4. Remove the key from the transaction list.
|
||||
|
||||
Recovery means removing all traces of all keys on the transaction list. This means following the destruction process, starting after the point where the key has been added to the transaction list, and ignoring any failure of a removal action if the item to remove does not exist:
|
||||
|
||||
1. Load the driver key identifier from the key file. If the key file does not exist, skip to step 4.
|
||||
2. Call the driver's `"destroy_key"` entry point, treating `DOES_NOT_EXIST` as a success.
|
||||
3. Remove the key file, treating `DOES_NOT_EXIST` as a success.
|
||||
4. Remove the key from the transaction list.
|
||||
|
||||
Compared with the basic always-destroy strategy:
|
||||
|
||||
* The transaction file handling is simpler since its entries have a fixed size.
|
||||
* The flow of information is somewhat different from transparent keys and keys in stateless secure elements: we aren't just replacing “create the key material” by “tell the secure element to create the key material”, those happen at different times. But there's a different flow for stateful secure elements anyway, since the call to `"allocate_key"` has no analog in the stateless secure element or transparent cases.
|
||||
|
||||
#### Assisting secure element drivers with recovery
|
||||
|
||||
The actions of the secure element driver may themselves be non-atomic. So the driver must be given a chance to perform recovery.
|
||||
|
||||
To simplify the design of the driver, the core should guarantee that the driver will know if a transaction was in progress and the core cannot be sure about the state of the secure element. Merely calling a read-only entry point such as `"get_key_attributes"` does not provide enough information to the driver for it to know that it should actively perform recovery related to that key.
|
||||
|
||||
This gives an advantage to the “always destroy” strategy. Under this strategy, if the key might be in a transitional state, the core will request a key destruction from the driver. This means that, if the driver has per-key auxiliary data to clean up, it can bundle that as part of the key's destruction.
|
||||
|
||||
### Testing non-atomic processes
|
||||
|
||||
In this section, we discuss how to test non-atomic processes that must implement an atomic and committing interface. As discussed in [“Overview of API functions”](#overview-of-api-functions), this concerns key management in stateful secure elements.
|
||||
|
||||
#### Naive test strategy for non-atomic processes
|
||||
|
||||
Non-atomic processes consist of a series of atomic, committing steps.
|
||||
|
||||
Our general strategy to test them is as follows: every time there is a modification of persistent state, either in storage or in the (simulated) secure element, try both the nominal case and simulating a power loss. If a power loss occurs, restart the system (i.e. clean up and call `psa_crypto_init()`), and check that the system ends up in a consistent state.
|
||||
|
||||
Note that this creates a binary tree of possibilities: after each state modification, there may or may not be a restart, and after that different state modifications may occur, each of which may or may not be followed by a restart.
|
||||
|
||||
For example, consider testing of one key creation operation (see [“Overview of two-phase commit with stateful secure elements”](#overview-of-two-phase-commit-with-stateful-secure-elements), under the simplifying assumption that each storage update step, as well as the recovery after a restart, each make a single (atomic) storage modification and no secure element access. The nominal case consists of three state modifications: storage modification (start transaction), creation on the secure element, storage modification (commit transaction). We need to test the following sequences:
|
||||
|
||||
* Start transaction, restart, recovery.
|
||||
* Start transaction, secure element operation, restart, recovery.
|
||||
* Start transaction, secure element operation, commit transaction.
|
||||
|
||||
If, for example, recovery consists of two atomic steps, the tree of possibilities expands and may be infinite:
|
||||
|
||||
* Start transaction, restart, recovery step 1, restart, recovery step 1, recovery step 2.
|
||||
* Start transaction, restart, recovery step 1, restart, recovery step 1, restart, recovery step 1, recovery step 2.
|
||||
* Start transaction, restart, recovery step 1, restart, recovery step 1, restart, recovery step 1, restart, recovery step 1, recovery step 2.
|
||||
* etc.
|
||||
* Start transaction, secure element operation, restart, ...
|
||||
* Start transaction, secure element operation, commit transaction.
|
||||
|
||||
In order to limit the possibilities, we need to make some assumptions about the recovery step. For example, if we have confidence that recovery step 1 is idempotent (i.e. doing it twice is the same as doing it once), we don't need to test what happens in execution sequences that take recovery step 1 more than twice in a row.
|
||||
|
||||
### Splitting normal behavior and transaction recovery
|
||||
|
||||
We introduce an abstraction level in transaction recovery:
|
||||
|
||||
* Normal operation must maintain a certain invariant on the state of the world (internal storage and secure element).
|
||||
* Transaction recovery is defined over all states of the world that satisfy this invariant.
|
||||
|
||||
This separation of concerns greatly facilitates testing, since it is now split into two parts:
|
||||
|
||||
* During the testing of normal operation, we can use read-only invasive testing to ensure that the invariant is maintained. No modification of normal behavior (such as simulated power failures) is necessary.
|
||||
* Testing of transaction recovery is independent of how the system state was reached. We only need to artificially construct a representative sample of system states that match the invariant. Transaction recovery is itself an operation that must respect the invariant, and so we do not need any special testing for the case of an interrupted recovery.
|
||||
|
||||
Another benefit of this approach is that it is easier to specify and test what happens if the library is updated on a device with leftovers from an interrupted transaction. We will require and test that the new version of the library supports recovery of the old library's states, without worrying how those states were reached.
|
||||
|
||||
#### Towards an invariant for transactions
|
||||
|
||||
As discussed in the section [“Recovery strategies”](#recovery-strategies), the information about active transactions is stored in a transaction list file. The name of the transaction list file does not depend on the identifiers of the keys in the list, but there may be more than one transaction list, for example one per secure element. If so, each transaction list can be considered independently.
|
||||
|
||||
When no transaction is in progress, the transaction list does not exist, or is empty. The empty case must be supported because this is the initial state of the filesystem. When no transaction is in progress, the state of the secure element must be consistent with references to keys in that secure element contained in key files. More generally, if a key is not in the transaction list, then the key must be present in the secure element if and only if the key file is in the internal storage.
|
||||
|
||||
For the purposes of the state invariant, it matters whether the transaction list file contains the driver key identifier, or if the driver key identifier is only stored in the key file. This is because the core needs to know the driver key id in order to access the secure element. If the transaction list does not contain the driver key identifier, and the key file does not exist, the key must not be present in the secure element.
|
||||
|
||||
We thus have two scenarios, each with their own invariant: one where the transaction list contains only key identifiers, and one where it also contains the secure element's key identifier (as well as the location of the secure element if this is not encoded in the name of the transaction list file).
|
||||
|
||||
#### Storage invariant if the transaction list contains application key identifiers only
|
||||
|
||||
Invariants:
|
||||
|
||||
* If the file `id` does not exist, then no resources corresponding to that key are in a secure element. This holds whether `id` is in the transaction list or not.
|
||||
* If `id` is not in the transaction list and the file `id` exists and references a key in a stateful secure element, then the key is present in the secure element.
|
||||
|
||||
If `id` is in the transaction list and the file `id` exists, the key may or may not be present in the secure element.
|
||||
|
||||
The invariant imposes constraints on the [order of operations for the two-phase commit](#overview-of-two-phase-commit-with-stateful-secure-elements): key creation must create `id` before calling the secure element's key creation entry point, and key destruction must remove `id` after calling the secure element's key destruction entry point.
|
||||
|
||||
For recovery:
|
||||
|
||||
* If the file `id` does not exist, then nothing needs to be done for recovery, other than removing `id` from the transaction list.
|
||||
* If the file `id` exists:
|
||||
* It is correct to destroy the key in the secure element (treating a `DOES_NOT_EXIST` error as a success), then remove `id`.
|
||||
* It is correct to check whether the key exists in the secure element, and if it does, keep it and keep `id`. If not, remove `id` from the internal storage.
|
||||
|
||||
#### Storage invariant if the transaction list contains driver key identifiers
|
||||
|
||||
Invariants:
|
||||
|
||||
* If `id` is not in the transaction list and the file `id` does not exist, then no resources corresponding to that key are in a secure element.
|
||||
* If `id` is not in the transaction list and the file `id` exists, then the key is present in the secure element.
|
||||
|
||||
If `id` is in the transaction list, neither the state of `id` in the internal storage nor the state of the key in the secure element is known.
|
||||
|
||||
For recovery:
|
||||
|
||||
* If the file `id` does not exist, then destroy the key in the secure element (treating a `DOES_NOT_EXIST` error as a success).
|
||||
* If the file `id` exists:
|
||||
* It is correct to destroy the key in the secure element (treating a `DOES_NOT_EXIST` error as a success), then remove `id`.
|
||||
* It is correct to check whether the key exists in the secure element, and if it does, keep it and keep `id`. If not, remove `id` from the internal storage.
|
||||
|
||||
#### Coverage of states that respect the invariant
|
||||
|
||||
For a given key, we have to consider three a priori independent boolean states:
|
||||
|
||||
* Whether the key file exists.
|
||||
* Whether the key is in the secure element.
|
||||
* Whether the key is in the transaction list.
|
||||
|
||||
There is full coverage for one key if we have tests of recovery for the states among these $2^3 = 8$ possibilities that satisfy the storage invariant.
|
||||
|
||||
In addition, testing should adequately cover the case of multiple keys in the transaction list. How much coverage is adequate depends on the layout of the list as well as white-box considerations of how the list is manipulated.
|
||||
|
||||
### Choice of a transaction design
|
||||
|
||||
#### Chosen transaction algorithm
|
||||
|
||||
Based on [“Optimization considerations for transactions”](#optimization-considerations-for-transactions), we choose a transaction algorithm that consists in the following operations:
|
||||
|
||||
1. Add the key identifier to the transaction list.
|
||||
2. Call the secure element's key creation or destruction entry point.
|
||||
3. Remove the key identifier from the transaction list.
|
||||
|
||||
In addition, before or after step 2, create or remove the key file in the internal storage.
|
||||
|
||||
In order to conveniently support multiple transactions at the same time, we pick the simplest possible layout for the transaction list: a simple array of key identifiers. Since the transaction list does not contain the driver key identifier:
|
||||
|
||||
* During key creation, create the key file in internal storage in the internal storage before calling the secure element's key creation entry point.
|
||||
* During key destruction, call the secure element's key destruction entry point before removing the key file in internal storage.
|
||||
|
||||
This choice of algorithm does not require the secure element driver to have a `"get_key_attributes"` entry point.
|
||||
|
||||
#### Chosen storage invariant
|
||||
|
||||
The [storage invariant](#storage-invariant-if-the-transaction-list-contains-application-key-identifiers-only) is as follows:
|
||||
|
||||
* If the file `id` does not exist, then no resources corresponding to that key are in a secure element. This holds whether `id` is in the transaction list or not.
|
||||
* If `id` is not in the transaction list and the file `id` exists and references a key in a stateful secure element, then the key is present in the secure element.
|
||||
* If `id` is in the transaction list and a key exists by that identifier, the key's location is a stateful secure element.
|
||||
|
||||
#### Chosen recovery process
|
||||
|
||||
To [assist secure element drivers with recovery](#assisting-secure-element-drivers-with-recovery), we pick the [always-destroy recovery strategy with a simple transaction file](#always-destroy-strategy-with-a-simpler-transaction-file). The the recovery process is as follows:
|
||||
|
||||
* If the file `id` does not exist, then nothing needs to be done for recovery, other than removing `id` from the transaction list.
|
||||
* If the file `id` exists, call the secure element's key destruction entry point (treating a `DOES_NOT_EXIST` error as a success), then remove `id`.
|
||||
|
||||
## Specification of key management in stateful secure elements
|
||||
|
||||
This section only concerns stateful secure elements as discussed in [“Designing key management for secure element keys”](#designing-key-management-for-secure-element-keys), i.e. secure elements with an `"allocate_key"` entry point. The design follows the general principle described in [“Overview of two-phase commit with stateful secure elements”](#overview-of-two-phase-commit-with-stateful-secure-elements) and the specific choices justified in [“Choice of a transaction design”](choice-of-a-transaction-design).
|
||||
|
||||
### Transaction list file manipulation
|
||||
|
||||
The transaction list is a simple array of key identifiers.
|
||||
|
||||
To add a key identifier to the list:
|
||||
|
||||
1. Load the current list from the transaction list if it exists and it is not already cached in memory.
|
||||
2. Append the key identifier to the array.
|
||||
3. Write the updated list file.
|
||||
|
||||
To remove a key identifier from the list:
|
||||
|
||||
1. Load the current list if it is not already cached in memory. It is an error if the file does not exist since it must contain this identifier.
|
||||
2. Remove the key identifier from the array. If it wasn't the last element in array, move array elements to fill the hole.
|
||||
3. If the list is now empty, remove the transaction list file. Otherwise write the updated list to the file.
|
||||
|
||||
### Key creation process in the core
|
||||
|
||||
Let _A_ be the application key identifier.
|
||||
|
||||
1. Call the driver's `"allocate_key"` entry point, obtaining the driver key identifier _D_ chosen by the driver.
|
||||
2. Add _A_ [to the transaction list file](#transaction-list-file-manipulation).
|
||||
3. Create the key file _A_ in the internal storage. Note that this is done at a different time from what happens when creating a transparent key or a key in a stateless secure element: in those cases, creating the key file happens after the actual creation of the key material.
|
||||
4. Call the secure element's key creation entry point.
|
||||
5. Remove _A_ [from the transaction list file](#transaction-list-file-manipulation).
|
||||
|
||||
If any step fails:
|
||||
|
||||
* If the secure element's key creation entry point has been called and succeeded, call the secure element's destroy entry point.
|
||||
* If the key file has been created in the internal storage, remove it.
|
||||
* Remove the key from the transaction list.
|
||||
|
||||
Note that this process is identical to key destruction, except that the key is already in the transaction list.
|
||||
|
||||
### Key destruction process in the core
|
||||
|
||||
Let _A_ be the application key identifier.
|
||||
|
||||
We assume that the key is loaded in a key slot in memory: the core needs to know the key's location in order to determine whether the key is in a stateful secure element, and if so to know the driver key identifier. A possible optimization would be to load only that information in local variables, without occupying a key store; this has the advantage that key destruction works even if the key store is full.
|
||||
|
||||
1. Add _A_ [to the transaction list file](#transaction-list-file-manipulation).
|
||||
2. Call the secure element's `"destroy_key"` entry point.
|
||||
3. Remove the key file _A_ from the internal storage.
|
||||
4. Remove _A_ [from the transaction list file](#transaction-list-file-manipulation).
|
||||
5. Free the corresponding key slot in memory.
|
||||
|
||||
If any step fails, remember the error but continue the process, to destroy the resources associated with the key as much as is practical.
|
||||
|
||||
### Transaction recovery
|
||||
|
||||
For each key _A_ in the transaction list file, if the file _A_ exists in the internal storage:
|
||||
|
||||
1. Load the key into a key slot in memory (to get its location and the driver key identifier, although we could get the location from the transaction list).
|
||||
2. Call the secure element's `"destroy_key"` entry point.
|
||||
3. Remove the key file _A_ from the internal storage.
|
||||
4. Remove _A_ [from the transaction list file](#transaction-list-file-manipulation).
|
||||
5. Free the corresponding key slot in memory.
|
||||
|
||||
The transaction list file can be processed in any order.
|
||||
|
||||
It is correct to update the transaction list after recovering each key, or to only delete the transaction list file once the recovery is over.
|
||||
|
||||
### Concrete format of the transaction list file
|
||||
|
||||
The transaction list file contains a [fixed header](#transaction-list-header-format) followed by a list of [fixed-size elements](#transaction-list-element-format).
|
||||
|
||||
The file uid is `PSA_CRYPTO_ITS_TRANSACTION_LIST_UID` = 0xffffff53.
|
||||
|
||||
#### Transaction list header format
|
||||
|
||||
* Version (2 bytes): 0x0003. (Chosen to differ from the first two bytes of a [dynamic secure element transaction file](#dynamic-secure-element-transaction-file), to reduce the risk of a mix-up.)
|
||||
* Key name size (2 bytes): `sizeof(psa_storage_uid_t)`. Storing this size avoids reading bad data if Mbed TLS is upgraded to a different integration that names keys differently.
|
||||
|
||||
#### Transaction list element format
|
||||
|
||||
In practice, there will rarely be more than one active transaction at a time, so the size of an element is not critical for efficiency. Therefore, in addition to the key identifier which is required, we add some potentially useful information in case it becomes useful later. We do not put the driver key identifier because its size is not a constant.
|
||||
|
||||
* Key id: `sizeof(psa_storage_uid_t)` bytes.
|
||||
* Key lifetime: 4 bytes (`sizeof(psa_key_lifetime_t)`). Currently unused during recovery.
|
||||
* Operation type: 1 byte. Currently unused during recovery.
|
||||
* 0: destroy key.
|
||||
* 1: import key.
|
||||
* 2: generate key.
|
||||
* 3: derive key.
|
||||
* 4: import key.
|
||||
* Padding: 3 bytes. Reserved for future use. Currently unused during recovery.
|
||||
|
||||
#### Dynamic secure element transaction file
|
||||
|
||||
Note that the code base already references a “transaction file” (`PSA_CRYPTO_ITS_TRANSACTION_UID` = 0xffffff54), used by dynamic secure elements (feature enabled with `MBEDTLS_PSA_CRYPTO_SE_C`). This is a deprecated feature that has not been fully implemented: when this feature is enabled, the transaction file gets written during transactions, but if it exists when PSA crypto starts, `psa_crypto_init()` fails because [recovery has never been implemented](https://github.com/ARMmbed/mbed-crypto/issues/218).
|
||||
|
||||
For the new kind of secure element driver, we pick a different file name to avoid any mixup.
|
||||
|
||||
## Testing key management in secure elements
|
||||
|
||||
### Instrumentation for checking the storage invariant
|
||||
|
||||
#### Test hook locations
|
||||
|
||||
When `MBEDTLS_TEST_HOOKS` is enabled, each call to `psa_its_set()` or `psa_its_remove()` also calls a test hook, passing the file UID as an argument to the hook.
|
||||
|
||||
When a stateful secure element driver is present in the build, we use this hook to verify that the storage respects the [storage invariant](#chosen-storage-invariant). In addition, if there is some information about key ongoing operation (set explicitly by the test function as a global variable in the test framework), the hook tests that the content of the storage is compatible with the ongoing operation.
|
||||
|
||||
#### Test hook behavior
|
||||
|
||||
The storage invariant check cannot check all keys in storage, and does not need to (for example, it would be pointless to check anything about transparent keys). It checks the following keys:
|
||||
|
||||
* When invoked from the test hook on a key file: on that key.
|
||||
* When invoked from the test hook on the transaction file: on all the keys listed in the transaction file.
|
||||
* When invoked from a test secure element: on the specified key.
|
||||
|
||||
#### Test hook extra data
|
||||
|
||||
Some tests set global variables to indicate which persistent keys they manipulate. We instrument at least some of these tests to also indicate what operation is in progress on the key. See the GitHub issues or the source code for details.
|
||||
|
||||
### Testing of transaction recovery
|
||||
|
||||
When no secure element driver is present in the build, the presence of a transaction list file during initialization is an error.
|
||||
|
||||
#### Recovery testing process
|
||||
|
||||
When the stateful test secure element driver is present in the build, we run test cases on a representative selection of states of the internal storage and the test secure element. Each test case for transaction recovery has the following form:
|
||||
|
||||
1. Create the initial state:
|
||||
* Create a transaction list file with a certain content.
|
||||
* Create key files that we want to have in the test.
|
||||
* Call the secure element test driver to create keys without going throught the PSA API.
|
||||
2. Call `psa_crypto_init()`. Expect success if the initial state satisfies the [storage invariant](#chosen-storage-invariant) and failure otherwise.
|
||||
3. On success, check that the expected keys exist, and that keys that are expected to have been destroyed by recovery do not exist.
|
||||
4. Clean up the storage and the secure element test driver's state.
|
||||
|
||||
#### States to test recovery on
|
||||
|
||||
For a given key located in a secure element, the following combination of states are possible:
|
||||
|
||||
* Key file: present, absent.
|
||||
* Key in secure element: present, absent.
|
||||
* Key in the transaction file: no, creation (import), destruction.
|
||||
|
||||
We test all $2 \times 2 \times 3 = 12$ possibilities, each in its own test case. In each case, call the test function that checks the storage invariant and check that its result is as expected. Then, if the storage invariant is met, follow the [recovery testing process](#recovery-testing-process).
|
||||
|
||||
In addition, have at least one positive test case for each creation method other than import, to ensure that we don't reject a valid value.
|
||||
|
||||
Note: testing of a damaged filesystem (including a filesystem that doesn't meet the invariant) is out of scope of the present document.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 49 KiB |
@@ -1,367 +0,0 @@
|
||||
# Thread-safety of the PSA subsystem
|
||||
|
||||
Currently, PSA Crypto API calls in Mbed TLS releases are not thread-safe.
|
||||
|
||||
As of Mbed TLS 3.6, an MVP for making the [PSA Crypto key management API](https://arm-software.github.io/psa-api/crypto/1.1/api/keys/management.html) and [`psa_crypto_init`](https://arm-software.github.io/psa-api/crypto/1.1/api/library/library.html#c.psa_crypto_init) thread-safe has been implemented. Implementations which only ever call PSA functions from a single thread are not affected by this new feature.
|
||||
|
||||
Summary of recent work:
|
||||
|
||||
- Key Store:
|
||||
- Slot states are described in the [Key slot states](#key-slot-states) section. They guarantee safe concurrent access to slot contents.
|
||||
- Key slots are protected by a global mutex, as described in [Key store consistency and abstraction function](#key-store-consistency-and-abstraction-function).
|
||||
- Key destruction strategy abiding by [Key destruction guarantees](#key-destruction-guarantees), with an implementation discussed in [Key destruction implementation](#key-destruction-implementation).
|
||||
- `global_data` variables in `psa_crypto.c` and `psa_crypto_slot_management.c` are now protected by mutexes, as described in the [Global data](#global-data) section.
|
||||
- The testing system has now been made thread-safe. Tests can now spin up multiple threads, see [Thread-safe testing](#thread-safe-testing) for details.
|
||||
- Some multithreaded testing of the key management API has been added, this is outlined in [Testing-and-analysis](#testing-and-analysis).
|
||||
- The solution uses the pre-existing `MBEDTLS_THREADING_C` threading abstraction.
|
||||
- The core makes no additional guarantees for drivers. See [Driver policy](#driver-policy) for details.
|
||||
|
||||
The other functions in the PSA Crypto API are planned to be made thread-safe in future, but currently we are not testing this.
|
||||
|
||||
## Overview of the document
|
||||
|
||||
* The [Guarantees](#guarantees) section describes the properties that are followed when PSA functions are invoked by multiple threads.
|
||||
* The [Usage guide](#usage-guide) section gives guidance on initializing, using and freeing PSA when using multiple threads.
|
||||
* The [Current strategy](#current-strategy) section describes how thread-safety of key management and `global_data` is achieved.
|
||||
* The [Testing and analysis](#testing-and-analysis) section discusses the state of our testing, as well as how this testing will be extended in future.
|
||||
* The [Future work](#future-work) section outlines our long-term goals for thread-safety; it also analyses how we might go about achieving these goals.
|
||||
|
||||
## Definitions
|
||||
|
||||
*Concurrent calls*
|
||||
|
||||
The PSA specification defines concurrent calls as: "In some environments, an application can make calls to the Crypto API in separate threads. In such an environment, concurrent calls are two or more calls to the API whose execution can overlap in time." (See PSA documentation [here](https://arm-software.github.io/psa-api/crypto/1.1/overview/conventions.html#concurrent-calls).)
|
||||
|
||||
*Thread-safety*
|
||||
|
||||
In general, a system is thread-safe if any valid set of concurrent calls is handled as if the effect and return code of every call is equivalent to some sequential ordering. We implement a weaker notion of thread-safety, we only guarantee thread-safety in the circumstances described in the [PSA Concurrent calling conventions](#psa-concurrent-calling-conventions) section.
|
||||
|
||||
## Guarantees
|
||||
|
||||
### Correctness out of the box
|
||||
|
||||
Building with `MBEDTLS_PSA_CRYPTO_C` and `MBEDTLS_THREADING_C` gives code which is correct; there are no race-conditions, deadlocks or livelocks when concurrently calling any set of PSA key management functions once `psa_crypto_init` has been called (see the [Initialization](#initialization) section for details on how to correctly initialize the PSA subsystem when using multiple threads).
|
||||
|
||||
We do not test or support calling other PSA API functions concurrently.
|
||||
|
||||
There is no busy-waiting in our implementation, every API call completes in a finite number of steps regardless of the locking policy of the underlying mutexes.
|
||||
|
||||
When only considering key management functions: Mbed TLS 3.6 abides by the minimum expectation for concurrent calls set by the PSA specification (see [PSA Concurrent calling conventions](#psa-concurrent-calling-conventions)).
|
||||
|
||||
#### PSA Concurrent calling conventions
|
||||
|
||||
These are the conventions which are planned to be added to the PSA 1.2 specification, Mbed TLS 3.6 abides by these when only considering [key management functions](https://arm-software.github.io/psa-api/crypto/1.1/api/keys/management.html):
|
||||
|
||||
> The result of two or more concurrent calls must be consistent with the same set of calls being executed sequentially in some order, provided that the calls obey the following constraints:
|
||||
>
|
||||
> * There is no overlap between an output parameter of one call and an input or output parameter of another call. Overlap between input parameters is permitted.
|
||||
>
|
||||
> * A call to `psa_destroy_key()` must not overlap with a concurrent call to any of the following functions:
|
||||
> - Any call where the same key identifier is a parameter to the call.
|
||||
> - Any call in a multi-part operation, where the same key identifier was used as a parameter to a previous step in the multi-part operation.
|
||||
>
|
||||
> * Concurrent calls must not use the same operation object.
|
||||
>
|
||||
> If any of these constraints are violated, the behaviour is undefined.
|
||||
>
|
||||
> The consistency requirement does not apply to errors that arise from resource failures or limitations. For example, errors resulting from resource exhaustion can arise in concurrent execution that do not arise in sequential execution.
|
||||
>
|
||||
> As an example of this rule: suppose two calls are executed concurrently which both attempt to create a new key with the same key identifier that is not already in the key store. Then:
|
||||
> * If one call returns `PSA_ERROR_ALREADY_EXISTS`, then the other call must succeed.
|
||||
> * If one of the calls succeeds, then the other must fail: either with `PSA_ERROR_ALREADY_EXISTS` or some other error status.
|
||||
> * Both calls can fail with error codes that are not `PSA_ERROR_ALREADY_EXISTS`.
|
||||
>
|
||||
> If the application concurrently modifies an input parameter while a function call is in progress, the behaviour is undefined.
|
||||
|
||||
### Backwards compatibility
|
||||
|
||||
Code which was working prior to Mbed TLS 3.6 will still work. Implementations which only ever call PSA functions from a single thread, or which protect all PSA calls using a mutex, are not affected by this new feature. If an application previously worked with a 3.X version, it will still work on version 3.6.
|
||||
|
||||
### Supported threading implementations
|
||||
|
||||
Currently, the only threading library with support shipped in the code base is pthread (enabled by `MBEDTLS_THREADING_PTHREAD`). The only concurrency primitives we use are mutexes, see [Condition variables](#condition-variables) for discussion about implementing new primitives in future major releases.
|
||||
|
||||
Users can add support to any platform which has mutexes using the Mbed TLS platform abstraction layer (see `include/mbedtls/threading.h` for details).
|
||||
|
||||
We intend to ship support for other platforms including Windows in future releases.
|
||||
|
||||
### Key destruction guarantees
|
||||
|
||||
Much like all other API calls, `psa_destroy_key` does not block indefinitely, and when `psa_destroy_key` returns:
|
||||
|
||||
1. The key identifier does not exist. This is a functional requirement for persistent keys: any thread can immediately create a new key with the same identifier.
|
||||
2. The resources from the key have been freed. This allows threads to create similar keys immediately after destruction, regardless of resources.
|
||||
|
||||
When `psa_destroy_key` is called on a key that is in use, guarantee 2 may be violated. This is consistent with the PSA specification requirements, as destruction of a key in use is undefined.
|
||||
|
||||
In future versions we aim to enforce stronger requirements for key destruction, see [Long term key destruction requirements](#long-term-key-destruction-requirements) for details.
|
||||
|
||||
### Driver policy
|
||||
|
||||
The core makes no additional guarantees for drivers. Driver entry points may be called concurrently from multiple threads. Threads can concurrently call entry points using the same key, there is also no protection from destroying a key which is in use.
|
||||
|
||||
### Random number generators
|
||||
|
||||
The PSA RNG can be accessed both from various PSA functions, and from application code via `mbedtls_psa_get_random`.
|
||||
|
||||
When using the built-in RNG implementations, i.e. when `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is disabled, querying the RNG is thread-safe (`mbedtls_psa_random_init` and `mbedtls_psa_random_seed` are only thread-safe when called while holding `mbedtls_threading_psa_rngdata_mutex`. `mbedtls_psa_random_free` is not thread-safe).
|
||||
|
||||
When `MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG` is enabled, it is down to the external implementation to ensure thread-safety, should threading be enabled.
|
||||
|
||||
## Usage guide
|
||||
|
||||
### Initialization
|
||||
|
||||
The PSA subsystem is initialized via a call to [`psa_crypto_init`](https://arm-software.github.io/psa-api/crypto/1.1/api/library/library.html#c.psa_crypto_init). This is a thread-safe function, and multiple calls to `psa_crypto_init` are explicitly allowed. It is valid to have multiple threads each calling `psa_crypto_init` followed by a call to any PSA key management function (if the init succeeds).
|
||||
|
||||
### General usage
|
||||
|
||||
Once initialized, threads can use any PSA function if there is no overlap between their calls. All threads share the same set of keys, as soon as one thread returns from creating/loading a key via a key management API call the key can be used by any thread. If multiple threads attempt to load the same persistent key, with the same key identifier, only one thread can succeed - the others will return `PSA_ERROR_ALREADY_EXISTS`.
|
||||
|
||||
Applications may need careful handling of resource management errors. As explained in ([PSA Concurrent calling conventions](#psa-concurrent-calling-conventions)), operations in progress can have memory related side effects. It is possible for a lack of resources to cause errors which do not arise in sequential execution. For example, multiple threads attempting to load the same persistent key can lead to some threads returning `PSA_ERROR_INSUFFICIENT_MEMORY` if the key is not currently in the key store - while trying to load a persistent key into the key store a thread temporarily reserves a free key slot.
|
||||
|
||||
If a mutex operation fails, which only happens if the mutex implementation fails, the error code `PSA_ERROR_SERVICE_FAILURE` will be returned. If this code is returned, execution of the PSA subsystem must be stopped. All functions which have internal mutex locks and unlocks (except for when the lock/unlock occurs in a function that has no return value) will return with this error code in this situation.
|
||||
|
||||
### Freeing
|
||||
|
||||
There is no thread-safe way to free all PSA resources. This is because any such operation would need to wait for all other threads to complete their tasks before wiping resources.
|
||||
|
||||
`mbedtls_psa_crypto_free` must only be called by a single thread once all threads have completed their operations.
|
||||
|
||||
## Current strategy
|
||||
|
||||
This section describes how we have implemented thread-safety. There is discussion of: techniques, internal properties for enforcing thread-safe access, how the system stays consistent and our abstraction model.
|
||||
|
||||
### Protected resources
|
||||
|
||||
#### Global data
|
||||
|
||||
We have added a mutex `mbedtls_threading_psa_globaldata_mutex` defined in `include/mbedtls/threading.h`, which is used to make `psa_crypto_init` thread-safe.
|
||||
|
||||
There are two `psa_global_data_t` structs, each with a single instance `global_data`:
|
||||
|
||||
* The struct in `library/psa_crypto.c` is protected by `mbedtls_threading_psa_globaldata_mutex`. The RNG fields within this struct are not protected by this mutex, and are not always thread-safe (see [Random number generators](#random-number-generators)).
|
||||
* The struct in `library/psa_crypto_slot_management.c` has two fields: `key_slots` is protected as described in [Key slots](#key-slots), `key_slots_initialized` is protected by the global data mutex.
|
||||
|
||||
#### Mutex usage
|
||||
|
||||
A deadlock would occur if a thread attempts to lock a mutex while already holding it. Functions which need to be called while holding the global mutex have documentation to say this.
|
||||
|
||||
To avoid performance degradation, functions must hold mutexes for as short a time as possible. In particular, they must not start expensive operations (eg. doing cryptography) while holding the mutex.
|
||||
|
||||
#### Key slots
|
||||
|
||||
|
||||
Keys are stored internally in a global array of key slots known as the "key store", defined in `library/psa_slot_management.c`.
|
||||
|
||||
##### Key slot states
|
||||
|
||||
Each key slot has a state variable and a `registered_readers` counter. These two variables dictate whether an operation can access a slot, and in what way the slot can be used.
|
||||
|
||||
There are four possible states for a key slot:
|
||||
|
||||
* `PSA_SLOT_EMPTY`: no thread is currently accessing the slot, and no information is stored in the slot. Any thread is able to change the slot's state to `PSA_SLOT_FILLING` and begin to load data into the slot.
|
||||
* `PSA_SLOT_FILLING`: one thread is currently loading or creating material to fill the slot, this thread is responsible for the next state transition. Other threads cannot read the contents of a slot which is in this state.
|
||||
* `PSA_SLOT_FULL`: the slot contains a key, and any thread is able to use the key after registering as a reader, increasing `registered_readers` by 1.
|
||||
* `PSA_SLOT_PENDING_DELETION`: the key within the slot has been destroyed or marked for destruction, but at least one thread is still registered as a reader (`registered_readers > 0`). No thread can register to read this slot. The slot must not be wiped until the last reader unregisters. It is during the last unregister that the contents of the slot are wiped, and the slot's state is set to `PSA_SLOT_EMPTY`.
|
||||
|
||||
###### Key slot state transition diagram
|
||||

|
||||
|
||||
In the state transition diagram above, an arrow between two states `q1` and `q2` with label `f` indicates that if the state of a slot is `q1` immediately before `f`'s linearization point, it may be `q2` immediately after `f`'s linearization point. Internal functions have italicized labels. The `PSA_SLOT_PENDING_DELETION -> PSA_SLOT_EMPTY` transition can be done by any function which calls `psa_unregister_read`.
|
||||
|
||||
The state transition diagram can be generated in https://app.diagrams.net/ via this [url](https://viewer.diagrams.net/?tags=%7B%7D&highlight=0000ff&edit=_blank&layers=1&nav=1#R3Vxbd5s4EP4t%2B%2BDH5CBxf6zrJJvW7aYn7W7dFx9qZFstBg7gW379CnMxkoUtY%2BGQ%2BiVISCPQjD59mhnSU98vNg%2BRE84%2FBS7yelBxNz110IMQAEsnf9KabVZjmHnFLMJu3mhf8YxfUF6p5LVL7KKYapgEgZfgkK6cBL6PJglV50RRsKabTQOPHjV0Zuig4nnieIe1%2F2E3mWe1FjT39X8jPJsXIwPDzu4snKJx%2Fibx3HGDdaVKveup76MgSLKrxeY98tLJK%2BYl63dfc7d8sAj5iUiHH%2BBlOP338cP6i%2B37%2Ff7oV%2Fjr442aSVk53jJ%2F4R40PCKv7%2BIVuZyll%2FffhsOimsiv3OE0njvxOEKOi6K4uPszYtuzUnbzk2yLSScPTvRLCv31HCfoOXQm6Z01MbF0hGThkRIgl04cZkqf4g1yS1HVScnnaYWiBG0qVfkkPaBggZJoS5rkdzUrV1hhsUpeXlf0n1fNK6ov6pzc4mal5L1SyEWulzN0BABHSeyM%2Be671NpJaeI5cYwn9ERFwdJ30xkaKKREJifafs9v7QqjamGwqbYbbIvSBidlJ3I9qtTvu6SFoketNuJgGU3QabtMnGiGkiPttKwdcqlVfKjbiu50ju6Kugh5ToJX9NrnKTQf4SnA5M1qTUc3GJvI3jvvVV2rrCDTvrUrP4sSq6mM2GyaDsTurK2chAsMENaiBC7WcBg746UfoRmOExTtEKCy2HH9UieaGzo%2Fya5BL2wPz%2FzUmInloIhUpOsXE1h%2Bl99YYNdNZfQjFOMX5%2BdOXmpzYToLu3nR%2Bz19wLXC48uMRYpyc8lHofCbhyDKLVRMm1LZDbzMwAoxgOkSTKcxakfpIjvD3aenr6O3CfOdQ3lbOsrneK1U8BocxetyXygLo2qhZl9ojvJQEOVBt1CetpwDNBYG%2BRObRcuoXvDSU6g%2BdbA3%2Fo224wkB9QQH%2FlvD9WJhdRHXc8mQEsr2bw%2FkDzf2%2B8fh8PHzQ6exWjVeGas1kb3xrFPTX3%2FcsenVlaSLKOnp7vNgZ%2B6CehrcDe%2B%2BPv7z%2BW3qqHOkx2yL84ifUZudhZtznsKJdYrzwE5xHqiQzc%2FSoAnI2VTTDXoX1DXj1gS6CS1TJwWVES9KiIDBMCvtuozIEkEMLkciZAVFKzSeRgjtuFLsBQmfJwkCDXeYmExAwuViXBw6OWpnOVuBC12kbKUY7VosDfD4hnyYvNWbHA6zXq96POyWEzCFSkUpoNIgqEaDGkhdewVWqpZiNgNLTWHAkti6yphk237B5oA5xT6O5wLHyjcGXOVSvRi5bogVabZJQ5cqx0ItrtQrABmPkzO6nCzJRuqWFOx6YQ1xN1lzRBMNa6idQjStiNmWMdyGHi%2FdYASxB4sawCI24GwrzfLlWf%2FANo2NpqIcfy7ItAcn2mvWMfnkInvipotn0NcmAD9MQu8FLR%2Fxs%2F7uaSN2nq1hpyejMpew0pqwTzNKKjYkMZKx47tjL5j8Lvn2%2BPtFA6VyJ14Q7wj8Wb3CJbHaaq%2BDwf8wel7iuIxdDqgWvZou5Oe5ZJr0Q%2F1ae5zKS6mQQtarG5SgT6PCztuN5GiCG1u3IjnQhJSV6HrDjQ3UOdauxMRV3gmRi1UuipMo2F6OcXLwtLMQVy5jCS4IzTLoM2CxDC403xuaTdktQByXicj32nKJ%2Bym0Oh8X28e3bnltVYbX6k1D1arJOBsEibssi6t3NDR1w3YBeI4uLinUymYc9ZJwBxRujjY9CNzZuUqSjLAnlIarFj2hon4DvdPwY4Cm8MOkyhjtJUByra547orZHXCpzgKKtPSXFFCKrpKJDO3mbCP9ha%2FXK2VWn4aGJjDUHE50QTjp2Gmtxkt3NpxAhs0Y7WXe8c0O1tKZhr42eZ61NQ4PqdPbdV8dX%2FYywsvlF05yIRGorwSJPKrNaFJ6iKaxX6oryMTEGxoHSFTNvIWWpWtQszUbqpbKyqVCy1AIts6NnpC3qY4CbPohTEW9NaFS%2FtTjbwTso8IAOEeY3vzJ2gnKcLP23%2FKnMcdBQQJgKrpFc0hJFLKNbJwnvNwMp3BsWbMvqx%2F3Hye%2BH3I%2FjJHDGanEmkZf47XGGEWzFruViqMyOTI667YSxmX9hCNNHmPk2pwQYUxxBi%2FCIEsRPMtPP0M%2BipykgYM%2FCM%2BPJaT00kURXu3yfsbBMgmX1DOfn1X9GlB5FB0kIKWuAe65%2BGLvHSX0almMsLMJDCeyCeScfv6wT%2FdEAyKimUz7YFkRebtSbpNNu7IPcs6F8zEZQaIh4L0gqUvww0j7vh7F%2FW9ujL7iR%2FfmYWy1QF0KOy2JxzmWSicnvP4nF93KumPJi9n4UMmQFxOKWea550bW3W9qcrPiuCZdz4yaJ4x1gVwcXb8SyAWwDTlsQmUijIxPogmYkeL%2B3%2BJkzff%2FXEi9%2Bx8%3D).
|
||||
##### Key slot access primitives
|
||||
|
||||
The state of a key slot is updated via the internal function `psa_key_slot_state_transition`. To change the state of `slot` from `expected_state` to `new_state`, when `new_state` is not `PSA_SLOT_EMPTY`, one must call `psa_key_slot_state_transition(slot, expected_state, new_state)`; if the state was not `expected_state` then `PSA_ERROR_CORRUPTION_DETECTED` is returned. The sole reason for having an expected state parameter here is to help guarantee that our functions work as expected, this error code cannot occur without an internal coding error.
|
||||
|
||||
Changing a slot's state to `PSA_SLOT_EMPTY` is done via `psa_wipe_key_slot`, this function wipes the entirety of the key slot.
|
||||
|
||||
The reader count of a slot is incremented via `psa_register_read`, and decremented via `psa_unregister_read`. Library functions register to read a slot via the `psa_get_and_lock_key_slot_X` functions, read from the slot, then call `psa_unregister_read` to make known that they have finished reading the slot's contents.
|
||||
|
||||
##### Key store consistency and abstraction function
|
||||
|
||||
The key store is protected by a single global mutex `mbedtls_threading_key_slot_mutex`.
|
||||
|
||||
We maintain the consistency of the key store by ensuring that all reads and writes to `slot->state` and `slot->registered_readers` are performed under `mbedtls_threading_key_slot_mutex`. All the access primitives described above must be called while the mutex is held; there is a convenience function `psa_unregister_read_under_mutex` which wraps a call to `psa_unregister_read` in a mutex lock/unlock pair.
|
||||
|
||||
A thread can only traverse the key store while holding `mbedtls_threading_key_slot_mutex`, the set of keys within the key store which the thread holding the mutex can access is equivalent to the set:
|
||||
|
||||
{mbedtls_svc_key_id_t k : (\exists slot := &global_data.key_slots[i]) [
|
||||
(slot->state == PSA_SLOT_FULL) &&
|
||||
(slot->attr.id == k)]}
|
||||
|
||||
The union of this set and the set of persistent keys not currently loaded into slots is our abstraction function for the key store, any key not in this union does not currently exist as far as the code is concerned (even if the key is in a slot which has a `PSA_SLOT_FILLING` or `PSA_SLOT_PENDING_DELETION` state). Attempting to start using any key which is not a member of the union will result in a `PSA_ERROR_INVALID_HANDLE` error code.
|
||||
|
||||
##### Locking and unlocking the mutex
|
||||
|
||||
If a lock or unlock operation fails and this is the first failure within a function, the function will return `PSA_ERROR_SERVICE_FAILURE`. If a lock or unlock operation fails after a different failure has been identified, the status code is not overwritten.
|
||||
|
||||
We have defined a set of macros in `library/psa_crypto_core.h` to capture the common pattern of (un)locking the mutex and returning or jumping to an exit label upon failure.
|
||||
|
||||
##### Key creation and loading
|
||||
|
||||
To load a new key into a slot, the following internal utility functions are used:
|
||||
|
||||
* `psa_reserve_free_key_slot` - This function, which must be called under `mbedtls_threading_key_slot_mutex`, iterates through the key store to find a slot whose state is `PSA_SLOT_EMPTY`. If found, it reserves the slot by setting its state to `PSA_SLOT_FILLING`. If not found, it will see if there are any persistent keys loaded which do not have any readers, if there are it will kick one such key out of the key store.
|
||||
* `psa_start_key_creation` - This function wraps around `psa_reserve_free_key_slot`, if a slot has been found then the slot id is set. This second step is not done under the mutex, at this point the calling thread has exclusive access to the slot.
|
||||
* `psa_finish_key_creation` - After the contents of the key have been loaded (again this loading is not done under the mutex), the thread calls `psa_finish_key_creation`. This function takes the mutex, checks that the key does not exist in the key store (this check cannot be done before this stage), sets the slot's state to `PSA_SLOT_FULL` and releases the mutex. Upon success, any thread is immediately able to use the new key.
|
||||
* `psa_fail_key_creation` - If there is a failure at any point in the key creation stage, this clean-up function takes the mutex, wipes the slot, and releases the mutex. Immediately after this unlock, any thread can start to use the slot for another key load.
|
||||
|
||||
##### Re-loading persistent keys
|
||||
|
||||
As described above, persistent keys can be kicked out of the key slot array provided they are not currently being used (`registered_readers == 0`). When attempting to use a persistent key that has been kicked out of a slot, the call to `psa_get_and_lock_key_slot` will see that the key is not in a slot, call `psa_reserve_free_key_slot` and load the key back into the reserved slot. This entire sequence is done during a single mutex lock, which is necessary for thread-safety (see documentation of `psa_get_and_lock_key_slot`).
|
||||
|
||||
If `psa_reserve_free_key_slot` cannot find a suitable slot, the key cannot be loaded back in. This will lead to a `PSA_ERROR_INSUFFICIENT_MEMORY` error.
|
||||
|
||||
##### Using existing keys
|
||||
|
||||
One-shot operations follow a standard pattern when using an existing key:
|
||||
|
||||
* They call one of the `psa_get_and_lock_key_slot_X` functions, which then finds the key and registers the thread as a reader.
|
||||
* They operate on the key slot, usually copying the key into a separate buffer to be used by the operation. This step is not performed under the key slot mutex.
|
||||
* Once finished, they call `psa_unregister_read_under_mutex`.
|
||||
|
||||
Multi-part and restartable operations each have a "setup" function where the key is passed in, these functions follow the above pattern. The key is copied into the `operation` object, and the thread unregisters from reading the key (the operations do not access the key slots again). The copy of the key will not be destroyed during a call to `psa_destroy_key`, the thread running the operation is responsible for deleting its copy in the clean-up. This may need to change to enforce the long term key requirements ([Long term key destruction requirements](#long-term-key-destruction-requirements)).
|
||||
|
||||
##### Key destruction implementation
|
||||
|
||||
The locking strategy here is explained in `library/psa_crypto.c`. The destroying thread (the thread calling `psa_destroy_key`) does not always wipe the key slot. The destroying thread registers to read the key, sets the slot's state to `PSA_SLOT_PENDING_DELETION`, wipes the slot from memory if the key is persistent, and then unregisters from reading the slot.
|
||||
|
||||
`psa_unregister_read` internally calls `psa_wipe_key_slot` if and only if the slot's state is `PSA_SLOT_PENDING_DELETION` and the slot's registered reader counter is equal to 1. This implements a "last one out closes the door" approach. The final thread to unregister from reading a destroyed key will automatically wipe the contents of the slot; no readers remain to reference the slot post deletion, so there cannot be corruption.
|
||||
|
||||
### linearizability of the system
|
||||
|
||||
To satisfy the requirements in [Correctness out of the box](#correctness-out-of-the-box), we require our functions to be "linearizable" (under certain constraints). This means that any (constraint satisfying) set of concurrent calls are performed as if they were executed in some sequential order.
|
||||
|
||||
The standard way of reasoning that this is the case is to identify a "linearization point" for each call, this is a single execution step where the function takes effect (this is usually a step in which the effects of the call become visible to other threads). If every call has a linearization point, the set of calls is equivalent to sequentially performing the calls in order of when their linearization point occurred.
|
||||
|
||||
We only require linearizability to hold in the case where a resource-management error is not returned. In a set of concurrent calls, it is permitted for a call c to fail with a `PSA_ERROR_INSUFFICIENT_MEMORY` return code even if there does not exist a sequential ordering of the calls in which c returns this error. Even if such an error occurs, all calls are still required to be functionally correct.
|
||||
|
||||
To help justify that our system is linearizable, here are the linearization points/planned linearization points of each PSA call :
|
||||
|
||||
* Key creation functions (including `psa_copy_key`) - The linearization point for a successful call is the mutex unlock within `psa_finish_key_creation`; it is at this point that the key becomes visible to other threads. The linearization point for a failed call is the closest mutex unlock after the failure is first identified.
|
||||
* `psa_destroy_key` - The linearization point for a successful destruction is the mutex unlock, the slot is now in the state `PSA_SLOT_PENDING_DELETION` meaning that the key has been destroyed. For failures, the linearization point is the same.
|
||||
* `psa_purge_key`, `psa_close_key` - The linearization point is the mutex unlock after wiping the slot for a success, or unregistering for a failure.
|
||||
* One shot operations - The linearization point is the final unlock of the mutex within `psa_get_and_lock_key_slot`, as that is the point in which it is decided whether or not the key exists.
|
||||
* Multi-part operations - The linearization point of the key input function is the final unlock of the mutex within `psa_get_and_lock_key_slot`. All other steps have no non resource-related side effects (except for key derivation, covered in the key creation functions).
|
||||
|
||||
Please note that one shot operations and multi-part operations are not yet considered thread-safe, as we have not yet tested whether they rely on unprotected global resources. The key slot access in these operations is thread-safe.
|
||||
|
||||
## Testing and analysis
|
||||
|
||||
### Thread-safe testing
|
||||
|
||||
It is now possible for individual tests to spin up multiple threads. This work has made the global variables used in tests thread-safe. If multiple threads fail a test assert, the first failure will be reported with correct line numbers.
|
||||
|
||||
Although the `step` feature used in some tests is thread-safe, it may produce unexpected results for multi-threaded tests. `mbedtls_test_set_step` or `mbedtls_test_increment_step` calls within threads can happen in any order, thus may not produce the desired result when precise ordering is required.
|
||||
|
||||
### Current state of testing
|
||||
|
||||
Our testing is a work in progress. It is not feasible to run our traditional, single-threaded, tests in such a way that tests concurrency. We need to write new test suites for concurrency testing.
|
||||
|
||||
Our tests currently only run on pthread, we hope to expand this in the future (our API already allows this).
|
||||
|
||||
We run tests using [ThreadSanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html) to detect data races. We test the key store, and test that our key slot state system is enforced. We also test the thread-safety of `psa_crypto_init`.
|
||||
|
||||
Currently, not every API call is tested, we also cannot feasibly test every combination of concurrent API calls. API calls can in general be split into a few categories, each category calling the same internal key management functions in the same order - it is the internal functions that are in charge of locking mutexes and interacting with the key store; we test the thread-safety of these functions.
|
||||
|
||||
Since we do not run every cryptographic operation concurrently, we do not test that operations are free of unexpected global variables.
|
||||
|
||||
### Expanding testing
|
||||
|
||||
Through future work on testing, it would be good to:
|
||||
|
||||
* For every API call, have a test which runs multiple copies of the call simultaneously.
|
||||
* After implementing other threading platforms, expand the tests to these platforms.
|
||||
* Have increased testing for kicking persistent keys out of slots.
|
||||
* Explicitly test that all global variables are protected, for this we would need to cover every operation in a concurrent scenario while running ThreadSanitizer.
|
||||
* Run tests on more threading implementations, once these implementations are supported.
|
||||
|
||||
### Performance
|
||||
|
||||
Key loading does somewhat run in parallel, deriving the key and copying it key into the slot is not done under any mutex.
|
||||
|
||||
Key destruction is entirely sequential, this is required for persistent keys to stop issues with re-loading keys which cannot otherwise be avoided without changing our approach to thread-safety.
|
||||
|
||||
|
||||
## Future work
|
||||
|
||||
### Long term requirements
|
||||
|
||||
As explained previously, we eventually aim to make the entirety of the PSA API thread-safe. This will build on the work that we have already completed. This requires a full suite of testing, see [Expanding testing](#expanding-testing) for details.
|
||||
|
||||
### Long term performance requirements
|
||||
|
||||
Our plan for cryptographic operations is that they are not performed under any global mutex. One-shot operations and multi-part operations will each only hold the global mutex for finding the relevant key in the key slot, and unregistering as a reader after the operation, using their own operation-specific mutexes to guard any shared data that they use.
|
||||
|
||||
We aim to eventually replace some/all of the mutexes with RWLocks, if possible.
|
||||
|
||||
### Long term key destruction requirements
|
||||
|
||||
The [PSA Crypto Key destruction specification](https://arm-software.github.io/psa-api/crypto/1.1/api/keys/management.html#key-destruction) mandates that implementations make a best effort to ensure that the key material cannot be recovered. In the long term, it would be good to guarantee that `psa_destroy_key` wipes all copies of the key material.
|
||||
|
||||
Here are our long term key destruction goals:
|
||||
|
||||
`psa_destroy_key` does not block indefinitely, and when `psa_destroy_key` returns:
|
||||
|
||||
1. The key identifier does not exist. This is a functional requirement for persistent keys: any thread can immediately create a new key with the same identifier.
|
||||
2. The resources from the key have been freed. This allows threads to create similar keys immediately after destruction, regardless of resources.
|
||||
4. No copy of the key material exists. Rationale: this is a security requirement. We do not have this requirement yet, but we need to document this as a security weakness, and we would like to satisfy this security requirement in the future.
|
||||
|
||||
#### Condition variables
|
||||
|
||||
It would be ideal to add these to a future major version; we cannot add these as requirements to the default `MBEDTLS_THREADING_C` for backwards compatibility reasons.
|
||||
|
||||
Condition variables would enable us to fulfil the final requirement in [Long term key destruction requirements](#long-term-key-destruction-requirements). Destruction would then work as follows:
|
||||
|
||||
* When a thread calls `psa_destroy_key`, they continue as normal until the `psa_unregister_read` call.
|
||||
* Instead of calling `psa_unregister_read`, the thread waits until the condition `slot->registered_readers == 1` is true (the destroying thread is the final reader).
|
||||
* At this point, the destroying thread directly calls `psa_wipe_key_slot`.
|
||||
|
||||
A few changes are needed for this to follow our destruction requirements:
|
||||
|
||||
* Multi-part operations will need to remain registered as readers of their key slot until their copy of the key is destroyed, i.e. at the end of the finish/abort call.
|
||||
* The functionality where `psa_unregister_read` can wipe the key slot will need to be removed, slot wiping is now only done by the destroying/wiping thread.
|
||||
|
||||
### Protecting operation contexts
|
||||
|
||||
Currently, we rely on the crypto service to ensure that the same operation is not invoked concurrently. This abides by the PSA Crypto API Specification ([PSA Concurrent calling conventions](#psa-concurrent-calling-conventions)).
|
||||
|
||||
Concurrent access to the same operation object can compromise the crypto service. For example, if the operation context has a pointer (depending on the compiler and the platform, the pointer assignment may or may not be atomic). This violates the functional correctness requirement of the crypto service.
|
||||
|
||||
If, in future, we want to protect against this within the library then operations will require a status field protected by a global mutex. On entry, API calls would check the state and return an error if the state is ACTIVE. If the state is INACTIVE, then the call will set the state to ACTIVE, do the operation section and then restore the state to INACTIVE before returning.
|
||||
|
||||
### Future driver work
|
||||
|
||||
A future policy we may wish to enforce for drivers is:
|
||||
|
||||
* By default, each driver only has at most one entry point active at any given time. In other words, each driver has its own exclusive lock.
|
||||
* Drivers have an optional `"thread_safe"` boolean property. If true, it allows concurrent calls to this driver.
|
||||
* Even with a thread-safe driver, the core never starts the destruction of a key while there are operations in progress on it, and never performs concurrent calls on the same multipart operation.
|
||||
|
||||
In the non-thread-safe case we have these natural assumptions/requirements:
|
||||
|
||||
1. Drivers don't call the core for any operation for which they provide an entry point.
|
||||
2. The core doesn't hold the driver mutex between calls to entry points.
|
||||
|
||||
With these, the only way of a deadlock is when there are several drivers with circular dependencies. That is, Driver A makes a call that is dispatched to Driver B; upon executing this call Driver B makes a call that is dispatched to Driver A. For example Driver A does CCM, which calls driver B to do CBC-MAC, which in turn calls Driver A to perform AES.
|
||||
|
||||
Potential ways for resolving this:
|
||||
|
||||
1. Non-thread-safe drivers must not call the core.
|
||||
2. Provide a new public API that drivers can safely call.
|
||||
3. Make the dispatch layer public for drivers to call.
|
||||
4. There is a whitelist of core APIs that drivers can call. Drivers providing entry points to these must not make a call to the core when handling these calls. (Drivers are still allowed to call any core API that can't have a driver entry point.)
|
||||
|
||||
The first is too restrictive, the second and the third would require making it a stable API, and would likely increase the code size for a relatively rare feature. We are choosing the fourth as that is the most viable option.
|
||||
|
||||
**Thread-safe drivers:**
|
||||
|
||||
A driver would be non-thread-safe if the `thread-safe` property is set to true.
|
||||
|
||||
To make re-entrancy in non-thread-safe drivers work, thread-safe drivers must not make a call to the core when handling a call that is on the non-thread-safe driver core API whitelist.
|
||||
|
||||
Thread-safe drivers have fewer guarantees from the core and need to implement more complex logic. We can reasonably expect them to be more flexible in terms of re-entrancy as well. At this point it is hard to see what further guarantees would be useful and feasible. Therefore, we don't provide any further guarantees for now.
|
||||
|
||||
Thread-safe drivers must not make any assumption about the operation of the core beyond what is discussed here.
|
||||
@@ -1,597 +0,0 @@
|
||||
# Mbed TLS driver interface test strategy
|
||||
|
||||
This document describes the test strategy for the driver interfaces in Mbed TLS. Mbed TLS has interfaces for secure element drivers, accelerator drivers and entropy drivers. This document is about testing Mbed TLS itself; testing drivers is out of scope.
|
||||
|
||||
The driver interfaces are standardized through PSA Cryptography functional specifications.
|
||||
|
||||
## Secure element driver interface testing
|
||||
|
||||
### Secure element driver interfaces
|
||||
|
||||
#### Opaque driver interface
|
||||
|
||||
The [unified driver interface](../../proposed/psa-driver-interface.md) supports both transparent drivers (for accelerators) and opaque drivers (for secure elements).
|
||||
|
||||
Drivers exposing this interface need to be registered at compile time by declaring their JSON description file.
|
||||
|
||||
#### Dynamic secure element driver interface
|
||||
|
||||
The dynamic secure element driver interface (SE interface for short) is defined by [`psa/crypto_se_driver.h`](../../../tf-psa-crypto/include/psa/crypto_se_driver.h). This is an interface between Mbed TLS and one or more third-party drivers.
|
||||
|
||||
The SE interface consists of one function provided by Mbed TLS (`psa_register_se_driver`) and many functions that drivers must implement. To make a driver usable by Mbed TLS, the initialization code must call `psa_register_se_driver` with a structure that describes the driver. The structure mostly contains function pointers, pointing to the driver's methods. All calls to a driver function are triggered by a call to a PSA crypto API function.
|
||||
|
||||
### SE driver interface unit tests
|
||||
|
||||
This section describes unit tests that must be implemented to validate the secure element driver interface. Note that a test case may cover multiple requirements; for example a “good case” test can validate that the proper function is called, that it receives the expected inputs and that it produces the expected outputs.
|
||||
|
||||
Many SE driver interface unit tests could be covered by running the existing API tests with a key in a secure element.
|
||||
|
||||
#### SE driver registration
|
||||
|
||||
This applies to dynamic drivers only.
|
||||
|
||||
* Test `psa_register_se_driver` with valid and with invalid arguments.
|
||||
* Make at least one failing call to `psa_register_se_driver` followed by a successful call.
|
||||
* Make at least one test that successfully registers the maximum number of drivers and fails to register one more.
|
||||
|
||||
#### Dispatch to SE driver
|
||||
|
||||
For each API function that can lead to a driver call (more precisely, for each driver method call site, but this is practically equivalent):
|
||||
|
||||
* Make at least one test with a key in a secure element that checks that the driver method is called. A few API functions involve multiple driver methods; these should validate that all the expected driver methods are called.
|
||||
* Make at least one test with a key that is not in a secure element that checks that the driver method is not called.
|
||||
* Make at least one test with a key in a secure element with a driver that does not have the requisite method (i.e. the method pointer is `NULL`) but has the substructure containing that method, and check that the return value is `PSA_ERROR_NOT_SUPPORTED`.
|
||||
* Make at least one test with a key in a secure element with a driver that does not have the substructure containing that method (i.e. the pointer to the substructure is `NULL`), and check that the return value is `PSA_ERROR_NOT_SUPPORTED`.
|
||||
* At least one test should register multiple drivers with a key in each driver and check that the expected driver is called. This does not need to be done for all operations (use a white-box approach to determine if operations may use different code paths to choose the driver).
|
||||
* At least one test should register the same driver structure with multiple lifetime values and check that the driver receives the expected lifetime value.
|
||||
|
||||
Some methods only make sense as a group (for example a driver that provides the MAC methods must provide all or none). In those cases, test with all of them null and none of them null.
|
||||
|
||||
#### SE driver inputs
|
||||
|
||||
For each API function that can lead to a driver call (more precisely, for each driver method call site, but this is practically equivalent):
|
||||
|
||||
* Wherever the specification guarantees parameters that satisfy certain preconditions, check these preconditions whenever practical.
|
||||
* If the API function can take parameters that are invalid and must not reach the driver, call the API function with such parameters and verify that the driver method is not called.
|
||||
* Check that the expected inputs reach the driver. This may be implicit in a test that checks the outputs if the only realistic way to obtain the correct outputs is to start from the expected inputs (as is often the case for cryptographic material, but not for metadata).
|
||||
|
||||
#### SE driver outputs
|
||||
|
||||
For each API function that leads to a driver call, call it with parameters that cause a driver to be invoked and check how Mbed TLS handles the outputs.
|
||||
|
||||
* Correct outputs.
|
||||
* Incorrect outputs such as an invalid output length.
|
||||
* Expected errors (e.g. `PSA_ERROR_INVALID_SIGNATURE` from a signature verification method).
|
||||
* Unexpected errors. At least test that if the driver returns `PSA_ERROR_GENERIC_ERROR`, this is propagated correctly.
|
||||
|
||||
Key creation functions invoke multiple methods and need more complex error handling:
|
||||
|
||||
* Check the consequence of errors detected at each stage (slot number allocation or validation, key creation method, storage accesses).
|
||||
* Check that the storage ends up in the expected state. At least make sure that no intermediate file remains after a failure.
|
||||
|
||||
#### Persistence of SE keys
|
||||
|
||||
The following tests must be performed at least one for each key creation method (import, generate, ...).
|
||||
|
||||
* Test that keys in a secure element survive `psa_close_key(); psa_open_key()`.
|
||||
* Test that keys in a secure element survive `mbedtls_psa_crypto_free(); psa_crypto_init()`.
|
||||
* Test that the driver's persistent data survives `mbedtls_psa_crypto_free(); psa_crypto_init()`.
|
||||
* Test that `psa_destroy_key()` does not leave any trace of the key.
|
||||
|
||||
#### Resilience for SE drivers
|
||||
|
||||
Creating or removing a key in a secure element involves multiple storage modifications (M<sub>1</sub>, ..., M<sub>n</sub>). If the operation is interrupted by a reset at any point, it must be either rolled back or completed.
|
||||
|
||||
* For each potential interruption point (before M<sub>1</sub>, between M<sub>1</sub> and M<sub>2</sub>, ..., after M<sub>n</sub>), call `mbedtls_psa_crypto_free(); psa_crypto_init()` at that point and check that this either rolls back or completes the operation that was started.
|
||||
* This must be done for each key creation method and for key destruction.
|
||||
* This must be done for each possible flow, including error cases (e.g. a key creation that fails midway due to `OUT_OF_MEMORY`).
|
||||
* The recovery during `psa_crypto_init` can itself be interrupted. Test those interruptions too.
|
||||
* Two things need to be tested: the key that is being created or destroyed, and the driver's persistent storage.
|
||||
* Check both that the storage has the expected content (this can be done by e.g. using a key that is supposed to be present) and does not have any unexpected content (for keys, this can be done by checking that `psa_open_key` fails with `PSA_ERROR_DOES_NOT_EXIST`).
|
||||
|
||||
This requires instrumenting the storage implementation, either to force it to fail at each point or to record successive storage states and replay each of them. Each `psa_its_xxx` function call is assumed to be atomic.
|
||||
|
||||
### SE driver system tests
|
||||
|
||||
#### Real-world use case
|
||||
|
||||
We must have at least one driver that is close to real-world conditions:
|
||||
|
||||
* With its own source tree.
|
||||
* Running on actual hardware.
|
||||
* Run the full driver validation test suite (which does not yet exist).
|
||||
* Run at least one test application (e.g. the Mbed OS TLS example).
|
||||
|
||||
This requirement shall be fulfilled by the [Microchip ATECC508A driver](https://github.com/ARMmbed/mbed-os-atecc608a/).
|
||||
|
||||
#### Complete driver
|
||||
|
||||
We should have at least one driver that covers the whole interface:
|
||||
|
||||
* With its own source tree.
|
||||
* Implementing all the methods.
|
||||
* Run the full driver validation test suite (which does not yet exist).
|
||||
|
||||
A PKCS#11 driver would be a good candidate. It would be useful as part of our product offering.
|
||||
|
||||
## Unified driver interface testing
|
||||
|
||||
The [unified driver interface](../../proposed/psa-driver-interface.md) defines interfaces for accelerators.
|
||||
|
||||
### Test requirements
|
||||
|
||||
#### Requirements for transparent driver testing
|
||||
|
||||
Every cryptographic mechanism for which a transparent driver interface exists (key creation, cryptographic operations, …) must be exercised in at least one build. The test must verify that the driver code is called.
|
||||
|
||||
#### Requirements for fallback
|
||||
|
||||
The driver interface includes a fallback mechanism so that a driver can reject a request at runtime and let another driver handle the request. For each entry point, there must be at least three test runs with two or more drivers available with driver A configured to fall back to driver B, with one run where A returns `PSA_SUCCESS`, one where A returns `PSA_ERROR_NOT_SUPPORTED` and B is invoked, and one where A returns a different error and B is not invoked.
|
||||
|
||||
### Test drivers
|
||||
|
||||
We have test drivers that are enabled by `PSA_CRYPTO_DRIVER_TEST` (not present
|
||||
in the usual config files, must be defined on the command line or in a custom
|
||||
config file). Those test drivers are implemented in `framework/tests/src/drivers/*.c`
|
||||
and their API is declared in `framework/tests/include/test/drivers/*.h`.
|
||||
|
||||
We have two test driver registered: `mbedtls_test_opaque_driver` and
|
||||
`mbedtls_test_transparent_driver`. These are described in
|
||||
`scripts/data_files/driver_jsons/mbedtls_test_xxx_driver.json` (as much as our
|
||||
JSON support currently allows). Each of the drivers can potentially implement
|
||||
support for several mechanism; conversely, each of the file mentioned in the
|
||||
previous paragraph can potentially contribute to both the opaque and the
|
||||
transparent test driver.
|
||||
|
||||
Each entry point is instrumented to record the number of hits for each part of
|
||||
the driver (same division as the files) and the status of the last call. It is
|
||||
also possible to force the next call to return a specified status, and
|
||||
sometimes more things can be forced: see the various
|
||||
`mbedtls_test_driver_XXX_hooks_t` structures declared by each driver (and
|
||||
subsections below).
|
||||
|
||||
The drivers can use one of two back-ends:
|
||||
- internal: this requires the built-in implementation to be present.
|
||||
- libtestdriver1: this allows the built-in implementation to be omitted from
|
||||
the build.
|
||||
|
||||
Historical note: internal was initially the only back-end; then support for
|
||||
libtestdriver1 was added gradually. Support for libtestdriver1 is now complete
|
||||
(see following sub-sections), so we could remove internal now. Note it's
|
||||
useful to have builds with both a driver and the built-in, in order to test
|
||||
fallback to built-in, which is currently done only with internal, but this can
|
||||
be achieved with libtestdriver1 just as well.
|
||||
|
||||
Note on instrumentation: originally, when only the internal backend was
|
||||
available, hits were how we knew that the driver was called, as opposed to
|
||||
directly calling the built-in code. With libtestdriver1, we can check that by
|
||||
ensuring that the built-in code is not present, so if the operation gives the
|
||||
correct result, only a driver call can have calculated that result. So,
|
||||
nowadays there is low value in checking the hit count. There is still some
|
||||
value for hit counts, e.g. checking that we don't call a multipart entry point
|
||||
when we intended to call the one-shot entry point, but it's limited.
|
||||
|
||||
Note: our test drivers tend to provide all possible entry points (with a few
|
||||
exceptions that may not be intentional, see the next sections). However, in
|
||||
some cases, when an entry point is not available, the core is supposed to
|
||||
implement it using other entry points, for example:
|
||||
- `mac_verify` may use `mac_compute` if the driver does no provide verify;
|
||||
- for things that have both one-shot and multi-part API, the driver can
|
||||
provide only the multi-part entry points, and the core is supposed to
|
||||
implement one-shot on top of it (but still call the one-shot entry points when
|
||||
they're available);
|
||||
- `sign/verify_message` can be implemented on top of `sign/verify_hash` for
|
||||
some algorithms;
|
||||
- (not sure if the list is exhaustive).
|
||||
|
||||
Ideally, we'd want build options for the test drivers so that we can test with
|
||||
different combinations of entry points present, and make sure the core behaves
|
||||
appropriately when some entry points are absent but other entry points allow
|
||||
implementing the operation. This will remain hard to test until we have proper
|
||||
support for JSON-defined drivers with auto-generation of dispatch code.
|
||||
(The `MBEDTLS_PSA_ACCEL_xxx` macros we currently use are not expressive enough
|
||||
to specify which entry points are supported for a given mechanism.)
|
||||
|
||||
Our implementation of PSA Crypto is structured in a way that the built-in
|
||||
implementation of each operation follows the driver API, see
|
||||
[`../architecture/psa-crypto-implementation-structure.md`](../architecture/psa-crypto-implementation-structure.html).
|
||||
This makes implementing the test drivers very easy: each entry point has a
|
||||
corresponding `mbedtls_psa_xxx()` function that it can call as its
|
||||
implementation - with the `libtestdriver1` back-end the function is called
|
||||
`libtestdriver1_mbedtls_psa_xxx()` instead.
|
||||
|
||||
A nice consequence of that strategy is that when an entry point has
|
||||
test-driver support, most of the time, it automatically works for all
|
||||
algorithms and key types supported by the library. (The exception being when
|
||||
the driver needs to call a different function for different key types, as is
|
||||
the case with some asymmetric key management operations.) (Note: it's still
|
||||
useful to test drivers in configurations with partial algorithm support, and
|
||||
that can still be done by configuring libtestdriver1 and the main library as
|
||||
desired.)
|
||||
|
||||
The renaming process for `libtestdriver1` is implemented as a few Perl regexes
|
||||
applied to a copy of the library code, see the `libtestdriver1.a` target in
|
||||
`tests/Makefile`. Another modification that's done to this copy is appending
|
||||
`tests/configs/crypto_config_test_driver_extension.h` to `psa/crypto_config.h`.
|
||||
This file reverses the `ACCEL`/`BUILTIN` macros so that `libtestdriver1`
|
||||
includes as built-in what the main `libmbedcrypto.a` will have accelerated;
|
||||
see that file's initial comment for details. See also `helper_libtestdriver1_`
|
||||
functions and the preceding comment in `all.sh` for how libtestdriver is used
|
||||
in practice.
|
||||
|
||||
This general framework needs specific code for each family of operations. At a
|
||||
given point in time, not all operations have the same level of support. The
|
||||
following sub-sections describe the status of the test driver support, mostly
|
||||
following the structure and order of sections 9.6 and 10.2 to 10.10 of the
|
||||
[PSA Crypto standard](https://arm-software.github.io/psa-api/crypto/1.1/) as
|
||||
that is also a natural division for implementing test drivers (that's how the
|
||||
code is divided into files).
|
||||
|
||||
#### Key management
|
||||
|
||||
The following entry points are declared in `test/drivers/key_management.h`:
|
||||
|
||||
- `"init"` (transparent and opaque)
|
||||
- `"generate_key"` (transparent and opaque)
|
||||
- `"export_public_key"` (transparent and opaque)
|
||||
- `"import_key"` (transparent and opaque)
|
||||
- `"export_key"` (opaque only)
|
||||
- `"get_builtin_key"` (opaque only)
|
||||
- `"copy_key"` (opaque only)
|
||||
|
||||
The transparent driver fully implements the declared entry points, and can use
|
||||
any backend: internal or libtestdriver1.
|
||||
|
||||
The opaque's driver implementation status is as follows:
|
||||
- `"generate_key"`: not implemented, always returns `NOT_SUPPORTED`.
|
||||
- `"export_public_key"`: implemented only for ECC and RSA keys, both backends.
|
||||
- `"import_key"`: implemented except for DH keys, both backends.
|
||||
- `"export_key"`: implemented for built-in keys (ECC and AES), and for
|
||||
non-builtin keys except DH keys. (Backend not relevant.)
|
||||
- `"get_builtin_key"`: implemented - provisioned keys: AES-128 and ECC
|
||||
secp2456r1. (Backend not relevant.)
|
||||
- `"copy_key"`: implemented - emulates a SE without storage. (Backend not
|
||||
relevant.)
|
||||
|
||||
Note: the `"init"` entry point is not part of the "key management" family, but
|
||||
listed here as it's declared and implemented in the same file. With the
|
||||
transparent driver and the libtestdriver1 backend, it calls
|
||||
`libtestdriver1_psa_crypto_init()`, which partially but not fully ensures
|
||||
that this entry point is called before other entry points in the test drivers.
|
||||
With the opaque driver, this entry point just does nothing an returns success.
|
||||
|
||||
The following entry points are defined by the driver interface but missing
|
||||
from our test drivers:
|
||||
- `"allocate_key"`, `"destroy_key"`: this is for opaque drivers that store the
|
||||
key material internally.
|
||||
|
||||
Note: the instrumentation also allows forcing the output and its length.
|
||||
|
||||
#### Message digests (Hashes)
|
||||
|
||||
The following entry points are declared (transparent only):
|
||||
- `"hash_compute"`
|
||||
- `"hash_setup"`
|
||||
- `"hash_clone"`
|
||||
- `"hash_update"`
|
||||
- `"hash_finish"`
|
||||
- `"hash_abort"`
|
||||
|
||||
The transparent driver fully implements the declared entry points, and can use
|
||||
any backend: internal or libtestdriver1.
|
||||
|
||||
This family is not part of the opaque driver as it doesn't use keys.
|
||||
|
||||
#### Message authentication codes (MAC)
|
||||
|
||||
The following entry points are declared (transparent and opaque):
|
||||
- `"mac_compute"`
|
||||
- `"mac_sign_setup"`
|
||||
- `"mac_verify_setup"`
|
||||
- `"mac_update"`
|
||||
- `"mac_sign_finish"`
|
||||
- `"mac_verify_finish"`
|
||||
- `"mac_abort"`
|
||||
|
||||
The transparent driver fully implements the declared entry points, and can use
|
||||
any backend: internal or libtestdriver1.
|
||||
|
||||
The opaque driver only implements the instrumentation but not the actual
|
||||
operations: entry points will always return `NOT_SUPPORTED`, unless another
|
||||
status is forced.
|
||||
|
||||
The following entry points are not implemented:
|
||||
- `mac_verify`: this mostly makes sense for opaque drivers; the core will fall
|
||||
back to using `"mac_compute"` if this is not implemented. So, perhaps
|
||||
ideally we should test both with `"mac_verify"` implemented and with it not
|
||||
implemented? Anyway, we have a test gap here.
|
||||
|
||||
#### Unauthenticated ciphers
|
||||
|
||||
The following entry points are declared (transparent and opaque):
|
||||
- `"cipher_encrypt"`
|
||||
- `"cipher_decrypt"`
|
||||
- `"cipher_encrypt_setup"`
|
||||
- `"cipher_decrypt_setup"`
|
||||
- `"cipher_set_iv"`
|
||||
- `"cipher_update"`
|
||||
- `"cipher_finish"`
|
||||
- `"cipher_abort"`
|
||||
|
||||
The transparent driver fully implements the declared entry points, and can use
|
||||
any backend: internal or libtestdriver1.
|
||||
|
||||
The opaque driver is not implemented at all, neither instumentation nor the
|
||||
operation: entry points always return `NOT_SUPPORTED`.
|
||||
|
||||
Note: the instrumentation also allows forcing a specific output and output
|
||||
length.
|
||||
|
||||
#### Authenticated encryption with associated data (AEAD)
|
||||
|
||||
The following entry points are declared (transparent only):
|
||||
- `"aead_encrypt"`
|
||||
- `"aead_decrypt"`
|
||||
- `"aead_encrypt_setup"`
|
||||
- `"aead_decrypt_setup"`
|
||||
- `"aead_set_nonce"`
|
||||
- `"aead_set_lengths"`
|
||||
- `"aead_update_ad"`
|
||||
- `"aead_update"`
|
||||
- `"aead_finish"`
|
||||
- `"aead_verify"`
|
||||
- `"aead_abort"`
|
||||
|
||||
The transparent driver fully implements the declared entry points, and can use
|
||||
any backend: internal or libtestdriver1.
|
||||
|
||||
The opaque driver does not implement or even declare entry points for this
|
||||
family.
|
||||
|
||||
Note: the instrumentation records the number of hits per entry point, not just
|
||||
the total number of hits for this family.
|
||||
|
||||
#### Key derivation
|
||||
|
||||
Not covered at all by the test drivers.
|
||||
|
||||
That's a test gap which reflects a feature gap: the driver interface does
|
||||
define a key derivation family of entry points, but we don't currently
|
||||
implement that part of the driver interface, see #5488 and related issues.
|
||||
|
||||
#### Asymmetric signature
|
||||
|
||||
The following entry points are declared (transparent and opaque):
|
||||
|
||||
- `"sign_message"`
|
||||
- `"verify_message"`
|
||||
- `"sign_hash"`
|
||||
- `"verify_hash"`
|
||||
|
||||
The transparent driver fully implements the declared entry points, and can use
|
||||
any backend: internal or libtestdriver1.
|
||||
|
||||
The opaque driver is not implemented at all, neither instumentation nor the
|
||||
operation: entry points always return `NOT_SUPPORTED`.
|
||||
|
||||
Note: the instrumentation also allows forcing a specific output and output
|
||||
length, and has two instance of the hooks structure: one for sign, the other
|
||||
for verify.
|
||||
|
||||
Note: when a driver implements only the `"xxx_hash"` entry points, the core is
|
||||
supposed to implement the `psa_xxx_message()` functions by computing the hash
|
||||
itself before calling the `"xxx_hash"` entry point. Since the test driver does
|
||||
implement the `"xxx_message"` entry point, it's not exercising that part of
|
||||
the core's expected behaviour.
|
||||
|
||||
#### Asymmetric encryption
|
||||
|
||||
The following entry points are declared (transparent and opaque):
|
||||
|
||||
- `"asymmetric_encrypt"`
|
||||
- `"asymmetric_decrypt"`
|
||||
|
||||
The transparent driver fully implements the declared entry points, and can use
|
||||
any backend: internal or libtestdriver1.
|
||||
|
||||
The opaque driver implements the declared entry points, and can use any
|
||||
backend: internal or libtestdriver1. However it does not implement the
|
||||
instrumentation (hits, forced output/status), as this [was not an immediate
|
||||
priority](https://github.com/Mbed-TLS/mbedtls/pull/8700#issuecomment-1892466159).
|
||||
|
||||
Note: the instrumentation also allows forcing a specific output and output
|
||||
length.
|
||||
|
||||
#### Key agreement
|
||||
|
||||
The following entry points are declared (transparent and opaque):
|
||||
|
||||
- `"key_agreement"`
|
||||
|
||||
The transparent driver fully implements the declared entry points, and can use
|
||||
any backend: internal or libtestdriver1.
|
||||
|
||||
The opaque driver is not implemented at all, neither instumentation nor the
|
||||
operation: entry points always return `NOT_SUPPORTED`.
|
||||
|
||||
Note: the instrumentation also allows forcing a specific output and output
|
||||
length.
|
||||
|
||||
#### Other cryptographic services (Random number generation)
|
||||
|
||||
Not covered at all by the test drivers.
|
||||
|
||||
The driver interface defines a `"get_entropy"` entry point, as well as a
|
||||
"Random generation" family of entry points. None of those are currently
|
||||
implemented in the library. Part of it will be planned for 4.0, see #8150.
|
||||
|
||||
#### PAKE extension
|
||||
|
||||
The following entry points are declared (transparent only):
|
||||
- `"pake_setup"`
|
||||
- `"pake_output"`
|
||||
- `"pake_input"`
|
||||
- `"pake_get_implicit_key"`
|
||||
- `"pake_abort"`
|
||||
|
||||
Note: the instrumentation records hits per entry point and allows forcing the
|
||||
output and its length, as well as forcing the status of setup independently
|
||||
from the others.
|
||||
|
||||
The transparent driver fully implements the declared entry points, and can use
|
||||
any backend: internal or libtestdriver1.
|
||||
|
||||
The opaque driver does not implement or even declare entry points for this
|
||||
family.
|
||||
|
||||
### Driver wrapper test suite
|
||||
|
||||
We have a test suite dedicated to driver dispatch, which takes advantage of the
|
||||
instrumentation in the test drivers described in the previous section, in
|
||||
order to check that drivers are called when they're supposed to, and that the
|
||||
core behaves as expected when they return errors (in particular, that we fall
|
||||
back to the built-in implementation when the driver returns `NOT_SUPPORTED`).
|
||||
|
||||
This is `test_suite_psa_crypto_driver_wrappers`, which is maintained manually
|
||||
(that is, the test cases in the `.data` files are not auto-generated). The
|
||||
entire test suite depends on the test drivers being enabled
|
||||
(`PSA_CRYPTO_DRIVER_TEST`), which is not the case in the default or full
|
||||
config.
|
||||
|
||||
The test suite is focused on driver usage (mostly by checking the expected
|
||||
number of hits) but also does some validation of the results: for
|
||||
deterministic algorithms, known-answers tests are used, and for the rest, some
|
||||
consistency checks are done (more or less detailed depending on the algorithm
|
||||
and build configuration).
|
||||
|
||||
#### Configurations coverage
|
||||
|
||||
The driver wrappers test suite has cases that expect both the driver and the
|
||||
built-in to be present, and also cases that expect the driver to be present
|
||||
but not the built-in. As such, it's impossible for a single configuration to
|
||||
run all test cases, and we need at least two: driver+built-in, and
|
||||
driver-only.
|
||||
|
||||
- The driver+built-in case is covered by `test_psa_crypto_drivers` in `all.sh`.
|
||||
This covers all areas (key types and algs) at once.
|
||||
- The driver-only case is split into multiple `all.sh` components whose names
|
||||
start with `test_psa_crypto_config_accel`; we have one or more component per
|
||||
area, see below.
|
||||
|
||||
Here's a summary of driver-only coverage, grouped by families of key types.
|
||||
|
||||
Hash (key types: none)
|
||||
- `test_psa_crypto_config_accel_hash`: all algs, default config, no parity
|
||||
testing.
|
||||
- `test_psa_crypto_config_accel_hash_use_psa`: all algs, full config, with
|
||||
parity testing.
|
||||
|
||||
HMAC (key type: HMAC)
|
||||
- `test_psa_crypto_config_accel_hmac`: all algs, full config except a few
|
||||
exclusions (PKCS5, PKCS7, HMAC-DRBG, legacy HKDF, deterministic ECDSA), with
|
||||
parity testing.
|
||||
|
||||
Cipher, AEAD and CMAC (key types: DES, AES, ARIA, CHACHA20, CAMELLIA):
|
||||
- `test_psa_crypto_config_accel_cipher_aead_cmac`: all key types and algs, full
|
||||
config with a few exclusions (NIST-KW), with parity testing.
|
||||
- `test_psa_crypto_config_accel_des`: only DES (with all algs), full
|
||||
config, no parity testing.
|
||||
- `test_psa_crypto_config_accel_aead`: only AEAD algs (with all relevant key
|
||||
types), full config, no parity testing.
|
||||
|
||||
Key derivation (key types: `DERIVE`, `RAW_DATA`, `PASSWORD`, `PEPPER`,
|
||||
`PASSWORD_HASH`):
|
||||
- No testing as we don't have driver support yet (see previous section).
|
||||
|
||||
RSA (key types: `RSA_KEY_PAIR_xxx`, `RSA_PUBLIC_KEY`):
|
||||
- `test_psa_crypto_config_accel_rsa_crypto`: all 4 algs (encryption &
|
||||
signature, v1.5 & v2.1), config `crypto_full`, with parity testing excluding
|
||||
PK.
|
||||
|
||||
DH (key types: `DH_KEY_PAIR_xxx`, `DH_PUBLIC_KEY`):
|
||||
- `test_psa_crypto_config_accel_ffdh`: all key types and algs, full config,
|
||||
with parity testing.
|
||||
- `test_psa_crypto_config_accel_ecc_ffdh_no_bignum`: with also bignum removed.
|
||||
|
||||
ECC (key types: `ECC_KEY_PAIR_xxx`, `ECC_PUBLIC_KEY`):
|
||||
- Single algorithm accelerated (both key types, all curves):
|
||||
- `test_psa_crypto_config_accel_ecdh`: default config, no parity testing.
|
||||
- `test_psa_crypto_config_accel_ecdsa`: default config, no parity testing.
|
||||
- `test_psa_crypto_config_accel_pake`: full config, no parity testing.
|
||||
- All key types, algs and curves accelerated (full config with exceptions,
|
||||
with parity testing):
|
||||
- `test_psa_crypto_config_accel_ecc_ecp_light_only`: `ECP_C` mostly disabled
|
||||
- `test_psa_crypto_config_accel_ecc_no_ecp_at_all`: `ECP_C` fully disabled
|
||||
- `test_psa_crypto_config_accel_ecc_no_bignum`: `BIGNUM_C` disabled (DH disabled)
|
||||
- `test_psa_crypto_config_accel_ecc_ffdh_no_bignum`: `BIGNUM_C` disabled (DH accelerated)
|
||||
- Other - all algs accelerated but only some algs/curves (full config with
|
||||
exceptions, no parity testing):
|
||||
- `test_psa_crypto_config_accel_ecc_some_key_types`
|
||||
- `test_psa_crypto_config_accel_ecc_non_weierstrass_curves`
|
||||
- `test_psa_crypto_config_accel_ecc_weierstrass_curves`
|
||||
|
||||
Note: `analyze_outcomes.py` provides a list of test cases that are not
|
||||
executed in any configuration tested on the CI. We're missing driver-only HMAC
|
||||
testing, but no test is flagged as never executed there; this reveals we don't
|
||||
have "fallback not available" cases for MAC, see #8565.
|
||||
|
||||
#### Test case coverage
|
||||
|
||||
Since `test_suite_psa_crypto_driver_wrappers.data` is maintained manually,
|
||||
we need to make sure it exercises all the cases that need to be tested. In the
|
||||
future, this file should be generated in order to ensure exhaustiveness.
|
||||
|
||||
In the meantime, one way to observe (lack of) completeness is to look at line
|
||||
coverage in test driver implementations - this doesn't reveal all gaps, but it
|
||||
does reveal cases where we thought about something when writing the test
|
||||
driver, but not when writing test functions/data.
|
||||
|
||||
Key management:
|
||||
- `mbedtls_test_transparent_generate_key()` is not tested with RSA keys.
|
||||
- `mbedtls_test_transparent_import_key()` is not tested with DH keys.
|
||||
- `mbedtls_test_opaque_import_key()` is not tested with unstructured keys nor
|
||||
with RSA keys (nor DH keys since that's not implemented).
|
||||
- `mbedtls_test_opaque_export_key()` is not tested with non-built-in keys.
|
||||
- `mbedtls_test_transparent_export_public_key()` is not tested with RSA or DH keys.
|
||||
- `mbedtls_test_opaque_export_public_key()` is not tested with non-built-in keys.
|
||||
- `mbedtls_test_opaque_copy_key()` is not tested at all.
|
||||
|
||||
Hash:
|
||||
- `mbedtls_test_transparent_hash_finish()` is not tested with a forced status.
|
||||
|
||||
MAC:
|
||||
- The following are not tested with a forced status:
|
||||
- `mbedtls_test_transparent_mac_sign_setup()`
|
||||
- `mbedtls_test_transparent_mac_verify_setup()`
|
||||
- `mbedtls_test_transparent_mac_update()`
|
||||
- `mbedtls_test_transparent_mac_verify_finish()`
|
||||
- `mbedtls_test_transparent_mac_abort()`
|
||||
- No opaque entry point is tested (they're not implemented either).
|
||||
|
||||
Cipher:
|
||||
- The following are not tested with a forced status nor with a forced output:
|
||||
- `mbedtls_test_transparent_cipher_encrypt()`
|
||||
- `mbedtls_test_transparent_cipher_finish()`
|
||||
- No opaque entry point is tested (they're not implemented either).
|
||||
|
||||
AEAD:
|
||||
- The following are not tested with a forced status:
|
||||
- `mbedtls_test_transparent_aead_set_nonce()`
|
||||
- `mbedtls_test_transparent_aead_set_lengths()`
|
||||
- `mbedtls_test_transparent_aead_update_ad()`
|
||||
- `mbedtls_test_transparent_aead_update()`
|
||||
- `mbedtls_test_transparent_aead_finish()`
|
||||
- `mbedtls_test_transparent_aead_verify()`
|
||||
- `mbedtls_test_transparent_aead_verify()` is not tested with an invalid tag
|
||||
(though it might be in another test suite).
|
||||
|
||||
Signature:
|
||||
- `sign_hash()` is not tested with RSA-PSS
|
||||
- No opaque entry point is tested (they're not implemented either).
|
||||
|
||||
Key agreement:
|
||||
- `mbedtls_test_transparent_key_agreement()` is not tested with FFDH.
|
||||
- No opaque entry point is tested (they're not implemented either).
|
||||
|
||||
PAKE:
|
||||
- All lines are covered.
|
||||
@@ -1,127 +0,0 @@
|
||||
# Mbed TLS PSA keystore format stability testing strategy
|
||||
|
||||
## Introduction
|
||||
|
||||
The PSA crypto subsystem includes a persistent key store. It is possible to create a persistent key and read it back later. This must work even if Mbed TLS has been upgraded in the meantime (except for deliberate breaks in the backward compatibility of the storage).
|
||||
|
||||
The goal of this document is to define a test strategy for the key store that not only validates that it's possible to load a key that was saved with the version of Mbed TLS under test, but also that it's possible to load a key that was saved with previous versions of Mbed TLS.
|
||||
|
||||
Interoperability is not a goal: PSA crypto implementations are not intended to have compatible storage formats. Downgrading is not required to work.
|
||||
|
||||
## General approach
|
||||
|
||||
### Limitations of a direct approach
|
||||
|
||||
The goal of storage format stability testing is: as a user of Mbed TLS, I want to store a key under version V and read it back under version W, with W ≥ V.
|
||||
|
||||
Doing the testing this way would be difficult because we'd need to have version V of Mbed TLS available when testing version W.
|
||||
|
||||
An alternative, semi-direct approach consists of generating test data under version V, and reading it back under version W. Done naively, this would require keeping a large amount of test data (full test coverage multiplied by the number of versions that we want to preserve backward compatibility with).
|
||||
|
||||
### Save-and-compare approach
|
||||
|
||||
Importing and saving a key is deterministic. Therefore we can ensure the stability of the storage format by creating test cases under a version V of Mbed TLS, where the test case parameters include both the parameters to pass to key creation and the expected state of the storage after the key is created. The test case creates a key as indicated by the parameters, then compares the actual state of the storage with the expected state.
|
||||
|
||||
In addition, the test case also loads the key and checks that it has the expected data and metadata. Import-and-save testing and load-and-check testing can be split into separate test functions with the same payloads.
|
||||
|
||||
If the test passes with version V, this means that the test data is consistent with what the implementation does. When the test later runs under version W ≥ V, it creates and reads back a storage state which is known to be identical to the state that V would have produced. Thus, this approach validates that W can read storage states created by V.
|
||||
|
||||
Note that it is the combination of import-and-save passing on version V and load-and-check passing on version W with the same data that proves that version W can read back what version V wrote. From the perspective of a particular version of the library, the import-and-save tests guarantee forward compatibility while the load-and-check tests guarantee backward compatibility.
|
||||
|
||||
Use a similar approach for files other than keys where possible and relevant.
|
||||
|
||||
### Keeping up with storage format evolution
|
||||
|
||||
Test cases should normally not be removed from the code base: if something has worked before, it should keep working in future versions, so we should keep testing it.
|
||||
|
||||
This cannot be enforced solely by looking at a single version of Mbed TLS, since there would be no indication that more test cases used to exist. It can only be enforced through review of library changes. The review is be assisted by a tool that compares the old and the new version, which is implemented in `scripts/abi_check.py`. This tool fails the CI if load-and-check test case disappears (changed test cases are raised as false positives).
|
||||
|
||||
If the way certain keys are stored changes, and we don't deliberately decide to stop supporting old keys (which should only be done by retiring a version of the storage format), then we should keep the corresponding test cases in load-only mode: create a file with the expected content, load it and check the data that it contains.
|
||||
|
||||
## Storage architecture overview
|
||||
|
||||
The PSA subsystem provides storage on top of the PSA trusted storage interface. The state of the storage is a mapping from file identifier (a 64-bit number) to file content (a byte array). These files include:
|
||||
|
||||
* [Key files](#key-storage) (files containing one key's metadata and, except for some secure element keys, key material).
|
||||
* The [random generator injected seed or state file](#random-generator-state) (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`).
|
||||
* [Storage transaction file](#storage-transaction-resumption).
|
||||
* [Driver state files](#driver-state-files).
|
||||
|
||||
For a more detailed description, refer to the [Mbed TLS storage specification](../mbed-crypto-storage-specification.md).
|
||||
|
||||
In addition, Mbed TLS includes an implementation of the PSA trusted storage interface on top of C stdio. This document addresses the test strategy for [PSA ITS over file](#psa-its-over-file) in a separate section below.
|
||||
|
||||
## Key storage testing
|
||||
|
||||
This section describes the desired test cases for keys created with the current storage format version. When the storage format changes, if backward compatibility is desired, old test data should be kept as described under [“Keeping up with storage format evolution”](#keeping-up-with-storage-format-evolution).
|
||||
|
||||
### Keystore layout
|
||||
|
||||
Objective: test that the key file name corresponds to the key identifier.
|
||||
|
||||
Method: Create a key with a given identifier (using `psa_import_key`) and verify that a file with the expected name is created, and no other. Repeat for different identifiers.
|
||||
|
||||
### General key format
|
||||
|
||||
Objective: test the format of the key file: which field goes where and how big it is.
|
||||
|
||||
Method: Create a key with certain metadata with `psa_import_key`. Read the file content and validate that it has the expected layout, deduced from the storage specification. Repeat with different metadata. Ensure that there are test cases covering all fields.
|
||||
|
||||
### Enumeration of test cases for keys
|
||||
|
||||
Objective: ensure that the coverage is sufficient to have assurance that all keys are stored correctly. This requires a sufficient selection of key types, sizes, policies, etc.
|
||||
|
||||
In particular, the tests must validate that each `PSA_xxx` constant that is stored in a key is covered by at least one test case:
|
||||
|
||||
* Lifetimes: `PSA_KEY_LIFETIME_xxx`, `PSA_KEY_PERSISTENCE_xxx`, `PSA_KEY_LOCATION_xxx`.
|
||||
* Usage flags: `PSA_KEY_USAGE_xxx`.
|
||||
* Algorithms in policies: `PSA_ALG_xxx`.
|
||||
* Key types: `PSA_KEY_TYPE_xxx`, `PSA_ECC_FAMILY_xxx`, `PSA_DH_FAMILY_xxx`.
|
||||
|
||||
In addition, the coverage of key material must ensure that any variation in key representation is detected. See [“Considerations on key material representations”](#Considerations-on-key-material-representations) for considerations regarding key types.
|
||||
|
||||
Method: Each test case creates a key with `psa_import_key`, purges it from memory, then reads it back and exercises it.
|
||||
|
||||
Generate test cases automatically based on an enumeration of available constants and some knowledge of what attributes (sizes, algorithms, …) and content to use for keys of a certain type.
|
||||
|
||||
### Testing with alternative lifetime values
|
||||
|
||||
Objective: have test coverage for lifetimes other than the default persistent lifetime (`PSA_KEY_LIFETIME_PERSISTENT`).
|
||||
|
||||
Method:
|
||||
|
||||
* For alternative locations: have tests conditional on the presence of a driver for that location.
|
||||
* For alternative persistence levels: have load-and-check tests for supported persistence levels. We may also want to have negative tests ensuring that keys with a not-supported persistence level are not accidentally created.
|
||||
|
||||
### Considerations on key material representations
|
||||
|
||||
The risks of incompatibilities in key representations depends on the key type and on the presence of drivers. Compatibility of and with drivers is currently out of scope of this document.
|
||||
|
||||
Some types only have one plausible representation. Others admit alternative plausible representations (different encodings, or non-canonical representations).
|
||||
Here are some areas to watch for, with an identified risk of incompatibilities.
|
||||
|
||||
* HMAC keys longer than the block size: pre-hashed or not?
|
||||
* DES keys: was parity enforced?
|
||||
* RSA keys: can invalid DER encodings (e.g. leading zeros, ignored sign bit) have been stored?
|
||||
* RSA private keys: can invalid CRT parameters have been stored?
|
||||
* Montgomery private keys: were they stored in masked form?
|
||||
|
||||
## Random generator state
|
||||
|
||||
TODO
|
||||
|
||||
## Driver state files
|
||||
|
||||
Not yet implemented.
|
||||
|
||||
TODO
|
||||
|
||||
## Storage transaction resumption
|
||||
|
||||
Only relevant for secure element support. Not yet fully implemented.
|
||||
|
||||
TODO
|
||||
|
||||
## PSA ITS over file
|
||||
|
||||
TODO
|
||||
@@ -1,451 +0,0 @@
|
||||
This document explains how to create builds of Mbed TLS where some
|
||||
cryptographic mechanisms are provided only by PSA drivers (that is, no
|
||||
built-in implementation of those algorithms), from a user's perspective.
|
||||
|
||||
This is useful to save code size for people who are using either a hardware
|
||||
accelerator, or an alternative software implementation that is more
|
||||
aggressively optimized for code size than the default one in Mbed TLS.
|
||||
|
||||
General considerations
|
||||
----------------------
|
||||
|
||||
This document assumes that you already have a working driver.
|
||||
Otherwise, please see the [PSA driver example and
|
||||
guide](psa-driver-example-and-guide.md) for information on writing a
|
||||
driver.
|
||||
|
||||
In order to have some mechanism provided only by a driver, you'll want
|
||||
the following compile-time configuration options enabled:
|
||||
|
||||
- `MBEDTLS_PSA_CRYPTO_C` (enabled by default) - this enables PSA Crypto.
|
||||
- `MBEDTLS_USE_PSA_CRYPTO` (disabled by default) - this makes PK, X.509 and
|
||||
TLS use PSA Crypto. You need to enable this if you're using PK, X.509 or TLS
|
||||
and want them to have access to the algorithms provided by your driver. (See
|
||||
[the dedicated document](use-psa-crypto.md) for details.)
|
||||
|
||||
In addition, for each mechanism you want provided only by your driver:
|
||||
|
||||
- Define the corresponding `PSA_WANT` macro in `psa/crypto_config.h` - this
|
||||
means the algorithm will be available in the PSA Crypto API.
|
||||
- Define the corresponding `MBEDTLS_PSA_ACCEL` in your build. This could be
|
||||
defined in `psa/crypto_config.h` or your compiler's command line. This
|
||||
informs the PSA code that an accelerator is available for this mechanism.
|
||||
- Undefine / comment out the corresponding `MBEDTLS_xxx_C` macro in
|
||||
`mbedtls/mbedtls_config.h`. This ensures the built-in implementation is not
|
||||
included in the build.
|
||||
|
||||
For example, if you want SHA-256 to be provided only by a driver, you'll want
|
||||
`PSA_WANT_ALG_SHA_256` and `MBEDTLS_PSA_ACCEL_SHA_256` defined, and
|
||||
`MBEDTLS_SHA256_C` undefined.
|
||||
|
||||
In addition to these compile-time considerations, at runtime you'll need to
|
||||
make sure you call `psa_crypto_init()` before any function that uses the
|
||||
driver-only mechanisms. Note that this is already a requirement for any use of
|
||||
the PSA Crypto API, as well as for use of the PK, X.509 and TLS modules when
|
||||
`MBEDTLS_USE_PSA_CRYPTO` is enabled, so in most cases your application will
|
||||
already be doing this.
|
||||
|
||||
Mechanisms covered
|
||||
------------------
|
||||
|
||||
For now, only the following (families of) mechanisms are supported:
|
||||
|
||||
- hashes: SHA-3, SHA-2, SHA-1, MD5, etc.
|
||||
- elliptic-curve cryptography (ECC): ECDH, ECDSA, EC J-PAKE, ECC key types.
|
||||
- finite-field Diffie-Hellman: FFDH algorithm, DH key types.
|
||||
- RSA: PKCS#1 v1.5 and v2.1 signature and encryption algorithms, RSA key types
|
||||
(for now, only crypto, no X.509 or TLS support).
|
||||
- AEADs:
|
||||
- GCM and CCM with AES, ARIA and Camellia key types
|
||||
- ChachaPoly with ChaCha20 Key type
|
||||
- Unauthenticated ciphers:
|
||||
- key types: AES, ARIA, Camellia, DES
|
||||
- modes: ECB, CBC, CTR, CFB, OFB, XTS
|
||||
|
||||
For each family listed above, all the mentioned alorithms/key types are also
|
||||
all the mechanisms that exist in PSA API.
|
||||
|
||||
Supported means that when those are provided only by drivers, everything
|
||||
(including PK, X.509 and TLS if `MBEDTLS_USE_PSA_CRYPTO` is enabled) should
|
||||
work in the same way as if the mechanisms where built-in, except as documented
|
||||
in the "Limitations" sub-sections of the sections dedicated to each family
|
||||
below.
|
||||
|
||||
Hashes
|
||||
------
|
||||
|
||||
It is possible to have all hash operations provided only by a driver.
|
||||
|
||||
More precisely:
|
||||
|
||||
- you can enable `PSA_WANT_ALG_SHA_256` without `MBEDTLS_SHA256_C`, provided
|
||||
you have `MBEDTLS_PSA_ACCEL_ALG_SHA_256` enabled;
|
||||
- and similarly for all supported hash algorithms: `MD5`, `RIPEMD160`,
|
||||
`SHA_1`, `SHA_224`, `SHA_256`, `SHA_384`, `SHA_512`, `SHA3_224`, `SHA3_256`,
|
||||
`SHA3_384`, `SHA3_512`.
|
||||
|
||||
In such a build, all crypto operations (via the PSA Crypto API, or non-PSA
|
||||
APIs), as well as X.509 and TLS, will work as usual, except that direct calls
|
||||
to low-level hash APIs (`mbedtls_sha256()` etc.) are not possible for the
|
||||
modules that are disabled.
|
||||
|
||||
You need to call `psa_crypto_init()` before any crypto operation that uses
|
||||
a hash algorithm that is provided only by a driver, as mentioned in [General
|
||||
considerations](#general-considerations) above.
|
||||
|
||||
If you want to check at compile-time whether a certain hash algorithm is
|
||||
available in the present build of Mbed TLS, regardless of whether it's
|
||||
provided by a driver or built-in, you should use `PSA_WANT_ALG_xxx` from
|
||||
`psa/crypto.h`.
|
||||
|
||||
### HMAC
|
||||
|
||||
In addition to accelerated hash operations, it is also possible to accelerate
|
||||
HMAC by enabling and accelerating:
|
||||
- HMAC algorithm and key type, i.e. `[PSA_WANT|MBEDTLS_PSA_ACCEL]_ALG_HMAC` and
|
||||
`[PSA_WANT|MBEDTLS_PSA_ACCEL]KEY_TYPE_HMAC`.
|
||||
- Required hash algorithm(s) as explained in [Hashes](#hashes) section.
|
||||
|
||||
In such a build it is possible to disable legacy HMAC support by disabling
|
||||
`MBEDTLS_MD_C` and still getting crypto operations, X.509 and TLS to work as
|
||||
usual. Exceptions are:
|
||||
- As mentioned in [Hashes](#hashes) direct calls to legacy lo-level hash APIs
|
||||
(`mbedtls_sha256()` etc.) will not be possible for the legacy modules that
|
||||
are disabled.
|
||||
- Legacy HMAC support (`mbedtls_md_hmac_xxx()`) won't be possible.
|
||||
- `MBEDTLS_PKCS[5|7]_C`, `MBEDTLS_HMAC_DRBG_C` and `MBEDTLS_HKDF_C` since they
|
||||
depend on the legacy implementation of HMAC.
|
||||
- disabling HMAC_DRBG_C cause deterministic ECDSA (i.e.
|
||||
`MBEDTLS_DETERMINISTIC_ECDSA` on the legacy side and
|
||||
`PSA_WANT_ALG_DETERMINISTIC_ECDSA` on the PSA one) to be not available.
|
||||
|
||||
Elliptic-curve cryptography (ECC)
|
||||
---------------------------------
|
||||
|
||||
It is possible to have most ECC operations provided only by a driver:
|
||||
|
||||
- the ECDH, ECDSA and EC J-PAKE algorithms;
|
||||
- key import, export, and random generation.
|
||||
|
||||
More precisely, if:
|
||||
|
||||
- you have driver support for ECC public and using private keys (that is,
|
||||
`MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY` and
|
||||
`MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC` are enabled), and
|
||||
- you have driver support for all ECC curves that are enabled (that is, for
|
||||
each `PSA_WANT_ECC_xxx` macro enabled, the corresponding
|
||||
`MBEDTLS_PSA_ACCEL_ECC_xxx` macros is enabled as well);
|
||||
|
||||
then you can:
|
||||
|
||||
- enable `PSA_WANT_ALG_ECDH` without `MBEDTLS_ECDH_C`, provided
|
||||
`MBEDTLS_PSA_ACCEL_ALG_ECDH` is enabled
|
||||
- enable `PSA_WANT_ALG_ECDSA` without `MBEDTLS_ECDSA_C`, provided
|
||||
`MBEDTLS_PSA_ACCEL_ALG_ECDSA` is enabled;
|
||||
- enable `PSA_WANT_ALG_JPAKE` without `MBEDTLS_ECJPAKE_C`, provided
|
||||
`MBEDTLS_PSA_ACCEL_ALG_JPAKE` is enabled.
|
||||
|
||||
In addition, if:
|
||||
|
||||
- none of `MBEDTLS_ECDH_C`, `MBEDTLS_ECDSA_C`, `MBEDTLS_ECJPAKE_C` are enabled
|
||||
(see conditions above), and
|
||||
- you have driver support for all enabled ECC key pair operations - that is,
|
||||
for each `PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_xxx` macro enabled, the
|
||||
corresponding `MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_xxx` macros is also
|
||||
enabled,
|
||||
|
||||
then you can also disable `MBEDTLS_ECP_C`. However, a small subset of it might
|
||||
still be included in the build, see limitations sub-section below.
|
||||
|
||||
In addition, if:
|
||||
|
||||
- `MBEDTLS_ECP_C` is fully removed (see limitation sub-section below),
|
||||
- and support for RSA key types and algorithms is either fully disabled or
|
||||
fully provided by a driver,
|
||||
- and support for DH key types and the FFDH algorithm is either disabled or
|
||||
fully provided by a driver,
|
||||
|
||||
then you can also disable `MBEDTLS_BIGNUM_C`.
|
||||
|
||||
In such builds, all crypto operations via the PSA Crypto API will work as
|
||||
usual, as well as the PK, X.509 and TLS modules if `MBEDTLS_USE_PSA_CRYPTO` is
|
||||
enabled, with the following exceptions:
|
||||
|
||||
- direct calls to APIs from the disabled modules are not possible;
|
||||
- PK, X.509 and TLS will not support restartable ECC operations (see
|
||||
limitation sub-section below).
|
||||
|
||||
If you want to check at compile-time whether a certain curve is available in
|
||||
the present build of Mbed TLS, regardless of whether ECC is provided by a
|
||||
driver or built-in, you should use `PSA_WANT_ECC_xxx` from
|
||||
`psa/crypto.h`.
|
||||
|
||||
Note that for externally-provided drivers, the integrator is responsible for
|
||||
ensuring the appropriate `MBEDTLS_PSA_ACCEL_xxx` macros are defined. However,
|
||||
for the p256-m driver that's provided with the library, those macros are
|
||||
automatically defined when enabling `MBEDTLS_PSA_P256M_DRIVER_ENABLED`.
|
||||
|
||||
### Limitations regarding fully removing `ecp.c`
|
||||
|
||||
A limited subset of `ecp.c` will still be automatically re-enabled if any of
|
||||
the following is enabled:
|
||||
|
||||
- `MBEDTLS_PK_PARSE_EC_COMPRESSED` - support for parsing ECC keys where the
|
||||
public part is in compressed format;
|
||||
- `MBEDTLS_PK_PARSE_EC_EXTENDED` - support for parsing ECC keys where the
|
||||
curve is identified not by name, but by explicit parameters;
|
||||
- `PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE` - support for deterministic
|
||||
derivation of an ECC keypair with `psa_key_derivation_output_key()`.
|
||||
|
||||
Note: when any of the above options is enabled, a subset of `ecp.c` will
|
||||
automatically be included in the build in order to support it. Therefore
|
||||
you can still disable `MBEDTLS_ECP_C` in `mbedtls_config.h` and this will
|
||||
result in some code size savings, but not as much as when none of the
|
||||
above features are enabled.
|
||||
|
||||
We do have plans to support each of these with `ecp.c` fully removed in the
|
||||
future, however there is no established timeline. If you're interested, please
|
||||
let us know, so we can take it into consideration in our planning.
|
||||
|
||||
### Limitations regarding restartable / interruptible ECC operations
|
||||
|
||||
At the moment, there is no driver support for interruptible operations
|
||||
(see `psa_sign_hash_start()` + `psa_sign_hash_complete()` etc.) so as a
|
||||
consequence these are not supported in builds without `MBEDTLS_ECDSA_C`.
|
||||
|
||||
Similarly, there is no PSA support for interruptible ECDH operations so these
|
||||
are not supported without `ECDH_C`. See also limitations regarding
|
||||
restartable operations with `MBEDTLS_USE_PSA_CRYPTO` in [its
|
||||
documentation](use-psa-crypto.md).
|
||||
|
||||
Again, we have plans to support this in the future but not with an established
|
||||
timeline, please let us know if you're interested.
|
||||
|
||||
### Limitations regarding "mixed" builds (driver and built-in)
|
||||
|
||||
In order for a build to be driver-only (no built-in implementation), all the
|
||||
requested algorithms, key types (key operations) and curves must be
|
||||
accelerated (plus a few other restrictions, see "Limitations regarding fully
|
||||
removing `ecp.c`" above). However, what if you have an accelerator that only
|
||||
supports some algorithms, some key types (key operations), or some curves, but
|
||||
want to have more enabled in you build?
|
||||
|
||||
It is possible to have acceleration for only a subset of the requested
|
||||
algorithms. In this case, the built-in implementation of the accelerated
|
||||
algorithms will be disabled, provided all the requested curves and key types
|
||||
that can be used with this algorithm are also declared as accelerated.
|
||||
|
||||
There is very limited support for having acceleration for only a subset of the
|
||||
requested key type operations. The only configuration that's tested is that of
|
||||
a driver accelerating `PUBLIC_KEY`, `KEY_PAIR_BASIC`, `KEY_PAIR_IMPORT`,
|
||||
`KEY_PAIR_EXPORT` but not `KEY_PAIR_GENERATE`. (Note: currently the driver
|
||||
interface does not support `KEY_PAIR_DERIVE`.)
|
||||
|
||||
There is limited support for having acceleration for only a subset of the
|
||||
requested curves. In such builds, only the PSA API is currently tested and
|
||||
working; there are known issues in PK, and X.509 and TLS are untested.
|
||||
|
||||
Finite-field Diffie-Hellman
|
||||
---------------------------
|
||||
|
||||
Support is pretty similar to the "Elliptic-curve cryptography (ECC)" section
|
||||
above.
|
||||
Key management and usage can be enabled by means of the usual `PSA_WANT` +
|
||||
`MBEDTLS_PSA_ACCEL` pairs:
|
||||
|
||||
- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_PUBLIC_KEY`;
|
||||
- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_KEY_PAIR_BASIC`;
|
||||
- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_KEY_PAIR_IMPORT`;
|
||||
- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_KEY_PAIR_EXPORT`;
|
||||
- `[PSA_WANT|MBEDTLS_PSA_ACCEL]_KEY_TYPE_DH_KEY_PAIR_GENERATE`;
|
||||
|
||||
The same holds for the associated algorithm:
|
||||
`[PSA_WANT|MBEDTLS_PSA_ACCEL]_ALG_FFDH` allow builds accelerating FFDH and
|
||||
removing builtin support (i.e. `MBEDTLS_DHM_C`).
|
||||
|
||||
Note that the PSA API only supports FFDH with RFC 7919 groups, whereas the
|
||||
Mbed TLS legacy API supports custom groups. As a consequence, the TLS layer
|
||||
of Mbed TLS only supports DHE cipher suites if built-in FFDH
|
||||
(`MBEDTLS_DHM_C`) is present, even when `MBEDTLS_USE_PSA_CRYPTO` is enabled.
|
||||
|
||||
RSA
|
||||
---
|
||||
|
||||
It is possible for all RSA operations to be provided only by a driver.
|
||||
|
||||
More precisely, if:
|
||||
|
||||
- all the RSA algorithms that are enabled (`PSA_WANT_ALG_RSA_*`) are also
|
||||
accelerated (`MBEDTLS_PSA_ACCEL_ALG_RSA_*`),
|
||||
- and all the RSA key types that are enabled (`PSA_WANT_KEY_TYPE_RSA_*`) are
|
||||
also accelerated (`MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_*`),
|
||||
|
||||
then you can disable `MBEDTLS_RSA_C`, `MBEDTLS_PKCS1_V15` and
|
||||
`MBEDTLS_PKCS1_V21`, and RSA will still work in PSA Crypto.
|
||||
|
||||
### Limitations on RSA acceleration
|
||||
|
||||
Unlike other mechanisms, for now in configurations with driver-only RSA, only
|
||||
PSA Crypto works. In particular, PK, X.509 and TLS will _not_ work with
|
||||
driver-only RSA even if `MBEDTLS_USE_PSA_CRYPTO` is enabled.
|
||||
|
||||
Currently (early 2024) we don't have plans to extend this support. If you're
|
||||
interested in wider driver-only support for RSA, please let us know.
|
||||
|
||||
Ciphers (unauthenticated and AEAD)
|
||||
----------------------------------
|
||||
|
||||
It is possible to have all ciphers and AEAD operations provided only by a
|
||||
driver. More precisely, for each desired combination of key type and
|
||||
algorithm/mode you can:
|
||||
|
||||
- Enable desired PSA key type(s):
|
||||
- `PSA_WANT_KEY_TYPE_AES`,
|
||||
- `PSA_WANT_KEY_TYPE_ARIA`,
|
||||
- `PSA_WANT_KEY_TYPE_CAMELLIA`,
|
||||
- `PSA_WANT_KEY_TYPE_CHACHA20`,
|
||||
- `PSA_WANT_KEY_TYPE_DES`.
|
||||
- Enable desired PSA algorithm(s):
|
||||
- Unauthenticated ciphers modes:
|
||||
- `PSA_WANT_ALG_CBC_NO_PADDING`,
|
||||
- `PSA_WANT_ALG_CBC_PKCS7`,
|
||||
- `PSA_WANT_ALG_CCM_STAR_NO_TAG`,
|
||||
- `PSA_WANT_ALG_CFB`,
|
||||
- `PSA_WANT_ALG_CTR`,
|
||||
- `PSA_WANT_ALG_ECB_NO_PADDING`,
|
||||
- `PSA_WANT_ALG_OFB`,
|
||||
- `PSA_WANT_ALG_STREAM_CIPHER`.
|
||||
- AEADs:
|
||||
- `PSA_WANT_ALG_CCM`,
|
||||
- `PSA_WANT_ALG_GCM`,
|
||||
- `PSA_WANT_ALG_CHACHA20_POLY1305`.
|
||||
- Enable `MBEDTLS_PSA_ACCEL_[KEY_TYPE_xxx|ALG_yyy]` symbol(s) which correspond
|
||||
to the `PSA_WANT_KEY_TYPE_xxx` and `PSA_WANT_ALG_yyy` of the previous steps.
|
||||
- Disable builtin support of key types:
|
||||
- `MBEDTLS_AES_C`,
|
||||
- `MBEDTLS_ARIA_C`,
|
||||
- `MBEDTLS_CAMELLIA_C`,
|
||||
- `MBEDTLS_DES_C`,
|
||||
- `MBEDTLS_CHACHA20_C`.
|
||||
and algorithms/modes:
|
||||
- `MBEDTLS_CBC_C`,
|
||||
- `MBEDTLS_CFB_C`,
|
||||
- `MBEDTLS_CTR_C`,
|
||||
- `MBEDTLS_OFB_C`,
|
||||
- `MBEDTLS_XTS_C`,
|
||||
- `MBEDTLS_CCM_C`,
|
||||
- `MBEDTLS_GCM_C`,
|
||||
- `MBEDTLS_CHACHAPOLY_C`,
|
||||
- `MBEDTLS_NULL_CIPHER`.
|
||||
|
||||
Once a key type and related algorithm are accelerated, all the PSA Crypto APIs
|
||||
will work, as well as X.509 and TLS (with `MBEDTLS_USE_PSA_CRYPTO` enabled) but
|
||||
some non-PSA APIs will be absent or have reduced functionality, see
|
||||
[Restrictions](#restrictions) for details.
|
||||
|
||||
### Restrictions
|
||||
|
||||
- If an algorithm other than CCM and GCM (see
|
||||
["Partial acceleration for CCM/GCM"](#partial-acceleration-for-ccmgcm) below)
|
||||
is enabled but not accelerated, then all key types that can be used with it
|
||||
will need to be built-in.
|
||||
- If a key type is enabled but not accelerated, then all algorithms that can be
|
||||
used with it will need to be built-in.
|
||||
|
||||
Some legacy modules can't take advantage of PSA drivers yet, and will either
|
||||
need to be disabled, or have reduced features when the built-in implementations
|
||||
of some ciphers are removed:
|
||||
|
||||
- `MBEDTLS_NIST_KW_C` needs built-in AES: it must be disabled when
|
||||
`MBEDTLS_AES_C` is disabled.
|
||||
- `MBEDTLS_CMAC_C` needs built-in AES/DES: it must be disabled when
|
||||
`MBEDTLS_AES_C` and `MBEDTLS_DES_C` are both disabled. When only one of them
|
||||
is enabled, then only the corresponding cipher will be available at runtime
|
||||
for use with `mbedtls_cipher_cmac_xxx`. (Note: if there is driver support for
|
||||
CMAC and all compatible key types, then `PSA_WANT_ALG_CMAC` can be enabled
|
||||
without `MBEDTLS_CMAC_C` and CMAC will be usable with `psa_max_xxx` APIs.)
|
||||
- `MBEDTLS_CIPHER_C`: the `mbedtls_cipher_xxx()` APIs will only work with
|
||||
ciphers that are built-in - that is, both the underlying cipher
|
||||
(eg `MBEDTLS_AES_C`) and the mode (eg `MBEDTLS_CIPHER_MODE_CBC` or
|
||||
`MBEDTLS_GCM_C`).
|
||||
- `MBEDTLS_PKCS5_C`: encryption/decryption (PBES2, PBE) will only work with
|
||||
ciphers that are built-in.
|
||||
- PEM decryption will only work with ciphers that are built-in.
|
||||
- PK parse will only be able to parse encrypted keys using built-in ciphers.
|
||||
|
||||
Note that if you also disable `MBEDTLS_CIPHER_C`, there will be additional
|
||||
restrictions, see [Disabling `MBEDTLS_CIPHER_C`](#disabling-mbedtls_cipher_c).
|
||||
|
||||
### Legacy <-> PSA matching
|
||||
|
||||
Note that the relationship between legacy (i.e. `MBEDTLS_xxx_C`) and PSA
|
||||
(i.e. `PSA_WANT_xxx`) symbols is not always 1:1. For example:
|
||||
|
||||
- ECB mode is always enabled in the legacy configuration for each key type that
|
||||
allows it (AES, ARIA, Camellia, DES), whereas it must be explicitly enabled
|
||||
in PSA with `PSA_WANT_ALG_ECB_NO_PADDING`.
|
||||
- In the legacy API, `MBEDTLS_CHACHA20_C` enables the ChaCha20 stream cipher, and
|
||||
enabling `MBEDTLS_CHACHAPOLY_C` also enables the ChaCha20-Poly1305 AEAD. In the
|
||||
PSA API, you need to enable `PSA_KEY_TYPE_CHACHA20` for both, plus
|
||||
`PSA_ALG_STREAM_CIPHER` or `PSA_ALG_CHACHA20_POLY1305` as desired.
|
||||
- The legacy symbol `MBEDTLS_CCM_C` adds support for both cipher and AEAD,
|
||||
whereas in PSA there are 2 different symbols: `PSA_WANT_ALG_CCM_STAR_NO_TAG`
|
||||
and `PSA_WANT_ALG_CCM`, respectively.
|
||||
|
||||
### Partial acceleration for CCM/GCM
|
||||
|
||||
[This section depends on #8598 so it might be updated while that PR progresses.]
|
||||
|
||||
In case legacy CCM/GCM algorithms are enabled, it is still possible to benefit
|
||||
from PSA acceleration of the underlying block cipher by enabling support for
|
||||
ECB mode (`PSA_WANT_ALG_ECB_NO_PADDING` + `MBEDTLS_PSA_ACCEL_ALG_ECB_NO_PADDING`)
|
||||
together with desired key type(s) (`PSA_WANT_KEY_TYPE_[AES|ARIA|CAMELLIA]` +
|
||||
`MBEDTLS_PSA_ACCEL_KEY_TYPE_[AES|ARIA|CAMELLIA]`).
|
||||
|
||||
In such configurations it is possible to:
|
||||
|
||||
- Use CCM and GCM via the PSA Crypto APIs.
|
||||
- Use CCM and GCM via legacy functions `mbedtls_[ccm|gcm]_xxx()` (but not the
|
||||
legacy functions `mbedtls_cipher_xxx()`).
|
||||
- Disable legacy key types (`MBEDTLS_[AES|ARIA|CAMELLIA]_C`) if there is no
|
||||
other dependency requiring them.
|
||||
|
||||
ChaChaPoly has no such feature, so it requires full acceleration (key type +
|
||||
algorithm) in order to work with a driver.
|
||||
|
||||
### CTR-DRBG
|
||||
|
||||
The legacy CTR-DRBG module (enabled by `MBEDTLS_CTR_DRBG_C`) can also benefit
|
||||
from PSA acceleration if both of the following conditions are met:
|
||||
|
||||
- The legacy AES module (`MBEDTLS_AES_C`) is not enabled and
|
||||
- AES is supported on the PSA side together with ECB mode, i.e.
|
||||
`PSA_WANT_KEY_TYPE_AES` + `PSA_WANT_ALG_ECB_NO_PADDING`.
|
||||
|
||||
### Disabling `MBEDTLS_CIPHER_C`
|
||||
|
||||
It is possible to save code size by disabling MBEDTLS_CIPHER_C when all of the
|
||||
following conditions are met:
|
||||
|
||||
- The application is not using the `mbedtls_cipher_` API.
|
||||
- In PSA, all unauthenticated (that is, non-AEAD) ciphers are either disabled or
|
||||
fully accelerated (that is, all compatible key types are accelerated too).
|
||||
- Either TLS is disabled, or `MBEDTLS_USE_PSA_CRYPTO` is enabled.
|
||||
- `MBEDTLS_NIST_KW` is disabled.
|
||||
- `MBEDTLS_CMAC_C` is disabled. (Note: support for CMAC in PSA can be provided by
|
||||
a driver.)
|
||||
|
||||
In such a build, everything will work as usual except for the following:
|
||||
|
||||
- Encryption/decryption functions from the PKCS5 and PKCS12 module will not be
|
||||
available (only key derivation functions).
|
||||
- Parsing of PKCS5- or PKCS12-encrypted keys in PK parse will fail.
|
||||
|
||||
Note: AEAD ciphers (CCM, GCM, ChachaPoly) do not have a dependency on
|
||||
MBEDTLS_CIPHER_C even when using the built-in implementations.
|
||||
|
||||
If you also have some ciphers fully accelerated and the built-ins removed, see
|
||||
[Restrictions](#restrictions) for restrictions related to removing the built-ins.
|
||||
|
||||
|
||||
|
||||
@@ -1,241 +0,0 @@
|
||||
Conditional inclusion of cryptographic mechanism through the PSA API in Mbed TLS
|
||||
================================================================================
|
||||
|
||||
This document is a proposed interface for deciding at build time which cryptographic mechanisms to include in the PSA Cryptography interface.
|
||||
|
||||
This is currently a proposal for Mbed TLS. It is not currently on track for standardization in PSA.
|
||||
|
||||
## Introduction
|
||||
|
||||
### Purpose of this specification
|
||||
|
||||
The [PSA Cryptography API specification](https://armmbed.github.io/mbed-crypto/psa/#application-programming-interface) specifies the interface between a PSA Cryptography implementation and an application. The interface defines a number of categories of cryptographic algorithms (hashes, MAC, signatures, etc.). In each category, a typical implementation offers many algorithms (e.g. for signatures: RSA-PKCS#1v1.5, RSA-PSS, ECDSA). When building the implementation for a specific use case, it is often desirable to include only a subset of the available cryptographic mechanisms, primarily in order to reduce the code footprint of the compiled system.
|
||||
|
||||
The present document proposes a way for an application using the PSA cryptography interface to declare which mechanisms it requires.
|
||||
|
||||
### Conditional inclusion of legacy cryptography modules
|
||||
|
||||
Mbed TLS offers a way to select which cryptographic mechanisms are included in a build through its configuration file (`mbedtls_config.h`). This mechanism is based on two main sets of symbols: `MBEDTLS_xxx_C` controls the availability of the mechanism to the application, and `MBEDTLS_xxx_ALT` controls the availability of an alternative implementation, so the software implementation is only included if `MBEDTLS_xxx_C` is defined but not `MBEDTLS_xxx_ALT`.
|
||||
|
||||
### PSA evolution
|
||||
|
||||
In the PSA cryptography interface, the **core** (built-in implementations of cryptographic mechanisms) can be augmented with drivers. **Transparent drivers** replace the built-in implementation of a cryptographic mechanism (or, with **fallback**, the built-in implementation is tried if the driver only has partial support for the mechanism). **Opaque drivers** implement cryptographic mechanisms on keys which are stored in a separate domain such as a secure element, for which the core only does key management and dispatch using wrapped key blobs or key identifiers.
|
||||
|
||||
The current model is difficult to adapt to the PSA interface for several reasons. The `MBEDTLS_xxx_ALT` symbols are somewhat inconsistent, and in particular do not work well for asymmetric cryptography. For example, many parts of the ECC code have no `MBEDTLS_xxx_ALT` symbol, so a platform with ECC acceleration that can perform all ECDSA and ECDH operations in the accelerator would still embark the `bignum` module and large parts of the `ecp_curves`, `ecp` and `ecdsa` modules. Also the availability of a transparent driver for a mechanism does not translate directly to `MBEDTLS_xxx` symbols.
|
||||
|
||||
### Requirements
|
||||
|
||||
[Req.interface] The application can declare which cryptographic mechanisms it needs.
|
||||
|
||||
[Req.inclusion] If the application does not require a mechanism, a suitably configured Mbed TLS build must not include it. The granularity of mechanisms must work for typical use cases and has [acceptable limitations](#acceptable-limitations).
|
||||
|
||||
[Req.drivers] If a PSA driver is available in the build, a suitably configured Mbed TLS build must not include the corresponding software code (unless a software fallback is needed).
|
||||
|
||||
[Req.c] The configuration mechanism consists of C preprocessor definitions, and the build does not require tools other than a C compiler. This is necessary to allow building an application and Mbed TLS in development environments that do not allow third-party tools.
|
||||
|
||||
[Req.adaptability] The implementation of the mechanism must be adaptable with future evolution of the PSA cryptography specifications and Mbed TLS. Therefore the interface must remain sufficiently simple and abstract.
|
||||
|
||||
### Acceptable limitations
|
||||
|
||||
[Limitation.matrix] If a mechanism is defined by a combination of algorithms and key types, for example a block cipher mode (CBC, CTR, CFB, …) and a block permutation (AES, CAMELLIA, ARIA, …), there is no requirement to include only specific combinations.
|
||||
|
||||
[Limitation.direction] For mechanisms that have multiple directions (for example encrypt/decrypt, sign/verify), there is no requirement to include only one direction.
|
||||
|
||||
[Limitation.size] There is no requirement to include only support for certain key sizes.
|
||||
|
||||
[Limitation.multipart] Where there are multiple ways to perform an operation, for example single-part and multi-part, there is no mechanism to select only one or a subset of the possible ways.
|
||||
|
||||
## Interface
|
||||
|
||||
### PSA Crypto configuration file
|
||||
|
||||
The PSA Crypto configuration file `psa/crypto_config.h` defines a series of symbols of the form `PSA_WANT_xxx` where `xxx` describes the feature that the symbol enables. The symbols are documented in the section [“PSA Crypto configuration symbols”](#psa-crypto-configuration-symbols) below.
|
||||
The necessary software implementations of cryptographic algorithms are included based on the content of the PSA Crypto configuration file. For example, the code in `aes.c` is enabled if `psa/crypto_config.h` contains `PSA_WANT_KEY_TYPE_AES`.
|
||||
|
||||
### PSA Crypto configuration symbols
|
||||
|
||||
#### Configuration symbol syntax
|
||||
|
||||
A PSA Crypto configuration symbol is a C preprocessor symbol whose name starts with `PSA_WANT_`.
|
||||
|
||||
* If the symbol is not defined, the corresponding feature is not included.
|
||||
* If the symbol is defined to a preprocessor expression with the value `1`, the corresponding feature is included.
|
||||
* If the symbol is defined with a different value, the behavior is currently undefined and reserved for future use.
|
||||
|
||||
#### Configuration symbol usage
|
||||
|
||||
The presence of a symbol `PSA_WANT_xxx` in the Mbed TLS configuration determines whether a feature is available through the PSA API. These symbols should be used in any place that requires conditional compilation based on the availability of a cryptographic mechanism through the PSA API, including:
|
||||
|
||||
* In Mbed TLS test code.
|
||||
* In Mbed TLS library code using `MBEDTLS_USE_PSA_CRYPTO`, for example in TLS to determine which cipher suites to enable.
|
||||
* In application code that provides additional features based on cryptographic capabilities, for example additional key parsing and formatting functions, or cipher suite availability for network protocols.
|
||||
|
||||
#### Configuration symbol semantics
|
||||
|
||||
If a feature is not requested for inclusion in the PSA Crypto configuration file, it may still be included in the build, either because the feature has been requested in some other way, or because the library does not support the exclusion of this feature. Mbed TLS should make a best effort to support the exclusion of all features, but in some cases this may be judged too much effort for too little benefit.
|
||||
|
||||
#### Configuration symbols for key types
|
||||
|
||||
For most constant or constructor macros of the form `PSA_KEY_TYPE_xxx`, the symbol **`PSA_WANT_KEY_TYPE_xxx`** indicates that support for this key type is desired.
|
||||
|
||||
As an exception, starting in Mbed TLS 3.5.0, for `KEY_PAIR` types (that is, private keys for asymmetric cryptography), the feature selection is more fine-grained, with an additional suffix:
|
||||
* `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_BASIC` enables basic support for the key type, and in particular support for operations with a key of that type for enabled algorithms. This is automatically enabled if any of the other `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy` options is enabled.
|
||||
* `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_IMPORT` enables support for `psa_import_key` to import a key of that type.
|
||||
* `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_GENERATE` enables support for `psa_generate_key` to randomly generate a key of that type.
|
||||
* `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_DERIVE` enables support for `psa_key_derivation_output_key` to deterministically derive a key of that type.
|
||||
* `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_EXPORT` enables support for `psa_export_key` to export a key of that type.
|
||||
|
||||
For asymmetric cryptography, `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_BASIC` determines whether private-key operations are desired, and `PSA_WANT_KEY_TYPE_xxx_PUBLIC_KEY` determines whether public-key operations are desired. `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_BASIC` implicitly enables `PSA_WANT_KEY_TYPE_xxx_PUBLIC_KEY`, as well as support for `psa_export_public_key` on the private key: there is no way to only include private-key operations (which typically saves little code).
|
||||
|
||||
Note: the implementation is always free to include support for more than what was explicitly requested. (For example, as of Mbed TLS 3.5.0, `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_BASIC` implicitly enables import and export support for that key type, but this may not be the case in future versions.) Applications should always request support for all operations they need, rather than rely on them being implicitly enabled by the implementation. The only thing that is documented and guaranteed in the future is as follows: `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_yyy` -> `PSA_WANT_KEY_TYPE_xxx_KEY_PAIR_BASIC` -> `PSA_WANT_KEY_TYPE_xxx_PUBLIC_KEY`.
|
||||
|
||||
#### Configuration symbols for elliptic curves
|
||||
|
||||
For elliptic curve key types, only the specified curves are included. To include a curve, include a symbol of the form **`PSA_WANT_ECC_family_size`**. For example: `PSA_WANT_ECC_SECP_R1_256` for secp256r1, `PSA_WANT_ECC_MONTGOMERY_255` for Curve25519. It is an error to require an ECC key type but no curve, and Mbed TLS will reject this at compile time.
|
||||
|
||||
Rationale: this is a deviation of the general principle that `PSA_ECC_FAMILY_xxx` would have a corresponding symbol `PSA_WANT_ECC_FAMILY_xxx`. This deviation is justified by the fact that it is very common to wish to include only certain curves in a family, and that can lead to a significant gain in code size.
|
||||
|
||||
#### Configuration symbols for Diffie-Hellman groups
|
||||
|
||||
There are no configuration symbols for Diffie-Hellman groups (`PSA_DH_GROUP_xxx`).
|
||||
|
||||
Rationale: Finite-field Diffie-Hellman code is usually not specialized for any particular group, so reducing the number of available groups at compile time only saves a little code space. Constrained implementations tend to omit FFDH anyway, so the small code size gain is not important.
|
||||
|
||||
#### Configuration symbols for algorithms
|
||||
|
||||
For each constant or constructor macro of the form `PSA_ALG_xxx`, the symbol **`PSA_WANT_ALG_xxx`** indicates that support for this algorithm is desired.
|
||||
|
||||
For parametrized algorithms, the `PSA_WANT_ALG_xxx` symbol indicates whether the base mechanism is supported. Parameters must themselves be included through their own `PSA_WANT_ALG_xxx` symbols. It is an error to include a base mechanism without at least one possible parameter, and Mbed TLS will reject this at compile time. For example, `PSA_WANT_ALG_ECDSA` requires the inclusion of randomized ECDSA for all hash algorithms whose corresponding symbol `PSA_WANT_ALG_xxx` is enabled.
|
||||
|
||||
## Implementation
|
||||
|
||||
### Additional non-public symbols
|
||||
|
||||
#### Accounting for transparent drivers
|
||||
|
||||
In addition to the [configuration symbols](#psa-crypto-configuration-symbols), we need two parallel or mostly parallel sets of symbols:
|
||||
|
||||
* **`MBEDTLS_PSA_ACCEL_xxx`** indicates whether a fully-featured, fallback-free transparent driver is available.
|
||||
* **`MBEDTLS_PSA_BUILTIN_xxx`** indicates whether the software implementation is needed.
|
||||
|
||||
`MBEDTLS_PSA_ACCEL_xxx` is one of the outputs of the transpilation of a driver description, alongside the glue code for calling the drivers.
|
||||
|
||||
`MBEDTLS_PSA_BUILTIN_xxx` is enabled when `PSA_WANT_xxx` is enabled and `MBEDTLS_PSA_ACCEL_xxx` is disabled.
|
||||
|
||||
These symbols are not part of the public interface of Mbed TLS towards applications or to drivers, regardless of whether the symbols are actually visible.
|
||||
|
||||
### Architecture of symbol definitions
|
||||
|
||||
#### Definition of configuration symbols
|
||||
|
||||
The header file `mbedtls/mbedtls_config.h` defines all the `MBEDTLS_xxx_C` configuration symbols, including the ones deduced from the PSA Crypto configuration. It does this by including the new header file **`mbedtls/config_psa.h`**, which defines the `MBEDTLS_PSA_BUILTIN_xxx` symbols and deduces the corresponding `MBEDTLS_xxx_C` (and other) symbols.
|
||||
|
||||
`mbedtls/config_psa.h` includes `psa/crypto_config.h`, the user-editable file that defines application requirements.
|
||||
|
||||
#### Summary of definitions of configuration symbols
|
||||
|
||||
`mbedtls/config_psa.h` includes `mbedtls/crypto_drivers.h`, a header file generated by the transpilation of the driver descriptions. It defines `MBEDTLS_PSA_ACCEL_xxx` symbols according to the availability of transparent drivers without fallback.
|
||||
|
||||
The following table summarizes where symbols are defined depending on the configuration mode.
|
||||
|
||||
* (U) indicates a symbol that is defined by the user (application).
|
||||
* (D) indicates a symbol that is deduced from other symbols by code that ships with Mbed TLS.
|
||||
* (G) indicates a symbol that is generated from driver descriptions.
|
||||
|
||||
| Symbols | |
|
||||
| ------------------------- | --------------------------------- |
|
||||
| `MBEDTLS_xxx_C` | `mbedtls/mbedtls_config.h` (U) or |
|
||||
| | `mbedtls/config_psa.h` (D) |
|
||||
| `PSA_WANT_xxx` | `psa/crypto_config.h` (U) |
|
||||
| `MBEDTLS_PSA_BUILTIN_xxx` | `mbedtls/config_psa.h` (D) |
|
||||
| `MBEDTLS_PSA_ACCEL_xxx` | `mbedtls/crypto_drivers.h` (G) |
|
||||
|
||||
#### Visibility of internal symbols
|
||||
|
||||
Ideally, the `MBEDTLS_PSA_ACCEL_xxx` and `MBEDTLS_PSA_BUILTIN_xxx` symbols should not be visible to application code or driver code, since they are not part of the public interface of the library. However these symbols are needed to deduce whether to include library modules (for example `MBEDTLS_AES_C` has to be enabled if `MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES` is enabled), which makes it difficult to keep them private.
|
||||
|
||||
#### Compile-time checks
|
||||
|
||||
The header file **`library/psa_check_config.h`** applies sanity checks to the configuration, throwing `#error` if something is wrong.
|
||||
|
||||
A mechanism similar to `mbedtls/check_config.h` detects errors such as enabling ECDSA but no curve.
|
||||
|
||||
Since configuration symbols must be undefined or 1, any other value should trigger an `#error`.
|
||||
|
||||
#### Automatic generation of preprocessor symbol manipulations
|
||||
|
||||
A lot of the preprocessor symbol manipulation is systematic calculations that analyze the configuration. `mbedtls/config_psa.h` and `library/psa_check_config.h` should be generated automatically, in the same manner as `version_features.c`.
|
||||
|
||||
### Structure of PSA Crypto library code
|
||||
|
||||
#### Conditional inclusion of library entry points
|
||||
|
||||
An entry point can be eliminated entirely if no algorithm requires it.
|
||||
|
||||
#### Conditional inclusion of mechanism-specific code
|
||||
|
||||
Code that is specific to certain key types or to certain algorithms must be guarded by the applicable symbols: `PSA_WANT_xxx` for code that is independent of the application, and `MBEDTLS_PSA_BUILTIN_xxx` for code that calls an Mbed TLS software implementation.
|
||||
|
||||
## PSA standardization
|
||||
|
||||
### JSON configuration mechanism
|
||||
|
||||
At the time of writing, the preferred configuration mechanism for a PSA service is in JSON syntax. The translation from JSON to build instructions is not specified by PSA.
|
||||
|
||||
For PSA Crypto, the preferred configuration mechanism would be similar to capability specifications of transparent drivers. The same JSON properties that are used to mean “this driver can perform that mechanism” in a driver description would be used to mean “the application wants to perform that mechanism” in the application configuration.
|
||||
|
||||
### From JSON to C
|
||||
|
||||
The JSON capability language allows a more fine-grained selection than the C mechanism proposed here. For example, it allows requesting only single-part mechanisms, only certain key sizes, or only certain combinations of algorithms and key types.
|
||||
|
||||
The JSON capability language can be translated approximately to the boolean symbol mechanism proposed here. The approximation considers a feature to be enabled if any part of it is enabled. For example, if there is a capability for AES-CTR and one for CAMELLIA-GCM, the translation to boolean symbols will also include AES-GCM and CAMELLIA-CTR. If there is a capability for AES-128, the translation will also include AES-192 and AES-256.
|
||||
|
||||
The boolean symbol mechanism proposed here can be translated to a list of JSON capabilities: for each included algorithm, include a capability with that algorithm, the key types that apply to that algorithm, no size restriction, and all the entry points that apply to that algorithm.
|
||||
|
||||
## Open questions
|
||||
|
||||
### Open questions about the interface
|
||||
|
||||
#### Naming of symbols
|
||||
|
||||
The names of [elliptic curve symbols](#configuration-symbols-for-elliptic-curves) are a bit weird: `SECP_R1_256` instead of `SECP256R1`, `MONTGOMERY_255` instead of `CURVE25519`. Should we make them more classical, but less systematic?
|
||||
|
||||
#### Impossible combinations
|
||||
|
||||
What does it mean to have `PSA_WANT_ALG_ECDSA` enabled but with only Curve25519? Is it a mandatory error?
|
||||
|
||||
#### Diffie-Hellman
|
||||
|
||||
Way to request only specific groups? Not a priority: constrained devices don't do FFDH. Specify it as may change in future versions.
|
||||
|
||||
#### Coexistence with the current Mbed TLS configuration
|
||||
|
||||
The two mechanisms have very different designs. Is there serious potential for confusion? Do we understand how the combinations work?
|
||||
|
||||
### Open questions about the design
|
||||
|
||||
#### Algorithms without a key type or vice versa
|
||||
|
||||
Is it realistic to mandate a compile-time error if a key type is required, but no matching algorithm, or vice versa? Is it always the right thing, for example if there is an opaque driver that manipulates this key type?
|
||||
|
||||
#### Opaque-only mechanisms
|
||||
|
||||
If a mechanism should only be supported in an opaque driver, what does the core need to know about it? Do we have all the information we need?
|
||||
|
||||
This is especially relevant to suppress a mechanism completely if there is no matching algorithm. For example, if there is no transparent implementation of RSA or ECDSA, `psa_sign_hash` and `psa_verify_hash` may still be needed if there is an opaque signature driver.
|
||||
|
||||
### Open questions about the implementation
|
||||
|
||||
#### Testability
|
||||
|
||||
Is this proposal decently testable? There are a lot of combinations. What combinations should we test?
|
||||
|
||||
<!--
|
||||
Local Variables:
|
||||
time-stamp-line-limit: 40
|
||||
time-stamp-start: "Time-stamp: *\""
|
||||
time-stamp-end: "\""
|
||||
time-stamp-format: "%04Y/%02m/%02d %02H:%02M:%02S %Z"
|
||||
time-stamp-time-zone: "GMT"
|
||||
End:
|
||||
-->
|
||||
@@ -1,52 +0,0 @@
|
||||
PSA Cryptoprocessor driver developer's guide
|
||||
============================================
|
||||
|
||||
**This is a specification of work in progress. The implementation is not yet merged into Mbed TLS.**
|
||||
For a description of the current state of drivers Mbed TLS, see our [PSA Cryptoprocessor driver development examples](../psa-driver-example-and-guide.html).
|
||||
|
||||
This document describes how to write drivers of cryptoprocessors such as accelerators and secure elements for the PSA cryptography subsystem of Mbed TLS.
|
||||
|
||||
This document focuses on behavior that is specific to Mbed TLS. For a reference of the interface between Mbed TLS and drivers, refer to the [PSA Cryptoprocessor Driver Interface specification](psa-driver-interface.html).
|
||||
|
||||
The interface is not fully implemented in Mbed TLS yet. Please note that the interface may still change: until further notice, we do not guarantee backward compatibility with existing driver code.
|
||||
|
||||
## Introduction
|
||||
|
||||
### Purpose
|
||||
|
||||
The PSA cryptography driver interface provides a way to build Mbed TLS with additional code that implements certain cryptographic primitives. This is primarily intended to support platform-specific hardware.
|
||||
|
||||
There are two types of drivers:
|
||||
|
||||
* **Transparent** drivers implement cryptographic operations on keys that are provided in cleartext at the beginning of each operation. They are typically used for hardware **accelerators**. When a transparent driver is available for a particular combination of parameters (cryptographic algorithm, key type and size, etc.), it is used instead of the default software implementation. Transparent drivers can also be pure software implementations that are distributed as plug-ins to a PSA Crypto implementation.
|
||||
* **Opaque** drivers implement cryptographic operations on keys that can only be used inside a protected environment such as a **secure element**, a hardware security module, a smartcard, a secure enclave, etc. An opaque driver is invoked for the specific key location that the driver is registered for: the dispatch is based on the key's lifetime.
|
||||
|
||||
### Deliverables for a driver
|
||||
|
||||
To write a driver, you need to implement some functions with C linkage, and to declare these functions in a **driver description file**. The driver description file declares which functions the driver implements and what cryptographic mechanisms they support. Depending on the driver type, you may also need to define some C types and macros in a header file.
|
||||
|
||||
The concrete syntax for a driver description file is JSON. The structure of this JSON file is specified in the section [“Driver description syntax”](psa-driver-interface.html#driver-description-syntax) of the PSA cryptography driver interface specification.
|
||||
|
||||
A driver therefore consists of:
|
||||
|
||||
* A driver description file (in JSON format).
|
||||
* C header files defining the types required by the driver description. The names of these header files is declared in the driver description file.
|
||||
* An object file compiled for the target platform defining the functions required by the driver description. Implementations may allow drivers to be provided as source files and compiled with the core instead of being pre-compiled.
|
||||
|
||||
## Driver C interfaces
|
||||
|
||||
Mbed TLS calls driver entry points [as specified in the PSA Cryptography Driver Interface specification](psa-driver-interface.html#driver-entry-points) except as otherwise indicated in this section.
|
||||
|
||||
## Mbed TLS extensions
|
||||
|
||||
The driver description can include Mbed TLS extensions (marked by the namespace "mbedtls"). Mbed TLS extensions are meant to extend/help integrating the driver into the library's infrastructure.
|
||||
* `"mbedtls/h_condition"` (optional, string) can include complex preprocessor definitions to conditionally include header files for a given driver.
|
||||
* `"mbedtls/c_condition"` (optional, string) can include complex preprocessor definitions to conditionally enable dispatch capabilities for a driver.
|
||||
|
||||
## Building and testing your driver
|
||||
|
||||
<!-- TODO -->
|
||||
|
||||
## Dependencies on the Mbed TLS configuration
|
||||
|
||||
<!-- TODO -->
|
||||
@@ -1,39 +0,0 @@
|
||||
Building Mbed TLS with PSA cryptoprocessor drivers
|
||||
==================================================
|
||||
|
||||
**This is a specification of work in progress. The implementation is not yet merged into Mbed TLS.**
|
||||
For a description of the current state of drivers Mbed TLS, see our [PSA Cryptoprocessor driver development examples](../psa-driver-example-and-guide.html).
|
||||
|
||||
This document describes how to build Mbed TLS with additional cryptoprocessor drivers that follow the PSA cryptoprocessor driver interface.
|
||||
|
||||
The interface is not fully implemented in Mbed TLS yet. Please note that the interface may still change: until further notice, we do not guarantee backward compatibility with existing driver code.
|
||||
|
||||
## Introduction
|
||||
|
||||
The PSA cryptography driver interface provides a way to build Mbed TLS with additional code that implements certain cryptographic primitives. This is primarily intended to support platform-specific hardware.
|
||||
|
||||
Note that such drivers are only available through the PSA cryptography API (crypto functions beginning with `psa_`, and X.509 and TLS interfaces that reference PSA types).
|
||||
|
||||
Concretely speaking, a driver consists of one or more **driver description files** in JSON format and some code to include in the build. The driver code can either be provided in binary form as additional object file to link, or in source form.
|
||||
|
||||
## How to build Mbed TLS with drivers
|
||||
|
||||
To build Mbed TLS with drivers:
|
||||
|
||||
1. Pass the driver description files through the Make variable `PSA_DRIVERS` when building the library.
|
||||
|
||||
```
|
||||
cd /path/to/mbedtls
|
||||
make PSA_DRIVERS="/path/to/acme/driver.json /path/to/nadir/driver.json" lib
|
||||
```
|
||||
|
||||
2. Link your application with the implementation of the driver functions.
|
||||
|
||||
```
|
||||
cd /path/to/application
|
||||
ld myapp.o -L/path/to/acme -lacmedriver -L/path/to/nadir -lnadirdriver -L/path/to/mbedtls -lmbedcrypto
|
||||
```
|
||||
|
||||
<!-- TODO: what if the driver is provided as C source code? -->
|
||||
|
||||
<!-- TODO: what about additional include files? -->
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,40 +0,0 @@
|
||||
Migrating to an auto generated psa_crypto_driver_wrappers.h file
|
||||
================================================================
|
||||
|
||||
This document describes how to migrate to the auto generated psa_crypto_driver_wrappers.h file.
|
||||
It is meant to give the library user migration guidelines while the Mbed TLS project tides over multiple minor revs of version 1.0, after which this will be merged into psa-driver-interface.md.
|
||||
|
||||
For a practical guide with a description of the current state of drivers Mbed TLS, see our [PSA Cryptoprocessor driver development examples](../psa-driver-example-and-guide.md).
|
||||
|
||||
## Introduction
|
||||
|
||||
The design of the Driver Wrappers code generation is based on the design proposal https://github.com/Mbed-TLS/mbedtls/pull/5067
|
||||
During the process of implementation there might be minor variations wrt versioning and broader implementation specific ideas, but the design remains the same.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Python3, Jinja2 rev 2.10.1 and jsonschema rev 3.2.0
|
||||
|
||||
## Feature Version
|
||||
|
||||
1.1
|
||||
|
||||
### What's critical for a migrating user
|
||||
|
||||
The Driver Wrapper auto generation project is designed to use a python templating library ( Jinja2 ) to render templates based on drivers that are defined using a Driver description JSON file(s).
|
||||
|
||||
While that is the larger goal, for version 1.1 here's what's changed
|
||||
|
||||
#### What's changed
|
||||
|
||||
(1) psa_crypto_driver_wrappers.h will from this point on be auto generated.
|
||||
(2) The auto generation is based on the template file at **scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja**.
|
||||
(3) The driver JSONS to be used for generating the psa_crypto_driver_wrappers.h file can be found at **scripts/data_files/driver_jsons/** as their default location, this path includes the schemas against which the driver schemas will be validated (driver_opaque_schema.json, driver_transparent_schema.json) and a driverlist.json which specifies the drivers to be considered and the order in which they want to be called into. The default location for driverlist.json and driver JSONS can be overloaded by passing an argument --json-dir while running the script generate_driver_wrappers.py.
|
||||
(4) While the complete driver wrapper templating support is yet to come in, if the library user sees a need to patch psa_crypto_driver_wrappers.h file, the user will need to patch into the template file as needed (psa_crypto_driver_wrappers.h.jinja).
|
||||
|
||||
#### How to set your driver up
|
||||
|
||||
Please refer to psa-driver-interface.md for information on how a driver schema can be written.
|
||||
One can also refer to the example test drivers/ JSON schemas under **scripts/data_files/driver_jsons/**.
|
||||
|
||||
The JSON file 'driverlist.json' is meant to be edited by the user to reflect the drivers one wants to use on a device. The order in which the drivers are passed is also essential if/when there are multiple transparent drivers on a given system to retain the same order in the templating.
|
||||
@@ -1,179 +0,0 @@
|
||||
# PSA Cryptoprocessor driver development examples
|
||||
|
||||
As of Mbed TLS 3.4.0, the PSA Driver Interface has only been partially implemented. As a result, the deliverables for writing a driver and the method for integrating a driver with Mbed TLS will vary depending on the operation being accelerated. This document describes how to write and integrate cryptoprocessor drivers depending on which operation or driver type is being implemented.
|
||||
|
||||
The `docs/proposed/` directory contains three documents which pertain to the proposed, work-in-progress driver system. The [PSA Driver Interface](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-interface.md) describes how drivers will interface with Mbed TLS in the future, as well as driver types, operation types, and entry points. As many key terms and concepts used in the examples in this document are defined in the PSA Driver Interface, it is recommended that developers read it prior to starting work on implementing drivers.
|
||||
The PSA Driver [Developer](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-developer-guide.md) Guide describes the deliverables for writing a driver that can be used with Mbed TLS, and the PSA Driver [Integration](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-integration-guide.md) Guide describes how a driver can be built alongside Mbed TLS.
|
||||
|
||||
## Contents:
|
||||
[Background on how Mbed TLS calls drivers](#background-on-how-mbed-tls-calls-drivers)\
|
||||
[Process for Entry Points where auto-generation is implemented](#process-for-entry-points-where-auto-generation-is-implemented) \
|
||||
[Process for Entry Points where auto-generation is not implemented](#process-for-entry-points-where-auto-generation-is-not-implemented) \
|
||||
[Example: Manually integrating a software accelerator alongside Mbed TLS](#example-manually-integrating-a-software-accelerator-alongside-mbed-tls)
|
||||
|
||||
## Background on how Mbed TLS calls drivers
|
||||
|
||||
The PSA Driver Interface specification specifies which cryptographic operations can be accelerated by third-party drivers. Operations that are completed within one step (one function call), such as verifying a signature, are called *Single-Part Operations*. On the other hand, operations that consist of multiple steps implemented by different functions called sequentially are called *Multi-Part Operations*. Single-part operations implemented by a driver will have one entry point, while multi-part operations will have multiple: one for each step.
|
||||
|
||||
There are two types of drivers: *transparent* or *opaque*. See below an excerpt from the PSA Driver Interface specification defining them:
|
||||
* **Transparent** drivers implement cryptographic operations on keys that are provided in cleartext at the beginning of each operation. They are typically used for hardware **accelerators**. When a transparent driver is available for a particular combination of parameters (cryptographic algorithm, key type and size, etc.), it is used instead of the default software implementation. Transparent drivers can also be pure software implementations that are distributed as plug-ins to a PSA Cryptography implementation (for example, an alternative implementation with different performance characteristics, or a certified implementation).
|
||||
* **Opaque** drivers implement cryptographic operations on keys that can only be used inside a protected environment such as a **secure element**, a hardware security module, a smartcard, a secure enclave, etc. An opaque driver is invoked for the specific [key location](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-interface.md#lifetimes-and-locations) that the driver is registered for: the dispatch is based on the key's lifetime.
|
||||
|
||||
Mbed TLS contains a **driver dispatch layer** (also called a driver wrapper layer). For each cryptographic operation that supports driver acceleration (or sub-part of a multi-part operation), the library calls the corresponding function in the driver wrapper. Using flags set at compile time, the driver wrapper ascertains whether any present drivers support the operation. When no such driver is present, the built-in library implementation is called as a fallback (if allowed). When a compatible driver is present, the driver wrapper calls the driver entry point function provided by the driver author.
|
||||
|
||||
The long-term goal is for the driver dispatch layer to be auto-generated using a JSON driver description file provided by the driver author.
|
||||
For some cryptographic operations, this auto-generation logic has already been implemented. When accelerating these operations, the instructions in the above documents can be followed. For the remaining operations which do not yet support auto-generation of the driver wrapper, developers will have to manually edit the driver dispatch layer and call their driver's entry point functions from there.
|
||||
|
||||
Auto-generation of the driver wrapper is supported for the operation entry points specified in the table below. Certain operations are only permitted for opaque drivers. All other operation entry points do not support auto-generation of the driver wrapper.
|
||||
|
||||
| Transparent Driver | Opaque Driver |
|
||||
|---------------------|---------------------|
|
||||
| `import_key` | `import_key` |
|
||||
| `export_public_key` | `export_public_key` |
|
||||
| | `export_key` |
|
||||
| | `copy_key` |
|
||||
| | `get_builtin_key` |
|
||||
|
||||
### Process for Entry Points where auto-generation is implemented
|
||||
|
||||
If the driver is accelerating operations whose entry points are in the above table, the instructions in the driver [developer](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-developer-guide.md) and [integration](https://github.com/Mbed-TLS/mbedtls/blob/development/docs/proposed/psa-driver-integration-guide.md) guides should be followed.
|
||||
|
||||
There are three deliverables for creating such a driver. These are:
|
||||
- A driver description file (in JSON format).
|
||||
- C header files defining the types required by the driver description. The names of these header files are declared in the driver description file.
|
||||
- An object file compiled for the target platform defining the functions required by the driver description. Implementations may allow drivers to be provided as source files and compiled with the core instead of being pre-compiled.
|
||||
|
||||
The Mbed TLS driver tests for the aforementioned entry points provide examples of how these deliverables can be implemented. For sample driver description JSON files, see [`mbedtls_test_transparent_driver.json`](https://github.com/Mbed-TLS/mbedtls/blob/development/tf-psa-crypto/scripts/data_files/driver_jsons/mbedtls_test_transparent_driver.json) or [`mbedtls_test_opaque_driver.json`](https://github.com/Mbed-TLS/mbedtls/blob/development/tf-psa-crypto/scripts/data_files/driver_jsons/mbedtls_test_transparent_driver.json). The header file required by the driver description is [`test_driver.h`](https://github.com/Mbed-TLS/mbedtls/blob/development/framework/tests/include/test/drivers/test_driver.h). As Mbed TLS tests are built from source, there is no object file for the test driver. However, the source for the test driver can be found under `framework/tests/src/drivers`.
|
||||
|
||||
### Process for Entry Points where auto-generation is not implemented
|
||||
|
||||
If the driver is accelerating operations whose entry points are not present in the table, a different process is followed where the developer manually edits the driver dispatch layer. The following steps describe this process. Steps 1, 2, 3, and 7 only need to be done once *per driver*. Steps 4, 5, and 6 must be done *for each single-part operation* or *for each sub-part of a multi-part operation* implemented by the driver.
|
||||
|
||||
**1. Choose a driver prefix and a macro name that indicates whether the driver is enabled** \
|
||||
A driver prefix is simply a word (often the name of the driver) that all functions/macros associated with the driver should begin with. This is similar to how most functions/macros in Mbed TLS begin with `PSA_XXX/psa_xxx` or `MBEDTLS_XXX/mbedtls_xxx`. The macro name can follow the form `DRIVER_PREFIX_ENABLED` or something similar; it will be used to indicate the driver is available to be called. When building with the driver present, define this macro at compile time.
|
||||
|
||||
**2. Include the following in one of the driver header files:**
|
||||
```
|
||||
#if defined(DRIVER_PREFIX_ENABLED)
|
||||
#ifndef PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#define PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT
|
||||
#endif
|
||||
|
||||
// other definitions here
|
||||
|
||||
#endif
|
||||
```
|
||||
|
||||
**3. Conditionally include header files required by the driver**
|
||||
Include any header files required by the driver in `psa_crypto_driver_wrappers.h`, placing the `#include` statements within an `#if defined` block which checks if the driver is available:
|
||||
```
|
||||
#if defined(DRIVER_PREFIX_ENABLED)
|
||||
#include ...
|
||||
#endif
|
||||
```
|
||||
|
||||
|
||||
**4. For each operation being accelerated, locate the function in the driver dispatch layer that corresponds to the entry point of that operation.** \
|
||||
The file `psa_crypto_driver_wrappers.h.jinja` and `psa_crypto_driver_wrappers_no_static.c.jinja` contains the driver wrapper functions. For the entry points that have driver wrapper auto-generation implemented, the functions have been replaced with `jinja` templating logic. While the file has a `.jinja` extension, the driver wrapper functions for the remaining entry points are simple C functions. The names of these functions are of the form `psa_driver_wrapper` followed by the entry point name. So, for example, the function `psa_driver_wrapper_sign_hash()` corresponds to the `sign_hash` entry point.
|
||||
|
||||
**5. If a driver entry point function has been provided then ensure it has the same signature as the driver wrapper function.** \
|
||||
If one has not been provided then write one. Its name should begin with the driver prefix, followed by transparent/opaque (depending on driver type), and end with the entry point name. It should have the same signature as the driver wrapper function. The purpose of the entry point function is to take arguments in PSA format for the implemented operation and return outputs/status codes in PSA format. \
|
||||
*Return Codes:*
|
||||
* `PSA_SUCCESS`: Successful Execution
|
||||
* `PSA_ERROR_NOT_SUPPORTED`: Input arguments are correct, but the driver does not support the operation. If a transparent driver returns this then it allows fallback to another driver or software implementation.
|
||||
* `PSA_ERROR_XXX`: Any other PSA error code, see API documentation
|
||||
|
||||
**6. Modify the driver wrapper function** \
|
||||
Each driver wrapper function contains a `switch` statement which checks the location of the key. If the key is stored in local storage, then operations are performed by a transparent driver. If it is stored elsewhere, then operations are performed by an opaque driver.
|
||||
* **Transparent drivers:** Calls to driver entry points go under `case PSA_KEY_LOCATION_LOCAL_STORAGE`.
|
||||
* **Opaque Drivers** Calls to driver entry points go in a separate `case` block corresponding to the key location.
|
||||
|
||||
|
||||
The diagram below shows the layout of a driver wrapper function which can dispatch to two transparent drivers `Foo` and `Bar`, and one opaque driver `Baz`.
|
||||
|
||||
```
|
||||
psa_driver_wrapper_xxx()
|
||||
├── switch(location)
|
||||
| |
|
||||
| ├── case PSA_KEY_LOCATION_LOCAL_STORAGE //transparent driver
|
||||
| | ├── #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
|
||||
| | | ├── #if defined(FOO_DRIVER_PREFIX_ENABLED)
|
||||
| | | | ├── if(//conditions for foo driver capibilities)
|
||||
| | | | ├── foo_driver_transparent_xxx() //call to driver entry point
|
||||
| | | | ├── if (status != PSA_ERROR_NOT_SUPPORTED) return status
|
||||
| | | ├── #endif
|
||||
| | | ├── #if defined(BAR_DRIVER_PREFIX_ENABLED)
|
||||
| | | | ├── if(//conditions for bar driver capibilities)
|
||||
| | | | ├── bar_driver_transparent_xxx() //call to driver entry point
|
||||
| | | | ├── if (status != PSA_ERROR_NOT_SUPPORTED) return status
|
||||
| | | ├── #endif
|
||||
| | ├── #endif
|
||||
| |
|
||||
| ├── case SECURE_ELEMENT_LOCATION //opaque driver
|
||||
| | ├── #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
|
||||
| | | ├── #if defined(BAZ_DRIVER_PREFIX_ENABLED)
|
||||
| | | | ├── if(//conditions for baz driver capibilities)
|
||||
| | | | ├── baz_driver_opaque_xxx() //call to driver entry point
|
||||
| | | | ├── if (status != PSA_ERROR_NOT_SUPPORTED) return status
|
||||
| | | ├── #endif
|
||||
| | ├── #endif
|
||||
└── return psa_xxx_builtin() // fall back to built in implementation
|
||||
```
|
||||
|
||||
All code related to driver calls within each `case` must be contained between `#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)` and a corresponding `#endif`. Within this block, each individual driver's compatibility checks and call to the entry point must be contained between `#if defined(DRIVER_PREFIX_ENABLED)` and a corresponding `#endif`. Checks that involve accessing key material using PSA macros, such as determining the key type or number of bits, must be done in the driver wrapper.
|
||||
|
||||
**7. Build Mbed TLS with the driver**
|
||||
This guide assumes you are building Mbed TLS from source alongside your project. If building with a driver present, the chosen driver macro (`DRIVER_PREFIX_ENABLED`) must be defined. This can be done in two ways:
|
||||
* *At compile time via flags.* This is the preferred option when your project uses Mbed TLS mostly out-of-the-box without significantly modifying the configuration. This can be done by passing the option via `CFLAGS`.
|
||||
* **Make**:
|
||||
```
|
||||
make CFLAGS="-DDRIVER_PREFIX_ENABLED"
|
||||
```
|
||||
* **CMake**: CFLAGS must be passed to CMake when it is invoked. Invoke CMake with
|
||||
|
||||
```
|
||||
CFLAGS="-DDRIVER_PREFIX_ENABLED" cmake path/to/source
|
||||
```
|
||||
* *Providing a user config file.* This is the preferred option when your project requires a custom configuration that is significantly different to the default. Define the macro for the driver, along with any other custom configurations in a separate header file, then use `config.py`, to set `MBEDTLS_USER_CONFIG_FILE`, providing the path to the defined header file. This will include your custom config file after the default. If you wish to completely replace the default config file, set `MBEDTLS_CONFIG_FILE` instead.
|
||||
|
||||
### Example: Manually integrating a software accelerator alongside Mbed TLS
|
||||
|
||||
[p256-m](https://github.com/mpg/p256-m) is a minimalistic implementation of ECDH and ECDSA on the NIST P-256 curve, specifically optimized for use in constrained 32-bit environments. It started out as an independent project and has been integrated in Mbed TLS as a PSA transparent driver. The source code of p256-m and the driver entry points is located in the Mbed TLS source tree under `drivers/p256-m`. In this section, we will look at how this integration was done.
|
||||
|
||||
The Mbed TLS build system includes the instructions needed to build p256-m. To build with and use p256-m, set the macro `MBEDTLS_PSA_P256M_DRIVER_ENABLED` using `config.py`, then build as usual using make/cmake. From the root of the `mbedtls/` directory, run:
|
||||
|
||||
python3 scripts/config.py set MBEDTLS_PSA_P256M_DRIVER_ENABLED
|
||||
make
|
||||
|
||||
(You need extra steps if you want to disable the built-in implementation of ECC algorithms, which includes more features than p256-m. Refer to the documentation of `MBEDTLS_PSA_P256M_DRIVER_ENABLED` and [`driver-only-builds.md`](driver-only-builds.md) for more information.)
|
||||
|
||||
The driver prefix for p256-m is `P256`/`p256`.
|
||||
The p256-m driver implements the following entry points: `"import_key"`, `"export_public_key"`, `"generate_key"`, `"key_agreement"`, `"sign_hash"`, `"verify_hash"`.
|
||||
There are no entry points for `"sign_message"` and `"verify_message"`, which are not necessary for a sign-and-hash algorithm. The core still implements these functions by doing the hashes and then calling the sign/verify-hash entry points.
|
||||
The driver entry point functions can be found in `p256m_driver_entrypoints.[hc]`. These functions act as an interface between Mbed TLS and p256-m; converting between PSA and p256-m argument formats and performing sanity checks. If the driver's status codes differ from PSA's, it is recommended to implement a status code translation function. The function `p256_to_psa_error()` converts error codes returned by p256-m into PSA error codes.
|
||||
|
||||
The driver wrapper functions in `psa_crypto_driver_wrappers.h.jinja` for all four entry points have also been modified. The code block below shows the additions made to `psa_driver_wrapper_sign_hash()`. In adherence to the defined process, all code related to the driver call is placed within a check for `MBEDTLS_PSA_P256M_DRIVER_ENABLED`. p256-m only supports non-deterministic ECDSA using keys based on NIST P256; these constraints are enforced through checks (see the `if` statement). Checks that involve accessing key attributes, (e.g. checking key type or bits) **must** be performed in the driver wrapper. This is because this information is marked private and may not be accessed outside the library. Other checks can be performed here or in the entry point function. The status returned by the driver is propagated up the call hierarchy **unless** the driver does not support the operation (i.e. return `PSA_ERROR_NOT_SUPPORTED`). In that case the next available driver/built-in implementation is called.
|
||||
|
||||
```
|
||||
#if defined (MBEDTLS_PSA_P256M_DRIVER_ENABLED)
|
||||
if( PSA_KEY_TYPE_IS_ECC( psa_get_key_type(attributes) ) &&
|
||||
PSA_ALG_IS_ECDSA(alg) &&
|
||||
!PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) &&
|
||||
PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes)) == PSA_ECC_FAMILY_SECP_R1 &&
|
||||
psa_get_key_bits(attributes) == 256 )
|
||||
{
|
||||
status = p256_transparent_sign_hash( attributes,
|
||||
key_buffer,
|
||||
key_buffer_size,
|
||||
alg,
|
||||
hash,
|
||||
hash_length,
|
||||
signature,
|
||||
signature_size,
|
||||
signature_length );
|
||||
if( status != PSA_ERROR_NOT_SUPPORTED )
|
||||
return( status );
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_P256M_DRIVER_ENABLED */
|
||||
```
|
||||
Following this, p256-m is now ready to use alongside Mbed TLS as a software accelerator. If `MBEDTLS_PSA_P256M_DRIVER_ENABLED` is set in the config, p256-m's implementations of key generation, ECDH, and ECDSA will be used where applicable.
|
||||
1
tf-psa-crypto/doxygen/.gitignore
vendored
1
tf-psa-crypto/doxygen/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
tfpsacrypto.doxyfile
|
||||
1
tf-psa-crypto/doxygen/input/.gitignore
vendored
1
tf-psa-crypto/doxygen/input/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
doc_mainpage.h
|
||||
@@ -1,19 +0,0 @@
|
||||
/**
|
||||
* \file doc_mainpage.h
|
||||
*
|
||||
* \brief Main page documentation file.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
/**
|
||||
* @mainpage TF-PSA-Crypto v@TF-PSA-Crypto_VERSION@ source code documentation
|
||||
*
|
||||
* This documentation describes the internal structure of the TF-PSA-Crypto
|
||||
* library. It was automatically generated from specially formatted comment
|
||||
* blocks in TF-PSA-Crypto source code using Doxygen (see
|
||||
* http://www.stack.nl/~dimitri/doxygen/ for more information on Doxygen).
|
||||
*/
|
||||
@@ -1,54 +0,0 @@
|
||||
PROJECT_NAME = "TF-PSA-Crypto v@TF-PSA-Crypto_VERSION@"
|
||||
OUTPUT_DIRECTORY = ../apidoc/
|
||||
FULL_PATH_NAMES = NO
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_PRIVATE = YES
|
||||
EXTRACT_STATIC = YES
|
||||
CASE_SENSE_NAMES = NO
|
||||
INPUT = ../include input
|
||||
FILE_PATTERNS = *.h
|
||||
EXCLUDE = ../include/psa/crypto_se_driver.h
|
||||
RECURSIVE = YES
|
||||
EXCLUDE_SYMLINKS = YES
|
||||
SOURCE_BROWSER = YES
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
ALPHABETICAL_INDEX = NO
|
||||
HTML_OUTPUT = .
|
||||
HTML_TIMESTAMP = YES
|
||||
SEARCHENGINE = YES
|
||||
GENERATE_LATEX = NO
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
INCLUDE_PATH = ../include
|
||||
EXPAND_AS_DEFINED = MBEDTLS_PRIVATE
|
||||
CLASS_DIAGRAMS = NO
|
||||
HAVE_DOT = YES
|
||||
DOT_GRAPH_MAX_NODES = 200
|
||||
MAX_DOT_GRAPH_DEPTH = 1000
|
||||
DOT_TRANSPARENT = YES
|
||||
|
||||
# We mostly use \retval declarations to document which error codes a function
|
||||
# can return. The reader can follow the hyperlink to the definition of the
|
||||
# constant to get the generic documentation of that error code. If we don't
|
||||
# have anything to say about the specific error code for the specific
|
||||
# function, we can leave the description part of the \retval command blank.
|
||||
# This is perfectly valid as far as Doxygen is concerned. However, with
|
||||
# Clang >=15, the -Wdocumentation option emits a warning for empty
|
||||
# descriptions.
|
||||
# https://github.com/Mbed-TLS/mbedtls/issues/6960
|
||||
# https://github.com/llvm/llvm-project/issues/60315
|
||||
# As a workaround, you can write something like
|
||||
# \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
|
||||
# This avoids writing redundant text and keeps Clang happy.
|
||||
ALIASES += emptydescription=""
|
||||
|
||||
# Define away macros that make parsing definitions difficult.
|
||||
# MBEDTLS_DEPRECATED is not included in this list as it's important to
|
||||
# display deprecated status in the documentation.
|
||||
PREDEFINED = "MBEDTLS_CHECK_RETURN_CRITICAL=" \
|
||||
"MBEDTLS_CHECK_RETURN_TYPICAL=" \
|
||||
"MBEDTLS_CHECK_RETURN_OPTIONAL=" \
|
||||
"MBEDTLS_PRINTF_ATTRIBUTE(a,b)=" \
|
||||
"__DOXYGEN__" \
|
||||
@@ -1,3 +0,0 @@
|
||||
add_subdirectory(everest)
|
||||
add_subdirectory(p256-m)
|
||||
add_subdirectory(builtin)
|
||||
@@ -1,111 +0,0 @@
|
||||
add_subdirectory(src)
|
||||
|
||||
file(GLOB src_builtin RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} src/*.c)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
set(LIBS_C_FLAGS -Wmissing-declarations -Wmissing-prototypes)
|
||||
endif(CMAKE_COMPILER_IS_GNUCC)
|
||||
|
||||
if(CMAKE_COMPILER_IS_CLANG)
|
||||
set(LIBS_C_FLAGS -Wmissing-declarations -Wmissing-prototypes -Wdocumentation -Wno-documentation-deprecated-sync -Wunreachable-code)
|
||||
endif(CMAKE_COMPILER_IS_CLANG)
|
||||
|
||||
if(CMAKE_COMPILER_IS_MSVC)
|
||||
option(MSVC_STATIC_RUNTIME "Build the libraries with /MT compiler flag" OFF)
|
||||
if(MSVC_STATIC_RUNTIME)
|
||||
foreach(flag_var
|
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_C_FLAGS_CHECK)
|
||||
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
||||
endforeach(flag_var)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(libs ${libs} ws2_32 bcrypt)
|
||||
endif(WIN32)
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang")
|
||||
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
|
||||
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
||||
endif()
|
||||
|
||||
if(LINK_WITH_PTHREAD)
|
||||
set(libs ${libs} ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
|
||||
set(builtin_target ${TF_PSA_CRYPTO_TARGET_PREFIX}builtin)
|
||||
if (USE_STATIC_TF_PSA_CRYPTO_LIBRARY)
|
||||
set(builtin_static_target ${builtin_target})
|
||||
endif()
|
||||
set(target_libraries ${builtin_target})
|
||||
if(USE_STATIC_TF_PSA_CRYPTO_LIBRARY AND USE_SHARED_TF_PSA_CRYPTO_LIBRARY)
|
||||
string(APPEND builtin_static_target "_static")
|
||||
list(APPEND target_libraries ${builtin_static_target})
|
||||
endif()
|
||||
|
||||
set(p256m_target "${TF_PSA_CRYPTO_TARGET_PREFIX}p256m")
|
||||
set(everest_target "${TF_PSA_CRYPTO_TARGET_PREFIX}everest")
|
||||
|
||||
if(USE_STATIC_TF_PSA_CRYPTO_LIBRARY)
|
||||
add_library(${builtin_static_target} STATIC ${src_builtin})
|
||||
set_base_compile_options(${builtin_static_target})
|
||||
target_compile_options(${builtin_static_target} PRIVATE ${LIBS_C_FLAGS})
|
||||
target_link_libraries(${builtin_static_target} PUBLIC ${libs})
|
||||
if(TARGET ${everest_target})
|
||||
target_link_libraries(${builtin_static_target} PUBLIC ${everest_target})
|
||||
endif()
|
||||
|
||||
if(TARGET ${p256m_target})
|
||||
target_link_libraries(${builtin_static_target} PUBLIC ${p256m_target})
|
||||
endif()
|
||||
endif(USE_STATIC_TF_PSA_CRYPTO_LIBRARY)
|
||||
|
||||
if(USE_SHARED_TF_PSA_CRYPTO_LIBRARY)
|
||||
add_library(${builtin_target} SHARED ${src_builtin})
|
||||
set_base_compile_options(${builtin_target})
|
||||
target_compile_options(${builtin_target} PRIVATE ${LIBS_C_FLAGS})
|
||||
target_link_libraries(${builtin_target} PUBLIC ${libs})
|
||||
if(TARGET ${everest_target})
|
||||
target_link_libraries(${builtin_target} PUBLIC ${everest_target})
|
||||
endif()
|
||||
|
||||
if(TARGET ${p256m_target})
|
||||
target_link_libraries(${builtin_target} PUBLIC ${p256m_target})
|
||||
endif()
|
||||
endif(USE_SHARED_TF_PSA_CRYPTO_LIBRARY)
|
||||
|
||||
foreach (target IN LISTS target_libraries)
|
||||
target_include_directories(${target}
|
||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<BUILD_INTERFACE:${TF_PSA_CRYPTO_DIR}/include>
|
||||
PRIVATE ${TF_PSA_CRYPTO_DIR}/core)
|
||||
set_config_files_compile_definitions(${target})
|
||||
|
||||
if(INSTALL_TF_PSA_CRYPTO_HEADERS)
|
||||
|
||||
install(DIRECTORY include/mbedtls
|
||||
DESTINATION include
|
||||
FILE_PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
|
||||
DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ
|
||||
GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
|
||||
FILES_MATCHING PATTERN "*.h")
|
||||
|
||||
endif(INSTALL_TF_PSA_CRYPTO_HEADERS)
|
||||
|
||||
install(TARGETS ${target}
|
||||
EXPORT MbedTLSTargets
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
|
||||
|
||||
install(TARGETS ${target}
|
||||
EXPORT TF-PSA-CryptoTargets
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
|
||||
endforeach(target)
|
||||
@@ -1,585 +0,0 @@
|
||||
/**
|
||||
* \file aes.h
|
||||
*
|
||||
* \brief This file contains AES definitions and functions.
|
||||
*
|
||||
* The Advanced Encryption Standard (AES) specifies a FIPS-approved
|
||||
* cryptographic algorithm that can be used to protect electronic
|
||||
* data.
|
||||
*
|
||||
* The AES algorithm is a symmetric block cipher that can
|
||||
* encrypt and decrypt information. For more information, see
|
||||
* <em>FIPS Publication 197: Advanced Encryption Standard</em> and
|
||||
* <em>ISO/IEC 18033-2:2006: Information technology -- Security
|
||||
* techniques -- Encryption algorithms -- Part 2: Asymmetric
|
||||
* ciphers</em>.
|
||||
*
|
||||
* The AES-XTS block mode is standardized by NIST SP 800-38E
|
||||
* <https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-38e.pdf>
|
||||
* and described in detail by IEEE P1619
|
||||
* <https://ieeexplore.ieee.org/servlet/opac?punumber=4375278>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_AES_H
|
||||
#define MBEDTLS_AES_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* aesni.c relies on these values! */
|
||||
#define MBEDTLS_AES_ENCRYPT 1 /**< AES encryption. */
|
||||
#define MBEDTLS_AES_DECRYPT 0 /**< AES decryption. */
|
||||
|
||||
/* Error codes in range 0x0020-0x0022 */
|
||||
/** Invalid key length. */
|
||||
#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020
|
||||
/** Invalid data input length. */
|
||||
#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022
|
||||
|
||||
/* Error codes in range 0x0021-0x0025 */
|
||||
/** Invalid input data. */
|
||||
#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The AES context-type definition.
|
||||
*/
|
||||
typedef struct mbedtls_aes_context {
|
||||
int MBEDTLS_PRIVATE(nr); /*!< The number of rounds. */
|
||||
size_t MBEDTLS_PRIVATE(rk_offset); /*!< The offset in array elements to AES
|
||||
round keys in the buffer. */
|
||||
#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
|
||||
uint32_t MBEDTLS_PRIVATE(buf)[44]; /*!< Aligned data buffer to hold
|
||||
10 round keys for 128-bit case. */
|
||||
#else
|
||||
uint32_t MBEDTLS_PRIVATE(buf)[68]; /*!< Unaligned data buffer. This buffer can
|
||||
hold 32 extra Bytes, which can be used for
|
||||
simplifying key expansion in the 256-bit
|
||||
case by generating an extra round key. */
|
||||
#endif /* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
|
||||
}
|
||||
mbedtls_aes_context;
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||
/**
|
||||
* \brief The AES XTS context-type definition.
|
||||
*/
|
||||
typedef struct mbedtls_aes_xts_context {
|
||||
mbedtls_aes_context MBEDTLS_PRIVATE(crypt); /*!< The AES context to use for AES block
|
||||
encryption or decryption. */
|
||||
mbedtls_aes_context MBEDTLS_PRIVATE(tweak); /*!< The AES context used for tweak
|
||||
computation. */
|
||||
} mbedtls_aes_xts_context;
|
||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||
|
||||
/**
|
||||
* \brief This function initializes the specified AES context.
|
||||
*
|
||||
* It must be the first API called before using
|
||||
* the context.
|
||||
*
|
||||
* \param ctx The AES context to initialize. This must not be \c NULL.
|
||||
*/
|
||||
void mbedtls_aes_init(mbedtls_aes_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function releases and clears the specified AES context.
|
||||
*
|
||||
* \param ctx The AES context to clear.
|
||||
* If this is \c NULL, this function does nothing.
|
||||
* Otherwise, the context must have been at least initialized.
|
||||
*/
|
||||
void mbedtls_aes_free(mbedtls_aes_context *ctx);
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||
/**
|
||||
* \brief This function initializes the specified AES XTS context.
|
||||
*
|
||||
* It must be the first API called before using
|
||||
* the context.
|
||||
*
|
||||
* \param ctx The AES XTS context to initialize. This must not be \c NULL.
|
||||
*/
|
||||
void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function releases and clears the specified AES XTS context.
|
||||
*
|
||||
* \param ctx The AES XTS context to clear.
|
||||
* If this is \c NULL, this function does nothing.
|
||||
* Otherwise, the context must have been at least initialized.
|
||||
*/
|
||||
void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||
|
||||
/**
|
||||
* \brief This function sets the encryption key.
|
||||
*
|
||||
* \param ctx The AES context to which the key should be bound.
|
||||
* It must be initialized.
|
||||
* \param key The encryption key.
|
||||
* This must be a readable buffer of size \p keybits bits.
|
||||
* \param keybits The size of data passed in bits. Valid options are:
|
||||
* <ul><li>128 bits</li>
|
||||
* <li>192 bits</li>
|
||||
* <li>256 bits</li></ul>
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
/**
|
||||
* \brief This function sets the decryption key.
|
||||
*
|
||||
* \param ctx The AES context to which the key should be bound.
|
||||
* It must be initialized.
|
||||
* \param key The decryption key.
|
||||
* This must be a readable buffer of size \p keybits bits.
|
||||
* \param keybits The size of data passed. Valid options are:
|
||||
* <ul><li>128 bits</li>
|
||||
* <li>192 bits</li>
|
||||
* <li>256 bits</li></ul>
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||
/**
|
||||
* \brief This function prepares an XTS context for encryption and
|
||||
* sets the encryption key.
|
||||
*
|
||||
* \param ctx The AES XTS context to which the key should be bound.
|
||||
* It must be initialized.
|
||||
* \param key The encryption key. This is comprised of the XTS key1
|
||||
* concatenated with the XTS key2.
|
||||
* This must be a readable buffer of size \p keybits bits.
|
||||
* \param keybits The size of \p key passed in bits. Valid options are:
|
||||
* <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
|
||||
* <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
|
||||
/**
|
||||
* \brief This function prepares an XTS context for decryption and
|
||||
* sets the decryption key.
|
||||
*
|
||||
* \param ctx The AES XTS context to which the key should be bound.
|
||||
* It must be initialized.
|
||||
* \param key The decryption key. This is comprised of the XTS key1
|
||||
* concatenated with the XTS key2.
|
||||
* This must be a readable buffer of size \p keybits bits.
|
||||
* \param keybits The size of \p key passed in bits. Valid options are:
|
||||
* <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
|
||||
* <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||
|
||||
/**
|
||||
* \brief This function performs an AES single-block encryption or
|
||||
* decryption operation.
|
||||
*
|
||||
* It performs the operation defined in the \p mode parameter
|
||||
* (encrypt or decrypt), on the input data buffer defined in
|
||||
* the \p input parameter.
|
||||
*
|
||||
* mbedtls_aes_init(), and either mbedtls_aes_setkey_enc() or
|
||||
* mbedtls_aes_setkey_dec() must be called before the first
|
||||
* call to this API with the same context.
|
||||
*
|
||||
* \param ctx The AES context to use for encryption or decryption.
|
||||
* It must be initialized and bound to a key.
|
||||
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
|
||||
* #MBEDTLS_AES_DECRYPT.
|
||||
* \param input The buffer holding the input data.
|
||||
* It must be readable and at least \c 16 Bytes long.
|
||||
* \param output The buffer where the output data will be written.
|
||||
* It must be writeable and at least \c 16 Bytes long.
|
||||
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16]);
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
/**
|
||||
* \brief This function performs an AES-CBC encryption or decryption operation
|
||||
* on full blocks.
|
||||
*
|
||||
* It performs the operation defined in the \p mode
|
||||
* parameter (encrypt/decrypt), on the input data buffer defined in
|
||||
* the \p input parameter.
|
||||
*
|
||||
* It can be called as many times as needed, until all the input
|
||||
* data is processed. mbedtls_aes_init(), and either
|
||||
* mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called
|
||||
* before the first call to this API with the same context.
|
||||
*
|
||||
* \note This function operates on full blocks, that is, the input size
|
||||
* must be a multiple of the AES block size of \c 16 Bytes.
|
||||
*
|
||||
* \note Upon exit, the content of the IV is updated so that you can
|
||||
* call the same function again on the next
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If you need to retain the contents of the IV, you should
|
||||
* either save it manually or use the cipher module instead.
|
||||
*
|
||||
*
|
||||
* \param ctx The AES context to use for encryption or decryption.
|
||||
* It must be initialized and bound to a key.
|
||||
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
|
||||
* #MBEDTLS_AES_DECRYPT.
|
||||
* \param length The length of the input data in Bytes. This must be a
|
||||
* multiple of the block size (\c 16 Bytes).
|
||||
* \param iv Initialization vector (updated after use).
|
||||
* It must be a readable and writeable buffer of \c 16 Bytes.
|
||||
* \param input The buffer holding the input data.
|
||||
* It must be readable and of size \p length Bytes.
|
||||
* \param output The buffer holding the output data.
|
||||
* It must be writeable and of size \p length Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
|
||||
* on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_XTS)
|
||||
/**
|
||||
* \brief This function performs an AES-XTS encryption or decryption
|
||||
* operation for an entire XTS data unit.
|
||||
*
|
||||
* AES-XTS encrypts or decrypts blocks based on their location as
|
||||
* defined by a data unit number. The data unit number must be
|
||||
* provided by \p data_unit.
|
||||
*
|
||||
* NIST SP 800-38E limits the maximum size of a data unit to 2^20
|
||||
* AES blocks. If the data unit is larger than this, this function
|
||||
* returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH.
|
||||
*
|
||||
* \param ctx The AES XTS context to use for AES XTS operations.
|
||||
* It must be initialized and bound to a key.
|
||||
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
|
||||
* #MBEDTLS_AES_DECRYPT.
|
||||
* \param length The length of a data unit in Bytes. This can be any
|
||||
* length between 16 bytes and 2^24 bytes inclusive
|
||||
* (between 1 and 2^20 block cipher blocks).
|
||||
* \param data_unit The address of the data unit encoded as an array of 16
|
||||
* bytes in little-endian format. For disk encryption, this
|
||||
* is typically the index of the block device sector that
|
||||
* contains the data.
|
||||
* \param input The buffer holding the input data (which is an entire
|
||||
* data unit). This function reads \p length Bytes from \p
|
||||
* input.
|
||||
* \param output The buffer holding the output data (which is an entire
|
||||
* data unit). This function writes \p length Bytes to \p
|
||||
* output.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is
|
||||
* smaller than an AES block in size (16 Bytes) or if \p
|
||||
* length is larger than 2^20 blocks (16 MiB).
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
const unsigned char data_unit[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_XTS */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||
/**
|
||||
* \brief This function performs an AES-CFB128 encryption or decryption
|
||||
* operation.
|
||||
*
|
||||
* It performs the operation defined in the \p mode
|
||||
* parameter (encrypt or decrypt), on the input data buffer
|
||||
* defined in the \p input parameter.
|
||||
*
|
||||
* For CFB, you must set up the context with mbedtls_aes_setkey_enc(),
|
||||
* regardless of whether you are performing an encryption or decryption
|
||||
* operation, that is, regardless of the \p mode parameter. This is
|
||||
* because CFB mode uses the same key schedule for encryption and
|
||||
* decryption.
|
||||
*
|
||||
* \note Upon exit, the content of the IV is updated so that you can
|
||||
* call the same function again on the next
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If you need to retain the contents of the
|
||||
* IV, you must either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
*
|
||||
* \param ctx The AES context to use for encryption or decryption.
|
||||
* It must be initialized and bound to a key.
|
||||
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
|
||||
* #MBEDTLS_AES_DECRYPT.
|
||||
* \param length The length of the input data in Bytes.
|
||||
* \param iv_off The offset in IV (updated after use).
|
||||
* It must point to a valid \c size_t.
|
||||
* \param iv The initialization vector (updated after use).
|
||||
* It must be a readable and writeable buffer of \c 16 Bytes.
|
||||
* \param input The buffer holding the input data.
|
||||
* It must be readable and of size \p length Bytes.
|
||||
* \param output The buffer holding the output data.
|
||||
* It must be writeable and of size \p length Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
|
||||
/**
|
||||
* \brief This function performs an AES-CFB8 encryption or decryption
|
||||
* operation.
|
||||
*
|
||||
* It performs the operation defined in the \p mode
|
||||
* parameter (encrypt/decrypt), on the input data buffer defined
|
||||
* in the \p input parameter.
|
||||
*
|
||||
* Due to the nature of CFB, you must use the same key schedule for
|
||||
* both encryption and decryption operations. Therefore, you must
|
||||
* use the context initialized with mbedtls_aes_setkey_enc() for
|
||||
* both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
|
||||
*
|
||||
* \note Upon exit, the content of the IV is updated so that you can
|
||||
* call the same function again on the next
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If you need to retain the contents of the
|
||||
* IV, you should either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
*
|
||||
* \param ctx The AES context to use for encryption or decryption.
|
||||
* It must be initialized and bound to a key.
|
||||
* \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or
|
||||
* #MBEDTLS_AES_DECRYPT
|
||||
* \param length The length of the input data.
|
||||
* \param iv The initialization vector (updated after use).
|
||||
* It must be a readable and writeable buffer of \c 16 Bytes.
|
||||
* \param input The buffer holding the input data.
|
||||
* It must be readable and of size \p length Bytes.
|
||||
* \param output The buffer holding the output data.
|
||||
* It must be writeable and of size \p length Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /*MBEDTLS_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_OFB)
|
||||
/**
|
||||
* \brief This function performs an AES-OFB (Output Feedback Mode)
|
||||
* encryption or decryption operation.
|
||||
*
|
||||
* For OFB, you must set up the context with
|
||||
* mbedtls_aes_setkey_enc(), regardless of whether you are
|
||||
* performing an encryption or decryption operation. This is
|
||||
* because OFB mode uses the same key schedule for encryption and
|
||||
* decryption.
|
||||
*
|
||||
* The OFB operation is identical for encryption or decryption,
|
||||
* therefore no operation mode needs to be specified.
|
||||
*
|
||||
* \note Upon exit, the content of iv, the Initialisation Vector, is
|
||||
* updated so that you can call the same function again on the next
|
||||
* block(s) of data and get the same result as if it was encrypted
|
||||
* in one call. This allows a "streaming" usage, by initialising
|
||||
* iv_off to 0 before the first call, and preserving its value
|
||||
* between calls.
|
||||
*
|
||||
* For non-streaming use, the iv should be initialised on each call
|
||||
* to a unique value, and iv_off set to 0 on each call.
|
||||
*
|
||||
* If you need to retain the contents of the initialisation vector,
|
||||
* you must either save it manually or use the cipher module
|
||||
* instead.
|
||||
*
|
||||
* \warning For the OFB mode, the initialisation vector must be unique
|
||||
* every encryption operation. Reuse of an initialisation vector
|
||||
* will compromise security.
|
||||
*
|
||||
* \param ctx The AES context to use for encryption or decryption.
|
||||
* It must be initialized and bound to a key.
|
||||
* \param length The length of the input data.
|
||||
* \param iv_off The offset in IV (updated after use).
|
||||
* It must point to a valid \c size_t.
|
||||
* \param iv The initialization vector (updated after use).
|
||||
* It must be a readable and writeable buffer of \c 16 Bytes.
|
||||
* \param input The buffer holding the input data.
|
||||
* It must be readable and of size \p length Bytes.
|
||||
* \param output The buffer holding the output data.
|
||||
* It must be writeable and of size \p length Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
|
||||
#endif /* MBEDTLS_CIPHER_MODE_OFB */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
||||
/**
|
||||
* \brief This function performs an AES-CTR encryption or decryption
|
||||
* operation.
|
||||
*
|
||||
* Due to the nature of CTR, you must use the same key schedule
|
||||
* for both encryption and decryption operations. Therefore, you
|
||||
* must use the context initialized with mbedtls_aes_setkey_enc()
|
||||
* for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
|
||||
*
|
||||
* \warning You must never reuse a nonce value with the same key. Doing so
|
||||
* would void the encryption for the two messages encrypted with
|
||||
* the same nonce and key.
|
||||
*
|
||||
* There are two common strategies for managing nonces with CTR:
|
||||
*
|
||||
* 1. You can handle everything as a single message processed over
|
||||
* successive calls to this function. In that case, you want to
|
||||
* set \p nonce_counter and \p nc_off to 0 for the first call, and
|
||||
* then preserve the values of \p nonce_counter, \p nc_off and \p
|
||||
* stream_block across calls to this function as they will be
|
||||
* updated by this function.
|
||||
*
|
||||
* With this strategy, you must not encrypt more than 2**128
|
||||
* blocks of data with the same key.
|
||||
*
|
||||
* 2. You can encrypt separate messages by dividing the \p
|
||||
* nonce_counter buffer in two areas: the first one used for a
|
||||
* per-message nonce, handled by yourself, and the second one
|
||||
* updated by this function internally.
|
||||
*
|
||||
* For example, you might reserve the first 12 bytes for the
|
||||
* per-message nonce, and the last 4 bytes for internal use. In that
|
||||
* case, before calling this function on a new message you need to
|
||||
* set the first 12 bytes of \p nonce_counter to your chosen nonce
|
||||
* value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
|
||||
* stream_block to be ignored). That way, you can encrypt at most
|
||||
* 2**96 messages of up to 2**32 blocks each with the same key.
|
||||
*
|
||||
* The per-message nonce (or information sufficient to reconstruct
|
||||
* it) needs to be communicated with the ciphertext and must be unique.
|
||||
* The recommended way to ensure uniqueness is to use a message
|
||||
* counter. An alternative is to generate random nonces, but this
|
||||
* limits the number of messages that can be securely encrypted:
|
||||
* for example, with 96-bit random nonces, you should not encrypt
|
||||
* more than 2**32 messages with the same key.
|
||||
*
|
||||
* Note that for both strategies, sizes are measured in blocks and
|
||||
* that an AES block is 16 bytes.
|
||||
*
|
||||
* \warning Upon return, \p stream_block contains sensitive data. Its
|
||||
* content must not be written to insecure storage and should be
|
||||
* securely discarded as soon as it's no longer needed.
|
||||
*
|
||||
* \param ctx The AES context to use for encryption or decryption.
|
||||
* It must be initialized and bound to a key.
|
||||
* \param length The length of the input data.
|
||||
* \param nc_off The offset in the current \p stream_block, for
|
||||
* resuming within the current cipher stream. The
|
||||
* offset pointer should be 0 at the start of a stream.
|
||||
* It must point to a valid \c size_t.
|
||||
* \param nonce_counter The 128-bit nonce and counter.
|
||||
* It must be a readable-writeable buffer of \c 16 Bytes.
|
||||
* \param stream_block The saved stream block for resuming. This is
|
||||
* overwritten by the function.
|
||||
* It must be a readable-writeable buffer of \c 16 Bytes.
|
||||
* \param input The buffer holding the input data.
|
||||
* It must be readable and of size \p length Bytes.
|
||||
* \param output The buffer holding the output data.
|
||||
* It must be writeable and of size \p length Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[16],
|
||||
unsigned char stream_block[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
/**
|
||||
* \brief Checkup routine.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c 1 on failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_aes_self_test(int verbose);
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* aes.h */
|
||||
@@ -1,335 +0,0 @@
|
||||
/**
|
||||
* \file aria.h
|
||||
*
|
||||
* \brief ARIA block cipher
|
||||
*
|
||||
* The ARIA algorithm is a symmetric block cipher that can encrypt and
|
||||
* decrypt information. It is defined by the Korean Agency for
|
||||
* Technology and Standards (KATS) in <em>KS X 1213:2004</em> (in
|
||||
* Korean, but see http://210.104.33.10/ARIA/index-e.html in English)
|
||||
* and also described by the IETF in <em>RFC 5794</em>.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_ARIA_H
|
||||
#define MBEDTLS_ARIA_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#define MBEDTLS_ARIA_ENCRYPT 1 /**< ARIA encryption. */
|
||||
#define MBEDTLS_ARIA_DECRYPT 0 /**< ARIA decryption. */
|
||||
|
||||
#define MBEDTLS_ARIA_BLOCKSIZE 16 /**< ARIA block size in bytes. */
|
||||
#define MBEDTLS_ARIA_MAX_ROUNDS 16 /**< Maximum number of rounds in ARIA. */
|
||||
#define MBEDTLS_ARIA_MAX_KEYSIZE 32 /**< Maximum size of an ARIA key in bytes. */
|
||||
|
||||
/** Bad input data. */
|
||||
#define MBEDTLS_ERR_ARIA_BAD_INPUT_DATA -0x005C
|
||||
|
||||
/** Invalid data input length. */
|
||||
#define MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH -0x005E
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The ARIA context-type definition.
|
||||
*/
|
||||
typedef struct mbedtls_aria_context {
|
||||
unsigned char MBEDTLS_PRIVATE(nr); /*!< The number of rounds (12, 14 or 16) */
|
||||
/*! The ARIA round keys. */
|
||||
uint32_t MBEDTLS_PRIVATE(rk)[MBEDTLS_ARIA_MAX_ROUNDS + 1][MBEDTLS_ARIA_BLOCKSIZE / 4];
|
||||
}
|
||||
mbedtls_aria_context;
|
||||
|
||||
/**
|
||||
* \brief This function initializes the specified ARIA context.
|
||||
*
|
||||
* It must be the first API called before using
|
||||
* the context.
|
||||
*
|
||||
* \param ctx The ARIA context to initialize. This must not be \c NULL.
|
||||
*/
|
||||
void mbedtls_aria_init(mbedtls_aria_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function releases and clears the specified ARIA context.
|
||||
*
|
||||
* \param ctx The ARIA context to clear. This may be \c NULL, in which
|
||||
* case this function returns immediately. If it is not \c NULL,
|
||||
* it must point to an initialized ARIA context.
|
||||
*/
|
||||
void mbedtls_aria_free(mbedtls_aria_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function sets the encryption key.
|
||||
*
|
||||
* \param ctx The ARIA context to which the key should be bound.
|
||||
* This must be initialized.
|
||||
* \param key The encryption key. This must be a readable buffer
|
||||
* of size \p keybits Bits.
|
||||
* \param keybits The size of \p key in Bits. Valid options are:
|
||||
* <ul><li>128 bits</li>
|
||||
* <li>192 bits</li>
|
||||
* <li>256 bits</li></ul>
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_aria_setkey_enc(mbedtls_aria_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
/**
|
||||
* \brief This function sets the decryption key.
|
||||
*
|
||||
* \param ctx The ARIA context to which the key should be bound.
|
||||
* This must be initialized.
|
||||
* \param key The decryption key. This must be a readable buffer
|
||||
* of size \p keybits Bits.
|
||||
* \param keybits The size of data passed. Valid options are:
|
||||
* <ul><li>128 bits</li>
|
||||
* <li>192 bits</li>
|
||||
* <li>256 bits</li></ul>
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_aria_setkey_dec(mbedtls_aria_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
|
||||
|
||||
/**
|
||||
* \brief This function performs an ARIA single-block encryption or
|
||||
* decryption operation.
|
||||
*
|
||||
* It performs encryption or decryption (depending on whether
|
||||
* the key was set for encryption on decryption) on the input
|
||||
* data buffer defined in the \p input parameter.
|
||||
*
|
||||
* mbedtls_aria_init(), and either mbedtls_aria_setkey_enc() or
|
||||
* mbedtls_aria_setkey_dec() must be called before the first
|
||||
* call to this API with the same context.
|
||||
*
|
||||
* \param ctx The ARIA context to use for encryption or decryption.
|
||||
* This must be initialized and bound to a key.
|
||||
* \param input The 16-Byte buffer holding the input data.
|
||||
* \param output The 16-Byte buffer holding the output data.
|
||||
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_aria_crypt_ecb(mbedtls_aria_context *ctx,
|
||||
const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE],
|
||||
unsigned char output[MBEDTLS_ARIA_BLOCKSIZE]);
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
/**
|
||||
* \brief This function performs an ARIA-CBC encryption or decryption operation
|
||||
* on full blocks.
|
||||
*
|
||||
* It performs the operation defined in the \p mode
|
||||
* parameter (encrypt/decrypt), on the input data buffer defined in
|
||||
* the \p input parameter.
|
||||
*
|
||||
* It can be called as many times as needed, until all the input
|
||||
* data is processed. mbedtls_aria_init(), and either
|
||||
* mbedtls_aria_setkey_enc() or mbedtls_aria_setkey_dec() must be called
|
||||
* before the first call to this API with the same context.
|
||||
*
|
||||
* \note This function operates on aligned blocks, that is, the input size
|
||||
* must be a multiple of the ARIA block size of 16 Bytes.
|
||||
*
|
||||
* \note Upon exit, the content of the IV is updated so that you can
|
||||
* call the same function again on the next
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If you need to retain the contents of the IV, you should
|
||||
* either save it manually or use the cipher module instead.
|
||||
*
|
||||
*
|
||||
* \param ctx The ARIA context to use for encryption or decryption.
|
||||
* This must be initialized and bound to a key.
|
||||
* \param mode The mode of operation. This must be either
|
||||
* #MBEDTLS_ARIA_ENCRYPT for encryption, or
|
||||
* #MBEDTLS_ARIA_DECRYPT for decryption.
|
||||
* \param length The length of the input data in Bytes. This must be a
|
||||
* multiple of the block size (16 Bytes).
|
||||
* \param iv Initialization vector (updated after use).
|
||||
* This must be a readable buffer of size 16 Bytes.
|
||||
* \param input The buffer holding the input data. This must
|
||||
* be a readable buffer of length \p length Bytes.
|
||||
* \param output The buffer holding the output data. This must
|
||||
* be a writable buffer of length \p length Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_aria_crypt_cbc(mbedtls_aria_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||
/**
|
||||
* \brief This function performs an ARIA-CFB128 encryption or decryption
|
||||
* operation.
|
||||
*
|
||||
* It performs the operation defined in the \p mode
|
||||
* parameter (encrypt or decrypt), on the input data buffer
|
||||
* defined in the \p input parameter.
|
||||
*
|
||||
* For CFB, you must set up the context with mbedtls_aria_setkey_enc(),
|
||||
* regardless of whether you are performing an encryption or decryption
|
||||
* operation, that is, regardless of the \p mode parameter. This is
|
||||
* because CFB mode uses the same key schedule for encryption and
|
||||
* decryption.
|
||||
*
|
||||
* \note Upon exit, the content of the IV is updated so that you can
|
||||
* call the same function again on the next
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If you need to retain the contents of the
|
||||
* IV, you must either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
*
|
||||
* \param ctx The ARIA context to use for encryption or decryption.
|
||||
* This must be initialized and bound to a key.
|
||||
* \param mode The mode of operation. This must be either
|
||||
* #MBEDTLS_ARIA_ENCRYPT for encryption, or
|
||||
* #MBEDTLS_ARIA_DECRYPT for decryption.
|
||||
* \param length The length of the input data \p input in Bytes.
|
||||
* \param iv_off The offset in IV (updated after use).
|
||||
* This must not be larger than 15.
|
||||
* \param iv The initialization vector (updated after use).
|
||||
* This must be a readable buffer of size 16 Bytes.
|
||||
* \param input The buffer holding the input data. This must
|
||||
* be a readable buffer of length \p length Bytes.
|
||||
* \param output The buffer holding the output data. This must
|
||||
* be a writable buffer of length \p length Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_aria_crypt_cfb128(mbedtls_aria_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
||||
/**
|
||||
* \brief This function performs an ARIA-CTR encryption or decryption
|
||||
* operation.
|
||||
*
|
||||
* Due to the nature of CTR, you must use the same key schedule
|
||||
* for both encryption and decryption operations. Therefore, you
|
||||
* must use the context initialized with mbedtls_aria_setkey_enc()
|
||||
* for both #MBEDTLS_ARIA_ENCRYPT and #MBEDTLS_ARIA_DECRYPT.
|
||||
*
|
||||
* \warning You must never reuse a nonce value with the same key. Doing so
|
||||
* would void the encryption for the two messages encrypted with
|
||||
* the same nonce and key.
|
||||
*
|
||||
* There are two common strategies for managing nonces with CTR:
|
||||
*
|
||||
* 1. You can handle everything as a single message processed over
|
||||
* successive calls to this function. In that case, you want to
|
||||
* set \p nonce_counter and \p nc_off to 0 for the first call, and
|
||||
* then preserve the values of \p nonce_counter, \p nc_off and \p
|
||||
* stream_block across calls to this function as they will be
|
||||
* updated by this function.
|
||||
*
|
||||
* With this strategy, you must not encrypt more than 2**128
|
||||
* blocks of data with the same key.
|
||||
*
|
||||
* 2. You can encrypt separate messages by dividing the \p
|
||||
* nonce_counter buffer in two areas: the first one used for a
|
||||
* per-message nonce, handled by yourself, and the second one
|
||||
* updated by this function internally.
|
||||
*
|
||||
* For example, you might reserve the first 12 bytes for the
|
||||
* per-message nonce, and the last 4 bytes for internal use. In that
|
||||
* case, before calling this function on a new message you need to
|
||||
* set the first 12 bytes of \p nonce_counter to your chosen nonce
|
||||
* value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
|
||||
* stream_block to be ignored). That way, you can encrypt at most
|
||||
* 2**96 messages of up to 2**32 blocks each with the same key.
|
||||
*
|
||||
* The per-message nonce (or information sufficient to reconstruct
|
||||
* it) needs to be communicated with the ciphertext and must be unique.
|
||||
* The recommended way to ensure uniqueness is to use a message
|
||||
* counter. An alternative is to generate random nonces, but this
|
||||
* limits the number of messages that can be securely encrypted:
|
||||
* for example, with 96-bit random nonces, you should not encrypt
|
||||
* more than 2**32 messages with the same key.
|
||||
*
|
||||
* Note that for both strategies, sizes are measured in blocks and
|
||||
* that an ARIA block is 16 bytes.
|
||||
*
|
||||
* \warning Upon return, \p stream_block contains sensitive data. Its
|
||||
* content must not be written to insecure storage and should be
|
||||
* securely discarded as soon as it's no longer needed.
|
||||
*
|
||||
* \param ctx The ARIA context to use for encryption or decryption.
|
||||
* This must be initialized and bound to a key.
|
||||
* \param length The length of the input data \p input in Bytes.
|
||||
* \param nc_off The offset in Bytes in the current \p stream_block,
|
||||
* for resuming within the current cipher stream. The
|
||||
* offset pointer should be \c 0 at the start of a
|
||||
* stream. This must not be larger than \c 15 Bytes.
|
||||
* \param nonce_counter The 128-bit nonce and counter. This must point to
|
||||
* a read/write buffer of length \c 16 bytes.
|
||||
* \param stream_block The saved stream block for resuming. This must
|
||||
* point to a read/write buffer of length \c 16 bytes.
|
||||
* This is overwritten by the function.
|
||||
* \param input The buffer holding the input data. This must
|
||||
* be a readable buffer of length \p length Bytes.
|
||||
* \param output The buffer holding the output data. This must
|
||||
* be a writable buffer of length \p length Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_aria_crypt_ctr(mbedtls_aria_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE],
|
||||
unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
/**
|
||||
* \brief Checkup routine.
|
||||
*
|
||||
* \return \c 0 on success, or \c 1 on failure.
|
||||
*/
|
||||
int mbedtls_aria_self_test(int verbose);
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* aria.h */
|
||||
@@ -1,642 +0,0 @@
|
||||
/**
|
||||
* \file asn1.h
|
||||
*
|
||||
* \brief Generic ASN.1 parsing
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_ASN1_H
|
||||
#define MBEDTLS_ASN1_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
#include "mbedtls/bignum.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \addtogroup asn1_module
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \name ASN1 Error codes
|
||||
* These error codes are combined with other error codes for
|
||||
* higher error granularity.
|
||||
* e.g. X.509 and PKCS #7 error codes
|
||||
* ASN1 is a standard to specify data structures.
|
||||
* \{
|
||||
*/
|
||||
/** Out of data when parsing an ASN1 data structure. */
|
||||
#define MBEDTLS_ERR_ASN1_OUT_OF_DATA -0x0060
|
||||
/** ASN1 tag was of an unexpected value. */
|
||||
#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG -0x0062
|
||||
/** Error when trying to determine the length or invalid length. */
|
||||
#define MBEDTLS_ERR_ASN1_INVALID_LENGTH -0x0064
|
||||
/** Actual length differs from expected length. */
|
||||
#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -0x0066
|
||||
/** Data is invalid. */
|
||||
#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068
|
||||
/** Memory allocation failed */
|
||||
#define MBEDTLS_ERR_ASN1_ALLOC_FAILED -0x006A
|
||||
/** Buffer too small when writing ASN.1 data structure. */
|
||||
#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -0x006C
|
||||
|
||||
/** \} name ASN1 Error codes */
|
||||
|
||||
/**
|
||||
* \name DER constants
|
||||
* These constants comply with the DER encoded ASN.1 type tags.
|
||||
* DER encoding uses hexadecimal representation.
|
||||
* An example DER sequence is:\n
|
||||
* - 0x02 -- tag indicating INTEGER
|
||||
* - 0x01 -- length in octets
|
||||
* - 0x05 -- value
|
||||
* Such sequences are typically read into \c ::mbedtls_x509_buf.
|
||||
* \{
|
||||
*/
|
||||
#define MBEDTLS_ASN1_BOOLEAN 0x01
|
||||
#define MBEDTLS_ASN1_INTEGER 0x02
|
||||
#define MBEDTLS_ASN1_BIT_STRING 0x03
|
||||
#define MBEDTLS_ASN1_OCTET_STRING 0x04
|
||||
#define MBEDTLS_ASN1_NULL 0x05
|
||||
#define MBEDTLS_ASN1_OID 0x06
|
||||
#define MBEDTLS_ASN1_ENUMERATED 0x0A
|
||||
#define MBEDTLS_ASN1_UTF8_STRING 0x0C
|
||||
#define MBEDTLS_ASN1_SEQUENCE 0x10
|
||||
#define MBEDTLS_ASN1_SET 0x11
|
||||
#define MBEDTLS_ASN1_PRINTABLE_STRING 0x13
|
||||
#define MBEDTLS_ASN1_T61_STRING 0x14
|
||||
#define MBEDTLS_ASN1_IA5_STRING 0x16
|
||||
#define MBEDTLS_ASN1_UTC_TIME 0x17
|
||||
#define MBEDTLS_ASN1_GENERALIZED_TIME 0x18
|
||||
#define MBEDTLS_ASN1_UNIVERSAL_STRING 0x1C
|
||||
#define MBEDTLS_ASN1_BMP_STRING 0x1E
|
||||
#define MBEDTLS_ASN1_PRIMITIVE 0x00
|
||||
#define MBEDTLS_ASN1_CONSTRUCTED 0x20
|
||||
#define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80
|
||||
|
||||
/* Slightly smaller way to check if tag is a string tag
|
||||
* compared to canonical implementation. */
|
||||
#define MBEDTLS_ASN1_IS_STRING_TAG(tag) \
|
||||
((unsigned int) (tag) < 32u && ( \
|
||||
((1u << (tag)) & ((1u << MBEDTLS_ASN1_BMP_STRING) | \
|
||||
(1u << MBEDTLS_ASN1_UTF8_STRING) | \
|
||||
(1u << MBEDTLS_ASN1_T61_STRING) | \
|
||||
(1u << MBEDTLS_ASN1_IA5_STRING) | \
|
||||
(1u << MBEDTLS_ASN1_UNIVERSAL_STRING) | \
|
||||
(1u << MBEDTLS_ASN1_PRINTABLE_STRING))) != 0))
|
||||
|
||||
/*
|
||||
* Bit masks for each of the components of an ASN.1 tag as specified in
|
||||
* ITU X.690 (08/2015), section 8.1 "General rules for encoding",
|
||||
* paragraph 8.1.2.2:
|
||||
*
|
||||
* Bit 8 7 6 5 1
|
||||
* +-------+-----+------------+
|
||||
* | Class | P/C | Tag number |
|
||||
* +-------+-----+------------+
|
||||
*/
|
||||
#define MBEDTLS_ASN1_TAG_CLASS_MASK 0xC0
|
||||
#define MBEDTLS_ASN1_TAG_PC_MASK 0x20
|
||||
#define MBEDTLS_ASN1_TAG_VALUE_MASK 0x1F
|
||||
|
||||
/** \} name DER constants */
|
||||
|
||||
/** Returns the size of the binary string, without the trailing \\0 */
|
||||
#define MBEDTLS_OID_SIZE(x) (sizeof(x) - 1)
|
||||
|
||||
/**
|
||||
* Compares an mbedtls_asn1_buf structure to a reference OID.
|
||||
*
|
||||
* Only works for 'defined' oid_str values (MBEDTLS_OID_HMAC_SHA1), you cannot use a
|
||||
* 'unsigned char *oid' here!
|
||||
*/
|
||||
#define MBEDTLS_OID_CMP(oid_str, oid_buf) \
|
||||
((MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len) || \
|
||||
memcmp((oid_str), (oid_buf)->p, (oid_buf)->len) != 0)
|
||||
|
||||
#define MBEDTLS_OID_CMP_RAW(oid_str, oid_buf, oid_buf_len) \
|
||||
((MBEDTLS_OID_SIZE(oid_str) != (oid_buf_len)) || \
|
||||
memcmp((oid_str), (oid_buf), (oid_buf_len)) != 0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \name Functions to parse ASN.1 data structures
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Type-length-value structure that allows for ASN1 using DER.
|
||||
*/
|
||||
typedef struct mbedtls_asn1_buf {
|
||||
int tag; /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */
|
||||
size_t len; /**< ASN1 length, in octets. */
|
||||
unsigned char *p; /**< ASN1 data, e.g. in ASCII. */
|
||||
}
|
||||
mbedtls_asn1_buf;
|
||||
|
||||
/**
|
||||
* Container for ASN1 bit strings.
|
||||
*/
|
||||
typedef struct mbedtls_asn1_bitstring {
|
||||
size_t len; /**< ASN1 length, in octets. */
|
||||
unsigned char unused_bits; /**< Number of unused bits at the end of the string */
|
||||
unsigned char *p; /**< Raw ASN1 data for the bit string */
|
||||
}
|
||||
mbedtls_asn1_bitstring;
|
||||
|
||||
/**
|
||||
* Container for a sequence of ASN.1 items
|
||||
*/
|
||||
typedef struct mbedtls_asn1_sequence {
|
||||
mbedtls_asn1_buf buf; /**< Buffer containing the given ASN.1 item. */
|
||||
|
||||
/** The next entry in the sequence.
|
||||
*
|
||||
* The details of memory management for sequences are not documented and
|
||||
* may change in future versions. Set this field to \p NULL when
|
||||
* initializing a structure, and do not modify it except via Mbed TLS
|
||||
* library functions.
|
||||
*/
|
||||
struct mbedtls_asn1_sequence *next;
|
||||
}
|
||||
mbedtls_asn1_sequence;
|
||||
|
||||
/**
|
||||
* Container for a sequence or list of 'named' ASN.1 data items
|
||||
*/
|
||||
typedef struct mbedtls_asn1_named_data {
|
||||
mbedtls_asn1_buf oid; /**< The object identifier. */
|
||||
mbedtls_asn1_buf val; /**< The named value. */
|
||||
|
||||
/** The next entry in the sequence.
|
||||
*
|
||||
* The details of memory management for named data sequences are not
|
||||
* documented and may change in future versions. Set this field to \p NULL
|
||||
* when initializing a structure, and do not modify it except via Mbed TLS
|
||||
* library functions.
|
||||
*/
|
||||
struct mbedtls_asn1_named_data *next;
|
||||
|
||||
/** Merge next item into the current one?
|
||||
*
|
||||
* This field exists for the sake of Mbed TLS's X.509 certificate parsing
|
||||
* code and may change in future versions of the library.
|
||||
*/
|
||||
unsigned char MBEDTLS_PRIVATE(next_merged);
|
||||
}
|
||||
mbedtls_asn1_named_data;
|
||||
|
||||
#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \
|
||||
defined(PSA_HAVE_ALG_SOME_ECDSA)
|
||||
/**
|
||||
* \brief Get the length of an ASN.1 element.
|
||||
* Updates the pointer to immediately behind the length.
|
||||
*
|
||||
* \param p On entry, \c *p points to the first byte of the length,
|
||||
* i.e. immediately after the tag.
|
||||
* On successful completion, \c *p points to the first byte
|
||||
* after the length, i.e. the first byte of the content.
|
||||
* On error, the value of \c *p is undefined.
|
||||
* \param end End of data.
|
||||
* \param len On successful completion, \c *len contains the length
|
||||
* read from the ASN.1 input.
|
||||
*
|
||||
* \return 0 if successful.
|
||||
* \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
|
||||
* would end beyond \p end.
|
||||
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparsable.
|
||||
*/
|
||||
int mbedtls_asn1_get_len(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
size_t *len);
|
||||
|
||||
/**
|
||||
* \brief Get the tag and length of the element.
|
||||
* Check for the requested tag.
|
||||
* Updates the pointer to immediately behind the tag and length.
|
||||
*
|
||||
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||
* On successful completion, \c *p points to the first byte
|
||||
* after the length, i.e. the first byte of the content.
|
||||
* On error, the value of \c *p is undefined.
|
||||
* \param end End of data.
|
||||
* \param len On successful completion, \c *len contains the length
|
||||
* read from the ASN.1 input.
|
||||
* \param tag The expected tag.
|
||||
*
|
||||
* \return 0 if successful.
|
||||
* \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the data does not start
|
||||
* with the requested tag.
|
||||
* \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
|
||||
* would end beyond \p end.
|
||||
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparsable.
|
||||
*/
|
||||
int mbedtls_asn1_get_tag(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
size_t *len, int tag);
|
||||
#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C || PSA_HAVE_ALG_SOME_ECDSA */
|
||||
|
||||
#if defined(MBEDTLS_ASN1_PARSE_C)
|
||||
/**
|
||||
* \brief Retrieve a boolean ASN.1 tag and its value.
|
||||
* Updates the pointer to immediately behind the full tag.
|
||||
*
|
||||
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||
* On successful completion, \c *p points to the first byte
|
||||
* beyond the ASN.1 element.
|
||||
* On error, the value of \c *p is undefined.
|
||||
* \param end End of data.
|
||||
* \param val On success, the parsed value (\c 0 or \c 1).
|
||||
*
|
||||
* \return 0 if successful.
|
||||
* \return An ASN.1 error code if the input does not start with
|
||||
* a valid ASN.1 BOOLEAN.
|
||||
*/
|
||||
int mbedtls_asn1_get_bool(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int *val);
|
||||
|
||||
/**
|
||||
* \brief Retrieve an integer ASN.1 tag and its value.
|
||||
* Updates the pointer to immediately behind the full tag.
|
||||
*
|
||||
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||
* On successful completion, \c *p points to the first byte
|
||||
* beyond the ASN.1 element.
|
||||
* On error, the value of \c *p is undefined.
|
||||
* \param end End of data.
|
||||
* \param val On success, the parsed value.
|
||||
*
|
||||
* \return 0 if successful.
|
||||
* \return An ASN.1 error code if the input does not start with
|
||||
* a valid ASN.1 INTEGER.
|
||||
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
|
||||
* not fit in an \c int.
|
||||
*/
|
||||
int mbedtls_asn1_get_int(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int *val);
|
||||
|
||||
/**
|
||||
* \brief Retrieve an enumerated ASN.1 tag and its value.
|
||||
* Updates the pointer to immediately behind the full tag.
|
||||
*
|
||||
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||
* On successful completion, \c *p points to the first byte
|
||||
* beyond the ASN.1 element.
|
||||
* On error, the value of \c *p is undefined.
|
||||
* \param end End of data.
|
||||
* \param val On success, the parsed value.
|
||||
*
|
||||
* \return 0 if successful.
|
||||
* \return An ASN.1 error code if the input does not start with
|
||||
* a valid ASN.1 ENUMERATED.
|
||||
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
|
||||
* not fit in an \c int.
|
||||
*/
|
||||
int mbedtls_asn1_get_enum(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
int *val);
|
||||
|
||||
/**
|
||||
* \brief Retrieve a bitstring ASN.1 tag and its value.
|
||||
* Updates the pointer to immediately behind the full tag.
|
||||
*
|
||||
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||
* On successful completion, \c *p is equal to \p end.
|
||||
* On error, the value of \c *p is undefined.
|
||||
* \param end End of data.
|
||||
* \param bs On success, ::mbedtls_asn1_bitstring information about
|
||||
* the parsed value.
|
||||
*
|
||||
* \return 0 if successful.
|
||||
* \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains
|
||||
* extra data after a valid BIT STRING.
|
||||
* \return An ASN.1 error code if the input does not start with
|
||||
* a valid ASN.1 BIT STRING.
|
||||
*/
|
||||
int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end,
|
||||
mbedtls_asn1_bitstring *bs);
|
||||
|
||||
/**
|
||||
* \brief Retrieve a bitstring ASN.1 tag without unused bits and its
|
||||
* value.
|
||||
* Updates the pointer to the beginning of the bit/octet string.
|
||||
*
|
||||
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||
* On successful completion, \c *p points to the first byte
|
||||
* of the content of the BIT STRING.
|
||||
* On error, the value of \c *p is undefined.
|
||||
* \param end End of data.
|
||||
* \param len On success, \c *len is the length of the content in bytes.
|
||||
*
|
||||
* \return 0 if successful.
|
||||
* \return #MBEDTLS_ERR_ASN1_INVALID_DATA if the input starts with
|
||||
* a valid BIT STRING with a nonzero number of unused bits.
|
||||
* \return An ASN.1 error code if the input does not start with
|
||||
* a valid ASN.1 BIT STRING.
|
||||
*/
|
||||
int mbedtls_asn1_get_bitstring_null(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
size_t *len);
|
||||
|
||||
/**
|
||||
* \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>".
|
||||
* Updates the pointer to immediately behind the full sequence tag.
|
||||
*
|
||||
* This function allocates memory for the sequence elements. You can free
|
||||
* the allocated memory with mbedtls_asn1_sequence_free().
|
||||
*
|
||||
* \note On error, this function may return a partial list in \p cur.
|
||||
* You must set `cur->next = NULL` before calling this function!
|
||||
* Otherwise it is impossible to distinguish a previously non-null
|
||||
* pointer from a pointer to an object allocated by this function.
|
||||
*
|
||||
* \note If the sequence is empty, this function does not modify
|
||||
* \c *cur. If the sequence is valid and non-empty, this
|
||||
* function sets `cur->buf.tag` to \p tag. This allows
|
||||
* callers to distinguish between an empty sequence and
|
||||
* a one-element sequence.
|
||||
*
|
||||
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||
* On successful completion, \c *p is equal to \p end.
|
||||
* On error, the value of \c *p is undefined.
|
||||
* \param end End of data.
|
||||
* \param cur A ::mbedtls_asn1_sequence which this function fills.
|
||||
* When this function returns, \c *cur is the head of a linked
|
||||
* list. Each node in this list is allocated with
|
||||
* mbedtls_calloc() apart from \p cur itself, and should
|
||||
* therefore be freed with mbedtls_free().
|
||||
* The list describes the content of the sequence.
|
||||
* The head of the list (i.e. \c *cur itself) describes the
|
||||
* first element, `*cur->next` describes the second element, etc.
|
||||
* For each element, `buf.tag == tag`, `buf.len` is the length
|
||||
* of the content of the content of the element, and `buf.p`
|
||||
* points to the first byte of the content (i.e. immediately
|
||||
* past the length of the element).
|
||||
* Note that list elements may be allocated even on error.
|
||||
* \param tag Each element of the sequence must have this tag.
|
||||
*
|
||||
* \return 0 if successful.
|
||||
* \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains
|
||||
* extra data after a valid SEQUENCE OF \p tag.
|
||||
* \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts with
|
||||
* an ASN.1 SEQUENCE in which an element has a tag that
|
||||
* is different from \p tag.
|
||||
* \return #MBEDTLS_ERR_ASN1_ALLOC_FAILED if a memory allocation failed.
|
||||
* \return An ASN.1 error code if the input does not start with
|
||||
* a valid ASN.1 SEQUENCE.
|
||||
*/
|
||||
int mbedtls_asn1_get_sequence_of(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_asn1_sequence *cur,
|
||||
int tag);
|
||||
/**
|
||||
* \brief Free a heap-allocated linked list presentation of
|
||||
* an ASN.1 sequence, including the first element.
|
||||
*
|
||||
* There are two common ways to manage the memory used for the representation
|
||||
* of a parsed ASN.1 sequence:
|
||||
* - Allocate a head node `mbedtls_asn1_sequence *head` with mbedtls_calloc().
|
||||
* Pass this node as the `cur` argument to mbedtls_asn1_get_sequence_of().
|
||||
* When you have finished processing the sequence,
|
||||
* call mbedtls_asn1_sequence_free() on `head`.
|
||||
* - Allocate a head node `mbedtls_asn1_sequence *head` in any manner,
|
||||
* for example on the stack. Make sure that `head->next == NULL`.
|
||||
* Pass `head` as the `cur` argument to mbedtls_asn1_get_sequence_of().
|
||||
* When you have finished processing the sequence,
|
||||
* call mbedtls_asn1_sequence_free() on `head->cur`,
|
||||
* then free `head` itself in the appropriate manner.
|
||||
*
|
||||
* \param seq The address of the first sequence component. This may
|
||||
* be \c NULL, in which case this functions returns
|
||||
* immediately.
|
||||
*/
|
||||
void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq);
|
||||
|
||||
/**
|
||||
* \brief Traverse an ASN.1 SEQUENCE container and
|
||||
* call a callback for each entry.
|
||||
*
|
||||
* This function checks that the input is a SEQUENCE of elements that
|
||||
* each have a "must" tag, and calls a callback function on the elements
|
||||
* that have a "may" tag.
|
||||
*
|
||||
* For example, to validate that the input is a SEQUENCE of `tag1` and call
|
||||
* `cb` on each element, use
|
||||
* ```
|
||||
* mbedtls_asn1_traverse_sequence_of(&p, end, 0xff, tag1, 0, 0, cb, ctx);
|
||||
* ```
|
||||
*
|
||||
* To validate that the input is a SEQUENCE of ANY and call `cb` on
|
||||
* each element, use
|
||||
* ```
|
||||
* mbedtls_asn1_traverse_sequence_of(&p, end, 0, 0, 0, 0, cb, ctx);
|
||||
* ```
|
||||
*
|
||||
* To validate that the input is a SEQUENCE of CHOICE {NULL, OCTET STRING}
|
||||
* and call `cb` on each element that is an OCTET STRING, use
|
||||
* ```
|
||||
* mbedtls_asn1_traverse_sequence_of(&p, end, 0xfe, 0x04, 0xff, 0x04, cb, ctx);
|
||||
* ```
|
||||
*
|
||||
* The callback is called on the elements with a "may" tag from left to
|
||||
* right. If the input is not a valid SEQUENCE of elements with a "must" tag,
|
||||
* the callback is called on the elements up to the leftmost point where
|
||||
* the input is invalid.
|
||||
*
|
||||
* \warning This function is still experimental and may change
|
||||
* at any time.
|
||||
*
|
||||
* \param p The address of the pointer to the beginning of
|
||||
* the ASN.1 SEQUENCE header. This is updated to
|
||||
* point to the end of the ASN.1 SEQUENCE container
|
||||
* on a successful invocation.
|
||||
* \param end The end of the ASN.1 SEQUENCE container.
|
||||
* \param tag_must_mask A mask to be applied to the ASN.1 tags found within
|
||||
* the SEQUENCE before comparing to \p tag_must_val.
|
||||
* \param tag_must_val The required value of each ASN.1 tag found in the
|
||||
* SEQUENCE, after masking with \p tag_must_mask.
|
||||
* Mismatching tags lead to an error.
|
||||
* For example, a value of \c 0 for both \p tag_must_mask
|
||||
* and \p tag_must_val means that every tag is allowed,
|
||||
* while a value of \c 0xFF for \p tag_must_mask means
|
||||
* that \p tag_must_val is the only allowed tag.
|
||||
* \param tag_may_mask A mask to be applied to the ASN.1 tags found within
|
||||
* the SEQUENCE before comparing to \p tag_may_val.
|
||||
* \param tag_may_val The desired value of each ASN.1 tag found in the
|
||||
* SEQUENCE, after masking with \p tag_may_mask.
|
||||
* Mismatching tags will be silently ignored.
|
||||
* For example, a value of \c 0 for \p tag_may_mask and
|
||||
* \p tag_may_val means that any tag will be considered,
|
||||
* while a value of \c 0xFF for \p tag_may_mask means
|
||||
* that all tags with value different from \p tag_may_val
|
||||
* will be ignored.
|
||||
* \param cb The callback to trigger for each component
|
||||
* in the ASN.1 SEQUENCE that matches \p tag_may_val.
|
||||
* The callback function is called with the following
|
||||
* parameters:
|
||||
* - \p ctx.
|
||||
* - The tag of the current element.
|
||||
* - A pointer to the start of the current element's
|
||||
* content inside the input.
|
||||
* - The length of the content of the current element.
|
||||
* If the callback returns a non-zero value,
|
||||
* the function stops immediately,
|
||||
* forwarding the callback's return value.
|
||||
* \param ctx The context to be passed to the callback \p cb.
|
||||
*
|
||||
* \return \c 0 if successful the entire ASN.1 SEQUENCE
|
||||
* was traversed without parsing or callback errors.
|
||||
* \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input
|
||||
* contains extra data after a valid SEQUENCE
|
||||
* of elements with an accepted tag.
|
||||
* \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts
|
||||
* with an ASN.1 SEQUENCE in which an element has a tag
|
||||
* that is not accepted.
|
||||
* \return An ASN.1 error code if the input does not start with
|
||||
* a valid ASN.1 SEQUENCE.
|
||||
* \return A non-zero error code forwarded from the callback
|
||||
* \p cb in case the latter returns a non-zero value.
|
||||
*/
|
||||
int mbedtls_asn1_traverse_sequence_of(
|
||||
unsigned char **p,
|
||||
const unsigned char *end,
|
||||
unsigned char tag_must_mask, unsigned char tag_must_val,
|
||||
unsigned char tag_may_mask, unsigned char tag_may_val,
|
||||
int (*cb)(void *ctx, int tag,
|
||||
unsigned char *start, size_t len),
|
||||
void *ctx);
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
/**
|
||||
* \brief Retrieve an integer ASN.1 tag and its value.
|
||||
* Updates the pointer to immediately behind the full tag.
|
||||
*
|
||||
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||
* On successful completion, \c *p points to the first byte
|
||||
* beyond the ASN.1 element.
|
||||
* On error, the value of \c *p is undefined.
|
||||
* \param end End of data.
|
||||
* \param X On success, the parsed value.
|
||||
*
|
||||
* \return 0 if successful.
|
||||
* \return An ASN.1 error code if the input does not start with
|
||||
* a valid ASN.1 INTEGER.
|
||||
* \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
|
||||
* not fit in an \c int.
|
||||
* \return An MPI error code if the parsed value is too large.
|
||||
*/
|
||||
int mbedtls_asn1_get_mpi(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_mpi *X);
|
||||
#endif /* MBEDTLS_BIGNUM_C */
|
||||
|
||||
/**
|
||||
* \brief Retrieve an AlgorithmIdentifier ASN.1 sequence.
|
||||
* Updates the pointer to immediately behind the full
|
||||
* AlgorithmIdentifier.
|
||||
*
|
||||
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||
* On successful completion, \c *p points to the first byte
|
||||
* beyond the AlgorithmIdentifier element.
|
||||
* On error, the value of \c *p is undefined.
|
||||
* \param end End of data.
|
||||
* \param alg The buffer to receive the OID.
|
||||
* \param params The buffer to receive the parameters.
|
||||
* This is zeroized if there are no parameters.
|
||||
*
|
||||
* \return 0 if successful or a specific ASN.1 or MPI error code.
|
||||
*/
|
||||
int mbedtls_asn1_get_alg(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params);
|
||||
|
||||
/**
|
||||
* \brief Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no
|
||||
* params.
|
||||
* Updates the pointer to immediately behind the full
|
||||
* AlgorithmIdentifier.
|
||||
*
|
||||
* \param p On entry, \c *p points to the start of the ASN.1 element.
|
||||
* On successful completion, \c *p points to the first byte
|
||||
* beyond the AlgorithmIdentifier element.
|
||||
* On error, the value of \c *p is undefined.
|
||||
* \param end End of data.
|
||||
* \param alg The buffer to receive the OID.
|
||||
*
|
||||
* \return 0 if successful or a specific ASN.1 or MPI error code.
|
||||
*/
|
||||
int mbedtls_asn1_get_alg_null(unsigned char **p,
|
||||
const unsigned char *end,
|
||||
mbedtls_asn1_buf *alg);
|
||||
|
||||
/**
|
||||
* \brief Find a specific named_data entry in a sequence or list based on
|
||||
* the OID.
|
||||
*
|
||||
* \param list The list to seek through
|
||||
* \param oid The OID to look for
|
||||
* \param len Size of the OID
|
||||
*
|
||||
* \return NULL if not found, or a pointer to the existing entry.
|
||||
*/
|
||||
const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data *list,
|
||||
const char *oid, size_t len);
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
/**
|
||||
* \brief Free a mbedtls_asn1_named_data entry
|
||||
*
|
||||
* \deprecated This function is deprecated and will be removed in a
|
||||
* future version of the library.
|
||||
* Please use mbedtls_asn1_free_named_data_list()
|
||||
* or mbedtls_asn1_free_named_data_list_shallow().
|
||||
*
|
||||
* \param entry The named data entry to free.
|
||||
* This function calls mbedtls_free() on
|
||||
* `entry->oid.p` and `entry->val.p`.
|
||||
*/
|
||||
void MBEDTLS_DEPRECATED mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *entry);
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
/**
|
||||
* \brief Free all entries in a mbedtls_asn1_named_data list.
|
||||
*
|
||||
* \param head Pointer to the head of the list of named data entries to free.
|
||||
* This function calls mbedtls_free() on
|
||||
* `entry->oid.p` and `entry->val.p` and then on `entry`
|
||||
* for each list entry, and sets \c *head to \c NULL.
|
||||
*/
|
||||
void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head);
|
||||
|
||||
/**
|
||||
* \brief Free all shallow entries in a mbedtls_asn1_named_data list,
|
||||
* but do not free internal pointer targets.
|
||||
*
|
||||
* \param name Head of the list of named data entries to free.
|
||||
* This function calls mbedtls_free() on each list element.
|
||||
*/
|
||||
void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name);
|
||||
|
||||
/** \} name Functions to parse ASN.1 data structures */
|
||||
/** \} addtogroup asn1_module */
|
||||
|
||||
#endif /* MBEDTLS_ASN1_PARSE_C */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* asn1.h */
|
||||
@@ -1,390 +0,0 @@
|
||||
/**
|
||||
* \file asn1write.h
|
||||
*
|
||||
* \brief ASN.1 buffer writing functionality
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_ASN1_WRITE_H
|
||||
#define MBEDTLS_ASN1_WRITE_H
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include "mbedtls/asn1.h"
|
||||
|
||||
#define MBEDTLS_ASN1_CHK_ADD(g, f) \
|
||||
do \
|
||||
{ \
|
||||
if ((ret = (f)) < 0) \
|
||||
return ret; \
|
||||
else \
|
||||
(g) += ret; \
|
||||
} while (0)
|
||||
|
||||
#define MBEDTLS_ASN1_CHK_CLEANUP_ADD(g, f) \
|
||||
do \
|
||||
{ \
|
||||
if ((ret = (f)) < 0) \
|
||||
goto cleanup; \
|
||||
else \
|
||||
(g) += ret; \
|
||||
} while (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C) || \
|
||||
defined(PSA_HAVE_ALG_SOME_ECDSA)
|
||||
/**
|
||||
* \brief Write a length field in ASN.1 format.
|
||||
*
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
* \param len The length value to write.
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_len(unsigned char **p, const unsigned char *start,
|
||||
size_t len);
|
||||
/**
|
||||
* \brief Write an ASN.1 tag in ASN.1 format.
|
||||
*
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
* \param tag The tag to write.
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_tag(unsigned char **p, const unsigned char *start,
|
||||
unsigned char tag);
|
||||
#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C || PSA_HAVE_ALG_SOME_ECDSA*/
|
||||
|
||||
#if defined(MBEDTLS_ASN1_WRITE_C)
|
||||
/**
|
||||
* \brief Write raw buffer data.
|
||||
*
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
* \param buf The data buffer to write.
|
||||
* \param size The length of the data buffer.
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_raw_buffer(unsigned char **p, const unsigned char *start,
|
||||
const unsigned char *buf, size_t size);
|
||||
|
||||
#if defined(MBEDTLS_BIGNUM_C)
|
||||
/**
|
||||
* \brief Write an arbitrary-precision number (#MBEDTLS_ASN1_INTEGER)
|
||||
* in ASN.1 format.
|
||||
*
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
* \param X The MPI to write.
|
||||
* It must be non-negative.
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_mpi(unsigned char **p, const unsigned char *start,
|
||||
const mbedtls_mpi *X);
|
||||
#endif /* MBEDTLS_BIGNUM_C */
|
||||
|
||||
/**
|
||||
* \brief Write a NULL tag (#MBEDTLS_ASN1_NULL) with zero data
|
||||
* in ASN.1 format.
|
||||
*
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_null(unsigned char **p, const unsigned char *start);
|
||||
|
||||
/**
|
||||
* \brief Write an OID tag (#MBEDTLS_ASN1_OID) and data
|
||||
* in ASN.1 format.
|
||||
*
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
* \param oid The OID to write.
|
||||
* \param oid_len The length of the OID.
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_oid(unsigned char **p, const unsigned char *start,
|
||||
const char *oid, size_t oid_len);
|
||||
|
||||
/**
|
||||
* \brief Write an AlgorithmIdentifier sequence in ASN.1 format.
|
||||
*
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
* \param oid The OID of the algorithm to write.
|
||||
* \param oid_len The length of the algorithm's OID.
|
||||
* \param par_len The length of the parameters, which must be already written.
|
||||
* If 0, NULL parameters are added
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_algorithm_identifier(unsigned char **p,
|
||||
const unsigned char *start,
|
||||
const char *oid, size_t oid_len,
|
||||
size_t par_len);
|
||||
|
||||
/**
|
||||
* \brief Write an AlgorithmIdentifier sequence in ASN.1 format.
|
||||
*
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
* \param oid The OID of the algorithm to write.
|
||||
* \param oid_len The length of the algorithm's OID.
|
||||
* \param par_len The length of the parameters, which must be already written.
|
||||
* \param has_par If there are any parameters. If 0, par_len must be 0. If 1
|
||||
* and \p par_len is 0, NULL parameters are added.
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_algorithm_identifier_ext(unsigned char **p,
|
||||
const unsigned char *start,
|
||||
const char *oid, size_t oid_len,
|
||||
size_t par_len, int has_par);
|
||||
|
||||
/**
|
||||
* \brief Write a boolean tag (#MBEDTLS_ASN1_BOOLEAN) and value
|
||||
* in ASN.1 format.
|
||||
*
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
* \param boolean The boolean value to write, either \c 0 or \c 1.
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_bool(unsigned char **p, const unsigned char *start,
|
||||
int boolean);
|
||||
|
||||
/**
|
||||
* \brief Write an int tag (#MBEDTLS_ASN1_INTEGER) and value
|
||||
* in ASN.1 format.
|
||||
*
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
* \param val The integer value to write.
|
||||
* It must be non-negative.
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_int(unsigned char **p, const unsigned char *start, int val);
|
||||
|
||||
/**
|
||||
* \brief Write an enum tag (#MBEDTLS_ASN1_ENUMERATED) and value
|
||||
* in ASN.1 format.
|
||||
*
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
* \param val The integer value to write.
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_enum(unsigned char **p, const unsigned char *start, int val);
|
||||
|
||||
/**
|
||||
* \brief Write a string in ASN.1 format using a specific
|
||||
* string encoding tag.
|
||||
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
* \param tag The string encoding tag to write, e.g.
|
||||
* #MBEDTLS_ASN1_UTF8_STRING.
|
||||
* \param text The string to write.
|
||||
* \param text_len The length of \p text in bytes (which might
|
||||
* be strictly larger than the number of characters).
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_tagged_string(unsigned char **p, const unsigned char *start,
|
||||
int tag, const char *text,
|
||||
size_t text_len);
|
||||
|
||||
/**
|
||||
* \brief Write a string in ASN.1 format using the PrintableString
|
||||
* string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING).
|
||||
*
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
* \param text The string to write.
|
||||
* \param text_len The length of \p text in bytes (which might
|
||||
* be strictly larger than the number of characters).
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_printable_string(unsigned char **p,
|
||||
const unsigned char *start,
|
||||
const char *text, size_t text_len);
|
||||
|
||||
/**
|
||||
* \brief Write a UTF8 string in ASN.1 format using the UTF8String
|
||||
* string encoding tag (#MBEDTLS_ASN1_UTF8_STRING).
|
||||
*
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
* \param text The string to write.
|
||||
* \param text_len The length of \p text in bytes (which might
|
||||
* be strictly larger than the number of characters).
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_utf8_string(unsigned char **p, const unsigned char *start,
|
||||
const char *text, size_t text_len);
|
||||
|
||||
/**
|
||||
* \brief Write a string in ASN.1 format using the IA5String
|
||||
* string encoding tag (#MBEDTLS_ASN1_IA5_STRING).
|
||||
*
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
* \param text The string to write.
|
||||
* \param text_len The length of \p text in bytes (which might
|
||||
* be strictly larger than the number of characters).
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_ia5_string(unsigned char **p, const unsigned char *start,
|
||||
const char *text, size_t text_len);
|
||||
|
||||
/**
|
||||
* \brief Write a bitstring tag (#MBEDTLS_ASN1_BIT_STRING) and
|
||||
* value in ASN.1 format.
|
||||
*
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
* \param buf The bitstring to write.
|
||||
* \param bits The total number of bits in the bitstring.
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_bitstring(unsigned char **p, const unsigned char *start,
|
||||
const unsigned char *buf, size_t bits);
|
||||
|
||||
/**
|
||||
* \brief This function writes a named bitstring tag
|
||||
* (#MBEDTLS_ASN1_BIT_STRING) and value in ASN.1 format.
|
||||
*
|
||||
* As stated in RFC 5280 Appendix B, trailing zeroes are
|
||||
* omitted when encoding named bitstrings in DER.
|
||||
*
|
||||
* \note This function works backwards within the data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer which is used for bounds-checking.
|
||||
* \param buf The bitstring to write.
|
||||
* \param bits The total number of bits in the bitstring.
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_named_bitstring(unsigned char **p,
|
||||
const unsigned char *start,
|
||||
const unsigned char *buf,
|
||||
size_t bits);
|
||||
|
||||
/**
|
||||
* \brief Write an octet string tag (#MBEDTLS_ASN1_OCTET_STRING)
|
||||
* and value in ASN.1 format.
|
||||
*
|
||||
* \note This function works backwards in data buffer.
|
||||
*
|
||||
* \param p The reference to the current position pointer.
|
||||
* \param start The start of the buffer, for bounds-checking.
|
||||
* \param buf The buffer holding the data to write.
|
||||
* \param size The length of the data buffer \p buf.
|
||||
*
|
||||
* \return The number of bytes written to \p p on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_asn1_write_octet_string(unsigned char **p, const unsigned char *start,
|
||||
const unsigned char *buf, size_t size);
|
||||
|
||||
/**
|
||||
* \brief Create or find a specific named_data entry for writing in a
|
||||
* sequence or list based on the OID. If not already in there,
|
||||
* a new entry is added to the head of the list.
|
||||
* Warning: Destructive behaviour for the val data!
|
||||
*
|
||||
* \param list The pointer to the location of the head of the list to seek
|
||||
* through (will be updated in case of a new entry).
|
||||
* \param oid The OID to look for.
|
||||
* \param oid_len The size of the OID.
|
||||
* \param val The associated data to store. If this is \c NULL,
|
||||
* no data is copied to the new or existing buffer.
|
||||
* \param val_len The minimum length of the data buffer needed.
|
||||
* If this is 0, do not allocate a buffer for the associated
|
||||
* data.
|
||||
* If the OID was already present, enlarge, shrink or free
|
||||
* the existing buffer to fit \p val_len.
|
||||
*
|
||||
* \return A pointer to the new / existing entry on success.
|
||||
* \return \c NULL if there was a memory allocation error.
|
||||
*/
|
||||
mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(mbedtls_asn1_named_data **list,
|
||||
const char *oid, size_t oid_len,
|
||||
const unsigned char *val,
|
||||
size_t val_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_ASN1_WRITE_C */
|
||||
|
||||
#endif /* MBEDTLS_ASN1_WRITE_H */
|
||||
@@ -1,82 +0,0 @@
|
||||
/**
|
||||
* \file base64.h
|
||||
*
|
||||
* \brief RFC 1521 base64 encoding/decoding
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_BASE64_H
|
||||
#define MBEDTLS_BASE64_H
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/** Output buffer too small. */
|
||||
#define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -0x002A
|
||||
/** Invalid character in input. */
|
||||
#define MBEDTLS_ERR_BASE64_INVALID_CHARACTER -0x002C
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Encode a buffer into base64 format
|
||||
*
|
||||
* \param dst destination buffer
|
||||
* \param dlen size of the destination buffer
|
||||
* \param olen number of bytes written
|
||||
* \param src source buffer
|
||||
* \param slen amount of data to be encoded
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL.
|
||||
* *olen is always updated to reflect the amount
|
||||
* of data that has (or would have) been written.
|
||||
* If that length cannot be represented, then no data is
|
||||
* written to the buffer and *olen is set to the maximum
|
||||
* length representable as a size_t.
|
||||
*
|
||||
* \note Call this function with dlen = 0 to obtain the
|
||||
* required buffer size in *olen
|
||||
*/
|
||||
int mbedtls_base64_encode(unsigned char *dst, size_t dlen, size_t *olen,
|
||||
const unsigned char *src, size_t slen);
|
||||
|
||||
/**
|
||||
* \brief Decode a base64-formatted buffer
|
||||
*
|
||||
* \param dst destination buffer (can be NULL for checking size)
|
||||
* \param dlen size of the destination buffer
|
||||
* \param olen number of bytes written
|
||||
* \param src source buffer
|
||||
* \param slen amount of data to be decoded
|
||||
*
|
||||
* \return 0 if successful, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL, or
|
||||
* MBEDTLS_ERR_BASE64_INVALID_CHARACTER if the input data is
|
||||
* not correct. *olen is always updated to reflect the amount
|
||||
* of data that has (or would have) been written.
|
||||
*
|
||||
* \note Call this function with *dst = NULL or dlen = 0 to obtain
|
||||
* the required buffer size in *olen
|
||||
*/
|
||||
int mbedtls_base64_decode(unsigned char *dst, size_t dlen, size_t *olen,
|
||||
const unsigned char *src, size_t slen);
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int mbedtls_base64_self_test(int verbose);
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* base64.h */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,76 +0,0 @@
|
||||
/**
|
||||
* \file block_cipher.h
|
||||
*
|
||||
* \brief Internal abstraction layer.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_BLOCK_CIPHER_H
|
||||
#define MBEDTLS_BLOCK_CIPHER_H
|
||||
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
#include "mbedtls/aes.h"
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
#include "mbedtls/aria.h"
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
#include "mbedtls/camellia.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
#include "psa/crypto_types.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
MBEDTLS_BLOCK_CIPHER_ID_NONE = 0, /**< Unset. */
|
||||
MBEDTLS_BLOCK_CIPHER_ID_AES, /**< The AES cipher. */
|
||||
MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */
|
||||
MBEDTLS_BLOCK_CIPHER_ID_ARIA, /**< The Aria cipher. */
|
||||
} mbedtls_block_cipher_id_t;
|
||||
|
||||
/**
|
||||
* Used internally to indicate whether a context uses legacy or PSA.
|
||||
*
|
||||
* Internal use only.
|
||||
*/
|
||||
typedef enum {
|
||||
MBEDTLS_BLOCK_CIPHER_ENGINE_LEGACY = 0,
|
||||
MBEDTLS_BLOCK_CIPHER_ENGINE_PSA,
|
||||
} mbedtls_block_cipher_engine_t;
|
||||
|
||||
typedef struct {
|
||||
mbedtls_block_cipher_id_t MBEDTLS_PRIVATE(id);
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
|
||||
mbedtls_block_cipher_engine_t MBEDTLS_PRIVATE(engine);
|
||||
mbedtls_svc_key_id_t MBEDTLS_PRIVATE(psa_key_id);
|
||||
#endif
|
||||
union {
|
||||
unsigned dummy; /* Make the union non-empty even with no supported algorithms. */
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
mbedtls_aes_context MBEDTLS_PRIVATE(aes);
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
mbedtls_aria_context MBEDTLS_PRIVATE(aria);
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
mbedtls_camellia_context MBEDTLS_PRIVATE(camellia);
|
||||
#endif
|
||||
} MBEDTLS_PRIVATE(ctx);
|
||||
} mbedtls_block_cipher_context_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_BLOCK_CIPHER_H */
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Alias to tf-psa-crypto/build_info.h for the purpose
|
||||
* of framework C headers and modules in the context
|
||||
* of TF-PSA-Crypto.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_BUILD_INFO_H
|
||||
#define MBEDTLS_BUILD_INFO_H
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#endif /* MBEDTLS_BUILD_INFO_H */
|
||||
@@ -1,297 +0,0 @@
|
||||
/**
|
||||
* \file camellia.h
|
||||
*
|
||||
* \brief Camellia block cipher
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_CAMELLIA_H
|
||||
#define MBEDTLS_CAMELLIA_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#define MBEDTLS_CAMELLIA_ENCRYPT 1
|
||||
#define MBEDTLS_CAMELLIA_DECRYPT 0
|
||||
|
||||
/** Bad input data. */
|
||||
#define MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA -0x0024
|
||||
|
||||
/** Invalid data input length. */
|
||||
#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief CAMELLIA context structure
|
||||
*/
|
||||
typedef struct mbedtls_camellia_context {
|
||||
int MBEDTLS_PRIVATE(nr); /*!< number of rounds */
|
||||
uint32_t MBEDTLS_PRIVATE(rk)[68]; /*!< CAMELLIA round keys */
|
||||
}
|
||||
mbedtls_camellia_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize a CAMELLIA context.
|
||||
*
|
||||
* \param ctx The CAMELLIA context to be initialized.
|
||||
* This must not be \c NULL.
|
||||
*/
|
||||
void mbedtls_camellia_init(mbedtls_camellia_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Clear a CAMELLIA context.
|
||||
*
|
||||
* \param ctx The CAMELLIA context to be cleared. This may be \c NULL,
|
||||
* in which case this function returns immediately. If it is not
|
||||
* \c NULL, it must be initialized.
|
||||
*/
|
||||
void mbedtls_camellia_free(mbedtls_camellia_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Perform a CAMELLIA key schedule operation for encryption.
|
||||
*
|
||||
* \param ctx The CAMELLIA context to use. This must be initialized.
|
||||
* \param key The encryption key to use. This must be a readable buffer
|
||||
* of size \p keybits Bits.
|
||||
* \param keybits The length of \p key in Bits. This must be either \c 128,
|
||||
* \c 192 or \c 256.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_camellia_setkey_enc(mbedtls_camellia_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
|
||||
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
|
||||
/**
|
||||
* \brief Perform a CAMELLIA key schedule operation for decryption.
|
||||
*
|
||||
* \param ctx The CAMELLIA context to use. This must be initialized.
|
||||
* \param key The decryption key. This must be a readable buffer
|
||||
* of size \p keybits Bits.
|
||||
* \param keybits The length of \p key in Bits. This must be either \c 128,
|
||||
* \c 192 or \c 256.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
|
||||
|
||||
/**
|
||||
* \brief Perform a CAMELLIA-ECB block encryption/decryption operation.
|
||||
*
|
||||
* \param ctx The CAMELLIA context to use. This must be initialized
|
||||
* and bound to a key.
|
||||
* \param mode The mode of operation. This must be either
|
||||
* #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
|
||||
* \param input The input block. This must be a readable buffer
|
||||
* of size \c 16 Bytes.
|
||||
* \param output The output block. This must be a writable buffer
|
||||
* of size \c 16 Bytes.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_camellia_crypt_ecb(mbedtls_camellia_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16]);
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
/**
|
||||
* \brief Perform a CAMELLIA-CBC buffer encryption/decryption operation.
|
||||
*
|
||||
* \note Upon exit, the content of the IV is updated so that you can
|
||||
* call the function same function again on the following
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If on the other hand you need to retain the contents of the
|
||||
* IV, you should either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
* \param ctx The CAMELLIA context to use. This must be initialized
|
||||
* and bound to a key.
|
||||
* \param mode The mode of operation. This must be either
|
||||
* #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
|
||||
* \param length The length in Bytes of the input data \p input.
|
||||
* This must be a multiple of \c 16 Bytes.
|
||||
* \param iv The initialization vector. This must be a read/write buffer
|
||||
* of length \c 16 Bytes. It is updated to allow streaming
|
||||
* use as explained above.
|
||||
* \param input The buffer holding the input data. This must point to a
|
||||
* readable buffer of length \p length Bytes.
|
||||
* \param output The buffer holding the output data. This must point to a
|
||||
* writable buffer of length \p length Bytes.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_camellia_crypt_cbc(mbedtls_camellia_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CFB)
|
||||
/**
|
||||
* \brief Perform a CAMELLIA-CFB128 buffer encryption/decryption
|
||||
* operation.
|
||||
*
|
||||
* \note Due to the nature of CFB mode, you should use the same
|
||||
* key for both encryption and decryption. In particular, calls
|
||||
* to this function should be preceded by a key-schedule via
|
||||
* mbedtls_camellia_setkey_enc() regardless of whether \p mode
|
||||
* is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
|
||||
*
|
||||
* \note Upon exit, the content of the IV is updated so that you can
|
||||
* call the function same function again on the following
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If on the other hand you need to retain the contents of the
|
||||
* IV, you should either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
* \param ctx The CAMELLIA context to use. This must be initialized
|
||||
* and bound to a key.
|
||||
* \param mode The mode of operation. This must be either
|
||||
* #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
|
||||
* \param length The length of the input data \p input. Any value is allowed.
|
||||
* \param iv_off The current offset in the IV. This must be smaller
|
||||
* than \c 16 Bytes. It is updated after this call to allow
|
||||
* the aforementioned streaming usage.
|
||||
* \param iv The initialization vector. This must be a read/write buffer
|
||||
* of length \c 16 Bytes. It is updated after this call to
|
||||
* allow the aforementioned streaming usage.
|
||||
* \param input The buffer holding the input data. This must be a readable
|
||||
* buffer of size \p length Bytes.
|
||||
* \param output The buffer to hold the output data. This must be a writable
|
||||
* buffer of length \p length Bytes.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_camellia_crypt_cfb128(mbedtls_camellia_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CTR)
|
||||
/**
|
||||
* \brief Perform a CAMELLIA-CTR buffer encryption/decryption operation.
|
||||
*
|
||||
* *note Due to the nature of CTR mode, you should use the same
|
||||
* key for both encryption and decryption. In particular, calls
|
||||
* to this function should be preceded by a key-schedule via
|
||||
* mbedtls_camellia_setkey_enc() regardless of whether the mode
|
||||
* is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
|
||||
*
|
||||
* \warning You must never reuse a nonce value with the same key. Doing so
|
||||
* would void the encryption for the two messages encrypted with
|
||||
* the same nonce and key.
|
||||
*
|
||||
* There are two common strategies for managing nonces with CTR:
|
||||
*
|
||||
* 1. You can handle everything as a single message processed over
|
||||
* successive calls to this function. In that case, you want to
|
||||
* set \p nonce_counter and \p nc_off to 0 for the first call, and
|
||||
* then preserve the values of \p nonce_counter, \p nc_off and \p
|
||||
* stream_block across calls to this function as they will be
|
||||
* updated by this function.
|
||||
*
|
||||
* With this strategy, you must not encrypt more than 2**128
|
||||
* blocks of data with the same key.
|
||||
*
|
||||
* 2. You can encrypt separate messages by dividing the \p
|
||||
* nonce_counter buffer in two areas: the first one used for a
|
||||
* per-message nonce, handled by yourself, and the second one
|
||||
* updated by this function internally.
|
||||
*
|
||||
* For example, you might reserve the first \c 12 Bytes for the
|
||||
* per-message nonce, and the last \c 4 Bytes for internal use.
|
||||
* In that case, before calling this function on a new message you
|
||||
* need to set the first \c 12 Bytes of \p nonce_counter to your
|
||||
* chosen nonce value, the last four to \c 0, and \p nc_off to \c 0
|
||||
* (which will cause \p stream_block to be ignored). That way, you
|
||||
* can encrypt at most \c 2**96 messages of up to \c 2**32 blocks
|
||||
* each with the same key.
|
||||
*
|
||||
* The per-message nonce (or information sufficient to reconstruct
|
||||
* it) needs to be communicated with the ciphertext and must be
|
||||
* unique. The recommended way to ensure uniqueness is to use a
|
||||
* message counter. An alternative is to generate random nonces,
|
||||
* but this limits the number of messages that can be securely
|
||||
* encrypted: for example, with 96-bit random nonces, you should
|
||||
* not encrypt more than 2**32 messages with the same key.
|
||||
*
|
||||
* Note that for both strategies, sizes are measured in blocks and
|
||||
* that a CAMELLIA block is \c 16 Bytes.
|
||||
*
|
||||
* \warning Upon return, \p stream_block contains sensitive data. Its
|
||||
* content must not be written to insecure storage and should be
|
||||
* securely discarded as soon as it's no longer needed.
|
||||
*
|
||||
* \param ctx The CAMELLIA context to use. This must be initialized
|
||||
* and bound to a key.
|
||||
* \param length The length of the input data \p input in Bytes.
|
||||
* Any value is allowed.
|
||||
* \param nc_off The offset in the current \p stream_block (for resuming
|
||||
* within current cipher stream). The offset pointer to
|
||||
* should be \c 0 at the start of a stream. It is updated
|
||||
* at the end of this call.
|
||||
* \param nonce_counter The 128-bit nonce and counter. This must be a read/write
|
||||
* buffer of length \c 16 Bytes.
|
||||
* \param stream_block The saved stream-block for resuming. This must be a
|
||||
* read/write buffer of length \c 16 Bytes.
|
||||
* \param input The input data stream. This must be a readable buffer of
|
||||
* size \p length Bytes.
|
||||
* \param output The output data stream. This must be a writable buffer
|
||||
* of size \p length Bytes.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_camellia_crypt_ctr(mbedtls_camellia_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[16],
|
||||
unsigned char stream_block[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CTR */
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int mbedtls_camellia_self_test(int verbose);
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* camellia.h */
|
||||
@@ -1,518 +0,0 @@
|
||||
/**
|
||||
* \file ccm.h
|
||||
*
|
||||
* \brief This file provides an API for the CCM authenticated encryption
|
||||
* mode for block ciphers.
|
||||
*
|
||||
* CCM combines Counter mode encryption with CBC-MAC authentication
|
||||
* for 128-bit block ciphers.
|
||||
*
|
||||
* Input to CCM includes the following elements:
|
||||
* <ul><li>Payload - data that is both authenticated and encrypted.</li>
|
||||
* <li>Associated data (Adata) - data that is authenticated but not
|
||||
* encrypted, For example, a header.</li>
|
||||
* <li>Nonce - A unique value that is assigned to the payload and the
|
||||
* associated data.</li></ul>
|
||||
*
|
||||
* Definition of CCM:
|
||||
* http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
|
||||
* RFC 3610 "Counter with CBC-MAC (CCM)"
|
||||
*
|
||||
* Related:
|
||||
* RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
|
||||
*
|
||||
* Definition of CCM*:
|
||||
* IEEE 802.15.4 - IEEE Standard for Local and metropolitan area networks
|
||||
* Integer representation is fixed most-significant-octet-first order and
|
||||
* the representation of octets is most-significant-bit-first order. This is
|
||||
* consistent with RFC 3610.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CCM_H
|
||||
#define MBEDTLS_CCM_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include "mbedtls/cipher.h"
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_C)
|
||||
#include "mbedtls/block_cipher.h"
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_CCM_DECRYPT 0
|
||||
#define MBEDTLS_CCM_ENCRYPT 1
|
||||
#define MBEDTLS_CCM_STAR_DECRYPT 2
|
||||
#define MBEDTLS_CCM_STAR_ENCRYPT 3
|
||||
|
||||
/** Bad input parameters to the function. */
|
||||
#define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D
|
||||
/** Authenticated decryption failed. */
|
||||
#define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The CCM context-type definition. The CCM context is passed
|
||||
* to the APIs called.
|
||||
*/
|
||||
typedef struct mbedtls_ccm_context {
|
||||
unsigned char MBEDTLS_PRIVATE(y)[16]; /*!< The Y working buffer */
|
||||
unsigned char MBEDTLS_PRIVATE(ctr)[16]; /*!< The counter buffer */
|
||||
size_t MBEDTLS_PRIVATE(plaintext_len); /*!< Total plaintext length */
|
||||
size_t MBEDTLS_PRIVATE(add_len); /*!< Total authentication data length */
|
||||
size_t MBEDTLS_PRIVATE(tag_len); /*!< Total tag length */
|
||||
size_t MBEDTLS_PRIVATE(processed); /*!< Track how many bytes of input data
|
||||
were processed (chunked input).
|
||||
Used independently for both auth data
|
||||
and plaintext/ciphertext.
|
||||
This variable is set to zero after
|
||||
auth data input is finished. */
|
||||
unsigned int MBEDTLS_PRIVATE(q); /*!< The Q working value */
|
||||
unsigned int MBEDTLS_PRIVATE(mode); /*!< The operation to perform:
|
||||
#MBEDTLS_CCM_ENCRYPT or
|
||||
#MBEDTLS_CCM_DECRYPT or
|
||||
#MBEDTLS_CCM_STAR_ENCRYPT or
|
||||
#MBEDTLS_CCM_STAR_DECRYPT. */
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_C)
|
||||
mbedtls_block_cipher_context_t MBEDTLS_PRIVATE(block_cipher_ctx); /*!< The cipher context used. */
|
||||
#else
|
||||
mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */
|
||||
#endif
|
||||
int MBEDTLS_PRIVATE(state); /*!< Working value holding context's
|
||||
state. Used for chunked data input */
|
||||
}
|
||||
mbedtls_ccm_context;
|
||||
|
||||
/**
|
||||
* \brief This function initializes the specified CCM context,
|
||||
* to make references valid, and prepare the context
|
||||
* for mbedtls_ccm_setkey() or mbedtls_ccm_free().
|
||||
*
|
||||
* \param ctx The CCM context to initialize. This must not be \c NULL.
|
||||
*/
|
||||
void mbedtls_ccm_init(mbedtls_ccm_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function initializes the CCM context set in the
|
||||
* \p ctx parameter and sets the encryption key.
|
||||
*
|
||||
* \param ctx The CCM context to initialize. This must be an initialized
|
||||
* context.
|
||||
* \param cipher The 128-bit block cipher to use.
|
||||
* \param key The encryption key. This must not be \c NULL.
|
||||
* \param keybits The key size in bits. This must be acceptable by the cipher.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A CCM or cipher-specific error code on failure.
|
||||
*/
|
||||
int mbedtls_ccm_setkey(mbedtls_ccm_context *ctx,
|
||||
mbedtls_cipher_id_t cipher,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
|
||||
/**
|
||||
* \brief This function releases and clears the specified CCM context
|
||||
* and underlying cipher sub-context.
|
||||
*
|
||||
* \param ctx The CCM context to clear. If this is \c NULL, the function
|
||||
* has no effect. Otherwise, this must be initialized.
|
||||
*/
|
||||
void mbedtls_ccm_free(mbedtls_ccm_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function encrypts a buffer using CCM.
|
||||
*
|
||||
* \note The tag is written to a separate buffer. To concatenate
|
||||
* the \p tag with the \p output, as done in <em>RFC-3610:
|
||||
* Counter with CBC-MAC (CCM)</em>, use
|
||||
* \p tag = \p output + \p length, and make sure that the
|
||||
* output buffer is at least \p length + \p tag_len wide.
|
||||
*
|
||||
* \param ctx The CCM context to use for encryption. This must be
|
||||
* initialized and bound to a key.
|
||||
* \param length The length of the input data in Bytes.
|
||||
* \param iv The initialization vector (nonce). This must be a readable
|
||||
* buffer of at least \p iv_len Bytes.
|
||||
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
|
||||
* or 13. The length L of the message length field is
|
||||
* 15 - \p iv_len.
|
||||
* \param ad The additional data field. If \p ad_len is greater than
|
||||
* zero, \p ad must be a readable buffer of at least that
|
||||
* length.
|
||||
* \param ad_len The length of additional data in Bytes.
|
||||
* This must be less than `2^16 - 2^8`.
|
||||
* \param input The buffer holding the input data. If \p length is greater
|
||||
* than zero, \p input must be a readable buffer of at least
|
||||
* that length.
|
||||
* \param output The buffer holding the output data. If \p length is greater
|
||||
* than zero, \p output must be a writable buffer of at least
|
||||
* that length.
|
||||
* \param tag The buffer holding the authentication field. This must be a
|
||||
* writable buffer of at least \p tag_len Bytes.
|
||||
* \param tag_len The length of the authentication field to generate in Bytes:
|
||||
* 4, 6, 8, 10, 12, 14 or 16.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A CCM or cipher-specific error code on failure.
|
||||
*/
|
||||
int mbedtls_ccm_encrypt_and_tag(mbedtls_ccm_context *ctx, size_t length,
|
||||
const unsigned char *iv, size_t iv_len,
|
||||
const unsigned char *ad, size_t ad_len,
|
||||
const unsigned char *input, unsigned char *output,
|
||||
unsigned char *tag, size_t tag_len);
|
||||
|
||||
/**
|
||||
* \brief This function encrypts a buffer using CCM*.
|
||||
*
|
||||
* \note The tag is written to a separate buffer. To concatenate
|
||||
* the \p tag with the \p output, as done in <em>RFC-3610:
|
||||
* Counter with CBC-MAC (CCM)</em>, use
|
||||
* \p tag = \p output + \p length, and make sure that the
|
||||
* output buffer is at least \p length + \p tag_len wide.
|
||||
*
|
||||
* \note When using this function in a variable tag length context,
|
||||
* the tag length has to be encoded into the \p iv passed to
|
||||
* this function.
|
||||
*
|
||||
* \param ctx The CCM context to use for encryption. This must be
|
||||
* initialized and bound to a key.
|
||||
* \param length The length of the input data in Bytes.
|
||||
* For tag length = 0, input length is ignored.
|
||||
* \param iv The initialization vector (nonce). This must be a readable
|
||||
* buffer of at least \p iv_len Bytes.
|
||||
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
|
||||
* or 13. The length L of the message length field is
|
||||
* 15 - \p iv_len.
|
||||
* \param ad The additional data field. This must be a readable buffer of
|
||||
* at least \p ad_len Bytes.
|
||||
* \param ad_len The length of additional data in Bytes.
|
||||
* This must be less than 2^16 - 2^8.
|
||||
* \param input The buffer holding the input data. If \p length is greater
|
||||
* than zero, \p input must be a readable buffer of at least
|
||||
* that length.
|
||||
* \param output The buffer holding the output data. If \p length is greater
|
||||
* than zero, \p output must be a writable buffer of at least
|
||||
* that length.
|
||||
* \param tag The buffer holding the authentication field. This must be a
|
||||
* writable buffer of at least \p tag_len Bytes.
|
||||
* \param tag_len The length of the authentication field to generate in Bytes:
|
||||
* 0, 4, 6, 8, 10, 12, 14 or 16.
|
||||
*
|
||||
* \warning Passing \c 0 as \p tag_len means that the message is no
|
||||
* longer authenticated.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A CCM or cipher-specific error code on failure.
|
||||
*/
|
||||
int mbedtls_ccm_star_encrypt_and_tag(mbedtls_ccm_context *ctx, size_t length,
|
||||
const unsigned char *iv, size_t iv_len,
|
||||
const unsigned char *ad, size_t ad_len,
|
||||
const unsigned char *input, unsigned char *output,
|
||||
unsigned char *tag, size_t tag_len);
|
||||
|
||||
/**
|
||||
* \brief This function performs a CCM authenticated decryption of a
|
||||
* buffer.
|
||||
*
|
||||
* \param ctx The CCM context to use for decryption. This must be
|
||||
* initialized and bound to a key.
|
||||
* \param length The length of the input data in Bytes.
|
||||
* \param iv The initialization vector (nonce). This must be a readable
|
||||
* buffer of at least \p iv_len Bytes.
|
||||
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
|
||||
* or 13. The length L of the message length field is
|
||||
* 15 - \p iv_len.
|
||||
* \param ad The additional data field. This must be a readable buffer
|
||||
* of at least that \p ad_len Bytes..
|
||||
* \param ad_len The length of additional data in Bytes.
|
||||
* This must be less than 2^16 - 2^8.
|
||||
* \param input The buffer holding the input data. If \p length is greater
|
||||
* than zero, \p input must be a readable buffer of at least
|
||||
* that length.
|
||||
* \param output The buffer holding the output data. If \p length is greater
|
||||
* than zero, \p output must be a writable buffer of at least
|
||||
* that length.
|
||||
* \param tag The buffer holding the authentication field. This must be a
|
||||
* readable buffer of at least \p tag_len Bytes.
|
||||
* \param tag_len The length of the authentication field to generate in Bytes:
|
||||
* 4, 6, 8, 10, 12, 14 or 16.
|
||||
*
|
||||
* \return \c 0 on success. This indicates that the message is authentic.
|
||||
* \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match.
|
||||
* \return A cipher-specific error code on calculation failure.
|
||||
*/
|
||||
int mbedtls_ccm_auth_decrypt(mbedtls_ccm_context *ctx, size_t length,
|
||||
const unsigned char *iv, size_t iv_len,
|
||||
const unsigned char *ad, size_t ad_len,
|
||||
const unsigned char *input, unsigned char *output,
|
||||
const unsigned char *tag, size_t tag_len);
|
||||
|
||||
/**
|
||||
* \brief This function performs a CCM* authenticated decryption of a
|
||||
* buffer.
|
||||
*
|
||||
* \note When using this function in a variable tag length context,
|
||||
* the tag length has to be decoded from \p iv and passed to
|
||||
* this function as \p tag_len. (\p tag needs to be adjusted
|
||||
* accordingly.)
|
||||
*
|
||||
* \param ctx The CCM context to use for decryption. This must be
|
||||
* initialized and bound to a key.
|
||||
* \param length The length of the input data in Bytes.
|
||||
* For tag length = 0, input length is ignored.
|
||||
* \param iv The initialization vector (nonce). This must be a readable
|
||||
* buffer of at least \p iv_len Bytes.
|
||||
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
|
||||
* or 13. The length L of the message length field is
|
||||
* 15 - \p iv_len.
|
||||
* \param ad The additional data field. This must be a readable buffer of
|
||||
* at least that \p ad_len Bytes.
|
||||
* \param ad_len The length of additional data in Bytes.
|
||||
* This must be less than 2^16 - 2^8.
|
||||
* \param input The buffer holding the input data. If \p length is greater
|
||||
* than zero, \p input must be a readable buffer of at least
|
||||
* that length.
|
||||
* \param output The buffer holding the output data. If \p length is greater
|
||||
* than zero, \p output must be a writable buffer of at least
|
||||
* that length.
|
||||
* \param tag The buffer holding the authentication field. This must be a
|
||||
* readable buffer of at least \p tag_len Bytes.
|
||||
* \param tag_len The length of the authentication field in Bytes.
|
||||
* 0, 4, 6, 8, 10, 12, 14 or 16.
|
||||
*
|
||||
* \warning Passing \c 0 as \p tag_len means that the message is nos
|
||||
* longer authenticated.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match.
|
||||
* \return A cipher-specific error code on calculation failure.
|
||||
*/
|
||||
int mbedtls_ccm_star_auth_decrypt(mbedtls_ccm_context *ctx, size_t length,
|
||||
const unsigned char *iv, size_t iv_len,
|
||||
const unsigned char *ad, size_t ad_len,
|
||||
const unsigned char *input, unsigned char *output,
|
||||
const unsigned char *tag, size_t tag_len);
|
||||
|
||||
/**
|
||||
* \brief This function starts a CCM encryption or decryption
|
||||
* operation.
|
||||
*
|
||||
* This function and mbedtls_ccm_set_lengths() must be called
|
||||
* before calling mbedtls_ccm_update_ad() or
|
||||
* mbedtls_ccm_update(). This function can be called before
|
||||
* or after mbedtls_ccm_set_lengths().
|
||||
*
|
||||
* \note This function is not implemented in Mbed TLS yet.
|
||||
*
|
||||
* \param ctx The CCM context. This must be initialized.
|
||||
* \param mode The operation to perform: #MBEDTLS_CCM_ENCRYPT or
|
||||
* #MBEDTLS_CCM_DECRYPT or #MBEDTLS_CCM_STAR_ENCRYPT or
|
||||
* #MBEDTLS_CCM_STAR_DECRYPT.
|
||||
* \param iv The initialization vector. This must be a readable buffer
|
||||
* of at least \p iv_len Bytes.
|
||||
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
|
||||
* or 13. The length L of the message length field is
|
||||
* 15 - \p iv_len.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CCM_BAD_INPUT on failure:
|
||||
* \p ctx is in an invalid state,
|
||||
* \p mode is invalid,
|
||||
* \p iv_len is invalid (lower than \c 7 or greater than
|
||||
* \c 13).
|
||||
*/
|
||||
int mbedtls_ccm_starts(mbedtls_ccm_context *ctx,
|
||||
int mode,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len);
|
||||
|
||||
/**
|
||||
* \brief This function declares the lengths of the message
|
||||
* and additional data for a CCM encryption or decryption
|
||||
* operation.
|
||||
*
|
||||
* This function and mbedtls_ccm_starts() must be called
|
||||
* before calling mbedtls_ccm_update_ad() or
|
||||
* mbedtls_ccm_update(). This function can be called before
|
||||
* or after mbedtls_ccm_starts().
|
||||
*
|
||||
* \note This function is not implemented in Mbed TLS yet.
|
||||
*
|
||||
* \param ctx The CCM context. This must be initialized.
|
||||
* \param total_ad_len The total length of additional data in bytes.
|
||||
* This must be less than `2^16 - 2^8`.
|
||||
* \param plaintext_len The length in bytes of the plaintext to encrypt or
|
||||
* result of the decryption (thus not encompassing the
|
||||
* additional data that are not encrypted).
|
||||
* \param tag_len The length of the tag to generate in Bytes:
|
||||
* 4, 6, 8, 10, 12, 14 or 16.
|
||||
* For CCM*, zero is also valid.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CCM_BAD_INPUT on failure:
|
||||
* \p ctx is in an invalid state,
|
||||
* \p total_ad_len is greater than \c 0xFF00.
|
||||
*/
|
||||
int mbedtls_ccm_set_lengths(mbedtls_ccm_context *ctx,
|
||||
size_t total_ad_len,
|
||||
size_t plaintext_len,
|
||||
size_t tag_len);
|
||||
|
||||
/**
|
||||
* \brief This function feeds an input buffer as associated data
|
||||
* (authenticated but not encrypted data) in a CCM
|
||||
* encryption or decryption operation.
|
||||
*
|
||||
* You may call this function zero, one or more times
|
||||
* to pass successive parts of the additional data. The
|
||||
* lengths \p ad_len of the data parts should eventually add
|
||||
* up exactly to the total length of additional data
|
||||
* \c total_ad_len passed to mbedtls_ccm_set_lengths(). You
|
||||
* may not call this function after calling
|
||||
* mbedtls_ccm_update().
|
||||
*
|
||||
* \note This function is not implemented in Mbed TLS yet.
|
||||
*
|
||||
* \param ctx The CCM context. This must have been started with
|
||||
* mbedtls_ccm_starts(), the lengths of the message and
|
||||
* additional data must have been declared with
|
||||
* mbedtls_ccm_set_lengths() and this must not have yet
|
||||
* received any input with mbedtls_ccm_update().
|
||||
* \param ad The buffer holding the additional data, or \c NULL
|
||||
* if \p ad_len is \c 0.
|
||||
* \param ad_len The length of the additional data. If \c 0,
|
||||
* \p ad may be \c NULL.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CCM_BAD_INPUT on failure:
|
||||
* \p ctx is in an invalid state,
|
||||
* total input length too long.
|
||||
*/
|
||||
int mbedtls_ccm_update_ad(mbedtls_ccm_context *ctx,
|
||||
const unsigned char *ad,
|
||||
size_t ad_len);
|
||||
|
||||
/**
|
||||
* \brief This function feeds an input buffer into an ongoing CCM
|
||||
* encryption or decryption operation.
|
||||
*
|
||||
* You may call this function zero, one or more times
|
||||
* to pass successive parts of the input: the plaintext to
|
||||
* encrypt, or the ciphertext (not including the tag) to
|
||||
* decrypt. After the last part of the input, call
|
||||
* mbedtls_ccm_finish(). The lengths \p input_len of the
|
||||
* data parts should eventually add up exactly to the
|
||||
* plaintext length \c plaintext_len passed to
|
||||
* mbedtls_ccm_set_lengths().
|
||||
*
|
||||
* This function may produce output in one of the following
|
||||
* ways:
|
||||
* - Immediate output: the output length is always equal
|
||||
* to the input length.
|
||||
* - Buffered output: except for the last part of input data,
|
||||
* the output consists of a whole number of 16-byte blocks.
|
||||
* If the total input length so far (not including
|
||||
* associated data) is 16 \* *B* + *A* with *A* < 16 then
|
||||
* the total output length is 16 \* *B*.
|
||||
* For the last part of input data, the output length is
|
||||
* equal to the input length plus the number of bytes (*A*)
|
||||
* buffered in the previous call to the function (if any).
|
||||
* The function uses the plaintext length
|
||||
* \c plaintext_len passed to mbedtls_ccm_set_lengths()
|
||||
* to detect the last part of input data.
|
||||
*
|
||||
* In particular:
|
||||
* - It is always correct to call this function with
|
||||
* \p output_size >= \p input_len + 15.
|
||||
* - If \p input_len is a multiple of 16 for all the calls
|
||||
* to this function during an operation (not necessary for
|
||||
* the last one) then it is correct to use \p output_size
|
||||
* =\p input_len.
|
||||
*
|
||||
* \note This function is not implemented in Mbed TLS yet.
|
||||
*
|
||||
* \param ctx The CCM context. This must have been started with
|
||||
* mbedtls_ccm_starts() and the lengths of the message and
|
||||
* additional data must have been declared with
|
||||
* mbedtls_ccm_set_lengths().
|
||||
* \param input The buffer holding the input data. If \p input_len
|
||||
* is greater than zero, this must be a readable buffer
|
||||
* of at least \p input_len bytes.
|
||||
* \param input_len The length of the input data in bytes.
|
||||
* \param output The buffer for the output data. If \p output_size
|
||||
* is greater than zero, this must be a writable buffer of
|
||||
* at least \p output_size bytes.
|
||||
* \param output_size The size of the output buffer in bytes.
|
||||
* See the function description regarding the output size.
|
||||
* \param output_len On success, \p *output_len contains the actual
|
||||
* length of the output written in \p output.
|
||||
* On failure, the content of \p *output_len is
|
||||
* unspecified.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CCM_BAD_INPUT on failure:
|
||||
* \p ctx is in an invalid state,
|
||||
* total input length too long,
|
||||
* or \p output_size too small.
|
||||
*/
|
||||
int mbedtls_ccm_update(mbedtls_ccm_context *ctx,
|
||||
const unsigned char *input, size_t input_len,
|
||||
unsigned char *output, size_t output_size,
|
||||
size_t *output_len);
|
||||
|
||||
/**
|
||||
* \brief This function finishes the CCM operation and generates
|
||||
* the authentication tag.
|
||||
*
|
||||
* It wraps up the CCM stream, and generates the
|
||||
* tag. The tag can have a maximum length of 16 Bytes.
|
||||
*
|
||||
* \note This function is not implemented in Mbed TLS yet.
|
||||
*
|
||||
* \param ctx The CCM context. This must have been started with
|
||||
* mbedtls_ccm_starts() and the lengths of the message and
|
||||
* additional data must have been declared with
|
||||
* mbedtls_ccm_set_lengths().
|
||||
* \param tag The buffer for holding the tag. If \p tag_len is greater
|
||||
* than zero, this must be a writable buffer of at least \p
|
||||
* tag_len Bytes.
|
||||
* \param tag_len The length of the tag. Must match the tag length passed to
|
||||
* mbedtls_ccm_set_lengths() function.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CCM_BAD_INPUT on failure:
|
||||
* \p ctx is in an invalid state,
|
||||
* invalid value of \p tag_len,
|
||||
* the total amount of additional data passed to
|
||||
* mbedtls_ccm_update_ad() was lower than the total length of
|
||||
* additional data \c total_ad_len passed to
|
||||
* mbedtls_ccm_set_lengths(),
|
||||
* the total amount of input data passed to
|
||||
* mbedtls_ccm_update() was lower than the plaintext length
|
||||
* \c plaintext_len passed to mbedtls_ccm_set_lengths().
|
||||
*/
|
||||
int mbedtls_ccm_finish(mbedtls_ccm_context *ctx,
|
||||
unsigned char *tag, size_t tag_len);
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_CCM_GCM_CAN_AES)
|
||||
/**
|
||||
* \brief The CCM checkup routine.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c 1 on failure.
|
||||
*/
|
||||
int mbedtls_ccm_self_test(int verbose);
|
||||
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_CCM_H */
|
||||
@@ -1,196 +0,0 @@
|
||||
/**
|
||||
* \file chacha20.h
|
||||
*
|
||||
* \brief This file contains ChaCha20 definitions and functions.
|
||||
*
|
||||
* ChaCha20 is a stream cipher that can encrypt and decrypt
|
||||
* information. ChaCha was created by Daniel Bernstein as a variant of
|
||||
* its Salsa cipher https://cr.yp.to/chacha/chacha-20080128.pdf
|
||||
* ChaCha20 is the variant with 20 rounds, that was also standardized
|
||||
* in RFC 7539.
|
||||
*
|
||||
* \author Daniel King <damaki.gh@gmail.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CHACHA20_H
|
||||
#define MBEDTLS_CHACHA20_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/** Invalid input parameter(s). */
|
||||
#define MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA -0x0051
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct mbedtls_chacha20_context {
|
||||
uint32_t MBEDTLS_PRIVATE(state)[16]; /*! The state (before round operations). */
|
||||
uint8_t MBEDTLS_PRIVATE(keystream8)[64]; /*! Leftover keystream bytes. */
|
||||
size_t MBEDTLS_PRIVATE(keystream_bytes_used); /*! Number of keystream bytes already used. */
|
||||
}
|
||||
mbedtls_chacha20_context;
|
||||
|
||||
/**
|
||||
* \brief This function initializes the specified ChaCha20 context.
|
||||
*
|
||||
* It must be the first API called before using
|
||||
* the context.
|
||||
*
|
||||
* It is usually followed by calls to
|
||||
* \c mbedtls_chacha20_setkey() and
|
||||
* \c mbedtls_chacha20_starts(), then one or more calls to
|
||||
* to \c mbedtls_chacha20_update(), and finally to
|
||||
* \c mbedtls_chacha20_free().
|
||||
*
|
||||
* \param ctx The ChaCha20 context to initialize.
|
||||
* This must not be \c NULL.
|
||||
*/
|
||||
void mbedtls_chacha20_init(mbedtls_chacha20_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function releases and clears the specified
|
||||
* ChaCha20 context.
|
||||
*
|
||||
* \param ctx The ChaCha20 context to clear. This may be \c NULL,
|
||||
* in which case this function is a no-op. If it is not
|
||||
* \c NULL, it must point to an initialized context.
|
||||
*
|
||||
*/
|
||||
void mbedtls_chacha20_free(mbedtls_chacha20_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function sets the encryption/decryption key.
|
||||
*
|
||||
* \note After using this function, you must also call
|
||||
* \c mbedtls_chacha20_starts() to set a nonce before you
|
||||
* start encrypting/decrypting data with
|
||||
* \c mbedtls_chacha_update().
|
||||
*
|
||||
* \param ctx The ChaCha20 context to which the key should be bound.
|
||||
* It must be initialized.
|
||||
* \param key The encryption/decryption key. This must be \c 32 Bytes
|
||||
* in length.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or key is NULL.
|
||||
*/
|
||||
int mbedtls_chacha20_setkey(mbedtls_chacha20_context *ctx,
|
||||
const unsigned char key[32]);
|
||||
|
||||
/**
|
||||
* \brief This function sets the nonce and initial counter value.
|
||||
*
|
||||
* \note A ChaCha20 context can be re-used with the same key by
|
||||
* calling this function to change the nonce.
|
||||
*
|
||||
* \warning You must never use the same nonce twice with the same key.
|
||||
* This would void any confidentiality guarantees for the
|
||||
* messages encrypted with the same nonce and key.
|
||||
*
|
||||
* \param ctx The ChaCha20 context to which the nonce should be bound.
|
||||
* It must be initialized and bound to a key.
|
||||
* \param nonce The nonce. This must be \c 12 Bytes in size.
|
||||
* \param counter The initial counter value. This is usually \c 0.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or nonce is
|
||||
* NULL.
|
||||
*/
|
||||
int mbedtls_chacha20_starts(mbedtls_chacha20_context *ctx,
|
||||
const unsigned char nonce[12],
|
||||
uint32_t counter);
|
||||
|
||||
/**
|
||||
* \brief This function encrypts or decrypts data.
|
||||
*
|
||||
* Since ChaCha20 is a stream cipher, the same operation is
|
||||
* used for encrypting and decrypting data.
|
||||
*
|
||||
* \note The \p input and \p output pointers must either be equal or
|
||||
* point to non-overlapping buffers.
|
||||
*
|
||||
* \note \c mbedtls_chacha20_setkey() and
|
||||
* \c mbedtls_chacha20_starts() must be called at least once
|
||||
* to setup the context before this function can be called.
|
||||
*
|
||||
* \note This function can be called multiple times in a row in
|
||||
* order to encrypt of decrypt data piecewise with the same
|
||||
* key and nonce.
|
||||
*
|
||||
* \param ctx The ChaCha20 context to use for encryption or decryption.
|
||||
* It must be initialized and bound to a key and nonce.
|
||||
* \param size The length of the input data in Bytes.
|
||||
* \param input The buffer holding the input data.
|
||||
* This pointer can be \c NULL if `size == 0`.
|
||||
* \param output The buffer holding the output data.
|
||||
* This must be able to hold \p size Bytes.
|
||||
* This pointer can be \c NULL if `size == 0`.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_chacha20_update(mbedtls_chacha20_context *ctx,
|
||||
size_t size,
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
|
||||
/**
|
||||
* \brief This function encrypts or decrypts data with ChaCha20 and
|
||||
* the given key and nonce.
|
||||
*
|
||||
* Since ChaCha20 is a stream cipher, the same operation is
|
||||
* used for encrypting and decrypting data.
|
||||
*
|
||||
* \warning You must never use the same (key, nonce) pair more than
|
||||
* once. This would void any confidentiality guarantees for
|
||||
* the messages encrypted with the same nonce and key.
|
||||
*
|
||||
* \note The \p input and \p output pointers must either be equal or
|
||||
* point to non-overlapping buffers.
|
||||
*
|
||||
* \param key The encryption/decryption key.
|
||||
* This must be \c 32 Bytes in length.
|
||||
* \param nonce The nonce. This must be \c 12 Bytes in size.
|
||||
* \param counter The initial counter value. This is usually \c 0.
|
||||
* \param size The length of the input data in Bytes.
|
||||
* \param input The buffer holding the input data.
|
||||
* This pointer can be \c NULL if `size == 0`.
|
||||
* \param output The buffer holding the output data.
|
||||
* This must be able to hold \p size Bytes.
|
||||
* This pointer can be \c NULL if `size == 0`.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_chacha20_crypt(const unsigned char key[32],
|
||||
const unsigned char nonce[12],
|
||||
uint32_t counter,
|
||||
size_t size,
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
/**
|
||||
* \brief The ChaCha20 checkup routine.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c 1 on failure.
|
||||
*/
|
||||
int mbedtls_chacha20_self_test(int verbose);
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_CHACHA20_H */
|
||||
@@ -1,336 +0,0 @@
|
||||
/**
|
||||
* \file chachapoly.h
|
||||
*
|
||||
* \brief This file contains the AEAD-ChaCha20-Poly1305 definitions and
|
||||
* functions.
|
||||
*
|
||||
* ChaCha20-Poly1305 is an algorithm for Authenticated Encryption
|
||||
* with Associated Data (AEAD) that can be used to encrypt and
|
||||
* authenticate data. It is based on ChaCha20 and Poly1305 by Daniel
|
||||
* Bernstein and was standardized in RFC 7539.
|
||||
*
|
||||
* \author Daniel King <damaki.gh@gmail.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CHACHAPOLY_H
|
||||
#define MBEDTLS_CHACHAPOLY_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
/* for shared error codes */
|
||||
#include "mbedtls/poly1305.h"
|
||||
|
||||
/** The requested operation is not permitted in the current state. */
|
||||
#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x0054
|
||||
/** Authenticated decryption failed: data was not authentic. */
|
||||
#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED -0x0056
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
MBEDTLS_CHACHAPOLY_ENCRYPT, /**< The mode value for performing encryption. */
|
||||
MBEDTLS_CHACHAPOLY_DECRYPT /**< The mode value for performing decryption. */
|
||||
}
|
||||
mbedtls_chachapoly_mode_t;
|
||||
|
||||
#include "mbedtls/chacha20.h"
|
||||
|
||||
typedef struct mbedtls_chachapoly_context {
|
||||
mbedtls_chacha20_context MBEDTLS_PRIVATE(chacha20_ctx); /**< The ChaCha20 context. */
|
||||
mbedtls_poly1305_context MBEDTLS_PRIVATE(poly1305_ctx); /**< The Poly1305 context. */
|
||||
uint64_t MBEDTLS_PRIVATE(aad_len); /**< The length (bytes) of the Additional Authenticated Data. */
|
||||
uint64_t MBEDTLS_PRIVATE(ciphertext_len); /**< The length (bytes) of the ciphertext. */
|
||||
int MBEDTLS_PRIVATE(state); /**< The current state of the context. */
|
||||
mbedtls_chachapoly_mode_t MBEDTLS_PRIVATE(mode); /**< Cipher mode (encrypt or decrypt). */
|
||||
}
|
||||
mbedtls_chachapoly_context;
|
||||
|
||||
/**
|
||||
* \brief This function initializes the specified ChaCha20-Poly1305 context.
|
||||
*
|
||||
* It must be the first API called before using
|
||||
* the context. It must be followed by a call to
|
||||
* \c mbedtls_chachapoly_setkey() before any operation can be
|
||||
* done, and to \c mbedtls_chachapoly_free() once all
|
||||
* operations with that context have been finished.
|
||||
*
|
||||
* In order to encrypt or decrypt full messages at once, for
|
||||
* each message you should make a single call to
|
||||
* \c mbedtls_chachapoly_crypt_and_tag() or
|
||||
* \c mbedtls_chachapoly_auth_decrypt().
|
||||
*
|
||||
* In order to encrypt messages piecewise, for each
|
||||
* message you should make a call to
|
||||
* \c mbedtls_chachapoly_starts(), then 0 or more calls to
|
||||
* \c mbedtls_chachapoly_update_aad(), then 0 or more calls to
|
||||
* \c mbedtls_chachapoly_update(), then one call to
|
||||
* \c mbedtls_chachapoly_finish().
|
||||
*
|
||||
* \warning Decryption with the piecewise API is discouraged! Always
|
||||
* use \c mbedtls_chachapoly_auth_decrypt() when possible!
|
||||
*
|
||||
* If however this is not possible because the data is too
|
||||
* large to fit in memory, you need to:
|
||||
*
|
||||
* - call \c mbedtls_chachapoly_starts() and (if needed)
|
||||
* \c mbedtls_chachapoly_update_aad() as above,
|
||||
* - call \c mbedtls_chachapoly_update() multiple times and
|
||||
* ensure its output (the plaintext) is NOT used in any other
|
||||
* way than placing it in temporary storage at this point,
|
||||
* - call \c mbedtls_chachapoly_finish() to compute the
|
||||
* authentication tag and compared it in constant time to the
|
||||
* tag received with the ciphertext.
|
||||
*
|
||||
* If the tags are not equal, you must immediately discard
|
||||
* all previous outputs of \c mbedtls_chachapoly_update(),
|
||||
* otherwise you can now safely use the plaintext.
|
||||
*
|
||||
* \param ctx The ChachaPoly context to initialize. Must not be \c NULL.
|
||||
*/
|
||||
void mbedtls_chachapoly_init(mbedtls_chachapoly_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function releases and clears the specified
|
||||
* ChaCha20-Poly1305 context.
|
||||
*
|
||||
* \param ctx The ChachaPoly context to clear. This may be \c NULL, in which
|
||||
* case this function is a no-op.
|
||||
*/
|
||||
void mbedtls_chachapoly_free(mbedtls_chachapoly_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function sets the ChaCha20-Poly1305
|
||||
* symmetric encryption key.
|
||||
*
|
||||
* \param ctx The ChaCha20-Poly1305 context to which the key should be
|
||||
* bound. This must be initialized.
|
||||
* \param key The \c 256 Bit (\c 32 Bytes) key.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_chachapoly_setkey(mbedtls_chachapoly_context *ctx,
|
||||
const unsigned char key[32]);
|
||||
|
||||
/**
|
||||
* \brief This function starts a ChaCha20-Poly1305 encryption or
|
||||
* decryption operation.
|
||||
*
|
||||
* \warning You must never use the same nonce twice with the same key.
|
||||
* This would void any confidentiality and authenticity
|
||||
* guarantees for the messages encrypted with the same nonce
|
||||
* and key.
|
||||
*
|
||||
* \note If the context is being used for AAD only (no data to
|
||||
* encrypt or decrypt) then \p mode can be set to any value.
|
||||
*
|
||||
* \warning Decryption with the piecewise API is discouraged, see the
|
||||
* warning on \c mbedtls_chachapoly_init().
|
||||
*
|
||||
* \param ctx The ChaCha20-Poly1305 context. This must be initialized
|
||||
* and bound to a key.
|
||||
* \param nonce The nonce/IV to use for the message.
|
||||
* This must be a readable buffer of length \c 12 Bytes.
|
||||
* \param mode The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or
|
||||
* #MBEDTLS_CHACHAPOLY_DECRYPT (discouraged, see warning).
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_chachapoly_starts(mbedtls_chachapoly_context *ctx,
|
||||
const unsigned char nonce[12],
|
||||
mbedtls_chachapoly_mode_t mode);
|
||||
|
||||
/**
|
||||
* \brief This function feeds additional data to be authenticated
|
||||
* into an ongoing ChaCha20-Poly1305 operation.
|
||||
*
|
||||
* The Additional Authenticated Data (AAD), also called
|
||||
* Associated Data (AD) is only authenticated but not
|
||||
* encrypted nor included in the encrypted output. It is
|
||||
* usually transmitted separately from the ciphertext or
|
||||
* computed locally by each party.
|
||||
*
|
||||
* \note This function is called before data is encrypted/decrypted.
|
||||
* I.e. call this function to process the AAD before calling
|
||||
* \c mbedtls_chachapoly_update().
|
||||
*
|
||||
* You may call this function multiple times to process
|
||||
* an arbitrary amount of AAD. It is permitted to call
|
||||
* this function 0 times, if no AAD is used.
|
||||
*
|
||||
* This function cannot be called any more if data has
|
||||
* been processed by \c mbedtls_chachapoly_update(),
|
||||
* or if the context has been finished.
|
||||
*
|
||||
* \warning Decryption with the piecewise API is discouraged, see the
|
||||
* warning on \c mbedtls_chachapoly_init().
|
||||
*
|
||||
* \param ctx The ChaCha20-Poly1305 context. This must be initialized
|
||||
* and bound to a key.
|
||||
* \param aad_len The length in Bytes of the AAD. The length has no
|
||||
* restrictions.
|
||||
* \param aad Buffer containing the AAD.
|
||||
* This pointer can be \c NULL if `aad_len == 0`.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
|
||||
* if \p ctx or \p aad are NULL.
|
||||
* \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
|
||||
* if the operations has not been started or has been
|
||||
* finished, or if the AAD has been finished.
|
||||
*/
|
||||
int mbedtls_chachapoly_update_aad(mbedtls_chachapoly_context *ctx,
|
||||
const unsigned char *aad,
|
||||
size_t aad_len);
|
||||
|
||||
/**
|
||||
* \brief Thus function feeds data to be encrypted or decrypted
|
||||
* into an on-going ChaCha20-Poly1305
|
||||
* operation.
|
||||
*
|
||||
* The direction (encryption or decryption) depends on the
|
||||
* mode that was given when calling
|
||||
* \c mbedtls_chachapoly_starts().
|
||||
*
|
||||
* You may call this function multiple times to process
|
||||
* an arbitrary amount of data. It is permitted to call
|
||||
* this function 0 times, if no data is to be encrypted
|
||||
* or decrypted.
|
||||
*
|
||||
* \warning Decryption with the piecewise API is discouraged, see the
|
||||
* warning on \c mbedtls_chachapoly_init().
|
||||
*
|
||||
* \param ctx The ChaCha20-Poly1305 context to use. This must be initialized.
|
||||
* \param len The length (in bytes) of the data to encrypt or decrypt.
|
||||
* \param input The buffer containing the data to encrypt or decrypt.
|
||||
* This pointer can be \c NULL if `len == 0`.
|
||||
* \param output The buffer to where the encrypted or decrypted data is
|
||||
* written. This must be able to hold \p len bytes.
|
||||
* This pointer can be \c NULL if `len == 0`.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
|
||||
* if the operation has not been started or has been
|
||||
* finished.
|
||||
* \return Another negative error code on other kinds of failure.
|
||||
*/
|
||||
int mbedtls_chachapoly_update(mbedtls_chachapoly_context *ctx,
|
||||
size_t len,
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
|
||||
/**
|
||||
* \brief This function finished the ChaCha20-Poly1305 operation and
|
||||
* generates the MAC (authentication tag).
|
||||
*
|
||||
* \param ctx The ChaCha20-Poly1305 context to use. This must be initialized.
|
||||
* \param mac The buffer to where the 128-bit (16 bytes) MAC is written.
|
||||
*
|
||||
* \warning Decryption with the piecewise API is discouraged, see the
|
||||
* warning on \c mbedtls_chachapoly_init().
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
|
||||
* if the operation has not been started or has been
|
||||
* finished.
|
||||
* \return Another negative error code on other kinds of failure.
|
||||
*/
|
||||
int mbedtls_chachapoly_finish(mbedtls_chachapoly_context *ctx,
|
||||
unsigned char mac[16]);
|
||||
|
||||
/**
|
||||
* \brief This function performs a complete ChaCha20-Poly1305
|
||||
* authenticated encryption with the previously-set key.
|
||||
*
|
||||
* \note Before using this function, you must set the key with
|
||||
* \c mbedtls_chachapoly_setkey().
|
||||
*
|
||||
* \warning You must never use the same nonce twice with the same key.
|
||||
* This would void any confidentiality and authenticity
|
||||
* guarantees for the messages encrypted with the same nonce
|
||||
* and key.
|
||||
*
|
||||
* \param ctx The ChaCha20-Poly1305 context to use (holds the key).
|
||||
* This must be initialized.
|
||||
* \param length The length (in bytes) of the data to encrypt or decrypt.
|
||||
* \param nonce The 96-bit (12 bytes) nonce/IV to use.
|
||||
* \param aad The buffer containing the additional authenticated
|
||||
* data (AAD). This pointer can be \c NULL if `aad_len == 0`.
|
||||
* \param aad_len The length (in bytes) of the AAD data to process.
|
||||
* \param input The buffer containing the data to encrypt or decrypt.
|
||||
* This pointer can be \c NULL if `ilen == 0`.
|
||||
* \param output The buffer to where the encrypted or decrypted data
|
||||
* is written. This pointer can be \c NULL if `ilen == 0`.
|
||||
* \param tag The buffer to where the computed 128-bit (16 bytes) MAC
|
||||
* is written. This must not be \c NULL.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_chachapoly_encrypt_and_tag(mbedtls_chachapoly_context *ctx,
|
||||
size_t length,
|
||||
const unsigned char nonce[12],
|
||||
const unsigned char *aad,
|
||||
size_t aad_len,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
unsigned char tag[16]);
|
||||
|
||||
/**
|
||||
* \brief This function performs a complete ChaCha20-Poly1305
|
||||
* authenticated decryption with the previously-set key.
|
||||
*
|
||||
* \note Before using this function, you must set the key with
|
||||
* \c mbedtls_chachapoly_setkey().
|
||||
*
|
||||
* \param ctx The ChaCha20-Poly1305 context to use (holds the key).
|
||||
* \param length The length (in Bytes) of the data to decrypt.
|
||||
* \param nonce The \c 96 Bit (\c 12 bytes) nonce/IV to use.
|
||||
* \param aad The buffer containing the additional authenticated data (AAD).
|
||||
* This pointer can be \c NULL if `aad_len == 0`.
|
||||
* \param aad_len The length (in bytes) of the AAD data to process.
|
||||
* \param tag The buffer holding the authentication tag.
|
||||
* This must be a readable buffer of length \c 16 Bytes.
|
||||
* \param input The buffer containing the data to decrypt.
|
||||
* This pointer can be \c NULL if `ilen == 0`.
|
||||
* \param output The buffer to where the decrypted data is written.
|
||||
* This pointer can be \c NULL if `ilen == 0`.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED
|
||||
* if the data was not authentic.
|
||||
* \return Another negative error code on other kinds of failure.
|
||||
*/
|
||||
int mbedtls_chachapoly_auth_decrypt(mbedtls_chachapoly_context *ctx,
|
||||
size_t length,
|
||||
const unsigned char nonce[12],
|
||||
const unsigned char *aad,
|
||||
size_t aad_len,
|
||||
const unsigned char tag[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
/**
|
||||
* \brief The ChaCha20-Poly1305 checkup routine.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c 1 on failure.
|
||||
*/
|
||||
int mbedtls_chachapoly_self_test(int verbose);
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_CHACHAPOLY_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,222 +0,0 @@
|
||||
/**
|
||||
* \file cmac.h
|
||||
*
|
||||
* \brief This file contains CMAC definitions and functions.
|
||||
*
|
||||
* The Cipher-based Message Authentication Code (CMAC) Mode for
|
||||
* Authentication is defined in <em>RFC-4493: The AES-CMAC Algorithm</em>.
|
||||
* It is supported with AES and DES.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CMAC_H
|
||||
#define MBEDTLS_CMAC_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include "mbedtls/cipher.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_AES_BLOCK_SIZE 16
|
||||
#define MBEDTLS_DES3_BLOCK_SIZE 8
|
||||
|
||||
/* We don't support Camellia or ARIA in this module */
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
#define MBEDTLS_CMAC_MAX_BLOCK_SIZE 16 /**< The longest block used by CMAC is that of AES. */
|
||||
#else
|
||||
#define MBEDTLS_CMAC_MAX_BLOCK_SIZE 8 /**< The longest block used by CMAC is that of 3DES. */
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
/** The longest block supported by the cipher module.
|
||||
*
|
||||
* \deprecated
|
||||
* For the maximum block size of a cipher supported by the CMAC module,
|
||||
* use #MBEDTLS_CMAC_MAX_BLOCK_SIZE.
|
||||
* For the maximum block size of a cipher supported by the cipher module,
|
||||
* use #MBEDTLS_MAX_BLOCK_LENGTH.
|
||||
*/
|
||||
/* Before Mbed TLS 3.5, this was the maximum block size supported by the CMAC
|
||||
* module, so it didn't take Camellia or ARIA into account. Since the name
|
||||
* of the macro doesn't even convey "CMAC", this was misleading. Now the size
|
||||
* is sufficient for any cipher, but the name is defined in cmac.h for
|
||||
* backward compatibility. */
|
||||
#define MBEDTLS_CIPHER_BLKSIZE_MAX MBEDTLS_MAX_BLOCK_LENGTH
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
/**
|
||||
* The CMAC context structure.
|
||||
*/
|
||||
struct mbedtls_cmac_context_t {
|
||||
/** The internal state of the CMAC algorithm. */
|
||||
unsigned char MBEDTLS_PRIVATE(state)[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
|
||||
|
||||
/** Unprocessed data - either data that was not block aligned and is still
|
||||
* pending processing, or the final block. */
|
||||
unsigned char MBEDTLS_PRIVATE(unprocessed_block)[MBEDTLS_CMAC_MAX_BLOCK_SIZE];
|
||||
|
||||
/** The length of data pending processing. */
|
||||
size_t MBEDTLS_PRIVATE(unprocessed_len);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief This function starts a new CMAC computation
|
||||
* by setting the CMAC key, and preparing to authenticate
|
||||
* the input data.
|
||||
* It must be called with an initialized cipher context.
|
||||
*
|
||||
* Once this function has completed, data can be supplied
|
||||
* to the CMAC computation by calling
|
||||
* mbedtls_cipher_cmac_update().
|
||||
*
|
||||
* To start a CMAC computation using the same key as a previous
|
||||
* CMAC computation, use mbedtls_cipher_cmac_finish().
|
||||
*
|
||||
* \param ctx The cipher context used for the CMAC operation, initialized
|
||||
* as one of the following types: MBEDTLS_CIPHER_AES_128_ECB,
|
||||
* MBEDTLS_CIPHER_AES_192_ECB, MBEDTLS_CIPHER_AES_256_ECB,
|
||||
* or MBEDTLS_CIPHER_DES_EDE3_ECB.
|
||||
* \param key The CMAC key.
|
||||
* \param keybits The length of the CMAC key in bits.
|
||||
* Must be supported by the cipher.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A cipher-specific error code on failure.
|
||||
*/
|
||||
int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx,
|
||||
const unsigned char *key, size_t keybits);
|
||||
|
||||
/**
|
||||
* \brief This function feeds an input buffer into an ongoing CMAC
|
||||
* computation.
|
||||
*
|
||||
* The CMAC computation must have previously been started
|
||||
* by calling mbedtls_cipher_cmac_starts() or
|
||||
* mbedtls_cipher_cmac_reset().
|
||||
*
|
||||
* Call this function as many times as needed to input the
|
||||
* data to be authenticated.
|
||||
* Once all of the required data has been input,
|
||||
* call mbedtls_cipher_cmac_finish() to obtain the result
|
||||
* of the CMAC operation.
|
||||
*
|
||||
* \param ctx The cipher context used for the CMAC operation.
|
||||
* \param input The buffer holding the input data.
|
||||
* \param ilen The length of the input data.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
|
||||
* if parameter verification fails.
|
||||
*/
|
||||
int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
|
||||
const unsigned char *input, size_t ilen);
|
||||
|
||||
/**
|
||||
* \brief This function finishes an ongoing CMAC operation, and
|
||||
* writes the result to the output buffer.
|
||||
*
|
||||
* It should be followed either by
|
||||
* mbedtls_cipher_cmac_reset(), which starts another CMAC
|
||||
* operation with the same key, or mbedtls_cipher_free(),
|
||||
* which clears the cipher context.
|
||||
*
|
||||
* \param ctx The cipher context used for the CMAC operation.
|
||||
* \param output The output buffer for the CMAC checksum result.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
|
||||
* if parameter verification fails.
|
||||
*/
|
||||
int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx,
|
||||
unsigned char *output);
|
||||
|
||||
/**
|
||||
* \brief This function starts a new CMAC operation with the same
|
||||
* key as the previous one.
|
||||
*
|
||||
* It should be called after finishing the previous CMAC
|
||||
* operation with mbedtls_cipher_cmac_finish().
|
||||
* After calling this function,
|
||||
* call mbedtls_cipher_cmac_update() to supply the new
|
||||
* CMAC operation with data.
|
||||
*
|
||||
* \param ctx The cipher context used for the CMAC operation.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
|
||||
* if parameter verification fails.
|
||||
*/
|
||||
int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function calculates the full generic CMAC
|
||||
* on the input buffer with the provided key.
|
||||
*
|
||||
* The function allocates the context, performs the
|
||||
* calculation, and frees the context.
|
||||
*
|
||||
* The CMAC result is calculated as
|
||||
* output = generic CMAC(cmac key, input buffer).
|
||||
*
|
||||
* \param cipher_info The cipher information.
|
||||
* \param key The CMAC key.
|
||||
* \param keylen The length of the CMAC key in bits.
|
||||
* \param input The buffer holding the input data.
|
||||
* \param ilen The length of the input data.
|
||||
* \param output The buffer for the generic CMAC result.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA
|
||||
* if parameter verification fails.
|
||||
*/
|
||||
int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info,
|
||||
const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output);
|
||||
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
/**
|
||||
* \brief This function implements the AES-CMAC-PRF-128 pseudorandom
|
||||
* function, as defined in
|
||||
* <em>RFC-4615: The Advanced Encryption Standard-Cipher-based
|
||||
* Message Authentication Code-Pseudo-Random Function-128
|
||||
* (AES-CMAC-PRF-128) Algorithm for the Internet Key
|
||||
* Exchange Protocol (IKE).</em>
|
||||
*
|
||||
* \param key The key to use.
|
||||
* \param key_len The key length in Bytes.
|
||||
* \param input The buffer holding the input data.
|
||||
* \param in_len The length of the input data in Bytes.
|
||||
* \param output The buffer holding the generated 16 Bytes of
|
||||
* pseudorandom output.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_len,
|
||||
const unsigned char *input, size_t in_len,
|
||||
unsigned char output[16]);
|
||||
#endif /* MBEDTLS_AES_C */
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST) && (defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C))
|
||||
/**
|
||||
* \brief The CMAC checkup routine.
|
||||
*
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c 1 on failure.
|
||||
*/
|
||||
int mbedtls_cmac_self_test(int verbose);
|
||||
#endif /* MBEDTLS_SELF_TEST && ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_CMAC_H */
|
||||
@@ -1,338 +0,0 @@
|
||||
/**
|
||||
* \file mbedtls/config_adjust_legacy_crypto.h
|
||||
* \brief Adjust legacy configuration configuration
|
||||
*
|
||||
* This is an internal header. Do not include it directly.
|
||||
*
|
||||
* Automatically enable certain dependencies. Generally, MBEDTLS_xxx
|
||||
* configurations need to be explicitly enabled by the user: enabling
|
||||
* MBEDTLS_xxx_A but not MBEDTLS_xxx_B when A requires B results in a
|
||||
* compilation error. However, we do automatically enable certain options
|
||||
* in some circumstances. One case is if MBEDTLS_xxx_B is an internal option
|
||||
* used to identify parts of a module that are used by other module, and we
|
||||
* don't want to make the symbol MBEDTLS_xxx_B part of the public API.
|
||||
* Another case is if A didn't depend on B in earlier versions, and we
|
||||
* want to use B in A but we need to preserve backward compatibility with
|
||||
* configurations that explicitly activate MBEDTLS_xxx_A but not
|
||||
* MBEDTLS_xxx_B.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H
|
||||
#define MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H
|
||||
|
||||
#if !defined(TF_PSA_CRYPTO_CONFIG_FILES_READ)
|
||||
#error "Do not include mbedtls/config_adjust_*.h manually! This can lead to problems, " \
|
||||
"up to and including runtime errors such as buffer overflows. " \
|
||||
"If you're trying to fix a complaint from check_config.h, just remove " \
|
||||
"it from your configuration file: since Mbed TLS 3.0, it is included " \
|
||||
"automatically at the right point."
|
||||
#endif /* */
|
||||
|
||||
/* Ideally, we'd set those as defaults in mbedtls_config.h, but
|
||||
* putting an #ifdef _WIN32 in mbedtls_config.h would confuse config.py.
|
||||
*
|
||||
* So, adjust it here.
|
||||
* Not related to crypto, but this is the bottom of the stack. */
|
||||
#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900)
|
||||
#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \
|
||||
!defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
|
||||
#define MBEDTLS_PLATFORM_SNPRINTF_ALT
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) && \
|
||||
!defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
|
||||
#define MBEDTLS_PLATFORM_VSNPRINTF_ALT
|
||||
#endif
|
||||
#endif /* _MINGW32__ || (_MSC_VER && (_MSC_VER <= 1900)) */
|
||||
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_USE_PSA_CRYPTO
|
||||
*
|
||||
* Make the X.509 and TLS libraries use PSA for cryptographic operations as
|
||||
* much as possible, and enable new APIs for using keys handled by PSA Crypto.
|
||||
*
|
||||
* \note This is a legacy symbol which still exists for backward compatibility.
|
||||
* Up to Mbed TLS 3.x, it was not enabled by default. Now it is always
|
||||
* enabled, and it will eventually disappear from the code base. This
|
||||
* is not part of the public API of TF-PSA-Crypto or of Mbed TLS >=4.0.
|
||||
*/
|
||||
#define MBEDTLS_USE_PSA_CRYPTO
|
||||
|
||||
/* Auto-enable CIPHER_C when any of the unauthenticated ciphers is builtin
|
||||
* in PSA. */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C) && \
|
||||
(defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CTR) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CFB) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_OFB) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC))
|
||||
#define MBEDTLS_CIPHER_C
|
||||
#endif
|
||||
|
||||
/* Auto-enable MBEDTLS_MD_LIGHT based on MBEDTLS_MD_C.
|
||||
* This allows checking for MD_LIGHT rather than MD_LIGHT || MD_C.
|
||||
*/
|
||||
#if defined(MBEDTLS_MD_C)
|
||||
#define MBEDTLS_MD_LIGHT
|
||||
#endif
|
||||
|
||||
/* Auto-enable MBEDTLS_MD_LIGHT if needed by a module that didn't require it
|
||||
* in a previous release, to ensure backwards compatibility.
|
||||
*/
|
||||
#if defined(MBEDTLS_ECJPAKE_C) || \
|
||||
defined(MBEDTLS_PEM_PARSE_C) || \
|
||||
defined(MBEDTLS_ENTROPY_C) || \
|
||||
defined(MBEDTLS_PK_C) || \
|
||||
defined(MBEDTLS_PKCS12_C) || \
|
||||
defined(MBEDTLS_RSA_C) || \
|
||||
defined(MBEDTLS_SSL_TLS_C) || \
|
||||
defined(MBEDTLS_X509_USE_C) || \
|
||||
defined(MBEDTLS_X509_CREATE_C)
|
||||
#define MBEDTLS_MD_LIGHT
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_MD_LIGHT)
|
||||
/*
|
||||
* - MBEDTLS_MD_xxx_VIA_PSA is defined if the md module may perform xxx via PSA
|
||||
* (see below).
|
||||
* - MBEDTLS_MD_SOME_PSA is defined if at least one algorithm may be performed
|
||||
* via PSA (see below).
|
||||
* - MBEDTLS_MD_SOME_LEGACY is defined if at least one algorithm may be performed
|
||||
* via a direct legacy call (see below).
|
||||
*
|
||||
* The md module performs an algorithm via PSA if there is a PSA hash
|
||||
* accelerator and the PSA driver subsytem is initialized at the time the
|
||||
* operation is started, and makes a direct legacy call otherwise.
|
||||
*/
|
||||
|
||||
/* PSA accelerated implementations */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_MD5)
|
||||
#define MBEDTLS_MD_MD5_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1)
|
||||
#define MBEDTLS_MD_SHA1_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224)
|
||||
#define MBEDTLS_MD_SHA224_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
|
||||
#define MBEDTLS_MD_SHA256_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384)
|
||||
#define MBEDTLS_MD_SHA384_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512)
|
||||
#define MBEDTLS_MD_SHA512_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160)
|
||||
#define MBEDTLS_MD_RIPEMD160_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_224)
|
||||
#define MBEDTLS_MD_SHA3_224_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_256)
|
||||
#define MBEDTLS_MD_SHA3_256_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_384)
|
||||
#define MBEDTLS_MD_SHA3_384_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_512)
|
||||
#define MBEDTLS_MD_SHA3_512_VIA_PSA
|
||||
#define MBEDTLS_MD_SOME_PSA
|
||||
#endif
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
/* Built-in implementations */
|
||||
#if defined(MBEDTLS_MD5_C) || \
|
||||
defined(MBEDTLS_SHA1_C) || \
|
||||
defined(MBEDTLS_SHA224_C) || \
|
||||
defined(MBEDTLS_SHA256_C) || \
|
||||
defined(MBEDTLS_SHA384_C) || \
|
||||
defined(MBEDTLS_SHA512_C) || \
|
||||
defined(MBEDTLS_SHA3_C) || \
|
||||
defined(MBEDTLS_RIPEMD160_C)
|
||||
#define MBEDTLS_MD_SOME_LEGACY
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_MD_LIGHT */
|
||||
|
||||
/* BLOCK_CIPHER module can dispatch to PSA when:
|
||||
* - PSA is enabled and drivers have been initialized
|
||||
* - desired key type is supported on the PSA side
|
||||
* If the above conditions are not met, but the legacy support is enabled, then
|
||||
* BLOCK_CIPHER will dynamically fallback to it.
|
||||
*
|
||||
* In case BLOCK_CIPHER is defined (see below) the following symbols/helpers
|
||||
* can be used to define its capabilities:
|
||||
* - MBEDTLS_BLOCK_CIPHER_SOME_PSA: there is at least 1 key type between AES,
|
||||
* ARIA and Camellia which is supported through a driver;
|
||||
* - MBEDTLS_BLOCK_CIPHER_xxx_VIA_PSA: xxx key type is supported through a
|
||||
* driver;
|
||||
* - MBEDTLS_BLOCK_CIPHER_xxx_VIA_LEGACY: xxx key type is supported through
|
||||
* a legacy module (i.e. MBEDTLS_xxx_C)
|
||||
*/
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_AES)
|
||||
#define MBEDTLS_BLOCK_CIPHER_AES_VIA_PSA
|
||||
#define MBEDTLS_BLOCK_CIPHER_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ARIA)
|
||||
#define MBEDTLS_BLOCK_CIPHER_ARIA_VIA_PSA
|
||||
#define MBEDTLS_BLOCK_CIPHER_SOME_PSA
|
||||
#endif
|
||||
#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA)
|
||||
#define MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_PSA
|
||||
#define MBEDTLS_BLOCK_CIPHER_SOME_PSA
|
||||
#endif
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
#if defined(MBEDTLS_AES_C)
|
||||
#define MBEDTLS_BLOCK_CIPHER_AES_VIA_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARIA_C)
|
||||
#define MBEDTLS_BLOCK_CIPHER_ARIA_VIA_LEGACY
|
||||
#endif
|
||||
#if defined(MBEDTLS_CAMELLIA_C)
|
||||
#define MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_LEGACY
|
||||
#endif
|
||||
|
||||
/* Helpers to state that BLOCK_CIPHER module supports AES, ARIA and/or Camellia
|
||||
* block ciphers via either PSA or legacy. */
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_AES_VIA_PSA) || \
|
||||
defined(MBEDTLS_BLOCK_CIPHER_AES_VIA_LEGACY)
|
||||
#define MBEDTLS_BLOCK_CIPHER_CAN_AES
|
||||
#endif
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_ARIA_VIA_PSA) || \
|
||||
defined(MBEDTLS_BLOCK_CIPHER_ARIA_VIA_LEGACY)
|
||||
#define MBEDTLS_BLOCK_CIPHER_CAN_ARIA
|
||||
#endif
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_PSA) || \
|
||||
defined(MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_LEGACY)
|
||||
#define MBEDTLS_BLOCK_CIPHER_CAN_CAMELLIA
|
||||
#endif
|
||||
|
||||
/* GCM_C and CCM_C can either depend on (in order of preference) BLOCK_CIPHER_C
|
||||
* or CIPHER_C. The former is auto-enabled when:
|
||||
* - CIPHER_C is not defined, which is also the legacy solution;
|
||||
* - BLOCK_CIPHER_SOME_PSA because in this case BLOCK_CIPHER can take advantage
|
||||
* of the driver's acceleration.
|
||||
*/
|
||||
#if (defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C)) && \
|
||||
(!defined(MBEDTLS_CIPHER_C) || defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA))
|
||||
#define MBEDTLS_BLOCK_CIPHER_C
|
||||
#endif
|
||||
|
||||
/* Helpers for GCM/CCM capabilities */
|
||||
#if (defined(MBEDTLS_CIPHER_C) && defined(MBEDTLS_AES_C)) || \
|
||||
(defined(MBEDTLS_BLOCK_CIPHER_C) && defined(MBEDTLS_BLOCK_CIPHER_CAN_AES))
|
||||
#define MBEDTLS_CCM_GCM_CAN_AES
|
||||
#endif
|
||||
|
||||
#if (defined(MBEDTLS_CIPHER_C) && defined(MBEDTLS_ARIA_C)) || \
|
||||
(defined(MBEDTLS_BLOCK_CIPHER_C) && defined(MBEDTLS_BLOCK_CIPHER_CAN_ARIA))
|
||||
#define MBEDTLS_CCM_GCM_CAN_ARIA
|
||||
#endif
|
||||
|
||||
#if (defined(MBEDTLS_CIPHER_C) && defined(MBEDTLS_CAMELLIA_C)) || \
|
||||
(defined(MBEDTLS_BLOCK_CIPHER_C) && defined(MBEDTLS_BLOCK_CIPHER_CAN_CAMELLIA))
|
||||
#define MBEDTLS_CCM_GCM_CAN_CAMELLIA
|
||||
#endif
|
||||
|
||||
/* MBEDTLS_ECP_LIGHT is auto-enabled by the following symbols:
|
||||
* - MBEDTLS_ECP_C because now it consists of MBEDTLS_ECP_LIGHT plus functions
|
||||
* for curve arithmetic. As a consequence if MBEDTLS_ECP_C is required for
|
||||
* some reason, then MBEDTLS_ECP_LIGHT should be enabled as well.
|
||||
* - MBEDTLS_PK_PARSE_EC_EXTENDED and MBEDTLS_PK_PARSE_EC_COMPRESSED because
|
||||
* these features are not supported in PSA so the only way to have them is
|
||||
* to enable the built-in solution.
|
||||
* Both of them are temporary dependencies:
|
||||
* - PK_PARSE_EC_EXTENDED will be removed after #7779 and #7789
|
||||
* - support for compressed points should also be added to PSA, but in this
|
||||
* case there is no associated issue to track it yet.
|
||||
* - PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE because Weierstrass key derivation
|
||||
* still depends on ECP_LIGHT.
|
||||
*/
|
||||
#if defined(MBEDTLS_ECP_C) || \
|
||||
defined(MBEDTLS_PK_PARSE_EC_EXTENDED) || \
|
||||
defined(MBEDTLS_PK_PARSE_EC_COMPRESSED) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE)
|
||||
#define MBEDTLS_ECP_LIGHT
|
||||
#endif
|
||||
|
||||
/* Backward compatibility: after #8740 the RSA module offers functions to parse
|
||||
* and write RSA private/public keys without relying on the PK one. Of course
|
||||
* this needs ASN1 support to do so, so we enable it here. */
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
#define MBEDTLS_ASN1_PARSE_C
|
||||
#define MBEDTLS_ASN1_WRITE_C
|
||||
#endif
|
||||
|
||||
/* MBEDTLS_PK_PARSE_EC_COMPRESSED is introduced in Mbed TLS version 3.5, while
|
||||
* in previous version compressed points were automatically supported as long
|
||||
* as PK_PARSE_C and ECP_C were enabled. As a consequence, for backward
|
||||
* compatibility, we auto-enable PK_PARSE_EC_COMPRESSED when these conditions
|
||||
* are met. */
|
||||
#if defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_ECP_C)
|
||||
#define MBEDTLS_PK_PARSE_EC_COMPRESSED
|
||||
#endif
|
||||
|
||||
/* Helper symbol to state that there is support for ECDH, either through
|
||||
* library implementation (ECDH_C) or through PSA. */
|
||||
#if (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_ECDH)) || \
|
||||
(!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ECDH_C))
|
||||
#define MBEDTLS_CAN_ECDH
|
||||
#endif
|
||||
|
||||
/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT
|
||||
* is defined as well to include all PSA code.
|
||||
*/
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
#define MBEDTLS_PSA_CRYPTO_CLIENT
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
/* Historically pkparse did not check the CBC padding when decrypting
|
||||
* a key. This was a bug, which is now fixed. As a consequence, pkparse
|
||||
* now needs PKCS7 padding support, but existing configurations might not
|
||||
* enable it, so we enable it here. */
|
||||
#if defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_PKCS5_C) && defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
#define MBEDTLS_CIPHER_PADDING_PKCS7
|
||||
#endif
|
||||
|
||||
/* Backwards compatibility for some macros which were renamed to reflect that
|
||||
* they are related to Armv8, not aarch64. */
|
||||
#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) && \
|
||||
!defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT)
|
||||
#define MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY) && !defined(MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY)
|
||||
#define MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
|
||||
#endif
|
||||
|
||||
/* Some internal helpers to determine which operation modes are available. */
|
||||
|
||||
#if defined(PSA_WANT_ALG_GCM) || defined(PSA_WANT_ALG_CCM) || \
|
||||
defined(PSA_WANT_ALG_CHACHA20_POLY1305)
|
||||
#define MBEDTLS_SSL_HAVE_AEAD
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H */
|
||||
@@ -1,891 +0,0 @@
|
||||
/**
|
||||
* \file mbedtls/config_adjust_legacy_from_psa.h
|
||||
* \brief Adjust PSA configuration: activate legacy implementations
|
||||
*
|
||||
* This is an internal header. Do not include it directly.
|
||||
*
|
||||
* Activate legacy implementations of cryptographic mechanisms as needed to
|
||||
* fulfill the needs of the PSA configuration. Generally speaking, we activate
|
||||
* a legacy mechanism if it's needed for a requested PSA mechanism and there is
|
||||
* no PSA driver for it.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CONFIG_ADJUST_LEGACY_FROM_PSA_H
|
||||
#define MBEDTLS_CONFIG_ADJUST_LEGACY_FROM_PSA_H
|
||||
|
||||
#if !defined(TF_PSA_CRYPTO_CONFIG_FILES_READ)
|
||||
#error "Do not include mbedtls/config_adjust_*.h manually! This can lead to problems, " \
|
||||
"up to and including runtime errors such as buffer overflows. " \
|
||||
"If you're trying to fix a complaint from check_config.h, just remove " \
|
||||
"it from your configuration file: since Mbed TLS 3.0, it is included " \
|
||||
"automatically at the right point."
|
||||
#endif /* */
|
||||
|
||||
/* Define appropriate ACCEL macros for the p256-m driver.
|
||||
* In the future, those should be generated from the drivers JSON description.
|
||||
*/
|
||||
#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED)
|
||||
#define MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_ECDSA
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_ECDH
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ECC: support for a feature is controlled by a triplet or a pair:
|
||||
* (curve, key_type public/basic, alg) or (curve, key_type_<action>).
|
||||
*
|
||||
* A triplet/pair is accelerated if all of is components are accelerated;
|
||||
* otherwise each component needs to be built in.
|
||||
*
|
||||
* We proceed in two passes:
|
||||
* 1. Check if acceleration is complete for curves, key types, algs.
|
||||
* 2. Then enable built-ins for each thing that's either not accelerated of
|
||||
* doesn't have complete acceleration of the other triplet/pair components.
|
||||
*
|
||||
* Note: this needs psa/crypto_adjust_keypair_types.h to have been included
|
||||
* already, so that we know the full set of key types that are requested.
|
||||
*/
|
||||
|
||||
/* ECC: curves: is acceleration complete? */
|
||||
#if (defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_256)) || \
|
||||
(defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_384)) || \
|
||||
(defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_512)) || \
|
||||
(defined(PSA_WANT_ECC_SECP_R1_192) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192)) || \
|
||||
(defined(PSA_WANT_ECC_SECP_R1_224) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_224)) || \
|
||||
(defined(PSA_WANT_ECC_SECP_R1_256) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256)) || \
|
||||
(defined(PSA_WANT_ECC_SECP_R1_384) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384)) || \
|
||||
(defined(PSA_WANT_ECC_SECP_R1_521) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521)) || \
|
||||
(defined(PSA_WANT_ECC_SECP_K1_192) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_192)) || \
|
||||
(defined(PSA_WANT_ECC_SECP_K1_224) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_224)) || \
|
||||
(defined(PSA_WANT_ECC_SECP_K1_256) && !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_256))
|
||||
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES
|
||||
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES
|
||||
#endif
|
||||
|
||||
#if (defined(PSA_WANT_ECC_MONTGOMERY_255) && !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_255)) || \
|
||||
(defined(PSA_WANT_ECC_MONTGOMERY_448) && !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448))
|
||||
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES
|
||||
#endif
|
||||
|
||||
/* ECC: algs: is acceleration complete? */
|
||||
#if (defined(PSA_WANT_ALG_ECDH) && !defined(MBEDTLS_PSA_ACCEL_ALG_ECDH)) || \
|
||||
(defined(PSA_WANT_ALG_ECDSA) && !defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA)) || \
|
||||
(defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA)) || \
|
||||
(defined(PSA_WANT_ALG_JPAKE) && !defined(MBEDTLS_PSA_ACCEL_ALG_JPAKE))
|
||||
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS
|
||||
#endif
|
||||
|
||||
/* ECC: key types: is acceleration complete? */
|
||||
#if (defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)) || \
|
||||
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC))
|
||||
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC
|
||||
#endif
|
||||
|
||||
/* Special case: we don't support cooked key derivation in drivers yet */
|
||||
#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE)
|
||||
#undef MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE
|
||||
#endif
|
||||
|
||||
/* Note: the condition about key derivation is always true as DERIVE can't be
|
||||
* accelerated yet */
|
||||
#if (defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)) || \
|
||||
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC)) || \
|
||||
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT)) || \
|
||||
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT)) || \
|
||||
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE)) || \
|
||||
(defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE))
|
||||
#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES
|
||||
#endif
|
||||
|
||||
/* ECC: curves: enable built-ins as needed.
|
||||
*
|
||||
* We need the curve built-in:
|
||||
* - if it's not accelerated, or
|
||||
* - if there's a key type with missing acceleration, or
|
||||
* - if there's a alg with missing acceleration.
|
||||
*/
|
||||
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_256) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_256 1
|
||||
#define MBEDTLS_ECP_DP_BP256R1_ENABLED
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_256 */
|
||||
|
||||
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_384) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_384 1
|
||||
#define MBEDTLS_ECP_DP_BP384R1_ENABLED
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_384 */
|
||||
|
||||
#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_512) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_512 1
|
||||
#define MBEDTLS_ECP_DP_BP512R1_ENABLED
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_512 */
|
||||
|
||||
#if defined(PSA_WANT_ECC_MONTGOMERY_255)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_255) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_255 1
|
||||
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_ECC_MONTGOMERY_255 */
|
||||
|
||||
#if defined(PSA_WANT_ECC_MONTGOMERY_448)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_448 1
|
||||
#define MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_ECC_MONTGOMERY_448 */
|
||||
|
||||
#if defined(PSA_WANT_ECC_SECP_R1_192)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_192 1
|
||||
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_ECC_SECP_R1_192 */
|
||||
|
||||
#if defined(PSA_WANT_ECC_SECP_R1_224)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_224) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_224 1
|
||||
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_ECC_SECP_R1_224 */
|
||||
|
||||
#if defined(PSA_WANT_ECC_SECP_R1_256)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_256 1
|
||||
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_ECC_SECP_R1_256 */
|
||||
|
||||
#if defined(PSA_WANT_ECC_SECP_R1_384)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_384 1
|
||||
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_ECC_SECP_R1_384 */
|
||||
|
||||
#if defined(PSA_WANT_ECC_SECP_R1_521)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_521 1
|
||||
#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_ECC_SECP_R1_521 */
|
||||
|
||||
#if defined(PSA_WANT_ECC_SECP_K1_192)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_192) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_192 1
|
||||
#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_ECC_SECP_K1_192 */
|
||||
|
||||
#if defined(PSA_WANT_ECC_SECP_K1_224)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_224) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_224 1
|
||||
#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
|
||||
/* https://github.com/Mbed-TLS/mbedtls/issues/3541 */
|
||||
#error "SECP224K1 is buggy via the PSA API in Mbed TLS."
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_ECC_SECP_K1_224 */
|
||||
|
||||
#if defined(PSA_WANT_ECC_SECP_K1_256)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_256) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_256 1
|
||||
#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_ECC_SECP_K1_256 */
|
||||
|
||||
/* ECC: algs: enable built-ins as needed.
|
||||
*
|
||||
* We need the alg built-in:
|
||||
* - if it's not accelerated, or
|
||||
* - if there's a relevant curve (see below) with missing acceleration, or
|
||||
* - if there's a key type among (public, basic) with missing acceleration.
|
||||
*
|
||||
* Relevant curves are:
|
||||
* - all curves for ECDH
|
||||
* - Weierstrass curves for (deterministic) ECDSA
|
||||
* - secp256r1 for EC J-PAKE
|
||||
*/
|
||||
#if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA 1
|
||||
#define MBEDTLS_ECDSA_DETERMINISTIC
|
||||
#define MBEDTLS_HMAC_DRBG_C
|
||||
#define MBEDTLS_MD_C
|
||||
#define MBEDTLS_ECDSA_C
|
||||
#define MBEDTLS_ECP_C
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#define MBEDTLS_ASN1_PARSE_C
|
||||
#define MBEDTLS_ASN1_WRITE_C
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_ALG_DETERMINISTIC_ECDSA */
|
||||
|
||||
#if defined(PSA_WANT_ALG_ECDH)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_ECDH) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_ECDH 1
|
||||
#define MBEDTLS_ECDH_C
|
||||
#define MBEDTLS_ECP_C
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_ALG_ECDH */
|
||||
|
||||
#if defined(PSA_WANT_ALG_ECDSA)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_ECDSA 1
|
||||
#define MBEDTLS_ECDSA_C
|
||||
#define MBEDTLS_ECP_C
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#define MBEDTLS_ASN1_PARSE_C
|
||||
#define MBEDTLS_ASN1_WRITE_C
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_ALG_ECDSA */
|
||||
|
||||
#if defined(PSA_WANT_ALG_JPAKE)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_JPAKE) || \
|
||||
!defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC)
|
||||
#define MBEDTLS_PSA_BUILTIN_PAKE 1
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_JPAKE 1
|
||||
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#define MBEDTLS_ECP_C
|
||||
#define MBEDTLS_ECJPAKE_C
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_ALG_JPAKE */
|
||||
|
||||
/* ECC: key types: enable built-ins as needed.
|
||||
*
|
||||
* We need the key type built-in:
|
||||
* - if it's not accelerated, or
|
||||
* - if there's a curve with missing acceleration, or
|
||||
* - only for public/basic: if there's an alg with missing acceleration.
|
||||
*/
|
||||
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC 1
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1
|
||||
#endif /* missing accel */
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE */
|
||||
|
||||
/* Note: the condition is always true as DERIVE can't be accelerated yet */
|
||||
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE) || \
|
||||
defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1
|
||||
#endif /* missing accel */
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE */
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE)
|
||||
#define MBEDTLS_ECP_LIGHT
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE)
|
||||
#define MBEDTLS_ECP_C
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#endif
|
||||
|
||||
/* End of ECC section */
|
||||
|
||||
/*
|
||||
* DH key types follow the same pattern used above for EC keys. They are defined
|
||||
* by a triplet (group, key_type, alg). A triplet is accelerated if all its
|
||||
* component are accelerated, otherwise each component needs to be builtin.
|
||||
*/
|
||||
|
||||
/* DH: groups: is acceleration complete? */
|
||||
#if (defined(PSA_WANT_DH_RFC7919_2048) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_2048)) || \
|
||||
(defined(PSA_WANT_DH_RFC7919_3072) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_3072)) || \
|
||||
(defined(PSA_WANT_DH_RFC7919_4096) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_4096)) || \
|
||||
(defined(PSA_WANT_DH_RFC7919_6144) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_6144)) || \
|
||||
(defined(PSA_WANT_DH_RFC7919_8192) && !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_8192))
|
||||
#define MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS
|
||||
#endif
|
||||
|
||||
/* DH: algs: is acceleration complete? */
|
||||
#if defined(PSA_WANT_ALG_FFDH) && !defined(MBEDTLS_PSA_ACCEL_ALG_FFDH)
|
||||
#define MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS
|
||||
#endif
|
||||
|
||||
/* DH: key types: is acceleration complete? */
|
||||
#if (defined(PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY)) || \
|
||||
(defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_BASIC)) || \
|
||||
(defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_IMPORT)) || \
|
||||
(defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_EXPORT)) || \
|
||||
(defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_GENERATE))
|
||||
#define MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_DH_RFC7919_2048)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_2048) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
|
||||
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 1
|
||||
#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_2048 */
|
||||
#endif /* PSA_WANT_DH_RFC7919_2048 */
|
||||
|
||||
#if defined(PSA_WANT_DH_RFC7919_3072)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_3072) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
|
||||
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 1
|
||||
#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_3072 */
|
||||
#endif /* PSA_WANT_DH_RFC7919_3072 */
|
||||
|
||||
#if defined(PSA_WANT_DH_RFC7919_4096)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_4096) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
|
||||
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 1
|
||||
#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_4096 */
|
||||
#endif /* PSA_WANT_DH_RFC7919_4096 */
|
||||
|
||||
#if defined(PSA_WANT_DH_RFC7919_6144)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_6144) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
|
||||
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 1
|
||||
#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_6144 */
|
||||
#endif /* PSA_WANT_DH_RFC7919_6144 */
|
||||
|
||||
#if defined(PSA_WANT_DH_RFC7919_8192)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_DH_RFC7919_8192) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
|
||||
#define MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 1
|
||||
#endif /* !MBEDTLS_PSA_BUILTIN_DH_RFC7919_8192 */
|
||||
#endif /* PSA_WANT_DH_RFC7919_8192 */
|
||||
|
||||
#if defined(PSA_WANT_ALG_FFDH)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_FFDH) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_KEY_TYPES)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_FFDH 1
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_FFDH */
|
||||
#endif /* PSA_WANT_ALG_FFDH */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_IMPORT) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_IMPORT */
|
||||
#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_EXPORT) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_EXPORT */
|
||||
#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_GENERATE)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_GENERATE */
|
||||
#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_BASIC) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_BASIC 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_BASIC */
|
||||
#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_GROUPS) || \
|
||||
defined(MBEDTLS_PSA_DH_ACCEL_INCOMPLETE_ALGS)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY 1
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY */
|
||||
#endif /* PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY */
|
||||
|
||||
/* End of DH section */
|
||||
|
||||
#if defined(PSA_WANT_ALG_HKDF)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF)
|
||||
/*
|
||||
* The PSA implementation has its own implementation of HKDF, separate from
|
||||
* hkdf.c. No need to enable MBEDTLS_HKDF_C here.
|
||||
*/
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF */
|
||||
#endif /* PSA_WANT_ALG_HKDF */
|
||||
|
||||
#if defined(PSA_WANT_ALG_HKDF_EXTRACT)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF_EXTRACT)
|
||||
/*
|
||||
* The PSA implementation has its own implementation of HKDF, separate from
|
||||
* hkdf.c. No need to enable MBEDTLS_HKDF_C here.
|
||||
*/
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF_EXTRACT */
|
||||
#endif /* PSA_WANT_ALG_HKDF_EXTRACT */
|
||||
|
||||
#if defined(PSA_WANT_ALG_HKDF_EXPAND)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF_EXPAND)
|
||||
/*
|
||||
* The PSA implementation has its own implementation of HKDF, separate from
|
||||
* hkdf.c. No need to enable MBEDTLS_HKDF_C here.
|
||||
*/
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF_EXPAND */
|
||||
#endif /* PSA_WANT_ALG_HKDF_EXPAND */
|
||||
|
||||
#if defined(PSA_WANT_ALG_HMAC)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_HMAC)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_HMAC */
|
||||
#endif /* PSA_WANT_ALG_HMAC */
|
||||
|
||||
#if defined(PSA_WANT_ALG_MD5) && !defined(MBEDTLS_PSA_ACCEL_ALG_MD5)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_MD5 1
|
||||
#define MBEDTLS_MD5_C
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_RIPEMD160) && !defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160 1
|
||||
#define MBEDTLS_RIPEMD160_C
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_RSA_OAEP)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP 1
|
||||
#define MBEDTLS_RSA_C
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#define MBEDTLS_OID_C
|
||||
#define MBEDTLS_PKCS1_V21
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP */
|
||||
#endif /* PSA_WANT_ALG_RSA_OAEP */
|
||||
|
||||
#if defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT 1
|
||||
#define MBEDTLS_RSA_C
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#define MBEDTLS_OID_C
|
||||
#define MBEDTLS_PKCS1_V15
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT */
|
||||
#endif /* PSA_WANT_ALG_RSA_PKCS1V15_CRYPT */
|
||||
|
||||
#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN 1
|
||||
#define MBEDTLS_RSA_C
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#define MBEDTLS_OID_C
|
||||
#define MBEDTLS_PKCS1_V15
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN */
|
||||
#endif /* PSA_WANT_ALG_RSA_PKCS1V15_SIGN */
|
||||
|
||||
#if defined(PSA_WANT_ALG_RSA_PSS)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PSS)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS 1
|
||||
#define MBEDTLS_RSA_C
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#define MBEDTLS_OID_C
|
||||
#define MBEDTLS_PKCS1_V21
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PSS */
|
||||
#endif /* PSA_WANT_ALG_RSA_PSS */
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_1) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_1 1
|
||||
#define MBEDTLS_SHA1_C
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_224) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_224 1
|
||||
#define MBEDTLS_SHA224_C
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_256) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_256 1
|
||||
#define MBEDTLS_SHA256_C
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_384) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_384 1
|
||||
#define MBEDTLS_SHA384_C
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_512) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_SHA_512 1
|
||||
#define MBEDTLS_SHA512_C
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA3_224) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_224)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_224 1
|
||||
#define MBEDTLS_SHA3_C
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA3_256) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_256)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_256 1
|
||||
#define MBEDTLS_SHA3_C
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA3_384) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_384)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_384 1
|
||||
#define MBEDTLS_SHA3_C
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA3_512) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_512)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_512 1
|
||||
#define MBEDTLS_SHA3_C
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_PBKDF2_HMAC)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_PBKDF2_HMAC)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC 1
|
||||
#define PSA_HAVE_SOFT_PBKDF2_HMAC 1
|
||||
#endif /* !MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
|
||||
#endif /* PSA_WANT_ALG_PBKDF2_HMAC */
|
||||
|
||||
#if defined(PSA_WANT_ALG_TLS12_PRF)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF */
|
||||
#endif /* PSA_WANT_ALG_TLS12_PRF */
|
||||
|
||||
#if defined(PSA_WANT_ALG_TLS12_PSK_TO_MS)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS */
|
||||
#endif /* PSA_WANT_ALG_TLS12_PSK_TO_MS */
|
||||
|
||||
#if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_ECJPAKE_TO_PMS)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_ECJPAKE_TO_PMS */
|
||||
#endif /* PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_IMPORT)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_IMPORT */
|
||||
#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_EXPORT)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_EXPORT */
|
||||
#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1
|
||||
#define MBEDTLS_GENPRIME
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE */
|
||||
#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_BASIC)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_BASIC 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_BASIC */
|
||||
#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY 1
|
||||
#define MBEDTLS_RSA_C
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#define MBEDTLS_OID_C
|
||||
#define MBEDTLS_ASN1_PARSE_C
|
||||
#define MBEDTLS_ASN1_WRITE_C
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY */
|
||||
#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY */
|
||||
|
||||
/* If any of the block modes are requested that don't have an
|
||||
* associated HW assist, define PSA_HAVE_SOFT_BLOCK_MODE for checking
|
||||
* in the block cipher key types. */
|
||||
#if (defined(PSA_WANT_ALG_CTR) && !defined(MBEDTLS_PSA_ACCEL_ALG_CTR)) || \
|
||||
(defined(PSA_WANT_ALG_CFB) && !defined(MBEDTLS_PSA_ACCEL_ALG_CFB)) || \
|
||||
(defined(PSA_WANT_ALG_OFB) && !defined(MBEDTLS_PSA_ACCEL_ALG_OFB)) || \
|
||||
(defined(PSA_WANT_ALG_ECB_NO_PADDING) && !defined(MBEDTLS_PSA_ACCEL_ALG_ECB_NO_PADDING)) || \
|
||||
(defined(PSA_WANT_ALG_CBC_NO_PADDING) && !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING)) || \
|
||||
(defined(PSA_WANT_ALG_CBC_PKCS7) && !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7)) || \
|
||||
(defined(PSA_WANT_ALG_CMAC) && !defined(MBEDTLS_PSA_ACCEL_ALG_CMAC))
|
||||
#define PSA_HAVE_SOFT_BLOCK_MODE 1
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_PBKDF2_AES_CMAC_PRF_128)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128 1
|
||||
#define PSA_HAVE_SOFT_PBKDF2_CMAC 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_PBKDF2_AES_CMAC_PRF_128 */
|
||||
#endif /* PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_AES)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_AES)
|
||||
#define PSA_HAVE_SOFT_KEY_TYPE_AES 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_AES */
|
||||
#if defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
|
||||
defined(PSA_HAVE_SOFT_BLOCK_MODE)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES 1
|
||||
#define MBEDTLS_AES_C
|
||||
#endif /* PSA_HAVE_SOFT_KEY_TYPE_AES || PSA_HAVE_SOFT_BLOCK_MODE */
|
||||
#endif /* PSA_WANT_KEY_TYPE_AES */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_ARIA)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ARIA)
|
||||
#define PSA_HAVE_SOFT_KEY_TYPE_ARIA 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ARIA */
|
||||
#if defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
|
||||
defined(PSA_HAVE_SOFT_BLOCK_MODE)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA 1
|
||||
#define MBEDTLS_ARIA_C
|
||||
#endif /* PSA_HAVE_SOFT_KEY_TYPE_ARIA || PSA_HAVE_SOFT_BLOCK_MODE */
|
||||
#endif /* PSA_WANT_KEY_TYPE_ARIA */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_CAMELLIA)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA)
|
||||
#define PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA */
|
||||
#if defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA) || \
|
||||
defined(PSA_HAVE_SOFT_BLOCK_MODE)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA 1
|
||||
#define MBEDTLS_CAMELLIA_C
|
||||
#endif /* PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA || PSA_HAVE_SOFT_BLOCK_MODE */
|
||||
#endif /* PSA_WANT_KEY_TYPE_CAMELLIA */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_DES)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DES)
|
||||
#define PSA_HAVE_SOFT_KEY_TYPE_DES 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DES */
|
||||
#if defined(PSA_HAVE_SOFT_KEY_TYPE_DES) || \
|
||||
defined(PSA_HAVE_SOFT_BLOCK_MODE)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES 1
|
||||
#define MBEDTLS_DES_C
|
||||
#endif /*PSA_HAVE_SOFT_KEY_TYPE_DES || PSA_HAVE_SOFT_BLOCK_MODE */
|
||||
#endif /* PSA_WANT_KEY_TYPE_DES */
|
||||
|
||||
#if defined(PSA_WANT_ALG_STREAM_CIPHER)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_STREAM_CIPHER)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER 1
|
||||
#endif /* MBEDTLS_PSA_ACCEL_ALG_STREAM_CIPHER */
|
||||
#endif /* PSA_WANT_ALG_STREAM_CIPHER */
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_CHACHA20)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20) || \
|
||||
defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
|
||||
#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20 1
|
||||
#define MBEDTLS_CHACHA20_C
|
||||
#endif /*!MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20 */
|
||||
#endif /* PSA_WANT_KEY_TYPE_CHACHA20 */
|
||||
|
||||
/* If any of the software block ciphers are selected, define
|
||||
* PSA_HAVE_SOFT_BLOCK_CIPHER, which can be used in any of these
|
||||
* situations. */
|
||||
#if defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_DES) || \
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA)
|
||||
#define PSA_HAVE_SOFT_BLOCK_CIPHER 1
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_CBC_MAC)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_MAC)
|
||||
#error "CBC-MAC is not yet supported via the PSA API in Mbed TLS."
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_CBC_MAC 1
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_CBC_MAC */
|
||||
#endif /* PSA_WANT_ALG_CBC_MAC */
|
||||
|
||||
#if defined(PSA_WANT_ALG_CMAC)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CMAC) || \
|
||||
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_CMAC 1
|
||||
#define MBEDTLS_CMAC_C
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_CMAC */
|
||||
#endif /* PSA_WANT_ALG_CMAC */
|
||||
|
||||
#if defined(PSA_HAVE_SOFT_PBKDF2_HMAC) || \
|
||||
defined(PSA_HAVE_SOFT_PBKDF2_CMAC)
|
||||
#define PSA_HAVE_SOFT_PBKDF2 1
|
||||
#endif /* PSA_HAVE_SOFT_PBKDF2_HMAC || PSA_HAVE_SOFT_PBKDF2_CMAC */
|
||||
|
||||
#if defined(PSA_WANT_ALG_CTR)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CTR) || \
|
||||
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_CTR 1
|
||||
#define MBEDTLS_CIPHER_MODE_CTR
|
||||
#endif
|
||||
#endif /* PSA_WANT_ALG_CTR */
|
||||
|
||||
#if defined(PSA_WANT_ALG_CFB)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CFB) || \
|
||||
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_CFB 1
|
||||
#define MBEDTLS_CIPHER_MODE_CFB
|
||||
#endif
|
||||
#endif /* PSA_WANT_ALG_CFB */
|
||||
|
||||
#if defined(PSA_WANT_ALG_OFB)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_OFB) || \
|
||||
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_OFB 1
|
||||
#define MBEDTLS_CIPHER_MODE_OFB
|
||||
#endif
|
||||
#endif /* PSA_WANT_ALG_OFB */
|
||||
|
||||
#if defined(PSA_WANT_ALG_ECB_NO_PADDING) && \
|
||||
!defined(MBEDTLS_PSA_ACCEL_ALG_ECB_NO_PADDING)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING 1
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING) || \
|
||||
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
|
||||
#define MBEDTLS_CIPHER_MODE_CBC
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING 1
|
||||
#endif
|
||||
#endif /* PSA_WANT_ALG_CBC_NO_PADDING */
|
||||
|
||||
#if defined(PSA_WANT_ALG_CBC_PKCS7)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7) || \
|
||||
defined(PSA_HAVE_SOFT_BLOCK_CIPHER)
|
||||
#define MBEDTLS_CIPHER_MODE_CBC
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 1
|
||||
#define MBEDTLS_CIPHER_PADDING_PKCS7
|
||||
#endif
|
||||
#endif /* PSA_WANT_ALG_CBC_PKCS7 */
|
||||
|
||||
#if defined(PSA_WANT_ALG_CCM)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CCM) || \
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_CCM 1
|
||||
#define MBEDTLS_CCM_C
|
||||
#endif
|
||||
#endif /* PSA_WANT_ALG_CCM */
|
||||
|
||||
#if defined(PSA_WANT_ALG_CCM_STAR_NO_TAG)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CCM_STAR_NO_TAG) || \
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG 1
|
||||
#define MBEDTLS_CCM_C
|
||||
#endif
|
||||
#endif /* PSA_WANT_ALG_CCM_STAR_NO_TAG */
|
||||
|
||||
#if defined(PSA_WANT_ALG_GCM)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_GCM) || \
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \
|
||||
defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA)
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_GCM 1
|
||||
#define MBEDTLS_GCM_C
|
||||
#endif
|
||||
#endif /* PSA_WANT_ALG_GCM */
|
||||
|
||||
#if defined(PSA_WANT_ALG_CHACHA20_POLY1305)
|
||||
#if !defined(MBEDTLS_PSA_ACCEL_ALG_CHACHA20_POLY1305)
|
||||
#if defined(PSA_WANT_KEY_TYPE_CHACHA20)
|
||||
#define MBEDTLS_CHACHAPOLY_C
|
||||
#define MBEDTLS_CHACHA20_C
|
||||
#define MBEDTLS_POLY1305_C
|
||||
#define MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 1
|
||||
#endif /* PSA_WANT_KEY_TYPE_CHACHA20 */
|
||||
#endif /* !MBEDTLS_PSA_ACCEL_ALG_CHACHA20_POLY1305 */
|
||||
#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */
|
||||
|
||||
#endif /* MBEDTLS_CONFIG_ADJUST_LEGACY_FROM_PSA_H */
|
||||
@@ -1,152 +0,0 @@
|
||||
/**
|
||||
* \file mbedtls/config_adjust_psa_superset_legacy.h
|
||||
* \brief Adjust PSA configuration: automatic enablement from legacy
|
||||
*
|
||||
* This is an internal header. Do not include it directly.
|
||||
*
|
||||
* To simplify some edge cases, we automatically enable certain cryptographic
|
||||
* mechanisms in the PSA API if they are enabled in the legacy API. The general
|
||||
* idea is that if legacy module M uses mechanism A internally, and A has
|
||||
* both a legacy and a PSA implementation, we enable A through PSA whenever
|
||||
* it's enabled through legacy. This facilitates the transition to PSA
|
||||
* implementations of A for users of M.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CONFIG_ADJUST_PSA_SUPERSET_LEGACY_H
|
||||
#define MBEDTLS_CONFIG_ADJUST_PSA_SUPERSET_LEGACY_H
|
||||
|
||||
#if !defined(TF_PSA_CRYPTO_CONFIG_FILES_READ)
|
||||
#error "Do not include mbedtls/config_adjust_*.h manually! This can lead to problems, " \
|
||||
"up to and including runtime errors such as buffer overflows. " \
|
||||
"If you're trying to fix a complaint from check_config.h, just remove " \
|
||||
"it from your configuration file: since Mbed TLS 3.0, it is included " \
|
||||
"automatically at the right point."
|
||||
#endif /* */
|
||||
|
||||
/****************************************************************/
|
||||
/* Hashes that are built in are also enabled in PSA.
|
||||
* This simplifies dependency declarations especially
|
||||
* for modules that obey MBEDTLS_USE_PSA_CRYPTO. */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(MBEDTLS_MD5_C)
|
||||
#define PSA_WANT_ALG_MD5 1
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_RIPEMD160_C)
|
||||
#define PSA_WANT_ALG_RIPEMD160 1
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA1_C)
|
||||
#define PSA_WANT_ALG_SHA_1 1
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA224_C)
|
||||
#define PSA_WANT_ALG_SHA_224 1
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
#define PSA_WANT_ALG_SHA_256 1
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA384_C)
|
||||
#define PSA_WANT_ALG_SHA_384 1
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA512_C)
|
||||
#define PSA_WANT_ALG_SHA_512 1
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA3_C)
|
||||
#define PSA_WANT_ALG_SHA3_224 1
|
||||
#define PSA_WANT_ALG_SHA3_256 1
|
||||
#define PSA_WANT_ALG_SHA3_384 1
|
||||
#define PSA_WANT_ALG_SHA3_512 1
|
||||
#endif
|
||||
|
||||
/* Ensure that the PSA's supported curves (PSA_WANT_ECC_xxx) are always a
|
||||
* superset of the builtin ones (MBEDTLS_ECP_DP_xxx). */
|
||||
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
|
||||
#if !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
|
||||
#define PSA_WANT_ECC_BRAINPOOL_P_R1_256 1
|
||||
#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_256 */
|
||||
#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
|
||||
#if !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
|
||||
#define PSA_WANT_ECC_BRAINPOOL_P_R1_384 1
|
||||
#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_384 */
|
||||
#endif /*MBEDTLS_ECP_DP_BP384R1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
|
||||
#if !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
|
||||
#define PSA_WANT_ECC_BRAINPOOL_P_R1_512 1
|
||||
#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_512 */
|
||||
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
|
||||
#if !defined(PSA_WANT_ECC_MONTGOMERY_255)
|
||||
#define PSA_WANT_ECC_MONTGOMERY_255 1
|
||||
#endif /* PSA_WANT_ECC_MONTGOMERY_255 */
|
||||
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
|
||||
#if !defined(PSA_WANT_ECC_MONTGOMERY_448)
|
||||
#define PSA_WANT_ECC_MONTGOMERY_448 1
|
||||
#endif /* PSA_WANT_ECC_MONTGOMERY_448 */
|
||||
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
|
||||
#if !defined(PSA_WANT_ECC_SECP_R1_192)
|
||||
#define PSA_WANT_ECC_SECP_R1_192 1
|
||||
#endif /* PSA_WANT_ECC_SECP_R1_192 */
|
||||
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
|
||||
#if !defined(PSA_WANT_ECC_SECP_R1_224)
|
||||
#define PSA_WANT_ECC_SECP_R1_224 1
|
||||
#endif /* PSA_WANT_ECC_SECP_R1_224 */
|
||||
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
|
||||
#if !defined(PSA_WANT_ECC_SECP_R1_256)
|
||||
#define PSA_WANT_ECC_SECP_R1_256 1
|
||||
#endif /* PSA_WANT_ECC_SECP_R1_256 */
|
||||
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
|
||||
#if !defined(PSA_WANT_ECC_SECP_R1_384)
|
||||
#define PSA_WANT_ECC_SECP_R1_384 1
|
||||
#endif /* PSA_WANT_ECC_SECP_R1_384 */
|
||||
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
|
||||
#if !defined(PSA_WANT_ECC_SECP_R1_521)
|
||||
#define PSA_WANT_ECC_SECP_R1_521 1
|
||||
#endif /* PSA_WANT_ECC_SECP_R1_521 */
|
||||
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
|
||||
#if !defined(PSA_WANT_ECC_SECP_K1_192)
|
||||
#define PSA_WANT_ECC_SECP_K1_192 1
|
||||
#endif /* PSA_WANT_ECC_SECP_K1_192 */
|
||||
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
|
||||
|
||||
/* SECP224K1 is buggy via the PSA API (https://github.com/Mbed-TLS/mbedtls/issues/3541) */
|
||||
#if 0 && defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
|
||||
#if !defined(PSA_WANT_ECC_SECP_K1_224)
|
||||
#define PSA_WANT_ECC_SECP_K1_224 1
|
||||
#endif /* PSA_WANT_ECC_SECP_K1_224 */
|
||||
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
|
||||
#if !defined(PSA_WANT_ECC_SECP_K1_256)
|
||||
#define PSA_WANT_ECC_SECP_K1_256 1
|
||||
#endif /* PSA_WANT_ECC_SECP_K1_256 */
|
||||
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
|
||||
|
||||
#endif /* MBEDTLS_CONFIG_ADJUST_PSA_SUPERSET_LEGACY_H */
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* \file mbedtls/config_adjust_test_accelerators.h
|
||||
* \brief Declare the transparent test drivers as accelerators
|
||||
*
|
||||
* This is an internal header for test purposes only. Do not include it directly.
|
||||
*
|
||||
* The purpose of this header is to keep executing as long as necessary some
|
||||
* driver-only related unit test cases when running the test_psa_crypto_drivers
|
||||
* all.sh component (namely test cases in test_suite_block_cipher and
|
||||
* test_suite_md.psa). It is expected that as the 4.x work progress these test
|
||||
* cases will not be necessary anymore and:
|
||||
* . test_psa_crypto_drivers scope is restricted to running the
|
||||
* test_suite_psa_crypto_driver_wrappers test suite: test of the dispatch to
|
||||
* drivers and fallbacks.
|
||||
* . this file can be removed.
|
||||
*
|
||||
* This header is used as part of a build containing all the built-in drivers
|
||||
* and all the transparent test drivers as wrappers around the built-in
|
||||
* drivers. All the built-in drivers and the transparent test drivers are
|
||||
* included in the build by starting from a full configuration (config.py full)
|
||||
* and defining PSA_CRYPTO_DRIVER_TEST when building
|
||||
* (make CFLAGS="-DPSA_CRYPTO_DRIVER_TEST ...").
|
||||
*
|
||||
* The purpose of this header is to declare the transparent test drivers as
|
||||
* accelerators just after infering the built-in drivers
|
||||
* (config_adjust_legacy_from_psa.h). Not before the inclusion
|
||||
* of config_adjust_legacy_from_psa.h in the build_info.h sequence of header
|
||||
* inclusions as this would remove the built-in drivers. Just after to set up
|
||||
* properly the internal macros introduced as part of the driver only work
|
||||
* (mainly if not only in config_adjust_legacy_crypto.h).
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CONFIG_ADJUST_TEST_ACCELERATORS_H
|
||||
#define MBEDTLS_CONFIG_ADJUST_TEST_ACCELERATORS_H
|
||||
|
||||
#if !defined(TF_PSA_CRYPTO_CONFIG_FILES_READ)
|
||||
#error "Do not include mbedtls/config_adjust_*.h manually! This can lead to problems, " \
|
||||
"up to and including runtime errors such as buffer overflows. " \
|
||||
"If you're trying to fix a complaint from check_config.h, just remove " \
|
||||
"it from your configuration file: since Mbed TLS 3.0, it is included " \
|
||||
"automatically at the right point."
|
||||
#endif
|
||||
|
||||
/* Declare the accelerator driver for all cryptographic mechanisms for which
|
||||
* the test driver is implemented. This is copied from psa/crypto_config.h
|
||||
* with the parts not implemented by the test driver commented out. */
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_DERIVE //no-check-names
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_PASSWORD //no-check-names
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_PASSWORD_HASH //no-check-names
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_HMAC //no-check-names
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_AES
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ARIA
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_DES
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE
|
||||
//#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_BASIC
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_IMPORT
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_EXPORT
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_GENERATE
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_RAW_DATA //no-check-names
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_BASIC
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_IMPORT
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_EXPORT
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE
|
||||
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY
|
||||
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_CCM
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_CCM_STAR_NO_TAG
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_CMAC
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_CFB
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_CHACHA20_POLY1305
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_CTR
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_ECB_NO_PADDING
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_ECDH
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_FFDH
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_ECDSA
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_JPAKE
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_GCM
|
||||
//#define MBEDTLS_PSA_ACCEL_ALG_HKDF
|
||||
//#define MBEDTLS_PSA_ACCEL_ALG_HKDF_EXTRACT
|
||||
//#define MBEDTLS_PSA_ACCEL_ALG_HKDF_EXPAND
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_HMAC
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_MD5
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_OFB
|
||||
//#define MBEDTLS_PSA_ACCEL_ALG_PBKDF2_HMAC
|
||||
//#define MBEDTLS_PSA_ACCEL_ALG_PBKDF2_AES_CMAC_PRF_128
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_RIPEMD160
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_RSA_PSS
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_SHA_1
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_SHA_224
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_SHA_256
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_SHA_384
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_SHA_512
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_SHA3_224
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_SHA3_256
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_SHA3_384
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_SHA3_512
|
||||
#define MBEDTLS_PSA_ACCEL_ALG_STREAM_CIPHER
|
||||
//#define MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF
|
||||
//#define MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS
|
||||
//#define MBEDTLS_PSA_ACCEL_ALG_TLS12_ECJPAKE_TO_PMS
|
||||
|
||||
#endif /* MBEDTLS_CONFIG_ADJUST_TEST_ACCELERATORS_H */
|
||||
@@ -1,48 +0,0 @@
|
||||
/**
|
||||
* \file mbedtls/config_psa.h
|
||||
* \brief PSA crypto configuration options (set of defines)
|
||||
*
|
||||
* This set of compile-time options takes settings defined in
|
||||
* include/mbedtls/mbedtls_config.h and include/psa/crypto_config.h and uses
|
||||
* those definitions to define symbols used in the library code.
|
||||
*
|
||||
* Users and integrators should not edit this file, please edit
|
||||
* include/mbedtls/mbedtls_config.h for MBEDTLS_XXX settings or
|
||||
* include/psa/crypto_config.h for PSA_WANT_XXX settings.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CONFIG_PSA_H
|
||||
#define MBEDTLS_CONFIG_PSA_H
|
||||
|
||||
#include "psa/crypto_legacy.h"
|
||||
|
||||
#include "psa/crypto_adjust_config_synonyms.h"
|
||||
|
||||
#include "psa/crypto_adjust_config_dependencies.h"
|
||||
|
||||
#include "mbedtls/config_adjust_psa_superset_legacy.h"
|
||||
|
||||
/* Require built-in implementations based on PSA requirements */
|
||||
|
||||
/* We need this to have a complete list of requirements
|
||||
* before we deduce what built-ins are required. */
|
||||
#include "psa/crypto_adjust_config_key_pair_types.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
/* If we are implementing PSA crypto ourselves, then we want to enable the
|
||||
* required built-ins. Otherwise, PSA features will be provided by the server. */
|
||||
#include "mbedtls/config_adjust_legacy_from_psa.h"
|
||||
#if defined(MBEDTLS_CONFIG_ADJUST_TEST_ACCELERATORS) //no-check-names
|
||||
#include "mbedtls/config_adjust_test_accelerators.h"
|
||||
#endif
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
#include "psa/crypto_adjust_config_derived.h"
|
||||
|
||||
#include "psa/crypto_adjust_auto_enabled.h"
|
||||
|
||||
#endif /* MBEDTLS_CONFIG_PSA_H */
|
||||
@@ -1,36 +0,0 @@
|
||||
/**
|
||||
* Constant-time functions
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CONSTANT_TIME_H
|
||||
#define MBEDTLS_CONSTANT_TIME_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/** Constant-time buffer comparison without branches.
|
||||
*
|
||||
* This is equivalent to the standard memcmp function, but is likely to be
|
||||
* compiled to code using bitwise operations rather than a branch, such that
|
||||
* the time taken is constant w.r.t. the data pointed to by \p a and \p b,
|
||||
* and w.r.t. whether \p a and \p b are equal or not. It is not constant-time
|
||||
* w.r.t. \p n .
|
||||
*
|
||||
* This function can be used to write constant-time code by replacing branches
|
||||
* with bit operations using masks.
|
||||
*
|
||||
* \param a Pointer to the first buffer, containing at least \p n bytes. May not be NULL.
|
||||
* \param b Pointer to the second buffer, containing at least \p n bytes. May not be NULL.
|
||||
* \param n The number of bytes to compare.
|
||||
*
|
||||
* \return Zero if the contents of the two buffers are the same,
|
||||
* otherwise non-zero.
|
||||
*/
|
||||
int mbedtls_ct_memcmp(const void *a,
|
||||
const void *b,
|
||||
size_t n);
|
||||
|
||||
#endif /* MBEDTLS_CONSTANT_TIME_H */
|
||||
@@ -1,597 +0,0 @@
|
||||
/**
|
||||
* \file ctr_drbg.h
|
||||
*
|
||||
* \brief This file contains definitions and functions for the
|
||||
* CTR_DRBG pseudorandom generator.
|
||||
*
|
||||
* CTR_DRBG is a standardized way of building a PRNG from a block-cipher
|
||||
* in counter mode operation, as defined in <em>NIST SP 800-90A:
|
||||
* Recommendation for Random Number Generation Using Deterministic Random
|
||||
* Bit Generators</em>.
|
||||
*
|
||||
* The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128
|
||||
* (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time)
|
||||
* as the underlying block cipher, with a derivation function.
|
||||
*
|
||||
* The security strength as defined in NIST SP 800-90A is
|
||||
* 128 bits when AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled)
|
||||
* and 256 bits otherwise, provided that #MBEDTLS_CTR_DRBG_ENTROPY_LEN is
|
||||
* kept at its default value (and not overridden in mbedtls_config.h) and that the
|
||||
* DRBG instance is set up with default parameters.
|
||||
* See the documentation of mbedtls_ctr_drbg_seed() for more
|
||||
* information.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CTR_DRBG_H
|
||||
#define MBEDTLS_CTR_DRBG_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
/* The CTR_DRBG implementation can either directly call the low-level AES
|
||||
* module (gated by MBEDTLS_AES_C) or call the PSA API to perform AES
|
||||
* operations. Calling the AES module directly is the default, both for
|
||||
* maximum backward compatibility and because it's a bit more efficient
|
||||
* (less glue code).
|
||||
*
|
||||
* When MBEDTLS_AES_C is disabled, the CTR_DRBG module calls PSA crypto and
|
||||
* thus benefits from the PSA AES accelerator driver.
|
||||
* It is technically possible to enable MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO
|
||||
* to use PSA even when MBEDTLS_AES_C is enabled, but there is very little
|
||||
* reason to do so other than testing purposes and this is not officially
|
||||
* supported.
|
||||
*/
|
||||
#if !defined(MBEDTLS_AES_C)
|
||||
#define MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
#include "psa/crypto.h"
|
||||
#else
|
||||
#include "mbedtls/aes.h"
|
||||
#endif
|
||||
|
||||
#include "entropy.h"
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
#include "mbedtls/threading.h"
|
||||
#endif
|
||||
|
||||
/** The entropy source failed. */
|
||||
#define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034
|
||||
/** The requested random buffer length is too big. */
|
||||
#define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036
|
||||
/** The input (entropy + additional data) is too large. */
|
||||
#define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038
|
||||
/** Read or write error in file. */
|
||||
#define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A
|
||||
|
||||
#define MBEDTLS_CTR_DRBG_BLOCKSIZE 16 /**< The block size used by the cipher. */
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
|
||||
#define MBEDTLS_CTR_DRBG_KEYSIZE 16
|
||||
/**< The key size in bytes used by the cipher.
|
||||
*
|
||||
* Compile-time choice: 16 bytes (128 bits)
|
||||
* because #MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled.
|
||||
*/
|
||||
#else
|
||||
#define MBEDTLS_CTR_DRBG_KEYSIZE 32
|
||||
/**< The key size in bytes used by the cipher.
|
||||
*
|
||||
* Compile-time choice: 32 bytes (256 bits)
|
||||
* because \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled.
|
||||
*/
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_CTR_DRBG_KEYBITS (MBEDTLS_CTR_DRBG_KEYSIZE * 8) /**< The key size for the DRBG operation, in bits. */
|
||||
#define MBEDTLS_CTR_DRBG_SEEDLEN (MBEDTLS_CTR_DRBG_KEYSIZE + MBEDTLS_CTR_DRBG_BLOCKSIZE) /**< The seed length, calculated as (counter + AES key). */
|
||||
|
||||
/**
|
||||
* \name SECTION: Module settings
|
||||
*
|
||||
* The configuration options you can set for this module are in this section.
|
||||
* Either change them in mbedtls_config.h or define them using the compiler command
|
||||
* line.
|
||||
* \{
|
||||
*/
|
||||
|
||||
/** \def MBEDTLS_CTR_DRBG_ENTROPY_LEN
|
||||
*
|
||||
* \brief The amount of entropy used per seed by default, in bytes.
|
||||
*/
|
||||
#if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN)
|
||||
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
|
||||
/** This is 48 bytes because the entropy module uses SHA-512.
|
||||
*/
|
||||
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48
|
||||
|
||||
#else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
|
||||
|
||||
/** This is 32 bytes because the entropy module uses SHA-256.
|
||||
*/
|
||||
#if !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
|
||||
/** \warning To achieve a 256-bit security strength, you must pass a nonce
|
||||
* to mbedtls_ctr_drbg_seed().
|
||||
*/
|
||||
#endif /* !defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY) */
|
||||
#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 32
|
||||
#endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
|
||||
#endif /* !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) */
|
||||
|
||||
#if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL)
|
||||
#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000
|
||||
/**< The interval before reseed is performed by default. */
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_CTR_DRBG_MAX_INPUT)
|
||||
#define MBEDTLS_CTR_DRBG_MAX_INPUT 256
|
||||
/**< The maximum number of additional input Bytes. */
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_CTR_DRBG_MAX_REQUEST)
|
||||
#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024
|
||||
/**< The maximum number of requested Bytes per call. */
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT)
|
||||
#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384
|
||||
/**< The maximum size of seed or reseed buffer in bytes. */
|
||||
#endif
|
||||
|
||||
/** \} name SECTION: Module settings */
|
||||
|
||||
#define MBEDTLS_CTR_DRBG_PR_OFF 0
|
||||
/**< Prediction resistance is disabled. */
|
||||
#define MBEDTLS_CTR_DRBG_PR_ON 1
|
||||
/**< Prediction resistance is enabled. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if MBEDTLS_CTR_DRBG_ENTROPY_LEN >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
|
||||
/** The default length of the nonce read from the entropy source.
|
||||
*
|
||||
* This is \c 0 because a single read from the entropy source is sufficient
|
||||
* to include a nonce.
|
||||
* See the documentation of mbedtls_ctr_drbg_seed() for more information.
|
||||
*/
|
||||
#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN 0
|
||||
#else
|
||||
/** The default length of the nonce read from the entropy source.
|
||||
*
|
||||
* This is half of the default entropy length because a single read from
|
||||
* the entropy source does not provide enough material to form a nonce.
|
||||
* See the documentation of mbedtls_ctr_drbg_seed() for more information.
|
||||
*/
|
||||
#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN (MBEDTLS_CTR_DRBG_ENTROPY_LEN + 1) / 2
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
typedef struct mbedtls_ctr_drbg_psa_context {
|
||||
mbedtls_svc_key_id_t key_id;
|
||||
psa_cipher_operation_t operation;
|
||||
} mbedtls_ctr_drbg_psa_context;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The CTR_DRBG context structure.
|
||||
*/
|
||||
typedef struct mbedtls_ctr_drbg_context {
|
||||
unsigned char MBEDTLS_PRIVATE(counter)[16]; /*!< The counter (V). */
|
||||
int MBEDTLS_PRIVATE(reseed_counter); /*!< The reseed counter.
|
||||
* This is the number of requests that have
|
||||
* been made since the last (re)seeding,
|
||||
* minus one.
|
||||
* Before the initial seeding, this field
|
||||
* contains the amount of entropy in bytes
|
||||
* to use as a nonce for the initial seeding,
|
||||
* or -1 if no nonce length has been explicitly
|
||||
* set (see mbedtls_ctr_drbg_set_nonce_len()).
|
||||
*/
|
||||
int MBEDTLS_PRIVATE(prediction_resistance); /*!< This determines whether prediction
|
||||
resistance is enabled, that is
|
||||
whether to systematically reseed before
|
||||
each random generation. */
|
||||
size_t MBEDTLS_PRIVATE(entropy_len); /*!< The amount of entropy grabbed on each
|
||||
seed or reseed operation, in bytes. */
|
||||
int MBEDTLS_PRIVATE(reseed_interval); /*!< The reseed interval.
|
||||
* This is the maximum number of requests
|
||||
* that can be made between reseedings. */
|
||||
|
||||
#if defined(MBEDTLS_CTR_DRBG_USE_PSA_CRYPTO)
|
||||
mbedtls_ctr_drbg_psa_context MBEDTLS_PRIVATE(psa_ctx); /*!< The PSA context. */
|
||||
#else
|
||||
mbedtls_aes_context MBEDTLS_PRIVATE(aes_ctx); /*!< The AES context. */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Callbacks (Entropy)
|
||||
*/
|
||||
int(*MBEDTLS_PRIVATE(f_entropy))(void *, unsigned char *, size_t);
|
||||
/*!< The entropy callback function. */
|
||||
|
||||
void *MBEDTLS_PRIVATE(p_entropy); /*!< The context for the entropy function. */
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* Invariant: the mutex is initialized if and only if f_entropy != NULL.
|
||||
* This means that the mutex is initialized during the initial seeding
|
||||
* in mbedtls_ctr_drbg_seed() and freed in mbedtls_ctr_drbg_free().
|
||||
*
|
||||
* Note that this invariant may change without notice. Do not rely on it
|
||||
* and do not access the mutex directly in application code.
|
||||
*/
|
||||
mbedtls_threading_mutex_t MBEDTLS_PRIVATE(mutex);
|
||||
#endif
|
||||
}
|
||||
mbedtls_ctr_drbg_context;
|
||||
|
||||
/**
|
||||
* \brief This function initializes the CTR_DRBG context,
|
||||
* and prepares it for mbedtls_ctr_drbg_seed()
|
||||
* or mbedtls_ctr_drbg_free().
|
||||
*
|
||||
* \note The reseed interval is
|
||||
* #MBEDTLS_CTR_DRBG_RESEED_INTERVAL by default.
|
||||
* You can override it by calling
|
||||
* mbedtls_ctr_drbg_set_reseed_interval().
|
||||
*
|
||||
* \param ctx The CTR_DRBG context to initialize.
|
||||
*/
|
||||
void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function seeds and sets up the CTR_DRBG
|
||||
* entropy source for future reseeds.
|
||||
*
|
||||
* A typical choice for the \p f_entropy and \p p_entropy parameters is
|
||||
* to use the entropy module:
|
||||
* - \p f_entropy is mbedtls_entropy_func();
|
||||
* - \p p_entropy is an instance of ::mbedtls_entropy_context initialized
|
||||
* with mbedtls_entropy_init() (which registers the platform's default
|
||||
* entropy sources).
|
||||
*
|
||||
* The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default.
|
||||
* You can override it by calling mbedtls_ctr_drbg_set_entropy_len().
|
||||
*
|
||||
* The entropy nonce length is:
|
||||
* - \c 0 if the entropy length is at least 3/2 times the entropy length,
|
||||
* which guarantees that the security strength is the maximum permitted
|
||||
* by the key size and entropy length according to NIST SP 800-90A §10.2.1;
|
||||
* - Half the entropy length otherwise.
|
||||
* You can override it by calling mbedtls_ctr_drbg_set_nonce_len().
|
||||
* With the default entropy length, the entropy nonce length is
|
||||
* #MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN.
|
||||
*
|
||||
* You can provide a nonce and personalization string in addition to the
|
||||
* entropy source, to make this instantiation as unique as possible.
|
||||
* See SP 800-90A §8.6.7 for more details about nonces.
|
||||
*
|
||||
* The _seed_material_ value passed to the derivation function in
|
||||
* the CTR_DRBG Instantiate Process described in NIST SP 800-90A §10.2.1.3.2
|
||||
* is the concatenation of the following strings:
|
||||
* - A string obtained by calling \p f_entropy function for the entropy
|
||||
* length.
|
||||
*/
|
||||
#if MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN == 0
|
||||
/**
|
||||
* - If mbedtls_ctr_drbg_set_nonce_len() has been called, a string
|
||||
* obtained by calling \p f_entropy function for the specified length.
|
||||
*/
|
||||
#else
|
||||
/**
|
||||
* - A string obtained by calling \p f_entropy function for the entropy nonce
|
||||
* length. If the entropy nonce length is \c 0, this function does not
|
||||
* make a second call to \p f_entropy.
|
||||
*/
|
||||
#endif
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/**
|
||||
* \note When Mbed TLS is built with threading support,
|
||||
* after this function returns successfully,
|
||||
* it is safe to call mbedtls_ctr_drbg_random()
|
||||
* from multiple threads. Other operations, including
|
||||
* reseeding, are not thread-safe.
|
||||
*/
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
/**
|
||||
* - The \p custom string.
|
||||
*
|
||||
* \note To achieve the nominal security strength permitted
|
||||
* by CTR_DRBG, the entropy length must be:
|
||||
* - at least 16 bytes for a 128-bit strength
|
||||
* (maximum achievable strength when using AES-128);
|
||||
* - at least 32 bytes for a 256-bit strength
|
||||
* (maximum achievable strength when using AES-256).
|
||||
*
|
||||
* In addition, if you do not pass a nonce in \p custom,
|
||||
* the sum of the entropy length
|
||||
* and the entropy nonce length must be:
|
||||
* - at least 24 bytes for a 128-bit strength
|
||||
* (maximum achievable strength when using AES-128);
|
||||
* - at least 48 bytes for a 256-bit strength
|
||||
* (maximum achievable strength when using AES-256).
|
||||
*
|
||||
* \param ctx The CTR_DRBG context to seed.
|
||||
* It must have been initialized with
|
||||
* mbedtls_ctr_drbg_init().
|
||||
* After a successful call to mbedtls_ctr_drbg_seed(),
|
||||
* you may not call mbedtls_ctr_drbg_seed() again on
|
||||
* the same context unless you call
|
||||
* mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init()
|
||||
* again first.
|
||||
* After a failed call to mbedtls_ctr_drbg_seed(),
|
||||
* you must call mbedtls_ctr_drbg_free().
|
||||
* \param f_entropy The entropy callback, taking as arguments the
|
||||
* \p p_entropy context, the buffer to fill, and the
|
||||
* length of the buffer.
|
||||
* \p f_entropy is always called with a buffer size
|
||||
* less than or equal to the entropy length.
|
||||
* \param p_entropy The entropy context to pass to \p f_entropy.
|
||||
* \param custom The personalization string.
|
||||
* This can be \c NULL, in which case the personalization
|
||||
* string is empty regardless of the value of \p len.
|
||||
* \param len The length of the personalization string.
|
||||
* This must be at most
|
||||
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
|
||||
* - #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
|
||||
*/
|
||||
int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx,
|
||||
int (*f_entropy)(void *, unsigned char *, size_t),
|
||||
void *p_entropy,
|
||||
const unsigned char *custom,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* \brief This function resets CTR_DRBG context to the state immediately
|
||||
* after initial call of mbedtls_ctr_drbg_init().
|
||||
*
|
||||
* \param ctx The CTR_DRBG context to clear.
|
||||
*/
|
||||
void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function turns prediction resistance on or off.
|
||||
* The default value is off.
|
||||
*
|
||||
* \note If enabled, entropy is gathered at the beginning of
|
||||
* every call to mbedtls_ctr_drbg_random_with_add()
|
||||
* or mbedtls_ctr_drbg_random().
|
||||
* Only use this if your entropy source has sufficient
|
||||
* throughput.
|
||||
*
|
||||
* \param ctx The CTR_DRBG context.
|
||||
* \param resistance #MBEDTLS_CTR_DRBG_PR_ON or #MBEDTLS_CTR_DRBG_PR_OFF.
|
||||
*/
|
||||
void mbedtls_ctr_drbg_set_prediction_resistance(mbedtls_ctr_drbg_context *ctx,
|
||||
int resistance);
|
||||
|
||||
/**
|
||||
* \brief This function sets the amount of entropy grabbed on each
|
||||
* seed or reseed.
|
||||
*
|
||||
* The default value is #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
|
||||
*
|
||||
* \note The security strength of CTR_DRBG is bounded by the
|
||||
* entropy length. Thus:
|
||||
* - When using AES-256
|
||||
* (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is disabled,
|
||||
* which is the default),
|
||||
* \p len must be at least 32 (in bytes)
|
||||
* to achieve a 256-bit strength.
|
||||
* - When using AES-128
|
||||
* (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled)
|
||||
* \p len must be at least 16 (in bytes)
|
||||
* to achieve a 128-bit strength.
|
||||
*
|
||||
* \param ctx The CTR_DRBG context.
|
||||
* \param len The amount of entropy to grab, in bytes.
|
||||
* This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
|
||||
* and at most the maximum length accepted by the
|
||||
* entropy function that is set in the context.
|
||||
*/
|
||||
void mbedtls_ctr_drbg_set_entropy_len(mbedtls_ctr_drbg_context *ctx,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* \brief This function sets the amount of entropy grabbed
|
||||
* as a nonce for the initial seeding.
|
||||
*
|
||||
* Call this function before calling mbedtls_ctr_drbg_seed() to read
|
||||
* a nonce from the entropy source during the initial seeding.
|
||||
*
|
||||
* \param ctx The CTR_DRBG context.
|
||||
* \param len The amount of entropy to grab for the nonce, in bytes.
|
||||
* This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
|
||||
* and at most the maximum length accepted by the
|
||||
* entropy function that is set in the context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if \p len is
|
||||
* more than #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
|
||||
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
|
||||
* if the initial seeding has already taken place.
|
||||
*/
|
||||
int mbedtls_ctr_drbg_set_nonce_len(mbedtls_ctr_drbg_context *ctx,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* \brief This function sets the reseed interval.
|
||||
*
|
||||
* The reseed interval is the number of calls to mbedtls_ctr_drbg_random()
|
||||
* or mbedtls_ctr_drbg_random_with_add() after which the entropy function
|
||||
* is called again.
|
||||
*
|
||||
* The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL.
|
||||
*
|
||||
* \param ctx The CTR_DRBG context.
|
||||
* \param interval The reseed interval.
|
||||
*/
|
||||
void mbedtls_ctr_drbg_set_reseed_interval(mbedtls_ctr_drbg_context *ctx,
|
||||
int interval);
|
||||
|
||||
/**
|
||||
* \brief This function reseeds the CTR_DRBG context, that is
|
||||
* extracts data from the entropy source.
|
||||
*
|
||||
* \note This function is not thread-safe. It is not safe
|
||||
* to call this function if another thread might be
|
||||
* concurrently obtaining random numbers from the same
|
||||
* context or updating or reseeding the same context.
|
||||
*
|
||||
* \param ctx The CTR_DRBG context.
|
||||
* \param additional Additional data to add to the state. Can be \c NULL.
|
||||
* \param len The length of the additional data.
|
||||
* This must be less than
|
||||
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len
|
||||
* where \c entropy_len is the entropy length
|
||||
* configured for the context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
|
||||
*/
|
||||
int mbedtls_ctr_drbg_reseed(mbedtls_ctr_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t len);
|
||||
|
||||
/**
|
||||
* \brief This function updates the state of the CTR_DRBG context.
|
||||
*
|
||||
* \note This function is not thread-safe. It is not safe
|
||||
* to call this function if another thread might be
|
||||
* concurrently obtaining random numbers from the same
|
||||
* context or updating or reseeding the same context.
|
||||
*
|
||||
* \param ctx The CTR_DRBG context.
|
||||
* \param additional The data to update the state with. This must not be
|
||||
* \c NULL unless \p add_len is \c 0.
|
||||
* \param add_len Length of \p additional in bytes. This must be at
|
||||
* most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if
|
||||
* \p add_len is more than
|
||||
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
|
||||
* \return An error from the underlying AES cipher on failure.
|
||||
*/
|
||||
int mbedtls_ctr_drbg_update(mbedtls_ctr_drbg_context *ctx,
|
||||
const unsigned char *additional,
|
||||
size_t add_len);
|
||||
|
||||
/**
|
||||
* \brief This function updates a CTR_DRBG instance with additional
|
||||
* data and uses it to generate random data.
|
||||
*
|
||||
* This function automatically reseeds if the reseed counter is exceeded
|
||||
* or prediction resistance is enabled.
|
||||
*
|
||||
* \note This function is not thread-safe. It is not safe
|
||||
* to call this function if another thread might be
|
||||
* concurrently obtaining random numbers from the same
|
||||
* context or updating or reseeding the same context.
|
||||
*
|
||||
* \param p_rng The CTR_DRBG context. This must be a pointer to a
|
||||
* #mbedtls_ctr_drbg_context structure.
|
||||
* \param output The buffer to fill.
|
||||
* \param output_len The length of the buffer in bytes.
|
||||
* \param additional Additional data to update. Can be \c NULL, in which
|
||||
* case the additional data is empty regardless of
|
||||
* the value of \p add_len.
|
||||
* \param add_len The length of the additional data
|
||||
* if \p additional is not \c NULL.
|
||||
* This must be less than #MBEDTLS_CTR_DRBG_MAX_INPUT
|
||||
* and less than
|
||||
* #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - \c entropy_len
|
||||
* where \c entropy_len is the entropy length
|
||||
* configured for the context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
|
||||
* #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
|
||||
*/
|
||||
int mbedtls_ctr_drbg_random_with_add(void *p_rng,
|
||||
unsigned char *output, size_t output_len,
|
||||
const unsigned char *additional, size_t add_len);
|
||||
|
||||
/**
|
||||
* \brief This function uses CTR_DRBG to generate random data.
|
||||
*
|
||||
* This function automatically reseeds if the reseed counter is exceeded
|
||||
* or prediction resistance is enabled.
|
||||
*/
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/**
|
||||
* \note When Mbed TLS is built with threading support,
|
||||
* it is safe to call mbedtls_ctr_drbg_random()
|
||||
* from multiple threads. Other operations, including
|
||||
* reseeding, are not thread-safe.
|
||||
*/
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
/**
|
||||
* \param p_rng The CTR_DRBG context. This must be a pointer to a
|
||||
* #mbedtls_ctr_drbg_context structure.
|
||||
* \param output The buffer to fill.
|
||||
* \param output_len The length of the buffer in bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
|
||||
* #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
|
||||
*/
|
||||
int mbedtls_ctr_drbg_random(void *p_rng,
|
||||
unsigned char *output, size_t output_len);
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
/**
|
||||
* \brief This function writes a seed file.
|
||||
*
|
||||
* \param ctx The CTR_DRBG context.
|
||||
* \param path The name of the file.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
|
||||
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on reseed
|
||||
* failure.
|
||||
*/
|
||||
int mbedtls_ctr_drbg_write_seed_file(mbedtls_ctr_drbg_context *ctx, const char *path);
|
||||
|
||||
/**
|
||||
* \brief This function reads and updates a seed file. The seed
|
||||
* is added to this instance.
|
||||
*
|
||||
* \param ctx The CTR_DRBG context.
|
||||
* \param path The name of the file.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
|
||||
* \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on
|
||||
* reseed failure.
|
||||
* \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if the existing
|
||||
* seed file is too large.
|
||||
*/
|
||||
int mbedtls_ctr_drbg_update_seed_file(mbedtls_ctr_drbg_context *ctx, const char *path);
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
/**
|
||||
* \brief The CTR_DRBG checkup routine.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c 1 on failure.
|
||||
*/
|
||||
int mbedtls_ctr_drbg_self_test(int verbose);
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ctr_drbg.h */
|
||||
@@ -1,363 +0,0 @@
|
||||
/**
|
||||
* \file des.h
|
||||
*
|
||||
* \brief DES block cipher
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*
|
||||
*/
|
||||
#ifndef MBEDTLS_DES_H
|
||||
#define MBEDTLS_DES_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MBEDTLS_DES_ENCRYPT 1
|
||||
#define MBEDTLS_DES_DECRYPT 0
|
||||
|
||||
/** The data input has an invalid length. */
|
||||
#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -0x0032
|
||||
|
||||
#define MBEDTLS_DES_KEY_SIZE 8
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief DES context structure
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
typedef struct mbedtls_des_context {
|
||||
uint32_t MBEDTLS_PRIVATE(sk)[32]; /*!< DES subkeys */
|
||||
}
|
||||
mbedtls_des_context;
|
||||
|
||||
/**
|
||||
* \brief Triple-DES context structure
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
typedef struct mbedtls_des3_context {
|
||||
uint32_t MBEDTLS_PRIVATE(sk)[96]; /*!< 3DES subkeys */
|
||||
}
|
||||
mbedtls_des3_context;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Initialize DES context
|
||||
*
|
||||
* \param ctx DES context to be initialized
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
void mbedtls_des_init(mbedtls_des_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Clear DES context
|
||||
*
|
||||
* \param ctx DES context to be cleared
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
void mbedtls_des_free(mbedtls_des_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Initialize Triple-DES context
|
||||
*
|
||||
* \param ctx DES3 context to be initialized
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
void mbedtls_des3_init(mbedtls_des3_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Clear Triple-DES context
|
||||
*
|
||||
* \param ctx DES3 context to be cleared
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
void mbedtls_des3_free(mbedtls_des3_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Set key parity on the given key to odd.
|
||||
*
|
||||
* DES keys are 56 bits long, but each byte is padded with
|
||||
* a parity bit to allow verification.
|
||||
*
|
||||
* \param key 8-byte secret key
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
void mbedtls_des_key_set_parity(unsigned char key[MBEDTLS_DES_KEY_SIZE]);
|
||||
|
||||
/**
|
||||
* \brief Check that key parity on the given key is odd.
|
||||
*
|
||||
* DES keys are 56 bits long, but each byte is padded with
|
||||
* a parity bit to allow verification.
|
||||
*
|
||||
* \param key 8-byte secret key
|
||||
*
|
||||
* \return 0 is parity was ok, 1 if parity was not correct.
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_des_key_check_key_parity(const unsigned char key[MBEDTLS_DES_KEY_SIZE]);
|
||||
|
||||
/**
|
||||
* \brief Check that key is not a weak or semi-weak DES key
|
||||
*
|
||||
* \param key 8-byte secret key
|
||||
*
|
||||
* \return 0 if no weak key was found, 1 if a weak key was identified.
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_des_key_check_weak(const unsigned char key[MBEDTLS_DES_KEY_SIZE]);
|
||||
|
||||
/**
|
||||
* \brief DES key schedule (56-bit, encryption)
|
||||
*
|
||||
* \param ctx DES context to be initialized
|
||||
* \param key 8-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_des_setkey_enc(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]);
|
||||
|
||||
/**
|
||||
* \brief DES key schedule (56-bit, decryption)
|
||||
*
|
||||
* \param ctx DES context to be initialized
|
||||
* \param key 8-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_des_setkey_dec(mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE]);
|
||||
|
||||
/**
|
||||
* \brief Triple-DES key schedule (112-bit, encryption)
|
||||
*
|
||||
* \param ctx 3DES context to be initialized
|
||||
* \param key 16-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_des3_set2key_enc(mbedtls_des3_context *ctx,
|
||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2]);
|
||||
|
||||
/**
|
||||
* \brief Triple-DES key schedule (112-bit, decryption)
|
||||
*
|
||||
* \param ctx 3DES context to be initialized
|
||||
* \param key 16-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_des3_set2key_dec(mbedtls_des3_context *ctx,
|
||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2]);
|
||||
|
||||
/**
|
||||
* \brief Triple-DES key schedule (168-bit, encryption)
|
||||
*
|
||||
* \param ctx 3DES context to be initialized
|
||||
* \param key 24-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_des3_set3key_enc(mbedtls_des3_context *ctx,
|
||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]);
|
||||
|
||||
/**
|
||||
* \brief Triple-DES key schedule (168-bit, decryption)
|
||||
*
|
||||
* \param ctx 3DES context to be initialized
|
||||
* \param key 24-byte secret key
|
||||
*
|
||||
* \return 0
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_des3_set3key_dec(mbedtls_des3_context *ctx,
|
||||
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3]);
|
||||
|
||||
/**
|
||||
* \brief DES-ECB block encryption/decryption
|
||||
*
|
||||
* \param ctx DES context
|
||||
* \param input 64-bit input block
|
||||
* \param output 64-bit output block
|
||||
*
|
||||
* \return 0 if successful
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_des_crypt_ecb(mbedtls_des_context *ctx,
|
||||
const unsigned char input[8],
|
||||
unsigned char output[8]);
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
/**
|
||||
* \brief DES-CBC buffer encryption/decryption
|
||||
*
|
||||
* \note Upon exit, the content of the IV is updated so that you can
|
||||
* call the function same function again on the following
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If on the other hand you need to retain the contents of the
|
||||
* IV, you should either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
* \param ctx DES context
|
||||
* \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_des_crypt_cbc(mbedtls_des_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[8],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||
|
||||
/**
|
||||
* \brief 3DES-ECB block encryption/decryption
|
||||
*
|
||||
* \param ctx 3DES context
|
||||
* \param input 64-bit input block
|
||||
* \param output 64-bit output block
|
||||
*
|
||||
* \return 0 if successful
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_des3_crypt_ecb(mbedtls_des3_context *ctx,
|
||||
const unsigned char input[8],
|
||||
unsigned char output[8]);
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
/**
|
||||
* \brief 3DES-CBC buffer encryption/decryption
|
||||
*
|
||||
* \note Upon exit, the content of the IV is updated so that you can
|
||||
* call the function same function again on the following
|
||||
* block(s) of data and get the same result as if it was
|
||||
* encrypted in one call. This allows a "streaming" usage.
|
||||
* If on the other hand you need to retain the contents of the
|
||||
* IV, you should either save it manually or use the cipher
|
||||
* module instead.
|
||||
*
|
||||
* \param ctx 3DES context
|
||||
* \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH
|
||||
*
|
||||
* \warning DES/3DES are considered weak ciphers and their use constitutes a
|
||||
* security risk. We recommend considering stronger ciphers
|
||||
* instead.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_des3_crypt_cbc(mbedtls_des3_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[8],
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_CIPHER_MODE_CBC */
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_CRITICAL
|
||||
int mbedtls_des_self_test(int verbose);
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* des.h */
|
||||
@@ -1,966 +0,0 @@
|
||||
/**
|
||||
* \file dhm.h
|
||||
*
|
||||
* \brief This file contains Diffie-Hellman-Merkle (DHM) key exchange
|
||||
* definitions and functions.
|
||||
*
|
||||
* Diffie-Hellman-Merkle (DHM) key exchange is defined in
|
||||
* <em>RFC-2631: Diffie-Hellman Key Agreement Method</em> and
|
||||
* <em>Public-Key Cryptography Standards (PKCS) #3: Diffie
|
||||
* Hellman Key Agreement Standard</em>.
|
||||
*
|
||||
* <em>RFC-3526: More Modular Exponential (MODP) Diffie-Hellman groups for
|
||||
* Internet Key Exchange (IKE)</em> defines a number of standardized
|
||||
* Diffie-Hellman groups for IKE.
|
||||
*
|
||||
* <em>RFC-5114: Additional Diffie-Hellman Groups for Use with IETF
|
||||
* Standards</em> defines a number of standardized Diffie-Hellman
|
||||
* groups that can be used.
|
||||
*
|
||||
* \warning The security of the DHM key exchange relies on the proper choice
|
||||
* of prime modulus - optimally, it should be a safe prime. The usage
|
||||
* of non-safe primes both decreases the difficulty of the underlying
|
||||
* discrete logarithm problem and can lead to small subgroup attacks
|
||||
* leaking private exponent bits when invalid public keys are used
|
||||
* and not detected. This is especially relevant if the same DHM
|
||||
* parameters are reused for multiple key exchanges as in static DHM,
|
||||
* while the criticality of small-subgroup attacks is lower for
|
||||
* ephemeral DHM.
|
||||
*
|
||||
* \warning For performance reasons, the code does neither perform primality
|
||||
* nor safe primality tests, nor the expensive checks for invalid
|
||||
* subgroups. Moreover, even if these were performed, non-standardized
|
||||
* primes cannot be trusted because of the possibility of backdoors
|
||||
* that can't be effectively checked for.
|
||||
*
|
||||
* \warning Diffie-Hellman-Merkle is therefore a security risk when not using
|
||||
* standardized primes generated using a trustworthy ("nothing up
|
||||
* my sleeve") method, such as the RFC 3526 / 7919 primes. In the TLS
|
||||
* protocol, DH parameters need to be negotiated, so using the default
|
||||
* primes systematically is not always an option. If possible, use
|
||||
* Elliptic Curve Diffie-Hellman (ECDH), which has better performance,
|
||||
* and for which the TLS protocol mandates the use of standard
|
||||
* parameters.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_DHM_H
|
||||
#define MBEDTLS_DHM_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
#include "mbedtls/bignum.h"
|
||||
|
||||
/*
|
||||
* DHM Error codes
|
||||
*/
|
||||
/** Bad input parameters. */
|
||||
#define MBEDTLS_ERR_DHM_BAD_INPUT_DATA -0x3080
|
||||
/** Reading of the DHM parameters failed. */
|
||||
#define MBEDTLS_ERR_DHM_READ_PARAMS_FAILED -0x3100
|
||||
/** Making of the DHM parameters failed. */
|
||||
#define MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED -0x3180
|
||||
/** Reading of the public values failed. */
|
||||
#define MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED -0x3200
|
||||
/** Making of the public value failed. */
|
||||
#define MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED -0x3280
|
||||
/** Calculation of the DHM secret failed. */
|
||||
#define MBEDTLS_ERR_DHM_CALC_SECRET_FAILED -0x3300
|
||||
/** The ASN.1 data is not formatted correctly. */
|
||||
#define MBEDTLS_ERR_DHM_INVALID_FORMAT -0x3380
|
||||
/** Allocation of memory failed. */
|
||||
#define MBEDTLS_ERR_DHM_ALLOC_FAILED -0x3400
|
||||
/** Read or write of file failed. */
|
||||
#define MBEDTLS_ERR_DHM_FILE_IO_ERROR -0x3480
|
||||
/** Setting the modulus and generator failed. */
|
||||
#define MBEDTLS_ERR_DHM_SET_GROUP_FAILED -0x3580
|
||||
|
||||
/** Which parameter to access in mbedtls_dhm_get_value(). */
|
||||
typedef enum {
|
||||
MBEDTLS_DHM_PARAM_P, /*!< The prime modulus. */
|
||||
MBEDTLS_DHM_PARAM_G, /*!< The generator. */
|
||||
MBEDTLS_DHM_PARAM_X, /*!< Our secret value. */
|
||||
MBEDTLS_DHM_PARAM_GX, /*!< Our public key = \c G^X mod \c P. */
|
||||
MBEDTLS_DHM_PARAM_GY, /*!< The public key of the peer = \c G^Y mod \c P. */
|
||||
MBEDTLS_DHM_PARAM_K, /*!< The shared secret = \c G^(XY) mod \c P. */
|
||||
} mbedtls_dhm_parameter;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The DHM context structure.
|
||||
*/
|
||||
typedef struct mbedtls_dhm_context {
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(P); /*!< The prime modulus. */
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(G); /*!< The generator. */
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(X); /*!< Our secret value. */
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(GX); /*!< Our public key = \c G^X mod \c P. */
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(GY); /*!< The public key of the peer = \c G^Y mod \c P. */
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(K); /*!< The shared secret = \c G^(XY) mod \c P. */
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(RP); /*!< The cached value = \c R^2 mod \c P. */
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(Vi); /*!< The blinding value. */
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(Vf); /*!< The unblinding value. */
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(pX); /*!< The previous \c X. */
|
||||
}
|
||||
mbedtls_dhm_context;
|
||||
|
||||
/**
|
||||
* \brief This function initializes the DHM context.
|
||||
*
|
||||
* \param ctx The DHM context to initialize.
|
||||
*/
|
||||
void mbedtls_dhm_init(mbedtls_dhm_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function parses the DHM parameters in a
|
||||
* TLS ServerKeyExchange handshake message
|
||||
* (DHM modulus, generator, and public key).
|
||||
*
|
||||
* \note In a TLS handshake, this is the how the client
|
||||
* sets up its DHM context from the server's public
|
||||
* DHM key material.
|
||||
*
|
||||
* \param ctx The DHM context to use. This must be initialized.
|
||||
* \param p On input, *p must be the start of the input buffer.
|
||||
* On output, *p is updated to point to the end of the data
|
||||
* that has been read. On success, this is the first byte
|
||||
* past the end of the ServerKeyExchange parameters.
|
||||
* On error, this is the point at which an error has been
|
||||
* detected, which is usually not useful except to debug
|
||||
* failures.
|
||||
* \param end The end of the input buffer.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_dhm_read_params(mbedtls_dhm_context *ctx,
|
||||
unsigned char **p,
|
||||
const unsigned char *end);
|
||||
|
||||
/**
|
||||
* \brief This function generates a DHM key pair and exports its
|
||||
* public part together with the DHM parameters in the format
|
||||
* used in a TLS ServerKeyExchange handshake message.
|
||||
*
|
||||
* \note This function assumes that the DHM parameters \c ctx->P
|
||||
* and \c ctx->G have already been properly set. For that, use
|
||||
* mbedtls_dhm_set_group() below in conjunction with
|
||||
* mbedtls_mpi_read_binary() and mbedtls_mpi_read_string().
|
||||
*
|
||||
* \note In a TLS handshake, this is the how the server generates
|
||||
* and exports its DHM key material.
|
||||
*
|
||||
* \param ctx The DHM context to use. This must be initialized
|
||||
* and have the DHM parameters set. It may or may not
|
||||
* already have imported the peer's public key.
|
||||
* \param x_size The private key size in Bytes.
|
||||
* \param olen The address at which to store the number of Bytes
|
||||
* written on success. This must not be \c NULL.
|
||||
* \param output The destination buffer. This must be a writable buffer of
|
||||
* sufficient size to hold the reduced binary presentation of
|
||||
* the modulus, the generator and the public key, each wrapped
|
||||
* with a 2-byte length field. It is the responsibility of the
|
||||
* caller to ensure that enough space is available. Refer to
|
||||
* mbedtls_mpi_size() to computing the byte-size of an MPI.
|
||||
* \param f_rng The RNG function. Must not be \c NULL.
|
||||
* \param p_rng The RNG context to be passed to \p f_rng. This may be
|
||||
* \c NULL if \p f_rng doesn't need a context parameter.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_dhm_make_params(mbedtls_dhm_context *ctx, int x_size,
|
||||
unsigned char *output, size_t *olen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/**
|
||||
* \brief This function sets the prime modulus and generator.
|
||||
*
|
||||
* \note This function can be used to set \c ctx->P, \c ctx->G
|
||||
* in preparation for mbedtls_dhm_make_params().
|
||||
*
|
||||
* \param ctx The DHM context to configure. This must be initialized.
|
||||
* \param P The MPI holding the DHM prime modulus. This must be
|
||||
* an initialized MPI.
|
||||
* \param G The MPI holding the DHM generator. This must be an
|
||||
* initialized MPI.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_dhm_set_group(mbedtls_dhm_context *ctx,
|
||||
const mbedtls_mpi *P,
|
||||
const mbedtls_mpi *G);
|
||||
|
||||
/**
|
||||
* \brief This function imports the raw public value of the peer.
|
||||
*
|
||||
* \note In a TLS handshake, this is the how the server imports
|
||||
* the Client's public DHM key.
|
||||
*
|
||||
* \param ctx The DHM context to use. This must be initialized and have
|
||||
* its DHM parameters set, e.g. via mbedtls_dhm_set_group().
|
||||
* It may or may not already have generated its own private key.
|
||||
* \param input The input buffer containing the \c G^Y value of the peer.
|
||||
* This must be a readable buffer of size \p ilen Bytes.
|
||||
* \param ilen The size of the input buffer \p input in Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_dhm_read_public(mbedtls_dhm_context *ctx,
|
||||
const unsigned char *input, size_t ilen);
|
||||
|
||||
/**
|
||||
* \brief This function creates a DHM key pair and exports
|
||||
* the raw public key in big-endian format.
|
||||
*
|
||||
* \note The destination buffer is always fully written
|
||||
* so as to contain a big-endian representation of G^X mod P.
|
||||
* If it is larger than \c ctx->len, it is padded accordingly
|
||||
* with zero-bytes at the beginning.
|
||||
*
|
||||
* \param ctx The DHM context to use. This must be initialized and
|
||||
* have the DHM parameters set. It may or may not already
|
||||
* have imported the peer's public key.
|
||||
* \param x_size The private key size in Bytes.
|
||||
* \param output The destination buffer. This must be a writable buffer of
|
||||
* size \p olen Bytes.
|
||||
* \param olen The length of the destination buffer. This must be at least
|
||||
* equal to `ctx->len` (the size of \c P).
|
||||
* \param f_rng The RNG function. This must not be \c NULL.
|
||||
* \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL
|
||||
* if \p f_rng doesn't need a context argument.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_dhm_make_public(mbedtls_dhm_context *ctx, int x_size,
|
||||
unsigned char *output, size_t olen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/**
|
||||
* \brief This function derives and exports the shared secret
|
||||
* \c (G^Y)^X mod \c P.
|
||||
*
|
||||
* \note If \p f_rng is not \c NULL, it is used to blind the input as
|
||||
* a countermeasure against timing attacks. Blinding is used
|
||||
* only if our private key \c X is re-used, and not used
|
||||
* otherwise. We recommend always passing a non-NULL
|
||||
* \p f_rng argument.
|
||||
*
|
||||
* \param ctx The DHM context to use. This must be initialized
|
||||
* and have its own private key generated and the peer's
|
||||
* public key imported.
|
||||
* \param output The buffer to write the generated shared key to. This
|
||||
* must be a writable buffer of size \p output_size Bytes.
|
||||
* \param output_size The size of the destination buffer. This must be at
|
||||
* least the size of \c ctx->len (the size of \c P).
|
||||
* \param olen On exit, holds the actual number of Bytes written.
|
||||
* \param f_rng The RNG function. Must not be \c NULL. Used for
|
||||
* blinding.
|
||||
* \param p_rng The RNG context to be passed to \p f_rng. This may be
|
||||
* \c NULL if \p f_rng doesn't need a context parameter.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_DHM_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_dhm_calc_secret(mbedtls_dhm_context *ctx,
|
||||
unsigned char *output, size_t output_size, size_t *olen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/**
|
||||
* \brief This function returns the size of the prime modulus in bits.
|
||||
*
|
||||
* \param ctx The DHM context to query.
|
||||
*
|
||||
* \return The size of the prime modulus in bits,
|
||||
* i.e. the number n such that 2^(n-1) <= P < 2^n.
|
||||
*/
|
||||
size_t mbedtls_dhm_get_bitlen(const mbedtls_dhm_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function returns the size of the prime modulus in bytes.
|
||||
*
|
||||
* \param ctx The DHM context to query.
|
||||
*
|
||||
* \return The size of the prime modulus in bytes,
|
||||
* i.e. the number n such that 2^(8*(n-1)) <= P < 2^(8*n).
|
||||
*/
|
||||
size_t mbedtls_dhm_get_len(const mbedtls_dhm_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function copies a parameter of a DHM key.
|
||||
*
|
||||
* \param ctx The DHM context to query.
|
||||
* \param param The parameter to copy.
|
||||
* \param dest The MPI object to copy the value into. It must be
|
||||
* initialized.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_DHM_BAD_INPUT_DATA if \p param is invalid.
|
||||
* \return An \c MBEDTLS_ERR_MPI_XXX error code if the copy fails.
|
||||
*/
|
||||
int mbedtls_dhm_get_value(const mbedtls_dhm_context *ctx,
|
||||
mbedtls_dhm_parameter param,
|
||||
mbedtls_mpi *dest);
|
||||
|
||||
/**
|
||||
* \brief This function frees and clears the components
|
||||
* of a DHM context.
|
||||
*
|
||||
* \param ctx The DHM context to free and clear. This may be \c NULL,
|
||||
* in which case this function is a no-op. If it is not \c NULL,
|
||||
* it must point to an initialized DHM context.
|
||||
*/
|
||||
void mbedtls_dhm_free(mbedtls_dhm_context *ctx);
|
||||
|
||||
#if defined(MBEDTLS_ASN1_PARSE_C)
|
||||
/**
|
||||
* \brief This function parses DHM parameters in PEM or DER format.
|
||||
*
|
||||
* \param dhm The DHM context to import the DHM parameters into.
|
||||
* This must be initialized.
|
||||
* \param dhmin The input buffer. This must be a readable buffer of
|
||||
* length \p dhminlen Bytes.
|
||||
* \param dhminlen The size of the input buffer \p dhmin, including the
|
||||
* terminating \c NULL Byte for PEM data.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX error
|
||||
* code on failure.
|
||||
*/
|
||||
int mbedtls_dhm_parse_dhm(mbedtls_dhm_context *dhm, const unsigned char *dhmin,
|
||||
size_t dhminlen);
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
/**
|
||||
* \brief This function loads and parses DHM parameters from a file.
|
||||
*
|
||||
* \param dhm The DHM context to load the parameters to.
|
||||
* This must be initialized.
|
||||
* \param path The filename to read the DHM parameters from.
|
||||
* This must not be \c NULL.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX
|
||||
* error code on failure.
|
||||
*/
|
||||
int mbedtls_dhm_parse_dhmfile(mbedtls_dhm_context *dhm, const char *path);
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
#endif /* MBEDTLS_ASN1_PARSE_C */
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
/**
|
||||
* \brief The DMH checkup routine.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c 1 on failure.
|
||||
*/
|
||||
int mbedtls_dhm_self_test(int verbose);
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* RFC 3526, RFC 5114 and RFC 7919 standardize a number of
|
||||
* Diffie-Hellman groups, some of which are included here
|
||||
* for use within the SSL/TLS module and the user's convenience
|
||||
* when configuring the Diffie-Hellman parameters by hand
|
||||
* through \c mbedtls_ssl_conf_dh_param.
|
||||
*
|
||||
* The following lists the source of the above groups in the standards:
|
||||
* - RFC 5114 section 2.2: 2048-bit MODP Group with 224-bit Prime Order Subgroup
|
||||
* - RFC 3526 section 3: 2048-bit MODP Group
|
||||
* - RFC 3526 section 4: 3072-bit MODP Group
|
||||
* - RFC 3526 section 5: 4096-bit MODP Group
|
||||
* - RFC 7919 section A.1: ffdhe2048
|
||||
* - RFC 7919 section A.2: ffdhe3072
|
||||
* - RFC 7919 section A.3: ffdhe4096
|
||||
* - RFC 7919 section A.4: ffdhe6144
|
||||
* - RFC 7919 section A.5: ffdhe8192
|
||||
*
|
||||
* The constants with suffix "_p" denote the chosen prime moduli, while
|
||||
* the constants with suffix "_g" denote the chosen generator
|
||||
* of the associated prime field.
|
||||
*
|
||||
* The constants further suffixed with "_bin" are provided in binary format,
|
||||
* while all other constants represent null-terminated strings holding the
|
||||
* hexadecimal presentation of the respective numbers.
|
||||
*
|
||||
* The primes from RFC 3526 and RFC 7919 have been generating by the following
|
||||
* trust-worthy procedure:
|
||||
* - Fix N in { 2048, 3072, 4096, 6144, 8192 } and consider the N-bit number
|
||||
* the first and last 64 bits are all 1, and the remaining N - 128 bits of
|
||||
* which are 0x7ff...ff.
|
||||
* - Add the smallest multiple of the first N - 129 bits of the binary expansion
|
||||
* of pi (for RFC 5236) or e (for RFC 7919) to this intermediate bit-string
|
||||
* such that the resulting integer is a safe-prime.
|
||||
* - The result is the respective RFC 3526 / 7919 prime, and the corresponding
|
||||
* generator is always chosen to be 2 (which is a square for these prime,
|
||||
* hence the corresponding subgroup has order (p-1)/2 and avoids leaking a
|
||||
* bit in the private exponent).
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Trustworthy DHM parameters in binary form
|
||||
*/
|
||||
|
||||
#define MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN { \
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
|
||||
0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \
|
||||
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \
|
||||
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \
|
||||
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \
|
||||
0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \
|
||||
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \
|
||||
0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \
|
||||
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \
|
||||
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \
|
||||
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \
|
||||
0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \
|
||||
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \
|
||||
0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \
|
||||
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \
|
||||
0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \
|
||||
0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \
|
||||
0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \
|
||||
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \
|
||||
0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \
|
||||
0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \
|
||||
0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \
|
||||
0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \
|
||||
0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \
|
||||
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \
|
||||
0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \
|
||||
0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \
|
||||
0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \
|
||||
0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \
|
||||
0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \
|
||||
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, \
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
|
||||
|
||||
#define MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN { 0x02 }
|
||||
|
||||
#define MBEDTLS_DHM_RFC3526_MODP_3072_P_BIN { \
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
|
||||
0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \
|
||||
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \
|
||||
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \
|
||||
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \
|
||||
0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \
|
||||
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \
|
||||
0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \
|
||||
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \
|
||||
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \
|
||||
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \
|
||||
0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \
|
||||
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \
|
||||
0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \
|
||||
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \
|
||||
0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \
|
||||
0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \
|
||||
0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \
|
||||
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \
|
||||
0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \
|
||||
0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \
|
||||
0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \
|
||||
0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \
|
||||
0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \
|
||||
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \
|
||||
0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \
|
||||
0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \
|
||||
0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \
|
||||
0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \
|
||||
0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \
|
||||
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, \
|
||||
0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, \
|
||||
0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, \
|
||||
0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, \
|
||||
0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, \
|
||||
0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, \
|
||||
0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, \
|
||||
0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, \
|
||||
0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, \
|
||||
0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, \
|
||||
0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, \
|
||||
0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, \
|
||||
0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, \
|
||||
0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, \
|
||||
0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, \
|
||||
0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, \
|
||||
0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, \
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
|
||||
|
||||
#define MBEDTLS_DHM_RFC3526_MODP_3072_G_BIN { 0x02 }
|
||||
|
||||
#define MBEDTLS_DHM_RFC3526_MODP_4096_P_BIN { \
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
|
||||
0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \
|
||||
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \
|
||||
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \
|
||||
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \
|
||||
0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \
|
||||
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \
|
||||
0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \
|
||||
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \
|
||||
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \
|
||||
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \
|
||||
0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \
|
||||
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \
|
||||
0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \
|
||||
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \
|
||||
0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \
|
||||
0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \
|
||||
0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \
|
||||
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \
|
||||
0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \
|
||||
0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \
|
||||
0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \
|
||||
0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \
|
||||
0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \
|
||||
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \
|
||||
0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \
|
||||
0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \
|
||||
0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \
|
||||
0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \
|
||||
0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \
|
||||
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, \
|
||||
0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, \
|
||||
0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, \
|
||||
0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, \
|
||||
0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, \
|
||||
0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, \
|
||||
0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, \
|
||||
0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, \
|
||||
0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, \
|
||||
0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, \
|
||||
0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, \
|
||||
0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, \
|
||||
0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, \
|
||||
0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, \
|
||||
0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, \
|
||||
0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, \
|
||||
0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, \
|
||||
0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, \
|
||||
0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, \
|
||||
0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, \
|
||||
0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, \
|
||||
0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, \
|
||||
0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, \
|
||||
0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, \
|
||||
0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, \
|
||||
0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, \
|
||||
0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, \
|
||||
0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, \
|
||||
0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, \
|
||||
0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, \
|
||||
0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, \
|
||||
0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, \
|
||||
0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, \
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
|
||||
|
||||
#define MBEDTLS_DHM_RFC3526_MODP_4096_G_BIN { 0x02 }
|
||||
|
||||
#define MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN { \
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
|
||||
0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \
|
||||
0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \
|
||||
0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \
|
||||
0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \
|
||||
0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \
|
||||
0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \
|
||||
0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \
|
||||
0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \
|
||||
0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \
|
||||
0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \
|
||||
0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \
|
||||
0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \
|
||||
0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \
|
||||
0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \
|
||||
0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \
|
||||
0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \
|
||||
0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \
|
||||
0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \
|
||||
0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \
|
||||
0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \
|
||||
0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \
|
||||
0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \
|
||||
0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \
|
||||
0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \
|
||||
0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \
|
||||
0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \
|
||||
0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \
|
||||
0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \
|
||||
0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \
|
||||
0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97, \
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }
|
||||
|
||||
#define MBEDTLS_DHM_RFC7919_FFDHE2048_G_BIN { 0x02 }
|
||||
|
||||
#define MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN { \
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
|
||||
0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \
|
||||
0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \
|
||||
0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \
|
||||
0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \
|
||||
0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \
|
||||
0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \
|
||||
0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \
|
||||
0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \
|
||||
0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \
|
||||
0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \
|
||||
0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \
|
||||
0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \
|
||||
0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \
|
||||
0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \
|
||||
0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \
|
||||
0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \
|
||||
0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \
|
||||
0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \
|
||||
0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \
|
||||
0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \
|
||||
0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \
|
||||
0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \
|
||||
0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \
|
||||
0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \
|
||||
0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \
|
||||
0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \
|
||||
0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \
|
||||
0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \
|
||||
0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \
|
||||
0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \
|
||||
0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \
|
||||
0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \
|
||||
0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \
|
||||
0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \
|
||||
0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \
|
||||
0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \
|
||||
0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \
|
||||
0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \
|
||||
0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \
|
||||
0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \
|
||||
0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \
|
||||
0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \
|
||||
0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \
|
||||
0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \
|
||||
0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \
|
||||
0x25, 0xE4, 0x1D, 0x2B, 0x66, 0xC6, 0x2E, 0x37, \
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
|
||||
|
||||
#define MBEDTLS_DHM_RFC7919_FFDHE3072_G_BIN { 0x02 }
|
||||
|
||||
#define MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN { \
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
|
||||
0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \
|
||||
0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \
|
||||
0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \
|
||||
0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \
|
||||
0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \
|
||||
0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \
|
||||
0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \
|
||||
0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \
|
||||
0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \
|
||||
0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \
|
||||
0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \
|
||||
0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \
|
||||
0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \
|
||||
0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \
|
||||
0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \
|
||||
0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \
|
||||
0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \
|
||||
0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \
|
||||
0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \
|
||||
0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \
|
||||
0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \
|
||||
0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \
|
||||
0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \
|
||||
0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \
|
||||
0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \
|
||||
0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \
|
||||
0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \
|
||||
0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \
|
||||
0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \
|
||||
0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \
|
||||
0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \
|
||||
0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \
|
||||
0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \
|
||||
0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \
|
||||
0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \
|
||||
0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \
|
||||
0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \
|
||||
0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \
|
||||
0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \
|
||||
0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \
|
||||
0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \
|
||||
0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \
|
||||
0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \
|
||||
0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \
|
||||
0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \
|
||||
0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \
|
||||
0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \
|
||||
0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \
|
||||
0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \
|
||||
0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \
|
||||
0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \
|
||||
0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \
|
||||
0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \
|
||||
0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \
|
||||
0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \
|
||||
0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \
|
||||
0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \
|
||||
0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \
|
||||
0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \
|
||||
0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \
|
||||
0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \
|
||||
0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x65, 0x5F, 0x6A, \
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
|
||||
|
||||
#define MBEDTLS_DHM_RFC7919_FFDHE4096_G_BIN { 0x02 }
|
||||
|
||||
#define MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN { \
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
|
||||
0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \
|
||||
0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \
|
||||
0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \
|
||||
0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \
|
||||
0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \
|
||||
0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \
|
||||
0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \
|
||||
0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \
|
||||
0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \
|
||||
0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \
|
||||
0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \
|
||||
0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \
|
||||
0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \
|
||||
0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \
|
||||
0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \
|
||||
0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \
|
||||
0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \
|
||||
0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \
|
||||
0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \
|
||||
0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \
|
||||
0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \
|
||||
0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \
|
||||
0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \
|
||||
0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \
|
||||
0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \
|
||||
0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \
|
||||
0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \
|
||||
0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \
|
||||
0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \
|
||||
0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \
|
||||
0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \
|
||||
0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \
|
||||
0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \
|
||||
0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \
|
||||
0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \
|
||||
0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \
|
||||
0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \
|
||||
0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \
|
||||
0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \
|
||||
0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \
|
||||
0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \
|
||||
0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \
|
||||
0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \
|
||||
0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \
|
||||
0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \
|
||||
0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \
|
||||
0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \
|
||||
0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \
|
||||
0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \
|
||||
0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \
|
||||
0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \
|
||||
0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \
|
||||
0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \
|
||||
0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \
|
||||
0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \
|
||||
0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \
|
||||
0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \
|
||||
0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \
|
||||
0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \
|
||||
0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \
|
||||
0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \
|
||||
0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, \
|
||||
0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, \
|
||||
0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, \
|
||||
0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, \
|
||||
0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, \
|
||||
0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, \
|
||||
0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, \
|
||||
0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, \
|
||||
0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, \
|
||||
0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, \
|
||||
0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, \
|
||||
0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, \
|
||||
0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, \
|
||||
0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, \
|
||||
0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, \
|
||||
0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, \
|
||||
0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, \
|
||||
0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, \
|
||||
0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, \
|
||||
0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, \
|
||||
0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, \
|
||||
0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, \
|
||||
0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, \
|
||||
0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, \
|
||||
0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, \
|
||||
0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, \
|
||||
0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, \
|
||||
0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, \
|
||||
0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, \
|
||||
0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, \
|
||||
0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, \
|
||||
0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, \
|
||||
0xA4, 0x0E, 0x32, 0x9C, 0xD0, 0xE4, 0x0E, 0x65, \
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
|
||||
|
||||
#define MBEDTLS_DHM_RFC7919_FFDHE6144_G_BIN { 0x02 }
|
||||
|
||||
#define MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN { \
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
|
||||
0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, \
|
||||
0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, \
|
||||
0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, \
|
||||
0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, \
|
||||
0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, \
|
||||
0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, \
|
||||
0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, \
|
||||
0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, \
|
||||
0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, \
|
||||
0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, \
|
||||
0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, \
|
||||
0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, \
|
||||
0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, \
|
||||
0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, \
|
||||
0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, \
|
||||
0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, \
|
||||
0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, \
|
||||
0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, \
|
||||
0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, \
|
||||
0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, \
|
||||
0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, \
|
||||
0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, \
|
||||
0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, \
|
||||
0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, \
|
||||
0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, \
|
||||
0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, \
|
||||
0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, \
|
||||
0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, \
|
||||
0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, \
|
||||
0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, \
|
||||
0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, \
|
||||
0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, \
|
||||
0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, \
|
||||
0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, \
|
||||
0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, \
|
||||
0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, \
|
||||
0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, \
|
||||
0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, \
|
||||
0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, \
|
||||
0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, \
|
||||
0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, \
|
||||
0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, \
|
||||
0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, \
|
||||
0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, \
|
||||
0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, \
|
||||
0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, \
|
||||
0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, \
|
||||
0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, \
|
||||
0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, \
|
||||
0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, \
|
||||
0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, \
|
||||
0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, \
|
||||
0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, \
|
||||
0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, \
|
||||
0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, \
|
||||
0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, \
|
||||
0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, \
|
||||
0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, \
|
||||
0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, \
|
||||
0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, \
|
||||
0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, \
|
||||
0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, \
|
||||
0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, \
|
||||
0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, \
|
||||
0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, \
|
||||
0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, \
|
||||
0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, \
|
||||
0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, \
|
||||
0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, \
|
||||
0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, \
|
||||
0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, \
|
||||
0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, \
|
||||
0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, \
|
||||
0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, \
|
||||
0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, \
|
||||
0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, \
|
||||
0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, \
|
||||
0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, \
|
||||
0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, \
|
||||
0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, \
|
||||
0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, \
|
||||
0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, \
|
||||
0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, \
|
||||
0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, \
|
||||
0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, \
|
||||
0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, \
|
||||
0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, \
|
||||
0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, \
|
||||
0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, \
|
||||
0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, \
|
||||
0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, \
|
||||
0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, \
|
||||
0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, \
|
||||
0xA4, 0x0E, 0x32, 0x9C, 0xCF, 0xF4, 0x6A, 0xAA, \
|
||||
0x36, 0xAD, 0x00, 0x4C, 0xF6, 0x00, 0xC8, 0x38, \
|
||||
0x1E, 0x42, 0x5A, 0x31, 0xD9, 0x51, 0xAE, 0x64, \
|
||||
0xFD, 0xB2, 0x3F, 0xCE, 0xC9, 0x50, 0x9D, 0x43, \
|
||||
0x68, 0x7F, 0xEB, 0x69, 0xED, 0xD1, 0xCC, 0x5E, \
|
||||
0x0B, 0x8C, 0xC3, 0xBD, 0xF6, 0x4B, 0x10, 0xEF, \
|
||||
0x86, 0xB6, 0x31, 0x42, 0xA3, 0xAB, 0x88, 0x29, \
|
||||
0x55, 0x5B, 0x2F, 0x74, 0x7C, 0x93, 0x26, 0x65, \
|
||||
0xCB, 0x2C, 0x0F, 0x1C, 0xC0, 0x1B, 0xD7, 0x02, \
|
||||
0x29, 0x38, 0x88, 0x39, 0xD2, 0xAF, 0x05, 0xE4, \
|
||||
0x54, 0x50, 0x4A, 0xC7, 0x8B, 0x75, 0x82, 0x82, \
|
||||
0x28, 0x46, 0xC0, 0xBA, 0x35, 0xC3, 0x5F, 0x5C, \
|
||||
0x59, 0x16, 0x0C, 0xC0, 0x46, 0xFD, 0x82, 0x51, \
|
||||
0x54, 0x1F, 0xC6, 0x8C, 0x9C, 0x86, 0xB0, 0x22, \
|
||||
0xBB, 0x70, 0x99, 0x87, 0x6A, 0x46, 0x0E, 0x74, \
|
||||
0x51, 0xA8, 0xA9, 0x31, 0x09, 0x70, 0x3F, 0xEE, \
|
||||
0x1C, 0x21, 0x7E, 0x6C, 0x38, 0x26, 0xE5, 0x2C, \
|
||||
0x51, 0xAA, 0x69, 0x1E, 0x0E, 0x42, 0x3C, 0xFC, \
|
||||
0x99, 0xE9, 0xE3, 0x16, 0x50, 0xC1, 0x21, 0x7B, \
|
||||
0x62, 0x48, 0x16, 0xCD, 0xAD, 0x9A, 0x95, 0xF9, \
|
||||
0xD5, 0xB8, 0x01, 0x94, 0x88, 0xD9, 0xC0, 0xA0, \
|
||||
0xA1, 0xFE, 0x30, 0x75, 0xA5, 0x77, 0xE2, 0x31, \
|
||||
0x83, 0xF8, 0x1D, 0x4A, 0x3F, 0x2F, 0xA4, 0x57, \
|
||||
0x1E, 0xFC, 0x8C, 0xE0, 0xBA, 0x8A, 0x4F, 0xE8, \
|
||||
0xB6, 0x85, 0x5D, 0xFE, 0x72, 0xB0, 0xA6, 0x6E, \
|
||||
0xDE, 0xD2, 0xFB, 0xAB, 0xFB, 0xE5, 0x8A, 0x30, \
|
||||
0xFA, 0xFA, 0xBE, 0x1C, 0x5D, 0x71, 0xA8, 0x7E, \
|
||||
0x2F, 0x74, 0x1E, 0xF8, 0xC1, 0xFE, 0x86, 0xFE, \
|
||||
0xA6, 0xBB, 0xFD, 0xE5, 0x30, 0x67, 0x7F, 0x0D, \
|
||||
0x97, 0xD1, 0x1D, 0x49, 0xF7, 0xA8, 0x44, 0x3D, \
|
||||
0x08, 0x22, 0xE5, 0x06, 0xA9, 0xF4, 0x61, 0x4E, \
|
||||
0x01, 0x1E, 0x2A, 0x94, 0x83, 0x8F, 0xF8, 0x8C, \
|
||||
0xD6, 0x8C, 0x8B, 0xB7, 0xC5, 0xC6, 0x42, 0x4C, \
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
|
||||
|
||||
#define MBEDTLS_DHM_RFC7919_FFDHE8192_G_BIN { 0x02 }
|
||||
|
||||
#endif /* dhm.h */
|
||||
@@ -1,494 +0,0 @@
|
||||
/**
|
||||
* \file ecdh.h
|
||||
*
|
||||
* \brief This file contains ECDH definitions and functions.
|
||||
*
|
||||
* The Elliptic Curve Diffie-Hellman (ECDH) protocol is an anonymous
|
||||
* key agreement protocol allowing two parties to establish a shared
|
||||
* secret over an insecure channel. Each party must have an
|
||||
* elliptic-curve public–private key pair.
|
||||
*
|
||||
* For more information, see <em>NIST SP 800-56A Rev. 2: Recommendation for
|
||||
* Pair-Wise Key Establishment Schemes Using Discrete Logarithm
|
||||
* Cryptography</em>.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_ECDH_H
|
||||
#define MBEDTLS_ECDH_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include "mbedtls/ecp.h"
|
||||
|
||||
/*
|
||||
* Mbed TLS supports two formats for ECDH contexts (#mbedtls_ecdh_context
|
||||
* defined in `ecdh.h`). For most applications, the choice of format makes
|
||||
* no difference, since all library functions can work with either format,
|
||||
* except that the new format is incompatible with MBEDTLS_ECP_RESTARTABLE.
|
||||
|
||||
* The new format used when this option is disabled is smaller
|
||||
* (56 bytes on a 32-bit platform). In future versions of the library, it
|
||||
* will support alternative implementations of ECDH operations.
|
||||
* The new format is incompatible with applications that access
|
||||
* context fields directly and with restartable ECP operations.
|
||||
*/
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
#define MBEDTLS_ECDH_LEGACY_CONTEXT
|
||||
#else
|
||||
#undef MBEDTLS_ECDH_LEGACY_CONTEXT
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||
#undef MBEDTLS_ECDH_LEGACY_CONTEXT
|
||||
#include "everest/everest.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Defines the source of the imported EC key.
|
||||
*/
|
||||
typedef enum {
|
||||
MBEDTLS_ECDH_OURS, /**< Our key. */
|
||||
MBEDTLS_ECDH_THEIRS, /**< The key of the peer. */
|
||||
} mbedtls_ecdh_side;
|
||||
|
||||
#if !defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||
/**
|
||||
* Defines the ECDH implementation used.
|
||||
*
|
||||
* Later versions of the library may add new variants, therefore users should
|
||||
* not make any assumptions about them.
|
||||
*/
|
||||
typedef enum {
|
||||
MBEDTLS_ECDH_VARIANT_NONE = 0, /*!< Implementation not defined. */
|
||||
MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0,/*!< The default Mbed TLS implementation */
|
||||
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||
MBEDTLS_ECDH_VARIANT_EVEREST /*!< Everest implementation */
|
||||
#endif
|
||||
} mbedtls_ecdh_variant;
|
||||
|
||||
/**
|
||||
* The context used by the default ECDH implementation.
|
||||
*
|
||||
* Later versions might change the structure of this context, therefore users
|
||||
* should not make any assumptions about the structure of
|
||||
* mbedtls_ecdh_context_mbed.
|
||||
*/
|
||||
typedef struct mbedtls_ecdh_context_mbed {
|
||||
mbedtls_ecp_group MBEDTLS_PRIVATE(grp); /*!< The elliptic curve used. */
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(d); /*!< The private key. */
|
||||
mbedtls_ecp_point MBEDTLS_PRIVATE(Q); /*!< The public key. */
|
||||
mbedtls_ecp_point MBEDTLS_PRIVATE(Qp); /*!< The value of the public key of the peer. */
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(z); /*!< The shared secret. */
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
mbedtls_ecp_restart_ctx MBEDTLS_PRIVATE(rs); /*!< The restart context for EC computations. */
|
||||
#endif
|
||||
} mbedtls_ecdh_context_mbed;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
#define MBEDTLS_ECDH_CONTEXT_MBED_INIT { MBEDTLS_ECP_GROUP_INIT, MBEDTLS_MPI_INIT, \
|
||||
MBEDTLS_ECP_POINT_INIT, \
|
||||
MBEDTLS_ECP_POINT_INIT, MBEDTLS_MPI_INIT, \
|
||||
MBEDTLS_ECP_RESTART_INIT }
|
||||
#else
|
||||
#define MBEDTLS_ECDH_CONTEXT_MBED_INIT { MBEDTLS_ECP_GROUP_INIT, MBEDTLS_MPI_INIT, \
|
||||
MBEDTLS_ECP_POINT_INIT, \
|
||||
MBEDTLS_ECP_POINT_INIT, MBEDTLS_MPI_INIT }
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
* \warning Performing multiple operations concurrently on the same
|
||||
* ECDSA context is not supported; objects of this type
|
||||
* should not be shared between multiple threads.
|
||||
* \brief The ECDH context structure.
|
||||
*/
|
||||
typedef struct mbedtls_ecdh_context {
|
||||
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||
mbedtls_ecp_group MBEDTLS_PRIVATE(grp); /*!< The elliptic curve used. */
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(d); /*!< The private key. */
|
||||
mbedtls_ecp_point MBEDTLS_PRIVATE(Q); /*!< The public key. */
|
||||
mbedtls_ecp_point MBEDTLS_PRIVATE(Qp); /*!< The value of the public key of the peer. */
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(z); /*!< The shared secret. */
|
||||
int MBEDTLS_PRIVATE(point_format); /*!< The format of point export in TLS messages. */
|
||||
mbedtls_ecp_point MBEDTLS_PRIVATE(Vi); /*!< The blinding value. */
|
||||
mbedtls_ecp_point MBEDTLS_PRIVATE(Vf); /*!< The unblinding value. */
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(_d); /*!< The previous \p d. */
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
int MBEDTLS_PRIVATE(restart_enabled); /*!< The flag for restartable mode. */
|
||||
mbedtls_ecp_restart_ctx MBEDTLS_PRIVATE(rs); /*!< The restart context for EC computations. */
|
||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||
#else
|
||||
uint8_t MBEDTLS_PRIVATE(point_format); /*!< The format of point export in TLS messages
|
||||
as defined in RFC 4492. */
|
||||
mbedtls_ecp_group_id MBEDTLS_PRIVATE(grp_id);/*!< The elliptic curve used. */
|
||||
mbedtls_ecdh_variant MBEDTLS_PRIVATE(var); /*!< The ECDH implementation/structure used. */
|
||||
union {
|
||||
mbedtls_ecdh_context_mbed MBEDTLS_PRIVATE(mbed_ecdh);
|
||||
#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
|
||||
mbedtls_ecdh_context_everest MBEDTLS_PRIVATE(everest_ecdh);
|
||||
#endif
|
||||
} MBEDTLS_PRIVATE(ctx); /*!< Implementation-specific context. The
|
||||
context in use is specified by the \c var
|
||||
field. */
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
uint8_t MBEDTLS_PRIVATE(restart_enabled); /*!< The flag for restartable mode. Functions of
|
||||
an alternative implementation not supporting
|
||||
restartable mode must return
|
||||
MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED error
|
||||
if this flag is set. */
|
||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||
#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */
|
||||
}
|
||||
mbedtls_ecdh_context;
|
||||
|
||||
#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
#define MBEDTLS_ECDH_CONTEXT_INIT { MBEDTLS_ECP_GROUP_INIT, MBEDTLS_MPI_INIT, \
|
||||
MBEDTLS_ECP_POINT_INIT, \
|
||||
MBEDTLS_ECP_POINT_INIT, MBEDTLS_MPI_INIT, \
|
||||
MBEDTLS_ECP_PF_UNCOMPRESSED, \
|
||||
MBEDTLS_ECP_POINT_INIT, MBEDTLS_ECP_POINT_INIT, \
|
||||
MBEDTLS_MPI_INIT, 0, \
|
||||
MBEDTLS_ECP_RESTART_INIT }
|
||||
#else
|
||||
#define MBEDTLS_ECDH_CONTEXT_INIT { MBEDTLS_ECP_GROUP_INIT, MBEDTLS_MPI_INIT, \
|
||||
MBEDTLS_ECP_POINT_INIT, \
|
||||
MBEDTLS_ECP_POINT_INIT, MBEDTLS_MPI_INIT, \
|
||||
MBEDTLS_ECP_PF_UNCOMPRESSED, \
|
||||
MBEDTLS_ECP_POINT_INIT, MBEDTLS_ECP_POINT_INIT, \
|
||||
MBEDTLS_MPI_INIT }
|
||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||
#else
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
#define MBEDTLS_ECDH_CONTEXT_INIT { MBEDTLS_ECP_PF_UNCOMPRESSED, MBEDTLS_ECP_DP_NONE, \
|
||||
MBEDTLS_ECDH_VARIANT_NONE, \
|
||||
{ MBEDTLS_ECDH_CONTEXT_MBED_INIT }, 0 }
|
||||
#else
|
||||
#define MBEDTLS_ECDH_CONTEXT_INIT { MBEDTLS_ECP_PF_UNCOMPRESSED, MBEDTLS_ECP_DP_NONE, \
|
||||
MBEDTLS_ECDH_VARIANT_NONE, \
|
||||
{ MBEDTLS_ECDH_CONTEXT_MBED_INIT } }
|
||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||
#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */
|
||||
|
||||
/**
|
||||
* \brief Return the ECP group for provided context.
|
||||
*
|
||||
* \note To access group specific fields, users should use
|
||||
* `mbedtls_ecp_curve_info_from_grp_id` or
|
||||
* `mbedtls_ecp_group_load` on the extracted `group_id`.
|
||||
*
|
||||
* \param ctx The ECDH context to parse. This must not be \c NULL.
|
||||
*
|
||||
* \return The \c mbedtls_ecp_group_id of the context.
|
||||
*/
|
||||
mbedtls_ecp_group_id mbedtls_ecdh_get_grp_id(mbedtls_ecdh_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Check whether a given group can be used for ECDH.
|
||||
*
|
||||
* \param gid The ECP group ID to check.
|
||||
*
|
||||
* \return \c 1 if the group can be used, \c 0 otherwise
|
||||
*/
|
||||
int mbedtls_ecdh_can_do(mbedtls_ecp_group_id gid);
|
||||
|
||||
/**
|
||||
* \brief This function generates an ECDH keypair on an elliptic
|
||||
* curve.
|
||||
*
|
||||
* This function performs the first of two core computations
|
||||
* implemented during the ECDH key exchange. The second core
|
||||
* computation is performed by mbedtls_ecdh_compute_shared().
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param grp The ECP group to use. This must be initialized and have
|
||||
* domain parameters loaded, for example through
|
||||
* mbedtls_ecp_load() or mbedtls_ecp_tls_read_group().
|
||||
* \param d The destination MPI (private key).
|
||||
* This must be initialized.
|
||||
* \param Q The destination point (public key).
|
||||
* This must be initialized.
|
||||
* \param f_rng The RNG function to use. This must not be \c NULL.
|
||||
* \param p_rng The RNG context to be passed to \p f_rng. This may be
|
||||
* \c NULL in case \p f_rng doesn't need a context argument.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return Another \c MBEDTLS_ERR_ECP_XXX or
|
||||
* \c MBEDTLS_MPI_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_ecdh_gen_public(mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/**
|
||||
* \brief This function computes the shared secret.
|
||||
*
|
||||
* This function performs the second of two core computations
|
||||
* implemented during the ECDH key exchange. The first core
|
||||
* computation is performed by mbedtls_ecdh_gen_public().
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \note If \p f_rng is not NULL, it is used to implement
|
||||
* countermeasures against side-channel attacks.
|
||||
* For more information, see mbedtls_ecp_mul().
|
||||
*
|
||||
* \param grp The ECP group to use. This must be initialized and have
|
||||
* domain parameters loaded, for example through
|
||||
* mbedtls_ecp_load() or mbedtls_ecp_tls_read_group().
|
||||
* \param z The destination MPI (shared secret).
|
||||
* This must be initialized.
|
||||
* \param Q The public key from another party.
|
||||
* This must be initialized.
|
||||
* \param d Our secret exponent (private key).
|
||||
* This must be initialized.
|
||||
* \param f_rng The RNG function to use. This must not be \c NULL.
|
||||
* \param p_rng The RNG context to be passed to \p f_rng. This may be
|
||||
* \c NULL if \p f_rng is \c NULL or doesn't need a
|
||||
* context argument.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return Another \c MBEDTLS_ERR_ECP_XXX or
|
||||
* \c MBEDTLS_MPI_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_ecdh_compute_shared(mbedtls_ecp_group *grp, mbedtls_mpi *z,
|
||||
const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/**
|
||||
* \brief This function initializes an ECDH context.
|
||||
*
|
||||
* \param ctx The ECDH context to initialize. This must not be \c NULL.
|
||||
*/
|
||||
void mbedtls_ecdh_init(mbedtls_ecdh_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function sets up the ECDH context with the information
|
||||
* given.
|
||||
*
|
||||
* This function should be called after mbedtls_ecdh_init() but
|
||||
* before mbedtls_ecdh_make_params(). There is no need to call
|
||||
* this function before mbedtls_ecdh_read_params().
|
||||
*
|
||||
* This is the first function used by a TLS server for ECDHE
|
||||
* ciphersuites.
|
||||
*
|
||||
* \param ctx The ECDH context to set up. This must be initialized.
|
||||
* \param grp_id The group id of the group to set up the context for.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
int mbedtls_ecdh_setup(mbedtls_ecdh_context *ctx,
|
||||
mbedtls_ecp_group_id grp_id);
|
||||
|
||||
/**
|
||||
* \brief This function frees a context.
|
||||
*
|
||||
* \param ctx The context to free. This may be \c NULL, in which
|
||||
* case this function does nothing. If it is not \c NULL,
|
||||
* it must point to an initialized ECDH context.
|
||||
*/
|
||||
void mbedtls_ecdh_free(mbedtls_ecdh_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function generates an EC key pair and exports its
|
||||
* in the format used in a TLS ServerKeyExchange handshake
|
||||
* message.
|
||||
*
|
||||
* This is the second function used by a TLS server for ECDHE
|
||||
* ciphersuites. (It is called after mbedtls_ecdh_setup().)
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The ECDH context to use. This must be initialized
|
||||
* and bound to a group, for example via mbedtls_ecdh_setup().
|
||||
* \param olen The address at which to store the number of Bytes written.
|
||||
* \param buf The destination buffer. This must be a writable buffer of
|
||||
* length \p blen Bytes.
|
||||
* \param blen The length of the destination buffer \p buf in Bytes.
|
||||
* \param f_rng The RNG function to use. This must not be \c NULL.
|
||||
* \param p_rng The RNG context to be passed to \p f_rng. This may be
|
||||
* \c NULL in case \p f_rng doesn't need a context argument.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
|
||||
* operations was reached: see \c mbedtls_ecp_set_max_ops().
|
||||
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_ecdh_make_params(mbedtls_ecdh_context *ctx, size_t *olen,
|
||||
unsigned char *buf, size_t blen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/**
|
||||
* \brief This function parses the ECDHE parameters in a
|
||||
* TLS ServerKeyExchange handshake message.
|
||||
*
|
||||
* \note In a TLS handshake, this is the how the client
|
||||
* sets up its ECDHE context from the server's public
|
||||
* ECDHE key material.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The ECDHE context to use. This must be initialized.
|
||||
* \param buf On input, \c *buf must be the start of the input buffer.
|
||||
* On output, \c *buf is updated to point to the end of the
|
||||
* data that has been read. On success, this is the first byte
|
||||
* past the end of the ServerKeyExchange parameters.
|
||||
* On error, this is the point at which an error has been
|
||||
* detected, which is usually not useful except to debug
|
||||
* failures.
|
||||
* \param end The end of the input buffer.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*
|
||||
*/
|
||||
int mbedtls_ecdh_read_params(mbedtls_ecdh_context *ctx,
|
||||
const unsigned char **buf,
|
||||
const unsigned char *end);
|
||||
|
||||
/**
|
||||
* \brief This function sets up an ECDH context from an EC key.
|
||||
*
|
||||
* It is used by clients and servers in place of the
|
||||
* ServerKeyExchange for static ECDH, and imports ECDH
|
||||
* parameters from the EC key information of a certificate.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The ECDH context to set up. This must be initialized.
|
||||
* \param key The EC key to use. This must be initialized.
|
||||
* \param side Defines the source of the key. Possible values are:
|
||||
* - #MBEDTLS_ECDH_OURS: The key is ours.
|
||||
* - #MBEDTLS_ECDH_THEIRS: The key is that of the peer.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*
|
||||
*/
|
||||
int mbedtls_ecdh_get_params(mbedtls_ecdh_context *ctx,
|
||||
const mbedtls_ecp_keypair *key,
|
||||
mbedtls_ecdh_side side);
|
||||
|
||||
/**
|
||||
* \brief This function generates a public key and exports it
|
||||
* as a TLS ClientKeyExchange payload.
|
||||
*
|
||||
* This is the second function used by a TLS client for ECDH(E)
|
||||
* ciphersuites.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The ECDH context to use. This must be initialized
|
||||
* and bound to a group, the latter usually by
|
||||
* mbedtls_ecdh_read_params().
|
||||
* \param olen The address at which to store the number of Bytes written.
|
||||
* This must not be \c NULL.
|
||||
* \param buf The destination buffer. This must be a writable buffer
|
||||
* of length \p blen Bytes.
|
||||
* \param blen The size of the destination buffer \p buf in Bytes.
|
||||
* \param f_rng The RNG function to use. This must not be \c NULL.
|
||||
* \param p_rng The RNG context to be passed to \p f_rng. This may be
|
||||
* \c NULL in case \p f_rng doesn't need a context argument.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
|
||||
* operations was reached: see \c mbedtls_ecp_set_max_ops().
|
||||
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_ecdh_make_public(mbedtls_ecdh_context *ctx, size_t *olen,
|
||||
unsigned char *buf, size_t blen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/**
|
||||
* \brief This function parses and processes the ECDHE payload of a
|
||||
* TLS ClientKeyExchange message.
|
||||
*
|
||||
* This is the third function used by a TLS server for ECDH(E)
|
||||
* ciphersuites. (It is called after mbedtls_ecdh_setup() and
|
||||
* mbedtls_ecdh_make_params().)
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The ECDH context to use. This must be initialized
|
||||
* and bound to a group, for example via mbedtls_ecdh_setup().
|
||||
* \param buf The pointer to the ClientKeyExchange payload. This must
|
||||
* be a readable buffer of length \p blen Bytes.
|
||||
* \param blen The length of the input buffer \p buf in Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_ecdh_read_public(mbedtls_ecdh_context *ctx,
|
||||
const unsigned char *buf, size_t blen);
|
||||
|
||||
/**
|
||||
* \brief This function derives and exports the shared secret.
|
||||
*
|
||||
* This is the last function used by both TLS client
|
||||
* and servers.
|
||||
*
|
||||
* \note If \p f_rng is not NULL, it is used to implement
|
||||
* countermeasures against side-channel attacks.
|
||||
* For more information, see mbedtls_ecp_mul().
|
||||
*
|
||||
* \see ecp.h
|
||||
|
||||
* \param ctx The ECDH context to use. This must be initialized
|
||||
* and have its own private key generated and the peer's
|
||||
* public key imported.
|
||||
* \param olen The address at which to store the total number of
|
||||
* Bytes written on success. This must not be \c NULL.
|
||||
* \param buf The buffer to write the generated shared key to. This
|
||||
* must be a writable buffer of size \p blen Bytes.
|
||||
* \param blen The length of the destination buffer \p buf in Bytes.
|
||||
* \param f_rng The RNG function to use. This must not be \c NULL.
|
||||
* \param p_rng The RNG context. This may be \c NULL if \p f_rng
|
||||
* doesn't need a context argument.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
|
||||
* operations was reached: see \c mbedtls_ecp_set_max_ops().
|
||||
* \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_ecdh_calc_secret(mbedtls_ecdh_context *ctx, size_t *olen,
|
||||
unsigned char *buf, size_t blen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
/**
|
||||
* \brief This function enables restartable EC computations for this
|
||||
* context. (Default: disabled.)
|
||||
*
|
||||
* \see \c mbedtls_ecp_set_max_ops()
|
||||
*
|
||||
* \note It is not possible to safely disable restartable
|
||||
* computations once enabled, except by free-ing the context,
|
||||
* which cancels possible in-progress operations.
|
||||
*
|
||||
* \param ctx The ECDH context to use. This must be initialized.
|
||||
*/
|
||||
void mbedtls_ecdh_enable_restart(mbedtls_ecdh_context *ctx);
|
||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ecdh.h */
|
||||
@@ -1,665 +0,0 @@
|
||||
/**
|
||||
* \file ecdsa.h
|
||||
*
|
||||
* \brief This file contains ECDSA definitions and functions.
|
||||
*
|
||||
* The Elliptic Curve Digital Signature Algorithm (ECDSA) is defined in
|
||||
* <em>Standards for Efficient Cryptography Group (SECG):
|
||||
* SEC1 Elliptic Curve Cryptography</em>.
|
||||
* The use of ECDSA for TLS is defined in <em>RFC-4492: Elliptic Curve
|
||||
* Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS)</em>.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_ECDSA_H
|
||||
#define MBEDTLS_ECDSA_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
/**
|
||||
* \brief Maximum ECDSA signature size for a given curve bit size
|
||||
*
|
||||
* \param bits Curve size in bits
|
||||
* \return Maximum signature size in bytes
|
||||
*
|
||||
* \note This macro returns a compile-time constant if its argument
|
||||
* is one. It may evaluate its argument multiple times.
|
||||
*/
|
||||
/*
|
||||
* Ecdsa-Sig-Value ::= SEQUENCE {
|
||||
* r INTEGER,
|
||||
* s INTEGER
|
||||
* }
|
||||
*
|
||||
* For each of r and s, the value (V) may include an extra initial "0" bit.
|
||||
*/
|
||||
#define MBEDTLS_ECDSA_MAX_SIG_LEN(bits) \
|
||||
(/*T,L of SEQUENCE*/ ((bits) >= 61 * 8 ? 3 : 2) + \
|
||||
/*T,L of r,s*/ 2 * (((bits) >= 127 * 8 ? 3 : 2) + \
|
||||
/*V of r,s*/ ((bits) + 8) / 8))
|
||||
|
||||
/** The maximal size of an ECDSA signature in Bytes. */
|
||||
#define MBEDTLS_ECDSA_MAX_LEN MBEDTLS_ECDSA_MAX_SIG_LEN(MBEDTLS_ECP_MAX_BITS)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The ECDSA context structure.
|
||||
*
|
||||
* \warning Performing multiple operations concurrently on the same
|
||||
* ECDSA context is not supported; objects of this type
|
||||
* should not be shared between multiple threads.
|
||||
*
|
||||
* \note pk_wrap module assumes that "ecdsa_context" is identical
|
||||
* to "ecp_keypair" (see for example structure
|
||||
* "mbedtls_eckey_info" where ECDSA sign/verify functions
|
||||
* are used also for EC key)
|
||||
*/
|
||||
typedef mbedtls_ecp_keypair mbedtls_ecdsa_context;
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
|
||||
/**
|
||||
* \brief Internal restart context for ecdsa_verify()
|
||||
*
|
||||
* \note Opaque struct, defined in ecdsa.c
|
||||
*/
|
||||
typedef struct mbedtls_ecdsa_restart_ver mbedtls_ecdsa_restart_ver_ctx;
|
||||
|
||||
/**
|
||||
* \brief Internal restart context for ecdsa_sign()
|
||||
*
|
||||
* \note Opaque struct, defined in ecdsa.c
|
||||
*/
|
||||
typedef struct mbedtls_ecdsa_restart_sig mbedtls_ecdsa_restart_sig_ctx;
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
||||
/**
|
||||
* \brief Internal restart context for ecdsa_sign_det()
|
||||
*
|
||||
* \note Opaque struct, defined in ecdsa.c
|
||||
*/
|
||||
typedef struct mbedtls_ecdsa_restart_det mbedtls_ecdsa_restart_det_ctx;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief General context for resuming ECDSA operations
|
||||
*/
|
||||
typedef struct {
|
||||
mbedtls_ecp_restart_ctx MBEDTLS_PRIVATE(ecp); /*!< base context for ECP restart and
|
||||
shared administrative info */
|
||||
mbedtls_ecdsa_restart_ver_ctx *MBEDTLS_PRIVATE(ver); /*!< ecdsa_verify() sub-context */
|
||||
mbedtls_ecdsa_restart_sig_ctx *MBEDTLS_PRIVATE(sig); /*!< ecdsa_sign() sub-context */
|
||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
||||
mbedtls_ecdsa_restart_det_ctx *MBEDTLS_PRIVATE(det); /*!< ecdsa_sign_det() sub-context */
|
||||
#endif
|
||||
} mbedtls_ecdsa_restart_ctx;
|
||||
|
||||
#else /* MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
/* Now we can declare functions that take a pointer to that */
|
||||
typedef void mbedtls_ecdsa_restart_ctx;
|
||||
|
||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
/**
|
||||
* \brief This function checks whether a given group can be used
|
||||
* for ECDSA.
|
||||
*
|
||||
* \param gid The ECP group ID to check.
|
||||
*
|
||||
* \return \c 1 if the group can be used, \c 0 otherwise
|
||||
*/
|
||||
int mbedtls_ecdsa_can_do(mbedtls_ecp_group_id gid);
|
||||
|
||||
/**
|
||||
* \brief This function computes the ECDSA signature of a
|
||||
* previously-hashed message.
|
||||
*
|
||||
* \note The deterministic version implemented in
|
||||
* mbedtls_ecdsa_sign_det_ext() is usually preferred.
|
||||
*
|
||||
* \note If the bitlength of the message hash is larger than the
|
||||
* bitlength of the group order, then the hash is truncated
|
||||
* as defined in <em>Standards for Efficient Cryptography Group
|
||||
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
|
||||
* 4.1.3, step 5.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param grp The context for the elliptic curve to use.
|
||||
* This must be initialized and have group parameters
|
||||
* set, for example through mbedtls_ecp_group_load().
|
||||
* \param r The MPI context in which to store the first part
|
||||
* the signature. This must be initialized.
|
||||
* \param s The MPI context in which to store the second part
|
||||
* the signature. This must be initialized.
|
||||
* \param d The private signing key. This must be initialized.
|
||||
* \param buf The content to be signed. This is usually the hash of
|
||||
* the original data to be signed. This must be a readable
|
||||
* buffer of length \p blen Bytes. It may be \c NULL if
|
||||
* \p blen is zero.
|
||||
* \param blen The length of \p buf in Bytes.
|
||||
* \param f_rng The RNG function. This must not be \c NULL.
|
||||
* \param p_rng The RNG context to be passed to \p f_rng. This may be
|
||||
* \c NULL if \p f_rng doesn't need a context parameter.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX
|
||||
* or \c MBEDTLS_MPI_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
|
||||
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
||||
/**
|
||||
* \brief This function computes the ECDSA signature of a
|
||||
* previously-hashed message, deterministic version.
|
||||
*
|
||||
* For more information, see <em>RFC-6979: Deterministic
|
||||
* Usage of the Digital Signature Algorithm (DSA) and Elliptic
|
||||
* Curve Digital Signature Algorithm (ECDSA)</em>.
|
||||
*
|
||||
* \note If the bitlength of the message hash is larger than the
|
||||
* bitlength of the group order, then the hash is truncated as
|
||||
* defined in <em>Standards for Efficient Cryptography Group
|
||||
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
|
||||
* 4.1.3, step 5.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param grp The context for the elliptic curve to use.
|
||||
* This must be initialized and have group parameters
|
||||
* set, for example through mbedtls_ecp_group_load().
|
||||
* \param r The MPI context in which to store the first part
|
||||
* the signature. This must be initialized.
|
||||
* \param s The MPI context in which to store the second part
|
||||
* the signature. This must be initialized.
|
||||
* \param d The private signing key. This must be initialized
|
||||
* and setup, for example through mbedtls_ecp_gen_privkey().
|
||||
* \param buf The hashed content to be signed. This must be a readable
|
||||
* buffer of length \p blen Bytes. It may be \c NULL if
|
||||
* \p blen is zero.
|
||||
* \param blen The length of \p buf in Bytes.
|
||||
* \param md_alg The hash algorithm used to hash the original data.
|
||||
* \param f_rng_blind The RNG function used for blinding. This must not be
|
||||
* \c NULL.
|
||||
* \param p_rng_blind The RNG context to be passed to \p f_rng_blind. This
|
||||
* may be \c NULL if \p f_rng_blind doesn't need a context
|
||||
* parameter.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
|
||||
* error code on failure.
|
||||
*/
|
||||
int mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group *grp, mbedtls_mpi *r,
|
||||
mbedtls_mpi *s, const mbedtls_mpi *d,
|
||||
const unsigned char *buf, size_t blen,
|
||||
mbedtls_md_type_t md_alg,
|
||||
int (*f_rng_blind)(void *, unsigned char *, size_t),
|
||||
void *p_rng_blind);
|
||||
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
|
||||
|
||||
/**
|
||||
* \brief This function computes the ECDSA signature of a
|
||||
* previously-hashed message, in a restartable way.
|
||||
*
|
||||
* \note The deterministic version implemented in
|
||||
* mbedtls_ecdsa_sign_det_restartable() is usually
|
||||
* preferred.
|
||||
*
|
||||
* \note This function is like \c mbedtls_ecdsa_sign() but
|
||||
* it can return early and restart according to the
|
||||
* limit set with \c mbedtls_ecp_set_max_ops() to
|
||||
* reduce blocking.
|
||||
*
|
||||
* \note If the bitlength of the message hash is larger
|
||||
* than the bitlength of the group order, then the
|
||||
* hash is truncated as defined in <em>Standards for
|
||||
* Efficient Cryptography Group (SECG): SEC1 Elliptic
|
||||
* Curve Cryptography</em>, section 4.1.3, step 5.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param grp The context for the elliptic curve to use.
|
||||
* This must be initialized and have group parameters
|
||||
* set, for example through mbedtls_ecp_group_load().
|
||||
* \param r The MPI context in which to store the first part
|
||||
* the signature. This must be initialized.
|
||||
* \param s The MPI context in which to store the second part
|
||||
* the signature. This must be initialized.
|
||||
* \param d The private signing key. This must be initialized
|
||||
* and setup, for example through
|
||||
* mbedtls_ecp_gen_privkey().
|
||||
* \param buf The hashed content to be signed. This must be a readable
|
||||
* buffer of length \p blen Bytes. It may be \c NULL if
|
||||
* \p blen is zero.
|
||||
* \param blen The length of \p buf in Bytes.
|
||||
* \param f_rng The RNG function. This must not be \c NULL.
|
||||
* \param p_rng The RNG context to be passed to \p f_rng. This may be
|
||||
* \c NULL if \p f_rng doesn't need a context parameter.
|
||||
* \param f_rng_blind The RNG function used for blinding. This must not be
|
||||
* \c NULL.
|
||||
* \param p_rng_blind The RNG context to be passed to \p f_rng. This may be
|
||||
* \c NULL if \p f_rng doesn't need a context parameter.
|
||||
* \param rs_ctx The restart context to use. This may be \c NULL
|
||||
* to disable restarting. If it is not \c NULL, it
|
||||
* must point to an initialized restart context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
|
||||
* operations was reached: see \c
|
||||
* mbedtls_ecp_set_max_ops().
|
||||
* \return Another \c MBEDTLS_ERR_ECP_XXX, \c
|
||||
* MBEDTLS_ERR_MPI_XXX or \c MBEDTLS_ERR_ASN1_XXX
|
||||
* error code on failure.
|
||||
*/
|
||||
int mbedtls_ecdsa_sign_restartable(
|
||||
mbedtls_ecp_group *grp,
|
||||
mbedtls_mpi *r, mbedtls_mpi *s,
|
||||
const mbedtls_mpi *d,
|
||||
const unsigned char *buf, size_t blen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int (*f_rng_blind)(void *, unsigned char *, size_t),
|
||||
void *p_rng_blind,
|
||||
mbedtls_ecdsa_restart_ctx *rs_ctx);
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
|
||||
|
||||
/**
|
||||
* \brief This function computes the ECDSA signature of a
|
||||
* previously-hashed message, in a restartable way.
|
||||
*
|
||||
* \note This function is like \c
|
||||
* mbedtls_ecdsa_sign_det_ext() but it can return
|
||||
* early and restart according to the limit set with
|
||||
* \c mbedtls_ecp_set_max_ops() to reduce blocking.
|
||||
*
|
||||
* \note If the bitlength of the message hash is larger
|
||||
* than the bitlength of the group order, then the
|
||||
* hash is truncated as defined in <em>Standards for
|
||||
* Efficient Cryptography Group (SECG): SEC1 Elliptic
|
||||
* Curve Cryptography</em>, section 4.1.3, step 5.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param grp The context for the elliptic curve to use.
|
||||
* This must be initialized and have group parameters
|
||||
* set, for example through mbedtls_ecp_group_load().
|
||||
* \param r The MPI context in which to store the first part
|
||||
* the signature. This must be initialized.
|
||||
* \param s The MPI context in which to store the second part
|
||||
* the signature. This must be initialized.
|
||||
* \param d The private signing key. This must be initialized
|
||||
* and setup, for example through
|
||||
* mbedtls_ecp_gen_privkey().
|
||||
* \param buf The hashed content to be signed. This must be a readable
|
||||
* buffer of length \p blen Bytes. It may be \c NULL if
|
||||
* \p blen is zero.
|
||||
* \param blen The length of \p buf in Bytes.
|
||||
* \param md_alg The hash algorithm used to hash the original data.
|
||||
* \param f_rng_blind The RNG function used for blinding. This must not be
|
||||
* \c NULL.
|
||||
* \param p_rng_blind The RNG context to be passed to \p f_rng_blind. This may be
|
||||
* \c NULL if \p f_rng_blind doesn't need a context parameter.
|
||||
* \param rs_ctx The restart context to use. This may be \c NULL
|
||||
* to disable restarting. If it is not \c NULL, it
|
||||
* must point to an initialized restart context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
|
||||
* operations was reached: see \c
|
||||
* mbedtls_ecp_set_max_ops().
|
||||
* \return Another \c MBEDTLS_ERR_ECP_XXX, \c
|
||||
* MBEDTLS_ERR_MPI_XXX or \c MBEDTLS_ERR_ASN1_XXX
|
||||
* error code on failure.
|
||||
*/
|
||||
int mbedtls_ecdsa_sign_det_restartable(
|
||||
mbedtls_ecp_group *grp,
|
||||
mbedtls_mpi *r, mbedtls_mpi *s,
|
||||
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
|
||||
mbedtls_md_type_t md_alg,
|
||||
int (*f_rng_blind)(void *, unsigned char *, size_t),
|
||||
void *p_rng_blind,
|
||||
mbedtls_ecdsa_restart_ctx *rs_ctx);
|
||||
|
||||
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
|
||||
|
||||
/**
|
||||
* \brief This function verifies the ECDSA signature of a
|
||||
* previously-hashed message.
|
||||
*
|
||||
* \note If the bitlength of the message hash is larger than the
|
||||
* bitlength of the group order, then the hash is truncated as
|
||||
* defined in <em>Standards for Efficient Cryptography Group
|
||||
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
|
||||
* 4.1.4, step 3.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param grp The ECP group to use.
|
||||
* This must be initialized and have group parameters
|
||||
* set, for example through mbedtls_ecp_group_load().
|
||||
* \param buf The hashed content that was signed. This must be a readable
|
||||
* buffer of length \p blen Bytes. It may be \c NULL if
|
||||
* \p blen is zero.
|
||||
* \param blen The length of \p buf in Bytes.
|
||||
* \param Q The public key to use for verification. This must be
|
||||
* initialized and setup.
|
||||
* \param r The first integer of the signature.
|
||||
* This must be initialized.
|
||||
* \param s The second integer of the signature.
|
||||
* This must be initialized.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
|
||||
* error code on failure.
|
||||
*/
|
||||
int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp,
|
||||
const unsigned char *buf, size_t blen,
|
||||
const mbedtls_ecp_point *Q, const mbedtls_mpi *r,
|
||||
const mbedtls_mpi *s);
|
||||
|
||||
/**
|
||||
* \brief This function verifies the ECDSA signature of a
|
||||
* previously-hashed message, in a restartable manner
|
||||
*
|
||||
* \note If the bitlength of the message hash is larger than the
|
||||
* bitlength of the group order, then the hash is truncated as
|
||||
* defined in <em>Standards for Efficient Cryptography Group
|
||||
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
|
||||
* 4.1.4, step 3.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param grp The ECP group to use.
|
||||
* This must be initialized and have group parameters
|
||||
* set, for example through mbedtls_ecp_group_load().
|
||||
* \param buf The hashed content that was signed. This must be a readable
|
||||
* buffer of length \p blen Bytes. It may be \c NULL if
|
||||
* \p blen is zero.
|
||||
* \param blen The length of \p buf in Bytes.
|
||||
* \param Q The public key to use for verification. This must be
|
||||
* initialized and setup.
|
||||
* \param r The first integer of the signature.
|
||||
* This must be initialized.
|
||||
* \param s The second integer of the signature.
|
||||
* This must be initialized.
|
||||
* \param rs_ctx The restart context to use. This may be \c NULL to disable
|
||||
* restarting. If it is not \c NULL, it must point to an
|
||||
* initialized restart context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
|
||||
* operations was reached: see \c mbedtls_ecp_set_max_ops().
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
|
||||
* error code on failure.
|
||||
*/
|
||||
int mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp,
|
||||
const unsigned char *buf, size_t blen,
|
||||
const mbedtls_ecp_point *Q,
|
||||
const mbedtls_mpi *r,
|
||||
const mbedtls_mpi *s,
|
||||
mbedtls_ecdsa_restart_ctx *rs_ctx);
|
||||
|
||||
/**
|
||||
* \brief This function computes the ECDSA signature and writes it
|
||||
* to a buffer, serialized as defined in <em>RFC-4492:
|
||||
* Elliptic Curve Cryptography (ECC) Cipher Suites for
|
||||
* Transport Layer Security (TLS)</em>.
|
||||
*
|
||||
* \warning It is not thread-safe to use the same context in
|
||||
* multiple threads.
|
||||
*
|
||||
* \note The deterministic version is used if
|
||||
* #MBEDTLS_ECDSA_DETERMINISTIC is defined. For more
|
||||
* information, see <em>RFC-6979: Deterministic Usage
|
||||
* of the Digital Signature Algorithm (DSA) and Elliptic
|
||||
* Curve Digital Signature Algorithm (ECDSA)</em>.
|
||||
*
|
||||
* \note If the bitlength of the message hash is larger than the
|
||||
* bitlength of the group order, then the hash is truncated as
|
||||
* defined in <em>Standards for Efficient Cryptography Group
|
||||
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
|
||||
* 4.1.3, step 5.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The ECDSA context to use. This must be initialized
|
||||
* and have a group and private key bound to it, for example
|
||||
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
|
||||
* \param md_alg The message digest that was used to hash the message.
|
||||
* \param hash The message hash to be signed. This must be a readable
|
||||
* buffer of length \p hlen Bytes.
|
||||
* \param hlen The length of the hash \p hash in Bytes.
|
||||
* \param sig The buffer to which to write the signature. This must be a
|
||||
* writable buffer of length at least twice as large as the
|
||||
* size of the curve used, plus 9. For example, 73 Bytes if
|
||||
* a 256-bit curve is used. A buffer length of
|
||||
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
|
||||
* \param sig_size The size of the \p sig buffer in bytes.
|
||||
* \param slen The address at which to store the actual length of
|
||||
* the signature written. Must not be \c NULL.
|
||||
* \param f_rng The RNG function. This must not be \c NULL if
|
||||
* #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
|
||||
* it is used only for blinding and may be set to \c NULL, but
|
||||
* doing so is DEPRECATED.
|
||||
* \param p_rng The RNG context to be passed to \p f_rng. This may be
|
||||
* \c NULL if \p f_rng is \c NULL or doesn't use a context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
|
||||
* \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx,
|
||||
mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hlen,
|
||||
unsigned char *sig, size_t sig_size, size_t *slen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/**
|
||||
* \brief This function computes the ECDSA signature and writes it
|
||||
* to a buffer, in a restartable way.
|
||||
*
|
||||
* \see \c mbedtls_ecdsa_write_signature()
|
||||
*
|
||||
* \note This function is like \c mbedtls_ecdsa_write_signature()
|
||||
* but it can return early and restart according to the limit
|
||||
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
|
||||
*
|
||||
* \param ctx The ECDSA context to use. This must be initialized
|
||||
* and have a group and private key bound to it, for example
|
||||
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
|
||||
* \param md_alg The message digest that was used to hash the message.
|
||||
* \param hash The message hash to be signed. This must be a readable
|
||||
* buffer of length \p hlen Bytes.
|
||||
* \param hlen The length of the hash \p hash in Bytes.
|
||||
* \param sig The buffer to which to write the signature. This must be a
|
||||
* writable buffer of length at least twice as large as the
|
||||
* size of the curve used, plus 9. For example, 73 Bytes if
|
||||
* a 256-bit curve is used. A buffer length of
|
||||
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
|
||||
* \param sig_size The size of the \p sig buffer in bytes.
|
||||
* \param slen The address at which to store the actual length of
|
||||
* the signature written. Must not be \c NULL.
|
||||
* \param f_rng The RNG function. This must not be \c NULL if
|
||||
* #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
|
||||
* it is unused and may be set to \c NULL.
|
||||
* \param p_rng The RNG context to be passed to \p f_rng. This may be
|
||||
* \c NULL if \p f_rng is \c NULL or doesn't use a context.
|
||||
* \param rs_ctx The restart context to use. This may be \c NULL to disable
|
||||
* restarting. If it is not \c NULL, it must point to an
|
||||
* initialized restart context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
|
||||
* operations was reached: see \c mbedtls_ecp_set_max_ops().
|
||||
* \return Another \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
|
||||
* \c MBEDTLS_ERR_ASN1_XXX error code on failure.
|
||||
*/
|
||||
int mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx,
|
||||
mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash, size_t hlen,
|
||||
unsigned char *sig, size_t sig_size, size_t *slen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
mbedtls_ecdsa_restart_ctx *rs_ctx);
|
||||
|
||||
/**
|
||||
* \brief This function reads and verifies an ECDSA signature.
|
||||
*
|
||||
* \note If the bitlength of the message hash is larger than the
|
||||
* bitlength of the group order, then the hash is truncated as
|
||||
* defined in <em>Standards for Efficient Cryptography Group
|
||||
* (SECG): SEC1 Elliptic Curve Cryptography</em>, section
|
||||
* 4.1.4, step 3.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The ECDSA context to use. This must be initialized
|
||||
* and have a group and public key bound to it.
|
||||
* \param hash The message hash that was signed. This must be a readable
|
||||
* buffer of length \p hlen Bytes.
|
||||
* \param hlen The size of the hash \p hash.
|
||||
* \param sig The signature to read and verify. This must be a readable
|
||||
* buffer of length \p slen Bytes.
|
||||
* \param slen The size of \p sig in Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
|
||||
* \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid
|
||||
* signature in \p sig, but its length is less than \p siglen.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
|
||||
* error code on failure for any other reason.
|
||||
*/
|
||||
int mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx,
|
||||
const unsigned char *hash, size_t hlen,
|
||||
const unsigned char *sig, size_t slen);
|
||||
|
||||
/**
|
||||
* \brief This function reads and verifies an ECDSA signature,
|
||||
* in a restartable way.
|
||||
*
|
||||
* \see \c mbedtls_ecdsa_read_signature()
|
||||
*
|
||||
* \note This function is like \c mbedtls_ecdsa_read_signature()
|
||||
* but it can return early and restart according to the limit
|
||||
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
|
||||
*
|
||||
* \param ctx The ECDSA context to use. This must be initialized
|
||||
* and have a group and public key bound to it.
|
||||
* \param hash The message hash that was signed. This must be a readable
|
||||
* buffer of length \p hlen Bytes.
|
||||
* \param hlen The size of the hash \p hash.
|
||||
* \param sig The signature to read and verify. This must be a readable
|
||||
* buffer of length \p slen Bytes.
|
||||
* \param slen The size of \p sig in Bytes.
|
||||
* \param rs_ctx The restart context to use. This may be \c NULL to disable
|
||||
* restarting. If it is not \c NULL, it must point to an
|
||||
* initialized restart context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
|
||||
* \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid
|
||||
* signature in \p sig, but its length is less than \p siglen.
|
||||
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
|
||||
* operations was reached: see \c mbedtls_ecp_set_max_ops().
|
||||
* \return Another \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
|
||||
* error code on failure for any other reason.
|
||||
*/
|
||||
int mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx,
|
||||
const unsigned char *hash, size_t hlen,
|
||||
const unsigned char *sig, size_t slen,
|
||||
mbedtls_ecdsa_restart_ctx *rs_ctx);
|
||||
|
||||
/**
|
||||
* \brief This function generates an ECDSA keypair on the given curve.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The ECDSA context to store the keypair in.
|
||||
* This must be initialized.
|
||||
* \param gid The elliptic curve to use. One of the various
|
||||
* \c MBEDTLS_ECP_DP_XXX macros depending on configuration.
|
||||
* \param f_rng The RNG function to use. This must not be \c NULL.
|
||||
* \param p_rng The RNG context to be passed to \p f_rng. This may be
|
||||
* \c NULL if \p f_rng doesn't need a context argument.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure.
|
||||
*/
|
||||
int mbedtls_ecdsa_genkey(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
|
||||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
|
||||
|
||||
/**
|
||||
* \brief This function sets up an ECDSA context from an EC key pair.
|
||||
*
|
||||
* \see ecp.h
|
||||
*
|
||||
* \param ctx The ECDSA context to setup. This must be initialized.
|
||||
* \param key The EC key to use. This must be initialized and hold
|
||||
* a private-public key pair or a public key. In the former
|
||||
* case, the ECDSA context may be used for signature creation
|
||||
* and verification after this call. In the latter case, it
|
||||
* may be used for signature verification.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure.
|
||||
*/
|
||||
int mbedtls_ecdsa_from_keypair(mbedtls_ecdsa_context *ctx,
|
||||
const mbedtls_ecp_keypair *key);
|
||||
|
||||
/**
|
||||
* \brief This function initializes an ECDSA context.
|
||||
*
|
||||
* \param ctx The ECDSA context to initialize.
|
||||
* This must not be \c NULL.
|
||||
*/
|
||||
void mbedtls_ecdsa_init(mbedtls_ecdsa_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function frees an ECDSA context.
|
||||
*
|
||||
* \param ctx The ECDSA context to free. This may be \c NULL,
|
||||
* in which case this function does nothing. If it
|
||||
* is not \c NULL, it must be initialized.
|
||||
*/
|
||||
void mbedtls_ecdsa_free(mbedtls_ecdsa_context *ctx);
|
||||
|
||||
#if defined(MBEDTLS_ECP_RESTARTABLE)
|
||||
/**
|
||||
* \brief Initialize a restart context.
|
||||
*
|
||||
* \param ctx The restart context to initialize.
|
||||
* This must not be \c NULL.
|
||||
*/
|
||||
void mbedtls_ecdsa_restart_init(mbedtls_ecdsa_restart_ctx *ctx);
|
||||
|
||||
/**
|
||||
* \brief Free the components of a restart context.
|
||||
*
|
||||
* \param ctx The restart context to free. This may be \c NULL,
|
||||
* in which case this function does nothing. If it
|
||||
* is not \c NULL, it must be initialized.
|
||||
*/
|
||||
void mbedtls_ecdsa_restart_free(mbedtls_ecdsa_restart_ctx *ctx);
|
||||
#endif /* MBEDTLS_ECP_RESTARTABLE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ecdsa.h */
|
||||
@@ -1,293 +0,0 @@
|
||||
/**
|
||||
* \file ecjpake.h
|
||||
*
|
||||
* \brief Elliptic curve J-PAKE
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_ECJPAKE_H
|
||||
#define MBEDTLS_ECJPAKE_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
/*
|
||||
* J-PAKE is a password-authenticated key exchange that allows deriving a
|
||||
* strong shared secret from a (potentially low entropy) pre-shared
|
||||
* passphrase, with forward secrecy and mutual authentication.
|
||||
* https://en.wikipedia.org/wiki/Password_Authenticated_Key_Exchange_by_Juggling
|
||||
*
|
||||
* This file implements the Elliptic Curve variant of J-PAKE,
|
||||
* as defined in Chapter 7.4 of the Thread v1.0 Specification,
|
||||
* available to members of the Thread Group http://threadgroup.org/
|
||||
*
|
||||
* As the J-PAKE algorithm is inherently symmetric, so is our API.
|
||||
* Each party needs to send its first round message, in any order, to the
|
||||
* other party, then each sends its second round message, in any order.
|
||||
* The payloads are serialized in a way suitable for use in TLS, but could
|
||||
* also be use outside TLS.
|
||||
*/
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Roles in the EC J-PAKE exchange
|
||||
*/
|
||||
typedef enum {
|
||||
MBEDTLS_ECJPAKE_CLIENT = 0, /**< Client */
|
||||
MBEDTLS_ECJPAKE_SERVER, /**< Server */
|
||||
MBEDTLS_ECJPAKE_NONE, /**< Undefined */
|
||||
} mbedtls_ecjpake_role;
|
||||
|
||||
/**
|
||||
* EC J-PAKE context structure.
|
||||
*
|
||||
* J-PAKE is a symmetric protocol, except for the identifiers used in
|
||||
* Zero-Knowledge Proofs, and the serialization of the second message
|
||||
* (KeyExchange) as defined by the Thread spec.
|
||||
*
|
||||
* In order to benefit from this symmetry, we choose a different naming
|
||||
* convention from the Thread v1.0 spec. Correspondence is indicated in the
|
||||
* description as a pair C: client name, S: server name
|
||||
*/
|
||||
typedef struct mbedtls_ecjpake_context {
|
||||
mbedtls_md_type_t MBEDTLS_PRIVATE(md_type); /**< Hash to use */
|
||||
mbedtls_ecp_group MBEDTLS_PRIVATE(grp); /**< Elliptic curve */
|
||||
mbedtls_ecjpake_role MBEDTLS_PRIVATE(role); /**< Are we client or server? */
|
||||
int MBEDTLS_PRIVATE(point_format); /**< Format for point export */
|
||||
|
||||
mbedtls_ecp_point MBEDTLS_PRIVATE(Xm1); /**< My public key 1 C: X1, S: X3 */
|
||||
mbedtls_ecp_point MBEDTLS_PRIVATE(Xm2); /**< My public key 2 C: X2, S: X4 */
|
||||
mbedtls_ecp_point MBEDTLS_PRIVATE(Xp1); /**< Peer public key 1 C: X3, S: X1 */
|
||||
mbedtls_ecp_point MBEDTLS_PRIVATE(Xp2); /**< Peer public key 2 C: X4, S: X2 */
|
||||
mbedtls_ecp_point MBEDTLS_PRIVATE(Xp); /**< Peer public key C: Xs, S: Xc */
|
||||
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(xm1); /**< My private key 1 C: x1, S: x3 */
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(xm2); /**< My private key 2 C: x2, S: x4 */
|
||||
|
||||
mbedtls_mpi MBEDTLS_PRIVATE(s); /**< Pre-shared secret (passphrase) */
|
||||
} mbedtls_ecjpake_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize an ECJPAKE context.
|
||||
*
|
||||
* \param ctx The ECJPAKE context to initialize.
|
||||
* This must not be \c NULL.
|
||||
*/
|
||||
void mbedtls_ecjpake_init(mbedtls_ecjpake_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Set up an ECJPAKE context for use.
|
||||
*
|
||||
* \note Currently the only values for hash/curve allowed by the
|
||||
* standard are #MBEDTLS_MD_SHA256/#MBEDTLS_ECP_DP_SECP256R1.
|
||||
*
|
||||
* \param ctx The ECJPAKE context to set up. This must be initialized.
|
||||
* \param role The role of the caller. This must be either
|
||||
* #MBEDTLS_ECJPAKE_CLIENT or #MBEDTLS_ECJPAKE_SERVER.
|
||||
* \param hash The identifier of the hash function to use,
|
||||
* for example #MBEDTLS_MD_SHA256.
|
||||
* \param curve The identifier of the elliptic curve to use,
|
||||
* for example #MBEDTLS_ECP_DP_SECP256R1.
|
||||
* \param secret The pre-shared secret (passphrase). This must be
|
||||
* a readable not empty buffer of length \p len Bytes. It need
|
||||
* only be valid for the duration of this call.
|
||||
* \param len The length of the pre-shared secret \p secret.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_ecjpake_setup(mbedtls_ecjpake_context *ctx,
|
||||
mbedtls_ecjpake_role role,
|
||||
mbedtls_md_type_t hash,
|
||||
mbedtls_ecp_group_id curve,
|
||||
const unsigned char *secret,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* \brief Set the point format for future reads and writes.
|
||||
*
|
||||
* \param ctx The ECJPAKE context to configure.
|
||||
* \param point_format The point format to use:
|
||||
* #MBEDTLS_ECP_PF_UNCOMPRESSED (default)
|
||||
* or #MBEDTLS_ECP_PF_COMPRESSED.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p point_format
|
||||
* is invalid.
|
||||
*/
|
||||
int mbedtls_ecjpake_set_point_format(mbedtls_ecjpake_context *ctx,
|
||||
int point_format);
|
||||
|
||||
/**
|
||||
* \brief Check if an ECJPAKE context is ready for use.
|
||||
*
|
||||
* \param ctx The ECJPAKE context to check. This must be
|
||||
* initialized.
|
||||
*
|
||||
* \return \c 0 if the context is ready for use.
|
||||
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise.
|
||||
*/
|
||||
int mbedtls_ecjpake_check(const mbedtls_ecjpake_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Generate and write the first round message
|
||||
* (TLS: contents of the Client/ServerHello extension,
|
||||
* excluding extension type and length bytes).
|
||||
*
|
||||
* \param ctx The ECJPAKE context to use. This must be
|
||||
* initialized and set up.
|
||||
* \param buf The buffer to write the contents to. This must be a
|
||||
* writable buffer of length \p len Bytes.
|
||||
* \param len The length of \p buf in Bytes.
|
||||
* \param olen The address at which to store the total number
|
||||
* of Bytes written to \p buf. This must not be \c NULL.
|
||||
* \param f_rng The RNG function to use. This must not be \c NULL.
|
||||
* \param p_rng The RNG parameter to be passed to \p f_rng. This
|
||||
* may be \c NULL if \p f_rng doesn't use a context.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_ecjpake_write_round_one(mbedtls_ecjpake_context *ctx,
|
||||
unsigned char *buf, size_t len, size_t *olen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/**
|
||||
* \brief Read and process the first round message
|
||||
* (TLS: contents of the Client/ServerHello extension,
|
||||
* excluding extension type and length bytes).
|
||||
*
|
||||
* \param ctx The ECJPAKE context to use. This must be initialized
|
||||
* and set up.
|
||||
* \param buf The buffer holding the first round message. This must
|
||||
* be a readable buffer of length \p len Bytes.
|
||||
* \param len The length in Bytes of \p buf.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_ecjpake_read_round_one(mbedtls_ecjpake_context *ctx,
|
||||
const unsigned char *buf,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* \brief Generate and write the second round message
|
||||
* (TLS: contents of the Client/ServerKeyExchange).
|
||||
*
|
||||
* \param ctx The ECJPAKE context to use. This must be initialized,
|
||||
* set up, and already have performed round one.
|
||||
* \param buf The buffer to write the round two contents to.
|
||||
* This must be a writable buffer of length \p len Bytes.
|
||||
* \param len The size of \p buf in Bytes.
|
||||
* \param olen The address at which to store the total number of Bytes
|
||||
* written to \p buf. This must not be \c NULL.
|
||||
* \param f_rng The RNG function to use. This must not be \c NULL.
|
||||
* \param p_rng The RNG parameter to be passed to \p f_rng. This
|
||||
* may be \c NULL if \p f_rng doesn't use a context.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_ecjpake_write_round_two(mbedtls_ecjpake_context *ctx,
|
||||
unsigned char *buf, size_t len, size_t *olen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/**
|
||||
* \brief Read and process the second round message
|
||||
* (TLS: contents of the Client/ServerKeyExchange).
|
||||
*
|
||||
* \param ctx The ECJPAKE context to use. This must be initialized
|
||||
* and set up and already have performed round one.
|
||||
* \param buf The buffer holding the second round message. This must
|
||||
* be a readable buffer of length \p len Bytes.
|
||||
* \param len The length in Bytes of \p buf.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_ecjpake_read_round_two(mbedtls_ecjpake_context *ctx,
|
||||
const unsigned char *buf,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* \brief Derive the shared secret
|
||||
* (TLS: Pre-Master Secret).
|
||||
*
|
||||
* \param ctx The ECJPAKE context to use. This must be initialized,
|
||||
* set up and have performed both round one and two.
|
||||
* \param buf The buffer to write the derived secret to. This must
|
||||
* be a writable buffer of length \p len Bytes.
|
||||
* \param len The length of \p buf in Bytes.
|
||||
* \param olen The address at which to store the total number of Bytes
|
||||
* written to \p buf. This must not be \c NULL.
|
||||
* \param f_rng The RNG function to use. This must not be \c NULL.
|
||||
* \param p_rng The RNG parameter to be passed to \p f_rng. This
|
||||
* may be \c NULL if \p f_rng doesn't use a context.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_ecjpake_derive_secret(mbedtls_ecjpake_context *ctx,
|
||||
unsigned char *buf, size_t len, size_t *olen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/**
|
||||
* \brief Write the shared key material to be passed to a Key
|
||||
* Derivation Function as described in RFC8236.
|
||||
*
|
||||
* \param ctx The ECJPAKE context to use. This must be initialized,
|
||||
* set up and have performed both round one and two.
|
||||
* \param buf The buffer to write the derived secret to. This must
|
||||
* be a writable buffer of length \p len Bytes.
|
||||
* \param len The length of \p buf in Bytes.
|
||||
* \param olen The address at which to store the total number of bytes
|
||||
* written to \p buf. This must not be \c NULL.
|
||||
* \param f_rng The RNG function to use. This must not be \c NULL.
|
||||
* \param p_rng The RNG parameter to be passed to \p f_rng. This
|
||||
* may be \c NULL if \p f_rng doesn't use a context.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_ecjpake_write_shared_key(mbedtls_ecjpake_context *ctx,
|
||||
unsigned char *buf, size_t len, size_t *olen,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng);
|
||||
|
||||
/**
|
||||
* \brief This clears an ECJPAKE context and frees any
|
||||
* embedded data structure.
|
||||
*
|
||||
* \param ctx The ECJPAKE context to free. This may be \c NULL,
|
||||
* in which case this function does nothing. If it is not
|
||||
* \c NULL, it must point to an initialized ECJPAKE context.
|
||||
*/
|
||||
void mbedtls_ecjpake_free(mbedtls_ecjpake_context *ctx);
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if a test failed
|
||||
*/
|
||||
int mbedtls_ecjpake_self_test(int verbose);
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* ecjpake.h */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,273 +0,0 @@
|
||||
/**
|
||||
* \file entropy.h
|
||||
*
|
||||
* \brief Entropy accumulator implementation
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_ENTROPY_H
|
||||
#define MBEDTLS_ENTROPY_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "md.h"
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA_512) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
|
||||
#define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR
|
||||
#define MBEDTLS_ENTROPY_MD MBEDTLS_MD_SHA512
|
||||
#define MBEDTLS_ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */
|
||||
#else
|
||||
#if defined(PSA_WANT_ALG_SHA_256)
|
||||
#define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR
|
||||
#define MBEDTLS_ENTROPY_MD MBEDTLS_MD_SHA256
|
||||
#define MBEDTLS_ENTROPY_BLOCK_SIZE 32 /**< Block size of entropy accumulator (SHA-256) */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
#include "mbedtls/threading.h"
|
||||
#endif
|
||||
|
||||
|
||||
/** Critical entropy source failure. */
|
||||
#define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED -0x003C
|
||||
/** No more sources can be added. */
|
||||
#define MBEDTLS_ERR_ENTROPY_MAX_SOURCES -0x003E
|
||||
/** No sources have been added to poll. */
|
||||
#define MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED -0x0040
|
||||
/** No strong sources have been added to poll. */
|
||||
#define MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE -0x003D
|
||||
/** Read/write error in file. */
|
||||
#define MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR -0x003F
|
||||
|
||||
/**
|
||||
* \name SECTION: Module settings
|
||||
*
|
||||
* The configuration options you can set for this module are in this section.
|
||||
* Either change them in mbedtls_config.h or define them on the compiler command line.
|
||||
* \{
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_ENTROPY_MAX_SOURCES)
|
||||
#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_ENTROPY_MAX_GATHER)
|
||||
#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */
|
||||
#endif
|
||||
|
||||
/** \} name SECTION: Module settings */
|
||||
|
||||
#define MBEDTLS_ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */
|
||||
#define MBEDTLS_ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_MAX_SOURCES
|
||||
|
||||
#define MBEDTLS_ENTROPY_SOURCE_STRONG 1 /**< Entropy source is strong */
|
||||
#define MBEDTLS_ENTROPY_SOURCE_WEAK 0 /**< Entropy source is weak */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Entropy poll callback pointer
|
||||
*
|
||||
* \param data Callback-specific data pointer
|
||||
* \param output Data to fill
|
||||
* \param len Maximum size to provide
|
||||
* \param olen The actual amount of bytes put into the buffer (Can be 0)
|
||||
*
|
||||
* \return 0 if no critical failures occurred,
|
||||
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED otherwise
|
||||
*/
|
||||
typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, size_t len,
|
||||
size_t *olen);
|
||||
|
||||
/**
|
||||
* \brief Entropy source state
|
||||
*/
|
||||
typedef struct mbedtls_entropy_source_state {
|
||||
mbedtls_entropy_f_source_ptr MBEDTLS_PRIVATE(f_source); /**< The entropy source callback */
|
||||
void *MBEDTLS_PRIVATE(p_source); /**< The callback data pointer */
|
||||
size_t MBEDTLS_PRIVATE(size); /**< Amount received in bytes */
|
||||
size_t MBEDTLS_PRIVATE(threshold); /**< Minimum bytes required before release */
|
||||
int MBEDTLS_PRIVATE(strong); /**< Is the source strong? */
|
||||
}
|
||||
mbedtls_entropy_source_state;
|
||||
|
||||
/**
|
||||
* \brief Entropy context structure
|
||||
*/
|
||||
typedef struct mbedtls_entropy_context {
|
||||
mbedtls_md_context_t MBEDTLS_PRIVATE(accumulator);
|
||||
int MBEDTLS_PRIVATE(accumulator_started); /* 0 after init.
|
||||
* 1 after the first update.
|
||||
* -1 after free. */
|
||||
int MBEDTLS_PRIVATE(source_count); /* Number of entries used in source. */
|
||||
mbedtls_entropy_source_state MBEDTLS_PRIVATE(source)[MBEDTLS_ENTROPY_MAX_SOURCES];
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_threading_mutex_t MBEDTLS_PRIVATE(mutex); /*!< mutex */
|
||||
#endif
|
||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||
int MBEDTLS_PRIVATE(initial_entropy_run);
|
||||
#endif
|
||||
}
|
||||
mbedtls_entropy_context;
|
||||
|
||||
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
|
||||
/**
|
||||
* \brief Platform-specific entropy poll callback
|
||||
*/
|
||||
int mbedtls_platform_entropy_poll(void *data,
|
||||
unsigned char *output, size_t len, size_t *olen);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Initialize the context
|
||||
*
|
||||
* \param ctx Entropy context to initialize
|
||||
*/
|
||||
void mbedtls_entropy_init(mbedtls_entropy_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Free the data in the context
|
||||
*
|
||||
* \param ctx Entropy context to free
|
||||
*/
|
||||
void mbedtls_entropy_free(mbedtls_entropy_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Adds an entropy source to poll
|
||||
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
|
||||
*
|
||||
* \param ctx Entropy context
|
||||
* \param f_source Entropy function
|
||||
* \param p_source Function data
|
||||
* \param threshold Minimum required from source before entropy is released
|
||||
* ( with mbedtls_entropy_func() ) (in bytes)
|
||||
* \param strong MBEDTLS_ENTROPY_SOURCE_STRONG or
|
||||
* MBEDTLS_ENTROPY_SOURCE_WEAK.
|
||||
* At least one strong source needs to be added.
|
||||
* Weaker sources (such as the cycle counter) can be used as
|
||||
* a complement.
|
||||
*
|
||||
* \return 0 if successful or MBEDTLS_ERR_ENTROPY_MAX_SOURCES
|
||||
*/
|
||||
int mbedtls_entropy_add_source(mbedtls_entropy_context *ctx,
|
||||
mbedtls_entropy_f_source_ptr f_source, void *p_source,
|
||||
size_t threshold, int strong);
|
||||
|
||||
/**
|
||||
* \brief Trigger an extra gather poll for the accumulator
|
||||
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
|
||||
*
|
||||
* \param ctx Entropy context
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
|
||||
*/
|
||||
int mbedtls_entropy_gather(mbedtls_entropy_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Retrieve entropy from the accumulator
|
||||
* (Maximum length: MBEDTLS_ENTROPY_BLOCK_SIZE)
|
||||
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
|
||||
*
|
||||
* \param data Entropy context
|
||||
* \param output Buffer to fill
|
||||
* \param len Number of bytes desired, must be at most MBEDTLS_ENTROPY_BLOCK_SIZE
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
|
||||
*/
|
||||
int mbedtls_entropy_func(void *data, unsigned char *output, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Add data to the accumulator manually
|
||||
* (Thread-safe if MBEDTLS_THREADING_C is enabled)
|
||||
*
|
||||
* \param ctx Entropy context
|
||||
* \param data Data to add
|
||||
* \param len Length of data
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int mbedtls_entropy_update_manual(mbedtls_entropy_context *ctx,
|
||||
const unsigned char *data, size_t len);
|
||||
|
||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||
/**
|
||||
* \brief Trigger an update of the seed file in NV by using the
|
||||
* current entropy pool.
|
||||
*
|
||||
* \param ctx Entropy context
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int mbedtls_entropy_update_nv_seed(mbedtls_entropy_context *ctx);
|
||||
#endif /* MBEDTLS_ENTROPY_NV_SEED */
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
/**
|
||||
* \brief Write a seed file
|
||||
*
|
||||
* \param ctx Entropy context
|
||||
* \param path Name of the file
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, or
|
||||
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
|
||||
*/
|
||||
int mbedtls_entropy_write_seed_file(mbedtls_entropy_context *ctx, const char *path);
|
||||
|
||||
/**
|
||||
* \brief Read and update a seed file. Seed is added to this
|
||||
* instance. No more than MBEDTLS_ENTROPY_MAX_SEED_SIZE bytes are
|
||||
* read from the seed file. The rest is ignored.
|
||||
*
|
||||
* \param ctx Entropy context
|
||||
* \param path Name of the file
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error,
|
||||
* MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
|
||||
*/
|
||||
int mbedtls_entropy_update_seed_file(mbedtls_entropy_context *ctx, const char *path);
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* This module self-test also calls the entropy self-test,
|
||||
* mbedtls_entropy_source_self_test();
|
||||
*
|
||||
* \return 0 if successful, or 1 if a test failed
|
||||
*/
|
||||
int mbedtls_entropy_self_test(int verbose);
|
||||
|
||||
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* Verifies the integrity of the hardware entropy source
|
||||
* provided by the function 'mbedtls_hardware_poll()'.
|
||||
*
|
||||
* Note this is the only hardware entropy source that is known
|
||||
* at link time, and other entropy sources configured
|
||||
* dynamically at runtime by the function
|
||||
* mbedtls_entropy_add_source() will not be tested.
|
||||
*
|
||||
* \return 0 if successful, or 1 if a test failed
|
||||
*/
|
||||
int mbedtls_entropy_source_self_test(int verbose);
|
||||
#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* entropy.h */
|
||||
@@ -1,159 +0,0 @@
|
||||
/**
|
||||
* \file error_common.h
|
||||
*
|
||||
* \brief Error codes
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_ERROR_COMMON_H
|
||||
#define MBEDTLS_ERROR_COMMON_H
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* Error code layout.
|
||||
*
|
||||
* Currently we try to keep all error codes within the negative space of 16
|
||||
* bits signed integers to support all platforms (-0x0001 - -0x7FFF). In
|
||||
* addition we'd like to give two layers of information on the error if
|
||||
* possible.
|
||||
*
|
||||
* For that purpose the error codes are segmented in the following manner:
|
||||
*
|
||||
* 16 bit error code bit-segmentation
|
||||
*
|
||||
* 1 bit - Unused (sign bit)
|
||||
* 3 bits - High level module ID
|
||||
* 5 bits - Module-dependent error code
|
||||
* 7 bits - Low level module errors
|
||||
*
|
||||
* For historical reasons, low-level error codes are divided in even and odd,
|
||||
* even codes were assigned first, and -1 is reserved for other errors.
|
||||
*
|
||||
* Low-level module errors (0x0002-0x007E, 0x0001-0x007F)
|
||||
*
|
||||
* Module Nr Codes assigned
|
||||
* ERROR 2 0x006E 0x0001
|
||||
* MPI 7 0x0002-0x0010
|
||||
* GCM 3 0x0012-0x0016 0x0013-0x0013
|
||||
* THREADING 3 0x001A-0x001E
|
||||
* AES 5 0x0020-0x0022 0x0021-0x0025
|
||||
* CAMELLIA 3 0x0024-0x0026 0x0027-0x0027
|
||||
* BASE64 2 0x002A-0x002C
|
||||
* OID 1 0x002E-0x002E 0x000B-0x000B
|
||||
* DES 2 0x0032-0x0032 0x0033-0x0033
|
||||
* CTR_DBRG 4 0x0034-0x003A
|
||||
* ENTROPY 3 0x003C-0x0040 0x003D-0x003F
|
||||
* NET 13 0x0042-0x0052 0x0043-0x0049
|
||||
* ARIA 4 0x0058-0x005E
|
||||
* ASN1 7 0x0060-0x006C
|
||||
* CMAC 1 0x007A-0x007A
|
||||
* PBKDF2 1 0x007C-0x007C
|
||||
* HMAC_DRBG 4 0x0003-0x0009
|
||||
* CCM 3 0x000D-0x0011
|
||||
* MD5 1 0x002F-0x002F
|
||||
* RIPEMD160 1 0x0031-0x0031
|
||||
* SHA1 1 0x0035-0x0035 0x0073-0x0073
|
||||
* SHA256 1 0x0037-0x0037 0x0074-0x0074
|
||||
* SHA512 1 0x0039-0x0039 0x0075-0x0075
|
||||
* SHA-3 1 0x0076-0x0076
|
||||
* CHACHA20 3 0x0051-0x0055
|
||||
* POLY1305 3 0x0057-0x005B
|
||||
* CHACHAPOLY 2 0x0054-0x0056
|
||||
* PLATFORM 2 0x0070-0x0072
|
||||
* LMS 5 0x0011-0x0019
|
||||
*
|
||||
* High-level module nr (3 bits - 0x0...-0x7...)
|
||||
* Name ID Nr of Errors
|
||||
* PEM 1 9
|
||||
* PKCS#12 1 4 (Started from top)
|
||||
* X509 2 20
|
||||
* PKCS5 2 4 (Started from top)
|
||||
* DHM 3 11
|
||||
* PK 3 15 (Started from top)
|
||||
* RSA 4 11
|
||||
* ECP 4 10 (Started from top)
|
||||
* MD 5 5
|
||||
* HKDF 5 1 (Started from top)
|
||||
* PKCS7 5 12 (Started from 0x5300)
|
||||
* SSL 5 2 (Started from 0x5F00)
|
||||
* CIPHER 6 8 (Started from 0x6080)
|
||||
* SSL 6 22 (Started from top, plus 0x6000)
|
||||
* SSL 7 20 (Started from 0x7000, gaps at
|
||||
* 0x7380, 0x7900-0x7980, 0x7A80-0x7E80)
|
||||
*
|
||||
* Module dependent error code (5 bits 0x.00.-0x.F8.)
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Generic error */
|
||||
#define MBEDTLS_ERR_ERROR_GENERIC_ERROR -0x0001
|
||||
/** This is a bug in the library */
|
||||
#define MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED -0x006E
|
||||
|
||||
/** Hardware accelerator failed */
|
||||
#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED -0x0070
|
||||
/** The requested feature is not supported by the platform */
|
||||
#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -0x0072
|
||||
|
||||
/**
|
||||
* \brief Combines a high-level and low-level error code together.
|
||||
*
|
||||
* Wrapper macro for mbedtls_error_add(). See that function for
|
||||
* more details.
|
||||
*/
|
||||
#define MBEDTLS_ERROR_ADD(high, low) \
|
||||
mbedtls_error_add(high, low, __FILE__, __LINE__)
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
/**
|
||||
* \brief Testing hook called before adding/combining two error codes together.
|
||||
* Only used when invasive testing is enabled via MBEDTLS_TEST_HOOKS.
|
||||
*/
|
||||
extern void (*mbedtls_test_hook_error_add)(int, int, const char *, int);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Combines a high-level and low-level error code together.
|
||||
*
|
||||
* This function can be called directly however it is usually
|
||||
* called via the #MBEDTLS_ERROR_ADD macro.
|
||||
*
|
||||
* While a value of zero is not a negative error code, it is still an
|
||||
* error code (that denotes success) and can be combined with both a
|
||||
* negative error code or another value of zero.
|
||||
*
|
||||
* \note When invasive testing is enabled via #MBEDTLS_TEST_HOOKS, also try to
|
||||
* call \link mbedtls_test_hook_error_add \endlink.
|
||||
*
|
||||
* \param high high-level error code. See error.h for more details.
|
||||
* \param low low-level error code. See error.h for more details.
|
||||
* \param file file where this error code addition occurred.
|
||||
* \param line line where this error code addition occurred.
|
||||
*/
|
||||
static inline int mbedtls_error_add(int high, int low,
|
||||
const char *file, int line)
|
||||
{
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
if (*mbedtls_test_hook_error_add != NULL) {
|
||||
(*mbedtls_test_hook_error_add)(high, low, file, line);
|
||||
}
|
||||
#endif
|
||||
(void) file;
|
||||
(void) line;
|
||||
|
||||
return high + low;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* error_common.h */
|
||||
@@ -1,377 +0,0 @@
|
||||
/**
|
||||
* \file gcm.h
|
||||
*
|
||||
* \brief This file contains GCM definitions and functions.
|
||||
*
|
||||
* The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined
|
||||
* in <em>D. McGrew, J. Viega, The Galois/Counter Mode of Operation
|
||||
* (GCM), Natl. Inst. Stand. Technol.</em>
|
||||
*
|
||||
* For more information on GCM, see <em>NIST SP 800-38D: Recommendation for
|
||||
* Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC</em>.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_GCM_H
|
||||
#define MBEDTLS_GCM_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include "mbedtls/cipher.h"
|
||||
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_C)
|
||||
#include "mbedtls/block_cipher.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MBEDTLS_GCM_ENCRYPT 1
|
||||
#define MBEDTLS_GCM_DECRYPT 0
|
||||
|
||||
/** Authenticated decryption failed. */
|
||||
#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012
|
||||
/** Bad input parameters to function. */
|
||||
#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014
|
||||
/** An output buffer is too small. */
|
||||
#define MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL -0x0016
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_GCM_LARGE_TABLE)
|
||||
#define MBEDTLS_GCM_HTABLE_SIZE 256
|
||||
#else
|
||||
#define MBEDTLS_GCM_HTABLE_SIZE 16
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The GCM context structure.
|
||||
*/
|
||||
typedef struct mbedtls_gcm_context {
|
||||
#if defined(MBEDTLS_BLOCK_CIPHER_C)
|
||||
mbedtls_block_cipher_context_t MBEDTLS_PRIVATE(block_cipher_ctx); /*!< The cipher context used. */
|
||||
#else
|
||||
mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */
|
||||
#endif
|
||||
uint64_t MBEDTLS_PRIVATE(H)[MBEDTLS_GCM_HTABLE_SIZE][2]; /*!< Precalculated HTable. */
|
||||
uint64_t MBEDTLS_PRIVATE(len); /*!< The total length of the encrypted data. */
|
||||
uint64_t MBEDTLS_PRIVATE(add_len); /*!< The total length of the additional data. */
|
||||
unsigned char MBEDTLS_PRIVATE(base_ectr)[16]; /*!< The first ECTR for tag. */
|
||||
unsigned char MBEDTLS_PRIVATE(y)[16]; /*!< The Y working value. */
|
||||
unsigned char MBEDTLS_PRIVATE(buf)[16]; /*!< The buf working value. */
|
||||
unsigned char MBEDTLS_PRIVATE(mode); /*!< The operation to perform:
|
||||
#MBEDTLS_GCM_ENCRYPT or
|
||||
#MBEDTLS_GCM_DECRYPT. */
|
||||
unsigned char MBEDTLS_PRIVATE(acceleration); /*!< The acceleration to use. */
|
||||
}
|
||||
mbedtls_gcm_context;
|
||||
|
||||
/**
|
||||
* \brief This function initializes the specified GCM context,
|
||||
* to make references valid, and prepares the context
|
||||
* for mbedtls_gcm_setkey() or mbedtls_gcm_free().
|
||||
*
|
||||
* The function does not bind the GCM context to a particular
|
||||
* cipher, nor set the key. For this purpose, use
|
||||
* mbedtls_gcm_setkey().
|
||||
*
|
||||
* \param ctx The GCM context to initialize. This must not be \c NULL.
|
||||
*/
|
||||
void mbedtls_gcm_init(mbedtls_gcm_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function associates a GCM context with a
|
||||
* cipher algorithm and a key.
|
||||
*
|
||||
* \param ctx The GCM context. This must be initialized.
|
||||
* \param cipher The 128-bit block cipher to use.
|
||||
* \param key The encryption key. This must be a readable buffer of at
|
||||
* least \p keybits bits.
|
||||
* \param keybits The key size in bits. Valid options are:
|
||||
* <ul><li>128 bits</li>
|
||||
* <li>192 bits</li>
|
||||
* <li>256 bits</li></ul>
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A cipher-specific error code on failure.
|
||||
*/
|
||||
int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx,
|
||||
mbedtls_cipher_id_t cipher,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits);
|
||||
|
||||
/**
|
||||
* \brief This function performs GCM encryption or decryption of a buffer.
|
||||
*
|
||||
* \note The output buffer \p output can be the same as the input
|
||||
* buffer \p input. If \p output is greater than \p input, they
|
||||
* cannot overlap.
|
||||
*
|
||||
* \warning When this function performs a decryption, it outputs the
|
||||
* authentication tag and does not verify that the data is
|
||||
* authentic. You should use this function to perform encryption
|
||||
* only. For decryption, use mbedtls_gcm_auth_decrypt() instead.
|
||||
*
|
||||
* \param ctx The GCM context to use for encryption or decryption. This
|
||||
* must be initialized.
|
||||
* \param mode The operation to perform:
|
||||
* - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption.
|
||||
* The ciphertext is written to \p output and the
|
||||
* authentication tag is written to \p tag.
|
||||
* - #MBEDTLS_GCM_DECRYPT to perform decryption.
|
||||
* The plaintext is written to \p output and the
|
||||
* authentication tag is written to \p tag.
|
||||
* Note that this mode is not recommended, because it does
|
||||
* not verify the authenticity of the data. For this reason,
|
||||
* you should use mbedtls_gcm_auth_decrypt() instead of
|
||||
* calling this function in decryption mode.
|
||||
* \param length The length of the input data, which is equal to the length
|
||||
* of the output data.
|
||||
* \param iv The initialization vector. This must be a readable buffer of
|
||||
* at least \p iv_len Bytes.
|
||||
* \param iv_len The length of the IV.
|
||||
* \param add The buffer holding the additional data. This must be of at
|
||||
* least that size in Bytes.
|
||||
* \param add_len The length of the additional data.
|
||||
* \param input The buffer holding the input data. If \p length is greater
|
||||
* than zero, this must be a readable buffer of at least that
|
||||
* size in Bytes.
|
||||
* \param output The buffer for holding the output data. If \p length is greater
|
||||
* than zero, this must be a writable buffer of at least that
|
||||
* size in Bytes.
|
||||
* \param tag_len The length of the tag to generate.
|
||||
* \param tag The buffer for holding the tag. This must be a writable
|
||||
* buffer of at least \p tag_len Bytes.
|
||||
*
|
||||
* \return \c 0 if the encryption or decryption was performed
|
||||
* successfully. Note that in #MBEDTLS_GCM_DECRYPT mode,
|
||||
* this does not indicate that the data is authentic.
|
||||
* \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
|
||||
* not valid or a cipher-specific error code if the encryption
|
||||
* or decryption failed.
|
||||
*/
|
||||
int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len,
|
||||
const unsigned char *add,
|
||||
size_t add_len,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t tag_len,
|
||||
unsigned char *tag);
|
||||
|
||||
/**
|
||||
* \brief This function performs a GCM authenticated decryption of a
|
||||
* buffer.
|
||||
*
|
||||
* \note The output buffer \p output can be the same as the input
|
||||
* buffer \p input. If \p output is greater than \p input, they
|
||||
* cannot overlap.
|
||||
*
|
||||
* \param ctx The GCM context. This must be initialized.
|
||||
* \param length The length of the ciphertext to decrypt, which is also
|
||||
* the length of the decrypted plaintext.
|
||||
* \param iv The initialization vector. This must be a readable buffer
|
||||
* of at least \p iv_len Bytes.
|
||||
* \param iv_len The length of the IV.
|
||||
* \param add The buffer holding the additional data. This must be of at
|
||||
* least that size in Bytes.
|
||||
* \param add_len The length of the additional data.
|
||||
* \param tag The buffer holding the tag to verify. This must be a
|
||||
* readable buffer of at least \p tag_len Bytes.
|
||||
* \param tag_len The length of the tag to verify.
|
||||
* \param input The buffer holding the ciphertext. If \p length is greater
|
||||
* than zero, this must be a readable buffer of at least that
|
||||
* size.
|
||||
* \param output The buffer for holding the decrypted plaintext. If \p length
|
||||
* is greater than zero, this must be a writable buffer of at
|
||||
* least that size.
|
||||
*
|
||||
* \return \c 0 if successful and authenticated.
|
||||
* \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match.
|
||||
* \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
|
||||
* not valid or a cipher-specific error code if the decryption
|
||||
* failed.
|
||||
*/
|
||||
int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx,
|
||||
size_t length,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len,
|
||||
const unsigned char *add,
|
||||
size_t add_len,
|
||||
const unsigned char *tag,
|
||||
size_t tag_len,
|
||||
const unsigned char *input,
|
||||
unsigned char *output);
|
||||
|
||||
/**
|
||||
* \brief This function starts a GCM encryption or decryption
|
||||
* operation.
|
||||
*
|
||||
* \param ctx The GCM context. This must be initialized.
|
||||
* \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or
|
||||
* #MBEDTLS_GCM_DECRYPT.
|
||||
* \param iv The initialization vector. This must be a readable buffer of
|
||||
* at least \p iv_len Bytes.
|
||||
* \param iv_len The length of the IV.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
|
||||
int mode,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len);
|
||||
|
||||
/**
|
||||
* \brief This function feeds an input buffer as associated data
|
||||
* (authenticated but not encrypted data) in a GCM
|
||||
* encryption or decryption operation.
|
||||
*
|
||||
* Call this function after mbedtls_gcm_starts() to pass
|
||||
* the associated data. If the associated data is empty,
|
||||
* you do not need to call this function. You may not
|
||||
* call this function after calling mbedtls_cipher_update().
|
||||
*
|
||||
* \param ctx The GCM context. This must have been started with
|
||||
* mbedtls_gcm_starts() and must not have yet received
|
||||
* any input with mbedtls_gcm_update().
|
||||
* \param add The buffer holding the additional data, or \c NULL
|
||||
* if \p add_len is \c 0.
|
||||
* \param add_len The length of the additional data. If \c 0,
|
||||
* \p add may be \c NULL.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx,
|
||||
const unsigned char *add,
|
||||
size_t add_len);
|
||||
|
||||
/**
|
||||
* \brief This function feeds an input buffer into an ongoing GCM
|
||||
* encryption or decryption operation.
|
||||
*
|
||||
* You may call this function zero, one or more times
|
||||
* to pass successive parts of the input: the plaintext to
|
||||
* encrypt, or the ciphertext (not including the tag) to
|
||||
* decrypt. After the last part of the input, call
|
||||
* mbedtls_gcm_finish().
|
||||
*
|
||||
* This function may produce output in one of the following
|
||||
* ways:
|
||||
* - Immediate output: the output length is always equal
|
||||
* to the input length.
|
||||
* - Buffered output: the output consists of a whole number
|
||||
* of 16-byte blocks. If the total input length so far
|
||||
* (not including associated data) is 16 \* *B* + *A*
|
||||
* with *A* < 16 then the total output length is 16 \* *B*.
|
||||
*
|
||||
* In particular:
|
||||
* - It is always correct to call this function with
|
||||
* \p output_size >= \p input_length + 15.
|
||||
* - If \p input_length is a multiple of 16 for all the calls
|
||||
* to this function during an operation, then it is
|
||||
* correct to use \p output_size = \p input_length.
|
||||
*
|
||||
* \note The output buffer \p output can be the same as the input
|
||||
* buffer \p input. If \p output is greater than \p input, they
|
||||
* cannot overlap.
|
||||
*
|
||||
* \param ctx The GCM context. This must be initialized.
|
||||
* \param input The buffer holding the input data. If \p input_length
|
||||
* is greater than zero, this must be a readable buffer
|
||||
* of at least \p input_length bytes.
|
||||
* \param input_length The length of the input data in bytes.
|
||||
* \param output The buffer for the output data. If \p output_size
|
||||
* is greater than zero, this must be a writable buffer of
|
||||
* of at least \p output_size bytes.
|
||||
* \param output_size The size of the output buffer in bytes.
|
||||
* See the function description regarding the output size.
|
||||
* \param output_length On success, \p *output_length contains the actual
|
||||
* length of the output written in \p output.
|
||||
* On failure, the content of \p *output_length is
|
||||
* unspecified.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure:
|
||||
* total input length too long,
|
||||
* unsupported input/output buffer overlap detected,
|
||||
* or \p output_size too small.
|
||||
*/
|
||||
int mbedtls_gcm_update(mbedtls_gcm_context *ctx,
|
||||
const unsigned char *input, size_t input_length,
|
||||
unsigned char *output, size_t output_size,
|
||||
size_t *output_length);
|
||||
|
||||
/**
|
||||
* \brief This function finishes the GCM operation and generates
|
||||
* the authentication tag.
|
||||
*
|
||||
* It wraps up the GCM stream, and generates the
|
||||
* tag. The tag can have a maximum length of 16 Bytes.
|
||||
*
|
||||
* \param ctx The GCM context. This must be initialized.
|
||||
* \param tag The buffer for holding the tag. This must be a writable
|
||||
* buffer of at least \p tag_len Bytes.
|
||||
* \param tag_len The length of the tag to generate. This must be at least
|
||||
* four.
|
||||
* \param output The buffer for the final output.
|
||||
* If \p output_size is nonzero, this must be a writable
|
||||
* buffer of at least \p output_size bytes.
|
||||
* \param output_size The size of the \p output buffer in bytes.
|
||||
* This must be large enough for the output that
|
||||
* mbedtls_gcm_update() has not produced. In particular:
|
||||
* - If mbedtls_gcm_update() produces immediate output,
|
||||
* or if the total input size is a multiple of \c 16,
|
||||
* then mbedtls_gcm_finish() never produces any output,
|
||||
* so \p output_size can be \c 0.
|
||||
* - \p output_size never needs to be more than \c 15.
|
||||
* \param output_length On success, \p *output_length contains the actual
|
||||
* length of the output written in \p output.
|
||||
* On failure, the content of \p *output_length is
|
||||
* unspecified.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure:
|
||||
* invalid value of \p tag_len,
|
||||
* or \p output_size too small.
|
||||
*/
|
||||
int mbedtls_gcm_finish(mbedtls_gcm_context *ctx,
|
||||
unsigned char *output, size_t output_size,
|
||||
size_t *output_length,
|
||||
unsigned char *tag, size_t tag_len);
|
||||
|
||||
/**
|
||||
* \brief This function clears a GCM context and the underlying
|
||||
* cipher sub-context.
|
||||
*
|
||||
* \param ctx The GCM context to clear. If this is \c NULL, the call has
|
||||
* no effect. Otherwise, this must be initialized.
|
||||
*/
|
||||
void mbedtls_gcm_free(mbedtls_gcm_context *ctx);
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
/**
|
||||
* \brief The GCM checkup routine.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c 1 on failure.
|
||||
*/
|
||||
int mbedtls_gcm_self_test(int verbose);
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* gcm.h */
|
||||
@@ -1,124 +0,0 @@
|
||||
/**
|
||||
* \file hkdf.h
|
||||
*
|
||||
* \brief This file contains the HKDF interface.
|
||||
*
|
||||
* The HMAC-based Extract-and-Expand Key Derivation Function (HKDF) is
|
||||
* specified by RFC 5869.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_HKDF_H
|
||||
#define MBEDTLS_HKDF_H
|
||||
|
||||
#include "mbedtls/build_info.h"
|
||||
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
/**
|
||||
* \name HKDF Error codes
|
||||
* \{
|
||||
*/
|
||||
/** Bad input parameters to function. */
|
||||
#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA -0x5F80
|
||||
/** \} name */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief This is the HMAC-based Extract-and-Expand Key Derivation Function
|
||||
* (HKDF).
|
||||
*
|
||||
* \param md A hash function; md.size denotes the length of the hash
|
||||
* function output in bytes.
|
||||
* \param salt An optional salt value (a non-secret random value);
|
||||
* if the salt is not provided, a string of all zeros of
|
||||
* md.size length is used as the salt.
|
||||
* \param salt_len The length in bytes of the optional \p salt.
|
||||
* \param ikm The input keying material.
|
||||
* \param ikm_len The length in bytes of \p ikm.
|
||||
* \param info An optional context and application specific information
|
||||
* string. This can be a zero-length string.
|
||||
* \param info_len The length of \p info in bytes.
|
||||
* \param okm The output keying material of \p okm_len bytes.
|
||||
* \param okm_len The length of the output keying material in bytes. This
|
||||
* must be less than or equal to 255 * md.size bytes.
|
||||
*
|
||||
* \return 0 on success.
|
||||
* \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
|
||||
* \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
|
||||
* MD layer.
|
||||
*/
|
||||
int mbedtls_hkdf(const mbedtls_md_info_t *md, const unsigned char *salt,
|
||||
size_t salt_len, const unsigned char *ikm, size_t ikm_len,
|
||||
const unsigned char *info, size_t info_len,
|
||||
unsigned char *okm, size_t okm_len);
|
||||
|
||||
/**
|
||||
* \brief Take the input keying material \p ikm and extract from it a
|
||||
* fixed-length pseudorandom key \p prk.
|
||||
*
|
||||
* \warning This function should only be used if the security of it has been
|
||||
* studied and established in that particular context (eg. TLS 1.3
|
||||
* key schedule). For standard HKDF security guarantees use
|
||||
* \c mbedtls_hkdf instead.
|
||||
*
|
||||
* \param md A hash function; md.size denotes the length of the
|
||||
* hash function output in bytes.
|
||||
* \param salt An optional salt value (a non-secret random value);
|
||||
* if the salt is not provided, a string of all zeros
|
||||
* of md.size length is used as the salt.
|
||||
* \param salt_len The length in bytes of the optional \p salt.
|
||||
* \param ikm The input keying material.
|
||||
* \param ikm_len The length in bytes of \p ikm.
|
||||
* \param[out] prk A pseudorandom key of at least md.size bytes.
|
||||
*
|
||||
* \return 0 on success.
|
||||
* \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
|
||||
* \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
|
||||
* MD layer.
|
||||
*/
|
||||
int mbedtls_hkdf_extract(const mbedtls_md_info_t *md,
|
||||
const unsigned char *salt, size_t salt_len,
|
||||
const unsigned char *ikm, size_t ikm_len,
|
||||
unsigned char *prk);
|
||||
|
||||
/**
|
||||
* \brief Expand the supplied \p prk into several additional pseudorandom
|
||||
* keys, which is the output of the HKDF.
|
||||
*
|
||||
* \warning This function should only be used if the security of it has been
|
||||
* studied and established in that particular context (eg. TLS 1.3
|
||||
* key schedule). For standard HKDF security guarantees use
|
||||
* \c mbedtls_hkdf instead.
|
||||
*
|
||||
* \param md A hash function; md.size denotes the length of the hash
|
||||
* function output in bytes.
|
||||
* \param prk A pseudorandom key of at least md.size bytes. \p prk is
|
||||
* usually the output from the HKDF extract step.
|
||||
* \param prk_len The length in bytes of \p prk.
|
||||
* \param info An optional context and application specific information
|
||||
* string. This can be a zero-length string.
|
||||
* \param info_len The length of \p info in bytes.
|
||||
* \param okm The output keying material of \p okm_len bytes.
|
||||
* \param okm_len The length of the output keying material in bytes. This
|
||||
* must be less than or equal to 255 * md.size bytes.
|
||||
*
|
||||
* \return 0 on success.
|
||||
* \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
|
||||
* \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
|
||||
* MD layer.
|
||||
*/
|
||||
int mbedtls_hkdf_expand(const mbedtls_md_info_t *md, const unsigned char *prk,
|
||||
size_t prk_len, const unsigned char *info,
|
||||
size_t info_len, unsigned char *okm, size_t okm_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* hkdf.h */
|
||||
@@ -1,434 +0,0 @@
|
||||
/**
|
||||
* \file hmac_drbg.h
|
||||
*
|
||||
* \brief The HMAC_DRBG pseudorandom generator.
|
||||
*
|
||||
* This module implements the HMAC_DRBG pseudorandom generator described
|
||||
* in <em>NIST SP 800-90A: Recommendation for Random Number Generation Using
|
||||
* Deterministic Random Bit Generators</em>.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_HMAC_DRBG_H
|
||||
#define MBEDTLS_HMAC_DRBG_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
#include "mbedtls/threading.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Error codes
|
||||
*/
|
||||
/** Too many random requested in single call. */
|
||||
#define MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG -0x0003
|
||||
/** Input too large (Entropy + additional). */
|
||||
#define MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG -0x0005
|
||||
/** Read/write error in file. */
|
||||
#define MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR -0x0007
|
||||
/** The entropy source failed. */
|
||||
#define MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED -0x0009
|
||||
|
||||
/**
|
||||
* \name SECTION: Module settings
|
||||
*
|
||||
* The configuration options you can set for this module are in this section.
|
||||
* Either change them in mbedtls_config.h or define them on the compiler command line.
|
||||
* \{
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_HMAC_DRBG_RESEED_INTERVAL)
|
||||
#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_HMAC_DRBG_MAX_INPUT)
|
||||
#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_HMAC_DRBG_MAX_REQUEST)
|
||||
#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT)
|
||||
#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
|
||||
#endif
|
||||
|
||||
/** \} name SECTION: Module settings */
|
||||
|
||||
#define MBEDTLS_HMAC_DRBG_PR_OFF 0 /**< No prediction resistance */
|
||||
#define MBEDTLS_HMAC_DRBG_PR_ON 1 /**< Prediction resistance enabled */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* HMAC_DRBG context.
|
||||
*/
|
||||
typedef struct mbedtls_hmac_drbg_context {
|
||||
/* Working state: the key K is not stored explicitly,
|
||||
* but is implied by the HMAC context */
|
||||
mbedtls_md_context_t MBEDTLS_PRIVATE(md_ctx); /*!< HMAC context (inc. K) */
|
||||
unsigned char MBEDTLS_PRIVATE(V)[MBEDTLS_MD_MAX_SIZE]; /*!< V in the spec */
|
||||
int MBEDTLS_PRIVATE(reseed_counter); /*!< reseed counter */
|
||||
|
||||
/* Administrative state */
|
||||
size_t MBEDTLS_PRIVATE(entropy_len); /*!< entropy bytes grabbed on each (re)seed */
|
||||
int MBEDTLS_PRIVATE(prediction_resistance); /*!< enable prediction resistance (Automatic
|
||||
reseed before every random generation) */
|
||||
int MBEDTLS_PRIVATE(reseed_interval); /*!< reseed interval */
|
||||
|
||||
/* Callbacks */
|
||||
int(*MBEDTLS_PRIVATE(f_entropy))(void *, unsigned char *, size_t); /*!< entropy function */
|
||||
void *MBEDTLS_PRIVATE(p_entropy); /*!< context for the entropy function */
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* Invariant: the mutex is initialized if and only if
|
||||
* md_ctx->md_info != NULL. This means that the mutex is initialized
|
||||
* during the initial seeding in mbedtls_hmac_drbg_seed() or
|
||||
* mbedtls_hmac_drbg_seed_buf() and freed in mbedtls_ctr_drbg_free().
|
||||
*
|
||||
* Note that this invariant may change without notice. Do not rely on it
|
||||
* and do not access the mutex directly in application code.
|
||||
*/
|
||||
mbedtls_threading_mutex_t MBEDTLS_PRIVATE(mutex);
|
||||
#endif
|
||||
} mbedtls_hmac_drbg_context;
|
||||
|
||||
/**
|
||||
* \brief HMAC_DRBG context initialization.
|
||||
*
|
||||
* This function makes the context ready for mbedtls_hmac_drbg_seed(),
|
||||
* mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free().
|
||||
*
|
||||
* \note The reseed interval is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL
|
||||
* by default. Override this value by calling
|
||||
* mbedtls_hmac_drbg_set_reseed_interval().
|
||||
*
|
||||
* \param ctx HMAC_DRBG context to be initialized.
|
||||
*/
|
||||
void mbedtls_hmac_drbg_init(mbedtls_hmac_drbg_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief HMAC_DRBG initial seeding.
|
||||
*
|
||||
* Set the initial seed and set up the entropy source for future reseeds.
|
||||
*
|
||||
* A typical choice for the \p f_entropy and \p p_entropy parameters is
|
||||
* to use the entropy module:
|
||||
* - \p f_entropy is mbedtls_entropy_func();
|
||||
* - \p p_entropy is an instance of ::mbedtls_entropy_context initialized
|
||||
* with mbedtls_entropy_init() (which registers the platform's default
|
||||
* entropy sources).
|
||||
*
|
||||
* You can provide a personalization string in addition to the
|
||||
* entropy source, to make this instantiation as unique as possible.
|
||||
*
|
||||
* \note By default, the security strength as defined by NIST is:
|
||||
* - 128 bits if \p md_info is SHA-1;
|
||||
* - 192 bits if \p md_info is SHA-224;
|
||||
* - 256 bits if \p md_info is SHA-256, SHA-384 or SHA-512.
|
||||
* Note that SHA-256 is just as efficient as SHA-224.
|
||||
* The security strength can be reduced if a smaller
|
||||
* entropy length is set with
|
||||
* mbedtls_hmac_drbg_set_entropy_len().
|
||||
*
|
||||
* \note The default entropy length is the security strength
|
||||
* (converted from bits to bytes). You can override
|
||||
* it by calling mbedtls_hmac_drbg_set_entropy_len().
|
||||
*
|
||||
* \note During the initial seeding, this function calls
|
||||
* the entropy source to obtain a nonce
|
||||
* whose length is half the entropy length.
|
||||
*/
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/**
|
||||
* \note When Mbed TLS is built with threading support,
|
||||
* after this function returns successfully,
|
||||
* it is safe to call mbedtls_hmac_drbg_random()
|
||||
* from multiple threads. Other operations, including
|
||||
* reseeding, are not thread-safe.
|
||||
*/
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
/**
|
||||
* \param ctx HMAC_DRBG context to be seeded.
|
||||
* \param md_info MD algorithm to use for HMAC_DRBG.
|
||||
* \param f_entropy The entropy callback, taking as arguments the
|
||||
* \p p_entropy context, the buffer to fill, and the
|
||||
* length of the buffer.
|
||||
* \p f_entropy is always called with a length that is
|
||||
* less than or equal to the entropy length.
|
||||
* \param p_entropy The entropy context to pass to \p f_entropy.
|
||||
* \param custom The personalization string.
|
||||
* This can be \c NULL, in which case the personalization
|
||||
* string is empty regardless of the value of \p len.
|
||||
* \param len The length of the personalization string.
|
||||
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
|
||||
* and also at most
|
||||
* #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \c entropy_len * 3 / 2
|
||||
* where \c entropy_len is the entropy length
|
||||
* described above.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is
|
||||
* invalid.
|
||||
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough
|
||||
* memory to allocate context data.
|
||||
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
|
||||
* if the call to \p f_entropy failed.
|
||||
*/
|
||||
int mbedtls_hmac_drbg_seed(mbedtls_hmac_drbg_context *ctx,
|
||||
const mbedtls_md_info_t *md_info,
|
||||
int (*f_entropy)(void *, unsigned char *, size_t),
|
||||
void *p_entropy,
|
||||
const unsigned char *custom,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* \brief Initialisation of simplified HMAC_DRBG (never reseeds).
|
||||
*
|
||||
* This function is meant for use in algorithms that need a pseudorandom
|
||||
* input such as deterministic ECDSA.
|
||||
*/
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/**
|
||||
* \note When Mbed TLS is built with threading support,
|
||||
* after this function returns successfully,
|
||||
* it is safe to call mbedtls_hmac_drbg_random()
|
||||
* from multiple threads. Other operations, including
|
||||
* reseeding, are not thread-safe.
|
||||
*/
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
/**
|
||||
* \param ctx HMAC_DRBG context to be initialised.
|
||||
* \param md_info MD algorithm to use for HMAC_DRBG.
|
||||
* \param data Concatenation of the initial entropy string and
|
||||
* the additional data.
|
||||
* \param data_len Length of \p data in bytes.
|
||||
*
|
||||
* \return \c 0 if successful. or
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is
|
||||
* invalid.
|
||||
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough
|
||||
* memory to allocate context data.
|
||||
*/
|
||||
int mbedtls_hmac_drbg_seed_buf(mbedtls_hmac_drbg_context *ctx,
|
||||
const mbedtls_md_info_t *md_info,
|
||||
const unsigned char *data, size_t data_len);
|
||||
|
||||
/**
|
||||
* \brief This function turns prediction resistance on or off.
|
||||
* The default value is off.
|
||||
*
|
||||
* \note If enabled, entropy is gathered at the beginning of
|
||||
* every call to mbedtls_hmac_drbg_random_with_add()
|
||||
* or mbedtls_hmac_drbg_random().
|
||||
* Only use this if your entropy source has sufficient
|
||||
* throughput.
|
||||
*
|
||||
* \param ctx The HMAC_DRBG context.
|
||||
* \param resistance #MBEDTLS_HMAC_DRBG_PR_ON or #MBEDTLS_HMAC_DRBG_PR_OFF.
|
||||
*/
|
||||
void mbedtls_hmac_drbg_set_prediction_resistance(mbedtls_hmac_drbg_context *ctx,
|
||||
int resistance);
|
||||
|
||||
/**
|
||||
* \brief This function sets the amount of entropy grabbed on each
|
||||
* seed or reseed.
|
||||
*
|
||||
* See the documentation of mbedtls_hmac_drbg_seed() for the default value.
|
||||
*
|
||||
* \param ctx The HMAC_DRBG context.
|
||||
* \param len The amount of entropy to grab, in bytes.
|
||||
*/
|
||||
void mbedtls_hmac_drbg_set_entropy_len(mbedtls_hmac_drbg_context *ctx,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* \brief Set the reseed interval.
|
||||
*
|
||||
* The reseed interval is the number of calls to mbedtls_hmac_drbg_random()
|
||||
* or mbedtls_hmac_drbg_random_with_add() after which the entropy function
|
||||
* is called again.
|
||||
*
|
||||
* The default value is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL.
|
||||
*
|
||||
* \param ctx The HMAC_DRBG context.
|
||||
* \param interval The reseed interval.
|
||||
*/
|
||||
void mbedtls_hmac_drbg_set_reseed_interval(mbedtls_hmac_drbg_context *ctx,
|
||||
int interval);
|
||||
|
||||
/**
|
||||
* \brief This function updates the state of the HMAC_DRBG context.
|
||||
*
|
||||
* \note This function is not thread-safe. It is not safe
|
||||
* to call this function if another thread might be
|
||||
* concurrently obtaining random numbers from the same
|
||||
* context or updating or reseeding the same context.
|
||||
*
|
||||
* \param ctx The HMAC_DRBG context.
|
||||
* \param additional The data to update the state with.
|
||||
* If this is \c NULL, there is no additional data.
|
||||
* \param add_len Length of \p additional in bytes.
|
||||
* Unused if \p additional is \c NULL.
|
||||
*
|
||||
* \return \c 0 on success, or an error from the underlying
|
||||
* hash calculation.
|
||||
*/
|
||||
int mbedtls_hmac_drbg_update(mbedtls_hmac_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t add_len);
|
||||
|
||||
/**
|
||||
* \brief This function reseeds the HMAC_DRBG context, that is
|
||||
* extracts data from the entropy source.
|
||||
*
|
||||
* \note This function is not thread-safe. It is not safe
|
||||
* to call this function if another thread might be
|
||||
* concurrently obtaining random numbers from the same
|
||||
* context or updating or reseeding the same context.
|
||||
*
|
||||
* \param ctx The HMAC_DRBG context.
|
||||
* \param additional Additional data to add to the state.
|
||||
* If this is \c NULL, there is no additional data
|
||||
* and \p len should be \c 0.
|
||||
* \param len The length of the additional data.
|
||||
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT
|
||||
* and also at most
|
||||
* #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \c entropy_len
|
||||
* where \c entropy_len is the entropy length
|
||||
* (see mbedtls_hmac_drbg_set_entropy_len()).
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
|
||||
* if a call to the entropy function failed.
|
||||
*/
|
||||
int mbedtls_hmac_drbg_reseed(mbedtls_hmac_drbg_context *ctx,
|
||||
const unsigned char *additional, size_t len);
|
||||
|
||||
/**
|
||||
* \brief This function updates an HMAC_DRBG instance with additional
|
||||
* data and uses it to generate random data.
|
||||
*
|
||||
* This function automatically reseeds if the reseed counter is exceeded
|
||||
* or prediction resistance is enabled.
|
||||
*
|
||||
* \note This function is not thread-safe. It is not safe
|
||||
* to call this function if another thread might be
|
||||
* concurrently obtaining random numbers from the same
|
||||
* context or updating or reseeding the same context.
|
||||
*
|
||||
* \param p_rng The HMAC_DRBG context. This must be a pointer to a
|
||||
* #mbedtls_hmac_drbg_context structure.
|
||||
* \param output The buffer to fill.
|
||||
* \param output_len The length of the buffer in bytes.
|
||||
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
|
||||
* \param additional Additional data to update with.
|
||||
* If this is \c NULL, there is no additional data
|
||||
* and \p add_len should be \c 0.
|
||||
* \param add_len The length of the additional data.
|
||||
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
|
||||
* if a call to the entropy source failed.
|
||||
* \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if
|
||||
* \p output_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
|
||||
* \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if
|
||||
* \p add_len > #MBEDTLS_HMAC_DRBG_MAX_INPUT.
|
||||
*/
|
||||
int mbedtls_hmac_drbg_random_with_add(void *p_rng,
|
||||
unsigned char *output, size_t output_len,
|
||||
const unsigned char *additional,
|
||||
size_t add_len);
|
||||
|
||||
/**
|
||||
* \brief This function uses HMAC_DRBG to generate random data.
|
||||
*
|
||||
* This function automatically reseeds if the reseed counter is exceeded
|
||||
* or prediction resistance is enabled.
|
||||
*/
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/**
|
||||
* \note When Mbed TLS is built with threading support,
|
||||
* it is safe to call mbedtls_ctr_drbg_random()
|
||||
* from multiple threads. Other operations, including
|
||||
* reseeding, are not thread-safe.
|
||||
*/
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
/**
|
||||
* \param p_rng The HMAC_DRBG context. This must be a pointer to a
|
||||
* #mbedtls_hmac_drbg_context structure.
|
||||
* \param output The buffer to fill.
|
||||
* \param out_len The length of the buffer in bytes.
|
||||
* This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
|
||||
* if a call to the entropy source failed.
|
||||
* \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if
|
||||
* \p out_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST.
|
||||
*/
|
||||
int mbedtls_hmac_drbg_random(void *p_rng, unsigned char *output, size_t out_len);
|
||||
|
||||
/**
|
||||
* \brief This function resets HMAC_DRBG context to the state immediately
|
||||
* after initial call of mbedtls_hmac_drbg_init().
|
||||
*
|
||||
* \param ctx The HMAC_DRBG context to free.
|
||||
*/
|
||||
void mbedtls_hmac_drbg_free(mbedtls_hmac_drbg_context *ctx);
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
/**
|
||||
* \brief This function writes a seed file.
|
||||
*
|
||||
* \param ctx The HMAC_DRBG context.
|
||||
* \param path The name of the file.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error.
|
||||
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on reseed
|
||||
* failure.
|
||||
*/
|
||||
int mbedtls_hmac_drbg_write_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path);
|
||||
|
||||
/**
|
||||
* \brief This function reads and updates a seed file. The seed
|
||||
* is added to this instance.
|
||||
*
|
||||
* \param ctx The HMAC_DRBG context.
|
||||
* \param path The name of the file.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error.
|
||||
* \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on
|
||||
* reseed failure.
|
||||
* \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if the existing
|
||||
* seed file is too large.
|
||||
*/
|
||||
int mbedtls_hmac_drbg_update_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path);
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
/**
|
||||
* \brief The HMAC_DRBG Checkup routine.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return \c 1 if the test failed.
|
||||
*/
|
||||
int mbedtls_hmac_drbg_self_test(int verbose);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* hmac_drbg.h */
|
||||
@@ -1,440 +0,0 @@
|
||||
/**
|
||||
* \file lms.h
|
||||
*
|
||||
* \brief This file provides an API for the LMS post-quantum-safe stateful-hash
|
||||
public-key signature scheme as defined in RFC8554 and NIST.SP.200-208.
|
||||
* This implementation currently only supports a single parameter set
|
||||
* MBEDTLS_LMS_SHA256_M32_H10 in order to reduce complexity. This is one
|
||||
* of the signature schemes recommended by the IETF draft SUIT standard
|
||||
* for IOT firmware upgrades (RFC9019).
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_LMS_H
|
||||
#define MBEDTLS_LMS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "mbedtls/private_access.h"
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#define MBEDTLS_ERR_LMS_BAD_INPUT_DATA -0x0011 /**< Bad data has been input to an LMS function */
|
||||
#define MBEDTLS_ERR_LMS_OUT_OF_PRIVATE_KEYS -0x0013 /**< Specified LMS key has utilised all of its private keys */
|
||||
#define MBEDTLS_ERR_LMS_VERIFY_FAILED -0x0015 /**< LMS signature verification failed */
|
||||
#define MBEDTLS_ERR_LMS_ALLOC_FAILED -0x0017 /**< LMS failed to allocate space for a private key */
|
||||
#define MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL -0x0019 /**< Input/output buffer is too small to contain requited data */
|
||||
|
||||
/* Currently only defined for SHA256, 32 is the max hash output size */
|
||||
#define MBEDTLS_LMOTS_N_HASH_LEN_MAX (32u)
|
||||
#define MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX (34u)
|
||||
#define MBEDTLS_LMOTS_N_HASH_LEN(type) ((type) == MBEDTLS_LMOTS_SHA256_N32_W8 ? 32u : 0)
|
||||
#define MBEDTLS_LMOTS_I_KEY_ID_LEN (16u)
|
||||
#define MBEDTLS_LMOTS_Q_LEAF_ID_LEN (4u)
|
||||
#define MBEDTLS_LMOTS_TYPE_LEN (4u)
|
||||
#define MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(type) ((type) == MBEDTLS_LMOTS_SHA256_N32_W8 ? 34u : 0)
|
||||
#define MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(type) (MBEDTLS_LMOTS_N_HASH_LEN(type))
|
||||
|
||||
#define MBEDTLS_LMOTS_SIG_LEN(type) (MBEDTLS_LMOTS_TYPE_LEN + \
|
||||
MBEDTLS_LMOTS_C_RANDOM_VALUE_LEN(type) + \
|
||||
(MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT(type) * \
|
||||
MBEDTLS_LMOTS_N_HASH_LEN(type)))
|
||||
|
||||
|
||||
#define MBEDTLS_LMS_TYPE_LEN (4)
|
||||
#define MBEDTLS_LMS_H_TREE_HEIGHT(type) ((type) == MBEDTLS_LMS_SHA256_M32_H10 ? 10u : 0)
|
||||
|
||||
/* The length of a hash output, Currently only implemented for SHA256.
|
||||
* Max is 32 bytes.
|
||||
*/
|
||||
#define MBEDTLS_LMS_M_NODE_BYTES(type) ((type) == MBEDTLS_LMS_SHA256_M32_H10 ? 32 : 0)
|
||||
#define MBEDTLS_LMS_M_NODE_BYTES_MAX 32
|
||||
|
||||
#define MBEDTLS_LMS_SIG_LEN(type, otstype) (MBEDTLS_LMOTS_Q_LEAF_ID_LEN + \
|
||||
MBEDTLS_LMOTS_SIG_LEN(otstype) + \
|
||||
MBEDTLS_LMS_TYPE_LEN + \
|
||||
(MBEDTLS_LMS_H_TREE_HEIGHT(type) * \
|
||||
MBEDTLS_LMS_M_NODE_BYTES(type)))
|
||||
|
||||
#define MBEDTLS_LMS_PUBLIC_KEY_LEN(type) (MBEDTLS_LMS_TYPE_LEN + \
|
||||
MBEDTLS_LMOTS_TYPE_LEN + \
|
||||
MBEDTLS_LMOTS_I_KEY_ID_LEN + \
|
||||
MBEDTLS_LMS_M_NODE_BYTES(type))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** The Identifier of the LMS parameter set, as per
|
||||
* https://www.iana.org/assignments/leighton-micali-signatures/leighton-micali-signatures.xhtml
|
||||
* We are only implementing a subset of the types, particularly H10, for the sake of simplicity.
|
||||
*/
|
||||
typedef enum {
|
||||
MBEDTLS_LMS_SHA256_M32_H10 = 0x6,
|
||||
} mbedtls_lms_algorithm_type_t;
|
||||
|
||||
/** The Identifier of the LMOTS parameter set, as per
|
||||
* https://www.iana.org/assignments/leighton-micali-signatures/leighton-micali-signatures.xhtml.
|
||||
* We are only implementing a subset of the types, particularly N32_W8, for the sake of simplicity.
|
||||
*/
|
||||
typedef enum {
|
||||
MBEDTLS_LMOTS_SHA256_N32_W8 = 4
|
||||
} mbedtls_lmots_algorithm_type_t;
|
||||
|
||||
/** LMOTS parameters structure.
|
||||
*
|
||||
* This contains the metadata associated with an LMOTS key, detailing the
|
||||
* algorithm type, the key ID, and the leaf identifier should be key be part of
|
||||
* a LMS key.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char MBEDTLS_PRIVATE(I_key_identifier[MBEDTLS_LMOTS_I_KEY_ID_LEN]); /*!< The key
|
||||
identifier. */
|
||||
unsigned char MBEDTLS_PRIVATE(q_leaf_identifier[MBEDTLS_LMOTS_Q_LEAF_ID_LEN]); /*!< Which
|
||||
leaf of the LMS key this is.
|
||||
0 if the key is not part of an LMS key. */
|
||||
mbedtls_lmots_algorithm_type_t MBEDTLS_PRIVATE(type); /*!< The LM-OTS key type identifier as
|
||||
per IANA. Only SHA256_N32_W8 is
|
||||
currently supported. */
|
||||
} mbedtls_lmots_parameters_t;
|
||||
|
||||
/** LMOTS public context structure.
|
||||
*
|
||||
* A LMOTS public key is a hash output, and the applicable parameter set.
|
||||
*
|
||||
* The context must be initialized before it is used. A public key must either
|
||||
* be imported or generated from a private context.
|
||||
*
|
||||
* \dot
|
||||
* digraph lmots_public_t {
|
||||
* UNINITIALIZED -> INIT [label="init"];
|
||||
* HAVE_PUBLIC_KEY -> INIT [label="free"];
|
||||
* INIT -> HAVE_PUBLIC_KEY [label="import_public_key"];
|
||||
* INIT -> HAVE_PUBLIC_KEY [label="calculate_public_key from private key"];
|
||||
* HAVE_PUBLIC_KEY -> HAVE_PUBLIC_KEY [label="export_public_key"];
|
||||
* }
|
||||
* \enddot
|
||||
*/
|
||||
typedef struct {
|
||||
mbedtls_lmots_parameters_t MBEDTLS_PRIVATE(params);
|
||||
unsigned char MBEDTLS_PRIVATE(public_key)[MBEDTLS_LMOTS_N_HASH_LEN_MAX];
|
||||
unsigned char MBEDTLS_PRIVATE(have_public_key); /*!< Whether the context contains a public key.
|
||||
Boolean values only. */
|
||||
} mbedtls_lmots_public_t;
|
||||
|
||||
#if defined(MBEDTLS_LMS_PRIVATE)
|
||||
/** LMOTS private context structure.
|
||||
*
|
||||
* A LMOTS private key is one hash output for each of digit of the digest +
|
||||
* checksum, and the applicable parameter set.
|
||||
*
|
||||
* The context must be initialized before it is used. A public key must either
|
||||
* be imported or generated from a private context.
|
||||
*
|
||||
* \dot
|
||||
* digraph lmots_public_t {
|
||||
* UNINITIALIZED -> INIT [label="init"];
|
||||
* HAVE_PRIVATE_KEY -> INIT [label="free"];
|
||||
* INIT -> HAVE_PRIVATE_KEY [label="generate_private_key"];
|
||||
* HAVE_PRIVATE_KEY -> INIT [label="sign"];
|
||||
* }
|
||||
* \enddot
|
||||
*/
|
||||
typedef struct {
|
||||
mbedtls_lmots_parameters_t MBEDTLS_PRIVATE(params);
|
||||
unsigned char MBEDTLS_PRIVATE(private_key)[MBEDTLS_LMOTS_P_SIG_DIGIT_COUNT_MAX][
|
||||
MBEDTLS_LMOTS_N_HASH_LEN_MAX];
|
||||
unsigned char MBEDTLS_PRIVATE(have_private_key); /*!< Whether the context contains a private key.
|
||||
Boolean values only. */
|
||||
} mbedtls_lmots_private_t;
|
||||
#endif /* defined(MBEDTLS_LMS_PRIVATE) */
|
||||
|
||||
|
||||
/** LMS parameters structure.
|
||||
*
|
||||
* This contains the metadata associated with an LMS key, detailing the
|
||||
* algorithm type, the type of the underlying OTS algorithm, and the key ID.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char MBEDTLS_PRIVATE(I_key_identifier[MBEDTLS_LMOTS_I_KEY_ID_LEN]); /*!< The key
|
||||
identifier. */
|
||||
mbedtls_lmots_algorithm_type_t MBEDTLS_PRIVATE(otstype); /*!< The LM-OTS key type identifier as
|
||||
per IANA. Only SHA256_N32_W8 is
|
||||
currently supported. */
|
||||
mbedtls_lms_algorithm_type_t MBEDTLS_PRIVATE(type); /*!< The LMS key type identifier as per
|
||||
IANA. Only SHA256_M32_H10 is currently
|
||||
supported. */
|
||||
} mbedtls_lms_parameters_t;
|
||||
|
||||
/** LMS public context structure.
|
||||
*
|
||||
* A LMS public key is the hash output that is the root of the Merkle tree, and
|
||||
* the applicable parameter set
|
||||
*
|
||||
* The context must be initialized before it is used. A public key must either
|
||||
* be imported or generated from a private context.
|
||||
*
|
||||
* \dot
|
||||
* digraph lms_public_t {
|
||||
* UNINITIALIZED -> INIT [label="init"];
|
||||
* HAVE_PUBLIC_KEY -> INIT [label="free"];
|
||||
* INIT -> HAVE_PUBLIC_KEY [label="import_public_key"];
|
||||
* INIT -> HAVE_PUBLIC_KEY [label="calculate_public_key from private key"];
|
||||
* HAVE_PUBLIC_KEY -> HAVE_PUBLIC_KEY [label="export_public_key"];
|
||||
* }
|
||||
* \enddot
|
||||
*/
|
||||
typedef struct {
|
||||
mbedtls_lms_parameters_t MBEDTLS_PRIVATE(params);
|
||||
unsigned char MBEDTLS_PRIVATE(T_1_pub_key)[MBEDTLS_LMS_M_NODE_BYTES_MAX]; /*!< The public key, in
|
||||
the form of the Merkle tree root node. */
|
||||
unsigned char MBEDTLS_PRIVATE(have_public_key); /*!< Whether the context contains a public key.
|
||||
Boolean values only. */
|
||||
} mbedtls_lms_public_t;
|
||||
|
||||
|
||||
#if defined(MBEDTLS_LMS_PRIVATE)
|
||||
/** LMS private context structure.
|
||||
*
|
||||
* A LMS private key is a set of LMOTS private keys, an index to the next usable
|
||||
* key, and the applicable parameter set.
|
||||
*
|
||||
* The context must be initialized before it is used. A public key must either
|
||||
* be imported or generated from a private context.
|
||||
*
|
||||
* \dot
|
||||
* digraph lms_public_t {
|
||||
* UNINITIALIZED -> INIT [label="init"];
|
||||
* HAVE_PRIVATE_KEY -> INIT [label="free"];
|
||||
* INIT -> HAVE_PRIVATE_KEY [label="generate_private_key"];
|
||||
* }
|
||||
* \enddot
|
||||
*/
|
||||
typedef struct {
|
||||
mbedtls_lms_parameters_t MBEDTLS_PRIVATE(params);
|
||||
uint32_t MBEDTLS_PRIVATE(q_next_usable_key); /*!< The index of the next OTS key that has not
|
||||
been used. */
|
||||
mbedtls_lmots_private_t *MBEDTLS_PRIVATE(ots_private_keys); /*!< The private key material. One OTS key
|
||||
for each leaf node in the Merkle tree. NULL
|
||||
when have_private_key is 0 and non-NULL otherwise.
|
||||
is 2^MBEDTLS_LMS_H_TREE_HEIGHT(type) in length. */
|
||||
mbedtls_lmots_public_t *MBEDTLS_PRIVATE(ots_public_keys); /*!< The OTS key public keys, used to
|
||||
build the Merkle tree. NULL
|
||||
when have_private_key is 0 and
|
||||
non-NULL otherwise.
|
||||
Is 2^MBEDTLS_LMS_H_TREE_HEIGHT(type)
|
||||
in length. */
|
||||
unsigned char MBEDTLS_PRIVATE(have_private_key); /*!< Whether the context contains a private key.
|
||||
Boolean values only. */
|
||||
} mbedtls_lms_private_t;
|
||||
#endif /* defined(MBEDTLS_LMS_PRIVATE) */
|
||||
|
||||
/**
|
||||
* \brief This function initializes an LMS public context
|
||||
*
|
||||
* \param ctx The uninitialized LMS context that will then be
|
||||
* initialized.
|
||||
*/
|
||||
void mbedtls_lms_public_init(mbedtls_lms_public_t *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function uninitializes an LMS public context
|
||||
*
|
||||
* \param ctx The initialized LMS context that will then be
|
||||
* uninitialized.
|
||||
*/
|
||||
void mbedtls_lms_public_free(mbedtls_lms_public_t *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function imports an LMS public key into a
|
||||
* public LMS context.
|
||||
*
|
||||
* \note Before this function is called, the context must
|
||||
* have been initialized.
|
||||
*
|
||||
* \note See IETF RFC8554 for details of the encoding of
|
||||
* this public key.
|
||||
*
|
||||
* \param ctx The initialized LMS context store the key in.
|
||||
* \param key The buffer from which the key will be read.
|
||||
* #MBEDTLS_LMS_PUBLIC_KEY_LEN bytes will be read from
|
||||
* this.
|
||||
* \param key_size The size of the key being imported.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lms_import_public_key(mbedtls_lms_public_t *ctx,
|
||||
const unsigned char *key, size_t key_size);
|
||||
|
||||
/**
|
||||
* \brief This function exports an LMS public key from a
|
||||
* LMS public context that already contains a public
|
||||
* key.
|
||||
*
|
||||
* \note Before this function is called, the context must
|
||||
* have been initialized and the context must contain
|
||||
* a public key.
|
||||
*
|
||||
* \note See IETF RFC8554 for details of the encoding of
|
||||
* this public key.
|
||||
*
|
||||
* \param ctx The initialized LMS public context that contains
|
||||
* the public key.
|
||||
* \param key The buffer into which the key will be output. Must
|
||||
* be at least #MBEDTLS_LMS_PUBLIC_KEY_LEN in size.
|
||||
* \param key_size The size of the key buffer.
|
||||
* \param key_len If not NULL, will be written with the size of the
|
||||
* key.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lms_export_public_key(const mbedtls_lms_public_t *ctx,
|
||||
unsigned char *key, size_t key_size,
|
||||
size_t *key_len);
|
||||
|
||||
/**
|
||||
* \brief This function verifies a LMS signature, using a
|
||||
* LMS context that contains a public key.
|
||||
*
|
||||
* \note Before this function is called, the context must
|
||||
* have been initialized and must contain a public key
|
||||
* (either by import or generation).
|
||||
*
|
||||
* \param ctx The initialized LMS public context from which the
|
||||
* public key will be read.
|
||||
* \param msg The buffer from which the message will be read.
|
||||
* \param msg_size The size of the message that will be read.
|
||||
* \param sig The buf from which the signature will be read.
|
||||
* #MBEDTLS_LMS_SIG_LEN bytes will be read from
|
||||
* this.
|
||||
* \param sig_size The size of the signature to be verified.
|
||||
*
|
||||
* \return \c 0 on successful verification.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lms_verify(const mbedtls_lms_public_t *ctx,
|
||||
const unsigned char *msg, size_t msg_size,
|
||||
const unsigned char *sig, size_t sig_size);
|
||||
|
||||
#if defined(MBEDTLS_LMS_PRIVATE)
|
||||
/**
|
||||
* \brief This function initializes an LMS private context
|
||||
*
|
||||
* \param ctx The uninitialized LMS private context that will
|
||||
* then be initialized. */
|
||||
void mbedtls_lms_private_init(mbedtls_lms_private_t *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function uninitializes an LMS private context
|
||||
*
|
||||
* \param ctx The initialized LMS private context that will then
|
||||
* be uninitialized.
|
||||
*/
|
||||
void mbedtls_lms_private_free(mbedtls_lms_private_t *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function generates an LMS private key, and
|
||||
* stores in into an LMS private context.
|
||||
*
|
||||
* \warning This function is **not intended for use in
|
||||
* production**, due to as-yet unsolved problems with
|
||||
* handling stateful keys. The API for this function
|
||||
* may change considerably in future versions.
|
||||
*
|
||||
* \note The seed must have at least 256 bits of entropy.
|
||||
*
|
||||
* \param ctx The initialized LMOTS context to generate the key
|
||||
* into.
|
||||
* \param type The LMS parameter set identifier.
|
||||
* \param otstype The LMOTS parameter set identifier.
|
||||
* \param f_rng The RNG function to be used to generate the key ID.
|
||||
* \param p_rng The RNG context to be passed to f_rng
|
||||
* \param seed The seed used to deterministically generate the
|
||||
* key.
|
||||
* \param seed_size The length of the seed.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lms_generate_private_key(mbedtls_lms_private_t *ctx,
|
||||
mbedtls_lms_algorithm_type_t type,
|
||||
mbedtls_lmots_algorithm_type_t otstype,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng, const unsigned char *seed,
|
||||
size_t seed_size);
|
||||
|
||||
/**
|
||||
* \brief This function calculates an LMS public key from a
|
||||
* LMS context that already contains a private key.
|
||||
*
|
||||
* \note Before this function is called, the context must
|
||||
* have been initialized and the context must contain
|
||||
* a private key.
|
||||
*
|
||||
* \param ctx The initialized LMS public context to calculate the key
|
||||
* from and store it into.
|
||||
*
|
||||
* \param priv_ctx The LMS private context to read the private key
|
||||
* from. This must have been initialized and contain a
|
||||
* private key.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lms_calculate_public_key(mbedtls_lms_public_t *ctx,
|
||||
const mbedtls_lms_private_t *priv_ctx);
|
||||
|
||||
/**
|
||||
* \brief This function creates a LMS signature, using a
|
||||
* LMS context that contains unused private keys.
|
||||
*
|
||||
* \warning This function is **not intended for use in
|
||||
* production**, due to as-yet unsolved problems with
|
||||
* handling stateful keys. The API for this function
|
||||
* may change considerably in future versions.
|
||||
*
|
||||
* \note Before this function is called, the context must
|
||||
* have been initialized and must contain a private
|
||||
* key.
|
||||
*
|
||||
* \note Each of the LMOTS private keys inside a LMS private
|
||||
* key can only be used once. If they are reused, then
|
||||
* attackers may be able to forge signatures with that
|
||||
* key. This is all handled transparently, but it is
|
||||
* important to not perform copy operations on LMS
|
||||
* contexts that contain private key material.
|
||||
*
|
||||
* \param ctx The initialized LMS private context from which the
|
||||
* private key will be read.
|
||||
* \param f_rng The RNG function to be used for signature
|
||||
* generation.
|
||||
* \param p_rng The RNG context to be passed to f_rng
|
||||
* \param msg The buffer from which the message will be read.
|
||||
* \param msg_size The size of the message that will be read.
|
||||
* \param sig The buf into which the signature will be stored.
|
||||
* Must be at least #MBEDTLS_LMS_SIG_LEN in size.
|
||||
* \param sig_size The size of the buffer the signature will be
|
||||
* written into.
|
||||
* \param sig_len If not NULL, will be written with the size of the
|
||||
* signature.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A non-zero error code on failure.
|
||||
*/
|
||||
int mbedtls_lms_sign(mbedtls_lms_private_t *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng, const unsigned char *msg,
|
||||
unsigned int msg_size, unsigned char *sig, size_t sig_size,
|
||||
size_t *sig_len);
|
||||
#endif /* defined(MBEDTLS_LMS_PRIVATE) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_LMS_H */
|
||||
@@ -1,526 +0,0 @@
|
||||
/**
|
||||
* \file md.h
|
||||
*
|
||||
* \brief This file contains the generic functions for message-digest
|
||||
* (hashing) and HMAC.
|
||||
*
|
||||
* \author Adriaan de Jong <dejong@fox-it.com>
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_MD_H
|
||||
#define MBEDTLS_MD_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
/** The selected feature is not available. */
|
||||
#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080
|
||||
/** Bad input parameters to function. */
|
||||
#define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100
|
||||
/** Failed to allocate memory. */
|
||||
#define MBEDTLS_ERR_MD_ALLOC_FAILED -0x5180
|
||||
/** Opening or reading of file failed. */
|
||||
#define MBEDTLS_ERR_MD_FILE_IO_ERROR -0x5200
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Supported message digests.
|
||||
*
|
||||
* \warning MD5 and SHA-1 are considered weak message digests and
|
||||
* their use constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
*/
|
||||
/* Note: these are aligned with the definitions of PSA_ALG_ macros for hashes,
|
||||
* in order to enable an efficient implementation of conversion functions.
|
||||
* This is tested by md_to_from_psa() in test_suite_md. */
|
||||
typedef enum {
|
||||
MBEDTLS_MD_NONE=0, /**< None. */
|
||||
MBEDTLS_MD_MD5=0x03, /**< The MD5 message digest. */
|
||||
MBEDTLS_MD_RIPEMD160=0x04, /**< The RIPEMD-160 message digest. */
|
||||
MBEDTLS_MD_SHA1=0x05, /**< The SHA-1 message digest. */
|
||||
MBEDTLS_MD_SHA224=0x08, /**< The SHA-224 message digest. */
|
||||
MBEDTLS_MD_SHA256=0x09, /**< The SHA-256 message digest. */
|
||||
MBEDTLS_MD_SHA384=0x0a, /**< The SHA-384 message digest. */
|
||||
MBEDTLS_MD_SHA512=0x0b, /**< The SHA-512 message digest. */
|
||||
MBEDTLS_MD_SHA3_224=0x10, /**< The SHA3-224 message digest. */
|
||||
MBEDTLS_MD_SHA3_256=0x11, /**< The SHA3-256 message digest. */
|
||||
MBEDTLS_MD_SHA3_384=0x12, /**< The SHA3-384 message digest. */
|
||||
MBEDTLS_MD_SHA3_512=0x13, /**< The SHA3-512 message digest. */
|
||||
} mbedtls_md_type_t;
|
||||
|
||||
/* Note: this should always be >= PSA_HASH_MAX_SIZE
|
||||
* in all builds with both CRYPTO_C and MD_LIGHT.
|
||||
*
|
||||
* This is to make things easier for modules such as TLS that may define a
|
||||
* buffer size using MD_MAX_SIZE in a part of the code that's common to PSA
|
||||
* and legacy, then assume the buffer's size is PSA_HASH_MAX_SIZE in another
|
||||
* part of the code based on PSA.
|
||||
*/
|
||||
#if defined(PSA_WANT_ALG_SHA_512) || defined(PSA_WANT_ALG_SHA3_512)
|
||||
#define MBEDTLS_MD_MAX_SIZE 64 /* longest known is SHA512 */
|
||||
#elif defined(PSA_WANT_ALG_SHA_384) || defined(PSA_WANT_ALG_SHA3_384)
|
||||
#define MBEDTLS_MD_MAX_SIZE 48 /* longest known is SHA384 */
|
||||
#elif defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA3_256)
|
||||
#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 */
|
||||
#elif defined(PSA_WANT_ALG_SHA_224) || defined(PSA_WANT_ALG_SHA3_224)
|
||||
#define MBEDTLS_MD_MAX_SIZE 28 /* longest known is SHA224 */
|
||||
#else
|
||||
#define MBEDTLS_MD_MAX_SIZE 20 /* longest known is SHA1 or RIPE MD-160
|
||||
or smaller (MD5 and earlier) */
|
||||
#endif
|
||||
|
||||
#if defined(PSA_WANT_ALG_SHA3_224)
|
||||
#define MBEDTLS_MD_MAX_BLOCK_SIZE 144 /* the longest known is SHA3-224 */
|
||||
#elif defined(PSA_WANT_ALG_SHA3_256)
|
||||
#define MBEDTLS_MD_MAX_BLOCK_SIZE 136
|
||||
#elif defined(PSA_WANT_ALG_SHA_512) || defined(PSA_WANT_ALG_SHA_384)
|
||||
#define MBEDTLS_MD_MAX_BLOCK_SIZE 128
|
||||
#elif defined(PSA_WANT_ALG_SHA3_384)
|
||||
#define MBEDTLS_MD_MAX_BLOCK_SIZE 104
|
||||
#elif defined(PSA_WANT_ALG_SHA3_512)
|
||||
#define MBEDTLS_MD_MAX_BLOCK_SIZE 72
|
||||
#else
|
||||
#define MBEDTLS_MD_MAX_BLOCK_SIZE 64
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Opaque struct.
|
||||
*
|
||||
* Constructed using either #mbedtls_md_info_from_string or
|
||||
* #mbedtls_md_info_from_type.
|
||||
*
|
||||
* Fields can be accessed with #mbedtls_md_get_size,
|
||||
* #mbedtls_md_get_type and #mbedtls_md_get_name.
|
||||
*/
|
||||
/* Defined internally in library/md_wrap.h. */
|
||||
typedef struct mbedtls_md_info_t mbedtls_md_info_t;
|
||||
|
||||
/**
|
||||
* Used internally to indicate whether a context uses legacy or PSA.
|
||||
*
|
||||
* Internal use only.
|
||||
*/
|
||||
typedef enum {
|
||||
MBEDTLS_MD_ENGINE_LEGACY = 0,
|
||||
MBEDTLS_MD_ENGINE_PSA,
|
||||
} mbedtls_md_engine_t;
|
||||
|
||||
/**
|
||||
* The generic message-digest context.
|
||||
*/
|
||||
typedef struct mbedtls_md_context_t {
|
||||
/** Information about the associated message digest. */
|
||||
const mbedtls_md_info_t *MBEDTLS_PRIVATE(md_info);
|
||||
|
||||
#if defined(MBEDTLS_MD_SOME_PSA)
|
||||
/** Are hash operations dispatched to PSA or legacy? */
|
||||
mbedtls_md_engine_t MBEDTLS_PRIVATE(engine);
|
||||
#endif
|
||||
|
||||
/** The digest-specific context (legacy) or the PSA operation. */
|
||||
void *MBEDTLS_PRIVATE(md_ctx);
|
||||
|
||||
#if defined(MBEDTLS_MD_C)
|
||||
/** The HMAC part of the context. */
|
||||
void *MBEDTLS_PRIVATE(hmac_ctx);
|
||||
#endif
|
||||
} mbedtls_md_context_t;
|
||||
|
||||
/**
|
||||
* \brief This function returns the message-digest information
|
||||
* associated with the given digest type.
|
||||
*
|
||||
* \param md_type The type of digest to search for.
|
||||
*
|
||||
* \return The message-digest information associated with \p md_type.
|
||||
* \return NULL if the associated message-digest information is not found.
|
||||
*/
|
||||
const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type);
|
||||
|
||||
/**
|
||||
* \brief This function initializes a message-digest context without
|
||||
* binding it to a particular message-digest algorithm.
|
||||
*
|
||||
* This function should always be called first. It prepares the
|
||||
* context for mbedtls_md_setup() for binding it to a
|
||||
* message-digest algorithm.
|
||||
*/
|
||||
void mbedtls_md_init(mbedtls_md_context_t *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function clears the internal structure of \p ctx and
|
||||
* frees any embedded internal structure, but does not free
|
||||
* \p ctx itself.
|
||||
*
|
||||
* If you have called mbedtls_md_setup() on \p ctx, you must
|
||||
* call mbedtls_md_free() when you are no longer using the
|
||||
* context.
|
||||
* Calling this function if you have previously
|
||||
* called mbedtls_md_init() and nothing else is optional.
|
||||
* You must not call this function if you have not called
|
||||
* mbedtls_md_init().
|
||||
*/
|
||||
void mbedtls_md_free(mbedtls_md_context_t *ctx);
|
||||
|
||||
|
||||
/**
|
||||
* \brief This function selects the message digest algorithm to use,
|
||||
* and allocates internal structures.
|
||||
*
|
||||
* It should be called after mbedtls_md_init() or
|
||||
* mbedtls_md_free(). Makes it necessary to call
|
||||
* mbedtls_md_free() later.
|
||||
*
|
||||
* \param ctx The context to set up.
|
||||
* \param md_info The information structure of the message-digest algorithm
|
||||
* to use.
|
||||
* \param hmac Defines if HMAC is used. 0: HMAC is not used (saves some memory),
|
||||
* or non-zero: HMAC is used with this context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||
* failure.
|
||||
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac);
|
||||
|
||||
/**
|
||||
* \brief This function clones the state of a message-digest
|
||||
* context.
|
||||
*
|
||||
* \note You must call mbedtls_md_setup() on \c dst before calling
|
||||
* this function.
|
||||
*
|
||||
* \note The two contexts must have the same type,
|
||||
* for example, both are SHA-256.
|
||||
*
|
||||
* \warning This function clones the message-digest state, not the
|
||||
* HMAC state.
|
||||
*
|
||||
* \param dst The destination context.
|
||||
* \param src The context to be cloned.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure.
|
||||
* \return #MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE if both contexts are
|
||||
* not using the same engine. This can be avoided by moving
|
||||
* the call to psa_crypto_init() before the first call to
|
||||
* mbedtls_md_setup().
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_md_clone(mbedtls_md_context_t *dst,
|
||||
const mbedtls_md_context_t *src);
|
||||
|
||||
/**
|
||||
* \brief This function extracts the message-digest size from the
|
||||
* message-digest information structure.
|
||||
*
|
||||
* \param md_info The information structure of the message-digest algorithm
|
||||
* to use.
|
||||
*
|
||||
* \return The size of the message-digest output in Bytes.
|
||||
*/
|
||||
unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info);
|
||||
|
||||
/**
|
||||
* \brief This function gives the message-digest size associated to
|
||||
* message-digest type.
|
||||
*
|
||||
* \param md_type The message-digest type.
|
||||
*
|
||||
* \return The size of the message-digest output in Bytes,
|
||||
* or 0 if the message-digest type is not known.
|
||||
*/
|
||||
static inline unsigned char mbedtls_md_get_size_from_type(mbedtls_md_type_t md_type)
|
||||
{
|
||||
return mbedtls_md_get_size(mbedtls_md_info_from_type(md_type));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief This function extracts the message-digest type from the
|
||||
* message-digest information structure.
|
||||
*
|
||||
* \param md_info The information structure of the message-digest algorithm
|
||||
* to use.
|
||||
*
|
||||
* \return The type of the message digest.
|
||||
*/
|
||||
mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info);
|
||||
|
||||
/**
|
||||
* \brief This function starts a message-digest computation.
|
||||
*
|
||||
* You must call this function after setting up the context
|
||||
* with mbedtls_md_setup(), and before passing data with
|
||||
* mbedtls_md_update().
|
||||
*
|
||||
* \param ctx The generic message-digest context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||
* failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_md_starts(mbedtls_md_context_t *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function feeds an input buffer into an ongoing
|
||||
* message-digest computation.
|
||||
*
|
||||
* You must call mbedtls_md_starts() before calling this
|
||||
* function. You may call this function multiple times.
|
||||
* Afterwards, call mbedtls_md_finish().
|
||||
*
|
||||
* \param ctx The generic message-digest context.
|
||||
* \param input The buffer holding the input data.
|
||||
* \param ilen The length of the input data.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||
* failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_md_update(mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen);
|
||||
|
||||
/**
|
||||
* \brief This function finishes the digest operation,
|
||||
* and writes the result to the output buffer.
|
||||
*
|
||||
* Call this function after a call to mbedtls_md_starts(),
|
||||
* followed by any number of calls to mbedtls_md_update().
|
||||
* Afterwards, you may either clear the context with
|
||||
* mbedtls_md_free(), or call mbedtls_md_starts() to reuse
|
||||
* the context for another digest operation with the same
|
||||
* algorithm.
|
||||
*
|
||||
* \param ctx The generic message-digest context.
|
||||
* \param output The buffer for the generic message-digest checksum result.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||
* failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_md_finish(mbedtls_md_context_t *ctx, unsigned char *output);
|
||||
|
||||
/**
|
||||
* \brief This function calculates the message-digest of a buffer,
|
||||
* with respect to a configurable message-digest algorithm
|
||||
* in a single call.
|
||||
*
|
||||
* The result is calculated as
|
||||
* Output = message_digest(input buffer).
|
||||
*
|
||||
* \param md_info The information structure of the message-digest algorithm
|
||||
* to use.
|
||||
* \param input The buffer holding the data.
|
||||
* \param ilen The length of the input data.
|
||||
* \param output The generic message-digest checksum result.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||
* failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
|
||||
unsigned char *output);
|
||||
|
||||
/**
|
||||
* \brief This function returns the list of digests supported by the
|
||||
* generic digest module.
|
||||
*
|
||||
* \note The list starts with the strongest available hashes.
|
||||
*
|
||||
* \return A statically allocated array of digests. Each element
|
||||
* in the returned list is an integer belonging to the
|
||||
* message-digest enumeration #mbedtls_md_type_t.
|
||||
* The last entry is 0.
|
||||
*/
|
||||
const int *mbedtls_md_list(void);
|
||||
|
||||
/**
|
||||
* \brief This function returns the message-digest information
|
||||
* associated with the given digest name.
|
||||
*
|
||||
* \param md_name The name of the digest to search for.
|
||||
*
|
||||
* \return The message-digest information associated with \p md_name.
|
||||
* \return NULL if the associated message-digest information is not found.
|
||||
*/
|
||||
const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name);
|
||||
|
||||
/**
|
||||
* \brief This function returns the name of the message digest for
|
||||
* the message-digest information structure given.
|
||||
*
|
||||
* \param md_info The information structure of the message-digest algorithm
|
||||
* to use.
|
||||
*
|
||||
* \return The name of the message digest.
|
||||
*/
|
||||
const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info);
|
||||
|
||||
/**
|
||||
* \brief This function returns the message-digest information
|
||||
* from the given context.
|
||||
*
|
||||
* \param ctx The context from which to extract the information.
|
||||
* This must be initialized (or \c NULL).
|
||||
*
|
||||
* \return The message-digest information associated with \p ctx.
|
||||
* \return \c NULL if \p ctx is \c NULL.
|
||||
*/
|
||||
const mbedtls_md_info_t *mbedtls_md_info_from_ctx(
|
||||
const mbedtls_md_context_t *ctx);
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
/**
|
||||
* \brief This function calculates the message-digest checksum
|
||||
* result of the contents of the provided file.
|
||||
*
|
||||
* The result is calculated as
|
||||
* Output = message_digest(file contents).
|
||||
*
|
||||
* \param md_info The information structure of the message-digest algorithm
|
||||
* to use.
|
||||
* \param path The input file name.
|
||||
* \param output The generic message-digest checksum result.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_MD_FILE_IO_ERROR on an I/O error accessing
|
||||
* the file pointed by \p path.
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_md_file(const mbedtls_md_info_t *md_info, const char *path,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
|
||||
/**
|
||||
* \brief This function sets the HMAC key and prepares to
|
||||
* authenticate a new message.
|
||||
*
|
||||
* Call this function after mbedtls_md_setup(), to use
|
||||
* the MD context for an HMAC calculation, then call
|
||||
* mbedtls_md_hmac_update() to provide the input data, and
|
||||
* mbedtls_md_hmac_finish() to get the HMAC value.
|
||||
*
|
||||
* \param ctx The message digest context containing an embedded HMAC
|
||||
* context.
|
||||
* \param key The HMAC secret key.
|
||||
* \param keylen The length of the HMAC key in Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||
* failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_md_hmac_starts(mbedtls_md_context_t *ctx, const unsigned char *key,
|
||||
size_t keylen);
|
||||
|
||||
/**
|
||||
* \brief This function feeds an input buffer into an ongoing HMAC
|
||||
* computation.
|
||||
*
|
||||
* Call mbedtls_md_hmac_starts() or mbedtls_md_hmac_reset()
|
||||
* before calling this function.
|
||||
* You may call this function multiple times to pass the
|
||||
* input piecewise.
|
||||
* Afterwards, call mbedtls_md_hmac_finish().
|
||||
*
|
||||
* \param ctx The message digest context containing an embedded HMAC
|
||||
* context.
|
||||
* \param input The buffer holding the input data.
|
||||
* \param ilen The length of the input data.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||
* failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_md_hmac_update(mbedtls_md_context_t *ctx, const unsigned char *input,
|
||||
size_t ilen);
|
||||
|
||||
/**
|
||||
* \brief This function finishes the HMAC operation, and writes
|
||||
* the result to the output buffer.
|
||||
*
|
||||
* Call this function after mbedtls_md_hmac_starts() and
|
||||
* mbedtls_md_hmac_update() to get the HMAC value. Afterwards
|
||||
* you may either call mbedtls_md_free() to clear the context,
|
||||
* or call mbedtls_md_hmac_reset() to reuse the context with
|
||||
* the same HMAC key.
|
||||
*
|
||||
* \param ctx The message digest context containing an embedded HMAC
|
||||
* context.
|
||||
* \param output The generic HMAC checksum result.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||
* failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_md_hmac_finish(mbedtls_md_context_t *ctx, unsigned char *output);
|
||||
|
||||
/**
|
||||
* \brief This function prepares to authenticate a new message with
|
||||
* the same key as the previous HMAC operation.
|
||||
*
|
||||
* You may call this function after mbedtls_md_hmac_finish().
|
||||
* Afterwards call mbedtls_md_hmac_update() to pass the new
|
||||
* input.
|
||||
*
|
||||
* \param ctx The message digest context containing an embedded HMAC
|
||||
* context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||
* failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_md_hmac_reset(mbedtls_md_context_t *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function calculates the full generic HMAC
|
||||
* on the input buffer with the provided key.
|
||||
*
|
||||
* The function allocates the context, performs the
|
||||
* calculation, and frees the context.
|
||||
*
|
||||
* The HMAC result is calculated as
|
||||
* output = generic HMAC(hmac key, input buffer).
|
||||
*
|
||||
* \param md_info The information structure of the message-digest algorithm
|
||||
* to use.
|
||||
* \param key The HMAC secret key.
|
||||
* \param keylen The length of the HMAC secret key in Bytes.
|
||||
* \param input The buffer holding the input data.
|
||||
* \param ilen The length of the input data.
|
||||
* \param output The generic HMAC result.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
|
||||
* failure.
|
||||
*/
|
||||
MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
int mbedtls_md_hmac(const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *input, size_t ilen,
|
||||
unsigned char *output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_MD_H */
|
||||
@@ -1,166 +0,0 @@
|
||||
/**
|
||||
* \file md5.h
|
||||
*
|
||||
* \brief MD5 message digest algorithm (hash function)
|
||||
*
|
||||
* \warning MD5 is considered a weak message digest and its use constitutes a
|
||||
* security risk. We recommend considering stronger message
|
||||
* digests instead.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_MD5_H
|
||||
#define MBEDTLS_MD5_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief MD5 context structure
|
||||
*
|
||||
* \warning MD5 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
*/
|
||||
typedef struct mbedtls_md5_context {
|
||||
uint32_t MBEDTLS_PRIVATE(total)[2]; /*!< number of bytes processed */
|
||||
uint32_t MBEDTLS_PRIVATE(state)[4]; /*!< intermediate digest state */
|
||||
unsigned char MBEDTLS_PRIVATE(buffer)[64]; /*!< data block being processed */
|
||||
}
|
||||
mbedtls_md5_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize MD5 context
|
||||
*
|
||||
* \param ctx MD5 context to be initialized
|
||||
*
|
||||
* \warning MD5 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
*/
|
||||
void mbedtls_md5_init(mbedtls_md5_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Clear MD5 context
|
||||
*
|
||||
* \param ctx MD5 context to be cleared
|
||||
*
|
||||
* \warning MD5 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
*/
|
||||
void mbedtls_md5_free(mbedtls_md5_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Clone (the state of) an MD5 context
|
||||
*
|
||||
* \param dst The destination context
|
||||
* \param src The context to be cloned
|
||||
*
|
||||
* \warning MD5 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
*/
|
||||
void mbedtls_md5_clone(mbedtls_md5_context *dst,
|
||||
const mbedtls_md5_context *src);
|
||||
|
||||
/**
|
||||
* \brief MD5 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
*
|
||||
* \return 0 if successful
|
||||
*
|
||||
* \warning MD5 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
*/
|
||||
int mbedtls_md5_starts(mbedtls_md5_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief MD5 process buffer
|
||||
*
|
||||
* \param ctx MD5 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*
|
||||
* \return 0 if successful
|
||||
*
|
||||
* \warning MD5 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
*/
|
||||
int mbedtls_md5_update(mbedtls_md5_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen);
|
||||
|
||||
/**
|
||||
* \brief MD5 final digest
|
||||
*
|
||||
* \param ctx MD5 context
|
||||
* \param output MD5 checksum result
|
||||
*
|
||||
* \return 0 if successful
|
||||
*
|
||||
* \warning MD5 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
*/
|
||||
int mbedtls_md5_finish(mbedtls_md5_context *ctx,
|
||||
unsigned char output[16]);
|
||||
|
||||
/**
|
||||
* \brief Output = MD5( input buffer )
|
||||
*
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output MD5 checksum result
|
||||
*
|
||||
* \return 0 if successful
|
||||
*
|
||||
* \warning MD5 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
*/
|
||||
int mbedtls_md5(const unsigned char *input,
|
||||
size_t ilen,
|
||||
unsigned char output[16]);
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*
|
||||
* \warning MD5 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
*/
|
||||
int mbedtls_md5_self_test(int verbose);
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* mbedtls_md5.h */
|
||||
@@ -1,142 +0,0 @@
|
||||
/**
|
||||
* \file memory_buffer_alloc.h
|
||||
*
|
||||
* \brief Buffer-based memory allocator
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_MEMORY_BUFFER_ALLOC_H
|
||||
#define MBEDTLS_MEMORY_BUFFER_ALLOC_H
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* \name SECTION: Module settings
|
||||
*
|
||||
* The configuration options you can set for this module are in this section.
|
||||
* Either change them in mbedtls_config.h or define them on the compiler command line.
|
||||
* \{
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_MEMORY_ALIGN_MULTIPLE)
|
||||
#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */
|
||||
#endif
|
||||
|
||||
/** \} name SECTION: Module settings */
|
||||
|
||||
#define MBEDTLS_MEMORY_VERIFY_NONE 0
|
||||
#define MBEDTLS_MEMORY_VERIFY_ALLOC (1 << 0)
|
||||
#define MBEDTLS_MEMORY_VERIFY_FREE (1 << 1)
|
||||
#define MBEDTLS_MEMORY_VERIFY_ALWAYS (MBEDTLS_MEMORY_VERIFY_ALLOC | \
|
||||
MBEDTLS_MEMORY_VERIFY_FREE)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Initialize use of stack-based memory allocator.
|
||||
* The stack-based allocator does memory management inside the
|
||||
* presented buffer and does not call calloc() and free().
|
||||
* It sets the global mbedtls_calloc() and mbedtls_free() pointers
|
||||
* to its own functions.
|
||||
* (Provided mbedtls_calloc() and mbedtls_free() are thread-safe if
|
||||
* MBEDTLS_THREADING_C is defined)
|
||||
*
|
||||
* \note This code is not optimized and provides a straight-forward
|
||||
* implementation of a stack-based memory allocator.
|
||||
*
|
||||
* \param buf buffer to use as heap
|
||||
* \param len size of the buffer
|
||||
*/
|
||||
void mbedtls_memory_buffer_alloc_init(unsigned char *buf, size_t len);
|
||||
|
||||
/**
|
||||
* \brief Free the mutex for thread-safety and clear remaining memory
|
||||
*/
|
||||
void mbedtls_memory_buffer_alloc_free(void);
|
||||
|
||||
/**
|
||||
* \brief Determine when the allocator should automatically verify the state
|
||||
* of the entire chain of headers / meta-data.
|
||||
* (Default: MBEDTLS_MEMORY_VERIFY_NONE)
|
||||
*
|
||||
* \param verify One of MBEDTLS_MEMORY_VERIFY_NONE, MBEDTLS_MEMORY_VERIFY_ALLOC,
|
||||
* MBEDTLS_MEMORY_VERIFY_FREE or MBEDTLS_MEMORY_VERIFY_ALWAYS
|
||||
*/
|
||||
void mbedtls_memory_buffer_set_verify(int verify);
|
||||
|
||||
#if defined(MBEDTLS_MEMORY_DEBUG)
|
||||
/**
|
||||
* \brief Print out the status of the allocated memory (primarily for use
|
||||
* after a program should have de-allocated all memory)
|
||||
* Prints out a list of 'still allocated' blocks and their stack
|
||||
* trace if MBEDTLS_MEMORY_BACKTRACE is defined.
|
||||
*/
|
||||
void mbedtls_memory_buffer_alloc_status(void);
|
||||
|
||||
/**
|
||||
* \brief Get the number of alloc/free so far.
|
||||
*
|
||||
* \param alloc_count Number of allocations.
|
||||
* \param free_count Number of frees.
|
||||
*/
|
||||
void mbedtls_memory_buffer_alloc_count_get(size_t *alloc_count, size_t *free_count);
|
||||
|
||||
/**
|
||||
* \brief Get the peak heap usage so far
|
||||
*
|
||||
* \param max_used Peak number of bytes in use or committed. This
|
||||
* includes bytes in allocated blocks too small to split
|
||||
* into smaller blocks but larger than the requested size.
|
||||
* \param max_blocks Peak number of blocks in use, including free and used
|
||||
*/
|
||||
void mbedtls_memory_buffer_alloc_max_get(size_t *max_used, size_t *max_blocks);
|
||||
|
||||
/**
|
||||
* \brief Reset peak statistics
|
||||
*/
|
||||
void mbedtls_memory_buffer_alloc_max_reset(void);
|
||||
|
||||
/**
|
||||
* \brief Get the current heap usage
|
||||
*
|
||||
* \param cur_used Current number of bytes in use or committed. This
|
||||
* includes bytes in allocated blocks too small to split
|
||||
* into smaller blocks but larger than the requested size.
|
||||
* \param cur_blocks Current number of blocks in use, including free and used
|
||||
*/
|
||||
void mbedtls_memory_buffer_alloc_cur_get(size_t *cur_used, size_t *cur_blocks);
|
||||
#endif /* MBEDTLS_MEMORY_DEBUG */
|
||||
|
||||
/**
|
||||
* \brief Verifies that all headers in the memory buffer are correct
|
||||
* and contain sane values. Helps debug buffer-overflow errors.
|
||||
*
|
||||
* Prints out first failure if MBEDTLS_MEMORY_DEBUG is defined.
|
||||
* Prints out full header information if MBEDTLS_MEMORY_DEBUG
|
||||
* is defined. (Includes stack trace information for each block if
|
||||
* MBEDTLS_MEMORY_BACKTRACE is defined as well).
|
||||
*
|
||||
* \return 0 if verified, 1 otherwise
|
||||
*/
|
||||
int mbedtls_memory_buffer_alloc_verify(void);
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if a test failed
|
||||
*/
|
||||
int mbedtls_memory_buffer_alloc_self_test(int verbose);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* memory_buffer_alloc.h */
|
||||
@@ -1,158 +0,0 @@
|
||||
/**
|
||||
* \file nist_kw.h
|
||||
*
|
||||
* \brief This file provides an API for key wrapping (KW) and key wrapping with
|
||||
* padding (KWP) as defined in NIST SP 800-38F.
|
||||
* https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf
|
||||
*
|
||||
* Key wrapping specifies a deterministic authenticated-encryption mode
|
||||
* of operation, according to <em>NIST SP 800-38F: Recommendation for
|
||||
* Block Cipher Modes of Operation: Methods for Key Wrapping</em>. Its
|
||||
* purpose is to protect cryptographic keys.
|
||||
*
|
||||
* Its equivalent is RFC 3394 for KW, and RFC 5649 for KWP.
|
||||
* https://tools.ietf.org/html/rfc3394
|
||||
* https://tools.ietf.org/html/rfc5649
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_NIST_KW_H
|
||||
#define MBEDTLS_NIST_KW_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include "mbedtls/cipher.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
MBEDTLS_KW_MODE_KW = 0,
|
||||
MBEDTLS_KW_MODE_KWP = 1
|
||||
} mbedtls_nist_kw_mode_t;
|
||||
|
||||
/**
|
||||
* \brief The key wrapping context-type definition. The key wrapping context is passed
|
||||
* to the APIs called.
|
||||
*
|
||||
* \note The definition of this type may change in future library versions.
|
||||
* Don't make any assumptions on this context!
|
||||
*/
|
||||
typedef struct {
|
||||
mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */
|
||||
} mbedtls_nist_kw_context;
|
||||
|
||||
/**
|
||||
* \brief This function initializes the specified key wrapping context
|
||||
* to make references valid and prepare the context
|
||||
* for mbedtls_nist_kw_setkey() or mbedtls_nist_kw_free().
|
||||
*
|
||||
* \param ctx The key wrapping context to initialize.
|
||||
*
|
||||
*/
|
||||
void mbedtls_nist_kw_init(mbedtls_nist_kw_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function initializes the key wrapping context set in the
|
||||
* \p ctx parameter and sets the encryption key.
|
||||
*
|
||||
* \param ctx The key wrapping context.
|
||||
* \param cipher The 128-bit block cipher to use. Only AES is supported.
|
||||
* \param key The Key Encryption Key (KEK).
|
||||
* \param keybits The KEK size in bits. This must be acceptable by the cipher.
|
||||
* \param is_wrap Specify whether the operation within the context is wrapping or unwrapping
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for any invalid input.
|
||||
* \return \c MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE for 128-bit block ciphers
|
||||
* which are not supported.
|
||||
* \return cipher-specific error code on failure of the underlying cipher.
|
||||
*/
|
||||
int mbedtls_nist_kw_setkey(mbedtls_nist_kw_context *ctx,
|
||||
mbedtls_cipher_id_t cipher,
|
||||
const unsigned char *key,
|
||||
unsigned int keybits,
|
||||
const int is_wrap);
|
||||
|
||||
/**
|
||||
* \brief This function releases and clears the specified key wrapping context
|
||||
* and underlying cipher sub-context.
|
||||
*
|
||||
* \param ctx The key wrapping context to clear.
|
||||
*/
|
||||
void mbedtls_nist_kw_free(mbedtls_nist_kw_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function encrypts a buffer using key wrapping.
|
||||
*
|
||||
* \param ctx The key wrapping context to use for encryption.
|
||||
* \param mode The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP)
|
||||
* \param input The buffer holding the input data.
|
||||
* \param in_len The length of the input data in Bytes.
|
||||
* The input uses units of 8 Bytes called semiblocks.
|
||||
* <ul><li>For KW mode: a multiple of 8 bytes between 16 and 2^57-8 inclusive. </li>
|
||||
* <li>For KWP mode: any length between 1 and 2^32-1 inclusive.</li></ul>
|
||||
* \param[out] output The buffer holding the output data.
|
||||
* <ul><li>For KW mode: Must be at least 8 bytes larger than \p in_len.</li>
|
||||
* <li>For KWP mode: Must be at least 8 bytes larger rounded up to a multiple of
|
||||
* 8 bytes for KWP (15 bytes at most).</li></ul>
|
||||
* \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure.
|
||||
* \param[in] out_size The capacity of the output buffer.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length.
|
||||
* \return cipher-specific error code on failure of the underlying cipher.
|
||||
*/
|
||||
int mbedtls_nist_kw_wrap(mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode,
|
||||
const unsigned char *input, size_t in_len,
|
||||
unsigned char *output, size_t *out_len, size_t out_size);
|
||||
|
||||
/**
|
||||
* \brief This function decrypts a buffer using key wrapping.
|
||||
*
|
||||
* \param ctx The key wrapping context to use for decryption.
|
||||
* \param mode The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP)
|
||||
* \param input The buffer holding the input data.
|
||||
* \param in_len The length of the input data in Bytes.
|
||||
* The input uses units of 8 Bytes called semiblocks.
|
||||
* The input must be a multiple of semiblocks.
|
||||
* <ul><li>For KW mode: a multiple of 8 bytes between 24 and 2^57 inclusive. </li>
|
||||
* <li>For KWP mode: a multiple of 8 bytes between 16 and 2^32 inclusive.</li></ul>
|
||||
* \param[out] output The buffer holding the output data.
|
||||
* The output buffer's minimal length is 8 bytes shorter than \p in_len.
|
||||
* \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure.
|
||||
* For KWP mode, the length could be up to 15 bytes shorter than \p in_len,
|
||||
* depending on how much padding was added to the data.
|
||||
* \param[in] out_size The capacity of the output buffer.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length.
|
||||
* \return \c MBEDTLS_ERR_CIPHER_AUTH_FAILED for verification failure of the ciphertext.
|
||||
* \return cipher-specific error code on failure of the underlying cipher.
|
||||
*/
|
||||
int mbedtls_nist_kw_unwrap(mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode,
|
||||
const unsigned char *input, size_t in_len,
|
||||
unsigned char *output, size_t *out_len, size_t out_size);
|
||||
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
|
||||
/**
|
||||
* \brief The key wrapping checkup routine.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c 1 on failure.
|
||||
*/
|
||||
int mbedtls_nist_kw_self_test(int verbose);
|
||||
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_NIST_KW_H */
|
||||
@@ -1,695 +0,0 @@
|
||||
/**
|
||||
* \file oid.h
|
||||
*
|
||||
* \brief Object Identifier (OID) database
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_OID_H
|
||||
#define MBEDTLS_OID_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include "mbedtls/asn1.h"
|
||||
#include "mbedtls/pk.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_C)
|
||||
#include "mbedtls/cipher.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
/** OID is not found. */
|
||||
#define MBEDTLS_ERR_OID_NOT_FOUND -0x002E
|
||||
/** output buffer is too small */
|
||||
#define MBEDTLS_ERR_OID_BUF_TOO_SMALL -0x000B
|
||||
|
||||
/* This is for the benefit of X.509, but defined here in order to avoid
|
||||
* having a "backwards" include of x.509.h here */
|
||||
/*
|
||||
* X.509 extension types (internal, arbitrary values for bitsets)
|
||||
*/
|
||||
#define MBEDTLS_OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER (1 << 0)
|
||||
#define MBEDTLS_OID_X509_EXT_SUBJECT_KEY_IDENTIFIER (1 << 1)
|
||||
#define MBEDTLS_OID_X509_EXT_KEY_USAGE (1 << 2)
|
||||
#define MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES (1 << 3)
|
||||
#define MBEDTLS_OID_X509_EXT_POLICY_MAPPINGS (1 << 4)
|
||||
#define MBEDTLS_OID_X509_EXT_SUBJECT_ALT_NAME (1 << 5)
|
||||
#define MBEDTLS_OID_X509_EXT_ISSUER_ALT_NAME (1 << 6)
|
||||
#define MBEDTLS_OID_X509_EXT_SUBJECT_DIRECTORY_ATTRS (1 << 7)
|
||||
#define MBEDTLS_OID_X509_EXT_BASIC_CONSTRAINTS (1 << 8)
|
||||
#define MBEDTLS_OID_X509_EXT_NAME_CONSTRAINTS (1 << 9)
|
||||
#define MBEDTLS_OID_X509_EXT_POLICY_CONSTRAINTS (1 << 10)
|
||||
#define MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE (1 << 11)
|
||||
#define MBEDTLS_OID_X509_EXT_CRL_DISTRIBUTION_POINTS (1 << 12)
|
||||
#define MBEDTLS_OID_X509_EXT_INIHIBIT_ANYPOLICY (1 << 13)
|
||||
#define MBEDTLS_OID_X509_EXT_FRESHEST_CRL (1 << 14)
|
||||
#define MBEDTLS_OID_X509_EXT_NS_CERT_TYPE (1 << 16)
|
||||
|
||||
/*
|
||||
* Maximum number of OID components allowed
|
||||
*/
|
||||
#define MBEDTLS_OID_MAX_COMPONENTS 128
|
||||
|
||||
/*
|
||||
* Top level OID tuples
|
||||
*/
|
||||
#define MBEDTLS_OID_ISO_MEMBER_BODIES "\x2a" /* {iso(1) member-body(2)} */
|
||||
#define MBEDTLS_OID_ISO_IDENTIFIED_ORG "\x2b" /* {iso(1) identified-organization(3)} */
|
||||
#define MBEDTLS_OID_ISO_CCITT_DS "\x55" /* {joint-iso-ccitt(2) ds(5)} */
|
||||
#define MBEDTLS_OID_ISO_ITU_COUNTRY "\x60" /* {joint-iso-itu-t(2) country(16)} */
|
||||
|
||||
/*
|
||||
* ISO Member bodies OID parts
|
||||
*/
|
||||
#define MBEDTLS_OID_COUNTRY_US "\x86\x48" /* {us(840)} */
|
||||
#define MBEDTLS_OID_ORG_RSA_DATA_SECURITY "\x86\xf7\x0d" /* {rsadsi(113549)} */
|
||||
#define MBEDTLS_OID_RSA_COMPANY MBEDTLS_OID_ISO_MEMBER_BODIES MBEDTLS_OID_COUNTRY_US \
|
||||
MBEDTLS_OID_ORG_RSA_DATA_SECURITY /* {iso(1) member-body(2) us(840) rsadsi(113549)} */
|
||||
#define MBEDTLS_OID_ORG_ANSI_X9_62 "\xce\x3d" /* ansi-X9-62(10045) */
|
||||
#define MBEDTLS_OID_ANSI_X9_62 MBEDTLS_OID_ISO_MEMBER_BODIES MBEDTLS_OID_COUNTRY_US \
|
||||
MBEDTLS_OID_ORG_ANSI_X9_62
|
||||
|
||||
/*
|
||||
* ISO Identified organization OID parts
|
||||
*/
|
||||
#define MBEDTLS_OID_ORG_DOD "\x06" /* {dod(6)} */
|
||||
#define MBEDTLS_OID_ORG_OIW "\x0e"
|
||||
#define MBEDTLS_OID_OIW_SECSIG MBEDTLS_OID_ORG_OIW "\x03"
|
||||
#define MBEDTLS_OID_OIW_SECSIG_ALG MBEDTLS_OID_OIW_SECSIG "\x02"
|
||||
#define MBEDTLS_OID_OIW_SECSIG_SHA1 MBEDTLS_OID_OIW_SECSIG_ALG "\x1a"
|
||||
#define MBEDTLS_OID_ORG_THAWTE "\x65" /* thawte(101) */
|
||||
#define MBEDTLS_OID_THAWTE MBEDTLS_OID_ISO_IDENTIFIED_ORG \
|
||||
MBEDTLS_OID_ORG_THAWTE
|
||||
#define MBEDTLS_OID_ORG_CERTICOM "\x81\x04" /* certicom(132) */
|
||||
#define MBEDTLS_OID_CERTICOM MBEDTLS_OID_ISO_IDENTIFIED_ORG \
|
||||
MBEDTLS_OID_ORG_CERTICOM
|
||||
#define MBEDTLS_OID_ORG_TELETRUST "\x24" /* teletrust(36) */
|
||||
#define MBEDTLS_OID_TELETRUST MBEDTLS_OID_ISO_IDENTIFIED_ORG \
|
||||
MBEDTLS_OID_ORG_TELETRUST
|
||||
|
||||
/*
|
||||
* ISO ITU OID parts
|
||||
*/
|
||||
#define MBEDTLS_OID_ORGANIZATION "\x01" /* {organization(1)} */
|
||||
#define MBEDTLS_OID_ISO_ITU_US_ORG MBEDTLS_OID_ISO_ITU_COUNTRY MBEDTLS_OID_COUNTRY_US \
|
||||
MBEDTLS_OID_ORGANIZATION /* {joint-iso-itu-t(2) country(16) us(840) organization(1)} */
|
||||
|
||||
#define MBEDTLS_OID_ORG_GOV "\x65" /* {gov(101)} */
|
||||
#define MBEDTLS_OID_GOV MBEDTLS_OID_ISO_ITU_US_ORG MBEDTLS_OID_ORG_GOV /* {joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)} */
|
||||
|
||||
#define MBEDTLS_OID_ORG_NETSCAPE "\x86\xF8\x42" /* {netscape(113730)} */
|
||||
#define MBEDTLS_OID_NETSCAPE MBEDTLS_OID_ISO_ITU_US_ORG MBEDTLS_OID_ORG_NETSCAPE /* Netscape OID {joint-iso-itu-t(2) country(16) us(840) organization(1) netscape(113730)} */
|
||||
|
||||
/* ISO arc for standard certificate and CRL extensions */
|
||||
#define MBEDTLS_OID_ID_CE MBEDTLS_OID_ISO_CCITT_DS "\x1D" /**< id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29} */
|
||||
|
||||
#define MBEDTLS_OID_NIST_ALG MBEDTLS_OID_GOV "\x03\x04" /** { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) */
|
||||
|
||||
/**
|
||||
* Private Internet Extensions
|
||||
* { iso(1) identified-organization(3) dod(6) internet(1)
|
||||
* security(5) mechanisms(5) pkix(7) }
|
||||
*/
|
||||
#define MBEDTLS_OID_INTERNET MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD \
|
||||
"\x01"
|
||||
#define MBEDTLS_OID_PKIX MBEDTLS_OID_INTERNET "\x05\x05\x07"
|
||||
|
||||
/*
|
||||
* Arc for standard naming attributes
|
||||
*/
|
||||
#define MBEDTLS_OID_AT MBEDTLS_OID_ISO_CCITT_DS "\x04" /**< id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4} */
|
||||
#define MBEDTLS_OID_AT_CN MBEDTLS_OID_AT "\x03" /**< id-at-commonName AttributeType:= {id-at 3} */
|
||||
#define MBEDTLS_OID_AT_SUR_NAME MBEDTLS_OID_AT "\x04" /**< id-at-surName AttributeType:= {id-at 4} */
|
||||
#define MBEDTLS_OID_AT_SERIAL_NUMBER MBEDTLS_OID_AT "\x05" /**< id-at-serialNumber AttributeType:= {id-at 5} */
|
||||
#define MBEDTLS_OID_AT_COUNTRY MBEDTLS_OID_AT "\x06" /**< id-at-countryName AttributeType:= {id-at 6} */
|
||||
#define MBEDTLS_OID_AT_LOCALITY MBEDTLS_OID_AT "\x07" /**< id-at-locality AttributeType:= {id-at 7} */
|
||||
#define MBEDTLS_OID_AT_STATE MBEDTLS_OID_AT "\x08" /**< id-at-state AttributeType:= {id-at 8} */
|
||||
#define MBEDTLS_OID_AT_ORGANIZATION MBEDTLS_OID_AT "\x0A" /**< id-at-organizationName AttributeType:= {id-at 10} */
|
||||
#define MBEDTLS_OID_AT_ORG_UNIT MBEDTLS_OID_AT "\x0B" /**< id-at-organizationalUnitName AttributeType:= {id-at 11} */
|
||||
#define MBEDTLS_OID_AT_TITLE MBEDTLS_OID_AT "\x0C" /**< id-at-title AttributeType:= {id-at 12} */
|
||||
#define MBEDTLS_OID_AT_POSTAL_ADDRESS MBEDTLS_OID_AT "\x10" /**< id-at-postalAddress AttributeType:= {id-at 16} */
|
||||
#define MBEDTLS_OID_AT_POSTAL_CODE MBEDTLS_OID_AT "\x11" /**< id-at-postalCode AttributeType:= {id-at 17} */
|
||||
#define MBEDTLS_OID_AT_GIVEN_NAME MBEDTLS_OID_AT "\x2A" /**< id-at-givenName AttributeType:= {id-at 42} */
|
||||
#define MBEDTLS_OID_AT_INITIALS MBEDTLS_OID_AT "\x2B" /**< id-at-initials AttributeType:= {id-at 43} */
|
||||
#define MBEDTLS_OID_AT_GENERATION_QUALIFIER MBEDTLS_OID_AT "\x2C" /**< id-at-generationQualifier AttributeType:= {id-at 44} */
|
||||
#define MBEDTLS_OID_AT_UNIQUE_IDENTIFIER MBEDTLS_OID_AT "\x2D" /**< id-at-uniqueIdentifier AttributeType:= {id-at 45} */
|
||||
#define MBEDTLS_OID_AT_DN_QUALIFIER MBEDTLS_OID_AT "\x2E" /**< id-at-dnQualifier AttributeType:= {id-at 46} */
|
||||
#define MBEDTLS_OID_AT_PSEUDONYM MBEDTLS_OID_AT "\x41" /**< id-at-pseudonym AttributeType:= {id-at 65} */
|
||||
|
||||
#define MBEDTLS_OID_UID "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x01" /** id-domainComponent AttributeType:= {itu-t(0) data(9) pss(2342) ucl(19200300) pilot(100) pilotAttributeType(1) uid(1)} */
|
||||
#define MBEDTLS_OID_DOMAIN_COMPONENT "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x19" /** id-domainComponent AttributeType:= {itu-t(0) data(9) pss(2342) ucl(19200300) pilot(100) pilotAttributeType(1) domainComponent(25)} */
|
||||
|
||||
/*
|
||||
* OIDs for standard certificate extensions
|
||||
*/
|
||||
#define MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER MBEDTLS_OID_ID_CE "\x23" /**< id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 } */
|
||||
#define MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER MBEDTLS_OID_ID_CE "\x0E" /**< id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 } */
|
||||
#define MBEDTLS_OID_KEY_USAGE MBEDTLS_OID_ID_CE "\x0F" /**< id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } */
|
||||
#define MBEDTLS_OID_CERTIFICATE_POLICIES MBEDTLS_OID_ID_CE "\x20" /**< id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 } */
|
||||
#define MBEDTLS_OID_POLICY_MAPPINGS MBEDTLS_OID_ID_CE "\x21" /**< id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 } */
|
||||
#define MBEDTLS_OID_SUBJECT_ALT_NAME MBEDTLS_OID_ID_CE "\x11" /**< id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } */
|
||||
#define MBEDTLS_OID_ISSUER_ALT_NAME MBEDTLS_OID_ID_CE "\x12" /**< id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 } */
|
||||
#define MBEDTLS_OID_SUBJECT_DIRECTORY_ATTRS MBEDTLS_OID_ID_CE "\x09" /**< id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 } */
|
||||
#define MBEDTLS_OID_BASIC_CONSTRAINTS MBEDTLS_OID_ID_CE "\x13" /**< id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } */
|
||||
#define MBEDTLS_OID_NAME_CONSTRAINTS MBEDTLS_OID_ID_CE "\x1E" /**< id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 } */
|
||||
#define MBEDTLS_OID_POLICY_CONSTRAINTS MBEDTLS_OID_ID_CE "\x24" /**< id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 } */
|
||||
#define MBEDTLS_OID_EXTENDED_KEY_USAGE MBEDTLS_OID_ID_CE "\x25" /**< id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } */
|
||||
#define MBEDTLS_OID_CRL_DISTRIBUTION_POINTS MBEDTLS_OID_ID_CE "\x1F" /**< id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-ce 31 } */
|
||||
#define MBEDTLS_OID_INIHIBIT_ANYPOLICY MBEDTLS_OID_ID_CE "\x36" /**< id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } */
|
||||
#define MBEDTLS_OID_FRESHEST_CRL MBEDTLS_OID_ID_CE "\x2E" /**< id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 } */
|
||||
|
||||
/*
|
||||
* Certificate policies
|
||||
*/
|
||||
#define MBEDTLS_OID_ANY_POLICY MBEDTLS_OID_CERTIFICATE_POLICIES "\x00" /**< anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 } */
|
||||
|
||||
/*
|
||||
* Netscape certificate extensions
|
||||
*/
|
||||
#define MBEDTLS_OID_NS_CERT MBEDTLS_OID_NETSCAPE "\x01"
|
||||
#define MBEDTLS_OID_NS_CERT_TYPE MBEDTLS_OID_NS_CERT "\x01"
|
||||
#define MBEDTLS_OID_NS_BASE_URL MBEDTLS_OID_NS_CERT "\x02"
|
||||
#define MBEDTLS_OID_NS_REVOCATION_URL MBEDTLS_OID_NS_CERT "\x03"
|
||||
#define MBEDTLS_OID_NS_CA_REVOCATION_URL MBEDTLS_OID_NS_CERT "\x04"
|
||||
#define MBEDTLS_OID_NS_RENEWAL_URL MBEDTLS_OID_NS_CERT "\x07"
|
||||
#define MBEDTLS_OID_NS_CA_POLICY_URL MBEDTLS_OID_NS_CERT "\x08"
|
||||
#define MBEDTLS_OID_NS_SSL_SERVER_NAME MBEDTLS_OID_NS_CERT "\x0C"
|
||||
#define MBEDTLS_OID_NS_COMMENT MBEDTLS_OID_NS_CERT "\x0D"
|
||||
#define MBEDTLS_OID_NS_DATA_TYPE MBEDTLS_OID_NETSCAPE "\x02"
|
||||
#define MBEDTLS_OID_NS_CERT_SEQUENCE MBEDTLS_OID_NS_DATA_TYPE "\x05"
|
||||
|
||||
/*
|
||||
* OIDs for CRL extensions
|
||||
*/
|
||||
#define MBEDTLS_OID_PRIVATE_KEY_USAGE_PERIOD MBEDTLS_OID_ID_CE "\x10"
|
||||
#define MBEDTLS_OID_CRL_NUMBER MBEDTLS_OID_ID_CE "\x14" /**< id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 } */
|
||||
|
||||
/*
|
||||
* X.509 v3 Extended key usage OIDs
|
||||
*/
|
||||
#define MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE MBEDTLS_OID_EXTENDED_KEY_USAGE "\x00" /**< anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } */
|
||||
|
||||
#define MBEDTLS_OID_KP MBEDTLS_OID_PKIX "\x03" /**< id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } */
|
||||
#define MBEDTLS_OID_SERVER_AUTH MBEDTLS_OID_KP "\x01" /**< id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } */
|
||||
#define MBEDTLS_OID_CLIENT_AUTH MBEDTLS_OID_KP "\x02" /**< id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } */
|
||||
#define MBEDTLS_OID_CODE_SIGNING MBEDTLS_OID_KP "\x03" /**< id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } */
|
||||
#define MBEDTLS_OID_EMAIL_PROTECTION MBEDTLS_OID_KP "\x04" /**< id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } */
|
||||
#define MBEDTLS_OID_TIME_STAMPING MBEDTLS_OID_KP "\x08" /**< id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } */
|
||||
#define MBEDTLS_OID_OCSP_SIGNING MBEDTLS_OID_KP "\x09" /**< id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } */
|
||||
|
||||
/**
|
||||
* Wi-SUN Alliance Field Area Network
|
||||
* { iso(1) identified-organization(3) dod(6) internet(1)
|
||||
* private(4) enterprise(1) WiSUN(45605) FieldAreaNetwork(1) }
|
||||
*/
|
||||
#define MBEDTLS_OID_WISUN_FAN MBEDTLS_OID_INTERNET "\x04\x01\x82\xe4\x25\x01"
|
||||
|
||||
#define MBEDTLS_OID_ON MBEDTLS_OID_PKIX "\x08" /**< id-on OBJECT IDENTIFIER ::= { id-pkix 8 } */
|
||||
#define MBEDTLS_OID_ON_HW_MODULE_NAME MBEDTLS_OID_ON "\x04" /**< id-on-hardwareModuleName OBJECT IDENTIFIER ::= { id-on 4 } */
|
||||
|
||||
/*
|
||||
* PKCS definition OIDs
|
||||
*/
|
||||
|
||||
#define MBEDTLS_OID_PKCS MBEDTLS_OID_RSA_COMPANY "\x01" /**< pkcs OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) 1 } */
|
||||
#define MBEDTLS_OID_PKCS1 MBEDTLS_OID_PKCS "\x01" /**< pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } */
|
||||
#define MBEDTLS_OID_PKCS5 MBEDTLS_OID_PKCS "\x05" /**< pkcs-5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 } */
|
||||
#define MBEDTLS_OID_PKCS7 MBEDTLS_OID_PKCS "\x07" /**< pkcs-7 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 } */
|
||||
#define MBEDTLS_OID_PKCS9 MBEDTLS_OID_PKCS "\x09" /**< pkcs-9 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } */
|
||||
#define MBEDTLS_OID_PKCS12 MBEDTLS_OID_PKCS "\x0c" /**< pkcs-12 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 } */
|
||||
|
||||
/*
|
||||
* PKCS#1 OIDs
|
||||
*/
|
||||
#define MBEDTLS_OID_PKCS1_RSA MBEDTLS_OID_PKCS1 "\x01" /**< rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } */
|
||||
#define MBEDTLS_OID_PKCS1_MD5 MBEDTLS_OID_PKCS1 "\x04" /**< md5WithRSAEncryption ::= { pkcs-1 4 } */
|
||||
#define MBEDTLS_OID_PKCS1_SHA1 MBEDTLS_OID_PKCS1 "\x05" /**< sha1WithRSAEncryption ::= { pkcs-1 5 } */
|
||||
#define MBEDTLS_OID_PKCS1_SHA224 MBEDTLS_OID_PKCS1 "\x0e" /**< sha224WithRSAEncryption ::= { pkcs-1 14 } */
|
||||
#define MBEDTLS_OID_PKCS1_SHA256 MBEDTLS_OID_PKCS1 "\x0b" /**< sha256WithRSAEncryption ::= { pkcs-1 11 } */
|
||||
#define MBEDTLS_OID_PKCS1_SHA384 MBEDTLS_OID_PKCS1 "\x0c" /**< sha384WithRSAEncryption ::= { pkcs-1 12 } */
|
||||
#define MBEDTLS_OID_PKCS1_SHA512 MBEDTLS_OID_PKCS1 "\x0d" /**< sha512WithRSAEncryption ::= { pkcs-1 13 } */
|
||||
|
||||
#define MBEDTLS_OID_RSA_SHA_OBS "\x2B\x0E\x03\x02\x1D"
|
||||
|
||||
#define MBEDTLS_OID_PKCS9_EMAIL MBEDTLS_OID_PKCS9 "\x01" /**< emailAddress AttributeType ::= { pkcs-9 1 } */
|
||||
|
||||
/* RFC 4055 */
|
||||
#define MBEDTLS_OID_RSASSA_PSS MBEDTLS_OID_PKCS1 "\x0a" /**< id-RSASSA-PSS ::= { pkcs-1 10 } */
|
||||
#define MBEDTLS_OID_MGF1 MBEDTLS_OID_PKCS1 "\x08" /**< id-mgf1 ::= { pkcs-1 8 } */
|
||||
|
||||
/*
|
||||
* Digest algorithms
|
||||
*/
|
||||
#define MBEDTLS_OID_DIGEST_ALG_MD5 MBEDTLS_OID_RSA_COMPANY "\x02\x05" /**< id-mbedtls_md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 } */
|
||||
#define MBEDTLS_OID_DIGEST_ALG_SHA1 MBEDTLS_OID_ISO_IDENTIFIED_ORG \
|
||||
MBEDTLS_OID_OIW_SECSIG_SHA1 /**< id-mbedtls_sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } */
|
||||
#define MBEDTLS_OID_DIGEST_ALG_SHA224 MBEDTLS_OID_NIST_ALG "\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */
|
||||
#define MBEDTLS_OID_DIGEST_ALG_SHA256 MBEDTLS_OID_NIST_ALG "\x02\x01" /**< id-mbedtls_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */
|
||||
|
||||
#define MBEDTLS_OID_DIGEST_ALG_SHA384 MBEDTLS_OID_NIST_ALG "\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */
|
||||
|
||||
#define MBEDTLS_OID_DIGEST_ALG_SHA512 MBEDTLS_OID_NIST_ALG "\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */
|
||||
|
||||
#define MBEDTLS_OID_DIGEST_ALG_RIPEMD160 MBEDTLS_OID_TELETRUST "\x03\x02\x01" /**< id-ripemd160 OBJECT IDENTIFIER :: { iso(1) identified-organization(3) teletrust(36) algorithm(3) hashAlgorithm(2) ripemd160(1) } */
|
||||
|
||||
#define MBEDTLS_OID_DIGEST_ALG_SHA3_224 MBEDTLS_OID_NIST_ALG "\x02\x07" /**< id-sha3-224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) sha3-224(7) } */
|
||||
|
||||
#define MBEDTLS_OID_DIGEST_ALG_SHA3_256 MBEDTLS_OID_NIST_ALG "\x02\x08" /**< id-sha3-256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) sha3-256(8) } */
|
||||
|
||||
#define MBEDTLS_OID_DIGEST_ALG_SHA3_384 MBEDTLS_OID_NIST_ALG "\x02\x09" /**< id-sha3-384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) sha3-384(9) } */
|
||||
|
||||
#define MBEDTLS_OID_DIGEST_ALG_SHA3_512 MBEDTLS_OID_NIST_ALG "\x02\x0a" /**< id-sha3-512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) sha3-512(10) } */
|
||||
|
||||
|
||||
#define MBEDTLS_OID_HMAC_SHA1 MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */
|
||||
|
||||
#define MBEDTLS_OID_HMAC_SHA224 MBEDTLS_OID_RSA_COMPANY "\x02\x08" /**< id-hmacWithSHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 } */
|
||||
|
||||
#define MBEDTLS_OID_HMAC_SHA256 MBEDTLS_OID_RSA_COMPANY "\x02\x09" /**< id-hmacWithSHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 9 } */
|
||||
|
||||
#define MBEDTLS_OID_HMAC_SHA384 MBEDTLS_OID_RSA_COMPANY "\x02\x0A" /**< id-hmacWithSHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 10 } */
|
||||
|
||||
#define MBEDTLS_OID_HMAC_SHA512 MBEDTLS_OID_RSA_COMPANY "\x02\x0B" /**< id-hmacWithSHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 11 } */
|
||||
|
||||
#define MBEDTLS_OID_HMAC_SHA3_224 MBEDTLS_OID_NIST_ALG "\x02\x0d" /**< id-hmacWithSHA3-512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) hmacWithSHA3-224(13) } */
|
||||
|
||||
#define MBEDTLS_OID_HMAC_SHA3_256 MBEDTLS_OID_NIST_ALG "\x02\x0e" /**< id-hmacWithSHA3-512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) hmacWithSHA3-256(14) } */
|
||||
|
||||
#define MBEDTLS_OID_HMAC_SHA3_384 MBEDTLS_OID_NIST_ALG "\x02\x0f" /**< id-hmacWithSHA3-512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) hmacWithSHA3-384(15) } */
|
||||
|
||||
#define MBEDTLS_OID_HMAC_SHA3_512 MBEDTLS_OID_NIST_ALG "\x02\x10" /**< id-hmacWithSHA3-512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) hashalgs(2) hmacWithSHA3-512(16) } */
|
||||
|
||||
#define MBEDTLS_OID_HMAC_RIPEMD160 MBEDTLS_OID_INTERNET "\x05\x05\x08\x01\x04" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= {iso(1) iso-identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) ipsec(8) isakmpOakley(1) hmacRIPEMD160(4)} */
|
||||
|
||||
/*
|
||||
* Encryption algorithms,
|
||||
* the following standardized object identifiers are specified at
|
||||
* https://datatracker.ietf.org/doc/html/rfc8018#appendix-C.
|
||||
*/
|
||||
#define MBEDTLS_OID_DES_CBC MBEDTLS_OID_ISO_IDENTIFIED_ORG \
|
||||
MBEDTLS_OID_OIW_SECSIG_ALG "\x07" /**< desCBC OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 7 } */
|
||||
#define MBEDTLS_OID_DES_EDE3_CBC MBEDTLS_OID_RSA_COMPANY "\x03\x07" /**< des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) -- us(840) rsadsi(113549) encryptionAlgorithm(3) 7 } */
|
||||
#define MBEDTLS_OID_AES MBEDTLS_OID_NIST_ALG "\x01" /** aes OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) 1 } */
|
||||
#define MBEDTLS_OID_AES_128_CBC MBEDTLS_OID_AES "\x02" /** aes128-cbc-pad OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) aes(1) aes128-CBC-PAD(2) } */
|
||||
#define MBEDTLS_OID_AES_192_CBC MBEDTLS_OID_AES "\x16" /** aes192-cbc-pad OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) aes(1) aes192-CBC-PAD(22) } */
|
||||
#define MBEDTLS_OID_AES_256_CBC MBEDTLS_OID_AES "\x2a" /** aes256-cbc-pad OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) aes(1) aes256-CBC-PAD(42) } */
|
||||
|
||||
/*
|
||||
* Key Wrapping algorithms
|
||||
*/
|
||||
/*
|
||||
* RFC 5649
|
||||
*/
|
||||
#define MBEDTLS_OID_AES128_KW MBEDTLS_OID_AES "\x05" /** id-aes128-wrap OBJECT IDENTIFIER ::= { aes 5 } */
|
||||
#define MBEDTLS_OID_AES128_KWP MBEDTLS_OID_AES "\x08" /** id-aes128-wrap-pad OBJECT IDENTIFIER ::= { aes 8 } */
|
||||
#define MBEDTLS_OID_AES192_KW MBEDTLS_OID_AES "\x19" /** id-aes192-wrap OBJECT IDENTIFIER ::= { aes 25 } */
|
||||
#define MBEDTLS_OID_AES192_KWP MBEDTLS_OID_AES "\x1c" /** id-aes192-wrap-pad OBJECT IDENTIFIER ::= { aes 28 } */
|
||||
#define MBEDTLS_OID_AES256_KW MBEDTLS_OID_AES "\x2d" /** id-aes256-wrap OBJECT IDENTIFIER ::= { aes 45 } */
|
||||
#define MBEDTLS_OID_AES256_KWP MBEDTLS_OID_AES "\x30" /** id-aes256-wrap-pad OBJECT IDENTIFIER ::= { aes 48 } */
|
||||
/*
|
||||
* PKCS#5 OIDs
|
||||
*/
|
||||
#define MBEDTLS_OID_PKCS5_PBKDF2 MBEDTLS_OID_PKCS5 "\x0c" /**< id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12} */
|
||||
#define MBEDTLS_OID_PKCS5_PBES2 MBEDTLS_OID_PKCS5 "\x0d" /**< id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13} */
|
||||
#define MBEDTLS_OID_PKCS5_PBMAC1 MBEDTLS_OID_PKCS5 "\x0e" /**< id-PBMAC1 OBJECT IDENTIFIER ::= {pkcs-5 14} */
|
||||
|
||||
/*
|
||||
* PKCS#5 PBES1 algorithms
|
||||
*/
|
||||
#define MBEDTLS_OID_PKCS5_PBE_MD5_DES_CBC MBEDTLS_OID_PKCS5 "\x03" /**< pbeWithMD5AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 3} */
|
||||
#define MBEDTLS_OID_PKCS5_PBE_MD5_RC2_CBC MBEDTLS_OID_PKCS5 "\x06" /**< pbeWithMD5AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 6} */
|
||||
#define MBEDTLS_OID_PKCS5_PBE_SHA1_DES_CBC MBEDTLS_OID_PKCS5 "\x0a" /**< pbeWithSHA1AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 10} */
|
||||
#define MBEDTLS_OID_PKCS5_PBE_SHA1_RC2_CBC MBEDTLS_OID_PKCS5 "\x0b" /**< pbeWithSHA1AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 11} */
|
||||
|
||||
/*
|
||||
* PKCS#7 OIDs
|
||||
*/
|
||||
#define MBEDTLS_OID_PKCS7_DATA MBEDTLS_OID_PKCS7 "\x01" /**< Content type is Data OBJECT IDENTIFIER ::= {pkcs-7 1} */
|
||||
#define MBEDTLS_OID_PKCS7_SIGNED_DATA MBEDTLS_OID_PKCS7 "\x02" /**< Content type is Signed Data OBJECT IDENTIFIER ::= {pkcs-7 2} */
|
||||
#define MBEDTLS_OID_PKCS7_ENVELOPED_DATA MBEDTLS_OID_PKCS7 "\x03" /**< Content type is Enveloped Data OBJECT IDENTIFIER ::= {pkcs-7 3} */
|
||||
#define MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA MBEDTLS_OID_PKCS7 "\x04" /**< Content type is Signed and Enveloped Data OBJECT IDENTIFIER ::= {pkcs-7 4} */
|
||||
#define MBEDTLS_OID_PKCS7_DIGESTED_DATA MBEDTLS_OID_PKCS7 "\x05" /**< Content type is Digested Data OBJECT IDENTIFIER ::= {pkcs-7 5} */
|
||||
#define MBEDTLS_OID_PKCS7_ENCRYPTED_DATA MBEDTLS_OID_PKCS7 "\x06" /**< Content type is Encrypted Data OBJECT IDENTIFIER ::= {pkcs-7 6} */
|
||||
|
||||
/*
|
||||
* PKCS#8 OIDs
|
||||
*/
|
||||
#define MBEDTLS_OID_PKCS9_CSR_EXT_REQ MBEDTLS_OID_PKCS9 "\x0e" /**< extensionRequest OBJECT IDENTIFIER ::= {pkcs-9 14} */
|
||||
|
||||
/*
|
||||
* PKCS#12 PBE OIDs
|
||||
*/
|
||||
#define MBEDTLS_OID_PKCS12_PBE MBEDTLS_OID_PKCS12 "\x01" /**< pkcs-12PbeIds OBJECT IDENTIFIER ::= {pkcs-12 1} */
|
||||
|
||||
#define MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC MBEDTLS_OID_PKCS12_PBE "\x03" /**< pbeWithSHAAnd3-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 3} */
|
||||
#define MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC MBEDTLS_OID_PKCS12_PBE "\x04" /**< pbeWithSHAAnd2-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 4} */
|
||||
#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_128_CBC MBEDTLS_OID_PKCS12_PBE "\x05" /**< pbeWithSHAAnd128BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 5} */
|
||||
#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_40_CBC MBEDTLS_OID_PKCS12_PBE "\x06" /**< pbeWithSHAAnd40BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 6} */
|
||||
|
||||
/*
|
||||
* EC key algorithms from RFC 5480
|
||||
*/
|
||||
|
||||
/* id-ecPublicKey OBJECT IDENTIFIER ::= {
|
||||
* iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 } */
|
||||
#define MBEDTLS_OID_EC_ALG_UNRESTRICTED MBEDTLS_OID_ANSI_X9_62 "\x02\01"
|
||||
|
||||
/* id-ecDH OBJECT IDENTIFIER ::= {
|
||||
* iso(1) identified-organization(3) certicom(132)
|
||||
* schemes(1) ecdh(12) } */
|
||||
#define MBEDTLS_OID_EC_ALG_ECDH MBEDTLS_OID_CERTICOM "\x01\x0c"
|
||||
|
||||
/*
|
||||
* ECParameters namedCurve identifiers, from RFC 5480, RFC 5639, and SEC2
|
||||
*/
|
||||
|
||||
/* secp192r1 OBJECT IDENTIFIER ::= {
|
||||
* iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 1 } */
|
||||
#define MBEDTLS_OID_EC_GRP_SECP192R1 MBEDTLS_OID_ANSI_X9_62 "\x03\x01\x01"
|
||||
|
||||
/* secp224r1 OBJECT IDENTIFIER ::= {
|
||||
* iso(1) identified-organization(3) certicom(132) curve(0) 33 } */
|
||||
#define MBEDTLS_OID_EC_GRP_SECP224R1 MBEDTLS_OID_CERTICOM "\x00\x21"
|
||||
|
||||
/* secp256r1 OBJECT IDENTIFIER ::= {
|
||||
* iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 7 } */
|
||||
#define MBEDTLS_OID_EC_GRP_SECP256R1 MBEDTLS_OID_ANSI_X9_62 "\x03\x01\x07"
|
||||
|
||||
/* secp384r1 OBJECT IDENTIFIER ::= {
|
||||
* iso(1) identified-organization(3) certicom(132) curve(0) 34 } */
|
||||
#define MBEDTLS_OID_EC_GRP_SECP384R1 MBEDTLS_OID_CERTICOM "\x00\x22"
|
||||
|
||||
/* secp521r1 OBJECT IDENTIFIER ::= {
|
||||
* iso(1) identified-organization(3) certicom(132) curve(0) 35 } */
|
||||
#define MBEDTLS_OID_EC_GRP_SECP521R1 MBEDTLS_OID_CERTICOM "\x00\x23"
|
||||
|
||||
/* secp192k1 OBJECT IDENTIFIER ::= {
|
||||
* iso(1) identified-organization(3) certicom(132) curve(0) 31 } */
|
||||
#define MBEDTLS_OID_EC_GRP_SECP192K1 MBEDTLS_OID_CERTICOM "\x00\x1f"
|
||||
|
||||
/* secp224k1 OBJECT IDENTIFIER ::= {
|
||||
* iso(1) identified-organization(3) certicom(132) curve(0) 32 } */
|
||||
#define MBEDTLS_OID_EC_GRP_SECP224K1 MBEDTLS_OID_CERTICOM "\x00\x20"
|
||||
|
||||
/* secp256k1 OBJECT IDENTIFIER ::= {
|
||||
* iso(1) identified-organization(3) certicom(132) curve(0) 10 } */
|
||||
#define MBEDTLS_OID_EC_GRP_SECP256K1 MBEDTLS_OID_CERTICOM "\x00\x0a"
|
||||
|
||||
/* RFC 5639 4.1
|
||||
* ecStdCurvesAndGeneration OBJECT IDENTIFIER::= {iso(1)
|
||||
* identified-organization(3) teletrust(36) algorithm(3) signature-
|
||||
* algorithm(3) ecSign(2) 8}
|
||||
* ellipticCurve OBJECT IDENTIFIER ::= {ecStdCurvesAndGeneration 1}
|
||||
* versionOne OBJECT IDENTIFIER ::= {ellipticCurve 1} */
|
||||
#define MBEDTLS_OID_EC_BRAINPOOL_V1 MBEDTLS_OID_TELETRUST "\x03\x03\x02\x08\x01\x01"
|
||||
|
||||
/* brainpoolP256r1 OBJECT IDENTIFIER ::= {versionOne 7} */
|
||||
#define MBEDTLS_OID_EC_GRP_BP256R1 MBEDTLS_OID_EC_BRAINPOOL_V1 "\x07"
|
||||
|
||||
/* brainpoolP384r1 OBJECT IDENTIFIER ::= {versionOne 11} */
|
||||
#define MBEDTLS_OID_EC_GRP_BP384R1 MBEDTLS_OID_EC_BRAINPOOL_V1 "\x0B"
|
||||
|
||||
/* brainpoolP512r1 OBJECT IDENTIFIER ::= {versionOne 13} */
|
||||
#define MBEDTLS_OID_EC_GRP_BP512R1 MBEDTLS_OID_EC_BRAINPOOL_V1 "\x0D"
|
||||
|
||||
/*
|
||||
* SEC1 C.1
|
||||
*
|
||||
* prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
|
||||
* id-fieldType OBJECT IDENTIFIER ::= { ansi-X9-62 fieldType(1)}
|
||||
*/
|
||||
#define MBEDTLS_OID_ANSI_X9_62_FIELD_TYPE MBEDTLS_OID_ANSI_X9_62 "\x01"
|
||||
#define MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD MBEDTLS_OID_ANSI_X9_62_FIELD_TYPE "\x01"
|
||||
|
||||
/*
|
||||
* ECDSA signature identifiers, from RFC 5480
|
||||
*/
|
||||
#define MBEDTLS_OID_ANSI_X9_62_SIG MBEDTLS_OID_ANSI_X9_62 "\x04" /* signatures(4) */
|
||||
#define MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 MBEDTLS_OID_ANSI_X9_62_SIG "\x03" /* ecdsa-with-SHA2(3) */
|
||||
|
||||
/* ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
|
||||
* iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) 1 } */
|
||||
#define MBEDTLS_OID_ECDSA_SHA1 MBEDTLS_OID_ANSI_X9_62_SIG "\x01"
|
||||
|
||||
/* ecdsa-with-SHA224 OBJECT IDENTIFIER ::= {
|
||||
* iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
|
||||
* ecdsa-with-SHA2(3) 1 } */
|
||||
#define MBEDTLS_OID_ECDSA_SHA224 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x01"
|
||||
|
||||
/* ecdsa-with-SHA256 OBJECT IDENTIFIER ::= {
|
||||
* iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
|
||||
* ecdsa-with-SHA2(3) 2 } */
|
||||
#define MBEDTLS_OID_ECDSA_SHA256 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x02"
|
||||
|
||||
/* ecdsa-with-SHA384 OBJECT IDENTIFIER ::= {
|
||||
* iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
|
||||
* ecdsa-with-SHA2(3) 3 } */
|
||||
#define MBEDTLS_OID_ECDSA_SHA384 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x03"
|
||||
|
||||
/* ecdsa-with-SHA512 OBJECT IDENTIFIER ::= {
|
||||
* iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
|
||||
* ecdsa-with-SHA2(3) 4 } */
|
||||
#define MBEDTLS_OID_ECDSA_SHA512 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x04"
|
||||
|
||||
/*
|
||||
* EC key algorithms from RFC 8410
|
||||
*/
|
||||
|
||||
#define MBEDTLS_OID_X25519 MBEDTLS_OID_THAWTE "\x6e" /**< id-X25519 OBJECT IDENTIFIER ::= { 1 3 101 110 } */
|
||||
#define MBEDTLS_OID_X448 MBEDTLS_OID_THAWTE "\x6f" /**< id-X448 OBJECT IDENTIFIER ::= { 1 3 101 111 } */
|
||||
#define MBEDTLS_OID_ED25519 MBEDTLS_OID_THAWTE "\x70" /**< id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 } */
|
||||
#define MBEDTLS_OID_ED448 MBEDTLS_OID_THAWTE "\x71" /**< id-Ed448 OBJECT IDENTIFIER ::= { 1 3 101 113 } */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Base OID descriptor structure
|
||||
*/
|
||||
typedef struct mbedtls_oid_descriptor_t {
|
||||
const char *MBEDTLS_PRIVATE(asn1); /*!< OID ASN.1 representation */
|
||||
size_t MBEDTLS_PRIVATE(asn1_len); /*!< length of asn1 */
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
const char *MBEDTLS_PRIVATE(name); /*!< official name (e.g. from RFC) */
|
||||
const char *MBEDTLS_PRIVATE(description); /*!< human friendly description */
|
||||
#endif
|
||||
} mbedtls_oid_descriptor_t;
|
||||
|
||||
/**
|
||||
* \brief Translate an X.509 extension OID into local values
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param ext_type place to store the extension type
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_x509_ext_type(const mbedtls_asn1_buf *oid, int *ext_type);
|
||||
|
||||
/**
|
||||
* \brief Translate an X.509 attribute type OID into the short name
|
||||
* (e.g. the OID for an X520 Common Name into "CN")
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param short_name place to store the string pointer
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_attr_short_name(const mbedtls_asn1_buf *oid, const char **short_name);
|
||||
|
||||
/**
|
||||
* \brief Translate PublicKeyAlgorithm OID into pk_type
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param pk_alg place to store public key algorithm
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_pk_alg(const mbedtls_asn1_buf *oid, mbedtls_pk_type_t *pk_alg);
|
||||
|
||||
/**
|
||||
* \brief Translate pk_type into PublicKeyAlgorithm OID
|
||||
*
|
||||
* \param pk_alg Public key type to look for
|
||||
* \param oid place to store ASN.1 OID string pointer
|
||||
* \param olen length of the OID
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_oid_by_pk_alg(mbedtls_pk_type_t pk_alg,
|
||||
const char **oid, size_t *olen);
|
||||
|
||||
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
/**
|
||||
* \brief Translate NamedCurve OID into an EC group identifier
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param grp_id place to store group id
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_ec_grp(const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *grp_id);
|
||||
|
||||
/**
|
||||
* \brief Translate EC group identifier into NamedCurve OID
|
||||
*
|
||||
* \param grp_id EC group identifier
|
||||
* \param oid place to store ASN.1 OID string pointer
|
||||
* \param olen length of the OID
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_oid_by_ec_grp(mbedtls_ecp_group_id grp_id,
|
||||
const char **oid, size_t *olen);
|
||||
|
||||
/**
|
||||
* \brief Translate AlgorithmIdentifier OID into an EC group identifier,
|
||||
* for curves that are directly encoded at this level
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param grp_id place to store group id
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_ec_grp_algid(const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *grp_id);
|
||||
|
||||
/**
|
||||
* \brief Translate EC group identifier into AlgorithmIdentifier OID,
|
||||
* for curves that are directly encoded at this level
|
||||
*
|
||||
* \param grp_id EC group identifier
|
||||
* \param oid place to store ASN.1 OID string pointer
|
||||
* \param olen length of the OID
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_oid_by_ec_grp_algid(mbedtls_ecp_group_id grp_id,
|
||||
const char **oid, size_t *olen);
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
|
||||
|
||||
/**
|
||||
* \brief Translate SignatureAlgorithm OID into md_type and pk_type
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param md_alg place to store message digest algorithm
|
||||
* \param pk_alg place to store public key algorithm
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_sig_alg(const mbedtls_asn1_buf *oid,
|
||||
mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg);
|
||||
|
||||
/**
|
||||
* \brief Translate SignatureAlgorithm OID into description
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param desc place to store string pointer
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_sig_alg_desc(const mbedtls_asn1_buf *oid, const char **desc);
|
||||
|
||||
/**
|
||||
* \brief Translate md_type and pk_type into SignatureAlgorithm OID
|
||||
*
|
||||
* \param md_alg message digest algorithm
|
||||
* \param pk_alg public key algorithm
|
||||
* \param oid place to store ASN.1 OID string pointer
|
||||
* \param olen length of the OID
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_oid_by_sig_alg(mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
|
||||
const char **oid, size_t *olen);
|
||||
|
||||
/**
|
||||
* \brief Translate hmac algorithm OID into md_type
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param md_hmac place to store message hmac algorithm
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_md_hmac(const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_hmac);
|
||||
|
||||
/**
|
||||
* \brief Translate hash algorithm OID into md_type
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param md_alg place to store message digest algorithm
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_md_alg(const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg);
|
||||
|
||||
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
||||
/**
|
||||
* \brief Translate Extended Key Usage OID into description
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param desc place to store string pointer
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_extended_key_usage(const mbedtls_asn1_buf *oid, const char **desc);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Translate certificate policies OID into description
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param desc place to store string pointer
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_certificate_policies(const mbedtls_asn1_buf *oid, const char **desc);
|
||||
|
||||
/**
|
||||
* \brief Translate md_type into hash algorithm OID
|
||||
*
|
||||
* \param md_alg message digest algorithm
|
||||
* \param oid place to store ASN.1 OID string pointer
|
||||
* \param olen length of the OID
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_oid_by_md(mbedtls_md_type_t md_alg, const char **oid, size_t *olen);
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_C)
|
||||
/**
|
||||
* \brief Translate encryption algorithm OID into cipher_type
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param cipher_alg place to store cipher algorithm
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_cipher_alg(const mbedtls_asn1_buf *oid, mbedtls_cipher_type_t *cipher_alg);
|
||||
|
||||
#if defined(MBEDTLS_PKCS12_C)
|
||||
/**
|
||||
* \brief Translate PKCS#12 PBE algorithm OID into md_type and
|
||||
* cipher_type
|
||||
*
|
||||
* \param oid OID to use
|
||||
* \param md_alg place to store message digest algorithm
|
||||
* \param cipher_alg place to store cipher algorithm
|
||||
*
|
||||
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
|
||||
*/
|
||||
int mbedtls_oid_get_pkcs12_pbe_alg(const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg,
|
||||
mbedtls_cipher_type_t *cipher_alg);
|
||||
#endif /* MBEDTLS_PKCS12_C */
|
||||
#endif /* MBEDTLS_CIPHER_C */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* oid.h */
|
||||
@@ -1,160 +0,0 @@
|
||||
/**
|
||||
* \file pem.h
|
||||
*
|
||||
* \brief Privacy Enhanced Mail (PEM) decoding
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_PEM_H
|
||||
#define MBEDTLS_PEM_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* \name PEM Error codes
|
||||
* These error codes are returned in case of errors reading the
|
||||
* PEM data.
|
||||
* \{
|
||||
*/
|
||||
/** No PEM header or footer found. */
|
||||
#define MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT -0x1080
|
||||
/** PEM string is not as expected. */
|
||||
#define MBEDTLS_ERR_PEM_INVALID_DATA -0x1100
|
||||
/** Failed to allocate memory. */
|
||||
#define MBEDTLS_ERR_PEM_ALLOC_FAILED -0x1180
|
||||
/** RSA IV is not in hex-format. */
|
||||
#define MBEDTLS_ERR_PEM_INVALID_ENC_IV -0x1200
|
||||
/** Unsupported key encryption algorithm. */
|
||||
#define MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG -0x1280
|
||||
/** Private key password can't be empty. */
|
||||
#define MBEDTLS_ERR_PEM_PASSWORD_REQUIRED -0x1300
|
||||
/** Given private key password does not allow for correct decryption. */
|
||||
#define MBEDTLS_ERR_PEM_PASSWORD_MISMATCH -0x1380
|
||||
/** Unavailable feature, e.g. hashing/encryption combination. */
|
||||
#define MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE -0x1400
|
||||
/** Bad input parameters to function. */
|
||||
#define MBEDTLS_ERR_PEM_BAD_INPUT_DATA -0x1480
|
||||
/** \} name PEM Error codes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PEM_PARSE_C)
|
||||
/**
|
||||
* \brief PEM context structure
|
||||
*/
|
||||
typedef struct mbedtls_pem_context {
|
||||
unsigned char *MBEDTLS_PRIVATE(buf); /*!< buffer for decoded data */
|
||||
size_t MBEDTLS_PRIVATE(buflen); /*!< length of the buffer */
|
||||
unsigned char *MBEDTLS_PRIVATE(info); /*!< buffer for extra header information */
|
||||
}
|
||||
mbedtls_pem_context;
|
||||
|
||||
/**
|
||||
* \brief PEM context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
*/
|
||||
void mbedtls_pem_init(mbedtls_pem_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Read a buffer for PEM information and store the resulting
|
||||
* data into the specified context buffers.
|
||||
*
|
||||
* \param ctx context to use
|
||||
* \param header header string to seek and expect
|
||||
* \param footer footer string to seek and expect
|
||||
* \param data source data to look in (must be nul-terminated)
|
||||
* \param pwd password for decryption (can be NULL)
|
||||
* \param pwdlen length of password
|
||||
* \param use_len destination for total length used from data buffer. It is
|
||||
* set after header is correctly read, so unless you get
|
||||
* MBEDTLS_ERR_PEM_BAD_INPUT_DATA or
|
||||
* MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT, use_len is
|
||||
* the length to skip.
|
||||
*
|
||||
* \note Attempts to check password correctness by verifying if
|
||||
* the decrypted text starts with an ASN.1 sequence of
|
||||
* appropriate length
|
||||
*
|
||||
* \note \c mbedtls_pem_free must be called on PEM context before
|
||||
* the PEM context can be reused in another call to
|
||||
* \c mbedtls_pem_read_buffer
|
||||
*
|
||||
* \return 0 on success, or a specific PEM error code
|
||||
*/
|
||||
int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const char *footer,
|
||||
const unsigned char *data,
|
||||
const unsigned char *pwd,
|
||||
size_t pwdlen, size_t *use_len);
|
||||
|
||||
/**
|
||||
* \brief Get the pointer to the decoded binary data in a PEM context.
|
||||
*
|
||||
* \param ctx PEM context to access.
|
||||
* \param buflen On success, this will contain the length of the binary data.
|
||||
* This must be a valid (non-null) pointer.
|
||||
*
|
||||
* \return A pointer to the decoded binary data.
|
||||
*
|
||||
* \note The returned pointer remains valid only until \p ctx is
|
||||
modified or freed.
|
||||
*/
|
||||
static inline const unsigned char *mbedtls_pem_get_buffer(mbedtls_pem_context *ctx, size_t *buflen)
|
||||
{
|
||||
*buflen = ctx->MBEDTLS_PRIVATE(buflen);
|
||||
return ctx->MBEDTLS_PRIVATE(buf);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief PEM context memory freeing
|
||||
*
|
||||
* \param ctx context to be freed
|
||||
*/
|
||||
void mbedtls_pem_free(mbedtls_pem_context *ctx);
|
||||
#endif /* MBEDTLS_PEM_PARSE_C */
|
||||
|
||||
#if defined(MBEDTLS_PEM_WRITE_C)
|
||||
/**
|
||||
* \brief Write a buffer of PEM information from a DER encoded
|
||||
* buffer.
|
||||
*
|
||||
* \param header The header string to write.
|
||||
* \param footer The footer string to write.
|
||||
* \param der_data The DER data to encode.
|
||||
* \param der_len The length of the DER data \p der_data in Bytes.
|
||||
* \param buf The buffer to write to.
|
||||
* \param buf_len The length of the output buffer \p buf in Bytes.
|
||||
* \param olen The address at which to store the total length written
|
||||
* or required (if \p buf_len is not enough).
|
||||
*
|
||||
* \note You may pass \c NULL for \p buf and \c 0 for \p buf_len
|
||||
* to request the length of the resulting PEM buffer in
|
||||
* `*olen`.
|
||||
*
|
||||
* \note This function may be called with overlapping \p der_data
|
||||
* and \p buf buffers.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL if \p buf isn't large
|
||||
* enough to hold the PEM buffer. In this case, `*olen` holds
|
||||
* the required minimum size of \p buf.
|
||||
* \return Another PEM or BASE64 error code on other kinds of failure.
|
||||
*/
|
||||
int mbedtls_pem_write_buffer(const char *header, const char *footer,
|
||||
const unsigned char *der_data, size_t der_len,
|
||||
unsigned char *buf, size_t buf_len, size_t *olen);
|
||||
#endif /* MBEDTLS_PEM_WRITE_C */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* pem.h */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,186 +0,0 @@
|
||||
/**
|
||||
* \file pkcs12.h
|
||||
*
|
||||
* \brief PKCS#12 Personal Information Exchange Syntax
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_PKCS12_H
|
||||
#define MBEDTLS_PKCS12_H
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include "mbedtls/md.h"
|
||||
#include "mbedtls/cipher.h"
|
||||
#include "mbedtls/asn1.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/** Bad input parameters to function. */
|
||||
#define MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA -0x1F80
|
||||
/** Feature not available, e.g. unsupported encryption scheme. */
|
||||
#define MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE -0x1F00
|
||||
/** PBE ASN.1 data not as expected. */
|
||||
#define MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT -0x1E80
|
||||
/** Given private key password does not allow for correct decryption. */
|
||||
#define MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH -0x1E00
|
||||
|
||||
#define MBEDTLS_PKCS12_DERIVE_KEY 1 /**< encryption/decryption key */
|
||||
#define MBEDTLS_PKCS12_DERIVE_IV 2 /**< initialization vector */
|
||||
#define MBEDTLS_PKCS12_DERIVE_MAC_KEY 3 /**< integrity / MAC key */
|
||||
|
||||
#define MBEDTLS_PKCS12_PBE_DECRYPT MBEDTLS_DECRYPT
|
||||
#define MBEDTLS_PKCS12_PBE_ENCRYPT MBEDTLS_ENCRYPT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ASN1_PARSE_C) && defined(MBEDTLS_CIPHER_C)
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
/**
|
||||
* \brief PKCS12 Password Based function (encryption / decryption)
|
||||
* for cipher-based and mbedtls_md-based PBE's
|
||||
*
|
||||
* \note When encrypting, #MBEDTLS_CIPHER_PADDING_PKCS7 must
|
||||
* be enabled at compile time.
|
||||
*
|
||||
* \deprecated This function is deprecated and will be removed in a
|
||||
* future version of the library.
|
||||
* Please use mbedtls_pkcs12_pbe_ext() instead.
|
||||
*
|
||||
* \warning When decrypting:
|
||||
* - if #MBEDTLS_CIPHER_PADDING_PKCS7 is enabled at compile
|
||||
* time, this function validates the CBC padding and returns
|
||||
* #MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH if the padding is
|
||||
* invalid. Note that this can help active adversaries
|
||||
* attempting to brute-forcing the password. Note also that
|
||||
* there is no guarantee that an invalid password will be
|
||||
* detected (the chances of a valid padding with a random
|
||||
* password are about 1/255).
|
||||
* - if #MBEDTLS_CIPHER_PADDING_PKCS7 is disabled at compile
|
||||
* time, this function does not validate the CBC padding.
|
||||
*
|
||||
* \param pbe_params an ASN1 buffer containing the pkcs-12 PbeParams structure
|
||||
* \param mode either #MBEDTLS_PKCS12_PBE_ENCRYPT or
|
||||
* #MBEDTLS_PKCS12_PBE_DECRYPT
|
||||
* \param cipher_type the cipher used
|
||||
* \param md_type the mbedtls_md used
|
||||
* \param pwd Latin1-encoded password used. This may only be \c NULL when
|
||||
* \p pwdlen is 0. No null terminator should be used.
|
||||
* \param pwdlen length of the password (may be 0)
|
||||
* \param data the input data
|
||||
* \param len data length
|
||||
* \param output Output buffer.
|
||||
* On success, it contains the encrypted or decrypted data,
|
||||
* possibly followed by the CBC padding.
|
||||
* On failure, the content is indeterminate.
|
||||
* For decryption, there must be enough room for \p len
|
||||
* bytes.
|
||||
* For encryption, there must be enough room for
|
||||
* \p len + 1 bytes, rounded up to the block size of
|
||||
* the block cipher identified by \p pbe_params.
|
||||
*
|
||||
* \return 0 if successful, or a MBEDTLS_ERR_XXX code
|
||||
*/
|
||||
int MBEDTLS_DEPRECATED mbedtls_pkcs12_pbe(mbedtls_asn1_buf *pbe_params, int mode,
|
||||
mbedtls_cipher_type_t cipher_type,
|
||||
mbedtls_md_type_t md_type,
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
const unsigned char *data, size_t len,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
|
||||
|
||||
/**
|
||||
* \brief PKCS12 Password Based function (encryption / decryption)
|
||||
* for cipher-based and mbedtls_md-based PBE's
|
||||
*
|
||||
*
|
||||
* \warning When decrypting:
|
||||
* - This function validates the CBC padding and returns
|
||||
* #MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH if the padding is
|
||||
* invalid. Note that this can help active adversaries
|
||||
* attempting to brute-forcing the password. Note also that
|
||||
* there is no guarantee that an invalid password will be
|
||||
* detected (the chances of a valid padding with a random
|
||||
* password are about 1/255).
|
||||
*
|
||||
* \param pbe_params an ASN1 buffer containing the pkcs-12 PbeParams structure
|
||||
* \param mode either #MBEDTLS_PKCS12_PBE_ENCRYPT or
|
||||
* #MBEDTLS_PKCS12_PBE_DECRYPT
|
||||
* \param cipher_type the cipher used
|
||||
* \param md_type the mbedtls_md used
|
||||
* \param pwd Latin1-encoded password used. This may only be \c NULL when
|
||||
* \p pwdlen is 0. No null terminator should be used.
|
||||
* \param pwdlen length of the password (may be 0)
|
||||
* \param data the input data
|
||||
* \param len data length
|
||||
* \param output Output buffer.
|
||||
* On success, it contains the encrypted or decrypted data,
|
||||
* possibly followed by the CBC padding.
|
||||
* On failure, the content is indeterminate.
|
||||
* For decryption, there must be enough room for \p len
|
||||
* bytes.
|
||||
* For encryption, there must be enough room for
|
||||
* \p len + 1 bytes, rounded up to the block size of
|
||||
* the block cipher identified by \p pbe_params.
|
||||
* \param output_size size of output buffer.
|
||||
* This must be big enough to accommodate for output plus
|
||||
* padding data.
|
||||
* \param output_len On success, length of actual data written to the output buffer.
|
||||
*
|
||||
* \return 0 if successful, or a MBEDTLS_ERR_XXX code
|
||||
*/
|
||||
int mbedtls_pkcs12_pbe_ext(mbedtls_asn1_buf *pbe_params, int mode,
|
||||
mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type,
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
const unsigned char *data, size_t len,
|
||||
unsigned char *output, size_t output_size,
|
||||
size_t *output_len);
|
||||
|
||||
#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
|
||||
|
||||
#endif /* MBEDTLS_ASN1_PARSE_C && MBEDTLS_CIPHER_C */
|
||||
|
||||
/**
|
||||
* \brief The PKCS#12 derivation function uses a password and a salt
|
||||
* to produce pseudo-random bits for a particular "purpose".
|
||||
*
|
||||
* Depending on the given id, this function can produce an
|
||||
* encryption/decryption key, an initialization vector or an
|
||||
* integrity key.
|
||||
*
|
||||
* \param data buffer to store the derived data in
|
||||
* \param datalen length of buffer to fill
|
||||
* \param pwd The password to use. For compliance with PKCS#12 §B.1, this
|
||||
* should be a BMPString, i.e. a Unicode string where each
|
||||
* character is encoded as 2 bytes in big-endian order, with
|
||||
* no byte order mark and with a null terminator (i.e. the
|
||||
* last two bytes should be 0x00 0x00).
|
||||
* \param pwdlen length of the password (may be 0).
|
||||
* \param salt Salt buffer to use. This may only be \c NULL when
|
||||
* \p saltlen is 0.
|
||||
* \param saltlen length of the salt (may be zero)
|
||||
* \param mbedtls_md mbedtls_md type to use during the derivation
|
||||
* \param id id that describes the purpose (can be
|
||||
* #MBEDTLS_PKCS12_DERIVE_KEY, #MBEDTLS_PKCS12_DERIVE_IV or
|
||||
* #MBEDTLS_PKCS12_DERIVE_MAC_KEY)
|
||||
* \param iterations number of iterations
|
||||
*
|
||||
* \return 0 if successful, or a MD, BIGNUM type error.
|
||||
*/
|
||||
int mbedtls_pkcs12_derivation(unsigned char *data, size_t datalen,
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
const unsigned char *salt, size_t saltlen,
|
||||
mbedtls_md_type_t mbedtls_md, int id, int iterations);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* pkcs12.h */
|
||||
@@ -1,198 +0,0 @@
|
||||
/**
|
||||
* \file pkcs5.h
|
||||
*
|
||||
* \brief PKCS#5 functions
|
||||
*
|
||||
* \author Mathias Olsson <mathias@kompetensum.com>
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_PKCS5_H
|
||||
#define MBEDTLS_PKCS5_H
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
||||
#include "mbedtls/asn1.h"
|
||||
#include "mbedtls/md.h"
|
||||
#include "mbedtls/cipher.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** Bad input parameters to function. */
|
||||
#define MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA -0x2f80
|
||||
/** Unexpected ASN.1 data. */
|
||||
#define MBEDTLS_ERR_PKCS5_INVALID_FORMAT -0x2f00
|
||||
/** Requested encryption or digest alg not available. */
|
||||
#define MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE -0x2e80
|
||||
/** Given private key password does not allow for correct decryption. */
|
||||
#define MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH -0x2e00
|
||||
|
||||
#define MBEDTLS_PKCS5_DECRYPT MBEDTLS_DECRYPT
|
||||
#define MBEDTLS_PKCS5_ENCRYPT MBEDTLS_ENCRYPT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ASN1_PARSE_C) && defined(MBEDTLS_CIPHER_C)
|
||||
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
/**
|
||||
* \brief PKCS#5 PBES2 function
|
||||
*
|
||||
* \note When encrypting, #MBEDTLS_CIPHER_PADDING_PKCS7 must
|
||||
* be enabled at compile time.
|
||||
*
|
||||
* \deprecated This function is deprecated and will be removed in a
|
||||
* future version of the library.
|
||||
* Please use mbedtls_pkcs5_pbes2_ext() instead.
|
||||
*
|
||||
* \warning When decrypting:
|
||||
* - if #MBEDTLS_CIPHER_PADDING_PKCS7 is enabled at compile
|
||||
* time, this function validates the CBC padding and returns
|
||||
* #MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH if the padding is
|
||||
* invalid. Note that this can help active adversaries
|
||||
* attempting to brute-forcing the password. Note also that
|
||||
* there is no guarantee that an invalid password will be
|
||||
* detected (the chances of a valid padding with a random
|
||||
* password are about 1/255).
|
||||
* - if #MBEDTLS_CIPHER_PADDING_PKCS7 is disabled at compile
|
||||
* time, this function does not validate the CBC padding.
|
||||
*
|
||||
* \param pbe_params the ASN.1 algorithm parameters
|
||||
* \param mode either #MBEDTLS_PKCS5_DECRYPT or #MBEDTLS_PKCS5_ENCRYPT
|
||||
* \param pwd password to use when generating key
|
||||
* \param pwdlen length of password
|
||||
* \param data data to process
|
||||
* \param datalen length of data
|
||||
* \param output Output buffer.
|
||||
* On success, it contains the encrypted or decrypted data,
|
||||
* possibly followed by the CBC padding.
|
||||
* On failure, the content is indeterminate.
|
||||
* For decryption, there must be enough room for \p datalen
|
||||
* bytes.
|
||||
* For encryption, there must be enough room for
|
||||
* \p datalen + 1 bytes, rounded up to the block size of
|
||||
* the block cipher identified by \p pbe_params.
|
||||
*
|
||||
* \returns 0 on success, or a MBEDTLS_ERR_XXX code if verification fails.
|
||||
*/
|
||||
int MBEDTLS_DEPRECATED mbedtls_pkcs5_pbes2(const mbedtls_asn1_buf *pbe_params, int mode,
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
const unsigned char *data, size_t datalen,
|
||||
unsigned char *output);
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
|
||||
|
||||
/**
|
||||
* \brief PKCS#5 PBES2 function
|
||||
*
|
||||
* \warning When decrypting:
|
||||
* - This function validates the CBC padding and returns
|
||||
* #MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH if the padding is
|
||||
* invalid. Note that this can help active adversaries
|
||||
* attempting to brute-forcing the password. Note also that
|
||||
* there is no guarantee that an invalid password will be
|
||||
* detected (the chances of a valid padding with a random
|
||||
* password are about 1/255).
|
||||
*
|
||||
* \param pbe_params the ASN.1 algorithm parameters
|
||||
* \param mode either #MBEDTLS_PKCS5_DECRYPT or #MBEDTLS_PKCS5_ENCRYPT
|
||||
* \param pwd password to use when generating key
|
||||
* \param pwdlen length of password
|
||||
* \param data data to process
|
||||
* \param datalen length of data
|
||||
* \param output Output buffer.
|
||||
* On success, it contains the decrypted data.
|
||||
* On failure, the content is indetermidate.
|
||||
* For decryption, there must be enough room for \p datalen
|
||||
* bytes.
|
||||
* For encryption, there must be enough room for
|
||||
* \p datalen + 1 bytes, rounded up to the block size of
|
||||
* the block cipher identified by \p pbe_params.
|
||||
* \param output_size size of output buffer.
|
||||
* This must be big enough to accommodate for output plus
|
||||
* padding data.
|
||||
* \param output_len On success, length of actual data written to the output buffer.
|
||||
*
|
||||
* \returns 0 on success, or a MBEDTLS_ERR_XXX code if parsing or decryption fails.
|
||||
*/
|
||||
int mbedtls_pkcs5_pbes2_ext(const mbedtls_asn1_buf *pbe_params, int mode,
|
||||
const unsigned char *pwd, size_t pwdlen,
|
||||
const unsigned char *data, size_t datalen,
|
||||
unsigned char *output, size_t output_size,
|
||||
size_t *output_len);
|
||||
|
||||
#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
|
||||
|
||||
#endif /* MBEDTLS_ASN1_PARSE_C && MBEDTLS_CIPHER_C*/
|
||||
|
||||
/**
|
||||
* \brief PKCS#5 PBKDF2 using HMAC without using the HMAC context
|
||||
*
|
||||
* \param md_type Hash algorithm used
|
||||
* \param password Password to use when generating key
|
||||
* \param plen Length of password
|
||||
* \param salt Salt to use when generating key
|
||||
* \param slen Length of salt
|
||||
* \param iteration_count Iteration count
|
||||
* \param key_length Length of generated key in bytes
|
||||
* \param output Generated key. Must be at least as big as key_length
|
||||
*
|
||||
* \returns 0 on success, or a MBEDTLS_ERR_XXX code if verification fails.
|
||||
*/
|
||||
int mbedtls_pkcs5_pbkdf2_hmac_ext(mbedtls_md_type_t md_type,
|
||||
const unsigned char *password,
|
||||
size_t plen, const unsigned char *salt, size_t slen,
|
||||
unsigned int iteration_count,
|
||||
uint32_t key_length, unsigned char *output);
|
||||
|
||||
#if defined(MBEDTLS_MD_C)
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
/**
|
||||
* \brief PKCS#5 PBKDF2 using HMAC
|
||||
*
|
||||
* \deprecated Superseded by mbedtls_pkcs5_pbkdf2_hmac_ext().
|
||||
*
|
||||
* \param ctx Generic HMAC context
|
||||
* \param password Password to use when generating key
|
||||
* \param plen Length of password
|
||||
* \param salt Salt to use when generating key
|
||||
* \param slen Length of salt
|
||||
* \param iteration_count Iteration count
|
||||
* \param key_length Length of generated key in bytes
|
||||
* \param output Generated key. Must be at least as big as key_length
|
||||
*
|
||||
* \returns 0 on success, or a MBEDTLS_ERR_XXX code if verification fails.
|
||||
*/
|
||||
int MBEDTLS_DEPRECATED mbedtls_pkcs5_pbkdf2_hmac(mbedtls_md_context_t *ctx,
|
||||
const unsigned char *password,
|
||||
size_t plen,
|
||||
const unsigned char *salt,
|
||||
size_t slen,
|
||||
unsigned int iteration_count,
|
||||
uint32_t key_length,
|
||||
unsigned char *output);
|
||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||
#endif /* MBEDTLS_MD_C */
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int mbedtls_pkcs5_self_test(int verbose);
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* pkcs5.h */
|
||||
@@ -1,485 +0,0 @@
|
||||
/**
|
||||
* \file platform.h
|
||||
*
|
||||
* \brief This file contains the definitions and functions of the
|
||||
* Mbed TLS platform abstraction layer.
|
||||
*
|
||||
* The platform abstraction layer removes the need for the library
|
||||
* to directly link to standard C library functions or operating
|
||||
* system services, making the library easier to port and embed.
|
||||
* Application developers and users of the library can provide their own
|
||||
* implementations of these functions, or implementations specific to
|
||||
* their platform, which can be statically linked to the library or
|
||||
* dynamically configured at runtime.
|
||||
*
|
||||
* When all compilation options related to platform abstraction are
|
||||
* disabled, this header just defines `mbedtls_xxx` function names
|
||||
* as aliases to the standard `xxx` function.
|
||||
*
|
||||
* Most modules in the library and example programs are expected to
|
||||
* include this header.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_PLATFORM_H
|
||||
#define MBEDTLS_PLATFORM_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
#include "mbedtls/platform_time.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \name SECTION: Module settings
|
||||
*
|
||||
* The configuration options you can set for this module are in this section.
|
||||
* Either change them in mbedtls_config.h or define them on the compiler command line.
|
||||
* \{
|
||||
*/
|
||||
|
||||
/* The older Microsoft Windows common runtime provides non-conforming
|
||||
* implementations of some standard library functions, including snprintf
|
||||
* and vsnprintf. This affects MSVC and MinGW builds.
|
||||
*/
|
||||
#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900)
|
||||
#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF
|
||||
#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#if defined(MBEDTLS_HAVE_TIME)
|
||||
#include <time.h>
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
|
||||
#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
|
||||
#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use. */
|
||||
#else
|
||||
#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< The default \c snprintf function to use. */
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF)
|
||||
#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
|
||||
#define MBEDTLS_PLATFORM_STD_VSNPRINTF mbedtls_platform_win32_vsnprintf /**< The default \c vsnprintf function to use. */
|
||||
#else
|
||||
#define MBEDTLS_PLATFORM_STD_VSNPRINTF vsnprintf /**< The default \c vsnprintf function to use. */
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
|
||||
#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< The default \c printf function to use. */
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF)
|
||||
#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< The default \c fprintf function to use. */
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
|
||||
#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< The default \c calloc function to use. */
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_FREE)
|
||||
#define MBEDTLS_PLATFORM_STD_FREE free /**< The default \c free function to use. */
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_SETBUF)
|
||||
#define MBEDTLS_PLATFORM_STD_SETBUF setbuf /**< The default \c setbuf function to use. */
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_EXIT)
|
||||
#define MBEDTLS_PLATFORM_STD_EXIT exit /**< The default \c exit function to use. */
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_TIME)
|
||||
#define MBEDTLS_PLATFORM_STD_TIME time /**< The default \c time function to use. */
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS)
|
||||
#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS /**< The default exit value to use. */
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
|
||||
#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE /**< The default exit value to use. */
|
||||
#endif
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ)
|
||||
#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE)
|
||||
#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write
|
||||
#endif
|
||||
#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE)
|
||||
#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile"
|
||||
#endif
|
||||
#endif /* MBEDTLS_FS_IO */
|
||||
#else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
|
||||
#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR)
|
||||
#include MBEDTLS_PLATFORM_STD_MEM_HDR
|
||||
#endif
|
||||
#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
|
||||
|
||||
/* Enable certain documented defines only when generating doxygen to avoid
|
||||
* an "unrecognized define" error. */
|
||||
#if defined(__DOXYGEN__) && !defined(MBEDTLS_PLATFORM_STD_CALLOC)
|
||||
#define MBEDTLS_PLATFORM_STD_CALLOC
|
||||
#endif
|
||||
|
||||
#if defined(__DOXYGEN__) && !defined(MBEDTLS_PLATFORM_STD_FREE)
|
||||
#define MBEDTLS_PLATFORM_STD_FREE
|
||||
#endif
|
||||
|
||||
/** \} name SECTION: Module settings */
|
||||
|
||||
/*
|
||||
* The function pointers for calloc and free.
|
||||
* Please see MBEDTLS_PLATFORM_STD_CALLOC and MBEDTLS_PLATFORM_STD_FREE
|
||||
* in mbedtls_config.h for more information about behaviour and requirements.
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_MEMORY)
|
||||
#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \
|
||||
defined(MBEDTLS_PLATFORM_CALLOC_MACRO)
|
||||
#undef mbedtls_free
|
||||
#undef mbedtls_calloc
|
||||
#define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO
|
||||
#define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO
|
||||
#else
|
||||
/* For size_t */
|
||||
#include <stddef.h>
|
||||
extern void *mbedtls_calloc(size_t n, size_t size);
|
||||
extern void mbedtls_free(void *ptr);
|
||||
|
||||
/**
|
||||
* \brief This function dynamically sets the memory-management
|
||||
* functions used by the library, during runtime.
|
||||
*
|
||||
* \param calloc_func The \c calloc function implementation.
|
||||
* \param free_func The \c free function implementation.
|
||||
*
|
||||
* \return \c 0.
|
||||
*/
|
||||
int mbedtls_platform_set_calloc_free(void *(*calloc_func)(size_t, size_t),
|
||||
void (*free_func)(void *));
|
||||
#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */
|
||||
#else /* !MBEDTLS_PLATFORM_MEMORY */
|
||||
#undef mbedtls_free
|
||||
#undef mbedtls_calloc
|
||||
#define mbedtls_free free
|
||||
#define mbedtls_calloc calloc
|
||||
#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */
|
||||
|
||||
/*
|
||||
* The function pointers for fprintf
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
|
||||
/* We need FILE * */
|
||||
#include <stdio.h>
|
||||
extern int (*mbedtls_fprintf)(FILE *stream, const char *format, ...);
|
||||
|
||||
/**
|
||||
* \brief This function dynamically configures the fprintf
|
||||
* function that is called when the
|
||||
* mbedtls_fprintf() function is invoked by the library.
|
||||
*
|
||||
* \param fprintf_func The \c fprintf function implementation.
|
||||
*
|
||||
* \return \c 0.
|
||||
*/
|
||||
int mbedtls_platform_set_fprintf(int (*fprintf_func)(FILE *stream, const char *,
|
||||
...));
|
||||
#else
|
||||
#undef mbedtls_fprintf
|
||||
#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO)
|
||||
#define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO
|
||||
#else
|
||||
#define mbedtls_fprintf fprintf
|
||||
#endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */
|
||||
#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */
|
||||
|
||||
/*
|
||||
* The function pointers for printf
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
|
||||
extern int (*mbedtls_printf)(const char *format, ...);
|
||||
|
||||
/**
|
||||
* \brief This function dynamically configures the snprintf
|
||||
* function that is called when the mbedtls_snprintf()
|
||||
* function is invoked by the library.
|
||||
*
|
||||
* \param printf_func The \c printf function implementation.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
int mbedtls_platform_set_printf(int (*printf_func)(const char *, ...));
|
||||
#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */
|
||||
#undef mbedtls_printf
|
||||
#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO)
|
||||
#define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO
|
||||
#else
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */
|
||||
#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */
|
||||
|
||||
/*
|
||||
* The function pointers for snprintf
|
||||
*
|
||||
* The snprintf implementation should conform to C99:
|
||||
* - it *must* always correctly zero-terminate the buffer
|
||||
* (except when n == 0, then it must leave the buffer untouched)
|
||||
* - however it is acceptable to return -1 instead of the required length when
|
||||
* the destination buffer is too short.
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
|
||||
/* For Windows (inc. MSYS2), we provide our own fixed implementation */
|
||||
int mbedtls_platform_win32_snprintf(char *s, size_t n, const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
|
||||
extern int (*mbedtls_snprintf)(char *s, size_t n, const char *format, ...);
|
||||
|
||||
/**
|
||||
* \brief This function allows configuring a custom
|
||||
* \c snprintf function pointer.
|
||||
*
|
||||
* \param snprintf_func The \c snprintf function implementation.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
int mbedtls_platform_set_snprintf(int (*snprintf_func)(char *s, size_t n,
|
||||
const char *format, ...));
|
||||
#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
|
||||
#undef mbedtls_snprintf
|
||||
#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
|
||||
#define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO
|
||||
#else
|
||||
#define mbedtls_snprintf MBEDTLS_PLATFORM_STD_SNPRINTF
|
||||
#endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */
|
||||
#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
|
||||
|
||||
/*
|
||||
* The function pointers for vsnprintf
|
||||
*
|
||||
* The vsnprintf implementation should conform to C99:
|
||||
* - it *must* always correctly zero-terminate the buffer
|
||||
* (except when n == 0, then it must leave the buffer untouched)
|
||||
* - however it is acceptable to return -1 instead of the required length when
|
||||
* the destination buffer is too short.
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
|
||||
#include <stdarg.h>
|
||||
/* For Older Windows (inc. MSYS2), we provide our own fixed implementation */
|
||||
int mbedtls_platform_win32_vsnprintf(char *s, size_t n, const char *fmt, va_list arg);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT)
|
||||
#include <stdarg.h>
|
||||
extern int (*mbedtls_vsnprintf)(char *s, size_t n, const char *format, va_list arg);
|
||||
|
||||
/**
|
||||
* \brief Set your own snprintf function pointer
|
||||
*
|
||||
* \param vsnprintf_func The \c vsnprintf function implementation
|
||||
*
|
||||
* \return \c 0
|
||||
*/
|
||||
int mbedtls_platform_set_vsnprintf(int (*vsnprintf_func)(char *s, size_t n,
|
||||
const char *format, va_list arg));
|
||||
#else /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
|
||||
#undef mbedtls_vsnprintf
|
||||
#if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
|
||||
#define mbedtls_vsnprintf MBEDTLS_PLATFORM_VSNPRINTF_MACRO
|
||||
#else
|
||||
#define mbedtls_vsnprintf vsnprintf
|
||||
#endif /* MBEDTLS_PLATFORM_VSNPRINTF_MACRO */
|
||||
#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
|
||||
|
||||
/*
|
||||
* The function pointers for setbuf
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_SETBUF_ALT)
|
||||
#include <stdio.h>
|
||||
/**
|
||||
* \brief Function pointer to call for `setbuf()` functionality
|
||||
* (changing the internal buffering on stdio calls).
|
||||
*
|
||||
* \note The library calls this function to disable
|
||||
* buffering when reading or writing sensitive data,
|
||||
* to avoid having extra copies of sensitive data
|
||||
* remaining in stdio buffers after the file is
|
||||
* closed. If this is not a concern, for example if
|
||||
* your platform's stdio doesn't have any buffering,
|
||||
* you can set mbedtls_setbuf to a function that
|
||||
* does nothing.
|
||||
*
|
||||
* The library always calls this function with
|
||||
* `buf` equal to `NULL`.
|
||||
*/
|
||||
extern void (*mbedtls_setbuf)(FILE *stream, char *buf);
|
||||
|
||||
/**
|
||||
* \brief Dynamically configure the function that is called
|
||||
* when the mbedtls_setbuf() function is called by the
|
||||
* library.
|
||||
*
|
||||
* \param setbuf_func The \c setbuf function implementation
|
||||
*
|
||||
* \return \c 0
|
||||
*/
|
||||
int mbedtls_platform_set_setbuf(void (*setbuf_func)(
|
||||
FILE *stream, char *buf));
|
||||
#else
|
||||
#undef mbedtls_setbuf
|
||||
#if defined(MBEDTLS_PLATFORM_SETBUF_MACRO)
|
||||
/**
|
||||
* \brief Macro defining the function for the library to
|
||||
* call for `setbuf` functionality (changing the
|
||||
* internal buffering on stdio calls).
|
||||
*
|
||||
* \note See extra comments on the mbedtls_setbuf() function
|
||||
* pointer above.
|
||||
*
|
||||
* \return \c 0 on success, negative on error.
|
||||
*/
|
||||
#define mbedtls_setbuf MBEDTLS_PLATFORM_SETBUF_MACRO
|
||||
#else
|
||||
#define mbedtls_setbuf setbuf
|
||||
#endif /* MBEDTLS_PLATFORM_SETBUF_MACRO */
|
||||
#endif /* MBEDTLS_PLATFORM_SETBUF_ALT */
|
||||
|
||||
/*
|
||||
* The function pointers for exit
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_EXIT_ALT)
|
||||
extern void (*mbedtls_exit)(int status);
|
||||
|
||||
/**
|
||||
* \brief This function dynamically configures the exit
|
||||
* function that is called when the mbedtls_exit()
|
||||
* function is invoked by the library.
|
||||
*
|
||||
* \param exit_func The \c exit function implementation.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
int mbedtls_platform_set_exit(void (*exit_func)(int status));
|
||||
#else
|
||||
#undef mbedtls_exit
|
||||
#if defined(MBEDTLS_PLATFORM_EXIT_MACRO)
|
||||
#define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO
|
||||
#else
|
||||
#define mbedtls_exit exit
|
||||
#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */
|
||||
#endif /* MBEDTLS_PLATFORM_EXIT_ALT */
|
||||
|
||||
/*
|
||||
* The default exit values
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS)
|
||||
#define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS
|
||||
#else
|
||||
#define MBEDTLS_EXIT_SUCCESS 0
|
||||
#endif
|
||||
#if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
|
||||
#define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE
|
||||
#else
|
||||
#define MBEDTLS_EXIT_FAILURE 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The function pointers for reading from and writing a seed file to
|
||||
* Non-Volatile storage (NV) in a platform-independent way
|
||||
*
|
||||
* Only enabled when the NV seed entropy source is enabled
|
||||
*/
|
||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
|
||||
#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
|
||||
/* Internal standard platform definitions */
|
||||
int mbedtls_platform_std_nv_seed_read(unsigned char *buf, size_t buf_len);
|
||||
int mbedtls_platform_std_nv_seed_write(unsigned char *buf, size_t buf_len);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
|
||||
extern int (*mbedtls_nv_seed_read)(unsigned char *buf, size_t buf_len);
|
||||
extern int (*mbedtls_nv_seed_write)(unsigned char *buf, size_t buf_len);
|
||||
|
||||
/**
|
||||
* \brief This function allows configuring custom seed file writing and
|
||||
* reading functions.
|
||||
*
|
||||
* \param nv_seed_read_func The seed reading function implementation.
|
||||
* \param nv_seed_write_func The seed writing function implementation.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
int mbedtls_platform_set_nv_seed(
|
||||
int (*nv_seed_read_func)(unsigned char *buf, size_t buf_len),
|
||||
int (*nv_seed_write_func)(unsigned char *buf, size_t buf_len)
|
||||
);
|
||||
#else
|
||||
#undef mbedtls_nv_seed_read
|
||||
#undef mbedtls_nv_seed_write
|
||||
#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \
|
||||
defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO)
|
||||
#define mbedtls_nv_seed_read MBEDTLS_PLATFORM_NV_SEED_READ_MACRO
|
||||
#define mbedtls_nv_seed_write MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO
|
||||
#else
|
||||
#define mbedtls_nv_seed_read mbedtls_platform_std_nv_seed_read
|
||||
#define mbedtls_nv_seed_write mbedtls_platform_std_nv_seed_write
|
||||
#endif
|
||||
#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
|
||||
#endif /* MBEDTLS_ENTROPY_NV_SEED */
|
||||
|
||||
#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT)
|
||||
|
||||
/**
|
||||
* \brief The platform context structure.
|
||||
*
|
||||
* \note This structure may be used to assist platform-specific
|
||||
* setup or teardown operations.
|
||||
*/
|
||||
typedef struct mbedtls_platform_context {
|
||||
char MBEDTLS_PRIVATE(dummy); /**< A placeholder member, as empty structs are not portable. */
|
||||
}
|
||||
mbedtls_platform_context;
|
||||
|
||||
#else
|
||||
#include "platform_alt.h"
|
||||
#endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
|
||||
|
||||
/**
|
||||
* \brief This function performs any platform-specific initialization
|
||||
* operations.
|
||||
*
|
||||
* \note This function should be called before any other library functions.
|
||||
*
|
||||
* Its implementation is platform-specific, and unless
|
||||
* platform-specific code is provided, it does nothing.
|
||||
*
|
||||
* \note The usage and necessity of this function is dependent on the platform.
|
||||
*
|
||||
* \param ctx The platform context.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
int mbedtls_platform_setup(mbedtls_platform_context *ctx);
|
||||
/**
|
||||
* \brief This function performs any platform teardown operations.
|
||||
*
|
||||
* \note This function should be called after every other Mbed TLS module
|
||||
* has been correctly freed using the appropriate free function.
|
||||
*
|
||||
* Its implementation is platform-specific, and unless
|
||||
* platform-specific code is provided, it does nothing.
|
||||
*
|
||||
* \note The usage and necessity of this function is dependent on the platform.
|
||||
*
|
||||
* \param ctx The platform context.
|
||||
*
|
||||
*/
|
||||
void mbedtls_platform_teardown(mbedtls_platform_context *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* platform.h */
|
||||
@@ -1,79 +0,0 @@
|
||||
/**
|
||||
* \file platform_time.h
|
||||
*
|
||||
* \brief Mbed TLS Platform time abstraction
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_PLATFORM_TIME_H
|
||||
#define MBEDTLS_PLATFORM_TIME_H
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The time_t datatype
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO)
|
||||
typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t;
|
||||
#else
|
||||
/* For time_t */
|
||||
#include <time.h>
|
||||
typedef time_t mbedtls_time_t;
|
||||
#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO)
|
||||
typedef MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO mbedtls_ms_time_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
typedef int64_t mbedtls_ms_time_t;
|
||||
#endif /* MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO */
|
||||
|
||||
/**
|
||||
* \brief Get time in milliseconds.
|
||||
*
|
||||
* \return Monotonically-increasing current time in milliseconds.
|
||||
*
|
||||
* \note Define MBEDTLS_PLATFORM_MS_TIME_ALT to be able to provide an
|
||||
* alternative implementation
|
||||
*
|
||||
* \warning This function returns a monotonically-increasing time value from a
|
||||
* start time that will differ from platform to platform, and possibly
|
||||
* from run to run of the process.
|
||||
*
|
||||
*/
|
||||
mbedtls_ms_time_t mbedtls_ms_time(void);
|
||||
|
||||
/*
|
||||
* The function pointers for time
|
||||
*/
|
||||
#if defined(MBEDTLS_PLATFORM_TIME_ALT)
|
||||
extern mbedtls_time_t (*mbedtls_time)(mbedtls_time_t *time);
|
||||
|
||||
/**
|
||||
* \brief Set your own time function pointer
|
||||
*
|
||||
* \param time_func the time function implementation
|
||||
*
|
||||
* \return 0
|
||||
*/
|
||||
int mbedtls_platform_set_time(mbedtls_time_t (*time_func)(mbedtls_time_t *time));
|
||||
#else
|
||||
#if defined(MBEDTLS_PLATFORM_TIME_MACRO)
|
||||
#define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO
|
||||
#else
|
||||
#define mbedtls_time time
|
||||
#endif /* MBEDTLS_PLATFORM_TIME_MACRO */
|
||||
#endif /* MBEDTLS_PLATFORM_TIME_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* platform_time.h */
|
||||
@@ -1,197 +0,0 @@
|
||||
/**
|
||||
* \file platform_util.h
|
||||
*
|
||||
* \brief Common and shared functions used by multiple modules in the Mbed TLS
|
||||
* library.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_PLATFORM_UTIL_H
|
||||
#define MBEDTLS_PLATFORM_UTIL_H
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#if defined(MBEDTLS_HAVE_TIME_DATE)
|
||||
#include "mbedtls/platform_time.h"
|
||||
#include <time.h>
|
||||
#endif /* MBEDTLS_HAVE_TIME_DATE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Internal helper macros for deprecating API constants. */
|
||||
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
|
||||
#if defined(MBEDTLS_DEPRECATED_WARNING)
|
||||
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
|
||||
MBEDTLS_DEPRECATED typedef char const *mbedtls_deprecated_string_constant_t;
|
||||
#define MBEDTLS_DEPRECATED_STRING_CONSTANT(VAL) \
|
||||
((mbedtls_deprecated_string_constant_t) (VAL))
|
||||
MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t;
|
||||
#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT(VAL) \
|
||||
((mbedtls_deprecated_numeric_constant_t) (VAL))
|
||||
#else /* MBEDTLS_DEPRECATED_WARNING */
|
||||
#define MBEDTLS_DEPRECATED
|
||||
#define MBEDTLS_DEPRECATED_STRING_CONSTANT(VAL) VAL
|
||||
#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT(VAL) VAL
|
||||
#endif /* MBEDTLS_DEPRECATED_WARNING */
|
||||
#endif /* MBEDTLS_DEPRECATED_REMOVED */
|
||||
|
||||
/* Implementation of the check-return facility.
|
||||
* See the user documentation in mbedtls_config.h.
|
||||
*
|
||||
* Do not use this macro directly to annotate function: instead,
|
||||
* use one of MBEDTLS_CHECK_RETURN_CRITICAL or MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
* depending on how important it is to check the return value.
|
||||
*/
|
||||
#if !defined(MBEDTLS_CHECK_RETURN)
|
||||
#if defined(__GNUC__)
|
||||
#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__))
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1700
|
||||
#include <sal.h>
|
||||
#define MBEDTLS_CHECK_RETURN _Check_return_
|
||||
#else
|
||||
#define MBEDTLS_CHECK_RETURN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** Critical-failure function
|
||||
*
|
||||
* This macro appearing at the beginning of the declaration of a function
|
||||
* indicates that its return value should be checked in all applications.
|
||||
* Omitting the check is very likely to indicate a bug in the application
|
||||
* and will result in a compile-time warning if #MBEDTLS_CHECK_RETURN
|
||||
* is implemented for the compiler in use.
|
||||
*
|
||||
* \note The use of this macro is a work in progress.
|
||||
* This macro may be added to more functions in the future.
|
||||
* Such an extension is not considered an API break, provided that
|
||||
* there are near-unavoidable circumstances under which the function
|
||||
* can fail. For example, signature/MAC/AEAD verification functions,
|
||||
* and functions that require a random generator, are considered
|
||||
* return-check-critical.
|
||||
*/
|
||||
#define MBEDTLS_CHECK_RETURN_CRITICAL MBEDTLS_CHECK_RETURN
|
||||
|
||||
/** Ordinary-failure function
|
||||
*
|
||||
* This macro appearing at the beginning of the declaration of a function
|
||||
* indicates that its return value should be generally be checked in portable
|
||||
* applications. Omitting the check will result in a compile-time warning if
|
||||
* #MBEDTLS_CHECK_RETURN is implemented for the compiler in use and
|
||||
* #MBEDTLS_CHECK_RETURN_WARNING is enabled in the compile-time configuration.
|
||||
*
|
||||
* You can use #MBEDTLS_IGNORE_RETURN to explicitly ignore the return value
|
||||
* of a function that is annotated with #MBEDTLS_CHECK_RETURN.
|
||||
*
|
||||
* \note The use of this macro is a work in progress.
|
||||
* This macro will be added to more functions in the future.
|
||||
* Eventually this should appear before most functions returning
|
||||
* an error code (as \c int in the \c mbedtls_xxx API or
|
||||
* as ::psa_status_t in the \c psa_xxx API).
|
||||
*/
|
||||
#if defined(MBEDTLS_CHECK_RETURN_WARNING)
|
||||
#define MBEDTLS_CHECK_RETURN_TYPICAL MBEDTLS_CHECK_RETURN
|
||||
#else
|
||||
#define MBEDTLS_CHECK_RETURN_TYPICAL
|
||||
#endif
|
||||
|
||||
/** Benign-failure function
|
||||
*
|
||||
* This macro appearing at the beginning of the declaration of a function
|
||||
* indicates that it is rarely useful to check its return value.
|
||||
*
|
||||
* This macro has an empty expansion. It exists for documentation purposes:
|
||||
* a #MBEDTLS_CHECK_RETURN_OPTIONAL annotation indicates that the function
|
||||
* has been analyzed for return-check usefulness, whereas the lack of
|
||||
* an annotation indicates that the function has not been analyzed and its
|
||||
* return-check usefulness is unknown.
|
||||
*/
|
||||
#define MBEDTLS_CHECK_RETURN_OPTIONAL
|
||||
|
||||
/** \def MBEDTLS_IGNORE_RETURN
|
||||
*
|
||||
* Call this macro with one argument, a function call, to suppress a warning
|
||||
* from #MBEDTLS_CHECK_RETURN due to that function call.
|
||||
*/
|
||||
#if !defined(MBEDTLS_IGNORE_RETURN)
|
||||
/* GCC doesn't silence the warning with just (void)(result).
|
||||
* (void)!(result) is known to work up at least up to GCC 10, as well
|
||||
* as with Clang and MSVC.
|
||||
*
|
||||
* https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Non_002dbugs.html
|
||||
* https://stackoverflow.com/questions/40576003/ignoring-warning-wunused-result
|
||||
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425#c34
|
||||
*/
|
||||
#define MBEDTLS_IGNORE_RETURN(result) ((void) !(result))
|
||||
#endif
|
||||
|
||||
/* If the following macro is defined, the library is being built by the test
|
||||
* framework, and the framework is going to provide a replacement
|
||||
* mbedtls_platform_zeroize() using a preprocessor macro, so the function
|
||||
* declaration should be omitted. */
|
||||
#if !defined(MBEDTLS_TEST_DEFINES_ZEROIZE) //no-check-names
|
||||
/**
|
||||
* \brief Securely zeroize a buffer
|
||||
*
|
||||
* The function is meant to wipe the data contained in a buffer so
|
||||
* that it can no longer be recovered even if the program memory
|
||||
* is later compromised. Call this function on sensitive data
|
||||
* stored on the stack before returning from a function, and on
|
||||
* sensitive data stored on the heap before freeing the heap
|
||||
* object.
|
||||
*
|
||||
* It is extremely difficult to guarantee that calls to
|
||||
* mbedtls_platform_zeroize() are not removed by aggressive
|
||||
* compiler optimizations in a portable way. For this reason, Mbed
|
||||
* TLS provides the configuration option
|
||||
* MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure
|
||||
* mbedtls_platform_zeroize() to use a suitable implementation for
|
||||
* their platform and needs
|
||||
*
|
||||
* \param buf Buffer to be zeroized
|
||||
* \param len Length of the buffer in bytes
|
||||
*
|
||||
*/
|
||||
void mbedtls_platform_zeroize(void *buf, size_t len);
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME_DATE)
|
||||
/**
|
||||
* \brief Platform-specific implementation of gmtime_r()
|
||||
*
|
||||
* The function is a thread-safe abstraction that behaves
|
||||
* similarly to the gmtime_r() function from Unix/POSIX.
|
||||
*
|
||||
* Mbed TLS will try to identify the underlying platform and
|
||||
* make use of an appropriate underlying implementation (e.g.
|
||||
* gmtime_r() for POSIX and gmtime_s() for Windows). If this is
|
||||
* not possible, then gmtime() will be used. In this case, calls
|
||||
* from the library to gmtime() will be guarded by the mutex
|
||||
* mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is
|
||||
* enabled. It is recommended that calls from outside the library
|
||||
* are also guarded by this mutex.
|
||||
*
|
||||
* If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will
|
||||
* unconditionally use the alternative implementation for
|
||||
* mbedtls_platform_gmtime_r() supplied by the user at compile time.
|
||||
*
|
||||
* \param tt Pointer to an object containing time (in seconds) since the
|
||||
* epoch to be converted
|
||||
* \param tm_buf Pointer to an object where the results will be stored
|
||||
*
|
||||
* \return Pointer to an object of type struct tm on success, otherwise
|
||||
* NULL
|
||||
*/
|
||||
struct tm *mbedtls_platform_gmtime_r(const mbedtls_time_t *tt,
|
||||
struct tm *tm_buf);
|
||||
#endif /* MBEDTLS_HAVE_TIME_DATE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_PLATFORM_UTIL_H */
|
||||
@@ -1,162 +0,0 @@
|
||||
/**
|
||||
* \file poly1305.h
|
||||
*
|
||||
* \brief This file contains Poly1305 definitions and functions.
|
||||
*
|
||||
* Poly1305 is a one-time message authenticator that can be used to
|
||||
* authenticate messages. Poly1305-AES was created by Daniel
|
||||
* Bernstein https://cr.yp.to/mac/poly1305-20050329.pdf The generic
|
||||
* Poly1305 algorithm (not tied to AES) was also standardized in RFC
|
||||
* 7539.
|
||||
*
|
||||
* \author Daniel King <damaki.gh@gmail.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_POLY1305_H
|
||||
#define MBEDTLS_POLY1305_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/** Invalid input parameter(s). */
|
||||
#define MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA -0x0057
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct mbedtls_poly1305_context {
|
||||
uint32_t MBEDTLS_PRIVATE(r)[4]; /** The value for 'r' (low 128 bits of the key). */
|
||||
uint32_t MBEDTLS_PRIVATE(s)[4]; /** The value for 's' (high 128 bits of the key). */
|
||||
uint32_t MBEDTLS_PRIVATE(acc)[5]; /** The accumulator number. */
|
||||
uint8_t MBEDTLS_PRIVATE(queue)[16]; /** The current partial block of data. */
|
||||
size_t MBEDTLS_PRIVATE(queue_len); /** The number of bytes stored in 'queue'. */
|
||||
}
|
||||
mbedtls_poly1305_context;
|
||||
|
||||
/**
|
||||
* \brief This function initializes the specified Poly1305 context.
|
||||
*
|
||||
* It must be the first API called before using
|
||||
* the context.
|
||||
*
|
||||
* It is usually followed by a call to
|
||||
* \c mbedtls_poly1305_starts(), then one or more calls to
|
||||
* \c mbedtls_poly1305_update(), then one call to
|
||||
* \c mbedtls_poly1305_finish(), then finally
|
||||
* \c mbedtls_poly1305_free().
|
||||
*
|
||||
* \param ctx The Poly1305 context to initialize. This must
|
||||
* not be \c NULL.
|
||||
*/
|
||||
void mbedtls_poly1305_init(mbedtls_poly1305_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function releases and clears the specified
|
||||
* Poly1305 context.
|
||||
*
|
||||
* \param ctx The Poly1305 context to clear. This may be \c NULL, in which
|
||||
* case this function is a no-op. If it is not \c NULL, it must
|
||||
* point to an initialized Poly1305 context.
|
||||
*/
|
||||
void mbedtls_poly1305_free(mbedtls_poly1305_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function sets the one-time authentication key.
|
||||
*
|
||||
* \warning The key must be unique and unpredictable for each
|
||||
* invocation of Poly1305.
|
||||
*
|
||||
* \param ctx The Poly1305 context to which the key should be bound.
|
||||
* This must be initialized.
|
||||
* \param key The buffer containing the \c 32 Byte (\c 256 Bit) key.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_poly1305_starts(mbedtls_poly1305_context *ctx,
|
||||
const unsigned char key[32]);
|
||||
|
||||
/**
|
||||
* \brief This functions feeds an input buffer into an ongoing
|
||||
* Poly1305 computation.
|
||||
*
|
||||
* It is called between \c mbedtls_cipher_poly1305_starts() and
|
||||
* \c mbedtls_cipher_poly1305_finish().
|
||||
* It can be called repeatedly to process a stream of data.
|
||||
*
|
||||
* \param ctx The Poly1305 context to use for the Poly1305 operation.
|
||||
* This must be initialized and bound to a key.
|
||||
* \param ilen The length of the input data in Bytes.
|
||||
* Any value is accepted.
|
||||
* \param input The buffer holding the input data.
|
||||
* This pointer can be \c NULL if `ilen == 0`.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_poly1305_update(mbedtls_poly1305_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen);
|
||||
|
||||
/**
|
||||
* \brief This function generates the Poly1305 Message
|
||||
* Authentication Code (MAC).
|
||||
*
|
||||
* \param ctx The Poly1305 context to use for the Poly1305 operation.
|
||||
* This must be initialized and bound to a key.
|
||||
* \param mac The buffer to where the MAC is written. This must
|
||||
* be a writable buffer of length \c 16 Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_poly1305_finish(mbedtls_poly1305_context *ctx,
|
||||
unsigned char mac[16]);
|
||||
|
||||
/**
|
||||
* \brief This function calculates the Poly1305 MAC of the input
|
||||
* buffer with the provided key.
|
||||
*
|
||||
* \warning The key must be unique and unpredictable for each
|
||||
* invocation of Poly1305.
|
||||
*
|
||||
* \param key The buffer containing the \c 32 Byte (\c 256 Bit) key.
|
||||
* \param ilen The length of the input data in Bytes.
|
||||
* Any value is accepted.
|
||||
* \param input The buffer holding the input data.
|
||||
* This pointer can be \c NULL if `ilen == 0`.
|
||||
* \param mac The buffer to where the MAC is written. This must be
|
||||
* a writable buffer of length \c 16 Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_poly1305_mac(const unsigned char key[32],
|
||||
const unsigned char *input,
|
||||
size_t ilen,
|
||||
unsigned char mac[16]);
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
/**
|
||||
* \brief The Poly1305 checkup routine.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c 1 on failure.
|
||||
*/
|
||||
int mbedtls_poly1305_self_test(int verbose);
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_POLY1305_H */
|
||||
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* \file private_access.h
|
||||
*
|
||||
* \brief Macro wrapper for struct's members.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_PRIVATE_ACCESS_H
|
||||
#define MBEDTLS_PRIVATE_ACCESS_H
|
||||
|
||||
#ifndef MBEDTLS_ALLOW_PRIVATE_ACCESS
|
||||
#define MBEDTLS_PRIVATE(member) private_##member
|
||||
#else
|
||||
#define MBEDTLS_PRIVATE(member) member
|
||||
#endif
|
||||
|
||||
#endif /* MBEDTLS_PRIVATE_ACCESS_H */
|
||||
@@ -1,207 +0,0 @@
|
||||
/**
|
||||
* \file psa_util.h
|
||||
*
|
||||
* \brief Utility functions for the use of the PSA Crypto library.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_PSA_UTIL_H
|
||||
#define MBEDTLS_PSA_UTIL_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
/* ASN1 defines used in the ECDSA conversion functions.
|
||||
* Note: intentionally not adding MBEDTLS_ASN1_[PARSE|WRITE]_C guards here
|
||||
* otherwise error codes would be unknown in test_suite_psa_crypto_util.data.*/
|
||||
#include <mbedtls/asn1write.h>
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
|
||||
|
||||
/** The random generator function for the PSA subsystem.
|
||||
*
|
||||
* This function is suitable as the `f_rng` random generator function
|
||||
* parameter of many `mbedtls_xxx` functions.
|
||||
*
|
||||
* The implementation of this function depends on the configuration of the
|
||||
* library.
|
||||
*
|
||||
* \note This function may only be used if the PSA crypto subsystem is active.
|
||||
* This means that you must call psa_crypto_init() before any call to
|
||||
* this function, and you must not call this function after calling
|
||||
* mbedtls_psa_crypto_free().
|
||||
*
|
||||
* \param p_rng This parameter is only kept for backward compatibility
|
||||
* reasons with legacy `f_rng` functions and it's ignored.
|
||||
* Set to #MBEDTLS_PSA_RANDOM_STATE or NULL.
|
||||
* \param output The buffer to fill. It must have room for
|
||||
* \c output_size bytes.
|
||||
* \param output_size The number of bytes to write to \p output.
|
||||
* This function may fail if \p output_size is too
|
||||
* large. It is guaranteed to accept any output size
|
||||
* requested by Mbed TLS library functions. The
|
||||
* maximum request size depends on the library
|
||||
* configuration.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return An `MBEDTLS_ERR_ENTROPY_xxx`,
|
||||
* `MBEDTLS_ERR_PLATFORM_xxx,
|
||||
* `MBEDTLS_ERR_CTR_DRBG_xxx` or
|
||||
* `MBEDTLS_ERR_HMAC_DRBG_xxx` on error.
|
||||
*/
|
||||
int mbedtls_psa_get_random(void *p_rng,
|
||||
unsigned char *output,
|
||||
size_t output_size);
|
||||
|
||||
/** The random generator state for the PSA subsystem.
|
||||
*
|
||||
* This macro always expands to NULL because the `p_rng` parameter is unused
|
||||
* in mbedtls_psa_get_random(), but it's kept for interface's backward
|
||||
* compatibility.
|
||||
*/
|
||||
#define MBEDTLS_PSA_RANDOM_STATE NULL
|
||||
|
||||
/** \defgroup psa_tls_helpers TLS helper functions
|
||||
* @{
|
||||
*/
|
||||
#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
|
||||
#include <mbedtls/ecp.h>
|
||||
|
||||
/** Convert an ECC curve identifier from the Mbed TLS encoding to PSA.
|
||||
*
|
||||
* \param grpid An Mbed TLS elliptic curve identifier
|
||||
* (`MBEDTLS_ECP_DP_xxx`).
|
||||
* \param[out] bits On success the bit size of the curve; 0 on failure.
|
||||
*
|
||||
* \return If the curve is supported in the PSA API, this function
|
||||
* returns the proper PSA curve identifier
|
||||
* (`PSA_ECC_FAMILY_xxx`). This holds even if the curve is
|
||||
* not supported by the ECP module.
|
||||
* \return \c 0 if the curve is not supported in the PSA API.
|
||||
*/
|
||||
psa_ecc_family_t mbedtls_ecc_group_to_psa(mbedtls_ecp_group_id grpid,
|
||||
size_t *bits);
|
||||
|
||||
/** Convert an ECC curve identifier from the PSA encoding to Mbed TLS.
|
||||
*
|
||||
* \param family A PSA elliptic curve family identifier
|
||||
* (`PSA_ECC_FAMILY_xxx`).
|
||||
* \param bits The bit-length of a private key on \p curve.
|
||||
*
|
||||
* \return If the curve is supported in the PSA API, this function
|
||||
* returns the corresponding Mbed TLS elliptic curve
|
||||
* identifier (`MBEDTLS_ECP_DP_xxx`).
|
||||
* \return #MBEDTLS_ECP_DP_NONE if the combination of \c curve
|
||||
* and \p bits is not supported.
|
||||
*/
|
||||
mbedtls_ecp_group_id mbedtls_ecc_group_from_psa(psa_ecc_family_t family,
|
||||
size_t bits);
|
||||
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
|
||||
|
||||
/**
|
||||
* \brief This function returns the PSA algorithm identifier
|
||||
* associated with the given digest type.
|
||||
*
|
||||
* \param md_type The type of digest to search for. Must not be NONE.
|
||||
*
|
||||
* \warning If \p md_type is \c MBEDTLS_MD_NONE, this function will
|
||||
* not return \c PSA_ALG_NONE, but an invalid algorithm.
|
||||
*
|
||||
* \warning This function does not check if the algorithm is
|
||||
* supported, it always returns the corresponding identifier.
|
||||
*
|
||||
* \return The PSA algorithm identifier associated with \p md_type,
|
||||
* regardless of whether it is supported or not.
|
||||
*/
|
||||
static inline psa_algorithm_t mbedtls_md_psa_alg_from_type(mbedtls_md_type_t md_type)
|
||||
{
|
||||
return PSA_ALG_CATEGORY_HASH | (psa_algorithm_t) md_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief This function returns the given digest type
|
||||
* associated with the PSA algorithm identifier.
|
||||
*
|
||||
* \param psa_alg The PSA algorithm identifier to search for.
|
||||
*
|
||||
* \warning This function does not check if the algorithm is
|
||||
* supported, it always returns the corresponding identifier.
|
||||
*
|
||||
* \return The MD type associated with \p psa_alg,
|
||||
* regardless of whether it is supported or not.
|
||||
*/
|
||||
static inline mbedtls_md_type_t mbedtls_md_type_from_psa_alg(psa_algorithm_t psa_alg)
|
||||
{
|
||||
return (mbedtls_md_type_t) (psa_alg & PSA_ALG_HASH_MASK);
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
|
||||
|
||||
#if defined(PSA_HAVE_ALG_SOME_ECDSA)
|
||||
|
||||
/** Convert an ECDSA signature from raw format to DER ASN.1 format.
|
||||
*
|
||||
* \param bits Size of each coordinate in bits.
|
||||
* \param raw Buffer that contains the signature in raw format.
|
||||
* \param raw_len Length of \p raw in bytes. This must be
|
||||
* PSA_BITS_TO_BYTES(bits) bytes.
|
||||
* \param[out] der Buffer that will be filled with the converted DER
|
||||
* output. It can overlap with raw buffer.
|
||||
* \param der_size Size of \p der in bytes. It is enough if \p der_size
|
||||
* is at least the size of the actual output. (The size
|
||||
* of the output can vary depending on the presence of
|
||||
* leading zeros in the data.) You can use
|
||||
* #MBEDTLS_ECDSA_MAX_SIG_LEN(\p bits) to determine a
|
||||
* size that is large enough for all signatures for a
|
||||
* given value of \p bits.
|
||||
* \param[out] der_len On success it contains the amount of valid data
|
||||
* (in bytes) written to \p der. It's undefined
|
||||
* in case of failure.
|
||||
*
|
||||
* \note The behavior is undefined if \p der is null,
|
||||
* even if \p der_size is 0.
|
||||
*
|
||||
* \return 0 if successful.
|
||||
* \return #MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if \p der_size
|
||||
* is too small or if \p bits is larger than the
|
||||
* largest supported curve.
|
||||
* \return #MBEDTLS_ERR_ASN1_INVALID_DATA if one of the
|
||||
* numbers in the signature is 0.
|
||||
*/
|
||||
int mbedtls_ecdsa_raw_to_der(size_t bits, const unsigned char *raw, size_t raw_len,
|
||||
unsigned char *der, size_t der_size, size_t *der_len);
|
||||
|
||||
/** Convert an ECDSA signature from DER ASN.1 format to raw format.
|
||||
*
|
||||
* \param bits Size of each coordinate in bits.
|
||||
* \param der Buffer that contains the signature in DER format.
|
||||
* \param der_len Size of \p der in bytes.
|
||||
* \param[out] raw Buffer that will be filled with the converted raw
|
||||
* signature. It can overlap with der buffer.
|
||||
* \param raw_size Size of \p raw in bytes. Must be at least
|
||||
* 2 * PSA_BITS_TO_BYTES(bits) bytes.
|
||||
* \param[out] raw_len On success it is updated with the amount of valid
|
||||
* data (in bytes) written to \p raw. It's undefined
|
||||
* in case of failure.
|
||||
*
|
||||
* \return 0 if successful.
|
||||
* \return #MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if \p raw_size
|
||||
* is too small or if \p bits is larger than the
|
||||
* largest supported curve.
|
||||
* \return #MBEDTLS_ERR_ASN1_INVALID_DATA if the data in
|
||||
* \p der is inconsistent with \p bits.
|
||||
* \return An \c MBEDTLS_ERR_ASN1_xxx error code if
|
||||
* \p der is malformed.
|
||||
*/
|
||||
int mbedtls_ecdsa_der_to_raw(size_t bits, const unsigned char *der, size_t der_len,
|
||||
unsigned char *raw, size_t raw_size, size_t *raw_len);
|
||||
|
||||
#endif /* PSA_HAVE_ALG_SOME_ECDSA */
|
||||
|
||||
/**@}*/
|
||||
|
||||
#endif /* MBEDTLS_PSA_UTIL_H */
|
||||
@@ -1,117 +0,0 @@
|
||||
/**
|
||||
* \file ripemd160.h
|
||||
*
|
||||
* \brief RIPE MD-160 message digest
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_RIPEMD160_H
|
||||
#define MBEDTLS_RIPEMD160_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief RIPEMD-160 context structure
|
||||
*/
|
||||
typedef struct mbedtls_ripemd160_context {
|
||||
uint32_t MBEDTLS_PRIVATE(total)[2]; /*!< number of bytes processed */
|
||||
uint32_t MBEDTLS_PRIVATE(state)[5]; /*!< intermediate digest state */
|
||||
unsigned char MBEDTLS_PRIVATE(buffer)[64]; /*!< data block being processed */
|
||||
}
|
||||
mbedtls_ripemd160_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize RIPEMD-160 context
|
||||
*
|
||||
* \param ctx RIPEMD-160 context to be initialized
|
||||
*/
|
||||
void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Clear RIPEMD-160 context
|
||||
*
|
||||
* \param ctx RIPEMD-160 context to be cleared
|
||||
*/
|
||||
void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief Clone (the state of) a RIPEMD-160 context
|
||||
*
|
||||
* \param dst The destination context
|
||||
* \param src The context to be cloned
|
||||
*/
|
||||
void mbedtls_ripemd160_clone(mbedtls_ripemd160_context *dst,
|
||||
const mbedtls_ripemd160_context *src);
|
||||
|
||||
/**
|
||||
* \brief RIPEMD-160 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int mbedtls_ripemd160_starts(mbedtls_ripemd160_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief RIPEMD-160 process buffer
|
||||
*
|
||||
* \param ctx RIPEMD-160 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen);
|
||||
|
||||
/**
|
||||
* \brief RIPEMD-160 final digest
|
||||
*
|
||||
* \param ctx RIPEMD-160 context
|
||||
* \param output RIPEMD-160 checksum result
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx,
|
||||
unsigned char output[20]);
|
||||
|
||||
/**
|
||||
* \brief Output = RIPEMD-160( input buffer )
|
||||
*
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output RIPEMD-160 checksum result
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int mbedtls_ripemd160(const unsigned char *input,
|
||||
size_t ilen,
|
||||
unsigned char output[20]);
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int mbedtls_ripemd160_self_test(int verbose);
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* mbedtls_ripemd160.h */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,193 +0,0 @@
|
||||
/**
|
||||
* \file sha1.h
|
||||
*
|
||||
* \brief This file contains SHA-1 definitions and functions.
|
||||
*
|
||||
* The Secure Hash Algorithm 1 (SHA-1) cryptographic hash function is defined in
|
||||
* <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
|
||||
*
|
||||
* \warning SHA-1 is considered a weak message digest and its use constitutes
|
||||
* a security risk. We recommend considering stronger message
|
||||
* digests instead.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_SHA1_H
|
||||
#define MBEDTLS_SHA1_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** SHA-1 input data was malformed. */
|
||||
#define MBEDTLS_ERR_SHA1_BAD_INPUT_DATA -0x0073
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The SHA-1 context structure.
|
||||
*
|
||||
* \warning SHA-1 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
*/
|
||||
typedef struct mbedtls_sha1_context {
|
||||
uint32_t MBEDTLS_PRIVATE(total)[2]; /*!< The number of Bytes processed. */
|
||||
uint32_t MBEDTLS_PRIVATE(state)[5]; /*!< The intermediate digest state. */
|
||||
unsigned char MBEDTLS_PRIVATE(buffer)[64]; /*!< The data block being processed. */
|
||||
}
|
||||
mbedtls_sha1_context;
|
||||
|
||||
/**
|
||||
* \brief This function initializes a SHA-1 context.
|
||||
*
|
||||
* \warning SHA-1 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
* \param ctx The SHA-1 context to initialize.
|
||||
* This must not be \c NULL.
|
||||
*
|
||||
*/
|
||||
void mbedtls_sha1_init(mbedtls_sha1_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function clears a SHA-1 context.
|
||||
*
|
||||
* \warning SHA-1 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
* \param ctx The SHA-1 context to clear. This may be \c NULL,
|
||||
* in which case this function does nothing. If it is
|
||||
* not \c NULL, it must point to an initialized
|
||||
* SHA-1 context.
|
||||
*
|
||||
*/
|
||||
void mbedtls_sha1_free(mbedtls_sha1_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function clones the state of a SHA-1 context.
|
||||
*
|
||||
* \warning SHA-1 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
* \param dst The SHA-1 context to clone to. This must be initialized.
|
||||
* \param src The SHA-1 context to clone from. This must be initialized.
|
||||
*
|
||||
*/
|
||||
void mbedtls_sha1_clone(mbedtls_sha1_context *dst,
|
||||
const mbedtls_sha1_context *src);
|
||||
|
||||
/**
|
||||
* \brief This function starts a SHA-1 checksum calculation.
|
||||
*
|
||||
* \warning SHA-1 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
* \param ctx The SHA-1 context to initialize. This must be initialized.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*
|
||||
*/
|
||||
int mbedtls_sha1_starts(mbedtls_sha1_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function feeds an input buffer into an ongoing SHA-1
|
||||
* checksum calculation.
|
||||
*
|
||||
* \warning SHA-1 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
* \param ctx The SHA-1 context. This must be initialized
|
||||
* and have a hash operation started.
|
||||
* \param input The buffer holding the input data.
|
||||
* This must be a readable buffer of length \p ilen Bytes.
|
||||
* \param ilen The length of the input data \p input in Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_sha1_update(mbedtls_sha1_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen);
|
||||
|
||||
/**
|
||||
* \brief This function finishes the SHA-1 operation, and writes
|
||||
* the result to the output buffer.
|
||||
*
|
||||
* \warning SHA-1 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
* \param ctx The SHA-1 context to use. This must be initialized and
|
||||
* have a hash operation started.
|
||||
* \param output The SHA-1 checksum result. This must be a writable
|
||||
* buffer of length \c 20 Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_sha1_finish(mbedtls_sha1_context *ctx,
|
||||
unsigned char output[20]);
|
||||
|
||||
/**
|
||||
* \brief This function calculates the SHA-1 checksum of a buffer.
|
||||
*
|
||||
* The function allocates the context, performs the
|
||||
* calculation, and frees the context.
|
||||
*
|
||||
* The SHA-1 result is calculated as
|
||||
* output = SHA-1(input buffer).
|
||||
*
|
||||
* \warning SHA-1 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
* \param input The buffer holding the input data.
|
||||
* This must be a readable buffer of length \p ilen Bytes.
|
||||
* \param ilen The length of the input data \p input in Bytes.
|
||||
* \param output The SHA-1 checksum result.
|
||||
* This must be a writable buffer of length \c 20 Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*
|
||||
*/
|
||||
int mbedtls_sha1(const unsigned char *input,
|
||||
size_t ilen,
|
||||
unsigned char output[20]);
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
/**
|
||||
* \brief The SHA-1 checkup routine.
|
||||
*
|
||||
* \warning SHA-1 is considered a weak message digest and its use
|
||||
* constitutes a security risk. We recommend considering
|
||||
* stronger message digests instead.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c 1 on failure.
|
||||
*
|
||||
*/
|
||||
int mbedtls_sha1_self_test(int verbose);
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* mbedtls_sha1.h */
|
||||
@@ -1,177 +0,0 @@
|
||||
/**
|
||||
* \file sha256.h
|
||||
*
|
||||
* \brief This file contains SHA-224 and SHA-256 definitions and functions.
|
||||
*
|
||||
* The Secure Hash Algorithms 224 and 256 (SHA-224 and SHA-256) cryptographic
|
||||
* hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_SHA256_H
|
||||
#define MBEDTLS_SHA256_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** SHA-256 input data was malformed. */
|
||||
#define MBEDTLS_ERR_SHA256_BAD_INPUT_DATA -0x0074
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The SHA-256 context structure.
|
||||
*
|
||||
* The structure is used both for SHA-256 and for SHA-224
|
||||
* checksum calculations. The choice between these two is
|
||||
* made in the call to mbedtls_sha256_starts().
|
||||
*/
|
||||
typedef struct mbedtls_sha256_context {
|
||||
unsigned char MBEDTLS_PRIVATE(buffer)[64]; /*!< The data block being processed. */
|
||||
uint32_t MBEDTLS_PRIVATE(total)[2]; /*!< The number of Bytes processed. */
|
||||
uint32_t MBEDTLS_PRIVATE(state)[8]; /*!< The intermediate digest state. */
|
||||
#if defined(MBEDTLS_SHA224_C)
|
||||
int MBEDTLS_PRIVATE(is224); /*!< Determines which function to use:
|
||||
0: Use SHA-256, or 1: Use SHA-224. */
|
||||
#endif
|
||||
}
|
||||
mbedtls_sha256_context;
|
||||
|
||||
/**
|
||||
* \brief This function initializes a SHA-256 context.
|
||||
*
|
||||
* \param ctx The SHA-256 context to initialize. This must not be \c NULL.
|
||||
*/
|
||||
void mbedtls_sha256_init(mbedtls_sha256_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function clears a SHA-256 context.
|
||||
*
|
||||
* \param ctx The SHA-256 context to clear. This may be \c NULL, in which
|
||||
* case this function returns immediately. If it is not \c NULL,
|
||||
* it must point to an initialized SHA-256 context.
|
||||
*/
|
||||
void mbedtls_sha256_free(mbedtls_sha256_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function clones the state of a SHA-256 context.
|
||||
*
|
||||
* \param dst The destination context. This must be initialized.
|
||||
* \param src The context to clone. This must be initialized.
|
||||
*/
|
||||
void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
|
||||
const mbedtls_sha256_context *src);
|
||||
|
||||
/**
|
||||
* \brief This function starts a SHA-224 or SHA-256 checksum
|
||||
* calculation.
|
||||
*
|
||||
* \param ctx The context to use. This must be initialized.
|
||||
* \param is224 This determines which function to use. This must be
|
||||
* either \c 0 for SHA-256, or \c 1 for SHA-224.
|
||||
*
|
||||
* \note is224 must be defined accordingly to the enabled
|
||||
* MBEDTLS_SHA224_C/MBEDTLS_SHA256_C symbols otherwise the
|
||||
* function will return #MBEDTLS_ERR_SHA512_BAD_INPUT_DATA.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224);
|
||||
|
||||
/**
|
||||
* \brief This function feeds an input buffer into an ongoing
|
||||
* SHA-256 checksum calculation.
|
||||
*
|
||||
* \param ctx The SHA-256 context. This must be initialized
|
||||
* and have a hash operation started.
|
||||
* \param input The buffer holding the data. This must be a readable
|
||||
* buffer of length \p ilen Bytes.
|
||||
* \param ilen The length of the input data in Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_sha256_update(mbedtls_sha256_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen);
|
||||
|
||||
/**
|
||||
* \brief This function finishes the SHA-256 operation, and writes
|
||||
* the result to the output buffer.
|
||||
*
|
||||
* \param ctx The SHA-256 context. This must be initialized
|
||||
* and have a hash operation started.
|
||||
* \param output The SHA-224 or SHA-256 checksum result.
|
||||
* This must be a writable buffer of length \c 32 bytes
|
||||
* for SHA-256, \c 28 bytes for SHA-224.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_sha256_finish(mbedtls_sha256_context *ctx,
|
||||
unsigned char *output);
|
||||
|
||||
/**
|
||||
* \brief This function calculates the SHA-224 or SHA-256
|
||||
* checksum of a buffer.
|
||||
*
|
||||
* The function allocates the context, performs the
|
||||
* calculation, and frees the context.
|
||||
*
|
||||
* The SHA-256 result is calculated as
|
||||
* output = SHA-256(input buffer).
|
||||
*
|
||||
* \param input The buffer holding the data. This must be a readable
|
||||
* buffer of length \p ilen Bytes.
|
||||
* \param ilen The length of the input data in Bytes.
|
||||
* \param output The SHA-224 or SHA-256 checksum result.
|
||||
* This must be a writable buffer of length \c 32 bytes
|
||||
* for SHA-256, \c 28 bytes for SHA-224.
|
||||
* \param is224 Determines which function to use. This must be
|
||||
* either \c 0 for SHA-256, or \c 1 for SHA-224.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_sha256(const unsigned char *input,
|
||||
size_t ilen,
|
||||
unsigned char *output,
|
||||
int is224);
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
#if defined(MBEDTLS_SHA224_C)
|
||||
/**
|
||||
* \brief The SHA-224 checkup routine.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c 1 on failure.
|
||||
*/
|
||||
int mbedtls_sha224_self_test(int verbose);
|
||||
#endif /* MBEDTLS_SHA224_C */
|
||||
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
/**
|
||||
* \brief The SHA-256 checkup routine.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c 1 on failure.
|
||||
*/
|
||||
int mbedtls_sha256_self_test(int verbose);
|
||||
#endif /* MBEDTLS_SHA256_C */
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* mbedtls_sha256.h */
|
||||
@@ -1,172 +0,0 @@
|
||||
/**
|
||||
* \file sha3.h
|
||||
*
|
||||
* \brief This file contains SHA-3 definitions and functions.
|
||||
*
|
||||
* The Secure Hash Algorithms cryptographic
|
||||
* hash functions are defined in <em>FIPS 202: SHA-3 Standard:
|
||||
* Permutation-Based Hash and Extendable-Output Functions </em>.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_SHA3_H
|
||||
#define MBEDTLS_SHA3_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** SHA-3 input data was malformed. */
|
||||
#define MBEDTLS_ERR_SHA3_BAD_INPUT_DATA -0x0076
|
||||
|
||||
/**
|
||||
* SHA-3 family id.
|
||||
*
|
||||
* It identifies the family (SHA3-256, SHA3-512, etc.)
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
MBEDTLS_SHA3_NONE = 0, /*!< Operation not defined. */
|
||||
MBEDTLS_SHA3_224, /*!< SHA3-224 */
|
||||
MBEDTLS_SHA3_256, /*!< SHA3-256 */
|
||||
MBEDTLS_SHA3_384, /*!< SHA3-384 */
|
||||
MBEDTLS_SHA3_512, /*!< SHA3-512 */
|
||||
} mbedtls_sha3_id;
|
||||
|
||||
/**
|
||||
* \brief The SHA-3 context structure.
|
||||
*
|
||||
* The structure is used SHA-3 checksum calculations.
|
||||
*/
|
||||
typedef struct {
|
||||
uint64_t MBEDTLS_PRIVATE(state[25]);
|
||||
uint32_t MBEDTLS_PRIVATE(index);
|
||||
uint16_t MBEDTLS_PRIVATE(olen);
|
||||
uint16_t MBEDTLS_PRIVATE(max_block_size);
|
||||
}
|
||||
mbedtls_sha3_context;
|
||||
|
||||
/**
|
||||
* \brief This function initializes a SHA-3 context.
|
||||
*
|
||||
* \param ctx The SHA-3 context to initialize. This must not be \c NULL.
|
||||
*/
|
||||
void mbedtls_sha3_init(mbedtls_sha3_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function clears a SHA-3 context.
|
||||
*
|
||||
* \param ctx The SHA-3 context to clear. This may be \c NULL, in which
|
||||
* case this function returns immediately. If it is not \c NULL,
|
||||
* it must point to an initialized SHA-3 context.
|
||||
*/
|
||||
void mbedtls_sha3_free(mbedtls_sha3_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function clones the state of a SHA-3 context.
|
||||
*
|
||||
* \param dst The destination context. This must be initialized.
|
||||
* \param src The context to clone. This must be initialized.
|
||||
*/
|
||||
void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
|
||||
const mbedtls_sha3_context *src);
|
||||
|
||||
/**
|
||||
* \brief This function starts a SHA-3 checksum
|
||||
* calculation.
|
||||
*
|
||||
* \param ctx The context to use. This must be initialized.
|
||||
* \param id The id of the SHA-3 family.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id);
|
||||
|
||||
/**
|
||||
* \brief This function feeds an input buffer into an ongoing
|
||||
* SHA-3 checksum calculation.
|
||||
*
|
||||
* \param ctx The SHA-3 context. This must be initialized
|
||||
* and have a hash operation started.
|
||||
* \param input The buffer holding the data. This must be a readable
|
||||
* buffer of length \p ilen Bytes.
|
||||
* \param ilen The length of the input data in Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
|
||||
const uint8_t *input,
|
||||
size_t ilen);
|
||||
|
||||
/**
|
||||
* \brief This function finishes the SHA-3 operation, and writes
|
||||
* the result to the output buffer.
|
||||
*
|
||||
* \param ctx The SHA-3 context. This must be initialized
|
||||
* and have a hash operation started.
|
||||
* \param output The SHA-3 checksum result.
|
||||
* This must be a writable buffer of length \c olen bytes.
|
||||
* \param olen Defines the length of output buffer (in bytes). For SHA-3 224, SHA-3 256,
|
||||
* SHA-3 384 and SHA-3 512 \c olen must equal to 28, 32, 48 and 64,
|
||||
* respectively.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
|
||||
uint8_t *output, size_t olen);
|
||||
|
||||
/**
|
||||
* \brief This function calculates the SHA-3
|
||||
* checksum of a buffer.
|
||||
*
|
||||
* The function allocates the context, performs the
|
||||
* calculation, and frees the context.
|
||||
*
|
||||
* The SHA-3 result is calculated as
|
||||
* output = SHA-3(id, input buffer, d).
|
||||
*
|
||||
* \param id The id of the SHA-3 family.
|
||||
* \param input The buffer holding the data. This must be a readable
|
||||
* buffer of length \p ilen Bytes.
|
||||
* \param ilen The length of the input data in Bytes.
|
||||
* \param output The SHA-3 checksum result.
|
||||
* This must be a writable buffer of length \c olen bytes.
|
||||
* \param olen Defines the length of output buffer (in bytes). For SHA-3 224, SHA-3 256,
|
||||
* SHA-3 384 and SHA-3 512 \c olen must equal to 28, 32, 48 and 64,
|
||||
* respectively.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
|
||||
size_t ilen,
|
||||
uint8_t *output,
|
||||
size_t olen);
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
/**
|
||||
* \brief Checkup routine for the algorithms implemented
|
||||
* by this module: SHA3-224, SHA3-256, SHA3-384, SHA3-512.
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed.
|
||||
*/
|
||||
int mbedtls_sha3_self_test(int verbose);
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* mbedtls_sha3.h */
|
||||
@@ -1,185 +0,0 @@
|
||||
/**
|
||||
* \file sha512.h
|
||||
* \brief This file contains SHA-384 and SHA-512 definitions and functions.
|
||||
*
|
||||
* The Secure Hash Algorithms 384 and 512 (SHA-384 and SHA-512) cryptographic
|
||||
* hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
|
||||
*/
|
||||
/*
|
||||
* Copyright The Mbed TLS Contributors
|
||||
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
*/
|
||||
#ifndef MBEDTLS_SHA512_H
|
||||
#define MBEDTLS_SHA512_H
|
||||
#include "mbedtls/private_access.h"
|
||||
|
||||
#include "tf-psa-crypto/build_info.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** SHA-512 input data was malformed. */
|
||||
#define MBEDTLS_ERR_SHA512_BAD_INPUT_DATA -0x0075
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The SHA-512 context structure.
|
||||
*
|
||||
* The structure is used both for SHA-384 and for SHA-512
|
||||
* checksum calculations. The choice between these two is
|
||||
* made in the call to mbedtls_sha512_starts().
|
||||
*/
|
||||
typedef struct mbedtls_sha512_context {
|
||||
uint64_t MBEDTLS_PRIVATE(total)[2]; /*!< The number of Bytes processed. */
|
||||
uint64_t MBEDTLS_PRIVATE(state)[8]; /*!< The intermediate digest state. */
|
||||
unsigned char MBEDTLS_PRIVATE(buffer)[128]; /*!< The data block being processed. */
|
||||
#if defined(MBEDTLS_SHA384_C)
|
||||
int MBEDTLS_PRIVATE(is384); /*!< Determines which function to use:
|
||||
0: Use SHA-512, or 1: Use SHA-384. */
|
||||
#endif
|
||||
}
|
||||
mbedtls_sha512_context;
|
||||
|
||||
/**
|
||||
* \brief This function initializes a SHA-512 context.
|
||||
*
|
||||
* \param ctx The SHA-512 context to initialize. This must
|
||||
* not be \c NULL.
|
||||
*/
|
||||
void mbedtls_sha512_init(mbedtls_sha512_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function clears a SHA-512 context.
|
||||
*
|
||||
* \param ctx The SHA-512 context to clear. This may be \c NULL,
|
||||
* in which case this function does nothing. If it
|
||||
* is not \c NULL, it must point to an initialized
|
||||
* SHA-512 context.
|
||||
*/
|
||||
void mbedtls_sha512_free(mbedtls_sha512_context *ctx);
|
||||
|
||||
/**
|
||||
* \brief This function clones the state of a SHA-512 context.
|
||||
*
|
||||
* \param dst The destination context. This must be initialized.
|
||||
* \param src The context to clone. This must be initialized.
|
||||
*/
|
||||
void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
|
||||
const mbedtls_sha512_context *src);
|
||||
|
||||
/**
|
||||
* \brief This function starts a SHA-384 or SHA-512 checksum
|
||||
* calculation.
|
||||
*
|
||||
* \param ctx The SHA-512 context to use. This must be initialized.
|
||||
* \param is384 Determines which function to use. This must be
|
||||
* either \c 0 for SHA-512, or \c 1 for SHA-384.
|
||||
*
|
||||
* \note is384 must be defined accordingly to the enabled
|
||||
* MBEDTLS_SHA384_C/MBEDTLS_SHA512_C symbols otherwise the
|
||||
* function will return #MBEDTLS_ERR_SHA512_BAD_INPUT_DATA.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384);
|
||||
|
||||
/**
|
||||
* \brief This function feeds an input buffer into an ongoing
|
||||
* SHA-512 checksum calculation.
|
||||
*
|
||||
* \param ctx The SHA-512 context. This must be initialized
|
||||
* and have a hash operation started.
|
||||
* \param input The buffer holding the input data. This must
|
||||
* be a readable buffer of length \p ilen Bytes.
|
||||
* \param ilen The length of the input data in Bytes.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_sha512_update(mbedtls_sha512_context *ctx,
|
||||
const unsigned char *input,
|
||||
size_t ilen);
|
||||
|
||||
/**
|
||||
* \brief This function finishes the SHA-512 operation, and writes
|
||||
* the result to the output buffer.
|
||||
*
|
||||
* \param ctx The SHA-512 context. This must be initialized
|
||||
* and have a hash operation started.
|
||||
* \param output The SHA-384 or SHA-512 checksum result.
|
||||
* This must be a writable buffer of length \c 64 bytes
|
||||
* for SHA-512, \c 48 bytes for SHA-384.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_sha512_finish(mbedtls_sha512_context *ctx,
|
||||
unsigned char *output);
|
||||
|
||||
/**
|
||||
* \brief This function calculates the SHA-512 or SHA-384
|
||||
* checksum of a buffer.
|
||||
*
|
||||
* The function allocates the context, performs the
|
||||
* calculation, and frees the context.
|
||||
*
|
||||
* The SHA-512 result is calculated as
|
||||
* output = SHA-512(input buffer).
|
||||
*
|
||||
* \param input The buffer holding the input data. This must be
|
||||
* a readable buffer of length \p ilen Bytes.
|
||||
* \param ilen The length of the input data in Bytes.
|
||||
* \param output The SHA-384 or SHA-512 checksum result.
|
||||
* This must be a writable buffer of length \c 64 bytes
|
||||
* for SHA-512, \c 48 bytes for SHA-384.
|
||||
* \param is384 Determines which function to use. This must be either
|
||||
* \c 0 for SHA-512, or \c 1 for SHA-384.
|
||||
*
|
||||
* \note is384 must be defined accordingly with the supported
|
||||
* symbols in the config file. If:
|
||||
* - is384 is 0, but \c MBEDTLS_SHA384_C is not defined, or
|
||||
* - is384 is 1, but \c MBEDTLS_SHA512_C is not defined
|
||||
* then the function will return
|
||||
* #MBEDTLS_ERR_SHA512_BAD_INPUT_DATA.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return A negative error code on failure.
|
||||
*/
|
||||
int mbedtls_sha512(const unsigned char *input,
|
||||
size_t ilen,
|
||||
unsigned char *output,
|
||||
int is384);
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
|
||||
#if defined(MBEDTLS_SHA384_C)
|
||||
/**
|
||||
* \brief The SHA-384 checkup routine.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c 1 on failure.
|
||||
*/
|
||||
int mbedtls_sha384_self_test(int verbose);
|
||||
#endif /* MBEDTLS_SHA384_C */
|
||||
|
||||
#if defined(MBEDTLS_SHA512_C)
|
||||
/**
|
||||
* \brief The SHA-512 checkup routine.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
* \return \c 1 on failure.
|
||||
*/
|
||||
int mbedtls_sha512_self_test(int verbose);
|
||||
#endif /* MBEDTLS_SHA512_C */
|
||||
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* mbedtls_sha512.h */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user