You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@teaclave.apache.org by yu...@apache.org on 2024/10/25 03:42:18 UTC

(incubator-teaclave-trustzone-sdk) 01/07: Add std-only examples

This is an automated email from the ASF dual-hosted git repository.

yuanz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave-trustzone-sdk.git

commit 62445d4dcc04bd5992186adaf461d29d9c271799
Author: Yuan Zhuang <yu...@apache.org>
AuthorDate: Mon Oct 14 09:16:01 2024 +0000

    Add std-only examples
---
 .licenserc.yaml                                    |   1 +
 ci/ci.sh                                           |  10 ++
 environment                                        |   2 +-
 .../message_passing_interface-rs/Makefile          |  34 ++--
 .../message_passing_interface-rs/host/Cargo.toml   |  34 ++--
 .../message_passing_interface-rs/host/Makefile     |  43 +++--
 .../message_passing_interface-rs/host/src/main.rs  |  80 +++++++++
 .../message_passing_interface-rs/proto/Cargo.toml  |  33 ++--
 .../message_passing_interface-rs/proto/build.rs    |  36 +++++
 .../message_passing_interface-rs/proto/src/lib.rs  |  51 ++++++
 .../message_passing_interface-rs/ta/Cargo.toml     |  38 ++---
 examples/message_passing_interface-rs/ta/Makefile  |  49 ++++++
 .../message_passing_interface-rs/ta/Xargo.toml     |  20 +--
 examples/message_passing_interface-rs/ta/build.rs  | 103 ++++++++++++
 .../message_passing_interface-rs/ta/src/main.rs    |  97 +++++++++++
 .../message_passing_interface-rs/ta/ta_static.rs   | 102 ++++++++++++
 examples/message_passing_interface-rs/uuid.txt     |   1 +
 ci/ci.sh => examples/serde-rs/Makefile             |  34 ++--
 ci/ci.sh => examples/serde-rs/host/Cargo.toml      |  35 ++--
 ci/ci.sh => examples/serde-rs/host/Makefile        |  43 +++--
 examples/serde-rs/host/src/main.rs                 |  51 ++++++
 ci/ci.sh => examples/serde-rs/proto/Cargo.toml     |  31 ++--
 examples/serde-rs/proto/build.rs                   |  36 +++++
 examples/serde-rs/proto/src/lib.rs                 |  33 ++++
 ci/ci.sh => examples/serde-rs/ta/Cargo.toml        |  40 ++---
 examples/serde-rs/ta/Makefile                      |  49 ++++++
 .licenserc.yaml => examples/serde-rs/ta/Xargo.toml |  20 +--
 examples/serde-rs/ta/build.rs                      | 103 ++++++++++++
 examples/serde-rs/ta/src/main.rs                   | 102 ++++++++++++
 examples/serde-rs/ta/ta_static.rs                  | 102 ++++++++++++
 examples/serde-rs/uuid.txt                         |   1 +
 ci/ci.sh => examples/tcp_client-rs/Makefile        |  34 ++--
 ci/ci.sh => examples/tcp_client-rs/host/Cargo.toml |  34 ++--
 ci/ci.sh => examples/tcp_client-rs/host/Makefile   |  42 +++--
 examples/tcp_client-rs/host/src/main.rs            |  37 +++++
 .../tcp_client-rs/proto/Cargo.toml                 |  31 ++--
 examples/tcp_client-rs/proto/build.rs              |  36 +++++
 examples/tcp_client-rs/proto/src/lib.rs            |  33 ++++
 ci/ci.sh => examples/tcp_client-rs/ta/Cargo.toml   |  38 ++---
 examples/tcp_client-rs/ta/Makefile                 |  49 ++++++
 .../tcp_client-rs/ta/Xargo.toml                    |  20 +--
 examples/tcp_client-rs/ta/build.rs                 | 103 ++++++++++++
 examples/tcp_client-rs/ta/src/main.rs              |  96 +++++++++++
 examples/tcp_client-rs/ta/ta_static.rs             | 102 ++++++++++++
 examples/tcp_client-rs/uuid.txt                    |   1 +
 ci/ci.sh => examples/tls_client-rs/Makefile        |  34 ++--
 ci/ci.sh => examples/tls_client-rs/host/Cargo.toml |  34 ++--
 ci/ci.sh => examples/tls_client-rs/host/Makefile   |  42 +++--
 examples/tls_client-rs/host/src/main.rs            |  37 +++++
 .../tls_client-rs/proto/Cargo.toml                 |  31 ++--
 examples/tls_client-rs/proto/build.rs              |  36 +++++
 examples/tls_client-rs/proto/src/lib.rs            |  33 ++++
 examples/tls_client-rs/ta/Cargo.toml               |  54 +++++++
 examples/tls_client-rs/ta/Makefile                 |  50 ++++++
 .../tls_client-rs/ta/Xargo.toml                    |  20 +--
 examples/tls_client-rs/ta/build.rs                 | 103 ++++++++++++
 examples/tls_client-rs/ta/src/main.rs              | 119 ++++++++++++++
 examples/tls_client-rs/ta/ta_static.rs             | 102 ++++++++++++
 examples/tls_client-rs/uuid.txt                    |   1 +
 ci/ci.sh => examples/tls_server-rs/Makefile        |  34 ++--
 ci/ci.sh => examples/tls_server-rs/host/Cargo.toml |  34 ++--
 ci/ci.sh => examples/tls_server-rs/host/Makefile   |  42 +++--
 examples/tls_server-rs/host/src/main.rs            | 119 ++++++++++++++
 .../tls_server-rs/proto/Cargo.toml                 |  31 ++--
 examples/tls_server-rs/proto/build.rs              |  36 +++++
 examples/tls_server-rs/proto/src/lib.rs            |  39 +++++
 examples/tls_server-rs/ta/Cargo.toml               |  56 +++++++
 examples/tls_server-rs/ta/Makefile                 |  50 ++++++
 .../tls_server-rs/ta/Xargo.toml                    |  20 +--
 examples/tls_server-rs/ta/build.rs                 | 103 ++++++++++++
 examples/tls_server-rs/ta/src/main.rs              | 179 +++++++++++++++++++++
 examples/tls_server-rs/ta/ta_static.rs             | 102 ++++++++++++
 examples/tls_server-rs/ta/test-ca/ecdsa/ca.cert    |  12 ++
 examples/tls_server-rs/ta/test-ca/ecdsa/ca.der     | Bin 0 -> 462 bytes
 examples/tls_server-rs/ta/test-ca/ecdsa/ca.key     |   6 +
 .../tls_server-rs/ta/test-ca/ecdsa/client.cert     |  13 ++
 .../tls_server-rs/ta/test-ca/ecdsa/client.chain    |  24 +++
 .../ta/test-ca/ecdsa/client.fullchain              |  37 +++++
 examples/tls_server-rs/ta/test-ca/ecdsa/client.key |   6 +
 examples/tls_server-rs/ta/test-ca/ecdsa/client.req |   8 +
 examples/tls_server-rs/ta/test-ca/ecdsa/end.cert   |  13 ++
 examples/tls_server-rs/ta/test-ca/ecdsa/end.chain  |  24 +++
 .../tls_server-rs/ta/test-ca/ecdsa/end.fullchain   |  37 +++++
 examples/tls_server-rs/ta/test-ca/ecdsa/end.key    |   5 +
 examples/tls_server-rs/ta/test-ca/ecdsa/end.req    |   7 +
 examples/tls_server-rs/ta/test-ca/ecdsa/inter.cert |  12 ++
 examples/tls_server-rs/ta/test-ca/ecdsa/inter.key  |   5 +
 examples/tls_server-rs/ta/test-ca/ecdsa/inter.req  |   7 +
 .../tls_server-rs/ta/test-ca/ecdsa/nistp256.pem    |   3 +
 .../tls_server-rs/ta/test-ca/ecdsa/nistp384.pem    |   3 +
 examples/tls_server-rs/uuid.txt                    |   1 +
 ci/ci.sh => examples/udp_socket-rs/Makefile        |  34 ++--
 ci/ci.sh => examples/udp_socket-rs/host/Cargo.toml |  34 ++--
 ci/ci.sh => examples/udp_socket-rs/host/Makefile   |  42 +++--
 examples/udp_socket-rs/host/src/main.rs            |  51 ++++++
 .../udp_socket-rs/proto/Cargo.toml                 |  31 ++--
 examples/udp_socket-rs/proto/build.rs              |  36 +++++
 examples/udp_socket-rs/proto/src/lib.rs            |  33 ++++
 ci/ci.sh => examples/udp_socket-rs/ta/Cargo.toml   |  39 ++---
 examples/udp_socket-rs/ta/Makefile                 |  49 ++++++
 .../udp_socket-rs/ta/Xargo.toml                    |  20 +--
 examples/udp_socket-rs/ta/build.rs                 | 103 ++++++++++++
 examples/udp_socket-rs/ta/src/main.rs              |  99 ++++++++++++
 examples/udp_socket-rs/ta/ta_static.rs             | 102 ++++++++++++
 examples/udp_socket-rs/uuid.txt                    |   1 +
 tests/optee-qemuv8.sh                              |   9 +-
 .../test_message_passing_interface.sh              |  36 +++--
 ci/ci.sh => tests/test_serde.sh                    |  39 +++--
 ci/ci.sh => tests/test_tcp_client.sh               |  36 +++--
 ci/ci.sh => tests/test_tls_client.sh               |  37 +++--
 ci/ci.sh => tests/test_tls_server.sh               |  46 +++---
 ci/ci.sh => tests/test_udp_socket.sh               |  36 +++--
 112 files changed, 3995 insertions(+), 752 deletions(-)

diff --git a/.licenserc.yaml b/.licenserc.yaml
index 0391c38..0d6d2dc 100644
--- a/.licenserc.yaml
+++ b/.licenserc.yaml
@@ -30,3 +30,4 @@ header:
     - 'KEYS'
     - 'DISCLAIMER-WIP'
     - '*.json'
+    - 'examples/tls_server-rs/ta/test-ca/**'
diff --git a/ci/ci.sh b/ci/ci.sh
index e530044..da12226 100755
--- a/ci/ci.sh
+++ b/ci/ci.sh
@@ -36,4 +36,14 @@ pushd ../tests
 ./test_supp_plugin.sh
 ./test_error_handling.sh
 
+# Run std only tests
+if [ "$STD" ]; then
+    ./test_serde.sh
+    ./test_message_passing_interface.sh
+    ./test_tcp_client.sh
+    ./test_udp_socket.sh
+    ./test_tls_client.sh
+    ./test_tls_server.sh
+fi
+
 popd
diff --git a/environment b/environment
index 6b89386..c8a82ff 100644
--- a/environment
+++ b/environment
@@ -92,4 +92,4 @@ then
 else
   echo -e "Error: OPTEE_CLIENT_EXPORT=$OPTEE_CLIENT_EXPORT does not exist, please set the correct OPTEE_CLIENT_EXPORT or run \"$ ./build_optee_libraries.sh optee/\" then try again\n"
   unset OPTEE_DIR
-fi
+fi
\ No newline at end of file
diff --git a/ci/ci.sh b/examples/message_passing_interface-rs/Makefile
old mode 100755
new mode 100644
similarity index 61%
copy from ci/ci.sh
copy to examples/message_passing_interface-rs/Makefile
index e530044..c266055
--- a/ci/ci.sh
+++ b/examples/message_passing_interface-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,23 +15,19 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+# 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
 
-./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
+all:
+	$(q)make -C host TARGET_HOST=$(TARGET_HOST) \
+		CROSS_COMPILE_HOST=$(CROSS_COMPILE_HOST)
+	$(q)make -C ta TARGET_TA=$(TARGET_TA) \
+		CROSS_COMPILE_TA=$(CROSS_COMPILE_TA)
 
-popd
+clean:
+	$(q)make -C host clean
+	$(q)make -C ta clean
diff --git a/ci/ci.sh b/examples/message_passing_interface-rs/host/Cargo.toml
old mode 100755
new mode 100644
similarity index 64%
copy from ci/ci.sh
copy to examples/message_passing_interface-rs/host/Cargo.toml
index e530044..27dfc27
--- a/ci/ci.sh
+++ b/examples/message_passing_interface-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,23 +15,19 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+[package]
+name = "message_passing_interface-rs"
+version = "0.3.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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
+[dependencies]
+url = "2.5.0"
+proto = { path = "../proto" }
+optee-teec = { path = "../../../optee-teec" }
 
-popd
+[profile.release]
+lto = true
diff --git a/ci/ci.sh b/examples/message_passing_interface-rs/host/Makefile
old mode 100755
new mode 100644
similarity index 62%
copy from ci/ci.sh
copy to examples/message_passing_interface-rs/host/Makefile
index e530044..94617ea
--- a/ci/ci.sh
+++ b/examples/message_passing_interface-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,23 +15,24 @@
 # 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
-
-popd
+NAME := message_passing_interface-rs
+
+TARGET_HOST ?= aarch64-unknown-linux-gnu
+CROSS_COMPILE_HOST ?= aarch64-linux-gnu-
+OBJCOPY := $(CROSS_COMPILE_HOST)objcopy
+LINKER_CFG := target.$(TARGET_HOST).linker=\"$(CROSS_COMPILE_HOST)gcc\"
+
+OUT_DIR := $(CURDIR)/target/$(TARGET_HOST)/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/message_passing_interface-rs/host/src/main.rs b/examples/message_passing_interface-rs/host/src/main.rs
new file mode 100644
index 0000000..0ba6b8e
--- /dev/null
+++ b/examples/message_passing_interface-rs/host/src/main.rs
@@ -0,0 +1,80 @@
+// 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, ParamNone, ParamTmpRef, ParamType, ParamValue, Uuid};
+use proto;
+use url;
+
+type Result<T> = optee_teec::Result<T>;
+
+pub struct EnclaveClient {
+    uuid: String,
+    context: optee_teec::Context,
+    buffer: Vec<u8>,
+}
+
+impl EnclaveClient {
+    pub fn open(url: &str) -> Result<Self> {
+        let url = url::Url::parse(url).unwrap();
+        match url.scheme() {
+            "trustzone-enclave" => Self::open_uuid(url.host_str().unwrap()),
+            _ => unimplemented!(),
+        }
+    }
+
+    fn open_uuid(uuid: &str) -> Result<Self> {
+        let context = Context::new()?;
+        Ok(Self {
+            uuid: uuid.to_string(),
+            context: context,
+            buffer: vec![0; 128],
+        })
+    }
+
+    pub fn invoke(&mut self, input: &proto::EnclaveInput) -> Result<proto::EnclaveOutput> {
+        let command_id = input.command as u32;
+        let mut serialized_input = proto::serde_json::to_vec(input).unwrap();
+
+        let p0 = ParamTmpRef::new_input(serialized_input.as_mut_slice());
+        let p1 = ParamTmpRef::new_output(&mut self.buffer);
+        let p2 = ParamValue::new(0, 0, ParamType::ValueInout);
+
+        let mut operation = Operation::new(0, p0, p1, p2, ParamNone);
+
+        let uuid = Uuid::parse_str(&self.uuid).unwrap();
+        let mut session = self.context.open_session(uuid)?;
+        session.invoke_command(command_id, &mut operation)?;
+        let len = operation.parameters().2.a() as usize;
+
+        let output: proto::EnclaveOutput =
+            proto::serde_json::from_slice(&self.buffer[0..len]).unwrap();
+        Ok(output)
+    }
+}
+
+fn main() -> optee_teec::Result<()> {
+    let url = format!("trustzone-enclave://{}", proto::UUID);
+    let mut enclave = EnclaveClient::open(&url).unwrap();
+    let input = proto::EnclaveInput {
+        command: proto::Command::Hello,
+        message: String::from("World!"),
+    };
+    let output = enclave.invoke(&input).unwrap();
+    println!("{:?}", output);
+
+    Ok(())
+}
diff --git a/ci/ci.sh b/examples/message_passing_interface-rs/proto/Cargo.toml
old mode 100755
new mode 100644
similarity index 63%
copy from ci/ci.sh
copy to examples/message_passing_interface-rs/proto/Cargo.toml
index e530044..e159de8
--- a/ci/ci.sh
+++ b/examples/message_passing_interface-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,23 +15,18 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+[package]
+name = "proto"
+version = "0.3.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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"
 
-./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
+[dependencies]
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
 
-popd
+[build-dependencies]
+uuid = { version = "1.8", default-features = false }
diff --git a/examples/message_passing_interface-rs/proto/build.rs b/examples/message_passing_interface-rs/proto/build.rs
new file mode 100644
index 0000000..b9d0612
--- /dev/null
+++ b/examples/message_passing_interface-rs/proto/build.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.
+
+use std::fs;
+use std::path::PathBuf;
+use std::fs::File;
+use std::env;
+use std::io::Write;
+
+fn main() {
+    let uuid = match fs::read_to_string("../uuid.txt") {
+        Ok(u) => {
+            u.trim().to_string()
+        },
+        Err(_) => {
+            panic!("Cannot find uuid.txt");
+        }
+    };
+    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+    let mut buffer = File::create(out.join("uuid.txt")).unwrap();
+    write!(buffer, "{}", uuid).unwrap();
+}
diff --git a/examples/message_passing_interface-rs/proto/src/lib.rs b/examples/message_passing_interface-rs/proto/src/lib.rs
new file mode 100644
index 0000000..7c99bdb
--- /dev/null
+++ b/examples/message_passing_interface-rs/proto/src/lib.rs
@@ -0,0 +1,51 @@
+// 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 serde::{Serialize, Deserialize};
+pub use serde_json;
+
+#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
+pub enum Command {
+    Hello,
+    Bye,
+    Unknown,
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+pub struct EnclaveInput {
+    pub command: Command,
+    pub message: String
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+pub struct EnclaveOutput {
+    pub message: String
+}
+
+impl From<u32> for Command {
+    #[inline]
+    fn from(value: u32) -> Command {
+        match value {
+            0 => Command::Hello,
+            1 => Command::Bye,
+            _ => Command::Unknown,
+        }
+    }
+}
+
+
+pub const UUID: &str = &include_str!(concat!(env!("OUT_DIR"), "/uuid.txt"));
diff --git a/ci/ci.sh b/examples/message_passing_interface-rs/ta/Cargo.toml
old mode 100755
new mode 100644
similarity index 56%
copy from ci/ci.sh
copy to examples/message_passing_interface-rs/ta/Cargo.toml
index e530044..bc84153
--- a/ci/ci.sh
+++ b/examples/message_passing_interface-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,23 +15,25 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
+[package]
+name = "ta"
+version = "0.3.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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"
 
-pushd ../tests
+[dependencies]
+proto = { path = "../proto" }
+optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
+optee-utee = { path = "../../../optee-utee" }
 
-./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
+[build-dependencies]
+uuid = { version = "1.8", default-features = false }
+proto = { path = "../proto" }
 
-popd
+[profile.release]
+panic = "abort"
+lto = false
+opt-level = 1
diff --git a/examples/message_passing_interface-rs/ta/Makefile b/examples/message_passing_interface-rs/ta/Makefile
new file mode 100644
index 0000000..17d6e73
--- /dev/null
+++ b/examples/message_passing_interface-rs/ta/Makefile
@@ -0,0 +1,49 @@
+# 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.
+
+# STD-ONLY example
+
+UUID ?= $(shell cat "../uuid.txt")
+
+TARGET_TA ?= aarch64-unknown-linux-gnu
+CROSS_COMPILE_TA ?= aarch64-linux-gnu-
+OBJCOPY := $(CROSS_COMPILE_TA)objcopy
+LINKER_CFG := target.$(TARGET_TA).linker=\"$(CROSS_COMPILE_TA)ld.bfd\"
+
+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_TA)/release
+
+ifeq ($(STD),)
+all:
+	@echo "Please export STD=y to build the STD version"
+else
+all: ta strip sign
+endif
+
+ta:
+	@xargo build --target $(TARGET_TA) --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/.licenserc.yaml b/examples/message_passing_interface-rs/ta/Xargo.toml
similarity index 72%
copy from .licenserc.yaml
copy to examples/message_passing_interface-rs/ta/Xargo.toml
index 0391c38..1b1a113 100644
--- a/.licenserc.yaml
+++ b/examples/message_passing_interface-rs/ta/Xargo.toml
@@ -15,18 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 
-header:
-  license:
-    spdx-id: Apache-2.0
-    copyright-owner: Apache Software Foundation
+[dependencies.std]
+path = "../../../rust/rust/library/std"
 
-  paths-ignore:
-    - 'dist'
-    - 'licenses'
-    - '**/*.md'
-    - 'LICENSE'
-    - 'NOTICE'
-    - '**/Cargo.lock'
-    - 'KEYS'
-    - 'DISCLAIMER-WIP'
-    - '*.json'
+[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/message_passing_interface-rs/ta/build.rs b/examples/message_passing_interface-rs/ta/build.rs
new file mode 100644
index 0000000..fa0d195
--- /dev/null
+++ b/examples/message_passing_interface-rs/ta/build.rs
@@ -0,0 +1,103 @@
+// 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 proto;
+use std::env;
+use std::fs::File;
+use std::io::{BufRead, BufReader, Write};
+use std::path::{Path, PathBuf};
+use uuid::Uuid;
+
+fn main() -> std::io::Result<()> {
+    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+
+    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
+    buffer.write_all(include_bytes!("ta_static.rs"))?;
+
+    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
+    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
+
+    write!(buffer, "\n")?;
+    write!(
+        buffer,
+        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
+    timeLow: {:#x},
+    timeMid: {:#x},
+    timeHiAndVersion: {:#x},
+    clockSeqAndNode: {:#x?},
+}};",
+        time_low, time_mid, time_hi_and_version, clock_seq_and_node
+    )?;
+
+    let mut aarch64_flag = true;
+    match env::var("TARGET_TA") {
+        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
+            println!("cargo:rustc-link-arg=--no-warn-mismatch");
+            aarch64_flag = false;
+        },
+        _ => {}
+    };
+
+    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
+    let search_path = Path::new(&optee_os_dir).join("lib");
+
+    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
+    let mut ta_lds = File::create(out.join("ta.lds"))?;
+    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
+    let f = BufReader::new(f);
+
+    for line in f.lines() {
+        let l = line?;
+
+        if aarch64_flag {
+            if l.starts_with('#') ||
+                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
+                l == "OUTPUT_ARCH(arm)" {
+                continue;
+            }
+        } else {
+            if l.starts_with('#') ||
+                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
+                l == "OUTPUT_ARCH(aarch64)" {
+                continue;
+            }
+        }
+
+        if l == "\t. = ALIGN(4096);" {
+            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
+        } else {
+            write!(ta_lds, "{}\n", l)?;
+        }
+    }
+
+    println!("cargo:rustc-link-search={}", out.display());
+    println!("cargo:rerun-if-changed=ta.lds");
+
+    println!("cargo:rustc-link-search={}", search_path.display());
+    println!("cargo:rustc-link-lib=static=utee");
+    println!("cargo:rustc-link-lib=static=utils");
+    println!("cargo:rustc-link-arg=-Tta.lds");
+    println!("cargo:rustc-link-arg=-e__ta_entry");
+    println!("cargo:rustc-link-arg=-pie");
+    println!("cargo:rustc-link-arg=-Os");
+    println!("cargo:rustc-link-arg=--sort-section=alignment");
+
+    let mut dyn_list = File::create(out.join("dyn_list"))?;
+    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
+    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
+    Ok(())
+}
diff --git a/examples/message_passing_interface-rs/ta/src/main.rs b/examples/message_passing_interface-rs/ta/src/main.rs
new file mode 100644
index 0000000..e79f78b
--- /dev/null
+++ b/examples/message_passing_interface-rs/ta/src/main.rs
@@ -0,0 +1,97 @@
+// 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_main]
+#![feature(c_size_t)]
+
+use optee_utee::{
+    ta_close_session, ta_create, ta_destroy, ta_invoke_command, ta_open_session, trace_println,
+};
+use optee_utee::{Error, ErrorKind, Parameters, Result};
+use proto::{self, Command};
+use std::io::Write;
+
+fn handle_invoke(command: Command, input: proto::EnclaveInput) -> Result<proto::EnclaveOutput> {
+    match command {
+        Command::Hello => {
+            let output = proto::EnclaveOutput {
+                message: format!("Hello, {}", input.message),
+            };
+            Ok(output)
+        }
+        Command::Bye => {
+            let output = proto::EnclaveOutput {
+                message: format!("Bye, {}", input.message),
+            };
+            Ok(output)
+        }
+        _ => Err(Error::new(ErrorKind::BadParameters)),
+    }
+}
+
+#[ta_create]
+fn create() -> Result<()> {
+    trace_println!("[+] TA create");
+    Ok(())
+}
+
+#[ta_open_session]
+fn open_session(_params: &mut Parameters) -> Result<()> {
+    trace_println!("[+] TA open session");
+    Ok(())
+}
+
+#[ta_close_session]
+fn close_session() {
+    trace_println!("[+] TA close session");
+}
+
+#[ta_destroy]
+fn destroy() {
+    trace_println!("[+] TA destroy");
+}
+
+#[ta_invoke_command]
+fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
+    trace_println!("[+] TA invoke command");
+    let mut p0 = unsafe { params.0.as_memref().unwrap() };
+    let mut p1 = unsafe { params.1.as_memref().unwrap() };
+    let mut p2 = unsafe { params.2.as_value().unwrap() };
+
+    let input: proto::EnclaveInput = proto::serde_json::from_slice(p0.buffer()).unwrap();
+    let output = handle_invoke(Command::from(cmd_id), input).unwrap();
+
+    let output_vec = proto::serde_json::to_vec(&output).unwrap();
+    p1.buffer().write(&output_vec).unwrap();
+    p2.set_a(output_vec.len() as u32);
+
+    Ok(())
+}
+
+// TA configurations
+const TA_FLAGS: u32 = 0;
+const TA_DATA_SIZE: u32 = 64 * 1024;
+const TA_STACK_SIZE: u32 = 4 * 1024;
+const TA_VERSION: &[u8] = b"0.3\0";
+const TA_DESCRIPTION: &[u8] = b"This is a message passing example using json.\0";
+const EXT_PROP_VALUE_1: &[u8] = b"Hello World TA\0";
+const EXT_PROP_VALUE_2: u32 = 0x0010;
+const TRACE_LEVEL: i32 = 4;
+const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
+const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
+
+include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/message_passing_interface-rs/ta/ta_static.rs b/examples/message_passing_interface-rs/ta/ta_static.rs
new file mode 100644
index 0000000..53ca210
--- /dev/null
+++ b/examples/message_passing_interface-rs/ta/ta_static.rs
@@ -0,0 +1,102 @@
+// 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 core::ffi::*;
+use core::mem;
+use core::primitive::u64;
+
+#[no_mangle]
+pub static mut trace_level: c_int = TRACE_LEVEL;
+
+#[no_mangle]
+pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
+
+#[no_mangle]
+#[link_section = ".ta_head"]
+pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
+    uuid: TA_UUID,
+    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
+    flags: TA_FLAGS,
+    depr_entry: u64::MAX,
+};
+
+#[no_mangle]
+#[link_section = ".bss"]
+pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
+
+#[no_mangle]
+pub static ta_heap_size: c_size_t = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
+static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
+static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
+static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
+
+#[no_mangle]
+pub static ta_num_props: c_size_t = 9;
+
+#[no_mangle]
+pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_BOOL as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_MULTI as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_INSTANCE as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &TA_DATA_SIZE as *const u32 as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &TA_STACK_SIZE as *const u32 as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_VERSION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: TA_VERSION as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: TA_DESCRIPTION as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: "gp.ta.description\0".as_ptr(),
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: "gp.ta.version\0".as_ptr(),
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
+    },
+];
+
+#[no_mangle]
+pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
+    return trace_level;
+}
diff --git a/examples/message_passing_interface-rs/uuid.txt b/examples/message_passing_interface-rs/uuid.txt
new file mode 100644
index 0000000..dc15e03
--- /dev/null
+++ b/examples/message_passing_interface-rs/uuid.txt
@@ -0,0 +1 @@
+17556a46-bdab-11eb-b325-d38c9a9af725
diff --git a/ci/ci.sh b/examples/serde-rs/Makefile
old mode 100755
new mode 100644
similarity index 61%
copy from ci/ci.sh
copy to examples/serde-rs/Makefile
index e530044..c266055
--- a/ci/ci.sh
+++ b/examples/serde-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,23 +15,19 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+# 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
 
-./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
+all:
+	$(q)make -C host TARGET_HOST=$(TARGET_HOST) \
+		CROSS_COMPILE_HOST=$(CROSS_COMPILE_HOST)
+	$(q)make -C ta TARGET_TA=$(TARGET_TA) \
+		CROSS_COMPILE_TA=$(CROSS_COMPILE_TA)
 
-popd
+clean:
+	$(q)make -C host clean
+	$(q)make -C ta clean
diff --git a/ci/ci.sh b/examples/serde-rs/host/Cargo.toml
old mode 100755
new mode 100644
similarity index 62%
copy from ci/ci.sh
copy to examples/serde-rs/host/Cargo.toml
index e530044..24f213d
--- a/ci/ci.sh
+++ b/examples/serde-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,23 +15,20 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+[package]
+name = "serde-rs"
+version = "0.3.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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
+[dependencies]
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
+proto = { path = "../proto" }
+optee-teec = { path = "../../../optee-teec" }
 
-popd
+[profile.release]
+lto = true
diff --git a/ci/ci.sh b/examples/serde-rs/host/Makefile
old mode 100755
new mode 100644
similarity index 63%
copy from ci/ci.sh
copy to examples/serde-rs/host/Makefile
index e530044..046200c
--- a/ci/ci.sh
+++ b/examples/serde-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,23 +15,24 @@
 # 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
-
-popd
+NAME := serde-rs
+
+TARGET_HOST ?= aarch64-unknown-linux-gnu
+CROSS_COMPILE_HOST ?= aarch64-linux-gnu-
+OBJCOPY := $(CROSS_COMPILE_HOST)objcopy
+LINKER_CFG := target.$(TARGET_HOST).linker=\"$(CROSS_COMPILE_HOST)gcc\"
+
+OUT_DIR := $(CURDIR)/target/$(TARGET_HOST)/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/serde-rs/host/src/main.rs b/examples/serde-rs/host/src/main.rs
new file mode 100644
index 0000000..cdeaab0
--- /dev/null
+++ b/examples/serde-rs/host/src/main.rs
@@ -0,0 +1,51 @@
+// 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, ParamNone, ParamTmpRef, Session, Uuid};
+use proto::{Command, UUID};
+use serde::Deserialize;
+
+#[derive(Deserialize, Debug)]
+struct Point {
+    x: i32,
+    y: i32,
+}
+
+fn serde(session: &mut Session) -> optee_teec::Result<()> {
+    let mut buffer = [0u8; 128];
+    let p0 = ParamTmpRef::new_output(&mut buffer);
+    let mut operation = Operation::new(0, p0, ParamNone, ParamNone, ParamNone);
+
+    session.invoke_command(Command::DefaultOp as u32, &mut operation)?;
+    let updated_size = operation.parameters().0.updated_size();
+
+    let p: Point = serde_json::from_slice(&buffer[..updated_size]).unwrap();
+    println!("{:?}", p);
+
+    Ok(())
+}
+
+fn main() -> optee_teec::Result<()> {
+    let mut ctx = Context::new()?;
+    let uuid = Uuid::parse_str(UUID).unwrap();
+    let mut session = ctx.open_session(uuid)?;
+
+    serde(&mut session)?;
+
+    println!("Success");
+    Ok(())
+}
diff --git a/ci/ci.sh b/examples/serde-rs/proto/Cargo.toml
old mode 100755
new mode 100644
similarity index 67%
copy from ci/ci.sh
copy to examples/serde-rs/proto/Cargo.toml
index e530044..2b03c35
--- a/ci/ci.sh
+++ b/examples/serde-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,23 +15,16 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+[package]
+name = "proto"
+version = "0.3.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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"
 
-./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
+[dependencies]
 
-popd
+[build-dependencies]
+uuid = { version = "1.8", default-features = false }
\ No newline at end of file
diff --git a/examples/serde-rs/proto/build.rs b/examples/serde-rs/proto/build.rs
new file mode 100644
index 0000000..b9d0612
--- /dev/null
+++ b/examples/serde-rs/proto/build.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.
+
+use std::fs;
+use std::path::PathBuf;
+use std::fs::File;
+use std::env;
+use std::io::Write;
+
+fn main() {
+    let uuid = match fs::read_to_string("../uuid.txt") {
+        Ok(u) => {
+            u.trim().to_string()
+        },
+        Err(_) => {
+            panic!("Cannot find uuid.txt");
+        }
+    };
+    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+    let mut buffer = File::create(out.join("uuid.txt")).unwrap();
+    write!(buffer, "{}", uuid).unwrap();
+}
diff --git a/examples/serde-rs/proto/src/lib.rs b/examples/serde-rs/proto/src/lib.rs
new file mode 100644
index 0000000..e21f550
--- /dev/null
+++ b/examples/serde-rs/proto/src/lib.rs
@@ -0,0 +1,33 @@
+// 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.
+
+pub enum Command {
+    DefaultOp,
+    Unknown,
+}
+
+impl From<u32> for Command {
+    #[inline]
+    fn from(value: u32) -> Command {
+        match value {
+            0 => Command::DefaultOp,
+            _ => Command::Unknown,
+        }
+    }
+}
+
+pub const UUID: &str = &include_str!(concat!(env!("OUT_DIR"), "/uuid.txt"));
diff --git a/ci/ci.sh b/examples/serde-rs/ta/Cargo.toml
old mode 100755
new mode 100644
similarity index 54%
copy from ci/ci.sh
copy to examples/serde-rs/ta/Cargo.toml
index e530044..be7cea8
--- a/ci/ci.sh
+++ b/examples/serde-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,23 +15,27 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
+[package]
+name = "ta"
+version = "0.2.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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"
 
-pushd ../tests
+[dependencies]
+proto = { path = "../proto" }
+optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
+optee-utee = { path = "../../../optee-utee" }
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
 
-./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
+[build_dependencies]
+uuid = { version = "1.6.1", default-features = false }
+proto = { path = "../proto" }
 
-popd
+[profile.release]
+panic = "abort"
+lto = false
+opt-level = 1
diff --git a/examples/serde-rs/ta/Makefile b/examples/serde-rs/ta/Makefile
new file mode 100644
index 0000000..17d6e73
--- /dev/null
+++ b/examples/serde-rs/ta/Makefile
@@ -0,0 +1,49 @@
+# 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.
+
+# STD-ONLY example
+
+UUID ?= $(shell cat "../uuid.txt")
+
+TARGET_TA ?= aarch64-unknown-linux-gnu
+CROSS_COMPILE_TA ?= aarch64-linux-gnu-
+OBJCOPY := $(CROSS_COMPILE_TA)objcopy
+LINKER_CFG := target.$(TARGET_TA).linker=\"$(CROSS_COMPILE_TA)ld.bfd\"
+
+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_TA)/release
+
+ifeq ($(STD),)
+all:
+	@echo "Please export STD=y to build the STD version"
+else
+all: ta strip sign
+endif
+
+ta:
+	@xargo build --target $(TARGET_TA) --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/.licenserc.yaml b/examples/serde-rs/ta/Xargo.toml
similarity index 72%
copy from .licenserc.yaml
copy to examples/serde-rs/ta/Xargo.toml
index 0391c38..1b1a113 100644
--- a/.licenserc.yaml
+++ b/examples/serde-rs/ta/Xargo.toml
@@ -15,18 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 
-header:
-  license:
-    spdx-id: Apache-2.0
-    copyright-owner: Apache Software Foundation
+[dependencies.std]
+path = "../../../rust/rust/library/std"
 
-  paths-ignore:
-    - 'dist'
-    - 'licenses'
-    - '**/*.md'
-    - 'LICENSE'
-    - 'NOTICE'
-    - '**/Cargo.lock'
-    - 'KEYS'
-    - 'DISCLAIMER-WIP'
-    - '*.json'
+[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/serde-rs/ta/build.rs b/examples/serde-rs/ta/build.rs
new file mode 100644
index 0000000..fa0d195
--- /dev/null
+++ b/examples/serde-rs/ta/build.rs
@@ -0,0 +1,103 @@
+// 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 proto;
+use std::env;
+use std::fs::File;
+use std::io::{BufRead, BufReader, Write};
+use std::path::{Path, PathBuf};
+use uuid::Uuid;
+
+fn main() -> std::io::Result<()> {
+    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+
+    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
+    buffer.write_all(include_bytes!("ta_static.rs"))?;
+
+    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
+    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
+
+    write!(buffer, "\n")?;
+    write!(
+        buffer,
+        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
+    timeLow: {:#x},
+    timeMid: {:#x},
+    timeHiAndVersion: {:#x},
+    clockSeqAndNode: {:#x?},
+}};",
+        time_low, time_mid, time_hi_and_version, clock_seq_and_node
+    )?;
+
+    let mut aarch64_flag = true;
+    match env::var("TARGET_TA") {
+        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
+            println!("cargo:rustc-link-arg=--no-warn-mismatch");
+            aarch64_flag = false;
+        },
+        _ => {}
+    };
+
+    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
+    let search_path = Path::new(&optee_os_dir).join("lib");
+
+    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
+    let mut ta_lds = File::create(out.join("ta.lds"))?;
+    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
+    let f = BufReader::new(f);
+
+    for line in f.lines() {
+        let l = line?;
+
+        if aarch64_flag {
+            if l.starts_with('#') ||
+                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
+                l == "OUTPUT_ARCH(arm)" {
+                continue;
+            }
+        } else {
+            if l.starts_with('#') ||
+                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
+                l == "OUTPUT_ARCH(aarch64)" {
+                continue;
+            }
+        }
+
+        if l == "\t. = ALIGN(4096);" {
+            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
+        } else {
+            write!(ta_lds, "{}\n", l)?;
+        }
+    }
+
+    println!("cargo:rustc-link-search={}", out.display());
+    println!("cargo:rerun-if-changed=ta.lds");
+
+    println!("cargo:rustc-link-search={}", search_path.display());
+    println!("cargo:rustc-link-lib=static=utee");
+    println!("cargo:rustc-link-lib=static=utils");
+    println!("cargo:rustc-link-arg=-Tta.lds");
+    println!("cargo:rustc-link-arg=-e__ta_entry");
+    println!("cargo:rustc-link-arg=-pie");
+    println!("cargo:rustc-link-arg=-Os");
+    println!("cargo:rustc-link-arg=--sort-section=alignment");
+
+    let mut dyn_list = File::create(out.join("dyn_list"))?;
+    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
+    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
+    Ok(())
+}
diff --git a/examples/serde-rs/ta/src/main.rs b/examples/serde-rs/ta/src/main.rs
new file mode 100644
index 0000000..c0918c2
--- /dev/null
+++ b/examples/serde-rs/ta/src/main.rs
@@ -0,0 +1,102 @@
+// 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_main]
+// this is the workaround for the error:
+// error[E0658]: use of unstable library feature 'c_size_t'
+#![feature(c_size_t)]
+
+use optee_utee::{
+    ta_close_session, ta_create, ta_destroy, ta_invoke_command, ta_open_session, trace_println,
+};
+use optee_utee::{Error, ErrorKind, Parameters, Result};
+use proto::Command;
+use serde::{Deserialize, Serialize};
+use std::io::Write;
+
+#[ta_create]
+fn create() -> Result<()> {
+    trace_println!("[+] TA create");
+    Ok(())
+}
+
+#[ta_open_session]
+fn open_session(_params: &mut Parameters) -> Result<()> {
+    trace_println!("[+] TA open session");
+    Ok(())
+}
+
+#[ta_close_session]
+fn close_session() {
+    trace_println!("[+] TA close session");
+}
+
+#[ta_destroy]
+fn destroy() {
+    trace_println!("[+] TA destroy");
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+struct Point {
+    x: i32,
+    y: i32,
+}
+
+#[ta_invoke_command]
+fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
+    trace_println!("[+] TA invoke command");
+    match Command::from(cmd_id) {
+        Command::DefaultOp => {
+            let mut p = unsafe { params.0.as_memref().unwrap() };
+            let mut buffer = p.buffer();
+            let point = Point { x: 1, y: 2 };
+
+            // Convert the Point to a JSON string.
+            let serialized = serde_json::to_string(&point).unwrap();
+            let len = buffer.write(serialized.as_bytes()).unwrap();
+
+            // update size of output buffer
+            unsafe { (*p.raw()).size = len };
+
+            // Prints serialized = {"x":1,"y":2}
+            trace_println!("serialized = {}", serialized);
+
+            // Convert the JSON string back to a Point.
+            let deserialized: Point = serde_json::from_str(&serialized).unwrap();
+
+            // Prints deserialized = Point { x: 1, y: 2 }
+            trace_println!("deserialized = {:?}", deserialized);
+
+            Ok(())
+        }
+        _ => Err(Error::new(ErrorKind::BadParameters)),
+    }
+}
+
+// TA configurations
+const TA_FLAGS: u32 = 0;
+const TA_DATA_SIZE: u32 = 64 * 1024;
+const TA_STACK_SIZE: u32 = 4 * 1024;
+const TA_VERSION: &[u8] = b"0.3\0";
+const TA_DESCRIPTION: &[u8] = b"This is a serde example.\0";
+const EXT_PROP_VALUE_1: &[u8] = b"Serde TA\0";
+const EXT_PROP_VALUE_2: u32 = 0x0010;
+const TRACE_LEVEL: i32 = 4;
+const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
+const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
+
+include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/serde-rs/ta/ta_static.rs b/examples/serde-rs/ta/ta_static.rs
new file mode 100644
index 0000000..53ca210
--- /dev/null
+++ b/examples/serde-rs/ta/ta_static.rs
@@ -0,0 +1,102 @@
+// 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 core::ffi::*;
+use core::mem;
+use core::primitive::u64;
+
+#[no_mangle]
+pub static mut trace_level: c_int = TRACE_LEVEL;
+
+#[no_mangle]
+pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
+
+#[no_mangle]
+#[link_section = ".ta_head"]
+pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
+    uuid: TA_UUID,
+    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
+    flags: TA_FLAGS,
+    depr_entry: u64::MAX,
+};
+
+#[no_mangle]
+#[link_section = ".bss"]
+pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
+
+#[no_mangle]
+pub static ta_heap_size: c_size_t = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
+static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
+static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
+static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
+
+#[no_mangle]
+pub static ta_num_props: c_size_t = 9;
+
+#[no_mangle]
+pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_BOOL as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_MULTI as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_INSTANCE as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &TA_DATA_SIZE as *const u32 as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &TA_STACK_SIZE as *const u32 as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_VERSION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: TA_VERSION as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: TA_DESCRIPTION as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: "gp.ta.description\0".as_ptr(),
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: "gp.ta.version\0".as_ptr(),
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
+    },
+];
+
+#[no_mangle]
+pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
+    return trace_level;
+}
diff --git a/examples/serde-rs/uuid.txt b/examples/serde-rs/uuid.txt
new file mode 100644
index 0000000..3767c5d
--- /dev/null
+++ b/examples/serde-rs/uuid.txt
@@ -0,0 +1 @@
+1ed47816-bdab-11eb-9ebd-3ffe0648da93
diff --git a/ci/ci.sh b/examples/tcp_client-rs/Makefile
old mode 100755
new mode 100644
similarity index 61%
copy from ci/ci.sh
copy to examples/tcp_client-rs/Makefile
index e530044..c266055
--- a/ci/ci.sh
+++ b/examples/tcp_client-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,23 +15,19 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+# 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
 
-./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
+all:
+	$(q)make -C host TARGET_HOST=$(TARGET_HOST) \
+		CROSS_COMPILE_HOST=$(CROSS_COMPILE_HOST)
+	$(q)make -C ta TARGET_TA=$(TARGET_TA) \
+		CROSS_COMPILE_TA=$(CROSS_COMPILE_TA)
 
-popd
+clean:
+	$(q)make -C host clean
+	$(q)make -C ta clean
diff --git a/ci/ci.sh b/examples/tcp_client-rs/host/Cargo.toml
old mode 100755
new mode 100644
similarity index 65%
copy from ci/ci.sh
copy to examples/tcp_client-rs/host/Cargo.toml
index e530044..c8f3610
--- a/ci/ci.sh
+++ b/examples/tcp_client-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,23 +15,19 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+[package]
+name = "tcp_client-rs"
+version = "0.3.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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
+[dependencies]
+libc = "0.2.48"
+proto = { path = "../proto" }
+optee-teec = { path = "../../../optee-teec" }
 
-popd
+[profile.release]
+lto = true
diff --git a/ci/ci.sh b/examples/tcp_client-rs/host/Makefile
old mode 100755
new mode 100644
similarity index 62%
copy from ci/ci.sh
copy to examples/tcp_client-rs/host/Makefile
index e530044..392aa90
--- a/ci/ci.sh
+++ b/examples/tcp_client-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,23 +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
-
-popd
+NAME := tcp_client-rs
+
+TARGET_HOST ?= aarch64-unknown-linux-gnu
+CROSS_COMPILE_HOST ?= aarch64-linux-gnu-
+OBJCOPY := $(CROSS_COMPILE_HOST)objcopy
+LINKER_CFG := target.$(TARGET_HOST).linker=\"$(CROSS_COMPILE_HOST)gcc\"
+
+OUT_DIR := $(CURDIR)/target/$(TARGET_HOST)/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/tcp_client-rs/host/src/main.rs b/examples/tcp_client-rs/host/src/main.rs
new file mode 100644
index 0000000..75624db
--- /dev/null
+++ b/examples/tcp_client-rs/host/src/main.rs
@@ -0,0 +1,37 @@
+// 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::ParamNone;
+use optee_teec::{Context, Operation, Session, Uuid};
+use proto::{Command, UUID};
+
+fn tcp_client(session: &mut Session) -> optee_teec::Result<()> {
+    let mut operation = Operation::new(0, ParamNone, ParamNone, ParamNone, ParamNone);
+    session.invoke_command(Command::Start as u32, &mut operation)?;
+    Ok(())
+}
+
+fn main() -> optee_teec::Result<()> {
+    let mut ctx = Context::new()?;
+    let uuid = Uuid::parse_str(UUID).unwrap();
+    let mut session = ctx.open_session(uuid)?;
+
+    tcp_client(&mut session)?;
+
+    println!("Success");
+    Ok(())
+}
diff --git a/ci/ci.sh b/examples/tcp_client-rs/proto/Cargo.toml
old mode 100755
new mode 100644
similarity index 67%
copy from ci/ci.sh
copy to examples/tcp_client-rs/proto/Cargo.toml
index e530044..b76ceb2
--- a/ci/ci.sh
+++ b/examples/tcp_client-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,23 +15,16 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+[package]
+name = "proto"
+version = "0.3.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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"
 
-./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
+[dependencies]
 
-popd
+[build-dependencies]
+uuid = { version = "1.8", default-features = false }
diff --git a/examples/tcp_client-rs/proto/build.rs b/examples/tcp_client-rs/proto/build.rs
new file mode 100644
index 0000000..b9d0612
--- /dev/null
+++ b/examples/tcp_client-rs/proto/build.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.
+
+use std::fs;
+use std::path::PathBuf;
+use std::fs::File;
+use std::env;
+use std::io::Write;
+
+fn main() {
+    let uuid = match fs::read_to_string("../uuid.txt") {
+        Ok(u) => {
+            u.trim().to_string()
+        },
+        Err(_) => {
+            panic!("Cannot find uuid.txt");
+        }
+    };
+    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+    let mut buffer = File::create(out.join("uuid.txt")).unwrap();
+    write!(buffer, "{}", uuid).unwrap();
+}
diff --git a/examples/tcp_client-rs/proto/src/lib.rs b/examples/tcp_client-rs/proto/src/lib.rs
new file mode 100644
index 0000000..7679b2d
--- /dev/null
+++ b/examples/tcp_client-rs/proto/src/lib.rs
@@ -0,0 +1,33 @@
+// 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.
+
+pub enum Command {
+    Start,
+    Unknown,
+}
+
+impl From<u32> for Command {
+    #[inline]
+    fn from(value: u32) -> Command {
+        match value {
+            0 => Command::Start,
+            _ => Command::Unknown,
+        }
+    }
+}
+
+pub const UUID: &str = &include_str!(concat!(env!("OUT_DIR"), "/uuid.txt"));
diff --git a/ci/ci.sh b/examples/tcp_client-rs/ta/Cargo.toml
old mode 100755
new mode 100644
similarity index 56%
copy from ci/ci.sh
copy to examples/tcp_client-rs/ta/Cargo.toml
index e530044..bc84153
--- a/ci/ci.sh
+++ b/examples/tcp_client-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,23 +15,25 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
+[package]
+name = "ta"
+version = "0.3.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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"
 
-pushd ../tests
+[dependencies]
+proto = { path = "../proto" }
+optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
+optee-utee = { path = "../../../optee-utee" }
 
-./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
+[build-dependencies]
+uuid = { version = "1.8", default-features = false }
+proto = { path = "../proto" }
 
-popd
+[profile.release]
+panic = "abort"
+lto = false
+opt-level = 1
diff --git a/examples/tcp_client-rs/ta/Makefile b/examples/tcp_client-rs/ta/Makefile
new file mode 100644
index 0000000..17d6e73
--- /dev/null
+++ b/examples/tcp_client-rs/ta/Makefile
@@ -0,0 +1,49 @@
+# 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.
+
+# STD-ONLY example
+
+UUID ?= $(shell cat "../uuid.txt")
+
+TARGET_TA ?= aarch64-unknown-linux-gnu
+CROSS_COMPILE_TA ?= aarch64-linux-gnu-
+OBJCOPY := $(CROSS_COMPILE_TA)objcopy
+LINKER_CFG := target.$(TARGET_TA).linker=\"$(CROSS_COMPILE_TA)ld.bfd\"
+
+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_TA)/release
+
+ifeq ($(STD),)
+all:
+	@echo "Please export STD=y to build the STD version"
+else
+all: ta strip sign
+endif
+
+ta:
+	@xargo build --target $(TARGET_TA) --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/.licenserc.yaml b/examples/tcp_client-rs/ta/Xargo.toml
similarity index 72%
copy from .licenserc.yaml
copy to examples/tcp_client-rs/ta/Xargo.toml
index 0391c38..1b1a113 100644
--- a/.licenserc.yaml
+++ b/examples/tcp_client-rs/ta/Xargo.toml
@@ -15,18 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 
-header:
-  license:
-    spdx-id: Apache-2.0
-    copyright-owner: Apache Software Foundation
+[dependencies.std]
+path = "../../../rust/rust/library/std"
 
-  paths-ignore:
-    - 'dist'
-    - 'licenses'
-    - '**/*.md'
-    - 'LICENSE'
-    - 'NOTICE'
-    - '**/Cargo.lock'
-    - 'KEYS'
-    - 'DISCLAIMER-WIP'
-    - '*.json'
+[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/tcp_client-rs/ta/build.rs b/examples/tcp_client-rs/ta/build.rs
new file mode 100644
index 0000000..fa0d195
--- /dev/null
+++ b/examples/tcp_client-rs/ta/build.rs
@@ -0,0 +1,103 @@
+// 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 proto;
+use std::env;
+use std::fs::File;
+use std::io::{BufRead, BufReader, Write};
+use std::path::{Path, PathBuf};
+use uuid::Uuid;
+
+fn main() -> std::io::Result<()> {
+    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+
+    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
+    buffer.write_all(include_bytes!("ta_static.rs"))?;
+
+    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
+    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
+
+    write!(buffer, "\n")?;
+    write!(
+        buffer,
+        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
+    timeLow: {:#x},
+    timeMid: {:#x},
+    timeHiAndVersion: {:#x},
+    clockSeqAndNode: {:#x?},
+}};",
+        time_low, time_mid, time_hi_and_version, clock_seq_and_node
+    )?;
+
+    let mut aarch64_flag = true;
+    match env::var("TARGET_TA") {
+        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
+            println!("cargo:rustc-link-arg=--no-warn-mismatch");
+            aarch64_flag = false;
+        },
+        _ => {}
+    };
+
+    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
+    let search_path = Path::new(&optee_os_dir).join("lib");
+
+    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
+    let mut ta_lds = File::create(out.join("ta.lds"))?;
+    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
+    let f = BufReader::new(f);
+
+    for line in f.lines() {
+        let l = line?;
+
+        if aarch64_flag {
+            if l.starts_with('#') ||
+                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
+                l == "OUTPUT_ARCH(arm)" {
+                continue;
+            }
+        } else {
+            if l.starts_with('#') ||
+                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
+                l == "OUTPUT_ARCH(aarch64)" {
+                continue;
+            }
+        }
+
+        if l == "\t. = ALIGN(4096);" {
+            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
+        } else {
+            write!(ta_lds, "{}\n", l)?;
+        }
+    }
+
+    println!("cargo:rustc-link-search={}", out.display());
+    println!("cargo:rerun-if-changed=ta.lds");
+
+    println!("cargo:rustc-link-search={}", search_path.display());
+    println!("cargo:rustc-link-lib=static=utee");
+    println!("cargo:rustc-link-lib=static=utils");
+    println!("cargo:rustc-link-arg=-Tta.lds");
+    println!("cargo:rustc-link-arg=-e__ta_entry");
+    println!("cargo:rustc-link-arg=-pie");
+    println!("cargo:rustc-link-arg=-Os");
+    println!("cargo:rustc-link-arg=--sort-section=alignment");
+
+    let mut dyn_list = File::create(out.join("dyn_list"))?;
+    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
+    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
+    Ok(())
+}
diff --git a/examples/tcp_client-rs/ta/src/main.rs b/examples/tcp_client-rs/ta/src/main.rs
new file mode 100644
index 0000000..de5c12e
--- /dev/null
+++ b/examples/tcp_client-rs/ta/src/main.rs
@@ -0,0 +1,96 @@
+// 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_main]
+#![feature(c_size_t)]
+
+use optee_utee::net::TcpStream;
+use optee_utee::{
+    ta_close_session, ta_create, ta_destroy, ta_invoke_command, ta_open_session, trace_println,
+};
+use optee_utee::{Error, ErrorKind, Parameters, Result};
+use proto::Command;
+use std::io::Read;
+use std::io::Write;
+
+#[ta_create]
+fn create() -> Result<()> {
+    trace_println!("[+] TA create");
+    Ok(())
+}
+
+#[ta_open_session]
+fn open_session(_params: &mut Parameters) -> Result<()> {
+    trace_println!("[+] TA open session");
+    Ok(())
+}
+
+#[ta_close_session]
+fn close_session() {
+    trace_println!("[+] TA close session");
+}
+
+#[ta_destroy]
+fn destroy() {
+    trace_println!("[+] TA destroy");
+}
+
+#[ta_invoke_command]
+fn invoke_command(cmd_id: u32, _params: &mut Parameters) -> Result<()> {
+    trace_println!("[+] TA invoke command");
+    match Command::from(cmd_id) {
+        Command::Start => {
+            tcp_client();
+            Ok(())
+        }
+        _ => Err(Error::new(ErrorKind::BadParameters)),
+    }
+}
+
+fn tcp_client() {
+    let mut stream = TcpStream::connect("teaclave.apache.org", 80).unwrap();
+    stream
+        .write_all(b"GET / HTTP/1.0\r\nHost: teaclave.apache.org\r\n\r\n")
+        .unwrap();
+    let mut response = Vec::new();
+    let mut chunk = [0u8; 1024];
+    loop {
+        match stream.read(&mut chunk) {
+            Ok(0) => break,
+            Ok(n) => response.extend_from_slice(&chunk[..n]),
+            Err(_) => {
+                trace_println!("Error");
+                panic!();
+            }
+        }
+    }
+    trace_println!("{}", String::from_utf8_lossy(&response));
+}
+
+// TA configurations
+const TA_FLAGS: u32 = 0;
+const TA_DATA_SIZE: u32 = 1 * 1024 * 1024;
+const TA_STACK_SIZE: u32 = 2 * 1024 * 1024;
+const TA_VERSION: &[u8] = b"0.3\0";
+const TA_DESCRIPTION: &[u8] = b"This is a tcp client example.\0";
+const EXT_PROP_VALUE_1: &[u8] = b"Hello World TA\0";
+const EXT_PROP_VALUE_2: u32 = 0x0010;
+const TRACE_LEVEL: i32 = 4;
+const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
+const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
+
+include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/tcp_client-rs/ta/ta_static.rs b/examples/tcp_client-rs/ta/ta_static.rs
new file mode 100644
index 0000000..53ca210
--- /dev/null
+++ b/examples/tcp_client-rs/ta/ta_static.rs
@@ -0,0 +1,102 @@
+// 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 core::ffi::*;
+use core::mem;
+use core::primitive::u64;
+
+#[no_mangle]
+pub static mut trace_level: c_int = TRACE_LEVEL;
+
+#[no_mangle]
+pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
+
+#[no_mangle]
+#[link_section = ".ta_head"]
+pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
+    uuid: TA_UUID,
+    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
+    flags: TA_FLAGS,
+    depr_entry: u64::MAX,
+};
+
+#[no_mangle]
+#[link_section = ".bss"]
+pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
+
+#[no_mangle]
+pub static ta_heap_size: c_size_t = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
+static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
+static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
+static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
+
+#[no_mangle]
+pub static ta_num_props: c_size_t = 9;
+
+#[no_mangle]
+pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_BOOL as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_MULTI as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_INSTANCE as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &TA_DATA_SIZE as *const u32 as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &TA_STACK_SIZE as *const u32 as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_VERSION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: TA_VERSION as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: TA_DESCRIPTION as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: "gp.ta.description\0".as_ptr(),
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: "gp.ta.version\0".as_ptr(),
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
+    },
+];
+
+#[no_mangle]
+pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
+    return trace_level;
+}
diff --git a/examples/tcp_client-rs/uuid.txt b/examples/tcp_client-rs/uuid.txt
new file mode 100644
index 0000000..386e8ab
--- /dev/null
+++ b/examples/tcp_client-rs/uuid.txt
@@ -0,0 +1 @@
+59db8536-e5e6-11eb-8e9b-a316ce7a6568
diff --git a/ci/ci.sh b/examples/tls_client-rs/Makefile
old mode 100755
new mode 100644
similarity index 61%
copy from ci/ci.sh
copy to examples/tls_client-rs/Makefile
index e530044..c266055
--- a/ci/ci.sh
+++ b/examples/tls_client-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,23 +15,19 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+# 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
 
-./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
+all:
+	$(q)make -C host TARGET_HOST=$(TARGET_HOST) \
+		CROSS_COMPILE_HOST=$(CROSS_COMPILE_HOST)
+	$(q)make -C ta TARGET_TA=$(TARGET_TA) \
+		CROSS_COMPILE_TA=$(CROSS_COMPILE_TA)
 
-popd
+clean:
+	$(q)make -C host clean
+	$(q)make -C ta clean
diff --git a/ci/ci.sh b/examples/tls_client-rs/host/Cargo.toml
old mode 100755
new mode 100644
similarity index 65%
copy from ci/ci.sh
copy to examples/tls_client-rs/host/Cargo.toml
index e530044..c853de9
--- a/ci/ci.sh
+++ b/examples/tls_client-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,23 +15,19 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+[package]
+name = "tls_client-rs"
+version = "0.3.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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
+[dependencies]
+libc = "0.2.48"
+proto = { path = "../proto" }
+optee-teec = { path = "../../../optee-teec" }
 
-popd
+[profile.release]
+lto = true
diff --git a/ci/ci.sh b/examples/tls_client-rs/host/Makefile
old mode 100755
new mode 100644
similarity index 62%
copy from ci/ci.sh
copy to examples/tls_client-rs/host/Makefile
index e530044..7920865
--- a/ci/ci.sh
+++ b/examples/tls_client-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,23 +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
-
-popd
+NAME := tls_client-rs
+
+TARGET_HOST ?= aarch64-unknown-linux-gnu
+CROSS_COMPILE_HOST ?= aarch64-linux-gnu-
+OBJCOPY := $(CROSS_COMPILE_HOST)objcopy
+LINKER_CFG := target.$(TARGET_HOST).linker=\"$(CROSS_COMPILE_HOST)gcc\"
+
+OUT_DIR := $(CURDIR)/target/$(TARGET_HOST)/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/tls_client-rs/host/src/main.rs b/examples/tls_client-rs/host/src/main.rs
new file mode 100644
index 0000000..50516b1
--- /dev/null
+++ b/examples/tls_client-rs/host/src/main.rs
@@ -0,0 +1,37 @@
+// 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::ParamNone;
+use optee_teec::{Context, Operation, Session, Uuid};
+use proto::{Command, UUID};
+
+fn tls_client(session: &mut Session) -> optee_teec::Result<()> {
+    let mut operation = Operation::new(0, ParamNone, ParamNone, ParamNone, ParamNone);
+    session.invoke_command(Command::Start as u32, &mut operation)?;
+    Ok(())
+}
+
+fn main() -> optee_teec::Result<()> {
+    let mut ctx = Context::new()?;
+    let uuid = Uuid::parse_str(UUID).unwrap();
+    let mut session = ctx.open_session(uuid)?;
+
+    tls_client(&mut session)?;
+
+    println!("Success");
+    Ok(())
+}
diff --git a/ci/ci.sh b/examples/tls_client-rs/proto/Cargo.toml
old mode 100755
new mode 100644
similarity index 67%
copy from ci/ci.sh
copy to examples/tls_client-rs/proto/Cargo.toml
index e530044..b76ceb2
--- a/ci/ci.sh
+++ b/examples/tls_client-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,23 +15,16 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+[package]
+name = "proto"
+version = "0.3.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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"
 
-./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
+[dependencies]
 
-popd
+[build-dependencies]
+uuid = { version = "1.8", default-features = false }
diff --git a/examples/tls_client-rs/proto/build.rs b/examples/tls_client-rs/proto/build.rs
new file mode 100644
index 0000000..b9d0612
--- /dev/null
+++ b/examples/tls_client-rs/proto/build.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.
+
+use std::fs;
+use std::path::PathBuf;
+use std::fs::File;
+use std::env;
+use std::io::Write;
+
+fn main() {
+    let uuid = match fs::read_to_string("../uuid.txt") {
+        Ok(u) => {
+            u.trim().to_string()
+        },
+        Err(_) => {
+            panic!("Cannot find uuid.txt");
+        }
+    };
+    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+    let mut buffer = File::create(out.join("uuid.txt")).unwrap();
+    write!(buffer, "{}", uuid).unwrap();
+}
diff --git a/examples/tls_client-rs/proto/src/lib.rs b/examples/tls_client-rs/proto/src/lib.rs
new file mode 100644
index 0000000..7679b2d
--- /dev/null
+++ b/examples/tls_client-rs/proto/src/lib.rs
@@ -0,0 +1,33 @@
+// 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.
+
+pub enum Command {
+    Start,
+    Unknown,
+}
+
+impl From<u32> for Command {
+    #[inline]
+    fn from(value: u32) -> Command {
+        match value {
+            0 => Command::Start,
+            _ => Command::Unknown,
+        }
+    }
+}
+
+pub const UUID: &str = &include_str!(concat!(env!("OUT_DIR"), "/uuid.txt"));
diff --git a/examples/tls_client-rs/ta/Cargo.toml b/examples/tls_client-rs/ta/Cargo.toml
new file mode 100644
index 0000000..b051d64
--- /dev/null
+++ b/examples/tls_client-rs/ta/Cargo.toml
@@ -0,0 +1,54 @@
+# 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.
+
+[package]
+name = "ta"
+version = "0.3.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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"
+
+[dependencies]
+libc = { path = "../../../rust/libc" }
+proto = { path = "../proto" }
+optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
+optee-utee = { path = "../../../optee-utee" }
+
+# use new ported version
+rustls = { git = "https://github.com/DemesneGH/rustls-optee.git", branch = "0.21.0-optee", features = ["dangerous_configuration"]}
+ring = "=0.16.20"
+webpki-roots = "0.21"
+webpki = "=0.21.0"
+sct = "=0.7.0"
+
+[build-dependencies]
+uuid = { version = "1.8", default-features = false }
+proto = { path = "../proto" }
+
+[profile.release]
+panic = "abort"
+lto = false
+opt-level = 1
+
+[patch.crates-io]
+ring = { git = "https://github.com/DemesneGH/ring-optee.git", branch = "0.16.20-optee" }
+
+# Patch optee-utee for rustls
+[patch."https://github.com/apache/incubator-teaclave-trustzone-sdk.git"]
+optee-utee = { path = "../../../optee-utee" }
\ No newline at end of file
diff --git a/examples/tls_client-rs/ta/Makefile b/examples/tls_client-rs/ta/Makefile
new file mode 100644
index 0000000..74aeb33
--- /dev/null
+++ b/examples/tls_client-rs/ta/Makefile
@@ -0,0 +1,50 @@
+# 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.
+
+# STD-ONLY example
+
+UUID ?= $(shell cat "../uuid.txt")
+
+TARGET_TA ?= aarch64-unknown-linux-gnu
+CROSS_COMPILE_TA ?= aarch64-linux-gnu-
+OBJCOPY := $(CROSS_COMPILE_TA)objcopy
+LINKER_CFG := target.$(TARGET_TA).linker=\"$(CROSS_COMPILE_TA)ld.bfd\"
+
+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_TA)/release
+
+ifeq ($(STD),)
+all:
+	@echo "Please export STD=y to build the STD version"
+else
+all: ta strip sign
+endif
+
+# set the cross compile for building inner libraries, such as C libraries in ring
+ta:
+	@CROSS_COMPILE=$(CROSS_COMPILE_TA) xargo build --target $(TARGET_TA) --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/.licenserc.yaml b/examples/tls_client-rs/ta/Xargo.toml
similarity index 72%
copy from .licenserc.yaml
copy to examples/tls_client-rs/ta/Xargo.toml
index 0391c38..1b1a113 100644
--- a/.licenserc.yaml
+++ b/examples/tls_client-rs/ta/Xargo.toml
@@ -15,18 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 
-header:
-  license:
-    spdx-id: Apache-2.0
-    copyright-owner: Apache Software Foundation
+[dependencies.std]
+path = "../../../rust/rust/library/std"
 
-  paths-ignore:
-    - 'dist'
-    - 'licenses'
-    - '**/*.md'
-    - 'LICENSE'
-    - 'NOTICE'
-    - '**/Cargo.lock'
-    - 'KEYS'
-    - 'DISCLAIMER-WIP'
-    - '*.json'
+[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/tls_client-rs/ta/build.rs b/examples/tls_client-rs/ta/build.rs
new file mode 100644
index 0000000..fa0d195
--- /dev/null
+++ b/examples/tls_client-rs/ta/build.rs
@@ -0,0 +1,103 @@
+// 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 proto;
+use std::env;
+use std::fs::File;
+use std::io::{BufRead, BufReader, Write};
+use std::path::{Path, PathBuf};
+use uuid::Uuid;
+
+fn main() -> std::io::Result<()> {
+    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+
+    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
+    buffer.write_all(include_bytes!("ta_static.rs"))?;
+
+    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
+    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
+
+    write!(buffer, "\n")?;
+    write!(
+        buffer,
+        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
+    timeLow: {:#x},
+    timeMid: {:#x},
+    timeHiAndVersion: {:#x},
+    clockSeqAndNode: {:#x?},
+}};",
+        time_low, time_mid, time_hi_and_version, clock_seq_and_node
+    )?;
+
+    let mut aarch64_flag = true;
+    match env::var("TARGET_TA") {
+        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
+            println!("cargo:rustc-link-arg=--no-warn-mismatch");
+            aarch64_flag = false;
+        },
+        _ => {}
+    };
+
+    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
+    let search_path = Path::new(&optee_os_dir).join("lib");
+
+    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
+    let mut ta_lds = File::create(out.join("ta.lds"))?;
+    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
+    let f = BufReader::new(f);
+
+    for line in f.lines() {
+        let l = line?;
+
+        if aarch64_flag {
+            if l.starts_with('#') ||
+                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
+                l == "OUTPUT_ARCH(arm)" {
+                continue;
+            }
+        } else {
+            if l.starts_with('#') ||
+                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
+                l == "OUTPUT_ARCH(aarch64)" {
+                continue;
+            }
+        }
+
+        if l == "\t. = ALIGN(4096);" {
+            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
+        } else {
+            write!(ta_lds, "{}\n", l)?;
+        }
+    }
+
+    println!("cargo:rustc-link-search={}", out.display());
+    println!("cargo:rerun-if-changed=ta.lds");
+
+    println!("cargo:rustc-link-search={}", search_path.display());
+    println!("cargo:rustc-link-lib=static=utee");
+    println!("cargo:rustc-link-lib=static=utils");
+    println!("cargo:rustc-link-arg=-Tta.lds");
+    println!("cargo:rustc-link-arg=-e__ta_entry");
+    println!("cargo:rustc-link-arg=-pie");
+    println!("cargo:rustc-link-arg=-Os");
+    println!("cargo:rustc-link-arg=--sort-section=alignment");
+
+    let mut dyn_list = File::create(out.join("dyn_list"))?;
+    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
+    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
+    Ok(())
+}
diff --git a/examples/tls_client-rs/ta/src/main.rs b/examples/tls_client-rs/ta/src/main.rs
new file mode 100644
index 0000000..b1de410
--- /dev/null
+++ b/examples/tls_client-rs/ta/src/main.rs
@@ -0,0 +1,119 @@
+// 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_main]
+#![feature(c_size_t)]
+
+use optee_utee::net::TcpStream;
+use optee_utee::{
+    ta_close_session, ta_create, ta_destroy, ta_invoke_command, ta_open_session, trace_println,
+};
+use optee_utee::{Error, ErrorKind, Parameters, Result};
+use proto::Command;
+use rustls::{OwnedTrustAnchor, RootCertStore};
+use std::convert::TryInto;
+use std::io::Read;
+use std::io::Write;
+use std::sync::Arc;
+
+#[ta_create]
+fn create() -> Result<()> {
+    trace_println!("[+] TA create");
+    Ok(())
+}
+
+#[ta_open_session]
+fn open_session(_params: &mut Parameters) -> Result<()> {
+    trace_println!("[+] TA open session");
+    Ok(())
+}
+
+#[ta_close_session]
+fn close_session() {
+    trace_println!("[+] TA close session");
+}
+
+#[ta_destroy]
+fn destroy() {
+    trace_println!("[+] TA destroy");
+}
+
+#[ta_invoke_command]
+fn invoke_command(cmd_id: u32, _params: &mut Parameters) -> Result<()> {
+    trace_println!("[+] TA invoke command");
+    match Command::from(cmd_id) {
+        Command::Start => {
+            tls_client();
+            Ok(())
+        }
+        _ => Err(Error::new(ErrorKind::BadParameters)),
+    }
+}
+
+// copied from https://github.com/rustls/rustls/blob/v/0.21.0/examples/src/bin/simpleclient.rs
+fn tls_client() {
+    let mut root_store = RootCertStore::empty();
+    root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| {
+        OwnedTrustAnchor::from_subject_spki_name_constraints(
+            ta.subject,
+            ta.spki,
+            ta.name_constraints,
+        )
+    }));
+    trace_println!("[+] root_store added");
+
+    let config = rustls::ClientConfig::builder()
+        .with_safe_defaults()
+        .with_root_certificates(root_store)
+        .with_no_client_auth();
+    trace_println!("[+] config created");
+
+    let server_name = "google.com".try_into().unwrap();
+    let mut conn = rustls::ClientConnection::new(Arc::new(config), server_name).unwrap();
+    let mut sock = TcpStream::connect("google.com", 443).unwrap();
+    let mut tls = rustls::Stream::new(&mut conn, &mut sock);
+    tls.write_all(
+        concat!(
+            "GET / HTTP/1.1\r\n",
+            "Host: google.com\r\n",
+            "Connection: close\r\n",
+            "Accept-Encoding: identity\r\n",
+            "\r\n"
+        )
+        .as_bytes(),
+    )
+    .unwrap();
+    let ciphersuite = tls.conn.negotiated_cipher_suite().unwrap();
+    trace_println!("Current ciphersuite: {:?}", ciphersuite.suite());
+    let mut plaintext = Vec::new();
+    tls.read_to_end(&mut plaintext).unwrap();
+    trace_println!("{}", String::from_utf8_lossy(&plaintext));
+}
+
+// TA configurations
+const TA_FLAGS: u32 = 0;
+const TA_DATA_SIZE: u32 = 18 * 1024 * 1024;
+const TA_STACK_SIZE: u32 = 2 * 1024 * 1024;
+const TA_VERSION: &[u8] = b"0.3\0";
+const TA_DESCRIPTION: &[u8] = b"This is a tls client example.\0";
+const EXT_PROP_VALUE_1: &[u8] = b"TLS Client TA\0";
+const EXT_PROP_VALUE_2: u32 = 0x0010;
+const TRACE_LEVEL: i32 = 4;
+const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
+const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
+
+include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/tls_client-rs/ta/ta_static.rs b/examples/tls_client-rs/ta/ta_static.rs
new file mode 100644
index 0000000..53ca210
--- /dev/null
+++ b/examples/tls_client-rs/ta/ta_static.rs
@@ -0,0 +1,102 @@
+// 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 core::ffi::*;
+use core::mem;
+use core::primitive::u64;
+
+#[no_mangle]
+pub static mut trace_level: c_int = TRACE_LEVEL;
+
+#[no_mangle]
+pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
+
+#[no_mangle]
+#[link_section = ".ta_head"]
+pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
+    uuid: TA_UUID,
+    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
+    flags: TA_FLAGS,
+    depr_entry: u64::MAX,
+};
+
+#[no_mangle]
+#[link_section = ".bss"]
+pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
+
+#[no_mangle]
+pub static ta_heap_size: c_size_t = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
+static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
+static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
+static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
+
+#[no_mangle]
+pub static ta_num_props: c_size_t = 9;
+
+#[no_mangle]
+pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_BOOL as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_MULTI as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_INSTANCE as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &TA_DATA_SIZE as *const u32 as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &TA_STACK_SIZE as *const u32 as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_VERSION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: TA_VERSION as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: TA_DESCRIPTION as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: "gp.ta.description\0".as_ptr(),
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: "gp.ta.version\0".as_ptr(),
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
+    },
+];
+
+#[no_mangle]
+pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
+    return trace_level;
+}
diff --git a/examples/tls_client-rs/uuid.txt b/examples/tls_client-rs/uuid.txt
new file mode 100644
index 0000000..b4a8678
--- /dev/null
+++ b/examples/tls_client-rs/uuid.txt
@@ -0,0 +1 @@
+ec55bfe2-d9c7-11eb-8b0e-f3f8fad927f7
diff --git a/ci/ci.sh b/examples/tls_server-rs/Makefile
old mode 100755
new mode 100644
similarity index 61%
copy from ci/ci.sh
copy to examples/tls_server-rs/Makefile
index e530044..c266055
--- a/ci/ci.sh
+++ b/examples/tls_server-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,23 +15,19 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+# 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
 
-./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
+all:
+	$(q)make -C host TARGET_HOST=$(TARGET_HOST) \
+		CROSS_COMPILE_HOST=$(CROSS_COMPILE_HOST)
+	$(q)make -C ta TARGET_TA=$(TARGET_TA) \
+		CROSS_COMPILE_TA=$(CROSS_COMPILE_TA)
 
-popd
+clean:
+	$(q)make -C host clean
+	$(q)make -C ta clean
diff --git a/ci/ci.sh b/examples/tls_server-rs/host/Cargo.toml
old mode 100755
new mode 100644
similarity index 65%
copy from ci/ci.sh
copy to examples/tls_server-rs/host/Cargo.toml
index e530044..243279e
--- a/ci/ci.sh
+++ b/examples/tls_server-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,23 +15,19 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+[package]
+name = "tls_server-rs"
+version = "0.3.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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
+[dependencies]
+libc = "0.2.48"
+proto = { path = "../proto" }
+optee-teec = { path = "../../../optee-teec" }
 
-popd
+[profile.release]
+lto = true
diff --git a/ci/ci.sh b/examples/tls_server-rs/host/Makefile
old mode 100755
new mode 100644
similarity index 62%
copy from ci/ci.sh
copy to examples/tls_server-rs/host/Makefile
index e530044..92dac4b
--- a/ci/ci.sh
+++ b/examples/tls_server-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,23 +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
-
-popd
+NAME := tls_server-rs
+
+TARGET_HOST ?= aarch64-unknown-linux-gnu
+CROSS_COMPILE_HOST ?= aarch64-linux-gnu-
+OBJCOPY := $(CROSS_COMPILE_HOST)objcopy
+LINKER_CFG := target.$(TARGET_HOST).linker=\"$(CROSS_COMPILE_HOST)gcc\"
+
+OUT_DIR := $(CURDIR)/target/$(TARGET_HOST)/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/tls_server-rs/host/src/main.rs b/examples/tls_server-rs/host/src/main.rs
new file mode 100644
index 0000000..f21d50c
--- /dev/null
+++ b/examples/tls_server-rs/host/src/main.rs
@@ -0,0 +1,119 @@
+// 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(())
+}
diff --git a/ci/ci.sh b/examples/tls_server-rs/proto/Cargo.toml
old mode 100755
new mode 100644
similarity index 67%
copy from ci/ci.sh
copy to examples/tls_server-rs/proto/Cargo.toml
index e530044..b76ceb2
--- a/ci/ci.sh
+++ b/examples/tls_server-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,23 +15,16 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+[package]
+name = "proto"
+version = "0.3.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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"
 
-./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
+[dependencies]
 
-popd
+[build-dependencies]
+uuid = { version = "1.8", default-features = false }
diff --git a/examples/tls_server-rs/proto/build.rs b/examples/tls_server-rs/proto/build.rs
new file mode 100644
index 0000000..b9d0612
--- /dev/null
+++ b/examples/tls_server-rs/proto/build.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.
+
+use std::fs;
+use std::path::PathBuf;
+use std::fs::File;
+use std::env;
+use std::io::Write;
+
+fn main() {
+    let uuid = match fs::read_to_string("../uuid.txt") {
+        Ok(u) => {
+            u.trim().to_string()
+        },
+        Err(_) => {
+            panic!("Cannot find uuid.txt");
+        }
+    };
+    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+    let mut buffer = File::create(out.join("uuid.txt")).unwrap();
+    write!(buffer, "{}", uuid).unwrap();
+}
diff --git a/examples/tls_server-rs/proto/src/lib.rs b/examples/tls_server-rs/proto/src/lib.rs
new file mode 100644
index 0000000..7f71a24
--- /dev/null
+++ b/examples/tls_server-rs/proto/src/lib.rs
@@ -0,0 +1,39 @@
+// 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.
+
+pub enum Command {
+    NewTlsSession,
+    CloseTlsSession,
+    DoTlsRead,
+    DoTlsWrite,
+    Unknown,
+}
+
+impl From<u32> for Command {
+    #[inline]
+    fn from(value: u32) -> Command {
+        match value {
+            0 => Command::NewTlsSession,
+            1 => Command::CloseTlsSession,
+            2 => Command::DoTlsRead,
+            3 => Command::DoTlsWrite,
+            _ => Command::Unknown,
+        }
+    }
+}
+
+pub const UUID: &str = &include_str!(concat!(env!("OUT_DIR"), "/uuid.txt"));
diff --git a/examples/tls_server-rs/ta/Cargo.toml b/examples/tls_server-rs/ta/Cargo.toml
new file mode 100644
index 0000000..fe86cb3
--- /dev/null
+++ b/examples/tls_server-rs/ta/Cargo.toml
@@ -0,0 +1,56 @@
+# 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.
+
+[package]
+name = "ta"
+version = "0.3.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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"
+
+[dependencies]
+libc = { path = "../../../rust/libc" }
+proto = { path = "../proto" }
+optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
+optee-utee = { path = "../../../optee-utee" }
+
+# use new ported version
+rustls = { git = "https://github.com/DemesneGH/rustls-optee.git", branch = "0.21.0-optee", features = ["dangerous_configuration"]}
+ring = "=0.16.20"
+webpki-roots = "0.21"
+webpki = "=0.21.0"
+rustls-pemfile = "1.0"
+sct = "=0.7.0"
+lazy_static = { version = "1.4.0", features=["spin_no_std"] }
+
+[build-dependencies]
+uuid = { version = "1.8", default-features = false }
+proto = { path = "../proto" }
+
+[profile.release]
+panic = "abort"
+lto = false
+opt-level = 1
+
+[patch.crates-io]
+ring = { git = "https://github.com/DemesneGH/ring-optee.git", branch = "0.16.20-optee" }
+
+# Patch optee-utee for rustls
+[patch."https://github.com/apache/incubator-teaclave-trustzone-sdk.git"]
+optee-utee = { path = "../../../optee-utee" }
diff --git a/examples/tls_server-rs/ta/Makefile b/examples/tls_server-rs/ta/Makefile
new file mode 100644
index 0000000..74aeb33
--- /dev/null
+++ b/examples/tls_server-rs/ta/Makefile
@@ -0,0 +1,50 @@
+# 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.
+
+# STD-ONLY example
+
+UUID ?= $(shell cat "../uuid.txt")
+
+TARGET_TA ?= aarch64-unknown-linux-gnu
+CROSS_COMPILE_TA ?= aarch64-linux-gnu-
+OBJCOPY := $(CROSS_COMPILE_TA)objcopy
+LINKER_CFG := target.$(TARGET_TA).linker=\"$(CROSS_COMPILE_TA)ld.bfd\"
+
+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_TA)/release
+
+ifeq ($(STD),)
+all:
+	@echo "Please export STD=y to build the STD version"
+else
+all: ta strip sign
+endif
+
+# set the cross compile for building inner libraries, such as C libraries in ring
+ta:
+	@CROSS_COMPILE=$(CROSS_COMPILE_TA) xargo build --target $(TARGET_TA) --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/.licenserc.yaml b/examples/tls_server-rs/ta/Xargo.toml
similarity index 72%
copy from .licenserc.yaml
copy to examples/tls_server-rs/ta/Xargo.toml
index 0391c38..1b1a113 100644
--- a/.licenserc.yaml
+++ b/examples/tls_server-rs/ta/Xargo.toml
@@ -15,18 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 
-header:
-  license:
-    spdx-id: Apache-2.0
-    copyright-owner: Apache Software Foundation
+[dependencies.std]
+path = "../../../rust/rust/library/std"
 
-  paths-ignore:
-    - 'dist'
-    - 'licenses'
-    - '**/*.md'
-    - 'LICENSE'
-    - 'NOTICE'
-    - '**/Cargo.lock'
-    - 'KEYS'
-    - 'DISCLAIMER-WIP'
-    - '*.json'
+[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/tls_server-rs/ta/build.rs b/examples/tls_server-rs/ta/build.rs
new file mode 100644
index 0000000..fa0d195
--- /dev/null
+++ b/examples/tls_server-rs/ta/build.rs
@@ -0,0 +1,103 @@
+// 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 proto;
+use std::env;
+use std::fs::File;
+use std::io::{BufRead, BufReader, Write};
+use std::path::{Path, PathBuf};
+use uuid::Uuid;
+
+fn main() -> std::io::Result<()> {
+    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+
+    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
+    buffer.write_all(include_bytes!("ta_static.rs"))?;
+
+    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
+    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
+
+    write!(buffer, "\n")?;
+    write!(
+        buffer,
+        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
+    timeLow: {:#x},
+    timeMid: {:#x},
+    timeHiAndVersion: {:#x},
+    clockSeqAndNode: {:#x?},
+}};",
+        time_low, time_mid, time_hi_and_version, clock_seq_and_node
+    )?;
+
+    let mut aarch64_flag = true;
+    match env::var("TARGET_TA") {
+        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
+            println!("cargo:rustc-link-arg=--no-warn-mismatch");
+            aarch64_flag = false;
+        },
+        _ => {}
+    };
+
+    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
+    let search_path = Path::new(&optee_os_dir).join("lib");
+
+    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
+    let mut ta_lds = File::create(out.join("ta.lds"))?;
+    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
+    let f = BufReader::new(f);
+
+    for line in f.lines() {
+        let l = line?;
+
+        if aarch64_flag {
+            if l.starts_with('#') ||
+                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
+                l == "OUTPUT_ARCH(arm)" {
+                continue;
+            }
+        } else {
+            if l.starts_with('#') ||
+                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
+                l == "OUTPUT_ARCH(aarch64)" {
+                continue;
+            }
+        }
+
+        if l == "\t. = ALIGN(4096);" {
+            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
+        } else {
+            write!(ta_lds, "{}\n", l)?;
+        }
+    }
+
+    println!("cargo:rustc-link-search={}", out.display());
+    println!("cargo:rerun-if-changed=ta.lds");
+
+    println!("cargo:rustc-link-search={}", search_path.display());
+    println!("cargo:rustc-link-lib=static=utee");
+    println!("cargo:rustc-link-lib=static=utils");
+    println!("cargo:rustc-link-arg=-Tta.lds");
+    println!("cargo:rustc-link-arg=-e__ta_entry");
+    println!("cargo:rustc-link-arg=-pie");
+    println!("cargo:rustc-link-arg=-Os");
+    println!("cargo:rustc-link-arg=--sort-section=alignment");
+
+    let mut dyn_list = File::create(out.join("dyn_list"))?;
+    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
+    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
+    Ok(())
+}
diff --git a/examples/tls_server-rs/ta/src/main.rs b/examples/tls_server-rs/ta/src/main.rs
new file mode 100644
index 0000000..0beb9ec
--- /dev/null
+++ b/examples/tls_server-rs/ta/src/main.rs
@@ -0,0 +1,179 @@
+// 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_main]
+#![feature(c_size_t)]
+
+use optee_utee::{
+    ta_close_session, ta_create, ta_destroy, ta_invoke_command, ta_open_session, trace_println,
+};
+use optee_utee::{Error, ErrorKind, Parameters, Result};
+use proto::Command;
+
+use lazy_static::lazy_static;
+use std::collections::HashMap;
+use std::io::{BufReader, Cursor, Read, Write};
+use std::sync::{Arc, Mutex, RwLock};
+
+lazy_static! {
+    static ref TLS_SESSIONS: RwLock<HashMap<u32, Mutex<rustls::ServerConnection>>> =
+        RwLock::new(HashMap::new());
+}
+
+#[ta_create]
+fn create() -> Result<()> {
+    trace_println!("[+] TA create");
+    Ok(())
+}
+
+#[ta_open_session]
+fn open_session(_params: &mut Parameters) -> Result<()> {
+    trace_println!("[+] TA open session");
+    Ok(())
+}
+
+#[ta_close_session]
+fn close_session() {
+    trace_println!("[+] TA close session");
+}
+
+#[ta_destroy]
+fn destroy() {
+    trace_println!("[+] TA destroy");
+}
+
+#[ta_invoke_command]
+fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
+    trace_println!("[+] TA invoke command");
+    let session_id = unsafe { params.0.as_value().unwrap().a() };
+    trace_println!("[+] session id: {}", session_id);
+    match Command::from(cmd_id) {
+        Command::NewTlsSession => {
+            trace_println!("[+] new_tls_session");
+            new_tls_session(session_id);
+            Ok(())
+        }
+        Command::DoTlsRead => {
+            let mut p1 = unsafe { params.1.as_memref().unwrap() };
+            let buffer = p1.buffer();
+            trace_println!("[+] do_tls_read");
+            do_tls_read(session_id, buffer);
+            Ok(())
+        }
+        Command::DoTlsWrite => {
+            trace_println!("[+] do_tls_write");
+            let mut p1 = unsafe { params.1.as_memref().unwrap() };
+            let mut p2 = unsafe { params.2.as_value().unwrap() };
+            let mut buffer = p1.buffer();
+            let n = do_tls_write(session_id, &mut buffer);
+            p2.set_a(n as u32);
+            Ok(())
+        }
+        Command::CloseTlsSession => {
+            trace_println!("[+] close_tls_session");
+            close_tls_session(session_id);
+            Ok(())
+        }
+        _ => Err(Error::new(ErrorKind::BadParameters)),
+    }
+}
+
+pub fn new_tls_session(session_id: u32) {
+    let tls_config = make_config();
+    let tls_session = rustls::ServerConnection::new(tls_config).unwrap();
+    TLS_SESSIONS
+        .write()
+        .unwrap()
+        .insert(session_id, Mutex::new(tls_session));
+}
+
+pub fn close_tls_session(session_id: u32) {
+    TLS_SESSIONS.write().unwrap().remove(&session_id);
+}
+
+pub fn do_tls_read(session_id: u32, buf: &[u8]) {
+    let mut rd = Cursor::new(buf);
+    let ts_guard = TLS_SESSIONS.read().unwrap();
+    let mut tls_session = ts_guard.get(&session_id).unwrap().lock().unwrap();
+    let _rc = tls_session.read_tls(&mut rd).unwrap();
+    let _processed = tls_session.process_new_packets().unwrap();
+
+    // Read and process all available plaintext.
+    let mut buf = Vec::new();
+    let _rc = tls_session.reader().read_to_end(&mut buf);
+    if !buf.is_empty() {
+        tls_session.writer().write_all(&buf).unwrap();
+    }
+}
+
+pub fn do_tls_write(session_id: u32, buf: &mut [u8]) -> usize {
+    let ts_guard = TLS_SESSIONS.read().unwrap();
+    let mut tls_session = ts_guard.get(&session_id).unwrap().lock().unwrap();
+    let mut wr = Cursor::new(buf);
+    let mut rc = 0;
+    while tls_session.wants_write() {
+        rc += tls_session.write_tls(&mut wr).unwrap();
+    }
+
+    rc
+}
+
+fn make_config() -> Arc<rustls::ServerConfig> {
+    let certs = load_certs();
+    let privkey = load_private_key();
+    let config = rustls::ServerConfig::builder()
+        .with_safe_defaults()
+        .with_no_client_auth()
+        .with_single_cert(certs, privkey)
+        .unwrap();
+
+    Arc::new(config)
+}
+
+fn load_certs() -> Vec<rustls::Certificate> {
+    let bytes = include_bytes!("../test-ca/ecdsa/end.fullchain").to_vec();
+    let cursor = std::io::Cursor::new(bytes);
+    let mut reader = BufReader::new(cursor);
+    let certs = rustls_pemfile::certs(&mut reader).unwrap();
+    certs
+        .iter()
+        .map(|v| rustls::Certificate(v.clone()))
+        .collect()
+}
+
+fn load_private_key() -> rustls::PrivateKey {
+    let bytes = include_bytes!("../test-ca/ecdsa/end.key").to_vec();
+    let cursor = std::io::Cursor::new(bytes);
+    let mut reader = BufReader::new(cursor);
+    let keys = rustls_pemfile::pkcs8_private_keys(&mut reader).unwrap();
+    assert_eq!(keys.len(), 1);
+    rustls::PrivateKey(keys[0].clone())
+}
+
+// TA configurations
+const TA_FLAGS: u32 = 0;
+const TA_DATA_SIZE: u32 = 18 * 1024 * 1024;
+const TA_STACK_SIZE: u32 = 2 * 1024 * 1024;
+const TA_VERSION: &[u8] = b"0.3\0";
+const TA_DESCRIPTION: &[u8] = b"This is a tls server example.\0";
+const EXT_PROP_VALUE_1: &[u8] = b"TLS Server TA\0";
+const EXT_PROP_VALUE_2: u32 = 0x0010;
+const TRACE_LEVEL: i32 = 4;
+const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
+const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
+
+include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/tls_server-rs/ta/ta_static.rs b/examples/tls_server-rs/ta/ta_static.rs
new file mode 100644
index 0000000..53ca210
--- /dev/null
+++ b/examples/tls_server-rs/ta/ta_static.rs
@@ -0,0 +1,102 @@
+// 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 core::ffi::*;
+use core::mem;
+use core::primitive::u64;
+
+#[no_mangle]
+pub static mut trace_level: c_int = TRACE_LEVEL;
+
+#[no_mangle]
+pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
+
+#[no_mangle]
+#[link_section = ".ta_head"]
+pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
+    uuid: TA_UUID,
+    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
+    flags: TA_FLAGS,
+    depr_entry: u64::MAX,
+};
+
+#[no_mangle]
+#[link_section = ".bss"]
+pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
+
+#[no_mangle]
+pub static ta_heap_size: c_size_t = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
+static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
+static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
+static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
+
+#[no_mangle]
+pub static ta_num_props: c_size_t = 9;
+
+#[no_mangle]
+pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_BOOL as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_MULTI as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_INSTANCE as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &TA_DATA_SIZE as *const u32 as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &TA_STACK_SIZE as *const u32 as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_VERSION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: TA_VERSION as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: TA_DESCRIPTION as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: "gp.ta.description\0".as_ptr(),
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: "gp.ta.version\0".as_ptr(),
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
+    },
+];
+
+#[no_mangle]
+pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
+    return trace_level;
+}
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/ca.cert b/examples/tls_server-rs/ta/test-ca/ecdsa/ca.cert
new file mode 100644
index 0000000..4b076bd
--- /dev/null
+++ b/examples/tls_server-rs/ta/test-ca/ecdsa/ca.cert
@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIByjCCAVCgAwIBAgIUSA11/39PY7uM9Nc2ITnV1eHzaKYwCgYIKoZIzj0EAwIw
+HDEaMBgGA1UEAwwRcG9ueXRvd24gRUNEU0EgQ0EwHhcNMTkwNjA5MTcxNTEyWhcN
+MjkwNjA2MTcxNTEyWjAcMRowGAYDVQQDDBFwb255dG93biBFQ0RTQSBDQTB2MBAG
+ByqGSM49AgEGBSuBBAAiA2IABLsXWEKs2xXCgW1OcC63pCPjQo0q3VnPc1J24n6m
+Xwxpg398nzR4n3iHcYA0pKgEneBstSOsXOhbNZ09DAvEr3iSc8ByWWntEbWVjY3g
+9Kt6Q6Y1sXGkaUIiP9be5lIQRaNTMFEwHQYDVR0OBBYEFKD72TTU/GXhb3/D1/Z7
+hD/ZG6lKMB8GA1UdIwQYMBaAFKD72TTU/GXhb3/D1/Z7hD/ZG6lKMA8GA1UdEwEB
+/wQFMAMBAf8wCgYIKoZIzj0EAwIDaAAwZQIxAL9FtbNV7i9trxukhakfTvbXCHgE
+2pIOT5r/Vc5kSrPU4vJu2MOJz6X/JCX15IbZlQIwJxYfsD8QTQf8J9bP9Pq4SY71
+obja/vQ6UBixlRB5vDSG0UuukL4kzlyUKpHkwUcj
+-----END CERTIFICATE-----
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/ca.der b/examples/tls_server-rs/ta/test-ca/ecdsa/ca.der
new file mode 100644
index 0000000..575c9c0
Binary files /dev/null and b/examples/tls_server-rs/ta/test-ca/ecdsa/ca.der differ
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/ca.key b/examples/tls_server-rs/ta/test-ca/ecdsa/ca.key
new file mode 100644
index 0000000..afeb1af
--- /dev/null
+++ b/examples/tls_server-rs/ta/test-ca/ecdsa/ca.key
@@ -0,0 +1,6 @@
+-----BEGIN PRIVATE KEY-----
+MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDDl30Srs7laSdaAOzoB
+kCiehcf1HXv7NqGQBECqshrtHxGEX6bAnBB7JgyDs28NvPGhZANiAAS7F1hCrNsV
+woFtTnAut6Qj40KNKt1Zz3NSduJ+pl8MaYN/fJ80eJ94h3GANKSoBJ3gbLUjrFzo
+WzWdPQwLxK94knPAcllp7RG1lY2N4PSrekOmNbFxpGlCIj/W3uZSEEU=
+-----END PRIVATE KEY-----
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/client.cert b/examples/tls_server-rs/ta/test-ca/ecdsa/client.cert
new file mode 100644
index 0000000..f40f1c9
--- /dev/null
+++ b/examples/tls_server-rs/ta/test-ca/ecdsa/client.cert
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB8jCCAZegAwIBAgICAxUwCgYIKoZIzj0EAwIwLjEsMCoGA1UEAwwjcG9ueXRv
+d24gRUNEU0EgbGV2ZWwgMiBpbnRlcm1lZGlhdGUwHhcNMTkwNjA5MTcxNTEyWhcN
+MjQxMTI5MTcxNTEyWjAaMRgwFgYDVQQDDA9wb255dG93biBjbGllbnQwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAATx0R97foSC0Ra9a13pJzfI1hh3G6476MIMslLHxg5w
+wCG8k5mMHia2hGOBbdGjoY0C1wJLNrUSov5SfcsYX6/VjHQH/elmb/KOO1AGwPD7
+1yD1+DG/cjK1okLZIVhbSQyjgZswgZgwDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMC
+BsAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwHQYDVR0OBBYEFFBkko+0OE2piFRx
+h9m2UonFYQFEMEQGA1UdIwQ9MDuAFD93gjUQ7CX28Dy5NlFYfYh8XlKSoSCkHjAc
+MRowGAYDVQQDDBFwb255dG93biBFQ0RTQSBDQYIBezAKBggqhkjOPQQDAgNJADBG
+AiEAvyquOUQlqAWkSlfwH3nYNmmEG9CT/jjzNs1OBr1RD6ACIQDtmqdbttqgqKAZ
+Wi5lCzftwM6Hy5aA0qy1v80H4xBJyw==
+-----END CERTIFICATE-----
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/client.chain b/examples/tls_server-rs/ta/test-ca/ecdsa/client.chain
new file mode 100644
index 0000000..c1fe549
--- /dev/null
+++ b/examples/tls_server-rs/ta/test-ca/ecdsa/client.chain
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIBuDCCAT2gAwIBAgIBezAKBggqhkjOPQQDAjAcMRowGAYDVQQDDBFwb255dG93
+biBFQ0RTQSBDQTAeFw0xOTA2MDkxNzE1MTJaFw0yOTA2MDYxNzE1MTJaMC4xLDAq
+BgNVBAMMI3Bvbnl0b3duIEVDRFNBIGxldmVsIDIgaW50ZXJtZWRpYXRlMFkwEwYH
+KoZIzj0CAQYIKoZIzj0DAQcDQgAEYtRlPykhT0YLnjcSsbe8rfmJ7ojfWuHImDGx
+DpF5vJ259giO99qFEcZTi7dNvQGBQC6bsUWddTl3Bc7gxiCr3aNeMFwwHQYDVR0O
+BBYEFD93gjUQ7CX28Dy5NlFYfYh8XlKSMCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMB
+BggrBgEFBQcDAjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB/jAKBggqhkjOPQQD
+AgNpADBmAjEAxdSnB7ryhG+y7tshwxqrFoZEWXpDLQDZGad0+Wf+7hiNoNCDDdIv
+MhYxzCDbTS/lAjEAwjsfrp4gxwoz/6fNfUvHyiA3j9jMd64tapzWy2hoqubKBEum
+EVczk9vVmsiJA5J3
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIByjCCAVCgAwIBAgIUSA11/39PY7uM9Nc2ITnV1eHzaKYwCgYIKoZIzj0EAwIw
+HDEaMBgGA1UEAwwRcG9ueXRvd24gRUNEU0EgQ0EwHhcNMTkwNjA5MTcxNTEyWhcN
+MjkwNjA2MTcxNTEyWjAcMRowGAYDVQQDDBFwb255dG93biBFQ0RTQSBDQTB2MBAG
+ByqGSM49AgEGBSuBBAAiA2IABLsXWEKs2xXCgW1OcC63pCPjQo0q3VnPc1J24n6m
+Xwxpg398nzR4n3iHcYA0pKgEneBstSOsXOhbNZ09DAvEr3iSc8ByWWntEbWVjY3g
+9Kt6Q6Y1sXGkaUIiP9be5lIQRaNTMFEwHQYDVR0OBBYEFKD72TTU/GXhb3/D1/Z7
+hD/ZG6lKMB8GA1UdIwQYMBaAFKD72TTU/GXhb3/D1/Z7hD/ZG6lKMA8GA1UdEwEB
+/wQFMAMBAf8wCgYIKoZIzj0EAwIDaAAwZQIxAL9FtbNV7i9trxukhakfTvbXCHgE
+2pIOT5r/Vc5kSrPU4vJu2MOJz6X/JCX15IbZlQIwJxYfsD8QTQf8J9bP9Pq4SY71
+obja/vQ6UBixlRB5vDSG0UuukL4kzlyUKpHkwUcj
+-----END CERTIFICATE-----
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/client.fullchain b/examples/tls_server-rs/ta/test-ca/ecdsa/client.fullchain
new file mode 100644
index 0000000..8f9c2b4
--- /dev/null
+++ b/examples/tls_server-rs/ta/test-ca/ecdsa/client.fullchain
@@ -0,0 +1,37 @@
+-----BEGIN CERTIFICATE-----
+MIIB8jCCAZegAwIBAgICAxUwCgYIKoZIzj0EAwIwLjEsMCoGA1UEAwwjcG9ueXRv
+d24gRUNEU0EgbGV2ZWwgMiBpbnRlcm1lZGlhdGUwHhcNMTkwNjA5MTcxNTEyWhcN
+MjQxMTI5MTcxNTEyWjAaMRgwFgYDVQQDDA9wb255dG93biBjbGllbnQwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAATx0R97foSC0Ra9a13pJzfI1hh3G6476MIMslLHxg5w
+wCG8k5mMHia2hGOBbdGjoY0C1wJLNrUSov5SfcsYX6/VjHQH/elmb/KOO1AGwPD7
+1yD1+DG/cjK1okLZIVhbSQyjgZswgZgwDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMC
+BsAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwHQYDVR0OBBYEFFBkko+0OE2piFRx
+h9m2UonFYQFEMEQGA1UdIwQ9MDuAFD93gjUQ7CX28Dy5NlFYfYh8XlKSoSCkHjAc
+MRowGAYDVQQDDBFwb255dG93biBFQ0RTQSBDQYIBezAKBggqhkjOPQQDAgNJADBG
+AiEAvyquOUQlqAWkSlfwH3nYNmmEG9CT/jjzNs1OBr1RD6ACIQDtmqdbttqgqKAZ
+Wi5lCzftwM6Hy5aA0qy1v80H4xBJyw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIBuDCCAT2gAwIBAgIBezAKBggqhkjOPQQDAjAcMRowGAYDVQQDDBFwb255dG93
+biBFQ0RTQSBDQTAeFw0xOTA2MDkxNzE1MTJaFw0yOTA2MDYxNzE1MTJaMC4xLDAq
+BgNVBAMMI3Bvbnl0b3duIEVDRFNBIGxldmVsIDIgaW50ZXJtZWRpYXRlMFkwEwYH
+KoZIzj0CAQYIKoZIzj0DAQcDQgAEYtRlPykhT0YLnjcSsbe8rfmJ7ojfWuHImDGx
+DpF5vJ259giO99qFEcZTi7dNvQGBQC6bsUWddTl3Bc7gxiCr3aNeMFwwHQYDVR0O
+BBYEFD93gjUQ7CX28Dy5NlFYfYh8XlKSMCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMB
+BggrBgEFBQcDAjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB/jAKBggqhkjOPQQD
+AgNpADBmAjEAxdSnB7ryhG+y7tshwxqrFoZEWXpDLQDZGad0+Wf+7hiNoNCDDdIv
+MhYxzCDbTS/lAjEAwjsfrp4gxwoz/6fNfUvHyiA3j9jMd64tapzWy2hoqubKBEum
+EVczk9vVmsiJA5J3
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIByjCCAVCgAwIBAgIUSA11/39PY7uM9Nc2ITnV1eHzaKYwCgYIKoZIzj0EAwIw
+HDEaMBgGA1UEAwwRcG9ueXRvd24gRUNEU0EgQ0EwHhcNMTkwNjA5MTcxNTEyWhcN
+MjkwNjA2MTcxNTEyWjAcMRowGAYDVQQDDBFwb255dG93biBFQ0RTQSBDQTB2MBAG
+ByqGSM49AgEGBSuBBAAiA2IABLsXWEKs2xXCgW1OcC63pCPjQo0q3VnPc1J24n6m
+Xwxpg398nzR4n3iHcYA0pKgEneBstSOsXOhbNZ09DAvEr3iSc8ByWWntEbWVjY3g
+9Kt6Q6Y1sXGkaUIiP9be5lIQRaNTMFEwHQYDVR0OBBYEFKD72TTU/GXhb3/D1/Z7
+hD/ZG6lKMB8GA1UdIwQYMBaAFKD72TTU/GXhb3/D1/Z7hD/ZG6lKMA8GA1UdEwEB
+/wQFMAMBAf8wCgYIKoZIzj0EAwIDaAAwZQIxAL9FtbNV7i9trxukhakfTvbXCHgE
+2pIOT5r/Vc5kSrPU4vJu2MOJz6X/JCX15IbZlQIwJxYfsD8QTQf8J9bP9Pq4SY71
+obja/vQ6UBixlRB5vDSG0UuukL4kzlyUKpHkwUcj
+-----END CERTIFICATE-----
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/client.key b/examples/tls_server-rs/ta/test-ca/ecdsa/client.key
new file mode 100644
index 0000000..412914c
--- /dev/null
+++ b/examples/tls_server-rs/ta/test-ca/ecdsa/client.key
@@ -0,0 +1,6 @@
+-----BEGIN PRIVATE KEY-----
+MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDALKtA1q+8ZBeLi2Gsq
+UxFTBxNPPhOuyNRkvwRKis/glf9GgEHgvM0qVaxWnRsdCE6hZANiAATx0R97foSC
+0Ra9a13pJzfI1hh3G6476MIMslLHxg5wwCG8k5mMHia2hGOBbdGjoY0C1wJLNrUS
+ov5SfcsYX6/VjHQH/elmb/KOO1AGwPD71yD1+DG/cjK1okLZIVhbSQw=
+-----END PRIVATE KEY-----
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/client.req b/examples/tls_server-rs/ta/test-ca/ecdsa/client.req
new file mode 100644
index 0000000..850b32a
--- /dev/null
+++ b/examples/tls_server-rs/ta/test-ca/ecdsa/client.req
@@ -0,0 +1,8 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBEzCBmQIBADAaMRgwFgYDVQQDDA9wb255dG93biBjbGllbnQwdjAQBgcqhkjO
+PQIBBgUrgQQAIgNiAATx0R97foSC0Ra9a13pJzfI1hh3G6476MIMslLHxg5wwCG8
+k5mMHia2hGOBbdGjoY0C1wJLNrUSov5SfcsYX6/VjHQH/elmb/KOO1AGwPD71yD1
++DG/cjK1okLZIVhbSQygADAKBggqhkjOPQQDAgNpADBmAjEA8p3W7yFCJ73dOmYQ
+rpMpLkYNcfxxpNfCWgqaPyWu3UeOcHvC7ihklnFTWzpmEO+PAjEA8O5P4mXlYUtl
+Dsw8qOrqWSdQ1IykXhM4NxPOkt0TMQZvvrpSsJU6PhwSbJGjVfBR
+-----END CERTIFICATE REQUEST-----
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/end.cert b/examples/tls_server-rs/ta/test-ca/ecdsa/end.cert
new file mode 100644
index 0000000..7391b34
--- /dev/null
+++ b/examples/tls_server-rs/ta/test-ca/ecdsa/end.cert
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB9zCCAZ6gAwIBAgICAcgwCgYIKoZIzj0EAwIwLjEsMCoGA1UEAwwjcG9ueXRv
+d24gRUNEU0EgbGV2ZWwgMiBpbnRlcm1lZGlhdGUwHhcNMTkwNjA5MTcxNTEyWhcN
+MjQxMTI5MTcxNTEyWjAZMRcwFQYDVQQDDA50ZXN0c2VydmVyLmNvbTBZMBMGByqG
+SM49AgEGCCqGSM49AwEHA0IABPprdHsWc3TtNne2409qO+fC9OFiiXFevQwJjUUC
+J/X0ihomRsHAnrJvcNyOEWsdu7OwOj4PD9QFMifDEHGYtHOjgcAwgb0wDAYDVR0T
+AQH/BAIwADALBgNVHQ8EBAMCBsAwHQYDVR0OBBYEFOXZcb/0+/Xql1fOb4pVblzV
+vUcZMEQGA1UdIwQ9MDuAFD93gjUQ7CX28Dy5NlFYfYh8XlKSoSCkHjAcMRowGAYD
+VQQDDBFwb255dG93biBFQ0RTQSBDQYIBezA7BgNVHREENDAygg50ZXN0c2VydmVy
+LmNvbYIVc2Vjb25kLnRlc3RzZXJ2ZXIuY29tgglsb2NhbGhvc3QwCgYIKoZIzj0E
+AwIDRwAwRAIgXONA4IOh4PbHTuK6oaHtguOIvmxxXCqp8kwJlI1e+MMCICOSrk1F
+e+VsbKeFQlJ6EM65CLTezDUIZKCmoNWvyTGy
+-----END CERTIFICATE-----
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/end.chain b/examples/tls_server-rs/ta/test-ca/ecdsa/end.chain
new file mode 100644
index 0000000..c1fe549
--- /dev/null
+++ b/examples/tls_server-rs/ta/test-ca/ecdsa/end.chain
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIBuDCCAT2gAwIBAgIBezAKBggqhkjOPQQDAjAcMRowGAYDVQQDDBFwb255dG93
+biBFQ0RTQSBDQTAeFw0xOTA2MDkxNzE1MTJaFw0yOTA2MDYxNzE1MTJaMC4xLDAq
+BgNVBAMMI3Bvbnl0b3duIEVDRFNBIGxldmVsIDIgaW50ZXJtZWRpYXRlMFkwEwYH
+KoZIzj0CAQYIKoZIzj0DAQcDQgAEYtRlPykhT0YLnjcSsbe8rfmJ7ojfWuHImDGx
+DpF5vJ259giO99qFEcZTi7dNvQGBQC6bsUWddTl3Bc7gxiCr3aNeMFwwHQYDVR0O
+BBYEFD93gjUQ7CX28Dy5NlFYfYh8XlKSMCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMB
+BggrBgEFBQcDAjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB/jAKBggqhkjOPQQD
+AgNpADBmAjEAxdSnB7ryhG+y7tshwxqrFoZEWXpDLQDZGad0+Wf+7hiNoNCDDdIv
+MhYxzCDbTS/lAjEAwjsfrp4gxwoz/6fNfUvHyiA3j9jMd64tapzWy2hoqubKBEum
+EVczk9vVmsiJA5J3
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIByjCCAVCgAwIBAgIUSA11/39PY7uM9Nc2ITnV1eHzaKYwCgYIKoZIzj0EAwIw
+HDEaMBgGA1UEAwwRcG9ueXRvd24gRUNEU0EgQ0EwHhcNMTkwNjA5MTcxNTEyWhcN
+MjkwNjA2MTcxNTEyWjAcMRowGAYDVQQDDBFwb255dG93biBFQ0RTQSBDQTB2MBAG
+ByqGSM49AgEGBSuBBAAiA2IABLsXWEKs2xXCgW1OcC63pCPjQo0q3VnPc1J24n6m
+Xwxpg398nzR4n3iHcYA0pKgEneBstSOsXOhbNZ09DAvEr3iSc8ByWWntEbWVjY3g
+9Kt6Q6Y1sXGkaUIiP9be5lIQRaNTMFEwHQYDVR0OBBYEFKD72TTU/GXhb3/D1/Z7
+hD/ZG6lKMB8GA1UdIwQYMBaAFKD72TTU/GXhb3/D1/Z7hD/ZG6lKMA8GA1UdEwEB
+/wQFMAMBAf8wCgYIKoZIzj0EAwIDaAAwZQIxAL9FtbNV7i9trxukhakfTvbXCHgE
+2pIOT5r/Vc5kSrPU4vJu2MOJz6X/JCX15IbZlQIwJxYfsD8QTQf8J9bP9Pq4SY71
+obja/vQ6UBixlRB5vDSG0UuukL4kzlyUKpHkwUcj
+-----END CERTIFICATE-----
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/end.fullchain b/examples/tls_server-rs/ta/test-ca/ecdsa/end.fullchain
new file mode 100644
index 0000000..535baef
--- /dev/null
+++ b/examples/tls_server-rs/ta/test-ca/ecdsa/end.fullchain
@@ -0,0 +1,37 @@
+-----BEGIN CERTIFICATE-----
+MIIB9zCCAZ6gAwIBAgICAcgwCgYIKoZIzj0EAwIwLjEsMCoGA1UEAwwjcG9ueXRv
+d24gRUNEU0EgbGV2ZWwgMiBpbnRlcm1lZGlhdGUwHhcNMTkwNjA5MTcxNTEyWhcN
+MjQxMTI5MTcxNTEyWjAZMRcwFQYDVQQDDA50ZXN0c2VydmVyLmNvbTBZMBMGByqG
+SM49AgEGCCqGSM49AwEHA0IABPprdHsWc3TtNne2409qO+fC9OFiiXFevQwJjUUC
+J/X0ihomRsHAnrJvcNyOEWsdu7OwOj4PD9QFMifDEHGYtHOjgcAwgb0wDAYDVR0T
+AQH/BAIwADALBgNVHQ8EBAMCBsAwHQYDVR0OBBYEFOXZcb/0+/Xql1fOb4pVblzV
+vUcZMEQGA1UdIwQ9MDuAFD93gjUQ7CX28Dy5NlFYfYh8XlKSoSCkHjAcMRowGAYD
+VQQDDBFwb255dG93biBFQ0RTQSBDQYIBezA7BgNVHREENDAygg50ZXN0c2VydmVy
+LmNvbYIVc2Vjb25kLnRlc3RzZXJ2ZXIuY29tgglsb2NhbGhvc3QwCgYIKoZIzj0E
+AwIDRwAwRAIgXONA4IOh4PbHTuK6oaHtguOIvmxxXCqp8kwJlI1e+MMCICOSrk1F
+e+VsbKeFQlJ6EM65CLTezDUIZKCmoNWvyTGy
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIBuDCCAT2gAwIBAgIBezAKBggqhkjOPQQDAjAcMRowGAYDVQQDDBFwb255dG93
+biBFQ0RTQSBDQTAeFw0xOTA2MDkxNzE1MTJaFw0yOTA2MDYxNzE1MTJaMC4xLDAq
+BgNVBAMMI3Bvbnl0b3duIEVDRFNBIGxldmVsIDIgaW50ZXJtZWRpYXRlMFkwEwYH
+KoZIzj0CAQYIKoZIzj0DAQcDQgAEYtRlPykhT0YLnjcSsbe8rfmJ7ojfWuHImDGx
+DpF5vJ259giO99qFEcZTi7dNvQGBQC6bsUWddTl3Bc7gxiCr3aNeMFwwHQYDVR0O
+BBYEFD93gjUQ7CX28Dy5NlFYfYh8XlKSMCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMB
+BggrBgEFBQcDAjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB/jAKBggqhkjOPQQD
+AgNpADBmAjEAxdSnB7ryhG+y7tshwxqrFoZEWXpDLQDZGad0+Wf+7hiNoNCDDdIv
+MhYxzCDbTS/lAjEAwjsfrp4gxwoz/6fNfUvHyiA3j9jMd64tapzWy2hoqubKBEum
+EVczk9vVmsiJA5J3
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIByjCCAVCgAwIBAgIUSA11/39PY7uM9Nc2ITnV1eHzaKYwCgYIKoZIzj0EAwIw
+HDEaMBgGA1UEAwwRcG9ueXRvd24gRUNEU0EgQ0EwHhcNMTkwNjA5MTcxNTEyWhcN
+MjkwNjA2MTcxNTEyWjAcMRowGAYDVQQDDBFwb255dG93biBFQ0RTQSBDQTB2MBAG
+ByqGSM49AgEGBSuBBAAiA2IABLsXWEKs2xXCgW1OcC63pCPjQo0q3VnPc1J24n6m
+Xwxpg398nzR4n3iHcYA0pKgEneBstSOsXOhbNZ09DAvEr3iSc8ByWWntEbWVjY3g
+9Kt6Q6Y1sXGkaUIiP9be5lIQRaNTMFEwHQYDVR0OBBYEFKD72TTU/GXhb3/D1/Z7
+hD/ZG6lKMB8GA1UdIwQYMBaAFKD72TTU/GXhb3/D1/Z7hD/ZG6lKMA8GA1UdEwEB
+/wQFMAMBAf8wCgYIKoZIzj0EAwIDaAAwZQIxAL9FtbNV7i9trxukhakfTvbXCHgE
+2pIOT5r/Vc5kSrPU4vJu2MOJz6X/JCX15IbZlQIwJxYfsD8QTQf8J9bP9Pq4SY71
+obja/vQ6UBixlRB5vDSG0UuukL4kzlyUKpHkwUcj
+-----END CERTIFICATE-----
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/end.key b/examples/tls_server-rs/ta/test-ca/ecdsa/end.key
new file mode 100644
index 0000000..a88818c
--- /dev/null
+++ b/examples/tls_server-rs/ta/test-ca/ecdsa/end.key
@@ -0,0 +1,5 @@
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgdoMBbIGRw+L9but3
+PO4WSJfS8wbvUNrF1VuQjsDVMKmhRANCAAT6a3R7FnN07TZ3tuNPajvnwvThYolx
+Xr0MCY1FAif19IoaJkbBwJ6yb3DcjhFrHbuzsDo+Dw/UBTInwxBxmLRz
+-----END PRIVATE KEY-----
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/end.req b/examples/tls_server-rs/ta/test-ca/ecdsa/end.req
new file mode 100644
index 0000000..ee7c2a0
--- /dev/null
+++ b/examples/tls_server-rs/ta/test-ca/ecdsa/end.req
@@ -0,0 +1,7 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIHTMHsCAQAwGTEXMBUGA1UEAwwOdGVzdHNlcnZlci5jb20wWTATBgcqhkjOPQIB
+BggqhkjOPQMBBwNCAAT6a3R7FnN07TZ3tuNPajvnwvThYolxXr0MCY1FAif19Ioa
+JkbBwJ6yb3DcjhFrHbuzsDo+Dw/UBTInwxBxmLRzoAAwCgYIKoZIzj0EAwIDSAAw
+RQIgA9G3IaH4syAQYGJ3ESqXQaoKSrZsDMBD0MgG2g2FC78CIQD+RRTETPkFq0as
+cca9W/yqg8QN/ZGzE38iEpohyGda/w==
+-----END CERTIFICATE REQUEST-----
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/inter.cert b/examples/tls_server-rs/ta/test-ca/ecdsa/inter.cert
new file mode 100644
index 0000000..f3843b4
--- /dev/null
+++ b/examples/tls_server-rs/ta/test-ca/ecdsa/inter.cert
@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIBuDCCAT2gAwIBAgIBezAKBggqhkjOPQQDAjAcMRowGAYDVQQDDBFwb255dG93
+biBFQ0RTQSBDQTAeFw0xOTA2MDkxNzE1MTJaFw0yOTA2MDYxNzE1MTJaMC4xLDAq
+BgNVBAMMI3Bvbnl0b3duIEVDRFNBIGxldmVsIDIgaW50ZXJtZWRpYXRlMFkwEwYH
+KoZIzj0CAQYIKoZIzj0DAQcDQgAEYtRlPykhT0YLnjcSsbe8rfmJ7ojfWuHImDGx
+DpF5vJ259giO99qFEcZTi7dNvQGBQC6bsUWddTl3Bc7gxiCr3aNeMFwwHQYDVR0O
+BBYEFD93gjUQ7CX28Dy5NlFYfYh8XlKSMCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMB
+BggrBgEFBQcDAjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB/jAKBggqhkjOPQQD
+AgNpADBmAjEAxdSnB7ryhG+y7tshwxqrFoZEWXpDLQDZGad0+Wf+7hiNoNCDDdIv
+MhYxzCDbTS/lAjEAwjsfrp4gxwoz/6fNfUvHyiA3j9jMd64tapzWy2hoqubKBEum
+EVczk9vVmsiJA5J3
+-----END CERTIFICATE-----
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/inter.key b/examples/tls_server-rs/ta/test-ca/ecdsa/inter.key
new file mode 100644
index 0000000..f9f8b12
--- /dev/null
+++ b/examples/tls_server-rs/ta/test-ca/ecdsa/inter.key
@@ -0,0 +1,5 @@
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgdniIWGzkYuZcwh/H
+9hDbaITfndAs+Hin6j+0XjD01MShRANCAARi1GU/KSFPRgueNxKxt7yt+YnuiN9a
+4ciYMbEOkXm8nbn2CI732oURxlOLt029AYFALpuxRZ11OXcFzuDGIKvd
+-----END PRIVATE KEY-----
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/inter.req b/examples/tls_server-rs/ta/test-ca/ecdsa/inter.req
new file mode 100644
index 0000000..d7c5ec9
--- /dev/null
+++ b/examples/tls_server-rs/ta/test-ca/ecdsa/inter.req
@@ -0,0 +1,7 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIHoMIGQAgEAMC4xLDAqBgNVBAMMI3Bvbnl0b3duIEVDRFNBIGxldmVsIDIgaW50
+ZXJtZWRpYXRlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYtRlPykhT0YLnjcS
+sbe8rfmJ7ojfWuHImDGxDpF5vJ259giO99qFEcZTi7dNvQGBQC6bsUWddTl3Bc7g
+xiCr3aAAMAoGCCqGSM49BAMCA0cAMEQCIFeMseiKS80m8KmHkl7W8lRXavH5yx/h
+qTFM+f3T4AnZAiBRR8+rFop/TR51gISUfbMj2W3yTAGxOkCdlPgT+Jxqwg==
+-----END CERTIFICATE REQUEST-----
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/nistp256.pem b/examples/tls_server-rs/ta/test-ca/ecdsa/nistp256.pem
new file mode 100644
index 0000000..a76e47d
--- /dev/null
+++ b/examples/tls_server-rs/ta/test-ca/ecdsa/nistp256.pem
@@ -0,0 +1,3 @@
+-----BEGIN EC PARAMETERS-----
+BggqhkjOPQMBBw==
+-----END EC PARAMETERS-----
diff --git a/examples/tls_server-rs/ta/test-ca/ecdsa/nistp384.pem b/examples/tls_server-rs/ta/test-ca/ecdsa/nistp384.pem
new file mode 100644
index 0000000..ceed209
--- /dev/null
+++ b/examples/tls_server-rs/ta/test-ca/ecdsa/nistp384.pem
@@ -0,0 +1,3 @@
+-----BEGIN EC PARAMETERS-----
+BgUrgQQAIg==
+-----END EC PARAMETERS-----
diff --git a/examples/tls_server-rs/uuid.txt b/examples/tls_server-rs/uuid.txt
new file mode 100644
index 0000000..d12f3ea
--- /dev/null
+++ b/examples/tls_server-rs/uuid.txt
@@ -0,0 +1 @@
+69547de6-f47e-11eb-994e-f34e88d5c2b4
diff --git a/ci/ci.sh b/examples/udp_socket-rs/Makefile
old mode 100755
new mode 100644
similarity index 61%
copy from ci/ci.sh
copy to examples/udp_socket-rs/Makefile
index e530044..c266055
--- a/ci/ci.sh
+++ b/examples/udp_socket-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,23 +15,19 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+# 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
 
-./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
+all:
+	$(q)make -C host TARGET_HOST=$(TARGET_HOST) \
+		CROSS_COMPILE_HOST=$(CROSS_COMPILE_HOST)
+	$(q)make -C ta TARGET_TA=$(TARGET_TA) \
+		CROSS_COMPILE_TA=$(CROSS_COMPILE_TA)
 
-popd
+clean:
+	$(q)make -C host clean
+	$(q)make -C ta clean
diff --git a/ci/ci.sh b/examples/udp_socket-rs/host/Cargo.toml
old mode 100755
new mode 100644
similarity index 65%
copy from ci/ci.sh
copy to examples/udp_socket-rs/host/Cargo.toml
index e530044..5d79461
--- a/ci/ci.sh
+++ b/examples/udp_socket-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,23 +15,19 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+[package]
+name = "udp_socket-rs"
+version = "0.3.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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
+[dependencies]
+libc = "0.2.48"
+proto = { path = "../proto" }
+optee-teec = { path = "../../../optee-teec" }
 
-popd
+[profile.release]
+lto = true
diff --git a/ci/ci.sh b/examples/udp_socket-rs/host/Makefile
old mode 100755
new mode 100644
similarity index 62%
copy from ci/ci.sh
copy to examples/udp_socket-rs/host/Makefile
index e530044..145a5ce
--- a/ci/ci.sh
+++ b/examples/udp_socket-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,23 +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
-
-popd
+NAME := udp_socket-rs
+
+TARGET_HOST ?= aarch64-unknown-linux-gnu
+CROSS_COMPILE_HOST ?= aarch64-linux-gnu-
+OBJCOPY := $(CROSS_COMPILE_HOST)objcopy
+LINKER_CFG := target.$(TARGET_HOST).linker=\"$(CROSS_COMPILE_HOST)gcc\"
+
+OUT_DIR := $(CURDIR)/target/$(TARGET_HOST)/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/udp_socket-rs/host/src/main.rs b/examples/udp_socket-rs/host/src/main.rs
new file mode 100644
index 0000000..5e1db59
--- /dev/null
+++ b/examples/udp_socket-rs/host/src/main.rs
@@ -0,0 +1,51 @@
+// 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::ParamNone;
+use optee_teec::{Context, Operation, Session, Uuid};
+use proto::{Command, UUID};
+use std::net::UdpSocket;
+use std::str;
+use std::thread;
+
+fn udp_socket(session: &mut Session) -> optee_teec::Result<()> {
+    let mut operation = Operation::new(0, ParamNone, ParamNone, ParamNone, ParamNone);
+    session.invoke_command(Command::Start as u32, &mut operation)?;
+    Ok(())
+}
+
+fn main() -> optee_teec::Result<()> {
+    let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
+
+    let mut ctx = Context::new()?;
+    let uuid = Uuid::parse_str(UUID).unwrap();
+    let child = thread::spawn(move || {
+        let mut session = ctx.open_session(uuid).unwrap();
+        udp_socket(&mut session).unwrap();
+    });
+
+    let mut buf = [0; 100];
+    let (_, src_addr) = socket.recv_from(&mut buf).unwrap();
+    socket
+        .send_to(b"[Host] Hello, Teaclave!", src_addr)
+        .unwrap();
+    println!("{}", str::from_utf8(&buf).unwrap());
+    let _ = child.join();
+
+    println!("Success");
+    Ok(())
+}
diff --git a/ci/ci.sh b/examples/udp_socket-rs/proto/Cargo.toml
old mode 100755
new mode 100644
similarity index 67%
copy from ci/ci.sh
copy to examples/udp_socket-rs/proto/Cargo.toml
index e530044..b76ceb2
--- a/ci/ci.sh
+++ b/examples/udp_socket-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,23 +15,16 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+[package]
+name = "proto"
+version = "0.3.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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"
 
-./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
+[dependencies]
 
-popd
+[build-dependencies]
+uuid = { version = "1.8", default-features = false }
diff --git a/examples/udp_socket-rs/proto/build.rs b/examples/udp_socket-rs/proto/build.rs
new file mode 100644
index 0000000..b9d0612
--- /dev/null
+++ b/examples/udp_socket-rs/proto/build.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.
+
+use std::fs;
+use std::path::PathBuf;
+use std::fs::File;
+use std::env;
+use std::io::Write;
+
+fn main() {
+    let uuid = match fs::read_to_string("../uuid.txt") {
+        Ok(u) => {
+            u.trim().to_string()
+        },
+        Err(_) => {
+            panic!("Cannot find uuid.txt");
+        }
+    };
+    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+    let mut buffer = File::create(out.join("uuid.txt")).unwrap();
+    write!(buffer, "{}", uuid).unwrap();
+}
diff --git a/examples/udp_socket-rs/proto/src/lib.rs b/examples/udp_socket-rs/proto/src/lib.rs
new file mode 100644
index 0000000..7679b2d
--- /dev/null
+++ b/examples/udp_socket-rs/proto/src/lib.rs
@@ -0,0 +1,33 @@
+// 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.
+
+pub enum Command {
+    Start,
+    Unknown,
+}
+
+impl From<u32> for Command {
+    #[inline]
+    fn from(value: u32) -> Command {
+        match value {
+            0 => Command::Start,
+            _ => Command::Unknown,
+        }
+    }
+}
+
+pub const UUID: &str = &include_str!(concat!(env!("OUT_DIR"), "/uuid.txt"));
diff --git a/ci/ci.sh b/examples/udp_socket-rs/ta/Cargo.toml
old mode 100755
new mode 100644
similarity index 55%
copy from ci/ci.sh
copy to examples/udp_socket-rs/ta/Cargo.toml
index e530044..6f83a03
--- a/ci/ci.sh
+++ b/examples/udp_socket-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,23 +15,26 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
+[package]
+name = "ta"
+version = "0.3.0"
+authors = ["Teaclave Contributors <de...@teaclave.apache.org>"]
+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"
 
-pushd ../tests
+[dependencies]
+libc = { path = "../../../rust/libc" }
+proto = { path = "../proto" }
+optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
+optee-utee = { path = "../../../optee-utee" }
 
-./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
+[build-dependencies]
+uuid = { version = "1.8", default-features = false }
+proto = { path = "../proto" }
 
-popd
+[profile.release]
+panic = "abort"
+lto = false
+opt-level = 1
diff --git a/examples/udp_socket-rs/ta/Makefile b/examples/udp_socket-rs/ta/Makefile
new file mode 100644
index 0000000..17d6e73
--- /dev/null
+++ b/examples/udp_socket-rs/ta/Makefile
@@ -0,0 +1,49 @@
+# 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.
+
+# STD-ONLY example
+
+UUID ?= $(shell cat "../uuid.txt")
+
+TARGET_TA ?= aarch64-unknown-linux-gnu
+CROSS_COMPILE_TA ?= aarch64-linux-gnu-
+OBJCOPY := $(CROSS_COMPILE_TA)objcopy
+LINKER_CFG := target.$(TARGET_TA).linker=\"$(CROSS_COMPILE_TA)ld.bfd\"
+
+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_TA)/release
+
+ifeq ($(STD),)
+all:
+	@echo "Please export STD=y to build the STD version"
+else
+all: ta strip sign
+endif
+
+ta:
+	@xargo build --target $(TARGET_TA) --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/.licenserc.yaml b/examples/udp_socket-rs/ta/Xargo.toml
similarity index 72%
copy from .licenserc.yaml
copy to examples/udp_socket-rs/ta/Xargo.toml
index 0391c38..1b1a113 100644
--- a/.licenserc.yaml
+++ b/examples/udp_socket-rs/ta/Xargo.toml
@@ -15,18 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 
-header:
-  license:
-    spdx-id: Apache-2.0
-    copyright-owner: Apache Software Foundation
+[dependencies.std]
+path = "../../../rust/rust/library/std"
 
-  paths-ignore:
-    - 'dist'
-    - 'licenses'
-    - '**/*.md'
-    - 'LICENSE'
-    - 'NOTICE'
-    - '**/Cargo.lock'
-    - 'KEYS'
-    - 'DISCLAIMER-WIP'
-    - '*.json'
+[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/udp_socket-rs/ta/build.rs b/examples/udp_socket-rs/ta/build.rs
new file mode 100644
index 0000000..fa0d195
--- /dev/null
+++ b/examples/udp_socket-rs/ta/build.rs
@@ -0,0 +1,103 @@
+// 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 proto;
+use std::env;
+use std::fs::File;
+use std::io::{BufRead, BufReader, Write};
+use std::path::{Path, PathBuf};
+use uuid::Uuid;
+
+fn main() -> std::io::Result<()> {
+    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+
+    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
+    buffer.write_all(include_bytes!("ta_static.rs"))?;
+
+    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
+    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
+
+    write!(buffer, "\n")?;
+    write!(
+        buffer,
+        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
+    timeLow: {:#x},
+    timeMid: {:#x},
+    timeHiAndVersion: {:#x},
+    clockSeqAndNode: {:#x?},
+}};",
+        time_low, time_mid, time_hi_and_version, clock_seq_and_node
+    )?;
+
+    let mut aarch64_flag = true;
+    match env::var("TARGET_TA") {
+        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
+            println!("cargo:rustc-link-arg=--no-warn-mismatch");
+            aarch64_flag = false;
+        },
+        _ => {}
+    };
+
+    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
+    let search_path = Path::new(&optee_os_dir).join("lib");
+
+    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
+    let mut ta_lds = File::create(out.join("ta.lds"))?;
+    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
+    let f = BufReader::new(f);
+
+    for line in f.lines() {
+        let l = line?;
+
+        if aarch64_flag {
+            if l.starts_with('#') ||
+                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
+                l == "OUTPUT_ARCH(arm)" {
+                continue;
+            }
+        } else {
+            if l.starts_with('#') ||
+                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
+                l == "OUTPUT_ARCH(aarch64)" {
+                continue;
+            }
+        }
+
+        if l == "\t. = ALIGN(4096);" {
+            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
+        } else {
+            write!(ta_lds, "{}\n", l)?;
+        }
+    }
+
+    println!("cargo:rustc-link-search={}", out.display());
+    println!("cargo:rerun-if-changed=ta.lds");
+
+    println!("cargo:rustc-link-search={}", search_path.display());
+    println!("cargo:rustc-link-lib=static=utee");
+    println!("cargo:rustc-link-lib=static=utils");
+    println!("cargo:rustc-link-arg=-Tta.lds");
+    println!("cargo:rustc-link-arg=-e__ta_entry");
+    println!("cargo:rustc-link-arg=-pie");
+    println!("cargo:rustc-link-arg=-Os");
+    println!("cargo:rustc-link-arg=--sort-section=alignment");
+
+    let mut dyn_list = File::create(out.join("dyn_list"))?;
+    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
+    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
+    Ok(())
+}
diff --git a/examples/udp_socket-rs/ta/src/main.rs b/examples/udp_socket-rs/ta/src/main.rs
new file mode 100644
index 0000000..4f3025d
--- /dev/null
+++ b/examples/udp_socket-rs/ta/src/main.rs
@@ -0,0 +1,99 @@
+// 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_main]
+#![feature(c_size_t)]
+
+use optee_utee::net::UdpSocket;
+use optee_utee::{
+    ta_close_session, ta_create, ta_destroy, ta_invoke_command, ta_open_session, trace_println,
+};
+use optee_utee::{Error, ErrorKind, Parameters, Result};
+use proto::Command;
+use std::io::Read;
+use std::io::Write;
+
+#[ta_create]
+fn create() -> Result<()> {
+    trace_println!("[+] TA create");
+    Ok(())
+}
+
+#[ta_open_session]
+fn open_session(_params: &mut Parameters) -> Result<()> {
+    trace_println!("[+] TA open session");
+    Ok(())
+}
+
+#[ta_close_session]
+fn close_session() {
+    trace_println!("[+] TA close session");
+}
+
+#[ta_destroy]
+fn destroy() {
+    trace_println!("[+] TA destroy");
+}
+
+#[ta_invoke_command]
+fn invoke_command(cmd_id: u32, _params: &mut Parameters) -> Result<()> {
+    trace_println!("[+] TA invoke command");
+    match Command::from(cmd_id) {
+        Command::Start => {
+            udp_socket();
+            Ok(())
+        }
+        _ => Err(Error::new(ErrorKind::BadParameters)),
+    }
+}
+
+fn udp_socket() {
+    let mut stream = UdpSocket::connect("127.0.0.1", 34254).unwrap();
+    stream.write_all(b"[TA]: Hello, Teaclave!").unwrap();
+    let mut response = Vec::new();
+    let mut chunk = [0u8; 1024];
+
+    // Loop until read something.
+    loop {
+        match stream.read(&mut chunk) {
+            Ok(0) => continue,
+            Ok(n) => {
+                response.extend_from_slice(&chunk[..n]);
+                break;
+            }
+            Err(_) => {
+                trace_println!("Error");
+                panic!();
+            }
+        }
+    }
+    trace_println!("{}", String::from_utf8_lossy(&response));
+}
+
+// TA configurations
+const TA_FLAGS: u32 = 0;
+const TA_DATA_SIZE: u32 = 1 * 1024 * 1024;
+const TA_STACK_SIZE: u32 = 2 * 1024 * 1024;
+const TA_VERSION: &[u8] = b"0.3\0";
+const TA_DESCRIPTION: &[u8] = b"This is a udp socket example.\0";
+const EXT_PROP_VALUE_1: &[u8] = b"Hello World TA\0";
+const EXT_PROP_VALUE_2: u32 = 0x0010;
+const TRACE_LEVEL: i32 = 4;
+const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
+const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
+
+include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/udp_socket-rs/ta/ta_static.rs b/examples/udp_socket-rs/ta/ta_static.rs
new file mode 100644
index 0000000..53ca210
--- /dev/null
+++ b/examples/udp_socket-rs/ta/ta_static.rs
@@ -0,0 +1,102 @@
+// 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 core::ffi::*;
+use core::mem;
+use core::primitive::u64;
+
+#[no_mangle]
+pub static mut trace_level: c_int = TRACE_LEVEL;
+
+#[no_mangle]
+pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
+
+#[no_mangle]
+#[link_section = ".ta_head"]
+pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
+    uuid: TA_UUID,
+    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
+    flags: TA_FLAGS,
+    depr_entry: u64::MAX,
+};
+
+#[no_mangle]
+#[link_section = ".bss"]
+pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
+
+#[no_mangle]
+pub static ta_heap_size: c_size_t = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
+static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
+static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
+static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
+
+#[no_mangle]
+pub static ta_num_props: c_size_t = 9;
+
+#[no_mangle]
+pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_BOOL as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_MULTI as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_INSTANCE as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &TA_DATA_SIZE as *const u32 as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &TA_STACK_SIZE as *const u32 as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_VERSION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: TA_VERSION as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: TA_DESCRIPTION as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: "gp.ta.description\0".as_ptr(),
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: "gp.ta.version\0".as_ptr(),
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
+    },
+];
+
+#[no_mangle]
+pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
+    return trace_level;
+}
diff --git a/examples/udp_socket-rs/uuid.txt b/examples/udp_socket-rs/uuid.txt
new file mode 100644
index 0000000..e91b72f
--- /dev/null
+++ b/examples/udp_socket-rs/uuid.txt
@@ -0,0 +1 @@
+87c2d78e-eb7b-11eb-8d25-df4d5338f285
diff --git a/tests/optee-qemuv8.sh b/tests/optee-qemuv8.sh
index 95d10de..0b8cd44 100755
--- a/tests/optee-qemuv8.sh
+++ b/tests/optee-qemuv8.sh
@@ -17,6 +17,13 @@
 # specific language governing permissions and limitations
 # under the License.
 
+# std examples: tcp_client, udp_socket, tls_client, tls_server needs the external network
+if [ "$STD" ]; then
+    EXTERNAL_NETWORK_PARAMS=" \
+    -netdev user,id=vmnic,hostfwd=:127.0.0.1:54433-:4433 \
+    -device virtio-net-device,netdev=vmnic"
+fi
+
 cd $1 && ./qemu-system-aarch64 \
     -nodefaults \
     -nographic \
@@ -30,4 +37,4 @@ cd $1 && ./qemu-system-aarch64 \
     -append 'console=ttyAMA0,38400 keep_bootcon root=/dev/vda2' \
     -kernel Image -no-acpi \
     -fsdev local,id=fsdev0,path=$(pwd)/../shared,security_model=none \
-    -device virtio-9p-device,fsdev=fsdev0,mount_tag=host 
+    -device virtio-9p-device,fsdev=fsdev0,mount_tag=host $EXTERNAL_NETWORK_PARAMS
\ No newline at end of file
diff --git a/ci/ci.sh b/tests/test_message_passing_interface.sh
similarity index 59%
copy from ci/ci.sh
copy to tests/test_message_passing_interface.sh
index e530044..cf476a1 100755
--- a/ci/ci.sh
+++ b/tests/test_message_passing_interface.sh
@@ -19,21 +19,25 @@
 
 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
+# Copy TA and host binary
+cp ../examples/message_passing_interface-rs/ta/target/$TARGET_TA/release/*.ta shared
+cp ../examples/message_passing_interface-rs/host/target/$TARGET_HOST/release/message_passing_interface-rs shared
 
-popd
+# Run script specific commands in QEMU
+run_in_qemu "cp *.ta /lib/optee_armtz/\n"
+run_in_qemu "./message_passing_interface-rs\n"
+run_in_qemu "^C"
+
+# Script specific checks
+{
+	grep -q "Hello, World" screenlog.0
+} || {
+	cat -v screenlog.0
+	cat -v /tmp/serial.log
+	false
+}
+
+rm screenlog.0
\ No newline at end of file
diff --git a/ci/ci.sh b/tests/test_serde.sh
similarity index 56%
copy from ci/ci.sh
copy to tests/test_serde.sh
index e530044..7bc4351 100755
--- a/ci/ci.sh
+++ b/tests/test_serde.sh
@@ -19,21 +19,28 @@
 
 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
+# Copy TA and host binary
+cp ../examples/serde-rs/ta/target/$TARGET_TA/release/*.ta shared
+cp ../examples/serde-rs/host/target/$TARGET_HOST/release/serde-rs shared
 
-popd
+# Run script specific commands in QEMU
+run_in_qemu "cp *.ta /lib/optee_armtz/\n"
+run_in_qemu "./serde-rs\n"
+run_in_qemu "^C"
+
+# Script specific checks
+{
+	grep -q "Success" screenlog.0 &&
+	grep -q "Point { x: 1, y: 2 }" screenlog.0 &&
+	grep -q "serialized = " /tmp/serial.log &&
+	grep -q "deserialized = " /tmp/serial.log
+} || {
+        cat -v screenlog.0
+        cat -v /tmp/serial.log
+        false
+}
+
+rm screenlog.0
\ No newline at end of file
diff --git a/ci/ci.sh b/tests/test_tcp_client.sh
similarity index 62%
copy from ci/ci.sh
copy to tests/test_tcp_client.sh
index e530044..232159b 100755
--- a/ci/ci.sh
+++ b/tests/test_tcp_client.sh
@@ -19,21 +19,25 @@
 
 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
+# Copy TA and host binary
+cp ../examples/tcp_client-rs/ta/target/$TARGET_TA/release/*.ta shared
+cp ../examples/tcp_client-rs/host/target/$TARGET_HOST/release/tcp_client-rs shared
 
-popd
+# Run script specific commands in QEMU
+run_in_qemu "cp *.ta /lib/optee_armtz/\n"
+run_in_qemu "./tcp_client-rs\n"
+run_in_qemu "^C"
+
+# Script specific checks
+{
+	grep -q "Success" screenlog.0
+} || {
+	cat -v screenlog.0
+	cat -v /tmp/serial.log
+        false
+}
+
+rm screenlog.0
\ No newline at end of file
diff --git a/ci/ci.sh b/tests/test_tls_client.sh
similarity index 61%
copy from ci/ci.sh
copy to tests/test_tls_client.sh
index e530044..895b3d1 100755
--- a/ci/ci.sh
+++ b/tests/test_tls_client.sh
@@ -19,21 +19,26 @@
 
 set -xe
 
-pushd ../tests
+NEED_EXPANDED_MEM=true
+# 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
+# Copy TA and host binary
+cp ../examples/tls_client-rs/ta/target/$TARGET_TA/release/*.ta shared
+cp ../examples/tls_client-rs/host/target/$TARGET_HOST/release/tls_client-rs shared
 
-popd
+# Run script specific commands in QEMU
+run_in_qemu "cp *.ta /lib/optee_armtz/\n"
+run_in_qemu "./tls_client-rs\n"
+run_in_qemu "^C"
+
+# Script specific checks
+{
+	grep -q "Success" screenlog.0
+} || {
+	cat -v screenlog.0
+	cat -v /tmp/serial.log
+	false
+}
+
+rm screenlog.0
diff --git a/ci/ci.sh b/tests/test_tls_server.sh
similarity index 55%
copy from ci/ci.sh
copy to tests/test_tls_server.sh
index e530044..dacb364 100755
--- a/ci/ci.sh
+++ b/tests/test_tls_server.sh
@@ -19,21 +19,31 @@
 
 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
-
-popd
+NEED_EXPANDED_MEM=true
+# Include base script
+source setup.sh
+
+# Copy TA and host binary
+cp ../examples/tls_server-rs/ta/target/$TARGET_TA/release/*.ta shared
+cp ../examples/tls_server-rs/host/target/$TARGET_HOST/release/tls_server-rs shared
+
+# Run script specific commands in QEMU
+run_in_qemu "cp *.ta /lib/optee_armtz/\n"
+run_in_qemu "./tls_server-rs\n"
+echo "Q" | openssl s_client -connect 127.0.0.1:54433 -debug > openssl.log 2>&1
+run_in_qemu "^C"
+
+# Script specific checks
+{
+	grep -q "DONE" openssl.log &&
+	grep -q "close session" screenlog.0
+} || {
+	cat -v screenlog.0
+	cat -v /tmp/serial.log
+	cat -v openssl.log
+	false
+}
+
+rm screenlog.0
+
+rm -rf openssl.log
\ No newline at end of file
diff --git a/ci/ci.sh b/tests/test_udp_socket.sh
similarity index 62%
copy from ci/ci.sh
copy to tests/test_udp_socket.sh
index e530044..04483f4 100755
--- a/ci/ci.sh
+++ b/tests/test_udp_socket.sh
@@ -19,21 +19,25 @@
 
 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
+# Copy TA and host binary
+cp ../examples/udp_socket-rs/ta/target/$TARGET_TA/release/*.ta shared
+cp ../examples/udp_socket-rs/host/target/$TARGET_HOST/release/udp_socket-rs shared
 
-popd
+# Run script specific commands in QEMU
+run_in_qemu "cp *.ta /lib/optee_armtz/\n"
+run_in_qemu "./udp_socket-rs\n"
+run_in_qemu "^C"
+
+# Script specific checks
+{
+	grep -q "Success" screenlog.0
+} || {
+	cat -v screenlog.0
+	cat -v /tmp/serial.log
+        false
+}
+
+rm screenlog.0
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org