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