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 alloc::boxed::Box;
26 use optee_utee::{
27 ta_close_session, ta_create, ta_destroy, ta_invoke_command, ta_open_session, trace_println,
28 };
29 use optee_utee::{AlgorithmId, OperationMode, AE};
30 use optee_utee::{AttributeId, AttributeMemref, TransientObject, TransientObjectType};
31 use optee_utee::{Error, ErrorKind, Parameters, Result};
32 use proto::{Command, Mode, AAD_LEN, BUFFER_SIZE, KEY_SIZE, TAG_LEN};
33
34 pub const PAYLOAD_NUMBER: usize = 2;
35
36 pub struct AEOp {
37 pub op: AE,
38 }
39
40 impl Default for AEOp {
default() -> Self41 fn default() -> Self {
42 Self {
43 op: AE::null()
44 }
45 }
46 }
47
48 #[ta_create]
create() -> Result<()>49 fn create() -> Result<()> {
50 trace_println!("[+] TA create");
51 Ok(())
52 }
53
54 #[ta_open_session]
open_session(_params: &mut Parameters, _sess_ctx: &mut AEOp) -> Result<()>55 fn open_session(_params: &mut Parameters, _sess_ctx: &mut AEOp) -> Result<()> {
56 trace_println!("[+] TA open session");
57 Ok(())
58 }
59
60 #[ta_close_session]
close_session(_sess_ctx: &mut AEOp)61 fn close_session(_sess_ctx: &mut AEOp) {
62 trace_println!("[+] TA close session");
63 }
64
65 #[ta_destroy]
destroy()66 fn destroy() {
67 trace_println!("[+] TA destroy");
68 }
69
70 #[ta_invoke_command]
invoke_command(sess_ctx: &mut AEOp, cmd_id: u32, params: &mut Parameters) -> Result<()>71 fn invoke_command(sess_ctx: &mut AEOp, cmd_id: u32, params: &mut Parameters) -> Result<()> {
72 trace_println!("[+] TA invoke command");
73 match Command::from(cmd_id) {
74 Command::Prepare => {
75 trace_println!("[+] TA prepare");
76 return prepare(sess_ctx, params);
77 }
78 Command::Update => {
79 trace_println!("[+] TA update");
80 return update(sess_ctx, params);
81 }
82 Command::EncFinal => {
83 trace_println!("[+] TA encrypt_final");
84 return encrypt_final(sess_ctx, params);
85 }
86 Command::DecFinal => {
87 trace_println!("[+] TA decrypt_final");
88 return decrypt_final(sess_ctx, params);
89 }
90 _ => {
91 return Err(Error::new(ErrorKind::BadParameters));
92 }
93 }
94 }
95
prepare(ae: &mut AEOp, params: &mut Parameters) -> Result<()>96 pub fn prepare(ae: &mut AEOp, params: &mut Parameters) -> Result<()> {
97 let p0 = unsafe { params.0.as_value().unwrap() };
98 let mut p1 = unsafe { params.1.as_memref().unwrap() };
99 let mut p2 = unsafe { params.2.as_memref().unwrap() };
100 let mut p3 = unsafe { params.3.as_memref().unwrap() };
101 let mode = match Mode::from(p0.a()) {
102 Mode::Encrypt => OperationMode::Encrypt,
103 Mode::Decrypt => OperationMode::Decrypt,
104 _ => OperationMode::IllegalValue,
105 };
106 let nonce = p1.buffer();
107 let key = p2.buffer();
108 let aad = p3.buffer();
109
110 ae.op = AE::allocate(AlgorithmId::AesCcm, mode, KEY_SIZE * 8).unwrap();
111
112 let mut key_object = TransientObject::allocate(TransientObjectType::Aes, KEY_SIZE * 8).unwrap();
113 let attr = AttributeMemref::from_ref(AttributeId::SecretValue, key);
114 key_object.populate(&[attr.into()])?;
115 ae.op.set_key(&key_object)?;
116 ae.op
117 .init(&nonce, TAG_LEN * 8, AAD_LEN, BUFFER_SIZE * PAYLOAD_NUMBER)?;
118 ae.op.update_aad(aad);
119 Ok(())
120 }
121
update(digest: &mut AEOp, params: &mut Parameters) -> Result<()>122 pub fn update(digest: &mut AEOp, params: &mut Parameters) -> Result<()> {
123 let mut p0 = unsafe { params.0.as_memref().unwrap() };
124 let mut p1 = unsafe { params.1.as_memref().unwrap() };
125 let src = p0.buffer();
126 let res = p1.buffer();
127 digest.op.update(src, res)?;
128 Ok(())
129 }
130
encrypt_final(digest: &mut AEOp, params: &mut Parameters) -> Result<()>131 pub fn encrypt_final(digest: &mut AEOp, 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 p2 = unsafe { params.2.as_memref().unwrap() };
135
136 let mut clear = vec![0; p0.buffer().len() as usize];
137 clear.copy_from_slice(p0.buffer());
138 let mut ciph = vec![0; p1.buffer().len() as usize];
139 ciph.copy_from_slice(p1.buffer());
140 let mut tag = vec![0; p2.buffer().len() as usize];
141 tag.copy_from_slice(p2.buffer());
142
143 match digest.op.encrypt_final(&clear, &mut ciph, &mut tag) {
144
145 Err(e) => Err(e),
146 Ok((_ciph_len, _tag_len)) => {
147 p0.buffer().copy_from_slice(&clear);
148 p1.buffer().copy_from_slice(&ciph);
149 p2.buffer().copy_from_slice(&tag);
150
151 Ok(())
152 },
153 }
154 }
155
decrypt_final(digest: &mut AEOp, params: &mut Parameters) -> Result<()>156 pub fn decrypt_final(digest: &mut AEOp, params: &mut Parameters) -> Result<()> {
157 let mut p0 = unsafe { params.0.as_memref().unwrap() };
158 let mut p1 = unsafe { params.1.as_memref().unwrap() };
159 let mut p2 = unsafe { params.2.as_memref().unwrap() };
160
161 let mut clear = vec![0; p0.buffer().len() as usize];
162 clear.copy_from_slice(p0.buffer());
163 let mut ciph = vec![0; p1.buffer().len() as usize];
164 ciph.copy_from_slice(p1.buffer());
165 let mut tag = vec![0; p2.buffer().len() as usize];
166 tag.copy_from_slice(p2.buffer());
167
168 match digest.op.decrypt_final(&clear, &mut ciph, &tag) {
169 Err(e) => Err(e),
170 Ok(_clear_len) => {
171 p0.buffer().copy_from_slice(&clear);
172 p1.buffer().copy_from_slice(&ciph);
173 p2.buffer().copy_from_slice(&tag);
174
175 Ok(())
176 },
177 }
178 }
179
180 // TA configurations
181 const TA_FLAGS: u32 = 0;
182 const TA_DATA_SIZE: u32 = 32 * 1024;
183 const TA_STACK_SIZE: u32 = 2 * 1024;
184 const TA_VERSION: &[u8] = b"0.1\0";
185 const TA_DESCRIPTION: &[u8] = b"This is an authentication encryption example.\0";
186 const EXT_PROP_VALUE_1: &[u8] = b"AE TA\0";
187 const EXT_PROP_VALUE_2: u32 = 0x0010;
188 const TRACE_LEVEL: i32 = 4;
189 const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
190 const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
191
192 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
193