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::{
19 Context, Operation, ParamNone, ParamTmpRef, ParamType, ParamValue, Session, Uuid,
20 };
21 use proto::{Algo, Command, KeySize, Mode, UUID};
22
23 const AES_TEST_BUFFER_SIZE: usize = 4096;
24 const AES_TEST_KEY_SIZE: usize = 16;
25 const AES_BLOCK_SIZE: usize = 16;
26
27 const DECODE: i8 = 0;
28 const ENCODE: i8 = 1;
29
prepare_aes(session: &mut Session, encode: i8) -> optee_teec::Result<()>30 fn prepare_aes(session: &mut Session, encode: i8) -> optee_teec::Result<()> {
31 let p2_value = if encode == ENCODE {
32 Mode::Encode as u32
33 } else {
34 Mode::Decode as u32
35 };
36 let p0 = ParamValue::new(Algo::CTR as u32, 0, ParamType::ValueInput);
37 let p1 = ParamValue::new(KeySize::Bit128 as u32, 0, ParamType::ValueInput);
38 let p2 = ParamValue::new(p2_value, 0, ParamType::ValueInput);
39 let mut operation = Operation::new(0, p0, p1, p2, ParamNone);
40
41 session.invoke_command(Command::Prepare as u32, &mut operation)?;
42
43 Ok(())
44 }
45
set_key(session: &mut Session, key: &[u8]) -> optee_teec::Result<()>46 fn set_key(session: &mut Session, key: &[u8]) -> optee_teec::Result<()> {
47 let p0 = ParamTmpRef::new_input(key);
48 let mut operation = Operation::new(0, p0, ParamNone, ParamNone, ParamNone);
49
50 session.invoke_command(Command::SetKey as u32, &mut operation)?;
51
52 Ok(())
53 }
54
set_iv(session: &mut Session, iv: &[u8]) -> optee_teec::Result<()>55 fn set_iv(session: &mut Session, iv: &[u8]) -> optee_teec::Result<()> {
56 let p0 = ParamTmpRef::new_input(iv);
57 let mut operation = Operation::new(0, p0, ParamNone, ParamNone, ParamNone);
58 session.invoke_command(Command::SetIV as u32, &mut operation)?;
59
60 Ok(())
61 }
62
cipher_buffer( session: &mut Session, intext: &[u8], outtext: &mut [u8], ) -> optee_teec::Result<()>63 fn cipher_buffer(
64 session: &mut Session,
65 intext: &[u8],
66 outtext: &mut [u8],
67 ) -> optee_teec::Result<()> {
68 let p0 = ParamTmpRef::new_input(intext);
69 let p1 = ParamTmpRef::new_output(outtext);
70 let mut operation = Operation::new(0, p0, p1, ParamNone, ParamNone);
71
72 session.invoke_command(Command::Cipher as u32, &mut operation)?;
73
74 Ok(())
75 }
76
main() -> optee_teec::Result<()>77 fn main() -> optee_teec::Result<()> {
78 let mut ctx = Context::new()?;
79 let uuid = Uuid::parse_str(UUID).unwrap();
80 let mut session = ctx.open_session(uuid)?;
81
82 let key = [0xa5u8; AES_TEST_KEY_SIZE];
83 let iv = [0x00u8; AES_BLOCK_SIZE];
84 let clear = [0x5au8; AES_TEST_BUFFER_SIZE];
85 let mut ciph = [0x00u8; AES_TEST_BUFFER_SIZE];
86 let mut tmp = [0x00u8; AES_TEST_BUFFER_SIZE];
87
88 println!("Prepare encode operation");
89 prepare_aes(&mut session, ENCODE)?;
90
91 println!("Load key in TA");
92 set_key(&mut session, &key)?;
93
94 println!("Reset ciphering operation in TA (provides the initial vector)");
95 set_iv(&mut session, &iv)?;
96
97 println!("Encode buffer from TA");
98 cipher_buffer(&mut session, &clear, &mut ciph)?;
99
100 println!("Prepare decode operation");
101 prepare_aes(&mut session, DECODE)?;
102
103 let key = [0xa5u8; AES_TEST_KEY_SIZE];
104 println!("Load key in TA");
105 set_key(&mut session, &key)?;
106
107 let iv = [0x00u8; AES_BLOCK_SIZE];
108 println!("Reset ciphering operation in TA (provides the initial vector)");
109 set_iv(&mut session, &iv)?;
110
111 println!("Decode buffer from TA");
112 cipher_buffer(&mut session, &ciph, &mut tmp)?;
113
114 if clear.iter().zip(tmp.iter()).all(|(a, b)| a == b) {
115 println!("Clear text and decoded text match");
116 } else {
117 println!("Clear text and decoded text differ => ERROR");
118 }
119 Ok(())
120 }
121