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