summaryrefslogtreecommitdiff
path: root/nrfdemo/build/tfm/api_ns/interface
diff options
context:
space:
mode:
Diffstat (limited to 'nrfdemo/build/tfm/api_ns/interface')
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/RTE_Device.h98
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/config_base.h271
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/config_impl.h58
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/config_tfm.h33
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/device_cfg.h55
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/os_wrapper/common.h26
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/os_wrapper/mutex.h65
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/psa/client.h197
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/psa/crypto.h4698
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_client_struct.h48
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_compat.h155
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_extra.h1495
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_platform.h56
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_sizes.h1351
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_struct.h267
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_types.h500
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_values.h2793
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/psa/error.h60
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/psa/framework_feature.h14
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/psa_manifest/sid.h31
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/tfm_crypto_defs.h303
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/tfm_ioctl_core_api.h120
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/tfm_ns_client_ext.h109
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/tfm_ns_interface.h66
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/tfm_platform_api.h100
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/tfm_psa_call_pack.h80
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/include/tfm_veneers.h75
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/lib/s_veneers.obin0 -> 456 bytes
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/src/os_wrapper/tfm_ns_interface_bare_metal.c23
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/src/os_wrapper/tfm_ns_interface_rtos.c56
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/src/tfm_crypto_api.c1849
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/src/tfm_ioctl_core_ns_api.c68
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/src/tfm_platform_api.c109
-rw-r--r--nrfdemo/build/tfm/api_ns/interface/src/tfm_tz_psa_ns_api.c63
34 files changed, 15292 insertions, 0 deletions
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/RTE_Device.h b/nrfdemo/build/tfm/api_ns/interface/include/RTE_Device.h
new file mode 100644
index 0000000..8dc751d
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/RTE_Device.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2021 - 2022 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
+ */
+
+#ifndef __RTE_DEVICE_H
+#define __RTE_DEVICE_H
+
+#include <autoconf.h>
+
+/* ARRAY_SIZE causes a conflict as it is defined both by TF-M and indirectly by devicetree.h */
+#undef ARRAY_SIZE
+#include <zephyr/devicetree.h>
+
+#include <nrf-pinctrl.h>
+
+#include <nrf.h>
+
+#define UART_PIN_INIT(node_id, prop, idx) DT_PROP_BY_IDX(node_id, prop, idx),
+
+#define RTE_USART_PINS(idx) \
+ { \
+ DT_FOREACH_CHILD_VARGS(DT_PINCTRL_BY_NAME(DT_NODELABEL(uart##idx), default, 0), \
+ DT_FOREACH_PROP_ELEM, psels, UART_PIN_INIT) \
+ }
+
+#define RTE_FLASH0 1
+
+#if DOMAIN_NS == 1U
+
+#ifdef NRF_UARTE0_S
+
+#define RTE_USART0 1
+
+#else /* NRF_UARTE0_S - 54L15 devices*/
+
+/* Only UART20 and UART30 are supported for TF-M tests, which are the
+ * Non-secure applications build via the TF-M build system
+ */
+#if defined(CONFIG_TFM_SECURE_UART30)
+#define RTE_USART20 1
+#else
+#define RTE_USART30 1
+#endif
+
+#endif /* NRF_UARTE0_S */
+
+#endif /* DOMAIN_NS == 1U */
+
+/*
+ * The defines RTE_USART0, RTE_USART1, etc. determine if
+ * Driver_USART.c instantiates UART instance 0, 1, etc..
+ */
+
+#if defined(CONFIG_TFM_SECURE_UART0)
+#define RTE_USART0 1
+#endif
+
+#if defined(CONFIG_TFM_SECURE_UART1)
+#define RTE_USART1 1
+#endif
+
+#if defined(CONFIG_TFM_SECURE_UART00)
+#define RTE_USART00 1
+#endif
+
+#if defined(CONFIG_TFM_SECURE_UART20)
+#define RTE_USART20 1
+#endif
+
+#if defined(CONFIG_TFM_SECURE_UART21)
+#define RTE_USART21 1
+#endif
+
+#if defined(CONFIG_TFM_SECURE_UART22)
+#define RTE_USART22 1
+#endif
+
+#if defined(CONFIG_TFM_SECURE_UART30)
+#define RTE_USART30 1
+#endif
+
+/*
+ * Note that the defines RTE_USART0_PINS, RTE_USART1_PINS, etc. are
+ * used by Driver_USART.c, but only when RTE_USART0, RTE_USART1
+ * etc. are defined to 1.
+ */
+#define RTE_USART0_PINS RTE_USART_PINS(0)
+#define RTE_USART1_PINS RTE_USART_PINS(1)
+
+#define RTE_USART00_PINS RTE_USART_PINS(00)
+#define RTE_USART20_PINS RTE_USART_PINS(20)
+#define RTE_USART21_PINS RTE_USART_PINS(21)
+#define RTE_USART22_PINS RTE_USART_PINS(22)
+#define RTE_USART30_PINS RTE_USART_PINS(30)
+
+#endif /* __RTE_DEVICE_H */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/config_base.h b/nrfdemo/build/tfm/api_ns/interface/include/config_base.h
new file mode 100644
index 0000000..62f25b1
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/config_base.h
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon
+ * company) or an affiliate of Cypress Semiconductor Corporation. All rights
+ * reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __CONFIG_BASE_H__
+#define __CONFIG_BASE_H__
+
+/* Platform Partition Configs */
+
+/* Size of input buffer in platform service */
+#ifndef PLATFORM_SERVICE_INPUT_BUFFER_SIZE
+#define PLATFORM_SERVICE_INPUT_BUFFER_SIZE 64
+#endif
+
+/* Size of output buffer in platform service */
+#ifndef PLATFORM_SERVICE_OUTPUT_BUFFER_SIZE
+#define PLATFORM_SERVICE_OUTPUT_BUFFER_SIZE 64
+#endif
+
+/* The stack size of the Platform Secure Partition */
+#ifndef PLATFORM_SP_STACK_SIZE
+#define PLATFORM_SP_STACK_SIZE 0x500
+#endif
+
+/* Disable Non-volatile counter module */
+#ifndef PLATFORM_NV_COUNTER_MODULE_DISABLED
+#define PLATFORM_NV_COUNTER_MODULE_DISABLED 0
+#endif
+
+/* Crypto Partition Configs */
+
+/*
+ * Heap size for the crypto backend
+ * CRYPTO_ENGINE_BUF_SIZE needs to be >8KB for EC signing by attest module.
+ */
+#ifndef CRYPTO_ENGINE_BUF_SIZE
+#define CRYPTO_ENGINE_BUF_SIZE 0x2080
+#endif
+
+/* The max number of concurrent operations that can be active (allocated) at any time in Crypto */
+#ifndef CRYPTO_CONC_OPER_NUM
+#define CRYPTO_CONC_OPER_NUM 8
+#endif
+
+/* Enable PSA Crypto random number generator module */
+#ifndef CRYPTO_RNG_MODULE_ENABLED
+#define CRYPTO_RNG_MODULE_ENABLED 1
+#endif
+
+/* Enable PSA Crypto Key module */
+#ifndef CRYPTO_KEY_MODULE_ENABLED
+#define CRYPTO_KEY_MODULE_ENABLED 1
+#endif
+
+/* Enable PSA Crypto AEAD module */
+#ifndef CRYPTO_AEAD_MODULE_ENABLED
+#define CRYPTO_AEAD_MODULE_ENABLED 1
+#endif
+
+/* Enable PSA Crypto MAC module */
+#ifndef CRYPTO_MAC_MODULE_ENABLED
+#define CRYPTO_MAC_MODULE_ENABLED 1
+#endif
+
+/* Enable PSA Crypto Hash module */
+#ifndef CRYPTO_HASH_MODULE_ENABLED
+#define CRYPTO_HASH_MODULE_ENABLED 1
+#endif
+
+/* Enable PSA Crypto Cipher module */
+#ifndef CRYPTO_CIPHER_MODULE_ENABLED
+#define CRYPTO_CIPHER_MODULE_ENABLED 1
+#endif
+
+/* Enable PSA Crypto asymmetric key signature module */
+#ifndef CRYPTO_ASYM_SIGN_MODULE_ENABLED
+#define CRYPTO_ASYM_SIGN_MODULE_ENABLED 1
+#endif
+
+/* Enable PSA Crypto asymmetric key encryption module */
+#ifndef CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED
+#define CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED 1
+#endif
+
+/* Enable PSA Crypto key derivation module */
+#ifndef CRYPTO_KEY_DERIVATION_MODULE_ENABLED
+#define CRYPTO_KEY_DERIVATION_MODULE_ENABLED 1
+#endif
+
+/* Default size of the internal scratch buffer used for PSA FF IOVec allocations */
+#ifndef CRYPTO_IOVEC_BUFFER_SIZE
+#define CRYPTO_IOVEC_BUFFER_SIZE 5120
+#endif
+
+/* Use stored NV seed to provide entropy */
+#ifndef CRYPTO_NV_SEED
+#define CRYPTO_NV_SEED 1
+#endif
+
+/*
+ * Only enable multi-part operations in Hash, MAC, AEAD and symmetric ciphers,
+ * to optimize memory footprint in resource-constrained devices.
+ */
+#ifndef CRYPTO_SINGLE_PART_FUNCS_DISABLED
+#define CRYPTO_SINGLE_PART_FUNCS_DISABLED 0
+#endif
+
+/* The stack size of the Crypto Secure Partition */
+#ifndef CRYPTO_STACK_SIZE
+#define CRYPTO_STACK_SIZE 0x1B00
+#endif
+
+/* FWU Partition Configs */
+
+/* Size of the FWU internal data transfer buffer */
+#ifndef TFM_FWU_BUF_SIZE
+#define TFM_FWU_BUF_SIZE PSA_FWU_MAX_WRITE_SIZE
+#endif
+
+/* The stack size of the Firmware Update Secure Partition */
+#ifndef FWU_STACK_SIZE
+#define FWU_STACK_SIZE 0x600
+#endif
+
+/* Attest Partition Configs */
+
+/* Include optional claims in initial attestation token */
+#ifndef ATTEST_INCLUDE_OPTIONAL_CLAIMS
+#define ATTEST_INCLUDE_OPTIONAL_CLAIMS 1
+#endif
+
+/* Include COSE key-id in initial attestation token */
+#ifndef ATTEST_INCLUDE_COSE_KEY_ID
+#define ATTEST_INCLUDE_COSE_KEY_ID 0
+#endif
+
+/* The stack size of the Initial Attestation Secure Partition */
+#ifndef ATTEST_STACK_SIZE
+#define ATTEST_STACK_SIZE 0x700
+#endif
+
+/* Set the initial attestation token profile */
+#if (!ATTEST_TOKEN_PROFILE_PSA_IOT_1) && \
+ (!ATTEST_TOKEN_PROFILE_PSA_2_0_0) && \
+ (!ATTEST_TOKEN_PROFILE_ARM_CCA)
+#define ATTEST_TOKEN_PROFILE_PSA_IOT_1 1
+#endif
+
+/* ITS Partition Configs */
+
+/* Create flash FS if it doesn't exist for Internal Trusted Storage partition */
+#ifndef ITS_CREATE_FLASH_LAYOUT
+#define ITS_CREATE_FLASH_LAYOUT 1
+#endif
+
+/* Enable emulated RAM FS for platforms that don't have flash for Internal Trusted Storage partition */
+#ifndef ITS_RAM_FS
+#define ITS_RAM_FS 0
+#endif
+
+/* Validate filesystem metadata every time it is read from flash */
+#ifndef ITS_VALIDATE_METADATA_FROM_FLASH
+#define ITS_VALIDATE_METADATA_FROM_FLASH 1
+#endif
+
+/* The maximum asset size to be stored in the Internal Trusted Storage */
+#ifndef ITS_MAX_ASSET_SIZE
+#define ITS_MAX_ASSET_SIZE 512
+#endif
+
+/*
+ * Size of the ITS internal data transfer buffer
+ * (Default to the max asset size so that all requests can be handled in one iteration.)
+ */
+#ifndef ITS_BUF_SIZE
+#define ITS_BUF_SIZE ITS_MAX_ASSET_SIZE
+#endif
+
+/* The maximum number of assets to be stored in the Internal Trusted Storage */
+#ifndef ITS_NUM_ASSETS
+#define ITS_NUM_ASSETS 10
+#endif
+
+/* The stack size of the Internal Trusted Storage Secure Partition */
+#ifndef ITS_STACK_SIZE
+#define ITS_STACK_SIZE 0x720
+#endif
+
+/* The size of the authentication tag used when authentication/encryption of ITS files is enabled */
+#ifndef TFM_ITS_AUTH_TAG_LENGTH
+#define TFM_ITS_AUTH_TAG_LENGTH 16
+#endif
+
+/* The size of the nonce used when ITS file encryption is enabled */
+#ifndef TFM_ITS_ENC_NONCE_LENGTH
+#define TFM_ITS_ENC_NONCE_LENGTH 12
+#endif
+
+/* PS Partition Configs */
+
+/* Create flash FS if it doesn't exist for Protected Storage partition */
+#ifndef PS_CREATE_FLASH_LAYOUT
+#define PS_CREATE_FLASH_LAYOUT 1
+#endif
+
+/* Enable emulated RAM FS for platforms that don't have flash for Protected Storage partition */
+#ifndef PS_RAM_FS
+#define PS_RAM_FS 0
+#endif
+
+/* Enable rollback protection for Protected Storage partition */
+#ifndef PS_ROLLBACK_PROTECTION
+#define PS_ROLLBACK_PROTECTION 1
+#endif
+
+/* Validate filesystem metadata every time it is read from flash */
+#ifndef PS_VALIDATE_METADATA_FROM_FLASH
+#define PS_VALIDATE_METADATA_FROM_FLASH 1
+#endif
+
+/* The maximum asset size to be stored in the Protected Storage */
+#ifndef PS_MAX_ASSET_SIZE
+#define PS_MAX_ASSET_SIZE 2048
+#endif
+
+/* The maximum number of assets to be stored in the Protected Storage */
+#ifndef PS_NUM_ASSETS
+#define PS_NUM_ASSETS 10
+#endif
+
+/* The stack size of the Protected Storage Secure Partition */
+#ifndef PS_STACK_SIZE
+#define PS_STACK_SIZE 0x700
+#endif
+
+/* The stack size of the NS Agent Mailbox Secure Partition */
+#ifndef NS_AGENT_MAILBOX_STACK_SIZE
+#define NS_AGENT_MAILBOX_STACK_SIZE 0x800
+#endif
+
+/* SPM Partition Configs */
+
+#ifdef CONFIG_TFM_CONNECTION_POOL_ENABLE
+/* The maximal number of secure services that are connected or requested at the same time */
+#ifndef CONFIG_TFM_CONN_HANDLE_MAX_NUM
+#define CONFIG_TFM_CONN_HANDLE_MAX_NUM 8
+#endif
+#endif
+
+/* Disable the doorbell APIs */
+#ifndef CONFIG_TFM_DOORBELL_API
+#define CONFIG_TFM_DOORBELL_API 0
+#endif
+
+/* Do not run the scheduler after handling a secure interrupt if the NSPE was pre-empted */
+#ifndef CONFIG_TFM_SCHEDULE_WHEN_NS_INTERRUPTED
+#define CONFIG_TFM_SCHEDULE_WHEN_NS_INTERRUPTED 0
+#endif
+
+/* Enable OTP/NV_COUNTERS emulation in RAM */
+#ifndef OTP_NV_COUNTERS_RAM_EMULATION
+#define OTP_NV_COUNTERS_RAM_EMULATION 0
+#endif
+
+#endif /* __CONFIG_BASE_H__ */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/config_impl.h b/nrfdemo/build/tfm/api_ns/interface/include/config_impl.h
new file mode 100644
index 0000000..27b86ea
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/config_impl.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+/*********** WARNING: This is an auto-generated file. Do not edit! ***********/
+
+#ifndef __CONFIG_IMPL_H__
+#define __CONFIG_IMPL_H__
+
+#include "config_tfm.h"
+
+/* Backends */
+#define CONFIG_TFM_SPM_BACKEND_IPC 0
+#define CONFIG_TFM_SPM_BACKEND_SFN 1
+
+#define CONFIG_TFM_CONNECTION_BASED_SERVICE_API 0
+#define CONFIG_TFM_MMIO_REGION_ENABLE 0
+#define CONFIG_TFM_FLIH_API 0
+#define CONFIG_TFM_SLIH_API 0
+
+#if CONFIG_TFM_SPM_BACKEND_IPC == 1
+/* Trustzone NS agent working stack size. */
+#if defined(TFM_FIH_PROFILE_ON) && TFM_ISOLATION_LEVEL == 1
+#define CONFIG_TFM_NS_AGENT_TZ_STACK_SIZE 1256
+#else
+#define CONFIG_TFM_NS_AGENT_TZ_STACK_SIZE 1024
+#endif
+
+/* SPM re-uses Trustzone NS agent stack. */
+#define CONFIG_TFM_SPM_THREAD_STACK_SIZE \
+ CONFIG_TFM_NS_AGENT_TZ_STACK_SIZE
+
+#elif CONFIG_TFM_SPM_BACKEND_SFN == 1
+/*
+ * In isolation level 1 SFN model, all subsequent components work on NS agent
+ * stack. It is observed that half of the sum of all partition stack sizes is
+ * enough for working. Define a divisor factor
+ * CONFIG_TFM_NS_AGENT_TZ_STK_SIZE_SHIFT_FACTOR for reference, and allow
+ * modification of the factor based on application situation. The stack size
+ * value is aligned to 8 bytes.
+ * The minimum value is 0x400 to satisfy the SPM functional requirement.
+ * Manifest tool will assure this.
+ */
+#define CONFIG_TFM_TOTAL_STACK_SIZE (0 + CRYPTO_STACK_SIZE + PLATFORM_SP_STACK_SIZE)
+#if (CONFIG_TFM_TOTAL_STACK_SIZE < 2048)
+#undef CONFIG_TFM_TOTAL_STACK_SIZE
+#define CONFIG_TFM_TOTAL_STACK_SIZE 2048
+#endif
+
+#define CONFIG_TFM_NS_AGENT_TZ_STK_SIZE_SHIFT_FACTOR 1
+#define CONFIG_TFM_NS_AGENT_TZ_STACK_SIZE \
+ (((CONFIG_TFM_TOTAL_STACK_SIZE >> CONFIG_TFM_NS_AGENT_TZ_STK_SIZE_SHIFT_FACTOR) + 0x7) & (~0x7))
+
+#endif /* CONFIG_TFM_SPM_BACKEND_IPC == 1 */
+
+#endif /* __CONFIG_IMPL_H__ */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/config_tfm.h b/nrfdemo/build/tfm/api_ns/interface/include/config_tfm.h
new file mode 100644
index 0000000..392069b
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/config_tfm.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __CONFIG_TFM_H__
+#define __CONFIG_TFM_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Platform defined header file for TF-M configs.
+ * Path: ${TARGET_PLATFORM_PATH}/config_tfm_target.h
+ */
+#ifdef TARGET_CONFIG_HEADER_FILE
+#include TARGET_CONFIG_HEADER_FILE
+#endif
+
+#ifdef PROJECT_CONFIG_HEADER_FILE
+#include PROJECT_CONFIG_HEADER_FILE
+#endif
+
+#include "config_base.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CONFIG_TFM_H__ */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/device_cfg.h b/nrfdemo/build/tfm/api_ns/interface/include/device_cfg.h
new file mode 100644
index 0000000..ef2bfba
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/device_cfg.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2022 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
+ */
+
+#ifndef DEVICE_CFG_H__
+#define DEVICE_CFG_H__
+
+#include <autoconf.h>
+
+/* ARRAY_SIZE causes a conflict as it is defined both by TF-M and indirectly by devicetree.h */
+#undef ARRAY_SIZE
+#include <zephyr/devicetree.h>
+
+#if !defined(NRF54L15_ENGA_XXAA)
+#if defined(CONFIG_TFM_SECURE_UART0) || DOMAIN_NS == 1U
+#define TFM_UART uart0
+#endif /* defined(CONFIG_TFM_SECURE_UART0) || DOMAIN_NS == 1U */
+
+#if defined(CONFIG_TFM_SECURE_UART1) && DOMAIN_NS != 1U
+#define TFM_UART uart1
+#endif /* defined(CONFIG_TFM_SECURE_UART1) */
+
+#else /* NRF54L15_ENGA_XXAA */
+#if defined(CONFIG_TFM_SECURE_UART00) && DOMAIN_NS != 1U
+#define TFM_UART uart00
+#endif /* defined(CONFIG_TFM_SECURE_UART00) */
+
+#if defined(CONFIG_TFM_SECURE_UART20) && DOMAIN_NS != 1U
+#define TFM_UART uart20
+#endif /* defined(CONFIG_TFM_SECURE_UART20) */
+
+#if defined(CONFIG_TFM_SECURE_UART21) && DOMAIN_NS != 1U
+#define TFM_UART uart21
+#endif /* defined(CONFIG_TFM_SECURE_UART21) */
+
+#if defined(CONFIG_TFM_SECURE_UART22) && DOMAIN_NS != 1U
+#define TFM_UART uart22
+#endif /* defined(CONFIG_TFM_SECURE_UART22) */
+
+#if defined(CONFIG_TFM_SECURE_UART30) && DOMAIN_NS != 1U
+#define TFM_UART uart30
+#endif /* defined(CONFIG_TFM_SECURE_UART30) */
+#endif /* NRF54L15_ENGA_XXAA */
+
+#define DEFAULT_UART_BAUDRATE DT_PROP_OR(DT_NODELABEL(TFM_UART), current_speed, 115200)
+
+#if DT_PROP(DT_NODELABEL(TFM_UART), hw_flow_control)
+#define DEFAULT_UART_CONTROL ARM_USART_FLOW_CONTROL_RTS_CTS
+#else
+#define DEFAULT_UART_CONTROL 0
+#endif
+
+#endif /* DEVICE_CFG_H__ */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/os_wrapper/common.h b/nrfdemo/build/tfm/api_ns/interface/include/os_wrapper/common.h
new file mode 100644
index 0000000..6494723
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/os_wrapper/common.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __OS_WRAPPER_COMMON_H__
+#define __OS_WRAPPER_COMMON_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define OS_WRAPPER_SUCCESS (0x0)
+#define OS_WRAPPER_ERROR (0xFFFFFFFFU)
+#define OS_WRAPPER_WAIT_FOREVER (0xFFFFFFFFU)
+#define OS_WRAPPER_DEFAULT_STACK_SIZE (-1)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __OS_WRAPPER_COMMON_H__ */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/os_wrapper/mutex.h b/nrfdemo/build/tfm/api_ns/interface/include/os_wrapper/mutex.h
new file mode 100644
index 0000000..ffdf92c
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/os_wrapper/mutex.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2017-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company)
+ * or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __OS_WRAPPER_MUTEX_H__
+#define __OS_WRAPPER_MUTEX_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "os_wrapper/common.h"
+
+/**
+ * \brief Creates a mutex for mutual exclusion of resources
+ *
+ * \return The handle of the created mutex on success or NULL on error
+ */
+void *os_wrapper_mutex_create(void);
+
+/**
+ * \brief Acquires a mutex that is created by \ref os_wrapper_mutex_create()
+ *
+ * \param[in] handle The handle of the mutex to acquire. Should be one of the
+ * handles returned by \ref os_wrapper_mutex_create()
+ * \param[in] timeout The maximum amount of time(in tick periods) for the
+ * thread to wait for the mutex to be available.
+ * If timeout is zero, the function will return immediately.
+ * Setting timeout to \ref OS_WRAPPER_WAIT_FOREVER will
+ * cause the thread to wait indefinitely
+ *
+ * \return \ref OS_WRAPPER_SUCCESS on success or \ref OS_WRAPPER_ERROR on error
+ * or timeout
+ */
+uint32_t os_wrapper_mutex_acquire(void *handle, uint32_t timeout);
+
+/**
+ * \brief Releases the mutex acquired previously
+ *
+
+ * \param[in] handle The handle of the mutex that has been acquired
+ *
+ * \return \ref OS_WRAPPER_SUCCESS on success or \ref OS_WRAPPER_ERROR on error
+ */
+uint32_t os_wrapper_mutex_release(void *handle);
+
+/**
+ * \brief Deletes a mutex that is created by \ref os_wrapper_mutex_create()
+ *
+ * \param[in] handle The handle of the mutex to be deleted
+ *
+ * \return \ref OS_WRAPPER_SUCCESS on success or \ref OS_WRAPPER_ERROR on error
+ */
+uint32_t os_wrapper_mutex_delete(void *handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __OS_WRAPPER_MUTEX_H__ */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/psa/client.h b/nrfdemo/build/tfm/api_ns/interface/include/psa/client.h
new file mode 100644
index 0000000..b4e8b09
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/psa/client.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __PSA_CLIENT_H__
+#define __PSA_CLIENT_H__
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "psa/error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef IOVEC_LEN
+#define IOVEC_LEN(arr) ((uint32_t)(sizeof(arr)/sizeof(arr[0])))
+#endif
+
+/*********************** PSA Client Macros and Types *************************/
+
+/**
+ * The version of the PSA Framework API that is being used to build the calling
+ * firmware. Only part of features of FF-M v1.1 have been implemented. FF-M v1.1
+ * is compatible with v1.0.
+ */
+#define PSA_FRAMEWORK_VERSION (0x0101u)
+
+/**
+ * Return value from psa_version() if the requested RoT Service is not present
+ * in the system.
+ */
+#define PSA_VERSION_NONE (0u)
+
+/**
+ * The zero-value null handle can be assigned to variables used in clients and
+ * RoT Services, indicating that there is no current connection or message.
+ */
+#define PSA_NULL_HANDLE ((psa_handle_t)0)
+
+/**
+ * Tests whether a handle value returned by psa_connect() is valid.
+ */
+#define PSA_HANDLE_IS_VALID(handle) ((psa_handle_t)(handle) > 0)
+
+/**
+ * Converts the handle value returned from a failed call psa_connect() into
+ * an error code.
+ */
+#define PSA_HANDLE_TO_ERROR(handle) ((psa_status_t)(handle))
+
+/**
+ * Maximum number of input and output vectors for a request to psa_call().
+ */
+#define PSA_MAX_IOVEC (4u)
+
+
+/**
+ * The minimum and maximum value in THIS implementation that can be passed
+ * as the type parameter in a call to psa_call().
+ */
+
+#define PSA_CALL_TYPE_MIN (0)
+#define PSA_CALL_TYPE_MAX (INT16_MAX)
+
+/**
+ * An IPC message type that indicates a generic client request.
+ */
+#define PSA_IPC_CALL (0)
+
+typedef int32_t psa_handle_t;
+
+/**
+ * A read-only input memory region provided to an RoT Service.
+ */
+typedef struct psa_invec {
+ const void *base; /*!< the start address of the memory buffer */
+ size_t len; /*!< the size in bytes */
+} psa_invec;
+
+/**
+ * A writable output memory region provided to an RoT Service.
+ */
+typedef struct psa_outvec {
+ void *base; /*!< the start address of the memory buffer */
+ size_t len; /*!< the size in bytes */
+} psa_outvec;
+
+/*************************** PSA Client API **********************************/
+
+/**
+ * \brief Retrieve the version of the PSA Framework API that is implemented.
+ *
+ * \return version The version of the PSA Framework implementation
+ * that is providing the runtime services to the
+ * caller. The major and minor version are encoded
+ * as follows:
+ * \arg version[15:8] -- major version number.
+ * \arg version[7:0] -- minor version number.
+ */
+uint32_t psa_framework_version(void);
+
+/**
+ * \brief Retrieve the version of an RoT Service or indicate that it is not
+ * present on this system.
+ *
+ * \param[in] sid ID of the RoT Service to query.
+ *
+ * \retval PSA_VERSION_NONE The RoT Service is not implemented, or the
+ * caller is not permitted to access the service.
+ * \retval > 0 The version of the implemented RoT Service.
+ */
+uint32_t psa_version(uint32_t sid);
+
+/**
+ * \brief Connect to an RoT Service by its SID.
+ *
+ * \param[in] sid ID of the RoT Service to connect to.
+ * \param[in] version Requested version of the RoT Service.
+ *
+ * \retval > 0 A handle for the connection.
+ * \retval PSA_ERROR_CONNECTION_REFUSED The SPM or RoT Service has refused the
+ * connection.
+ * \retval PSA_ERROR_CONNECTION_BUSY The SPM or RoT Service cannot make the
+ * connection at the moment.
+ * \retval "PROGRAMMER ERROR" The call is a PROGRAMMER ERROR if one or more
+ * of the following are true:
+ * \arg The RoT Service ID is not present.
+ * \arg The RoT Service version is not supported.
+ * \arg The caller is not allowed to access the RoT
+ * service.
+ */
+psa_handle_t psa_connect(uint32_t sid, uint32_t version);
+
+/**
+ * \brief Call an RoT Service on an established connection.
+ *
+ * \note FF-M 1.0 proposes 6 parameters for psa_call but the secure gateway ABI
+ * support at most 4 parameters. TF-M chooses to encode 'in_len',
+ * 'out_len', and 'type' into a 32-bit integer to improve efficiency.
+ * Compared with struct-based encoding, this method saves extra memory
+ * check and memory copy operation. The disadvantage is that the 'type'
+ * range has to be reduced into a 16-bit integer. So with this encoding,
+ * the valid range for 'type' is 0-32767.
+ *
+ * \param[in] handle A handle to an established connection.
+ * \param[in] type The request type.
+ * Must be zero( \ref PSA_IPC_CALL) or positive.
+ * \param[in] in_vec Array of input \ref psa_invec structures.
+ * \param[in] in_len Number of input \ref psa_invec structures.
+ * \param[in,out] out_vec Array of output \ref psa_outvec structures.
+ * \param[in] out_len Number of output \ref psa_outvec structures.
+ *
+ * \retval >=0 RoT Service-specific status value.
+ * \retval <0 RoT Service-specific error code.
+ * \retval PSA_ERROR_PROGRAMMER_ERROR The connection has been terminated by the
+ * RoT Service. The call is a PROGRAMMER ERROR if
+ * one or more of the following are true:
+ * \arg An invalid handle was passed.
+ * \arg The connection is already handling a request.
+ * \arg type < 0.
+ * \arg An invalid memory reference was provided.
+ * \arg in_len + out_len > PSA_MAX_IOVEC.
+ * \arg The message is unrecognized by the RoT
+ * Service or incorrectly formatted.
+ */
+psa_status_t psa_call(psa_handle_t handle, int32_t type,
+ const psa_invec *in_vec,
+ size_t in_len,
+ psa_outvec *out_vec,
+ size_t out_len);
+
+/**
+ * \brief Close a connection to an RoT Service.
+ *
+ * \param[in] handle A handle to an established connection, or the
+ * null handle.
+ *
+ * \retval void Success.
+ * \retval "PROGRAMMER ERROR" The call is a PROGRAMMER ERROR if one or more
+ * of the following are true:
+ * \arg An invalid handle was provided that is not
+ * the null handle.
+ * \arg The connection is currently handling a
+ * request.
+ */
+void psa_close(psa_handle_t handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PSA_CLIENT_H__ */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto.h b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto.h
new file mode 100644
index 0000000..10480fa
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto.h
@@ -0,0 +1,4698 @@
+/*
+ * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+/**
+ * \file psa/crypto.h
+ * \brief Platform Security Architecture cryptography module
+ */
+
+#ifndef PSA_CRYPTO_H
+#define PSA_CRYPTO_H
+
+/* In Mbed TLS, we would query the current config through inclusion of
+ * mbedtls/build_info.h, but in TF-M, we don't rely on build_info.h
+ * hence we just include the current configuration if it has been passed
+ * through command line. These config defines are required in crypto_sizes.h
+ * to compute macros that define sizes which depend on algorithms supported
+ * by the implementation
+ */
+#if defined(MBEDTLS_PSA_CRYPTO_CONFIG_FILE)
+#include MBEDTLS_PSA_CRYPTO_CONFIG_FILE
+#endif /* MBEDTLS_PSA_CRYPTO_CONFIG_FILE */
+
+#if defined(MBEDTLS_PSA_CRYPTO_PLATFORM_FILE)
+#include MBEDTLS_PSA_CRYPTO_PLATFORM_FILE
+#else
+#include "crypto_platform.h"
+#endif
+
+#include <stddef.h>
+
+#ifdef __DOXYGEN_ONLY__
+/* This __DOXYGEN_ONLY__ block contains mock definitions for things that
+ * must be defined in the crypto_platform.h header. These mock definitions
+ * are present in this file as a convenience to generate pretty-printed
+ * documentation that includes those definitions. */
+
+/** \defgroup platform Implementation-specific definitions
+ * @{
+ */
+
+/**@}*/
+#endif /* __DOXYGEN_ONLY__ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The file "crypto_types.h" declares types that encode errors,
+ * algorithms, key types, policies, etc. */
+#include "crypto_types.h"
+
+/** \defgroup version API version
+ * @{
+ */
+
+/**
+ * The major version of this implementation of the PSA Crypto API
+ */
+#define PSA_CRYPTO_API_VERSION_MAJOR 1
+
+/**
+ * The minor version of this implementation of the PSA Crypto API
+ */
+#define PSA_CRYPTO_API_VERSION_MINOR 0
+
+/**@}*/
+
+/* The file "crypto_values.h" declares macros to build and analyze values
+ * of integral types defined in "crypto_types.h". */
+#include "crypto_values.h"
+
+/** \defgroup initialization Library initialization
+ * @{
+ */
+
+/**
+ * \brief Library initialization.
+ *
+ * Applications must call this function before calling any other
+ * function in this module.
+ *
+ * Applications may call this function more than once. Once a call
+ * succeeds, subsequent calls are guaranteed to succeed.
+ *
+ * If the application calls other functions before calling psa_crypto_init(),
+ * the behavior is undefined. Implementations are encouraged to either perform
+ * the operation as if the library had been initialized or to return
+ * #PSA_ERROR_BAD_STATE or some other applicable error. In particular,
+ * implementations should not return a success status if the lack of
+ * initialization may have security implications, for example due to improper
+ * seeding of the random number generator.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
+ */
+psa_status_t psa_crypto_init(void);
+
+/**@}*/
+
+/** \addtogroup attributes
+ * @{
+ */
+
+/** \def PSA_KEY_ATTRIBUTES_INIT
+ *
+ * This macro returns a suitable initializer for a key attribute structure
+ * of type #psa_key_attributes_t.
+ */
+
+/** Return an initial value for a key attributes structure.
+ */
+static psa_key_attributes_t psa_key_attributes_init(void);
+
+/** Declare a key as persistent and set its key identifier.
+ *
+ * If the attribute structure currently declares the key as volatile (which
+ * is the default content of an attribute structure), this function sets
+ * the lifetime attribute to #PSA_KEY_LIFETIME_PERSISTENT.
+ *
+ * This function does not access storage, it merely stores the given
+ * value in the structure.
+ * The persistent key will be written to storage when the attribute
+ * structure is passed to a key creation function such as
+ * psa_import_key(), psa_generate_key(),
+ * psa_key_derivation_output_key() or psa_copy_key().
+ *
+ * This function may be declared as `static` (i.e. without external
+ * linkage). This function may be provided as a function-like macro,
+ * but in this case it must evaluate each of its arguments exactly once.
+ *
+ * \param[out] attributes The attribute structure to write to.
+ * \param key The persistent identifier for the key.
+ */
+static void psa_set_key_id(psa_key_attributes_t *attributes,
+ mbedtls_svc_key_id_t key);
+
+#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
+/** Set the owner identifier of a key.
+ *
+ * When key identifiers encode key owner identifiers, psa_set_key_id() does
+ * not allow to define in key attributes the owner of volatile keys as
+ * psa_set_key_id() enforces the key to be persistent.
+ *
+ * This function allows to set in key attributes the owner identifier of a
+ * key. It is intended to be used for volatile keys. For persistent keys,
+ * it is recommended to use the PSA Cryptography API psa_set_key_id() to define
+ * the owner of a key.
+ *
+ * \param[out] attributes The attribute structure to write to.
+ * \param owner The key owner identifier.
+ */
+static void mbedtls_set_key_owner_id(psa_key_attributes_t *attributes,
+ mbedtls_key_owner_id_t owner);
+#endif
+
+/** Set the location of a persistent key.
+ *
+ * To make a key persistent, you must give it a persistent key identifier
+ * with psa_set_key_id(). By default, a key that has a persistent identifier
+ * is stored in the default storage area identifier by
+ * #PSA_KEY_LIFETIME_PERSISTENT. Call this function to choose a storage
+ * area, or to explicitly declare the key as volatile.
+ *
+ * This function does not access storage, it merely stores the given
+ * value in the structure.
+ * The persistent key will be written to storage when the attribute
+ * structure is passed to a key creation function such as
+ * psa_import_key(), psa_generate_key(),
+ * psa_key_derivation_output_key() or psa_copy_key().
+ *
+ * This function may be declared as `static` (i.e. without external
+ * linkage). This function may be provided as a function-like macro,
+ * but in this case it must evaluate each of its arguments exactly once.
+ *
+ * \param[out] attributes The attribute structure to write to.
+ * \param lifetime The lifetime for the key.
+ * If this is #PSA_KEY_LIFETIME_VOLATILE, the
+ * key will be volatile, and the key identifier
+ * attribute is reset to 0.
+ */
+static void psa_set_key_lifetime(psa_key_attributes_t *attributes,
+ psa_key_lifetime_t lifetime);
+
+/** Retrieve the key identifier from key attributes.
+ *
+ * This function may be declared as `static` (i.e. without external
+ * linkage). This function may be provided as a function-like macro,
+ * but in this case it must evaluate its argument exactly once.
+ *
+ * \param[in] attributes The key attribute structure to query.
+ *
+ * \return The persistent identifier stored in the attribute structure.
+ * This value is unspecified if the attribute structure declares
+ * the key as volatile.
+ */
+static mbedtls_svc_key_id_t psa_get_key_id(
+ const psa_key_attributes_t *attributes);
+
+/** Retrieve the lifetime from key attributes.
+ *
+ * This function may be declared as `static` (i.e. without external
+ * linkage). This function may be provided as a function-like macro,
+ * but in this case it must evaluate its argument exactly once.
+ *
+ * \param[in] attributes The key attribute structure to query.
+ *
+ * \return The lifetime value stored in the attribute structure.
+ */
+static psa_key_lifetime_t psa_get_key_lifetime(
+ const psa_key_attributes_t *attributes);
+
+/** Declare usage flags for a key.
+ *
+ * Usage flags are part of a key's usage policy. They encode what
+ * kind of operations are permitted on the key. For more details,
+ * refer to the documentation of the type #psa_key_usage_t.
+ *
+ * This function overwrites any usage flags
+ * previously set in \p attributes.
+ *
+ * This function may be declared as `static` (i.e. without external
+ * linkage). This function may be provided as a function-like macro,
+ * but in this case it must evaluate each of its arguments exactly once.
+ *
+ * \param[out] attributes The attribute structure to write to.
+ * \param usage_flags The usage flags to write.
+ */
+static void psa_set_key_usage_flags(psa_key_attributes_t *attributes,
+ psa_key_usage_t usage_flags);
+
+/** Retrieve the usage flags from key attributes.
+ *
+ * This function may be declared as `static` (i.e. without external
+ * linkage). This function may be provided as a function-like macro,
+ * but in this case it must evaluate its argument exactly once.
+ *
+ * \param[in] attributes The key attribute structure to query.
+ *
+ * \return The usage flags stored in the attribute structure.
+ */
+static psa_key_usage_t psa_get_key_usage_flags(
+ const psa_key_attributes_t *attributes);
+
+/** Declare the permitted algorithm policy for a key.
+ *
+ * The permitted algorithm policy of a key encodes which algorithm or
+ * algorithms are permitted to be used with this key. The following
+ * algorithm policies are supported:
+ * - 0 does not allow any cryptographic operation with the key. The key
+ * may be used for non-cryptographic actions such as exporting (if
+ * permitted by the usage flags).
+ * - An algorithm value permits this particular algorithm.
+ * - An algorithm wildcard built from #PSA_ALG_ANY_HASH allows the specified
+ * signature scheme with any hash algorithm.
+ * - An algorithm built from #PSA_ALG_AT_LEAST_THIS_LENGTH_MAC allows
+ * any MAC algorithm from the same base class (e.g. CMAC) which
+ * generates/verifies a MAC length greater than or equal to the length
+ * encoded in the wildcard algorithm.
+ * - An algorithm built from #PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG
+ * allows any AEAD algorithm from the same base class (e.g. CCM) which
+ * generates/verifies a tag length greater than or equal to the length
+ * encoded in the wildcard algorithm.
+ *
+ * This function overwrites any algorithm policy
+ * previously set in \p attributes.
+ *
+ * This function may be declared as `static` (i.e. without external
+ * linkage). This function may be provided as a function-like macro,
+ * but in this case it must evaluate each of its arguments exactly once.
+ *
+ * \param[out] attributes The attribute structure to write to.
+ * \param alg The permitted algorithm policy to write.
+ */
+static void psa_set_key_algorithm(psa_key_attributes_t *attributes,
+ psa_algorithm_t alg);
+
+
+/** Retrieve the algorithm policy from key attributes.
+ *
+ * This function may be declared as `static` (i.e. without external
+ * linkage). This function may be provided as a function-like macro,
+ * but in this case it must evaluate its argument exactly once.
+ *
+ * \param[in] attributes The key attribute structure to query.
+ *
+ * \return The algorithm stored in the attribute structure.
+ */
+static psa_algorithm_t psa_get_key_algorithm(
+ const psa_key_attributes_t *attributes);
+
+/** Declare the type of a key.
+ *
+ * This function overwrites any key type
+ * previously set in \p attributes.
+ *
+ * This function may be declared as `static` (i.e. without external
+ * linkage). This function may be provided as a function-like macro,
+ * but in this case it must evaluate each of its arguments exactly once.
+ *
+ * \param[out] attributes The attribute structure to write to.
+ * \param type The key type to write.
+ * If this is 0, the key type in \p attributes
+ * becomes unspecified.
+ */
+static void psa_set_key_type(psa_key_attributes_t *attributes,
+ psa_key_type_t type);
+
+
+/** Declare the size of a key.
+ *
+ * This function overwrites any key size previously set in \p attributes.
+ *
+ * This function may be declared as `static` (i.e. without external
+ * linkage). This function may be provided as a function-like macro,
+ * but in this case it must evaluate each of its arguments exactly once.
+ *
+ * \param[out] attributes The attribute structure to write to.
+ * \param bits The key size in bits.
+ * If this is 0, the key size in \p attributes
+ * becomes unspecified. Keys of size 0 are
+ * not supported.
+ */
+static void psa_set_key_bits(psa_key_attributes_t *attributes,
+ size_t bits);
+
+/** Retrieve the key type from key attributes.
+ *
+ * This function may be declared as `static` (i.e. without external
+ * linkage). This function may be provided as a function-like macro,
+ * but in this case it must evaluate its argument exactly once.
+ *
+ * \param[in] attributes The key attribute structure to query.
+ *
+ * \return The key type stored in the attribute structure.
+ */
+static psa_key_type_t psa_get_key_type(const psa_key_attributes_t *attributes);
+
+/** Retrieve the key size from key attributes.
+ *
+ * This function may be declared as `static` (i.e. without external
+ * linkage). This function may be provided as a function-like macro,
+ * but in this case it must evaluate its argument exactly once.
+ *
+ * \param[in] attributes The key attribute structure to query.
+ *
+ * \return The key size stored in the attribute structure, in bits.
+ */
+static size_t psa_get_key_bits(const psa_key_attributes_t *attributes);
+
+/** Retrieve the attributes of a key.
+ *
+ * This function first resets the attribute structure as with
+ * psa_reset_key_attributes(). It then copies the attributes of
+ * the given key into the given attribute structure.
+ *
+ * \note This function may allocate memory or other resources.
+ * Once you have called this function on an attribute structure,
+ * you must call psa_reset_key_attributes() to free these resources.
+ *
+ * \param[in] key Identifier of the key to query.
+ * \param[in,out] attributes On success, the attributes of the key.
+ * On failure, equivalent to a
+ * freshly-initialized structure.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
+ * \retval #PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key,
+ psa_key_attributes_t *attributes);
+
+/** Reset a key attribute structure to a freshly initialized state.
+ *
+ * You must initialize the attribute structure as described in the
+ * documentation of the type #psa_key_attributes_t before calling this
+ * function. Once the structure has been initialized, you may call this
+ * function at any time.
+ *
+ * This function frees any auxiliary resources that the structure
+ * may contain.
+ *
+ * \param[in,out] attributes The attribute structure to reset.
+ */
+void psa_reset_key_attributes(psa_key_attributes_t *attributes);
+
+/**@}*/
+
+/** \defgroup key_management Key management
+ * @{
+ */
+
+/** Remove non-essential copies of key material from memory.
+ *
+ * If the key identifier designates a volatile key, this functions does not do
+ * anything and returns successfully.
+ *
+ * If the key identifier designates a persistent key, then this function will
+ * free all resources associated with the key in volatile memory. The key
+ * data in persistent storage is not affected and the key can still be used.
+ *
+ * \param key Identifier of the key to purge.
+ *
+ * \retval #PSA_SUCCESS
+ * The key material will have been removed from memory if it is not
+ * currently required.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not a valid key identifier.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_purge_key(mbedtls_svc_key_id_t key);
+
+/** Make a copy of a key.
+ *
+ * Copy key material from one location to another.
+ *
+ * This function is primarily useful to copy a key from one location
+ * to another, since it populates a key using the material from
+ * another key which may have a different lifetime.
+ *
+ * This function may be used to share a key with a different party,
+ * subject to implementation-defined restrictions on key sharing.
+ *
+ * The policy on the source key must have the usage flag
+ * #PSA_KEY_USAGE_COPY set.
+ * This flag is sufficient to permit the copy if the key has the lifetime
+ * #PSA_KEY_LIFETIME_VOLATILE or #PSA_KEY_LIFETIME_PERSISTENT.
+ * Some secure elements do not provide a way to copy a key without
+ * making it extractable from the secure element. If a key is located
+ * in such a secure element, then the key must have both usage flags
+ * #PSA_KEY_USAGE_COPY and #PSA_KEY_USAGE_EXPORT in order to make
+ * a copy of the key outside the secure element.
+ *
+ * The resulting key may only be used in a way that conforms to
+ * both the policy of the original key and the policy specified in
+ * the \p attributes parameter:
+ * - The usage flags on the resulting key are the bitwise-and of the
+ * usage flags on the source policy and the usage flags in \p attributes.
+ * - If both allow the same algorithm or wildcard-based
+ * algorithm policy, the resulting key has the same algorithm policy.
+ * - If either of the policies allows an algorithm and the other policy
+ * allows a wildcard-based algorithm policy that includes this algorithm,
+ * the resulting key allows the same algorithm.
+ * - If the policies do not allow any algorithm in common, this function
+ * fails with the status #PSA_ERROR_INVALID_ARGUMENT.
+ *
+ * The effect of this function on implementation-defined attributes is
+ * implementation-defined.
+ *
+ * \param source_key The key to copy. It must allow the usage
+ * #PSA_KEY_USAGE_COPY. If a private or secret key is
+ * being copied outside of a secure element it must
+ * also allow #PSA_KEY_USAGE_EXPORT.
+ * \param[in] attributes The attributes for the new key.
+ * They are used as follows:
+ * - The key type and size may be 0. If either is
+ * nonzero, it must match the corresponding
+ * attribute of the source key.
+ * - The key location (the lifetime and, for
+ * persistent keys, the key identifier) is
+ * used directly.
+ * - The policy constraints (usage flags and
+ * algorithm policy) are combined from
+ * the source key and \p attributes so that
+ * both sets of restrictions apply, as
+ * described in the documentation of this function.
+ * \param[out] target_key On success, an identifier for the newly created
+ * key. For persistent keys, this is the key
+ * identifier defined in \p attributes.
+ * \c 0 on failure.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_INVALID_HANDLE
+ * \p source_key is invalid.
+ * \retval #PSA_ERROR_ALREADY_EXISTS
+ * This is an attempt to create a persistent key, and there is
+ * already a persistent key with the given identifier.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The lifetime or identifier in \p attributes are invalid, or
+ * the policy constraints on the source and specified in
+ * \p attributes are incompatible, or
+ * \p attributes specifies a key type or key size
+ * which does not match the attributes of the source key.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * The source key does not have the #PSA_KEY_USAGE_COPY usage flag, or
+ * the source key is not exportable and its lifetime does not
+ * allow copying it to the target's lifetime.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key,
+ const psa_key_attributes_t *attributes,
+ mbedtls_svc_key_id_t *target_key);
+
+
+/**
+ * \brief Destroy a key.
+ *
+ * This function destroys a key from both volatile
+ * memory and, if applicable, non-volatile storage. Implementations shall
+ * make a best effort to ensure that the key material cannot be recovered.
+ *
+ * This function also erases any metadata such as policies and frees
+ * resources associated with the key.
+ *
+ * If a key is currently in use in a multipart operation, then destroying the
+ * key will cause the multipart operation to fail.
+ *
+ * \param key Identifier of the key to erase. If this is \c 0, do nothing and
+ * return #PSA_SUCCESS.
+ *
+ * \retval #PSA_SUCCESS
+ * \p key was a valid identifier and the key material that it
+ * referred to has been erased. Alternatively, \p key is \c 0.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * The key cannot be erased because it is
+ * read-only, either due to a policy or due to physical restrictions.
+ * \retval #PSA_ERROR_INVALID_HANDLE
+ * \p key is not a valid identifier nor \c 0.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * There was a failure in communication with the cryptoprocessor.
+ * The key material may still be present in the cryptoprocessor.
+ * \retval #PSA_ERROR_DATA_INVALID
+ * This error is typically a result of either storage corruption on a
+ * cleartext storage backend, or an attempt to read data that was
+ * written by an incompatible version of the library.
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * The storage is corrupted. Implementations shall make a best effort
+ * to erase key material even in this stage, however applications
+ * should be aware that it may be impossible to guarantee that the
+ * key material is not recoverable in such cases.
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * An unexpected condition which is not a storage corruption or
+ * a communication failure occurred. The cryptoprocessor may have
+ * been compromised.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key);
+
+/**@}*/
+
+/** \defgroup import_export Key import and export
+ * @{
+ */
+
+/**
+ * \brief Import a key in binary format.
+ *
+ * This function supports any output from psa_export_key(). Refer to the
+ * documentation of psa_export_public_key() for the format of public keys
+ * and to the documentation of psa_export_key() for the format for
+ * other key types.
+ *
+ * The key data determines the key size. The attributes may optionally
+ * specify a key size; in this case it must match the size determined
+ * from the key data. A key size of 0 in \p attributes indicates that
+ * the key size is solely determined by the key data.
+ *
+ * Implementations must reject an attempt to import a key of size 0.
+ *
+ * This specification supports a single format for each key type.
+ * Implementations may support other formats as long as the standard
+ * format is supported. Implementations that support other formats
+ * should ensure that the formats are clearly unambiguous so as to
+ * minimize the risk that an invalid input is accidentally interpreted
+ * according to a different format.
+ *
+ * \param[in] attributes The attributes for the new key.
+ * The key size is always determined from the
+ * \p data buffer.
+ * If the key size in \p attributes is nonzero,
+ * it must be equal to the size from \p data.
+ * \param[out] key On success, an identifier to the newly created key.
+ * For persistent keys, this is the key identifier
+ * defined in \p attributes.
+ * \c 0 on failure.
+ * \param[in] data Buffer containing the key data. The content of this
+ * buffer is interpreted according to the type declared
+ * in \p attributes.
+ * All implementations must support at least the format
+ * described in the documentation
+ * of psa_export_key() or psa_export_public_key() for
+ * the chosen type. Implementations may allow other
+ * formats, but should be conservative: implementations
+ * should err on the side of rejecting content if it
+ * may be erroneous (e.g. wrong type or truncated data).
+ * \param data_length Size of the \p data buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * If the key is persistent, the key material and the key's metadata
+ * have been saved to persistent storage.
+ * \retval #PSA_ERROR_ALREADY_EXISTS
+ * This is an attempt to create a persistent key, and there is
+ * already a persistent key with the given identifier.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * The key type or key size is not supported, either by the
+ * implementation in general or in this particular persistent location.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The key attributes, as a whole, are invalid, or
+ * the key data is not correctly formatted, or
+ * the size in \p attributes is nonzero and does not match the size
+ * of the key data.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
+ * \retval #PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_import_key(const psa_key_attributes_t *attributes,
+ const uint8_t *data,
+ size_t data_length,
+ mbedtls_svc_key_id_t *key);
+
+
+
+/**
+ * \brief Export a key in binary format.
+ *
+ * The output of this function can be passed to psa_import_key() to
+ * create an equivalent object.
+ *
+ * If the implementation of psa_import_key() supports other formats
+ * beyond the format specified here, the output from psa_export_key()
+ * must use the representation specified here, not the original
+ * representation.
+ *
+ * For standard key types, the output format is as follows:
+ *
+ * - For symmetric keys (including MAC keys), the format is the
+ * raw bytes of the key.
+ * - For DES, the key data consists of 8 bytes. The parity bits must be
+ * correct.
+ * - For Triple-DES, the format is the concatenation of the
+ * two or three DES keys.
+ * - For RSA key pairs (#PSA_KEY_TYPE_RSA_KEY_PAIR), the format
+ * is the non-encrypted DER encoding of the representation defined by
+ * PKCS\#1 (RFC 8017) as `RSAPrivateKey`, version 0.
+ * ```
+ * RSAPrivateKey ::= SEQUENCE {
+ * version INTEGER, -- must be 0
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER, -- e
+ * privateExponent INTEGER, -- d
+ * prime1 INTEGER, -- p
+ * prime2 INTEGER, -- q
+ * exponent1 INTEGER, -- d mod (p-1)
+ * exponent2 INTEGER, -- d mod (q-1)
+ * coefficient INTEGER, -- (inverse of q) mod p
+ * }
+ * ```
+ * - For elliptic curve key pairs (key types for which
+ * #PSA_KEY_TYPE_IS_ECC_KEY_PAIR is true), the format is
+ * a representation of the private value as a `ceiling(m/8)`-byte string
+ * where `m` is the bit size associated with the curve, i.e. the bit size
+ * of the order of the curve's coordinate field. This byte string is
+ * in little-endian order for Montgomery curves (curve types
+ * `PSA_ECC_FAMILY_CURVEXXX`), and in big-endian order for Weierstrass
+ * curves (curve types `PSA_ECC_FAMILY_SECTXXX`, `PSA_ECC_FAMILY_SECPXXX`
+ * and `PSA_ECC_FAMILY_BRAINPOOL_PXXX`).
+ * For Weierstrass curves, this is the content of the `privateKey` field of
+ * the `ECPrivateKey` format defined by RFC 5915. For Montgomery curves,
+ * the format is defined by RFC 7748, and output is masked according to §5.
+ * For twisted Edwards curves, the private key is as defined by RFC 8032
+ * (a 32-byte string for Edwards25519, a 57-byte string for Edwards448).
+ * - For Diffie-Hellman key exchange key pairs (key types for which
+ * #PSA_KEY_TYPE_IS_DH_KEY_PAIR is true), the
+ * format is the representation of the private key `x` as a big-endian byte
+ * string. The length of the byte string is the private key size in bytes
+ * (leading zeroes are not stripped).
+ * - For public keys (key types for which #PSA_KEY_TYPE_IS_PUBLIC_KEY is
+ * true), the format is the same as for psa_export_public_key().
+ *
+ * The policy on the key must have the usage flag #PSA_KEY_USAGE_EXPORT set.
+ *
+ * \param key Identifier of the key to export. It must allow the
+ * usage #PSA_KEY_USAGE_EXPORT, unless it is a public
+ * key.
+ * \param[out] data Buffer where the key data is to be written.
+ * \param data_size Size of the \p data buffer in bytes.
+ * \param[out] data_length On success, the number of bytes
+ * that make up the key data.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * The key does not have the #PSA_KEY_USAGE_EXPORT flag.
+ * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p data buffer is too small. You can determine a
+ * sufficient buffer size by calling
+ * #PSA_EXPORT_KEY_OUTPUT_SIZE(\c type, \c bits)
+ * where \c type is the key type
+ * and \c bits is the key size in bits.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_export_key(mbedtls_svc_key_id_t key,
+ uint8_t *data,
+ size_t data_size,
+ size_t *data_length);
+
+/**
+ * \brief Export a public key or the public part of a key pair in binary format.
+ *
+ * The output of this function can be passed to psa_import_key() to
+ * create an object that is equivalent to the public key.
+ *
+ * This specification supports a single format for each key type.
+ * Implementations may support other formats as long as the standard
+ * format is supported. Implementations that support other formats
+ * should ensure that the formats are clearly unambiguous so as to
+ * minimize the risk that an invalid input is accidentally interpreted
+ * according to a different format.
+ *
+ * For standard key types, the output format is as follows:
+ * - For RSA public keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY), the DER encoding of
+ * the representation defined by RFC 3279 &sect;2.3.1 as `RSAPublicKey`.
+ * ```
+ * RSAPublicKey ::= SEQUENCE {
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER } -- e
+ * ```
+ * - For elliptic curve keys on a twisted Edwards curve (key types for which
+ * #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true and #PSA_KEY_TYPE_ECC_GET_FAMILY
+ * returns #PSA_ECC_FAMILY_TWISTED_EDWARDS), the public key is as defined
+ * by RFC 8032
+ * (a 32-byte string for Edwards25519, a 57-byte string for Edwards448).
+ * - For other elliptic curve public keys (key types for which
+ * #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true), the format is the uncompressed
+ * representation defined by SEC1 &sect;2.3.3 as the content of an ECPoint.
+ * Let `m` be the bit size associated with the curve, i.e. the bit size of
+ * `q` for a curve over `F_q`. The representation consists of:
+ * - The byte 0x04;
+ * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
+ * - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
+ * - For Diffie-Hellman key exchange public keys (key types for which
+ * #PSA_KEY_TYPE_IS_DH_PUBLIC_KEY is true),
+ * the format is the representation of the public key `y = g^x mod p` as a
+ * big-endian byte string. The length of the byte string is the length of the
+ * base prime `p` in bytes.
+ *
+ * Exporting a public key object or the public part of a key pair is
+ * always permitted, regardless of the key's usage flags.
+ *
+ * \param key Identifier of the key to export.
+ * \param[out] data Buffer where the key data is to be written.
+ * \param data_size Size of the \p data buffer in bytes.
+ * \param[out] data_length On success, the number of bytes
+ * that make up the key data.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The key is neither a public key nor a key pair.
+ * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p data buffer is too small. You can determine a
+ * sufficient buffer size by calling
+ * #PSA_EXPORT_KEY_OUTPUT_SIZE(#PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\c type), \c bits)
+ * where \c type is the key type
+ * and \c bits is the key size in bits.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key,
+ uint8_t *data,
+ size_t data_size,
+ size_t *data_length);
+
+
+
+/**@}*/
+
+/** \defgroup hash Message digests
+ * @{
+ */
+
+/** Calculate the hash (digest) of a message.
+ *
+ * \note To verify the hash of a message against an
+ * expected value, use psa_hash_compare() instead.
+ *
+ * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value
+ * such that #PSA_ALG_IS_HASH(\p alg) is true).
+ * \param[in] input Buffer containing the message to hash.
+ * \param input_length Size of the \p input buffer in bytes.
+ * \param[out] hash Buffer where the hash is to be written.
+ * \param hash_size Size of the \p hash buffer in bytes.
+ * \param[out] hash_length On success, the number of bytes
+ * that make up the hash value. This is always
+ * #PSA_HASH_LENGTH(\p alg).
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not a hash algorithm.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * \p hash_size is too small
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_hash_compute(psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length);
+
+/** Calculate the hash (digest) of a message and compare it with a
+ * reference value.
+ *
+ * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value
+ * such that #PSA_ALG_IS_HASH(\p alg) is true).
+ * \param[in] input Buffer containing the message to hash.
+ * \param input_length Size of the \p input buffer in bytes.
+ * \param[out] hash Buffer containing the expected hash value.
+ * \param hash_length Size of the \p hash buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * The expected hash is identical to the actual hash of the input.
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ * The hash of the message was calculated successfully, but it
+ * differs from the expected hash.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not a hash algorithm.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p input_length or \p hash_length do not match the hash size for \p alg
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_hash_compare(psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *hash,
+ size_t hash_length);
+
+/** The type of the state data structure for multipart hash operations.
+ *
+ * Before calling any function on a hash operation object, the application must
+ * initialize it by any of the following means:
+ * - Set the structure to all-bits-zero, for example:
+ * \code
+ * psa_hash_operation_t operation;
+ * memset(&operation, 0, sizeof(operation));
+ * \endcode
+ * - Initialize the structure to logical zero values, for example:
+ * \code
+ * psa_hash_operation_t operation = {0};
+ * \endcode
+ * - Initialize the structure to the initializer #PSA_HASH_OPERATION_INIT,
+ * for example:
+ * \code
+ * psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
+ * \endcode
+ * - Assign the result of the function psa_hash_operation_init()
+ * to the structure, for example:
+ * \code
+ * psa_hash_operation_t operation;
+ * operation = psa_hash_operation_init();
+ * \endcode
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure.
+ * Implementation details can change in future versions without notice. */
+typedef struct psa_hash_operation_s psa_hash_operation_t;
+
+/** \def PSA_HASH_OPERATION_INIT
+ *
+ * This macro returns a suitable initializer for a hash operation object
+ * of type #psa_hash_operation_t.
+ */
+
+/** Return an initial value for a hash operation object.
+ */
+static psa_hash_operation_t psa_hash_operation_init(void);
+
+/** Set up a multipart hash operation.
+ *
+ * The sequence of operations to calculate a hash (message digest)
+ * is as follows:
+ * -# Allocate an operation object which will be passed to all the functions
+ * listed here.
+ * -# Initialize the operation object with one of the methods described in the
+ * documentation for #psa_hash_operation_t, e.g. #PSA_HASH_OPERATION_INIT.
+ * -# Call psa_hash_setup() to specify the algorithm.
+ * -# Call psa_hash_update() zero, one or more times, passing a fragment
+ * of the message each time. The hash that is calculated is the hash
+ * of the concatenation of these messages in order.
+ * -# To calculate the hash, call psa_hash_finish().
+ * To compare the hash with an expected value, call psa_hash_verify().
+ *
+ * If an error occurs at any step after a call to psa_hash_setup(), the
+ * operation will need to be reset by a call to psa_hash_abort(). The
+ * application may call psa_hash_abort() at any time after the operation
+ * has been initialized.
+ *
+ * After a successful call to psa_hash_setup(), the application must
+ * eventually terminate the operation. The following events terminate an
+ * operation:
+ * - A successful call to psa_hash_finish() or psa_hash_verify().
+ * - A call to psa_hash_abort().
+ *
+ * \param[in,out] operation The operation object to set up. It must have
+ * been initialized as per the documentation for
+ * #psa_hash_operation_t and not yet in use.
+ * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value
+ * such that #PSA_ALG_IS_HASH(\p alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not a supported hash algorithm.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p alg is not a hash algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be inactive), or
+ * the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_hash_setup(psa_hash_operation_t *operation,
+ psa_algorithm_t alg);
+
+/** Add a message fragment to a multipart hash operation.
+ *
+ * The application must call psa_hash_setup() before calling this function.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_hash_abort().
+ *
+ * \param[in,out] operation Active hash operation.
+ * \param[in] input Buffer containing the message fragment to hash.
+ * \param input_length Size of the \p input buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active), or
+ * the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_hash_update(psa_hash_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length);
+
+/** Finish the calculation of the hash of a message.
+ *
+ * The application must call psa_hash_setup() before calling this function.
+ * This function calculates the hash of the message formed by concatenating
+ * the inputs passed to preceding calls to psa_hash_update().
+ *
+ * When this function returns successfully, the operation becomes inactive.
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_hash_abort().
+ *
+ * \warning Applications should not call this function if they expect
+ * a specific value for the hash. Call psa_hash_verify() instead.
+ * Beware that comparing integrity or authenticity data such as
+ * hash values with a function such as \c memcmp is risky
+ * because the time taken by the comparison may leak information
+ * about the hashed data which could allow an attacker to guess
+ * a valid hash and thereby bypass security controls.
+ *
+ * \param[in,out] operation Active hash operation.
+ * \param[out] hash Buffer where the hash is to be written.
+ * \param hash_size Size of the \p hash buffer in bytes.
+ * \param[out] hash_length On success, the number of bytes
+ * that make up the hash value. This is always
+ * #PSA_HASH_LENGTH(\c alg) where \c alg is the
+ * hash algorithm that is calculated.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p hash buffer is too small. You can determine a
+ * sufficient buffer size by calling #PSA_HASH_LENGTH(\c alg)
+ * where \c alg is the hash algorithm that is calculated.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active), or
+ * the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_hash_finish(psa_hash_operation_t *operation,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length);
+
+/** Finish the calculation of the hash of a message and compare it with
+ * an expected value.
+ *
+ * The application must call psa_hash_setup() before calling this function.
+ * This function calculates the hash of the message formed by concatenating
+ * the inputs passed to preceding calls to psa_hash_update(). It then
+ * compares the calculated hash with the expected hash passed as a
+ * parameter to this function.
+ *
+ * When this function returns successfully, the operation becomes inactive.
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_hash_abort().
+ *
+ * \note Implementations shall make the best effort to ensure that the
+ * comparison between the actual hash and the expected hash is performed
+ * in constant time.
+ *
+ * \param[in,out] operation Active hash operation.
+ * \param[in] hash Buffer containing the expected hash value.
+ * \param hash_length Size of the \p hash buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * The expected hash is identical to the actual hash of the message.
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ * The hash of the message was calculated successfully, but it
+ * differs from the expected hash.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active), or
+ * the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
+ const uint8_t *hash,
+ size_t hash_length);
+
+/** Abort a hash operation.
+ *
+ * Aborting an operation frees all associated resources except for the
+ * \p operation structure itself. Once aborted, the operation object
+ * can be reused for another operation by calling
+ * psa_hash_setup() again.
+ *
+ * You may call this function any time after the operation object has
+ * been initialized by one of the methods described in #psa_hash_operation_t.
+ *
+ * In particular, calling psa_hash_abort() after the operation has been
+ * terminated by a call to psa_hash_abort(), psa_hash_finish() or
+ * psa_hash_verify() is safe and has no effect.
+ *
+ * \param[in,out] operation Initialized hash operation.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_hash_abort(psa_hash_operation_t *operation);
+
+/** Clone a hash operation.
+ *
+ * This function copies the state of an ongoing hash operation to
+ * a new operation object. In other words, this function is equivalent
+ * to calling psa_hash_setup() on \p target_operation with the same
+ * algorithm that \p source_operation was set up for, then
+ * psa_hash_update() on \p target_operation with the same input that
+ * that was passed to \p source_operation. After this function returns, the
+ * two objects are independent, i.e. subsequent calls involving one of
+ * the objects do not affect the other object.
+ *
+ * \param[in] source_operation The active hash operation to clone.
+ * \param[in,out] target_operation The operation object to set up.
+ * It must be initialized but not active.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The \p source_operation state is not valid (it must be active), or
+ * the \p target_operation state is not valid (it must be inactive), or
+ * the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
+ psa_hash_operation_t *target_operation);
+
+/**@}*/
+
+/** \defgroup MAC Message authentication codes
+ * @{
+ */
+
+/** Calculate the MAC (message authentication code) of a message.
+ *
+ * \note To verify the MAC of a message against an
+ * expected value, use psa_mac_verify() instead.
+ * Beware that comparing integrity or authenticity data such as
+ * MAC values with a function such as \c memcmp is risky
+ * because the time taken by the comparison may leak information
+ * about the MAC value which could allow an attacker to guess
+ * a valid MAC and thereby bypass security controls.
+ *
+ * \param key Identifier of the key to use for the operation. It
+ * must allow the usage PSA_KEY_USAGE_SIGN_MESSAGE.
+ * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value
+ * such that #PSA_ALG_IS_MAC(\p alg) is true).
+ * \param[in] input Buffer containing the input message.
+ * \param input_length Size of the \p input buffer in bytes.
+ * \param[out] mac Buffer where the MAC value is to be written.
+ * \param mac_size Size of the \p mac buffer in bytes.
+ * \param[out] mac_length On success, the number of bytes
+ * that make up the MAC value.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not compatible with \p alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not a MAC algorithm.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * \p mac_size is too small
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * The key could not be retrieved from storage.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *mac,
+ size_t mac_size,
+ size_t *mac_length);
+
+/** Calculate the MAC of a message and compare it with a reference value.
+ *
+ * \param key Identifier of the key to use for the operation. It
+ * must allow the usage PSA_KEY_USAGE_VERIFY_MESSAGE.
+ * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value
+ * such that #PSA_ALG_IS_MAC(\p alg) is true).
+ * \param[in] input Buffer containing the input message.
+ * \param input_length Size of the \p input buffer in bytes.
+ * \param[out] mac Buffer containing the expected MAC value.
+ * \param mac_length Size of the \p mac buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * The expected MAC is identical to the actual MAC of the input.
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ * The MAC of the message was calculated successfully, but it
+ * differs from the expected value.
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not compatible with \p alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not a MAC algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * The key could not be retrieved from storage.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_mac_verify(mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *mac,
+ size_t mac_length);
+
+/** The type of the state data structure for multipart MAC operations.
+ *
+ * Before calling any function on a MAC operation object, the application must
+ * initialize it by any of the following means:
+ * - Set the structure to all-bits-zero, for example:
+ * \code
+ * psa_mac_operation_t operation;
+ * memset(&operation, 0, sizeof(operation));
+ * \endcode
+ * - Initialize the structure to logical zero values, for example:
+ * \code
+ * psa_mac_operation_t operation = {0};
+ * \endcode
+ * - Initialize the structure to the initializer #PSA_MAC_OPERATION_INIT,
+ * for example:
+ * \code
+ * psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+ * \endcode
+ * - Assign the result of the function psa_mac_operation_init()
+ * to the structure, for example:
+ * \code
+ * psa_mac_operation_t operation;
+ * operation = psa_mac_operation_init();
+ * \endcode
+ *
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure.
+ * Implementation details can change in future versions without notice. */
+typedef struct psa_mac_operation_s psa_mac_operation_t;
+
+/** \def PSA_MAC_OPERATION_INIT
+ *
+ * This macro returns a suitable initializer for a MAC operation object of type
+ * #psa_mac_operation_t.
+ */
+
+/** Return an initial value for a MAC operation object.
+ */
+static psa_mac_operation_t psa_mac_operation_init(void);
+
+/** Set up a multipart MAC calculation operation.
+ *
+ * This function sets up the calculation of the MAC
+ * (message authentication code) of a byte string.
+ * To verify the MAC of a message against an
+ * expected value, use psa_mac_verify_setup() instead.
+ *
+ * The sequence of operations to calculate a MAC is as follows:
+ * -# Allocate an operation object which will be passed to all the functions
+ * listed here.
+ * -# Initialize the operation object with one of the methods described in the
+ * documentation for #psa_mac_operation_t, e.g. #PSA_MAC_OPERATION_INIT.
+ * -# Call psa_mac_sign_setup() to specify the algorithm and key.
+ * -# Call psa_mac_update() zero, one or more times, passing a fragment
+ * of the message each time. The MAC that is calculated is the MAC
+ * of the concatenation of these messages in order.
+ * -# At the end of the message, call psa_mac_sign_finish() to finish
+ * calculating the MAC value and retrieve it.
+ *
+ * If an error occurs at any step after a call to psa_mac_sign_setup(), the
+ * operation will need to be reset by a call to psa_mac_abort(). The
+ * application may call psa_mac_abort() at any time after the operation
+ * has been initialized.
+ *
+ * After a successful call to psa_mac_sign_setup(), the application must
+ * eventually terminate the operation through one of the following methods:
+ * - A successful call to psa_mac_sign_finish().
+ * - A call to psa_mac_abort().
+ *
+ * \param[in,out] operation The operation object to set up. It must have
+ * been initialized as per the documentation for
+ * #psa_mac_operation_t and not yet in use.
+ * \param key Identifier of the key to use for the operation. It
+ * must remain valid until the operation terminates.
+ * It must allow the usage PSA_KEY_USAGE_SIGN_MESSAGE.
+ * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value
+ * such that #PSA_ALG_IS_MAC(\p alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not compatible with \p alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not a MAC algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * The key could not be retrieved from storage.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be inactive), or
+ * the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation,
+ mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg);
+
+/** Set up a multipart MAC verification operation.
+ *
+ * This function sets up the verification of the MAC
+ * (message authentication code) of a byte string against an expected value.
+ *
+ * The sequence of operations to verify a MAC is as follows:
+ * -# Allocate an operation object which will be passed to all the functions
+ * listed here.
+ * -# Initialize the operation object with one of the methods described in the
+ * documentation for #psa_mac_operation_t, e.g. #PSA_MAC_OPERATION_INIT.
+ * -# Call psa_mac_verify_setup() to specify the algorithm and key.
+ * -# Call psa_mac_update() zero, one or more times, passing a fragment
+ * of the message each time. The MAC that is calculated is the MAC
+ * of the concatenation of these messages in order.
+ * -# At the end of the message, call psa_mac_verify_finish() to finish
+ * calculating the actual MAC of the message and verify it against
+ * the expected value.
+ *
+ * If an error occurs at any step after a call to psa_mac_verify_setup(), the
+ * operation will need to be reset by a call to psa_mac_abort(). The
+ * application may call psa_mac_abort() at any time after the operation
+ * has been initialized.
+ *
+ * After a successful call to psa_mac_verify_setup(), the application must
+ * eventually terminate the operation through one of the following methods:
+ * - A successful call to psa_mac_verify_finish().
+ * - A call to psa_mac_abort().
+ *
+ * \param[in,out] operation The operation object to set up. It must have
+ * been initialized as per the documentation for
+ * #psa_mac_operation_t and not yet in use.
+ * \param key Identifier of the key to use for the operation. It
+ * must remain valid until the operation terminates.
+ * It must allow the usage
+ * PSA_KEY_USAGE_VERIFY_MESSAGE.
+ * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value
+ * such that #PSA_ALG_IS_MAC(\p alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \c key is not compatible with \c alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \c alg is not supported or is not a MAC algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * The key could not be retrieved from storage.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be inactive), or
+ * the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation,
+ mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg);
+
+/** Add a message fragment to a multipart MAC operation.
+ *
+ * The application must call psa_mac_sign_setup() or psa_mac_verify_setup()
+ * before calling this function.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_mac_abort().
+ *
+ * \param[in,out] operation Active MAC operation.
+ * \param[in] input Buffer containing the message fragment to add to
+ * the MAC calculation.
+ * \param input_length Size of the \p input buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active), or
+ * the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_mac_update(psa_mac_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length);
+
+/** Finish the calculation of the MAC of a message.
+ *
+ * The application must call psa_mac_sign_setup() before calling this function.
+ * This function calculates the MAC of the message formed by concatenating
+ * the inputs passed to preceding calls to psa_mac_update().
+ *
+ * When this function returns successfully, the operation becomes inactive.
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_mac_abort().
+ *
+ * \warning Applications should not call this function if they expect
+ * a specific value for the MAC. Call psa_mac_verify_finish() instead.
+ * Beware that comparing integrity or authenticity data such as
+ * MAC values with a function such as \c memcmp is risky
+ * because the time taken by the comparison may leak information
+ * about the MAC value which could allow an attacker to guess
+ * a valid MAC and thereby bypass security controls.
+ *
+ * \param[in,out] operation Active MAC operation.
+ * \param[out] mac Buffer where the MAC value is to be written.
+ * \param mac_size Size of the \p mac buffer in bytes.
+ * \param[out] mac_length On success, the number of bytes
+ * that make up the MAC value. This is always
+ * #PSA_MAC_LENGTH(\c key_type, \c key_bits, \c alg)
+ * where \c key_type and \c key_bits are the type and
+ * bit-size respectively of the key and \c alg is the
+ * MAC algorithm that is calculated.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p mac buffer is too small. You can determine a
+ * sufficient buffer size by calling PSA_MAC_LENGTH().
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be an active mac sign
+ * operation), or the library has not been previously initialized
+ * by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation,
+ uint8_t *mac,
+ size_t mac_size,
+ size_t *mac_length);
+
+/** Finish the calculation of the MAC of a message and compare it with
+ * an expected value.
+ *
+ * The application must call psa_mac_verify_setup() before calling this function.
+ * This function calculates the MAC of the message formed by concatenating
+ * the inputs passed to preceding calls to psa_mac_update(). It then
+ * compares the calculated MAC with the expected MAC passed as a
+ * parameter to this function.
+ *
+ * When this function returns successfully, the operation becomes inactive.
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_mac_abort().
+ *
+ * \note Implementations shall make the best effort to ensure that the
+ * comparison between the actual MAC and the expected MAC is performed
+ * in constant time.
+ *
+ * \param[in,out] operation Active MAC operation.
+ * \param[in] mac Buffer containing the expected MAC value.
+ * \param mac_length Size of the \p mac buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * The expected MAC is identical to the actual MAC of the message.
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ * The MAC of the message was calculated successfully, but it
+ * differs from the expected MAC.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be an active mac verify
+ * operation), or the library has not been previously initialized
+ * by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation,
+ const uint8_t *mac,
+ size_t mac_length);
+
+/** Abort a MAC operation.
+ *
+ * Aborting an operation frees all associated resources except for the
+ * \p operation structure itself. Once aborted, the operation object
+ * can be reused for another operation by calling
+ * psa_mac_sign_setup() or psa_mac_verify_setup() again.
+ *
+ * You may call this function any time after the operation object has
+ * been initialized by one of the methods described in #psa_mac_operation_t.
+ *
+ * In particular, calling psa_mac_abort() after the operation has been
+ * terminated by a call to psa_mac_abort(), psa_mac_sign_finish() or
+ * psa_mac_verify_finish() is safe and has no effect.
+ *
+ * \param[in,out] operation Initialized MAC operation.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_mac_abort(psa_mac_operation_t *operation);
+
+/**@}*/
+
+/** \defgroup cipher Symmetric ciphers
+ * @{
+ */
+
+/** Encrypt a message using a symmetric cipher.
+ *
+ * This function encrypts a message with a random IV (initialization
+ * vector). Use the multipart operation interface with a
+ * #psa_cipher_operation_t object to provide other forms of IV.
+ *
+ * \param key Identifier of the key to use for the operation.
+ * It must allow the usage #PSA_KEY_USAGE_ENCRYPT.
+ * \param alg The cipher algorithm to compute
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_CIPHER(\p alg) is true).
+ * \param[in] input Buffer containing the message to encrypt.
+ * \param input_length Size of the \p input buffer in bytes.
+ * \param[out] output Buffer where the output is to be written.
+ * The output contains the IV followed by
+ * the ciphertext proper.
+ * \param output_size Size of the \p output buffer in bytes.
+ * \param[out] output_length On success, the number of bytes
+ * that make up the output.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not compatible with \p alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not a cipher algorithm.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length);
+
+/** Decrypt a message using a symmetric cipher.
+ *
+ * This function decrypts a message encrypted with a symmetric cipher.
+ *
+ * \param key Identifier of the key to use for the operation.
+ * It must remain valid until the operation
+ * terminates. It must allow the usage
+ * #PSA_KEY_USAGE_DECRYPT.
+ * \param alg The cipher algorithm to compute
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_CIPHER(\p alg) is true).
+ * \param[in] input Buffer containing the message to decrypt.
+ * This consists of the IV followed by the
+ * ciphertext proper.
+ * \param input_length Size of the \p input buffer in bytes.
+ * \param[out] output Buffer where the plaintext is to be written.
+ * \param output_size Size of the \p output buffer in bytes.
+ * \param[out] output_length On success, the number of bytes
+ * that make up the output.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not compatible with \p alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not a cipher algorithm.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length);
+
+/** The type of the state data structure for multipart cipher operations.
+ *
+ * Before calling any function on a cipher operation object, the application
+ * must initialize it by any of the following means:
+ * - Set the structure to all-bits-zero, for example:
+ * \code
+ * psa_cipher_operation_t operation;
+ * memset(&operation, 0, sizeof(operation));
+ * \endcode
+ * - Initialize the structure to logical zero values, for example:
+ * \code
+ * psa_cipher_operation_t operation = {0};
+ * \endcode
+ * - Initialize the structure to the initializer #PSA_CIPHER_OPERATION_INIT,
+ * for example:
+ * \code
+ * psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
+ * \endcode
+ * - Assign the result of the function psa_cipher_operation_init()
+ * to the structure, for example:
+ * \code
+ * psa_cipher_operation_t operation;
+ * operation = psa_cipher_operation_init();
+ * \endcode
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure.
+ * Implementation details can change in future versions without notice. */
+typedef struct psa_cipher_operation_s psa_cipher_operation_t;
+
+/** \def PSA_CIPHER_OPERATION_INIT
+ *
+ * This macro returns a suitable initializer for a cipher operation object of
+ * type #psa_cipher_operation_t.
+ */
+
+/** Return an initial value for a cipher operation object.
+ */
+static psa_cipher_operation_t psa_cipher_operation_init(void);
+
+/** Set the key for a multipart symmetric encryption operation.
+ *
+ * The sequence of operations to encrypt a message with a symmetric cipher
+ * is as follows:
+ * -# Allocate an operation object which will be passed to all the functions
+ * listed here.
+ * -# Initialize the operation object with one of the methods described in the
+ * documentation for #psa_cipher_operation_t, e.g.
+ * #PSA_CIPHER_OPERATION_INIT.
+ * -# Call psa_cipher_encrypt_setup() to specify the algorithm and key.
+ * -# Call either psa_cipher_generate_iv() or psa_cipher_set_iv() to
+ * generate or set the IV (initialization vector). You should use
+ * psa_cipher_generate_iv() unless the protocol you are implementing
+ * requires a specific IV value.
+ * -# Call psa_cipher_update() zero, one or more times, passing a fragment
+ * of the message each time.
+ * -# Call psa_cipher_finish().
+ *
+ * If an error occurs at any step after a call to psa_cipher_encrypt_setup(),
+ * the operation will need to be reset by a call to psa_cipher_abort(). The
+ * application may call psa_cipher_abort() at any time after the operation
+ * has been initialized.
+ *
+ * After a successful call to psa_cipher_encrypt_setup(), the application must
+ * eventually terminate the operation. The following events terminate an
+ * operation:
+ * - A successful call to psa_cipher_finish().
+ * - A call to psa_cipher_abort().
+ *
+ * \param[in,out] operation The operation object to set up. It must have
+ * been initialized as per the documentation for
+ * #psa_cipher_operation_t and not yet in use.
+ * \param key Identifier of the key to use for the operation.
+ * It must remain valid until the operation
+ * terminates. It must allow the usage
+ * #PSA_KEY_USAGE_ENCRYPT.
+ * \param alg The cipher algorithm to compute
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_CIPHER(\p alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not compatible with \p alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not a cipher algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be inactive), or
+ * the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation,
+ mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg);
+
+/** Set the key for a multipart symmetric decryption operation.
+ *
+ * The sequence of operations to decrypt a message with a symmetric cipher
+ * is as follows:
+ * -# Allocate an operation object which will be passed to all the functions
+ * listed here.
+ * -# Initialize the operation object with one of the methods described in the
+ * documentation for #psa_cipher_operation_t, e.g.
+ * #PSA_CIPHER_OPERATION_INIT.
+ * -# Call psa_cipher_decrypt_setup() to specify the algorithm and key.
+ * -# Call psa_cipher_set_iv() with the IV (initialization vector) for the
+ * decryption. If the IV is prepended to the ciphertext, you can call
+ * psa_cipher_update() on a buffer containing the IV followed by the
+ * beginning of the message.
+ * -# Call psa_cipher_update() zero, one or more times, passing a fragment
+ * of the message each time.
+ * -# Call psa_cipher_finish().
+ *
+ * If an error occurs at any step after a call to psa_cipher_decrypt_setup(),
+ * the operation will need to be reset by a call to psa_cipher_abort(). The
+ * application may call psa_cipher_abort() at any time after the operation
+ * has been initialized.
+ *
+ * After a successful call to psa_cipher_decrypt_setup(), the application must
+ * eventually terminate the operation. The following events terminate an
+ * operation:
+ * - A successful call to psa_cipher_finish().
+ * - A call to psa_cipher_abort().
+ *
+ * \param[in,out] operation The operation object to set up. It must have
+ * been initialized as per the documentation for
+ * #psa_cipher_operation_t and not yet in use.
+ * \param key Identifier of the key to use for the operation.
+ * It must remain valid until the operation
+ * terminates. It must allow the usage
+ * #PSA_KEY_USAGE_DECRYPT.
+ * \param alg The cipher algorithm to compute
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_CIPHER(\p alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not compatible with \p alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not a cipher algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be inactive), or
+ * the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation,
+ mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg);
+
+/** Generate an IV for a symmetric encryption operation.
+ *
+ * This function generates a random IV (initialization vector), nonce
+ * or initial counter value for the encryption operation as appropriate
+ * for the chosen algorithm, key type and key size.
+ *
+ * The application must call psa_cipher_encrypt_setup() before
+ * calling this function.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_cipher_abort().
+ *
+ * \param[in,out] operation Active cipher operation.
+ * \param[out] iv Buffer where the generated IV is to be written.
+ * \param iv_size Size of the \p iv buffer in bytes.
+ * \param[out] iv_length On success, the number of bytes of the
+ * generated IV.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p iv buffer is too small.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active, with no IV set),
+ * or the library has not been previously initialized
+ * by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation,
+ uint8_t *iv,
+ size_t iv_size,
+ size_t *iv_length);
+
+/** Set the IV for a symmetric encryption or decryption operation.
+ *
+ * This function sets the IV (initialization vector), nonce
+ * or initial counter value for the encryption or decryption operation.
+ *
+ * The application must call psa_cipher_encrypt_setup() before
+ * calling this function.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_cipher_abort().
+ *
+ * \note When encrypting, applications should use psa_cipher_generate_iv()
+ * instead of this function, unless implementing a protocol that requires
+ * a non-random IV.
+ *
+ * \param[in,out] operation Active cipher operation.
+ * \param[in] iv Buffer containing the IV to use.
+ * \param iv_length Size of the IV in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The size of \p iv is not acceptable for the chosen algorithm,
+ * or the chosen algorithm does not use an IV.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be an active cipher
+ * encrypt operation, with no IV set), or the library has not been
+ * previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation,
+ const uint8_t *iv,
+ size_t iv_length);
+
+/** Encrypt or decrypt a message fragment in an active cipher operation.
+ *
+ * Before calling this function, you must:
+ * 1. Call either psa_cipher_encrypt_setup() or psa_cipher_decrypt_setup().
+ * The choice of setup function determines whether this function
+ * encrypts or decrypts its input.
+ * 2. If the algorithm requires an IV, call psa_cipher_generate_iv()
+ * (recommended when encrypting) or psa_cipher_set_iv().
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_cipher_abort().
+ *
+ * \param[in,out] operation Active cipher operation.
+ * \param[in] input Buffer containing the message fragment to
+ * encrypt or decrypt.
+ * \param input_length Size of the \p input buffer in bytes.
+ * \param[out] output Buffer where the output is to be written.
+ * \param output_size Size of the \p output buffer in bytes.
+ * \param[out] output_length On success, the number of bytes
+ * that make up the returned output.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p output buffer is too small.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active, with an IV set
+ * if required for the algorithm), or the library has not been
+ * previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_cipher_update(psa_cipher_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length);
+
+/** Finish encrypting or decrypting a message in a cipher operation.
+ *
+ * The application must call psa_cipher_encrypt_setup() or
+ * psa_cipher_decrypt_setup() before calling this function. The choice
+ * of setup function determines whether this function encrypts or
+ * decrypts its input.
+ *
+ * This function finishes the encryption or decryption of the message
+ * formed by concatenating the inputs passed to preceding calls to
+ * psa_cipher_update().
+ *
+ * When this function returns successfully, the operation becomes inactive.
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_cipher_abort().
+ *
+ * \param[in,out] operation Active cipher operation.
+ * \param[out] output Buffer where the output is to be written.
+ * \param output_size Size of the \p output buffer in bytes.
+ * \param[out] output_length On success, the number of bytes
+ * that make up the returned output.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The total input size passed to this operation is not valid for
+ * this particular algorithm. For example, the algorithm is a based
+ * on block cipher and requires a whole number of blocks, but the
+ * total input size is not a multiple of the block size.
+ * \retval #PSA_ERROR_INVALID_PADDING
+ * This is a decryption operation for an algorithm that includes
+ * padding, and the ciphertext does not contain valid padding.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p output buffer is too small.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active, with an IV set
+ * if required for the algorithm), or the library has not been
+ * previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length);
+
+/** Abort a cipher operation.
+ *
+ * Aborting an operation frees all associated resources except for the
+ * \p operation structure itself. Once aborted, the operation object
+ * can be reused for another operation by calling
+ * psa_cipher_encrypt_setup() or psa_cipher_decrypt_setup() again.
+ *
+ * You may call this function any time after the operation object has
+ * been initialized as described in #psa_cipher_operation_t.
+ *
+ * In particular, calling psa_cipher_abort() after the operation has been
+ * terminated by a call to psa_cipher_abort() or psa_cipher_finish()
+ * is safe and has no effect.
+ *
+ * \param[in,out] operation Initialized cipher operation.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation);
+
+/**@}*/
+
+/** \defgroup aead Authenticated encryption with associated data (AEAD)
+ * @{
+ */
+
+/** Process an authenticated encryption operation.
+ *
+ * \param key Identifier of the key to use for the
+ * operation. It must allow the usage
+ * #PSA_KEY_USAGE_ENCRYPT.
+ * \param alg The AEAD algorithm to compute
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(\p alg) is true).
+ * \param[in] nonce Nonce or IV to use.
+ * \param nonce_length Size of the \p nonce buffer in bytes.
+ * \param[in] additional_data Additional data that will be authenticated
+ * but not encrypted.
+ * \param additional_data_length Size of \p additional_data in bytes.
+ * \param[in] plaintext Data that will be authenticated and
+ * encrypted.
+ * \param plaintext_length Size of \p plaintext in bytes.
+ * \param[out] ciphertext Output buffer for the authenticated and
+ * encrypted data. The additional data is not
+ * part of this output. For algorithms where the
+ * encrypted data and the authentication tag
+ * are defined as separate outputs, the
+ * authentication tag is appended to the
+ * encrypted data.
+ * \param ciphertext_size Size of the \p ciphertext buffer in bytes.
+ * This must be appropriate for the selected
+ * algorithm and key:
+ * - A sufficient output size is
+ * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\c key_type,
+ * \p alg, \p plaintext_length) where
+ * \c key_type is the type of \p key.
+ * - #PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(\p
+ * plaintext_length) evaluates to the maximum
+ * ciphertext size of any supported AEAD
+ * encryption.
+ * \param[out] ciphertext_length On success, the size of the output
+ * in the \p ciphertext buffer.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not compatible with \p alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not an AEAD algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * \p ciphertext_size is too small.
+ * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\c key_type, \p alg,
+ * \p plaintext_length) or
+ * #PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(\p plaintext_length) can be used to
+ * determine the required buffer size.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *nonce,
+ size_t nonce_length,
+ const uint8_t *additional_data,
+ size_t additional_data_length,
+ const uint8_t *plaintext,
+ size_t plaintext_length,
+ uint8_t *ciphertext,
+ size_t ciphertext_size,
+ size_t *ciphertext_length);
+
+/** Process an authenticated decryption operation.
+ *
+ * \param key Identifier of the key to use for the
+ * operation. It must allow the usage
+ * #PSA_KEY_USAGE_DECRYPT.
+ * \param alg The AEAD algorithm to compute
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(\p alg) is true).
+ * \param[in] nonce Nonce or IV to use.
+ * \param nonce_length Size of the \p nonce buffer in bytes.
+ * \param[in] additional_data Additional data that has been authenticated
+ * but not encrypted.
+ * \param additional_data_length Size of \p additional_data in bytes.
+ * \param[in] ciphertext Data that has been authenticated and
+ * encrypted. For algorithms where the
+ * encrypted data and the authentication tag
+ * are defined as separate inputs, the buffer
+ * must contain the encrypted data followed
+ * by the authentication tag.
+ * \param ciphertext_length Size of \p ciphertext in bytes.
+ * \param[out] plaintext Output buffer for the decrypted data.
+ * \param plaintext_size Size of the \p plaintext buffer in bytes.
+ * This must be appropriate for the selected
+ * algorithm and key:
+ * - A sufficient output size is
+ * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\c key_type,
+ * \p alg, \p ciphertext_length) where
+ * \c key_type is the type of \p key.
+ * - #PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(\p
+ * ciphertext_length) evaluates to the maximum
+ * plaintext size of any supported AEAD
+ * decryption.
+ * \param[out] plaintext_length On success, the size of the output
+ * in the \p plaintext buffer.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ * The ciphertext is not authentic.
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not compatible with \p alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not an AEAD algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * \p plaintext_size is too small.
+ * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\c key_type, \p alg,
+ * \p ciphertext_length) or
+ * #PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(\p ciphertext_length) can be used
+ * to determine the required buffer size.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *nonce,
+ size_t nonce_length,
+ const uint8_t *additional_data,
+ size_t additional_data_length,
+ const uint8_t *ciphertext,
+ size_t ciphertext_length,
+ uint8_t *plaintext,
+ size_t plaintext_size,
+ size_t *plaintext_length);
+
+/** The type of the state data structure for multipart AEAD operations.
+ *
+ * Before calling any function on an AEAD operation object, the application
+ * must initialize it by any of the following means:
+ * - Set the structure to all-bits-zero, for example:
+ * \code
+ * psa_aead_operation_t operation;
+ * memset(&operation, 0, sizeof(operation));
+ * \endcode
+ * - Initialize the structure to logical zero values, for example:
+ * \code
+ * psa_aead_operation_t operation = {0};
+ * \endcode
+ * - Initialize the structure to the initializer #PSA_AEAD_OPERATION_INIT,
+ * for example:
+ * \code
+ * psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
+ * \endcode
+ * - Assign the result of the function psa_aead_operation_init()
+ * to the structure, for example:
+ * \code
+ * psa_aead_operation_t operation;
+ * operation = psa_aead_operation_init();
+ * \endcode
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure.
+ * Implementation details can change in future versions without notice. */
+typedef struct psa_aead_operation_s psa_aead_operation_t;
+
+/** \def PSA_AEAD_OPERATION_INIT
+ *
+ * This macro returns a suitable initializer for an AEAD operation object of
+ * type #psa_aead_operation_t.
+ */
+
+/** Return an initial value for an AEAD operation object.
+ */
+static psa_aead_operation_t psa_aead_operation_init(void);
+
+/** Set the key for a multipart authenticated encryption operation.
+ *
+ * The sequence of operations to encrypt a message with authentication
+ * is as follows:
+ * -# Allocate an operation object which will be passed to all the functions
+ * listed here.
+ * -# Initialize the operation object with one of the methods described in the
+ * documentation for #psa_aead_operation_t, e.g.
+ * #PSA_AEAD_OPERATION_INIT.
+ * -# Call psa_aead_encrypt_setup() to specify the algorithm and key.
+ * -# If needed, call psa_aead_set_lengths() to specify the length of the
+ * inputs to the subsequent calls to psa_aead_update_ad() and
+ * psa_aead_update(). See the documentation of psa_aead_set_lengths()
+ * for details.
+ * -# Call either psa_aead_generate_nonce() or psa_aead_set_nonce() to
+ * generate or set the nonce. You should use
+ * psa_aead_generate_nonce() unless the protocol you are implementing
+ * requires a specific nonce value.
+ * -# Call psa_aead_update_ad() zero, one or more times, passing a fragment
+ * of the non-encrypted additional authenticated data each time.
+ * -# Call psa_aead_update() zero, one or more times, passing a fragment
+ * of the message to encrypt each time.
+ * -# Call psa_aead_finish().
+ *
+ * If an error occurs at any step after a call to psa_aead_encrypt_setup(),
+ * the operation will need to be reset by a call to psa_aead_abort(). The
+ * application may call psa_aead_abort() at any time after the operation
+ * has been initialized.
+ *
+ * After a successful call to psa_aead_encrypt_setup(), the application must
+ * eventually terminate the operation. The following events terminate an
+ * operation:
+ * - A successful call to psa_aead_finish().
+ * - A call to psa_aead_abort().
+ *
+ * \param[in,out] operation The operation object to set up. It must have
+ * been initialized as per the documentation for
+ * #psa_aead_operation_t and not yet in use.
+ * \param key Identifier of the key to use for the operation.
+ * It must remain valid until the operation
+ * terminates. It must allow the usage
+ * #PSA_KEY_USAGE_ENCRYPT.
+ * \param alg The AEAD algorithm to compute
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(\p alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be inactive), or
+ * the library has not been previously initialized by psa_crypto_init().
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not compatible with \p alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not an AEAD algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation,
+ mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg);
+
+/** Set the key for a multipart authenticated decryption operation.
+ *
+ * The sequence of operations to decrypt a message with authentication
+ * is as follows:
+ * -# Allocate an operation object which will be passed to all the functions
+ * listed here.
+ * -# Initialize the operation object with one of the methods described in the
+ * documentation for #psa_aead_operation_t, e.g.
+ * #PSA_AEAD_OPERATION_INIT.
+ * -# Call psa_aead_decrypt_setup() to specify the algorithm and key.
+ * -# If needed, call psa_aead_set_lengths() to specify the length of the
+ * inputs to the subsequent calls to psa_aead_update_ad() and
+ * psa_aead_update(). See the documentation of psa_aead_set_lengths()
+ * for details.
+ * -# Call psa_aead_set_nonce() with the nonce for the decryption.
+ * -# Call psa_aead_update_ad() zero, one or more times, passing a fragment
+ * of the non-encrypted additional authenticated data each time.
+ * -# Call psa_aead_update() zero, one or more times, passing a fragment
+ * of the ciphertext to decrypt each time.
+ * -# Call psa_aead_verify().
+ *
+ * If an error occurs at any step after a call to psa_aead_decrypt_setup(),
+ * the operation will need to be reset by a call to psa_aead_abort(). The
+ * application may call psa_aead_abort() at any time after the operation
+ * has been initialized.
+ *
+ * After a successful call to psa_aead_decrypt_setup(), the application must
+ * eventually terminate the operation. The following events terminate an
+ * operation:
+ * - A successful call to psa_aead_verify().
+ * - A call to psa_aead_abort().
+ *
+ * \param[in,out] operation The operation object to set up. It must have
+ * been initialized as per the documentation for
+ * #psa_aead_operation_t and not yet in use.
+ * \param key Identifier of the key to use for the operation.
+ * It must remain valid until the operation
+ * terminates. It must allow the usage
+ * #PSA_KEY_USAGE_DECRYPT.
+ * \param alg The AEAD algorithm to compute
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(\p alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not compatible with \p alg.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not supported or is not an AEAD algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be inactive), or the
+ * library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation,
+ mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg);
+
+/** Generate a random nonce for an authenticated encryption operation.
+ *
+ * This function generates a random nonce for the authenticated encryption
+ * operation with an appropriate size for the chosen algorithm, key type
+ * and key size.
+ *
+ * The application must call psa_aead_encrypt_setup() before
+ * calling this function.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_aead_abort().
+ *
+ * \param[in,out] operation Active AEAD operation.
+ * \param[out] nonce Buffer where the generated nonce is to be
+ * written.
+ * \param nonce_size Size of the \p nonce buffer in bytes.
+ * \param[out] nonce_length On success, the number of bytes of the
+ * generated nonce.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p nonce buffer is too small.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be an active aead encrypt
+ * operation, with no nonce set), or the library has not been
+ * previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation,
+ uint8_t *nonce,
+ size_t nonce_size,
+ size_t *nonce_length);
+
+/** Set the nonce for an authenticated encryption or decryption operation.
+ *
+ * This function sets the nonce for the authenticated
+ * encryption or decryption operation.
+ *
+ * The application must call psa_aead_encrypt_setup() or
+ * psa_aead_decrypt_setup() before calling this function.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_aead_abort().
+ *
+ * \note When encrypting, applications should use psa_aead_generate_nonce()
+ * instead of this function, unless implementing a protocol that requires
+ * a non-random IV.
+ *
+ * \param[in,out] operation Active AEAD operation.
+ * \param[in] nonce Buffer containing the nonce to use.
+ * \param nonce_length Size of the nonce in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The size of \p nonce is not acceptable for the chosen algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active, with no nonce
+ * set), or the library has not been previously initialized
+ * by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation,
+ const uint8_t *nonce,
+ size_t nonce_length);
+
+/** Declare the lengths of the message and additional data for AEAD.
+ *
+ * The application must call this function before calling
+ * psa_aead_update_ad() or psa_aead_update() if the algorithm for
+ * the operation requires it. If the algorithm does not require it,
+ * calling this function is optional, but if this function is called
+ * then the implementation must enforce the lengths.
+ *
+ * You may call this function before or after setting the nonce with
+ * psa_aead_set_nonce() or psa_aead_generate_nonce().
+ *
+ * - For #PSA_ALG_CCM, calling this function is required.
+ * - For the other AEAD algorithms defined in this specification, calling
+ * this function is not required.
+ * - For vendor-defined algorithm, refer to the vendor documentation.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_aead_abort().
+ *
+ * \param[in,out] operation Active AEAD operation.
+ * \param ad_length Size of the non-encrypted additional
+ * authenticated data in bytes.
+ * \param plaintext_length Size of the plaintext to encrypt in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * At least one of the lengths is not acceptable for the chosen
+ * algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active, and
+ * psa_aead_update_ad() and psa_aead_update() must not have been
+ * called yet), or the library has not been previously initialized
+ * by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation,
+ size_t ad_length,
+ size_t plaintext_length);
+
+/** Pass additional data to an active AEAD operation.
+ *
+ * Additional data is authenticated, but not encrypted.
+ *
+ * You may call this function multiple times to pass successive fragments
+ * of the additional data. You may not call this function after passing
+ * data to encrypt or decrypt with psa_aead_update().
+ *
+ * Before calling this function, you must:
+ * 1. Call either psa_aead_encrypt_setup() or psa_aead_decrypt_setup().
+ * 2. Set the nonce with psa_aead_generate_nonce() or psa_aead_set_nonce().
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_aead_abort().
+ *
+ * \warning When decrypting, until psa_aead_verify() has returned #PSA_SUCCESS,
+ * there is no guarantee that the input is valid. Therefore, until
+ * you have called psa_aead_verify() and it has returned #PSA_SUCCESS,
+ * treat the input as untrusted and prepare to undo any action that
+ * depends on the input if psa_aead_verify() returns an error status.
+ *
+ * \param[in,out] operation Active AEAD operation.
+ * \param[in] input Buffer containing the fragment of
+ * additional data.
+ * \param input_length Size of the \p input buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The total input length overflows the additional data length that
+ * was previously specified with psa_aead_set_lengths().
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active, have a nonce
+ * set, have lengths set if required by the algorithm, and
+ * psa_aead_update() must not have been called yet), or the library
+ * has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length);
+
+/** Encrypt or decrypt a message fragment in an active AEAD operation.
+ *
+ * Before calling this function, you must:
+ * 1. Call either psa_aead_encrypt_setup() or psa_aead_decrypt_setup().
+ * The choice of setup function determines whether this function
+ * encrypts or decrypts its input.
+ * 2. Set the nonce with psa_aead_generate_nonce() or psa_aead_set_nonce().
+ * 3. Call psa_aead_update_ad() to pass all the additional data.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_aead_abort().
+ *
+ * \warning When decrypting, until psa_aead_verify() has returned #PSA_SUCCESS,
+ * there is no guarantee that the input is valid. Therefore, until
+ * you have called psa_aead_verify() and it has returned #PSA_SUCCESS:
+ * - Do not use the output in any way other than storing it in a
+ * confidential location. If you take any action that depends
+ * on the tentative decrypted data, this action will need to be
+ * undone if the input turns out not to be valid. Furthermore,
+ * if an adversary can observe that this action took place
+ * (for example through timing), they may be able to use this
+ * fact as an oracle to decrypt any message encrypted with the
+ * same key.
+ * - In particular, do not copy the output anywhere but to a
+ * memory or storage space that you have exclusive access to.
+ *
+ * This function does not require the input to be aligned to any
+ * particular block boundary. If the implementation can only process
+ * a whole block at a time, it must consume all the input provided, but
+ * it may delay the end of the corresponding output until a subsequent
+ * call to psa_aead_update(), psa_aead_finish() or psa_aead_verify()
+ * provides sufficient input. The amount of data that can be delayed
+ * in this way is bounded by #PSA_AEAD_UPDATE_OUTPUT_SIZE.
+ *
+ * \param[in,out] operation Active AEAD operation.
+ * \param[in] input Buffer containing the message fragment to
+ * encrypt or decrypt.
+ * \param input_length Size of the \p input buffer in bytes.
+ * \param[out] output Buffer where the output is to be written.
+ * \param output_size Size of the \p output buffer in bytes.
+ * This must be appropriate for the selected
+ * algorithm and key:
+ * - A sufficient output size is
+ * #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type,
+ * \c alg, \p input_length) where
+ * \c key_type is the type of key and \c alg is
+ * the algorithm that were used to set up the
+ * operation.
+ * - #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p
+ * input_length) evaluates to the maximum
+ * output size of any supported AEAD
+ * algorithm.
+ * \param[out] output_length On success, the number of bytes
+ * that make up the returned output.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p output buffer is too small.
+ * #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type, \c alg, \p input_length) or
+ * #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p input_length) can be used to
+ * determine the required buffer size.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The total length of input to psa_aead_update_ad() so far is
+ * less than the additional data length that was previously
+ * specified with psa_aead_set_lengths(), or
+ * the total input length overflows the plaintext length that
+ * was previously specified with psa_aead_set_lengths().
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active, have a nonce
+ * set, and have lengths set if required by the algorithm), or the
+ * library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t 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);
+
+/** Finish encrypting a message in an AEAD operation.
+ *
+ * The operation must have been set up with psa_aead_encrypt_setup().
+ *
+ * This function finishes the authentication of the additional data
+ * formed by concatenating the inputs passed to preceding calls to
+ * psa_aead_update_ad() with the plaintext formed by concatenating the
+ * inputs passed to preceding calls to psa_aead_update().
+ *
+ * This function has two output buffers:
+ * - \p ciphertext contains trailing ciphertext that was buffered from
+ * preceding calls to psa_aead_update().
+ * - \p tag contains the authentication tag.
+ *
+ * When this function returns successfully, the operation becomes inactive.
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_aead_abort().
+ *
+ * \param[in,out] operation Active AEAD operation.
+ * \param[out] ciphertext Buffer where the last part of the ciphertext
+ * is to be written.
+ * \param ciphertext_size Size of the \p ciphertext buffer in bytes.
+ * This must be appropriate for the selected
+ * algorithm and key:
+ * - A sufficient output size is
+ * #PSA_AEAD_FINISH_OUTPUT_SIZE(\c key_type,
+ * \c alg) where \c key_type is the type of key
+ * and \c alg is the algorithm that were used to
+ * set up the operation.
+ * - #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE evaluates to
+ * the maximum output size of any supported AEAD
+ * algorithm.
+ * \param[out] ciphertext_length On success, the number of bytes of
+ * returned ciphertext.
+ * \param[out] tag Buffer where the authentication tag is
+ * to be written.
+ * \param tag_size Size of the \p tag buffer in bytes.
+ * This must be appropriate for the selected
+ * algorithm and key:
+ * - The exact tag size is #PSA_AEAD_TAG_LENGTH(\c
+ * key_type, \c key_bits, \c alg) where
+ * \c key_type and \c key_bits are the type and
+ * bit-size of the key, and \c alg is the
+ * algorithm that were used in the call to
+ * psa_aead_encrypt_setup().
+ * - #PSA_AEAD_TAG_MAX_SIZE evaluates to the
+ * maximum tag size of any supported AEAD
+ * algorithm.
+ * \param[out] tag_length On success, the number of bytes
+ * that make up the returned tag.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p ciphertext or \p tag buffer is too small.
+ * #PSA_AEAD_FINISH_OUTPUT_SIZE(\c key_type, \c alg) or
+ * #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE can be used to determine the
+ * required \p ciphertext buffer size. #PSA_AEAD_TAG_LENGTH(\c key_type,
+ * \c key_bits, \c alg) or #PSA_AEAD_TAG_MAX_SIZE can be used to
+ * determine the required \p tag buffer size.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The total length of input to psa_aead_update_ad() so far is
+ * less than the additional data length that was previously
+ * specified with psa_aead_set_lengths(), or
+ * the total length of input to psa_aead_update() so far is
+ * less than the plaintext length that was previously
+ * specified with psa_aead_set_lengths().
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be an active encryption
+ * operation with a nonce set), or the library has not been previously
+ * initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_aead_finish(psa_aead_operation_t *operation,
+ uint8_t *ciphertext,
+ size_t ciphertext_size,
+ size_t *ciphertext_length,
+ uint8_t *tag,
+ size_t tag_size,
+ size_t *tag_length);
+
+/** Finish authenticating and decrypting a message in an AEAD operation.
+ *
+ * The operation must have been set up with psa_aead_decrypt_setup().
+ *
+ * This function finishes the authenticated decryption of the message
+ * components:
+ *
+ * - The additional data consisting of the concatenation of the inputs
+ * passed to preceding calls to psa_aead_update_ad().
+ * - The ciphertext consisting of the concatenation of the inputs passed to
+ * preceding calls to psa_aead_update().
+ * - The tag passed to this function call.
+ *
+ * If the authentication tag is correct, this function outputs any remaining
+ * plaintext and reports success. If the authentication tag is not correct,
+ * this function returns #PSA_ERROR_INVALID_SIGNATURE.
+ *
+ * When this function returns successfully, the operation becomes inactive.
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_aead_abort().
+ *
+ * \note Implementations shall make the best effort to ensure that the
+ * comparison between the actual tag and the expected tag is performed
+ * in constant time.
+ *
+ * \param[in,out] operation Active AEAD operation.
+ * \param[out] plaintext Buffer where the last part of the plaintext
+ * is to be written. This is the remaining data
+ * from previous calls to psa_aead_update()
+ * that could not be processed until the end
+ * of the input.
+ * \param plaintext_size Size of the \p plaintext buffer in bytes.
+ * This must be appropriate for the selected algorithm and key:
+ * - A sufficient output size is
+ * #PSA_AEAD_VERIFY_OUTPUT_SIZE(\c key_type,
+ * \c alg) where \c key_type is the type of key
+ * and \c alg is the algorithm that were used to
+ * set up the operation.
+ * - #PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE evaluates to
+ * the maximum output size of any supported AEAD
+ * algorithm.
+ * \param[out] plaintext_length On success, the number of bytes of
+ * returned plaintext.
+ * \param[in] tag Buffer containing the authentication tag.
+ * \param tag_length Size of the \p tag buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ * The calculations were successful, but the authentication tag is
+ * not correct.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p plaintext buffer is too small.
+ * #PSA_AEAD_VERIFY_OUTPUT_SIZE(\c key_type, \c alg) or
+ * #PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE can be used to determine the
+ * required buffer size.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The total length of input to psa_aead_update_ad() so far is
+ * less than the additional data length that was previously
+ * specified with psa_aead_set_lengths(), or
+ * the total length of input to psa_aead_update() so far is
+ * less than the plaintext length that was previously
+ * specified with psa_aead_set_lengths().
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be an active decryption
+ * operation with a nonce set), or the library has not been previously
+ * initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_aead_verify(psa_aead_operation_t *operation,
+ uint8_t *plaintext,
+ size_t plaintext_size,
+ size_t *plaintext_length,
+ const uint8_t *tag,
+ size_t tag_length);
+
+/** Abort an AEAD operation.
+ *
+ * Aborting an operation frees all associated resources except for the
+ * \p operation structure itself. Once aborted, the operation object
+ * can be reused for another operation by calling
+ * psa_aead_encrypt_setup() or psa_aead_decrypt_setup() again.
+ *
+ * You may call this function any time after the operation object has
+ * been initialized as described in #psa_aead_operation_t.
+ *
+ * In particular, calling psa_aead_abort() after the operation has been
+ * terminated by a call to psa_aead_abort(), psa_aead_finish() or
+ * psa_aead_verify() is safe and has no effect.
+ *
+ * \param[in,out] operation Initialized AEAD operation.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_aead_abort(psa_aead_operation_t *operation);
+
+/**@}*/
+
+/** \defgroup asymmetric Asymmetric cryptography
+ * @{
+ */
+
+/**
+ * \brief Sign a message with a private key. For hash-and-sign algorithms,
+ * this includes the hashing step.
+ *
+ * \note To perform a multi-part hash-and-sign signature algorithm, first use
+ * a multi-part hash operation and then pass the resulting hash to
+ * psa_sign_hash(). PSA_ALG_GET_HASH(\p alg) can be used to determine the
+ * hash algorithm to use.
+ *
+ * \param[in] key Identifier of the key to use for the operation.
+ * It must be an asymmetric key pair. The key must
+ * allow the usage #PSA_KEY_USAGE_SIGN_MESSAGE.
+ * \param[in] alg An asymmetric signature algorithm (PSA_ALG_XXX
+ * value such that #PSA_ALG_IS_SIGN_MESSAGE(\p alg)
+ * is true), that is compatible with the type of
+ * \p key.
+ * \param[in] input The input message to sign.
+ * \param[in] input_length Size of the \p input buffer in bytes.
+ * \param[out] signature Buffer where the signature is to be written.
+ * \param[in] signature_size Size of the \p signature buffer in bytes. This
+ * must be appropriate for the selected
+ * algorithm and key:
+ * - The required signature size is
+ * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
+ * where \c key_type and \c key_bits are the type and
+ * bit-size respectively of key.
+ * - #PSA_SIGNATURE_MAX_SIZE evaluates to the
+ * maximum signature size of any supported
+ * signature algorithm.
+ * \param[out] signature_length On success, the number of bytes that make up
+ * the returned signature value.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * The key does not have the #PSA_KEY_USAGE_SIGN_MESSAGE flag,
+ * or it does not permit the requested algorithm.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p signature buffer is too small. You can
+ * determine a sufficient buffer size by calling
+ * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
+ * where \c key_type and \c key_bits are the type and bit-size
+ * respectively of \p key.
+ * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
+ * \retval #PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_sign_message(mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *signature,
+ size_t signature_size,
+ size_t *signature_length);
+
+/** \brief Verify the signature of a message with a public key, using
+ * a hash-and-sign verification algorithm.
+ *
+ * \note To perform a multi-part hash-and-sign signature verification
+ * algorithm, first use a multi-part hash operation to hash the message
+ * and then pass the resulting hash to psa_verify_hash().
+ * PSA_ALG_GET_HASH(\p alg) can be used to determine the hash algorithm
+ * to use.
+ *
+ * \param[in] key Identifier of the key to use for the operation.
+ * It must be a public key or an asymmetric key
+ * pair. The key must allow the usage
+ * #PSA_KEY_USAGE_VERIFY_MESSAGE.
+ * \param[in] alg An asymmetric signature algorithm (PSA_ALG_XXX
+ * value such that #PSA_ALG_IS_SIGN_MESSAGE(\p alg)
+ * is true), that is compatible with the type of
+ * \p key.
+ * \param[in] input The message whose signature is to be verified.
+ * \param[in] input_length Size of the \p input buffer in bytes.
+ * \param[out] signature Buffer containing the signature to verify.
+ * \param[in] signature_length Size of the \p signature buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * The key does not have the #PSA_KEY_USAGE_SIGN_MESSAGE flag,
+ * or it does not permit the requested algorithm.
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ * The calculation was performed successfully, but the passed signature
+ * is not a valid signature.
+ * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
+ * \retval #PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_verify_message(mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *signature,
+ size_t signature_length);
+
+/**
+ * \brief Sign a hash or short message with a private key.
+ *
+ * Note that to perform a hash-and-sign signature algorithm, you must
+ * first calculate the hash by calling psa_hash_setup(), psa_hash_update()
+ * and psa_hash_finish(), or alternatively by calling psa_hash_compute().
+ * Then pass the resulting hash as the \p hash
+ * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg)
+ * to determine the hash algorithm to use.
+ *
+ * \param key Identifier of the key to use for the operation.
+ * It must be an asymmetric key pair. The key must
+ * allow the usage #PSA_KEY_USAGE_SIGN_HASH.
+ * \param alg A signature algorithm (PSA_ALG_XXX
+ * value such that #PSA_ALG_IS_SIGN_HASH(\p alg)
+ * is true), that is compatible with
+ * the type of \p key.
+ * \param[in] hash The hash or message to sign.
+ * \param hash_length Size of the \p hash buffer in bytes.
+ * \param[out] signature Buffer where the signature is to be written.
+ * \param signature_size Size of the \p signature buffer in bytes.
+ * \param[out] signature_length On success, the number of bytes
+ * that make up the returned signature value.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p signature buffer is too small. You can
+ * determine a sufficient buffer size by calling
+ * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
+ * where \c key_type and \c key_bits are the type and bit-size
+ * respectively of \p key.
+ * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_sign_hash(mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *hash,
+ size_t hash_length,
+ uint8_t *signature,
+ size_t signature_size,
+ size_t *signature_length);
+
+/**
+ * \brief Verify the signature of a hash or short message using a public key.
+ *
+ * Note that to perform a hash-and-sign signature algorithm, you must
+ * first calculate the hash by calling psa_hash_setup(), psa_hash_update()
+ * and psa_hash_finish(), or alternatively by calling psa_hash_compute().
+ * Then pass the resulting hash as the \p hash
+ * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg)
+ * to determine the hash algorithm to use.
+ *
+ * \param key Identifier of the key to use for the operation. It
+ * must be a public key or an asymmetric key pair. The
+ * key must allow the usage
+ * #PSA_KEY_USAGE_VERIFY_HASH.
+ * \param alg A signature algorithm (PSA_ALG_XXX
+ * value such that #PSA_ALG_IS_SIGN_HASH(\p alg)
+ * is true), that is compatible with
+ * the type of \p key.
+ * \param[in] hash The hash or message whose signature is to be
+ * verified.
+ * \param hash_length Size of the \p hash buffer in bytes.
+ * \param[in] signature Buffer containing the signature to verify.
+ * \param signature_length Size of the \p signature buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * The signature is valid.
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ * The calculation was performed successfully, but the passed
+ * signature is not a valid signature.
+ * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_verify_hash(mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *hash,
+ size_t hash_length,
+ const uint8_t *signature,
+ size_t signature_length);
+
+/**
+ * \brief Encrypt a short message with a public key.
+ *
+ * \param key Identifier of the key to use for the operation.
+ * It must be a public key or an asymmetric key
+ * pair. It must allow the usage
+ * #PSA_KEY_USAGE_ENCRYPT.
+ * \param alg An asymmetric encryption algorithm that is
+ * compatible with the type of \p key.
+ * \param[in] input The message to encrypt.
+ * \param input_length Size of the \p input buffer in bytes.
+ * \param[in] salt A salt or label, if supported by the
+ * encryption algorithm.
+ * If the algorithm does not support a
+ * salt, pass \c NULL.
+ * If the algorithm supports an optional
+ * salt and you do not want to pass a salt,
+ * pass \c NULL.
+ *
+ * - For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
+ * supported.
+ * \param salt_length Size of the \p salt buffer in bytes.
+ * If \p salt is \c NULL, pass 0.
+ * \param[out] output Buffer where the encrypted message is to
+ * be written.
+ * \param output_size Size of the \p output buffer in bytes.
+ * \param[out] output_length On success, the number of bytes
+ * that make up the returned output.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p output buffer is too small. You can
+ * determine a sufficient buffer size by calling
+ * #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
+ * where \c key_type and \c key_bits are the type and bit-size
+ * respectively of \p key.
+ * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *salt,
+ size_t salt_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length);
+
+/**
+ * \brief Decrypt a short message with a private key.
+ *
+ * \param key Identifier of the key to use for the operation.
+ * It must be an asymmetric key pair. It must
+ * allow the usage #PSA_KEY_USAGE_DECRYPT.
+ * \param alg An asymmetric encryption algorithm that is
+ * compatible with the type of \p key.
+ * \param[in] input The message to decrypt.
+ * \param input_length Size of the \p input buffer in bytes.
+ * \param[in] salt A salt or label, if supported by the
+ * encryption algorithm.
+ * If the algorithm does not support a
+ * salt, pass \c NULL.
+ * If the algorithm supports an optional
+ * salt and you do not want to pass a salt,
+ * pass \c NULL.
+ *
+ * - For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
+ * supported.
+ * \param salt_length Size of the \p salt buffer in bytes.
+ * If \p salt is \c NULL, pass 0.
+ * \param[out] output Buffer where the decrypted message is to
+ * be written.
+ * \param output_size Size of the \c output buffer in bytes.
+ * \param[out] output_length On success, the number of bytes
+ * that make up the returned output.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p output buffer is too small. You can
+ * determine a sufficient buffer size by calling
+ * #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
+ * where \c key_type and \c key_bits are the type and bit-size
+ * respectively of \p key.
+ * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
+ * \retval #PSA_ERROR_INVALID_PADDING \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *salt,
+ size_t salt_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length);
+
+/**@}*/
+
+/** \defgroup key_derivation Key derivation and pseudorandom generation
+ * @{
+ */
+
+/** The type of the state data structure for key derivation operations.
+ *
+ * Before calling any function on a key derivation operation object, the
+ * application must initialize it by any of the following means:
+ * - Set the structure to all-bits-zero, for example:
+ * \code
+ * psa_key_derivation_operation_t operation;
+ * memset(&operation, 0, sizeof(operation));
+ * \endcode
+ * - Initialize the structure to logical zero values, for example:
+ * \code
+ * psa_key_derivation_operation_t operation = {0};
+ * \endcode
+ * - Initialize the structure to the initializer #PSA_KEY_DERIVATION_OPERATION_INIT,
+ * for example:
+ * \code
+ * psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
+ * \endcode
+ * - Assign the result of the function psa_key_derivation_operation_init()
+ * to the structure, for example:
+ * \code
+ * psa_key_derivation_operation_t operation;
+ * operation = psa_key_derivation_operation_init();
+ * \endcode
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure.
+ * Implementation details can change in future versions without notice.
+ */
+typedef struct psa_key_derivation_s psa_key_derivation_operation_t;
+
+/** \def PSA_KEY_DERIVATION_OPERATION_INIT
+ *
+ * This macro returns a suitable initializer for a key derivation operation
+ * object of type #psa_key_derivation_operation_t.
+ */
+
+/** Return an initial value for a key derivation operation object.
+ */
+static psa_key_derivation_operation_t psa_key_derivation_operation_init(void);
+
+/** Set up a key derivation operation.
+ *
+ * A key derivation algorithm takes some inputs and uses them to generate
+ * a byte stream in a deterministic way.
+ * This byte stream can be used to produce keys and other
+ * cryptographic material.
+ *
+ * To derive a key:
+ * -# Start with an initialized object of type #psa_key_derivation_operation_t.
+ * -# Call psa_key_derivation_setup() to select the algorithm.
+ * -# Provide the inputs for the key derivation by calling
+ * psa_key_derivation_input_bytes() or psa_key_derivation_input_key()
+ * as appropriate. Which inputs are needed, in what order, and whether
+ * they may be keys and if so of what type depends on the algorithm.
+ * -# Optionally set the operation's maximum capacity with
+ * psa_key_derivation_set_capacity(). You may do this before, in the middle
+ * of or after providing inputs. For some algorithms, this step is mandatory
+ * because the output depends on the maximum capacity.
+ * -# To derive a key, call psa_key_derivation_output_key().
+ * To derive a byte string for a different purpose, call
+ * psa_key_derivation_output_bytes().
+ * Successive calls to these functions use successive output bytes
+ * calculated by the key derivation algorithm.
+ * -# Clean up the key derivation operation object with
+ * psa_key_derivation_abort().
+ *
+ * If this function returns an error, the key derivation operation object is
+ * not changed.
+ *
+ * If an error occurs at any step after a call to psa_key_derivation_setup(),
+ * the operation will need to be reset by a call to psa_key_derivation_abort().
+ *
+ * Implementations must reject an attempt to derive a key of size 0.
+ *
+ * \param[in,out] operation The key derivation operation object
+ * to set up. It must
+ * have been initialized but not set up yet.
+ * \param alg The key derivation algorithm to compute
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_KEY_DERIVATION(\p alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \c alg is not a key derivation algorithm.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \c alg is not supported or is not a key derivation algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be inactive), or
+ * the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_key_derivation_setup(
+ psa_key_derivation_operation_t *operation,
+ psa_algorithm_t alg);
+
+/** Retrieve the current capacity of a key derivation operation.
+ *
+ * The capacity of a key derivation is the maximum number of bytes that it can
+ * return. When you get *N* bytes of output from a key derivation operation,
+ * this reduces its capacity by *N*.
+ *
+ * \param[in] operation The operation to query.
+ * \param[out] capacity On success, the capacity of the operation.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active), or
+ * the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_key_derivation_get_capacity(
+ const psa_key_derivation_operation_t *operation,
+ size_t *capacity);
+
+/** Set the maximum capacity of a key derivation operation.
+ *
+ * The capacity of a key derivation operation is the maximum number of bytes
+ * that the key derivation operation can return from this point onwards.
+ *
+ * \param[in,out] operation The key derivation operation object to modify.
+ * \param capacity The new capacity of the operation.
+ * It must be less or equal to the operation's
+ * current capacity.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p capacity is larger than the operation's current capacity.
+ * In this case, the operation object remains valid and its capacity
+ * remains unchanged.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active), or the
+ * library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_key_derivation_set_capacity(
+ psa_key_derivation_operation_t *operation,
+ size_t capacity);
+
+/** Use the maximum possible capacity for a key derivation operation.
+ *
+ * Use this value as the capacity argument when setting up a key derivation
+ * to indicate that the operation should have the maximum possible capacity.
+ * The value of the maximum possible capacity depends on the key derivation
+ * algorithm.
+ */
+#define PSA_KEY_DERIVATION_UNLIMITED_CAPACITY ((size_t) (-1))
+
+/** Provide an input for key derivation or key agreement.
+ *
+ * Which inputs are required and in what order depends on the algorithm.
+ * Refer to the documentation of each key derivation or key agreement
+ * algorithm for information.
+ *
+ * This function passes direct inputs, which is usually correct for
+ * non-secret inputs. To pass a secret input, which should be in a key
+ * object, call psa_key_derivation_input_key() instead of this function.
+ * Refer to the documentation of individual step types
+ * (`PSA_KEY_DERIVATION_INPUT_xxx` values of type ::psa_key_derivation_step_t)
+ * for more information.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_key_derivation_abort().
+ *
+ * \param[in,out] operation The key derivation operation object to use.
+ * It must have been set up with
+ * psa_key_derivation_setup() and must not
+ * have produced any output yet.
+ * \param step Which step the input data is for.
+ * \param[in] data Input data to use.
+ * \param data_length Size of the \p data buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \c step is not compatible with the operation's algorithm, or
+ * \c step does not allow direct inputs.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid for this input \p step, or
+ * the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_key_derivation_input_bytes(
+ psa_key_derivation_operation_t *operation,
+ psa_key_derivation_step_t step,
+ const uint8_t *data,
+ size_t data_length);
+
+/** Provide a numeric input for key derivation or key agreement.
+ *
+ * Which inputs are required and in what order depends on the algorithm.
+ * However, when an algorithm requires a particular order, numeric inputs
+ * usually come first as they tend to be configuration parameters.
+ * Refer to the documentation of each key derivation or key agreement
+ * algorithm for information.
+ *
+ * This function is used for inputs which are fixed-size non-negative
+ * integers.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_key_derivation_abort().
+ *
+ * \param[in,out] operation The key derivation operation object to use.
+ * It must have been set up with
+ * psa_key_derivation_setup() and must not
+ * have produced any output yet.
+ * \param step Which step the input data is for.
+ * \param[in] value The value of the numeric input.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \c step is not compatible with the operation's algorithm, or
+ * \c step does not allow numeric inputs.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid for this input \p step, or
+ * the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_key_derivation_input_integer(
+ psa_key_derivation_operation_t *operation,
+ psa_key_derivation_step_t step,
+ uint64_t value);
+
+/** Provide an input for key derivation in the form of a key.
+ *
+ * Which inputs are required and in what order depends on the algorithm.
+ * Refer to the documentation of each key derivation or key agreement
+ * algorithm for information.
+ *
+ * This function obtains input from a key object, which is usually correct for
+ * secret inputs or for non-secret personalization strings kept in the key
+ * store. To pass a non-secret parameter which is not in the key store,
+ * call psa_key_derivation_input_bytes() instead of this function.
+ * Refer to the documentation of individual step types
+ * (`PSA_KEY_DERIVATION_INPUT_xxx` values of type ::psa_key_derivation_step_t)
+ * for more information.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_key_derivation_abort().
+ *
+ * \param[in,out] operation The key derivation operation object to use.
+ * It must have been set up with
+ * psa_key_derivation_setup() and must not
+ * have produced any output yet.
+ * \param step Which step the input data is for.
+ * \param key Identifier of the key. It must have an
+ * appropriate type for step and must allow the
+ * usage #PSA_KEY_USAGE_DERIVE or
+ * #PSA_KEY_USAGE_VERIFY_DERIVATION (see note)
+ * and the algorithm used by the operation.
+ *
+ * \note Once all inputs steps are completed, the operations will allow:
+ * - psa_key_derivation_output_bytes() if each input was either a direct input
+ * or a key with #PSA_KEY_USAGE_DERIVE set;
+ * - psa_key_derivation_output_key() if the input for step
+ * #PSA_KEY_DERIVATION_INPUT_SECRET or #PSA_KEY_DERIVATION_INPUT_PASSWORD
+ * was from a key slot with #PSA_KEY_USAGE_DERIVE and each other input was
+ * either a direct input or a key with #PSA_KEY_USAGE_DERIVE set;
+ * - psa_key_derivation_verify_bytes() if each input was either a direct input
+ * or a key with #PSA_KEY_USAGE_VERIFY_DERIVATION set;
+ * - psa_key_derivation_verify_key() under the same conditions as
+ * psa_key_derivation_verify_bytes().
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * The key allows neither #PSA_KEY_USAGE_DERIVE nor
+ * #PSA_KEY_USAGE_VERIFY_DERIVATION, or it doesn't allow this
+ * algorithm.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \c step is not compatible with the operation's algorithm, or
+ * \c step does not allow key inputs of the given type
+ * or does not allow key inputs at all.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid for this input \p step, or
+ * the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_key_derivation_input_key(
+ psa_key_derivation_operation_t *operation,
+ psa_key_derivation_step_t step,
+ mbedtls_svc_key_id_t key);
+
+/** Perform a key agreement and use the shared secret as input to a key
+ * derivation.
+ *
+ * A key agreement algorithm takes two inputs: a private key \p private_key
+ * a public key \p peer_key.
+ * The result of this function is passed as input to a key derivation.
+ * The output of this key derivation can be extracted by reading from the
+ * resulting operation to produce keys and other cryptographic material.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_key_derivation_abort().
+ *
+ * \param[in,out] operation The key derivation operation object to use.
+ * It must have been set up with
+ * psa_key_derivation_setup() with a
+ * key agreement and derivation algorithm
+ * \c alg (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_KEY_AGREEMENT(\c alg) is true
+ * and #PSA_ALG_IS_RAW_KEY_AGREEMENT(\c alg)
+ * is false).
+ * The operation must be ready for an
+ * input of the type given by \p step.
+ * \param step Which step the input data is for.
+ * \param private_key Identifier of the private key to use. It must
+ * allow the usage #PSA_KEY_USAGE_DERIVE.
+ * \param[in] peer_key Public key of the peer. The peer key must be in the
+ * same format that psa_import_key() accepts for the
+ * public key type corresponding to the type of
+ * private_key. That is, this function performs the
+ * equivalent of
+ * #psa_import_key(...,
+ * `peer_key`, `peer_key_length`) where
+ * with key attributes indicating the public key
+ * type corresponding to the type of `private_key`.
+ * For example, for EC keys, this means that peer_key
+ * is interpreted as a point on the curve that the
+ * private key is on. The standard formats for public
+ * keys are documented in the documentation of
+ * psa_export_public_key().
+ * \param peer_key_length Size of \p peer_key in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \c private_key is not compatible with \c alg,
+ * or \p peer_key is not valid for \c alg or not compatible with
+ * \c private_key, or \c step does not allow an input resulting
+ * from a key agreement.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \c alg is not supported or is not a key derivation algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid for this key agreement \p step,
+ * or the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_key_derivation_key_agreement(
+ psa_key_derivation_operation_t *operation,
+ psa_key_derivation_step_t step,
+ mbedtls_svc_key_id_t private_key,
+ const uint8_t *peer_key,
+ size_t peer_key_length);
+
+/** Read some data from a key derivation operation.
+ *
+ * This function calculates output bytes from a key derivation algorithm and
+ * return those bytes.
+ * If you view the key derivation's output as a stream of bytes, this
+ * function destructively reads the requested number of bytes from the
+ * stream.
+ * The operation's capacity decreases by the number of bytes read.
+ *
+ * If this function returns an error status other than
+ * #PSA_ERROR_INSUFFICIENT_DATA, the operation enters an error
+ * state and must be aborted by calling psa_key_derivation_abort().
+ *
+ * \param[in,out] operation The key derivation operation object to read from.
+ * \param[out] output Buffer where the output will be written.
+ * \param output_length Number of bytes to output.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * One of the inputs was a key whose policy didn't allow
+ * #PSA_KEY_USAGE_DERIVE.
+ * \retval #PSA_ERROR_INSUFFICIENT_DATA
+ * The operation's capacity was less than
+ * \p output_length bytes. Note that in this case,
+ * no output is written to the output buffer.
+ * The operation's capacity is set to 0, thus
+ * subsequent calls to this function will not
+ * succeed, even with a smaller output buffer.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active and completed
+ * all required input steps), or the library has not been previously
+ * initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_key_derivation_output_bytes(
+ psa_key_derivation_operation_t *operation,
+ uint8_t *output,
+ size_t output_length);
+
+/** Derive a key from an ongoing key derivation operation.
+ *
+ * This function calculates output bytes from a key derivation algorithm
+ * and uses those bytes to generate a key deterministically.
+ * The key's location, usage policy, type and size are taken from
+ * \p attributes.
+ *
+ * If you view the key derivation's output as a stream of bytes, this
+ * function destructively reads as many bytes as required from the
+ * stream.
+ * The operation's capacity decreases by the number of bytes read.
+ *
+ * If this function returns an error status other than
+ * #PSA_ERROR_INSUFFICIENT_DATA, the operation enters an error
+ * state and must be aborted by calling psa_key_derivation_abort().
+ *
+ * How much output is produced and consumed from the operation, and how
+ * the key is derived, depends on the key type and on the key size
+ * (denoted \c bits below):
+ *
+ * - For key types for which the key is an arbitrary sequence of bytes
+ * of a given size, this function is functionally equivalent to
+ * calling #psa_key_derivation_output_bytes
+ * and passing the resulting output to #psa_import_key.
+ * However, this function has a security benefit:
+ * if the implementation provides an isolation boundary then
+ * the key material is not exposed outside the isolation boundary.
+ * As a consequence, for these key types, this function always consumes
+ * exactly (\c bits / 8) bytes from the operation.
+ * The following key types defined in this specification follow this scheme:
+ *
+ * - #PSA_KEY_TYPE_AES;
+ * - #PSA_KEY_TYPE_ARIA;
+ * - #PSA_KEY_TYPE_CAMELLIA;
+ * - #PSA_KEY_TYPE_DERIVE;
+ * - #PSA_KEY_TYPE_HMAC;
+ * - #PSA_KEY_TYPE_PASSWORD_HASH.
+ *
+ * - For ECC keys on a Montgomery elliptic curve
+ * (#PSA_KEY_TYPE_ECC_KEY_PAIR(\c curve) where \c curve designates a
+ * Montgomery curve), this function always draws a byte string whose
+ * length is determined by the curve, and sets the mandatory bits
+ * accordingly. That is:
+ *
+ * - Curve25519 (#PSA_ECC_FAMILY_MONTGOMERY, 255 bits): draw a 32-byte
+ * string and process it as specified in RFC 7748 &sect;5.
+ * - Curve448 (#PSA_ECC_FAMILY_MONTGOMERY, 448 bits): draw a 56-byte
+ * string and process it as specified in RFC 7748 &sect;5.
+ *
+ * - For key types for which the key is represented by a single sequence of
+ * \c bits bits with constraints as to which bit sequences are acceptable,
+ * this function draws a byte string of length (\c bits / 8) bytes rounded
+ * up to the nearest whole number of bytes. If the resulting byte string
+ * is acceptable, it becomes the key, otherwise the drawn bytes are discarded.
+ * This process is repeated until an acceptable byte string is drawn.
+ * The byte string drawn from the operation is interpreted as specified
+ * for the output produced by psa_export_key().
+ * The following key types defined in this specification follow this scheme:
+ *
+ * - #PSA_KEY_TYPE_DES.
+ * Force-set the parity bits, but discard forbidden weak keys.
+ * For 2-key and 3-key triple-DES, the three keys are generated
+ * successively (for example, for 3-key triple-DES,
+ * if the first 8 bytes specify a weak key and the next 8 bytes do not,
+ * discard the first 8 bytes, use the next 8 bytes as the first key,
+ * and continue reading output from the operation to derive the other
+ * two keys).
+ * - Finite-field Diffie-Hellman keys (#PSA_KEY_TYPE_DH_KEY_PAIR(\c group)
+ * where \c group designates any Diffie-Hellman group) and
+ * ECC keys on a Weierstrass elliptic curve
+ * (#PSA_KEY_TYPE_ECC_KEY_PAIR(\c curve) where \c curve designates a
+ * Weierstrass curve).
+ * For these key types, interpret the byte string as integer
+ * in big-endian order. Discard it if it is not in the range
+ * [0, *N* - 2] where *N* is the boundary of the private key domain
+ * (the prime *p* for Diffie-Hellman, the subprime *q* for DSA,
+ * or the order of the curve's base point for ECC).
+ * Add 1 to the resulting integer and use this as the private key *x*.
+ * This method allows compliance to NIST standards, specifically
+ * the methods titled "key-pair generation by testing candidates"
+ * in NIST SP 800-56A &sect;5.6.1.1.4 for Diffie-Hellman,
+ * in FIPS 186-4 &sect;B.1.2 for DSA, and
+ * in NIST SP 800-56A &sect;5.6.1.2.2 or
+ * FIPS 186-4 &sect;B.4.2 for elliptic curve keys.
+ *
+ * - For other key types, including #PSA_KEY_TYPE_RSA_KEY_PAIR,
+ * the way in which the operation output is consumed is
+ * implementation-defined.
+ *
+ * In all cases, the data that is read is discarded from the operation.
+ * The operation's capacity is decreased by the number of bytes read.
+ *
+ * For algorithms that take an input step #PSA_KEY_DERIVATION_INPUT_SECRET,
+ * the input to that step must be provided with psa_key_derivation_input_key().
+ * Future versions of this specification may include additional restrictions
+ * on the derived key based on the attributes and strength of the secret key.
+ *
+ * \param[in] attributes The attributes for the new key.
+ * If the key type to be created is
+ * #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in
+ * the policy must be the same as in the current
+ * operation.
+ * \param[in,out] operation The key derivation operation object to read from.
+ * \param[out] key On success, an identifier for the newly created
+ * key. For persistent keys, this is the key
+ * identifier defined in \p attributes.
+ * \c 0 on failure.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * If the key is persistent, the key material and the key's metadata
+ * have been saved to persistent storage.
+ * \retval #PSA_ERROR_ALREADY_EXISTS
+ * This is an attempt to create a persistent key, and there is
+ * already a persistent key with the given identifier.
+ * \retval #PSA_ERROR_INSUFFICIENT_DATA
+ * There was not enough data to create the desired key.
+ * Note that in this case, no output is written to the output buffer.
+ * The operation's capacity is set to 0, thus subsequent calls to
+ * this function will not succeed, even with a smaller output buffer.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * The key type or key size is not supported, either by the
+ * implementation in general or in this particular location.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The provided key attributes are not valid for the operation.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * The #PSA_KEY_DERIVATION_INPUT_SECRET or
+ * #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a
+ * key; or one of the inputs was a key whose policy didn't allow
+ * #PSA_KEY_USAGE_DERIVE.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active and completed
+ * all required input steps), or the library has not been previously
+ * initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_key_derivation_output_key(
+ const psa_key_attributes_t *attributes,
+ psa_key_derivation_operation_t *operation,
+ mbedtls_svc_key_id_t *key);
+
+/** Compare output data from a key derivation operation to an expected value.
+ *
+ * This function calculates output bytes from a key derivation algorithm and
+ * compares those bytes to an expected value in constant time.
+ * If you view the key derivation's output as a stream of bytes, this
+ * function destructively reads the expected number of bytes from the
+ * stream before comparing them.
+ * The operation's capacity decreases by the number of bytes read.
+ *
+ * This is functionally equivalent to the following code:
+ * \code
+ * psa_key_derivation_output_bytes(operation, tmp, output_length);
+ * if (memcmp(output, tmp, output_length) != 0)
+ * return PSA_ERROR_INVALID_SIGNATURE;
+ * \endcode
+ * except (1) it works even if the key's policy does not allow outputting the
+ * bytes, and (2) the comparison will be done in constant time.
+ *
+ * If this function returns an error status other than
+ * #PSA_ERROR_INSUFFICIENT_DATA or #PSA_ERROR_INVALID_SIGNATURE,
+ * the operation enters an error state and must be aborted by calling
+ * psa_key_derivation_abort().
+ *
+ * \param[in,out] operation The key derivation operation object to read from.
+ * \param[in] expected_output Buffer containing the expected derivation output.
+ * \param output_length Length of the expected output; this is also the
+ * number of bytes that will be read.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ * The output was read successfully, but it differs from the expected
+ * output.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * One of the inputs was a key whose policy didn't allow
+ * #PSA_KEY_USAGE_VERIFY_DERIVATION.
+ * \retval #PSA_ERROR_INSUFFICIENT_DATA
+ * The operation's capacity was less than
+ * \p output_length bytes. Note that in this case,
+ * the operation's capacity is set to 0, thus
+ * subsequent calls to this function will not
+ * succeed, even with a smaller expected output.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active and completed
+ * all required input steps), or the library has not been previously
+ * initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_key_derivation_verify_bytes(
+ psa_key_derivation_operation_t *operation,
+ const uint8_t *expected_output,
+ size_t output_length);
+
+/** Compare output data from a key derivation operation to an expected value
+ * stored in a key object.
+ *
+ * This function calculates output bytes from a key derivation algorithm and
+ * compares those bytes to an expected value, provided as key of type
+ * #PSA_KEY_TYPE_PASSWORD_HASH.
+ * If you view the key derivation's output as a stream of bytes, this
+ * function destructively reads the number of bytes corresponding to the
+ * length of the expected value from the stream before comparing them.
+ * The operation's capacity decreases by the number of bytes read.
+ *
+ * This is functionally equivalent to exporting the key and calling
+ * psa_key_derivation_verify_bytes() on the result, except that it
+ * works even if the key cannot be exported.
+ *
+ * If this function returns an error status other than
+ * #PSA_ERROR_INSUFFICIENT_DATA or #PSA_ERROR_INVALID_SIGNATURE,
+ * the operation enters an error state and must be aborted by calling
+ * psa_key_derivation_abort().
+ *
+ * \param[in,out] operation The key derivation operation object to read from.
+ * \param[in] expected A key of type #PSA_KEY_TYPE_PASSWORD_HASH
+ * containing the expected output. Its policy must
+ * include the #PSA_KEY_USAGE_VERIFY_DERIVATION flag
+ * and the permitted algorithm must match the
+ * operation. The value of this key was likely
+ * computed by a previous call to
+ * psa_key_derivation_output_key().
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ * The output was read successfully, but if differs from the expected
+ * output.
+ * \retval #PSA_ERROR_INVALID_HANDLE
+ * The key passed as the expected value does not exist.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The key passed as the expected value has an invalid type.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * The key passed as the expected value does not allow this usage or
+ * this algorithm; or one of the inputs was a key whose policy didn't
+ * allow #PSA_KEY_USAGE_VERIFY_DERIVATION.
+ * \retval #PSA_ERROR_INSUFFICIENT_DATA
+ * The operation's capacity was less than
+ * the length of the expected value. In this case,
+ * the operation's capacity is set to 0, thus
+ * subsequent calls to this function will not
+ * succeed, even with a smaller expected output.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active and completed
+ * all required input steps), or the library has not been previously
+ * initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_key_derivation_verify_key(
+ psa_key_derivation_operation_t *operation,
+ mbedtls_svc_key_id_t expected);
+
+/** Abort a key derivation operation.
+ *
+ * Aborting an operation frees all associated resources except for the \c
+ * operation structure itself. Once aborted, the operation object can be reused
+ * for another operation by calling psa_key_derivation_setup() again.
+ *
+ * This function may be called at any time after the operation
+ * object has been initialized as described in #psa_key_derivation_operation_t.
+ *
+ * In particular, it is valid to call psa_key_derivation_abort() twice, or to
+ * call psa_key_derivation_abort() on an operation that has not been set up.
+ *
+ * \param[in,out] operation The operation to abort.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_key_derivation_abort(
+ psa_key_derivation_operation_t *operation);
+
+/** Perform a key agreement and return the raw shared secret.
+ *
+ * \warning The raw result of a key agreement algorithm such as finite-field
+ * Diffie-Hellman or elliptic curve Diffie-Hellman has biases and should
+ * not be used directly as key material. It should instead be passed as
+ * input to a key derivation algorithm. To chain a key agreement with
+ * a key derivation, use psa_key_derivation_key_agreement() and other
+ * functions from the key derivation interface.
+ *
+ * \param alg The key agreement algorithm to compute
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_RAW_KEY_AGREEMENT(\p alg)
+ * is true).
+ * \param private_key Identifier of the private key to use. It must
+ * allow the usage #PSA_KEY_USAGE_DERIVE.
+ * \param[in] peer_key Public key of the peer. It must be
+ * in the same format that psa_import_key()
+ * accepts. The standard formats for public
+ * keys are documented in the documentation
+ * of psa_export_public_key().
+ * \param peer_key_length Size of \p peer_key in bytes.
+ * \param[out] output Buffer where the decrypted message is to
+ * be written.
+ * \param output_size Size of the \c output buffer in bytes.
+ * \param[out] output_length On success, the number of bytes
+ * that make up the returned output.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p alg is not a key agreement algorithm, or
+ * \p private_key is not compatible with \p alg,
+ * or \p peer_key is not valid for \p alg or not compatible with
+ * \p private_key.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * \p output_size is too small
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p alg is not a supported key agreement algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,
+ mbedtls_svc_key_id_t private_key,
+ const uint8_t *peer_key,
+ size_t peer_key_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length);
+
+/**@}*/
+
+/** \defgroup random Random generation
+ * @{
+ */
+
+/**
+ * \brief Generate random bytes.
+ *
+ * \warning This function **can** fail! Callers MUST check the return status
+ * and MUST NOT use the content of the output buffer if the return
+ * status is not #PSA_SUCCESS.
+ *
+ * \note To generate a key, use psa_generate_key() instead.
+ *
+ * \param[out] output Output buffer for the generated data.
+ * \param output_size Number of bytes to generate and output.
+ *
+ * \retval #PSA_SUCCESS \emptydescription
+ * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_generate_random(uint8_t *output,
+ size_t output_size);
+
+/**
+ * \brief Generate a key or key pair.
+ *
+ * The key is generated randomly.
+ * Its location, usage policy, type and size are taken from \p attributes.
+ *
+ * Implementations must reject an attempt to generate a key of size 0.
+ *
+ * The following type-specific considerations apply:
+ * - For RSA keys (#PSA_KEY_TYPE_RSA_KEY_PAIR),
+ * the public exponent is 65537.
+ * The modulus is a product of two probabilistic primes
+ * between 2^{n-1} and 2^n where n is the bit size specified in the
+ * attributes.
+ *
+ * \param[in] attributes The attributes for the new key.
+ * \param[out] key On success, an identifier for the newly created
+ * key. For persistent keys, this is the key
+ * identifier defined in \p attributes.
+ * \c 0 on failure.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * If the key is persistent, the key material and the key's metadata
+ * have been saved to persistent storage.
+ * \retval #PSA_ERROR_ALREADY_EXISTS
+ * This is an attempt to create a persistent key, and there is
+ * already a persistent key with the given identifier.
+ * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
+ * \retval #PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
+ mbedtls_svc_key_id_t *key);
+
+/**@}*/
+
+/** \defgroup interruptible_hash Interruptible sign/verify hash
+ * @{
+ */
+
+/** The type of the state data structure for interruptible hash
+ * signing operations.
+ *
+ * Before calling any function on a sign hash operation object, the
+ * application must initialize it by any of the following means:
+ * - Set the structure to all-bits-zero, for example:
+ * \code
+ * psa_sign_hash_interruptible_operation_t operation;
+ * memset(&operation, 0, sizeof(operation));
+ * \endcode
+ * - Initialize the structure to logical zero values, for example:
+ * \code
+ * psa_sign_hash_interruptible_operation_t operation = {0};
+ * \endcode
+ * - Initialize the structure to the initializer
+ * #PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT, for example:
+ * \code
+ * psa_sign_hash_interruptible_operation_t operation =
+ * PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT;
+ * \endcode
+ * - Assign the result of the function
+ * psa_sign_hash_interruptible_operation_init() to the structure, for
+ * example:
+ * \code
+ * psa_sign_hash_interruptible_operation_t operation;
+ * operation = psa_sign_hash_interruptible_operation_init();
+ * \endcode
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure.
+ * Implementation details can change in future versions without notice. */
+typedef struct psa_sign_hash_interruptible_operation_s psa_sign_hash_interruptible_operation_t;
+
+/** The type of the state data structure for interruptible hash
+ * verification operations.
+ *
+ * Before calling any function on a sign hash operation object, the
+ * application must initialize it by any of the following means:
+ * - Set the structure to all-bits-zero, for example:
+ * \code
+ * psa_verify_hash_interruptible_operation_t operation;
+ * memset(&operation, 0, sizeof(operation));
+ * \endcode
+ * - Initialize the structure to logical zero values, for example:
+ * \code
+ * psa_verify_hash_interruptible_operation_t operation = {0};
+ * \endcode
+ * - Initialize the structure to the initializer
+ * #PSA_VERIFY_HASH_INTERRUPTIBLE_OPERATION_INIT, for example:
+ * \code
+ * psa_verify_hash_interruptible_operation_t operation =
+ * PSA_VERIFY_HASH_INTERRUPTIBLE_OPERATION_INIT;
+ * \endcode
+ * - Assign the result of the function
+ * psa_verify_hash_interruptible_operation_init() to the structure, for
+ * example:
+ * \code
+ * psa_verify_hash_interruptible_operation_t operation;
+ * operation = psa_verify_hash_interruptible_operation_init();
+ * \endcode
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure.
+ * Implementation details can change in future versions without notice. */
+typedef struct psa_verify_hash_interruptible_operation_s psa_verify_hash_interruptible_operation_t;
+
+/**
+ * \brief Set the maximum number of ops allowed to be
+ * executed by an interruptible function in a
+ * single call.
+ *
+ * \warning This is a beta API, and thus subject to change
+ * at any point. It is not bound by the usual
+ * interface stability promises.
+ *
+ * \note The time taken to execute a single op is
+ * implementation specific and depends on
+ * software, hardware, the algorithm, key type and
+ * curve chosen. Even within a single operation,
+ * successive ops can take differing amounts of
+ * time. The only guarantee is that lower values
+ * for \p max_ops means functions will block for a
+ * lesser maximum amount of time. The functions
+ * \c psa_sign_interruptible_get_num_ops() and
+ * \c psa_verify_interruptible_get_num_ops() are
+ * provided to help with tuning this value.
+ *
+ * \note This value defaults to
+ * #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED, which
+ * means the whole operation will be done in one
+ * go, regardless of the number of ops required.
+ *
+ * \note If more ops are needed to complete a
+ * computation, #PSA_OPERATION_INCOMPLETE will be
+ * returned by the function performing the
+ * computation. It is then the caller's
+ * responsibility to either call again with the
+ * same operation context until it returns 0 or an
+ * error code; or to call the relevant abort
+ * function if the answer is no longer required.
+ *
+ * \note The interpretation of \p max_ops is also
+ * implementation defined. On a hard real time
+ * system, this can indicate a hard deadline, as a
+ * real-time system needs a guarantee of not
+ * spending more than X time, however care must be
+ * taken in such an implementation to avoid the
+ * situation whereby calls just return, not being
+ * able to do any actual work within the allotted
+ * time. On a non-real-time system, the
+ * implementation can be more relaxed, but again
+ * whether this number should be interpreted as as
+ * hard or soft limit or even whether a less than
+ * or equals as regards to ops executed in a
+ * single call is implementation defined.
+ *
+ * \note For keys in local storage when no accelerator
+ * driver applies, please see also the
+ * documentation for \c mbedtls_ecp_set_max_ops(),
+ * which is the internal implementation in these
+ * cases.
+ *
+ * \warning With implementations that interpret this number
+ * as a hard limit, setting this number too small
+ * may result in an infinite loop, whereby each
+ * call results in immediate return with no ops
+ * done (as there is not enough time to execute
+ * any), and thus no result will ever be achieved.
+ *
+ * \note This only applies to functions whose
+ * documentation mentions they may return
+ * #PSA_OPERATION_INCOMPLETE.
+ *
+ * \param max_ops The maximum number of ops to be executed in a
+ * single call. This can be a number from 0 to
+ * #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED, where 0
+ * is the least amount of work done per call.
+ */
+void psa_interruptible_set_max_ops(uint32_t max_ops);
+
+/**
+ * \brief Get the maximum number of ops allowed to be
+ * executed by an interruptible function in a
+ * single call. This will return the last
+ * value set by
+ * \c psa_interruptible_set_max_ops() or
+ * #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED if
+ * that function has never been called.
+ *
+ * \warning This is a beta API, and thus subject to change
+ * at any point. It is not bound by the usual
+ * interface stability promises.
+ *
+ * \return Maximum number of ops allowed to be
+ * executed by an interruptible function in a
+ * single call.
+ */
+uint32_t psa_interruptible_get_max_ops(void);
+
+/**
+ * \brief Get the number of ops that a hash signing
+ * operation has taken so far. If the operation
+ * has completed, then this will represent the
+ * number of ops required for the entire
+ * operation. After initialization or calling
+ * \c psa_sign_hash_interruptible_abort() on
+ * the operation, a value of 0 will be returned.
+ *
+ * \note This interface is guaranteed re-entrant and
+ * thus may be called from driver code.
+ *
+ * \warning This is a beta API, and thus subject to change
+ * at any point. It is not bound by the usual
+ * interface stability promises.
+ *
+ * This is a helper provided to help you tune the
+ * value passed to \c
+ * psa_interruptible_set_max_ops().
+ *
+ * \param operation The \c psa_sign_hash_interruptible_operation_t
+ * to use. This must be initialized first.
+ *
+ * \return Number of ops that the operation has taken so
+ * far.
+ */
+uint32_t psa_sign_hash_get_num_ops(
+ const psa_sign_hash_interruptible_operation_t *operation);
+
+/**
+ * \brief Get the number of ops that a hash verification
+ * operation has taken so far. If the operation
+ * has completed, then this will represent the
+ * number of ops required for the entire
+ * operation. After initialization or calling \c
+ * psa_verify_hash_interruptible_abort() on the
+ * operation, a value of 0 will be returned.
+ *
+ * \warning This is a beta API, and thus subject to change
+ * at any point. It is not bound by the usual
+ * interface stability promises.
+ *
+ * This is a helper provided to help you tune the
+ * value passed to \c
+ * psa_interruptible_set_max_ops().
+ *
+ * \param operation The \c
+ * psa_verify_hash_interruptible_operation_t to
+ * use. This must be initialized first.
+ *
+ * \return Number of ops that the operation has taken so
+ * far.
+ */
+uint32_t psa_verify_hash_get_num_ops(
+ const psa_verify_hash_interruptible_operation_t *operation);
+
+/**
+ * \brief Start signing a hash or short message with a
+ * private key, in an interruptible manner.
+ *
+ * \see \c psa_sign_hash_complete()
+ *
+ * \warning This is a beta API, and thus subject to change
+ * at any point. It is not bound by the usual
+ * interface stability promises.
+ *
+ * \note This function combined with \c
+ * psa_sign_hash_complete() is equivalent to
+ * \c psa_sign_hash() but
+ * \c psa_sign_hash_complete() can return early and
+ * resume according to the limit set with \c
+ * psa_interruptible_set_max_ops() to reduce the
+ * maximum time spent in a function call.
+ *
+ * \note Users should call \c psa_sign_hash_complete()
+ * repeatedly on the same context after a
+ * successful call to this function until \c
+ * psa_sign_hash_complete() either returns 0 or an
+ * error. \c psa_sign_hash_complete() will return
+ * #PSA_OPERATION_INCOMPLETE if there is more work
+ * to do. Alternatively users can call
+ * \c psa_sign_hash_abort() at any point if they no
+ * longer want the result.
+ *
+ * \note If this function returns an error status, the
+ * operation enters an error state and must be
+ * aborted by calling \c psa_sign_hash_abort().
+ *
+ * \param[in, out] operation The \c psa_sign_hash_interruptible_operation_t
+ * to use. This must be initialized first.
+ *
+ * \param key Identifier of the key to use for the operation.
+ * It must be an asymmetric key pair. The key must
+ * allow the usage #PSA_KEY_USAGE_SIGN_HASH.
+ * \param alg A signature algorithm (\c PSA_ALG_XXX
+ * value such that #PSA_ALG_IS_SIGN_HASH(\p alg)
+ * is true), that is compatible with
+ * the type of \p key.
+ * \param[in] hash The hash or message to sign.
+ * \param hash_length Size of the \p hash buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * The operation started successfully - call \c psa_sign_hash_complete()
+ * with the same context to complete the operation
+ *
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * The key does not have the #PSA_KEY_USAGE_SIGN_HASH flag, or it does
+ * not permit the requested algorithm.
+ * \retval #PSA_ERROR_BAD_STATE
+ * An operation has previously been started on this context, and is
+ * still in progress.
+ * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
+ * \retval #PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_sign_hash_start(
+ psa_sign_hash_interruptible_operation_t *operation,
+ mbedtls_svc_key_id_t key, psa_algorithm_t alg,
+ const uint8_t *hash, size_t hash_length);
+
+/**
+ * \brief Continue and eventually complete the action of
+ * signing a hash or short message with a private
+ * key, in an interruptible manner.
+ *
+ * \see \c psa_sign_hash_start()
+ *
+ * \warning This is a beta API, and thus subject to change
+ * at any point. It is not bound by the usual
+ * interface stability promises.
+ *
+ * \note This function combined with \c
+ * psa_sign_hash_start() is equivalent to
+ * \c psa_sign_hash() but this function can return
+ * early and resume according to the limit set with
+ * \c psa_interruptible_set_max_ops() to reduce the
+ * maximum time spent in a function call.
+ *
+ * \note Users should call this function on the same
+ * operation object repeatedly until it either
+ * returns 0 or an error. This function will return
+ * #PSA_OPERATION_INCOMPLETE if there is more work
+ * to do. Alternatively users can call
+ * \c psa_sign_hash_abort() at any point if they no
+ * longer want the result.
+ *
+ * \note When this function returns successfully, the
+ * operation becomes inactive. If this function
+ * returns an error status, the operation enters an
+ * error state and must be aborted by calling
+ * \c psa_sign_hash_abort().
+ *
+ * \param[in, out] operation The \c psa_sign_hash_interruptible_operation_t
+ * to use. This must be initialized first, and have
+ * had \c psa_sign_hash_start() called with it
+ * first.
+ *
+ * \param[out] signature Buffer where the signature is to be written.
+ * \param signature_size Size of the \p signature buffer in bytes. This
+ * must be appropriate for the selected
+ * algorithm and key:
+ * - The required signature size is
+ * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c
+ * key_bits, \c alg) where \c key_type and \c
+ * key_bits are the type and bit-size
+ * respectively of key.
+ * - #PSA_SIGNATURE_MAX_SIZE evaluates to the
+ * maximum signature size of any supported
+ * signature algorithm.
+ * \param[out] signature_length On success, the number of bytes that make up
+ * the returned signature value.
+ *
+ * \retval #PSA_SUCCESS
+ * Operation completed successfully
+ *
+ * \retval #PSA_OPERATION_INCOMPLETE
+ * Operation was interrupted due to the setting of \c
+ * psa_interruptible_set_max_ops(). There is still work to be done.
+ * Call this function again with the same operation object.
+ *
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p signature buffer is too small. You can
+ * determine a sufficient buffer size by calling
+ * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg)
+ * where \c key_type and \c key_bits are the type and bit-size
+ * respectively of \p key.
+ *
+ * \retval #PSA_ERROR_BAD_STATE
+ * An operation was not previously started on this context via
+ * \c psa_sign_hash_start().
+ *
+ * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
+ * \retval #PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has either not been previously initialized by
+ * psa_crypto_init() or you did not previously call
+ * psa_sign_hash_start() with this operation object. It is
+ * implementation-dependent whether a failure to initialize results in
+ * this error code.
+ */
+psa_status_t psa_sign_hash_complete(
+ psa_sign_hash_interruptible_operation_t *operation,
+ uint8_t *signature, size_t signature_size,
+ size_t *signature_length);
+
+/**
+ * \brief Abort a sign hash operation.
+ *
+ * \warning This is a beta API, and thus subject to change
+ * at any point. It is not bound by the usual
+ * interface stability promises.
+ *
+ * \note This function is the only function that clears
+ * the number of ops completed as part of the
+ * operation. Please ensure you copy this value via
+ * \c psa_sign_hash_get_num_ops() if required
+ * before calling.
+ *
+ * \note Aborting an operation frees all associated
+ * resources except for the \p operation structure
+ * itself. Once aborted, the operation object can
+ * be reused for another operation by calling \c
+ * psa_sign_hash_start() again.
+ *
+ * \note You may call this function any time after the
+ * operation object has been initialized. In
+ * particular, calling \c psa_sign_hash_abort()
+ * after the operation has already been terminated
+ * by a call to \c psa_sign_hash_abort() or
+ * psa_sign_hash_complete() is safe.
+ *
+ * \param[in,out] operation Initialized sign hash operation.
+ *
+ * \retval #PSA_SUCCESS
+ * The operation was aborted successfully.
+ *
+ * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_sign_hash_abort(
+ psa_sign_hash_interruptible_operation_t *operation);
+
+/**
+ * \brief Start reading and verifying a hash or short
+ * message, in an interruptible manner.
+ *
+ * \see \c psa_verify_hash_complete()
+ *
+ * \warning This is a beta API, and thus subject to change
+ * at any point. It is not bound by the usual
+ * interface stability promises.
+ *
+ * \note This function combined with \c
+ * psa_verify_hash_complete() is equivalent to
+ * \c psa_verify_hash() but \c
+ * psa_verify_hash_complete() can return early and
+ * resume according to the limit set with \c
+ * psa_interruptible_set_max_ops() to reduce the
+ * maximum time spent in a function.
+ *
+ * \note Users should call \c psa_verify_hash_complete()
+ * repeatedly on the same operation object after a
+ * successful call to this function until \c
+ * psa_verify_hash_complete() either returns 0 or
+ * an error. \c psa_verify_hash_complete() will
+ * return #PSA_OPERATION_INCOMPLETE if there is
+ * more work to do. Alternatively users can call
+ * \c psa_verify_hash_abort() at any point if they
+ * no longer want the result.
+ *
+ * \note If this function returns an error status, the
+ * operation enters an error state and must be
+ * aborted by calling \c psa_verify_hash_abort().
+ *
+ * \param[in, out] operation The \c psa_verify_hash_interruptible_operation_t
+ * to use. This must be initialized first.
+ *
+ * \param key Identifier of the key to use for the operation.
+ * The key must allow the usage
+ * #PSA_KEY_USAGE_VERIFY_HASH.
+ * \param alg A signature algorithm (\c PSA_ALG_XXX
+ * value such that #PSA_ALG_IS_SIGN_HASH(\p alg)
+ * is true), that is compatible with
+ * the type of \p key.
+ * \param[in] hash The hash whose signature is to be verified.
+ * \param hash_length Size of the \p hash buffer in bytes.
+ * \param[in] signature Buffer containing the signature to verify.
+ * \param signature_length Size of the \p signature buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * The operation started successfully - please call \c
+ * psa_verify_hash_complete() with the same context to complete the
+ * operation.
+ *
+ * \retval #PSA_ERROR_BAD_STATE
+ * Another operation has already been started on this context, and is
+ * still in progress.
+ *
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * The key does not have the #PSA_KEY_USAGE_VERIFY_HASH flag, or it does
+ * not permit the requested algorithm.
+ *
+ * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval PSA_ERROR_DATA_CORRUPT \emptydescription
+ * \retval PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_verify_hash_start(
+ psa_verify_hash_interruptible_operation_t *operation,
+ mbedtls_svc_key_id_t key, psa_algorithm_t alg,
+ const uint8_t *hash, size_t hash_length,
+ const uint8_t *signature, size_t signature_length);
+
+/**
+ * \brief Continue and eventually complete the action of
+ * reading and verifying a hash or short message
+ * signed with a private key, in an interruptible
+ * manner.
+ *
+ * \see \c psa_verify_hash_start()
+ *
+ * \warning This is a beta API, and thus subject to change
+ * at any point. It is not bound by the usual
+ * interface stability promises.
+ *
+ * \note This function combined with \c
+ * psa_verify_hash_start() is equivalent to
+ * \c psa_verify_hash() but this function can
+ * return early and resume according to the limit
+ * set with \c psa_interruptible_set_max_ops() to
+ * reduce the maximum time spent in a function
+ * call.
+ *
+ * \note Users should call this function on the same
+ * operation object repeatedly until it either
+ * returns 0 or an error. This function will return
+ * #PSA_OPERATION_INCOMPLETE if there is more work
+ * to do. Alternatively users can call
+ * \c psa_verify_hash_abort() at any point if they
+ * no longer want the result.
+ *
+ * \note When this function returns successfully, the
+ * operation becomes inactive. If this function
+ * returns an error status, the operation enters an
+ * error state and must be aborted by calling
+ * \c psa_verify_hash_abort().
+ *
+ * \param[in, out] operation The \c psa_verify_hash_interruptible_operation_t
+ * to use. This must be initialized first, and have
+ * had \c psa_verify_hash_start() called with it
+ * first.
+ *
+ * \retval #PSA_SUCCESS
+ * Operation completed successfully, and the passed signature is valid.
+ *
+ * \retval #PSA_OPERATION_INCOMPLETE
+ * Operation was interrupted due to the setting of \c
+ * psa_interruptible_set_max_ops(). There is still work to be done.
+ * Call this function again with the same operation object.
+ *
+ * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ * The calculation was performed successfully, but the passed
+ * signature is not a valid signature.
+ * \retval #PSA_ERROR_BAD_STATE
+ * An operation was not previously started on this context via
+ * \c psa_verify_hash_start().
+ * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
+ * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
+ * \retval #PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has either not been previously initialized by
+ * psa_crypto_init() or you did not previously call
+ * psa_verify_hash_start() on this object. It is
+ * implementation-dependent whether a failure to initialize results in
+ * this error code.
+ */
+psa_status_t psa_verify_hash_complete(
+ psa_verify_hash_interruptible_operation_t *operation);
+
+/**
+ * \brief Abort a verify hash operation.
+ *
+ * \warning This is a beta API, and thus subject to change at
+ * any point. It is not bound by the usual interface
+ * stability promises.
+ *
+ * \note This function is the only function that clears the
+ * number of ops completed as part of the operation.
+ * Please ensure you copy this value via
+ * \c psa_verify_hash_get_num_ops() if required
+ * before calling.
+ *
+ * \note Aborting an operation frees all associated
+ * resources except for the operation structure
+ * itself. Once aborted, the operation object can be
+ * reused for another operation by calling \c
+ * psa_verify_hash_start() again.
+ *
+ * \note You may call this function any time after the
+ * operation object has been initialized.
+ * In particular, calling \c psa_verify_hash_abort()
+ * after the operation has already been terminated by
+ * a call to \c psa_verify_hash_abort() or
+ * psa_verify_hash_complete() is safe.
+ *
+ * \param[in,out] operation Initialized verify hash operation.
+ *
+ * \retval #PSA_SUCCESS
+ * The operation was aborted successfully.
+ *
+ * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_verify_hash_abort(
+ psa_verify_hash_interruptible_operation_t *operation);
+
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+/* The file "crypto_sizes.h" contains definitions for size calculation
+ * macros whose definitions are implementation-specific. */
+#include "crypto_sizes.h"
+
+/* The file "crypto_struct.h" contains definitions for
+ * implementation-specific structs that are declared above. */
+#if defined(MBEDTLS_PSA_CRYPTO_STRUCT_FILE)
+#include MBEDTLS_PSA_CRYPTO_STRUCT_FILE
+#else
+#include "crypto_struct.h"
+#endif
+
+/* The file "crypto_extra.h" contains vendor-specific definitions. This
+ * can include vendor-defined algorithms, extra functions, etc. */
+#include "crypto_extra.h"
+
+#endif /* PSA_CRYPTO_H */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_client_struct.h b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_client_struct.h
new file mode 100644
index 0000000..bf95c98
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_client_struct.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+/**
+ * \file psa/crypto_client_struct.h
+ *
+ * \brief PSA cryptography client key attribute definitions
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h.
+ *
+ * This file contains the definitions of some data structures with
+ * PSA crypto client specific definitions. This is for implementations
+ * with isolation between the Client applications and the Crypto
+ * Server module, it is expected that the front-end and the back-end
+ * would have different versions of the data structure.
+ */
+#ifndef PSA_CRYPTO_CLIENT_STRUCT_H
+#define PSA_CRYPTO_CLIENT_STRUCT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This is the client view of the `key_attributes` structure. Only
+ * fields which need to be set by the PSA crypto client are present.
+ * The PSA crypto service will maintain a different version of the
+ * data structure internally. */
+struct psa_client_key_attributes_s
+{
+ uint16_t type;
+ uint16_t bits;
+ uint32_t lifetime;
+ psa_key_id_t id;
+ uint32_t usage;
+ uint32_t alg;
+};
+
+#define PSA_CLIENT_KEY_ATTRIBUTES_INIT {0, 0, 0, 0, 0, 0}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PSA_CRYPTO_CLIENT_STRUCT_H */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_compat.h b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_compat.h
new file mode 100644
index 0000000..c21649d
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_compat.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2019-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+/**
+ * \file psa/crypto_compat.h
+ *
+ * \brief PSA cryptography module: Backward compatibility aliases
+ *
+ * This header declares alternative names for macro and functions.
+ * New application code should not use these names.
+ * These names may be removed in a future version of Mbed Crypto.
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h.
+ */
+
+#ifndef PSA_CRYPTO_COMPAT_H
+#define PSA_CRYPTO_COMPAT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * To support both openless APIs and psa_open_key() temporarily, define
+ * psa_key_handle_t to be equal to mbedtls_svc_key_id_t. Do not mark the
+ * type and its utility macros and functions deprecated yet. This will be done
+ * in a subsequent phase.
+ */
+typedef mbedtls_svc_key_id_t psa_key_handle_t;
+
+#define PSA_KEY_HANDLE_INIT MBEDTLS_SVC_KEY_ID_INIT
+
+/** Check whether a handle is null.
+ *
+ * \param handle Handle
+ *
+ * \return Non-zero if the handle is null, zero otherwise.
+ */
+static inline int psa_key_handle_is_null(psa_key_handle_t handle)
+{
+ return mbedtls_svc_key_id_is_null(handle);
+}
+
+/** Open a handle to an existing persistent key.
+ *
+ * Open a handle to a persistent key. A key is persistent if it was created
+ * with a lifetime other than #PSA_KEY_LIFETIME_VOLATILE. A persistent key
+ * always has a nonzero key identifier, set with psa_set_key_id() when
+ * creating the key. Implementations may provide additional pre-provisioned
+ * keys that can be opened with psa_open_key(). Such keys have an application
+ * key identifier in the vendor range, as documented in the description of
+ * #psa_key_id_t.
+ *
+ * The application must eventually close the handle with psa_close_key() or
+ * psa_destroy_key() to release associated resources. If the application dies
+ * without calling one of these functions, the implementation should perform
+ * the equivalent of a call to psa_close_key().
+ *
+ * Some implementations permit an application to open the same key multiple
+ * times. If this is successful, each call to psa_open_key() will return a
+ * different key handle.
+ *
+ * \note This API is not part of the PSA Cryptography API Release 1.0.0
+ * specification. It was defined in the 1.0 Beta 3 version of the
+ * specification but was removed in the 1.0.0 released version. This API is
+ * kept for the time being to not break applications relying on it. It is not
+ * deprecated yet but will be in the near future.
+ *
+ * \note Applications that rely on opening a key multiple times will not be
+ * portable to implementations that only permit a single key handle to be
+ * opened. See also :ref:\`key-handles\`.
+ *
+ *
+ * \param key The persistent identifier of the key.
+ * \param[out] handle On success, a handle to the key.
+ *
+ * \retval #PSA_SUCCESS
+ * Success. The application can now use the value of `*handle`
+ * to access the key.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * The implementation does not have sufficient resources to open the
+ * key. This can be due to reaching an implementation limit on the
+ * number of open keys, the number of open key handles, or available
+ * memory.
+ * \retval #PSA_ERROR_DOES_NOT_EXIST
+ * There is no persistent key with key identifier \p key.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p key is not a valid persistent key identifier.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * The specified key exists, but the application does not have the
+ * permission to access it. Note that this specification does not
+ * define any way to create such a key, but it may be possible
+ * through implementation-specific means.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_open_key(mbedtls_svc_key_id_t key,
+ psa_key_handle_t *handle);
+
+/** Close a key handle.
+ *
+ * If the handle designates a volatile key, this will destroy the key material
+ * and free all associated resources, just like psa_destroy_key().
+ *
+ * If this is the last open handle to a persistent key, then closing the handle
+ * will free all resources associated with the key in volatile memory. The key
+ * data in persistent storage is not affected and can be opened again later
+ * with a call to psa_open_key().
+ *
+ * Closing the key handle makes the handle invalid, and the key handle
+ * must not be used again by the application.
+ *
+ * \note This API is not part of the PSA Cryptography API Release 1.0.0
+ * specification. It was defined in the 1.0 Beta 3 version of the
+ * specification but was removed in the 1.0.0 released version. This API is
+ * kept for the time being to not break applications relying on it. It is not
+ * deprecated yet but will be in the near future.
+ *
+ * \note If the key handle was used to set up an active
+ * :ref:\`multipart operation <multipart-operations>\`, then closing the
+ * key handle can cause the multipart operation to fail. Applications should
+ * maintain the key handle until after the multipart operation has finished.
+ *
+ * \param handle The key handle to close.
+ * If this is \c 0, do nothing and return \c PSA_SUCCESS.
+ *
+ * \retval #PSA_SUCCESS
+ * \p handle was a valid handle or \c 0. It is now closed.
+ * \retval #PSA_ERROR_INVALID_HANDLE
+ * \p handle is not a valid handle nor \c 0.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_close_key(psa_key_handle_t handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PSA_CRYPTO_COMPAT_H */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_extra.h b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_extra.h
new file mode 100644
index 0000000..6709b7b
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_extra.h
@@ -0,0 +1,1495 @@
+/*
+ * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+/**
+ * \file psa/crypto_extra.h
+ *
+ * \brief PSA cryptography module: vendor extensions
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h.
+ *
+ * This file is reserved for vendor-specific definitions.
+ */
+
+#ifndef PSA_CRYPTO_EXTRA_H
+#define PSA_CRYPTO_EXTRA_H
+
+#include "crypto_types.h"
+#include "crypto_compat.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \addtogroup crypto_types
+ * @{
+ */
+
+/** DSA public key.
+ *
+ * The import and export format is the
+ * representation of the public key `y = g^x mod p` as a big-endian byte
+ * string. The length of the byte string is the length of the base prime `p`
+ * in bytes.
+ */
+#define PSA_KEY_TYPE_DSA_PUBLIC_KEY ((psa_key_type_t) 0x4002)
+
+/** DSA key pair (private and public key).
+ *
+ * The import and export format is the
+ * representation of the private key `x` as a big-endian byte string. The
+ * length of the byte string is the private key size in bytes (leading zeroes
+ * are not stripped).
+ *
+ * Deterministic DSA key derivation with psa_generate_derived_key follows
+ * FIPS 186-4 &sect;B.1.2: interpret the byte string as integer
+ * in big-endian order. Discard it if it is not in the range
+ * [0, *N* - 2] where *N* is the boundary of the private key domain
+ * (the prime *p* for Diffie-Hellman, the subprime *q* for DSA,
+ * or the order of the curve's base point for ECC).
+ * Add 1 to the resulting integer and use this as the private key *x*.
+ *
+ */
+#define PSA_KEY_TYPE_DSA_KEY_PAIR ((psa_key_type_t) 0x7002)
+
+/** Whether a key type is a DSA key (pair or public-only). */
+#define PSA_KEY_TYPE_IS_DSA(type) \
+ (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY)
+
+#define PSA_ALG_DSA_BASE ((psa_algorithm_t) 0x06000400)
+/** DSA signature with hashing.
+ *
+ * This is the signature scheme defined by FIPS 186-4,
+ * with a random per-message secret number (*k*).
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ * This includes #PSA_ALG_ANY_HASH
+ * when specifying the algorithm in a usage policy.
+ *
+ * \return The corresponding DSA signature algorithm.
+ * \return Unspecified if \p hash_alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_DSA(hash_alg) \
+ (PSA_ALG_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_DETERMINISTIC_DSA_BASE ((psa_algorithm_t) 0x06000500)
+#define PSA_ALG_DSA_DETERMINISTIC_FLAG PSA_ALG_ECDSA_DETERMINISTIC_FLAG
+/** Deterministic DSA signature with hashing.
+ *
+ * This is the deterministic variant defined by RFC 6979 of
+ * the signature scheme defined by FIPS 186-4.
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ * This includes #PSA_ALG_ANY_HASH
+ * when specifying the algorithm in a usage policy.
+ *
+ * \return The corresponding DSA signature algorithm.
+ * \return Unspecified if \p hash_alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_DETERMINISTIC_DSA(hash_alg) \
+ (PSA_ALG_DETERMINISTIC_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_IS_DSA(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) == \
+ PSA_ALG_DSA_BASE)
+#define PSA_ALG_DSA_IS_DETERMINISTIC(alg) \
+ (((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0)
+#define PSA_ALG_IS_DETERMINISTIC_DSA(alg) \
+ (PSA_ALG_IS_DSA(alg) && PSA_ALG_DSA_IS_DETERMINISTIC(alg))
+#define PSA_ALG_IS_RANDOMIZED_DSA(alg) \
+ (PSA_ALG_IS_DSA(alg) && !PSA_ALG_DSA_IS_DETERMINISTIC(alg))
+
+
+/* We need to expand the sample definition of this macro from
+ * the API definition. */
+#undef PSA_ALG_IS_VENDOR_HASH_AND_SIGN
+#define PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg) \
+ PSA_ALG_IS_DSA(alg)
+
+/* Workaround for build warnings when MBed TLS has enabled MBEDTLS_USE_PSA_CRYPTO
+ *
+ * Mbed TLS is not compatible with TF-Ms PSA API headers.
+ *
+ * In order to prevent build warnings for the follow functions we add the
+ * prototypes for them here.
+ * If the application tries to link with these functions it will get a link-time
+ * error. This use-case is not supported by TF-M.
+ */
+void psa_set_key_enrollment_algorithm(
+ psa_key_attributes_t *attributes,
+ psa_algorithm_t alg2);
+psa_algorithm_t psa_get_key_enrollment_algorithm(
+ const psa_key_attributes_t *attributes);
+
+
+#define PSA_KEY_TYPE_SPAKE2P_KEY_PAIR_BASE ((psa_key_type_t) 0x7400)
+#define PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY_BASE ((psa_key_type_t) 0x4400)
+#define PSA_KEY_TYPE_SPAKE2P_CURVE_MASK ((psa_key_type_t) 0x00ff)
+
+ /** SPAKE2+ key pair. Both the prover and verifier key.
+ *
+ * The size of a SPAKE2+ key is the size associated with the elliptic curve
+ * group. See the documentation of each elliptic curve family for details.
+ * To construct a SPAKE2+ key pair, it must be output from a key derivation
+ * operation.
+ * The corresponding public key can be exported using psa_export_public_key().
+ * See also #PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY().
+ *
+ * \param curve A value of type psa_ecc_family_t that identifies the elliptic
+ * curve family to be used.
+ */
+#define PSA_KEY_TYPE_SPAKE2P_KEY_PAIR(curve) \
+ ((psa_key_type_t) (PSA_KEY_TYPE_SPAKE2P_KEY_PAIR_BASE | (curve)))
+
+ /** SPAKE2+ public key. The verifier key.
+ *
+ * The size of an SPAKE2+ public key is the same as the corresponding private
+ * key. See #PSA_KEY_TYPE_SPAKE2P_KEY_PAIR() and the documentation of each
+ * elliptic curve family for details.
+ * To construct a SPAKE2+ public key, it must be imported.
+ *
+ * \param curve A value of type psa_ecc_family_t that identifies the elliptic
+ * curve family to be used.
+ */
+#define PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY(curve) \
+ ((psa_key_type_t) (PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY_BASE | (curve)))
+
+ /** Whether a key type is a SPAKE2+ key (pair or public-only). */
+#define PSA_KEY_TYPE_IS_SPAKE2P(type) \
+ ((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) & \
+ ~PSA_KEY_TYPE_SPAKE2P_CURVE_MASK) == \
+ PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY_BASE)
+ /** Whether a key type is a SPAKE2+ key pair. */
+#define PSA_KEY_TYPE_IS_SPAKE2P_KEY_PAIR(type) \
+ (((type) & ~PSA_KEY_TYPE_SPAKE2P_CURVE_MASK) == \
+ PSA_KEY_TYPE_SPAKE2P_KEY_PAIR_BASE)
+ /** Whether a key type is a SPAKE2+ public key. */
+#define PSA_KEY_TYPE_IS_SPAKE2P_PUBLIC_KEY(type) \
+ (((type) & ~PSA_KEY_TYPE_SPAKE2P_CURVE_MASK) == \
+ PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY_BASE)
+ /** Extract the curve from a SPAKE2+ key type. */
+#define PSA_KEY_TYPE_SPAKE2P_GET_FAMILY(type) \
+ ((psa_ecc_family_t) (PSA_KEY_TYPE_IS_SPAKE2P(type) ? \
+ ((type) & PSA_KEY_TYPE_SPAKE2P_CURVE_MASK) : \
+ 0))
+
+#define PSA_KEY_TYPE_SRP_KEY_PAIR_BASE ((psa_key_type_t) 0x7700)
+#define PSA_KEY_TYPE_SRP_PUBLIC_KEY_BASE ((psa_key_type_t) 0x4700)
+#define PSA_KEY_TYPE_SRP_GROUP_MASK ((psa_key_type_t) 0x00ff)
+
+ /** SRP key pair. Both the client and server key.
+ *
+ * The size of a SRP key is the size associated with the Diffie-Hellman
+ * group. See the documentation of each Diffie-Hellman group for details.
+ * To construct a SRP key pair, the password hash must be imported.
+ * The corresponding public key (password verifier) can be exported using
+ * psa_export_public_key(). See also #PSA_KEY_TYPE_SRP_PUBLIC_KEY().
+ *
+ * \param group A value of type ::psa_dh_family_t that identifies the
+ * Diffie-Hellman group to be used.
+ */
+#define PSA_KEY_TYPE_SRP_KEY_PAIR(group) \
+ ((psa_key_type_t) (PSA_KEY_TYPE_SRP_KEY_PAIR_BASE | (group)))
+
+ /** SRP public key. The server key (password verifier).
+ *
+ * The size of an SRP public key is the same as the corresponding private
+ * key. See #PSA_KEY_TYPE_SRP_KEY_PAIR() and the documentation of each
+ * Diffie-Hellman group for details.
+ * To construct a SRP public key, it must be imported. The key size
+ * in attributes must not be zero.
+ *
+ * \param group A value of type ::psa_dh_family_t that identifies the
+ * Diffie-Hellman group to be used.
+ */
+#define PSA_KEY_TYPE_SRP_PUBLIC_KEY(group) \
+ ((psa_key_type_t) (PSA_KEY_TYPE_SRP_PUBLIC_KEY_BASE | (group)))
+
+ /** Whether a key type is a SRP key (pair or public-only). */
+#define PSA_KEY_TYPE_IS_SRP(type) \
+ ((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) & \
+ ~PSA_KEY_TYPE_SRP_GROUP_MASK) == \
+ PSA_KEY_TYPE_SRP_PUBLIC_KEY_BASE)
+ /** Whether a key type is a SRP key pair. */
+#define PSA_KEY_TYPE_IS_SRP_KEY_PAIR(type) \
+ (((type) & ~PSA_KEY_TYPE_SRP_GROUP_MASK) == \
+ PSA_KEY_TYPE_SRP_KEY_PAIR_BASE)
+ /** Whether a key type is a SRP public key. */
+#define PSA_KEY_TYPE_IS_SRP_PUBLIC_KEY(type) \
+ (((type) & ~PSA_KEY_TYPE_SRP_GROUP_MASK) == \
+ PSA_KEY_TYPE_SRP_PUBLIC_KEY_BASE)
+ /** Extract the curve from a SRP key type. */
+#define PSA_KEY_TYPE_SRP_GET_FAMILY(type) \
+ ((psa_ecc_family_t) (PSA_KEY_TYPE_IS_SRP(type) ? \
+ ((type) & PSA_KEY_TYPE_SRP_GROUP_MASK) : \
+ 0))
+
+#define PSA_ALG_CATEGORY_PAKE ((psa_algorithm_t) 0x0a000000)
+
+/** Whether the specified algorithm is a password-authenticated key exchange.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a password-authenticated key exchange (PAKE)
+ * algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_PAKE(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_PAKE)
+
+/** The Password-authenticated key exchange by juggling (J-PAKE) algorithm.
+ *
+ * This is J-PAKE as defined by RFC 8236, instantiated with the following
+ * parameters:
+ *
+ * - The group can be either an elliptic curve or defined over a finite field.
+ * - Schnorr NIZK proof as defined by RFC 8235 and using the same group as the
+ * J-PAKE algorithm.
+ * - A cryptographic hash function.
+ *
+ * To select these parameters and set up the cipher suite, call these functions
+ * in any order:
+ *
+ * \code
+ * psa_pake_cs_set_algorithm(cipher_suite, PSA_ALG_JPAKE(hash));
+ * psa_pake_cs_set_primitive(cipher_suite,
+ * PSA_PAKE_PRIMITIVE(type, family, bits));
+ * \endcode
+ *
+ * For more information on how to set a specific curve or field, refer to the
+ * documentation of the individual \c PSA_PAKE_PRIMITIVE_TYPE_XXX constants.
+ *
+ * After initializing a J-PAKE operation, call
+ *
+ * \code
+ * psa_pake_setup(operation, key, cipher_suite);
+ * psa_pake_set_user(operation, ...);
+ * psa_pake_set_peer(operation, ...);
+ * \endcode
+ *
+ * The password is provided as a key. This can be the password text itself,
+ * in an agreed character encoding, or some value derived from the password
+ * as required by a higher level protocol.
+ *
+ * (The implementation converts the key material to a number as described in
+ * Section 2.3.8 of _SEC 1: Elliptic Curve Cryptography_
+ * (https://www.secg.org/sec1-v2.pdf), before reducing it modulo \c q. Here
+ * \c q is order of the group defined by the primitive set in the cipher suite.
+ * The \c psa_pake_setup() function returns an error if the result of the
+ * reduction is 0.)
+ *
+ * The key exchange flow for J-PAKE is as follows:
+ * -# To get the first round data that needs to be sent to the peer, call
+ * \code
+ * // Get g1
+ * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // Get the ZKP public key for x1
+ * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...);
+ * // Get the ZKP proof for x1
+ * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PROOF, ...);
+ * // Get g2
+ * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // Get the ZKP public key for x2
+ * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...);
+ * // Get the ZKP proof for x2
+ * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PROOF, ...);
+ * \endcode
+ * -# To provide the first round data received from the peer to the operation,
+ * call
+ * \code
+ * // Set g3
+ * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // Set the ZKP public key for x3
+ * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...);
+ * // Set the ZKP proof for x3
+ * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PROOF, ...);
+ * // Set g4
+ * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // Set the ZKP public key for x4
+ * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...);
+ * // Set the ZKP proof for x4
+ * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PROOF, ...);
+ * \endcode
+ * -# To get the second round data that needs to be sent to the peer, call
+ * \code
+ * // Get A
+ * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // Get ZKP public key for x2*s
+ * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...);
+ * // Get ZKP proof for x2*s
+ * psa_pake_output(operation, #PSA_PAKE_STEP_ZK_PROOF, ...);
+ * \endcode
+ * -# To provide the second round data received from the peer to the operation,
+ * call
+ * \code
+ * // Set B
+ * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // Set ZKP public key for x4*s
+ * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PUBLIC, ...);
+ * // Set ZKP proof for x4*s
+ * psa_pake_input(operation, #PSA_PAKE_STEP_ZK_PROOF, ...);
+ * \endcode
+ * -# To access the shared secret call
+ * \code
+ * // Get Ka=Kb=K
+ * psa_pake_get_shared_key()
+ * \endcode
+ *
+ * For more information consult the documentation of the individual
+ * \c PSA_PAKE_STEP_XXX constants.
+ *
+ * At this point there is a cryptographic guarantee that only the authenticated
+ * party who used the same password is able to compute the key. But there is no
+ * guarantee that the peer is the party it claims to be and was able to do so.
+ *
+ * That is, the authentication is only implicit (the peer is not authenticated
+ * at this point, and no action should be taken that assume that they are - like
+ * for example accessing restricted files).
+ *
+ * To make the authentication explicit there are various methods, see Section 5
+ * of RFC 8236 for two examples.
+ *
+ */
+#define PSA_ALG_JPAKE_BASE ((psa_algorithm_t) 0x0a000100)
+#define PSA_ALG_JPAKE(hash_alg) (PSA_ALG_JPAKE_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_IS_JPAKE(alg) (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_JPAKE_BASE)
+
+ /** The SPAKE2+ algorithm.
+ *
+ * SPAKE2+ is the augmented password-authenticated key exchange protocol,
+ * defined by RFC9383. SPAKE2+ includes confirmation of the shared secret
+ * key that results from the key exchange.
+ * SPAKE2+ is required by Matter Specification, Version 1.2, as MATTER_PAKE.
+ * Matter uses an earlier draft of the SPAKE2+ protocol: "SPAKE2+, an
+ * Augmented PAKE (Draft 02)".
+ * Although the operation of the PAKE is similar for both of these variants,
+ * they have different key schedules for the derivation of the shared secret.
+ *
+ * When setting up a PAKE cipher suite to use the SPAKE2+ protocol defined
+ * in RFC9383:
+ * - For cipher-suites that use HMAC for key confirmation, use the
+ * PSA_ALG_SPAKE2P_HMAC() algorithm, parameterized by the required hash
+ * algorithm.
+ * - For cipher-suites that use CMAC-AES-128 for key confirmation, use the
+ * PSA_ALG_SPAKE2P_CMAC() algorithm, parameterized by the required hash
+ * algorithm.
+ * - Use a PAKE primitive for the required elliptic curve.
+ *
+ * For example, the following code creates a cipher suite to select SPAKE2+
+ * using edwards25519 with the SHA-256 hash function:
+ *
+ * \code
+ * psa_pake_cipher_suite_t cipher_suite = PSA_PAKE_CIPHER_SUITE_INIT;
+ * psa_pake_cs_set_algorithm(cipher_suite, PSA_ALG_SPAKE2P_HMAC(PSA_ALG_SHA_256));
+ * psa_pake_cs_set_primitive(&cipher_suite,
+ * PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC,
+ * PSA_ECC_FAMILY_TWISTED_EDWARDS, 255));
+ * \endcode
+ *
+ * When setting up a PAKE cipher suite to use the SPAKE2+ protocol used by
+ * Matter:
+ * - Use the PSA_ALG_SPAKE2P_MATTER algorithm.
+ * - Use the PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC,
+ * PSA_ECC_FAMILY_SECP_R1, 256)
+ * PAKE primitive.
+ *
+ * The following code creates a cipher suite to select the Matter variant of
+ * SPAKE2+:
+ *
+ * \code
+ * psa_pake_cipher_suite_t cipher_suite = PSA_PAKE_CIPHER_SUITE_INIT;
+ * psa_pake_cs_set_algorithm(&cipher_suite, PSA_ALG_SPAKE2P_MATTER);
+ * psa_pake_cs_set_primitive(&cipher_suite,
+ * PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC,
+ * PSA_ECC_FAMILY_SECP_R1, 256));
+ * \endcode
+ *
+ * After initializing a SPAKE2+ operation, call
+ *
+ * \code
+ * psa_pake_setup(operation, password, cipher_suite);
+ * psa_pake_set_role(operation, ...);
+ * \endcode
+ *
+ * The password provided to the client side must be of type
+ * #PSA_KEY_TYPE_SPAKE2P_KEY_PAIR.
+ * The password provided to the server side must be of type
+ * #PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY.
+ *
+ * The role set by \c psa_pake_set_role() must be either
+ * \c PSA_PAKE_ROLE_CLIENT or \c PSA_PAKE_ROLE_SERVER.
+ *
+ * Then provide any additional, optional parameters:
+ *
+ * \code
+ * psa_pake_set_user(operation, ...);
+ * psa_pake_set_peer(operation, ...);
+ * psa_pake_set_context(operation, ...);
+ * \endcode
+ *
+ *
+ * The key exchange flow for a SPAKE2+ client is as follows:
+ * \code
+ * // send shareP
+ * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // receive shareV
+ * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // receive confirmV
+ * psa_pake_input(operation, #PSA_PAKE_STEP_CONFIRM, ...);
+ * // send confirmP
+ * psa_pake_output(operation, #PSA_PAKE_STEP_CONFIRM, ...);
+ * // get K_shared
+ * psa_pake_get_shared_key(operation, ...);
+ * \endcode
+ *
+ * The key exchange flow for a SPAKE2+ server is as follows:
+ * \code
+ * // receive shareP
+ * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // send shareV
+ * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // send confirmV
+ * psa_pake_output(operation, #PSA_PAKE_STEP_CONFIRM, ...);
+ * // receive confirmP
+ * psa_pake_input(operation, #PSA_PAKE_STEP_CONFIRM, ...);
+ * // get K_shared
+ * psa_pake_get_shared_key(operation, ...);
+ * \endcode
+ *
+ * The shared secret that is produced by SPAKE2+ is pseudorandom. Although
+ * it can be used directly as an encryption key, it is recommended to use
+ * the shared secret as an input to a key derivation operation to produce
+ * additional cryptographic keys.
+ */
+#define PSA_ALG_IS_SPAKE2P_HMAC_BASE ((psa_algorithm_t) 0x0a000400)
+#define PSA_ALG_SPAKE2P_HMAC(hash_alg) (PSA_ALG_IS_SPAKE2P_HMAC_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_IS_SPAKE2P_CMAC_BASE ((psa_algorithm_t) 0x0a000500)
+#define PSA_ALG_SPAKE2P_CMAC(hash_alg) (PSA_ALG_IS_SPAKE2P_CMAC_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_SPAKE2P_MATTER ((psa_algorithm_t) 0x0A000609)
+#define PSA_ALG_IS_SPAKE2P(alg) (((alg) & ~0x000003ff) == PSA_ALG_IS_SPAKE2P_HMAC_BASE)
+#define PSA_ALG_IS_SPAKE2P_HMAC(alg) (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_IS_SPAKE2P_HMAC_BASE)
+#define PSA_ALG_IS_SPAKE2P_CMAC(alg) (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_IS_SPAKE2P_CMAC_BASE)
+
+ /** The Secure Remote Passwort key exchange (SRP) algorithm.
+ *
+ * This is SRP-6 as defined by RFC 2945 and RFC 5054, instantiated with the
+ * following parameters:
+ *
+ * - The group is defined over a finite field using a secure prime.
+ * - A cryptographic hash function.
+ *
+ * To select these parameters and set up the cipher suite, call these functions:
+ *
+ * \code
+ * psa_pake_cipher_suite_t cipher_suite = PSA_PAKE_CIPHER_SUITE_INIT;
+ * psa_pake_cs_set_algorithm(cipher_suite, PSA_ALG_SRP_6(hash));
+ * psa_pake_cs_set_primitive(&cipher_suite,
+ * PSA_PAKE_PRIMITIVE(type, family, bits));
+ * \endcode
+ *
+ * After initializing a SRP operation, call:
+ *
+ * \code
+ * psa_pake_setup(operation, password, cipher_suite);
+ * psa_pake_set_role(operation, ...);
+ * psa_pake_set_user(operation, ...);
+ * \endcode
+ *
+ * The password provided to the client side must be of type
+ * #PSA_KEY_TYPE_SRP_KEY_PAIR.
+ * The password provided to the server side must be of type
+ * #PSA_KEY_TYPE_SRP_PUBLIC_KEY.
+ *
+ * The role set by \c psa_pake_set_role() must be either
+ * \c PSA_PAKE_ROLE_CLIENT or \c PSA_PAKE_ROLE_SERVER.
+ *
+ * For the SRP client key exchange call the following functions in any order:
+ * \code
+ * // get salt
+ * psa_pake_input(operation, #PSA_PAKE_STEP_SALT, ...);
+ * // get server key
+ * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // write client key
+ * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * \endcode
+ *
+ * For the SRP server key exchange call the following functions in any order:
+ * \code
+ * // get salt
+ * psa_pake_input(operation, #PSA_PAKE_STEP_SALT, ...);
+ * // get client key
+ * psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * // write server key
+ * psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...);
+ * \endcode
+ *
+ * For the client proof phase call the following functions in this order:
+ * \code
+ * // send M1
+ * psa_pake_input(operation, #PSA_PAKE_STEP_CONFIRM, ...);
+ * // receive M2
+ * psa_pake_output(operation, #PSA_PAKE_STEP_CONFIRM, ...);
+ * // Get secret
+ * psa_pake_get_shared_key()
+ * \endcode
+ *
+ * For the server proof phase call the following functions in this order:
+ * \code
+ * // receive M1
+ * psa_pake_output(operation, #PSA_PAKE_STEP_CONFIRM, ...);
+ * // send M2
+ * psa_pake_input(operation, #PSA_PAKE_STEP_CONFIRM, ...);
+ * // Get secret
+ * psa_pake_get_shared_key()
+ * \endcode
+ *
+ * The shared secret that is produced by SRP is pseudorandom. Although
+ * it can be used directly as an encryption key, it is recommended to use
+ * the shared secret as an input to a key derivation operation to produce
+ * additional cryptographic keys.
+ */
+#define PSA_ALG_SRP_6_BASE ((psa_algorithm_t) 0x0a000300)
+#define PSA_ALG_SRP_6(hash_alg) (PSA_ALG_SRP_6_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_IS_SRP_6(alg) (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_SRP_6_BASE)
+
+/** @} */
+
+/** \defgroup pake Password-authenticated key exchange (PAKE)
+ *
+ * This is a proposed PAKE interface for the PSA Crypto API. It is not part of
+ * the official PSA Crypto API yet.
+ *
+ * \note The content of this section is not part of the stable API and ABI
+ * of Mbed TLS and may change arbitrarily from version to version.
+ * Same holds for the corresponding macros #PSA_ALG_CATEGORY_PAKE and
+ * #PSA_ALG_JPAKE.
+ * @{
+ */
+
+/** A value to indicate no role in a PAKE algorithm.
+ * This value can be used in a call to psa_pake_set_role() for symmetric PAKE
+ * algorithms which do not assign roles.
+ */
+#define PSA_PAKE_ROLE_NONE ((psa_pake_role_t) 0x00)
+
+/** The first peer in a balanced PAKE.
+ *
+ * Although balanced PAKE algorithms are symmetric, some of them need an
+ * ordering of peers for the transcript calculations. If the algorithm does not
+ * need this, both #PSA_PAKE_ROLE_FIRST and #PSA_PAKE_ROLE_SECOND are
+ * accepted.
+ */
+#define PSA_PAKE_ROLE_FIRST ((psa_pake_role_t) 0x01)
+
+/** The second peer in a balanced PAKE.
+ *
+ * Although balanced PAKE algorithms are symmetric, some of them need an
+ * ordering of peers for the transcript calculations. If the algorithm does not
+ * need this, either #PSA_PAKE_ROLE_FIRST or #PSA_PAKE_ROLE_SECOND are
+ * accepted.
+ */
+#define PSA_PAKE_ROLE_SECOND ((psa_pake_role_t) 0x02)
+
+/** The client in an augmented PAKE.
+ *
+ * Augmented PAKE algorithms need to differentiate between client and server.
+ */
+#define PSA_PAKE_ROLE_CLIENT ((psa_pake_role_t) 0x11)
+
+/** The server in an augmented PAKE.
+ *
+ * Augmented PAKE algorithms need to differentiate between client and server.
+ */
+#define PSA_PAKE_ROLE_SERVER ((psa_pake_role_t) 0x12)
+
+/** The PAKE primitive type indicating the use of elliptic curves.
+ *
+ * The values of the \c family and \c bits fields of the cipher suite identify a
+ * specific elliptic curve, using the same mapping that is used for ECC
+ * (::psa_ecc_family_t) keys.
+ *
+ * (Here \c family means the value returned by PSA_PAKE_PRIMITIVE_GET_FAMILY() and
+ * \c bits means the value returned by PSA_PAKE_PRIMITIVE_GET_BITS().)
+ *
+ * Input and output during the operation can involve group elements and scalar
+ * values:
+ * -# The format for group elements is the same as for public keys on the
+ * specific curve would be. For more information, consult the documentation of
+ * psa_export_public_key().
+ * -# The format for scalars is the same as for private keys on the specific
+ * curve would be. For more information, consult the documentation of
+ * psa_export_key().
+ */
+#define PSA_PAKE_PRIMITIVE_TYPE_ECC ((psa_pake_primitive_type_t) 0x01)
+
+/** The PAKE primitive type indicating the use of Diffie-Hellman groups.
+ *
+ * The values of the \c family and \c bits fields of the cipher suite identify
+ * a specific Diffie-Hellman group, using the same mapping that is used for
+ * Diffie-Hellman (::psa_dh_family_t) keys.
+ *
+ * (Here \c family means the value returned by PSA_PAKE_PRIMITIVE_GET_FAMILY() and
+ * \c bits means the value returned by PSA_PAKE_PRIMITIVE_GET_BITS().)
+ *
+ * Input and output during the operation can involve group elements and scalar
+ * values:
+ * -# The format for group elements is the same as for public keys on the
+ * specific group would be. For more information, consult the documentation of
+ * psa_export_public_key().
+ * -# The format for scalars is the same as for private keys on the specific
+ * group would be. For more information, consult the documentation of
+ * psa_export_key().
+ */
+#define PSA_PAKE_PRIMITIVE_TYPE_DH ((psa_pake_primitive_type_t) 0x02)
+
+/** Construct a PAKE primitive from type, family and bit-size.
+ *
+ * \param pake_type The type of the primitive
+ * (value of type ::psa_pake_primitive_type_t).
+ * \param pake_family The family of the primitive
+ * (the type and interpretation of this parameter depends
+ * on \p pake_type, for more information consult the
+ * documentation of individual ::psa_pake_primitive_type_t
+ * constants).
+ * \param pake_bits The bit-size of the primitive
+ * (Value of type \c size_t. The interpretation
+ * of this parameter depends on \p pake_family, for more
+ * information consult the documentation of individual
+ * ::psa_pake_primitive_type_t constants).
+ *
+ * \return The constructed primitive value of type ::psa_pake_primitive_t.
+ * Return 0 if the requested primitive can't be encoded as
+ * ::psa_pake_primitive_t.
+ */
+#define PSA_PAKE_PRIMITIVE(pake_type, pake_family, pake_bits) \
+ (((pake_bits & 0xFFFF) != pake_bits) ? 0 : \
+ ((psa_pake_primitive_t) (((pake_type) << 24 | \
+ (pake_family) << 16) | (pake_bits))))
+
+#define PSA_PAKE_PRIMITIVE_GET_BITS(pake_primitive) \
+ ((size_t)(pake_primitive & 0xFFFF))
+
+#define PSA_PAKE_PRIMITIVE_GET_FAMILY(pake_primitive) \
+ ((psa_pake_family_t)((pake_primitive >> 16) & 0xFF))
+
+#define PSA_PAKE_PRIMITIVE_GET_TYPE(pake_primitive) \
+ ((psa_pake_primitive_type_t)((pake_primitive >> 24) & 0xFF))
+
+/** A key confirmation value that indicates a confirmed key in a PAKE cipher
+ * suite.
+ *
+ * This key confirmation value will result in the PAKE algorithm exchanging
+ * data to verify that the shared key is identical for both parties. This is
+ * the default key confirmation value in an initialized PAKE cipher suite
+ * object.
+ * Some algorithms do not include confirmation of the shared key.
+ */
+#define PSA_PAKE_CONFIRMED_KEY 0
+
+/** A key confirmation value that indicates an unconfirmed key in a PAKE cipher
+ * suite.
+ *
+ * This key confirmation value will result in the PAKE algorithm terminating
+ * prior to confirming that the resulting shared key is identical for both
+ * parties.
+ * Some algorithms do not support returning an unconfirmed shared key.
+ */
+#define PSA_PAKE_UNCONFIRMED_KEY 1
+
+ /** The key share being sent to or received from the peer.
+ *
+ * The format for both input and output at this step is the same as for public
+ * keys on the group determined by the primitive (::psa_pake_primitive_t) would
+ * be.
+ *
+ * For more information on the format, consult the documentation of
+ * psa_export_public_key().
+ *
+ * For information regarding how the group is determined, consult the
+ * documentation #PSA_PAKE_PRIMITIVE.
+ */
+#define PSA_PAKE_STEP_KEY_SHARE ((psa_pake_step_t) 0x01)
+
+/** A Schnorr NIZKP public key.
+ *
+ * This is the ephemeral public key in the Schnorr Non-Interactive
+ * Zero-Knowledge Proof (the value denoted by the letter 'V' in RFC 8235).
+ *
+ * The format for both input and output at this step is the same as for public
+ * keys on the group determined by the primitive (::psa_pake_primitive_t) would
+ * be.
+ *
+ * For more information on the format, consult the documentation of
+ * psa_export_public_key().
+ *
+ * For information regarding how the group is determined, consult the
+ * documentation #PSA_PAKE_PRIMITIVE.
+ */
+#define PSA_PAKE_STEP_ZK_PUBLIC ((psa_pake_step_t) 0x02)
+
+/** A Schnorr NIZKP proof.
+ *
+ * This is the proof in the Schnorr Non-Interactive Zero-Knowledge Proof (the
+ * value denoted by the letter 'r' in RFC 8235).
+ *
+ * Both for input and output, the value at this step is an integer less than
+ * the order of the group selected in the cipher suite. The format depends on
+ * the group as well:
+ *
+ * - For Montgomery curves, the encoding is little endian.
+ * - For everything else the encoding is big endian (see Section 2.3.8 of
+ * _SEC 1: Elliptic Curve Cryptography_ at https://www.secg.org/sec1-v2.pdf).
+ *
+ * In both cases leading zeroes are allowed as long as the length in bytes does
+ * not exceed the byte length of the group order.
+ *
+ * For information regarding how the group is determined, consult the
+ * documentation #PSA_PAKE_PRIMITIVE.
+ */
+#define PSA_PAKE_STEP_ZK_PROOF ((psa_pake_step_t) 0x03)
+
+/** The key confirmation value.
+ *
+ * This value is used during the key confirmation phase of a PAKE protocol.
+ * The format of the value depends on the algorithm and cipher suite:
+ *
+ * For SPAKE2+ algorithms, the format for both input and output at this step is
+ * the same as the output of the MAC algorithm specified in the cipher suite.
+ *
+ * For PSA_ALG_SRP_6, the format for both input and output at this step is
+ * the same as the output of the Hash algorithm specified.
+ */
+#define PSA_PAKE_STEP_CONFIRM ((psa_pake_step_t)0x04)
+
+/** The salt.
+ *
+ * The format for both input and output at this step is plain binary data.
+ */
+#define PSA_PAKE_STEP_SALT ((psa_pake_step_t)0x05)
+
+/** Retrieve the PAKE algorithm from a PAKE cipher suite.
+ *
+ * \param[in] cipher_suite The cipher suite structure to query.
+ *
+ * \return The PAKE algorithm stored in the cipher suite structure.
+ */
+static psa_algorithm_t psa_pake_cs_get_algorithm(
+ const psa_pake_cipher_suite_t *cipher_suite);
+
+/** Declare the PAKE algorithm for the cipher suite.
+ *
+ * This function overwrites any PAKE algorithm
+ * previously set in \p cipher_suite.
+ *
+ * \param[out] cipher_suite The cipher suite structure to write to.
+ * \param algorithm The PAKE algorithm to write.
+ * (`PSA_ALG_XXX` values of type ::psa_algorithm_t
+ * such that #PSA_ALG_IS_PAKE(\c alg) is true.)
+ * If this is 0, the PAKE algorithm in
+ * \p cipher_suite becomes unspecified.
+ */
+static void psa_pake_cs_set_algorithm(psa_pake_cipher_suite_t *cipher_suite,
+ psa_algorithm_t algorithm);
+
+/** Retrieve the primitive from a PAKE cipher suite.
+ *
+ * \param[in] cipher_suite The cipher suite structure to query.
+ *
+ * \return The primitive stored in the cipher suite structure.
+ */
+static psa_pake_primitive_t psa_pake_cs_get_primitive(
+ const psa_pake_cipher_suite_t *cipher_suite);
+
+/** Declare the primitive for a PAKE cipher suite.
+ *
+ * This function overwrites any primitive previously set in \p cipher_suite.
+ *
+ * \param[out] cipher_suite The cipher suite structure to write to.
+ * \param primitive The primitive to write. If this is 0, the
+ * primitive type in \p cipher_suite becomes
+ * unspecified.
+ */
+static void psa_pake_cs_set_primitive(psa_pake_cipher_suite_t *cipher_suite,
+ psa_pake_primitive_t primitive);
+
+/** The type of the state data structure for PAKE operations.
+ *
+ * Before calling any function on a PAKE operation object, the application
+ * must initialize it by any of the following means:
+ * - Set the structure to all-bits-zero, for example:
+ * \code
+ * psa_pake_operation_t operation;
+ * memset(&operation, 0, sizeof(operation));
+ * \endcode
+ * - Initialize the structure to logical zero values, for example:
+ * \code
+ * psa_pake_operation_t operation = {0};
+ * \endcode
+ * - Initialize the structure to the initializer #PSA_PAKE_OPERATION_INIT,
+ * for example:
+ * \code
+ * psa_pake_operation_t operation = PSA_PAKE_OPERATION_INIT;
+ * \endcode
+ * - Assign the result of the function psa_pake_operation_init()
+ * to the structure, for example:
+ * \code
+ * psa_pake_operation_t operation;
+ * operation = psa_pake_operation_init();
+ * \endcode
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure.
+ * Implementation details can change in future versions without notice. */
+typedef struct psa_pake_operation_s psa_pake_operation_t;
+
+/** Return an initial value for a PAKE operation object.
+ */
+static psa_pake_operation_t psa_pake_operation_init(void);
+
+/** Set the session information for a password-authenticated key exchange.
+ *
+ * The sequence of operations to set up a password-authenticated key exchange
+ * is as follows:
+ * -# Allocate an operation object which will be passed to all the functions
+ * listed here.
+ * -# Initialize the operation object with one of the methods described in the
+ * documentation for #psa_pake_operation_t, e.g.
+ * #PSA_PAKE_OPERATION_INIT.
+ * -# Call psa_pake_setup() to specify the password key and the cipher suite.
+ * -# Call \c psa_pake_set_xxx() functions on the operation to complete the
+ * setup. The exact sequence of \c psa_pake_set_xxx() functions that needs
+ * to be called depends on the algorithm in use.
+ *
+ * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX`
+ * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true)
+ * for more information.
+ *
+ * A typical sequence of calls to perform a password-authenticated key
+ * exchange:
+ * -# Call psa_pake_output(operation, #PSA_PAKE_STEP_KEY_SHARE, ...) to get the
+ * key share that needs to be sent to the peer.
+ * -# Call psa_pake_input(operation, #PSA_PAKE_STEP_KEY_SHARE, ...) to provide
+ * the key share that was received from the peer.
+ * -# Depending on the algorithm additional calls to psa_pake_output() and
+ * psa_pake_input() might be necessary.
+ * -# Call psa_pake_get_shared_key() for accessing the shared secret.
+ *
+ * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX`
+ * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true)
+ * for more information.
+ *
+ * If an error occurs at any step after a call to psa_pake_setup(),
+ * the operation will need to be reset by a call to psa_pake_abort(). The
+ * application may call psa_pake_abort() at any time after the operation
+ * has been initialized.
+ *
+ * After a successful call to psa_pake_setup(), the application must
+ * eventually terminate the operation. The following events terminate an
+ * operation:
+ * - A call to psa_pake_abort().
+ * - A successful call to psa_pake_get_shared_key().
+ *
+ * \param[in,out] operation The operation object to set up. It must have
+ * been initialized but not set up yet.
+ * \param[in] password_key Identifier of the key holding the password or
+ * a value derived from the password. It must
+ * remain valid until the operation terminates.
+ * The valid key types depend on the PAKE algorithm,
+ * and participant role.
+ * \param[in] cipher_suite The cipher suite to use. (A cipher suite fully
+ * characterizes a PAKE algorithm and determines
+ * the algorithm as well.)
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_HANDLE
+ * \p password_key is not a valid key identifier.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * The key does not have the #PSA_KEY_USAGE_DERIVE flag, or it does not
+ * permit the \p operation's algorithm.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The algorithm in \p cipher_suite is not a PAKE algorithm or encodes
+ * an invalid hash algorithm, or the PAKE primitive in \p cipher_suite
+ * is not compatible with the PAKE algorithm, or the key confirmation
+ * value in \p cipher_suite is not compatible with the PAKE algorithm
+ * and primitive, or the \p password_key is not compatible with
+ * \p cipher_suite.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * The algorithm in \p cipher_suite is not a supported PAKE algorithm,
+ * or the PAKE primitive in \p cipher_suite is not supported or not
+ * compatible with the PAKE algorithm, or the key confirmation value
+ * in \p cipher_suite is not supported or not compatible with the PAKE
+ * algorithm and primitive, or the key type or key size of
+ * \p password_key is not supported with \p cipher_suite.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid, or
+ * the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_pake_setup(psa_pake_operation_t *operation,
+ mbedtls_svc_key_id_t password_key,
+ const psa_pake_cipher_suite_t *cipher_suite);
+
+/** Set the application role for a password-authenticated key exchange.
+*
+* Not all PAKE algorithms need to differentiate the communicating entities.
+* It is optional to call this function for PAKEs that don't require a role
+* to be specified. For such PAKEs the application role parameter is ignored,
+* or #PSA_PAKE_ROLE_NONE can be passed as \c role.
+*
+* Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX`
+* values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true)
+* for more information.
+*
+* \param[in,out] operation The operation object to specify the
+* application's role for. It must have been set up
+* by psa_pake_setup() and not yet in use (neither
+* psa_pake_output() nor psa_pake_input() has been
+* called yet). It must be an operation for which
+* the application's role hasn't been specified
+* (psa_pake_set_role() hasn't been called yet).
+* \param role A value of type ::psa_pake_role_t indicating the
+* application's role in the PAKE algorithm
+* that is being set up. For more information see
+* the documentation of \c PSA_PAKE_ROLE_XXX
+* constants.
+*
+* \retval #PSA_SUCCESS
+* Success.
+* \retval #PSA_ERROR_INVALID_ARGUMENT
+* The \p role is not a valid PAKE role in the \p operation’s algorithm.
+* \retval #PSA_ERROR_NOT_SUPPORTED
+* The \p role for this algorithm is not supported or is not valid.
+* \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+* \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+* \retval #PSA_ERROR_BAD_STATE
+* The operation state is not valid, or
+* the library has not been previously initialized by psa_crypto_init().
+* It is implementation-dependent whether a failure to initialize
+* results in this error code.
+*/
+psa_status_t psa_pake_set_role(psa_pake_operation_t *operation,
+ psa_pake_role_t role);
+
+/** Set the user ID for a password-authenticated key exchange.
+ *
+ * Call this function to set the user ID. For PAKE algorithms that associate a
+ * user identifier with each side of the session you need to call
+ * psa_pake_set_peer() as well. For PAKE algorithms that associate a single
+ * user identifier with the session, call psa_pake_set_user() only.
+ *
+ * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX`
+ * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true)
+ * for more information.
+ *
+ * \param[in,out] operation The operation object to set the user ID for. It
+ * must have been set up by psa_pake_setup() and
+ * not yet in use (neither psa_pake_output() nor
+ * psa_pake_input() has been called yet). It must
+ * be on operation for which the user ID hasn't
+ * been set (psa_pake_set_user() hasn't been
+ * called yet).
+ * \param[in] user_id The user ID to authenticate with.
+ * \param user_id_len Size of the \p user_id buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p user_id is not valid for the \p operation's algorithm and cipher
+ * suite.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * The value of \p user_id is not supported by the implementation.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid, or
+ * the library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_pake_set_user(psa_pake_operation_t *operation,
+ const uint8_t *user_id,
+ size_t user_id_len);
+
+/** Set the peer ID for a password-authenticated key exchange.
+ *
+ * Call this function in addition to psa_pake_set_user() for PAKE algorithms
+ * that associate a user identifier with each side of the session. For PAKE
+ * algorithms that associate a single user identifier with the session, call
+ * psa_pake_set_user() only.
+ *
+ * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX`
+ * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true)
+ * for more information.
+ *
+ * \param[in,out] operation The operation object to set the peer ID for. It
+ * must have been set up by psa_pake_setup() and
+ * not yet in use (neither psa_pake_output() nor
+ * psa_pake_input() has been called yet). It must
+ * be on operation for which the peer ID hasn't
+ * been set (psa_pake_set_peer() hasn't been
+ * called yet).
+ * \param[in] peer_id The peer's ID to authenticate.
+ * \param peer_id_len Size of the \p peer_id buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p peer_id is not valid for the \p operation's algorithm and cipher
+ * suite.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * The algorithm doesn't associate a second identity with the session.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * Calling psa_pake_set_peer() is invalid with the \p operation's
+ * algorithm, the operation state is not valid, or the library has not
+ * been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_pake_set_peer(psa_pake_operation_t *operation,
+ const uint8_t *peer_id,
+ size_t peer_id_len);
+
+/** Set the context data for a password-authenticated key exchange.
+ *
+ * Call this function for PAKE algorithms that accept additional context data
+ * as part of the protocol setup.
+ *
+ * Refer to the documentation of individual PAKE algorithm types (`PSA_ALG_XXX`
+ * values of type ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true)
+ * for more information.
+ *
+ * \param[in,out] operation The operation object to set the context for. It
+ * must have been set up by psa_pake_setup() and
+ * not yet in use (neither psa_pake_output() nor
+ * psa_pake_input() has been called yet). It must
+ * be on operation for which the context hasn't
+ * been set (psa_pake_set_context() hasn't been
+ * called yet).
+ * \param[in] context The context.
+ * \param context_len Size of the \p context buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The \p context is not valid for the operation’s algorithm and cipher suite.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * The \p context is not supported by the implementation.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * Calling psa_pake_set_context() is invalid with the \p operation's
+ * algorithm, the operation state is not valid, or the library has not
+ * been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_pake_set_context(psa_pake_operation_t *operation,
+ const uint8_t *context,
+ size_t context_len);
+
+/** Get output for a step of a password-authenticated key exchange.
+ *
+ * Depending on the algorithm being executed, you might need to call this
+ * function several times or you might not need to call this at all.
+ *
+ * The exact sequence of calls to perform a password-authenticated key
+ * exchange depends on the algorithm in use. Refer to the documentation of
+ * individual PAKE algorithm types (`PSA_ALG_XXX` values of type
+ * ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) for more
+ * information.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_pake_abort().
+ *
+ * \param[in,out] operation Active PAKE operation.
+ * \param step The step of the algorithm for which the output
+ * is requested.
+ * \param[out] output Buffer where the output is to be written in the
+ * format appropriate for this \p step. Refer to
+ * the documentation of the individual
+ * \c PSA_PAKE_STEP_XXX constants for more
+ * information.
+ * \param output_size Size of the \p output buffer in bytes. This must
+ * be at least #PSA_PAKE_OUTPUT_SIZE(\c alg, \c
+ * primitive, \p output_step) where \c alg and
+ * \p primitive are the PAKE algorithm and primitive
+ * in the operation's cipher suite, and \p step is
+ * the output step.
+ *
+ * \param[out] output_length On success, the number of bytes of the returned
+ * output.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * The size of the \p output buffer is too small.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p step is not compatible with the operation's algorithm.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p step is not supported with the operation's algorithm.
+ * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
+ * \retval #PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active, and fully set
+ * up, and this call must conform to the algorithm's requirements
+ * for ordering of input and output steps), or the library has not
+ * been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_pake_output(psa_pake_operation_t *operation,
+ psa_pake_step_t step,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length);
+
+/** Provide input for a step of a password-authenticated key exchange.
+ *
+ * Depending on the algorithm being executed, you might need to call this
+ * function several times or you might not need to call this at all.
+ *
+ * The exact sequence of calls to perform a password-authenticated key
+ * exchange depends on the algorithm in use. Refer to the documentation of
+ * individual PAKE algorithm types (`PSA_ALG_XXX` values of type
+ * ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) for more
+ * information.
+ *
+ * If this function returns an error status, the operation enters an error
+ * state and must be aborted by calling psa_pake_abort().
+ *
+ * \param[in,out] operation Active PAKE operation.
+ * \param step The step for which the input is provided.
+ * \param[in] input Buffer containing the input in the format
+ * appropriate for this \p step. Refer to the
+ * documentation of the individual
+ * \c PSA_PAKE_STEP_XXX constants for more
+ * information.
+ * \param input_length Size of the \p input buffer in bytes.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_INVALID_SIGNATURE
+ * The verification fails for a #PSA_PAKE_STEP_ZK_PROOF input step.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \p step is not compatible with the operation's algorithm, or
+ * \p input_length is not compatible with the \p operation’s algorithm,
+ * or the \p input is not valid for the \p operation's algorithm,
+ * cipher suite or \p step.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \p step is not supported with the operation's algorithm, or
+ * \p step p is not supported with the \p operation's algorithm, or the
+ * \p input is not supported for the \p operation's algorithm, cipher
+ * suite or \p step.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
+ * \retval #PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The operation state is not valid (it must be active, and fully set
+ * up, and this call must conform to the algorithm's requirements
+ * for ordering of input and output steps), or the library has not
+ * been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_pake_input(psa_pake_operation_t *operation,
+ psa_pake_step_t step,
+ const uint8_t *input,
+ size_t input_length);
+
+/** Get shared secret from a PAKE.
+ *
+ * This is the final call in a PAKE operation, which retrieves the shared
+ * secret as a key. It is recommended that this key is used as an input to a
+ * key derivation operation to produce additional cryptographic keys. For
+ * some PAKE algorithms, the shared secret is also suitable for use as a key
+ * in cryptographic operations such as encryption. Refer to the documentation
+ * of individual PAKE algorithm types (`PSA_ALG_XXX` values of type
+ * ::psa_algorithm_t such that #PSA_ALG_IS_PAKE(\c alg) is true) for more
+ * information.
+ *
+ * Depending on the key confirmation requested in the cipher suite,
+ * psa_pake_get_shared_key() must be called either before or after the
+ * key-confirmation output and input steps for the PAKE algorithm. The key
+ * confirmation affects the guarantees that can be made about the shared key:
+ *
+ * Unconfirmed key
+ * If the cipher suite used to set up the operation requested an unconfirmed
+ * key, the application must call psa_pake_get_shared_key() after the
+ * key-exchange output and input steps are completed. The PAKE algorithm
+ * provides a cryptographic guarantee that only a peer who used the same
+ * password, and identity inputs, is able to compute the same key. However,
+ * there is no guarantee that the peer is the participant it claims to be,
+ * and was able to compute the same key.
+ * Since the peer is not authenticated, no action should be taken that assumes
+ * that the peer is who it claims to be. For example, do not access restricted
+ * files on the peer’s behalf until an explicit authentication has succeeded.
+ * Note:
+ * Some PAKE algorithms do not enable the output of the shared secret until it
+ * has been confirmed.
+ *
+ * Confirmed key
+ * If the cipher suite used to set up the operation requested a confirmed key,
+ * the application must call psa_pake_get_shared_key() after the key-exchange
+ * and key-confirmation output and input steps are completed.
+ * Following key confirmation, the PAKE algorithm provides a cryptographic
+ * guarantee that the peer used the same password and identity inputs, and has
+ * computed the identical shared secret key.
+ * Since the peer is not authenticated, no action should be taken that assumes
+ * that the peer is who it claims to be. For example, do not access restricted
+ * files on the peer’s behalf until an explicit authentication has succeeded.
+ * Note:
+ * Some PAKE algorithms do not include any key-confirmation steps.
+ *
+ * The exact sequence of calls to perform a password-authenticated key
+ * exchange depends on the algorithm in use.
+ *
+ * When this function returns successfully, \p operation becomes inactive.
+ * If this function returns an error status, both \p operation
+ * and \c key_derivation operations enter an error state and must be aborted
+ * by calling psa_pake_abort().
+ *
+ * \param[in,out] operation Active PAKE operation.
+ * \param[in] attributes The attributes for the new key.
+ * \param[out] key On success, an identifier for the newly created
+ * key. #PSA_KEY_ID_NULL on failure.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * The implementation does not permit creating a key with the
+ * specified attributes due to some implementation-specific policy.
+ * \retval #PSA_ERROR_ALREADY_EXISTS
+ * This is an attempt to create a persistent key, and there is
+ * already a persistent key with the given identifier.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * The key type is not valid for output from this operation’s
+ * algorithm, or the key size is nonzero, or the key lifetime is
+ * invalid, the key identifier is not valid for the key lifetime,
+ * or the key usage flags include invalid values, or the key’s
+ * permitted-usage algorithm is invalid, or the key attributes,
+ * as a whole, are invalid.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * The key attributes, as a whole, are not supported for creation
+ * from a PAKE secret, either by the implementation in general or
+ * in the specified storage location.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
+ * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
+ * \retval #PSA_ERROR_DATA_INVALID \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The PAKE operation state is not valid (it must be ready to return
+ * the shared secret), or the library has not been previously
+ * initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_pake_get_shared_key(psa_pake_operation_t *operation,
+ const psa_key_attributes_t *attributes,
+ mbedtls_svc_key_id_t *key);
+
+/** Abort a PAKE operation.
+ *
+ * Aborting an operation frees all associated resources except for the \c
+ * operation structure itself. Once aborted, the operation object can be reused
+ * for another operation by calling psa_pake_setup() again.
+ *
+ * This function may be called at any time after the operation
+ * object has been initialized as described in #psa_pake_operation_t.
+ *
+ * In particular, calling psa_pake_abort() after the operation has been
+ * terminated by a call to psa_pake_abort() or psa_pake_get_shared_key()
+ * is safe and has no effect.
+ *
+ * \param[in,out] operation The operation to abort.
+ *
+ * \retval #PSA_SUCCESS
+ * Success.
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
+ * \retval #PSA_ERROR_BAD_STATE
+ * The library has not been previously initialized by psa_crypto_init().
+ * It is implementation-dependent whether a failure to initialize
+ * results in this error code.
+ */
+psa_status_t psa_pake_abort(psa_pake_operation_t *operation);
+
+/**@}*/
+
+/** A sufficient output buffer size for psa_pake_output().
+ *
+ * If the size of the output buffer is at least this large, it is guaranteed
+ * that psa_pake_output() will not fail due to an insufficient output buffer
+ * size. The actual size of the output might be smaller in any given call.
+ *
+ * See also #PSA_PAKE_OUTPUT_MAX_SIZE
+ *
+ * \param alg A PAKE algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_PAKE(\p alg) is true).
+ * \param primitive A primitive of type ::psa_pake_primitive_t that is
+ * compatible with algorithm \p alg.
+ * \param output_step A value of type ::psa_pake_step_t that is valid for the
+ * algorithm \p alg.
+ * \return A sufficient output buffer size for the specified
+ * PAKE algorithm, primitive, and output step. If the
+ * PAKE algorithm, primitive, or output step is not
+ * recognized, or the parameters are incompatible,
+ * return 0.
+ */
+#define PSA_PAKE_OUTPUT_SIZE(alg, primitive, output_step) \
+ (output_step == PSA_PAKE_STEP_KEY_SHARE ? \
+ PSA_PAKE_PRIMITIVE_GET_TYPE(primitive) == PSA_PAKE_PRIMITIVE_TYPE_DH ? \
+ PSA_BITS_TO_BYTES(PSA_PAKE_PRIMITIVE_GET_BITS(primitive)) : \
+ PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_PAKE_PRIMITIVE_GET_BITS(primitive)) : \
+ output_step == PSA_PAKE_STEP_ZK_PUBLIC ? \
+ PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_PAKE_PRIMITIVE_GET_BITS(primitive)) : \
+ output_step == PSA_PAKE_STEP_ZK_PROOF ? \
+ PSA_BITS_TO_BYTES(PSA_PAKE_PRIMITIVE_GET_BITS(primitive)) : \
+ output_step == PSA_PAKE_STEP_CONFIRM ? \
+ PSA_ALG_IS_SPAKE2P_CMAC(alg) ? \
+ PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC) : \
+ PSA_HASH_LENGTH(alg) : \
+ 0u)
+
+/** A sufficient input buffer size for psa_pake_input().
+ *
+ * The value returned by this macro is guaranteed to be large enough for any
+ * valid input to psa_pake_input() in an operation with the specified
+ * parameters.
+ *
+ * See also #PSA_PAKE_INPUT_MAX_SIZE
+ *
+ * \param alg A PAKE algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_PAKE(\p alg) is true).
+ * \param primitive A primitive of type ::psa_pake_primitive_t that is
+ * compatible with algorithm \p alg.
+ * \param input_step A value of type ::psa_pake_step_t that is valid for the
+ * algorithm \p alg.
+ * \return A sufficient input buffer size for the specified
+ * input, cipher suite and algorithm. If the cipher suite,
+ * the input type or PAKE algorithm is not recognized, or
+ * the parameters are incompatible, return 0.
+ */
+#define PSA_PAKE_INPUT_SIZE(alg, primitive, input_step) \
+ (input_step == PSA_PAKE_STEP_KEY_SHARE ? \
+ PSA_PAKE_PRIMITIVE_GET_TYPE(primitive) == PSA_PAKE_PRIMITIVE_TYPE_DH ? \
+ PSA_BITS_TO_BYTES(PSA_PAKE_PRIMITIVE_GET_BITS(primitive)) : \
+ PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_PAKE_PRIMITIVE_GET_BITS(primitive)) : \
+ input_step == PSA_PAKE_STEP_ZK_PUBLIC ? \
+ PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_PAKE_PRIMITIVE_GET_BITS(primitive)) : \
+ input_step == PSA_PAKE_STEP_ZK_PROOF ? \
+ PSA_BITS_TO_BYTES(PSA_PAKE_PRIMITIVE_GET_BITS(primitive)) : \
+ input_step == PSA_PAKE_STEP_CONFIRM ? \
+ PSA_ALG_IS_SPAKE2P_CMAC(alg) ? \
+ PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128, PSA_ALG_CMAC) : \
+ PSA_HASH_LENGTH(alg) : \
+ input_step == PSA_PAKE_STEP_SALT ? \
+ 64u : \
+ 0u)
+
+/** Output buffer size for psa_pake_output() for any of the supported PAKE
+ * algorithm and primitive suites and output step.
+ *
+ * This macro must expand to a compile-time constant integer.
+ *
+ * The value of this macro must be at least as large as the largest value
+ * returned by PSA_PAKE_OUTPUT_SIZE()
+ *
+ * See also #PSA_PAKE_OUTPUT_SIZE(\p alg, \p primitive, \p output_step).
+ */
+#ifdef PSA_WANT_ALG_SRP_6
+#define PSA_PAKE_OUTPUT_MAX_SIZE PSA_BITS_TO_BYTES(PSA_VENDOR_FFDH_MAX_KEY_BITS)
+#else
+#define PSA_PAKE_OUTPUT_MAX_SIZE PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
+#endif
+
+/** Input buffer size for psa_pake_input() for any of the supported PAKE
+ * algorithm and primitive suites and input step.
+ *
+ * This macro must expand to a compile-time constant integer.
+ *
+ * The value of this macro must be at least as large as the largest value
+ * returned by PSA_PAKE_INPUT_SIZE()
+ *
+ * See also #PSA_PAKE_INPUT_SIZE(\p alg, \p primitive, \p output_step).
+ */
+#ifdef PSA_WANT_ALG_SRP_6
+#define PSA_PAKE_INPUT_MAX_SIZE PSA_BITS_TO_BYTES(PSA_VENDOR_FFDH_MAX_KEY_BITS)
+#else
+#define PSA_PAKE_INPUT_MAX_SIZE PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
+#endif
+
+static inline psa_algorithm_t psa_pake_cs_get_algorithm(
+ const psa_pake_cipher_suite_t *cipher_suite)
+{
+ return cipher_suite->algorithm;
+}
+
+static inline void psa_pake_cs_set_algorithm(
+ psa_pake_cipher_suite_t *cipher_suite,
+ psa_algorithm_t algorithm)
+{
+ if (!PSA_ALG_IS_PAKE(algorithm)) {
+ cipher_suite->algorithm = 0;
+ } else {
+ cipher_suite->algorithm = algorithm;
+ }
+}
+
+static inline psa_pake_primitive_t psa_pake_cs_get_primitive(
+ const psa_pake_cipher_suite_t *cipher_suite)
+{
+ return cipher_suite->primitive;
+}
+
+static inline void psa_pake_cs_set_primitive(
+ psa_pake_cipher_suite_t *cipher_suite,
+ psa_pake_primitive_t primitive)
+{
+ cipher_suite->primitive = primitive;
+}
+
+static inline uint32_t psa_pake_cs_get_key_confirmation(
+ const psa_pake_cipher_suite_t* cipher_suite)
+{
+ return cipher_suite->key_confirmation;
+}
+
+static inline void psa_pake_cs_set_key_confirmation(
+ psa_pake_cipher_suite_t* cipher_suite,
+ uint32_t key_confirmation)
+{
+ cipher_suite->key_confirmation = key_confirmation;
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PSA_CRYPTO_EXTRA_H */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_platform.h b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_platform.h
new file mode 100644
index 0000000..c462898
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_platform.h
@@ -0,0 +1,56 @@
+
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+/**
+ * \file psa/crypto_platform.h
+ *
+ * \brief PSA cryptography module: TF-M platform definitions
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h.
+ *
+ * This file contains platform-dependent type definitions.
+ *
+ * In implementations with isolation between the application and the
+ * cryptography module, implementers should take care to ensure that
+ * the definitions that are exposed to applications match what the
+ * module implements.
+ */
+
+#ifndef PSA_CRYPTO_PLATFORM_H
+#define PSA_CRYPTO_PLATFORM_H
+
+/* PSA requires several types which C99 provides in stdint.h. */
+#include <stdint.h>
+
+/* No particular platform definition is currently required for the
+ * TF-M client view of the PSA Crytpo APIs, but we keep this header
+ * available for reference and future compatibility
+ */
+
+#if defined(__NRF_TFM__) && defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
+/*
+ * This header file is provided by TF-M and is only intended to be
+ * used by clients of PSA, not implementations of PSA. So secure
+ * partitions in the TF-M image (other than the crypto partition
+ * itself), and non-secure images.
+ *
+ * In NCS, the TF-M crypto partition should be using PSA header files
+ * from Oberon as it is Oberon that implements PSA.
+ *
+ * We want to detect that a source file is in the crypto partition,
+ * but has accidentally used this TF-M header instead of headers
+ * provided by Oberon. To do this we would ideally have a
+ * IS_IN_CRYPTO_PARTION define, but since there is no such define at
+ * time of writing we check MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
+ * instead, which should only be defined by the PSA implementation,
+ * not by PSA clients.
+ */
+#error "The TF-M image included the TF-M PSA headers but should have included Oberon PSA headers"
+#endif
+
+#endif /* PSA_CRYPTO_PLATFORM_H */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_sizes.h b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_sizes.h
new file mode 100644
index 0000000..94da583
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_sizes.h
@@ -0,0 +1,1351 @@
+/*
+ * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+/**
+ * \file psa/crypto_sizes.h
+ *
+ * \brief PSA cryptography module: Mbed TLS buffer size macros
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h.
+ *
+ * This file contains the definitions of macros that are useful to
+ * compute buffer sizes. The signatures and semantics of these macros
+ * are standardized, but the definitions are not, because they depend on
+ * the available algorithms and, in some cases, on permitted tolerances
+ * on buffer sizes.
+ *
+ * In implementations with isolation between the application and the
+ * cryptography module, implementers should take care to ensure that
+ * the definitions that are exposed to applications match what the
+ * module implements.
+ *
+ * Macros that compute sizes whose values do not depend on the
+ * implementation are in crypto.h.
+ */
+
+#ifndef PSA_CRYPTO_SIZES_H
+#define PSA_CRYPTO_SIZES_H
+
+#define PSA_BITS_TO_BYTES(bits) (((bits) + 7u) / 8u)
+#define PSA_BYTES_TO_BITS(bytes) ((bytes) * 8u)
+#define PSA_MAX_OF_THREE(a, b, c) ((a) <= (b) ? (b) <= (c) ? \
+ (c) : (b) : (a) <= (c) ? (c) : (a))
+
+#define PSA_ROUND_UP_TO_MULTIPLE(block_size, length) \
+ (((length) + (block_size) - 1) / (block_size) * (block_size))
+
+/** The size of the output of psa_hash_finish(), in bytes.
+ *
+ * This is also the hash size that psa_hash_verify() expects.
+ *
+ * \param alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p alg) is true), or an HMAC algorithm
+ * (#PSA_ALG_HMAC(\c hash_alg) where \c hash_alg is a
+ * hash algorithm).
+ *
+ * \return The hash size for the specified hash algorithm.
+ * If the hash algorithm is not recognized, return 0.
+ */
+#define PSA_HASH_LENGTH(alg) \
+ ( \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 16u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 20u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 20u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 28u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 32u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 48u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 64u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 28u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 32u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 28u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 32u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 48u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 64u : \
+ 0u)
+
+/** The input block size of a hash algorithm, in bytes.
+ *
+ * Hash algorithms process their input data in blocks. Hash operations will
+ * retain any partial blocks until they have enough input to fill the block or
+ * until the operation is finished.
+ * This affects the output from psa_hash_suspend().
+ *
+ * \param alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * PSA_ALG_IS_HASH(\p alg) is true).
+ *
+ * \return The block size in bytes for the specified hash algorithm.
+ * If the hash algorithm is not recognized, return 0.
+ * An implementation can return either 0 or the correct size for a
+ * hash algorithm that it recognizes, but does not support.
+ */
+#define PSA_HASH_BLOCK_LENGTH(alg) \
+ ( \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 64u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 64u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 64u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 64u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 64u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 128u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 128u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 128u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 128u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 144u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 136u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 104u : \
+ PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 72u : \
+ 0u)
+
+/** \def PSA_HASH_MAX_SIZE
+ *
+ * Maximum size of a hash.
+ *
+ * This macro expands to a compile-time constant integer. This value
+ * is the maximum size of a hash in bytes.
+ */
+/* Note: for HMAC-SHA-3, the block size is 144 bytes for HMAC-SHA3-224,
+ * 136 bytes for HMAC-SHA3-256, 104 bytes for SHA3-384, 72 bytes for
+ * HMAC-SHA3-512. */
+/* Note: PSA_HASH_MAX_SIZE should be kept in sync with MBEDTLS_MD_MAX_SIZE,
+ * see the note on MBEDTLS_MD_MAX_SIZE for details.
+ */
+#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
+#if defined(PSA_WANT_ALG_SHA3_224)
+#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 144u
+#elif defined(PSA_WANT_ALG_SHA3_256)
+#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 136u
+#elif defined(PSA_WANT_ALG_SHA_512)
+#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 128u
+#elif defined(PSA_WANT_ALG_SHA_384)
+#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 128u
+#elif defined(PSA_WANT_ALG_SHA3_384)
+#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 104u
+#elif defined(PSA_WANT_ALG_SHA3_512)
+#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 72u
+#elif defined(PSA_WANT_ALG_SHA_256)
+#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 64u
+#elif defined(PSA_WANT_ALG_SHA_224)
+#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 64u
+#else /* SHA-1 or smaller */
+#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 64u
+#endif
+
+#if defined(PSA_WANT_ALG_SHA_512) || defined(PSA_WANT_ALG_SHA3_512)
+#define PSA_HASH_MAX_SIZE 64u
+#elif defined(PSA_WANT_ALG_SHA_384) || defined(PSA_WANT_ALG_SHA3_384)
+#define PSA_HASH_MAX_SIZE 48u
+#elif defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA3_256)
+#define PSA_HASH_MAX_SIZE 32u
+#elif defined(PSA_WANT_ALG_SHA_224) || defined(PSA_WANT_ALG_SHA3_224)
+#define PSA_HASH_MAX_SIZE 28u
+#else /* SHA-1 or smaller */
+#define PSA_HASH_MAX_SIZE 20u
+#endif
+#else /* defined(MBEDTLS_PSA_CRYPTO_CONFIG) */
+/* Without any PSA configuration we must assume the maximum size possible. */
+#define PSA_HASH_MAX_SIZE 64u
+#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 144u
+#endif /* defined(MBEDTLS_PSA_CRYPTO_CONFIG) */
+
+/** \def PSA_MAC_MAX_SIZE
+ *
+ * Maximum size of a MAC.
+ *
+ * This macro expands to a compile-time constant integer. This value
+ * is the maximum size of a MAC in bytes.
+ */
+/* All non-HMAC MACs have a maximum size that's smaller than the
+ * minimum possible value of PSA_HASH_MAX_SIZE in this implementation. */
+/* Note that the encoding of truncated MAC algorithms limits this value
+ * to 64 bytes.
+ */
+#define PSA_MAC_MAX_SIZE PSA_HASH_MAX_SIZE
+
+/** The length of a tag for an AEAD algorithm, in bytes.
+ *
+ * This macro can be used to allocate a buffer of sufficient size to store the
+ * tag output from psa_aead_finish().
+ *
+ * See also #PSA_AEAD_TAG_MAX_SIZE.
+ *
+ * \param key_type The type of the AEAD key.
+ * \param key_bits The size of the AEAD key in bits.
+ * \param alg An AEAD algorithm
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(\p alg) is true).
+ *
+ * \return The tag length for the specified algorithm and key.
+ * If the AEAD algorithm does not have an identified
+ * tag that can be distinguished from the rest of
+ * the ciphertext, return 0.
+ * If the key type or AEAD algorithm is not
+ * recognized, or the parameters are incompatible,
+ * return 0.
+ */
+#define PSA_AEAD_TAG_LENGTH(key_type, key_bits, alg) \
+ (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 ? \
+ PSA_ALG_AEAD_GET_TAG_LENGTH(alg) : \
+ ((void) (key_bits), 0u))
+
+/** The maximum tag size for all supported AEAD algorithms, in bytes.
+ *
+ * See also #PSA_AEAD_TAG_LENGTH(\p key_type, \p key_bits, \p alg).
+ */
+#define PSA_AEAD_TAG_MAX_SIZE 16u
+
+/* The maximum size of an RSA key on this implementation, in bits.
+ * This is a vendor-specific macro.
+ *
+ * Mbed TLS does not set a hard limit on the size of RSA keys: any key
+ * whose parameters fit in a bignum is accepted. However large keys can
+ * induce a large memory usage and long computation times. Unlike other
+ * auxiliary macros in this file and in crypto.h, which reflect how the
+ * library is configured, this macro defines how the library is
+ * configured. This implementation refuses to import or generate an
+ * RSA key whose size is larger than the value defined here.
+ *
+ * Note that an implementation may set different size limits for different
+ * operations, and does not need to accept all key sizes up to the limit. */
+#define PSA_VENDOR_RSA_MAX_KEY_BITS 4096u
+
+/* The minimum size of an RSA key on this implementation, in bits.
+ * This is a vendor-specific macro.
+ *
+ * Limits RSA key generation to a minimum due to avoid accidental misuse.
+ * This value cannot be less than 128 bits.
+ */
+#if defined(MBEDTLS_RSA_GEN_KEY_MIN_BITS)
+#define PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS MBEDTLS_RSA_GEN_KEY_MIN_BITS
+#else
+#define PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS 1024
+#endif
+
+/* The maximum size of an DH key on this implementation, in bits.
+ *
+ * Note that an implementation may set different size limits for different
+ * operations, and does not need to accept all key sizes up to the limit.
+ */
+#define PSA_VENDOR_FFDH_MAX_KEY_BITS 8192u
+
+/* The maximum size of an ECC key on this implementation, in bits.
+ * This is a vendor-specific macro. */
+#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
+#if defined(PSA_WANT_ECC_SECP_R1_521)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 521u
+#elif defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 512u
+#elif defined(PSA_WANT_ECC_MONTGOMERY_448)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 448u
+#elif defined(PSA_WANT_ECC_SECP_R1_384)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 384u
+#elif defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 384u
+#elif defined(PSA_WANT_ECC_SECP_R1_256)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 256u
+#elif defined(PSA_WANT_ECC_SECP_K1_256)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 256u
+#elif defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 256u
+#elif defined(PSA_WANT_ECC_MONTGOMERY_255)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 255u
+#elif defined(PSA_WANT_ECC_SECP_R1_224)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 224u
+#elif defined(PSA_WANT_ECC_SECP_K1_224)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 224u
+#elif defined(PSA_WANT_ECC_SECP_R1_192)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 192u
+#elif defined(PSA_WANT_ECC_SECP_K1_192)
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 192u
+#else
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 0u
+#endif
+#else /* defined(MBEDTLS_PSA_CRYPTO_CONFIG) */
+/* Without any PSA configuration we must assume the maximum size possible. */
+#define PSA_VENDOR_ECC_MAX_CURVE_BITS 521
+#endif /* defined(MBEDTLS_PSA_CRYPTO_CONFIG) */
+
+/** This macro returns the maximum supported length of the PSK for the
+ * TLS-1.2 PSK-to-MS key derivation
+ * (#PSA_ALG_TLS12_PSK_TO_MS(\c hash_alg)).
+ *
+ * The maximum supported length does not depend on the chosen hash algorithm.
+ *
+ * Quoting RFC 4279, Sect 5.3:
+ * TLS implementations supporting these ciphersuites MUST support
+ * arbitrary PSK identities up to 128 octets in length, and arbitrary
+ * PSKs up to 64 octets in length. Supporting longer identities and
+ * keys is RECOMMENDED.
+ *
+ * Therefore, no implementation should define a value smaller than 64
+ * for #PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE.
+ */
+#define PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE 128u
+
+/* The expected size of input passed to psa_tls12_ecjpake_to_pms_input,
+ * which is expected to work with P-256 curve only. */
+#define PSA_TLS12_ECJPAKE_TO_PMS_INPUT_SIZE 65u
+
+/* The size of a serialized K.X coordinate to be used in
+ * psa_tls12_ecjpake_to_pms_input. This function only accepts the P-256
+ * curve. */
+#define PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE 32u
+
+/* The maximum number of iterations for PBKDF2 on this implementation, in bits.
+ * This is a vendor-specific macro. This can be configured if necessary.
+ */
+#define PSA_VENDOR_PBKDF2_MAX_ITERATIONS 0xffffffffU
+
+/** The maximum size of a block cipher. */
+#define PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE 16u
+
+/** The size of the output of psa_mac_sign_finish(), in bytes.
+ *
+ * This is also the MAC size that psa_mac_verify_finish() expects.
+ *
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * \param key_type The type of the MAC key.
+ * \param key_bits The size of the MAC key in bits.
+ * \param alg A MAC algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_MAC(\p alg) is true).
+ *
+ * \return The MAC size for the specified algorithm with
+ * the specified key parameters.
+ * \return 0 if the MAC algorithm is not recognized.
+ * \return Either 0 or the correct size for a MAC algorithm that
+ * the implementation recognizes, but does not support.
+ * \return Unspecified if the key parameters are not consistent
+ * with the algorithm.
+ */
+#define PSA_MAC_LENGTH(key_type, key_bits, alg) \
+ ((alg) & PSA_ALG_MAC_TRUNCATION_MASK ? PSA_MAC_TRUNCATED_LENGTH(alg) : \
+ PSA_ALG_IS_HMAC(alg) ? PSA_HASH_LENGTH(PSA_ALG_HMAC_GET_HASH(alg)) : \
+ PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) ? PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \
+ ((void) (key_type), (void) (key_bits), 0u))
+
+/** The maximum size of the output of psa_aead_encrypt(), in bytes.
+ *
+ * If the size of the ciphertext buffer is at least this large, it is
+ * guaranteed that psa_aead_encrypt() will not fail due to an
+ * insufficient buffer size. Depending on the algorithm, the actual size of
+ * the ciphertext may be smaller.
+ *
+ * See also #PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(\p plaintext_length).
+ *
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * \param key_type A symmetric key type that is
+ * compatible with algorithm \p alg.
+ * \param alg An AEAD algorithm
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(\p alg) is true).
+ * \param plaintext_length Size of the plaintext in bytes.
+ *
+ * \return The AEAD ciphertext size for the specified
+ * algorithm.
+ * If the key type or AEAD algorithm is not
+ * recognized, or the parameters are incompatible,
+ * return 0.
+ */
+#define PSA_AEAD_ENCRYPT_OUTPUT_SIZE(key_type, alg, plaintext_length) \
+ (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 ? \
+ (plaintext_length) + PSA_ALG_AEAD_GET_TAG_LENGTH(alg) : \
+ 0u)
+
+/** A sufficient output buffer size for psa_aead_encrypt(), for any of the
+ * supported key types and AEAD algorithms.
+ *
+ * If the size of the ciphertext buffer is at least this large, it is guaranteed
+ * that psa_aead_encrypt() will not fail due to an insufficient buffer size.
+ *
+ * \note This macro returns a compile-time constant if its arguments are
+ * compile-time constants.
+ *
+ * See also #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\p key_type, \p alg,
+ * \p plaintext_length).
+ *
+ * \param plaintext_length Size of the plaintext in bytes.
+ *
+ * \return A sufficient output buffer size for any of the
+ * supported key types and AEAD algorithms.
+ *
+ */
+#define PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(plaintext_length) \
+ ((plaintext_length) + PSA_AEAD_TAG_MAX_SIZE)
+
+
+/** The maximum size of the output of psa_aead_decrypt(), in bytes.
+ *
+ * If the size of the plaintext buffer is at least this large, it is
+ * guaranteed that psa_aead_decrypt() will not fail due to an
+ * insufficient buffer size. Depending on the algorithm, the actual size of
+ * the plaintext may be smaller.
+ *
+ * See also #PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(\p ciphertext_length).
+ *
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * \param key_type A symmetric key type that is
+ * compatible with algorithm \p alg.
+ * \param alg An AEAD algorithm
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(\p alg) is true).
+ * \param ciphertext_length Size of the plaintext in bytes.
+ *
+ * \return The AEAD ciphertext size for the specified
+ * algorithm.
+ * If the key type or AEAD algorithm is not
+ * recognized, or the parameters are incompatible,
+ * return 0.
+ */
+#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(key_type, alg, ciphertext_length) \
+ (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 && \
+ (ciphertext_length) > PSA_ALG_AEAD_GET_TAG_LENGTH(alg) ? \
+ (ciphertext_length) - PSA_ALG_AEAD_GET_TAG_LENGTH(alg) : \
+ 0u)
+
+/** A sufficient output buffer size for psa_aead_decrypt(), for any of the
+ * supported key types and AEAD algorithms.
+ *
+ * If the size of the plaintext buffer is at least this large, it is guaranteed
+ * that psa_aead_decrypt() will not fail due to an insufficient buffer size.
+ *
+ * \note This macro returns a compile-time constant if its arguments are
+ * compile-time constants.
+ *
+ * See also #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\p key_type, \p alg,
+ * \p ciphertext_length).
+ *
+ * \param ciphertext_length Size of the ciphertext in bytes.
+ *
+ * \return A sufficient output buffer size for any of the
+ * supported key types and AEAD algorithms.
+ *
+ */
+#define PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(ciphertext_length) \
+ (ciphertext_length)
+
+/** The default nonce size for an AEAD algorithm, in bytes.
+ *
+ * This macro can be used to allocate a buffer of sufficient size to
+ * store the nonce output from #psa_aead_generate_nonce().
+ *
+ * See also #PSA_AEAD_NONCE_MAX_SIZE.
+ *
+ * \note This is not the maximum size of nonce supported as input to
+ * #psa_aead_set_nonce(), #psa_aead_encrypt() or #psa_aead_decrypt(),
+ * just the default size that is generated by #psa_aead_generate_nonce().
+ *
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * \param key_type A symmetric key type that is compatible with
+ * algorithm \p alg.
+ *
+ * \param alg An AEAD algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(\p alg) is true).
+ *
+ * \return The default nonce size for the specified key type and algorithm.
+ * If the key type or AEAD algorithm is not recognized,
+ * or the parameters are incompatible, return 0.
+ */
+#define PSA_AEAD_NONCE_LENGTH(key_type, alg) \
+ (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) == 16 ? \
+ MBEDTLS_PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_CCM) ? 13u : \
+ MBEDTLS_PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_GCM) ? 12u : \
+ 0u : \
+ (key_type) == PSA_KEY_TYPE_CHACHA20 && \
+ MBEDTLS_PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_CHACHA20_POLY1305) ? 12u : \
+ 0u)
+
+/** The maximum default nonce size among all supported pairs of key types and
+ * AEAD algorithms, in bytes.
+ *
+ * This is equal to or greater than any value that #PSA_AEAD_NONCE_LENGTH()
+ * may return.
+ *
+ * \note This is not the maximum size of nonce supported as input to
+ * #psa_aead_set_nonce(), #psa_aead_encrypt() or #psa_aead_decrypt(),
+ * just the largest size that may be generated by
+ * #psa_aead_generate_nonce().
+ */
+#define PSA_AEAD_NONCE_MAX_SIZE 13u
+
+/** A sufficient output buffer size for psa_aead_update().
+ *
+ * If the size of the output buffer is at least this large, it is
+ * guaranteed that psa_aead_update() will not fail due to an
+ * insufficient buffer size. The actual size of the output may be smaller
+ * in any given call.
+ *
+ * See also #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p input_length).
+ *
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * \param key_type A symmetric key type that is
+ * compatible with algorithm \p alg.
+ * \param alg An AEAD algorithm
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(\p alg) is true).
+ * \param input_length Size of the input in bytes.
+ *
+ * \return A sufficient output buffer size for the specified
+ * algorithm.
+ * If the key type or AEAD algorithm is not
+ * recognized, or the parameters are incompatible,
+ * return 0.
+ */
+/* For all the AEAD modes defined in this specification, it is possible
+ * to emit output without delay. However, hardware may not always be
+ * capable of this. So for modes based on a block cipher, allow the
+ * implementation to delay the output until it has a full block. */
+#define PSA_AEAD_UPDATE_OUTPUT_SIZE(key_type, alg, input_length) \
+ (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 ? \
+ PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
+ PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type), (input_length)) : \
+ (input_length) : \
+ 0u)
+
+/** A sufficient output buffer size for psa_aead_update(), for any of the
+ * supported key types and AEAD algorithms.
+ *
+ * If the size of the output buffer is at least this large, it is guaranteed
+ * that psa_aead_update() will not fail due to an insufficient buffer size.
+ *
+ * See also #PSA_AEAD_UPDATE_OUTPUT_SIZE(\p key_type, \p alg, \p input_length).
+ *
+ * \param input_length Size of the input in bytes.
+ */
+#define PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(input_length) \
+ (PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, (input_length)))
+
+/** A sufficient ciphertext buffer size for psa_aead_finish().
+ *
+ * If the size of the ciphertext buffer is at least this large, it is
+ * guaranteed that psa_aead_finish() will not fail due to an
+ * insufficient ciphertext buffer size. The actual size of the output may
+ * be smaller in any given call.
+ *
+ * See also #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE.
+ *
+ * \param key_type A symmetric key type that is
+ compatible with algorithm \p alg.
+ * \param alg An AEAD algorithm
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(\p alg) is true).
+ *
+ * \return A sufficient ciphertext buffer size for the
+ * specified algorithm.
+ * If the key type or AEAD algorithm is not
+ * recognized, or the parameters are incompatible,
+ * return 0.
+ */
+#define PSA_AEAD_FINISH_OUTPUT_SIZE(key_type, alg) \
+ (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 && \
+ PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
+ PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \
+ 0u)
+
+/** A sufficient ciphertext buffer size for psa_aead_finish(), for any of the
+ * supported key types and AEAD algorithms.
+ *
+ * See also #PSA_AEAD_FINISH_OUTPUT_SIZE(\p key_type, \p alg).
+ */
+#define PSA_AEAD_FINISH_OUTPUT_MAX_SIZE (PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE)
+
+/** A sufficient plaintext buffer size for psa_aead_verify().
+ *
+ * If the size of the plaintext buffer is at least this large, it is
+ * guaranteed that psa_aead_verify() will not fail due to an
+ * insufficient plaintext buffer size. The actual size of the output may
+ * be smaller in any given call.
+ *
+ * See also #PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE.
+ *
+ * \param key_type A symmetric key type that is
+ * compatible with algorithm \p alg.
+ * \param alg An AEAD algorithm
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(\p alg) is true).
+ *
+ * \return A sufficient plaintext buffer size for the
+ * specified algorithm.
+ * If the key type or AEAD algorithm is not
+ * recognized, or the parameters are incompatible,
+ * return 0.
+ */
+#define PSA_AEAD_VERIFY_OUTPUT_SIZE(key_type, alg) \
+ (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 && \
+ PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
+ PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \
+ 0u)
+
+/** A sufficient plaintext buffer size for psa_aead_verify(), for any of the
+ * supported key types and AEAD algorithms.
+ *
+ * See also #PSA_AEAD_VERIFY_OUTPUT_SIZE(\p key_type, \p alg).
+ */
+#define PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE (PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE)
+
+#define PSA_RSA_MINIMUM_PADDING_SIZE(alg) \
+ (PSA_ALG_IS_RSA_OAEP(alg) ? \
+ 2u * PSA_HASH_LENGTH(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1u : \
+ 11u /*PKCS#1v1.5*/)
+
+/**
+ * \brief ECDSA signature size for a given curve bit size
+ *
+ * \param curve_bits Curve size in bits.
+ * \return Signature size in bytes.
+ *
+ * \note This macro returns a compile-time constant if its argument is one.
+ */
+#define PSA_ECDSA_SIGNATURE_SIZE(curve_bits) \
+ (PSA_BITS_TO_BYTES(curve_bits) * 2u)
+
+/** Sufficient signature buffer size for psa_sign_hash().
+ *
+ * This macro returns a sufficient buffer size for a signature using a key
+ * of the specified type and size, with the specified algorithm.
+ * Note that the actual size of the signature may be smaller
+ * (some algorithms produce a variable-size signature).
+ *
+ * \warning This function may call its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * \param key_type An asymmetric key type (this may indifferently be a
+ * key pair type or a public key type).
+ * \param key_bits The size of the key in bits.
+ * \param alg The signature algorithm.
+ *
+ * \return If the parameters are valid and supported, return
+ * a buffer size in bytes that guarantees that
+ * psa_sign_hash() will not fail with
+ * #PSA_ERROR_BUFFER_TOO_SMALL.
+ * If the parameters are a valid combination that is not supported,
+ * return either a sensible size or 0.
+ * If the parameters are not valid, the
+ * return value is unspecified.
+ */
+#define PSA_SIGN_OUTPUT_SIZE(key_type, key_bits, alg) \
+ (PSA_KEY_TYPE_IS_RSA(key_type) ? ((void) alg, PSA_BITS_TO_BYTES(key_bits)) : \
+ PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_ECDSA_SIGNATURE_SIZE(key_bits) : \
+ ((void) alg, 0u))
+
+#define PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE \
+ PSA_ECDSA_SIGNATURE_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
+
+/** \def PSA_SIGNATURE_MAX_SIZE
+ *
+ * Maximum size of an asymmetric signature.
+ *
+ * This macro expands to a compile-time constant integer. This value
+ * is the maximum size of a signature in bytes.
+ */
+#define PSA_SIGNATURE_MAX_SIZE 1
+
+#if (defined(PSA_WANT_ALG_ECDSA) || defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)) && \
+ (PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE > PSA_SIGNATURE_MAX_SIZE)
+#undef PSA_SIGNATURE_MAX_SIZE
+#define PSA_SIGNATURE_MAX_SIZE PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE
+#endif
+#if (defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) || defined(PSA_WANT_ALG_RSA_PSS)) && \
+ (PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS) > PSA_SIGNATURE_MAX_SIZE)
+#undef PSA_SIGNATURE_MAX_SIZE
+#define PSA_SIGNATURE_MAX_SIZE PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS)
+#endif
+
+/** Sufficient output buffer size for psa_asymmetric_encrypt().
+ *
+ * This macro returns a sufficient buffer size for a ciphertext produced using
+ * a key of the specified type and size, with the specified algorithm.
+ * Note that the actual size of the ciphertext may be smaller, depending
+ * on the algorithm.
+ *
+ * \warning This function may call its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * \param key_type An asymmetric key type (this may indifferently be a
+ * key pair type or a public key type).
+ * \param key_bits The size of the key in bits.
+ * \param alg The asymmetric encryption algorithm.
+ *
+ * \return If the parameters are valid and supported, return
+ * a buffer size in bytes that guarantees that
+ * psa_asymmetric_encrypt() will not fail with
+ * #PSA_ERROR_BUFFER_TOO_SMALL.
+ * If the parameters are a valid combination that is not supported,
+ * return either a sensible size or 0.
+ * If the parameters are not valid, the
+ * return value is unspecified.
+ */
+#define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(key_type, key_bits, alg) \
+ (PSA_KEY_TYPE_IS_RSA(key_type) ? \
+ ((void) alg, PSA_BITS_TO_BYTES(key_bits)) : \
+ 0u)
+
+/** A sufficient output buffer size for psa_asymmetric_encrypt(), for any
+ * supported asymmetric encryption.
+ *
+ * See also #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\p key_type, \p key_bits, \p alg).
+ */
+/* This macro assumes that RSA is the only supported asymmetric encryption. */
+#define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE \
+ (PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS))
+
+/** Sufficient output buffer size for psa_asymmetric_decrypt().
+ *
+ * This macro returns a sufficient buffer size for a plaintext produced using
+ * a key of the specified type and size, with the specified algorithm.
+ * Note that the actual size of the plaintext may be smaller, depending
+ * on the algorithm.
+ *
+ * \warning This function may call its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * \param key_type An asymmetric key type (this may indifferently be a
+ * key pair type or a public key type).
+ * \param key_bits The size of the key in bits.
+ * \param alg The asymmetric encryption algorithm.
+ *
+ * \return If the parameters are valid and supported, return
+ * a buffer size in bytes that guarantees that
+ * psa_asymmetric_decrypt() will not fail with
+ * #PSA_ERROR_BUFFER_TOO_SMALL.
+ * If the parameters are a valid combination that is not supported,
+ * return either a sensible size or 0.
+ * If the parameters are not valid, the
+ * return value is unspecified.
+ */
+#define PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(key_type, key_bits, alg) \
+ (PSA_KEY_TYPE_IS_RSA(key_type) ? \
+ PSA_BITS_TO_BYTES(key_bits) - PSA_RSA_MINIMUM_PADDING_SIZE(alg) : \
+ 0u)
+
+/** A sufficient output buffer size for psa_asymmetric_decrypt(), for any
+ * supported asymmetric decryption.
+ *
+ * This macro assumes that RSA is the only supported asymmetric encryption.
+ *
+ * See also #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\p key_type, \p key_bits, \p alg).
+ */
+#define PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE \
+ (PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS))
+
+/* Maximum size of the ASN.1 encoding of an INTEGER with the specified
+ * number of bits.
+ *
+ * This definition assumes that bits <= 2^19 - 9 so that the length field
+ * is at most 3 bytes. The length of the encoding is the length of the
+ * bit string padded to a whole number of bytes plus:
+ * - 1 type byte;
+ * - 1 to 3 length bytes;
+ * - 0 to 1 bytes of leading 0 due to the sign bit.
+ */
+#define PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(bits) \
+ ((bits) / 8u + 5u)
+
+/* Maximum size of the export encoding of an RSA public key.
+ * Assumes that the public exponent is less than 2^32.
+ *
+ * RSAPublicKey ::= SEQUENCE {
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER } -- e
+ *
+ * - 4 bytes of SEQUENCE overhead;
+ * - n : INTEGER;
+ * - 7 bytes for the public exponent.
+ */
+#define PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) \
+ (PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) + 11u)
+
+/* Maximum size of the export encoding of an RSA key pair.
+ * Assumes that the public exponent is less than 2^32 and that the size
+ * difference between the two primes is at most 1 bit.
+ *
+ * RSAPrivateKey ::= SEQUENCE {
+ * version Version, -- 0
+ * modulus INTEGER, -- N-bit
+ * publicExponent INTEGER, -- 32-bit
+ * privateExponent INTEGER, -- N-bit
+ * prime1 INTEGER, -- N/2-bit
+ * prime2 INTEGER, -- N/2-bit
+ * exponent1 INTEGER, -- N/2-bit
+ * exponent2 INTEGER, -- N/2-bit
+ * coefficient INTEGER, -- N/2-bit
+ * }
+ *
+ * - 4 bytes of SEQUENCE overhead;
+ * - 3 bytes of version;
+ * - 7 half-size INTEGERs plus 2 full-size INTEGERs,
+ * overapproximated as 9 half-size INTEGERS;
+ * - 7 bytes for the public exponent.
+ */
+#define PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) \
+ (9u * PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE((key_bits) / 2u + 1u) + 14u)
+
+/* Maximum size of the export encoding of a DSA public key.
+ *
+ * SubjectPublicKeyInfo ::= SEQUENCE {
+ * algorithm AlgorithmIdentifier,
+ * subjectPublicKey BIT STRING } -- contains DSAPublicKey
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters Dss-Params } -- SEQUENCE of 3 INTEGERs
+ * DSAPublicKey ::= INTEGER -- public key, Y
+ *
+ * - 3 * 4 bytes of SEQUENCE overhead;
+ * - 1 + 1 + 7 bytes of algorithm (DSA OID);
+ * - 4 bytes of BIT STRING overhead;
+ * - 3 full-size INTEGERs (p, g, y);
+ * - 1 + 1 + 32 bytes for 1 sub-size INTEGER (q <= 256 bits).
+ */
+#define PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) \
+ (PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) * 3u + 59u)
+
+/* Maximum size of the export encoding of a DSA key pair.
+ *
+ * DSAPrivateKey ::= SEQUENCE {
+ * version Version, -- 0
+ * prime INTEGER, -- p
+ * subprime INTEGER, -- q
+ * generator INTEGER, -- g
+ * public INTEGER, -- y
+ * private INTEGER, -- x
+ * }
+ *
+ * - 4 bytes of SEQUENCE overhead;
+ * - 3 bytes of version;
+ * - 3 full-size INTEGERs (p, g, y);
+ * - 2 * (1 + 1 + 32) bytes for 2 sub-size INTEGERs (q, x <= 256 bits).
+ */
+#define PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) \
+ (PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) * 3u + 75u)
+
+/* Maximum size of the export encoding of an ECC public key.
+ *
+ * The representation of an ECC public key is:
+ * - The byte 0x04;
+ * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
+ * - `y_P` as a `ceiling(m/8)`-byte string, big-endian;
+ * - where m is the bit size associated with the curve.
+ *
+ * - 1 byte + 2 * point size.
+ */
+#define PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) \
+ (2u * PSA_BITS_TO_BYTES(key_bits) + 1u)
+
+/* Maximum size of the export encoding of an ECC key pair.
+ *
+ * An ECC key pair is represented by the secret value.
+ */
+#define PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) \
+ (PSA_BITS_TO_BYTES(key_bits))
+
+/* Maximum size of the export encoding of an DH key pair.
+ *
+ * An DH key pair is represented by the secret value.
+ */
+#define PSA_KEY_EXPORT_FFDH_KEY_PAIR_MAX_SIZE(key_bits) \
+ (PSA_BITS_TO_BYTES(key_bits))
+
+/* Maximum size of the export encoding of an DH public key.
+ */
+#define PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(key_bits) \
+ (PSA_BITS_TO_BYTES(key_bits))
+
+/* Maximum size of the export encoding of an SPAKE2+ public key.
+ *
+ * An SPAKE2+ public key is represented by the secret values w0 and L.
+ */
+#define PSA_KEY_EXPORT_SPAKE2P_PUBLIC_KEY_MAX_SIZE(key_bits) \
+ (3u * PSA_BITS_TO_BYTES(key_bits) + 1u)
+
+/* Maximum size of the export encoding of an SPAKE2+ key pair.
+ *
+ * An SPAKE2+ key pair is represented by the secret values w0 and w1.
+ */
+#define PSA_KEY_EXPORT_SPAKE2P_KEY_PAIR_MAX_SIZE(key_bits) \
+ (2u * PSA_BITS_TO_BYTES(key_bits))
+
+/* Maximum size of the export encoding of an SRP public key.
+ *
+ * An SRP public key is represented by the password verifier.
+ */
+#define PSA_KEY_EXPORT_SRP_PUBLIC_KEY_MAX_SIZE(key_bits) \
+ (PSA_BITS_TO_BYTES(key_bits))
+
+/* Maximum size of the export encoding of an SRP key pair.
+ *
+ * An SRP key pair is represented by the password hash.
+ */
+#define PSA_KEY_EXPORT_SRP_KEY_PAIR_MAX_SIZE(key_bits) \
+ (PSA_HASH_MAX_SIZE)
+
+/** Sufficient output buffer size for psa_export_key() or
+ * psa_export_public_key().
+ *
+ * This macro returns a compile-time constant if its arguments are
+ * compile-time constants.
+ *
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * The following code illustrates how to allocate enough memory to export
+ * a key by querying the key type and size at runtime.
+ * \code{c}
+ * psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ * psa_status_t status;
+ * status = psa_get_key_attributes(key, &attributes);
+ * if (status != PSA_SUCCESS) handle_error(...);
+ * psa_key_type_t key_type = psa_get_key_type(&attributes);
+ * size_t key_bits = psa_get_key_bits(&attributes);
+ * size_t buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits);
+ * psa_reset_key_attributes(&attributes);
+ * uint8_t *buffer = malloc(buffer_size);
+ * if (buffer == NULL) handle_error(...);
+ * size_t buffer_length;
+ * status = psa_export_key(key, buffer, buffer_size, &buffer_length);
+ * if (status != PSA_SUCCESS) handle_error(...);
+ * \endcode
+ *
+ * \param key_type A supported key type.
+ * \param key_bits The size of the key in bits.
+ *
+ * \return If the parameters are valid and supported, return
+ * a buffer size in bytes that guarantees that
+ * psa_export_key() or psa_export_public_key() will not fail with
+ * #PSA_ERROR_BUFFER_TOO_SMALL.
+ * If the parameters are a valid combination that is not supported,
+ * return either a sensible size or 0.
+ * If the parameters are not valid, the return value is unspecified.
+ */
+#define PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits) \
+ (PSA_KEY_TYPE_IS_UNSTRUCTURED(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \
+ PSA_KEY_TYPE_IS_DH(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \
+ (key_type) == PSA_KEY_TYPE_RSA_KEY_PAIR ? PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) : \
+ (key_type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
+ (key_type) == PSA_KEY_TYPE_DSA_KEY_PAIR ? PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) : \
+ (key_type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY ? PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
+ PSA_KEY_TYPE_IS_SPAKE2P_KEY_PAIR(key_type) ? 2u * PSA_BITS_TO_BYTES(key_bits) : \
+ PSA_KEY_TYPE_IS_SPAKE2P_PUBLIC_KEY(key_type) ? 3u * PSA_BITS_TO_BYTES(key_bits) + 1u : \
+ PSA_KEY_TYPE_IS_SRP_KEY_PAIR(key_type) ? PSA_HASH_MAX_SIZE : \
+ PSA_KEY_TYPE_IS_SRP_PUBLIC_KEY(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \
+ PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) : \
+ PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \
+ 0u)
+
+/** Sufficient output buffer size for psa_export_public_key().
+ *
+ * This macro returns a compile-time constant if its arguments are
+ * compile-time constants.
+ *
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * The following code illustrates how to allocate enough memory to export
+ * a public key by querying the key type and size at runtime.
+ * \code{c}
+ * psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ * psa_status_t status;
+ * status = psa_get_key_attributes(key, &attributes);
+ * if (status != PSA_SUCCESS) handle_error(...);
+ * psa_key_type_t key_type = psa_get_key_type(&attributes);
+ * size_t key_bits = psa_get_key_bits(&attributes);
+ * size_t buffer_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits);
+ * psa_reset_key_attributes(&attributes);
+ * uint8_t *buffer = malloc(buffer_size);
+ * if (buffer == NULL) handle_error(...);
+ * size_t buffer_length;
+ * status = psa_export_public_key(key, buffer, buffer_size, &buffer_length);
+ * if (status != PSA_SUCCESS) handle_error(...);
+ * \endcode
+ *
+ * \param key_type A public key or key pair key type.
+ * \param key_bits The size of the key in bits.
+ *
+ * \return If the parameters are valid and supported, return
+ * a buffer size in bytes that guarantees that
+ * psa_export_public_key() will not fail with
+ * #PSA_ERROR_BUFFER_TOO_SMALL.
+ * If the parameters are a valid combination that is not
+ * supported, return either a sensible size or 0.
+ * If the parameters are not valid,
+ * the return value is unspecified.
+ *
+ * If the parameters are valid and supported,
+ * return the same result as
+ * #PSA_EXPORT_KEY_OUTPUT_SIZE(
+ * \p #PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\p key_type),
+ * \p key_bits).
+ */
+#define PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits) \
+ (PSA_KEY_TYPE_IS_RSA(key_type) ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
+ PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \
+ PSA_KEY_TYPE_IS_DH(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \
+ PSA_KEY_TYPE_IS_SPAKE2P(key_type) ? 3u * PSA_BITS_TO_BYTES(key_bits) + 1u : \
+ PSA_KEY_TYPE_IS_SRP(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \
+ 0u)
+
+/** Sufficient buffer size for exporting any asymmetric key pair.
+ *
+ * This macro expands to a compile-time constant integer. This value is
+ * a sufficient buffer size when calling psa_export_key() to export any
+ * asymmetric key pair, regardless of the exact key type and key size.
+ *
+ * See also #PSA_EXPORT_KEY_OUTPUT_SIZE(\p key_type, \p key_bits).
+ */
+#define PSA_EXPORT_KEY_PAIR_MAX_SIZE 1
+
+#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) && \
+ (PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) > \
+ PSA_EXPORT_KEY_PAIR_MAX_SIZE)
+#undef PSA_EXPORT_KEY_PAIR_MAX_SIZE
+#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \
+ PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
+#endif
+#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) && \
+ (PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) > \
+ PSA_EXPORT_KEY_PAIR_MAX_SIZE)
+#undef PSA_EXPORT_KEY_PAIR_MAX_SIZE
+#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \
+ PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)
+#endif
+#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC) && \
+ (PSA_KEY_EXPORT_FFDH_KEY_PAIR_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) > \
+ PSA_EXPORT_KEY_PAIR_MAX_SIZE)
+#undef PSA_EXPORT_KEY_PAIR_MAX_SIZE
+#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \
+ PSA_KEY_EXPORT_FFDH_KEY_PAIR_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS)
+#endif
+#if defined(PSA_WANT_KEY_TYPE_SPAKE2P_KEY_PAIR_BASIC) && \
+ (PSA_KEY_EXPORT_SPAKE2P_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) > \
+ PSA_EXPORT_KEY_PAIR_MAX_SIZE)
+#undef PSA_EXPORT_KEY_PAIR_MAX_SIZE
+#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \
+ PSA_KEY_EXPORT_SPAKE2P_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
+#endif
+#if defined(PSA_WANT_KEY_TYPE_SRP_KEY_PAIR_BASIC) && \
+ (PSA_KEY_EXPORT_SRP_KEY_PAIR_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) > \
+ PSA_EXPORT_KEY_PAIR_MAX_SIZE)
+#undef PSA_EXPORT_KEY_PAIR_MAX_SIZE
+#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \
+ PSA_KEY_EXPORT_SRP_KEY_PAIR_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS)
+#endif
+
+/** Sufficient buffer size for exporting any asymmetric public key.
+ *
+ * This macro expands to a compile-time constant integer. This value is
+ * a sufficient buffer size when calling psa_export_key() or
+ * psa_export_public_key() to export any asymmetric public key,
+ * regardless of the exact key type and key size.
+ *
+ * See also #PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(\p key_type, \p key_bits).
+ */
+#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE 1
+
+#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \
+ (PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) > \
+ PSA_EXPORT_PUBLIC_KEY_MAX_SIZE)
+#undef PSA_EXPORT_PUBLIC_KEY_MAX_SIZE
+#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \
+ PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
+#endif
+#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) && \
+ (PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) > \
+ PSA_EXPORT_PUBLIC_KEY_MAX_SIZE)
+#undef PSA_EXPORT_PUBLIC_KEY_MAX_SIZE
+#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \
+ PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS)
+#endif
+#if defined(PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY) && \
+ (PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) > \
+ PSA_EXPORT_PUBLIC_KEY_MAX_SIZE)
+#undef PSA_EXPORT_PUBLIC_KEY_MAX_SIZE
+#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \
+ PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS)
+#endif
+#if defined(PSA_WANT_KEY_TYPE_SPAKE2P_PUBLIC_KEY) && \
+ (PSA_KEY_EXPORT_SPAKE2P_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) > \
+ PSA_EXPORT_PUBLIC_KEY_MAX_SIZE)
+#undef PSA_EXPORT_PUBLIC_KEY_MAX_SIZE
+#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \
+ PSA_KEY_EXPORT_SPAKE2P_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)
+#endif
+#if defined(PSA_WANT_KEY_TYPE_SRP_PUBLIC_KEY) && \
+ (PSA_KEY_EXPORT_SRP_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS) > \
+ PSA_EXPORT_PUBLIC_KEY_MAX_SIZE)
+#undef PSA_EXPORT_PUBLIC_KEY_MAX_SIZE
+#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \
+ PSA_KEY_EXPORT_SRP_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS)
+#endif
+
+/** Sufficient output buffer size for psa_raw_key_agreement().
+ *
+ * This macro returns a compile-time constant if its arguments are
+ * compile-time constants.
+ *
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE.
+ *
+ * \param key_type A supported key type.
+ * \param key_bits The size of the key in bits.
+ *
+ * \return If the parameters are valid and supported, return
+ * a buffer size in bytes that guarantees that
+ * psa_raw_key_agreement() will not fail with
+ * #PSA_ERROR_BUFFER_TOO_SMALL.
+ * If the parameters are a valid combination that
+ * is not supported, return either a sensible size or 0.
+ * If the parameters are not valid,
+ * the return value is unspecified.
+ */
+#define PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(key_type, key_bits) \
+ ((PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) || \
+ PSA_KEY_TYPE_IS_DH_KEY_PAIR(key_type)) ? PSA_BITS_TO_BYTES(key_bits) : 0u)
+
+/** Maximum size of the output from psa_raw_key_agreement().
+ *
+ * This macro expands to a compile-time constant integer. This value is the
+ * maximum size of the output any raw key agreement algorithm, in bytes.
+ *
+ * See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(\p key_type, \p key_bits).
+ */
+#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE 1
+
+#if defined(PSA_WANT_ALG_ECDH) && \
+ (PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS) > PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE)
+#undef PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE
+#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)
+#endif
+#if defined(PSA_WANT_ALG_FFDH) && \
+ (PSA_BITS_TO_BYTES(PSA_VENDOR_FFDH_MAX_KEY_BITS) > PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE)
+#undef PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE
+#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE PSA_BITS_TO_BYTES(PSA_VENDOR_FFDH_MAX_KEY_BITS)
+#endif
+
+/** The default IV size for a cipher algorithm, in bytes.
+ *
+ * The IV that is generated as part of a call to #psa_cipher_encrypt() is always
+ * the default IV length for the algorithm.
+ *
+ * This macro can be used to allocate a buffer of sufficient size to
+ * store the IV output from #psa_cipher_generate_iv() when using
+ * a multi-part cipher operation.
+ *
+ * See also #PSA_CIPHER_IV_MAX_SIZE.
+ *
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * \param key_type A symmetric key type that is compatible with algorithm \p alg.
+ *
+ * \param alg A cipher algorithm (\c PSA_ALG_XXX value such that #PSA_ALG_IS_CIPHER(\p alg) is true).
+ *
+ * \return The default IV size for the specified key type and algorithm.
+ * If the algorithm does not use an IV, return 0.
+ * If the key type or cipher algorithm is not recognized,
+ * or the parameters are incompatible, return 0.
+ */
+#define PSA_CIPHER_IV_LENGTH(key_type, alg) \
+ (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) > 1 && \
+ ((alg) == PSA_ALG_CTR || \
+ (alg) == PSA_ALG_CFB || \
+ (alg) == PSA_ALG_OFB || \
+ (alg) == PSA_ALG_XTS || \
+ (alg) == PSA_ALG_CBC_NO_PADDING || \
+ (alg) == PSA_ALG_CBC_PKCS7) ? PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \
+ (key_type) == PSA_KEY_TYPE_CHACHA20 && \
+ (alg) == PSA_ALG_STREAM_CIPHER ? 12u : \
+ (alg) == PSA_ALG_CCM_STAR_NO_TAG ? 13u : \
+ 0u)
+
+/** The maximum IV size for all supported cipher algorithms, in bytes.
+ *
+ * See also #PSA_CIPHER_IV_LENGTH().
+ */
+#define PSA_CIPHER_IV_MAX_SIZE 16u
+
+/** The maximum size of the output of psa_cipher_encrypt(), in bytes.
+ *
+ * If the size of the output buffer is at least this large, it is guaranteed
+ * that psa_cipher_encrypt() will not fail due to an insufficient buffer size.
+ * Depending on the algorithm, the actual size of the output might be smaller.
+ *
+ * See also #PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE(\p input_length).
+ *
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * \param key_type A symmetric key type that is compatible with algorithm
+ * alg.
+ * \param alg A cipher algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_CIPHER(\p alg) is true).
+ * \param input_length Size of the input in bytes.
+ *
+ * \return A sufficient output size for the specified key type and
+ * algorithm. If the key type or cipher algorithm is not
+ * recognized, or the parameters are incompatible,
+ * return 0.
+ */
+#define PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(key_type, alg, input_length) \
+ (alg == PSA_ALG_CBC_PKCS7 ? \
+ (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) != 0 ? \
+ PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type), \
+ (input_length) + 1u) + \
+ PSA_CIPHER_IV_LENGTH((key_type), (alg)) : 0u) : \
+ (PSA_ALG_IS_CIPHER(alg) ? \
+ (input_length) + PSA_CIPHER_IV_LENGTH((key_type), (alg)) : \
+ 0u))
+
+/** A sufficient output buffer size for psa_cipher_encrypt(), for any of the
+ * supported key types and cipher algorithms.
+ *
+ * If the size of the output buffer is at least this large, it is guaranteed
+ * that psa_cipher_encrypt() will not fail due to an insufficient buffer size.
+ *
+ * See also #PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(\p key_type, \p alg, \p input_length).
+ *
+ * \param input_length Size of the input in bytes.
+ *
+ */
+#define PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE(input_length) \
+ (PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, \
+ (input_length) + 1u) + \
+ PSA_CIPHER_IV_MAX_SIZE)
+
+/** The maximum size of the output of psa_cipher_decrypt(), in bytes.
+ *
+ * If the size of the output buffer is at least this large, it is guaranteed
+ * that psa_cipher_decrypt() will not fail due to an insufficient buffer size.
+ * Depending on the algorithm, the actual size of the output might be smaller.
+ *
+ * See also #PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE(\p input_length).
+ *
+ * \param key_type A symmetric key type that is compatible with algorithm
+ * alg.
+ * \param alg A cipher algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_CIPHER(\p alg) is true).
+ * \param input_length Size of the input in bytes.
+ *
+ * \return A sufficient output size for the specified key type and
+ * algorithm. If the key type or cipher algorithm is not
+ * recognized, or the parameters are incompatible,
+ * return 0.
+ */
+#define PSA_CIPHER_DECRYPT_OUTPUT_SIZE(key_type, alg, input_length) \
+ (PSA_ALG_IS_CIPHER(alg) && \
+ ((key_type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \
+ (input_length) : \
+ 0u)
+
+/** A sufficient output buffer size for psa_cipher_decrypt(), for any of the
+ * supported key types and cipher algorithms.
+ *
+ * If the size of the output buffer is at least this large, it is guaranteed
+ * that psa_cipher_decrypt() will not fail due to an insufficient buffer size.
+ *
+ * See also #PSA_CIPHER_DECRYPT_OUTPUT_SIZE(\p key_type, \p alg, \p input_length).
+ *
+ * \param input_length Size of the input in bytes.
+ */
+#define PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE(input_length) \
+ (input_length)
+
+/** A sufficient output buffer size for psa_cipher_update().
+ *
+ * If the size of the output buffer is at least this large, it is guaranteed
+ * that psa_cipher_update() will not fail due to an insufficient buffer size.
+ * The actual size of the output might be smaller in any given call.
+ *
+ * See also #PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE(\p input_length).
+ *
+ * \param key_type A symmetric key type that is compatible with algorithm
+ * alg.
+ * \param alg A cipher algorithm (PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_CIPHER(\p alg) is true).
+ * \param input_length Size of the input in bytes.
+ *
+ * \return A sufficient output size for the specified key type and
+ * algorithm. If the key type or cipher algorithm is not
+ * recognized, or the parameters are incompatible, return 0.
+ */
+#define PSA_CIPHER_UPDATE_OUTPUT_SIZE(key_type, alg, input_length) \
+ (PSA_ALG_IS_CIPHER(alg) ? \
+ (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) != 0 ? \
+ (((alg) == PSA_ALG_CBC_PKCS7 || \
+ (alg) == PSA_ALG_CBC_NO_PADDING || \
+ (alg) == PSA_ALG_ECB_NO_PADDING) ? \
+ PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type), \
+ input_length) : \
+ (input_length)) : 0u) : \
+ 0u)
+
+/** A sufficient output buffer size for psa_cipher_update(), for any of the
+ * supported key types and cipher algorithms.
+ *
+ * If the size of the output buffer is at least this large, it is guaranteed
+ * that psa_cipher_update() will not fail due to an insufficient buffer size.
+ *
+ * See also #PSA_CIPHER_UPDATE_OUTPUT_SIZE(\p key_type, \p alg, \p input_length).
+ *
+ * \param input_length Size of the input in bytes.
+ */
+#define PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE(input_length) \
+ (PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, input_length))
+
+/** A sufficient ciphertext buffer size for psa_cipher_finish().
+ *
+ * If the size of the ciphertext buffer is at least this large, it is
+ * guaranteed that psa_cipher_finish() will not fail due to an insufficient
+ * ciphertext buffer size. The actual size of the output might be smaller in
+ * any given call.
+ *
+ * See also #PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE().
+ *
+ * \param key_type A symmetric key type that is compatible with algorithm
+ * alg.
+ * \param alg A cipher algorithm (PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_CIPHER(\p alg) is true).
+ * \return A sufficient output size for the specified key type and
+ * algorithm. If the key type or cipher algorithm is not
+ * recognized, or the parameters are incompatible, return 0.
+ */
+#define PSA_CIPHER_FINISH_OUTPUT_SIZE(key_type, alg) \
+ (PSA_ALG_IS_CIPHER(alg) ? \
+ (alg == PSA_ALG_CBC_PKCS7 ? \
+ PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \
+ 0u) : \
+ 0u)
+
+/** A sufficient ciphertext buffer size for psa_cipher_finish(), for any of the
+ * supported key types and cipher algorithms.
+ *
+ * See also #PSA_CIPHER_FINISH_OUTPUT_SIZE(\p key_type, \p alg).
+ */
+#define PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE \
+ (PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE)
+
+#endif /* PSA_CRYPTO_SIZES_H */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_struct.h b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_struct.h
new file mode 100644
index 0000000..1cbbe40
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_struct.h
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+/**
+ * \file psa/crypto_struct.h
+ *
+ * \brief PSA cryptography module: structured type implementations
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h.
+ *
+ * This file contains the definitions of some data structures with
+ * implementation-specific definitions.
+ *
+ * In implementations with isolation between the application and the
+ * cryptography module, it is expected that the front-end and the back-end
+ * would have different versions of this file.
+ */
+
+#ifndef PSA_CRYPTO_STRUCT_H
+#define PSA_CRYPTO_STRUCT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Note that the below structures are different from the decalrations in
+ * mbed-crypto. This is because TF-M maintains 'front-end' and 'back-end'
+ * versions of this header. In the front-end version, exported to NS
+ * clients in interface/include/psa, a crypto operation is defined as an
+ * opaque handle to a context in the Crypto service. The back-end
+ * version, directly included from the mbed-crypto repo by the Crypto
+ * service, contains the full definition of the operation structs.
+ *
+ * One of the functions of the Crypto service is to allocate the back-end
+ * operation contexts in its own partition memory (in crypto_alloc.c),
+ * and then do the mapping between front-end operation handles passed by
+ * NS clients and the corresponding back-end operation contexts. The
+ * advantage of doing it this way is that internal mbed-crypto state is never
+ * exposed to the NS client.
+ */
+
+struct psa_hash_operation_s
+{
+ uint32_t handle;
+};
+
+#define PSA_HASH_OPERATION_INIT {0}
+static inline struct psa_hash_operation_s psa_hash_operation_init(void)
+{
+ const struct psa_hash_operation_s v = PSA_HASH_OPERATION_INIT;
+ return v;
+}
+
+struct psa_mac_operation_s
+{
+ uint32_t handle;
+};
+
+#define PSA_MAC_OPERATION_INIT {0}
+static inline struct psa_mac_operation_s psa_mac_operation_init(void)
+{
+ const struct psa_mac_operation_s v = PSA_MAC_OPERATION_INIT;
+ return v;
+}
+
+struct psa_cipher_operation_s
+{
+ uint32_t handle;
+};
+
+#define PSA_CIPHER_OPERATION_INIT {0}
+static inline struct psa_cipher_operation_s psa_cipher_operation_init(void)
+{
+ const struct psa_cipher_operation_s v = PSA_CIPHER_OPERATION_INIT;
+ return v;
+}
+
+struct psa_aead_operation_s
+{
+ uint32_t handle;
+};
+
+#define PSA_AEAD_OPERATION_INIT {0}
+static inline struct psa_aead_operation_s psa_aead_operation_init(void)
+{
+ const struct psa_aead_operation_s v = PSA_AEAD_OPERATION_INIT;
+ return v;
+}
+
+struct psa_key_derivation_s
+{
+ uint32_t handle;
+};
+
+#define PSA_KEY_DERIVATION_OPERATION_INIT {0}
+static inline struct psa_key_derivation_s psa_key_derivation_operation_init(void)
+{
+ const struct psa_key_derivation_s v = PSA_KEY_DERIVATION_OPERATION_INIT;
+ return v;
+}
+
+/* The type used internally for key sizes.
+ * Public interfaces use size_t, but internally we use a smaller type. */
+typedef uint16_t psa_key_bits_t;
+/* The maximum value of the type used to represent bit-sizes.
+ * This is used to mark an invalid key size. */
+#define PSA_KEY_BITS_TOO_LARGE ((psa_key_bits_t) -1)
+/* The maximum size of a key in bits.
+ * Currently defined as the maximum that can be represented, rounded down
+ * to a whole number of bytes.
+ * This is an uncast value so that it can be used in preprocessor
+ * conditionals. */
+#define PSA_MAX_KEY_BITS 0xfff8
+
+/* On the client side, only some key attributes are visible.
+ * The server has a different definition of psa_key_attributes_s which
+ * maintains more attributes.
+ */
+#include "crypto_client_struct.h"
+struct psa_key_attributes_s {
+ struct psa_client_key_attributes_s client;
+};
+
+#define PSA_KEY_ATTRIBUTES_INIT {PSA_CLIENT_KEY_ATTRIBUTES_INIT}
+
+static inline struct psa_key_attributes_s psa_key_attributes_init(void)
+{
+ const struct psa_key_attributes_s v = PSA_KEY_ATTRIBUTES_INIT;
+ return v;
+}
+
+static inline void psa_set_key_id(psa_key_attributes_t *attributes,
+ mbedtls_svc_key_id_t key)
+{
+ psa_key_lifetime_t lifetime = attributes->client.lifetime;
+
+ attributes->client.id = (psa_key_id_t)key;
+
+ if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime))
+ {
+ attributes->client.lifetime =
+ PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
+ PSA_KEY_LIFETIME_PERSISTENT,
+ PSA_KEY_LIFETIME_GET_LOCATION(lifetime));
+ }
+}
+
+static inline mbedtls_svc_key_id_t psa_get_key_id(
+ const psa_key_attributes_t *attributes)
+{
+ return (mbedtls_svc_key_id_t)attributes->client.id;
+}
+
+static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes,
+ psa_key_lifetime_t lifetime)
+{
+ attributes->client.lifetime = lifetime;
+ if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime))
+ {
+ attributes->client.id = 0;
+ }
+}
+
+static inline psa_key_lifetime_t psa_get_key_lifetime(
+ const psa_key_attributes_t *attributes)
+{
+ return attributes->client.lifetime;
+}
+
+static inline void psa_extend_key_usage_flags(psa_key_usage_t *usage_flags)
+{
+ if (*usage_flags & PSA_KEY_USAGE_SIGN_HASH) {
+ *usage_flags |= PSA_KEY_USAGE_SIGN_MESSAGE;
+ }
+
+ if (*usage_flags & PSA_KEY_USAGE_VERIFY_HASH) {
+ *usage_flags |= PSA_KEY_USAGE_VERIFY_MESSAGE;
+ }
+}
+
+static inline void psa_set_key_usage_flags(psa_key_attributes_t *attributes,
+ psa_key_usage_t usage_flags)
+{
+ psa_extend_key_usage_flags(&usage_flags);
+ attributes->client.usage = usage_flags;
+}
+
+static inline psa_key_usage_t psa_get_key_usage_flags(
+ const psa_key_attributes_t *attributes)
+{
+ return attributes->client.usage;
+}
+
+static inline void psa_set_key_algorithm(psa_key_attributes_t *attributes,
+ psa_algorithm_t alg)
+{
+ attributes->client.alg = alg;
+}
+
+static inline psa_algorithm_t psa_get_key_algorithm(
+ const psa_key_attributes_t *attributes)
+{
+ return attributes->client.alg;
+}
+
+static inline void psa_set_key_type(psa_key_attributes_t *attributes,
+ psa_key_type_t type)
+{
+ attributes->client.type = type;
+}
+
+static inline psa_key_type_t psa_get_key_type(
+ const psa_key_attributes_t *attributes)
+{
+ return attributes->client.type;
+}
+
+static inline void psa_set_key_bits(psa_key_attributes_t *attributes,
+ size_t bits)
+{
+ if (bits > PSA_MAX_KEY_BITS) {
+ attributes->client.bits = PSA_KEY_BITS_TOO_LARGE;
+ } else {
+ attributes->client.bits = bits;
+ }
+}
+
+static inline size_t psa_get_key_bits(
+ const psa_key_attributes_t *attributes)
+{
+ return attributes->client.bits;
+}
+
+struct psa_pake_cipher_suite_s {
+ psa_algorithm_t algorithm;
+ psa_pake_primitive_t primitive;
+ uint32_t key_confirmation;
+};
+
+#define PSA_PAKE_CIPHER_SUITE_INIT {PSA_ALG_NONE, 0, 0}
+static inline struct psa_pake_cipher_suite_s psa_pake_cipher_suite_init(void)
+{
+ const struct psa_pake_cipher_suite_s v = PSA_PAKE_CIPHER_SUITE_INIT;
+ return v;
+}
+
+struct psa_pake_operation_s {
+ uint32_t handle;
+};
+
+#define PSA_PAKE_OPERATION_INIT {0}
+static inline struct psa_pake_operation_s psa_pake_operation_init(void)
+{
+ const struct psa_pake_operation_s v = PSA_PAKE_OPERATION_INIT;
+ return v;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PSA_CRYPTO_STRUCT_H */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_types.h b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_types.h
new file mode 100644
index 0000000..01feaeb
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_types.h
@@ -0,0 +1,500 @@
+/*
+ * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+/**
+ * \file psa/crypto_types.h
+ *
+ * \brief PSA cryptography module: type aliases.
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h. Drivers must include the appropriate driver
+ * header file.
+ *
+ * This file contains portable definitions of integral types for properties
+ * of cryptographic keys, designations of cryptographic algorithms, and
+ * error codes returned by the library.
+ *
+ * This header file does not declare any function.
+ */
+
+#ifndef PSA_CRYPTO_TYPES_H
+#define PSA_CRYPTO_TYPES_H
+
+#if defined(MBEDTLS_PSA_CRYPTO_PLATFORM_FILE)
+#include MBEDTLS_PSA_CRYPTO_PLATFORM_FILE
+#else
+#include "crypto_platform.h"
+#endif
+
+#include <stdint.h>
+
+/** \defgroup error Error codes
+ * @{
+ */
+
+/**
+ * \brief Function return status.
+ *
+ * This is either #PSA_SUCCESS (which is zero), indicating success,
+ * or a small negative value indicating that an error occurred. Errors are
+ * encoded as one of the \c PSA_ERROR_xxx values defined here. */
+/* If #PSA_SUCCESS is already defined, it means that #psa_status_t
+ * is also defined in an external header, so prevent its multiple
+ * definition.
+ */
+#ifndef PSA_SUCCESS
+typedef int32_t psa_status_t;
+#endif
+
+/**@}*/
+
+/** \defgroup crypto_types Key and algorithm types
+ * @{
+ */
+
+/** \brief Encoding of a key type.
+ *
+ * Values of this type are generally constructed by macros called
+ * `PSA_KEY_TYPE_xxx`.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ * Any changes to existing values will require bumping the storage
+ * format version and providing a translation when reading the old
+ * format.
+ */
+typedef uint16_t psa_key_type_t;
+
+/** The type of PSA elliptic curve family identifiers.
+ *
+ * Values of this type are generally constructed by macros called
+ * `PSA_ECC_FAMILY_xxx`.
+ *
+ * The curve identifier is required to create an ECC key using the
+ * PSA_KEY_TYPE_ECC_KEY_PAIR() or PSA_KEY_TYPE_ECC_PUBLIC_KEY()
+ * macros.
+ *
+ * Values defined by this standard will never be in the range 0x80-0xff.
+ * Vendors who define additional families must use an encoding in this range.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ * Any changes to existing values will require bumping the storage
+ * format version and providing a translation when reading the old
+ * format.
+ */
+typedef uint8_t psa_ecc_family_t;
+
+/** The type of PSA Diffie-Hellman group family identifiers.
+ *
+ * Values of this type are generally constructed by macros called
+ * `PSA_DH_FAMILY_xxx`.
+ *
+ * The group identifier is required to create a Diffie-Hellman key using the
+ * PSA_KEY_TYPE_DH_KEY_PAIR() or PSA_KEY_TYPE_DH_PUBLIC_KEY()
+ * macros.
+ *
+ * Values defined by this standard will never be in the range 0x80-0xff.
+ * Vendors who define additional families must use an encoding in this range.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ * Any changes to existing values will require bumping the storage
+ * format version and providing a translation when reading the old
+ * format.
+ */
+typedef uint8_t psa_dh_family_t;
+
+/** \brief Encoding of a cryptographic algorithm.
+ *
+ * Values of this type are generally constructed by macros called
+ * `PSA_ALG_xxx`.
+ *
+ * For algorithms that can be applied to multiple key types, this type
+ * does not encode the key type. For example, for symmetric ciphers
+ * based on a block cipher, #psa_algorithm_t encodes the block cipher
+ * mode and the padding mode while the block cipher itself is encoded
+ * via #psa_key_type_t.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ * Any changes to existing values will require bumping the storage
+ * format version and providing a translation when reading the old
+ * format.
+ */
+typedef uint32_t psa_algorithm_t;
+
+/**@}*/
+
+/** \defgroup key_lifetimes Key lifetimes
+ * @{
+ */
+
+/** Encoding of key lifetimes.
+ *
+ * The lifetime of a key indicates where it is stored and what system actions
+ * may create and destroy it.
+ *
+ * Lifetime values have the following structure:
+ * - Bits 0-7 (#PSA_KEY_LIFETIME_GET_PERSISTENCE(\c lifetime)):
+ * persistence level. This value indicates what device management
+ * actions can cause it to be destroyed. In particular, it indicates
+ * whether the key is _volatile_ or _persistent_.
+ * See ::psa_key_persistence_t for more information.
+ * - Bits 8-31 (#PSA_KEY_LIFETIME_GET_LOCATION(\c lifetime)):
+ * location indicator. This value indicates which part of the system
+ * has access to the key material and can perform operations using the key.
+ * See ::psa_key_location_t for more information.
+ *
+ * Volatile keys are automatically destroyed when the application instance
+ * terminates or on a power reset of the device. Persistent keys are
+ * preserved until the application explicitly destroys them or until an
+ * integration-specific device management event occurs (for example,
+ * a factory reset).
+ *
+ * Persistent keys have a key identifier of type #mbedtls_svc_key_id_t.
+ * This identifier remains valid throughout the lifetime of the key,
+ * even if the application instance that created the key terminates.
+ * The application can call psa_open_key() to open a persistent key that
+ * it created previously.
+ *
+ * The default lifetime of a key is #PSA_KEY_LIFETIME_VOLATILE. The lifetime
+ * #PSA_KEY_LIFETIME_PERSISTENT is supported if persistent storage is
+ * available. Other lifetime values may be supported depending on the
+ * library configuration.
+ *
+ * Values of this type are generally constructed by macros called
+ * `PSA_KEY_LIFETIME_xxx`.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ * Any changes to existing values will require bumping the storage
+ * format version and providing a translation when reading the old
+ * format.
+ */
+typedef uint32_t psa_key_lifetime_t;
+
+/** Encoding of key persistence levels.
+ *
+ * What distinguishes different persistence levels is what device management
+ * events may cause keys to be destroyed. _Volatile_ keys are destroyed
+ * by a power reset. Persistent keys may be destroyed by events such as
+ * a transfer of ownership or a factory reset. What management events
+ * actually affect persistent keys at different levels is outside the
+ * scope of the PSA Cryptography specification.
+ *
+ * The PSA Cryptography specification defines the following values of
+ * persistence levels:
+ * - \c 0 = #PSA_KEY_PERSISTENCE_VOLATILE: volatile key.
+ * A volatile key is automatically destroyed by the implementation when
+ * the application instance terminates. In particular, a volatile key
+ * is automatically destroyed on a power reset of the device.
+ * - \c 1 = #PSA_KEY_PERSISTENCE_DEFAULT:
+ * persistent key with a default lifetime.
+ * - \c 2-254: currently not supported by Mbed TLS.
+ * - \c 255 = #PSA_KEY_PERSISTENCE_READ_ONLY:
+ * read-only or write-once key.
+ * A key with this persistence level cannot be destroyed.
+ * Mbed TLS does not currently offer a way to create such keys, but
+ * integrations of Mbed TLS can use it for built-in keys that the
+ * application cannot modify (for example, a hardware unique key (HUK)).
+ *
+ * \note Key persistence levels are 8-bit values. Key management
+ * interfaces operate on lifetimes (type ::psa_key_lifetime_t) which
+ * encode the persistence as the lower 8 bits of a 32-bit value.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ * Any changes to existing values will require bumping the storage
+ * format version and providing a translation when reading the old
+ * format.
+ */
+typedef uint8_t psa_key_persistence_t;
+
+/** Encoding of key location indicators.
+ *
+ * If an integration of Mbed TLS can make calls to external
+ * cryptoprocessors such as secure elements, the location of a key
+ * indicates which secure element performs the operations on the key.
+ * Depending on the design of the secure element, the key
+ * material may be stored either in the secure element, or
+ * in wrapped (encrypted) form alongside the key metadata in the
+ * primary local storage.
+ *
+ * The PSA Cryptography API specification defines the following values of
+ * location indicators:
+ * - \c 0: primary local storage.
+ * This location is always available.
+ * The primary local storage is typically the same storage area that
+ * contains the key metadata.
+ * - \c 1: primary secure element.
+ * Integrations of Mbed TLS should support this value if there is a secure
+ * element attached to the operating environment.
+ * As a guideline, secure elements may provide higher resistance against
+ * side channel and physical attacks than the primary local storage, but may
+ * have restrictions on supported key types, sizes, policies and operations
+ * and may have different performance characteristics.
+ * - \c 2-0x7fffff: other locations defined by a PSA specification.
+ * The PSA Cryptography API does not currently assign any meaning to these
+ * locations, but future versions of that specification or other PSA
+ * specifications may do so.
+ * - \c 0x800000-0xffffff: vendor-defined locations.
+ * No PSA specification will assign a meaning to locations in this range.
+ *
+ * \note Key location indicators are 24-bit values. Key management
+ * interfaces operate on lifetimes (type ::psa_key_lifetime_t) which
+ * encode the location as the upper 24 bits of a 32-bit value.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ * Any changes to existing values will require bumping the storage
+ * format version and providing a translation when reading the old
+ * format.
+ */
+typedef uint32_t psa_key_location_t;
+
+/** Encoding of identifiers of persistent keys.
+ *
+ * - Applications may freely choose key identifiers in the range
+ * #PSA_KEY_ID_USER_MIN to #PSA_KEY_ID_USER_MAX.
+ * - The implementation may define additional key identifiers in the range
+ * #PSA_KEY_ID_VENDOR_MIN to #PSA_KEY_ID_VENDOR_MAX.
+ * - 0 is reserved as an invalid key identifier.
+ * - Key identifiers outside these ranges are reserved for future use.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ * Any changes to how values are allocated must require careful
+ * consideration to allow backward compatibility.
+ */
+typedef uint32_t psa_key_id_t;
+
+/** Encoding of key identifiers as seen inside the PSA Crypto implementation.
+ *
+ * When PSA Crypto is built as a library inside an application, this type
+ * is identical to #psa_key_id_t. When PSA Crypto is built as a service
+ * that can store keys on behalf of multiple clients, this type
+ * encodes the #psa_key_id_t value seen by each client application as
+ * well as extra information that identifies the client that owns
+ * the key.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ * Any changes to existing values will require bumping the storage
+ * format version and providing a translation when reading the old
+ * format.
+ */
+#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
+typedef psa_key_id_t mbedtls_svc_key_id_t;
+
+#else /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
+/* Define the MBEDTLS_PRIVATE macro. */
+#include "mbedtls/private_access.h"
+/* Implementation-specific: The Mbed Cryptography library can be built as
+ * part of a multi-client service that exposes the PSA Cryptography API in each
+ * client and encodes the client identity in the key identifier argument of
+ * functions such as psa_open_key().
+ */
+typedef struct {
+ psa_key_id_t MBEDTLS_PRIVATE(key_id);
+ mbedtls_key_owner_id_t MBEDTLS_PRIVATE(owner);
+} mbedtls_svc_key_id_t;
+
+#endif /* !MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
+
+/**@}*/
+
+/** \defgroup policy Key policies
+ * @{
+ */
+
+/** \brief Encoding of permitted usage on a key.
+ *
+ * Values of this type are generally constructed as bitwise-ors of macros
+ * called `PSA_KEY_USAGE_xxx`.
+ *
+ * \note Values of this type are encoded in the persistent key store.
+ * Any changes to existing values will require bumping the storage
+ * format version and providing a translation when reading the old
+ * format.
+ */
+typedef uint32_t psa_key_usage_t;
+
+/**@}*/
+
+/** \defgroup attributes Key attributes
+ * @{
+ */
+
+/** The type of a structure containing key attributes.
+ *
+ * This is an opaque structure that can represent the metadata of a key
+ * object. Metadata that can be stored in attributes includes:
+ * - The location of the key in storage, indicated by its key identifier
+ * and its lifetime.
+ * - The key's policy, comprising usage flags and a specification of
+ * the permitted algorithm(s).
+ * - Information about the key itself: the key type and its size.
+ * - Additional implementation-defined attributes.
+ *
+ * The actual key material is not considered an attribute of a key.
+ * Key attributes do not contain information that is generally considered
+ * highly confidential.
+ *
+ * An attribute structure works like a simple data structure where each function
+ * `psa_set_key_xxx` sets a field and the corresponding function
+ * `psa_get_key_xxx` retrieves the value of the corresponding field.
+ * However, a future version of the library may report values that are
+ * equivalent to the original one, but have a different encoding. Invalid
+ * values may be mapped to different, also invalid values.
+ *
+ * An attribute structure may contain references to auxiliary resources,
+ * for example pointers to allocated memory or indirect references to
+ * pre-calculated values. In order to free such resources, the application
+ * must call psa_reset_key_attributes(). As an exception, calling
+ * psa_reset_key_attributes() on an attribute structure is optional if
+ * the structure has only been modified by the following functions
+ * since it was initialized or last reset with psa_reset_key_attributes():
+ * - psa_set_key_id()
+ * - psa_set_key_lifetime()
+ * - psa_set_key_type()
+ * - psa_set_key_bits()
+ * - psa_set_key_usage_flags()
+ * - psa_set_key_algorithm()
+ *
+ * Before calling any function on a key attribute structure, the application
+ * must initialize it by any of the following means:
+ * - Set the structure to all-bits-zero, for example:
+ * \code
+ * psa_key_attributes_t attributes;
+ * memset(&attributes, 0, sizeof(attributes));
+ * \endcode
+ * - Initialize the structure to logical zero values, for example:
+ * \code
+ * psa_key_attributes_t attributes = {0};
+ * \endcode
+ * - Initialize the structure to the initializer #PSA_KEY_ATTRIBUTES_INIT,
+ * for example:
+ * \code
+ * psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ * \endcode
+ * - Assign the result of the function psa_key_attributes_init()
+ * to the structure, for example:
+ * \code
+ * psa_key_attributes_t attributes;
+ * attributes = psa_key_attributes_init();
+ * \endcode
+ *
+ * A freshly initialized attribute structure contains the following
+ * values:
+ *
+ * - lifetime: #PSA_KEY_LIFETIME_VOLATILE.
+ * - key identifier: 0 (which is not a valid key identifier).
+ * - type: \c 0 (meaning that the type is unspecified).
+ * - key size: \c 0 (meaning that the size is unspecified).
+ * - usage flags: \c 0 (which allows no usage except exporting a public key).
+ * - algorithm: \c 0 (which allows no cryptographic usage, but allows
+ * exporting).
+ *
+ * A typical sequence to create a key is as follows:
+ * -# Create and initialize an attribute structure.
+ * -# If the key is persistent, call psa_set_key_id().
+ * Also call psa_set_key_lifetime() to place the key in a non-default
+ * location.
+ * -# Set the key policy with psa_set_key_usage_flags() and
+ * psa_set_key_algorithm().
+ * -# Set the key type with psa_set_key_type().
+ * Skip this step if copying an existing key with psa_copy_key().
+ * -# When generating a random key with psa_generate_key() or deriving a key
+ * with psa_key_derivation_output_key(), set the desired key size with
+ * psa_set_key_bits().
+ * -# Call a key creation function: psa_import_key(), psa_generate_key(),
+ * psa_key_derivation_output_key() or psa_copy_key(). This function reads
+ * the attribute structure, creates a key with these attributes, and
+ * outputs a key identifier to the newly created key.
+ * -# The attribute structure is now no longer necessary.
+ * You may call psa_reset_key_attributes(), although this is optional
+ * with the workflow presented here because the attributes currently
+ * defined in this specification do not require any additional resources
+ * beyond the structure itself.
+ *
+ * A typical sequence to query a key's attributes is as follows:
+ * -# Call psa_get_key_attributes().
+ * -# Call `psa_get_key_xxx` functions to retrieve the attribute(s) that
+ * you are interested in.
+ * -# Call psa_reset_key_attributes() to free any resources that may be
+ * used by the attribute structure.
+ *
+ * Once a key has been created, it is impossible to change its attributes.
+ */
+typedef struct psa_key_attributes_s psa_key_attributes_t;
+
+
+#ifndef __DOXYGEN_ONLY__
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+/* Mbed TLS defines this type in crypto_types.h because it is also
+ * visible to applications through an implementation-specific extension.
+ * For the PSA Cryptography specification, this type is only visible
+ * via crypto_se_driver.h.
+ */
+typedef uint64_t psa_key_slot_number_t;
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
+#endif /* !__DOXYGEN_ONLY__ */
+
+/**@}*/
+
+/** \defgroup derivation Key derivation
+ * @{
+ */
+
+/** \brief Encoding of the step of a key derivation.
+ *
+ * Values of this type are generally constructed by macros called
+ * `PSA_KEY_DERIVATION_INPUT_xxx`.
+ */
+typedef uint16_t psa_key_derivation_step_t;
+
+/**@}*/
+
+/** The type of the data structure for PAKE cipher suites.
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure.
+ * Implementation details can change in future versions without notice.
+ */
+typedef struct psa_pake_cipher_suite_s psa_pake_cipher_suite_t;
+
+/** Encoding of the type of the PAKE's primitive.
+*
+* Values defined by this standard will never be in the range 0x80-0xff.
+* Vendors who define additional types must use an encoding in this range.
+*
+* For more information see the documentation of individual
+* \c PSA_PAKE_PRIMITIVE_TYPE_XXX constants.
+*/
+typedef uint8_t psa_pake_primitive_type_t;
+
+/** \brief Encoding of the family of the primitive associated with the PAKE.
+*
+* For more information see the documentation of individual
+* \c PSA_PAKE_PRIMITIVE_TYPE_XXX constants.
+*/
+typedef uint8_t psa_pake_family_t;
+
+/** \brief Encoding of the primitive associated with the PAKE.
+*
+* For more information see the documentation of the #PSA_PAKE_PRIMITIVE macro.
+*/
+typedef uint32_t psa_pake_primitive_t;
+
+/** \brief Encoding of the application role of PAKE
+ *
+ * Encodes the application's role in the algorithm being executed. For more
+ * information see the documentation of individual \c PSA_PAKE_ROLE_XXX
+ * constants.
+ */
+typedef uint8_t psa_pake_role_t;
+
+/** Encoding of input and output indicators for PAKE.
+ *
+ * Some PAKE algorithms need to exchange more data than just a single key share.
+ * This type is for encoding additional input and output data for such
+ * algorithms.
+ */
+typedef uint8_t psa_pake_step_t;
+
+#endif /* PSA_CRYPTO_TYPES_H */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_values.h b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_values.h
new file mode 100644
index 0000000..a2b21ae
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/psa/crypto_values.h
@@ -0,0 +1,2793 @@
+/*
+ * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+/**
+ * \file psa/crypto_values.h
+ *
+ * \brief PSA cryptography module: macros to build and analyze integer values.
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h. Drivers must include the appropriate driver
+ * header file.
+ *
+ * This file contains portable definitions of macros to build and analyze
+ * values of integral types that encode properties of cryptographic keys,
+ * designations of cryptographic algorithms, and error codes returned by
+ * the library.
+ *
+ * Note that many of the constants defined in this file are embedded in
+ * the persistent key store, as part of key metadata (including usage
+ * policies). As a consequence, they must not be changed (unless the storage
+ * format version changes).
+ *
+ * This header file only defines preprocessor macros.
+ */
+
+#ifndef PSA_CRYPTO_VALUES_H
+#define PSA_CRYPTO_VALUES_H
+
+/** \defgroup error Error codes
+ * @{
+ */
+
+/* PSA error codes */
+
+/* Error codes are standardized across PSA domains (framework, crypto, storage,
+ * etc.). Do not change the values in this section or even the expansions
+ * of each macro: it must be possible to `#include` both this header
+ * and some other PSA component's headers in the same C source,
+ * which will lead to duplicate definitions of the `PSA_SUCCESS` and
+ * `PSA_ERROR_xxx` macros, which is ok if and only if the macros expand
+ * to the same sequence of tokens.
+ *
+ * If you must add a new
+ * value, check with the Arm PSA framework group to pick one that other
+ * domains aren't already using. */
+
+/* Tell uncrustify not to touch the constant definitions, otherwise
+ * it might change the spacing to something that is not PSA-compliant
+ * (e.g. adding a space after casts).
+ *
+ * *INDENT-OFF*
+ */
+
+/** The action was completed successfully. */
+#ifndef PSA_SUCCESS
+#define PSA_SUCCESS ((psa_status_t)0)
+#endif
+
+/** An error occurred that does not correspond to any defined
+ * failure cause.
+ *
+ * Implementations may use this error code if none of the other standard
+ * error codes are applicable. */
+#define PSA_ERROR_GENERIC_ERROR ((psa_status_t)-132)
+
+/** The requested operation or a parameter is not supported
+ * by this implementation.
+ *
+ * Implementations should return this error code when an enumeration
+ * parameter such as a key type, algorithm, etc. is not recognized.
+ * If a combination of parameters is recognized and identified as
+ * not valid, return #PSA_ERROR_INVALID_ARGUMENT instead. */
+#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)-134)
+
+/** The requested action is denied by a policy.
+ *
+ * Implementations should return this error code when the parameters
+ * are recognized as valid and supported, and a policy explicitly
+ * denies the requested operation.
+ *
+ * If a subset of the parameters of a function call identify a
+ * forbidden operation, and another subset of the parameters are
+ * not valid or not supported, it is unspecified whether the function
+ * returns #PSA_ERROR_NOT_PERMITTED, #PSA_ERROR_NOT_SUPPORTED or
+ * #PSA_ERROR_INVALID_ARGUMENT. */
+#define PSA_ERROR_NOT_PERMITTED ((psa_status_t)-133)
+
+/** An output buffer is too small.
+ *
+ * Applications can call the \c PSA_xxx_SIZE macro listed in the function
+ * description to determine a sufficient buffer size.
+ *
+ * Implementations should preferably return this error code only
+ * in cases when performing the operation with a larger output
+ * buffer would succeed. However implementations may return this
+ * error if a function has invalid or unsupported parameters in addition
+ * to the parameters that determine the necessary output buffer size. */
+#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t)-138)
+
+/** Asking for an item that already exists
+ *
+ * Implementations should return this error, when attempting
+ * to write an item (like a key) that already exists. */
+#define PSA_ERROR_ALREADY_EXISTS ((psa_status_t)-139)
+
+/** Asking for an item that doesn't exist
+ *
+ * Implementations should return this error, if a requested item (like
+ * a key) does not exist. */
+#define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t)-140)
+
+/** The requested action cannot be performed in the current state.
+ *
+ * Multipart operations return this error when one of the
+ * functions is called out of sequence. Refer to the function
+ * descriptions for permitted sequencing of functions.
+ *
+ * Implementations shall not return this error code to indicate
+ * that a key either exists or not,
+ * but shall instead return #PSA_ERROR_ALREADY_EXISTS or #PSA_ERROR_DOES_NOT_EXIST
+ * as applicable.
+ *
+ * Implementations shall not return this error code to indicate that a
+ * key identifier is invalid, but shall return #PSA_ERROR_INVALID_HANDLE
+ * instead. */
+#define PSA_ERROR_BAD_STATE ((psa_status_t)-137)
+
+/** The parameters passed to the function are invalid.
+ *
+ * Implementations may return this error any time a parameter or
+ * combination of parameters are recognized as invalid.
+ *
+ * Implementations shall not return this error code to indicate that a
+ * key identifier is invalid, but shall return #PSA_ERROR_INVALID_HANDLE
+ * instead.
+ */
+#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)-135)
+
+/** There is not enough runtime memory.
+ *
+ * If the action is carried out across multiple security realms, this
+ * error can refer to available memory in any of the security realms. */
+#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t)-141)
+
+/** There is not enough persistent storage.
+ *
+ * Functions that modify the key storage return this error code if
+ * there is insufficient storage space on the host media. In addition,
+ * many functions that do not otherwise access storage may return this
+ * error code if the implementation requires a mandatory log entry for
+ * the requested action and the log storage space is full. */
+#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)-142)
+
+/** There was a communication failure inside the implementation.
+ *
+ * This can indicate a communication failure between the application
+ * and an external cryptoprocessor or between the cryptoprocessor and
+ * an external volatile or persistent memory. A communication failure
+ * may be transient or permanent depending on the cause.
+ *
+ * \warning If a function returns this error, it is undetermined
+ * whether the requested action has completed or not. Implementations
+ * should return #PSA_SUCCESS on successful completion whenever
+ * possible, however functions may return #PSA_ERROR_COMMUNICATION_FAILURE
+ * if the requested action was completed successfully in an external
+ * cryptoprocessor but there was a breakdown of communication before
+ * the cryptoprocessor could report the status to the application.
+ */
+#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)-145)
+
+/** There was a storage failure that may have led to data loss.
+ *
+ * This error indicates that some persistent storage is corrupted.
+ * It should not be used for a corruption of volatile memory
+ * (use #PSA_ERROR_CORRUPTION_DETECTED), for a communication error
+ * between the cryptoprocessor and its external storage (use
+ * #PSA_ERROR_COMMUNICATION_FAILURE), or when the storage is
+ * in a valid state but is full (use #PSA_ERROR_INSUFFICIENT_STORAGE).
+ *
+ * Note that a storage failure does not indicate that any data that was
+ * previously read is invalid. However this previously read data may no
+ * longer be readable from storage.
+ *
+ * When a storage failure occurs, it is no longer possible to ensure
+ * the global integrity of the keystore. Depending on the global
+ * integrity guarantees offered by the implementation, access to other
+ * data may or may not fail even if the data is still readable but
+ * its integrity cannot be guaranteed.
+ *
+ * Implementations should only use this error code to report a
+ * permanent storage corruption. However application writers should
+ * keep in mind that transient errors while reading the storage may be
+ * reported using this error code. */
+#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)-146)
+
+/** A hardware failure was detected.
+ *
+ * A hardware failure may be transient or permanent depending on the
+ * cause. */
+#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t)-147)
+
+/** A tampering attempt was detected.
+ *
+ * If an application receives this error code, there is no guarantee
+ * that previously accessed or computed data was correct and remains
+ * confidential. Applications should not perform any security function
+ * and should enter a safe failure state.
+ *
+ * Implementations may return this error code if they detect an invalid
+ * state that cannot happen during normal operation and that indicates
+ * that the implementation's security guarantees no longer hold. Depending
+ * on the implementation architecture and on its security and safety goals,
+ * the implementation may forcibly terminate the application.
+ *
+ * This error code is intended as a last resort when a security breach
+ * is detected and it is unsure whether the keystore data is still
+ * protected. Implementations shall only return this error code
+ * to report an alarm from a tampering detector, to indicate that
+ * the confidentiality of stored data can no longer be guaranteed,
+ * or to indicate that the integrity of previously returned data is now
+ * considered compromised. Implementations shall not use this error code
+ * to indicate a hardware failure that merely makes it impossible to
+ * perform the requested operation (use #PSA_ERROR_COMMUNICATION_FAILURE,
+ * #PSA_ERROR_STORAGE_FAILURE, #PSA_ERROR_HARDWARE_FAILURE,
+ * #PSA_ERROR_INSUFFICIENT_ENTROPY or other applicable error code
+ * instead).
+ *
+ * This error indicates an attack against the application. Implementations
+ * shall not return this error code as a consequence of the behavior of
+ * the application itself. */
+#define PSA_ERROR_CORRUPTION_DETECTED ((psa_status_t)-151)
+
+/** There is not enough entropy to generate random data needed
+ * for the requested action.
+ *
+ * This error indicates a failure of a hardware random generator.
+ * Application writers should note that this error can be returned not
+ * only by functions whose purpose is to generate random data, such
+ * as key, IV or nonce generation, but also by functions that execute
+ * an algorithm with a randomized result, as well as functions that
+ * use randomization of intermediate computations as a countermeasure
+ * to certain attacks.
+ *
+ * Implementations should avoid returning this error after psa_crypto_init()
+ * has succeeded. Implementations should generate sufficient
+ * entropy during initialization and subsequently use a cryptographically
+ * secure pseudorandom generator (PRNG). However implementations may return
+ * this error at any time if a policy requires the PRNG to be reseeded
+ * during normal operation. */
+#define PSA_ERROR_INSUFFICIENT_ENTROPY ((psa_status_t)-148)
+
+/** The signature, MAC or hash is incorrect.
+ *
+ * Verification functions return this error if the verification
+ * calculations completed successfully, and the value to be verified
+ * was determined to be incorrect.
+ *
+ * If the value to verify has an invalid size, implementations may return
+ * either #PSA_ERROR_INVALID_ARGUMENT or #PSA_ERROR_INVALID_SIGNATURE. */
+#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)-149)
+
+/** The decrypted padding is incorrect.
+ *
+ * \warning In some protocols, when decrypting data, it is essential that
+ * the behavior of the application does not depend on whether the padding
+ * is correct, down to precise timing. Applications should prefer
+ * protocols that use authenticated encryption rather than plain
+ * encryption. If the application must perform a decryption of
+ * unauthenticated data, the application writer should take care not
+ * to reveal whether the padding is invalid.
+ *
+ * Implementations should strive to make valid and invalid padding
+ * as close as possible to indistinguishable to an external observer.
+ * In particular, the timing of a decryption operation should not
+ * depend on the validity of the padding. */
+#define PSA_ERROR_INVALID_PADDING ((psa_status_t)-150)
+
+/** Return this error when there's insufficient data when attempting
+ * to read from a resource. */
+#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143)
+
+/** The key identifier is not valid. See also :ref:\`key-handles\`.
+ */
+#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136)
+
+/** Stored data has been corrupted.
+ *
+ * This error indicates that some persistent storage has suffered corruption.
+ * It does not indicate the following situations, which have specific error
+ * codes:
+ *
+ * - A corruption of volatile memory - use #PSA_ERROR_CORRUPTION_DETECTED.
+ * - A communication error between the cryptoprocessor and its external
+ * storage - use #PSA_ERROR_COMMUNICATION_FAILURE.
+ * - When the storage is in a valid state but is full - use
+ * #PSA_ERROR_INSUFFICIENT_STORAGE.
+ * - When the storage fails for other reasons - use
+ * #PSA_ERROR_STORAGE_FAILURE.
+ * - When the stored data is not valid - use #PSA_ERROR_DATA_INVALID.
+ *
+ * \note A storage corruption does not indicate that any data that was
+ * previously read is invalid. However this previously read data might no
+ * longer be readable from storage.
+ *
+ * When a storage failure occurs, it is no longer possible to ensure the
+ * global integrity of the keystore.
+ */
+#define PSA_ERROR_DATA_CORRUPT ((psa_status_t)-152)
+
+/** Data read from storage is not valid for the implementation.
+ *
+ * This error indicates that some data read from storage does not have a valid
+ * format. It does not indicate the following situations, which have specific
+ * error codes:
+ *
+ * - When the storage or stored data is corrupted - use #PSA_ERROR_DATA_CORRUPT
+ * - When the storage fails for other reasons - use #PSA_ERROR_STORAGE_FAILURE
+ * - An invalid argument to the API - use #PSA_ERROR_INVALID_ARGUMENT
+ *
+ * This error is typically a result of either storage corruption on a
+ * cleartext storage backend, or an attempt to read data that was
+ * written by an incompatible version of the library.
+ */
+#define PSA_ERROR_DATA_INVALID ((psa_status_t)-153)
+
+/** The function that returns this status is defined as interruptible and
+ * still has work to do, thus the user should call the function again with the
+ * same operation context until it either returns #PSA_SUCCESS or any other
+ * error. This is not an error per se, more a notification of status.
+ */
+#define PSA_OPERATION_INCOMPLETE ((psa_status_t)-248)
+
+/* *INDENT-ON* */
+
+/**@}*/
+
+/** \defgroup crypto_types Key and algorithm types
+ * @{
+ */
+
+/* Note that key type values, including ECC family and DH group values, are
+ * embedded in the persistent key store, as part of key metadata. As a
+ * consequence, they must not be changed (unless the storage format version
+ * changes).
+ */
+
+/** An invalid key type value.
+ *
+ * Zero is not the encoding of any key type.
+ */
+#define PSA_KEY_TYPE_NONE ((psa_key_type_t) 0x0000)
+
+/** Vendor-defined key type flag.
+ *
+ * Key types defined by this standard will never have the
+ * #PSA_KEY_TYPE_VENDOR_FLAG bit set. Vendors who define additional key types
+ * must use an encoding with the #PSA_KEY_TYPE_VENDOR_FLAG bit set and should
+ * respect the bitwise structure used by standard encodings whenever practical.
+ */
+#define PSA_KEY_TYPE_VENDOR_FLAG ((psa_key_type_t) 0x8000)
+
+#define PSA_KEY_TYPE_CATEGORY_MASK ((psa_key_type_t) 0x7000)
+#define PSA_KEY_TYPE_CATEGORY_RAW ((psa_key_type_t) 0x1000)
+#define PSA_KEY_TYPE_CATEGORY_SYMMETRIC ((psa_key_type_t) 0x2000)
+#define PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY ((psa_key_type_t) 0x4000)
+#define PSA_KEY_TYPE_CATEGORY_KEY_PAIR ((psa_key_type_t) 0x7000)
+
+#define PSA_KEY_TYPE_CATEGORY_FLAG_PAIR ((psa_key_type_t) 0x3000)
+
+/** Whether a key type is vendor-defined.
+ *
+ * See also #PSA_KEY_TYPE_VENDOR_FLAG.
+ */
+#define PSA_KEY_TYPE_IS_VENDOR_DEFINED(type) \
+ (((type) & PSA_KEY_TYPE_VENDOR_FLAG) != 0)
+
+/** Whether a key type is an unstructured array of bytes.
+ *
+ * This encompasses both symmetric keys and non-key data.
+ */
+#define PSA_KEY_TYPE_IS_UNSTRUCTURED(type) \
+ (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_RAW || \
+ ((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC)
+
+/** Whether a key type is asymmetric: either a key pair or a public key. */
+#define PSA_KEY_TYPE_IS_ASYMMETRIC(type) \
+ (((type) & PSA_KEY_TYPE_CATEGORY_MASK \
+ & ~PSA_KEY_TYPE_CATEGORY_FLAG_PAIR) == \
+ PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY)
+/** Whether a key type is the public part of a key pair. */
+#define PSA_KEY_TYPE_IS_PUBLIC_KEY(type) \
+ (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY)
+/** Whether a key type is a key pair containing a private part and a public
+ * part. */
+#define PSA_KEY_TYPE_IS_KEY_PAIR(type) \
+ (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_KEY_PAIR)
+/** The key pair type corresponding to a public key type.
+ *
+ * You may also pass a key pair type as \p type, it will be left unchanged.
+ *
+ * \param type A public key type or key pair type.
+ *
+ * \return The corresponding key pair type.
+ * If \p type is not a public key or a key pair,
+ * the return value is undefined.
+ */
+#define PSA_KEY_TYPE_KEY_PAIR_OF_PUBLIC_KEY(type) \
+ ((type) | PSA_KEY_TYPE_CATEGORY_FLAG_PAIR)
+/** The public key type corresponding to a key pair type.
+ *
+ * You may also pass a key pair type as \p type, it will be left unchanged.
+ *
+ * \param type A public key type or key pair type.
+ *
+ * \return The corresponding public key type.
+ * If \p type is not a public key or a key pair,
+ * the return value is undefined.
+ */
+#define PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) \
+ ((type) & ~PSA_KEY_TYPE_CATEGORY_FLAG_PAIR)
+
+/** Raw data.
+ *
+ * A "key" of this type cannot be used for any cryptographic operation.
+ * Applications may use this type to store arbitrary data in the keystore. */
+#define PSA_KEY_TYPE_RAW_DATA ((psa_key_type_t) 0x1001)
+
+/** HMAC key.
+ *
+ * The key policy determines which underlying hash algorithm the key can be
+ * used for.
+ *
+ * HMAC keys should generally have the same size as the underlying hash.
+ * This size can be calculated with #PSA_HASH_LENGTH(\c alg) where
+ * \c alg is the HMAC algorithm or the underlying hash algorithm. */
+#define PSA_KEY_TYPE_HMAC ((psa_key_type_t) 0x1100)
+
+/** A secret for key derivation.
+ *
+ * This key type is for high-entropy secrets only. For low-entropy secrets,
+ * #PSA_KEY_TYPE_PASSWORD should be used instead.
+ *
+ * These keys can be used as the #PSA_KEY_DERIVATION_INPUT_SECRET or
+ * #PSA_KEY_DERIVATION_INPUT_PASSWORD input of key derivation algorithms.
+ *
+ * The key policy determines which key derivation algorithm the key
+ * can be used for.
+ */
+#define PSA_KEY_TYPE_DERIVE ((psa_key_type_t) 0x1200)
+
+/** A low-entropy secret for password hashing or key derivation.
+ *
+ * This key type is suitable for passwords and passphrases which are typically
+ * intended to be memorizable by humans, and have a low entropy relative to
+ * their size. It can be used for randomly generated or derived keys with
+ * maximum or near-maximum entropy, but #PSA_KEY_TYPE_DERIVE is more suitable
+ * for such keys. It is not suitable for passwords with extremely low entropy,
+ * such as numerical PINs.
+ *
+ * These keys can be used as the #PSA_KEY_DERIVATION_INPUT_PASSWORD input of
+ * key derivation algorithms. Algorithms that accept such an input were
+ * designed to accept low-entropy secret and are known as password hashing or
+ * key stretching algorithms.
+ *
+ * These keys cannot be used as the #PSA_KEY_DERIVATION_INPUT_SECRET input of
+ * key derivation algorithms, as the algorithms that take such an input expect
+ * it to be high-entropy.
+ *
+ * The key policy determines which key derivation algorithm the key can be
+ * used for, among the permissible subset defined above.
+ */
+#define PSA_KEY_TYPE_PASSWORD ((psa_key_type_t) 0x1203)
+
+/** A secret value that can be used to verify a password hash.
+ *
+ * The key policy determines which key derivation algorithm the key
+ * can be used for, among the same permissible subset as for
+ * #PSA_KEY_TYPE_PASSWORD.
+ */
+#define PSA_KEY_TYPE_PASSWORD_HASH ((psa_key_type_t) 0x1205)
+
+/** A secret value that can be used in when computing a password hash.
+ *
+ * The key policy determines which key derivation algorithm the key
+ * can be used for, among the subset of algorithms that can use pepper.
+ */
+#define PSA_KEY_TYPE_PEPPER ((psa_key_type_t) 0x1206)
+
+/** Key for a cipher, AEAD or MAC algorithm based on the AES block cipher.
+ *
+ * The size of the key can be 16 bytes (AES-128), 24 bytes (AES-192) or
+ * 32 bytes (AES-256).
+ */
+#define PSA_KEY_TYPE_AES ((psa_key_type_t) 0x2400)
+
+/** Key for a cipher, AEAD or MAC algorithm based on the
+ * ARIA block cipher. */
+#define PSA_KEY_TYPE_ARIA ((psa_key_type_t) 0x2406)
+
+/** Key for a cipher or MAC algorithm based on DES or 3DES (Triple-DES).
+ *
+ * The size of the key can be 64 bits (single DES), 128 bits (2-key 3DES) or
+ * 192 bits (3-key 3DES).
+ *
+ * Note that single DES and 2-key 3DES are weak and strongly
+ * deprecated and should only be used to decrypt legacy data. 3-key 3DES
+ * is weak and deprecated and should only be used in legacy protocols.
+ */
+#define PSA_KEY_TYPE_DES ((psa_key_type_t) 0x2301)
+
+/** Key for a cipher, AEAD or MAC algorithm based on the
+ * Camellia block cipher. */
+#define PSA_KEY_TYPE_CAMELLIA ((psa_key_type_t) 0x2403)
+
+/** Key for the ChaCha20 stream cipher or the Chacha20-Poly1305 AEAD algorithm.
+ *
+ * ChaCha20 and the ChaCha20_Poly1305 construction are defined in RFC 7539.
+ *
+ * \note For ChaCha20 and ChaCha20_Poly1305, Mbed TLS only supports
+ * 12-byte nonces.
+ *
+ * \note For ChaCha20, the initial counter value is 0. To encrypt or decrypt
+ * with the initial counter value 1, you can process and discard a
+ * 64-byte block before the real data.
+ */
+#define PSA_KEY_TYPE_CHACHA20 ((psa_key_type_t) 0x2004)
+
+/** RSA public key.
+ *
+ * The size of an RSA key is the bit size of the modulus.
+ */
+#define PSA_KEY_TYPE_RSA_PUBLIC_KEY ((psa_key_type_t) 0x4001)
+/** RSA key pair (private and public key).
+ *
+ * The size of an RSA key is the bit size of the modulus.
+ */
+#define PSA_KEY_TYPE_RSA_KEY_PAIR ((psa_key_type_t) 0x7001)
+/** Whether a key type is an RSA key (pair or public-only). */
+#define PSA_KEY_TYPE_IS_RSA(type) \
+ (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY)
+
+#define PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE ((psa_key_type_t) 0x4100)
+#define PSA_KEY_TYPE_ECC_KEY_PAIR_BASE ((psa_key_type_t) 0x7100)
+#define PSA_KEY_TYPE_ECC_CURVE_MASK ((psa_key_type_t) 0x00ff)
+/** Elliptic curve key pair.
+ *
+ * The size of an elliptic curve key is the bit size associated with the curve,
+ * i.e. the bit size of *q* for a curve over a field *F<sub>q</sub>*.
+ * See the documentation of `PSA_ECC_FAMILY_xxx` curve families for details.
+ *
+ * \param curve A value of type ::psa_ecc_family_t that
+ * identifies the ECC curve to be used.
+ */
+#define PSA_KEY_TYPE_ECC_KEY_PAIR(curve) \
+ (PSA_KEY_TYPE_ECC_KEY_PAIR_BASE | (curve))
+/** Elliptic curve public key.
+ *
+ * The size of an elliptic curve public key is the same as the corresponding
+ * private key (see #PSA_KEY_TYPE_ECC_KEY_PAIR and the documentation of
+ * `PSA_ECC_FAMILY_xxx` curve families).
+ *
+ * \param curve A value of type ::psa_ecc_family_t that
+ * identifies the ECC curve to be used.
+ */
+#define PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve) \
+ (PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE | (curve))
+
+/** Whether a key type is an elliptic curve key (pair or public-only). */
+#define PSA_KEY_TYPE_IS_ECC(type) \
+ ((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) & \
+ ~PSA_KEY_TYPE_ECC_CURVE_MASK) == PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE)
+/** Whether a key type is an elliptic curve key pair. */
+#define PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type) \
+ (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \
+ PSA_KEY_TYPE_ECC_KEY_PAIR_BASE)
+/** Whether a key type is an elliptic curve public key. */
+#define PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type) \
+ (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \
+ PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE)
+
+/** Extract the curve from an elliptic curve key type. */
+#define PSA_KEY_TYPE_ECC_GET_FAMILY(type) \
+ ((psa_ecc_family_t) (PSA_KEY_TYPE_IS_ECC(type) ? \
+ ((type) & PSA_KEY_TYPE_ECC_CURVE_MASK) : \
+ 0))
+
+/** Check if the curve of given family is Weierstrass elliptic curve. */
+#define PSA_ECC_FAMILY_IS_WEIERSTRASS(family) ((family & 0xc0) == 0)
+
+/** SEC Koblitz curves over prime fields.
+ *
+ * This family comprises the following curves:
+ * secp192k1, secp224k1, secp256k1.
+ * They are defined in _Standards for Efficient Cryptography_,
+ * _SEC 2: Recommended Elliptic Curve Domain Parameters_.
+ * https://www.secg.org/sec2-v2.pdf
+ */
+#define PSA_ECC_FAMILY_SECP_K1 ((psa_ecc_family_t) 0x17)
+
+/** SEC random curves over prime fields.
+ *
+ * This family comprises the following curves:
+ * secp192k1, secp224r1, secp256r1, secp384r1, secp521r1.
+ * They are defined in _Standards for Efficient Cryptography_,
+ * _SEC 2: Recommended Elliptic Curve Domain Parameters_.
+ * https://www.secg.org/sec2-v2.pdf
+ */
+#define PSA_ECC_FAMILY_SECP_R1 ((psa_ecc_family_t) 0x12)
+/* SECP160R2 (SEC2 v1, obsolete) */
+#define PSA_ECC_FAMILY_SECP_R2 ((psa_ecc_family_t) 0x1b)
+
+/** SEC Koblitz curves over binary fields.
+ *
+ * This family comprises the following curves:
+ * sect163k1, sect233k1, sect239k1, sect283k1, sect409k1, sect571k1.
+ * They are defined in _Standards for Efficient Cryptography_,
+ * _SEC 2: Recommended Elliptic Curve Domain Parameters_.
+ * https://www.secg.org/sec2-v2.pdf
+ */
+#define PSA_ECC_FAMILY_SECT_K1 ((psa_ecc_family_t) 0x27)
+
+/** SEC random curves over binary fields.
+ *
+ * This family comprises the following curves:
+ * sect163r1, sect233r1, sect283r1, sect409r1, sect571r1.
+ * They are defined in _Standards for Efficient Cryptography_,
+ * _SEC 2: Recommended Elliptic Curve Domain Parameters_.
+ * https://www.secg.org/sec2-v2.pdf
+ */
+#define PSA_ECC_FAMILY_SECT_R1 ((psa_ecc_family_t) 0x22)
+
+/** SEC additional random curves over binary fields.
+ *
+ * This family comprises the following curve:
+ * sect163r2.
+ * It is defined in _Standards for Efficient Cryptography_,
+ * _SEC 2: Recommended Elliptic Curve Domain Parameters_.
+ * https://www.secg.org/sec2-v2.pdf
+ */
+#define PSA_ECC_FAMILY_SECT_R2 ((psa_ecc_family_t) 0x2b)
+
+/** Brainpool P random curves.
+ *
+ * This family comprises the following curves:
+ * brainpoolP160r1, brainpoolP192r1, brainpoolP224r1, brainpoolP256r1,
+ * brainpoolP320r1, brainpoolP384r1, brainpoolP512r1.
+ * It is defined in RFC 5639.
+ */
+#define PSA_ECC_FAMILY_BRAINPOOL_P_R1 ((psa_ecc_family_t) 0x30)
+
+/** Curve25519 and Curve448.
+ *
+ * This family comprises the following Montgomery curves:
+ * - 255-bit: Bernstein et al.,
+ * _Curve25519: new Diffie-Hellman speed records_, LNCS 3958, 2006.
+ * The algorithm #PSA_ALG_ECDH performs X25519 when used with this curve.
+ * - 448-bit: Hamburg,
+ * _Ed448-Goldilocks, a new elliptic curve_, NIST ECC Workshop, 2015.
+ * The algorithm #PSA_ALG_ECDH performs X448 when used with this curve.
+ */
+#define PSA_ECC_FAMILY_MONTGOMERY ((psa_ecc_family_t) 0x41)
+
+/** The twisted Edwards curves Ed25519 and Ed448.
+ *
+ * These curves are suitable for EdDSA (#PSA_ALG_PURE_EDDSA for both curves,
+ * #PSA_ALG_ED25519PH for the 255-bit curve,
+ * #PSA_ALG_ED448PH for the 448-bit curve).
+ *
+ * This family comprises the following twisted Edwards curves:
+ * - 255-bit: Edwards25519, the twisted Edwards curve birationally equivalent
+ * to Curve25519.
+ * Bernstein et al., _Twisted Edwards curves_, Africacrypt 2008.
+ * - 448-bit: Edwards448, the twisted Edwards curve birationally equivalent
+ * to Curve448.
+ * Hamburg, _Ed448-Goldilocks, a new elliptic curve_, NIST ECC Workshop, 2015.
+ */
+#define PSA_ECC_FAMILY_TWISTED_EDWARDS ((psa_ecc_family_t) 0x42)
+
+#define PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE ((psa_key_type_t) 0x4200)
+#define PSA_KEY_TYPE_DH_KEY_PAIR_BASE ((psa_key_type_t) 0x7200)
+#define PSA_KEY_TYPE_DH_GROUP_MASK ((psa_key_type_t) 0x00ff)
+/** Diffie-Hellman key pair.
+ *
+ * \param group A value of type ::psa_dh_family_t that identifies the
+ * Diffie-Hellman group to be used.
+ */
+#define PSA_KEY_TYPE_DH_KEY_PAIR(group) \
+ (PSA_KEY_TYPE_DH_KEY_PAIR_BASE | (group))
+/** Diffie-Hellman public key.
+ *
+ * \param group A value of type ::psa_dh_family_t that identifies the
+ * Diffie-Hellman group to be used.
+ */
+#define PSA_KEY_TYPE_DH_PUBLIC_KEY(group) \
+ (PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE | (group))
+
+/** Whether a key type is a Diffie-Hellman key (pair or public-only). */
+#define PSA_KEY_TYPE_IS_DH(type) \
+ ((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) & \
+ ~PSA_KEY_TYPE_DH_GROUP_MASK) == PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE)
+/** Whether a key type is a Diffie-Hellman key pair. */
+#define PSA_KEY_TYPE_IS_DH_KEY_PAIR(type) \
+ (((type) & ~PSA_KEY_TYPE_DH_GROUP_MASK) == \
+ PSA_KEY_TYPE_DH_KEY_PAIR_BASE)
+/** Whether a key type is a Diffie-Hellman public key. */
+#define PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) \
+ (((type) & ~PSA_KEY_TYPE_DH_GROUP_MASK) == \
+ PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE)
+
+/** Extract the group from a Diffie-Hellman key type. */
+#define PSA_KEY_TYPE_DH_GET_FAMILY(type) \
+ ((psa_dh_family_t) (PSA_KEY_TYPE_IS_DH(type) ? \
+ ((type) & PSA_KEY_TYPE_DH_GROUP_MASK) : \
+ 0))
+
+/** Diffie-Hellman groups defined in RFC 7919 Appendix A.
+ *
+ * This family includes groups with the following key sizes (in bits):
+ * 2048, 3072, 4096, 6144, 8192. A given implementation may support
+ * all of these sizes or only a subset.
+ */
+#define PSA_DH_FAMILY_RFC7919 ((psa_dh_family_t) 0x03)
+
+/** Diffie-Hellman groups defined in RFC 3526.
+ *
+ * This family includes groups with the following key sizes (in bits):
+ * 1536, 2048, 3072, 4096, 6144, 8192. A given implementation may support
+ * all of these sizes or only a subset.
+ */
+#define PSA_DH_FAMILY_RFC3526 ((psa_dh_family_t) 0x05) /*!!OM*/
+
+#define PSA_GET_KEY_TYPE_BLOCK_SIZE_EXPONENT(type) \
+ (((type) >> 8) & 7)
+/** The block size of a block cipher.
+ *
+ * \param type A cipher key type (value of type #psa_key_type_t).
+ *
+ * \return The block size for a block cipher, or 1 for a stream cipher.
+ * The return value is undefined if \p type is not a supported
+ * cipher key type.
+ *
+ * \note It is possible to build stream cipher algorithms on top of a block
+ * cipher, for example CTR mode (#PSA_ALG_CTR).
+ * This macro only takes the key type into account, so it cannot be
+ * used to determine the size of the data that #psa_cipher_update()
+ * might buffer for future processing in general.
+ *
+ * \note This macro returns a compile-time constant if its argument is one.
+ *
+ * \warning This macro may evaluate its argument multiple times.
+ */
+#define PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) \
+ (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \
+ 1u << PSA_GET_KEY_TYPE_BLOCK_SIZE_EXPONENT(type) : \
+ 0u)
+
+/* Note that algorithm values are embedded in the persistent key store,
+ * as part of key metadata. As a consequence, they must not be changed
+ * (unless the storage format version changes).
+ */
+
+/** Vendor-defined algorithm flag.
+ *
+ * Algorithms defined by this standard will never have the #PSA_ALG_VENDOR_FLAG
+ * bit set. Vendors who define additional algorithms must use an encoding with
+ * the #PSA_ALG_VENDOR_FLAG bit set and should respect the bitwise structure
+ * used by standard encodings whenever practical.
+ */
+#define PSA_ALG_VENDOR_FLAG ((psa_algorithm_t) 0x80000000)
+
+#define PSA_ALG_CATEGORY_MASK ((psa_algorithm_t) 0x7f000000)
+#define PSA_ALG_CATEGORY_HASH ((psa_algorithm_t) 0x02000000)
+#define PSA_ALG_CATEGORY_MAC ((psa_algorithm_t) 0x03000000)
+#define PSA_ALG_CATEGORY_CIPHER ((psa_algorithm_t) 0x04000000)
+#define PSA_ALG_CATEGORY_AEAD ((psa_algorithm_t) 0x05000000)
+#define PSA_ALG_CATEGORY_SIGN ((psa_algorithm_t) 0x06000000)
+#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION ((psa_algorithm_t) 0x07000000)
+#define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t) 0x08000000)
+#define PSA_ALG_CATEGORY_KEY_AGREEMENT ((psa_algorithm_t) 0x09000000)
+
+/** Whether an algorithm is vendor-defined.
+ *
+ * See also #PSA_ALG_VENDOR_FLAG.
+ */
+#define PSA_ALG_IS_VENDOR_DEFINED(alg) \
+ (((alg) & PSA_ALG_VENDOR_FLAG) != 0)
+
+/** Whether the specified algorithm is a hash algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a hash algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_HASH(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_HASH)
+
+/** Whether the specified algorithm is a MAC algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a MAC algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_MAC(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_MAC)
+
+/** Whether the specified algorithm is a symmetric cipher algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a symmetric cipher algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_CIPHER(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_CIPHER)
+
+/** Whether the specified algorithm is an authenticated encryption
+ * with associated data (AEAD) algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is an AEAD algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_AEAD(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_AEAD)
+
+/** Whether the specified algorithm is an asymmetric signature algorithm,
+ * also known as public-key signature algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is an asymmetric signature algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_SIGN(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_SIGN)
+
+/** Whether the specified algorithm is an asymmetric encryption algorithm,
+ * also known as public-key encryption algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is an asymmetric encryption algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION)
+
+/** Whether the specified algorithm is a key agreement algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a key agreement algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_KEY_AGREEMENT(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_AGREEMENT)
+
+/** Whether the specified algorithm is a key derivation algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a key derivation algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_KEY_DERIVATION(alg) \
+ (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION)
+
+/** Whether the specified algorithm is a key stretching / password hashing
+ * algorithm.
+ *
+ * A key stretching / password hashing algorithm is a key derivation algorithm
+ * that is suitable for use with a low-entropy secret such as a password.
+ * Equivalently, it's a key derivation algorithm that uses a
+ * #PSA_KEY_DERIVATION_INPUT_PASSWORD input step.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a key stretching / password hashing algorithm, 0
+ * otherwise. This macro may return either 0 or 1 if \p alg is not a
+ * supported algorithm identifier.
+ */
+#define PSA_ALG_IS_KEY_DERIVATION_STRETCHING(alg) \
+ (PSA_ALG_IS_KEY_DERIVATION(alg) && \
+ (alg) & PSA_ALG_KEY_DERIVATION_STRETCHING_FLAG)
+
+/** An invalid algorithm identifier value. */
+/* *INDENT-OFF* (https://github.com/ARM-software/psa-arch-tests/issues/337) */
+#define PSA_ALG_NONE ((psa_algorithm_t)0)
+/* *INDENT-ON* */
+
+#define PSA_ALG_HASH_MASK ((psa_algorithm_t) 0x000000ff)
+/** MD5 */
+#define PSA_ALG_MD5 ((psa_algorithm_t) 0x02000003)
+/** PSA_ALG_RIPEMD160 */
+#define PSA_ALG_RIPEMD160 ((psa_algorithm_t) 0x02000004)
+/** SHA1 */
+#define PSA_ALG_SHA_1 ((psa_algorithm_t) 0x02000005)
+/** SHA2-224 */
+#define PSA_ALG_SHA_224 ((psa_algorithm_t) 0x02000008)
+/** SHA2-256 */
+#define PSA_ALG_SHA_256 ((psa_algorithm_t) 0x02000009)
+/** SHA2-384 */
+#define PSA_ALG_SHA_384 ((psa_algorithm_t) 0x0200000a)
+/** SHA2-512 */
+#define PSA_ALG_SHA_512 ((psa_algorithm_t) 0x0200000b)
+/** SHA2-512/224 */
+#define PSA_ALG_SHA_512_224 ((psa_algorithm_t) 0x0200000c)
+/** SHA2-512/256 */
+#define PSA_ALG_SHA_512_256 ((psa_algorithm_t) 0x0200000d)
+/** SHA3-224 */
+#define PSA_ALG_SHA3_224 ((psa_algorithm_t) 0x02000010)
+/** SHA3-256 */
+#define PSA_ALG_SHA3_256 ((psa_algorithm_t) 0x02000011)
+/** SHA3-384 */
+#define PSA_ALG_SHA3_384 ((psa_algorithm_t) 0x02000012)
+/** SHA3-512 */
+#define PSA_ALG_SHA3_512 ((psa_algorithm_t) 0x02000013)
+/** The first 512 bits (64 bytes) of the SHAKE256 output.
+ *
+ * This is the prehashing for Ed448ph (see #PSA_ALG_ED448PH). For other
+ * scenarios where a hash function based on SHA3/SHAKE is desired, SHA3-512
+ * has the same output size and a (theoretically) higher security strength.
+ */
+#define PSA_ALG_SHAKE256_512 ((psa_algorithm_t) 0x02000015)
+
+/** In a hash-and-sign algorithm policy, allow any hash algorithm.
+ *
+ * This value may be used to form the algorithm usage field of a policy
+ * for a signature algorithm that is parametrized by a hash. The key
+ * may then be used to perform operations using the same signature
+ * algorithm parametrized with any supported hash.
+ *
+ * That is, suppose that `PSA_xxx_SIGNATURE` is one of the following macros:
+ * - #PSA_ALG_RSA_PKCS1V15_SIGN, #PSA_ALG_RSA_PSS, #PSA_ALG_RSA_PSS_ANY_SALT,
+ * - #PSA_ALG_ECDSA, #PSA_ALG_DETERMINISTIC_ECDSA.
+ * Then you may create and use a key as follows:
+ * - Set the key usage field using #PSA_ALG_ANY_HASH, for example:
+ * ```
+ * psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); // or VERIFY
+ * psa_set_key_algorithm(&attributes, PSA_xxx_SIGNATURE(PSA_ALG_ANY_HASH));
+ * ```
+ * - Import or generate key material.
+ * - Call psa_sign_hash() or psa_verify_hash(), passing
+ * an algorithm built from `PSA_xxx_SIGNATURE` and a specific hash. Each
+ * call to sign or verify a message may use a different hash.
+ * ```
+ * psa_sign_hash(key, PSA_xxx_SIGNATURE(PSA_ALG_SHA_256), ...);
+ * psa_sign_hash(key, PSA_xxx_SIGNATURE(PSA_ALG_SHA_512), ...);
+ * psa_sign_hash(key, PSA_xxx_SIGNATURE(PSA_ALG_SHA3_256), ...);
+ * ```
+ *
+ * This value may not be used to build other algorithms that are
+ * parametrized over a hash. For any valid use of this macro to build
+ * an algorithm \c alg, #PSA_ALG_IS_HASH_AND_SIGN(\c alg) is true.
+ *
+ * This value may not be used to build an algorithm specification to
+ * perform an operation. It is only valid to build policies.
+ */
+#define PSA_ALG_ANY_HASH ((psa_algorithm_t) 0x020000ff)
+
+#define PSA_ALG_MAC_SUBCATEGORY_MASK ((psa_algorithm_t) 0x00c00000)
+#define PSA_ALG_HMAC_BASE ((psa_algorithm_t) 0x03800000)
+/** Macro to build an HMAC algorithm.
+ *
+ * For example, #PSA_ALG_HMAC(#PSA_ALG_SHA_256) is HMAC-SHA-256.
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return The corresponding HMAC algorithm.
+ * \return Unspecified if \p hash_alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_HMAC(hash_alg) \
+ (PSA_ALG_HMAC_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+
+#define PSA_ALG_HMAC_GET_HASH(hmac_alg) \
+ (PSA_ALG_CATEGORY_HASH | ((hmac_alg) & PSA_ALG_HASH_MASK))
+
+/** Whether the specified algorithm is an HMAC algorithm.
+ *
+ * HMAC is a family of MAC algorithms that are based on a hash function.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is an HMAC algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_HMAC(alg) \
+ (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_MAC_SUBCATEGORY_MASK)) == \
+ PSA_ALG_HMAC_BASE)
+
+/* In the encoding of a MAC algorithm, the bits corresponding to
+ * PSA_ALG_MAC_TRUNCATION_MASK encode the length to which the MAC is
+ * truncated. As an exception, the value 0 means the untruncated algorithm,
+ * whatever its length is. The length is encoded in 6 bits, so it can
+ * reach up to 63; the largest MAC is 64 bytes so its trivial truncation
+ * to full length is correctly encoded as 0 and any non-trivial truncation
+ * is correctly encoded as a value between 1 and 63. */
+#define PSA_ALG_MAC_TRUNCATION_MASK ((psa_algorithm_t) 0x003f0000)
+#define PSA_MAC_TRUNCATION_OFFSET 16
+
+/* In the encoding of a MAC algorithm, the bit corresponding to
+ * #PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG encodes the fact that the algorithm
+ * is a wildcard algorithm. A key with such wildcard algorithm as permitted
+ * algorithm policy can be used with any algorithm corresponding to the
+ * same base class and having a (potentially truncated) MAC length greater or
+ * equal than the one encoded in #PSA_ALG_MAC_TRUNCATION_MASK. */
+#define PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ((psa_algorithm_t) 0x00008000)
+
+/** Macro to build a truncated MAC algorithm.
+ *
+ * A truncated MAC algorithm is identical to the corresponding MAC
+ * algorithm except that the MAC value for the truncated algorithm
+ * consists of only the first \p mac_length bytes of the MAC value
+ * for the untruncated algorithm.
+ *
+ * \note This macro may allow constructing algorithm identifiers that
+ * are not valid, either because the specified length is larger
+ * than the untruncated MAC or because the specified length is
+ * smaller than permitted by the implementation.
+ *
+ * \note It is implementation-defined whether a truncated MAC that
+ * is truncated to the same length as the MAC of the untruncated
+ * algorithm is considered identical to the untruncated algorithm
+ * for policy comparison purposes.
+ *
+ * \param mac_alg A MAC algorithm identifier (value of type
+ * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p mac_alg)
+ * is true). This may be a truncated or untruncated
+ * MAC algorithm.
+ * \param mac_length Desired length of the truncated MAC in bytes.
+ * This must be at most the full length of the MAC
+ * and must be at least an implementation-specified
+ * minimum. The implementation-specified minimum
+ * shall not be zero.
+ *
+ * \return The corresponding MAC algorithm with the specified
+ * length.
+ * \return Unspecified if \p mac_alg is not a supported
+ * MAC algorithm or if \p mac_length is too small or
+ * too large for the specified MAC algorithm.
+ */
+#define PSA_ALG_TRUNCATED_MAC(mac_alg, mac_length) \
+ (((mac_alg) & ~(PSA_ALG_MAC_TRUNCATION_MASK | \
+ PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG)) | \
+ ((mac_length) << PSA_MAC_TRUNCATION_OFFSET & PSA_ALG_MAC_TRUNCATION_MASK))
+
+/** Macro to build the base MAC algorithm corresponding to a truncated
+ * MAC algorithm.
+ *
+ * \param mac_alg A MAC algorithm identifier (value of type
+ * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p mac_alg)
+ * is true). This may be a truncated or untruncated
+ * MAC algorithm.
+ *
+ * \return The corresponding base MAC algorithm.
+ * \return Unspecified if \p mac_alg is not a supported
+ * MAC algorithm.
+ */
+#define PSA_ALG_FULL_LENGTH_MAC(mac_alg) \
+ ((mac_alg) & ~(PSA_ALG_MAC_TRUNCATION_MASK | \
+ PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG))
+
+/** Length to which a MAC algorithm is truncated.
+ *
+ * \param mac_alg A MAC algorithm identifier (value of type
+ * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p mac_alg)
+ * is true).
+ *
+ * \return Length of the truncated MAC in bytes.
+ * \return 0 if \p mac_alg is a non-truncated MAC algorithm.
+ * \return Unspecified if \p mac_alg is not a supported
+ * MAC algorithm.
+ */
+#define PSA_MAC_TRUNCATED_LENGTH(mac_alg) \
+ (((mac_alg) & PSA_ALG_MAC_TRUNCATION_MASK) >> PSA_MAC_TRUNCATION_OFFSET)
+
+/** Macro to build a MAC minimum-MAC-length wildcard algorithm.
+ *
+ * A minimum-MAC-length MAC wildcard algorithm permits all MAC algorithms
+ * sharing the same base algorithm, and where the (potentially truncated) MAC
+ * length of the specific algorithm is equal to or larger then the wildcard
+ * algorithm's minimum MAC length.
+ *
+ * \note When setting the minimum required MAC length to less than the
+ * smallest MAC length allowed by the base algorithm, this effectively
+ * becomes an 'any-MAC-length-allowed' policy for that base algorithm.
+ *
+ * \param mac_alg A MAC algorithm identifier (value of type
+ * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p mac_alg)
+ * is true).
+ * \param min_mac_length Desired minimum length of the message authentication
+ * code in bytes. This must be at most the untruncated
+ * length of the MAC and must be at least 1.
+ *
+ * \return The corresponding MAC wildcard algorithm with the
+ * specified minimum length.
+ * \return Unspecified if \p mac_alg is not a supported MAC
+ * algorithm or if \p min_mac_length is less than 1 or
+ * too large for the specified MAC algorithm.
+ */
+#define PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(mac_alg, min_mac_length) \
+ (PSA_ALG_TRUNCATED_MAC(mac_alg, min_mac_length) | \
+ PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG)
+
+#define PSA_ALG_CIPHER_MAC_BASE ((psa_algorithm_t) 0x03c00000)
+/** The CBC-MAC construction over a block cipher
+ *
+ * \warning CBC-MAC is insecure in many cases.
+ * A more secure mode, such as #PSA_ALG_CMAC, is recommended.
+ */
+#define PSA_ALG_CBC_MAC ((psa_algorithm_t) 0x03c00100)
+/** The CMAC construction over a block cipher */
+#define PSA_ALG_CMAC ((psa_algorithm_t) 0x03c00200)
+
+/** Whether the specified algorithm is a MAC algorithm based on a block cipher.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a MAC algorithm based on a block cipher, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) \
+ (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_MAC_SUBCATEGORY_MASK)) == \
+ PSA_ALG_CIPHER_MAC_BASE)
+
+#define PSA_ALG_CIPHER_STREAM_FLAG ((psa_algorithm_t) 0x00800000)
+#define PSA_ALG_CIPHER_FROM_BLOCK_FLAG ((psa_algorithm_t) 0x00400000)
+
+/** Whether the specified algorithm is a stream cipher.
+ *
+ * A stream cipher is a symmetric cipher that encrypts or decrypts messages
+ * by applying a bitwise-xor with a stream of bytes that is generated
+ * from a key.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a stream cipher algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier or if it is not a symmetric cipher algorithm.
+ */
+#define PSA_ALG_IS_STREAM_CIPHER(alg) \
+ (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_CIPHER_STREAM_FLAG)) == \
+ (PSA_ALG_CATEGORY_CIPHER | PSA_ALG_CIPHER_STREAM_FLAG))
+
+/** The stream cipher mode of a stream cipher algorithm.
+ *
+ * The underlying stream cipher is determined by the key type.
+ * - To use ChaCha20, use a key type of #PSA_KEY_TYPE_CHACHA20.
+ */
+#define PSA_ALG_STREAM_CIPHER ((psa_algorithm_t) 0x04800100)
+
+/** The CTR stream cipher mode.
+ *
+ * CTR is a stream cipher which is built from a block cipher.
+ * The underlying block cipher is determined by the key type.
+ * For example, to use AES-128-CTR, use this algorithm with
+ * a key of type #PSA_KEY_TYPE_AES and a length of 128 bits (16 bytes).
+ */
+#define PSA_ALG_CTR ((psa_algorithm_t) 0x04c01000)
+
+/** The CFB stream cipher mode.
+ *
+ * The underlying block cipher is determined by the key type.
+ */
+#define PSA_ALG_CFB ((psa_algorithm_t) 0x04c01100)
+
+/** The OFB stream cipher mode.
+ *
+ * The underlying block cipher is determined by the key type.
+ */
+#define PSA_ALG_OFB ((psa_algorithm_t) 0x04c01200)
+
+/** The XTS cipher mode.
+ *
+ * XTS is a cipher mode which is built from a block cipher. It requires at
+ * least one full block of input, but beyond this minimum the input
+ * does not need to be a whole number of blocks.
+ */
+#define PSA_ALG_XTS ((psa_algorithm_t) 0x0440ff00)
+
+/** The Electronic Code Book (ECB) mode of a block cipher, with no padding.
+ *
+ * \warning ECB mode does not protect the confidentiality of the encrypted data
+ * except in extremely narrow circumstances. It is recommended that applications
+ * only use ECB if they need to construct an operating mode that the
+ * implementation does not provide. Implementations are encouraged to provide
+ * the modes that applications need in preference to supporting direct access
+ * to ECB.
+ *
+ * The underlying block cipher is determined by the key type.
+ *
+ * This symmetric cipher mode can only be used with messages whose lengths are a
+ * multiple of the block size of the chosen block cipher.
+ *
+ * ECB mode does not accept an initialization vector (IV). When using a
+ * multi-part cipher operation with this algorithm, psa_cipher_generate_iv()
+ * and psa_cipher_set_iv() must not be called.
+ */
+#define PSA_ALG_ECB_NO_PADDING ((psa_algorithm_t) 0x04404400)
+
+/** The CBC block cipher chaining mode, with no padding.
+ *
+ * The underlying block cipher is determined by the key type.
+ *
+ * This symmetric cipher mode can only be used with messages whose lengths
+ * are whole number of blocks for the chosen block cipher.
+ */
+#define PSA_ALG_CBC_NO_PADDING ((psa_algorithm_t) 0x04404000)
+
+/** The CBC block cipher chaining mode with PKCS#7 padding.
+ *
+ * The underlying block cipher is determined by the key type.
+ *
+ * This is the padding method defined by PKCS#7 (RFC 2315) &sect;10.3.
+ */
+#define PSA_ALG_CBC_PKCS7 ((psa_algorithm_t) 0x04404100)
+
+#define PSA_ALG_AEAD_FROM_BLOCK_FLAG ((psa_algorithm_t) 0x00400000)
+
+/** Whether the specified algorithm is an AEAD mode on a block cipher.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is an AEAD algorithm which is an AEAD mode based on
+ * a block cipher, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) \
+ (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_AEAD_FROM_BLOCK_FLAG)) == \
+ (PSA_ALG_CATEGORY_AEAD | PSA_ALG_AEAD_FROM_BLOCK_FLAG))
+
+/** The CCM authenticated encryption algorithm.
+ *
+ * The underlying block cipher is determined by the key type.
+ */
+#define PSA_ALG_CCM ((psa_algorithm_t) 0x05500100)
+
+/** The CCM* cipher mode without authentication.
+ *
+ * This is CCM* as specified in IEEE 802.15.4 §7, with a tag length of 0.
+ * For CCM* with a nonzero tag length, use the AEAD algorithm #PSA_ALG_CCM.
+ *
+ * The underlying block cipher is determined by the key type.
+ *
+ * Currently only 13-byte long IV's are supported.
+ */
+#define PSA_ALG_CCM_STAR_NO_TAG ((psa_algorithm_t) 0x04c01300)
+
+/** The GCM authenticated encryption algorithm.
+ *
+ * The underlying block cipher is determined by the key type.
+ */
+#define PSA_ALG_GCM ((psa_algorithm_t) 0x05500200)
+
+/** The Chacha20-Poly1305 AEAD algorithm.
+ *
+ * The ChaCha20_Poly1305 construction is defined in RFC 7539.
+ *
+ * Implementations must support 12-byte nonces, may support 8-byte nonces,
+ * and should reject other sizes.
+ *
+ * Implementations must support 16-byte tags and should reject other sizes.
+ */
+#define PSA_ALG_CHACHA20_POLY1305 ((psa_algorithm_t) 0x05100500)
+
+/* In the encoding of an AEAD algorithm, the bits corresponding to
+ * PSA_ALG_AEAD_TAG_LENGTH_MASK encode the length of the AEAD tag.
+ * The constants for default lengths follow this encoding.
+ */
+#define PSA_ALG_AEAD_TAG_LENGTH_MASK ((psa_algorithm_t) 0x003f0000)
+#define PSA_AEAD_TAG_LENGTH_OFFSET 16
+
+/* In the encoding of an AEAD algorithm, the bit corresponding to
+ * #PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG encodes the fact that the algorithm
+ * is a wildcard algorithm. A key with such wildcard algorithm as permitted
+ * algorithm policy can be used with any algorithm corresponding to the
+ * same base class and having a tag length greater than or equal to the one
+ * encoded in #PSA_ALG_AEAD_TAG_LENGTH_MASK. */
+#define PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ((psa_algorithm_t) 0x00008000)
+
+/** Macro to build a shortened AEAD algorithm.
+ *
+ * A shortened AEAD algorithm is similar to the corresponding AEAD
+ * algorithm, but has an authentication tag that consists of fewer bytes.
+ * Depending on the algorithm, the tag length may affect the calculation
+ * of the ciphertext.
+ *
+ * \param aead_alg An AEAD algorithm identifier (value of type
+ * #psa_algorithm_t such that #PSA_ALG_IS_AEAD(\p aead_alg)
+ * is true).
+ * \param tag_length Desired length of the authentication tag in bytes.
+ *
+ * \return The corresponding AEAD algorithm with the specified
+ * length.
+ * \return Unspecified if \p aead_alg is not a supported
+ * AEAD algorithm or if \p tag_length is not valid
+ * for the specified AEAD algorithm.
+ */
+#define PSA_ALG_AEAD_WITH_SHORTENED_TAG(aead_alg, tag_length) \
+ (((aead_alg) & ~(PSA_ALG_AEAD_TAG_LENGTH_MASK | \
+ PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG)) | \
+ ((tag_length) << PSA_AEAD_TAG_LENGTH_OFFSET & \
+ PSA_ALG_AEAD_TAG_LENGTH_MASK))
+
+/** Retrieve the tag length of a specified AEAD algorithm
+ *
+ * \param aead_alg An AEAD algorithm identifier (value of type
+ * #psa_algorithm_t such that #PSA_ALG_IS_AEAD(\p aead_alg)
+ * is true).
+ *
+ * \return The tag length specified by the input algorithm.
+ * \return Unspecified if \p aead_alg is not a supported
+ * AEAD algorithm.
+ */
+#define PSA_ALG_AEAD_GET_TAG_LENGTH(aead_alg) \
+ (((aead_alg) & PSA_ALG_AEAD_TAG_LENGTH_MASK) >> \
+ PSA_AEAD_TAG_LENGTH_OFFSET)
+
+/** Calculate the corresponding AEAD algorithm with the default tag length.
+ *
+ * \param aead_alg An AEAD algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(\p aead_alg) is true).
+ *
+ * \return The corresponding AEAD algorithm with the default
+ * tag length for that algorithm.
+ */
+#define PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(aead_alg) \
+ ( \
+ PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, PSA_ALG_CCM) \
+ PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, PSA_ALG_GCM) \
+ PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, PSA_ALG_CHACHA20_POLY1305) \
+ 0)
+#define PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, ref) \
+ PSA_ALG_AEAD_WITH_SHORTENED_TAG(aead_alg, 0) == \
+ PSA_ALG_AEAD_WITH_SHORTENED_TAG(ref, 0) ? \
+ ref :
+
+/** Macro to build an AEAD minimum-tag-length wildcard algorithm.
+ *
+ * A minimum-tag-length AEAD wildcard algorithm permits all AEAD algorithms
+ * sharing the same base algorithm, and where the tag length of the specific
+ * algorithm is equal to or larger then the minimum tag length specified by the
+ * wildcard algorithm.
+ *
+ * \note When setting the minimum required tag length to less than the
+ * smallest tag length allowed by the base algorithm, this effectively
+ * becomes an 'any-tag-length-allowed' policy for that base algorithm.
+ *
+ * \param aead_alg An AEAD algorithm identifier (value of type
+ * #psa_algorithm_t such that
+ * #PSA_ALG_IS_AEAD(\p aead_alg) is true).
+ * \param min_tag_length Desired minimum length of the authentication tag in
+ * bytes. This must be at least 1 and at most the largest
+ * allowed tag length of the algorithm.
+ *
+ * \return The corresponding AEAD wildcard algorithm with the
+ * specified minimum length.
+ * \return Unspecified if \p aead_alg is not a supported
+ * AEAD algorithm or if \p min_tag_length is less than 1
+ * or too large for the specified AEAD algorithm.
+ */
+#define PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(aead_alg, min_tag_length) \
+ (PSA_ALG_AEAD_WITH_SHORTENED_TAG(aead_alg, min_tag_length) | \
+ PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG)
+
+#define PSA_ALG_RSA_PKCS1V15_SIGN_BASE ((psa_algorithm_t) 0x06000200)
+/** RSA PKCS#1 v1.5 signature with hashing.
+ *
+ * This is the signature scheme defined by RFC 8017
+ * (PKCS#1: RSA Cryptography Specifications) under the name
+ * RSASSA-PKCS1-v1_5.
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ * This includes #PSA_ALG_ANY_HASH
+ * when specifying the algorithm in a usage policy.
+ *
+ * \return The corresponding RSA PKCS#1 v1.5 signature algorithm.
+ * \return Unspecified if \p hash_alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg) \
+ (PSA_ALG_RSA_PKCS1V15_SIGN_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+/** Raw PKCS#1 v1.5 signature.
+ *
+ * The input to this algorithm is the DigestInfo structure used by
+ * RFC 8017 (PKCS#1: RSA Cryptography Specifications), &sect;9.2
+ * steps 3&ndash;6.
+ */
+#define PSA_ALG_RSA_PKCS1V15_SIGN_RAW PSA_ALG_RSA_PKCS1V15_SIGN_BASE
+#define PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PKCS1V15_SIGN_BASE)
+
+#define PSA_ALG_RSA_PSS_BASE ((psa_algorithm_t) 0x06000300)
+#define PSA_ALG_RSA_PSS_ANY_SALT_BASE ((psa_algorithm_t) 0x06001300)
+/** RSA PSS signature with hashing.
+ *
+ * This is the signature scheme defined by RFC 8017
+ * (PKCS#1: RSA Cryptography Specifications) under the name
+ * RSASSA-PSS, with the message generation function MGF1, and with
+ * a salt length equal to the length of the hash, or the largest
+ * possible salt length for the algorithm and key size if that is
+ * smaller than the hash length. The specified hash algorithm is
+ * used to hash the input message, to create the salted hash, and
+ * for the mask generation.
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ * This includes #PSA_ALG_ANY_HASH
+ * when specifying the algorithm in a usage policy.
+ *
+ * \return The corresponding RSA PSS signature algorithm.
+ * \return Unspecified if \p hash_alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_RSA_PSS(hash_alg) \
+ (PSA_ALG_RSA_PSS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+
+/** RSA PSS signature with hashing with relaxed verification.
+ *
+ * This algorithm has the same behavior as #PSA_ALG_RSA_PSS when signing,
+ * but allows an arbitrary salt length (including \c 0) when verifying a
+ * signature.
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ * This includes #PSA_ALG_ANY_HASH
+ * when specifying the algorithm in a usage policy.
+ *
+ * \return The corresponding RSA PSS signature algorithm.
+ * \return Unspecified if \p hash_alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_RSA_PSS_ANY_SALT(hash_alg) \
+ (PSA_ALG_RSA_PSS_ANY_SALT_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+
+/** Whether the specified algorithm is RSA PSS with standard salt.
+ *
+ * \param alg An algorithm value or an algorithm policy wildcard.
+ *
+ * \return 1 if \p alg is of the form
+ * #PSA_ALG_RSA_PSS(\c hash_alg),
+ * where \c hash_alg is a hash algorithm or
+ * #PSA_ALG_ANY_HASH. 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not
+ * a supported algorithm identifier or policy.
+ */
+#define PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_BASE)
+
+/** Whether the specified algorithm is RSA PSS with any salt.
+ *
+ * \param alg An algorithm value or an algorithm policy wildcard.
+ *
+ * \return 1 if \p alg is of the form
+ * #PSA_ALG_RSA_PSS_ANY_SALT_BASE(\c hash_alg),
+ * where \c hash_alg is a hash algorithm or
+ * #PSA_ALG_ANY_HASH. 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not
+ * a supported algorithm identifier or policy.
+ */
+#define PSA_ALG_IS_RSA_PSS_ANY_SALT(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_ANY_SALT_BASE)
+
+/** Whether the specified algorithm is RSA PSS.
+ *
+ * This includes any of the RSA PSS algorithm variants, regardless of the
+ * constraints on salt length.
+ *
+ * \param alg An algorithm value or an algorithm policy wildcard.
+ *
+ * \return 1 if \p alg is of the form
+ * #PSA_ALG_RSA_PSS(\c hash_alg) or
+ * #PSA_ALG_RSA_PSS_ANY_SALT_BASE(\c hash_alg),
+ * where \c hash_alg is a hash algorithm or
+ * #PSA_ALG_ANY_HASH. 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not
+ * a supported algorithm identifier or policy.
+ */
+#define PSA_ALG_IS_RSA_PSS(alg) \
+ (PSA_ALG_IS_RSA_PSS_STANDARD_SALT(alg) || \
+ PSA_ALG_IS_RSA_PSS_ANY_SALT(alg))
+
+#define PSA_ALG_ECDSA_BASE ((psa_algorithm_t) 0x06000600)
+/** ECDSA signature with hashing.
+ *
+ * This is the ECDSA signature scheme defined by ANSI X9.62,
+ * with a random per-message secret number (*k*).
+ *
+ * The representation of the signature as a byte string consists of
+ * the concatenation of the signature values *r* and *s*. Each of
+ * *r* and *s* is encoded as an *N*-octet string, where *N* is the length
+ * of the base point of the curve in octets. Each value is represented
+ * in big-endian order (most significant octet first).
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ * This includes #PSA_ALG_ANY_HASH
+ * when specifying the algorithm in a usage policy.
+ *
+ * \return The corresponding ECDSA signature algorithm.
+ * \return Unspecified if \p hash_alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_ECDSA(hash_alg) \
+ (PSA_ALG_ECDSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+/** ECDSA signature without hashing.
+ *
+ * This is the same signature scheme as #PSA_ALG_ECDSA(), but
+ * without specifying a hash algorithm. This algorithm may only be
+ * used to sign or verify a sequence of bytes that should be an
+ * already-calculated hash. Note that the input is padded with
+ * zeros on the left or truncated on the left as required to fit
+ * the curve size.
+ */
+#define PSA_ALG_ECDSA_ANY PSA_ALG_ECDSA_BASE
+#define PSA_ALG_DETERMINISTIC_ECDSA_BASE ((psa_algorithm_t) 0x06000700)
+/** Deterministic ECDSA signature with hashing.
+ *
+ * This is the deterministic ECDSA signature scheme defined by RFC 6979.
+ *
+ * The representation of a signature is the same as with #PSA_ALG_ECDSA().
+ *
+ * Note that when this algorithm is used for verification, signatures
+ * made with randomized ECDSA (#PSA_ALG_ECDSA(\p hash_alg)) with the
+ * same private key are accepted. In other words,
+ * #PSA_ALG_DETERMINISTIC_ECDSA(\p hash_alg) differs from
+ * #PSA_ALG_ECDSA(\p hash_alg) only for signature, not for verification.
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ * This includes #PSA_ALG_ANY_HASH
+ * when specifying the algorithm in a usage policy.
+ *
+ * \return The corresponding deterministic ECDSA signature
+ * algorithm.
+ * \return Unspecified if \p hash_alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_DETERMINISTIC_ECDSA(hash_alg) \
+ (PSA_ALG_DETERMINISTIC_ECDSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_ECDSA_DETERMINISTIC_FLAG ((psa_algorithm_t) 0x00000100)
+#define PSA_ALG_IS_ECDSA(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_ECDSA_DETERMINISTIC_FLAG) == \
+ PSA_ALG_ECDSA_BASE)
+#define PSA_ALG_ECDSA_IS_DETERMINISTIC(alg) \
+ (((alg) & PSA_ALG_ECDSA_DETERMINISTIC_FLAG) != 0)
+#define PSA_ALG_IS_DETERMINISTIC_ECDSA(alg) \
+ (PSA_ALG_IS_ECDSA(alg) && PSA_ALG_ECDSA_IS_DETERMINISTIC(alg))
+#define PSA_ALG_IS_RANDOMIZED_ECDSA(alg) \
+ (PSA_ALG_IS_ECDSA(alg) && !PSA_ALG_ECDSA_IS_DETERMINISTIC(alg))
+
+/** Edwards-curve digital signature algorithm without prehashing (PureEdDSA),
+ * using standard parameters.
+ *
+ * Contexts are not supported in the current version of this specification
+ * because there is no suitable signature interface that can take the
+ * context as a parameter. A future version of this specification may add
+ * suitable functions and extend this algorithm to support contexts.
+ *
+ * PureEdDSA requires an elliptic curve key on a twisted Edwards curve.
+ * In this specification, the following curves are supported:
+ * - #PSA_ECC_FAMILY_TWISTED_EDWARDS, 255-bit: Ed25519 as specified
+ * in RFC 8032.
+ * The curve is Edwards25519.
+ * The hash function used internally is SHA-512.
+ * - #PSA_ECC_FAMILY_TWISTED_EDWARDS, 448-bit: Ed448 as specified
+ * in RFC 8032.
+ * The curve is Edwards448.
+ * The hash function used internally is the first 114 bytes of the
+ * SHAKE256 output.
+ *
+ * This algorithm can be used with psa_sign_message() and
+ * psa_verify_message(). Since there is no prehashing, it cannot be used
+ * with psa_sign_hash() or psa_verify_hash().
+ *
+ * The signature format is the concatenation of R and S as defined by
+ * RFC 8032 §5.1.6 and §5.2.6 (a 64-byte string for Ed25519, a 114-byte
+ * string for Ed448).
+ */
+#define PSA_ALG_PURE_EDDSA ((psa_algorithm_t) 0x06000800)
+
+#define PSA_ALG_HASH_EDDSA_BASE ((psa_algorithm_t) 0x06000900)
+#define PSA_ALG_IS_HASH_EDDSA(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HASH_EDDSA_BASE)
+
+/** Edwards-curve digital signature algorithm with prehashing (HashEdDSA),
+ * using SHA-512 and the Edwards25519 curve.
+ *
+ * See #PSA_ALG_PURE_EDDSA regarding context support and the signature format.
+ *
+ * This algorithm is Ed25519 as specified in RFC 8032.
+ * The curve is Edwards25519.
+ * The prehash is SHA-512.
+ * The hash function used internally is SHA-512.
+ *
+ * This is a hash-and-sign algorithm: to calculate a signature,
+ * you can either:
+ * - call psa_sign_message() on the message;
+ * - or calculate the SHA-512 hash of the message
+ * with psa_hash_compute()
+ * or with a multi-part hash operation started with psa_hash_setup(),
+ * using the hash algorithm #PSA_ALG_SHA_512,
+ * then sign the calculated hash with psa_sign_hash().
+ * Verifying a signature is similar, using psa_verify_message() or
+ * psa_verify_hash() instead of the signature function.
+ */
+#define PSA_ALG_ED25519PH \
+ (PSA_ALG_HASH_EDDSA_BASE | (PSA_ALG_SHA_512 & PSA_ALG_HASH_MASK))
+
+/** Edwards-curve digital signature algorithm with prehashing (HashEdDSA),
+ * using SHAKE256 and the Edwards448 curve.
+ *
+ * See #PSA_ALG_PURE_EDDSA regarding context support and the signature format.
+ *
+ * This algorithm is Ed448 as specified in RFC 8032.
+ * The curve is Edwards448.
+ * The prehash is the first 64 bytes of the SHAKE256 output.
+ * The hash function used internally is the first 114 bytes of the
+ * SHAKE256 output.
+ *
+ * This is a hash-and-sign algorithm: to calculate a signature,
+ * you can either:
+ * - call psa_sign_message() on the message;
+ * - or calculate the first 64 bytes of the SHAKE256 output of the message
+ * with psa_hash_compute()
+ * or with a multi-part hash operation started with psa_hash_setup(),
+ * using the hash algorithm #PSA_ALG_SHAKE256_512,
+ * then sign the calculated hash with psa_sign_hash().
+ * Verifying a signature is similar, using psa_verify_message() or
+ * psa_verify_hash() instead of the signature function.
+ */
+#define PSA_ALG_ED448PH \
+ (PSA_ALG_HASH_EDDSA_BASE | (PSA_ALG_SHAKE256_512 & PSA_ALG_HASH_MASK))
+
+/* Default definition, to be overridden if the library is extended with
+ * more hash-and-sign algorithms that we want to keep out of this header
+ * file. */
+#define PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg) 0
+
+/** Whether the specified algorithm is a signature algorithm that can be used
+ * with psa_sign_hash() and psa_verify_hash().
+ *
+ * This encompasses all strict hash-and-sign algorithms categorized by
+ * PSA_ALG_IS_HASH_AND_SIGN(), as well as algorithms that follow the
+ * paradigm more loosely:
+ * - #PSA_ALG_RSA_PKCS1V15_SIGN_RAW (expects its input to be an encoded hash)
+ * - #PSA_ALG_ECDSA_ANY (doesn't specify what kind of hash the input is)
+ *
+ * \param alg An algorithm identifier (value of type psa_algorithm_t).
+ *
+ * \return 1 if alg is a signature algorithm that can be used to sign a
+ * hash. 0 if alg is a signature algorithm that can only be used
+ * to sign a message. 0 if alg is not a signature algorithm.
+ * This macro can return either 0 or 1 if alg is not a
+ * supported algorithm identifier.
+ */
+#define PSA_ALG_IS_SIGN_HASH(alg) \
+ (PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \
+ PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_HASH_EDDSA(alg) || \
+ PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg))
+
+/** Whether the specified algorithm is a signature algorithm that can be used
+ * with psa_sign_message() and psa_verify_message().
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if alg is a signature algorithm that can be used to sign a
+ * message. 0 if \p alg is a signature algorithm that can only be used
+ * to sign an already-calculated hash. 0 if \p alg is not a signature
+ * algorithm. This macro can return either 0 or 1 if \p alg is not a
+ * supported algorithm identifier.
+ */
+#define PSA_ALG_IS_SIGN_MESSAGE(alg) \
+ (PSA_ALG_IS_SIGN_HASH(alg) || (alg) == PSA_ALG_PURE_EDDSA)
+
+/** Whether the specified algorithm is a hash-and-sign algorithm.
+ *
+ * Hash-and-sign algorithms are asymmetric (public-key) signature algorithms
+ * structured in two parts: first the calculation of a hash in a way that
+ * does not depend on the key, then the calculation of a signature from the
+ * hash value and the key. Hash-and-sign algorithms encode the hash
+ * used for the hashing step, and you can call #PSA_ALG_SIGN_GET_HASH
+ * to extract this algorithm.
+ *
+ * Thus, for a hash-and-sign algorithm,
+ * `psa_sign_message(key, alg, input, ...)` is equivalent to
+ * ```
+ * psa_hash_compute(PSA_ALG_SIGN_GET_HASH(alg), input, ..., hash, ...);
+ * psa_sign_hash(key, alg, hash, ..., signature, ...);
+ * ```
+ * Most usefully, separating the hash from the signature allows the hash
+ * to be calculated in multiple steps with psa_hash_setup(), psa_hash_update()
+ * and psa_hash_finish(). Likewise psa_verify_message() is equivalent to
+ * calculating the hash and then calling psa_verify_hash().
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a hash-and-sign algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_HASH_AND_SIGN(alg) \
+ (PSA_ALG_IS_SIGN_HASH(alg) && \
+ ((alg) & PSA_ALG_HASH_MASK) != 0)
+
+/** Get the hash used by a hash-and-sign signature algorithm.
+ *
+ * A hash-and-sign algorithm is a signature algorithm which is
+ * composed of two phases: first a hashing phase which does not use
+ * the key and produces a hash of the input message, then a signing
+ * phase which only uses the hash and the key and not the message
+ * itself.
+ *
+ * \param alg A signature algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_SIGN(\p alg) is true).
+ *
+ * \return The underlying hash algorithm if \p alg is a hash-and-sign
+ * algorithm.
+ * \return 0 if \p alg is a signature algorithm that does not
+ * follow the hash-and-sign structure.
+ * \return Unspecified if \p alg is not a signature algorithm or
+ * if it is not supported by the implementation.
+ */
+#define PSA_ALG_SIGN_GET_HASH(alg) \
+ (PSA_ALG_IS_HASH_AND_SIGN(alg) ? \
+ ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH : \
+ 0)
+
+/** RSA PKCS#1 v1.5 encryption.
+ */
+#define PSA_ALG_RSA_PKCS1V15_CRYPT ((psa_algorithm_t) 0x07000200)
+
+#define PSA_ALG_RSA_OAEP_BASE ((psa_algorithm_t) 0x07000300)
+/** RSA OAEP encryption.
+ *
+ * This is the encryption scheme defined by RFC 8017
+ * (PKCS#1: RSA Cryptography Specifications) under the name
+ * RSAES-OAEP, with the message generation function MGF1.
+ *
+ * \param hash_alg The hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true) to use
+ * for MGF1.
+ *
+ * \return The corresponding RSA OAEP encryption algorithm.
+ * \return Unspecified if \p hash_alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_RSA_OAEP(hash_alg) \
+ (PSA_ALG_RSA_OAEP_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_IS_RSA_OAEP(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_OAEP_BASE)
+#define PSA_ALG_RSA_OAEP_GET_HASH(alg) \
+ (PSA_ALG_IS_RSA_OAEP(alg) ? \
+ ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH : \
+ 0)
+
+#define PSA_ALG_HKDF_BASE ((psa_algorithm_t) 0x08000100)
+/** Macro to build an HKDF algorithm.
+ *
+ * For example, `PSA_ALG_HKDF(PSA_ALG_SHA_256)` is HKDF using HMAC-SHA-256.
+ *
+ * This key derivation algorithm uses the following inputs:
+ * - #PSA_KEY_DERIVATION_INPUT_SALT is the salt used in the "extract" step.
+ * It is optional; if omitted, the derivation uses an empty salt.
+ * - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key used in the "extract" step.
+ * - #PSA_KEY_DERIVATION_INPUT_INFO is the info string used in the "expand" step.
+ * You must pass #PSA_KEY_DERIVATION_INPUT_SALT before #PSA_KEY_DERIVATION_INPUT_SECRET.
+ * You may pass #PSA_KEY_DERIVATION_INPUT_INFO at any time after steup and before
+ * starting to generate output.
+ *
+ * \warning HKDF processes the salt as follows: first hash it with hash_alg
+ * if the salt is longer than the block size of the hash algorithm; then
+ * pad with null bytes up to the block size. As a result, it is possible
+ * for distinct salt inputs to result in the same outputs. To ensure
+ * unique outputs, it is recommended to use a fixed length for salt values.
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return The corresponding HKDF algorithm.
+ * \return Unspecified if \p hash_alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_HKDF(hash_alg) \
+ (PSA_ALG_HKDF_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+/** Whether the specified algorithm is an HKDF algorithm.
+ *
+ * HKDF is a family of key derivation algorithms that are based on a hash
+ * function and the HMAC construction.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is an HKDF algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \c alg is not a supported
+ * key derivation algorithm identifier.
+ */
+#define PSA_ALG_IS_HKDF(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_BASE)
+#define PSA_ALG_HKDF_GET_HASH(hkdf_alg) \
+ (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
+
+#define PSA_ALG_HKDF_EXTRACT_BASE ((psa_algorithm_t) 0x08000400)
+/** Macro to build an HKDF-Extract algorithm.
+ *
+ * For example, `PSA_ALG_HKDF_EXTRACT(PSA_ALG_SHA_256)` is
+ * HKDF-Extract using HMAC-SHA-256.
+ *
+ * This key derivation algorithm uses the following inputs:
+ * - PSA_KEY_DERIVATION_INPUT_SALT is the salt.
+ * - PSA_KEY_DERIVATION_INPUT_SECRET is the input keying material used in the
+ * "extract" step.
+ * The inputs are mandatory and must be passed in the order above.
+ * Each input may only be passed once.
+ *
+ * \warning HKDF-Extract is not meant to be used on its own. PSA_ALG_HKDF
+ * should be used instead if possible. PSA_ALG_HKDF_EXTRACT is provided
+ * as a separate algorithm for the sake of protocols that use it as a
+ * building block. It may also be a slight performance optimization
+ * in applications that use HKDF with the same salt and key but many
+ * different info strings.
+ *
+ * \warning HKDF processes the salt as follows: first hash it with hash_alg
+ * if the salt is longer than the block size of the hash algorithm; then
+ * pad with null bytes up to the block size. As a result, it is possible
+ * for distinct salt inputs to result in the same outputs. To ensure
+ * unique outputs, it is recommended to use a fixed length for salt values.
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return The corresponding HKDF-Extract algorithm.
+ * \return Unspecified if \p hash_alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_HKDF_EXTRACT(hash_alg) \
+ (PSA_ALG_HKDF_EXTRACT_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+/** Whether the specified algorithm is an HKDF-Extract algorithm.
+ *
+ * HKDF-Extract is a family of key derivation algorithms that are based
+ * on a hash function and the HMAC construction.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is an HKDF-Extract algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \c alg is not a supported
+ * key derivation algorithm identifier.
+ */
+#define PSA_ALG_IS_HKDF_EXTRACT(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_EXTRACT_BASE)
+
+#define PSA_ALG_HKDF_EXPAND_BASE ((psa_algorithm_t) 0x08000500)
+/** Macro to build an HKDF-Expand algorithm.
+ *
+ * For example, `PSA_ALG_HKDF_EXPAND(PSA_ALG_SHA_256)` is
+ * HKDF-Expand using HMAC-SHA-256.
+ *
+ * This key derivation algorithm uses the following inputs:
+ * - PSA_KEY_DERIVATION_INPUT_SECRET is the pseudorandom key (PRK).
+ * - PSA_KEY_DERIVATION_INPUT_INFO is the info string.
+ *
+ * The inputs are mandatory and must be passed in the order above.
+ * Each input may only be passed once.
+ *
+ * \warning HKDF-Expand is not meant to be used on its own. `PSA_ALG_HKDF`
+ * should be used instead if possible. `PSA_ALG_HKDF_EXPAND` is provided as
+ * a separate algorithm for the sake of protocols that use it as a building
+ * block. It may also be a slight performance optimization in applications
+ * that use HKDF with the same salt and key but many different info strings.
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return The corresponding HKDF-Expand algorithm.
+ * \return Unspecified if \p hash_alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_HKDF_EXPAND(hash_alg) \
+ (PSA_ALG_HKDF_EXPAND_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+/** Whether the specified algorithm is an HKDF-Expand algorithm.
+ *
+ * HKDF-Expand is a family of key derivation algorithms that are based
+ * on a hash function and the HMAC construction.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is an HKDF-Expand algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \c alg is not a supported
+ * key derivation algorithm identifier.
+ */
+#define PSA_ALG_IS_HKDF_EXPAND(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_EXPAND_BASE)
+
+/** Whether the specified algorithm is an HKDF or HKDF-Extract or
+ * HKDF-Expand algorithm.
+ *
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is any HKDF type algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \c alg is not a supported
+ * key derivation algorithm identifier.
+ */
+#define PSA_ALG_IS_ANY_HKDF(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_BASE || \
+ ((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_EXTRACT_BASE || \
+ ((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_EXPAND_BASE)
+
+#define PSA_ALG_TLS12_PRF_BASE ((psa_algorithm_t) 0x08000200)
+/** Macro to build a TLS-1.2 PRF algorithm.
+ *
+ * TLS 1.2 uses a custom pseudorandom function (PRF) for key schedule,
+ * specified in Section 5 of RFC 5246. It is based on HMAC and can be
+ * used with either SHA-256 or SHA-384.
+ *
+ * This key derivation algorithm uses the following inputs, which must be
+ * passed in the order given here:
+ * - #PSA_KEY_DERIVATION_INPUT_SEED is the seed.
+ * - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key.
+ * - #PSA_KEY_DERIVATION_INPUT_LABEL is the label.
+ *
+ * For the application to TLS-1.2 key expansion, the seed is the
+ * concatenation of ServerHello.Random + ClientHello.Random,
+ * and the label is "key expansion".
+ *
+ * For example, `PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256)` represents the
+ * TLS 1.2 PRF using HMAC-SHA-256.
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return The corresponding TLS-1.2 PRF algorithm.
+ * \return Unspecified if \p hash_alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_TLS12_PRF(hash_alg) \
+ (PSA_ALG_TLS12_PRF_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+
+/** Whether the specified algorithm is a TLS-1.2 PRF algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is a TLS-1.2 PRF algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \c alg is not a supported
+ * key derivation algorithm identifier.
+ */
+#define PSA_ALG_IS_TLS12_PRF(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_TLS12_PRF_BASE)
+#define PSA_ALG_TLS12_PRF_GET_HASH(hkdf_alg) \
+ (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
+
+#define PSA_ALG_TLS12_PSK_TO_MS_BASE ((psa_algorithm_t) 0x08000300)
+/** Macro to build a TLS-1.2 PSK-to-MasterSecret algorithm.
+ *
+ * In a pure-PSK handshake in TLS 1.2, the master secret is derived
+ * from the PreSharedKey (PSK) through the application of padding
+ * (RFC 4279, Section 2) and the TLS-1.2 PRF (RFC 5246, Section 5).
+ * The latter is based on HMAC and can be used with either SHA-256
+ * or SHA-384.
+ *
+ * This key derivation algorithm uses the following inputs, which must be
+ * passed in the order given here:
+ * - #PSA_KEY_DERIVATION_INPUT_SEED is the seed.
+ * - #PSA_KEY_DERIVATION_INPUT_OTHER_SECRET is the other secret for the
+ * computation of the premaster secret. This input is optional;
+ * if omitted, it defaults to a string of null bytes with the same length
+ * as the secret (PSK) input.
+ * - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key.
+ * - #PSA_KEY_DERIVATION_INPUT_LABEL is the label.
+ *
+ * For the application to TLS-1.2, the seed (which is
+ * forwarded to the TLS-1.2 PRF) is the concatenation of the
+ * ClientHello.Random + ServerHello.Random,
+ * the label is "master secret" or "extended master secret" and
+ * the other secret depends on the key exchange specified in the cipher suite:
+ * - for a plain PSK cipher suite (RFC 4279, Section 2), omit
+ * PSA_KEY_DERIVATION_INPUT_OTHER_SECRET
+ * - for a DHE-PSK (RFC 4279, Section 3) or ECDHE-PSK cipher suite
+ * (RFC 5489, Section 2), the other secret should be the output of the
+ * PSA_ALG_FFDH or PSA_ALG_ECDH key agreement performed with the peer.
+ * The recommended way to pass this input is to use a key derivation
+ * algorithm constructed as
+ * PSA_ALG_KEY_AGREEMENT(ka_alg, PSA_ALG_TLS12_PSK_TO_MS(hash_alg))
+ * and to call psa_key_derivation_key_agreement(). Alternatively,
+ * this input may be an output of `psa_raw_key_agreement()` passed with
+ * psa_key_derivation_input_bytes(), or an equivalent input passed with
+ * psa_key_derivation_input_bytes() or psa_key_derivation_input_key().
+ * - for a RSA-PSK cipher suite (RFC 4279, Section 4), the other secret
+ * should be the 48-byte client challenge (the PreMasterSecret of
+ * (RFC 5246, Section 7.4.7.1)) concatenation of the TLS version and
+ * a 46-byte random string chosen by the client. On the server, this is
+ * typically an output of psa_asymmetric_decrypt() using
+ * PSA_ALG_RSA_PKCS1V15_CRYPT, passed to the key derivation operation
+ * with `psa_key_derivation_input_bytes()`.
+ *
+ * For example, `PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256)` represents the
+ * TLS-1.2 PSK to MasterSecret derivation PRF using HMAC-SHA-256.
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return The corresponding TLS-1.2 PSK to MS algorithm.
+ * \return Unspecified if \p hash_alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_TLS12_PSK_TO_MS(hash_alg) \
+ (PSA_ALG_TLS12_PSK_TO_MS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+
+/** Whether the specified algorithm is a TLS-1.2 PSK to MS algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is a TLS-1.2 PSK to MS algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \c alg is not a supported
+ * key derivation algorithm identifier.
+ */
+#define PSA_ALG_IS_TLS12_PSK_TO_MS(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_TLS12_PSK_TO_MS_BASE)
+#define PSA_ALG_TLS12_PSK_TO_MS_GET_HASH(hkdf_alg) \
+ (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
+
+/* The TLS 1.2 ECJPAKE-to-PMS KDF. It takes the shared secret K (an EC point
+ * in case of EC J-PAKE) and calculates SHA256(K.X) that the rest of TLS 1.2
+ * will use to derive the session secret, as defined by step 2 of
+ * https://datatracker.ietf.org/doc/html/draft-cragie-tls-ecjpake-01#section-8.7.
+ * Uses PSA_ALG_SHA_256.
+ * This function takes a single input:
+ * #PSA_KEY_DERIVATION_INPUT_SECRET is the shared secret K from EC J-PAKE.
+ * The only supported curve is secp256r1 (the 256-bit curve in
+ * #PSA_ECC_FAMILY_SECP_R1), so the input must be exactly 65 bytes.
+ * The output has to be read as a single chunk of 32 bytes, defined as
+ * PSA_TLS12_ECJPAKE_TO_PMS_DATA_SIZE.
+ */
+#define PSA_ALG_TLS12_ECJPAKE_TO_PMS ((psa_algorithm_t) 0x08000609)
+
+/* This flag indicates whether the key derivation algorithm is suitable for
+ * use on low-entropy secrets such as password - these algorithms are also
+ * known as key stretching or password hashing schemes. These are also the
+ * algorithms that accepts inputs of type #PSA_KEY_DERIVATION_INPUT_PASSWORD.
+ *
+ * Those algorithms cannot be combined with a key agreement algorithm.
+ */
+#define PSA_ALG_KEY_DERIVATION_STRETCHING_FLAG ((psa_algorithm_t) 0x00800000)
+
+#define PSA_ALG_PBKDF2_HMAC_BASE ((psa_algorithm_t) 0x08800100)
+/** Macro to build a PBKDF2-HMAC password hashing / key stretching algorithm.
+ *
+ * PBKDF2 is defined by PKCS#5, republished as RFC 8018 (section 5.2).
+ * This macro specifies the PBKDF2 algorithm constructed using a PRF based on
+ * HMAC with the specified hash.
+ * For example, `PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_256)` specifies PBKDF2
+ * using the PRF HMAC-SHA-256.
+ *
+ * This key derivation algorithm uses the following inputs, which must be
+ * provided in the following order:
+ * - #PSA_KEY_DERIVATION_INPUT_COST is the iteration count.
+ * This input step must be used exactly once.
+ * - #PSA_KEY_DERIVATION_INPUT_SALT is the salt.
+ * This input step must be used one or more times; if used several times, the
+ * inputs will be concatenated. This can be used to build the final salt
+ * from multiple sources, both public and secret (also known as pepper).
+ * - #PSA_KEY_DERIVATION_INPUT_PASSWORD is the password to be hashed.
+ * This input step must be used exactly once.
+ *
+ * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return The corresponding PBKDF2-HMAC-XXX algorithm.
+ * \return Unspecified if \p hash_alg is not a supported
+ * hash algorithm.
+ */
+#define PSA_ALG_PBKDF2_HMAC(hash_alg) \
+ (PSA_ALG_PBKDF2_HMAC_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+
+/** Whether the specified algorithm is a PBKDF2-HMAC algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is a PBKDF2-HMAC algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \c alg is not a supported
+ * key derivation algorithm identifier.
+ */
+#define PSA_ALG_IS_PBKDF2_HMAC(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_PBKDF2_HMAC_BASE)
+
+#define PSA_ALG_SP800_108_COUNTER_CMAC ((psa_algorithm_t) 0x08000800)
+
+/** The PBKDF2-AES-CMAC-PRF-128 password hashing / key stretching algorithm.
+ *
+ * PBKDF2 is defined by PKCS#5, republished as RFC 8018 (section 5.2).
+ * This macro specifies the PBKDF2 algorithm constructed using the
+ * AES-CMAC-PRF-128 PRF specified by RFC 4615.
+ *
+ * This key derivation algorithm uses the same inputs as
+ * #PSA_ALG_PBKDF2_HMAC() with the same constraints.
+ */
+#define PSA_ALG_PBKDF2_AES_CMAC_PRF_128 ((psa_algorithm_t) 0x08800200)
+
+#define PSA_ALG_SRP_PASSWORD_HASH_BASE ((psa_algorithm_t) 0x08800300)
+ /** The SRP password to password-hash KDF.
+ * It takes the password p, the salt s, and the user id u.
+ * It calculates the password hash h as
+ * h = H(salt || H(u || ":" || p))
+ * where H is the given hash algorithm.
+ *
+ * This key derivation algorithm uses the following inputs, which must be
+ * provided in the following order:
+ * - #PSA_KEY_DERIVATION_INPUT_INFO is the user id.
+ * - #PSA_KEY_DERIVATION_INPUT_PASSWORD is the password.
+ * - #PSA_KEY_DERIVATION_INPUT_SALT is the salt.
+ * The output has to be read as a key of type PSA_KEY_TYPE_SRP_KEY_PAIR.
+ */
+#define PSA_ALG_SRP_PASSWORD_HASH(hash_alg) \
+ (PSA_ALG_SRP_PASSWORD_HASH_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+
+ /** Whether the specified algorithm is a key derivation algorithm constructed
+ * using #PSA_ALG_SRP_PASSWORD_HASH(\p hash_alg).
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a key derivation algorithm constructed using #PSA_ALG_SRP_PASSWORD_HASH(),
+ * 0 otherwise. This macro may return either 0 or 1 if \c alg is not a supported
+ * key derivation algorithm identifier.
+ */
+#define PSA_ALG_IS_SRP_PASSWORD_HASH(alg) \
+ (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_SRP_PASSWORD_HASH_BASE)
+
+#define PSA_ALG_KEY_DERIVATION_MASK ((psa_algorithm_t) 0xfe00ffff)
+#define PSA_ALG_KEY_AGREEMENT_MASK ((psa_algorithm_t) 0xffff0000)
+
+/** Macro to build a combined algorithm that chains a key agreement with
+ * a key derivation.
+ *
+ * \param ka_alg A key agreement algorithm (\c PSA_ALG_XXX value such
+ * that #PSA_ALG_IS_KEY_AGREEMENT(\p ka_alg) is true).
+ * \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such
+ * that #PSA_ALG_IS_KEY_DERIVATION(\p kdf_alg) is true).
+ *
+ * \return The corresponding key agreement and derivation
+ * algorithm.
+ * \return Unspecified if \p ka_alg is not a supported
+ * key agreement algorithm or \p kdf_alg is not a
+ * supported key derivation algorithm.
+ */
+#define PSA_ALG_KEY_AGREEMENT(ka_alg, kdf_alg) \
+ ((ka_alg) | (kdf_alg))
+
+#define PSA_ALG_KEY_AGREEMENT_GET_KDF(alg) \
+ (((alg) & PSA_ALG_KEY_DERIVATION_MASK) | PSA_ALG_CATEGORY_KEY_DERIVATION)
+
+#define PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) \
+ (((alg) & PSA_ALG_KEY_AGREEMENT_MASK) | PSA_ALG_CATEGORY_KEY_AGREEMENT)
+
+/** Whether the specified algorithm is a raw key agreement algorithm.
+ *
+ * A raw key agreement algorithm is one that does not specify
+ * a key derivation function.
+ * Usually, raw key agreement algorithms are constructed directly with
+ * a \c PSA_ALG_xxx macro while non-raw key agreement algorithms are
+ * constructed with #PSA_ALG_KEY_AGREEMENT().
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a raw key agreement algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \p alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_RAW_KEY_AGREEMENT(alg) \
+ (PSA_ALG_IS_KEY_AGREEMENT(alg) && \
+ PSA_ALG_KEY_AGREEMENT_GET_KDF(alg) == PSA_ALG_CATEGORY_KEY_DERIVATION)
+
+#define PSA_ALG_IS_KEY_DERIVATION_OR_AGREEMENT(alg) \
+ ((PSA_ALG_IS_KEY_DERIVATION(alg) || PSA_ALG_IS_KEY_AGREEMENT(alg)))
+
+/** The finite-field Diffie-Hellman (DH) key agreement algorithm.
+ *
+ * The shared secret produced by key agreement is
+ * `g^{ab}` in big-endian format.
+ * It is `ceiling(m / 8)` bytes long where `m` is the size of the prime `p`
+ * in bits.
+ */
+#define PSA_ALG_FFDH ((psa_algorithm_t) 0x09010000)
+
+/** Whether the specified algorithm is a finite field Diffie-Hellman algorithm.
+ *
+ * This includes the raw finite field Diffie-Hellman algorithm as well as
+ * finite-field Diffie-Hellman followed by any supporter key derivation
+ * algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is a finite field Diffie-Hellman algorithm, 0 otherwise.
+ * This macro may return either 0 or 1 if \c alg is not a supported
+ * key agreement algorithm identifier.
+ */
+#define PSA_ALG_IS_FFDH(alg) \
+ (PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_FFDH)
+
+/** The elliptic curve Diffie-Hellman (ECDH) key agreement algorithm.
+ *
+ * The shared secret produced by key agreement is the x-coordinate of
+ * the shared secret point. It is always `ceiling(m / 8)` bytes long where
+ * `m` is the bit size associated with the curve, i.e. the bit size of the
+ * order of the curve's coordinate field. When `m` is not a multiple of 8,
+ * the byte containing the most significant bit of the shared secret
+ * is padded with zero bits. The byte order is either little-endian
+ * or big-endian depending on the curve type.
+ *
+ * - For Montgomery curves (curve types `PSA_ECC_FAMILY_CURVEXXX`),
+ * the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A`
+ * in little-endian byte order.
+ * The bit size is 448 for Curve448 and 255 for Curve25519.
+ * - For Weierstrass curves over prime fields (curve types
+ * `PSA_ECC_FAMILY_SECPXXX` and `PSA_ECC_FAMILY_BRAINPOOL_PXXX`),
+ * the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A`
+ * in big-endian byte order.
+ * The bit size is `m = ceiling(log_2(p))` for the field `F_p`.
+ * - For Weierstrass curves over binary fields (curve types
+ * `PSA_ECC_FAMILY_SECTXXX`),
+ * the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A`
+ * in big-endian byte order.
+ * The bit size is `m` for the field `F_{2^m}`.
+ */
+#define PSA_ALG_ECDH ((psa_algorithm_t) 0x09020000)
+
+/** Whether the specified algorithm is an elliptic curve Diffie-Hellman
+ * algorithm.
+ *
+ * This includes the raw elliptic curve Diffie-Hellman algorithm as well as
+ * elliptic curve Diffie-Hellman followed by any supporter key derivation
+ * algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is an elliptic curve Diffie-Hellman algorithm,
+ * 0 otherwise.
+ * This macro may return either 0 or 1 if \c alg is not a supported
+ * key agreement algorithm identifier.
+ */
+#define PSA_ALG_IS_ECDH(alg) \
+ (PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_ECDH)
+
+/** Whether the specified algorithm encoding is a wildcard.
+ *
+ * Wildcard values may only be used to set the usage algorithm field in
+ * a policy, not to perform an operation.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is a wildcard algorithm encoding.
+ * \return 0 if \c alg is a non-wildcard algorithm encoding (suitable for
+ * an operation).
+ * \return This macro may return either 0 or 1 if \c alg is not a supported
+ * algorithm identifier.
+ */
+#define PSA_ALG_IS_WILDCARD(alg) \
+ (PSA_ALG_IS_HASH_AND_SIGN(alg) ? \
+ PSA_ALG_SIGN_GET_HASH(alg) == PSA_ALG_ANY_HASH : \
+ PSA_ALG_IS_MAC(alg) ? \
+ (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0 : \
+ PSA_ALG_IS_AEAD(alg) ? \
+ (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0 : \
+ (alg) == PSA_ALG_ANY_HASH)
+
+/** Get the hash used by a composite algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return The underlying hash algorithm if alg is a composite algorithm that
+ * uses a hash algorithm.
+ *
+ * \return \c 0 if alg is not a composite algorithm that uses a hash.
+ */
+#define PSA_ALG_GET_HASH(alg) \
+ (((alg) & 0x000000ff) == 0 ? ((psa_algorithm_t) 0) : 0x02000000 | ((alg) & 0x000000ff))
+
+/**@}*/
+
+/** \defgroup key_lifetimes Key lifetimes
+ * @{
+ */
+
+/* Note that location and persistence level values are embedded in the
+ * persistent key store, as part of key metadata. As a consequence, they
+ * must not be changed (unless the storage format version changes).
+ */
+
+/** The default lifetime for volatile keys.
+ *
+ * A volatile key only exists as long as the identifier to it is not destroyed.
+ * The key material is guaranteed to be erased on a power reset.
+ *
+ * A key with this lifetime is typically stored in the RAM area of the
+ * PSA Crypto subsystem. However this is an implementation choice.
+ * If an implementation stores data about the key in a non-volatile memory,
+ * it must release all the resources associated with the key and erase the
+ * key material if the calling application terminates.
+ */
+#define PSA_KEY_LIFETIME_VOLATILE ((psa_key_lifetime_t) 0x00000000)
+
+/** The default lifetime for persistent keys.
+ *
+ * A persistent key remains in storage until it is explicitly destroyed or
+ * until the corresponding storage area is wiped. This specification does
+ * not define any mechanism to wipe a storage area, but integrations may
+ * provide their own mechanism (for example to perform a factory reset,
+ * to prepare for device refurbishment, or to uninstall an application).
+ *
+ * This lifetime value is the default storage area for the calling
+ * application. Integrations of Mbed TLS may support other persistent lifetimes.
+ * See ::psa_key_lifetime_t for more information.
+ */
+#define PSA_KEY_LIFETIME_PERSISTENT ((psa_key_lifetime_t) 0x00000001)
+
+/** The persistence level of volatile keys.
+ *
+ * See ::psa_key_persistence_t for more information.
+ */
+#define PSA_KEY_PERSISTENCE_VOLATILE ((psa_key_persistence_t) 0x00)
+
+/** The default persistence level for persistent keys.
+ *
+ * See ::psa_key_persistence_t for more information.
+ */
+#define PSA_KEY_PERSISTENCE_DEFAULT ((psa_key_persistence_t) 0x01)
+
+/** A persistence level indicating that a key is never destroyed.
+ *
+ * See ::psa_key_persistence_t for more information.
+ */
+#define PSA_KEY_PERSISTENCE_READ_ONLY ((psa_key_persistence_t) 0xff)
+
+#define PSA_KEY_LIFETIME_GET_PERSISTENCE(lifetime) \
+ ((psa_key_persistence_t) ((lifetime) & 0x000000ff))
+
+#define PSA_KEY_LIFETIME_GET_LOCATION(lifetime) \
+ ((psa_key_location_t) ((lifetime) >> 8))
+
+/** Whether a key lifetime indicates that the key is volatile.
+ *
+ * A volatile key is automatically destroyed by the implementation when
+ * the application instance terminates. In particular, a volatile key
+ * is automatically destroyed on a power reset of the device.
+ *
+ * A key that is not volatile is persistent. Persistent keys are
+ * preserved until the application explicitly destroys them or until an
+ * implementation-specific device management event occurs (for example,
+ * a factory reset).
+ *
+ * \param lifetime The lifetime value to query (value of type
+ * ::psa_key_lifetime_t).
+ *
+ * \return \c 1 if the key is volatile, otherwise \c 0.
+ */
+#define PSA_KEY_LIFETIME_IS_VOLATILE(lifetime) \
+ (PSA_KEY_LIFETIME_GET_PERSISTENCE(lifetime) == \
+ PSA_KEY_PERSISTENCE_VOLATILE)
+
+/** Whether a key lifetime indicates that the key is read-only.
+ *
+ * Read-only keys cannot be created or destroyed through the PSA Crypto API.
+ * They must be created through platform-specific means that bypass the API.
+ *
+ * Some platforms may offer ways to destroy read-only keys. For example,
+ * consider a platform with multiple levels of privilege, where a
+ * low-privilege application can use a key but is not allowed to destroy
+ * it, and the platform exposes the key to the application with a read-only
+ * lifetime. High-privilege code can destroy the key even though the
+ * application sees the key as read-only.
+ *
+ * \param lifetime The lifetime value to query (value of type
+ * ::psa_key_lifetime_t).
+ *
+ * \return \c 1 if the key is read-only, otherwise \c 0.
+ */
+#define PSA_KEY_LIFETIME_IS_READ_ONLY(lifetime) \
+ (PSA_KEY_LIFETIME_GET_PERSISTENCE(lifetime) == \
+ PSA_KEY_PERSISTENCE_READ_ONLY)
+
+/** Construct a lifetime from a persistence level and a location.
+ *
+ * \param persistence The persistence level
+ * (value of type ::psa_key_persistence_t).
+ * \param location The location indicator
+ * (value of type ::psa_key_location_t).
+ *
+ * \return The constructed lifetime value.
+ */
+#define PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(persistence, location) \
+ ((location) << 8 | (persistence))
+
+/** The local storage area for persistent keys.
+ *
+ * This storage area is available on all systems that can store persistent
+ * keys without delegating the storage to a third-party cryptoprocessor.
+ *
+ * See ::psa_key_location_t for more information.
+ */
+#define PSA_KEY_LOCATION_LOCAL_STORAGE ((psa_key_location_t) 0x000000)
+
+#define PSA_KEY_LOCATION_VENDOR_FLAG ((psa_key_location_t) 0x800000)
+
+/* Note that key identifier values are embedded in the
+ * persistent key store, as part of key metadata. As a consequence, they
+ * must not be changed (unless the storage format version changes).
+ */
+
+/** The null key identifier.
+ */
+/* *INDENT-OFF* (https://github.com/ARM-software/psa-arch-tests/issues/337) */
+#define PSA_KEY_ID_NULL ((psa_key_id_t)0)
+/* *INDENT-ON* */
+/** The minimum value for a key identifier chosen by the application.
+ */
+#define PSA_KEY_ID_USER_MIN ((psa_key_id_t) 0x00000001)
+/** The maximum value for a key identifier chosen by the application.
+ */
+#define PSA_KEY_ID_USER_MAX ((psa_key_id_t) 0x3fffffff)
+/** The minimum value for a key identifier chosen by the implementation.
+ */
+#define PSA_KEY_ID_VENDOR_MIN ((psa_key_id_t) 0x40000000)
+/** The maximum value for a key identifier chosen by the implementation.
+ */
+#define PSA_KEY_ID_VENDOR_MAX ((psa_key_id_t) 0x7fffffff)
+
+
+#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
+
+#define MBEDTLS_SVC_KEY_ID_INIT ((psa_key_id_t) 0)
+#define MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) (id)
+#define MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(id) (0)
+
+/** Utility to initialize a key identifier at runtime.
+ *
+ * \param unused Unused parameter.
+ * \param key_id Identifier of the key.
+ */
+static inline mbedtls_svc_key_id_t mbedtls_svc_key_id_make(
+ unsigned int unused, psa_key_id_t key_id)
+{
+ (void) unused;
+
+ return key_id;
+}
+
+/** Compare two key identifiers.
+ *
+ * \param id1 First key identifier.
+ * \param id2 Second key identifier.
+ *
+ * \return Non-zero if the two key identifier are equal, zero otherwise.
+ */
+static inline int mbedtls_svc_key_id_equal(mbedtls_svc_key_id_t id1,
+ mbedtls_svc_key_id_t id2)
+{
+ return id1 == id2;
+}
+
+/** Check whether a key identifier is null.
+ *
+ * \param key Key identifier.
+ *
+ * \return Non-zero if the key identifier is null, zero otherwise.
+ */
+static inline int mbedtls_svc_key_id_is_null(mbedtls_svc_key_id_t key)
+{
+ return key == 0;
+}
+
+#else /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
+#include "mbedtls/private_access.h"
+#define MBEDTLS_SVC_KEY_ID_INIT ((mbedtls_svc_key_id_t){ 0, 0 })
+#define MBEDTLS_SVC_KEY_ID_GET_KEY_ID(id) ((id).MBEDTLS_PRIVATE(key_id))
+#define MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(id) ((id).MBEDTLS_PRIVATE(owner))
+
+/** Utility to initialize a key identifier at runtime.
+ *
+ * \param owner_id Identifier of the key owner.
+ * \param key_id Identifier of the key.
+ */
+static inline mbedtls_svc_key_id_t mbedtls_svc_key_id_make(
+ mbedtls_key_owner_id_t owner_id, psa_key_id_t key_id)
+{
+ return (mbedtls_svc_key_id_t){ .MBEDTLS_PRIVATE(key_id) = key_id,
+ .MBEDTLS_PRIVATE(owner) = owner_id };
+}
+
+/** Compare two key identifiers.
+ *
+ * \param id1 First key identifier.
+ * \param id2 Second key identifier.
+ *
+ * \return Non-zero if the two key identifier are equal, zero otherwise.
+ */
+static inline int mbedtls_svc_key_id_equal(mbedtls_svc_key_id_t id1,
+ mbedtls_svc_key_id_t id2)
+{
+ return (id1.MBEDTLS_PRIVATE(key_id) == id2.MBEDTLS_PRIVATE(key_id)) &&
+ mbedtls_key_owner_id_equal(id1.MBEDTLS_PRIVATE(owner), id2.MBEDTLS_PRIVATE(owner));
+}
+
+/** Check whether a key identifier is null.
+ *
+ * \param key Key identifier.
+ *
+ * \return Non-zero if the key identifier is null, zero otherwise.
+ */
+static inline int mbedtls_svc_key_id_is_null(mbedtls_svc_key_id_t key)
+{
+ return key.MBEDTLS_PRIVATE(key_id) == 0;
+}
+
+#endif /* !MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
+
+/**@}*/
+
+/** \defgroup policy Key policies
+ * @{
+ */
+
+/* Note that key usage flags are embedded in the
+ * persistent key store, as part of key metadata. As a consequence, they
+ * must not be changed (unless the storage format version changes).
+ */
+
+/** Whether the key may be exported.
+ *
+ * A public key or the public part of a key pair may always be exported
+ * regardless of the value of this permission flag.
+ *
+ * If a key does not have export permission, implementations shall not
+ * allow the key to be exported in plain form from the cryptoprocessor,
+ * whether through psa_export_key() or through a proprietary interface.
+ * The key may however be exportable in a wrapped form, i.e. in a form
+ * where it is encrypted by another key.
+ */
+#define PSA_KEY_USAGE_EXPORT ((psa_key_usage_t) 0x00000001)
+
+/** Whether the key may be copied.
+ *
+ * This flag allows the use of psa_copy_key() to make a copy of the key
+ * with the same policy or a more restrictive policy.
+ *
+ * For lifetimes for which the key is located in a secure element which
+ * enforce the non-exportability of keys, copying a key outside the secure
+ * element also requires the usage flag #PSA_KEY_USAGE_EXPORT.
+ * Copying the key inside the secure element is permitted with just
+ * #PSA_KEY_USAGE_COPY if the secure element supports it.
+ * For keys with the lifetime #PSA_KEY_LIFETIME_VOLATILE or
+ * #PSA_KEY_LIFETIME_PERSISTENT, the usage flag #PSA_KEY_USAGE_COPY
+ * is sufficient to permit the copy.
+ */
+#define PSA_KEY_USAGE_COPY ((psa_key_usage_t) 0x00000002)
+
+/** Whether the key may be used to encrypt a message.
+ *
+ * This flag allows the key to be used for a symmetric encryption operation,
+ * for an AEAD encryption-and-authentication operation,
+ * or for an asymmetric encryption operation,
+ * if otherwise permitted by the key's type and policy.
+ *
+ * For a key pair, this concerns the public key.
+ */
+#define PSA_KEY_USAGE_ENCRYPT ((psa_key_usage_t) 0x00000100)
+
+/** Whether the key may be used to decrypt a message.
+ *
+ * This flag allows the key to be used for a symmetric decryption operation,
+ * for an AEAD decryption-and-verification operation,
+ * or for an asymmetric decryption operation,
+ * if otherwise permitted by the key's type and policy.
+ *
+ * For a key pair, this concerns the private key.
+ */
+#define PSA_KEY_USAGE_DECRYPT ((psa_key_usage_t) 0x00000200)
+
+/** Whether the key may be used to sign a message.
+ *
+ * This flag allows the key to be used for a MAC calculation operation or for
+ * an asymmetric message signature operation, if otherwise permitted by the
+ * key’s type and policy.
+ *
+ * For a key pair, this concerns the private key.
+ */
+#define PSA_KEY_USAGE_SIGN_MESSAGE ((psa_key_usage_t) 0x00000400)
+
+/** Whether the key may be used to verify a message.
+ *
+ * This flag allows the key to be used for a MAC verification operation or for
+ * an asymmetric message signature verification operation, if otherwise
+ * permitted by the key’s type and policy.
+ *
+ * For a key pair, this concerns the public key.
+ */
+#define PSA_KEY_USAGE_VERIFY_MESSAGE ((psa_key_usage_t) 0x00000800)
+
+/** Whether the key may be used to sign a message.
+ *
+ * This flag allows the key to be used for a MAC calculation operation
+ * or for an asymmetric signature operation,
+ * if otherwise permitted by the key's type and policy.
+ *
+ * For a key pair, this concerns the private key.
+ */
+#define PSA_KEY_USAGE_SIGN_HASH ((psa_key_usage_t) 0x00001000)
+
+/** Whether the key may be used to verify a message signature.
+ *
+ * This flag allows the key to be used for a MAC verification operation
+ * or for an asymmetric signature verification operation,
+ * if otherwise permitted by the key's type and policy.
+ *
+ * For a key pair, this concerns the public key.
+ */
+#define PSA_KEY_USAGE_VERIFY_HASH ((psa_key_usage_t) 0x00002000)
+
+/** Whether the key may be used to derive other keys or produce a password
+ * hash.
+ *
+ * This flag allows the key to be used for a key derivation operation or for
+ * a key agreement operation, if otherwise permitted by the key's type and
+ * policy.
+ *
+ * If this flag is present on all keys used in calls to
+ * psa_key_derivation_input_key() for a key derivation operation, then it
+ * permits calling psa_key_derivation_output_bytes() or
+ * psa_key_derivation_output_key() at the end of the operation.
+ */
+#define PSA_KEY_USAGE_DERIVE ((psa_key_usage_t) 0x00004000)
+
+/** Whether the key may be used to verify the result of a key derivation,
+ * including password hashing.
+ *
+ * This flag allows the key to be used:
+ *
+ * This flag allows the key to be used in a key derivation operation, if
+ * otherwise permitted by the key's type and policy.
+ *
+ * If this flag is present on all keys used in calls to
+ * psa_key_derivation_input_key() for a key derivation operation, then it
+ * permits calling psa_key_derivation_verify_bytes() or
+ * psa_key_derivation_verify_key() at the end of the operation.
+ */
+#define PSA_KEY_USAGE_VERIFY_DERIVATION ((psa_key_usage_t) 0x00008000)
+
+/**@}*/
+
+/** \defgroup derivation Key derivation
+ * @{
+ */
+
+/* Key input steps are not embedded in the persistent storage, so you can
+ * change them if needed: it's only an ABI change. */
+
+/** A secret input for key derivation.
+ *
+ * This should be a key of type #PSA_KEY_TYPE_DERIVE
+ * (passed to psa_key_derivation_input_key())
+ * or the shared secret resulting from a key agreement
+ * (obtained via psa_key_derivation_key_agreement()).
+ *
+ * The secret can also be a direct input (passed to
+ * key_derivation_input_bytes()). In this case, the derivation operation
+ * may not be used to derive keys: the operation will only allow
+ * psa_key_derivation_output_bytes(),
+ * psa_key_derivation_verify_bytes(), or
+ * psa_key_derivation_verify_key(), but not
+ * psa_key_derivation_output_key().
+ */
+#define PSA_KEY_DERIVATION_INPUT_SECRET ((psa_key_derivation_step_t) 0x0101)
+
+/** A low-entropy secret input for password hashing / key stretching.
+ *
+ * This is usually a key of type #PSA_KEY_TYPE_PASSWORD (passed to
+ * psa_key_derivation_input_key()) or a direct input (passed to
+ * psa_key_derivation_input_bytes()) that is a password or passphrase. It can
+ * also be high-entropy secret such as a key of type #PSA_KEY_TYPE_DERIVE or
+ * the shared secret resulting from a key agreement.
+ *
+ * The secret can also be a direct input (passed to
+ * key_derivation_input_bytes()). In this case, the derivation operation
+ * may not be used to derive keys: the operation will only allow
+ * psa_key_derivation_output_bytes(),
+ * psa_key_derivation_verify_bytes(), or
+ * psa_key_derivation_verify_key(), but not
+ * psa_key_derivation_output_key().
+ */
+#define PSA_KEY_DERIVATION_INPUT_PASSWORD ((psa_key_derivation_step_t) 0x0102)
+
+/** A high-entropy additional secret input for key derivation.
+ *
+ * This is typically the shared secret resulting from a key agreement obtained
+ * via `psa_key_derivation_key_agreement()`. It may alternatively be a key of
+ * type `PSA_KEY_TYPE_DERIVE` passed to `psa_key_derivation_input_key()`, or
+ * a direct input passed to `psa_key_derivation_input_bytes()`.
+ */
+#define PSA_KEY_DERIVATION_INPUT_OTHER_SECRET \
+ ((psa_key_derivation_step_t) 0x0103)
+
+/** A label for key derivation.
+ *
+ * This should be a direct input.
+ * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA.
+ */
+#define PSA_KEY_DERIVATION_INPUT_LABEL ((psa_key_derivation_step_t) 0x0201)
+
+/** A salt for key derivation.
+ *
+ * This should be a direct input.
+ * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA or
+ * #PSA_KEY_TYPE_PEPPER.
+ */
+#define PSA_KEY_DERIVATION_INPUT_SALT ((psa_key_derivation_step_t) 0x0202)
+
+/** An information string for key derivation.
+ *
+ * This should be a direct input.
+ * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA.
+ */
+#define PSA_KEY_DERIVATION_INPUT_INFO ((psa_key_derivation_step_t) 0x0203)
+
+/** A seed for key derivation.
+ *
+ * This should be a direct input.
+ * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA.
+ */
+#define PSA_KEY_DERIVATION_INPUT_SEED ((psa_key_derivation_step_t) 0x0204)
+
+/** A cost parameter for password hashing / key stretching.
+ *
+ * This must be a direct input, passed to psa_key_derivation_input_integer().
+ */
+#define PSA_KEY_DERIVATION_INPUT_COST ((psa_key_derivation_step_t) 0x0205)
+
+/**@}*/
+
+/** \defgroup helper_macros Helper macros
+ * @{
+ */
+
+/* Helper macros */
+
+/** Check if two AEAD algorithm identifiers refer to the same AEAD algorithm
+ * regardless of the tag length they encode.
+ *
+ * \param aead_alg_1 An AEAD algorithm identifier.
+ * \param aead_alg_2 An AEAD algorithm identifier.
+ *
+ * \return 1 if both identifiers refer to the same AEAD algorithm,
+ * 0 otherwise.
+ * Unspecified if neither \p aead_alg_1 nor \p aead_alg_2 are
+ * a supported AEAD algorithm.
+ */
+#define MBEDTLS_PSA_ALG_AEAD_EQUAL(aead_alg_1, aead_alg_2) \
+ (!(((aead_alg_1) ^ (aead_alg_2)) & \
+ ~(PSA_ALG_AEAD_TAG_LENGTH_MASK | PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG)))
+
+/**@}*/
+
+/**@}*/
+
+/** \defgroup interruptible Interruptible operations
+ * @{
+ */
+
+/** Maximum value for use with \c psa_interruptible_set_max_ops() to determine
+ * the maximum number of ops allowed to be executed by an interruptible
+ * function in a single call.
+ */
+#define PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED UINT32_MAX
+
+/**@}*/
+
+#endif /* PSA_CRYPTO_VALUES_H */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/psa/error.h b/nrfdemo/build/tfm/api_ns/interface/include/psa/error.h
new file mode 100644
index 0000000..fee8c99
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/psa/error.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/**
+ * \file psa/error.h
+ * \brief Standard error codes for the SPM and RoT Services
+ */
+
+#ifndef __PSA_ERROR_H__
+#define __PSA_ERROR_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* If #PSA_SUCCESS is already defined, it means that #psa_status_t
+ * is also defined in an external header, so prevent its multiple
+ * definition.
+ */
+#ifndef PSA_SUCCESS
+typedef int32_t psa_status_t;
+#endif
+
+#define PSA_SUCCESS ((psa_status_t)0)
+
+#define PSA_ERROR_PROGRAMMER_ERROR ((psa_status_t)-129)
+#define PSA_ERROR_CONNECTION_REFUSED ((psa_status_t)-130)
+#define PSA_ERROR_CONNECTION_BUSY ((psa_status_t)-131)
+#define PSA_ERROR_GENERIC_ERROR ((psa_status_t)-132)
+#define PSA_ERROR_NOT_PERMITTED ((psa_status_t)-133)
+#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)-134)
+#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)-135)
+#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136)
+#define PSA_ERROR_BAD_STATE ((psa_status_t)-137)
+#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t)-138)
+#define PSA_ERROR_ALREADY_EXISTS ((psa_status_t)-139)
+#define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t)-140)
+#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t)-141)
+#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)-142)
+#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143)
+#define PSA_ERROR_SERVICE_FAILURE ((psa_status_t)-144)
+#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)-145)
+#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)-146)
+#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t)-147)
+#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)-149)
+#define PSA_ERROR_DEPENDENCY_NEEDED ((psa_status_t)-156)
+#define PSA_ERROR_FLASH_ABUSE ((psa_status_t)-160)
+#define PSA_ERROR_INSUFFICIENT_POWER ((psa_status_t)-161)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PSA_ERROR_H__ */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/psa/framework_feature.h b/nrfdemo/build/tfm/api_ns/interface/include/psa/framework_feature.h
new file mode 100644
index 0000000..bb9436e
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/psa/framework_feature.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __PSA_FRAMEWORK_FEATURE_H__
+#define __PSA_FRAMEWORK_FEATURE_H__
+
+#define PSA_FRAMEWORK_ISOLATION_LEVEL 1
+#define PSA_FRAMEWORK_HAS_MM_IOVEC 0
+
+#endif /* __PSA_FRAMEWORK_FEATURE_H__ */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/psa_manifest/sid.h b/nrfdemo/build/tfm/api_ns/interface/include/psa_manifest/sid.h
new file mode 100644
index 0000000..203ab4e
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/psa_manifest/sid.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/*********** WARNING: This is an auto-generated file. Do not edit! ***********/
+
+#ifndef __PSA_MANIFEST_SID_H__
+#define __PSA_MANIFEST_SID_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******** TFM_SP_CRYPTO ********/
+#define TFM_CRYPTO_SID (0x00000080U)
+#define TFM_CRYPTO_VERSION (1U)
+#define TFM_CRYPTO_HANDLE (0x40000100U)
+
+/******** TFM_SP_PLATFORM ********/
+#define TFM_PLATFORM_SERVICE_SID (0x00000040U)
+#define TFM_PLATFORM_SERVICE_VERSION (1U)
+#define TFM_PLATFORM_SERVICE_HANDLE (0x40000105U)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PSA_MANIFEST_SID_H__ */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/tfm_crypto_defs.h b/nrfdemo/build/tfm/api_ns/interface/include/tfm_crypto_defs.h
new file mode 100644
index 0000000..4b3cfca
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/tfm_crypto_defs.h
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_CRYPTO_DEFS_H__
+#define __TFM_CRYPTO_DEFS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "psa/crypto.h"
+#ifdef PLATFORM_DEFAULT_CRYPTO_KEYS
+#include "crypto_keys/tfm_builtin_key_ids.h"
+#else
+#include "tfm_builtin_key_ids.h"
+#endif /* PLATFORM_DEFAULT_CRYPTO_KEYS */
+
+/**
+ * \brief The maximum supported length of a nonce through the TF-M
+ * interfaces
+ */
+#define TFM_CRYPTO_MAX_NONCE_LENGTH (16u)
+
+/**
+ * \brief This type is used to overcome a limitation in the number of maximum
+ * IOVECs that can be used especially in psa_aead_encrypt and
+ * psa_aead_decrypt. By using this type we pack the nonce and the actual
+ * nonce_length at part of the same structure
+ */
+struct tfm_crypto_aead_pack_input {
+ uint8_t nonce[TFM_CRYPTO_MAX_NONCE_LENGTH];
+ uint32_t nonce_length;
+};
+
+/**
+ * \brief Structure used to pack non-pointer types in a call to PSA Crypto APIs
+ *
+ */
+struct tfm_crypto_pack_iovec {
+ psa_key_id_t key_id; /*!< Key id */
+ psa_algorithm_t alg; /*!< Algorithm */
+ uint32_t op_handle; /*!< Frontend context handle associated to a
+ * multipart operation
+ */
+ size_t ad_length; /*!< Additional Data length for multipart AEAD */
+ size_t plaintext_length; /*!< Plaintext length for multipart AEAD */
+
+ struct tfm_crypto_aead_pack_input aead_in; /*!< Packs AEAD-related inputs */
+
+ uint16_t function_id; /*!< Used to identify the function in the
+ * API dispatcher to the service backend
+ * See tfm_crypto_func_sid for detail
+ */
+ uint16_t step; /*!< Key derivation step */
+ psa_pake_role_t role; /*!< PAKE role */
+ union {
+ size_t capacity; /*!< Key derivation capacity */
+ uint64_t value; /*!< Key derivation integer for update*/
+ };
+};
+
+/**
+ * \brief Type associated to the group of a function encoding. There can be
+ * nine groups (Random, Key management, Hash, MAC, Cipher, AEAD,
+ * Asym sign, Asym encrypt, Key derivation).
+ */
+enum tfm_crypto_group_id {
+ TFM_CRYPTO_GROUP_ID_RANDOM = 0x0,
+ TFM_CRYPTO_GROUP_ID_KEY_MANAGEMENT,
+ TFM_CRYPTO_GROUP_ID_HASH,
+ TFM_CRYPTO_GROUP_ID_MAC,
+ TFM_CRYPTO_GROUP_ID_CIPHER,
+ TFM_CRYPTO_GROUP_ID_AEAD,
+ TFM_CRYPTO_GROUP_ID_ASYM_SIGN,
+ TFM_CRYPTO_GROUP_ID_ASYM_ENCRYPT,
+ TFM_CRYPTO_GROUP_ID_KEY_DERIVATION,
+ TFM_CRYPTO_GROUP_ID_PAKE,
+};
+
+/* Set of X macros describing each of the available PSA Crypto APIs */
+#define KEY_MANAGEMENT_FUNCS \
+ X(TFM_CRYPTO_GET_KEY_ATTRIBUTES) \
+ X(TFM_CRYPTO_RESET_KEY_ATTRIBUTES) \
+ X(TFM_CRYPTO_OPEN_KEY) \
+ X(TFM_CRYPTO_CLOSE_KEY) \
+ X(TFM_CRYPTO_IMPORT_KEY) \
+ X(TFM_CRYPTO_DESTROY_KEY) \
+ X(TFM_CRYPTO_EXPORT_KEY) \
+ X(TFM_CRYPTO_EXPORT_PUBLIC_KEY) \
+ X(TFM_CRYPTO_PURGE_KEY) \
+ X(TFM_CRYPTO_COPY_KEY) \
+ X(TFM_CRYPTO_GENERATE_KEY)
+
+#define HASH_FUNCS \
+ X(TFM_CRYPTO_HASH_COMPUTE) \
+ X(TFM_CRYPTO_HASH_COMPARE) \
+ X(TFM_CRYPTO_HASH_SETUP) \
+ X(TFM_CRYPTO_HASH_UPDATE) \
+ X(TFM_CRYPTO_HASH_CLONE) \
+ X(TFM_CRYPTO_HASH_FINISH) \
+ X(TFM_CRYPTO_HASH_VERIFY) \
+ X(TFM_CRYPTO_HASH_ABORT)
+
+#define MAC_FUNCS \
+ X(TFM_CRYPTO_MAC_COMPUTE) \
+ X(TFM_CRYPTO_MAC_VERIFY) \
+ X(TFM_CRYPTO_MAC_SIGN_SETUP) \
+ X(TFM_CRYPTO_MAC_VERIFY_SETUP) \
+ X(TFM_CRYPTO_MAC_UPDATE) \
+ X(TFM_CRYPTO_MAC_SIGN_FINISH) \
+ X(TFM_CRYPTO_MAC_VERIFY_FINISH) \
+ X(TFM_CRYPTO_MAC_ABORT)
+
+#define CIPHER_FUNCS \
+ X(TFM_CRYPTO_CIPHER_ENCRYPT) \
+ X(TFM_CRYPTO_CIPHER_DECRYPT) \
+ X(TFM_CRYPTO_CIPHER_ENCRYPT_SETUP) \
+ X(TFM_CRYPTO_CIPHER_DECRYPT_SETUP) \
+ X(TFM_CRYPTO_CIPHER_GENERATE_IV) \
+ X(TFM_CRYPTO_CIPHER_SET_IV) \
+ X(TFM_CRYPTO_CIPHER_UPDATE) \
+ X(TFM_CRYPTO_CIPHER_FINISH) \
+ X(TFM_CRYPTO_CIPHER_ABORT)
+
+#define AEAD_FUNCS \
+ X(TFM_CRYPTO_AEAD_ENCRYPT) \
+ X(TFM_CRYPTO_AEAD_DECRYPT) \
+ X(TFM_CRYPTO_AEAD_ENCRYPT_SETUP) \
+ X(TFM_CRYPTO_AEAD_DECRYPT_SETUP) \
+ X(TFM_CRYPTO_AEAD_GENERATE_NONCE) \
+ X(TFM_CRYPTO_AEAD_SET_NONCE) \
+ X(TFM_CRYPTO_AEAD_SET_LENGTHS) \
+ X(TFM_CRYPTO_AEAD_UPDATE_AD) \
+ X(TFM_CRYPTO_AEAD_UPDATE) \
+ X(TFM_CRYPTO_AEAD_FINISH) \
+ X(TFM_CRYPTO_AEAD_VERIFY) \
+ X(TFM_CRYPTO_AEAD_ABORT)
+
+#define ASYMMETRIC_SIGN_FUNCS \
+ X(TFM_CRYPTO_ASYMMETRIC_SIGN_MESSAGE) \
+ X(TFM_CRYPTO_ASYMMETRIC_VERIFY_MESSAGE) \
+ X(TFM_CRYPTO_ASYMMETRIC_SIGN_HASH) \
+ X(TFM_CRYPTO_ASYMMETRIC_VERIFY_HASH)
+
+#define AYSMMETRIC_ENCRYPT_FUNCS \
+ X(TFM_CRYPTO_ASYMMETRIC_ENCRYPT) \
+ X(TFM_CRYPTO_ASYMMETRIC_DECRYPT)
+
+#define KEY_DERIVATION_FUNCS \
+ X(TFM_CRYPTO_RAW_KEY_AGREEMENT) \
+ X(TFM_CRYPTO_KEY_DERIVATION_SETUP) \
+ X(TFM_CRYPTO_KEY_DERIVATION_GET_CAPACITY) \
+ X(TFM_CRYPTO_KEY_DERIVATION_SET_CAPACITY) \
+ X(TFM_CRYPTO_KEY_DERIVATION_INPUT_BYTES) \
+ X(TFM_CRYPTO_KEY_DERIVATION_INPUT_KEY) \
+ X(TFM_CRYPTO_KEY_DERIVATION_INPUT_INTEGER) \
+ X(TFM_CRYPTO_KEY_DERIVATION_KEY_AGREEMENT) \
+ X(TFM_CRYPTO_KEY_DERIVATION_OUTPUT_BYTES) \
+ X(TFM_CRYPTO_KEY_DERIVATION_OUTPUT_KEY) \
+ X(TFM_CRYPTO_KEY_DERIVATION_ABORT)
+
+#define RANDOM_FUNCS \
+ X(TFM_CRYPTO_GENERATE_RANDOM)
+
+#define PAKE_FUNCS \
+ X(TFM_CRYPTO_PAKE_SETUP) \
+ X(TFM_CRYPTO_PAKE_SET_ROLE) \
+ X(TFM_CRYPTO_PAKE_SET_USER) \
+ X(TFM_CRYPTO_PAKE_SET_PEER) \
+ X(TFM_CRYPTO_PAKE_SET_CONTEXT) \
+ X(TFM_CRYPTO_PAKE_OUTPUT) \
+ X(TFM_CRYPTO_PAKE_INPUT) \
+ X(TFM_CRYPTO_PAKE_GET_SHARED_KEY) \
+ X(TFM_CRYPTO_PAKE_ABORT)
+
+/**
+ * \brief Define function IDs in each group. The function ID will be encoded into
+ * tfm_crypto_func_sid below. Each group is defined as a dedicated enum
+ */
+#define X(func_id) func_id,
+enum tfm_crypto_key_management_func_id {
+ KEY_MANAGEMENT_FUNCS
+};
+enum tfm_crypto_hash_func_id {
+ HASH_FUNCS
+};
+enum tfm_crypto_mac_func_id {
+ MAC_FUNCS
+};
+enum tfm_crypto_cipher_func_id {
+ CIPHER_FUNCS
+};
+enum tfm_crypto_aead_func_id {
+ AEAD_FUNCS
+};
+enum tfm_crypto_asym_sign_func_id {
+ ASYMMETRIC_SIGN_FUNCS
+};
+enum tfm_crypto_asym_encrypt_func_id {
+ AYSMMETRIC_ENCRYPT_FUNCS
+};
+enum tfm_crypto_key_derivation_func_id {
+ KEY_DERIVATION_FUNCS
+};
+enum tfm_crypto_random_func_id {
+ RANDOM_FUNCS
+};
+enum tfm_crypto_pake_func_id {
+ PAKE_FUNCS
+};
+#undef X
+
+/**
+ * \brief This macro is used to encode a function ID in a 16-bit value as the
+ * top 8 bits towards the MSB
+ */
+#define FUNC_ID(func_id) (((func_id) & 0xFF) << 8)
+
+/**
+ * \brief This macro is used to extract the group_id from an encoded function_id
+ * by accessing the low 8 bits towards the LSB
+ */
+#define TFM_CRYPTO_GET_GROUP_ID(_function_id) \
+ ((enum tfm_crypto_group_id)((_function_id) & 0xFF))
+/**
+ * \brief This type defines numerical progressive values identifying a function API
+ * exposed through the interfaces (S or NS). It's used to dispatch the requests
+ * from S/NS to the corresponding API implementation in the Crypto service backend.
+ *
+ * \note Each function SID is encoded as uint16_t.
+ * +-----------+-----------+
+ * | Func ID | Group ID |
+ * +-----------+-----------+
+ * (MSB)15 8 7 0(LSB)
+ *
+ * where Func ID is defined in each group tfm_crypto_*_func_id enum above and Group ID
+ * is defined in \ref tfm_crypto_group_id.
+ */
+enum tfm_crypto_func_sid {
+
+#define X(func_id) func_id ## _SID = (uint16_t)((FUNC_ID(func_id)) | \
+ (TFM_CRYPTO_GROUP_ID_KEY_MANAGEMENT & 0xFF)),
+
+ KEY_MANAGEMENT_FUNCS
+
+#undef X
+#define X(func_id) func_id ## _SID = (uint16_t)((FUNC_ID(func_id)) | \
+ (TFM_CRYPTO_GROUP_ID_HASH & 0xFF)),
+ HASH_FUNCS
+
+#undef X
+#define X(func_id) func_id ## _SID = (uint16_t)((FUNC_ID(func_id)) | \
+ (TFM_CRYPTO_GROUP_ID_MAC & 0xFF)),
+ MAC_FUNCS
+
+#undef X
+#define X(func_id) func_id ## _SID = (uint16_t)((FUNC_ID(func_id)) | \
+ (TFM_CRYPTO_GROUP_ID_CIPHER & 0xFF)),
+ CIPHER_FUNCS
+
+#undef X
+#define X(func_id) func_id ## _SID = (uint16_t)((FUNC_ID(func_id)) | \
+ (TFM_CRYPTO_GROUP_ID_AEAD & 0xFF)),
+ AEAD_FUNCS
+
+#undef X
+#define X(func_id) func_id ## _SID = (uint16_t)((FUNC_ID(func_id)) | \
+ (TFM_CRYPTO_GROUP_ID_ASYM_SIGN & 0xFF)),
+ ASYMMETRIC_SIGN_FUNCS
+
+#undef X
+#define X(func_id) func_id ## _SID = (uint16_t)((FUNC_ID(func_id)) | \
+ (TFM_CRYPTO_GROUP_ID_ASYM_ENCRYPT & 0xFF)),
+ AYSMMETRIC_ENCRYPT_FUNCS
+
+#undef X
+#define X(func_id) func_id ## _SID = (uint16_t)((FUNC_ID(func_id)) | \
+ (TFM_CRYPTO_GROUP_ID_KEY_DERIVATION & 0xFF)),
+ KEY_DERIVATION_FUNCS
+
+#undef X
+#define X(func_id) func_id ## _SID = (uint16_t)((FUNC_ID(func_id)) | \
+ (TFM_CRYPTO_GROUP_ID_RANDOM & 0xFF)),
+ RANDOM_FUNCS
+
+#undef X
+#define X(func_id) func_id ## _SID = (uint16_t)((FUNC_ID(func_id)) | \
+ (TFM_CRYPTO_GROUP_ID_PAKE & 0xFF)),
+ PAKE_FUNCS
+
+};
+#undef X
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_CRYPTO_DEFS_H__ */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/tfm_ioctl_core_api.h b/nrfdemo/build/tfm/api_ns/interface/include/tfm_ioctl_core_api.h
new file mode 100644
index 0000000..df3c8d6
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/tfm_ioctl_core_api.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2021 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/** @file
+ * @brief TFM IOCTL API header.
+ */
+
+
+#ifndef TFM_IOCTL_CORE_API_H__
+#define TFM_IOCTL_CORE_API_H__
+
+/**
+ * @defgroup tfm_ioctl_api TFM IOCTL API
+ * @{
+ *
+ */
+
+#include <limits.h>
+#include <tfm_platform_api.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Supported request types.
+ */
+enum tfm_platform_ioctl_core_reqest_types_t {
+ TFM_PLATFORM_IOCTL_READ_SERVICE,
+ TFM_PLATFORM_IOCTL_GPIO_SERVICE,
+
+ /* Last core service, start platform specific from this value. */
+ TFM_PLATFORM_IOCTL_CORE_LAST
+};
+
+/** @brief Argument list for each platform read service.
+ */
+struct tfm_read_service_args_t {
+ void *destination;
+ uint32_t addr;
+ size_t len;
+};
+
+
+/** @brief Output list for each read platform service
+ */
+struct tfm_read_service_out_t {
+ uint32_t result;
+};
+
+enum tfm_gpio_service_type {
+ /** Select which MCU / Subsystem controls the pin */
+ TFM_GPIO_SERVICE_TYPE_PIN_MCU_SELECT = 0,
+};
+
+/** @brief Arguments for selecting the MCU to control a GPIO pin. */
+struct tfm_gpio_service_args_mcu_select {
+ uint32_t pin_number;
+ uint32_t mcu;
+};
+
+/** @brief Argument list for each platform GPIO service */
+struct tfm_gpio_service_args {
+ uint32_t type;
+ union {
+ struct tfm_gpio_service_args_mcu_select mcu_select;
+ };
+};
+
+/** @brief Output list for each GPIO platform service
+ */
+struct tfm_gpio_service_out {
+ uint32_t result;
+};
+
+/**
+ * @brief Perform a read operation.
+ *
+ * @param[out] destination Pointer where read result is stored
+ * @param[in] addr Address to read from
+ * @param[in] len Number of bytes to read
+ * @param[out] result Result of operation
+ *
+ * @return Returns values as specified by the tfm_platform_err_t
+ */
+enum tfm_platform_err_t tfm_platform_mem_read(void *destination, uint32_t addr,
+ size_t len, uint32_t *result);
+
+/** @brief Represents an accepted read range.
+ */
+struct tfm_read_service_range {
+ uint32_t start;
+ size_t size;
+};
+
+/**
+ * @brief Perform a GPIO MCU select operation.
+ *
+ * @param pin_number Pin_number.
+ * @param mcu MCU to control the pin, use nrf_gpio_pin_sel_t values.
+
+ * @param[out] result Result of operation
+ *
+ * @return Returns values as specified by the tfm_platform_err_t
+ */
+enum tfm_platform_err_t tfm_platform_gpio_pin_mcu_select(uint32_t pin_number, uint32_t mcu,
+ uint32_t *result);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* TFM_IOCTL_CORE_API_H__ */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/tfm_ns_client_ext.h b/nrfdemo/build/tfm/api_ns/interface/include/tfm_ns_client_ext.h
new file mode 100644
index 0000000..b6e944c
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/tfm_ns_client_ext.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_NS_CLIENT_EXT_H__
+#define __TFM_NS_CLIENT_EXT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define TFM_NS_CLIENT_INVALID_TOKEN 0xFFFFFFFF
+
+/* TF-M NSID Error code */
+#define TFM_NS_CLIENT_ERR_SUCCESS 0x0
+#define TFM_NS_CLIENT_ERR_INVALID_TOKEN 0x1
+#define TFM_NS_CLIENT_ERR_INVALID_NSID 0x2
+#define TFM_NS_CLIENT_ERR_INVALID_ACCESS 0x3
+
+/**
+ * \brief Initialize the non-secure client extension
+ *
+ * \details This function should be called before any other non-secure client
+ * APIs. It gives NSPE the opportunity to initialize the non-secure
+ * client extension in TF-M. Also, NSPE can get the number of allocated
+ * non-secure client context slots in the return value. That is useful
+ * if NSPE wants to decide the group (context) assignment at runtime.
+ *
+ * \param[in] ctx_requested The number of non-secure context requested from the
+ * NS entity. If request maximum available context, then set it to 0.
+ *
+ * \return Returns the number of non-secure context allocated to the NS entity.
+ * The allocated context number <= maximum supported context number.
+ * If the initialization is failed, then 0 is returned.
+ */
+uint32_t tfm_nsce_init(uint32_t ctx_requested);
+
+/**
+ * \brief Acquire the context for a non-secure client
+ *
+ * \details This function should be called before a non-secure client calling
+ * the PSA API into TF-M. It is to request the allocation of the
+ * context for the upcoming service call from that non-secure client.
+ * The non-secure clients in one group share the same context.
+ * The thread ID is used to identify the different non-secure clients.
+ *
+ * \param[in] group_id The group ID of the non-secure client
+ * \param[in] thread_id The thread ID of the non-secure client
+ *
+ * \return Returns the token of the allocated context. 0xFFFFFFFF means the
+ * allocation failed and the token is invalid.
+ */
+uint32_t tfm_nsce_acquire_ctx(uint8_t group_id, uint8_t thread_id);
+
+/**
+ * \brief Release the context for the non-secure client
+ *
+ * \details This function should be called when a non-secure client is going to
+ * be terminated or will not call TF-M secure services in the future.
+ * It is to release the context allocated for the calling non-secure
+ * client. If the calling non-secure client is the only thread in the
+ * group, then the context will be deallocated. Otherwise, the context
+ * will still be taken for the other threads in the group.
+ *
+ * \param[in] token The token returned by tfm_nsce_acquire_ctx
+ *
+ * \return Returns the error code.
+ */
+uint32_t tfm_nsce_release_ctx(uint32_t token);
+
+/**
+ * \brief Load the context for the non-secure client
+ *
+ * \details This function should be called when a non-secure client is going to
+ * be scheduled in at the non-secure side.
+ * The caller is usually the scheduler of the RTOS.
+ * The non-secure client ID is managed by the non-secure world and
+ * passed to TF-M as the input parameter of TF-M.
+ *
+ * \param[in] token The token returned by tfm_nsce_acquire_ctx
+ * \param[in] nsid The non-secure client ID for this client
+ *
+ * \return Returns the error code.
+ */
+uint32_t tfm_nsce_load_ctx(uint32_t token, int32_t nsid);
+
+/**
+ * \brief Save the context for the non-secure client
+ *
+ * \details This function should be called when a non-secure client is going to
+ * be scheduled out at the non-secure side.
+ * The caller is usually the scheduler of the RTOS.
+ *
+ * \param[in] token The token returned by tfm_nsce_acquire_ctx
+ *
+ * \return Returns the error code.
+ */
+uint32_t tfm_nsce_save_ctx(uint32_t token);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_NS_CLIENT_EXT_H__ */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/tfm_ns_interface.h b/nrfdemo/build/tfm/api_ns/interface/include/tfm_ns_interface.h
new file mode 100644
index 0000000..32a04c5
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/tfm_ns_interface.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company)
+ * or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#ifndef __TFM_NS_INTERFACE_H__
+#define __TFM_NS_INTERFACE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "tfm_veneers.h"
+
+typedef int32_t (*veneer_fn) (uint32_t arg0, uint32_t arg1,
+ uint32_t arg2, uint32_t arg3);
+
+/**
+ * \brief NS interface, veneer function dispatcher
+ *
+ * \details This function implements the dispatching mechanism for the
+ * desired veneer function, to be called with the parameters
+ * described from arg0 to arg3.
+ *
+ * \note NSPE can use default implementation of this function or implement
+ * this function according to NS specific implementation and actual
+ * usage scenario.
+ *
+ * \param[in] fn Function pointer to the veneer function desired
+ * \param[in] arg0 Argument 0 of fn
+ * \param[in] arg1 Argument 1 of fn
+ * \param[in] arg2 Argument 2 of fn
+ * \param[in] arg3 Argument 3 of fn
+ *
+ * \return Returns the same return value of the requested veneer function
+ *
+ * \note This API must ensure the return value is from the veneer function.
+ * Other unrecoverable errors must be considered as fatal error and should
+ * not return.
+ */
+int32_t tfm_ns_interface_dispatch(veneer_fn fn,
+ uint32_t arg0, uint32_t arg1,
+ uint32_t arg2, uint32_t arg3);
+
+/**
+ * \brief NS interface initialization function
+ *
+ * \details This function initializes TF-M NS interface.
+ *
+ * \note NSPE can use default implementation of this function or implement
+ * this function according to NS specific implementation and actual
+ * usage scenario.
+ *
+ * \return \ref OS_WRAPPER_SUCCESS on success or \ref OS_WRAPPER_ERROR on error
+ */
+uint32_t tfm_ns_interface_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_NS_INTERFACE_H__ */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/tfm_platform_api.h b/nrfdemo/build/tfm/api_ns/interface/include/tfm_platform_api.h
new file mode 100644
index 0000000..e925503
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/tfm_platform_api.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_PLATFORM_API__
+#define __TFM_PLATFORM_API__
+
+#include <limits.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include "psa/client.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief TFM secure partition platform API version
+ */
+#define TFM_PLATFORM_API_VERSION_MAJOR (0)
+#define TFM_PLATFORM_API_VERSION_MINOR (3)
+
+#define TFM_PLATFORM_API_ID_NV_READ (1010)
+#define TFM_PLATFORM_API_ID_NV_INCREMENT (1011)
+#define TFM_PLATFORM_API_ID_SYSTEM_RESET (1012)
+#define TFM_PLATFORM_API_ID_IOCTL (1013)
+
+/*!
+ * \enum tfm_platform_err_t
+ *
+ * \brief Platform service error types
+ *
+ */
+enum tfm_platform_err_t {
+ TFM_PLATFORM_ERR_SUCCESS = 0,
+ TFM_PLATFORM_ERR_SYSTEM_ERROR,
+ TFM_PLATFORM_ERR_INVALID_PARAM,
+ TFM_PLATFORM_ERR_NOT_SUPPORTED,
+
+ /* Following entry is only to ensure the error code of int size */
+ TFM_PLATFORM_ERR_FORCE_INT_SIZE = INT_MAX
+};
+
+typedef int32_t tfm_platform_ioctl_req_t;
+
+/*!
+ * \brief Resets the system.
+ *
+ * \return Returns values as specified by the \ref tfm_platform_err_t
+ */
+enum tfm_platform_err_t tfm_platform_system_reset(void);
+
+/*!
+ * \brief Performs a platform-specific service
+ *
+ * \param[in] request Request identifier (valid values vary
+ * based on the platform)
+ * \param[in] input Input buffer to the requested service (or NULL)
+ * \param[in,out] output Output buffer to the requested service (or NULL)
+ *
+ * \return Returns values as specified by the \ref tfm_platform_err_t
+ */
+enum tfm_platform_err_t tfm_platform_ioctl(tfm_platform_ioctl_req_t request,
+ psa_invec *input,
+ psa_outvec *output);
+
+/*!
+ * \brief Increments the given non-volatile (NV) counter by one
+ *
+ * \param[in] counter_id NV counter ID.
+ *
+ * \return TFM_PLATFORM_ERR_SUCCESS if the value is read correctly. Otherwise,
+ * it returns TFM_PLATFORM_ERR_SYSTEM_ERROR.
+ */
+enum tfm_platform_err_t
+tfm_platform_nv_counter_increment(uint32_t counter_id);
+
+/*!
+ * \brief Reads the given non-volatile (NV) counter
+ *
+ * \param[in] counter_id NV counter ID.
+ * \param[in] size Size of the buffer to store NV counter value
+ * in bytes.
+ * \param[out] val Pointer to store the current NV counter value.
+ *
+ * \return TFM_PLATFORM_ERR_SUCCESS if the value is read correctly. Otherwise,
+ * it returns TFM_PLATFORM_ERR_SYSTEM_ERROR.
+ */
+enum tfm_platform_err_t
+tfm_platform_nv_counter_read(uint32_t counter_id,
+ uint32_t size, uint8_t *val);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_PLATFORM_API__ */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/tfm_psa_call_pack.h b/nrfdemo/build/tfm/api_ns/interface/include/tfm_psa_call_pack.h
new file mode 100644
index 0000000..7cf62f8
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/tfm_psa_call_pack.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_PSA_CALL_PACK_H__
+#define __TFM_PSA_CALL_PACK_H__
+
+#include "psa/client.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * 31 30-28 27 26-24 23-20 19 18-16 15-0
+ * +------------+-----+------+-------+-----+-------+-------+------+
+ * | NS vector | | NS | invec | | NS | outvec| type |
+ * | descriptor | Res | invec| number| Res | outvec| number| |
+ * +------------+-----+------+-------+-----+-------+-------+------+
+ *
+ * Res: Reserved.
+ */
+#define TYPE_MASK 0xFFFFUL
+
+#define IN_LEN_OFFSET 24
+#define IN_LEN_MASK (0x7UL << IN_LEN_OFFSET)
+
+#define OUT_LEN_OFFSET 16
+#define OUT_LEN_MASK (0x7UL << OUT_LEN_OFFSET)
+
+/*
+ * NS_VEC_DESC_BIT is referenced by inline assembly, which does not
+ * support composited bit operations. So NS_VEC_DESC_BIT must be
+ * defined as a number.
+ */
+#define NS_VEC_DESC_BIT 0x80000000UL
+
+#define NS_INVEC_OFFSET 27
+#define NS_INVEC_BIT (1UL << NS_INVEC_OFFSET)
+#define NS_OUTVEC_OFFSET 19
+#define NS_OUTVEC_BIT (1UL << NS_OUTVEC_OFFSET)
+
+#define PARAM_PACK(type, in_len, out_len) \
+ ((((uint32_t)(type)) & TYPE_MASK) | \
+ ((((uint32_t)(in_len)) << IN_LEN_OFFSET) & IN_LEN_MASK) | \
+ ((((uint32_t)(out_len)) << OUT_LEN_OFFSET) & OUT_LEN_MASK))
+
+#define PARAM_UNPACK_TYPE(ctrl_param) \
+ ((int32_t)(int16_t)((ctrl_param) & TYPE_MASK))
+
+#define PARAM_UNPACK_IN_LEN(ctrl_param) \
+ ((size_t)(((ctrl_param) & IN_LEN_MASK) >> IN_LEN_OFFSET))
+
+#define PARAM_UNPACK_OUT_LEN(ctrl_param) \
+ ((size_t)(((ctrl_param) & OUT_LEN_MASK) >> OUT_LEN_OFFSET))
+
+#define PARAM_SET_NS_VEC(ctrl_param) ((ctrl_param) | NS_VEC_DESC_BIT)
+#define PARAM_IS_NS_VEC(ctrl_param) ((ctrl_param) & NS_VEC_DESC_BIT)
+
+#define PARAM_SET_NS_INVEC(ctrl_param) ((ctrl_param) | NS_INVEC_BIT)
+#define PARAM_IS_NS_INVEC(ctrl_param) ((ctrl_param) & NS_INVEC_BIT)
+#define PARAM_SET_NS_OUTVEC(ctrl_param) ((ctrl_param) | NS_OUTVEC_BIT)
+#define PARAM_IS_NS_OUTVEC(ctrl_param) ((ctrl_param) & NS_OUTVEC_BIT)
+
+#define PARAM_HAS_IOVEC(ctrl_param) \
+ ((ctrl_param) != (uint32_t)PARAM_UNPACK_TYPE(ctrl_param))
+
+psa_status_t tfm_psa_call_pack(psa_handle_t handle,
+ uint32_t ctrl_param,
+ const psa_invec *in_vec,
+ psa_outvec *out_vec);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_PSA_CALL_PACK_H__ */
diff --git a/nrfdemo/build/tfm/api_ns/interface/include/tfm_veneers.h b/nrfdemo/build/tfm/api_ns/interface/include/tfm_veneers.h
new file mode 100644
index 0000000..24c4036
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/include/tfm_veneers.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_VENEERS_H__
+#define __TFM_VENEERS_H__
+
+#include <stdint.h>
+#include "psa/client.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/********************* Secure function declarations ***************************/
+
+/**
+ * \brief Retrieve the version of the PSA Framework API that is implemented.
+ *
+ * \return The version of the PSA Framework.
+ */
+uint32_t tfm_psa_framework_version_veneer(void);
+
+/**
+ * \brief Return version of secure function provided by secure binary.
+ *
+ * \param[in] sid ID of secure service.
+ *
+ * \return Version number of secure function.
+ */
+uint32_t tfm_psa_version_veneer(uint32_t sid);
+
+/**
+ * \brief Connect to secure function.
+ *
+ * \param[in] sid ID of secure service.
+ * \param[in] version Version of SF requested by client.
+ *
+ * \return Returns handle to connection.
+ */
+psa_handle_t tfm_psa_connect_veneer(uint32_t sid, uint32_t version);
+
+/**
+ * \brief Call a secure function referenced by a connection handle.
+ *
+ * \param[in] handle Handle to connection.
+ * \param[in] ctrl_param Parameters combined in uint32_t,
+ * includes request type, in_num and out_num.
+ * \param[in] in_vec Array of input \ref psa_invec structures.
+ * \param[in,out] out_vec Array of output \ref psa_outvec structures.
+ *
+ * \return Returns \ref psa_status_t status code.
+ */
+psa_status_t tfm_psa_call_veneer(psa_handle_t handle,
+ uint32_t ctrl_param,
+ const psa_invec *in_vec,
+ psa_outvec *out_vec);
+
+/**
+ * \brief Close connection to secure function referenced by a connection handle.
+ *
+ * \param[in] handle Handle to connection
+ */
+void tfm_psa_close_veneer(psa_handle_t handle);
+
+/***************** End Secure function declarations ***************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_VENEERS_H__ */
diff --git a/nrfdemo/build/tfm/api_ns/interface/lib/s_veneers.o b/nrfdemo/build/tfm/api_ns/interface/lib/s_veneers.o
new file mode 100644
index 0000000..c4ae99b
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/lib/s_veneers.o
Binary files differ
diff --git a/nrfdemo/build/tfm/api_ns/interface/src/os_wrapper/tfm_ns_interface_bare_metal.c b/nrfdemo/build/tfm/api_ns/interface/src/os_wrapper/tfm_ns_interface_bare_metal.c
new file mode 100644
index 0000000..01da8b8
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/src/os_wrapper/tfm_ns_interface_bare_metal.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company)
+ * or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* This file provides implementation of TF-M NS os wrapper functions for the
+ * bare metal use case.
+ *
+ * \note This implementation does not provide multithread safety, so it
+ * shouldn't be used in RTOS environment.
+ */
+
+#include "tfm_ns_interface.h"
+
+int32_t tfm_ns_interface_dispatch(veneer_fn fn,
+ uint32_t arg0, uint32_t arg1,
+ uint32_t arg2, uint32_t arg3)
+{
+ return fn(arg0, arg1, arg2, arg3);
+}
diff --git a/nrfdemo/build/tfm/api_ns/interface/src/os_wrapper/tfm_ns_interface_rtos.c b/nrfdemo/build/tfm/api_ns/interface/src/os_wrapper/tfm_ns_interface_rtos.c
new file mode 100644
index 0000000..a1f7727
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/src/os_wrapper/tfm_ns_interface_rtos.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company)
+ * or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* This file provides implementation of TF-M NS os wrapper functions for the
+ * RTOS use case. This implementation provides multithread safety, so it
+ * can be used in RTOS environment.
+ */
+
+#include <stdint.h>
+
+#include "os_wrapper/mutex.h"
+
+#include "tfm_ns_interface.h"
+
+/**
+ * \brief the ns_lock ID
+ */
+static void *ns_lock_handle = NULL;
+
+int32_t tfm_ns_interface_dispatch(veneer_fn fn,
+ uint32_t arg0, uint32_t arg1,
+ uint32_t arg2, uint32_t arg3)
+{
+ int32_t result;
+
+ /* TFM request protected by NS lock */
+ while (os_wrapper_mutex_acquire(ns_lock_handle, OS_WRAPPER_WAIT_FOREVER)
+ != OS_WRAPPER_SUCCESS) {
+ }
+
+ result = fn(arg0, arg1, arg2, arg3);
+
+ while (os_wrapper_mutex_release(ns_lock_handle) != OS_WRAPPER_SUCCESS) {
+ }
+
+ return result;
+}
+
+uint32_t tfm_ns_interface_init(void)
+{
+ void *handle;
+
+ handle = os_wrapper_mutex_create();
+ if (!handle) {
+ return OS_WRAPPER_ERROR;
+ }
+
+ ns_lock_handle = handle;
+ return OS_WRAPPER_SUCCESS;
+}
diff --git a/nrfdemo/build/tfm/api_ns/interface/src/tfm_crypto_api.c b/nrfdemo/build/tfm/api_ns/interface/src/tfm_crypto_api.c
new file mode 100644
index 0000000..4dc7ea8
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/src/tfm_crypto_api.c
@@ -0,0 +1,1849 @@
+/*
+ * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_crypto_defs.h"
+#include "psa/crypto.h"
+#include "psa/client.h"
+#include "psa_manifest/sid.h"
+
+#define API_DISPATCH(in_vec, out_vec) \
+ psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, \
+ in_vec, IOVEC_LEN(in_vec), \
+ out_vec, IOVEC_LEN(out_vec))
+#define API_DISPATCH_NO_OUTVEC(in_vec) \
+ psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, \
+ in_vec, IOVEC_LEN(in_vec), \
+ (psa_outvec *)NULL, 0)
+
+/*!
+ * \def CONFIG_TFM_CRYPTO_API_RENAME
+ *
+ * \brief By setting this to 1, system integrators can rename the symbols of the
+ * PSA Crypto APIs available in the TF-M interface. It allows flexibility
+ * for some integration setups where multiple providers of the PSA Crypto
+ * APIs are available at link time. Normally this configuration option
+ * should not be enabled when building the Secure interface because the
+ * secure partitions will just use the standard function names. By default
+ * it prepends the "tfm_crypto__" prefix.
+ *
+ * \note This config option is not available through the TF-M configuration as
+ * it's for NS applications and system integrators to enable.
+ */
+
+/*!
+ * \def TFM_CRYPTO_API(ret, fun)
+ *
+ * \brief Define the function signature of a TF-M Crypto API with return
+ * type \a ret and PSA Crypto API function name \a fun
+ *
+ * \param ret return type associated to the API
+ * \param fun API name (e.g. a PSA Crypto API function name)
+ *
+ * \returns Function signature
+ */
+
+#if CONFIG_TFM_CRYPTO_API_RENAME == 1
+#define TFM_CRYPTO_API(ret, fun) ret tfm_crypto__##fun
+#else
+#define TFM_CRYPTO_API(ret, fun) ret fun
+#endif /* CONFIG_TFM_CRYPTO_API_RENAME */
+
+TFM_CRYPTO_API(psa_status_t, psa_crypto_init)(void)
+{
+ /* Service init is performed during TFM boot up,
+ * so application level initialisation is empty
+ */
+ return PSA_SUCCESS;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_open_key)(psa_key_id_t id,
+ psa_key_id_t *key)
+{
+ const struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_OPEN_KEY_SID,
+ .key_id = id,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = key, .len = sizeof(psa_key_id_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_close_key)(psa_key_id_t key)
+{
+ const struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CLOSE_KEY_SID,
+ .key_id = key,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_import_key)(const psa_key_attributes_t *attributes,
+ const uint8_t *data,
+ size_t data_length,
+ psa_key_id_t *key)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_IMPORT_KEY_SID,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = attributes, .len = sizeof(psa_key_attributes_t)},
+ {.base = data, .len = data_length}
+ };
+ psa_outvec out_vec[] = {
+ {.base = key, .len = sizeof(psa_key_id_t)}
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_destroy_key)(psa_key_id_t key)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_DESTROY_KEY_SID,
+ .key_id = key,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_get_key_attributes)(psa_key_id_t key,
+ psa_key_attributes_t *attributes)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_GET_KEY_ATTRIBUTES_SID,
+ .key_id = key,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = attributes, .len = sizeof(psa_key_attributes_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(void, psa_reset_key_attributes)(psa_key_attributes_t *attributes)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_RESET_KEY_ATTRIBUTES_SID,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = attributes, .len = sizeof(psa_key_attributes_t)},
+ };
+
+ (void)API_DISPATCH(in_vec, out_vec);
+ return;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_export_key)(psa_key_id_t key,
+ uint8_t *data,
+ size_t data_size,
+ size_t *data_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_EXPORT_KEY_SID,
+ .key_id = key,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = data, .len = data_size}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *data_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_export_public_key)(psa_key_id_t key,
+ uint8_t *data,
+ size_t data_size,
+ size_t *data_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_EXPORT_PUBLIC_KEY_SID,
+ .key_id = key,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = data, .len = data_size}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *data_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_purge_key)(psa_key_id_t key)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PURGE_KEY_SID,
+ .key_id = key,
+ };
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_copy_key)(psa_key_id_t source_key,
+ const psa_key_attributes_t *attributes,
+ psa_key_id_t *target_key)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_COPY_KEY_SID,
+ .key_id = source_key,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = attributes, .len = sizeof(psa_key_attributes_t)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = target_key, .len = sizeof(psa_key_id_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_generate_iv)(psa_cipher_operation_t *operation,
+ unsigned char *iv,
+ size_t iv_size,
+ size_t *iv_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_GENERATE_IV_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = iv, .len = iv_size},
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *iv_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_set_iv)(psa_cipher_operation_t *operation,
+ const unsigned char *iv,
+ size_t iv_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_SET_IV_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = iv, .len = iv_length},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_encrypt_setup)(psa_cipher_operation_t *operation,
+ psa_key_id_t key,
+ psa_algorithm_t alg)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SID,
+ .key_id = key,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_decrypt_setup)(psa_cipher_operation_t *operation,
+ psa_key_id_t key,
+ psa_algorithm_t alg)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SID,
+ .key_id = key,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_update)(psa_cipher_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length,
+ unsigned char *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_UPDATE_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *output_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_abort)(psa_cipher_operation_t *operation)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_ABORT_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_finish)(psa_cipher_operation_t *operation,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_FINISH_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = output, .len = output_size},
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *output_length = out_vec[1].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_hash_setup)(psa_hash_operation_t *operation,
+ psa_algorithm_t alg)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_HASH_SETUP_SID,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_hash_update)(psa_hash_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_HASH_UPDATE_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_hash_finish)(psa_hash_operation_t *operation,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_HASH_FINISH_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = hash, .len = hash_size},
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *hash_length = out_vec[1].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_hash_verify)(psa_hash_operation_t *operation,
+ const uint8_t *hash,
+ size_t hash_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_HASH_VERIFY_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = hash, .len = hash_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_hash_abort)(psa_hash_operation_t *operation)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_HASH_ABORT_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_hash_clone)(const psa_hash_operation_t *source_operation,
+ psa_hash_operation_t *target_operation)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_HASH_CLONE_SID,
+ .op_handle = source_operation->handle,
+ };
+
+ if (target_operation && (target_operation->handle != 0)) {
+ return PSA_ERROR_BAD_STATE;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = &(target_operation->handle),
+ .len = sizeof(target_operation->handle)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(target_operation->handle),
+ .len = sizeof(target_operation->handle)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_hash_compute)(psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *hash,
+ size_t hash_size,
+ size_t *hash_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_HASH_COMPUTE_SID,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = hash, .len = hash_size}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *hash_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_hash_compare)(psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *hash,
+ size_t hash_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_HASH_COMPARE_SID,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ {.base = hash, .len = hash_length},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_mac_sign_setup)(psa_mac_operation_t *operation,
+ psa_key_id_t key,
+ psa_algorithm_t alg)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_MAC_SIGN_SETUP_SID,
+ .key_id = key,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_mac_verify_setup)(psa_mac_operation_t *operation,
+ psa_key_id_t key,
+ psa_algorithm_t alg)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_MAC_VERIFY_SETUP_SID,
+ .key_id = key,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_mac_update)(psa_mac_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_MAC_UPDATE_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_mac_sign_finish)(psa_mac_operation_t *operation,
+ uint8_t *mac,
+ size_t mac_size,
+ size_t *mac_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_MAC_SIGN_FINISH_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = mac, .len = mac_size},
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *mac_length = out_vec[1].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_mac_verify_finish)(psa_mac_operation_t *operation,
+ const uint8_t *mac,
+ size_t mac_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_MAC_VERIFY_FINISH_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = mac, .len = mac_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_mac_abort)(psa_mac_operation_t *operation)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_MAC_ABORT_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_encrypt)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *nonce,
+ size_t nonce_length,
+ const uint8_t *additional_data,
+ size_t additional_data_length,
+ const uint8_t *plaintext,
+ size_t plaintext_length,
+ uint8_t *ciphertext,
+ size_t ciphertext_size,
+ size_t *ciphertext_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_ENCRYPT_SID,
+ .key_id = key,
+ .alg = alg,
+ .aead_in = {.nonce = {0}, .nonce_length = 0}
+ };
+
+ /* Sanitize the optional input */
+ if ((additional_data == NULL) && (additional_data_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = NULL, .len = 0},
+ {.base = plaintext, .len = plaintext_length},
+ {.base = additional_data, .len = additional_data_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = ciphertext, .len = ciphertext_size},
+ };
+
+ if (nonce_length > TFM_CRYPTO_MAX_NONCE_LENGTH) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (nonce != NULL) {
+ for (size_t idx = 0; idx < nonce_length; idx++) {
+ iov.aead_in.nonce[idx] = nonce[idx];
+ }
+ iov.aead_in.nonce_length = nonce_length;
+ }
+
+ in_vec[0].base = &iov;
+ in_vec[0].len = sizeof(struct tfm_crypto_pack_iovec);
+
+ size_t in_len = IOVEC_LEN(in_vec);
+
+ if (additional_data == NULL) {
+ in_len--;
+ }
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
+ out_vec, IOVEC_LEN(out_vec));
+
+ *ciphertext_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_decrypt)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *nonce,
+ size_t nonce_length,
+ const uint8_t *additional_data,
+ size_t additional_data_length,
+ const uint8_t *ciphertext,
+ size_t ciphertext_length,
+ uint8_t *plaintext,
+ size_t plaintext_size,
+ size_t *plaintext_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_DECRYPT_SID,
+ .key_id = key,
+ .alg = alg,
+ .aead_in = {.nonce = {0}, .nonce_length = 0}
+ };
+
+ /* Sanitize the optional input */
+ if ((additional_data == NULL) && (additional_data_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = NULL, .len = 0},
+ {.base = ciphertext, .len = ciphertext_length},
+ {.base = additional_data, .len = additional_data_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = plaintext, .len = plaintext_size},
+ };
+
+ if (nonce_length > TFM_CRYPTO_MAX_NONCE_LENGTH) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (nonce != NULL) {
+ for (size_t idx = 0; idx < nonce_length; idx++) {
+ iov.aead_in.nonce[idx] = nonce[idx];
+ }
+ iov.aead_in.nonce_length = nonce_length;
+ }
+
+ in_vec[0].base = &iov;
+ in_vec[0].len = sizeof(struct tfm_crypto_pack_iovec);
+
+ size_t in_len = IOVEC_LEN(in_vec);
+
+ if (additional_data == NULL) {
+ in_len--;
+ }
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
+ out_vec, IOVEC_LEN(out_vec));
+
+ *plaintext_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_encrypt_setup)(psa_aead_operation_t *operation,
+ psa_key_id_t key,
+ psa_algorithm_t alg)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_ENCRYPT_SETUP_SID,
+ .key_id = key,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_decrypt_setup)(psa_aead_operation_t *operation,
+ psa_key_id_t key,
+ psa_algorithm_t alg)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_DECRYPT_SETUP_SID,
+ .key_id = key,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_generate_nonce)(psa_aead_operation_t *operation,
+ uint8_t *nonce,
+ size_t nonce_size,
+ size_t *nonce_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_GENERATE_NONCE_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = nonce, .len = nonce_size}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *nonce_length = out_vec[0].len;
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_set_nonce)(psa_aead_operation_t *operation,
+ const uint8_t *nonce,
+ size_t nonce_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_SET_NONCE_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = nonce, .len = nonce_length}
+ };
+
+ status = API_DISPATCH_NO_OUTVEC(in_vec);
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_set_lengths)(psa_aead_operation_t *operation,
+ size_t ad_length,
+ size_t plaintext_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_SET_LENGTHS_SID,
+ .ad_length = ad_length,
+ .plaintext_length = plaintext_length,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ status = API_DISPATCH_NO_OUTVEC(in_vec);
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_update_ad)(psa_aead_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_UPDATE_AD_SID,
+ .op_handle = operation->handle,
+ };
+
+ /* Sanitize the optional input */
+ if ((input == NULL) && (input_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length}
+ };
+
+ size_t in_len = IOVEC_LEN(in_vec);
+
+ if (input == NULL) {
+ in_len--;
+ }
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
+ NULL, 0);
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, 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)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_UPDATE_SID,
+ .op_handle = operation->handle,
+ };
+
+ /* Sanitize the optional input */
+ if ((input == NULL) && (input_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length}
+ };
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size},
+ };
+
+ size_t in_len = IOVEC_LEN(in_vec);
+
+ if (input == NULL) {
+ in_len--;
+ }
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
+ out_vec, IOVEC_LEN(out_vec));
+
+ *output_length = out_vec[0].len;
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_finish)(psa_aead_operation_t *operation,
+ uint8_t *ciphertext,
+ size_t ciphertext_size,
+ size_t *ciphertext_length,
+ uint8_t *tag,
+ size_t tag_size,
+ size_t *tag_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_FINISH_SID,
+ .op_handle = operation->handle,
+ };
+
+ /* Sanitize the optional output */
+ if ((ciphertext == NULL) && (ciphertext_size != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = tag, .len = tag_size},
+ {.base = ciphertext, .len = ciphertext_size}
+ };
+
+ size_t out_len = IOVEC_LEN(out_vec);
+
+ if (ciphertext == NULL || ciphertext_size == 0) {
+ out_len--;
+ }
+ if ((out_len == 3) && (ciphertext_length == NULL)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL,
+ in_vec, IOVEC_LEN(in_vec),
+ out_vec, out_len);
+
+ if (out_len == 3) {
+ *ciphertext_length = out_vec[2].len;
+ } else {
+ *ciphertext_length = 0;
+ }
+
+ *tag_length = out_vec[1].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_verify)(psa_aead_operation_t *operation,
+ uint8_t *plaintext,
+ size_t plaintext_size,
+ size_t *plaintext_length,
+ const uint8_t *tag,
+ size_t tag_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_VERIFY_SID,
+ .op_handle = operation->handle,
+ };
+
+ /* Sanitize the optional output */
+ if ((plaintext == NULL) && (plaintext_size != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = tag, .len = tag_length}
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = plaintext, .len = plaintext_size}
+ };
+
+ size_t out_len = IOVEC_LEN(out_vec);
+
+ if (plaintext == NULL || plaintext_size == 0) {
+ out_len--;
+ }
+ if ((out_len == 2) && (plaintext_length == NULL)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL,
+ in_vec, IOVEC_LEN(in_vec),
+ out_vec, out_len);
+
+ if (out_len == 2) {
+ *plaintext_length = out_vec[1].len;
+ } else {
+ *plaintext_length = 0;
+ }
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_aead_abort)(psa_aead_operation_t *operation)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_AEAD_ABORT_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_sign_message)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *signature,
+ size_t signature_size,
+ size_t *signature_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_ASYMMETRIC_SIGN_MESSAGE_SID,
+ .key_id = key,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = signature, .len = signature_size},
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *signature_length = out_vec[0].len;
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_verify_message)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *signature,
+ size_t signature_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_ASYMMETRIC_VERIFY_MESSAGE_SID,
+ .key_id = key,
+ .alg = alg
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ {.base = signature, .len = signature_length}
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_sign_hash)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *hash,
+ size_t hash_length,
+ uint8_t *signature,
+ size_t signature_size,
+ size_t *signature_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_ASYMMETRIC_SIGN_HASH_SID,
+ .key_id = key,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = hash, .len = hash_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = signature, .len = signature_size},
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *signature_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_verify_hash)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *hash,
+ size_t hash_length,
+ const uint8_t *signature,
+ size_t signature_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_ASYMMETRIC_VERIFY_HASH_SID,
+ .key_id = key,
+ .alg = alg
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = hash, .len = hash_length},
+ {.base = signature, .len = signature_length}
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_asymmetric_encrypt)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *salt,
+ size_t salt_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_ASYMMETRIC_ENCRYPT_SID,
+ .key_id = key,
+ .alg = alg
+ };
+
+ /* Sanitize the optional input */
+ if ((salt == NULL) && (salt_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ {.base = salt, .len = salt_length}
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size},
+ };
+
+ size_t in_len = IOVEC_LEN(in_vec);
+
+ if (salt == NULL) {
+ in_len--;
+ }
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
+ out_vec, IOVEC_LEN(out_vec));
+
+ *output_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_asymmetric_decrypt)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *salt,
+ size_t salt_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_ASYMMETRIC_DECRYPT_SID,
+ .key_id = key,
+ .alg = alg
+ };
+
+ /* Sanitize the optional input */
+ if ((salt == NULL) && (salt_length != 0)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ {.base = salt, .len = salt_length}
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size},
+ };
+
+ size_t in_len = IOVEC_LEN(in_vec);
+
+ if (salt == NULL) {
+ in_len--;
+ }
+ status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
+ out_vec, IOVEC_LEN(out_vec));
+
+ *output_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_get_capacity)(
+ const psa_key_derivation_operation_t *operation,
+ size_t *capacity)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_GET_CAPACITY_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = capacity, .len = sizeof(size_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_output_bytes)(
+ psa_key_derivation_operation_t *operation,
+ uint8_t *output,
+ size_t output_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_OUTPUT_BYTES_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_length},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_input_key)(
+ psa_key_derivation_operation_t *operation,
+ psa_key_derivation_step_t step,
+ psa_key_id_t key)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_INPUT_KEY_SID,
+ .key_id = key,
+ .step = step,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_abort)(psa_key_derivation_operation_t *operation)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_ABORT_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_key_agreement)(
+ psa_key_derivation_operation_t *operation,
+ psa_key_derivation_step_t step,
+ psa_key_id_t private_key,
+ const uint8_t *peer_key,
+ size_t peer_key_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_KEY_AGREEMENT_SID,
+ .key_id = private_key,
+ .step = step,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = peer_key, .len = peer_key_length},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_generate_random)(uint8_t *output,
+ size_t output_size)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_GENERATE_RANDOM_SID,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size},
+ };
+
+ if (output_size == 0) {
+ return PSA_SUCCESS;
+ }
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_generate_key)(const psa_key_attributes_t *attributes,
+ psa_key_id_t *key)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_GENERATE_KEY_SID,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = attributes, .len = sizeof(psa_key_attributes_t)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = key, .len = sizeof(psa_key_id_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_mac_compute)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *mac,
+ size_t mac_size,
+ size_t *mac_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_MAC_COMPUTE_SID,
+ .key_id = key,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = mac, .len = mac_size},
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *mac_length = out_vec[0].len;
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_mac_verify)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *mac,
+ const size_t mac_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_MAC_VERIFY_SID,
+ .key_id = key,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ {.base = mac, .len = mac_length},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_encrypt)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_ENCRYPT_SID,
+ .key_id = key,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *output_length = out_vec[0].len;
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_cipher_decrypt)(psa_key_id_t key,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_CIPHER_DECRYPT_SID,
+ .key_id = key,
+ .alg = alg,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ };
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size}
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *output_length = out_vec[0].len;
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_raw_key_agreement)(psa_algorithm_t alg,
+ psa_key_id_t private_key,
+ const uint8_t *peer_key,
+ size_t peer_key_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t status;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_RAW_KEY_AGREEMENT_SID,
+ .alg = alg,
+ .key_id = private_key
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = peer_key, .len = peer_key_length},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = output, .len = output_size},
+ };
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *output_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_setup)(psa_key_derivation_operation_t *operation,
+ psa_algorithm_t alg)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_SETUP_SID,
+ .alg = alg,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_set_capacity)(
+ psa_key_derivation_operation_t *operation,
+ size_t capacity)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_SET_CAPACITY_SID,
+ .capacity = capacity,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_input_bytes)(
+ psa_key_derivation_operation_t *operation,
+ psa_key_derivation_step_t step,
+ const uint8_t *data,
+ size_t data_length)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_INPUT_BYTES_SID,
+ .step = step,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = data, .len = data_length},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_output_key)(
+ const psa_key_attributes_t *attributes,
+ psa_key_derivation_operation_t *operation,
+ psa_key_id_t *key)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_OUTPUT_KEY_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = attributes, .len = sizeof(psa_key_attributes_t)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = key, .len = sizeof(psa_key_id_t)}
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_setup)
+(psa_pake_operation_t *operation, psa_key_id_t password_key,
+ const psa_pake_cipher_suite_t *cipher_suite) {
+ struct tfm_crypto_pack_iovec iov = {.function_id = TFM_CRYPTO_PAKE_SETUP_SID,
+ .op_handle = operation->handle,
+ .key_id = password_key};
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = cipher_suite, .len = sizeof(psa_pake_cipher_suite_t)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_set_role)
+(psa_pake_operation_t *operation, psa_pake_role_t role) {
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PAKE_SET_ROLE_SID,
+ .op_handle = operation->handle,
+ .role = role,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_set_user)
+(psa_pake_operation_t *operation, const uint8_t *user_id, size_t user_id_len) {
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PAKE_SET_USER_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = user_id, .len = user_id_len},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_set_peer)
+(psa_pake_operation_t *operation, const uint8_t *peer_id, size_t peer_id_len) {
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PAKE_SET_PEER_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = peer_id, .len = peer_id_len},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_set_context)
+(psa_pake_operation_t *operation, const uint8_t *context, size_t context_len) {
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PAKE_SET_CONTEXT_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = context, .len = context_len},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_output)
+(psa_pake_operation_t *operation, psa_pake_step_t step, uint8_t *output,
+ size_t output_size, size_t *output_length) {
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PAKE_OUTPUT_SID,
+ .op_handle = operation->handle,
+ .step = step,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ psa_outvec out_vec[] = {{.base = output, .len = output_size}};
+
+ status = API_DISPATCH(in_vec, out_vec);
+
+ *output_length = out_vec[0].len;
+
+ return status;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_input)
+(psa_pake_operation_t *operation, psa_pake_step_t step, const uint8_t *input,
+ size_t input_length) {
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PAKE_INPUT_SID,
+ .op_handle = operation->handle,
+ .step = step,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = input, .len = input_length},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_get_shared_key)
+(psa_pake_operation_t *operation, const psa_key_attributes_t *attributes,
+ mbedtls_svc_key_id_t *key) {
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PAKE_GET_SHARED_KEY_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ {.base = attributes, .len = sizeof(psa_key_attributes_t)},
+ };
+
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ {.base = key, .len = sizeof(mbedtls_svc_key_id_t)}};
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_pake_abort)(psa_pake_operation_t *operation) {
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_PAKE_ABORT_SID,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+ psa_outvec out_vec[] = {
+ {.base = &(operation->handle), .len = sizeof(uint32_t)},
+ };
+
+ return API_DISPATCH(in_vec, out_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_input_integer)(
+ psa_key_derivation_operation_t *operation,
+ psa_key_derivation_step_t step,
+ uint64_t value)
+{
+ struct tfm_crypto_pack_iovec iov = {
+ .function_id = TFM_CRYPTO_KEY_DERIVATION_INPUT_INTEGER_SID,
+ .step = step,
+ .value = value,
+ .op_handle = operation->handle,
+ };
+
+ psa_invec in_vec[] = {
+ {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+ };
+
+ return API_DISPATCH_NO_OUTVEC(in_vec);
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_verify_bytes)(
+ psa_key_derivation_operation_t *operation,
+ const uint8_t *expected_output,
+ size_t output_length)
+{
+ /* To be implemented when the PSA backend supports it */
+ return PSA_ERROR_NOT_SUPPORTED;
+}
+
+TFM_CRYPTO_API(psa_status_t, psa_key_derivation_verify_key)(
+ psa_key_derivation_operation_t *operation,
+ psa_key_id_t expected)
+{
+ /* To be implemented when the PSA backend supports it */
+ return PSA_ERROR_NOT_SUPPORTED;
+}
diff --git a/nrfdemo/build/tfm/api_ns/interface/src/tfm_ioctl_core_ns_api.c b/nrfdemo/build/tfm/api_ns/interface/src/tfm_ioctl_core_ns_api.c
new file mode 100644
index 0000000..2370988
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/src/tfm_ioctl_core_ns_api.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2021 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "nrf.h"
+#include <stdint.h>
+#include <tfm_platform_api.h>
+#include <tfm_ioctl_core_api.h>
+
+enum tfm_platform_err_t tfm_platform_mem_read(void *destination, uint32_t addr,
+ size_t len, uint32_t *result)
+{
+ enum tfm_platform_err_t ret;
+ psa_invec in_vec;
+ psa_outvec out_vec;
+ struct tfm_read_service_args_t args;
+ struct tfm_read_service_out_t out;
+
+ in_vec.base = (const void *)&args;
+ in_vec.len = sizeof(args);
+
+ out_vec.base = (void *)&out;
+ out_vec.len = sizeof(out);
+
+ args.destination = destination;
+ args.addr = addr;
+ args.len = len;
+
+ ret = tfm_platform_ioctl(TFM_PLATFORM_IOCTL_READ_SERVICE, &in_vec,
+ &out_vec);
+
+ *result = out.result;
+
+ return ret;
+}
+
+enum tfm_platform_err_t tfm_platform_gpio_pin_mcu_select(uint32_t pin_number, uint32_t mcu,
+ uint32_t *result)
+{
+#if defined(GPIO_PIN_CNF_MCUSEL_Msk)
+ enum tfm_platform_err_t ret;
+ psa_invec in_vec;
+ psa_outvec out_vec;
+ struct tfm_gpio_service_args args;
+ struct tfm_gpio_service_out out;
+
+ args.type = TFM_GPIO_SERVICE_TYPE_PIN_MCU_SELECT;
+ args.mcu_select.pin_number = pin_number;
+ args.mcu_select.mcu = mcu;
+
+ in_vec.base = (const void *)&args;
+ in_vec.len = sizeof(args);
+
+ out_vec.base = (void *)&out;
+ out_vec.len = sizeof(out);
+
+ ret = tfm_platform_ioctl(TFM_PLATFORM_IOCTL_GPIO_SERVICE, &in_vec,
+ &out_vec);
+
+ *result = out.result;
+
+ return ret;
+#else
+ return TFM_PLATFORM_ERR_NOT_SUPPORTED;
+#endif
+}
diff --git a/nrfdemo/build/tfm/api_ns/interface/src/tfm_platform_api.c b/nrfdemo/build/tfm/api_ns/interface/src/tfm_platform_api.c
new file mode 100644
index 0000000..4fc564b
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/src/tfm_platform_api.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2019-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdbool.h>
+#include "tfm_platform_api.h"
+#include "psa/client.h"
+#include "psa_manifest/sid.h"
+
+enum tfm_platform_err_t tfm_platform_system_reset(void)
+{
+ psa_status_t status = PSA_ERROR_CONNECTION_REFUSED;
+
+ status = psa_call(TFM_PLATFORM_SERVICE_HANDLE,
+ TFM_PLATFORM_API_ID_SYSTEM_RESET,
+ NULL, 0, NULL, 0);
+
+ if (status < PSA_SUCCESS) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ } else {
+ return (enum tfm_platform_err_t)status;
+ }
+
+}
+
+enum tfm_platform_err_t
+tfm_platform_ioctl(tfm_platform_ioctl_req_t request,
+ psa_invec *input, psa_outvec *output)
+{
+ tfm_platform_ioctl_req_t req = request;
+ struct psa_invec in_vec[2] = { {0} };
+ size_t inlen, outlen;
+ psa_status_t status = PSA_ERROR_CONNECTION_REFUSED;
+
+ in_vec[0].base = &req;
+ in_vec[0].len = sizeof(req);
+ if (input != NULL) {
+ in_vec[1].base = input->base;
+ in_vec[1].len = input->len;
+ inlen = 2;
+ } else {
+ inlen = 1;
+ }
+
+ if (output != NULL) {
+ outlen = 1;
+ } else {
+ outlen = 0;
+ }
+
+ status = psa_call(TFM_PLATFORM_SERVICE_HANDLE,
+ TFM_PLATFORM_API_ID_IOCTL,
+ in_vec, inlen,
+ output, outlen);
+
+ if (status < PSA_SUCCESS) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ } else {
+ return (enum tfm_platform_err_t)status;
+ }
+}
+
+enum tfm_platform_err_t
+tfm_platform_nv_counter_increment(uint32_t counter_id)
+{
+ psa_status_t status = PSA_ERROR_CONNECTION_REFUSED;
+ struct psa_invec in_vec[1];
+
+ in_vec[0].base = &counter_id;
+ in_vec[0].len = sizeof(counter_id);
+
+ status = psa_call(TFM_PLATFORM_SERVICE_HANDLE,
+ TFM_PLATFORM_API_ID_NV_INCREMENT,
+ in_vec, 1, (psa_outvec *)NULL, 0);
+
+ if (status < PSA_SUCCESS) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ } else {
+ return (enum tfm_platform_err_t)status;
+ }
+}
+
+enum tfm_platform_err_t
+tfm_platform_nv_counter_read(uint32_t counter_id,
+ uint32_t size, uint8_t *val)
+{
+ psa_status_t status = PSA_ERROR_CONNECTION_REFUSED;
+ struct psa_invec in_vec[1];
+ struct psa_outvec out_vec[1];
+
+ in_vec[0].base = &counter_id;
+ in_vec[0].len = sizeof(counter_id);
+
+ out_vec[0].base = val;
+ out_vec[0].len = size;
+
+ status = psa_call(TFM_PLATFORM_SERVICE_HANDLE,
+ TFM_PLATFORM_API_ID_NV_READ,
+ in_vec, 1, out_vec, 1);
+
+ if (status < PSA_SUCCESS) {
+ return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+ } else {
+ return (enum tfm_platform_err_t)status;
+ }
+}
diff --git a/nrfdemo/build/tfm/api_ns/interface/src/tfm_tz_psa_ns_api.c b/nrfdemo/build/tfm/api_ns/interface/src/tfm_tz_psa_ns_api.c
new file mode 100644
index 0000000..1f9fbe4
--- /dev/null
+++ b/nrfdemo/build/tfm/api_ns/interface/src/tfm_tz_psa_ns_api.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "psa/client.h"
+#include "tfm_ns_interface.h"
+#include "tfm_psa_call_pack.h"
+
+/**** API functions ****/
+
+uint32_t psa_framework_version(void)
+{
+ return tfm_ns_interface_dispatch(
+ (veneer_fn)tfm_psa_framework_version_veneer,
+ 0,
+ 0,
+ 0,
+ 0);
+}
+
+uint32_t psa_version(uint32_t sid)
+{
+ return tfm_ns_interface_dispatch(
+ (veneer_fn)tfm_psa_version_veneer,
+ sid,
+ 0,
+ 0,
+ 0);
+}
+
+psa_status_t psa_call(psa_handle_t handle, int32_t type,
+ const psa_invec *in_vec,
+ size_t in_len,
+ psa_outvec *out_vec,
+ size_t out_len)
+{
+ if ((type > PSA_CALL_TYPE_MAX) ||
+ (type < PSA_CALL_TYPE_MIN) ||
+ (in_len > PSA_MAX_IOVEC) ||
+ (out_len > PSA_MAX_IOVEC)) {
+ return PSA_ERROR_PROGRAMMER_ERROR;
+ }
+
+ return tfm_ns_interface_dispatch(
+ (veneer_fn)tfm_psa_call_veneer,
+ (uint32_t)handle,
+ PARAM_PACK(type, in_len, out_len),
+ (uint32_t)in_vec,
+ (uint32_t)out_vec);
+}
+
+psa_handle_t psa_connect(uint32_t sid, uint32_t version)
+{
+ return tfm_ns_interface_dispatch((veneer_fn)tfm_psa_connect_veneer, sid, version, 0, 0);
+}
+
+void psa_close(psa_handle_t handle)
+{
+ (void)tfm_ns_interface_dispatch((veneer_fn)tfm_psa_close_veneer, (uint32_t)handle, 0, 0, 0);
+}