From 218efa91388868cb850791967b3395546d966da1 Mon Sep 17 00:00:00 2001 From: JeffMboya Date: Thu, 19 Mar 2026 13:49:03 +0300 Subject: [PATCH 1/5] feat(examples): add platform-test and attestation-test wasm examples Signed-off-by: JeffMboya --- Makefile | 8 ++ embed-proplet/modules/wamr/wasm-micro-runtime | 2 +- examples/attestation-test/Cargo.lock | 7 ++ examples/attestation-test/Cargo.toml | 8 ++ examples/attestation-test/src/main.rs | 53 +++++++++++++ examples/platform-test/Cargo.lock | 7 ++ examples/platform-test/Cargo.toml | 8 ++ examples/platform-test/src/main.rs | 77 +++++++++++++++++++ 8 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 examples/attestation-test/Cargo.lock create mode 100644 examples/attestation-test/Cargo.toml create mode 100644 examples/attestation-test/src/main.rs create mode 100644 examples/platform-test/Cargo.lock create mode 100644 examples/platform-test/Cargo.toml create mode 100644 examples/platform-test/src/main.rs diff --git a/Makefile b/Makefile index 01d28074..4c1b07b9 100644 --- a/Makefile +++ b/Makefile @@ -198,6 +198,14 @@ hal-test: cd examples/hal-test && cargo build --release cp examples/hal-test/target/wasm32-wasip1/release/hal-test.wasm build/hal-test.wasm +platform-test: + cd examples/platform-test && cargo build --release + cp examples/platform-test/target/wasm32-wasip1/release/platform-test.wasm build/platform-test.wasm + +attestation-test: + cd examples/attestation-test && cargo build --release + cp examples/attestation-test/target/wasm32-wasip1/release/attestation-test.wasm build/attestation-test.wasm + help: @echo "Usage: make " @echo "" diff --git a/embed-proplet/modules/wamr/wasm-micro-runtime b/embed-proplet/modules/wamr/wasm-micro-runtime index 46472ee6..dcf137e9 160000 --- a/embed-proplet/modules/wamr/wasm-micro-runtime +++ b/embed-proplet/modules/wamr/wasm-micro-runtime @@ -1 +1 @@ -Subproject commit 46472ee6c849382f4cb54db75b40bd9492bb6e9b +Subproject commit dcf137e961e7d84ed1fdff90bcc40ccadfc01090 diff --git a/examples/attestation-test/Cargo.lock b/examples/attestation-test/Cargo.lock new file mode 100644 index 00000000..989be15c --- /dev/null +++ b/examples/attestation-test/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "attestation-test" +version = "0.1.0" diff --git a/examples/attestation-test/Cargo.toml b/examples/attestation-test/Cargo.toml new file mode 100644 index 00000000..8b0151b8 --- /dev/null +++ b/examples/attestation-test/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "attestation-test" +version = "0.1.0" +edition = "2021" + +[[bin]] +name = "attestation-test" +path = "src/main.rs" diff --git a/examples/attestation-test/src/main.rs b/examples/attestation-test/src/main.rs new file mode 100644 index 00000000..70fadbc8 --- /dev/null +++ b/examples/attestation-test/src/main.rs @@ -0,0 +1,53 @@ +#[link(wasm_import_module = "elastic:attestation/hal")] +unsafe extern "C" { + #[link_name = "get-attestation"] + fn get_attestation( + nonce_ptr: i32, + nonce_len: i32, + out_ptr: i32, + out_len_ptr: i32, + ) -> i32; +} + +const BUF: usize = 4096; + +fn hex(bytes: &[u8]) -> String { + bytes.iter().map(|b| format!("{b:02x}")).collect() +} + +fn run() -> i32 { + let nonce: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; + let mut buf = [0u8; BUF]; + let mut len: u32 = 0; + let rc = unsafe { + get_attestation( + nonce.as_ptr() as i32, + nonce.len() as i32, + buf.as_mut_ptr() as i32, + &mut len as *mut u32 as i32, + ) + }; + if rc < 0 { + eprintln!( + "get-attestation: FAILED (rc={}) msg={}", + rc, + String::from_utf8_lossy(&buf[..len as usize]) + ); + return 1; + } + println!("get-attestation: ok (report len={})", len); + println!("get-attestation report: {}", hex(&buf[..len as usize])); + 0 +} + +#[no_mangle] +pub extern "C" fn run_export() -> i32 { + run() +} + +fn main() { + let result = run(); + if result != 0 { + eprintln!("attestation-test failed with exit code: {}", result); + } +} diff --git a/examples/platform-test/Cargo.lock b/examples/platform-test/Cargo.lock new file mode 100644 index 00000000..923b5d1d --- /dev/null +++ b/examples/platform-test/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "platform-test" +version = "0.1.0" diff --git a/examples/platform-test/Cargo.toml b/examples/platform-test/Cargo.toml new file mode 100644 index 00000000..a982071d --- /dev/null +++ b/examples/platform-test/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "platform-test" +version = "0.1.0" +edition = "2021" + +[[bin]] +name = "platform-test" +path = "src/main.rs" diff --git a/examples/platform-test/src/main.rs b/examples/platform-test/src/main.rs new file mode 100644 index 00000000..b1a0a1eb --- /dev/null +++ b/examples/platform-test/src/main.rs @@ -0,0 +1,77 @@ +#[link(wasm_import_module = "elastic:platform/platform")] +unsafe extern "C" { + #[link_name = "get-platform-info"] + fn get_platform_info(out_ptr: i32, out_len_ptr: i32) -> i32; + + fn attestation( + report_data_ptr: i32, + report_data_len: i32, + out_ptr: i32, + out_len_ptr: i32, + ) -> i32; +} + +const BUF: usize = 4096; + +fn hex(bytes: &[u8]) -> String { + bytes.iter().map(|b| format!("{b:02x}")).collect() +} + +fn run() -> i32 { + let mut ok = true; + + { + let mut buf = [0u8; BUF]; + let mut len: u32 = 0; + let rc = + unsafe { get_platform_info(buf.as_mut_ptr() as i32, &mut len as *mut u32 as i32) }; + if rc < 0 { + eprintln!("get-platform-info: FAILED (rc={})", rc); + ok = false; + } else { + println!( + "get-platform-info: {}", + String::from_utf8_lossy(&buf[..len as usize]) + ); + } + } + + { + let report_data = [0x42u8; 32]; + let mut buf = [0u8; BUF]; + let mut len: u32 = 0; + let rc = unsafe { + attestation( + report_data.as_ptr() as i32, + report_data.len() as i32, + buf.as_mut_ptr() as i32, + &mut len as *mut u32 as i32, + ) + }; + if rc < 0 { + eprintln!( + "attestation: FAILED (rc={}) msg={}", + rc, + String::from_utf8_lossy(&buf[..len as usize]) + ); + ok = false; + } else { + println!("attestation: ok (evidence len={})", len); + println!("attestation evidence: {}", hex(&buf[..len as usize])); + } + } + + if ok { 0 } else { 1 } +} + +#[no_mangle] +pub extern "C" fn run_export() -> i32 { + run() +} + +fn main() { + let result = run(); + if result != 0 { + eprintln!("platform-test failed with exit code: {}", result); + } +} From d2bd0b3c432073d4f30b319dd60ddd5cc5f75760 Mon Sep 17 00:00:00 2001 From: JeffMboya Date: Thu, 19 Mar 2026 17:05:31 +0300 Subject: [PATCH 2/5] fix(examples): align wasm examples with elastic:tee-hal/platform interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix incorrect WIT import namespaces in platform-test and attestation-test: - attestation-test: elastic:attestation/hal -> elastic:tee-hal/platform, get-attestation -> attestation - platform-test: elastic:platform/platform -> elastic:tee-hal/platform, get-platform-info -> platform-info Add wasm-hal-runner binary to proplet for standalone testing of wasip1 WASM files with HAL host imports, and expose hal_linker as a public module in lib.rs. Verified against real Intel TDX hardware — both examples produce valid attestation evidence with platform_type: IntelTdx. --- examples/attestation-test/src/main.rs | 4 +- examples/platform-test/src/main.rs | 4 +- proplet/src/bin/wasm-hal-runner.rs | 53 +++++++++++++++++++++++++++ proplet/src/lib.rs | 1 + 4 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 proplet/src/bin/wasm-hal-runner.rs create mode 100644 proplet/src/lib.rs diff --git a/examples/attestation-test/src/main.rs b/examples/attestation-test/src/main.rs index 70fadbc8..d4ebbf04 100644 --- a/examples/attestation-test/src/main.rs +++ b/examples/attestation-test/src/main.rs @@ -1,6 +1,6 @@ -#[link(wasm_import_module = "elastic:attestation/hal")] +#[link(wasm_import_module = "elastic:tee-hal/platform")] unsafe extern "C" { - #[link_name = "get-attestation"] + #[link_name = "attestation"] fn get_attestation( nonce_ptr: i32, nonce_len: i32, diff --git a/examples/platform-test/src/main.rs b/examples/platform-test/src/main.rs index b1a0a1eb..7403ea0a 100644 --- a/examples/platform-test/src/main.rs +++ b/examples/platform-test/src/main.rs @@ -1,6 +1,6 @@ -#[link(wasm_import_module = "elastic:platform/platform")] +#[link(wasm_import_module = "elastic:tee-hal/platform")] unsafe extern "C" { - #[link_name = "get-platform-info"] + #[link_name = "platform-info"] fn get_platform_info(out_ptr: i32, out_len_ptr: i32) -> i32; fn attestation( diff --git a/proplet/src/bin/wasm-hal-runner.rs b/proplet/src/bin/wasm-hal-runner.rs new file mode 100644 index 00000000..e13d6651 --- /dev/null +++ b/proplet/src/bin/wasm-hal-runner.rs @@ -0,0 +1,53 @@ +/// Standalone CLI runner: executes a wasip1 WASM file with the ELASTIC TEE HAL host imports. +/// Usage: wasm-hal-runner +use anyhow::{Context, Result}; +use elastic_tee_hal::interfaces::HalProvider; +use std::sync::Arc; +use wasmtime::*; +use wasmtime_wasi::p1::WasiP1Ctx; + +fn main() -> Result<()> { + let wasm_path = std::env::args() + .nth(1) + .ok_or_else(|| anyhow::anyhow!("usage: wasm-hal-runner "))?; + + let wasm_bytes = + std::fs::read(&wasm_path).with_context(|| format!("failed to read {wasm_path}"))?; + + let mut cfg = Config::new(); + cfg.wasm_reference_types(true); + cfg.wasm_bulk_memory(true); + cfg.wasm_simd(true); + + let engine = Engine::new(&cfg)?; + let module = Module::from_binary(&engine, &wasm_bytes) + .map_err(|e| anyhow::anyhow!("failed to compile WASM module: {e}"))?; + + let mut wasi_builder = wasmtime_wasi::WasiCtxBuilder::new(); + wasi_builder.inherit_stdio(); + wasi_builder.arg(&wasm_path); + let wasi: WasiP1Ctx = wasi_builder.build_p1(); + + let mut store = Store::new(&engine, wasi); + + let mut linker: Linker = Linker::new(&engine); + wasmtime_wasi::p1::add_to_linker_sync(&mut linker, |ctx| ctx) + .map_err(|e| anyhow::anyhow!("failed to add WASI to linker: {e}"))?; + + let provider = Arc::new(HalProvider::with_defaults()); + proplet::hal_linker::add_to_linker(&mut linker, provider) + .context("failed to add HAL to linker")?; + + let instance = linker + .instantiate(&mut store, &module) + .map_err(|e| anyhow::anyhow!("failed to instantiate module: {e}"))?; + + let func = instance + .get_typed_func::<(), ()>(&mut store, "_start") + .map_err(|e| anyhow::anyhow!("module has no _start export: {e}"))?; + + func.call(&mut store, ()) + .map_err(|e| anyhow::anyhow!("WASM execution failed: {e}"))?; + + Ok(()) +} diff --git a/proplet/src/lib.rs b/proplet/src/lib.rs new file mode 100644 index 00000000..1044b0fa --- /dev/null +++ b/proplet/src/lib.rs @@ -0,0 +1 @@ +pub mod hal_linker; From 2d4641a0173522284e7706d32591fef5da8d7909 Mon Sep 17 00:00:00 2001 From: JeffMboya Date: Thu, 19 Mar 2026 17:06:59 +0300 Subject: [PATCH 3/5] fix(proplet): remove doc comments from wasm-hal-runner --- proplet/src/bin/wasm-hal-runner.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/proplet/src/bin/wasm-hal-runner.rs b/proplet/src/bin/wasm-hal-runner.rs index e13d6651..abdab2db 100644 --- a/proplet/src/bin/wasm-hal-runner.rs +++ b/proplet/src/bin/wasm-hal-runner.rs @@ -1,5 +1,3 @@ -/// Standalone CLI runner: executes a wasip1 WASM file with the ELASTIC TEE HAL host imports. -/// Usage: wasm-hal-runner use anyhow::{Context, Result}; use elastic_tee_hal::interfaces::HalProvider; use std::sync::Arc; From 66e3380befb3e464bb03e97e5917f23ffe6486b9 Mon Sep 17 00:00:00 2001 From: JeffMboya Date: Thu, 19 Mar 2026 19:03:09 +0300 Subject: [PATCH 4/5] remove wasm-hal-runner: test via full MQTT/task pipeline instead --- proplet/src/bin/wasm-hal-runner.rs | 51 ------------------------------ proplet/src/lib.rs | 1 - 2 files changed, 52 deletions(-) delete mode 100644 proplet/src/bin/wasm-hal-runner.rs delete mode 100644 proplet/src/lib.rs diff --git a/proplet/src/bin/wasm-hal-runner.rs b/proplet/src/bin/wasm-hal-runner.rs deleted file mode 100644 index abdab2db..00000000 --- a/proplet/src/bin/wasm-hal-runner.rs +++ /dev/null @@ -1,51 +0,0 @@ -use anyhow::{Context, Result}; -use elastic_tee_hal::interfaces::HalProvider; -use std::sync::Arc; -use wasmtime::*; -use wasmtime_wasi::p1::WasiP1Ctx; - -fn main() -> Result<()> { - let wasm_path = std::env::args() - .nth(1) - .ok_or_else(|| anyhow::anyhow!("usage: wasm-hal-runner "))?; - - let wasm_bytes = - std::fs::read(&wasm_path).with_context(|| format!("failed to read {wasm_path}"))?; - - let mut cfg = Config::new(); - cfg.wasm_reference_types(true); - cfg.wasm_bulk_memory(true); - cfg.wasm_simd(true); - - let engine = Engine::new(&cfg)?; - let module = Module::from_binary(&engine, &wasm_bytes) - .map_err(|e| anyhow::anyhow!("failed to compile WASM module: {e}"))?; - - let mut wasi_builder = wasmtime_wasi::WasiCtxBuilder::new(); - wasi_builder.inherit_stdio(); - wasi_builder.arg(&wasm_path); - let wasi: WasiP1Ctx = wasi_builder.build_p1(); - - let mut store = Store::new(&engine, wasi); - - let mut linker: Linker = Linker::new(&engine); - wasmtime_wasi::p1::add_to_linker_sync(&mut linker, |ctx| ctx) - .map_err(|e| anyhow::anyhow!("failed to add WASI to linker: {e}"))?; - - let provider = Arc::new(HalProvider::with_defaults()); - proplet::hal_linker::add_to_linker(&mut linker, provider) - .context("failed to add HAL to linker")?; - - let instance = linker - .instantiate(&mut store, &module) - .map_err(|e| anyhow::anyhow!("failed to instantiate module: {e}"))?; - - let func = instance - .get_typed_func::<(), ()>(&mut store, "_start") - .map_err(|e| anyhow::anyhow!("module has no _start export: {e}"))?; - - func.call(&mut store, ()) - .map_err(|e| anyhow::anyhow!("WASM execution failed: {e}"))?; - - Ok(()) -} diff --git a/proplet/src/lib.rs b/proplet/src/lib.rs deleted file mode 100644 index 1044b0fa..00000000 --- a/proplet/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod hal_linker; From 5d7cb92f4b0c3d6588cc96153f9e840f842f6df9 Mon Sep 17 00:00:00 2001 From: JeffMboya Date: Fri, 20 Mar 2026 20:05:38 +0300 Subject: [PATCH 5/5] revert(attestation-test): use elastic:attestation/hal interface from wasmhal PR#4 --- examples/attestation-test/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/attestation-test/src/main.rs b/examples/attestation-test/src/main.rs index d4ebbf04..70fadbc8 100644 --- a/examples/attestation-test/src/main.rs +++ b/examples/attestation-test/src/main.rs @@ -1,6 +1,6 @@ -#[link(wasm_import_module = "elastic:tee-hal/platform")] +#[link(wasm_import_module = "elastic:attestation/hal")] unsafe extern "C" { - #[link_name = "attestation"] + #[link_name = "get-attestation"] fn get_attestation( nonce_ptr: i32, nonce_len: i32,