This is an automated email from the ASF dual-hosted git repository. ivila pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/incubator-teaclave-trustzone-sdk.git
commit 4069aacc76185374d7c9bf21240064a2bbbf6102 Author: ivila <[email protected]> AuthorDate: Tue Mar 25 11:18:14 2025 +0800 examples: add client_pool-rs Signed-off-by: Zehui Chen <[email protected]> Reviewed-by: Yuan Zhuang <[email protected]> --- ci/ci.sh | 1 + docs/overview-of-optee-rust-examples.md | 1 + ci/ci.sh => examples/client_pool-rs/Makefile | 50 ++++-------- .../client_pool-rs/host/Cargo.toml | 54 +++++------- ci/ci.sh => examples/client_pool-rs/host/Makefile | 56 +++++-------- examples/client_pool-rs/host/src/main.rs | 48 +++++++++++ .../client_pool-rs/host/src/pool/connection.rs | 94 +++++++++++++++++++++ examples/client_pool-rs/host/src/pool/mobc_pool.rs | 93 +++++++++++++++++++++ examples/client_pool-rs/host/src/pool/mod.rs | 44 ++++++++++ examples/client_pool-rs/host/src/pool/r2d2_pool.rs | 95 ++++++++++++++++++++++ .../client_pool-rs/proto/Cargo.toml | 45 +++------- examples/client_pool-rs/proto/src/lib.rs | 36 ++++++++ ci/ci.sh => examples/client_pool-rs/ta/Cargo.toml | 53 +++++------- examples/client_pool-rs/ta/Makefile | 45 ++++++++++ ci/ci.sh => examples/client_pool-rs/ta/Xargo.toml | 41 ++-------- examples/client_pool-rs/ta/build.rs | 23 ++++++ examples/client_pool-rs/ta/src/main.rs | 81 ++++++++++++++++++ examples/client_pool-rs/uuid.txt | 1 + ci/ci.sh => tests/test_client_pool.sh | 50 +++++------- 19 files changed, 677 insertions(+), 234 deletions(-) diff --git a/ci/ci.sh b/ci/ci.sh index 8281081..6016891 100755 --- a/ci/ci.sh +++ b/ci/ci.sh @@ -37,6 +37,7 @@ pushd ../tests ./test_error_handling.sh ./test_tcp_client.sh ./test_udp_socket.sh +./test_client_pool.sh # Run std only tests if [ "$STD" ]; then diff --git a/docs/overview-of-optee-rust-examples.md b/docs/overview-of-optee-rust-examples.md index e731cb7..c440eb2 100644 --- a/docs/overview-of-optee-rust-examples.md +++ b/docs/overview-of-optee-rust-examples.md @@ -36,3 +36,4 @@ To compile one of the examples, run `make -C examples/EXAMPLE_DIR`. | tls_server-rs | `69547de6-f47e-11eb-994e-f34e88d5c2b4` | Set up the TLS server in Trusted Application. | | secure_db_abstraction-rs | `e55291e1-521c-4dca-aa24-51e34ab32ad9` | An abstraction of database base on Secure Storage. | | mnist-rs | Train: `1b5f5b74-e9cf-4e62-8c3e-7e41da6d76f6` <br/> Infer: `ff09aa8a-fbb9-4734-ae8c-d7cd1a3f6744` | Training and Performing Inference in Trusted Application. | +| client_pool-rs | `c9d73f40-ba45-4315-92c4-cf1255958729` | Generic Client Session Pool. | diff --git a/ci/ci.sh b/examples/client_pool-rs/Makefile old mode 100755 new mode 100644 similarity index 56% copy from ci/ci.sh copy to examples/client_pool-rs/Makefile index 8281081..a7a3dec --- a/ci/ci.sh +++ b/examples/client_pool-rs/Makefile @@ -1,5 +1,3 @@ -#!/bin/bash - # 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 @@ -17,37 +15,25 @@ # specific language governing permissions and limitations # under the License. -set -xe +# If _HOST or _TA specific compiler/target are not specified, then use common +# compiler/target for both +CROSS_COMPILE_HOST ?= aarch64-linux-gnu- +CROSS_COMPILE_TA ?= aarch64-linux-gnu- +TARGET_HOST ?= aarch64-unknown-linux-gnu +TARGET_TA ?= aarch64-unknown-linux-gnu + +.PHONY: host ta all clean -pushd ../tests +all: host ta -./test_hello_world.sh -./test_random.sh -./test_secure_storage.sh -./test_aes.sh -./test_hotp.sh -./test_acipher.sh -./test_big_int.sh -./test_diffie_hellman.sh -./test_digest.sh -./test_authentication.sh -./test_time.sh -./test_signature_verification.sh -./test_supp_plugin.sh -./test_error_handling.sh -./test_tcp_client.sh -./test_udp_socket.sh +host: + $(q)make -C host TARGET=$(TARGET_HOST) \ + CROSS_COMPILE=$(CROSS_COMPILE_HOST) -# Run std only tests -if [ "$STD" ]; then - ./test_serde.sh - ./test_message_passing_interface.sh - ./test_tls_client.sh - ./test_tls_server.sh - ./test_eth_wallet.sh - ./test_secure_db_abstraction.sh -else - ./test_mnist_rs.sh -fi +ta: + $(q)make -C ta TARGET=$(TARGET_TA) \ + CROSS_COMPILE=$(CROSS_COMPILE_TA) -popd +clean: + $(q)make -C host clean + $(q)make -C ta clean diff --git a/ci/ci.sh b/examples/client_pool-rs/host/Cargo.toml old mode 100755 new mode 100644 similarity index 54% copy from ci/ci.sh copy to examples/client_pool-rs/host/Cargo.toml index 8281081..2da4c9c --- a/ci/ci.sh +++ b/examples/client_pool-rs/host/Cargo.toml @@ -1,5 +1,3 @@ -#!/bin/bash - # 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 @@ -17,37 +15,25 @@ # specific language governing permissions and limitations # under the License. -set -xe - -pushd ../tests - -./test_hello_world.sh -./test_random.sh -./test_secure_storage.sh -./test_aes.sh -./test_hotp.sh -./test_acipher.sh -./test_big_int.sh -./test_diffie_hellman.sh -./test_digest.sh -./test_authentication.sh -./test_time.sh -./test_signature_verification.sh -./test_supp_plugin.sh -./test_error_handling.sh -./test_tcp_client.sh -./test_udp_socket.sh +[package] +name = "client_pool-rs" +version = "0.4.0" +authors = ["Teaclave Contributors <[email protected]>"] +license = "Apache-2.0" +repository = "https://github.com/apache/incubator-teaclave-trustzone-sdk.git" +description = "An example of Rust OP-TEE TrustZone SDK." +edition = "2018" -# Run std only tests -if [ "$STD" ]; then - ./test_serde.sh - ./test_message_passing_interface.sh - ./test_tls_client.sh - ./test_tls_server.sh - ./test_eth_wallet.sh - ./test_secure_db_abstraction.sh -else - ./test_mnist_rs.sh -fi +[dependencies] +proto = { path = "../proto" } +optee-teec = { path = "../../../optee-teec" } +r2d2 = "0.8.10" +clap = { version = "4.5.32", features = ["derive"] } +anyhow = "1.0.97" +hex = "0.4.3" +mobc = "0.8.5" +tokio = { version = "1.44.1", features = ["rt-multi-thread", "sync"] } +strum = { version = "0.27.1", features = ["derive"] } -popd +[profile.release] +lto = true diff --git a/ci/ci.sh b/examples/client_pool-rs/host/Makefile old mode 100755 new mode 100644 similarity index 56% copy from ci/ci.sh copy to examples/client_pool-rs/host/Makefile index 8281081..9f5117f --- a/ci/ci.sh +++ b/examples/client_pool-rs/host/Makefile @@ -1,5 +1,3 @@ -#!/bin/bash - # 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 @@ -17,37 +15,23 @@ # specific language governing permissions and limitations # under the License. -set -xe - -pushd ../tests - -./test_hello_world.sh -./test_random.sh -./test_secure_storage.sh -./test_aes.sh -./test_hotp.sh -./test_acipher.sh -./test_big_int.sh -./test_diffie_hellman.sh -./test_digest.sh -./test_authentication.sh -./test_time.sh -./test_signature_verification.sh -./test_supp_plugin.sh -./test_error_handling.sh -./test_tcp_client.sh -./test_udp_socket.sh - -# Run std only tests -if [ "$STD" ]; then - ./test_serde.sh - ./test_message_passing_interface.sh - ./test_tls_client.sh - ./test_tls_server.sh - ./test_eth_wallet.sh - ./test_secure_db_abstraction.sh -else - ./test_mnist_rs.sh -fi - -popd +NAME := client_pool-rs + +TARGET ?= aarch64-unknown-linux-gnu +CROSS_COMPILE ?= aarch64-linux-gnu- +OBJCOPY := $(CROSS_COMPILE)objcopy +LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\" + +OUT_DIR := $(CURDIR)/target/$(TARGET)/release + + +all: host strip + +host: + @cargo build --target $(TARGET_HOST) --release --config $(LINKER_CFG) + +strip: host + @$(OBJCOPY) --strip-unneeded $(OUT_DIR)/$(NAME) $(OUT_DIR)/$(NAME) + +clean: + @cargo clean diff --git a/examples/client_pool-rs/host/src/main.rs b/examples/client_pool-rs/host/src/main.rs new file mode 100644 index 0000000..2abccff --- /dev/null +++ b/examples/client_pool-rs/host/src/main.rs @@ -0,0 +1,48 @@ +// 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. + +mod pool; + +use clap::{Parser, Subcommand}; + +/// A program that demonstrates the TEEC_Session pool in both threading and +/// async scenarios. +#[derive(Parser)] +#[command(version, long_about)] +struct Cli { + #[command(subcommand)] + command: Commands, +} + +#[derive(Subcommand)] +enum Commands { + /// Test an r2d2 connection pool with each task running in its own thread. + #[command(long_about)] + Thread(pool::Args), + /// Test a mobc connection pool with each task running in a Tokio async + /// task. + #[command(long_about)] + Async(pool::Args), +} + +fn main() -> anyhow::Result<()> { + let args = Cli::parse(); + match args.command { + Commands::Thread(args) => pool::r2d2_pool::run(args), + Commands::Async(args) => pool::mobc_pool::run(args), + } +} diff --git a/examples/client_pool-rs/host/src/pool/connection.rs b/examples/client_pool-rs/host/src/pool/connection.rs new file mode 100644 index 0000000..2e604a4 --- /dev/null +++ b/examples/client_pool-rs/host/src/pool/connection.rs @@ -0,0 +1,94 @@ +// 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, Error, ErrorKind, ErrorOrigin, Operation, Param, Session, Uuid}; +use optee_teec::{ParamNone, ParamTmpRef, ParamType, ParamValue}; +use proto::Command; + +pub struct Connection { + session: Session, + identity: [u8; proto::IDENTITY_SIZE], + last_err: Option<Error>, +} + +impl Connection { + pub fn new(ctx: &mut Context, uuid: Uuid) -> optee_teec::Result<Self> { + let mut identity = [0_u8; proto::IDENTITY_SIZE]; + let session = { + let mut operation = Operation::new( + 0, + ParamTmpRef::new_output(&mut identity), + ParamNone, + ParamNone, + ParamNone, + ); + ctx.open_session_with_operation(uuid, &mut operation)? + }; + Ok(Connection { + session, + identity, + last_err: None, + }) + } + + pub fn invoke_command<A: Param, B: Param, C: Param, D: Param>( + &mut self, + command_id: u32, + operation: &mut Operation<A, B, C, D>, + ) -> optee_teec::Result<()> { + let result = self.session.invoke_command(command_id, operation); + self.last_err = result.clone().err(); + result + } + + pub fn identity(&self) -> &[u8] { + &self.identity + } + + // Check if this session still valid. + // We currently consider the session valid unless it is marked as dead. + // So if the command returns ErrorKind::TargetDead and ErrorOrigin is not + // the TA, the session is not valid anymore. + // + // One of the scenario is: + // Refer to "TEE Internal Core API Specification – Public Release v1.3.1" + // - From the client’s point of view, when a Trusted Application + // panics, the client commands SHALL return the error + // TEE_ERROR_TARGET_DEAD with an origin value of TEE_ORIGIN_TEE + // until the session is closed. + pub fn valid(&self) -> optee_teec::Result<()> { + if let Some(err) = self.last_err.as_ref() { + if err.kind() == ErrorKind::TargetDead + && err.origin().is_some_and(|x| x != ErrorOrigin::TA) + { + return Err(err.clone()); + } + } + Ok(()) + } +} + +pub fn tee_wait(session: &mut Connection, milliseconds: u32) -> optee_teec::Result<()> { + let mut operation = Operation::new( + Command::Sleep as u32, + ParamValue::new(milliseconds, 0, ParamType::ValueInput), + ParamNone, + ParamNone, + ParamNone, + ); + session.invoke_command(0, &mut operation) +} diff --git a/examples/client_pool-rs/host/src/pool/mobc_pool.rs b/examples/client_pool-rs/host/src/pool/mobc_pool.rs new file mode 100644 index 0000000..3dc8206 --- /dev/null +++ b/examples/client_pool-rs/host/src/pool/mobc_pool.rs @@ -0,0 +1,93 @@ +// 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 super::{ + connection::{tee_wait, Connection}, + Args, +}; +use optee_teec::{Context, ErrorKind, Uuid}; +use std::{ + sync::{atomic, Arc, Mutex}, + time::Duration, +}; + +struct Manager { + ctx: Arc<Mutex<Context>>, + uuid: Uuid, +} + +#[mobc::async_trait] +impl mobc::Manager for Manager { + type Error = optee_teec::Error; + type Connection = Connection; + + async fn connect(&self) -> Result<Self::Connection, Self::Error> { + let mut guard = self.ctx.lock().map_err(|err| { + eprintln!("mobc: cannot acquire lock due to {:#?}", err); + ErrorKind::BadState + })?; + Connection::new(&mut guard, self.uuid.clone()) + } + + async fn check(&self, conn: Self::Connection) -> Result<Self::Connection, Self::Error> { + conn.valid().map(|_| conn) + } +} + +fn new_pool(args: &Args) -> anyhow::Result<mobc::Pool<Manager>> { + let manager = Manager { + ctx: Arc::new(Mutex::new(Context::new()?)), + uuid: Uuid::parse_str(proto::UUID)?, + }; + Ok(mobc::Builder::new() + .max_idle(0) + .max_open(args.pool_capacity as u64) + .build(manager)) +} + +pub fn run(args: Args) -> anyhow::Result<()> { + let pool = new_pool(&args)?; + let runtime = tokio::runtime::Runtime::new()?; + let finish_counter = Arc::new(atomic::AtomicU64::new(0)); + + for i in 0..args.concurrency { + let pool = pool.clone(); + let finish_counter = finish_counter.clone(); + let ta_wait_timeout = args.ta_wait_timeout; + + let _task: tokio::task::JoinHandle<anyhow::Result<()>> = runtime.spawn(async move { + let mut session = pool.get().await?; + tee_wait(&mut session, ta_wait_timeout)?; + finish_counter.fetch_add(1, atomic::Ordering::Relaxed); + println!( + "mobc: {}: {} finish", + i, + hex::encode_upper(session.identity()) + ); + Ok(()) + }); + } + + std::thread::sleep(Duration::from_millis(args.execution_timeout as u64)); + println!( + "mobc: total tasks: {}, total finish: {}", + args.concurrency, + finish_counter.load(atomic::Ordering::Relaxed) + ); + + Ok(()) +} diff --git a/examples/client_pool-rs/host/src/pool/mod.rs b/examples/client_pool-rs/host/src/pool/mod.rs new file mode 100644 index 0000000..f4ea8fc --- /dev/null +++ b/examples/client_pool-rs/host/src/pool/mod.rs @@ -0,0 +1,44 @@ +// 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. + +mod connection; +pub mod mobc_pool; +pub mod r2d2_pool; + +use clap::Parser; + +#[derive(Debug, Parser)] +#[command(about = None, long_about)] +pub struct Args { + /// The duration of the REE wait time, which the REE waits for all tasks to + /// complete. + #[arg(short, long, default_value_t = 1500)] + execution_timeout: u32, + + /// The duration of the TEE wait time, which a TEEC_Session is holding. + #[arg(short, long, default_value_t = 1000)] + ta_wait_timeout: u32, + + /// The capacity of the TEEC_Session pool. + #[arg(short, long, default_value_t = 10)] + pool_capacity: u32, + + /// The total number of tasks running concurrently, with each task holding a + /// TEEC_Session for approximately ${ta_wait_timeout}. + #[arg(short, long, default_value_t = 10)] + concurrency: u64, +} diff --git a/examples/client_pool-rs/host/src/pool/r2d2_pool.rs b/examples/client_pool-rs/host/src/pool/r2d2_pool.rs new file mode 100644 index 0000000..22bef95 --- /dev/null +++ b/examples/client_pool-rs/host/src/pool/r2d2_pool.rs @@ -0,0 +1,95 @@ +// 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 super::{ + connection::{tee_wait, Connection}, + Args, +}; +use optee_teec::{Context, ErrorKind, Uuid}; +use std::{ + sync::{atomic, Arc, Mutex}, + thread, + time::Duration, +}; + +struct Manager { + ctx: Mutex<Context>, + uuid: Uuid, +} + +impl r2d2::ManageConnection for Manager { + type Error = optee_teec::Error; + type Connection = Connection; + + fn connect(&self) -> Result<Self::Connection, Self::Error> { + let mut guard = self.ctx.lock().map_err(|err| { + eprintln!("r2d2: cannot acquire lock due to {:#?}", err); + ErrorKind::BadState + })?; + Connection::new(&mut guard, self.uuid.clone()) + } + + fn is_valid(&self, conn: &mut Self::Connection) -> Result<(), Self::Error> { + conn.valid() + } + + fn has_broken(&self, conn: &mut Self::Connection) -> bool { + conn.valid().is_err() + } +} + +fn new_pool(args: &Args) -> Result<r2d2::Pool<Manager>, anyhow::Error> { + let manager = Manager { + ctx: Mutex::new(Context::new()?), + uuid: Uuid::parse_str(proto::UUID)?, + }; + + Ok(r2d2::Pool::builder() + .max_size(args.pool_capacity) + .build(manager)?) +} + +pub fn run(args: Args) -> anyhow::Result<()> { + let pool = new_pool(&args)?; + let finish_counter = Arc::new(atomic::AtomicU64::new(0)); + + for i in 0..args.concurrency { + let pool = pool.clone(); + let finish_counter = finish_counter.clone(); + let ta_wait_timeout = args.ta_wait_timeout; + thread::spawn(move || -> anyhow::Result<()> { + let mut session = pool.get()?; + tee_wait(&mut session, ta_wait_timeout)?; + finish_counter.fetch_add(1, atomic::Ordering::Relaxed); + println!( + "r2d2: {}: {} finish", + i, + hex::encode_upper(session.identity()) + ); + Ok(()) + }); + } + + thread::sleep(Duration::from_millis(args.execution_timeout as u64)); + println!( + "r2d2: total tasks: {}, total finish: {}", + args.concurrency, + finish_counter.load(atomic::Ordering::Relaxed) + ); + + Ok(()) +} diff --git a/ci/ci.sh b/examples/client_pool-rs/proto/Cargo.toml old mode 100755 new mode 100644 similarity index 55% copy from ci/ci.sh copy to examples/client_pool-rs/proto/Cargo.toml index 8281081..91066a3 --- a/ci/ci.sh +++ b/examples/client_pool-rs/proto/Cargo.toml @@ -1,5 +1,3 @@ -#!/bin/bash - # 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 @@ -17,37 +15,14 @@ # specific language governing permissions and limitations # under the License. -set -xe - -pushd ../tests - -./test_hello_world.sh -./test_random.sh -./test_secure_storage.sh -./test_aes.sh -./test_hotp.sh -./test_acipher.sh -./test_big_int.sh -./test_diffie_hellman.sh -./test_digest.sh -./test_authentication.sh -./test_time.sh -./test_signature_verification.sh -./test_supp_plugin.sh -./test_error_handling.sh -./test_tcp_client.sh -./test_udp_socket.sh - -# Run std only tests -if [ "$STD" ]; then - ./test_serde.sh - ./test_message_passing_interface.sh - ./test_tls_client.sh - ./test_tls_server.sh - ./test_eth_wallet.sh - ./test_secure_db_abstraction.sh -else - ./test_mnist_rs.sh -fi +[package] +name = "proto" +version = "0.4.0" +authors = ["Teaclave Contributors <[email protected]>"] +license = "Apache-2.0" +repository = "https://github.com/apache/incubator-teaclave-trustzone-sdk.git" +description = "Data structures and functions shared by host and TA." +edition = "2018" -popd +[dependencies] +num_enum = { version = "0.7.3", default-features = false } diff --git a/examples/client_pool-rs/proto/src/lib.rs b/examples/client_pool-rs/proto/src/lib.rs new file mode 100644 index 0000000..19debb3 --- /dev/null +++ b/examples/client_pool-rs/proto/src/lib.rs @@ -0,0 +1,36 @@ +// 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. + +#![no_std] + +use num_enum::{FromPrimitive, IntoPrimitive}; + +#[derive(FromPrimitive, IntoPrimitive)] +#[repr(u32)] +pub enum Command { + Sleep, + #[default] + Unknown, +} + +// If Uuid::parse_str() returns an InvalidLength error, there may be an extra +// newline in your uuid.txt file. You can remove it by running +// `truncate -s 36 uuid.txt`. +pub const UUID: &str = include_str!("../../uuid.txt"); + +// the size of the identity bytes; +pub const IDENTITY_SIZE: usize = 32; diff --git a/ci/ci.sh b/examples/client_pool-rs/ta/Cargo.toml old mode 100755 new mode 100644 similarity index 54% copy from ci/ci.sh copy to examples/client_pool-rs/ta/Cargo.toml index 8281081..3ecfc6e --- a/ci/ci.sh +++ b/examples/client_pool-rs/ta/Cargo.toml @@ -1,5 +1,3 @@ -#!/bin/bash - # 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 @@ -17,37 +15,26 @@ # specific language governing permissions and limitations # under the License. -set -xe - -pushd ../tests +[package] +name = "ta" +version = "0.4.0" +authors = ["Teaclave Contributors <[email protected]>"] +license = "Apache-2.0" +repository = "https://github.com/apache/incubator-teaclave-trustzone-sdk.git" +description = "An example of Rust OP-TEE TrustZone SDK." +edition = "2018" -./test_hello_world.sh -./test_random.sh -./test_secure_storage.sh -./test_aes.sh -./test_hotp.sh -./test_acipher.sh -./test_big_int.sh -./test_diffie_hellman.sh -./test_digest.sh -./test_authentication.sh -./test_time.sh -./test_signature_verification.sh -./test_supp_plugin.sh -./test_error_handling.sh -./test_tcp_client.sh -./test_udp_socket.sh +[dependencies] +proto = { path = "../proto" } +optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" } +optee-utee = { path = "../../../optee-utee" } +hex = { version = "0.4.3", default-features = false } -# Run std only tests -if [ "$STD" ]; then - ./test_serde.sh - ./test_message_passing_interface.sh - ./test_tls_client.sh - ./test_tls_server.sh - ./test_eth_wallet.sh - ./test_secure_db_abstraction.sh -else - ./test_mnist_rs.sh -fi +[build-dependencies] +proto = { path = "../proto" } +optee-utee-build = { path = "../../../optee-utee-build" } -popd +[profile.release] +panic = "abort" +lto = true +opt-level = 1 diff --git a/examples/client_pool-rs/ta/Makefile b/examples/client_pool-rs/ta/Makefile new file mode 100644 index 0000000..029e66d --- /dev/null +++ b/examples/client_pool-rs/ta/Makefile @@ -0,0 +1,45 @@ +# 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. + +UUID ?= $(shell cat "../uuid.txt") + +TARGET ?= aarch64-unknown-linux-gnu +CROSS_COMPILE ?= aarch64-linux-gnu- +OBJCOPY := $(CROSS_COMPILE)objcopy +# Configure the linker to use GCC, which works on both cross-compilation and ARM machines +LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\" + +TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem +SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py +OUT_DIR := $(CURDIR)/target/$(TARGET)/release + +BUILDER = $(if $(STD),xargo,cargo) + +all: ta strip sign + +ta: + @$(BUILDER) build --target $(TARGET) --release --config $(LINKER_CFG) + +strip: ta + @$(OBJCOPY) --strip-unneeded $(OUT_DIR)/ta $(OUT_DIR)/stripped_ta + +sign: strip + @$(SIGN) --uuid $(UUID) --key $(TA_SIGN_KEY) --in $(OUT_DIR)/stripped_ta --out $(OUT_DIR)/$(UUID).ta + @echo "SIGN => ${UUID}" + +clean: + @cargo clean diff --git a/ci/ci.sh b/examples/client_pool-rs/ta/Xargo.toml old mode 100755 new mode 100644 similarity index 55% copy from ci/ci.sh copy to examples/client_pool-rs/ta/Xargo.toml index 8281081..1b1a113 --- a/ci/ci.sh +++ b/examples/client_pool-rs/ta/Xargo.toml @@ -1,5 +1,3 @@ -#!/bin/bash - # 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 @@ -17,37 +15,10 @@ # specific language governing permissions and limitations # under the License. -set -xe - -pushd ../tests - -./test_hello_world.sh -./test_random.sh -./test_secure_storage.sh -./test_aes.sh -./test_hotp.sh -./test_acipher.sh -./test_big_int.sh -./test_diffie_hellman.sh -./test_digest.sh -./test_authentication.sh -./test_time.sh -./test_signature_verification.sh -./test_supp_plugin.sh -./test_error_handling.sh -./test_tcp_client.sh -./test_udp_socket.sh - -# Run std only tests -if [ "$STD" ]; then - ./test_serde.sh - ./test_message_passing_interface.sh - ./test_tls_client.sh - ./test_tls_server.sh - ./test_eth_wallet.sh - ./test_secure_db_abstraction.sh -else - ./test_mnist_rs.sh -fi +[dependencies.std] +path = "../../../rust/rust/library/std" -popd +[patch.crates-io] +libc = { path = "../../../rust/libc" } +rustc-std-workspace-core = { path = "../../../rust/rust/library/rustc-std-workspace-core" } +rustc-std-workspace-alloc = { path = "../../../rust/rust/library/rustc-std-workspace-alloc" } diff --git a/examples/client_pool-rs/ta/build.rs b/examples/client_pool-rs/ta/build.rs new file mode 100644 index 0000000..1337f93 --- /dev/null +++ b/examples/client_pool-rs/ta/build.rs @@ -0,0 +1,23 @@ +// 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_utee_build::{Error, RustEdition, TaConfig}; + +fn main() -> Result<(), Error> { + let config = TaConfig::new_default_with_cargo_env(proto::UUID)?; + optee_utee_build::build(RustEdition::Before2024, config) +} diff --git a/examples/client_pool-rs/ta/src/main.rs b/examples/client_pool-rs/ta/src/main.rs new file mode 100644 index 0000000..66bcb0a --- /dev/null +++ b/examples/client_pool-rs/ta/src/main.rs @@ -0,0 +1,81 @@ +// 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. + +#![no_std] +#![no_main] +extern crate alloc; + +use alloc::{boxed::Box, string::String}; +use optee_utee::{ + ta_close_session, ta_create, ta_destroy, ta_invoke_command, ta_open_session, trace_println, +}; +use optee_utee::{ErrorKind, Parameters, Result}; +use proto::Command; + +#[ta_create] +fn create() -> Result<()> { + trace_println!("[+] TA create"); + Ok(()) +} + +#[ta_open_session] +fn open_session(params: &mut Parameters, ctx: &mut String) -> Result<()> { + let mut p0 = unsafe { params.0.as_memref()? }; + + let mut buffer = [0_u8; proto::IDENTITY_SIZE]; + optee_utee::Random::generate(&mut buffer); + *ctx = hex::encode(buffer).to_uppercase(); + + trace_println!("[+] TA open session, identity: {}", ctx); + p0.buffer().copy_from_slice(&buffer); + + Ok(()) +} + +#[ta_close_session] +fn close_session(ctx: &mut String) { + trace_println!("[+] TA close session, identity: {}", ctx); +} + +#[ta_destroy] +fn destroy() { + trace_println!("[+] TA destroy"); +} + +#[ta_invoke_command] +fn invoke_command(ctx: &mut String, cmd_id: u32, params: &mut Parameters) -> Result<()> { + match Command::from(cmd_id) { + Command::Sleep => { + let values = unsafe { params.0.as_value()? }; + + let milliseconds = values.a(); + let mut now = optee_utee::Time::new(); + now.system_time(); + // this would cause messy output in the console when running concurrently. + trace_println!( + "[+] TA {} wait for {} milliseconds at {}", + ctx, + milliseconds, + now.seconds * 1000 + now.millis + ); + optee_utee::Time::wait(milliseconds) + } + Command::Unknown => Err(ErrorKind::BadParameters.into()), + } +} + +include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs")); diff --git a/examples/client_pool-rs/uuid.txt b/examples/client_pool-rs/uuid.txt new file mode 100644 index 0000000..1f96819 --- /dev/null +++ b/examples/client_pool-rs/uuid.txt @@ -0,0 +1 @@ +c9d73f40-ba45-4315-92c4-cf1255958729 \ No newline at end of file diff --git a/ci/ci.sh b/tests/test_client_pool.sh similarity index 55% copy from ci/ci.sh copy to tests/test_client_pool.sh index 8281081..0569d2b 100755 --- a/ci/ci.sh +++ b/tests/test_client_pool.sh @@ -19,35 +19,27 @@ set -xe -pushd ../tests +# Include base script +source setup.sh -./test_hello_world.sh -./test_random.sh -./test_secure_storage.sh -./test_aes.sh -./test_hotp.sh -./test_acipher.sh -./test_big_int.sh -./test_diffie_hellman.sh -./test_digest.sh -./test_authentication.sh -./test_time.sh -./test_signature_verification.sh -./test_supp_plugin.sh -./test_error_handling.sh -./test_tcp_client.sh -./test_udp_socket.sh +# Copy TA and host binary +cp ../examples/client_pool-rs/ta/target/$TARGET_TA/release/*.ta shared +cp ../examples/client_pool-rs/host/target/$TARGET_HOST/release/client_pool-rs shared -# Run std only tests -if [ "$STD" ]; then - ./test_serde.sh - ./test_message_passing_interface.sh - ./test_tls_client.sh - ./test_tls_server.sh - ./test_eth_wallet.sh - ./test_secure_db_abstraction.sh -else - ./test_mnist_rs.sh -fi +# Run script specific commands in QEMU +run_in_qemu "cp *.ta /lib/optee_armtz/\n" +run_in_qemu "./client_pool-rs thread -p 2 -c 2\n" +run_in_qemu "./client_pool-rs async -p 2 -c 2\n" +run_in_qemu "^C" -popd +# Script specific checks +{ + grep -q "r2d2: total tasks: 2, total finish: 2" screenlog.0 && + grep -q "mobc: total tasks: 2, total finish: 2" screenlog.0 +} || { + cat -v screenlog.0 + cat -v /tmp/serial.log + false +} + +rm screenlog.0 --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
