optee_teec/
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 super::context::InnerContext;
19use crate::{Context, Error, Operation, Param, Result, Uuid, raw};
20use std::{cell::RefCell, ptr, rc::Rc};
21
22/// Session login methods.
23#[derive(Copy, Clone)]
24pub enum ConnectionMethods {
25    /// No login data is provided.
26    LoginPublic,
27    /// Login data about the user running the Client Application process is provided.
28    LoginUser,
29    /// Login data about the group running the Client Application process is provided.
30    LoginGroup,
31    /// Login data about the running Client Application itself is provided.
32    LoginApplication,
33    /// Login data about the user and the running Client Application itself is provided.
34    LoginUserApplication,
35    /// Login data about the group and the running Client Application itself is provided.
36    LoginGroupApplication,
37}
38
39/// Represents a connection between a client application and a trusted application.
40pub struct Session {
41    raw: raw::TEEC_Session,
42
43    // Just a holder to ensure InnerContext is not dropped and to eliminate the
44    // lifetime constraint, never use it.
45    _ctx: Rc<RefCell<InnerContext>>,
46}
47
48// Since raw::TEEC_Session contains a raw pointer, Rust does not automatically
49// implement Send and Sync for it. We need to manually implement them and ensure
50// that raw::TEEC_Session is used safely.
51unsafe impl Send for Session {}
52unsafe impl Sync for Session {}
53
54impl Session {
55    /// Initializes a TEE session object with specified context and uuid.
56    pub fn new<A: Param, B: Param, C: Param, D: Param>(
57        context: &mut Context,
58        uuid: Uuid,
59        login: ConnectionMethods,
60        operation: Option<&mut Operation<A, B, C, D>>,
61    ) -> Result<Self> {
62        // SAFETY:
63        // raw_session is a C struct(TEEC_Session), which zero value is valid.
64        let mut raw_session = unsafe { std::mem::zeroed() };
65        // define all parameters for raw::TEEC_OpenSession outside of the unsafe
66        // block to maximize Rust's safety checks and leverage the compiler's
67        // validation.
68        let mut err_origin: u32 = 0;
69        let raw_operation = match operation {
70            Some(o) => o.as_mut_raw_ptr(),
71            None => ptr::null_mut(),
72        };
73        let inner_ctx = context.inner_context();
74        let raw_ctx = &mut inner_ctx.borrow_mut().0;
75        let raw_uuid = uuid.as_raw_ptr();
76
77        match unsafe {
78            raw::TEEC_OpenSession(
79                raw_ctx,
80                &mut raw_session,
81                raw_uuid,
82                login as u32,
83                ptr::null(),
84                raw_operation,
85                &mut err_origin,
86            )
87        } {
88            raw::TEEC_SUCCESS => Ok(Self {
89                raw: raw_session,
90                _ctx: context.inner_context(),
91            }),
92            code => Err(Error::from_raw_error(code).with_origin(err_origin.into())),
93        }
94    }
95
96    /// Invokes a command with an operation with this session.
97    pub fn invoke_command<A: Param, B: Param, C: Param, D: Param>(
98        &mut self,
99        command_id: u32,
100        operation: &mut Operation<A, B, C, D>,
101    ) -> Result<()> {
102        let mut err_origin: u32 = 0;
103        match unsafe {
104            raw::TEEC_InvokeCommand(
105                &mut self.raw,
106                command_id,
107                operation.as_mut_raw_ptr(),
108                &mut err_origin,
109            )
110        } {
111            raw::TEEC_SUCCESS => Ok(()),
112            code => Err(Error::from_raw_error(code).with_origin(err_origin.into())),
113        }
114    }
115}
116
117impl Drop for Session {
118    fn drop(&mut self) {
119        unsafe {
120            raw::TEEC_CloseSession(&mut self.raw);
121        }
122    }
123}