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