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}