optee_utee/
ta_session.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use crate::{Error, Result, TeeParams, Uuid};
19use optee_utee_sys as raw;
20
21pub struct TaSessionBuilder<'a> {
22    target_uuid: Uuid,
23    timeout: u32,
24    params: Option<TeeParams<'a>>,
25}
26
27impl<'a> TaSessionBuilder<'a> {
28    /// Creates a new builder for the given TA UUID.
29    pub fn new(uuid: Uuid) -> Self {
30        Self {
31            target_uuid: uuid,
32            timeout: raw::TEE_TIMEOUT_INFINITE,
33            params: None,
34        }
35    }
36
37    /// Sets a custom timeout for the session opening.
38    pub fn with_timeout(mut self, timeout: u32) -> Self {
39        self.timeout = timeout;
40        self
41    }
42
43    /// Sets the parameters to be passed during session opening.
44    pub fn with_params(mut self, params: TeeParams<'a>) -> Self {
45        self.params = Some(params);
46        self
47    }
48
49    /// Builds and opens the `TaSession`. Returns an error if the session fails to open.
50    pub fn build(mut self) -> Result<TaSession> {
51        let mut err_origin: u32 = 0;
52        let mut raw_session: raw::TEE_TASessionHandle = core::ptr::null_mut();
53        // Check if the parameters are provided and prepare them for the C API call.
54        let (raw_param_types, raw_params_ptr, raw_params_opt) =
55            if let Some(params) = &mut self.params {
56                let mut raw_params = params.as_raw();
57                let raw_ptr = raw_params.as_mut_ptr();
58                (params.raw_param_types(), raw_ptr, Some(raw_params))
59            } else {
60                (0, core::ptr::null_mut(), None)
61            };
62
63        // SAFETY:
64        // self.target_uuid.as_raw_ptr() provides a valid pointer to the UUID.
65        // raw_params.as_mut_ptr() provides a valid pointer to the parameters.
66        // The remaining arguments are either valid values or null/mut pointers as expected by the C API.
67        // For parameters that are intended to be modified by the call, the buffer constraints are checked later in update_from_raw().
68        match unsafe {
69            raw::TEE_OpenTASession(
70                self.target_uuid.as_raw_ptr(),
71                self.timeout,
72                raw_param_types,
73                raw_params_ptr,
74                &mut raw_session,
75                &mut err_origin,
76            )
77        } {
78            raw::TEE_SUCCESS => {
79                if let (Some(params), Some(raw_params)) = (&mut self.params, raw_params_opt) {
80                    params.update_from_raw(&raw_params)?;
81                }
82
83                Ok(TaSession { raw: raw_session })
84            }
85            code => Err(Error::from_raw_error(code).with_origin(err_origin.into())),
86        }
87    }
88}
89
90pub struct TaSession {
91    raw: raw::TEE_TASessionHandle,
92}
93
94impl TaSession {
95    /// Invokes a command with the provided parameters using the session's default timeout.
96    /// Returns the result directly without allowing further method chaining.
97    pub fn invoke_command(&mut self, command_id: u32, params: &mut TeeParams) -> Result<()> {
98        self.invoke_command_with_timeout(command_id, params, raw::TEE_TIMEOUT_INFINITE)
99    }
100
101    pub fn invoke_command_with_timeout(
102        &mut self,
103        command_id: u32,
104        params: &mut TeeParams,
105        timeout: u32,
106    ) -> Result<()> {
107        let mut err_origin: u32 = 0;
108        let mut raw_params = params.as_raw();
109        let param_types = params.raw_param_types();
110
111        // SAFETY:
112        // self.raw is a valid pointer to an active session handle.
113        // raw_params.as_mut_ptr() yields a valid mutable pointer to the parameters array.
114        // The remaining arguments are either valid values or null/mutable pointers, as expected by the C API.
115        // For parameters that are intended to be modified by the call, the buffer constraints are checked later in update_from_raw().
116        match unsafe {
117            raw::TEE_InvokeTACommand(
118                self.raw,
119                timeout,
120                command_id,
121                param_types,
122                raw_params.as_mut_ptr(),
123                &mut err_origin,
124            )
125        } {
126            raw::TEE_SUCCESS => {
127                // Update the parameters with the results
128                params.update_from_raw(&raw_params)?;
129                Ok(())
130            }
131            code => Err(Error::from_raw_error(code).with_origin(err_origin.into())),
132        }
133    }
134}
135
136// Drop implementation to close the session
137impl Drop for TaSession {
138    fn drop(&mut self) {
139        // SAFETY:
140        // self.raw is a valid pointer to an active session handle.
141        // The function call is expected to clean up the session resources.
142        unsafe {
143            raw::TEE_CloseTASession(self.raw);
144        }
145    }
146}