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 let raw: raw::TEEC_Parameter = unsafe { mem::zeroed() };
78 raw
79 }
80
81 fn param_type(&self) -> ParamType {
82 ParamType::None
83 }
84
85 fn from_raw(_raw: raw::TEEC_Parameter, _param_type: ParamType) -> Self {
86 Self
87 }
88}
89
90/// This type defines a temporary memory reference. It is used as a
91/// `Operation` parameter when the corresponding parameter type is one of
92/// `MemrefTempInput`, `MemrefTempOutput`, or `MemrefTempInout`.
93pub struct ParamTmpRef<'a> {
94 raw: raw::TEEC_TempMemoryReference,
95 param_type: ParamType,
96 _marker: marker::PhantomData<&'a mut [u8]>,
97}
98
99impl<'a> ParamTmpRef<'a> {
100 /// Creates a temporary input only memory reference.
101 /// `buffer` is a region of memory which needs to be temporarily
102 /// registered for the duration of the `Operation`.
103 pub fn new_input(buffer: &'a [u8]) -> Self {
104 let raw = raw::TEEC_TempMemoryReference {
105 buffer: buffer.as_ptr() as _,
106 size: buffer.len(),
107 };
108 Self {
109 raw,
110 param_type: ParamType::MemrefTempInput,
111 _marker: marker::PhantomData,
112 }
113 }
114
115 /// Creates a temporary memory reference. `buffer` is a region of memory
116 /// which needs to be temporarily registered for the duration of the
117 /// `Operation`.
118 pub fn new_output(buffer: &'a mut [u8]) -> Self {
119 let raw = raw::TEEC_TempMemoryReference {
120 buffer: buffer.as_ptr() as _,
121 size: buffer.len(),
122 };
123 Self {
124 raw,
125 param_type: ParamType::MemrefTempOutput,
126 _marker: marker::PhantomData,
127 }
128 }
129
130 pub fn updated_size(&self) -> usize {
131 self.raw.size
132 }
133}
134
135impl<'a> Param for ParamTmpRef<'a> {
136 fn to_raw(&mut self) -> raw::TEEC_Parameter {
137 raw::TEEC_Parameter { tmpref: self.raw }
138 }
139
140 fn param_type(&self) -> ParamType {
141 self.param_type
142 }
143
144 fn from_raw(raw: raw::TEEC_Parameter, param_type: ParamType) -> Self {
145 Self {
146 raw: unsafe { raw.tmpref },
147 param_type,
148 _marker: marker::PhantomData,
149 }
150 }
151}
152
153/// These are used to indicate the type of Parameter encoded inside the
154/// operation structure.
155#[derive(Copy, Clone)]
156pub enum ParamType {
157 /// The Parameter is not used.
158 None = 0,
159 /// The Parameter is a TEEC_Value tagged as input.
160 ValueInput = 1,
161 /// The Parameter is a TEEC_Value tagged as output.
162 ValueOutput = 2,
163 /// The Parameter is a TEEC_Value tagged as both as input and output, i.e.,
164 /// for which both the behaviors of ValueInput and ValueOutput apply.
165 ValueInout = 3,
166 /// The Parameter is a TEEC_TempMemoryReference describing a region of
167 /// memory which needs to be temporarily registered for the duration of the
168 /// Operation and is tagged as input.
169 MemrefTempInput = 5,
170 /// Same as MemrefTempInput, but the Memory Reference is tagged as
171 /// output. The Implementation may update the size field to reflect the
172 /// required output size in some use cases.
173 MemrefTempOutput = 6,
174 /// A Temporary Memory Reference tagged as both input and output, i.e., for
175 /// which both the behaviors of MemrefTempInput and MemrefTempOutput apply.
176 MemrefTempInout = 7,
177 /// The Parameter is a Registered Memory Reference that refers to the
178 /// entirety of its parent Shared Memory block. The parameter structure is a
179 /// TEEC_MemoryReference. In this structure, the Implementation MUST read
180 /// only the parent field and MAY update the size field when the operation
181 /// completes.
182 MemrefWhole = 0xC,
183 /// A Registered Memory Reference structure that refers to a partial region
184 /// of its parent Shared Memory block and is tagged as input.
185 MemrefPartialInput = 0xD,
186 /// A Registered Memory Reference structure that refers to a partial region
187 /// of its parent Shared Memory block and is tagged as output.
188 MemrefPartialOutput = 0xE,
189 /// The Registered Memory Reference structure that refers to a partial
190 /// region of its parent Shared Memory block and is tagged as both input and
191 /// output, i.e., for which both the behaviors of MemrefPartialInput and
192 /// MemrefPartialOutput apply.
193 MemrefPartialInout = 0xF,
194}
195
196impl From<u32> for ParamType {
197 fn from(value: u32) -> Self {
198 match value {
199 0 => ParamType::None,
200 1 => ParamType::ValueInput,
201 2 => ParamType::ValueOutput,
202 3 => ParamType::ValueInout,
203 5 => ParamType::MemrefTempInput,
204 6 => ParamType::MemrefTempOutput,
205 7 => ParamType::MemrefTempInout,
206 0xC => ParamType::MemrefWhole,
207 0xD => ParamType::MemrefPartialInput,
208 0xE => ParamType::MemrefPartialOutput,
209 0xF => ParamType::MemrefPartialInout,
210 _ => ParamType::None,
211 }
212 }
213}
214
215pub struct ParamTypes(u32);
216
217impl ParamTypes {
218 pub fn new(p0: ParamType, p1: ParamType, p2: ParamType, p3: ParamType) -> Self {
219 ParamTypes((p0 as u32) | (p1 as u32) << 4 | (p2 as u32) << 8 | (p3 as u32) << 12)
220 }
221
222 pub fn into_flags(&self) -> (ParamType, ParamType, ParamType, ParamType) {
223 (
224 (0x000fu32 & self.0).into(),
225 (0x00f0u32 & self.0).into(),
226 (0x0f00u32 & self.0).into(),
227 (0xf000u32 & self.0).into(),
228 )
229 }
230}
231
232impl From<u32> for ParamTypes {
233 fn from(value: u32) -> Self {
234 ParamTypes(value)
235 }
236}
237
238impl From<[u32; 4]> for ParamTypes {
239 fn from(param_types: [u32; 4]) -> Self {
240 ParamTypes(
241 param_types[0] | param_types[1] << 4 | param_types[2] << 8 | param_types[3] << 12,
242 )
243 }
244}
245
246impl From<ParamTypes> for u32 {
247 fn from(a: ParamTypes) -> u32 {
248 a.0
249 }
250}