blob: f21d50c08ba021a2294da11786201ec142c5c6cd [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
use optee_teec::{Context, Operation, Session, Uuid};
use optee_teec::{ParamNone, ParamTmpRef, ParamType, ParamValue};
use proto::{Command, UUID};
use std::io::Read;
use std::io::Write;
use std::net::{TcpListener, TcpStream};
const MAX_PAYLOAD: u16 = 16384 + 2048;
const HEADER_SIZE: u16 = 1 + 2 + 2;
pub const MAX_WIRE_SIZE: usize = (MAX_PAYLOAD + HEADER_SIZE) as usize;
fn main() -> optee_teec::Result<()> {
let mut ctx = Context::new()?;
let uuid = Uuid::parse_str(UUID).unwrap();
let mut ta_session = ctx.open_session(uuid)?;
let mut session_id: u32 = 0;
println!("listening");
let listener = TcpListener::bind("0.0.0.0:4433").unwrap();
for stream in listener.incoming() {
session_id += 1;
handle_client(&mut ta_session, session_id, stream.unwrap())?;
}
println!("Success");
Ok(())
}
fn new_tls_session(ta_session: &mut Session, session_id: u32) -> optee_teec::Result<()> {
let p0 = ParamValue::new(session_id, 0, ParamType::ValueInput);
let mut operation = Operation::new(0, p0, ParamNone, ParamNone, ParamNone);
ta_session.invoke_command(Command::NewTlsSession as u32, &mut operation)?;
Ok(())
}
fn close_tls_session(ta_session: &mut Session, session_id: u32) -> optee_teec::Result<()> {
let p0 = ParamValue::new(session_id, 0, ParamType::ValueInput);
let mut operation = Operation::new(0, p0, ParamNone, ParamNone, ParamNone);
ta_session.invoke_command(Command::CloseTlsSession as u32, &mut operation)?;
Ok(())
}
fn do_tls_read(
ta_session: &mut Session,
session_id: u32,
buf: &mut [u8],
) -> optee_teec::Result<()> {
let p0 = ParamValue::new(session_id, 0, ParamType::ValueInput);
let p1 = ParamTmpRef::new_input(buf);
let mut operation = Operation::new(0, p0, p1, ParamNone, ParamNone);
ta_session.invoke_command(Command::DoTlsRead as u32, &mut operation)?;
Ok(())
}
fn do_tls_write(
ta_session: &mut Session,
session_id: u32,
buf: &mut [u8],
) -> optee_teec::Result<usize> {
let p0 = ParamValue::new(session_id, 0, ParamType::ValueInput);
let p1 = ParamTmpRef::new_output(buf);
let p2 = ParamValue::new(0, 0, ParamType::ValueOutput);
let mut operation = Operation::new(0, p0, p1, p2, ParamNone);
ta_session.invoke_command(Command::DoTlsWrite as u32, &mut operation)?;
Ok(operation.parameters().2.a() as usize)
}
fn handle_client(
ta_session: &mut Session,
session_id: u32,
mut stream: TcpStream,
) -> optee_teec::Result<()> {
println!("new session");
new_tls_session(ta_session, session_id)?;
loop {
let mut buf = [0u8; MAX_WIRE_SIZE];
println!("stream read");
match stream.read(&mut buf) {
Ok(0) | Err(_) => {
println!("close session");
close_tls_session(ta_session, session_id)?;
break;
}
Ok(n) => {
println!("read bytes: {}", n);
do_tls_read(ta_session, session_id, &mut buf[..n])?
}
}
let n = do_tls_write(ta_session, session_id, &mut buf)?;
println!("stream write n: {}", n);
let res = stream.write_all(&buf[..n]);
if res.is_err() {
println!("close session");
close_tls_session(ta_session, session_id)?;
break;
}
}
Ok(())
}