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