This is an automated email from the ASF dual-hosted git repository.
yuanz pushed a commit to branch release-v0.3.0
in repository
https://gitbox.apache.org/repos/asf/incubator-teaclave-trustzone-sdk.git
The following commit(s) were added to refs/heads/release-v0.3.0 by this push:
new 01fb02e Add eth-wallet example project
01fb02e is described below
commit 01fb02e199fc24ee8205cbbe178e6045869f2481
Author: Yuan Zhuang <[email protected]>
AuthorDate: Mon Sep 2 12:53:27 2024 +0000
Add eth-wallet example project
---
projects/eth_wallet-rs/Makefile | 24 +
projects/eth_wallet-rs/README.md | 181 +++++++
projects/eth_wallet-rs/host/Cargo.lock | 377 ++++++++++++++
projects/eth_wallet-rs/host/Cargo.toml | 39 ++
projects/eth_wallet-rs/host/Makefile | 48 ++
projects/eth_wallet-rs/host/src/cli.rs | 97 ++++
projects/eth_wallet-rs/host/src/main.rs | 113 +++++
projects/eth_wallet-rs/proto/Cargo.toml | 32 ++
projects/eth_wallet-rs/proto/build.rs | 36 ++
projects/eth_wallet-rs/proto/src/in_out.rs | 71 +++
projects/eth_wallet-rs/proto/src/lib.rs | 43 ++
projects/eth_wallet-rs/ta/Cargo.lock | 634 ++++++++++++++++++++++++
projects/eth_wallet-rs/ta/Cargo.toml | 49 ++
projects/eth_wallet-rs/ta/Makefile | 56 +++
projects/eth_wallet-rs/ta/Xargo.toml | 24 +
projects/eth_wallet-rs/ta/build.rs | 101 ++++
projects/eth_wallet-rs/ta/src/hash.rs | 38 ++
projects/eth_wallet-rs/ta/src/main.rs | 177 +++++++
projects/eth_wallet-rs/ta/src/secure_storage.rs | 103 ++++
projects/eth_wallet-rs/ta/src/wallet.rs | 164 ++++++
projects/eth_wallet-rs/ta/ta_aarch64.lds | 92 ++++
projects/eth_wallet-rs/ta/ta_arm.lds | 91 ++++
projects/eth_wallet-rs/ta/ta_static.rs | 98 ++++
projects/eth_wallet-rs/uuid.txt | 1 +
24 files changed, 2689 insertions(+)
diff --git a/projects/eth_wallet-rs/Makefile b/projects/eth_wallet-rs/Makefile
new file mode 100644
index 0000000..09679cd
--- /dev/null
+++ b/projects/eth_wallet-rs/Makefile
@@ -0,0 +1,24 @@
+# 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.
+
+all:
+ @make -s -C host
+ @make -s -C ta
+
+clean:
+ @make -s -C host clean
+ @make -s -C ta clean
diff --git a/projects/eth_wallet-rs/README.md b/projects/eth_wallet-rs/README.md
new file mode 100644
index 0000000..4b4d4f3
--- /dev/null
+++ b/projects/eth_wallet-rs/README.md
@@ -0,0 +1,181 @@
+# ETH Wallet
+
+## Introduction
+
+**ETH Wallet** is an open-source Ethereum wallet designed to run on TrustZone
+(OP-TEE). It has two main components:
+
+- **TA** (`/ta`): The Trusted Application (TA) that operates within the
+ secure environment provided by TrustZone.
+- **CA** (`/host`): The Client Application (CA) that runs in the normal
+ world and interacts with the TA.
+
+Shared structures are defined in the `proto` directory.
+
+### Benefits
+
+- **Secure Key Management**: Keys are generated and stored within the Trusted
+ Execution Environment (TEE) and never leave it throughout their entire
+ lifecycle.
+
+## 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
+```
+
+## 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
+[+] Deriving address: wallet loaded: Wallet { id:
aa5798a1-3c89-4708-b316-712aea4f59e2, entropy: [...] }
+[+] 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
+[+] Sign transaction: wallet loaded: Wallet { id:
aa5798a1-3c89-4708-b316-712aea4f59e2, entropy: [...] }
+[+] Wallet::derive_prv_key(): prv key: ...
+[+] Wallet::derive_prv_key(): non-extended prv key: ...
+[+] 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
+[+] Removing wallet: wallet loaded: Wallet { id:
aa5798a1-3c89-4708-b316-712aea4f59e2, entropy: [...] }
+[+] Wallet removed from secure storage
+```
diff --git a/projects/eth_wallet-rs/host/Cargo.lock
b/projects/eth_wallet-rs/host/Cargo.lock
new file mode 100644
index 0000000..287cc16
--- /dev/null
+++ b/projects/eth_wallet-rs/host/Cargo.lock
@@ -0,0 +1,377 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "ansi_term"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.86"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
+
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "bincode"
+version = "1.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "clap"
+version = "2.34.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
+dependencies = [
+ "ansi_term",
+ "atty",
+ "bitflags",
+ "strsim",
+ "textwrap",
+ "unicode-width",
+ "vec_map",
+]
+
+[[package]]
+name = "eth_wallet-rs"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "bincode",
+ "hex 0.4.3",
+ "libc",
+ "optee-teec",
+ "proto",
+ "structopt",
+ "uuid 1.10.0",
+]
+
+[[package]]
+name = "heck"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
+dependencies = [
+ "unicode-segmentation",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "hex"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
+
+[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+
+[[package]]
+name = "libc"
+version = "0.2.155"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
+
+[[package]]
+name = "optee-teec"
+version = "0.2.0"
+dependencies = [
+ "hex 0.3.2",
+ "libc",
+ "optee-teec-macros",
+ "optee-teec-sys",
+ "uuid 0.7.4",
+]
+
+[[package]]
+name = "optee-teec-macros"
+version = "0.2.0"
+dependencies = [
+ "quote 0.6.13",
+ "syn 0.15.44",
+]
+
+[[package]]
+name = "optee-teec-sys"
+version = "0.2.0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2 1.0.86",
+ "quote 1.0.36",
+ "syn 1.0.109",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2 1.0.86",
+ "quote 1.0.36",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "0.4.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
+dependencies = [
+ "unicode-xid",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.86"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "proto"
+version = "0.3.0"
+dependencies = [
+ "serde",
+ "uuid 1.10.0",
+]
+
+[[package]]
+name = "quote"
+version = "0.6.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
+dependencies = [
+ "proc-macro2 0.4.30",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.36"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
+dependencies = [
+ "proc-macro2 1.0.86",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.204"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.204"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
+dependencies = [
+ "proc-macro2 1.0.86",
+ "quote 1.0.36",
+ "syn 2.0.72",
+]
+
+[[package]]
+name = "strsim"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
+
+[[package]]
+name = "structopt"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10"
+dependencies = [
+ "clap",
+ "lazy_static",
+ "structopt-derive",
+]
+
+[[package]]
+name = "structopt-derive"
+version = "0.4.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
+dependencies = [
+ "heck",
+ "proc-macro-error",
+ "proc-macro2 1.0.86",
+ "quote 1.0.36",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "syn"
+version = "0.15.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
+dependencies = [
+ "proc-macro2 0.4.30",
+ "quote 0.6.13",
+ "unicode-xid",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2 1.0.86",
+ "quote 1.0.36",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.72"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
+dependencies = [
+ "proc-macro2 1.0.86",
+ "quote 1.0.36",
+ "unicode-ident",
+]
+
+[[package]]
+name = "textwrap"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
+dependencies = [
+ "unicode-width",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
+
+[[package]]
+name = "unicode-width"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
+
+[[package]]
+name = "unicode-xid"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
+
+[[package]]
+name = "uuid"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a"
+
+[[package]]
+name = "uuid"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "vec_map"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
+
+[[package]]
+name = "version_check"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/projects/eth_wallet-rs/host/Cargo.toml
b/projects/eth_wallet-rs/host/Cargo.toml
new file mode 100644
index 0000000..39b0578
--- /dev/null
+++ b/projects/eth_wallet-rs/host/Cargo.toml
@@ -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.
+
+[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"
+
+[dependencies]
+libc = "0.2.48"
+proto = { path = "../proto" }
+optee-teec = { path = "../../../optee-teec" }
+
+structopt = "0.3"
+bincode = "1.3.3"
+anyhow = "1.0"
+uuid = { version = "1.8", features = ["serde"] }
+hex = { version = "0.4", features = ["serde"] }
+
+[profile.release]
+lto = true
diff --git a/projects/eth_wallet-rs/host/Makefile
b/projects/eth_wallet-rs/host/Makefile
new file mode 100644
index 0000000..1160a2a
--- /dev/null
+++ b/projects/eth_wallet-rs/host/Makefile
@@ -0,0 +1,48 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+NAME := eth_wallet-rs
+ARCH ?= aarch64
+
+OPTEE_DIR ?= ../../../optee
+
+ifeq ($(ARCH), arm)
+ OPTEE_BIN := $(OPTEE_DIR)/toolchains/aarch32/bin
+ OBJCOPY := $(OPTEE_BIN)/arm-linux-gnueabihf-objcopy
+ TARGET := arm-unknown-linux-gnueabihf
+else
+ OPTEE_BIN := $(OPTEE_DIR)/toolchains/$(ARCH)/bin
+ OBJCOPY := $(OPTEE_BIN)/aarch64-linux-gnu-objcopy
+ TARGET := aarch64-unknown-linux-gnu
+endif
+
+OUT_DIR := $(CURDIR)/target/$(TARGET)/release
+
+
+all: host strip
+
+host:
+ @cargo build --target $(TARGET) --release
+
+fmt:
+ @cargo fmt
+
+strip:
+ @$(OBJCOPY) --strip-unneeded $(OUT_DIR)/$(NAME) $(OUT_DIR)/$(NAME)
+
+clean:
+ @cargo clean
diff --git a/projects/eth_wallet-rs/host/src/cli.rs
b/projects/eth_wallet-rs/host/src/cli.rs
new file mode 100644
index 0000000..8d90546
--- /dev/null
+++ b/projects/eth_wallet-rs/host/src/cli.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.
+
+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),
+}
+
+#[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/eth_wallet-rs/host/src/main.rs
b/projects/eth_wallet-rs/host/src/main.rs
new file mode 100644
index 0000000..f071975
--- /dev/null
+++ b/projects/eth_wallet-rs/host/src/main.rs
@@ -0,0 +1,113 @@
+// 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;
+
+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)
+ }
+ }
+}
+
+fn main() -> Result<()> {
+ let args = cli::Opt::from_args();
+ match args.command {
+ cli::Command::CreateWallet(_opt) => {
+ let serialized_output =
invoke_command(proto::Command::CreateWallet, &[])?;
+ let output: proto::CreateWalletOutput =
bincode::deserialize(&serialized_output)?;
+ println!("Wallet ID: {:?}", output.wallet_id);
+ }
+ cli::Command::RemoveWallet(opt) => {
+ let input = proto::RemoveWalletInput {
+ wallet_id: opt.wallet_id,
+ };
+ let _output =
+ invoke_command(proto::Command::RemoveWallet,
&bincode::serialize(&input)?)?;
+ println!("Wallet removed");
+ }
+ cli::Command::DeriveAddress(opt) => {
+ let input = proto::DeriveAddressInput {
+ wallet_id: opt.wallet_id,
+ hd_path: opt.hd_path,
+ };
+ let serialized_output =
+ invoke_command(proto::Command::DeriveAddress,
&bincode::serialize(&input)?)?;
+ let output: proto::DeriveAddressOutput =
bincode::deserialize(&serialized_output)?;
+ println!("Address: 0x{:?}", hex::encode(&output.address));
+ println!("Public key: {:?}", hex::encode(&output.public_key));
+ }
+ cli::Command::SignTransaction(opt) => {
+ let transaction = proto::EthTransaction {
+ chain_id: opt.chain_id,
+ nonce: opt.nonce,
+ to: Some(opt.to),
+ value: opt.value,
+ gas_price: opt.gas_price,
+ gas: opt.gas,
+ data: vec![],
+ };
+ let input = proto::SignTransactionInput {
+ wallet_id: opt.wallet_id,
+ hd_path: opt.hd_path,
+ transaction,
+ };
+ let serialized_output = invoke_command(
+ proto::Command::SignTransaction,
+ &bincode::serialize(&input)?,
+ )?;
+ let output: proto::SignTransactionOutput =
bincode::deserialize(&serialized_output)?;
+ println!("Signature: {:?}", hex::encode(&output.signature));
+ }
+ _ => {
+ bail!("Unsupported command");
+ }
+ }
+ Ok(())
+}
diff --git a/projects/eth_wallet-rs/proto/Cargo.toml
b/projects/eth_wallet-rs/proto/Cargo.toml
new file mode 100644
index 0000000..1bd3681
--- /dev/null
+++ b/projects/eth_wallet-rs/proto/Cargo.toml
@@ -0,0 +1,32 @@
+# 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 = "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"
+
+[dependencies]
+uuid = { version = "1.8", features = ["serde"] }
+serde = { version = "1.0", features = ["derive"] }
+
+[build-dependencies]
+uuid = { version = "1.8", default-features = false }
diff --git a/projects/eth_wallet-rs/proto/build.rs
b/projects/eth_wallet-rs/proto/build.rs
new file mode 100644
index 0000000..b9d0612
--- /dev/null
+++ b/projects/eth_wallet-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/projects/eth_wallet-rs/proto/src/in_out.rs
b/projects/eth_wallet-rs/proto/src/in_out.rs
new file mode 100644
index 0000000..5225c5a
--- /dev/null
+++ b/projects/eth_wallet-rs/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>,
+}
\ No newline at end of file
diff --git a/projects/eth_wallet-rs/proto/src/lib.rs
b/projects/eth_wallet-rs/proto/src/lib.rs
new file mode 100644
index 0000000..87c42bb
--- /dev/null
+++ b/projects/eth_wallet-rs/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/eth_wallet-rs/ta/Cargo.lock
b/projects/eth_wallet-rs/ta/Cargo.lock
new file mode 100644
index 0000000..83bf9e5
--- /dev/null
+++ b/projects/eth_wallet-rs/ta/Cargo.lock
@@ -0,0 +1,634 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "anyhow"
+version = "1.0.86"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
+
+[[package]]
+name = "autocfg"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
+
+[[package]]
+name = "base16ct"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce"
+
+[[package]]
+name = "bincode"
+version = "1.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "bip32"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "873faa4363bfc54c36a48321da034c92a0645a363eed34d948683ffc1706e37f"
+dependencies = [
+ "bs58",
+ "hmac",
+ "k256",
+ "once_cell",
+ "pbkdf2",
+ "rand_core",
+ "ripemd160",
+ "sha2",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "block-buffer"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
+dependencies = [
+ "block-padding",
+ "generic-array",
+]
+
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "block-padding"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
+
+[[package]]
+name = "bs58"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
+dependencies = [
+ "sha2",
+]
+
+[[package]]
+name = "bytes"
+version = "1.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
+
+[[package]]
+name = "cc"
+version = "1.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "const-oid"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3"
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
+dependencies = [
+ "libc 0.2.155",
+]
+
+[[package]]
+name = "crunchy"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
+
+[[package]]
+name = "crypto-bigint"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21"
+dependencies = [
+ "generic-array",
+ "rand_core",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "crypto-mac"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714"
+dependencies = [
+ "generic-array",
+ "subtle",
+]
+
+[[package]]
+name = "der"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c"
+dependencies = [
+ "const-oid",
+]
+
+[[package]]
+name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer 0.10.4",
+ "crypto-common",
+]
+
+[[package]]
+name = "ecdsa"
+version = "0.13.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9"
+dependencies = [
+ "der",
+ "elliptic-curve",
+ "rfc6979",
+ "signature",
+]
+
+[[package]]
+name = "elliptic-curve"
+version = "0.11.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6"
+dependencies = [
+ "base16ct",
+ "crypto-bigint",
+ "der",
+ "ff",
+ "generic-array",
+ "group",
+ "rand_core",
+ "sec1",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "ethereum-tx-sign"
+version = "6.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b13a263688dba5fd4822fc57e022c221ed25c12495939f1246b14de2f7db69d2"
+dependencies = [
+ "bytes",
+ "hex",
+ "num-traits",
+ "rlp",
+ "secp256k1 0.27.0",
+ "serde",
+ "serde_derive",
+ "tiny-keccak",
+]
+
+[[package]]
+name = "ff"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924"
+dependencies = [
+ "rand_core",
+ "subtle",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "group"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89"
+dependencies = [
+ "ff",
+ "rand_core",
+ "subtle",
+]
+
+[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "hmac"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b"
+dependencies = [
+ "crypto-mac",
+ "digest 0.9.0",
+]
+
+[[package]]
+name = "k256"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d"
+dependencies = [
+ "cfg-if",
+ "ecdsa",
+ "elliptic-curve",
+ "sec1",
+ "sha2",
+ "sha3 0.9.1",
+]
+
+[[package]]
+name = "keccak"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654"
+dependencies = [
+ "cpufeatures",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.153"
+
+[[package]]
+name = "libc"
+version = "0.2.155"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
+
+[[package]]
+name = "num-traits"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+
+[[package]]
+name = "opaque-debug"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
+
+[[package]]
+name = "optee-utee"
+version = "0.2.0"
+dependencies = [
+ "bitflags",
+ "hex",
+ "libc 0.2.153",
+ "optee-utee-macros",
+ "optee-utee-sys",
+ "uuid",
+]
+
+[[package]]
+name = "optee-utee-macros"
+version = "0.2.0"
+dependencies = [
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "optee-utee-sys"
+version = "0.2.0"
+dependencies = [
+ "libc 0.2.153",
+]
+
+[[package]]
+name = "pbkdf2"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739"
+dependencies = [
+ "crypto-mac",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.86"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "proto"
+version = "0.3.0"
+dependencies = [
+ "serde",
+ "uuid",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.36"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+
+[[package]]
+name = "rfc6979"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525"
+dependencies = [
+ "crypto-bigint",
+ "hmac",
+ "zeroize",
+]
+
+[[package]]
+name = "ripemd160"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251"
+dependencies = [
+ "block-buffer 0.9.0",
+ "digest 0.9.0",
+ "opaque-debug",
+]
+
+[[package]]
+name = "rlp"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec"
+dependencies = [
+ "bytes",
+ "rustc-hex",
+]
+
+[[package]]
+name = "rustc-hex"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6"
+
+[[package]]
+name = "sec1"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1"
+dependencies = [
+ "der",
+ "generic-array",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "secp256k1"
+version = "0.24.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62"
+dependencies = [
+ "secp256k1-sys 0.6.1",
+]
+
+[[package]]
+name = "secp256k1"
+version = "0.27.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f"
+dependencies = [
+ "secp256k1-sys 0.8.1",
+]
+
+[[package]]
+name = "secp256k1-sys"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "secp256k1-sys"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.204"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.204"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "sha2"
+version = "0.9.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
+dependencies = [
+ "block-buffer 0.9.0",
+ "cfg-if",
+ "cpufeatures",
+ "digest 0.9.0",
+ "opaque-debug",
+]
+
+[[package]]
+name = "sha3"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809"
+dependencies = [
+ "block-buffer 0.9.0",
+ "digest 0.9.0",
+ "keccak",
+ "opaque-debug",
+]
+
+[[package]]
+name = "sha3"
+version = "0.10.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60"
+dependencies = [
+ "digest 0.10.7",
+ "keccak",
+]
+
+[[package]]
+name = "signature"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788"
+dependencies = [
+ "digest 0.9.0",
+ "rand_core",
+]
+
+[[package]]
+name = "subtle"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
+
+[[package]]
+name = "syn"
+version = "2.0.72"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "ta"
+version = "0.3.0"
+dependencies = [
+ "anyhow",
+ "bincode",
+ "bip32",
+ "ethereum-tx-sign",
+ "hex",
+ "libc 0.2.153",
+ "optee-utee",
+ "optee-utee-sys",
+ "proto",
+ "secp256k1 0.24.3",
+ "serde",
+ "sha3 0.10.8",
+ "uuid",
+]
+
+[[package]]
+name = "tiny-keccak"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
+dependencies = [
+ "crunchy",
+]
+
+[[package]]
+name = "typenum"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+
+[[package]]
+name = "uuid"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "version_check"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+
+[[package]]
+name = "zeroize"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
diff --git a/projects/eth_wallet-rs/ta/Cargo.toml
b/projects/eth_wallet-rs/ta/Cargo.toml
new file mode 100644
index 0000000..006c696
--- /dev/null
+++ b/projects/eth_wallet-rs/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.24.3"
+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 = 1
diff --git a/projects/eth_wallet-rs/ta/Makefile
b/projects/eth_wallet-rs/ta/Makefile
new file mode 100644
index 0000000..f7b32fb
--- /dev/null
+++ b/projects/eth_wallet-rs/ta/Makefile
@@ -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.
+
+OPTEE_DIR ?= ../../../optee
+OPTEE_OS_DIR ?= $(OPTEE_DIR)/optee_os
+UUID ?= $(shell cat "../uuid.txt")
+
+ARCH ?= aarch64
+
+ifeq ($(ARCH), arm)
+ TA_SIGN_KEY ?=
$(OPTEE_OS_DIR)/out/arm/export-ta_arm32/keys/default_ta.pem
+ SIGN := $(OPTEE_OS_DIR)/out/arm/export-ta_arm32/scripts/sign_encrypt.py
+ OPTEE_BIN := $(OPTEE_DIR)/toolchains/aarch32/bin
+ OBJCOPY := $(OPTEE_BIN)/arm-linux-gnueabihf-objcopy
+ TARGET := arm-unknown-optee
+else
+ TA_SIGN_KEY ?=
$(OPTEE_OS_DIR)/out/arm/export-ta_arm64/keys/default_ta.pem
+ SIGN := $(OPTEE_OS_DIR)/out/arm/export-ta_arm64/scripts/sign_encrypt.py
+ OPTEE_BIN := $(OPTEE_DIR)/toolchains/$(ARCH)/bin
+ OBJCOPY := $(OPTEE_BIN)/aarch64-linux-gnu-objcopy
+ TARGET := aarch64-unknown-optee
+endif
+
+OUT_DIR := $(CURDIR)/target/$(TARGET)/release
+
+all: ta strip sign
+
+ta:
+ @xargo build --target $(TARGET) --release --verbose
+
+fmt:
+ @cargo fmt
+
+strip:
+ @$(OBJCOPY) --strip-unneeded $(OUT_DIR)/ta $(OUT_DIR)/stripped_ta
+
+sign:
+ @$(SIGN) --uuid $(UUID) --key $(TA_SIGN_KEY) --in
$(OUT_DIR)/stripped_ta --out $(OUT_DIR)/$(UUID).ta
+ @echo "SIGN => ${UUID}"
+
+clean:
+ @xargo clean
diff --git a/projects/eth_wallet-rs/ta/Xargo.toml
b/projects/eth_wallet-rs/ta/Xargo.toml
new file mode 100644
index 0000000..1b1a113
--- /dev/null
+++ b/projects/eth_wallet-rs/ta/Xargo.toml
@@ -0,0 +1,24 @@
+# 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.
+
+[dependencies.std]
+path = "../../../rust/rust/library/std"
+
+[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/eth_wallet-rs/ta/build.rs
b/projects/eth_wallet-rs/ta/build.rs
new file mode 100644
index 0000000..40bdbae
--- /dev/null
+++ b/projects/eth_wallet-rs/ta/build.rs
@@ -0,0 +1,101 @@
+// 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("ARCH") {
+ Ok(ref v) if v == "arm" => {
+ 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");
+
+ 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/eth_wallet-rs/ta/src/hash.rs
b/projects/eth_wallet-rs/ta/src/hash.rs
new file mode 100644
index 0000000..4d6204f
--- /dev/null
+++ b/projects/eth_wallet-rs/ta/src/hash.rs
@@ -0,0 +1,38 @@
+// 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<T>(data: &T) -> String
+where
+ T: ?Sized + Serialize + AsRef<[u8]>,
+{
+ let mut hasher = Keccak256::new();
+ hasher.update(data);
+ let result = hasher.finalize();
+ hex::encode(result)
+}
+
+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/eth_wallet-rs/ta/src/main.rs
b/projects/eth_wallet-rs/ta/src/main.rs
new file mode 100644
index 0000000..0951671
--- /dev/null
+++ b/projects/eth_wallet-rs/ta/src/main.rs
@@ -0,0 +1,177 @@
+// 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::{TryFrom, 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");
+}
+
+fn create_wallet(input: &proto::CreateWalletInput) ->
Result<proto::CreateWalletOutput> {
+ let wallet = Wallet::new()?;
+ trace_println!("[+] Wallet created: {:?}", wallet);
+
+ let wallet_id = wallet.get_id();
+ let mnemonic = wallet.get_mnemonic()?;
+ trace_println!("[+] Wallet ID: {:?}", wallet_id);
+
+ let secure_object: Vec<u8> = wallet.try_into()?;
+ save_in_secure_storage(wallet_id.as_bytes(), &secure_object)?;
+ trace_println!("[+] Wallet saved in secure storage");
+
+ Ok(proto::CreateWalletOutput {
+ wallet_id,
+ mnemonic,
+ })
+}
+
+fn remove_wallet(input: &proto::RemoveWalletInput) ->
Result<proto::RemoveWalletOutput> {
+ trace_println!("[+] Removing wallet: {:?}", input.wallet_id);
+
+ delete_from_secure_storage(input.wallet_id.as_bytes())?;
+ trace_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))?;
+ trace_println!("[+] Deriving address: secure object loaded");
+
+ let wallet: Wallet = secure_object.try_into()?;
+ trace_println!("[+] Deriving address: wallet loaded: {:?}", wallet);
+
+ let (address, public_key) = wallet.derive_address(&input.hd_path)?;
+ trace_println!("[+] Deriving address: address: {:?}", address);
+ trace_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))?;
+ trace_println!("[+] Sign transaction: secure object loaded");
+
+ let wallet: Wallet = secure_object.try_into()?;
+ trace_println!("[+] Sign transaction: wallet loaded: {:?}", wallet);
+
+ let signature = wallet.sign_transaction(&input.hd_path,
&input.transaction)?;
+ trace_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).unwrap();
+ 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<()> {
+ 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 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/eth_wallet-rs/ta/src/secure_storage.rs
b/projects/eth_wallet-rs/ta/src/secure_storage.rs
new file mode 100644
index 0000000..65a1dfb
--- /dev/null
+++ b/projects/eth_wallet-rs/ta/src/secure_storage.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 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 = object.read(&mut buf).unwrap();
+
+ if read_bytes != obj_info.data_size() as u32 {
+ bail!("[-] {:?}: failed to read data", &obj_id);
+ }
+
+ unsafe {
+ buf.set_len(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/eth_wallet-rs/ta/src/wallet.rs
b/projects/eth_wallet-rs/ta/src/wallet.rs
new file mode 100644
index 0000000..f69d2ec
--- /dev/null
+++ b/projects/eth_wallet-rs/ta/src/wallet.rs
@@ -0,0 +1,164 @@
+// 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, bail, Result};
+use bip32::{Mnemonic, Prefix, XPrv};
+use serde::{Deserialize, Serialize};
+use std::convert::{TryFrom, TryInto};
+use uuid::Uuid;
+
+use crate::hash::{keccak_hash, keccak_hash_to_bytes};
+use ethereum_tx_sign::Transaction;
+use optee_utee::{trace_println, 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)?;
+ trace_println!(
+ "[+] Wallet::derive_prv_key(): prv key: {:?}",
+ child_xprv.to_string(Prefix::XPRV)
+ );
+ let child_xprv_bytes = child_xprv.to_bytes();
+ trace_println!(
+ "[+] Wallet::derive_prv_key(): non-extended prv key: {}",
+ &hex::encode(&child_xprv_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)?;
+ trace_println!(
+ "[+] Wallet::derive_pub_key(): pub key: {:?}",
+ child_xprv.public_key().to_string(Prefix::XPUB)
+ );
+ // public key
+ let child_xpub_bytes = child_xprv.public_key().to_bytes();
+ trace_println!(
+ "[+] Wallet::derive_pub_key(): non-extended pub key: {}",
+ &hex::encode(&child_xpub_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..];
+ trace_println!("[+] Wallet::derive_address(): address: {:?}",
&address);
+
+ 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);
+ trace_println!(
+ "[+] sign_transaction: signed transaction bytes: {:?}",
+ &signature
+ );
+ 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/eth_wallet-rs/ta/ta_aarch64.lds
b/projects/eth_wallet-rs/ta/ta_aarch64.lds
new file mode 100644
index 0000000..adb7603
--- /dev/null
+++ b/projects/eth_wallet-rs/ta/ta_aarch64.lds
@@ -0,0 +1,92 @@
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+
+PHDRS {
+ /*
+ * Exec and rodata headers are hard coded to RX and RO
+ * respectively. This is needed because the binary is relocatable
+ * and the linker would automatically make any header writeable
+ * that need to be updated during relocation.
+ */
+ exec PT_LOAD FLAGS (5); /* RX */
+ rodata PT_LOAD FLAGS (4); /* RO */
+ rwdata PT_LOAD;
+ dyn PT_DYNAMIC;
+}
+
+SECTIONS {
+ .ta_head : {*(.ta_head)} :exec
+ .text : {
+ __text_start = .;
+ *(.text .text.*)
+ *(.stub)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.gnu.linkonce.t.*)
+ /* Workaround for an erratum in ARM's VFP11 coprocessor */
+ *(.vfp11_veneer)
+ PROVIDE(__gnu_mcount_nc = __utee_mcount);
+ __text_end = .;
+ }
+ .plt : { *(.plt) }
+
+ .eh_frame : { *(.eh_frame) } :rodata
+ .rodata : {
+ *(.gnu.linkonce.r.*)
+ *(.rodata .rodata.*)
+ }
+ /* .ARM.exidx is sorted, so has to go in its own output section. */
+ .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+ .rel.text : { *(.rel.text) *(.rel.gnu.linkonce.t*) }
+ .rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) }
+ .rel.data : { *(.rel.data) *(.rel.gnu.linkonce.d*) }
+ .rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) }
+ .rel.rodata : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
+ .rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
+ .rel.dyn : { *(.rel.dyn) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.init : { *(.rel.init) }
+ .rela.init : { *(.rela.init) }
+ .rel.fini : { *(.rel.fini) }
+ .rela.fini : { *(.rela.fini) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .dynamic : { *(.dynamic) } :dyn :rodata
+ .dynsym : { *(.dynsym) } :rodata
+ .dynstr : { *(.dynstr) }
+ .hash : { *(.hash) }
+
+ /* Page align to allow dropping execute bit for RW data */
+ . = ALIGN(4096);
+
+ .data : { *(.data .data.* .gnu.linkonce.d.*) } :rwdata
+ .got : { *(.got.plt) *(.got) }
+ .bss : {
+ *(.bss .bss.* .gnu.linkonce.b.* COMMON)
+
+ /*
+ * TA profiling with gprof
+ * Reserve some space for the profiling buffer, only if the
+ * TA is instrumented (i.e., some files were built with -pg).
+ * Note that PROVIDE() above defines a symbol only if it is
+ * referenced in the object files.
+ * This also provides a way to detect at runtime if the TA is
+ * instrumented or not.
+ */
+ . = ALIGN(8);
+ __gprof_buf_start = .;
+ __gprof_buf_end = .;
+ }
+
+ /DISCARD/ : { *(.interp) }
+}
+
diff --git a/projects/eth_wallet-rs/ta/ta_arm.lds
b/projects/eth_wallet-rs/ta/ta_arm.lds
new file mode 100644
index 0000000..764ea25
--- /dev/null
+++ b/projects/eth_wallet-rs/ta/ta_arm.lds
@@ -0,0 +1,91 @@
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+PHDRS {
+ /*
+ * Exec and rodata headers are hard coded to RX and RO
+ * respectively. This is needed because the binary is relocatable
+ * and the linker would automatically make any header writeable
+ * that need to be updated during relocation.
+ */
+ exec PT_LOAD FLAGS (5); /* RX */
+ rodata PT_LOAD FLAGS (4); /* RO */
+ rwdata PT_LOAD;
+ dyn PT_DYNAMIC;
+}
+
+SECTIONS {
+ .ta_head : {*(.ta_head)} :exec
+ .text : {
+ __text_start = .;
+ *(.text .text.*)
+ *(.stub)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.gnu.linkonce.t.*)
+ /* Workaround for an erratum in ARM's VFP11 coprocessor */
+ *(.vfp11_veneer)
+ PROVIDE(__gnu_mcount_nc = __utee_mcount);
+ __text_end = .;
+ }
+ .plt : { *(.plt) }
+
+ .eh_frame : { *(.eh_frame) } :rodata
+ .rodata : {
+ *(.gnu.linkonce.r.*)
+ *(.rodata .rodata.*)
+ }
+ /* .ARM.exidx is sorted, so has to go in its own output section. */
+ .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+ .rel.text : { *(.rel.text) *(.rel.gnu.linkonce.t*) }
+ .rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) }
+ .rel.data : { *(.rel.data) *(.rel.gnu.linkonce.d*) }
+ .rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) }
+ .rel.rodata : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
+ .rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
+ .rel.dyn : { *(.rel.dyn) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.init : { *(.rel.init) }
+ .rela.init : { *(.rela.init) }
+ .rel.fini : { *(.rel.fini) }
+ .rela.fini : { *(.rela.fini) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .dynamic : { *(.dynamic) } :dyn :rodata
+ .dynsym : { *(.dynsym) } :rodata
+ .dynstr : { *(.dynstr) }
+ .hash : { *(.hash) }
+
+ /* Page align to allow dropping execute bit for RW data */
+ . = ALIGN(4096);
+
+ .data : { *(.data .data.* .gnu.linkonce.d.*) } :rwdata
+ .got : { *(.got.plt) *(.got) }
+ .bss : {
+ *(.bss .bss.* .gnu.linkonce.b.* COMMON)
+
+ /*
+ * TA profiling with gprof
+ * Reserve some space for the profiling buffer, only if the
+ * TA is instrumented (i.e., some files were built with -pg).
+ * Note that PROVIDE() above defines a symbol only if it is
+ * referenced in the object files.
+ * This also provides a way to detect at runtime if the TA is
+ * instrumented or not.
+ */
+ . = ALIGN(8);
+ __gprof_buf_start = .;
+ __gprof_buf_end = .;
+ }
+
+ /DISCARD/ : { *(.interp) }
+}
diff --git a/projects/eth_wallet-rs/ta/ta_static.rs
b/projects/eth_wallet-rs/ta/ta_static.rs
new file mode 100644
index 0000000..b31f8c3
--- /dev/null
+++ b/projects/eth_wallet-rs/ta/ta_static.rs
@@ -0,0 +1,98 @@
+// 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_mangle]
+pub static mut trace_level: libc::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: std::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: libc::size_t = std::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: libc::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() -> libc::c_int {
+ return trace_level;
+}
diff --git a/projects/eth_wallet-rs/uuid.txt b/projects/eth_wallet-rs/uuid.txt
new file mode 100644
index 0000000..c0c0f3f
--- /dev/null
+++ b/projects/eth_wallet-rs/uuid.txt
@@ -0,0 +1 @@
+be2dc9a0-02b4-4b33-ba21-9964dbdf1573
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]