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


The following commit(s) were added to refs/heads/main by this push:
     new edcb7a2  Add demo projects for Web3 scenarios (#150)
edcb7a2 is described below

commit edcb7a27e37b8a2517ba255cc8358273807f4afd
Author: Yuan Zhuang <[email protected]>
AuthorDate: Thu Dec 12 10:20:59 2024 +0800

    Add demo projects for Web3 scenarios (#150)
    
    * projects: add basic ETH wallet demo
    * Add test scripts and CI for projects/eth_wallet
    * Add license and documentation
---
 .github/workflows/ci.yml                           |   6 +
 ci/ci.sh                                           |   1 +
 projects/README.md                                 |  44 ++++
 projects/web3/README.md                            |  41 ++++
 ci/ci.sh => projects/web3/eth_wallet/Makefile      |  44 ++--
 projects/web3/eth_wallet/README.md                 | 234 +++++++++++++++++++++
 .../web3/eth_wallet/host/Cargo.toml                |  47 ++---
 ci/ci.sh => projects/web3/eth_wallet/host/Makefile |  48 ++---
 projects/web3/eth_wallet/host/src/cli.rs           | 100 +++++++++
 projects/web3/eth_wallet/host/src/main.rs          | 152 +++++++++++++
 projects/web3/eth_wallet/host/src/tests.rs         |  37 ++++
 .../web3/eth_wallet/proto/Cargo.toml               |  43 ++--
 projects/web3/eth_wallet/proto/build.rs            |  36 ++++
 projects/web3/eth_wallet/proto/src/in_out.rs       |  71 +++++++
 projects/web3/eth_wallet/proto/src/lib.rs          |  43 ++++
 projects/web3/eth_wallet/ta/Cargo.toml             |  49 +++++
 projects/web3/eth_wallet/ta/Makefile               |  50 +++++
 ci/ci.sh => projects/web3/eth_wallet/ta/Xargo.toml |  37 +---
 projects/web3/eth_wallet/ta/build.rs               | 108 ++++++++++
 projects/web3/eth_wallet/ta/src/hash.rs            |  28 +++
 projects/web3/eth_wallet/ta/src/main.rs            | 181 ++++++++++++++++
 projects/web3/eth_wallet/ta/src/secure_storage.rs  | 106 ++++++++++
 projects/web3/eth_wallet/ta/src/wallet.rs          | 142 +++++++++++++
 projects/web3/eth_wallet/ta/ta_static.rs           | 102 +++++++++
 projects/web3/eth_wallet/uuid.txt                  |   1 +
 ci/ci.sh => tests/test_eth_wallet.sh               |  43 ++--
 26 files changed, 1621 insertions(+), 173 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8346633..72b59cc 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -130,6 +130,9 @@ jobs:
 
           # Build OP-TEE Rust examples for Arm 64-bit both host and TA
           make -j`nproc`
+
+          # Build project
+          (cd projects/web3/eth_wallet && make -j`nproc`)
       - name: Run tests for Arm 64-bit both host and TA
         run: |
           apt update && apt install libslirp-dev -y
@@ -166,6 +169,9 @@ jobs:
 
           # Build OP-TEE Rust examples for Arm 64-bit both host and TA
           make -j`nproc`
+
+          # Build project
+          (cd projects/web3/eth_wallet && make -j`nproc`)
       - name: Run tests for Arm 32-bit both host and TA
         run: |
           apt update && apt install libslirp-dev -y
diff --git a/ci/ci.sh b/ci/ci.sh
index da12226..c58a03f 100755
--- a/ci/ci.sh
+++ b/ci/ci.sh
@@ -44,6 +44,7 @@ if [ "$STD" ]; then
     ./test_udp_socket.sh
     ./test_tls_client.sh
     ./test_tls_server.sh
+    ./test_eth_wallet.sh
 fi
 
 popd
diff --git a/projects/README.md b/projects/README.md
new file mode 100644
index 0000000..3ad8f82
--- /dev/null
+++ b/projects/README.md
@@ -0,0 +1,44 @@
+# Projects in Multiple Scenarios
+
+Trusted Execution Environments (TEEs) play a vital role in providing critical
+security solutions across various scenarios. The Teaclave TrustZone SDK 
empowers
+developers to implement robust use cases such as Web3 private key protection,
+authentication, and more.
+
+The `projects/` directory showcases real-world scenarios and essential
+primitives designed to help developers build secure applications tailored to
+their needs.
+
+Currently, we have released a Web3-focused scenario, with plans to expand the
+project and introduce more use cases in the future.
+
+## Available Scenarios
+
+- **Web3**: Available in `projects/web3/`, this scenario offers utilities for
+  Web3 development, such as key custodians and decentralized identifiers 
(DIDs).
+  It currently includes a basic Ethereum wallet that demonstrates how to
+  securely create a wallet and sign transactions using wallet-derived keys
+  within the TEE.
+
+## Upcoming Scenarios
+
+- **X509 Certificate Signing & Verification**: This scenario provides
+  foundational Public Key Infrastructure (PKI) primitives for securely issuing
+  self-signed certificates and verifying externally provided leaf certificates
+  using a trusted certificate store. The Trusted Application (TA) inside the 
TEE
+  handles secure key pair generation and certificate issuance, facilitating
+  identity verification for secure communications. This primitive is
+  particularly valuable for establishing trusted communication channels between
+  nodes or devices.
+
+- **Remote Attestation**: This foundational primitive enables remote 
attestation
+  of a Trusted Application (TA) to ensure it is running within a Trusted
+  Execution Environment (TEE). It utilizes TLS and X509 PKI to establish a
+  secure communication channel.
+
+- **Multi-Factor Authentication (MFA)**: This example demonstrates how to
+  implement MFA by securely provisioning the public keys of trusted MFA devices
+  (e.g., a user’s cellphone) within the Trusted Application (TA). When 
high-risk
+  operations like key usage or transaction signing require user confirmation,
+  the TA securely verifies user-provided details via the trusted MFA device,
+  eliminating reliance on third-party services.
diff --git a/projects/web3/README.md b/projects/web3/README.md
new file mode 100644
index 0000000..e501c2a
--- /dev/null
+++ b/projects/web3/README.md
@@ -0,0 +1,41 @@
+# Reference Implementation Examples for Web3 Trusted Applications
+
+Teaclave TrustZone SDK allows developers to create Trusted Applications (TAs) 
in
+Rust, offering a memory-safe and secure environment. Many examples in this
+repository are ported from OP-TEE C examples. With Rust's ecosystem and support
+for Rust-std in Teaclave TrustZone SDK, developers can build secure TAs to
+protect confidential information.
+
+In Web3, private key protection is vital for securing on-chain identities and
+assets. TAs safeguard the entire lifecycle of Web3 credentials used in wallets
+or validator key protection. In DePIN, TAs enable secure device attestation,
+helping to prevent Sybil attacks.
+
+This directory contains a collection of reference implementations of TAs,
+specifically tailored for Web3 use cases. These examples demonstrate how to use
+Rust within TrustZone to support basic Web3 use cases. We will gradually
+open-source each of them as reference implementation examples for Web3 TAs. 
Web3
+builders can leverage these examples to integrate secure functionalities into
+their projects, particularly in environments where OP-TEE and TrustZone
+technologies are employed.
+
+## Basic Web3 Wallet
+
+**AVAILABLE** in [eth-wallet/](./eth-wallet)
+
+A wallet abstraction featuring key functionalities like secure key management
+and transaction signing. The key management includes secure seed generation,
+mnemonic derivation, and safe key storage within external TEE-protected
+environments. For transaction signing, we demonstrate how to securely sign an
+Ethereum transaction using wallet-derived keys inside the TEE, ensuring the
+private keys never leave the trusted environment.
+
+## Decentralized Identifier (DID)
+
+**To Be Released**
+
+This example will illustrate how to integrate Decentralized Identifiers (DIDs)
+into TAs. DIDs enable self-sovereign identity by proving ownership without
+relying on central authorities. Secure key management for creating and 
operating
+DIDs ensures reliable device identification, mitigating the risk of fake 
devices
+in DePIN.
diff --git a/ci/ci.sh b/projects/web3/eth_wallet/Makefile
old mode 100755
new mode 100644
similarity index 59%
copy from ci/ci.sh
copy to projects/web3/eth_wallet/Makefile
index da12226..c266055
--- a/ci/ci.sh
+++ b/projects/web3/eth_wallet/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,33 +15,19 @@
 # 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
+# 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
 
-# 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
+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/projects/web3/eth_wallet/README.md 
b/projects/web3/eth_wallet/README.md
new file mode 100644
index 0000000..5552457
--- /dev/null
+++ b/projects/web3/eth_wallet/README.md
@@ -0,0 +1,234 @@
+# Eth-Wallet: A Sample Trusted Application for Wallet Abstraction and 
Transaction Signing
+
+This repository provides a reference implementation of an Ethereum wallet as a
+Trusted Application (TA) written in Rust. The primary goal is to ensure that
+secret credentials (such as private keys) remain securely within the Trusted
+Execution Environment (TEE) throughout their entire lifecycle, enhancing
+security and privacy for Ethereum-based operations. This reference
+implementation can be extended to support additional wallet features or adapted
+to other blockchain platforms with similar requirements for secure key
+management. The implementation provides basic wallet abstractions, including:
+
+- Key Generation: Securely generating random seeds within the TEE.
+- Key Derivation: Deriving keys from seeds within the TEE.
+- Key Persistency: Storing cryptographic keys securely in the TEE.
+- Transaction Signing: Signing Ethereum transactions without exposing private
+  keys to the normal world.
+- Key Erase: Erasing keys when they are no longer needed.
+
+## Security Assumptions
+
+This demo assumes the following security foundations:
+
+1. **Trusted Environment**:
+
+   - The device supports OP-TEE as the TEE operating system.
+   - Both the TEE OS and the Trusted Application (TA) are considered secure and
+     trusted.
+
+2. **Hardware-Specific Security Capabilities**
+   - The hardware provides secure storage capabilities to protect cryptographic
+     keys.
+   - The device includes secure display capabilities (or a Multi-Factor
+     Authentication device as alternative) for secure user interface. (MFA
+     integration is planned for another demo project)
+   - Note that these capabilities depend on specific hardware implementations.
+     While this demo provides a default implementation, it should be customized
+     to suit the target hardware.
+
+### Important Notes on Security Design
+
+This demo focuses on showcasing core functionalities and may not implement all
+security measures required for a production-grade key custodian solution across
+the entire key lifecycle. Developers should address the following 
considerations
+when adapting this demo for real-world use cases:
+
+- **Secure User Interface**:  
+  In the `create_wallet` function, the mnemonic is returned to the Normal World
+  for backup. This approach is inherently risky. For production systems, it is
+  strongly recommended to display the mnemonic on a Trusted UI or secure
+  display. Additionally, transactions should be confirmed by the user through
+  this secure display. As secure display implementations are hardware-specific,
+  this demo does not include such functionality.
+
+- **Secure Storage Limitations**:  
+  Keys in this demo are stored in an encrypted file on the Normal World File
+  System. While this approach ensures basic protection, root access in the
+  Normal World could delete this file, leading to key loss. For production
+  scenarios, consider more reliable storage solutions like Replay Protected
+  Memory Block (RPMB), which is hardware-specific and not included in this 
demo.
+
+For developers, please note that this demo is intended as a foundational
+reference and must be enhanced with hardware-specific adaptations for
+production-grade security.
+
+## Structure
+
+- [TA](./ta): The Trusted Application (TA) that performs all secure operations
+  related to the wallet. This component runs within the TrustZone TEE, ensuring
+  that secret credentials never leave the secure environment.
+- [CA](./host): The Client Application (CA) that runs in the normal world and
+  communicates with the TA. It is responsible for user interaction and
+  non-sensitive operations.
+- [Proto](./proto): Contains shared structures and definitions used by both the
+  TA and CA to facilitate communication between the two environments.
+
+## Setup
+
+To set up the environment, follow the instructions in the
+[Apache Teaclave TrustZone SDK 
README](https://github.com/apache/incubator-teaclave-trustzone-sdk/blob/master/README.md).
+
+## Functionalities
+
+- **Create Wallet**: Generate a new Ethereum wallet with a unique ID.
+- **Derive Address**: Derive an Ethereum address from a wallet.
+- **Sign Transaction**: Sign Ethereum transactions securely within the TEE.
+- **Remove Wallet**: Delete a wallet and its associated keys from the TEE.
+
+## Usage
+
+### Build
+
+```
+$ cd projects/eth_wallet-rs
+$ make
+```
+
+### Run
+
+After QEMU boots:
+
+```bash
+Welcome to Buildroot, type root or test to login
+buildroot login: root
+# mkdir shared && mount -t 9p -o trans=virtio host shared
+# cd shared/
+# ls
+be2dc9a0-02b4-4b33-ba21-9964dbdf1573.ta
+eth_wallet-rs
+# cp be2dc9a0-02b4-4b33-ba21-9964dbdf1573.ta /lib/optee_armtz/
+# ./eth_wallet-rs
+```
+
+### Command-Line Interface
+
+```bash
+A simple Ethereum wallet based on TEE
+
+USAGE:
+eth_wallet-rs <SUBCOMMAND>
+
+FLAGS:
+    -h, --help       Prints help information
+    -V, --version    Prints version information
+
+SUBCOMMANDS:
+    create-wallet       Create a new wallet
+    derive-address      Derive an address from a wallet
+    help                Prints this message or the help of the given 
subcommand(s)
+    remove-wallet       Remove a wallet
+    sign-transaction    Sign a transaction
+    test                Run tests
+```
+
+## Example Commands
+
+### Create a Wallet
+
+```bash
+# ./eth_wallet-rs create-wallet
+```
+
+**CA Output:**
+
+```text
+CA: command: CreateWallet
+CA: invoke_command success
+Wallet ID: aa5798a1-3c89-4708-b316-712aea4f59e2
+```
+
+**TA Output:**
+
+```text
+[+] TA create
+[+] TA open session
+[+] TA invoke command
+[+] Wallet created: Wallet { id: aa5798a1-3c89-4708-b316-712aea4f59e2, 
entropy: [...] }
+[+] Wallet ID: aa5798a1-3c89-4708-b316-712aea4f59e2
+[+] Wallet saved in secure storage
+```
+
+### Derive an Address
+
+```bash
+# ./eth_wallet-rs derive-address -w aa5798a1-3c89-4708-b316-712aea4f59e2
+```
+
+**CA Output:**
+
+```text
+CA: command: DeriveAddress
+CA: invoke_command success
+Address: 0x7ca2b64a29bbf7a77bf8a3187ab09f50413826ea
+Public key: 03e1289e07eca6fe47c4825ea52f7cd27e3143ac5d65d5842aa5f59b5eba2d58df
+```
+
+**TA Output:**
+
+```text
+[+] TA invoke command
+[+] Deriving address: secure object loaded
+[+] Wallet::derive_pub_key(): pub key: 
"xpub6FhY8TmVeQ6Yo5ViNX6LK3mM66nMJDe4ZumHmznLNRkK2wEhGoEjaossvKmjgETpFHNGs9CFjUS7HK1un9Djzw9jfsukyNxu53b87abRJUv"
+[+] Wallet::derive_pub_key(): non-extended pub key: 
03e1289e07eca6fe47c4825ea52f7cd27e3143ac5d65d5842aa5f59b5eba2d58df
+[+] Wallet::derive_address(): address: [124, 162, 182, 74, 41, 187, 247, 167, 
123, 248, 163, 24, 122, 176, 159, 80, 65, 56, 38, 234]
+[+] Deriving address: address: [124, 162, 182, 74, 41, 187, 247, 167, 123, 
248, 163, 24, 122, 176, 159, 80, 65, 56, 38, 234]
+[+] Deriving address: public key: [3, 225, 40, 158, 7, 236, 166, 254, 71, 196, 
130, 94, 165, 47, 124, 210, 126, 49, 67, 172, 93, 101, 213, 132, 42, 165, 245, 
155, 94, 186, 45, 88, 223]
+```
+
+### Sign a Transaction
+
+```bash
+# ./eth_wallet-rs sign-transaction -t 
0xc0ffee254729296a45a3885639AC7E10F9d54979 -v 100 -w 
aa5798a1-3c89-4708-b316-712aea4f59e2
+```
+
+**CA Output:**
+
+```text
+CA: command: SignTransaction
+CA: invoke_command success
+Signature: 
"f86380843b9aca0082520894c0ffee254729296a45a3885639ac7e10f9d5497964802ea0774fc5a364c3d7e3f4e039f8da96b66fb0a5d51cad7524e54a0c9013fb473304a033922ecf964f02c6ebdd7380bc86fe759b65c87dc9e09677d983622e35334931"
+```
+
+**TA Output:**
+
+```text
+[+] TA invoke command
+[+] Sign transaction: secure object loaded
+[+] Wallet::derive_prv_key() finished
+[+] sign_transaction: signed transaction bytes: [248, 99, 128, 132, 59, 154, 
202, 0, 130, 82, 8, 148, 192, 255, 238, 37, 71, 41, 41, 106, 69, 163, 136, 86, 
57, 172, 126, 16, 249, 213, 73, 121, 100, 128, 46, 160, 119, 79, 197, 163, 100, 
195, 215, 227, 244, 224, 57, 248, 218, 150, 182, 111, 176, 165, 213, 28, 173, 
117, 36, 229, 74, 12, 144, 19, 251, 71, 51, 4, 160, 51, 146, 46, 207, 150, 79, 
2, 198, 235, 221, 115, 128, 188, 134, 254, 117, 155, 101, 200, 125, 201, 224, 
150, 119, 217, 131, 9 [...]
+[+] Sign transaction: signature: [248, 99, 128, 132, 59, 154, 202, 0, 130, 82, 
8, 148, 192, 255, 238, 37, 71, 41, 41, 106, 69, 163, 136, 86, 57, 172, 126, 16, 
249, 213, 73, 121, 100, 128, 46, 160, 119, 79, 197, 163, 100, 195, 215, 227, 
244, 224, 57, 248, 218, 150
+
+, 182, 111, 176, 165, 213, 28, 173, 117, 36, 229, 74, 12, 144, 19, 251, 71, 
51, 4, 160, 51, 146, 46, 207, 150, 79, 2, 198, 235, 221, 115, 128, 188, 134, 
254, 117, 155, 101, 200, 125, 201, 224, 150, 119, 217, 131, 98, 46, 53, 51, 73, 
49]
+```
+
+### Remove a Wallet
+
+```bash
+# ./eth_wallet-rs remove-wallet -w aa5798a1-3c89-4708-b316-712aea4f59e2
+```
+
+**CA Output:**
+
+```text
+CA: command: RemoveWallet
+CA: invoke_command success
+Wallet removed
+```
+
+**TA Output:**
+
+```text
+[+] TA invoke command
+[+] Removing wallet: secure object loaded
+[+] Wallet removed from secure storage
+```
diff --git a/ci/ci.sh b/projects/web3/eth_wallet/host/Cargo.toml
old mode 100755
new mode 100644
similarity index 58%
copy from ci/ci.sh
copy to projects/web3/eth_wallet/host/Cargo.toml
index da12226..e1e36bf
--- a/ci/ci.sh
+++ b/projects/web3/eth_wallet/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,33 +15,24 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+[package]
+name = "eth_wallet-rs"
+version = "0.1.0"
+authors = ["Teaclave Contributors <[email protected]>"]
+license = "Apache-2.0"
+repository = "https://github.com/apache/incubator-teaclave-trustzone-sdk.git";
+description = "An example of Rust OP-TEE TrustZone SDK."
+edition = "2018"
 
-./test_hello_world.sh
-./test_random.sh
-./test_secure_storage.sh
-./test_aes.sh
-./test_hotp.sh
-./test_acipher.sh
-./test_big_int.sh
-./test_diffie_hellman.sh
-./test_digest.sh
-./test_authentication.sh
-./test_time.sh
-./test_signature_verification.sh
-./test_supp_plugin.sh
-./test_error_handling.sh
+[dependencies]
+proto = { path = "../proto" }
+optee-teec = { path = "../../../../optee-teec" }
 
-# 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
+structopt = "0.3"
+bincode = "1.3.3"
+anyhow = "1.0"
+uuid = { version = "1.8", features = ["serde"] }
+hex = { version = "0.4", features = ["serde"] }
 
-popd
+[profile.release]
+lto = true
diff --git a/ci/ci.sh b/projects/web3/eth_wallet/host/Makefile
old mode 100755
new mode 100644
similarity index 57%
copy from ci/ci.sh
copy to projects/web3/eth_wallet/host/Makefile
index da12226..b1c50c4
--- a/ci/ci.sh
+++ b/projects/web3/eth_wallet/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,33 +15,27 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
+NAME := eth_wallet-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
 
-pushd ../tests
+ifeq ($(STD),)
+all:
+       @echo "Please `export STD=y` then rerun `source environment` to build 
the STD version"
+else
+all: host strip
+endif
 
-./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
+host:
+       @cargo build --target $(TARGET_HOST) --release --config $(LINKER_CFG)
 
-# 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
+strip: host
+       @$(OBJCOPY) --strip-unneeded $(OUT_DIR)/$(NAME) $(OUT_DIR)/$(NAME)
 
-popd
+clean:
+       @cargo clean
diff --git a/projects/web3/eth_wallet/host/src/cli.rs 
b/projects/web3/eth_wallet/host/src/cli.rs
new file mode 100644
index 0000000..6881518
--- /dev/null
+++ b/projects/web3/eth_wallet/host/src/cli.rs
@@ -0,0 +1,100 @@
+// 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 anyhow::{bail, Result};
+use structopt::StructOpt;
+
+// decode hex string to [u8; 20]
+pub fn decode_hex_to_address(src: &str) -> Result<[u8; 20]> {
+    // strip the 0x prefix
+    let src = src.trim_start_matches("0x");
+    let vec = hex::decode(src)?;
+    if vec.len() < 20 {
+        bail!("invalid address length: {}", vec.len());
+    }
+    let mut array = [0u8; 20];
+    array.copy_from_slice(&vec[..20]);
+    Ok(array)
+}
+
+// decode string to uuid
+pub fn decode_str_to_uuid(s: &str) -> Result<uuid::Uuid> {
+    uuid::Uuid::parse_str(s).map_err(|e| e.into())
+}
+
+#[derive(Debug, StructOpt)]
+pub struct CreateWalletOpt {}
+
+#[derive(Debug, StructOpt)]
+pub struct RemoveWalletOpt {
+    #[structopt(short, long, required = true)]
+    pub wallet_id: uuid::Uuid,
+}
+
+#[derive(Debug, StructOpt)]
+pub struct DeriveAddressOpt {
+    #[structopt(short, long, required = true)]
+    pub wallet_id: uuid::Uuid,
+    #[structopt(short, long, required = true, default_value = 
"m/44'/60'/0'/0/0")]
+    pub hd_path: String,
+}
+
+#[derive(Debug, StructOpt)]
+pub struct SignTransactionOpt {
+    #[structopt(short, long, required = true, parse(try_from_str = 
decode_str_to_uuid))]
+    pub wallet_id: uuid::Uuid,
+    #[structopt(short, long, default_value = "m/44'/60'/0'/0/0")]
+    pub hd_path: String,
+    #[structopt(short, long, default_value = "5")]
+    pub chain_id: u64,
+    #[structopt(short, long, default_value = "0")]
+    pub nonce: u128,
+    #[structopt(short, long, required = true, parse(try_from_str = 
decode_hex_to_address))]
+    pub to: [u8; 20],
+    #[structopt(short, long, required = true)]
+    pub value: u128,
+    #[structopt(short = "p", long, default_value = "1000000000")]
+    pub gas_price: u128,
+    #[structopt(short, long, default_value = "21000")]
+    pub gas: u128,
+}
+
+#[derive(Debug, StructOpt)]
+pub enum Command {
+    /// Create a new wallet.
+    #[structopt(name = "create-wallet")]
+    CreateWallet(CreateWalletOpt),
+    /// Remove a wallet.
+    #[structopt(name = "remove-wallet")]
+    RemoveWallet(RemoveWalletOpt),
+    /// Derive an address from a wallet.
+    #[structopt(name = "derive-address")]
+    DeriveAddress(DeriveAddressOpt),
+    /// Sign a transaction.
+    #[structopt(name = "sign-transaction")]
+    SignTransaction(SignTransactionOpt),
+    /// Run tests
+    #[structopt(name = "test")]
+    Test,
+}
+
+#[derive(Debug, StructOpt)]
+#[structopt(name = "eth_wallet", about = "A simple Ethereum wallet based on 
TEE")]
+pub struct Opt {
+    #[structopt(subcommand)]
+    pub command: Command,
+}
diff --git a/projects/web3/eth_wallet/host/src/main.rs 
b/projects/web3/eth_wallet/host/src/main.rs
new file mode 100644
index 0000000..6c4d71a
--- /dev/null
+++ b/projects/web3/eth_wallet/host/src/main.rs
@@ -0,0 +1,152 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+mod cli;
+mod tests;
+
+use optee_teec::{Context, Operation, ParamType, Uuid};
+use optee_teec::{ParamNone, ParamTmpRef, ParamValue};
+
+use anyhow::{bail, Result};
+use structopt::StructOpt;
+
+const OUTPUT_MAX_SIZE: usize = 1024;
+
+fn invoke_command(command: proto::Command, input: &[u8]) -> 
optee_teec::Result<Vec<u8>> {
+    let mut ctx = Context::new()?;
+    let uuid = Uuid::parse_str(proto::UUID)
+        .map_err(|_| 
optee_teec::Error::new(optee_teec::ErrorKind::ItemNotFound))?;
+    let mut session = ctx.open_session(uuid)?;
+
+    println!("CA: command: {:?}", command);
+    // input buffer
+    let p0 = ParamTmpRef::new_input(input);
+    // output buffer
+    let mut output = vec![0u8; OUTPUT_MAX_SIZE];
+    let p1 = ParamTmpRef::new_output(output.as_mut_slice());
+    // output buffer size
+    let p2 = ParamValue::new(0, 0, ParamType::ValueInout);
+
+    let mut operation = Operation::new(0, p0, p1, p2, ParamNone);
+    match session.invoke_command(command as u32, &mut operation) {
+        Ok(()) => {
+            println!("CA: invoke_command success");
+            let output_len = operation.parameters().2.a() as usize;
+            Ok(output[..output_len].to_vec())
+        }
+        Err(e) => {
+            let output_len = operation.parameters().2.a() as usize;
+            let err_message = String::from_utf8_lossy(&output[..output_len]);
+            println!("CA: invoke_command failed: {:?}", err_message);
+            Err(e)
+        }
+    }
+}
+
+pub fn create_wallet() -> Result<uuid::Uuid> {
+    let serialized_output = invoke_command(proto::Command::CreateWallet, &[])?;
+    let output: proto::CreateWalletOutput = 
bincode::deserialize(&serialized_output)?;
+    Ok(output.wallet_id)
+}
+
+pub fn remove_wallet(wallet_id: uuid::Uuid) -> Result<()> {
+    let input = proto::RemoveWalletInput { wallet_id };
+    let _output = invoke_command(proto::Command::RemoveWallet, 
&bincode::serialize(&input)?)?;
+    Ok(())
+}
+
+pub fn derive_address(wallet_id: uuid::Uuid, hd_path: &str) -> Result<[u8; 
20]> {
+    let input = proto::DeriveAddressInput {
+        wallet_id,
+        hd_path: hd_path.to_string(),
+    };
+    let serialized_output =
+        invoke_command(proto::Command::DeriveAddress, 
&bincode::serialize(&input)?)?;
+    let output: proto::DeriveAddressOutput = 
bincode::deserialize(&serialized_output)?;
+    Ok(output.address)
+}
+
+pub fn sign_transaction(
+    wallet_id: uuid::Uuid,
+    hd_path: &str,
+    chain_id: u64,
+    nonce: u128,
+    to: [u8; 20],
+    value: u128,
+    gas_price: u128,
+    gas: u128,
+) -> Result<Vec<u8>> {
+    let transaction = proto::EthTransaction {
+        chain_id,
+        nonce,
+        to: Some(to),
+        value,
+        gas_price,
+        gas,
+        data: vec![],
+    };
+    let input = proto::SignTransactionInput {
+        wallet_id,
+        hd_path: hd_path.to_string(),
+        transaction,
+    };
+    let serialized_output = invoke_command(
+        proto::Command::SignTransaction,
+        &bincode::serialize(&input)?,
+    )?;
+    let output: proto::SignTransactionOutput = 
bincode::deserialize(&serialized_output)?;
+    Ok(output.signature)
+}
+
+fn main() -> Result<()> {
+    let args = cli::Opt::from_args();
+    match args.command {
+        cli::Command::CreateWallet(_opt) => {
+            let wallet_id = create_wallet()?;
+            println!("Wallet ID: {}", wallet_id);
+        }
+        cli::Command::RemoveWallet(opt) => {
+            remove_wallet(opt.wallet_id)?;
+            println!("Wallet removed");
+        }
+        cli::Command::DeriveAddress(opt) => {
+            let address = derive_address(opt.wallet_id, &opt.hd_path)?;
+            println!("Address: 0x{}", hex::encode(&address));
+        }
+        cli::Command::SignTransaction(opt) => {
+            let signature = sign_transaction(
+                opt.wallet_id,
+                &opt.hd_path,
+                opt.chain_id,
+                opt.nonce,
+                opt.to,
+                opt.value,
+                opt.gas_price,
+                opt.gas,
+            )?;
+            println!("Signature: {}", hex::encode(&signature));
+        }
+        cli::Command::Test => {
+            tests::tests::test_workflow();
+            println!("Tests passed");
+        }
+        _ => {
+            bail!("Unsupported command");
+        }
+    }
+    Ok(())
+}
diff --git a/projects/web3/eth_wallet/host/src/tests.rs 
b/projects/web3/eth_wallet/host/src/tests.rs
new file mode 100644
index 0000000..439cc17
--- /dev/null
+++ b/projects/web3/eth_wallet/host/src/tests.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.
+
+pub mod tests {
+    use crate::*;
+
+    pub fn test_workflow() {
+        // Simulate the workflow of creating a wallet, deriving an address, 
and signing a transaction
+        let wallet_id = create_wallet().unwrap();
+        let address = derive_address(wallet_id, "m/44'/60'/0'/0/0").unwrap();
+        let result = sign_transaction(
+            wallet_id,
+            "m/44'/60'/0'/0/0",
+            5,
+            0,
+            address,
+            100,
+            1000000000,
+            21000,
+        );
+        assert!(result.is_ok());
+    }
+}
diff --git a/ci/ci.sh b/projects/web3/eth_wallet/proto/Cargo.toml
old mode 100755
new mode 100644
similarity index 59%
copy from ci/ci.sh
copy to projects/web3/eth_wallet/proto/Cargo.toml
index da12226..1bd3681
--- a/ci/ci.sh
+++ b/projects/web3/eth_wallet/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,33 +15,18 @@
 # 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
+[package]
+name = "proto"
+version = "0.3.0"
+authors = ["Teaclave Contributors <[email protected]>"]
+license = "Apache-2.0"
+repository = "https://github.com/apache/incubator-teaclave-trustzone-sdk.git";
+description = "Data structures and functions shared by host and TA."
+edition = "2018"
 
-# 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
+[dependencies]
+uuid = { version = "1.8", features = ["serde"] }
+serde = { version = "1.0", features = ["derive"] }
 
-popd
+[build-dependencies]
+uuid = { version = "1.8", default-features = false }
diff --git a/projects/web3/eth_wallet/proto/build.rs 
b/projects/web3/eth_wallet/proto/build.rs
new file mode 100644
index 0000000..b9d0612
--- /dev/null
+++ b/projects/web3/eth_wallet/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/projects/web3/eth_wallet/proto/src/in_out.rs 
b/projects/web3/eth_wallet/proto/src/in_out.rs
new file mode 100644
index 0000000..36a5bce
--- /dev/null
+++ b/projects/web3/eth_wallet/proto/src/in_out.rs
@@ -0,0 +1,71 @@
+// 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::{Deserialize, Serialize};
+use uuid::Uuid;
+
+#[derive(Serialize, Deserialize, Debug, Clone)]
+pub struct CreateWalletInput {}
+
+#[derive(Serialize, Deserialize, Debug, Clone)]
+pub struct CreateWalletOutput {
+    pub wallet_id: Uuid,
+    pub mnemonic: String,
+}
+
+#[derive(Serialize, Deserialize, Debug, Clone)]
+pub struct RemoveWalletInput {
+    pub wallet_id: Uuid,
+}
+
+#[derive(Serialize, Deserialize, Debug, Clone)]
+pub struct RemoveWalletOutput {}
+
+#[derive(Serialize, Deserialize, Debug, Clone)]
+pub struct DeriveAddressInput {
+    pub wallet_id: Uuid,
+    pub hd_path: String,
+}
+
+#[derive(Serialize, Deserialize, Debug, Clone)]
+pub struct DeriveAddressOutput {
+    pub address: [u8; 20],
+    pub public_key: Vec<u8>,
+}
+
+#[derive(Serialize, Deserialize, Debug, Clone)]
+pub struct EthTransaction {
+    pub chain_id: u64,
+    pub nonce: u128,
+    pub to: Option<[u8; 20]>,
+    pub value: u128,
+    pub gas_price: u128,
+    pub gas: u128,
+    pub data: Vec<u8>,
+}
+
+#[derive(Serialize, Deserialize, Debug, Clone)]
+pub struct SignTransactionInput {
+    pub wallet_id: Uuid,
+    pub hd_path: String,
+    pub transaction: EthTransaction,
+}
+
+#[derive(Serialize, Deserialize, Debug, Clone)]
+pub struct SignTransactionOutput {
+    pub signature: Vec<u8>,
+}
diff --git a/projects/web3/eth_wallet/proto/src/lib.rs 
b/projects/web3/eth_wallet/proto/src/lib.rs
new file mode 100644
index 0000000..87c42bb
--- /dev/null
+++ b/projects/web3/eth_wallet/proto/src/lib.rs
@@ -0,0 +1,43 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+mod in_out;
+pub use in_out::*;
+
+#[derive(Debug)]
+pub enum Command {
+    CreateWallet,
+    RemoveWallet,
+    DeriveAddress,
+    SignTransaction,
+    Unknown,
+}
+
+impl From<u32> for Command {
+    #[inline]
+    fn from(value: u32) -> Command {
+        match value {
+            0 => Command::CreateWallet,
+            1 => Command::RemoveWallet,
+            2 => Command::DeriveAddress,
+            3 => Command::SignTransaction,
+            _ => Command::Unknown,
+        }
+    }
+}
+
+pub const UUID: &str = &include_str!(concat!(env!("OUT_DIR"), "/uuid.txt"));
diff --git a/projects/web3/eth_wallet/ta/Cargo.toml 
b/projects/web3/eth_wallet/ta/Cargo.toml
new file mode 100644
index 0000000..e118e59
--- /dev/null
+++ b/projects/web3/eth_wallet/ta/Cargo.toml
@@ -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.
+
+[package]
+name = "ta"
+version = "0.3.0"
+authors = ["Teaclave Contributors <[email protected]>"]
+license = "Apache-2.0"
+repository = "https://github.com/apache/incubator-teaclave-trustzone-sdk.git";
+description = "An example of Rust OP-TEE TrustZone SDK."
+edition = "2018"
+
+[dependencies]
+libc = { path = "../../../../rust/libc" }
+proto = { path = "../proto" }
+optee-utee-sys = { path = "../../../../optee-utee/optee-utee-sys" }
+optee-utee = { path = "../../../../optee-utee" }
+
+anyhow = "1.0"
+uuid = { version = "1.8", default-features = false }
+bip32 = { version = "0.3.0", features = ["bip39"]}
+hex = { version = "0.4", features = ["serde"] }
+serde = { version = "1.0", features = ["derive"] }
+sha3 = "0.10.6"
+secp256k1 = "0.27.0"
+ethereum-tx-sign = "6.1.3"
+bincode = "1.3.3"
+
+[build-dependencies]
+uuid = { version = "1.8", default-features = false }
+proto = { path = "../proto" }
+
+[profile.release]
+lto = false
+opt-level = 3
diff --git a/projects/web3/eth_wallet/ta/Makefile 
b/projects/web3/eth_wallet/ta/Makefile
new file mode 100644
index 0000000..46037a8
--- /dev/null
+++ b/projects/web3/eth_wallet/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` then rerun `source environment` 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
\ No newline at end of file
diff --git a/ci/ci.sh b/projects/web3/eth_wallet/ta/Xargo.toml
old mode 100755
new mode 100644
similarity index 59%
copy from ci/ci.sh
copy to projects/web3/eth_wallet/ta/Xargo.toml
index da12226..251ee70
--- a/ci/ci.sh
+++ b/projects/web3/eth_wallet/ta/Xargo.toml
@@ -1,5 +1,3 @@
-#!/bin/bash
-
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -17,33 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
-
-./test_hello_world.sh
-./test_random.sh
-./test_secure_storage.sh
-./test_aes.sh
-./test_hotp.sh
-./test_acipher.sh
-./test_big_int.sh
-./test_diffie_hellman.sh
-./test_digest.sh
-./test_authentication.sh
-./test_time.sh
-./test_signature_verification.sh
-./test_supp_plugin.sh
-./test_error_handling.sh
-
-# 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
+[dependencies.std]
+path = "../../../../rust/rust/library/std"
 
-popd
+[patch.crates-io]
+libc =  { path = "../../../../rust/libc" }
+rustc-std-workspace-core = { path = 
"../../../../rust/rust/library/rustc-std-workspace-core" }
+rustc-std-workspace-alloc = { path = 
"../../../../rust/rust/library/rustc-std-workspace-alloc" }
diff --git a/projects/web3/eth_wallet/ta/build.rs 
b/projects/web3/eth_wallet/ta/build.rs
new file mode 100644
index 0000000..9efe628
--- /dev/null
+++ b/projects/web3/eth_wallet/ta/build.rs
@@ -0,0 +1,108 @@
+// 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/projects/web3/eth_wallet/ta/src/hash.rs 
b/projects/web3/eth_wallet/ta/src/hash.rs
new file mode 100644
index 0000000..9b5f3a6
--- /dev/null
+++ b/projects/web3/eth_wallet/ta/src/hash.rs
@@ -0,0 +1,28 @@
+// 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;
+use sha3::{Digest, Keccak256};
+
+pub fn keccak_hash_to_bytes<T>(data: &T) -> Vec<u8>
+where
+    T: ?Sized + Serialize + AsRef<[u8]>,
+{
+    let mut hasher = Keccak256::new();
+    hasher.update(data);
+    hasher.finalize().to_vec()
+}
diff --git a/projects/web3/eth_wallet/ta/src/main.rs 
b/projects/web3/eth_wallet/ta/src/main.rs
new file mode 100644
index 0000000..d889a26
--- /dev/null
+++ b/projects/web3/eth_wallet/ta/src/main.rs
@@ -0,0 +1,181 @@
+// 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]
+
+mod hash;
+mod secure_storage;
+mod wallet;
+
+use crate::secure_storage::{
+    delete_from_secure_storage, load_from_secure_storage, 
save_in_secure_storage,
+};
+use optee_utee::{
+    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
+};
+use optee_utee::{Error, ErrorKind, Parameters};
+use proto::Command;
+
+use anyhow::{anyhow, bail, Result};
+use std::convert::TryInto;
+use std::io::Write;
+use wallet::Wallet;
+
+#[ta_create]
+fn create() -> optee_utee::Result<()> {
+    trace_println!("[+] TA create");
+    Ok(())
+}
+
+#[ta_open_session]
+fn open_session(_params: &mut Parameters) -> optee_utee::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");
+}
+
+#[cfg(debug_assertions)]
+macro_rules! dbg_println {
+    ($($arg:tt)*) => (trace_println!($($arg)*));
+}
+
+#[cfg(not(debug_assertions))]
+macro_rules! dbg_println {
+    ($($arg:tt)*) => {};
+}
+
+fn create_wallet(_input: &proto::CreateWalletInput) -> 
Result<proto::CreateWalletOutput> {
+    let wallet = Wallet::new()?;
+    let wallet_id = wallet.get_id();
+    let mnemonic = wallet.get_mnemonic()?;
+    dbg_println!("[+] Wallet ID: {:?}", wallet_id);
+
+    let secure_object: Vec<u8> = wallet.try_into()?;
+    save_in_secure_storage(wallet_id.as_bytes(), &secure_object)?;
+    dbg_println!("[+] Wallet saved in secure storage");
+
+    Ok(proto::CreateWalletOutput {
+        wallet_id,
+        mnemonic,
+    })
+}
+
+fn remove_wallet(input: &proto::RemoveWalletInput) -> 
Result<proto::RemoveWalletOutput> {
+    dbg_println!("[+] Removing wallet: {:?}", input.wallet_id);
+
+    delete_from_secure_storage(input.wallet_id.as_bytes())?;
+    dbg_println!("[+] Wallet removed");
+
+    Ok(proto::RemoveWalletOutput {})
+}
+
+fn derive_address(input: &proto::DeriveAddressInput) -> 
Result<proto::DeriveAddressOutput> {
+    let secure_object = load_from_secure_storage(input.wallet_id.as_bytes())
+        .map_err(|e| anyhow!("[+] Deriving address: error: wallet not found: 
{:?}", e))?;
+    dbg_println!("[+] Deriving address: secure object loaded");
+
+    let wallet: Wallet = secure_object.try_into()?;
+    let (address, public_key) = wallet.derive_address(&input.hd_path)?;
+    dbg_println!("[+] Deriving address: address: {:?}", address);
+    dbg_println!("[+] Deriving address: public key: {:?}", public_key);
+
+    Ok(proto::DeriveAddressOutput {
+        address,
+        public_key,
+    })
+}
+
+fn sign_transaction(input: &proto::SignTransactionInput) -> 
Result<proto::SignTransactionOutput> {
+    let secure_object = load_from_secure_storage(input.wallet_id.as_bytes())
+        .map_err(|e| anyhow!("[+] Sign transaction: error: wallet not found: 
{:?}", e))?;
+    dbg_println!("[+] Sign transaction: secure object loaded");
+
+    let wallet: Wallet = secure_object.try_into()?;
+    let signature = wallet.sign_transaction(&input.hd_path, 
&input.transaction)?;
+    dbg_println!("[+] Sign transaction: signature: {:?}", signature);
+
+    Ok(proto::SignTransactionOutput { signature })
+}
+
+fn handle_invoke(command: Command, serialized_input: &[u8]) -> Result<Vec<u8>> 
{
+    fn process<T: serde::de::DeserializeOwned, U: serde::Serialize, F: Fn(&T) 
-> Result<U>>(
+        serialized_input: &[u8],
+        handler: F,
+    ) -> Result<Vec<u8>> {
+        let input: T = bincode::deserialize(serialized_input)?;
+        let output = handler(&input)?;
+        let serialized_output = bincode::serialize(&output)?;
+        Ok(serialized_output)
+    }
+
+    match command {
+        Command::CreateWallet => process(serialized_input, create_wallet),
+        Command::RemoveWallet => process(serialized_input, remove_wallet),
+        Command::DeriveAddress => process(serialized_input, derive_address),
+        Command::SignTransaction => process(serialized_input, 
sign_transaction),
+        _ => bail!("Unsupported command"),
+    }
+}
+
+#[ta_invoke_command]
+fn invoke_command(cmd_id: u32, params: &mut Parameters) -> 
optee_utee::Result<()> {
+    dbg_println!("[+] TA invoke command");
+    let mut p0 = unsafe { params.0.as_memref()? };
+    let mut p1 = unsafe { params.1.as_memref()? };
+    let mut p2 = unsafe { params.2.as_value()? };
+
+    let output_vec = match handle_invoke(Command::from(cmd_id), p0.buffer()) {
+        Ok(output) => output,
+        Err(e) => {
+            let err_message = format!("{:?}", e).as_bytes().to_vec();
+            p1.buffer()
+                .write(&err_message)
+                .map_err(|_| Error::new(ErrorKind::BadState))?;
+            p2.set_a(err_message.len() as u32);
+            return Err(Error::new(ErrorKind::BadParameters));
+        }
+    };
+    p1.buffer()
+        .write(&output_vec)
+        .map_err(|_| Error::new(ErrorKind::BadState))?;
+    p2.set_a(output_vec.len() as u32);
+
+    Ok(())
+}
+
+// TA configurations
+const TA_FLAGS: u32 = 0;
+const TA_DATA_SIZE: u32 = 1024 * 1024;
+const TA_STACK_SIZE: u32 = 128 * 1024;
+const TA_VERSION: &[u8] = b"0.3\0";
+const TA_DESCRIPTION: &[u8] = b"This is an example of Ethereum wallet TA\0";
+const EXT_PROP_VALUE_1: &[u8] = b"Ethereum wallet 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/projects/web3/eth_wallet/ta/src/secure_storage.rs 
b/projects/web3/eth_wallet/ta/src/secure_storage.rs
new file mode 100644
index 0000000..808adb7
--- /dev/null
+++ b/projects/web3/eth_wallet/ta/src/secure_storage.rs
@@ -0,0 +1,106 @@
+// 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 anyhow::{bail, Result};
+use optee_utee::{DataFlag, ObjectStorageConstants, PersistentObject};
+
+pub fn save_in_secure_storage(obj_id: &[u8], data: &[u8]) -> Result<()> {
+    let obj_data_flag = DataFlag::ACCESS_READ
+        | DataFlag::ACCESS_WRITE
+        | DataFlag::ACCESS_WRITE_META
+        | DataFlag::OVERWRITE;
+
+    let mut init_data: [u8; 0] = [0; 0];
+    match PersistentObject::create(
+        ObjectStorageConstants::Private,
+        obj_id,
+        obj_data_flag,
+        None,
+        &mut init_data,
+    ) {
+        Err(e) => {
+            bail!("[-] {:?}: failed to create object: {:?}", &obj_id, e);
+        }
+
+        Ok(mut object) => match object.write(&data) {
+            Ok(()) => {
+                return Ok(());
+            }
+            Err(e_write) => {
+                object.close_and_delete()?;
+                std::mem::forget(object);
+                bail!(
+                    "[-] {:?}: failed to write data to object: {:?}",
+                    &obj_id,
+                    e_write
+                );
+            }
+        },
+    }
+}
+
+pub fn load_from_secure_storage(obj_id: &[u8]) -> Result<Vec<u8>> {
+    let mut buf = vec![0; 5000];
+
+    match PersistentObject::open(
+        ObjectStorageConstants::Private,
+        obj_id,
+        DataFlag::ACCESS_READ | DataFlag::SHARE_READ,
+    ) {
+        Err(e) => bail!("[-] {:?}: failed to open object: {:?}", &obj_id, e),
+
+        Ok(object) => {
+            let obj_info = object.info()?;
+
+            if obj_info.data_size() > buf.len() {
+                bail!("[-] {:?}: data size is too large", &obj_id);
+            }
+            let read_bytes = match object.read(&mut buf) {
+                Ok(read_bytes) => read_bytes,
+                Err(e) => {
+                    bail!("[-] {:?}: failed to read data: {:?}", &obj_id, e);
+                }
+            };
+
+            if read_bytes != obj_info.data_size() as u32 {
+                bail!("[-] {:?}: failed to read data", &obj_id);
+            }
+
+            buf.truncate(read_bytes as usize);
+        }
+    }
+
+    Ok(buf)
+}
+
+pub fn delete_from_secure_storage(obj_id: &[u8]) -> Result<()> {
+    match PersistentObject::open(
+        ObjectStorageConstants::Private,
+        &mut obj_id.to_vec(),
+        DataFlag::ACCESS_READ | DataFlag::ACCESS_WRITE_META,
+    ) {
+        Err(e) => {
+            bail!("[-] {:?}: failed to open object: {:?}", &obj_id, e);
+        }
+
+        Ok(mut object) => {
+            object.close_and_delete()?;
+            std::mem::forget(object);
+            return Ok(());
+        }
+    }
+}
diff --git a/projects/web3/eth_wallet/ta/src/wallet.rs 
b/projects/web3/eth_wallet/ta/src/wallet.rs
new file mode 100644
index 0000000..4072061
--- /dev/null
+++ b/projects/web3/eth_wallet/ta/src/wallet.rs
@@ -0,0 +1,142 @@
+// 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 anyhow::{anyhow, Result};
+use bip32::{Mnemonic, XPrv};
+use serde::{Deserialize, Serialize};
+use std::convert::{TryFrom, TryInto};
+use uuid::Uuid;
+
+use crate::hash::keccak_hash_to_bytes;
+use ethereum_tx_sign::Transaction;
+use optee_utee::Random;
+use proto::EthTransaction;
+
+#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
+pub struct Wallet {
+    id: Uuid,
+    entropy: Vec<u8>,
+}
+
+impl Wallet {
+    pub fn new() -> Result<Self> {
+        let mut entropy = vec![0u8; 32];
+        Random::generate(entropy.as_mut() as _);
+
+        let mut random_bytes = vec![0u8; 16];
+        Random::generate(random_bytes.as_mut() as _);
+        let uuid = uuid::Builder::from_random_bytes(
+            random_bytes
+                .try_into()
+                .map_err(|_| anyhow!("[-] Wallet::new(): invalid random 
bytes"))?,
+        )
+        .into_uuid();
+
+        Ok(Self {
+            id: uuid,
+            entropy: entropy,
+        })
+    }
+
+    pub fn get_id(&self) -> Uuid {
+        self.id.clone()
+    }
+
+    pub fn get_mnemonic(&self) -> Result<String> {
+        let mnemonic = Mnemonic::from_entropy(
+            self.entropy.as_slice().try_into()?,
+            bip32::Language::English,
+        );
+        Ok(mnemonic.phrase().to_string())
+    }
+
+    pub fn get_seed(&self) -> Result<Vec<u8>> {
+        let mnemonic = Mnemonic::from_entropy(
+            self.entropy.as_slice().try_into()?,
+            bip32::Language::English,
+        );
+        let seed = mnemonic.to_seed(""); // empty passwords
+        Ok(seed.as_bytes().to_vec())
+    }
+
+    pub fn derive_prv_key(&self, hd_path: &str) -> Result<Vec<u8>> {
+        let path = hd_path.parse()?;
+        let child_xprv = XPrv::derive_from_path(self.get_seed()?, &path)?;
+        let child_xprv_bytes = child_xprv.to_bytes();
+        Ok(child_xprv_bytes.to_vec())
+    }
+
+    pub fn derive_pub_key(&self, hd_path: &str) -> Result<Vec<u8>> {
+        let path = hd_path.parse()?;
+        let child_xprv = XPrv::derive_from_path(self.get_seed()?, &path)?;
+        // public key
+        let child_xpub_bytes = child_xprv.public_key().to_bytes();
+        Ok(child_xpub_bytes.to_vec())
+    }
+
+    pub fn derive_address(&self, hd_path: &str) -> Result<([u8; 20], Vec<u8>)> 
{
+        let public_key_bytes = self.derive_pub_key(hd_path)?;
+        // uncompress public key
+        let public_key = secp256k1::PublicKey::from_slice(&public_key_bytes)?;
+        let uncompressed_public_key = 
&public_key.serialize_uncompressed()[1..];
+
+        // pubkey to address
+        let address = &keccak_hash_to_bytes(&uncompressed_public_key)[12..];
+        Ok((address.try_into()?, public_key_bytes))
+    }
+
+    pub fn sign_transaction(&self, hd_path: &str, transaction: 
&EthTransaction) -> Result<Vec<u8>> {
+        let xprv = self.derive_prv_key(hd_path)?;
+        let legacy_transaction = ethereum_tx_sign::LegacyTransaction {
+            chain: transaction.chain_id,
+            nonce: transaction.nonce,
+            gas_price: transaction.gas_price,
+            gas: transaction.gas,
+            to: transaction.to,
+            value: transaction.value,
+            data: transaction.data.clone(),
+        };
+        let ecdsa = legacy_transaction.ecdsa(&xprv).map_err(|e| {
+            let ethereum_tx_sign::Error::Secp256k1(inner_error) = e;
+            inner_error
+        })?;
+        let signature = legacy_transaction.sign(&ecdsa);
+        Ok(signature)
+    }
+}
+
+impl TryFrom<Wallet> for Vec<u8> {
+    type Error = anyhow::Error;
+
+    fn try_from(wallet: Wallet) -> Result<Vec<u8>> {
+        bincode::serialize(&wallet).map_err(|e| anyhow!("[-] 
Wallet::try_into(): {:?}", e))
+    }
+}
+
+impl TryFrom<Vec<u8>> for Wallet {
+    type Error = anyhow::Error;
+
+    fn try_from(data: Vec<u8>) -> Result<Wallet> {
+        bincode::deserialize(&data).map_err(|e| anyhow!("[-] 
Wallet::try_from(): {:?}", e))
+    }
+}
+
+impl Drop for Wallet {
+    fn drop(&mut self) {
+        self.entropy.iter_mut().for_each(|x| *x = 0);
+    }
+}
diff --git a/projects/web3/eth_wallet/ta/ta_static.rs 
b/projects/web3/eth_wallet/ta/ta_static.rs
new file mode 100644
index 0000000..20e1d97
--- /dev/null
+++ b/projects/web3/eth_wallet/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::{c_int, c_void};
+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: usize = 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: usize = 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/projects/web3/eth_wallet/uuid.txt 
b/projects/web3/eth_wallet/uuid.txt
new file mode 100644
index 0000000..c0c0f3f
--- /dev/null
+++ b/projects/web3/eth_wallet/uuid.txt
@@ -0,0 +1 @@
+be2dc9a0-02b4-4b33-ba21-9964dbdf1573
diff --git a/ci/ci.sh b/tests/test_eth_wallet.sh
similarity index 61%
copy from ci/ci.sh
copy to tests/test_eth_wallet.sh
index da12226..3e41433 100755
--- a/ci/ci.sh
+++ b/tests/test_eth_wallet.sh
@@ -19,31 +19,24 @@
 
 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 ../projects/web3/eth_wallet/ta/target/$TARGET_TA/release/*.ta shared
+cp ../projects/web3/eth_wallet/host/target/$TARGET_HOST/release/eth_wallet-rs 
shared
 
-# 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
+# Run script specific commands in QEMU
+run_in_qemu "cp *.ta /lib/optee_armtz/\n"
+run_in_qemu "./eth_wallet-rs test\n"
+run_in_qemu "^C"
 
-popd
+# Script specific checks
+{
+       grep -q "Tests passed" screenlog.0
+} || {
+        cat -v screenlog.0
+        false
+}
+
+rm screenlog.0
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to