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 #![no_std]
19 #![no_main]
20 #![feature(c_size_t)]
21
22 extern crate alloc;
23
24 use alloc::vec;
25 use optee_utee::{
26 ta_close_session, ta_create, ta_destroy, ta_invoke_command, ta_open_session, trace_println,
27 };
28 use optee_utee::{DataFlag, ObjectStorageConstants, PersistentObject};
29 use optee_utee::{Error, ErrorKind, Parameters, Result};
30 use proto::{Command};
31
32 #[ta_create]
create() -> Result<()>33 fn create() -> Result<()> {
34 trace_println!("[+] TA create");
35 Ok(())
36 }
37
38 #[ta_open_session]
open_session(_params: &mut Parameters) -> Result<()>39 fn open_session(_params: &mut Parameters) -> Result<()> {
40 trace_println!("[+] TA open session");
41 Ok(())
42 }
43
44 #[ta_close_session]
close_session()45 fn close_session() {
46 trace_println!("[+] TA close session");
47 }
48
49 #[ta_destroy]
destroy()50 fn destroy() {
51 trace_println!("[+] TA destroy");
52 }
53
54 #[ta_invoke_command]
invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()>55 fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
56 trace_println!("[+] TA invoke command");
57 match Command::from(cmd_id) {
58 Command::Write => {
59 return create_raw_object(params);
60 }
61 Command::Read => {
62 return read_raw_object(params);
63 }
64 Command::Delete => {
65 return delete_object(params);
66 }
67 _ => {
68 return Err(Error::new(ErrorKind::NotSupported));
69 }
70 }
71 }
72
delete_object(params: &mut Parameters) -> Result<()>73 pub fn delete_object(params: &mut Parameters) -> Result<()> {
74 let mut p0 = unsafe { params.0.as_memref().unwrap() };
75
76 let mut obj_id = vec![0; p0.buffer().len() as usize];
77 obj_id.copy_from_slice(p0.buffer());
78
79 match PersistentObject::open(
80 ObjectStorageConstants::Private,
81 &mut obj_id,
82 DataFlag::ACCESS_READ | DataFlag::ACCESS_WRITE_META,
83 ) {
84 Err(e) => {
85 return Err(e);
86 }
87
88 Ok(mut object) => {
89 object.close_and_delete()?;
90 mem::forget(object);
91 return Ok(());
92 }
93 }
94 }
95
create_raw_object(params: &mut Parameters) -> Result<()>96 pub fn create_raw_object(params: &mut Parameters) -> Result<()> {
97 let mut p0 = unsafe { params.0.as_memref().unwrap() };
98 let mut p1 = unsafe { params.1.as_memref().unwrap() };
99
100 let mut obj_id = vec![0; p0.buffer().len() as usize];
101 obj_id.copy_from_slice(p0.buffer());
102 let mut data_buffer = vec![0; p1.buffer().len() as usize];
103 data_buffer.copy_from_slice(p1.buffer());
104
105 let obj_data_flag = DataFlag::ACCESS_READ
106 | DataFlag::ACCESS_WRITE
107 | DataFlag::ACCESS_WRITE_META
108 | DataFlag::OVERWRITE;
109
110 let mut init_data: [u8; 0] = [0; 0];
111
112 match PersistentObject::create(
113 ObjectStorageConstants::Private,
114 &mut obj_id,
115 obj_data_flag,
116 None,
117 &mut init_data,
118 ) {
119 Err(e) => {
120 return Err(e);
121 }
122
123 Ok(mut object) => match object.write(&data_buffer) {
124 Ok(()) => {
125 return Ok(());
126 }
127 Err(e_write) => {
128 object.close_and_delete()?;
129 mem::forget(object);
130 return Err(e_write);
131 }
132 },
133 }
134 }
135
read_raw_object(params: &mut Parameters) -> Result<()>136 pub fn read_raw_object(params: &mut Parameters) -> Result<()> {
137 let mut p0 = unsafe { params.0.as_memref().unwrap() };
138 let mut p1 = unsafe { params.1.as_memref().unwrap() };
139 let mut obj_id = vec![0; p0.buffer().len() as usize];
140 obj_id.copy_from_slice(p0.buffer());
141
142 let mut data_buffer = vec![0;p1.buffer().len() as usize];
143 data_buffer.copy_from_slice(p1.buffer());
144
145 match PersistentObject::open(
146 ObjectStorageConstants::Private,
147 &mut obj_id,
148 DataFlag::ACCESS_READ | DataFlag::SHARE_READ,
149 ) {
150 Err(e) => return Err(e),
151
152 Ok(object) => {
153 let obj_info = object.info()?;
154
155 if obj_info.data_size() > p1.buffer().len() {
156 p1.set_updated_size(obj_info.data_size());
157 return Err(Error::new(ErrorKind::ShortBuffer));
158 }
159 let read_bytes = object.read(&mut data_buffer).unwrap();
160 if read_bytes != obj_info.data_size() as u32 {
161 return Err(Error::new(ErrorKind::ExcessData));
162 }
163
164 p1.set_updated_size(read_bytes as usize);
165 p1.buffer().copy_from_slice(&data_buffer);
166
167 Ok(())
168 }
169 }
170 }
171
172 // TA configurations
173 const TA_FLAGS: u32 = 0;
174 const TA_DATA_SIZE: u32 = 32 * 1024;
175 const TA_STACK_SIZE: u32 = 2 * 1024;
176 const TA_VERSION: &[u8] = b"0.1\0";
177 const TA_DESCRIPTION: &[u8] = b"This is a secure storage example.\0";
178 const EXT_PROP_VALUE_1: &[u8] = b"Secure Storage TA\0";
179 const EXT_PROP_VALUE_2: u32 = 0x0010;
180 const TRACE_LEVEL: i32 = 4;
181 const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
182 const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
183
184 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
185