Skip to main content

optee_teec/
parameter.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::raw;
19use std::{marker, mem};
20
21pub trait Param {
22    fn to_raw(&mut self) -> raw::TEEC_Parameter;
23    fn param_type(&self) -> ParamType;
24    fn from_raw(raw: raw::TEEC_Parameter, param_type: ParamType) -> Self;
25}
26
27/// This type defines a parameter that is not referencing shared memory, but
28/// carries instead small raw data passed by value. It is used as a `Operation`
29/// parameter when the corresponding parameter type is one of `ValueInput`,
30/// `ValueOutput`, or `ValueInout`.
31pub struct ParamValue {
32    raw: raw::TEEC_Value,
33    param_type: ParamType,
34}
35
36impl ParamValue {
37    /// Creates a value parameter with two `u32` integer and `ParamType` for
38    /// operation.
39    pub fn new(a: u32, b: u32, param_type: ParamType) -> Self {
40        let raw = raw::TEEC_Value { a, b };
41        Self { raw, param_type }
42    }
43
44    /// Returns the first value in the value parameter.
45    pub fn a(&self) -> u32 {
46        self.raw.a
47    }
48
49    /// Returns the second value in the value parameter.
50    pub fn b(&self) -> u32 {
51        self.raw.b
52    }
53}
54
55impl Param for ParamValue {
56    fn to_raw(&mut self) -> raw::TEEC_Parameter {
57        raw::TEEC_Parameter { value: self.raw }
58    }
59
60    fn from_raw(raw: raw::TEEC_Parameter, param_type: ParamType) -> Self {
61        Self {
62            raw: unsafe { raw.value },
63            param_type,
64        }
65    }
66
67    fn param_type(&self) -> ParamType {
68        self.param_type
69    }
70}
71
72/// Represents none parameter which carries no information.
73pub struct ParamNone;
74
75impl Param for ParamNone {
76    fn to_raw(&mut self) -> raw::TEEC_Parameter {
77        unsafe { mem::zeroed() }
78    }
79
80    fn param_type(&self) -> ParamType {
81        ParamType::None
82    }
83
84    fn from_raw(_raw: raw::TEEC_Parameter, _param_type: ParamType) -> Self {
85        Self
86    }
87}
88
89/// This type defines a temporary memory reference. It is used as a
90/// `Operation` parameter when the corresponding parameter type is one of
91/// `MemrefTempInput`, `MemrefTempOutput`, or `MemrefTempInout`.
92pub struct ParamTmpRef<'a> {
93    raw: raw::TEEC_TempMemoryReference,
94    param_type: ParamType,
95    _marker: marker::PhantomData<&'a mut [u8]>,
96}
97
98impl<'a> ParamTmpRef<'a> {
99    /// Creates a temporary input only memory reference.
100    /// `buffer` is a region of memory which needs to be temporarily
101    /// registered for the duration of the `Operation`.
102    pub fn new_input(buffer: &'a [u8]) -> Self {
103        let raw = raw::TEEC_TempMemoryReference {
104            buffer: buffer.as_ptr() as _,
105            size: buffer.len(),
106        };
107        Self {
108            raw,
109            param_type: ParamType::MemrefTempInput,
110            _marker: marker::PhantomData,
111        }
112    }
113
114    /// Creates a temporary memory reference. `buffer` is a region of memory
115    /// which needs to be temporarily registered for the duration of the
116    /// `Operation`.
117    pub fn new_output(buffer: &'a mut [u8]) -> Self {
118        let raw = raw::TEEC_TempMemoryReference {
119            buffer: buffer.as_ptr() as _,
120            size: buffer.len(),
121        };
122        Self {
123            raw,
124            param_type: ParamType::MemrefTempOutput,
125            _marker: marker::PhantomData,
126        }
127    }
128
129    /// Creates a temporary input/output memory reference.
130    ///
131    /// `buffer` is a region of memory which needs to be temporarily
132    /// registered for the duration of the `Operation` and can be both
133    /// read and written by the Trusted Application (TA).
134    ///
135    /// This is useful when you need to pass data to a TA that will
136    /// modify it and return the modified data in the same buffer.
137    pub fn new_inout(buffer: &'a mut [u8]) -> Self {
138        let raw = raw::TEEC_TempMemoryReference {
139            buffer: buffer.as_ptr() as _,
140            size: buffer.len(),
141        };
142        Self {
143            raw,
144            param_type: ParamType::MemrefTempInout,
145            _marker: marker::PhantomData,
146        }
147    }
148
149    pub fn updated_size(&self) -> usize {
150        self.raw.size
151    }
152}
153
154impl<'a> Param for ParamTmpRef<'a> {
155    fn to_raw(&mut self) -> raw::TEEC_Parameter {
156        raw::TEEC_Parameter { tmpref: self.raw }
157    }
158
159    fn param_type(&self) -> ParamType {
160        self.param_type
161    }
162
163    fn from_raw(raw: raw::TEEC_Parameter, param_type: ParamType) -> Self {
164        Self {
165            raw: unsafe { raw.tmpref },
166            param_type,
167            _marker: marker::PhantomData,
168        }
169    }
170}
171
172/// These are used to indicate the type of Parameter encoded inside the
173/// operation structure.
174#[derive(Copy, Clone)]
175pub enum ParamType {
176    /// The Parameter is not used.
177    None = 0,
178    /// The Parameter is a TEEC_Value tagged as input.
179    ValueInput = 1,
180    /// The Parameter is a TEEC_Value tagged as output.
181    ValueOutput = 2,
182    /// The Parameter is a TEEC_Value tagged as both as input and output, i.e.,
183    /// for which both the behaviors of ValueInput and ValueOutput apply.
184    ValueInout = 3,
185    /// The Parameter is a TEEC_TempMemoryReference describing a region of
186    /// memory which needs to be temporarily registered for the duration of the
187    /// Operation and is tagged as input.
188    MemrefTempInput = 5,
189    /// Same as MemrefTempInput, but the Memory Reference is tagged as
190    /// output. The Implementation may update the size field to reflect the
191    /// required output size in some use cases.
192    MemrefTempOutput = 6,
193    /// A Temporary Memory Reference tagged as both input and output, i.e., for
194    /// which both the behaviors of MemrefTempInput and MemrefTempOutput apply.
195    MemrefTempInout = 7,
196    /// The Parameter is a Registered Memory Reference that refers to the
197    /// entirety of its parent Shared Memory block. The parameter structure is a
198    /// TEEC_MemoryReference. In this structure, the Implementation MUST read
199    /// only the parent field and MAY update the size field when the operation
200    /// completes.
201    MemrefWhole = 0xC,
202    /// A Registered Memory Reference structure that refers to a partial region
203    /// of its parent Shared Memory block and is tagged as input.
204    MemrefPartialInput = 0xD,
205    /// A Registered Memory Reference structure that refers to a partial region
206    /// of its parent Shared Memory block and is tagged as output.
207    MemrefPartialOutput = 0xE,
208    /// The Registered Memory Reference structure that refers to a partial
209    /// region of its parent Shared Memory block and is tagged as both input and
210    /// output, i.e., for which both the behaviors of MemrefPartialInput and
211    /// MemrefPartialOutput apply.
212    MemrefPartialInout = 0xF,
213}
214
215impl From<u32> for ParamType {
216    fn from(value: u32) -> Self {
217        match value {
218            0 => ParamType::None,
219            1 => ParamType::ValueInput,
220            2 => ParamType::ValueOutput,
221            3 => ParamType::ValueInout,
222            5 => ParamType::MemrefTempInput,
223            6 => ParamType::MemrefTempOutput,
224            7 => ParamType::MemrefTempInout,
225            0xC => ParamType::MemrefWhole,
226            0xD => ParamType::MemrefPartialInput,
227            0xE => ParamType::MemrefPartialOutput,
228            0xF => ParamType::MemrefPartialInout,
229            _ => ParamType::None,
230        }
231    }
232}
233
234pub struct ParamTypes(u32);
235
236impl ParamTypes {
237    pub fn new(p0: ParamType, p1: ParamType, p2: ParamType, p3: ParamType) -> Self {
238        ParamTypes((p0 as u32) | (p1 as u32) << 4 | (p2 as u32) << 8 | (p3 as u32) << 12)
239    }
240
241    pub fn into_flags(&self) -> (ParamType, ParamType, ParamType, ParamType) {
242        (
243            (0x000f_u32 & self.0).into(),
244            ((0x00f0_u32 & self.0) >> 4).into(),
245            ((0x0f00_u32 & self.0) >> 8).into(),
246            ((0xf000_u32 & self.0) >> 12).into(),
247        )
248    }
249}
250
251impl From<u32> for ParamTypes {
252    fn from(value: u32) -> Self {
253        ParamTypes(value)
254    }
255}
256
257impl From<[u32; 4]> for ParamTypes {
258    fn from(param_types: [u32; 4]) -> Self {
259        ParamTypes(
260            param_types[0] | param_types[1] << 4 | param_types[2] << 8 | param_types[3] << 12,
261        )
262    }
263}
264
265impl From<ParamTypes> for u32 {
266    fn from(a: ParamTypes) -> u32 {
267        a.0
268    }
269}