blob: 97ceb76df4bed8876f4b0343c30e1adf82b7abc1 [file] [log] [blame]
/*
* Copyright (c) 2023 EPAM Systems
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file drivers/tee.h
*
* @brief Public APIs for the tee driver.
*/
/*
* Copyright (c) 2015-2016, Linaro Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ZEPHYR_INCLUDE_DRIVERS_TEE_H_
#define ZEPHYR_INCLUDE_DRIVERS_TEE_H_
#include <zephyr/device.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/util.h>
/**
* @brief Trusted Execution Environment Interface
* @defgroup tee_interface TEE Interface
* @ingroup io_interfaces
* @{
*
* The generic interface to work with Trusted Execution Environment (TEE).
* TEE is Trusted OS, running in the Secure Space, such as TrustZone in ARM cpus.
* It also can be presented as the separate secure co-processors. It allows system
* to implement logic, separated from the Normal World.
*
* Using TEE syscalls:
* - tee_get_version() to get current TEE capabilities
* - tee_open_session() to open new session to the TA
* - tee_close_session() to close session to the TA
* - tee_cancel() to cancel session or invoke function
* - tee_invoke_func() to invoke function to the TA
* - tee_shm_register() to register shared memory region
* - tee_shm_unregister() to unregister shared memory region
* - tee_shm_alloc() to allocate shared memory region
* - tee_shm_free() to free shared memory region
*/
#ifdef __cplusplus
extern "C" {
#endif
#define TEE_UUID_LEN 16
#define TEE_GEN_CAP_GP BIT(0) /* GlobalPlatform compliant TEE */
#define TEE_GEN_CAP_PRIVILEGED BIT(1) /* Privileged device (for supplicant) */
#define TEE_GEN_CAP_REG_MEM BIT(2) /* Supports registering shared memory */
#define TEE_GEN_CAP_MEMREF_NULL BIT(3) /* Support NULL MemRef */
#define TEE_SHM_REGISTER BIT(0)
#define TEE_SHM_ALLOC BIT(1)
#define TEE_PARAM_ATTR_TYPE_NONE 0 /* parameter not used */
#define TEE_PARAM_ATTR_TYPE_VALUE_INPUT 1
#define TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT 2
#define TEE_PARAM_ATTR_TYPE_VALUE_INOUT 3 /* input and output */
#define TEE_PARAM_ATTR_TYPE_MEMREF_INPUT 5
#define TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT 6
#define TEE_PARAM_ATTR_TYPE_MEMREF_INOUT 7 /* input and output */
#define TEE_PARAM_ATTR_TYPE_MASK 0xff
#define TEE_PARAM_ATTR_META 0x100
#define TEE_PARAM_ATTR_MASK (TEE_PARAM_ATTR_TYPE_MASK | TEE_PARAM_ATTR_META)
/**
* @brief Function error origins, of type TEEC_ErrorOrigin. These indicate where in
* the software stack a particular return value originates from.
*
* TEEC_ORIGIN_API The error originated within the TEE Client API
* implementation.
* TEEC_ORIGIN_COMMS The error originated within the underlying
* communications stack linking the rich OS with
* the TEE.
* TEEC_ORIGIN_TEE The error originated within the common TEE code.
* TEEC_ORIGIN_TRUSTED_APP The error originated within the Trusted Application
* code.
*/
#define TEEC_ORIGIN_API 0x00000001
#define TEEC_ORIGIN_COMMS 0x00000002
#define TEEC_ORIGIN_TEE 0x00000003
#define TEEC_ORIGIN_TRUSTED_APP 0x00000004
/**
* Return values. Type is TEEC_Result
*
* TEEC_SUCCESS The operation was successful.
* TEEC_ERROR_GENERIC Non-specific cause.
* TEEC_ERROR_ACCESS_DENIED Access privileges are not sufficient.
* TEEC_ERROR_CANCEL The operation was canceled.
* TEEC_ERROR_ACCESS_CONFLICT Concurrent accesses caused conflict.
* TEEC_ERROR_EXCESS_DATA Too much data for the requested operation was
* passed.
* TEEC_ERROR_BAD_FORMAT Input data was of invalid format.
* TEEC_ERROR_BAD_PARAMETERS Input parameters were invalid.
* TEEC_ERROR_BAD_STATE Operation is not valid in the current state.
* TEEC_ERROR_ITEM_NOT_FOUND The requested data item is not found.
* TEEC_ERROR_NOT_IMPLEMENTED The requested operation should exist but is not
* yet implemented.
* TEEC_ERROR_NOT_SUPPORTED The requested operation is valid but is not
* supported in this implementation.
* TEEC_ERROR_NO_DATA Expected data was missing.
* TEEC_ERROR_OUT_OF_MEMORY System ran out of resources.
* TEEC_ERROR_BUSY The system is busy working on something else.
* TEEC_ERROR_COMMUNICATION Communication with a remote party failed.
* TEEC_ERROR_SECURITY A security fault was detected.
* TEEC_ERROR_SHORT_BUFFER The supplied buffer is too short for the
* generated output.
* TEEC_ERROR_TARGET_DEAD Trusted Application has panicked
* during the operation.
*/
/**
* Standard defined error codes.
*/
#define TEEC_SUCCESS 0x00000000
#define TEEC_ERROR_STORAGE_NOT_AVAILABLE 0xF0100003
#define TEEC_ERROR_GENERIC 0xFFFF0000
#define TEEC_ERROR_ACCESS_DENIED 0xFFFF0001
#define TEEC_ERROR_CANCEL 0xFFFF0002
#define TEEC_ERROR_ACCESS_CONFLICT 0xFFFF0003
#define TEEC_ERROR_EXCESS_DATA 0xFFFF0004
#define TEEC_ERROR_BAD_FORMAT 0xFFFF0005
#define TEEC_ERROR_BAD_PARAMETERS 0xFFFF0006
#define TEEC_ERROR_BAD_STATE 0xFFFF0007
#define TEEC_ERROR_ITEM_NOT_FOUND 0xFFFF0008
#define TEEC_ERROR_NOT_IMPLEMENTED 0xFFFF0009
#define TEEC_ERROR_NOT_SUPPORTED 0xFFFF000A
#define TEEC_ERROR_NO_DATA 0xFFFF000B
#define TEEC_ERROR_OUT_OF_MEMORY 0xFFFF000C
#define TEEC_ERROR_BUSY 0xFFFF000D
#define TEEC_ERROR_COMMUNICATION 0xFFFF000E
#define TEEC_ERROR_SECURITY 0xFFFF000F
#define TEEC_ERROR_SHORT_BUFFER 0xFFFF0010
#define TEEC_ERROR_EXTERNAL_CANCEL 0xFFFF0011
#define TEEC_ERROR_TARGET_DEAD 0xFFFF3024
#define TEEC_ERROR_STORAGE_NO_SPACE 0xFFFF3041
/**
* Session login methods, for use in tee_open_session() as parameter
* connectionMethod. Type is uint32_t.
*
* TEEC_LOGIN_PUBLIC No login data is provided.
* TEEC_LOGIN_USER Login data about the user running the Client
* Application process is provided.
* TEEC_LOGIN_GROUP Login data about the group running the Client
* Application process is provided.
* TEEC_LOGIN_APPLICATION Login data about the running Client Application
* itself is provided.
* TEEC_LOGIN_USER_APPLICATION Login data about the user and the running
* Client Application itself is provided.
* TEEC_LOGIN_GROUP_APPLICATION Login data about the group and the running
* Client Application itself is provided.
*/
#define TEEC_LOGIN_PUBLIC 0x00000000
#define TEEC_LOGIN_USER 0x00000001
#define TEEC_LOGIN_GROUP 0x00000002
#define TEEC_LOGIN_APPLICATION 0x00000004
#define TEEC_LOGIN_USER_APPLICATION 0x00000005
#define TEEC_LOGIN_GROUP_APPLICATION 0x00000006
/**
* @brief TEE version
*
* Identifies the TEE implementation,@ref impl_id is one of TEE_IMPL_ID_* above.
* @ref impl_caps is implementation specific, for example TEE_OPTEE_CAP_*
* is valid when @ref impl_id == TEE_IMPL_ID_OPTEE.
*/
struct tee_version_info {
uint32_t impl_id; /**< [out] TEE implementation id */
uint32_t impl_caps; /**< [out] implementation specific capabilities */
uint32_t gen_caps; /**< Generic capabilities, defined by TEE_GEN_CAPS_* above */
};
/**
* @brief - Open session argument
*/
struct tee_open_session_arg {
uint8_t uuid[TEE_UUID_LEN]; /**< [in] UUID of the Trusted Application */
uint8_t clnt_uuid[TEE_UUID_LEN]; /**< [in] UUID of client */
uint32_t clnt_login; /**< login class of client, TEE_IOCTL_LOGIN_* above */
uint32_t cancel_id; /**< [in] cancellation id, a unique value to identify this request */
uint32_t session; /**< [out] session id */
uint32_t ret; /**< [out] return value */
uint32_t ret_origin; /**< [out] origin of the return value */
};
/**
* @brief Tee parameter
*
* @ref attr & TEE_PARAM_ATTR_TYPE_MASK indicates if memref or value is used in
* the union. TEE_PARAM_ATTR_TYPE_VALUE_* indicates value and
* TEE_PARAM_ATTR_TYPE_MEMREF_* indicates memref. TEE_PARAM_ATTR_TYPE_NONE
* indicates that none of the members are used.
*
* Shared memory is allocated with TEE_IOC_SHM_ALLOC which returns an
* identifier representing the shared memory object. A memref can reference
* a part of a shared memory by specifying an offset (@ref a) and size (@ref b) of
* the object. To supply the entire shared memory object set the offset
* (@ref a) to 0 and size (@ref b) to the previously returned size of the object.
*/
struct tee_param {
uint64_t attr; /**< attributes */
uint64_t a; /**< if a memref, offset into the shared memory object, else a value*/
uint64_t b; /**< if a memref, size of the buffer, else a value parameter */
uint64_t c; /**< if a memref, shared memory identifier, else a value parameter */
};
/**
* @brief Invokes a function in a Trusted Application
*/
struct tee_invoke_func_arg {
uint32_t func; /**< [in] Trusted Application function, specific to the TA */
uint32_t session; /**< [in] session id */
uint32_t cancel_id; /**< [in] cancellation id, a unique value to identify this request */
uint32_t ret; /**< [out] return value */
uint32_t ret_origin; /**< [out] origin of the return value */
};
/**
* @brief Tee shared memory structure
*/
struct tee_shm {
const struct device *dev; /**< [out] pointer to the device driver structure */
void *addr; /**< [out] shared buffer pointer */
uint64_t size; /**< [out] shared buffer size */
uint32_t flags; /**< [out] shared buffer flags */
};
/**
* @typedef tee_get_version_t
*
* @brief Callback API to get current tee version
*
* See @a tee_version_get() for argument definitions.
*/
typedef int (*tee_get_version_t)(const struct device *dev, struct tee_version_info *info);
/**
* @typedef tee_open_session_t
*
* @brief Callback API to open session to Trusted Application
*
* See @a tee_open_session() for argument definitions.
*/
typedef int (*tee_open_session_t)(const struct device *dev, struct tee_open_session_arg *arg,
unsigned int num_param, struct tee_param *param,
uint32_t *session_id);
/**
* @typedef tee_close_session_t
*
* @brief Callback API to close session to TA
*
* See @a tee_close_session() for argument definitions.
*/
typedef int (*tee_close_session_t)(const struct device *dev, uint32_t session_id);
/**
* @typedef tee_cancel_t
*
* @brief Callback API to cancel open session of invoke function to TA
*
* See @a tee_cancel() for argument definitions.
*/
typedef int (*tee_cancel_t)(const struct device *dev, uint32_t session_id, uint32_t cancel_id);
/**
* @typedef tee_invoke_func_t
*
* @brief Callback API to invoke function to TA
*
* See @a tee_invoke_func() for argument definitions.
*/
typedef int (*tee_invoke_func_t)(const struct device *dev, struct tee_invoke_func_arg *arg,
unsigned int num_param, struct tee_param *param);
/**
* @typedef tee_shm_register_t
*
* @brief Callback API to register shared memory
*
* See @a tee_shm_register() for argument definitions.
*/
typedef int (*tee_shm_register_t)(const struct device *dev, struct tee_shm *shm);
/**
* @typedef tee_shm_unregister_t
*
* @brief Callback API to unregister shared memory
*
* See @a tee_shm_unregister() for argument definitions.
*/
typedef int (*tee_shm_unregister_t)(const struct device *dev, struct tee_shm *shm);
/**
* @typedef tee_suppl_recv_t
*
* @brief Callback API to receive a request for TEE supplicant
*
* See @a tee_suppl_recv() for argument definitions.
*/
typedef int (*tee_suppl_recv_t)(const struct device *dev, uint32_t *func, unsigned int *num_params,
struct tee_param *param);
/**
* @typedef tee_suppl_send_t
*
* @brief Callback API to send a request for TEE supplicant
*
* See @a tee_suppl_send() for argument definitions.
*/
typedef int (*tee_suppl_send_t)(const struct device *dev, unsigned int ret, unsigned int num_params,
struct tee_param *param);
__subsystem struct tee_driver_api {
tee_get_version_t get_version;
tee_open_session_t open_session;
tee_close_session_t close_session;
tee_cancel_t cancel;
tee_invoke_func_t invoke_func;
tee_shm_register_t shm_register;
tee_shm_unregister_t shm_unregister;
tee_suppl_recv_t suppl_recv;
tee_suppl_send_t suppl_send;
};
/**
* @brief Get the current TEE version info
*
* Returns info as tee version info which includes capabilities description
*
* @param dev TEE device
* @param info Structure to return the capabilities
*
* @retval -ENOSYS If callback was not implemented
*
* @retval 0 On success, negative on error
*/
__syscall int tee_get_version(const struct device *dev, struct tee_version_info *info);
static inline int z_impl_tee_get_version(const struct device *dev, struct tee_version_info *info)
{
const struct tee_driver_api *api = (const struct tee_driver_api *)dev->api;
if (!api->get_version) {
return -ENOSYS;
}
return api->get_version(dev, info);
}
/**
* @brief Open session for Trusted Environment
*
* Opens the new session to the Trusted Environment
*
* @param dev TEE device
* @param arg Structure with the session arguments
* @param num_param Number of the additional params to be passed
* @param param List of the params to pass to open_session call
* @param session_id Returns id of the created session
*
* @retval -ENOSYS If callback was not implemented
*
* @retval 0 On success, negative on error
*/
__syscall int tee_open_session(const struct device *dev, struct tee_open_session_arg *arg,
unsigned int num_param, struct tee_param *param,
uint32_t *session_id);
static inline int z_impl_tee_open_session(const struct device *dev,
struct tee_open_session_arg *arg,
unsigned int num_param, struct tee_param *param,
uint32_t *session_id)
{
const struct tee_driver_api *api = (const struct tee_driver_api *)dev->api;
if (!api->open_session) {
return -ENOSYS;
}
return api->open_session(dev, arg, num_param, param, session_id);
}
/**
* @brief Close session for Trusted Environment
*
* Closes session to the Trusted Environment
*
* @param dev TEE device
* @param session_id session to close
*
* @retval -ENOSYS If callback was not implemented
*
* @retval 0 On success, negative on error
*/
__syscall int tee_close_session(const struct device *dev, uint32_t session_id);
static inline int z_impl_tee_close_session(const struct device *dev, uint32_t session_id)
{
const struct tee_driver_api *api = (const struct tee_driver_api *)dev->api;
if (!api->close_session) {
return -ENOSYS;
}
return api->close_session(dev, session_id);
}
/**
* @brief Cancel session or invoke function for Trusted Environment
*
* Cancels session or invoke function for TA
*
* @param dev TEE device
* @param session_id session to close
* @param cancel_id cancel reason
*
* @retval -ENOSYS If callback was not implemented
*
* @retval 0 On success, negative on error
*/
__syscall int tee_cancel(const struct device *dev, uint32_t session_id, uint32_t cancel_id);
static inline int z_impl_tee_cancel(const struct device *dev, uint32_t session_id,
uint32_t cancel_id)
{
const struct tee_driver_api *api = (const struct tee_driver_api *)dev->api;
if (!api->cancel) {
return -ENOSYS;
}
return api->cancel(dev, session_id, cancel_id);
}
/**
* @brief Invoke function for Trusted Environment Application
*
* Invokes function to the TA
*
* @param dev TEE device
* @param arg Structure with the invoke function arguments
* @param num_param Number of the additional params to be passed
* @param param List of the params to pass to open_session call
*
* @retval -ENOSYS If callback was not implemented
*
* @retval 0 On success, negative on error
*/
__syscall int tee_invoke_func(const struct device *dev, struct tee_invoke_func_arg *arg,
unsigned int num_param, struct tee_param *param);
static inline int z_impl_tee_invoke_func(const struct device *dev, struct tee_invoke_func_arg *arg,
unsigned int num_param, struct tee_param *param)
{
const struct tee_driver_api *api = (const struct tee_driver_api *)dev->api;
if (!api->invoke_func) {
return -ENOSYS;
}
return api->invoke_func(dev, arg, num_param, param);
}
/**
* @brief Helper function to allocate and register shared memory
*
* Allocates and registers shared memory for TEE
*
* @param dev TEE device
* @param addr Address of the shared memory
* @param align Region alignment
* @param size Size of the shared memory region
* @param flags Flags to set registering parameters
* @param shmp Return shared memory structure
*
* @retval 0 On success, negative on error
*/
int tee_add_shm(const struct device *dev, void *addr, size_t align, size_t size, uint32_t flags,
struct tee_shm **shmp);
/**
* @brief Helper function to remove and unregister shared memory
*
* Removes and unregisters shared memory for TEE
*
* @param dev TEE device
* @param shm Pointer to tee_shm structure
*
* @retval 0 On success, negative on error
*/
int tee_rm_shm(const struct device *dev, struct tee_shm *shm);
/**
* @brief Register shared memory for Trusted Environment
*
* Registers shared memory for TEE
*
* @param dev TEE device
* @param addr Address of the shared memory
* @param size Size of the shared memory region
* @param flags Flags to set registering parameters
* @param shm Return shared memory structure
*
* @retval -ENOSYS If callback was not implemented
*
* @retval 0 On success, negative on error
*/
__syscall int tee_shm_register(const struct device *dev, void *addr, size_t size,
uint32_t flags, struct tee_shm **shm);
static inline int z_impl_tee_shm_register(const struct device *dev, void *addr, size_t size,
uint32_t flags, struct tee_shm **shm)
{
flags &= ~TEE_SHM_ALLOC;
return tee_add_shm(dev, addr, 0, size, flags | TEE_SHM_REGISTER, shm);
}
/**
* @brief Unregister shared memory for Trusted Environment
*
* Unregisters shared memory for TEE
*
* @param dev TEE device
* @param shm Shared memory structure
*
* @retval -ENOSYS If callback was not implemented
*
* @retval 0 On success, negative on error
*/
__syscall int tee_shm_unregister(const struct device *dev, struct tee_shm *shm);
static inline int z_impl_tee_shm_unregister(const struct device *dev, struct tee_shm *shm)
{
return tee_rm_shm(dev, shm);
}
/**
* @brief Allocate shared memory region for Trusted Environment
*
* Allocate shared memory for TEE
*
* @param dev TEE device
* @param size Region size
* @param flags to allocate region
* @param shm Return shared memory structure
*
* @retval -ENOSYS If callback was not implemented
*
* @retval 0 On success, negative on error
*/
__syscall int tee_shm_alloc(const struct device *dev, size_t size, uint32_t flags,
struct tee_shm **shm);
static inline int z_impl_tee_shm_alloc(const struct device *dev, size_t size, uint32_t flags,
struct tee_shm **shm)
{
return tee_add_shm(dev, NULL, 0, size, flags | TEE_SHM_ALLOC | TEE_SHM_REGISTER, shm);
}
/**
* @brief Free shared memory region for Trusted Environment
*
* Frees shared memory for TEE
*
* @param dev TEE device
* @param shm Shared memory structure
*
* @retval -ENOSYS If callback was not implemented
*
* @retval 0 On success, negative on error
*/
__syscall int tee_shm_free(const struct device *dev, struct tee_shm *shm);
static inline int z_impl_tee_shm_free(const struct device *dev, struct tee_shm *shm)
{
return tee_rm_shm(dev, shm);
}
/**
* @brief Receive a request for TEE Supplicant
*
* @param dev TEE device
* @param func Supplicant function
* @param num_params Number of parameters to be passed
* @param param List of the params for send/receive
*
* @retval -ENOSYS If callback was not implemented
*
* @retval 0 On success, negative on error
*/
__syscall int tee_suppl_recv(const struct device *dev, uint32_t *func, unsigned int *num_params,
struct tee_param *param);
static inline int z_impl_tee_suppl_recv(const struct device *dev, uint32_t *func,
unsigned int *num_params, struct tee_param *param)
{
const struct tee_driver_api *api = (const struct tee_driver_api *)dev->api;
if (!api->suppl_recv) {
return -ENOSYS;
}
return api->suppl_recv(dev, func, num_params, param);
}
/**
* @brief Send a request for TEE Supplicant function
*
* @param dev TEE device
* @param ret supplicant return code
* @param num_params Number of parameters to be passed
* @param param List of the params for send/receive
*
* @retval -ENOSYS If callback was not implemented
* @retval Return value for sent request
*
* @retval 0 On success, negative on error
*/
__syscall int tee_suppl_send(const struct device *dev, unsigned int ret, unsigned int num_params,
struct tee_param *param);
static inline int z_impl_tee_suppl_send(const struct device *dev, unsigned int ret,
unsigned int num_params, struct tee_param *param)
{
const struct tee_driver_api *api = (const struct tee_driver_api *)dev->api;
if (!api->suppl_send) {
return -ENOSYS;
}
return api->suppl_send(dev, ret, num_params, param);
}
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#include <zephyr/syscalls/tee.h>
#endif /* ZEPHYR_INCLUDE_DRIVERS_TEE_H_ */