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 7daee91 optee-utee: support TEE_GetProperty API
7daee91 is described below
commit 7daee9178955ff9727b3577b3a7f2a0b5a50f9d9
Author: Yuan Zhuang <[email protected]>
AuthorDate: Wed Apr 16 08:43:58 2025 +0000
optee-utee: support TEE_GetProperty API
This commit introduces support for accessing TEE properties, as
specified in the
GlobalPlatform TEE Internal Core API Specification v1.3.1.
It also provide the `property-rs` example for demostration.
Signed-off-by: Yuan Zhuang <[email protected]>
Reviewed-by: Zehui Chen <[email protected]>
---
ci/ci.sh | 1 +
examples/property-rs/Makefile | 39 ++
.../property-rs/host}/Cargo.toml | 29 +-
examples/property-rs/host/Makefile | 37 ++
examples/property-rs/host/src/main.rs | 32 ++
.../property-rs/proto}/Cargo.toml | 26 +-
examples/property-rs/proto/src/lib.rs | 32 ++
{optee-utee => examples/property-rs/ta}/Cargo.toml | 33 +-
examples/property-rs/ta/Makefile | 45 ++
examples/property-rs/ta/Xargo.toml | 24 +
examples/property-rs/ta/build.rs | 24 +
examples/property-rs/ta/src/main.rs | 114 +++++
examples/property-rs/uuid.txt | 1 +
optee-utee/Cargo.toml | 1 +
optee-utee/optee-utee-sys/src/tee_api_types.rs | 1 +
optee-utee/src/identity.rs | 62 +++
optee-utee/src/lib.rs | 3 +
optee-utee/src/property.rs | 487 +++++++++++++++++++++
optee-utee/src/uuid.rs | 8 +-
ci/ci.sh => tests/test_property.sh | 52 +--
20 files changed, 949 insertions(+), 102 deletions(-)
diff --git a/ci/ci.sh b/ci/ci.sh
index 2b1501d..fbd1ccc 100755
--- a/ci/ci.sh
+++ b/ci/ci.sh
@@ -54,6 +54,7 @@ fi
./test_udp_socket.sh
./test_client_pool.sh
./test_inter_ta.sh
+./test_property.sh
popd
diff --git a/examples/property-rs/Makefile b/examples/property-rs/Makefile
new file mode 100644
index 0000000..a7a3dec
--- /dev/null
+++ b/examples/property-rs/Makefile
@@ -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.
+
+# If _HOST or _TA specific compiler/target are not specified, then use common
+# compiler/target for both
+CROSS_COMPILE_HOST ?= aarch64-linux-gnu-
+CROSS_COMPILE_TA ?= aarch64-linux-gnu-
+TARGET_HOST ?= aarch64-unknown-linux-gnu
+TARGET_TA ?= aarch64-unknown-linux-gnu
+
+.PHONY: host ta all clean
+
+all: host ta
+
+host:
+ $(q)make -C host TARGET=$(TARGET_HOST) \
+ CROSS_COMPILE=$(CROSS_COMPILE_HOST)
+
+ta:
+ $(q)make -C ta TARGET=$(TARGET_TA) \
+ CROSS_COMPILE=$(CROSS_COMPILE_TA)
+
+clean:
+ $(q)make -C host clean
+ $(q)make -C ta clean
diff --git a/optee-utee/Cargo.toml b/examples/property-rs/host/Cargo.toml
similarity index 59%
copy from optee-utee/Cargo.toml
copy to examples/property-rs/host/Cargo.toml
index 0bc7a9d..bfa5ea0 100644
--- a/optee-utee/Cargo.toml
+++ b/examples/property-rs/host/Cargo.toml
@@ -16,33 +16,18 @@
# under the License.
[package]
-name = "optee-utee"
+name = "property-rs"
version = "0.4.0"
authors = ["Teaclave Contributors <[email protected]>"]
license = "Apache-2.0"
repository = "https://github.com/apache/incubator-teaclave-trustzone-sdk.git"
-description = "TEE internal core API."
+description = "An example of Rust OP-TEE TrustZone SDK."
edition = "2018"
[dependencies]
-optee-utee-sys = { version = "0.4.0", path = "optee-utee-sys" }
-optee-utee-macros = { version = "0.4.0", path = "macros" }
-bitflags = "1.0.4"
-uuid = { version = "0.8", default-features = false }
-hex = { version = "0.4", default-features = false, features = ["alloc"] }
-libc_alloc = "1.0.5"
+libc = "0.2.48"
+proto = { path = "../proto" }
+optee-teec = { path = "../../../optee-teec" }
-[dev-dependencies]
-rand = "0.8.5"
-once_cell = "1.20.2"
-serde = { version = "1.0.215" }
-serde_json = { version = "1.0.133" }
-# disable linking when running unit tests
-optee-utee-sys = { version = "0.4.0", path = "optee-utee-sys", features =
["no_link"] }
-
-[features]
-no_panic_handler = []
-
-[workspace]
-resolver = "2"
-members = ['systest']
+[profile.release]
+lto = true
diff --git a/examples/property-rs/host/Makefile
b/examples/property-rs/host/Makefile
new file mode 100644
index 0000000..0166655
--- /dev/null
+++ b/examples/property-rs/host/Makefile
@@ -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.
+
+NAME := property-rs
+
+TARGET ?= aarch64-unknown-linux-gnu
+CROSS_COMPILE ?= aarch64-linux-gnu-
+OBJCOPY := $(CROSS_COMPILE)objcopy
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
+
+OUT_DIR := $(CURDIR)/target/$(TARGET)/release
+
+
+all: host strip
+
+host:
+ @cargo build --target $(TARGET_HOST) --release --config $(LINKER_CFG)
+
+strip: host
+ @$(OBJCOPY) --strip-unneeded $(OUT_DIR)/$(NAME) $(OUT_DIR)/$(NAME)
+
+clean:
+ @cargo clean
diff --git a/examples/property-rs/host/src/main.rs
b/examples/property-rs/host/src/main.rs
new file mode 100644
index 0000000..1647efd
--- /dev/null
+++ b/examples/property-rs/host/src/main.rs
@@ -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.
+
+use optee_teec::{Context, ErrorKind, Operation, ParamNone, Uuid};
+use proto::{Command, UUID};
+
+fn main() -> optee_teec::Result<()> {
+ let mut ctx = Context::new()?;
+ let uuid =
+ Uuid::parse_str(UUID).map_err(|_|
optee_teec::Error::from(ErrorKind::BadParameters))?;
+ let mut session = ctx.open_session(uuid)?;
+ let mut operation = Operation::new(0, ParamNone, ParamNone, ParamNone,
ParamNone);
+
+ // Nothing to send, just invoke the Test command
+ session.invoke_command(Command::Test as u32, &mut operation)?;
+ println!("Success");
+ Ok(())
+}
diff --git a/optee-utee/Cargo.toml b/examples/property-rs/proto/Cargo.toml
similarity index 59%
copy from optee-utee/Cargo.toml
copy to examples/property-rs/proto/Cargo.toml
index 0bc7a9d..91066a3 100644
--- a/optee-utee/Cargo.toml
+++ b/examples/property-rs/proto/Cargo.toml
@@ -16,33 +16,13 @@
# under the License.
[package]
-name = "optee-utee"
+name = "proto"
version = "0.4.0"
authors = ["Teaclave Contributors <[email protected]>"]
license = "Apache-2.0"
repository = "https://github.com/apache/incubator-teaclave-trustzone-sdk.git"
-description = "TEE internal core API."
+description = "Data structures and functions shared by host and TA."
edition = "2018"
[dependencies]
-optee-utee-sys = { version = "0.4.0", path = "optee-utee-sys" }
-optee-utee-macros = { version = "0.4.0", path = "macros" }
-bitflags = "1.0.4"
-uuid = { version = "0.8", default-features = false }
-hex = { version = "0.4", default-features = false, features = ["alloc"] }
-libc_alloc = "1.0.5"
-
-[dev-dependencies]
-rand = "0.8.5"
-once_cell = "1.20.2"
-serde = { version = "1.0.215" }
-serde_json = { version = "1.0.133" }
-# disable linking when running unit tests
-optee-utee-sys = { version = "0.4.0", path = "optee-utee-sys", features =
["no_link"] }
-
-[features]
-no_panic_handler = []
-
-[workspace]
-resolver = "2"
-members = ['systest']
+num_enum = { version = "0.7.3", default-features = false }
diff --git a/examples/property-rs/proto/src/lib.rs
b/examples/property-rs/proto/src/lib.rs
new file mode 100644
index 0000000..98090b9
--- /dev/null
+++ b/examples/property-rs/proto/src/lib.rs
@@ -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.
+
+#![no_std]
+use num_enum::{FromPrimitive, IntoPrimitive};
+
+#[derive(FromPrimitive, IntoPrimitive)]
+#[repr(u32)]
+pub enum Command {
+ Test,
+ #[default]
+ Unknown,
+}
+
+// If Uuid::parse_str() returns an InvalidLength error, there may be an extra
+// newline in your uuid.txt file. You can remove it by running
+// `truncate -s 36 uuid.txt`.
+pub const UUID: &str = &include_str!("../../uuid.txt");
\ No newline at end of file
diff --git a/optee-utee/Cargo.toml b/examples/property-rs/ta/Cargo.toml
similarity index 59%
copy from optee-utee/Cargo.toml
copy to examples/property-rs/ta/Cargo.toml
index 0bc7a9d..4a0f9d2 100644
--- a/optee-utee/Cargo.toml
+++ b/examples/property-rs/ta/Cargo.toml
@@ -16,33 +16,24 @@
# under the License.
[package]
-name = "optee-utee"
+name = "ta"
version = "0.4.0"
authors = ["Teaclave Contributors <[email protected]>"]
license = "Apache-2.0"
repository = "https://github.com/apache/incubator-teaclave-trustzone-sdk.git"
-description = "TEE internal core API."
+description = "An example of Rust OP-TEE TrustZone SDK."
edition = "2018"
[dependencies]
-optee-utee-sys = { version = "0.4.0", path = "optee-utee-sys" }
-optee-utee-macros = { version = "0.4.0", path = "macros" }
-bitflags = "1.0.4"
-uuid = { version = "0.8", default-features = false }
-hex = { version = "0.4", default-features = false, features = ["alloc"] }
-libc_alloc = "1.0.5"
+proto = { path = "../proto" }
+optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
+optee-utee = { path = "../../../optee-utee" }
-[dev-dependencies]
-rand = "0.8.5"
-once_cell = "1.20.2"
-serde = { version = "1.0.215" }
-serde_json = { version = "1.0.133" }
-# disable linking when running unit tests
-optee-utee-sys = { version = "0.4.0", path = "optee-utee-sys", features =
["no_link"] }
+[build-dependencies]
+proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
-[features]
-no_panic_handler = []
-
-[workspace]
-resolver = "2"
-members = ['systest']
+[profile.release]
+panic = "abort"
+lto = true
+opt-level = 1
diff --git a/examples/property-rs/ta/Makefile b/examples/property-rs/ta/Makefile
new file mode 100644
index 0000000..029e66d
--- /dev/null
+++ b/examples/property-rs/ta/Makefile
@@ -0,0 +1,45 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+UUID ?= $(shell cat "../uuid.txt")
+
+TARGET ?= aarch64-unknown-linux-gnu
+CROSS_COMPILE ?= aarch64-linux-gnu-
+OBJCOPY := $(CROSS_COMPILE)objcopy
+# Configure the linker to use GCC, which works on both cross-compilation and
ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
+
+TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
+SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
+OUT_DIR := $(CURDIR)/target/$(TARGET)/release
+
+BUILDER = $(if $(STD),xargo,cargo)
+
+all: ta strip sign
+
+ta:
+ @$(BUILDER) build --target $(TARGET) --release --config $(LINKER_CFG)
+
+strip: ta
+ @$(OBJCOPY) --strip-unneeded $(OUT_DIR)/ta $(OUT_DIR)/stripped_ta
+
+sign: strip
+ @$(SIGN) --uuid $(UUID) --key $(TA_SIGN_KEY) --in
$(OUT_DIR)/stripped_ta --out $(OUT_DIR)/$(UUID).ta
+ @echo "SIGN => ${UUID}"
+
+clean:
+ @cargo clean
diff --git a/examples/property-rs/ta/Xargo.toml
b/examples/property-rs/ta/Xargo.toml
new file mode 100644
index 0000000..1b1a113
--- /dev/null
+++ b/examples/property-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/examples/property-rs/ta/build.rs b/examples/property-rs/ta/build.rs
new file mode 100644
index 0000000..c6d585f
--- /dev/null
+++ b/examples/property-rs/ta/build.rs
@@ -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.
+
+use optee_utee_build::{Error, RustEdition, TaConfig};
+use proto;
+
+fn main() -> Result<(), Error> {
+ let config = TaConfig::new_default_with_cargo_env(proto::UUID)?;
+ optee_utee_build::build(RustEdition::Before2024, config)
+}
diff --git a/examples/property-rs/ta/src/main.rs
b/examples/property-rs/ta/src/main.rs
new file mode 100644
index 0000000..df9fc83
--- /dev/null
+++ b/examples/property-rs/ta/src/main.rs
@@ -0,0 +1,114 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#![no_std]
+#![no_main]
+
+extern crate alloc;
+use alloc::string::ToString;
+
+use optee_utee::property::{
+ ClientIdentity, PropertyKey, TaDescription, TaMultiSession,
TeeInternalCoreVersion,
+};
+use optee_utee::LoginType;
+use optee_utee::{
+ ta_close_session, ta_create, ta_destroy, ta_invoke_command,
ta_open_session, trace_println,
+};
+use optee_utee::{Error, ErrorKind, Parameters, Result};
+use proto::Command;
+
+#[ta_create]
+fn create() -> Result<()> {
+ trace_println!("[+] TA create");
+ Ok(())
+}
+
+#[ta_open_session]
+fn open_session(_params: &mut Parameters) -> Result<()> {
+ trace_println!("[+] TA open session");
+ Ok(())
+}
+
+#[ta_close_session]
+fn close_session() {
+ trace_println!("[+] TA close session");
+}
+
+#[ta_destroy]
+fn destroy() {
+ trace_println!("[+] TA destroy");
+}
+
+fn get_properties() -> Result<()> {
+ // check caller
+ let client_identity = ClientIdentity.get()?;
+ trace_println!(
+ "[+] TA get caller identity: login: {}, uuid: {}",
+ client_identity.login_type(),
+ client_identity.uuid()
+ );
+ // login type should be Public
+ if client_identity.login_type() != LoginType::Public {
+ return Err(Error::new(ErrorKind::BadParameters));
+ }
+ // uuid should be all zero
+ if client_identity.uuid().to_string() !=
"00000000-0000-0000-0000-000000000000" {
+ return Err(Error::new(ErrorKind::BadParameters));
+ }
+
+ // test the other property:
+ let core_version = TeeInternalCoreVersion.get()?;
+ trace_println!("[+] TA get core version: {}", core_version);
+ // core version should not be zero
+ if core_version == 0 {
+ return Err(Error::new(ErrorKind::BadParameters));
+ }
+
+ let ta_multi_session = TaMultiSession.get()?;
+ trace_println!("[+] TA get multi session: {}", ta_multi_session);
+ // multi session should be false
+ if ta_multi_session {
+ return Err(Error::new(ErrorKind::BadParameters));
+ }
+
+ let ta_description = TaDescription.get()?;
+ trace_println!("[+] TA get description: {}", ta_description);
+ // description should be the specified string
+ if ta_description != "An example of Rust OP-TEE TrustZone SDK." {
+ return Err(Error::new(ErrorKind::BadParameters));
+ }
+
+ Ok(())
+}
+
+#[ta_invoke_command]
+fn invoke_command(cmd_id: u32, _params: &mut Parameters) -> Result<()> {
+ trace_println!("[+] TA invoke command");
+ match Command::from(cmd_id) {
+ Command::Test => {
+ get_properties()?;
+
+ trace_println!("[+] Test passed");
+ Ok(())
+ }
+ _ => {
+ return Err(Error::new(ErrorKind::NotSupported));
+ }
+ }
+}
+
+include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/property-rs/uuid.txt b/examples/property-rs/uuid.txt
new file mode 100644
index 0000000..870c3f7
--- /dev/null
+++ b/examples/property-rs/uuid.txt
@@ -0,0 +1 @@
+a3859d33-b540-4a69-8d29-696dde9115cc
\ No newline at end of file
diff --git a/optee-utee/Cargo.toml b/optee-utee/Cargo.toml
index 0bc7a9d..3ad0bf3 100644
--- a/optee-utee/Cargo.toml
+++ b/optee-utee/Cargo.toml
@@ -31,6 +31,7 @@ bitflags = "1.0.4"
uuid = { version = "0.8", default-features = false }
hex = { version = "0.4", default-features = false, features = ["alloc"] }
libc_alloc = "1.0.5"
+strum_macros = "0.26"
[dev-dependencies]
rand = "0.8.5"
diff --git a/optee-utee/optee-utee-sys/src/tee_api_types.rs
b/optee-utee/optee-utee-sys/src/tee_api_types.rs
index da95338..f925204 100644
--- a/optee-utee/optee-utee-sys/src/tee_api_types.rs
+++ b/optee-utee/optee-utee-sys/src/tee_api_types.rs
@@ -32,6 +32,7 @@ pub struct TEE_UUID {
pub clockSeqAndNode: [u8; 8],
}
+#[derive(Copy, Clone)]
#[repr(C)]
pub struct TEE_Identity {
pub login: u32,
diff --git a/optee-utee/src/identity.rs b/optee-utee/src/identity.rs
new file mode 100644
index 0000000..ae3e3f8
--- /dev/null
+++ b/optee-utee/src/identity.rs
@@ -0,0 +1,62 @@
+// 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 crate::Uuid;
+use optee_utee_sys as raw;
+use strum_macros::Display;
+
+#[derive(Copy, Clone)]
+pub struct Identity {
+ raw: raw::TEE_Identity,
+}
+
+impl Identity {
+ pub fn login_type(&self) -> LoginType {
+ match self.raw.login {
+ raw::TEE_LOGIN_PUBLIC => LoginType::Public,
+ raw::TEE_LOGIN_USER => LoginType::User,
+ raw::TEE_LOGIN_GROUP => LoginType::Group,
+ raw::TEE_LOGIN_APPLICATION => LoginType::Application,
+ raw::TEE_LOGIN_APPLICATION_USER => LoginType::ApplicationUser,
+ raw::TEE_LOGIN_APPLICATION_GROUP => LoginType::ApplicationGroup,
+ raw::TEE_LOGIN_TRUSTED_APP => LoginType::TrustedApp,
+ _ => panic!("Invalid login type"),
+ }
+ }
+
+ pub fn uuid(&self) -> Uuid {
+ Uuid::from(self.raw.uuid)
+ }
+}
+
+impl From<raw::TEE_Identity> for Identity {
+ fn from(raw: raw::TEE_Identity) -> Self {
+ Self { raw }
+ }
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Display)]
+#[repr(u32)]
+pub enum LoginType {
+ Public = raw::TEE_LOGIN_PUBLIC,
+ User = raw::TEE_LOGIN_USER,
+ Group = raw::TEE_LOGIN_GROUP,
+ Application = raw::TEE_LOGIN_APPLICATION,
+ ApplicationUser = raw::TEE_LOGIN_APPLICATION_USER,
+ ApplicationGroup = raw::TEE_LOGIN_APPLICATION_GROUP,
+ TrustedApp = raw::TEE_LOGIN_TRUSTED_APP,
+}
diff --git a/optee-utee/src/lib.rs b/optee-utee/src/lib.rs
index 795c5ca..c1fc00a 100644
--- a/optee-utee/src/lib.rs
+++ b/optee-utee/src/lib.rs
@@ -47,6 +47,7 @@ pub use self::arithmetical::*;
pub use self::crypto_op::*;
pub use self::error::{Error, ErrorKind, Result};
pub use self::extension::*;
+pub use self::identity::{Identity, LoginType};
pub use self::object::*;
pub use self::parameter::{ParamType, ParamTypes, Parameter, Parameters};
pub use self::ta_session::{TaSession, TaSessionBuilder};
@@ -64,9 +65,11 @@ pub mod arithmetical;
pub mod crypto_op;
mod error;
pub mod extension;
+pub mod identity;
pub mod net;
pub mod object;
mod parameter;
+pub mod property;
mod ta_session;
mod tee_parameter;
pub mod time;
diff --git a/optee-utee/src/property.rs b/optee-utee/src/property.rs
new file mode 100644
index 0000000..2a033a1
--- /dev/null
+++ b/optee-utee/src/property.rs
@@ -0,0 +1,487 @@
+// 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 crate::{Error, ErrorKind, Result};
+use crate::{Identity, Uuid};
+use alloc::{ffi::CString, string::String, vec::Vec};
+use optee_utee_sys as raw;
+
+/// Represents a TEE property set according to the TEE Internal API.
+/// The property set is a collection of properties that can be
+/// queried from the TEE. The property set is identified by a
+/// handle, which is a pointer to a TEE_PropSetHandle structure.
+pub enum PropertySet {
+ TeeImplementation,
+ CurrentClient,
+ CurrentTa,
+}
+
+impl PropertySet {
+ fn as_raw(&self) -> raw::TEE_PropSetHandle {
+ match self {
+ PropertySet::TeeImplementation =>
raw::TEE_PROPSET_TEE_IMPLEMENTATION,
+ PropertySet::CurrentClient => raw::TEE_PROPSET_CURRENT_CLIENT,
+ PropertySet::CurrentTa => raw::TEE_PROPSET_CURRENT_TA,
+ }
+ }
+}
+
+/// Represents a TEE property value.
+/// The property value can be of different types, such as
+/// string, bool, u32, TEE_UUID, TEE_Identity, etc.
+/// The property value is obtained from the TEE
+/// property set using the TEE_GetPropertyAs* functions.
+pub trait PropertyValue: Sized {
+ fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self>;
+}
+
+/// Implements the PropertyValue trait for all return types:
+/// String, Bool, u32, u64, BinaryBlock, UUID, Identity.
+impl PropertyValue for String {
+ fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
+ let mut out_size = 0;
+
+ // The first call is to get the size of the string
+ // So we pass a null pointer and a size of 0
+ let res = unsafe {
+ raw::TEE_GetPropertyAsString(
+ set,
+ key.as_ptr() as *const core::ffi::c_char,
+ core::ptr::null_mut(),
+ &mut out_size,
+ )
+ };
+ match res {
+ raw::TEE_SUCCESS => {
+ if out_size == 0 {
+ // return an empty string
+ return Ok(String::new());
+ }
+ else {
+ return Err(Error::new(ErrorKind::Generic));
+ }
+ }
+ raw::TEE_ERROR_SHORT_BUFFER => {
+ // Resize the string to the actual size
+ let mut out_buffer = vec![0; out_size as usize];
+ let res = unsafe {
+ raw::TEE_GetPropertyAsString(
+ set,
+ key.as_ptr() as *const core::ffi::c_char,
+ out_buffer.as_mut_ptr() as *mut core::ffi::c_char,
+ &mut out_size,
+ )
+ };
+ if res != raw::TEE_SUCCESS {
+ return Err(Error::from_raw_error(res));
+ }
+
+ // Convert the char buffer with null terminator to a C string
+ let c_str = core::ffi::CStr::from_bytes_with_nul(&out_buffer)
+ .map_err(|_| Error::new(ErrorKind::BadFormat))?;
+ // Convert the C string to a Rust string
+ let result = c_str.to_string_lossy().into_owned();
+
+ Ok(result)
+ }
+ _ => {
+ return Err(Error::from_raw_error(res));
+ }
+ }
+ }
+}
+
+impl PropertyValue for bool {
+ fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
+ let mut b: bool = false;
+
+ let res = unsafe { raw::TEE_GetPropertyAsBool(set, key.as_ptr() as
*const core::ffi::c_char, &mut b) };
+ if res != 0 {
+ return Err(Error::from_raw_error(res));
+ }
+
+ Ok(b)
+ }
+}
+
+impl PropertyValue for u32 {
+ fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
+ let mut value = 0;
+
+ let res = unsafe { raw::TEE_GetPropertyAsU32(set, key.as_ptr() as
*const core::ffi::c_char, &mut value) };
+ if res != 0 {
+ return Err(Error::from_raw_error(res));
+ }
+
+ Ok(value)
+ }
+}
+
+impl PropertyValue for u64 {
+ fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
+ let mut value = 0;
+
+ let res = unsafe { raw::TEE_GetPropertyAsU64(set, key.as_ptr() as
*const core::ffi::c_char, &mut value) };
+ if res != 0 {
+ return Err(Error::from_raw_error(res));
+ }
+
+ Ok(value)
+ }
+}
+
+impl PropertyValue for Vec<u8> {
+ fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
+ let mut out_size = 0;
+
+ // The first call is to get the size of the binary block
+ // So we pass a null pointer and a size of 0
+ let res = unsafe {
+ raw::TEE_GetPropertyAsBinaryBlock(
+ set,
+ key.as_ptr() as *const core::ffi::c_char,
+ core::ptr::null_mut(),
+ &mut out_size,
+ )
+ };
+
+ match res {
+ raw::TEE_SUCCESS => {
+ if out_size == 0 {
+ // return an empty buffer
+ return Ok(vec![]);
+ }
+ else {
+ return Err(Error::new(ErrorKind::Generic));
+ }
+ }
+ raw::TEE_ERROR_SHORT_BUFFER => {
+ let mut buf = vec![0; out_size as usize];
+
+ let res = unsafe {
+ raw::TEE_GetPropertyAsBinaryBlock(
+ set,
+ key.as_ptr() as *const core::ffi::c_char,
+ buf.as_mut_ptr() as *mut core::ffi::c_void,
+ &mut out_size,
+ )
+ };
+ if res != raw::TEE_SUCCESS {
+ return Err(Error::from_raw_error(res));
+ }
+
+ Ok(buf)
+ }
+ _ => {
+ return Err(Error::from_raw_error(res));
+ }
+ }
+ }
+}
+
+impl PropertyValue for Uuid {
+ fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
+ let mut raw_uuid = raw::TEE_UUID {
+ timeLow: 0,
+ timeMid: 0,
+ timeHiAndVersion: 0,
+ clockSeqAndNode: [0; 8],
+ };
+
+ let res =
+ unsafe { raw::TEE_GetPropertyAsUUID(set, key.as_ptr() as *const
core::ffi::c_char, &mut raw_uuid) };
+ if res != 0 {
+ return Err(Error::from_raw_error(res));
+ }
+
+ Ok(Uuid::from(raw_uuid))
+ }
+}
+
+impl PropertyValue for Identity {
+ fn from_raw(set: raw::TEE_PropSetHandle, key: CString) -> Result<Self> {
+ // Allocate a buffer for the raw identity
+ let mut raw_id = raw::TEE_Identity {
+ login: 0,
+ uuid: raw::TEE_UUID {
+ timeLow: 0,
+ timeMid: 0,
+ timeHiAndVersion: 0,
+ clockSeqAndNode: [0; 8],
+ },
+ };
+
+ let res = unsafe {
+ raw::TEE_GetPropertyAsIdentity(set, key.as_ptr() as *const
core::ffi::c_char, &mut raw_id)
+ };
+ if res != 0 {
+ return Err(Error::from_raw_error(res));
+ }
+
+ Ok(Identity::from(raw_id))
+ }
+}
+
+/// Represents a TEE property key.
+/// The property key is used to identify a specific property
+/// within a property set. The property key is a string that
+/// is used to query the property value from the TEE property
+/// set. The property key is defined in the TEE Internal API,
+/// such as "gpd.client.identity" or "gpd.tee.apiversion".
+pub trait PropertyKey {
+ type Output: PropertyValue;
+ fn key(&self) -> CString;
+ fn set(&self) -> PropertySet;
+
+ fn get(&self) -> Result<Self::Output> {
+ Self::Output::from_raw(self.set().as_raw(), self.key())
+ }
+}
+
+/// Macro to define a property key.
+/// This macro generates a struct that implements the
+/// PropertyKey trait.
+macro_rules! define_property_key {
+ (
+ $name:ident,
+ $set:ident,
+ $key:literal,
+ $output:ty
+ ) => {
+ pub struct $name;
+
+ impl PropertyKey for $name {
+ type Output = $output;
+
+ fn key(&self) -> CString {
+ CString::new($key).unwrap_or_default()
+ }
+
+ fn set(&self) -> PropertySet {
+ PropertySet::$set
+ }
+ }
+ };
+}
+
+// Define all existing property keys for the TEE property set.
+// The format is:
+// `define_property_key!(Name, Set, "key", OutputType);`
+// The `Set` is one of the PropertySet it belongs to.
+// The `key` is the raw property key string.
+// The `OutputType` is the type of the property value.
+//
+// To get the property value, use the `get` method.
+// Example usage:
+//
+// ``` no_run
+// use optee_utee::{PropertyKey, TaAppId};
+//
+// let my_property = TaAppId.get()?;
+// ```
+define_property_key!(TaAppId, CurrentTa, "gpd.ta.appID", Uuid);
+define_property_key!(
+ TaSingleInstance,
+ CurrentTa,
+ "gpd.ta.singleInstance",
+ bool
+);
+define_property_key!(
+ TaMultiSession,
+ CurrentTa,
+ "gpd.ta.multiSession",
+ bool
+);
+define_property_key!(
+ TaInstanceKeepAlive,
+ CurrentTa,
+ "gpd.ta.instanceKeepAlive",
+ bool
+);
+define_property_key!(TaDataSize, CurrentTa, "gpd.ta.dataSize", u32);
+define_property_key!(TaStackSize, CurrentTa, "gpd.ta.stackSize", u32);
+define_property_key!(TaVersion, CurrentTa, "gpd.ta.version", String);
+define_property_key!(
+ TaDescription,
+ CurrentTa,
+ "gpd.ta.description",
+ String
+);
+define_property_key!(TaEndian, CurrentTa, "gpd.ta.endian", u32);
+define_property_key!(
+ TaDoesNotCloseHandleOnCorruptObject,
+ CurrentTa,
+ "gpd.ta.doesNotCloseHandleOnCorruptObject",
+ bool
+);
+define_property_key!(
+ ClientIdentity,
+ CurrentClient,
+ "gpd.client.identity",
+ Identity
+);
+define_property_key!(ClientEndian, CurrentClient, "gpd.client.endian", u32);
+define_property_key!(
+ TeeApiVersion,
+ TeeImplementation,
+ "gpd.tee.apiversion",
+ String
+);
+define_property_key!(
+ TeeInternalCoreVersion,
+ TeeImplementation,
+ "gpd.tee.internalCore.version",
+ u32
+);
+define_property_key!(
+ TeeDescription,
+ TeeImplementation,
+ "gpd.tee.description",
+ String
+);
+define_property_key!(
+ TeeDeviceId,
+ TeeImplementation,
+ "gpd.tee.deviceID",
+ Uuid
+);
+define_property_key!(
+ TeeSystemTimeProtectionLevel,
+ TeeImplementation,
+ "gpd.tee.systemTime.protectionLevel",
+ u32
+);
+define_property_key!(
+ TeeTaPersistentTimeProtectionLevel,
+ TeeImplementation,
+ "gpd.tee.TAPersistentTime.protectionLevel",
+ u32
+);
+define_property_key!(
+ TeeArithMaxBigIntSize,
+ TeeImplementation,
+ "gpd.tee.arith.maxBigIntSize",
+ u32
+);
+define_property_key!(
+ TeeCryptographyEcc,
+ TeeImplementation,
+ "gpd.tee.cryptography.ecc",
+ bool
+);
+define_property_key!(
+ TeeCryptographyNist,
+ TeeImplementation,
+ "gpd.tee.cryptography.nist",
+ bool
+);
+define_property_key!(
+ TeeCryptographyBsiR,
+ TeeImplementation,
+ "gpd.tee.cryptography.bsi-r",
+ bool
+);
+define_property_key!(
+ TeeCryptographyBsiT,
+ TeeImplementation,
+ "gpd.tee.cryptography.bsi-t",
+ bool
+);
+define_property_key!(
+ TeeCryptographyIetf,
+ TeeImplementation,
+ "gpd.tee.cryptography.ietf",
+ bool
+);
+define_property_key!(
+ TeeCryptographyOcta,
+ TeeImplementation,
+ "gpd.tee.cryptography.octa",
+ bool
+);
+define_property_key!(
+ TeeTrustedStoragePrivateRollbackProtection,
+ TeeImplementation,
+ "gpd.tee.trustedStorage.private.rollbackProtection",
+ u32
+);
+define_property_key!(
+ TeeTrustedStoragePersoRollbackProtection,
+ TeeImplementation,
+ "gpd.tee.trustedStorage.perso.rollbackProtection",
+ u32
+);
+define_property_key!(
+ TeeTrustedStorageProtectedRollbackProtection,
+ TeeImplementation,
+ "gpd.tee.trustedStorage.protected.rollbackProtection",
+ u32
+);
+define_property_key!(
+ TeeTrustedStorageAntiRollbackProtectionLevel,
+ TeeImplementation,
+ "gpd.tee.trustedStorage.antiRollback.protectionLevel",
+ u32
+);
+define_property_key!(
+ TeeTrustedStorageRollbackDetectionProtectionLevel,
+ TeeImplementation,
+ "gpd.tee.trustedStorage.rollbackDetection.protectionLevel",
+ u32
+);
+define_property_key!(
+ TeeTrustedOsImplementationVersion,
+ TeeImplementation,
+ "gpd.tee.trustedos.implementation.version",
+ String
+);
+define_property_key!(
+ TeeTrustedOsImplementationBinaryVersion,
+ TeeImplementation,
+ "gpd.tee.trustedos.implementation.binaryversion",
+ Vec<u8>
+);
+define_property_key!(
+ TeeTrustedOsManufacturer,
+ TeeImplementation,
+ "gpd.tee.trustedos.manufacturer",
+ String
+);
+define_property_key!(
+ TeeFirmwareImplementationVersion,
+ TeeImplementation,
+ "gpd.tee.firmware.implementation.version",
+ String
+);
+define_property_key!(
+ TeeFirmwareImplementationBinaryVersion,
+ TeeImplementation,
+ "gpd.tee.firmware.implementation.binaryversion",
+ Vec<u8>
+);
+define_property_key!(
+ TeeFirmwareManufacturer,
+ TeeImplementation,
+ "gpd.tee.firmware.manufacturer",
+ String
+);
+define_property_key!(
+ TeeEventMaxSources,
+ TeeImplementation,
+ "gpd.tee.event.maxSources",
+ u32
+);
diff --git a/optee-utee/src/uuid.rs b/optee-utee/src/uuid.rs
index 4017943..99c4930 100644
--- a/optee-utee/src/uuid.rs
+++ b/optee-utee/src/uuid.rs
@@ -79,7 +79,7 @@ impl Uuid {
))
}
- /// Crates a raw TEE client uuid object with specified parameters.
+ /// Creates a raw TEE client uuid object with specified parameters.
pub fn new_raw(
time_low: u32,
time_mid: u16,
@@ -115,6 +115,12 @@ impl fmt::Display for Uuid {
}
}
+impl From<raw::TEE_UUID> for Uuid {
+ fn from(raw: raw::TEE_UUID) -> Self {
+ Uuid { raw }
+ }
+}
+
#[cfg(test)]
mod tests {
extern crate alloc;
diff --git a/ci/ci.sh b/tests/test_property.sh
similarity index 50%
copy from ci/ci.sh
copy to tests/test_property.sh
index 2b1501d..588c903 100755
--- a/ci/ci.sh
+++ b/tests/test_property.sh
@@ -19,41 +19,23 @@
set -xe
-pushd ../tests
+# Include base script
+source setup.sh
-# Prioritize running specialized test suites first, as they have a higher
-# probability of detecting failures early in the pipeline.
-# Run std only tests
-if [ "$STD" ]; then
- ./test_serde.sh
- ./test_message_passing_interface.sh
- ./test_tls_client.sh
- ./test_tls_server.sh
- ./test_eth_wallet.sh
- ./test_secure_db_abstraction.sh
-else
- ./test_mnist_rs.sh
- ./test_build_with_optee_utee_sys.sh
-fi
+# Copy TA and host binary
+cp ../examples/property-rs/host/target/$TARGET_HOST/release/property-rs shared
+cp ../examples/property-rs/ta/target/$TARGET_TA/release/*.ta shared
-./test_hello_world.sh
-./test_random.sh
-./test_secure_storage.sh
-./test_aes.sh
-./test_hotp.sh
-./test_acipher.sh
-./test_big_int.sh
-./test_diffie_hellman.sh
-./test_digest.sh
-./test_authentication.sh
-./test_time.sh
-./test_signature_verification.sh
-./test_supp_plugin.sh
-./test_error_handling.sh
-./test_tcp_client.sh
-./test_udp_socket.sh
-./test_client_pool.sh
-./test_inter_ta.sh
+# Run script specific commands in QEMU
+run_in_qemu "cp *.ta /lib/optee_armtz/\n"
+run_in_qemu "./property-rs\n"
+run_in_qemu "^C"
-
-popd
+# Script specific checks
+{
+ grep -q "Success" screenlog.0
+} || {
+ cat -v screenlog.0
+ cat -v /tmp/serial.log
+ false
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]