OPTEE
Amit Nadiger
Polyglot(Rust??, Move, C++, C, Kotlin, Java) Blockchain, Polkadot, UTXO, Substrate, Sui, Aptos, Wasm, Proxy-wasm,AndroidTV, Dvb, STB, Linux, Cas, Engineering management.
OP-TEE
OP-TEE, or Open Portable Trusted Execution Environment, is a software framework that provides a secure execution environment for running sensitive code on modern embedded systems. It is an open-source implementation of the Global Platform Trusted Execution Environment (TEE) specification and is designed to be highly portable, flexible, and configurable.
OP-TEE is a software-based Trusted Execution Environment (TEE). It runs as a normal application on a hardware platform and provides a secure execution environment that is isolated from the normal operating system and applications running on the platform.
OP-TEE leverages the hardware security features of the underlying hardware platform, such as secure boot, secure storage, and secure interconnects, to create a trusted execution environment. However, the actual implementation of the TEE is done entirely in software, using a combination of secure operating system components, secure libraries, and trusted applications.
OP-TEE is designed to be highly portable and can run on a wide range of hardware platforms. This makes it a flexible and versatile solution for building secure systems on a variety of embedded and mobile devices.
OP-TEE provides a secure environment where sensitive code can run without interference from other software on the system. This makes it an ideal solution for a wide range of applications, including mobile devices, IoT devices, and other embedded systems that require a high level of security.
The architecture of OP-TEE consists of two main components: the normal world (REE) and the secure world (TEE). The normal world is the non-secure environment in which the operating system and applications run, while the secure world is a separate, isolated environment that provides a trusted execution environment for sensitive code. The two worlds communicate via a set of interfaces defined by the TEE specification, which provide a secure way for the normal world to communicate with the secure world.
The secure world in OP-TEE is implemented using ARM TrustZone technology, which provides hardware-based isolation between the normal world and the secure world. This ensures that sensitive code can run in a protected environment, isolated from the rest of the system.
OP-TEE provides a range of security features that help to ensure the integrity and confidentiality of sensitive code and data. These features include secure boot, secure storage, secure communication, and secure key management. The secure boot process ensures that only trusted code can be loaded into the secure world, while secure storage provides a protected area for storing sensitive data. Secure communication ensures that data is transmitted securely between the normal world and the secure world, while secure key management provides a secure way to manage cryptographic keys.
OP-TEE is highly flexible and configurable, allowing developers to customize the software to meet their specific needs. It supports a wide range of hardware platforms and can be customized to support different use cases and security requirements. Additionally, OP-TEE is designed to be easily integrated into existing software stacks, making it a versatile and convenient solution for developers.
In conclusion, OP-TEE is a powerful and flexible software framework that provides a secure execution environment for running sensitive code on modern embedded systems. It offers a wide range of security features and is highly configurable, making it an ideal solution for a wide range of applications. With its open-source implementation of the GlobalPlatform TEE specification and its support for a wide range of hardware platforms, OP-TEE is an excellent choice for developers looking for a trusted execution environment for their embedded systems.
OP-TEE is a software framework that provides a Trusted Execution Environment (TEE) for running trusted applications on modern embedded systems. A trusted application is an application that is designed to run within the TEE and provides a secure execution environment for sensitive code. A client application is an application that runs in the normal world, outside the TEE, and communicates with the trusted application to perform secure operations. OP-TEE OS is the operating system that provides the infrastructure for the TEE and manages the execution of trusted applications.
The communication flow between the client application and the trusted application in OP-TEE typically happens through a set of APIs (Application Programming Interfaces) that are provided by the TEE. These APIs allow the client application to securely communicate with the trusted application and perform operations that require a high level of security.
Let's take an example of a secure payment system to understand how the communication flow works between the client application and the trusted application in OP-TEE.
In this example, the client application is a mobile payment application that runs on a smartphone, while the trusted application is a payment processing application that runs in the TEE of the smartphone. The payment processing application is responsible for performing the cryptographic operations required for secure payment processing, such as generating and verifying digital signatures, and managing the storage of cryptographic keys.
The communication flow between the client application and the trusted application in this example typically happens as follows:
By using OP-TEE to run the payment processing application in the TEE, the payment system is more secure and less vulnerable to attacks, such as malware or other software exploits. Additionally, by using the TEE APIs to communicate between the client application and the trusted application, the system is protected from eavesdropping or other types of attacks that could compromise the security of the transaction.
In summary, OP-TEE provides a secure environment for running trusted applications that can be accessed by client applications through a set of APIs. By using OP-TEE to run trusted applications, developers can create more secure and trustworthy systems for sensitive applications, such as mobile payments, digital wallets, and other applications that require a high level of security.
Here are the step-by-step instructions for a client application (CA) to communicate with a trusted application (TA) running inside a TEE:
TEEC_Context teec_ctx;
TEEC_Result teec_res;
teec_res = TEEC_InitializeContext(NULL, &teec_ctx);
if (teec_res != TEEC_SUCCESS) {
// handle error
}
2. Open a session with the TA: After the TEE context has been initialized, the CA can open a session with the TA by calling TEEC_OpenSession. This step allows the CA to communicate with the TA and execute its functions. This function takes the TA's UUID as a parameter and returns a session ID that can be used to communicate with the TA.
TEEC_Session teec_sess;
TEEC_UUID ta_uuid = {0x01234567, 0x89ab, 0xcdef, {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}};
teec_res = TEEC_OpenSession(&teec_ctx, &teec_sess, &ta_uuid, TEEC_LOGIN_PUBLIC, NULL, NULL, NULL);
if (teec_res != TEEC_SUCCESS) {
// handle error
}
3. Prepare the command parameters: Once the session with the TA has been established, the CA needs to prepare the command parameters that will be passed to the TA function. This involves creating a TEEC_Operation struct and populating it with the appropriate values. These parameters can include input data, output data, and other parameters required by the TA function.
TEEC_Operation teec_op;
memset(&teec_op, 0, sizeof(teec_op));
teec_op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INPUT, TEEC_VALUE_OUTPUT, TEEC_NONE);
teec_op.params[0].value.a = num1;
teec_op.params[1].value.a = num2;
In this example, the TEEC_Operation struct is initialized with the input and output parameter types, and the input parameters (num1 and num2) are set to the appropriate values.
4. Invoke the TA function: Once the command parameters have been prepared, the CA can invoke the TA function by calling TEEC_InvokeCommand. This function takes the session ID, command ID (which is typically 0), the TEEC_Operation struct, and a TEEC_TempMemoryReference struct (which can be set to NULL in this case).
TEEC_InvokeCommand() is a synchronous function in the TEE Client API. It blocks until the execution of the command in the Trusted Application is complete and a response is returned.
However, there is an asynchronous version of this function called TEEC_InvokeCommandAsync(). This function allows the client application to execute a command in the Trusted Application asynchronously, meaning that the function returns immediately without waiting for the command to complete. The client application can then poll for the completion status of the command using the TEEC_Wait() function.
The use of synchronous or asynchronous function depends on the specific requirements of the client application. If the client application can tolerate blocking while waiting for a response, it can use the synchronous function. On the other hand, if the client application needs to perform other tasks while waiting for a response, it can use the asynchronous function.
teec_res = TEEC_InvokeCommand(&teec_sess, 0, &teec_op, NULL);
if (teec_res != TEEC_SUCCESS) {
// handle error
}
5. Process the output: After the TA function has been invoked. The TEE executes the TA function and returns the result to the CA. the output parameters are stored in the TEEC_Operation struct. The CA can read these values and use them as needed.
*result = teec_op.params[2].value.a;
6. Close the session: Once the communication with the TA is complete, the CA should close the session with TA by calling TEEC_CloseSession.This step is important to ensure that system resources are properly released and to prevent any potential security vulnerabilities.
TEEC_CloseSession(&teec_sess);
7. Finalize the TEE context: Finally, the CA should call TEEC_FinalizeContext to clean up the TEE Client API resources i.e destroy or release any resources allocated by the TEE. This step ensures that the TEE context is properly closed and that no resources are left open.
TEEC_FinalizeContext(&tee_ctx);
Here is an example code snippet that demonstrates how to create a Trusted Application (TA), a Client Application (CA), and how they communicate with each other through the OP-TEE OS:
By following these steps, the CA can securely communicate with the TA and execute its functions in the TEE.
It is important to note that the exact implementation of these steps can vary depending on the specific TEE and programming language used. For example, some TEEs may have additional steps or require different parameter formats. It is important to consult the specific TEE documentation and programming guides for accurate implementation details.
Here are the API definitions for TEEC_InvokeCommandAsync() and TEEC_Wait() in the TEE Client API:
TEEC_Result TEEC_InvokeCommandAsync(TEEC_Session* session, uint32_t commandID, uint32_t paramTypes, TEEC_Operation* operation, uintptr_t userData);
This function is used to invoke a command in a Trusted Application asynchronously. The session parameter specifies the session handle to use, commandID specifies the ID of the command to execute, paramTypes specifies the types of the parameters used in the command, operation specifies the data buffer and length used in the command, and userData is a user-defined value that is passed to the completion callback function. This function returns a TEEC_Result value that indicates whether the command was successfully scheduled for execution.
TEEC_Result TEEC_Wait(TEEC_Context* context, TEEC_Operation* operation, uintptr_t timeout);
This function is used to wait for an asynchronous command to complete. The context parameter specifies the context handle to use, operation specifies the data buffer and length used in the command, and timeout specifies the maximum time to wait for the command to complete in milliseconds. This function returns a TEEC_Result value that indicates whether the command completed successfully within the specified timeout.
In addition to TEEC_InvokeCommandAsync() and TEEC_Wait(), the TEE Client API also provides other functions for asynchronous operations, such as:
These functions provide the client application with the flexibility to perform asynchronous operations and manage shared memory between the client application and the Trusted Application.
Trusted Application (TA) code:
There are standard functions of the Trusted Application Framework (TA Framework) that are provided by the TEE implementation.
The TEE provides an environment for executing TAs securely and isolating them from the normal world. When a TA is loaded into the TEE, it registers entry points with the TEE using these APIs. Then, when a normal world application wants to invoke a service provided by the TA, it makes a TEE Client API call to the TEE. The TEE then forwards this call to the appropriate TA entry point, which executes the requested service securely within the TEE.
For example, TA_CreateEntryPoint is a function that is called when a TA is first loaded into memory, and it is responsible for initializing the TA's data structures and setting up any required resources. Similarly, TA_DestroyEntryPoint is called when the TA is unloaded, and it is responsible for cleaning up any resources that were allocated by the TA.
Other standard functions include TA_OpenSessionEntryPoint, which is called when a client opens a session with the TA, and TA_CloseSessionEntryPoint, which is called when the session is closed. These functions provide a standard way for clients to interact with the TA and for the TA to manage its resources.
The specific names and functionality of these functions may vary slightly depending on the TEE implementation, but the overall concept of a TA Framework with standard functions for creating, initializing, and destroying TAs is common across many TEEs.
Here are some of the important ones:
1.TA_CreateEntryPoint: =>
TEE_Result TA_CreateEntryPoint(void)
This function is called when the TA is loaded into memory for the first time. It is used to initialize the TA and set up any data structures or resources that it requires. The function takes a single parameter, which is a pointer to the TA context structure.
2. TA_DestroyEntryPoint:
void TA_DestroyEntryPoint(void )
This function is called when the TA is unloaded from memory. It is used to free any resources that were allocated by the TA during its lifetime. The function takes a single parameter, which is a pointer to the TA context structure.
3. TA_OpenSessionEntryPoint:
TEE_Result TA_OpenSessionEntryPoint(uint32_t nParamTypes, TEE_Param pParams[4], void **ppSessionContext )
This function is called when a client application requests to open a session with the TA. It is used to set up any session-specific data structures or resources that the TA requires. The function takes three parameters: a pointer to the TA context structure, a parameter buffer containing any parameters that were passed by the client application, and the size of the parameter buffer.
4. TA_CloseSessionEntryPoint:
void TA_CloseSessionEntryPoint(void *pSessionContext )
This function is called when a client application closes a session with the TA. It is used to free any resources that were allocated by the TA during the lifetime of the session. The function takes two parameters: a pointer to the TA context structure, and a session ID that identifies the session to be closed.
5. TA_InvokeCommandEntryPoint:
TEE_Result TA_InvokeCommandEntryPoint(void *pSessionContext, uint32_t nCommandID, uint32_t nParamTypes, TEE_Param pParams[4] )
This function is called when a client application sends a command to the TA. It is used to perform the requested operation and return any results to the client. The function takes four parameters: a pointer to the TA context structure, a session ID that identifies the session in which the command was sent, a command ID that identifies the command, and a parameter buffer containing any parameters that were passed by the client application.
领英推荐
6. TA_ExportEntryPoint:
TEEC_Result TA_ExportEntryPoint(uint32_t type
void *buf,
uint32_t *len); ,
This function exports the public key of the entry point of the trusted application to a buffer. This public key can be used by other trusted applications to authenticate and establish secure communication with the trusted application. The type parameter specifies the format of the exported key (e.g. raw binary, X.509 certificate), buf is the buffer to store the exported key, and len is a pointer to the size of the buffer. The function returns a TEEC_Result status code.
7. TA_GetEntryPointUUID:
void TA_GetEntryPointUUID(TEEC_UUID *uuid) ;
This function retrieves the UUID of the trusted application's entry point. The uuid parameter is a pointer to a TEEC_UUID structure that will be filled with the UUID. This function does not return a value.
8. TA_GetInstanceUUID:
void TA_GetInstanceUUID(TEEC_UUID *uuid) ;
This function retrieves the UUID of the currently running instance of the trusted application. The uuid parameter is a pointer to a TEEC_UUID structure that will be filled with the UUID. This function does not return a value.
These are some of the standard functions that are part of the TA Framework and provided by the TEE implementation. The parameters and use of each function may vary based on the specific implementation of the TEE.
#include <tee_internal_api.h>
#include <tee_internal_api_extensions.h>
// TA function to add two numbers
TEE_Result TA_AddNumbers(uint32_t param_types, TEE_Param params[4]) {
uint32_t exp_param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
TEE_PARAM_TYPE_VALUE_INPUT,
TEE_PARAM_TYPE_VALUE_OUTPUT,
TEE_PARAM_TYPE_NONE);
if (param_types != exp_param_types) {
return TEE_ERROR_BAD_PARAMETERS;
}
// Add the two input numbers
uint32_t sum = params[0].value.a + params[1].value.a;
// Set the output parameter
params[2].value.a = sum;
return TEE_SUCCESS;
}
// TA entry point
TEE_Result TA_CreateEntryPoint(void) {
return TEE_SUCCESS;
}
void TA_DestroyEntryPoint(void) {
return;
}
TEE_Result TA_OpenSessionEntryPoint(uint32_t param_types,
TEE_Param params[4],
void **sess_ctx) {
return TEE_SUCCESS;
}
void TA_CloseSessionEntryPoint(void *sess_ctx) {
return;
}
TEE_Result TA_InvokeCommandEntryPoint(void *sess_ctx,
uint32_t cmd_id,
uint32_t param_types,
TEE_Param params[4]) {
switch (cmd_id) {
case 0:
return TA_AddNumbers(param_types, params);
default:
return TEE_ERROR_BAD_PARAMETERS;
}
}
The above code defines a simple TA function called TA_AddNumbers that adds two input numbers and returns the result in an output parameter. The TA_CreateEntryPoint, TA_DestroyEntryPoint, TA_OpenSessionEntryPoint, and TA_CloseSessionEntryPoint functions are used to manage the lifecycle of the TA.
Client Application (CA) code:
#include <stdio.h>
#include <stdlib.h>
#include <tee_client_api.h>
#include <tee_api_defines.h>
#define TA_UUID {0x12345678, 0x8765, 0x4321, \
{0xab, 0xcd, 0xef, 0x00, 0x11, 0x22, 0x33, 0x44}}
// Function to add two numbers using the TA
TEE_Result CA_AddNumbers(uint32_t num1, uint32_t num2, uint32_t *result) {
TEEC_Result teec_res;
TEEC_Context teec_ctx;
TEEC_Session teec_sess;
TEEC_Operation teec_op;
TEEC_UUID ta_uuid = TA_UUID;
teec_res = TEEC_InitializeContext(NULL, &teec_ctx);
if (teec_res != TEEC_SUCCESS) {
return teec_res;
}
teec_res = TEEC_OpenSession(&teec_ctx, &teec_sess, &ta_uuid,
TEEC_LOGIN_PUBLIC, NULL, NULL, NULL);
if (teec_res != TEEC_SUCCESS) {
TEEC_FinalizeContext(&teec_ctx);
return teec_res;
}
memset(&teec_op, 0, sizeof(teec_op));
teec_op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_VALUE_INPUT,
TEEC_VALUE_OUTPUT, TEEC_NONE);
teec_op.params[0].value.a = num1
teec_op.params[1].value.a = num2;
teec_res = TEEC_InvokeCommand(&teec_sess, 0, &teec_op, NULL);
if (teec_res != TEEC_SUCCESS) {
TEEC_CloseSession(&teec_sess);
TEEC_FinalizeContext(&teec_ctx);
return teec_res;
}
*result = teec_op.params[2].value.a;
TEEC_CloseSession(&teec_sess);
TEEC_FinalizeContext(&teec_ctx);
return TEEC_SUCCESS;
}
int main(void) {
TEE_Result tee_res;
uint32_t num1 = 5, num2 = 10, result;
tee_res = CA_AddNumbers(num1, num2, &result)
if (tee_res != TEEC_SUCCESS) {
printf("Error: Failed to add numbers (%x)\n", tee_res);
return 1;
}
printf("Result: %d\n", result);
return 0;
}
The above code defines a simple function called `CA_AddNumbers` that uses the TEE Client API to communicate with the TA and add two input numbers. The `main` function simply calls `CA_AddNumbers` and prints the result.
General sequence diagram that shows the flow of communication between a CA (Client Application) and a TA (Trusted Application):
? ? ? ? ?CA? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?TA
? ? ? ? ? |? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
? ? ? ? ? |? ? ? ?TA_CreateEntryPoint()? ? ? ? ? ? ? ? ? |
? ? ? ? ? |--------------------------------------------->|
? ? ? ? ? |? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
? ? ? ? ? |? ? ? ? ? ? TA_GetEntryPointUUID()? ? ? ? ? ? |
? ? ? ? ? |--------------------------------------------->|
? ? ? ? ? |? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
? ? ? ? ? |? ? ? ? ? ? TA_ExportEntryPoint()? ? ? ? ? ? ?|
? ? ? ? ? |--------------------------------------------->|
? ? ? ? ? |? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
? ? ? ? ? |? ? ? ? ? ? TA_InitializeEntryPoint()? ? ? ? |
? ? ? ? ? |--------------------------------------------->|
? ? ? ? ? |? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
? ? ? ? ? |? ? ? ? ? ? TA_OpenSession()? ? ? ? ? ? ? ? ? |
? ? ? ? ? |<---------------------------------------------|
? ? ? ? ? |? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
? ? ? ? ? |? ? ? TA_InvokeCommand()? ? ? ? ? ? ? ? ? ? ??|
? ? ? ? ? |--------------------------------------------->|
? ? ? ? ? |? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
? ? ? ? ? |? ? ? ?TA_CloseSession()? ? ? ? ? ? ? ? ? ? ? |
? ? ? ? ? |<---------------------------------------------|
? ? ? ? ? |? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
? ? ? ? ? |? ? ? ?TA_FinalizeEntryPoint()? ? ? ? ? ? ? ? |
? ? ? ? ? |<---------------------------------------------|
? ? ? ? ? |? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
? ? ? ? ? |? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
The communication flow between the TA and the CA happens as follows:
1. The CA calls `CA_AddNumbers` and passes in two input numbers and a pointer to an output parameter.
2. `CA_AddNumbers` initializes the TEE Client API and opens a session with the TA using the TA's UUID.
3. `CA_AddNumbers` sets up a TEEC_Operation with the input and output parameters, and invokes the TA function `TA_AddNumbers` using TEEC_InvokeCommand.
4. `TA_AddNumbers` adds the two input numbers and returns the result in an output parameter.
5. The output parameter is read by `CA_AddNumbers` and returned to the `main` function, which prints the result.
Note that in a real-world scenario, the TA would typically provide more complex functionality and the CA would need to perform more error handling and parameter validation. The above code is intended only as a simple example to demonstrate the basic communication flow between a TA and a CA using OP-TEE OS.
Compilation Steps:
To compile the above code, you'll need to install the OP-TEE OS development environment on your system. This typically involves downloading the OP-TEE OS source code, configuring and building it, and installing the necessary toolchains and dependencies.
Below are optee build components:
Link for Optee:
Once you have a working OP-TEE OS development environment, you can compile the code by running the following commands in a terminal:
$ arm-linux-gnueabihf-gcc -I<OPTEE-OS-INC-DIR> -c ca.c -o ca.o
$ arm-linux-gnueabihf-gcc -I<OPTEE-OS-INC-DIR> -c ta.c -o ta.o
$ arm-linux-gnueabihf-gcc -I<OPTEE-OS-INC-DIR> -o ca ca.o -L<OPTEE-OS-LIB-DIR> -lteec
$ arm-linux-gnueabihf-gcc -I<OPTEE-OS-INC-DIR> -o ta ta.o -L<OPTEE-OS-LIB-DIR> -lteec -L<OPTEE-OS-LIB-DIR> -lutee
Replace <OPTEE-OS-INC-DIR> and <OPTEE-OS-LIB-DIR> with the paths to your OP-TEE OS include and library directories, respectively.
The output of the above code should be:
Result: 15
This is the result of adding the two input numbers (5 and 10) in the TA function TA_AddNumbers. The result is returned to the CA function CA_AddNumbers, which prints it to the console.
BTW what is UUID?
UUID (Universally Unique Identifier) is a 128-bit value used to uniquely identify an entity or object in computer systems. In the context of Trusted Execution Environments (TEEs), UUIDs are used to identify trusted applications (TAs) and to establish communication between the client application (CA) and the TA.
When a TA is created, it is assigned a UUID that is unique across all TAs on the system. This UUID is used by the CA to identify the TA and establish a session with it. The UUID is stored in the TA's binary file and is typically specified in the TA's manifest file.
It is important to choose a UUID carefully to ensure that it is unique and does not conflict with other UUIDs in the system. One common approach is to use a UUID generator tool, such as uuidgen on Linux, to generate a random UUID. Another approach is to use a UUID namespace, such as the one defined by the Internet Engineering Task Force (IETF), to generate a UUID that is guaranteed to be unique within the namespace.
Here is an example of how to generate a UUID using uuidgen on Linux:
$ uuidgen b5db2d5a-0bb4-4d4f-b81a-2ee39ca41742
Once a UUID has been generated or chosen, it should be included in the TA's manifest file, which is used by the TEE to register the TA and make it available to the CA. The manifest file typically includes information about the TA, such as its UUID, name, version, and required permissions.
Here is an example of a TA manifest file that includes a UUID:
{
"uuid": "b5db2d5a-0bb4-4d4f-b81a-2ee39ca41742",
"name": "example-ta",
"author": "Amit Nadiger",
"version": "1.0",
"description": "An example trusted application",
"config": {},
"properties": {},
"commands": [
{
"name": "example_command",
"description": "An example command",
"uuid": "b5db2d5a-0bb4-4d4f-b81a-2ee39ca41742",
"types": [
"value-input",
"value-input",
"value-output",
"none"
]
}
],
"default_permission": "false"
}
In this example, the uuid field specifies the UUID of the TA, and the commands field specifies the UUID of the command that can be invoked by the CA. When the TA is loaded by the TEE, it registers itself using the UUID specified in the manifest file, making it available for the CA to connect to and invoke its commands.
What is A Trusted Application's (TA) manifest file
A Trusted Application's (TA) manifest file is a JSON-formatted file that contains information about the TA, such as its UUID, name, version, and required permissions. The manifest file is required by the Trusted Execution Environment (TEE) to register the TA and make it available to the Client Application (CA).
The manifest file is typically included in the TA's binary package and is installed along with the TA when it is loaded into the TEE. When the TEE starts up, it reads the manifest files of all installed TAs and registers them, making their commands available for the CA to invoke.
The manifest file serves several important purposes:
How the OP-TEE OS authenticates and checks integrity of TAs when loading in to TEE?
The OP-TEE OS needs to be compiled along with the normal OS that runs on the device. The normal OS acts as the Rich Execution Environment (REE) and communicates with the Trusted Execution Environment (TEE) provided by the OP-TEE OS through a set of secure interfaces.
Regarding the authenticity and integrity check of TA with OP-TEE OS, the TA needs to be signed using a private key that corresponds to a public key stored in the OP-TEE OS. This ensures that only trusted TAs are loaded into the TEE and executed. The signature is verified by the OP-TEE OS during the TA loading process.
The process of verifying the authenticity and integrity of a TA involves several steps:
How sharing of key pair happens between op-tee os and TA developer?
The process of sharing the public key between the TA developer and the OP-TEE OS involves several steps:
It's important to note that the private key should be kept secure and not shared with anyone else, as it is used to sign TAs and is an essential component of the authentication process. The public key, on the other hand, can be shared freely with anyone who needs to verify the authenticity of the TA.
Advantages of OP-TEE:
Disadvantages of OP-TEE:
OP-TEE limitations,:
Thanks for reading till end ! Please let me know if you know any other TEE.
References:
Optee documentation: OP-TEE Documentation — OP-TEE documentation documentation (optee.readthedocs.io)
Please see sample apps in below: