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