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 proto;
19 use url;
20 use optee_teec::{Context, Uuid, ParamType, ParamTmpRef, ParamValue, ParamNone, Operation};
21
22 type Result<T> = optee_teec::Result<T>;
23
24 pub struct EnclaveClient {
25 uuid: String,
26 context: optee_teec::Context,
27 buffer: Vec<u8>
28 }
29
30 impl EnclaveClient {
open(url: &str) -> Result<Self>31 pub fn open(url: &str) -> Result<Self> {
32 let url = url::Url::parse(url).unwrap();
33 match url.scheme() {
34 "trustzone-enclave" => {
35 Self::open_uuid(url.host_str().unwrap())
36 },
37 _ => unimplemented!(),
38 }
39 }
40
open_uuid(uuid: &str) -> Result<Self>41 fn open_uuid(uuid: &str) -> Result<Self> {
42 let context = Context::new()?;
43 Ok(Self {
44 uuid: uuid.to_string(),
45 context: context,
46 buffer: vec![0; 128]
47 })
48 }
49
invoke(&mut self, input: &proto::EnclaveInput) -> Result<proto::EnclaveOutput>50 pub fn invoke(&mut self, input: &proto::EnclaveInput) -> Result<proto::EnclaveOutput> {
51 let command_id = input.command as u32;
52 let mut serialized_input = proto::serde_json::to_vec(input).unwrap();
53
54 let p0 = ParamTmpRef::new_input(serialized_input.as_mut_slice());
55 let p1 = ParamTmpRef::new_output(&mut self.buffer);
56 let p2 = ParamValue::new(0, 0, ParamType::ValueInout);
57
58 let mut operation = Operation::new(0, p0, p1, p2, ParamNone);
59
60 let uuid = Uuid::parse_str(&self.uuid).unwrap();
61 let mut session = self.context.open_session(uuid)?;
62 session.invoke_command(command_id, &mut operation)?;
63 let len = operation.parameters().2.a() as usize;
64
65 let output: proto::EnclaveOutput = proto::serde_json::from_slice(&self.buffer[0..len]).unwrap();
66 Ok(output)
67 }
68 }
69
main() -> optee_teec::Result<()>70 fn main() -> optee_teec::Result<()> {
71 let url = format!("trustzone-enclave://{}", proto::UUID);
72 let mut enclave = EnclaveClient::open(&url).unwrap();
73 let input = proto::EnclaveInput {
74 command: proto::Command::Hello,
75 message: String::from("World!")
76 };
77 let output = enclave.invoke(&input).unwrap();
78 println!("{:?}", output);
79
80 Ok(())
81 }
82