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

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

commit ac16b830ab65b38de5b66af697ccd73954a9da09
Author: ivila <[email protected]>
AuthorDate: Wed Jun 24 15:26:55 2026 +0800

    examples, projects: migrate to typed parameter API
    
    Update all TA examples and dependent host applications to use the new
    typed parameter API:
    
    - Replace `&mut Parameters` with `ParametersAny<'_>` or `ParametersNone`
    - Use `ParameterAny::as_value_input()` / `as_memref_output()` helper methods
      instead of unsafe `as_value()` / `as_memref()` + raw buffer access
    - Consolidate imports via `use optee_utee::prelude::*`
---
 crates/optee-utee/src/crypto_op.rs                 |   8 +-
 crates/optee-utee/src/error.rs                     |   4 +-
 crates/optee-utee/src/object/object_handle.rs      |   1 -
 examples/acipher-rs/ta/src/main.rs                 |  85 ++++------
 examples/aes-rs/ta/src/main.rs                     |  51 +++---
 examples/authentication-rs/ta/src/main.rs          | 106 +++++--------
 examples/big_int-rs/ta/src/main.rs                 |  18 +--
 .../build_with_optee_utee_sys-rs/ta/src/main.rs    |  12 +-
 examples/client_pool-rs/ta/src/main.rs             |  24 +--
 examples/diffie_hellman-rs/ta/src/main.rs          |  86 +++++-----
 examples/digest-rs/ta/src/main.rs                  |  44 +++---
 examples/error_handling-rs/ta/src/main.rs          |  14 +-
 examples/hello_world-rs/ta/src/main.rs             |  24 +--
 examples/hotp-rs/ta/src/main.rs                    |  28 ++--
 examples/inter_ta-rs/ta/src/main.rs                |  11 +-
 .../message_passing_interface-rs/ta/Cargo.lock     | 176 +++++----------------
 .../message_passing_interface-rs/ta/src/main.rs    |  35 ++--
 examples/mnist-rs/ta/common/src/lib.rs             |   2 -
 examples/mnist-rs/ta/common/src/utils.rs           |  35 ----
 examples/mnist-rs/ta/inference/src/main.rs         |  45 ++++--
 examples/mnist-rs/ta/train/src/main.rs             |  43 +++--
 examples/property-rs/ta/src/main.rs                |  11 +-
 examples/random-rs/ta/src/main.rs                  |  22 ++-
 examples/secure_db_abstraction-rs/ta/Cargo.lock    |   1 +
 examples/secure_db_abstraction-rs/ta/src/main.rs   |  11 +-
 examples/secure_storage-rs/ta/src/main.rs          |  90 ++++-------
 examples/serde-rs/ta/Cargo.lock                    | 162 +++++--------------
 examples/serde-rs/ta/src/main.rs                   |  32 +---
 examples/signature_verification-rs/ta/src/main.rs  |  87 ++++------
 examples/supp_plugin-rs/ta/src/main.rs             |  21 +--
 examples/tcp_client-rs/ta/src/main.rs              |  24 ++-
 examples/time-rs/ta/src/main.rs                    |  10 +-
 examples/tls_client-rs/ta/Cargo.lock               |   1 +
 examples/tls_client-rs/ta/src/main.rs              |  11 +-
 examples/tls_server-rs/host/src/main.rs            |   5 +-
 examples/tls_server-rs/ta/Cargo.lock               |   1 +
 examples/tls_server-rs/ta/src/main.rs              |  36 ++---
 examples/udp_socket-rs/ta/src/main.rs              |  20 ++-
 projects/web3/eth_wallet/host/src/main.rs          |  17 +-
 projects/web3/eth_wallet/ta/Cargo.lock             |   1 +
 projects/web3/eth_wallet/ta/src/main.rs            |  38 ++---
 41 files changed, 539 insertions(+), 914 deletions(-)

diff --git a/crates/optee-utee/src/crypto_op.rs 
b/crates/optee-utee/src/crypto_op.rs
index 7784196..0499926 100644
--- a/crates/optee-utee/src/crypto_op.rs
+++ b/crates/optee-utee/src/crypto_op.rs
@@ -1283,7 +1283,7 @@ impl Asymmetric {
     ///             AlgorithmId::RsaesPkcs1V15,
     ///             OperationMode::Encrypt,
     ///             256) {
-    ///             Ok(operation) => {
+    ///             Ok(mut operation) => {
     ///                 operation.set_key(&key)?;
     ///                 match operation.encrypt(&[], &clear) {
     ///                     Ok(ciph_text) => {
@@ -1497,7 +1497,7 @@ impl Asymmetric {
     }
 
     /// Function usage is similar to [Cipher::set_key](Cipher::set_key).
-    pub fn set_key<T: GenericObject>(&self, object: &T) -> Result<()> {
+    pub fn set_key<T: GenericObject>(&mut self, object: &T) -> Result<()> {
         self.0.set_key(object)
     }
 
@@ -1556,7 +1556,7 @@ impl DeriveKey {
     ///     Ok(key_pair_2) => {
     ///         key_pair_2.generate_key(256, &[attr_prime.into(), 
attr_base.into()])?;
     ///         match DeriveKey::allocate(AlgorithmId::DhDeriveSharedSecret, 
256) {
-    ///             Ok(operation) => {
+    ///             Ok(mut operation) => {
     ///                 operation.set_key(&key_pair_2)?;
     ///                 match 
TransientObject::allocate(TransientObjectType::GenericSecret, 256) {
     ///                     // Derived key is saved as an transient object
@@ -1622,7 +1622,7 @@ impl DeriveKey {
     }
 
     /// Function usage is similar to [Cipher::set_key](Cipher::set_key).
-    pub fn set_key<T: GenericObject>(&self, object: &T) -> Result<()> {
+    pub fn set_key<T: GenericObject>(&mut self, object: &T) -> Result<()> {
         self.0.set_key(object)
     }
 
diff --git a/crates/optee-utee/src/error.rs b/crates/optee-utee/src/error.rs
index f66ed47..a936fb0 100644
--- a/crates/optee-utee/src/error.rs
+++ b/crates/optee-utee/src/error.rs
@@ -28,9 +28,9 @@ use std::error;
 /// # Examples
 ///
 /// ``` rust,no_run
-/// # use optee_utee::Parameters;
+/// # use optee_utee::prelude::*;
 /// use optee_utee::Result;
-/// fn open_session(params: &mut Parameters) -> Result<()> {
+/// fn open_session(params: &mut ParametersAny) -> Result<()> {
 ///     Ok(())
 /// }
 /// ````
diff --git a/crates/optee-utee/src/object/object_handle.rs 
b/crates/optee-utee/src/object/object_handle.rs
index f2d54a9..fd8f8d0 100644
--- a/crates/optee-utee/src/object/object_handle.rs
+++ b/crates/optee-utee/src/object/object_handle.rs
@@ -38,7 +38,6 @@ impl ObjectHandle {
     /// ``` rust,no_run
     /// # use optee_utee::ObjectHandle;
     /// # use optee_utee_sys as raw;
-    /// # let external_handle: raw::TEE_ObjectHandle = core::ptr::null_mut();
     /// # fn main() -> optee_utee::Result<()> {
     /// # let external_handle = core::ptr::null_mut();
     /// // `external_handle` is a handle that is constructed and controlled
diff --git a/examples/acipher-rs/ta/src/main.rs 
b/examples/acipher-rs/ta/src/main.rs
index f2537e3..610407b 100644
--- a/examples/acipher-rs/ta/src/main.rs
+++ b/examples/acipher-rs/ta/src/main.rs
@@ -20,12 +20,9 @@
 
 extern crate alloc;
 
-use alloc::boxed::Box;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
+use optee_utee::prelude::*;
 use optee_utee::{AlgorithmId, Asymmetric, OperationMode};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::{ErrorKind, Result};
 use optee_utee::{GenericObject, TransientObject, TransientObjectType};
 use proto::Command;
 
@@ -48,7 +45,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters, _sess_ctx: &mut RsaCipher) -> 
Result<()> {
+fn open_session(_params: &mut ParametersNone, _sess_ctx: &mut RsaCipher) -> 
Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -63,79 +60,53 @@ fn destroy() {
     trace_println!("[+] TA destroy");
 }
 
-fn gen_key(rsa: &mut RsaCipher, params: &mut Parameters) -> Result<()> {
-    let key_size = unsafe { params.0.as_value()?.a() };
+fn gen_key(rsa: &mut RsaCipher, (p0, _, _, _): &mut ParametersAny<'_>) -> 
Result<()> {
+    let key_size = p0.as_value_input()?.get_a();
     rsa.key = TransientObject::allocate(TransientObjectType::RsaKeypair, 
key_size as usize)?;
     rsa.key.generate_key(key_size as usize, &[])?;
     Ok(())
 }
 
-fn get_size(rsa: &mut RsaCipher, params: &mut Parameters) -> Result<()> {
+fn get_size(rsa: &mut RsaCipher, (p0, _, _, _): &mut ParametersAny<'_>) -> 
Result<()> {
     let key_info = rsa.key.info()?;
-    unsafe {
-        params
-            .0
-            .as_value()?
-            .set_a((key_info.object_size() / 8) as u32)
-    };
+    p0.as_value_output()?
+        .set_a((key_info.object_size() / 8) as u32);
     Ok(())
 }
 
-fn encrypt(rsa: &mut RsaCipher, params: &mut Parameters) -> Result<()> {
+fn encrypt(rsa: &mut RsaCipher, (p0, p1, _, _): &mut ParametersAny<'_>) -> 
Result<()> {
     let key_info = rsa.key.info()?;
-    let mut p0 = unsafe { params.0.as_memref()? };
-    let plain_text = p0.buffer();
-    let mut p1 = unsafe { params.1.as_memref()? };
-    match Asymmetric::allocate(
+    let (p0, p1) = (p0.as_memref_input()?, p1.as_memref_output()?);
+    let mut cipher = Asymmetric::allocate(
         AlgorithmId::RsaesPkcs1V15,
         OperationMode::Encrypt,
         key_info.object_size(),
-    ) {
-        Err(e) => Err(e),
-        Ok(cipher) => {
-            cipher.set_key(&rsa.key)?;
-            match cipher.encrypt(&[], plain_text) {
-                Err(e) => Err(e),
-                Ok(cipher_text) => {
-                    if cipher_text.len() > p1.buffer().len() {
-                        p1.set_updated_size(cipher_text.len());
-                        Err(ErrorKind::ShortBuffer.into())
-                    } else {
-                        p1.buffer().clone_from_slice(&cipher_text);
-                        Ok(())
-                    }
-                }
-            }
-        }
-    }
+    )?;
+    cipher.set_key(&rsa.key)?;
+    let cipher_text = cipher.encrypt(&[], p0.get_buffer())?;
+    p1.set_output(cipher_text)?;
+    Ok(())
 }
 
-fn decrypt(rsa: &mut RsaCipher, params: &mut Parameters) -> Result<()> {
+fn decrypt(rsa: &mut RsaCipher, (p0, p1, _, _): &mut ParametersAny<'_>) -> 
Result<()> {
     let key_info = rsa.key.info()?;
-    let mut p0 = unsafe { params.0.as_memref()? };
-    let cipher_text = p0.buffer();
-    let mut p1 = unsafe { params.1.as_memref()? };
-    match Asymmetric::allocate(
+    let (p0, p1) = (p0.as_memref_input()?, p1.as_memref_output()?);
+    let mut cipher = Asymmetric::allocate(
         AlgorithmId::RsaesPkcs1V15,
         OperationMode::Decrypt,
         key_info.object_size(),
-    ) {
-        Err(e) => Err(e),
-        Ok(cipher) => {
-            cipher.set_key(&rsa.key)?;
-            match cipher.decrypt(&[], cipher_text) {
-                Err(e) => Err(e),
-                Ok(plain_text) => {
-                    p1.buffer().clone_from_slice(&plain_text);
-                    Ok(())
-                }
-            }
-        }
-    }
+    )?;
+    cipher.set_key(&rsa.key)?;
+    let plain_text = cipher.decrypt(&[], p0.get_buffer())?;
+    p1.set_output(plain_text)
 }
 
 #[ta_invoke_command]
-fn invoke_command(sess_ctx: &mut RsaCipher, cmd_id: u32, params: &mut 
Parameters) -> Result<()> {
+fn invoke_command(
+    sess_ctx: &mut RsaCipher,
+    cmd_id: u32,
+    params: &mut ParametersAny<'_>,
+) -> Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
         Command::GenKey => gen_key(sess_ctx, params),
diff --git a/examples/aes-rs/ta/src/main.rs b/examples/aes-rs/ta/src/main.rs
index 41cbd94..0e5d3be 100644
--- a/examples/aes-rs/ta/src/main.rs
+++ b/examples/aes-rs/ta/src/main.rs
@@ -20,15 +20,12 @@
 
 extern crate alloc;
 
-use alloc::boxed::Box;
 use alloc::vec;
 use optee_utee::is_algorithm_supported;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
+use optee_utee::prelude::*;
 use optee_utee::{AlgorithmId, Cipher, ElementId, OperationMode};
 use optee_utee::{AttributeId, AttributeMemref, TransientObject, 
TransientObjectType};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::{ErrorKind, Result};
 use proto::{Algo, Command, KeySize, Mode};
 
 pub struct AesCipher {
@@ -54,7 +51,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters, _sess_ctx: &mut AesCipher) -> 
Result<()> {
+fn open_session(_params: &mut ParametersNone, _sess_ctx: &mut AesCipher) -> 
Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -70,7 +67,11 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(sess_ctx: &mut AesCipher, cmd_id: u32, params: &mut 
Parameters) -> Result<()> {
+fn invoke_command(
+    sess_ctx: &mut AesCipher,
+    cmd_id: u32,
+    params: &mut ParametersAny<'_>,
+) -> Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
         Command::Prepare => alloc_resources(sess_ctx, params),
@@ -105,10 +106,12 @@ pub fn ta2tee_mode_id(mode: u32) -> Result<OperationMode> 
{
     }
 }
 
-pub fn alloc_resources(aes: &mut AesCipher, params: &mut Parameters) -> 
Result<()> {
-    let algo_value = unsafe { params.0.as_value()?.a() };
-    let key_size_value = unsafe { params.1.as_value()?.a() };
-    let mode_id_value = unsafe { params.2.as_value()?.a() };
+pub fn alloc_resources(aes: &mut AesCipher, (p0, p1, p2, _): &mut 
ParametersAny<'_>) -> Result<()> {
+    let (algo_value, key_size_value, mode_id_value) = (
+        p0.as_value_input()?.get_a(),
+        p1.as_value_input()?.get_a(),
+        p2.as_value_input()?.get_a(),
+    );
 
     aes.key_size = ta2tee_key_size(key_size_value)?;
 
@@ -131,9 +134,8 @@ pub fn alloc_resources(aes: &mut AesCipher, params: &mut 
Parameters) -> Result<(
     Ok(())
 }
 
-pub fn set_aes_key(aes: &mut AesCipher, params: &mut Parameters) -> Result<()> 
{
-    let mut param0 = unsafe { params.0.as_memref()? };
-    let key = param0.buffer();
+pub fn set_aes_key(aes: &mut AesCipher, (p0, _, _, _): &mut ParametersAny<'_>) 
-> Result<()> {
+    let key = p0.as_memref_input()?.get_buffer();
 
     if key.len() != aes.key_size {
         trace_println!("[+] Get wrong key size !\n");
@@ -149,9 +151,8 @@ pub fn set_aes_key(aes: &mut AesCipher, params: &mut 
Parameters) -> Result<()> {
     Ok(())
 }
 
-pub fn reset_aes_iv(aes: &mut AesCipher, params: &mut Parameters) -> 
Result<()> {
-    let mut param0 = unsafe { params.0.as_memref()? };
-    let iv = param0.buffer();
+pub fn reset_aes_iv(aes: &mut AesCipher, (p0, _, _, _): &mut 
ParametersAny<'_>) -> Result<()> {
+    let iv = p0.as_memref_input()?.get_buffer();
 
     aes.cipher.init(iv);
 
@@ -159,21 +160,19 @@ pub fn reset_aes_iv(aes: &mut AesCipher, params: &mut 
Parameters) -> Result<()>
     Ok(())
 }
 
-pub fn cipher_buffer(aes: &mut AesCipher, params: &mut Parameters) -> 
Result<()> {
-    let mut param0 = unsafe { params.0.as_memref()? };
-    let mut param1 = unsafe { params.1.as_memref()? };
+pub fn cipher_buffer(aes: &mut AesCipher, (p0, p1, _, _): &mut 
ParametersAny<'_>) -> Result<()> {
+    let (input, output) = (p0.as_memref_input()?, p1.as_memref_output()?);
 
-    let input = param0.buffer();
-    let output = param1.buffer();
-
-    if output.len() < input.len() {
+    if output.get_capacity() < input.get_buffer().len() {
         return Err(ErrorKind::BadParameters.into());
     }
 
     trace_println!("[+] TA tries to update ciphers!");
 
-    let tmp_size = aes.cipher.update(input, output)?;
-    param1.set_updated_size(tmp_size);
+    let tmp_size = aes
+        .cipher
+        .update(input.get_buffer(), output.get_buffer_mut())?;
+    output.set_updated_size(tmp_size)?;
     Ok(())
 }
 
diff --git a/examples/authentication-rs/ta/src/main.rs 
b/examples/authentication-rs/ta/src/main.rs
index 0aa33c9..657cc84 100644
--- a/examples/authentication-rs/ta/src/main.rs
+++ b/examples/authentication-rs/ta/src/main.rs
@@ -20,14 +20,10 @@
 
 extern crate alloc;
 
-use alloc::boxed::Box;
-use alloc::vec;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
+use optee_utee::prelude::*;
 use optee_utee::{AlgorithmId, OperationMode, AE};
 use optee_utee::{AttributeId, AttributeMemref, TransientObject, 
TransientObjectType};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::{ErrorKind, Result};
 use proto::{Command, Mode, AAD_LEN, BUFFER_SIZE, KEY_SIZE, TAG_LEN};
 
 pub const PAYLOAD_NUMBER: usize = 2;
@@ -49,7 +45,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters, _sess_ctx: &mut AEOp) -> Result<()> {
+fn open_session(_params: &mut ParametersNone, _sess_ctx: &mut AEOp) -> 
Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -65,7 +61,7 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(sess_ctx: &mut AEOp, cmd_id: u32, params: &mut Parameters) 
-> Result<()> {
+fn invoke_command(sess_ctx: &mut AEOp, cmd_id: u32, params: &mut 
ParametersAny<'_>) -> Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
         Command::Prepare => {
@@ -88,19 +84,15 @@ fn invoke_command(sess_ctx: &mut AEOp, cmd_id: u32, params: 
&mut Parameters) ->
     }
 }
 
-pub fn prepare(ae: &mut AEOp, params: &mut Parameters) -> Result<()> {
-    let p0 = unsafe { params.0.as_value()? };
-    let mut p1 = unsafe { params.1.as_memref()? };
-    let mut p2 = unsafe { params.2.as_memref()? };
-    let mut p3 = unsafe { params.3.as_memref()? };
-    let mode = match Mode::from(p0.a()) {
+pub fn prepare(ae: &mut AEOp, (p0, p1, p2, p3): &mut ParametersAny<'_>) -> 
Result<()> {
+    let mode = match Mode::from(p0.as_value_input()?.get_a()) {
         Mode::Encrypt => OperationMode::Encrypt,
         Mode::Decrypt => OperationMode::Decrypt,
         _ => OperationMode::IllegalValue,
     };
-    let nonce = p1.buffer();
-    let key = p2.buffer();
-    let aad = p3.buffer();
+    let nonce = p1.as_memref_input()?.get_buffer();
+    let key = p2.as_memref_input()?.get_buffer();
+    let aad = p3.as_memref_input()?.get_buffer();
 
     ae.op = AE::allocate(AlgorithmId::AesCcm, mode, KEY_SIZE * 8)?;
 
@@ -114,61 +106,41 @@ pub fn prepare(ae: &mut AEOp, params: &mut Parameters) -> 
Result<()> {
     Ok(())
 }
 
-pub fn update(digest: &mut AEOp, params: &mut Parameters) -> Result<()> {
-    let mut p0 = unsafe { params.0.as_memref()? };
-    let mut p1 = unsafe { params.1.as_memref()? };
-    let src = p0.buffer();
-    let res = p1.buffer();
-    digest.op.update(src, res)?;
+pub fn update(digest: &mut AEOp, (p0, p1, _, _): &mut ParametersAny<'_>) -> 
Result<()> {
+    let (p0, p1) = (p0.as_memref_input()?, p1.as_memref_output()?);
+    let size = digest.op.update(p0.get_buffer(), p1.get_buffer_mut())?;
+    p1.set_updated_size(size)?;
     Ok(())
 }
 
-pub fn encrypt_final(digest: &mut AEOp, params: &mut Parameters) -> Result<()> 
{
-    let mut p0 = unsafe { params.0.as_memref()? };
-    let mut p1 = unsafe { params.1.as_memref()? };
-    let mut p2 = unsafe { params.2.as_memref()? };
-
-    let mut clear = vec![0; p0.buffer().len()];
-    clear.copy_from_slice(p0.buffer());
-    let mut ciph = vec![0; p1.buffer().len()];
-    ciph.copy_from_slice(p1.buffer());
-    let mut tag = vec![0; p2.buffer().len()];
-    tag.copy_from_slice(p2.buffer());
-
-    match digest.op.encrypt_final(&clear, &mut ciph, &mut tag) {
-        Err(e) => Err(e),
-        Ok((_ciph_len, _tag_len)) => {
-            p0.buffer().copy_from_slice(&clear);
-            p1.buffer().copy_from_slice(&ciph);
-            p2.buffer().copy_from_slice(&tag);
-
-            Ok(())
-        }
-    }
+pub fn encrypt_final(digest: &mut AEOp, (p0, p1, p2, _): &mut 
ParametersAny<'_>) -> Result<()> {
+    let (p0, p1, p2) = (
+        p0.as_memref_input()?,
+        p1.as_memref_output()?,
+        p2.as_memref_output()?,
+    );
+
+    let (ciph_len, tag_len) =
+        digest
+            .op
+            .encrypt_final(p0.get_buffer(), p1.get_buffer_mut(), 
p2.get_buffer_mut())?;
+    p1.set_updated_size(ciph_len)?;
+    p2.set_updated_size(tag_len)?;
+    Ok(())
 }
 
-pub fn decrypt_final(digest: &mut AEOp, params: &mut Parameters) -> Result<()> 
{
-    let mut p0 = unsafe { params.0.as_memref()? };
-    let mut p1 = unsafe { params.1.as_memref()? };
-    let mut p2 = unsafe { params.2.as_memref()? };
-
-    let mut clear = vec![0; p0.buffer().len()];
-    clear.copy_from_slice(p0.buffer());
-    let mut ciph = vec![0; p1.buffer().len()];
-    ciph.copy_from_slice(p1.buffer());
-    let mut tag = vec![0; p2.buffer().len()];
-    tag.copy_from_slice(p2.buffer());
-
-    match digest.op.decrypt_final(&clear, &mut ciph, &tag) {
-        Err(e) => Err(e),
-        Ok(_clear_len) => {
-            p0.buffer().copy_from_slice(&clear);
-            p1.buffer().copy_from_slice(&ciph);
-            p2.buffer().copy_from_slice(&tag);
-
-            Ok(())
-        }
-    }
+pub fn decrypt_final(digest: &mut AEOp, (p0, p1, p2, _): &mut 
ParametersAny<'_>) -> Result<()> {
+    let (p0, p1, p2) = (
+        p0.as_memref_input()?,
+        p1.as_memref_output()?,
+        p2.as_memref_input()?,
+    );
+
+    let len = digest
+        .op
+        .decrypt_final(p0.get_buffer(), p1.get_buffer_mut(), p2.get_buffer())?;
+    p1.set_updated_size(len)?;
+    Ok(())
 }
 
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/big_int-rs/ta/src/main.rs 
b/examples/big_int-rs/ta/src/main.rs
index e5228f5..0bed97a 100644
--- a/examples/big_int-rs/ta/src/main.rs
+++ b/examples/big_int-rs/ta/src/main.rs
@@ -18,11 +18,9 @@
 #![cfg_attr(not(feature = "std"), no_std)]
 #![no_main]
 
+use optee_utee::prelude::*;
 use optee_utee::BigInt;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::{ErrorKind, Result};
 use proto::Command;
 
 #[ta_create]
@@ -32,7 +30,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> Result<()> {
+fn open_session(_params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -97,16 +95,16 @@ fn module(n0: &BigInt, n1: &BigInt) -> Result<()> {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, (p0, p1, _, _): &mut ParametersAny<'_>) -> 
Result<()> {
     trace_println!("[+] TA invoke command");
-    let mut n0_buffer = unsafe { params.0.as_memref()? };
-    let n1_value = unsafe { params.1.as_value()? };
+    let n0_buffer = p0.as_memref_input()?;
+    let n1_value = p1.as_value_input()?;
 
     let mut n0 = BigInt::new(64);
     let mut n1 = BigInt::new(2);
 
-    n0.convert_from_octet_string(n0_buffer.buffer(), 0)?;
-    n1.convert_from_s32(n1_value.a() as i32);
+    n0.convert_from_octet_string(n0_buffer.get_buffer(), 0)?;
+    n1.convert_from_s32(n1_value.get_a() as i32);
 
     match Command::from(cmd_id) {
         Command::Compare => compare(&n0, &n1),
diff --git a/examples/build_with_optee_utee_sys-rs/ta/src/main.rs 
b/examples/build_with_optee_utee_sys-rs/ta/src/main.rs
index 0a2a61e..360e3ee 100644
--- a/examples/build_with_optee_utee_sys-rs/ta/src/main.rs
+++ b/examples/build_with_optee_utee_sys-rs/ta/src/main.rs
@@ -19,10 +19,8 @@
 #![no_main]
 
 use core::sync::atomic::{AtomicU32, Ordering};
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::prelude::*;
+use optee_utee::{ErrorKind, Result};
 use proto::Command;
 
 static GLOBAL_VALUE: AtomicU32 = AtomicU32::new(0);
@@ -35,7 +33,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> Result<()> {
+fn open_session(_params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -51,9 +49,9 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, (p0, _, _, _): &mut ParametersAny<'_>) -> 
Result<()> {
     trace_println!("[+] TA invoke command");
-    let mut values = unsafe { params.0.as_value()? };
+    let values = p0.as_value_output()?;
 
     match Command::from(cmd_id) {
         Command::IncValue => {
diff --git a/examples/client_pool-rs/ta/src/main.rs 
b/examples/client_pool-rs/ta/src/main.rs
index e35b34b..10fa52e 100644
--- a/examples/client_pool-rs/ta/src/main.rs
+++ b/examples/client_pool-rs/ta/src/main.rs
@@ -19,11 +19,9 @@
 #![no_main]
 extern crate alloc;
 
-use alloc::{boxed::Box, string::String};
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result};
+use alloc::string::String;
+use optee_utee::prelude::*;
+use optee_utee::{ErrorKind, Result};
 use proto::Command;
 
 #[ta_create]
@@ -33,15 +31,15 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(params: &mut Parameters, ctx: &mut String) -> Result<()> {
-    let mut p0 = unsafe { params.0.as_memref()? };
+fn open_session((p0, _, _, _): &mut ParametersAny<'_>, ctx: &mut String) -> 
Result<()> {
+    let p0 = p0.as_memref_output()?;
 
     let mut buffer = [0_u8; proto::IDENTITY_SIZE];
     optee_utee::Random::generate(&mut buffer);
     *ctx = hex::encode(buffer).to_uppercase();
 
     trace_println!("[+] TA open session, identity: {}", ctx);
-    p0.buffer().copy_from_slice(&buffer);
+    p0.set_output(buffer)?;
 
     Ok(())
 }
@@ -57,12 +55,16 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(ctx: &mut String, cmd_id: u32, params: &mut Parameters) -> 
Result<()> {
+fn invoke_command(
+    ctx: &mut String,
+    cmd_id: u32,
+    (p0, _, _, _): &mut ParametersAny<'_>,
+) -> Result<()> {
     match Command::from(cmd_id) {
         Command::Sleep => {
-            let values = unsafe { params.0.as_value()? };
+            let values = p0.as_value_input()?;
 
-            let milliseconds = values.a();
+            let milliseconds = values.get_a();
             let mut now = optee_utee::Time::new();
             now.system_time();
             // this would cause messy output in the console when running 
concurrently.
diff --git a/examples/diffie_hellman-rs/ta/src/main.rs 
b/examples/diffie_hellman-rs/ta/src/main.rs
index 51de9c6..aa7c00c 100644
--- a/examples/diffie_hellman-rs/ta/src/main.rs
+++ b/examples/diffie_hellman-rs/ta/src/main.rs
@@ -20,15 +20,12 @@
 
 extern crate alloc;
 
-use alloc::boxed::Box;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
+use optee_utee::prelude::*;
 use optee_utee::{AlgorithmId, DeriveKey};
 use optee_utee::{
     AttributeId, AttributeMemref, GenericObject, TransientObject, 
TransientObjectType,
 };
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::{ErrorKind, Result};
 use proto::{Command, KEY_SIZE};
 
 pub struct DiffieHellman {
@@ -50,7 +47,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters, _sess_ctx: &mut DiffieHellman) -> 
Result<()> {
+fn open_session(_params: &mut ParametersNone, _sess_ctx: &mut DiffieHellman) 
-> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -65,14 +62,15 @@ fn destroy() {
     trace_println!("[+] TA destroy");
 }
 
-fn generate_key(dh: &mut DiffieHellman, params: &mut Parameters) -> Result<()> 
{
-    let mut p0 = unsafe { params.0.as_memref()? };
-    let mut p1 = unsafe { params.1.as_value()? };
-    let mut p2 = unsafe { params.2.as_memref()? };
-    let mut p3 = unsafe { params.3.as_memref()? };
-
+fn generate_key(dh: &mut DiffieHellman, (p0, p1, p2, p3): &mut 
ParametersAny<'_>) -> Result<()> {
+    let (p0, p1, p2, p3) = (
+        p0.as_memref_input()?,
+        p1.as_value_output()?,
+        p2.as_memref_output()?,
+        p3.as_memref_output()?,
+    );
     // Extract prime and base from parameters
-    let prime_base_vec = p0.buffer();
+    let prime_base_vec = p0.get_buffer();
     let prime_slice = &prime_base_vec[..KEY_SIZE / 8];
     let base_slice = &prime_base_vec[KEY_SIZE / 8..];
 
@@ -81,48 +79,50 @@ fn generate_key(dh: &mut DiffieHellman, params: &mut 
Parameters) -> Result<()> {
 
     // Generate key pair
     dh.key = TransientObject::allocate(TransientObjectType::DhKeypair, 
KEY_SIZE)?;
-    let public_buffer = p2.buffer();
-    let private_buffer = p3.buffer();
 
     dh.key
         .generate_key(KEY_SIZE, &[attr_prime.into(), attr_base.into()])?;
-    let mut key_size = dh
-        .key
-        .ref_attribute(AttributeId::DhPublicValue, public_buffer)?;
-    p1.set_a(key_size as u32);
-    key_size = dh
-        .key
-        .ref_attribute(AttributeId::DhPrivateValue, private_buffer)?;
-    p1.set_b(key_size as u32);
+    {
+        let key_size = dh
+            .key
+            .ref_attribute(AttributeId::DhPublicValue, p2.get_buffer_mut())?;
+        p2.set_updated_size(key_size)?;
+        p1.set_a(key_size as u32);
+    }
+
+    {
+        let key_size = dh
+            .key
+            .ref_attribute(AttributeId::DhPrivateValue, p3.get_buffer_mut())?;
+        p3.set_updated_size(key_size)?;
+        p1.set_b(key_size as u32);
+    }
     Ok(())
 }
 
-fn derive_key(dh: &mut DiffieHellman, params: &mut Parameters) -> Result<()> {
-    let mut p0 = unsafe { params.0.as_memref()? };
-    let mut p1 = unsafe { params.1.as_memref()? };
-    let mut p2 = unsafe { params.2.as_value()? };
-
-    let received_public = 
AttributeMemref::from_ref(AttributeId::DhPublicValue, p0.buffer());
-
-    match DeriveKey::allocate(AlgorithmId::DhDeriveSharedSecret, KEY_SIZE) {
-        Err(e) => Err(e),
-        Ok(operation) => {
-            operation.set_key(&dh.key)?;
-            let mut derived_key =
-                TransientObject::allocate(TransientObjectType::GenericSecret, 
KEY_SIZE)?;
-            operation.derive(&[received_public.into()], &mut derived_key);
-            let key_size = derived_key.ref_attribute(AttributeId::SecretValue, 
p1.buffer())?;
-            p2.set_a(key_size as u32);
-            Ok(())
-        }
-    }
+fn derive_key(dh: &mut DiffieHellman, (p0, p1, p2, _): &mut ParametersAny<'_>) 
-> Result<()> {
+    let (p0, p1, p2) = (
+        p0.as_memref_input()?,
+        p1.as_memref_output()?,
+        p2.as_value_output()?,
+    );
+    let received_public = 
AttributeMemref::from_ref(AttributeId::DhPublicValue, p0.get_buffer());
+
+    let mut operation = DeriveKey::allocate(AlgorithmId::DhDeriveSharedSecret, 
KEY_SIZE)?;
+    operation.set_key(&dh.key)?;
+    let mut derived_key = 
TransientObject::allocate(TransientObjectType::GenericSecret, KEY_SIZE)?;
+    operation.derive(&[received_public.into()], &mut derived_key);
+    let key_size = derived_key.ref_attribute(AttributeId::SecretValue, 
p1.get_buffer_mut())?;
+    p1.set_updated_size(key_size)?;
+    p2.set_a(key_size as u32);
+    Ok(())
 }
 
 #[ta_invoke_command]
 fn invoke_command(
     sess_ctx: &mut DiffieHellman,
     cmd_id: u32,
-    params: &mut Parameters,
+    params: &mut ParametersAny<'_>,
 ) -> Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
diff --git a/examples/digest-rs/ta/src/main.rs 
b/examples/digest-rs/ta/src/main.rs
index 26cdaa7..bc49700 100644
--- a/examples/digest-rs/ta/src/main.rs
+++ b/examples/digest-rs/ta/src/main.rs
@@ -20,12 +20,9 @@
 
 extern crate alloc;
 
-use alloc::boxed::Box;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
+use optee_utee::prelude::*;
 use optee_utee::{AlgorithmId, Digest};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::{ErrorKind, Result};
 use proto::Command;
 
 pub struct DigestOp {
@@ -50,7 +47,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters, _sess_ctx: &mut DigestOp) -> 
Result<()> {
+fn open_session(_params: &mut ParametersNone, _sess_ctx: &mut DigestOp) -> 
Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -66,7 +63,11 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(sess_ctx: &mut DigestOp, cmd_id: u32, params: &mut 
Parameters) -> Result<()> {
+fn invoke_command(
+    sess_ctx: &mut DigestOp,
+    cmd_id: u32,
+    params: &mut ParametersAny<'_>,
+) -> Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
         Command::Update => update(sess_ctx, params),
@@ -75,26 +76,23 @@ fn invoke_command(sess_ctx: &mut DigestOp, cmd_id: u32, 
params: &mut Parameters)
     }
 }
 
-pub fn update(digest: &mut DigestOp, params: &mut Parameters) -> Result<()> {
-    let mut p = unsafe { params.0.as_memref()? };
-    let buffer = p.buffer();
+pub fn update(digest: &mut DigestOp, (p0, _, _, _): &mut ParametersAny<'_>) -> 
Result<()> {
+    let buffer = p0.as_memref_input()?.get_buffer();
     digest.op.update(buffer);
     Ok(())
 }
 
-pub fn do_final(digest: &mut DigestOp, params: &mut Parameters) -> Result<()> {
-    let mut p0 = unsafe { params.0.as_memref()? };
-    let mut p1 = unsafe { params.1.as_memref()? };
-    let mut p2 = unsafe { params.2.as_value()? };
-    let input = p0.buffer();
-    let output = p1.buffer();
-    match digest.op.do_final(input, output) {
-        Err(e) => Err(e),
-        Ok(hash_length) => {
-            p2.set_a(hash_length as u32);
-            Ok(())
-        }
-    }
+pub fn do_final(digest: &mut DigestOp, (p0, p1, p2, _): &mut 
ParametersAny<'_>) -> Result<()> {
+    let (p0, p1, p2) = (
+        p0.as_memref_input()?,
+        p1.as_memref_output()?,
+        p2.as_value_output()?,
+    );
+    let input = p0.get_buffer();
+    let length = digest.op.do_final(input, p1.get_buffer_mut())?;
+    p2.set_a(length as u32);
+    p1.set_updated_size(length)?;
+    Ok(())
 }
 
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/error_handling-rs/ta/src/main.rs 
b/examples/error_handling-rs/ta/src/main.rs
index 19727b7..241f980 100644
--- a/examples/error_handling-rs/ta/src/main.rs
+++ b/examples/error_handling-rs/ta/src/main.rs
@@ -20,14 +20,10 @@
 
 extern crate alloc;
 
-use alloc::boxed::Box;
-use alloc::vec;
-use alloc::vec::Vec;
+use alloc::{vec, vec::Vec};
 
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::prelude::*;
+use optee_utee::{ErrorKind, Result};
 use proto::Command;
 
 pub struct SessionContext {
@@ -49,7 +45,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters, _sess_ctx: &mut SessionContext) -> 
Result<()> {
+fn open_session(_params: &mut ParametersNone, _sess_ctx: &mut SessionContext) 
-> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -68,7 +64,7 @@ fn destroy() {
 fn invoke_command(
     _sess_ctx: &mut SessionContext,
     cmd_id: u32,
-    _params: &mut Parameters,
+    _params: &mut ParametersNone,
 ) -> Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
diff --git a/examples/hello_world-rs/ta/src/main.rs 
b/examples/hello_world-rs/ta/src/main.rs
index c6aa15c..46ab288 100644
--- a/examples/hello_world-rs/ta/src/main.rs
+++ b/examples/hello_world-rs/ta/src/main.rs
@@ -18,10 +18,8 @@
 #![cfg_attr(not(feature = "std"), no_std)]
 #![no_main]
 
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::prelude::*;
+use optee_utee::{ErrorKind, Result};
 use proto::Command;
 
 #[ta_create]
@@ -31,7 +29,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> Result<()> {
+fn open_session(_params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -47,16 +45,24 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
+fn invoke_command(
+    cmd_id: u32,
+    params: &mut (
+        ParameterValueInout,
+        ParameterNone,
+        ParameterNone,
+        ParameterNone,
+    ),
+) -> Result<()> {
     trace_println!("[+] TA invoke command");
-    let mut values = unsafe { params.0.as_value()? };
+    let values = &mut params.0;
     match Command::from(cmd_id) {
         Command::IncValue => {
-            values.set_a(values.a() + 100);
+            values.set_a(values.get_a() + 100);
             Ok(())
         }
         Command::DecValue => {
-            values.set_a(values.a() - 100);
+            values.set_a(values.get_a() - 100);
             Ok(())
         }
         _ => Err(ErrorKind::BadParameters.into()),
diff --git a/examples/hotp-rs/ta/src/main.rs b/examples/hotp-rs/ta/src/main.rs
index 4a927ff..f08cb97 100644
--- a/examples/hotp-rs/ta/src/main.rs
+++ b/examples/hotp-rs/ta/src/main.rs
@@ -20,13 +20,10 @@
 
 extern crate alloc;
 
-use alloc::boxed::Box;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
+use optee_utee::prelude::*;
 use optee_utee::{AlgorithmId, Mac};
 use optee_utee::{AttributeId, AttributeMemref, TransientObject, 
TransientObjectType};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::{ErrorKind, Result};
 use proto::Command;
 
 pub const SHA1_HASH_SIZE: usize = 20;
@@ -57,7 +54,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters, _sess_ctx: &mut HmacOtp) -> 
Result<()> {
+fn open_session(_params: &mut ParametersNone, _sess_ctx: &mut HmacOtp) -> 
Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -73,7 +70,11 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(sess_ctx: &mut HmacOtp, cmd_id: u32, params: &mut 
Parameters) -> Result<()> {
+fn invoke_command(
+    sess_ctx: &mut HmacOtp,
+    cmd_id: u32,
+    params: &mut ParametersAny<'_>,
+) -> Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
         Command::RegisterSharedKey => register_shared_key(sess_ctx, params),
@@ -82,15 +83,17 @@ fn invoke_command(sess_ctx: &mut HmacOtp, cmd_id: u32, 
params: &mut Parameters)
     }
 }
 
-pub fn register_shared_key(hotp: &mut HmacOtp, params: &mut Parameters) -> 
Result<()> {
-    let mut p = unsafe { params.0.as_memref()? };
-    let buffer = p.buffer();
+pub fn register_shared_key(
+    hotp: &mut HmacOtp,
+    (p0, _, _, _): &mut ParametersAny<'_>,
+) -> Result<()> {
+    let buffer = p0.as_memref_input()?.get_buffer();
     hotp.key_len = buffer.len();
     hotp.key[..hotp.key_len].clone_from_slice(buffer);
     Ok(())
 }
 
-pub fn get_hotp(hotp: &mut HmacOtp, params: &mut Parameters) -> Result<()> {
+pub fn get_hotp(hotp: &mut HmacOtp, (p0, _, _, _): &mut ParametersAny<'_>) -> 
Result<()> {
     let mut mac: [u8; SHA1_HASH_SIZE] = [0x0; SHA1_HASH_SIZE];
 
     hmac_sha1(hotp, &mut mac)?;
@@ -102,8 +105,7 @@ pub fn get_hotp(hotp: &mut HmacOtp, params: &mut 
Parameters) -> Result<()> {
         }
     }
     let hotp_val = truncate(&mut mac);
-    let mut p = unsafe { params.0.as_value()? };
-    p.set_a(hotp_val);
+    p0.as_value_output()?.set_a(hotp_val);
     Ok(())
 }
 
diff --git a/examples/inter_ta-rs/ta/src/main.rs 
b/examples/inter_ta-rs/ta/src/main.rs
index 6df23fb..654e6b4 100644
--- a/examples/inter_ta-rs/ta/src/main.rs
+++ b/examples/inter_ta-rs/ta/src/main.rs
@@ -18,15 +18,12 @@
 #![cfg_attr(not(feature = "std"), no_std)]
 #![no_main]
 
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result, Uuid};
+use optee_utee::prelude::*;
+use optee_utee::{ErrorKind, Result, Uuid};
 use optee_utee::{ParamIndex, TaSessionBuilder, TeeParams};
 use proto::{
     Command, HelloWorldTaCommand, SystemPtaCommand, HELLO_WORLD_USER_TA_UUID, 
SYSTEM_PTA_UUID,
 };
-
 #[ta_create]
 fn create() -> Result<()> {
     trace_println!("[+] TA create");
@@ -34,7 +31,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> Result<()> {
+fn open_session(_params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -131,7 +128,7 @@ fn test_invoke_hello_world_user_ta() -> Result<()> {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, _params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, _params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
         Command::Test => {
diff --git a/examples/message_passing_interface-rs/ta/Cargo.lock 
b/examples/message_passing_interface-rs/ta/Cargo.lock
index b31ff89..2491221 100644
--- a/examples/message_passing_interface-rs/ta/Cargo.lock
+++ b/examples/message_passing_interface-rs/ta/Cargo.lock
@@ -4,21 +4,18 @@ version = 4
 
 [[package]]
 name = "bitflags"
-version = "1.3.2"
+version = "2.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
 
 [[package]]
-name = "bumpalo"
-version = "3.18.1"
+name = "document-features"
+version = "0.2.12"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee"
-
-[[package]]
-name = "cfg-if"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61"
+dependencies = [
+ "litrs",
+]
 
 [[package]]
 name = "heck"
@@ -38,22 +35,6 @@ version = "1.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
 
-[[package]]
-name = "js-sys"
-version = "0.3.77"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
-dependencies = [
- "once_cell",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "libc"
-version = "0.2.172"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
-
 [[package]]
 name = "libc_alloc"
 version = "1.0.7"
@@ -61,10 +42,10 @@ source = 
"registry+https://github.com/rust-lang/crates.io-index";
 checksum = "7581282928bc99698341d1de7590964c28db747c164eaac9409432a3eaed098a"
 
 [[package]]
-name = "log"
-version = "0.4.27"
+name = "litrs"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
+checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
 
 [[package]]
 name = "memchr"
@@ -74,58 +55,54 @@ checksum = 
"78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
 
 [[package]]
 name = "num_enum"
-version = "0.7.3"
+version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179"
+checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26"
 dependencies = [
  "num_enum_derive",
+ "rustversion",
 ]
 
 [[package]]
 name = "num_enum_derive"
-version = "0.7.3"
+version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
+checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8"
 dependencies = [
  "proc-macro2",
  "quote",
  "syn",
 ]
 
-[[package]]
-name = "once_cell"
-version = "1.21.3"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
-
 [[package]]
 name = "optee-utee"
-version = "0.8.0"
+version = "0.9.0"
 dependencies = [
  "bitflags",
+ "document-features",
  "hex",
  "libc_alloc",
+ "num_enum",
  "optee-utee-macros",
  "optee-utee-sys",
- "rustc_version",
- "strum_macros",
- "uuid 0.8.2",
+ "strum",
+ "uuid",
 ]
 
 [[package]]
 name = "optee-utee-build"
-version = "0.8.0"
+version = "0.9.0"
 dependencies = [
  "prettyplease",
  "proc-macro2",
  "quote",
  "syn",
- "uuid 1.22.0",
+ "uuid",
 ]
 
 [[package]]
 name = "optee-utee-macros"
-version = "0.8.0"
+version = "0.9.0"
 dependencies = [
  "quote",
  "syn",
@@ -133,9 +110,9 @@ dependencies = [
 
 [[package]]
 name = "optee-utee-sys"
-version = "0.8.0"
+version = "0.9.0"
 dependencies = [
- "libc",
+ "document-features",
 ]
 
 [[package]]
@@ -174,15 +151,6 @@ dependencies = [
  "proc-macro2",
 ]
 
-[[package]]
-name = "rustc_version"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
-dependencies = [
- "semver",
-]
-
 [[package]]
 name = "rustversion"
 version = "1.0.21"
@@ -195,12 +163,6 @@ version = "1.0.20"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
 
-[[package]]
-name = "semver"
-version = "1.0.27"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
-
 [[package]]
 name = "serde"
 version = "1.0.219"
@@ -233,16 +195,24 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "strum"
+version = "0.28.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd"
+dependencies = [
+ "strum_macros",
+]
+
 [[package]]
 name = "strum_macros"
-version = "0.26.4"
+version = "0.28.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
+checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664"
 dependencies = [
  "heck",
  "proc-macro2",
  "quote",
- "rustversion",
  "syn",
 ]
 
@@ -276,74 +246,6 @@ checksum = 
"5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
 
 [[package]]
 name = "uuid"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
-
-[[package]]
-name = "uuid"
-version = "1.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "wasm-bindgen"
-version = "0.2.100"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
-dependencies = [
- "cfg-if",
- "once_cell",
- "rustversion",
- "wasm-bindgen-macro",
-]
-
-[[package]]
-name = "wasm-bindgen-backend"
-version = "0.2.100"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
-dependencies = [
- "bumpalo",
- "log",
- "proc-macro2",
- "quote",
- "syn",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-macro"
-version = "0.2.100"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
-dependencies = [
- "quote",
- "wasm-bindgen-macro-support",
-]
-
-[[package]]
-name = "wasm-bindgen-macro-support"
-version = "0.2.100"
+version = "1.23.3"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
- "wasm-bindgen-backend",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-shared"
-version = "0.2.100"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
-dependencies = [
- "unicode-ident",
-]
+checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7"
diff --git a/examples/message_passing_interface-rs/ta/src/main.rs 
b/examples/message_passing_interface-rs/ta/src/main.rs
index 54770ae..2d39adf 100644
--- a/examples/message_passing_interface-rs/ta/src/main.rs
+++ b/examples/message_passing_interface-rs/ta/src/main.rs
@@ -21,11 +21,9 @@
 extern crate alloc;
 
 use alloc::format;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result};
-use proto::{self, Command};
+use optee_utee::prelude::*;
+use optee_utee::{ErrorKind, Result};
+use proto::Command;
 
 fn handle_invoke(command: Command, input: proto::EnclaveInput) -> 
Result<proto::EnclaveOutput> {
     match command {
@@ -52,7 +50,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> Result<()> {
+fn open_session(_params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -68,12 +66,17 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
+fn invoke_command(
+    cmd_id: u32,
+    (p0, p1, _, _): &mut (
+        ParameterMemrefInput<'_>,
+        ParameterMemrefOutput<'_>,
+        ParameterNone,
+        ParameterNone,
+    ),
+) -> Result<()> {
     trace_println!("[+] TA invoke command");
-    let mut p0 = unsafe { params.0.as_memref()? };
-    let mut p1 = unsafe { params.1.as_memref()? };
-
-    let input: proto::EnclaveInput = 
serde_json::from_slice(p0.buffer()).map_err(|e| {
+    let input: proto::EnclaveInput = 
serde_json::from_slice(p0.get_buffer()).map_err(|e| {
         trace_println!("Failed to deserialize input: {}", e);
         ErrorKind::BadFormat
     })?;
@@ -83,15 +86,7 @@ fn invoke_command(cmd_id: u32, params: &mut Parameters) -> 
Result<()> {
         trace_println!("Failed to serialize output: {}", e);
         ErrorKind::BadFormat
     })?;
-
-    let len = output_vec.len();
-    if len > p1.buffer().len() {
-        trace_println!("Buffer too small, cannot copy all bytes");
-        return Err(ErrorKind::BadParameters.into());
-    }
-
-    p1.buffer()[..len].copy_from_slice(&output_vec);
-    p1.set_updated_size(len);
+    p1.set_output(output_vec)?;
 
     Ok(())
 }
diff --git a/examples/mnist-rs/ta/common/src/lib.rs 
b/examples/mnist-rs/ta/common/src/lib.rs
index 9332788..ec1f802 100644
--- a/examples/mnist-rs/ta/common/src/lib.rs
+++ b/examples/mnist-rs/ta/common/src/lib.rs
@@ -19,7 +19,5 @@
 extern crate alloc;
 
 mod model;
-mod utils;
 
 pub use model::Model;
-pub use utils::*;
diff --git a/examples/mnist-rs/ta/common/src/utils.rs 
b/examples/mnist-rs/ta/common/src/utils.rs
deleted file mode 100644
index e80e030..0000000
--- a/examples/mnist-rs/ta/common/src/utils.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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::{trace_println, ErrorKind, Parameter, Result};
-
-pub fn copy_to_output(param: &mut Parameter, data: &[u8]) -> Result<()> {
-    let mut output = unsafe { param.as_memref()? };
-
-    let buffer = output.buffer();
-    if buffer.len() < data.len() {
-        trace_println!(
-            "expect output buffer size {}, got size {} instead",
-            data.len(),
-            buffer.len()
-        );
-        return Err(ErrorKind::ShortBuffer.into());
-    }
-    buffer[..data.len()].copy_from_slice(data);
-    output.set_updated_size(data.len());
-    Ok(())
-}
diff --git a/examples/mnist-rs/ta/inference/src/main.rs 
b/examples/mnist-rs/ta/inference/src/main.rs
index 9c23396..7df9625 100644
--- a/examples/mnist-rs/ta/inference/src/main.rs
+++ b/examples/mnist-rs/ta/inference/src/main.rs
@@ -24,11 +24,9 @@ use burn::{
     tensor::cast::ToElement,
 };
 
-use common::{copy_to_output, Model};
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result};
+use common::Model;
+use optee_utee::prelude::*;
+use optee_utee::{ErrorKind, Result};
 use proto::Image;
 use spin::Mutex;
 
@@ -43,14 +41,21 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(params: &mut Parameters) -> Result<()> {
-    let mut p0 = unsafe { params.0.as_memref()? };
-
+fn open_session(
+    (p0, _, _, _): &mut (
+        ParameterMemrefInput<'_>,
+        ParameterNone,
+        ParameterNone,
+        ParameterNone,
+    ),
+) -> Result<()> {
     let mut model = MODEL.lock();
-    model.replace(Model::import(&DEVICE, p0.buffer().to_vec()).map_err(|err| {
-        trace_println!("import failed: {:?}", err);
-        ErrorKind::BadParameters
-    })?);
+    model.replace(
+        Model::import(&DEVICE, p0.get_buffer().to_vec()).map_err(|err| {
+            trace_println!("import failed: {:?}", err);
+            ErrorKind::BadParameters
+        })?,
+    );
 
     Ok(())
 }
@@ -66,10 +71,17 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(_cmd_id: u32, params: &mut Parameters) -> Result<()> {
+fn invoke_command(
+    _cmd_id: u32,
+    (p0, p1, _, _): &mut (
+        ParameterMemrefInput<'_>,
+        ParameterMemrefOutput<'_>,
+        ParameterNone,
+        ParameterNone,
+    ),
+) -> Result<()> {
     trace_println!("[+] TA invoke command");
-    let mut p0 = unsafe { params.0.as_memref()? };
-    let images: &[Image] = bytemuck::cast_slice(p0.buffer());
+    let images: &[Image] = bytemuck::cast_slice(p0.get_buffer());
     let input = NoStdModel::images_to_tensors(&DEVICE, images);
 
     let output = MODEL
@@ -84,8 +96,7 @@ fn invoke_command(_cmd_id: u32, params: &mut Parameters) -> 
Result<()> {
             data.argmax(1).into_scalar().to_u8()
         })
         .collect();
-
-    copy_to_output(&mut params.1, &result)
+    p1.set_output(result)
 }
 
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/mnist-rs/ta/train/src/main.rs 
b/examples/mnist-rs/ta/train/src/main.rs
index f3ad57a..e48a327 100644
--- a/examples/mnist-rs/ta/train/src/main.rs
+++ b/examples/mnist-rs/ta/train/src/main.rs
@@ -20,11 +20,8 @@
 extern crate alloc;
 
 use burn::backend::{ndarray::NdArrayDevice, Autodiff, NdArray};
-use common::copy_to_output;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::prelude::*;
+use optee_utee::{ErrorKind, Result};
 use proto::train::Command;
 use spin::Mutex;
 
@@ -42,10 +39,15 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(params: &mut Parameters) -> Result<()> {
-    let mut p0 = unsafe { params.0.as_memref()? };
-
-    let learning_rate = 
f64::from_le_bytes(p0.buffer().try_into().map_err(|err| {
+fn open_session(
+    (p0, _, _, _): &mut (
+        ParameterMemrefInput<'_>,
+        ParameterNone,
+        ParameterNone,
+        ParameterNone,
+    ),
+) -> Result<()> {
+    let learning_rate = 
f64::from_le_bytes(p0.get_buffer().try_into().map_err(|err| {
         trace_println!("bad parameter {:?}", err);
         ErrorKind::BadParameters
     })?);
@@ -68,14 +70,11 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, (p0, p1, p2, _): &mut ParametersAny<'_>) -> 
Result<()> {
     match Command::try_from(cmd_id) {
         Ok(Command::Train) => {
-            let mut p0 = unsafe { params.0.as_memref()? };
-            let mut p1 = unsafe { params.1.as_memref()? };
-
-            let images = p0.buffer();
-            let labels = p1.buffer();
+            let images = p0.as_memref_input()?.get_buffer();
+            let labels = p1.as_memref_input()?.get_buffer();
 
             let mut trainer = TRAINER.lock();
             let result = trainer
@@ -86,15 +85,11 @@ fn invoke_command(cmd_id: u32, params: &mut Parameters) -> 
Result<()> {
                 trace_println!("unexpected error: {:?}", err);
                 ErrorKind::BadState
             })?;
-
-            copy_to_output(&mut params.2, &bytes)
+            p2.as_memref_output()?.set_output(bytes)
         }
         Ok(Command::Valid) => {
-            let mut p0 = unsafe { params.0.as_memref()? };
-            let mut p1 = unsafe { params.1.as_memref()? };
-
-            let images = p0.buffer();
-            let labels = p1.buffer();
+            let images = p0.as_memref_input()?.get_buffer();
+            let labels = p1.as_memref_input()?.get_buffer();
 
             let trainer = TRAINER.lock();
             let result = trainer
@@ -106,7 +101,7 @@ fn invoke_command(cmd_id: u32, params: &mut Parameters) -> 
Result<()> {
                 trace_println!("unexpected error: {:?}", err);
                 ErrorKind::BadState
             })?;
-            copy_to_output(&mut params.2, &bytes)
+            p2.as_memref_output()?.set_output(bytes)
         }
         Ok(Command::Export) => {
             let trainer = TRAINER.lock();
@@ -118,7 +113,7 @@ fn invoke_command(cmd_id: u32, params: &mut Parameters) -> 
Result<()> {
                     trace_println!("unexpected error: {:?}", err);
                     ErrorKind::BadState
                 })?;
-            copy_to_output(&mut params.0, &result)
+            p0.as_memref_output()?.set_output(result)
         }
         Err(_) => Err(ErrorKind::BadParameters.into()),
     }
diff --git a/examples/property-rs/ta/src/main.rs 
b/examples/property-rs/ta/src/main.rs
index 0b0c518..0cb2c5c 100644
--- a/examples/property-rs/ta/src/main.rs
+++ b/examples/property-rs/ta/src/main.rs
@@ -21,14 +21,13 @@
 extern crate alloc;
 use alloc::string::ToString;
 
+use optee_utee::prelude::*;
 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::{ErrorKind, Parameters, Result};
+
+use optee_utee::{ErrorKind, Result};
 use proto::Command;
 
 #[ta_create]
@@ -38,7 +37,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> Result<()> {
+fn open_session(_params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -96,7 +95,7 @@ fn get_properties() -> Result<()> {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, _params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, _params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
         Command::Test => {
diff --git a/examples/random-rs/ta/src/main.rs 
b/examples/random-rs/ta/src/main.rs
index b8b854a..a2f3e05 100644
--- a/examples/random-rs/ta/src/main.rs
+++ b/examples/random-rs/ta/src/main.rs
@@ -20,12 +20,10 @@
 
 extern crate alloc;
 
-use alloc::vec;
+use optee_utee::prelude::*;
 use optee_utee::Random;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result};
+
+use optee_utee::{ErrorKind, Result};
 use proto::Command;
 
 #[ta_create]
@@ -35,7 +33,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> Result<()> {
+fn open_session(_params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -50,19 +48,17 @@ fn destroy() {
     trace_println!("[+] TA destroy");
 }
 
-pub fn random_number_generate(params: &mut Parameters) -> Result<()> {
-    let mut p = unsafe { params.0.as_memref()? };
-    let mut buf = vec![0; p.buffer().len()];
-    buf.copy_from_slice(p.buffer());
+pub fn random_number_generate((p0, _, _, _): &mut ParametersAny<'_>) -> 
Result<()> {
+    let p0 = p0.as_memref_output()?;
 
-    Random::generate(buf.as_mut() as _);
-    p.buffer().copy_from_slice(&buf);
+    Random::generate(p0.get_buffer_mut());
+    p0.set_updated_size(p0.get_capacity())?;
 
     Ok(())
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, params: &mut ParametersAny<'_>) -> Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
         Command::RandomGenerator => random_number_generate(params),
diff --git a/examples/secure_db_abstraction-rs/ta/Cargo.lock 
b/examples/secure_db_abstraction-rs/ta/Cargo.lock
index 1ea2d82..e3539ac 100644
--- a/examples/secure_db_abstraction-rs/ta/Cargo.lock
+++ b/examples/secure_db_abstraction-rs/ta/Cargo.lock
@@ -115,6 +115,7 @@ dependencies = [
  "document-features",
  "hex",
  "libc_alloc",
+ "num_enum",
  "optee-utee-macros",
  "optee-utee-sys",
  "strum",
diff --git a/examples/secure_db_abstraction-rs/ta/src/main.rs 
b/examples/secure_db_abstraction-rs/ta/src/main.rs
index aa0f54e..605af03 100644
--- a/examples/secure_db_abstraction-rs/ta/src/main.rs
+++ b/examples/secure_db_abstraction-rs/ta/src/main.rs
@@ -20,10 +20,8 @@
 extern crate alloc;
 
 use alloc::vec;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::prelude::*;
+use optee_utee::{ErrorKind, Result};
 use proto::Command;
 use secure_db::{SecureStorageClient, Storable};
 use serde::{Deserialize, Serialize};
@@ -35,7 +33,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> Result<()> {
+fn open_session(_params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -51,7 +49,7 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, _params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, _params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
         Command::Test => match test() {
@@ -91,7 +89,6 @@ pub fn test() -> anyhow::Result<()> {
         id: "example_data".to_string(),
         data: vec![1, 2, 3, 4, 5],
     };
-
     // Initialize secure storage db client with a db name
     let db_client = SecureStorageClient::open("secure_db")?;
 
diff --git a/examples/secure_storage-rs/ta/src/main.rs 
b/examples/secure_storage-rs/ta/src/main.rs
index fe2af16..f99ba78 100644
--- a/examples/secure_storage-rs/ta/src/main.rs
+++ b/examples/secure_storage-rs/ta/src/main.rs
@@ -20,12 +20,9 @@
 
 extern crate alloc;
 
-use alloc::vec;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
+use optee_utee::prelude::*;
 use optee_utee::{DataFlag, GenericObject, ObjectStorageConstants, 
PersistentObject};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::{ErrorKind, Result};
 use proto::Command;
 
 #[ta_create]
@@ -35,7 +32,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> Result<()> {
+fn open_session(_params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -51,7 +48,7 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, params: &mut ParametersAny<'_>) -> Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
         Command::Write => create_raw_object(params),
@@ -61,11 +58,9 @@ fn invoke_command(cmd_id: u32, params: &mut Parameters) -> 
Result<()> {
     }
 }
 
-pub fn delete_object(params: &mut Parameters) -> Result<()> {
-    let mut p0 = unsafe { params.0.as_memref()? };
-
-    let mut obj_id = vec![0; p0.buffer().len()];
-    obj_id.copy_from_slice(p0.buffer());
+pub fn delete_object((p0, _, _, _): &mut ParametersAny<'_>) -> Result<()> {
+    // use to_vec to copy into tee memory
+    let obj_id = p0.as_memref_input()?.get_buffer().to_vec();
 
     match PersistentObject::open(
         ObjectStorageConstants::Private,
@@ -81,14 +76,10 @@ pub fn delete_object(params: &mut Parameters) -> Result<()> 
{
     }
 }
 
-pub fn create_raw_object(params: &mut Parameters) -> Result<()> {
-    let mut p0 = unsafe { params.0.as_memref()? };
-    let mut p1 = unsafe { params.1.as_memref()? };
-
-    let mut obj_id = vec![0; p0.buffer().len()];
-    obj_id.copy_from_slice(p0.buffer());
-    let mut data_buffer = vec![0; p1.buffer().len()];
-    data_buffer.copy_from_slice(p1.buffer());
+pub fn create_raw_object((p0, p1, _, _): &mut ParametersAny<'_>) -> Result<()> 
{
+    // use to_vec to copy into tee memory
+    let obj_id = p0.as_memref_input()?.get_buffer().to_vec();
+    let data_buffer = p1.as_memref_input()?.get_buffer().to_vec();
 
     let obj_data_flag = DataFlag::ACCESS_READ
         | DataFlag::ACCESS_WRITE
@@ -97,59 +88,42 @@ pub fn create_raw_object(params: &mut Parameters) -> 
Result<()> {
 
     let init_data: [u8; 0] = [0; 0];
 
-    match PersistentObject::create(
+    let mut object = PersistentObject::create(
         ObjectStorageConstants::Private,
         &obj_id,
         obj_data_flag,
         None,
         &init_data,
-    ) {
-        Err(e) => Err(e),
-
-        Ok(mut object) => match object.write(&data_buffer) {
-            Ok(()) => Ok(()),
-            Err(e_write) => {
-                object.close_and_delete()?;
-                Err(e_write)
-            }
-        },
+    )?;
+    match object.write(&data_buffer) {
+        Ok(()) => Ok(()),
+        Err(e_write) => {
+            object.close_and_delete()?;
+            Err(e_write)
+        }
     }
 }
 
-pub fn read_raw_object(params: &mut Parameters) -> Result<()> {
-    let mut p0 = unsafe { params.0.as_memref()? };
-    let mut p1 = unsafe { params.1.as_memref()? };
-    let mut obj_id = vec![0; p0.buffer().len()];
-    obj_id.copy_from_slice(p0.buffer());
+pub fn read_raw_object((p0, p1, _, _): &mut ParametersAny<'_>) -> Result<()> {
+    // use to_vec to copy into tee memory
+    let obj_id = p0.as_memref_input()?.get_buffer().to_vec();
+    let p1 = p1.as_memref_output()?;
 
-    let mut data_buffer = vec![0; p1.buffer().len()];
-    data_buffer.copy_from_slice(p1.buffer());
-
-    match PersistentObject::open(
+    let mut object = PersistentObject::open(
         ObjectStorageConstants::Private,
         &obj_id,
         DataFlag::ACCESS_READ | DataFlag::SHARE_READ,
-    ) {
-        Err(e) => Err(e),
+    )?;
+    let obj_info = object.info()?;
 
-        Ok(mut object) => {
-            let obj_info = object.info()?;
-
-            if obj_info.data_size() > p1.buffer().len() {
-                p1.set_updated_size(obj_info.data_size());
-                return Err(ErrorKind::ShortBuffer.into());
-            }
-            let read_bytes = object.read(&mut data_buffer)?;
-            if read_bytes != obj_info.data_size() as u32 {
-                return Err(ErrorKind::ExcessData.into());
-            }
+    let read_bytes = object.read(p1.get_buffer_mut())?;
+    if read_bytes != obj_info.data_size() as u32 {
+        return Err(ErrorKind::ExcessData.into());
+    }
 
-            p1.set_updated_size(read_bytes as usize);
-            p1.buffer().copy_from_slice(&data_buffer);
+    p1.set_updated_size(read_bytes as usize)?;
 
-            Ok(())
-        }
-    }
+    Ok(())
 }
 
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/serde-rs/ta/Cargo.lock b/examples/serde-rs/ta/Cargo.lock
index 2864773..b6e7e42 100644
--- a/examples/serde-rs/ta/Cargo.lock
+++ b/examples/serde-rs/ta/Cargo.lock
@@ -4,21 +4,18 @@ version = 4
 
 [[package]]
 name = "bitflags"
-version = "1.3.2"
+version = "2.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
 
 [[package]]
-name = "bumpalo"
-version = "3.19.0"
+name = "document-features"
+version = "0.2.12"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
-
-[[package]]
-name = "cfg-if"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
+checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61"
+dependencies = [
+ "litrs",
+]
 
 [[package]]
 name = "heck"
@@ -38,28 +35,18 @@ version = "1.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
 
-[[package]]
-name = "js-sys"
-version = "0.3.82"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65"
-dependencies = [
- "once_cell",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "libc"
-version = "0.2.177"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
-
 [[package]]
 name = "libc_alloc"
 version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "7581282928bc99698341d1de7590964c28db747c164eaac9409432a3eaed098a"
 
+[[package]]
+name = "litrs"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
+
 [[package]]
 name = "memchr"
 version = "2.7.6"
@@ -68,9 +55,9 @@ checksum = 
"f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
 
 [[package]]
 name = "num_enum"
-version = "0.7.5"
+version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c"
+checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26"
 dependencies = [
  "num_enum_derive",
  "rustversion",
@@ -78,49 +65,44 @@ dependencies = [
 
 [[package]]
 name = "num_enum_derive"
-version = "0.7.5"
+version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7"
+checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8"
 dependencies = [
  "proc-macro2",
  "quote",
  "syn",
 ]
 
-[[package]]
-name = "once_cell"
-version = "1.21.3"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
-
 [[package]]
 name = "optee-utee"
-version = "0.8.0"
+version = "0.9.0"
 dependencies = [
  "bitflags",
+ "document-features",
  "hex",
  "libc_alloc",
+ "num_enum",
  "optee-utee-macros",
  "optee-utee-sys",
- "rustc_version",
- "strum_macros",
- "uuid 0.8.2",
+ "strum",
+ "uuid",
 ]
 
 [[package]]
 name = "optee-utee-build"
-version = "0.8.0"
+version = "0.9.0"
 dependencies = [
  "prettyplease",
  "proc-macro2",
  "quote",
  "syn",
- "uuid 1.22.0",
+ "uuid",
 ]
 
 [[package]]
 name = "optee-utee-macros"
-version = "0.8.0"
+version = "0.9.0"
 dependencies = [
  "quote",
  "syn",
@@ -128,9 +110,9 @@ dependencies = [
 
 [[package]]
 name = "optee-utee-sys"
-version = "0.8.0"
+version = "0.9.0"
 dependencies = [
- "libc",
+ "document-features",
 ]
 
 [[package]]
@@ -169,15 +151,6 @@ dependencies = [
  "proc-macro2",
 ]
 
-[[package]]
-name = "rustc_version"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
-dependencies = [
- "semver",
-]
-
 [[package]]
 name = "rustversion"
 version = "1.0.22"
@@ -190,12 +163,6 @@ version = "1.0.20"
 source = "registry+https://github.com/rust-lang/crates.io-index";
 checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
 
-[[package]]
-name = "semver"
-version = "1.0.27"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
-
 [[package]]
 name = "serde"
 version = "1.0.228"
@@ -239,16 +206,24 @@ dependencies = [
  "serde_core",
 ]
 
+[[package]]
+name = "strum"
+version = "0.28.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd"
+dependencies = [
+ "strum_macros",
+]
+
 [[package]]
 name = "strum_macros"
-version = "0.26.4"
+version = "0.28.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
+checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664"
 dependencies = [
  "heck",
  "proc-macro2",
  "quote",
- "rustversion",
  "syn",
 ]
 
@@ -283,61 +258,6 @@ checksum = 
"9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
 
 [[package]]
 name = "uuid"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
-
-[[package]]
-name = "uuid"
-version = "1.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "wasm-bindgen"
-version = "0.2.105"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60"
-dependencies = [
- "cfg-if",
- "once_cell",
- "rustversion",
- "wasm-bindgen-macro",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-macro"
-version = "0.2.105"
+version = "1.23.3"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2"
-dependencies = [
- "quote",
- "wasm-bindgen-macro-support",
-]
-
-[[package]]
-name = "wasm-bindgen-macro-support"
-version = "0.2.105"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc"
-dependencies = [
- "bumpalo",
- "proc-macro2",
- "quote",
- "syn",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-shared"
-version = "0.2.105"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76"
-dependencies = [
- "unicode-ident",
-]
+checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7"
diff --git a/examples/serde-rs/ta/src/main.rs b/examples/serde-rs/ta/src/main.rs
index 67424eb..1a342ed 100644
--- a/examples/serde-rs/ta/src/main.rs
+++ b/examples/serde-rs/ta/src/main.rs
@@ -20,11 +20,8 @@
 
 extern crate alloc;
 
-use alloc::string::String;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::prelude::*;
+use optee_utee::{ErrorKind, Result};
 use proto::{Command, Point};
 
 #[ta_create]
@@ -34,7 +31,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> Result<()> {
+fn open_session(_params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -50,34 +47,19 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, (p0, _, _, _): &mut ParametersAny<'_>) -> 
Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
         Command::DefaultOp => {
-            let mut p = unsafe { params.0.as_memref()? };
-            let buffer = p.buffer();
+            let output = p0.as_memref_output()?;
             let point = Point { x: 1, y: 2 };
 
             // Convert the Point to a JSON string.
-            let serialized: String = serde_json::to_string(&point).map_err(|e| 
{
+            let serialized = serde_json::to_string(&point).map_err(|e| {
                 trace_println!("Failed to serialize point: {}", e);
                 ErrorKind::BadParameters
             })?;
-
-            let bytes = serialized.as_bytes();
-
-            // Ensure the buffer is large enough to hold the serialized data.
-            let len = bytes.len();
-            if len > buffer.len() {
-                trace_println!("Buffer too small, cannot copy all bytes");
-                return Err(ErrorKind::BadParameters.into());
-            }
-
-            // Copy the serialized JSON string into the buffer.
-            buffer[..len].copy_from_slice(bytes);
-
-            // update size of output buffer
-            p.set_updated_size(len);
+            output.set_output(serialized.as_bytes())?;
 
             // Prints serialized = {"x":1,"y":2}
             trace_println!("serialized = {}", serialized);
diff --git a/examples/signature_verification-rs/ta/src/main.rs 
b/examples/signature_verification-rs/ta/src/main.rs
index 7a11467..cf404a0 100644
--- a/examples/signature_verification-rs/ta/src/main.rs
+++ b/examples/signature_verification-rs/ta/src/main.rs
@@ -21,11 +21,9 @@
 extern crate alloc;
 
 use alloc::vec;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
+use optee_utee::prelude::*;
 use optee_utee::{AlgorithmId, Asymmetric, AttributeId, AttributeMemref, 
Digest, OperationMode};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::{ErrorKind, Result};
 use optee_utee::{GenericObject, TransientObject, TransientObjectType};
 use proto::Command;
 
@@ -48,7 +46,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> Result<()> {
+fn open_session(_params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -63,38 +61,24 @@ fn destroy() {
     trace_println!("[+] TA destroy");
 }
 
-fn sign(params: &mut Parameters) -> Result<()> {
-    let mut p0 = unsafe { params.0.as_memref()? };
-    let mut p1 = unsafe { params.1.as_memref()? };
-    let mut p2 = unsafe { params.2.as_memref()? };
-    let message = p0.buffer();
-    let mut pub_key_size: usize = 0;
-    trace_println!("[+] message: {:?}", &message);
+fn sign((p0, p1, p2, _): &mut ParametersAny<'_>) -> Result<()> {
+    let p0 = p0.as_memref_input()?;
+    let p1 = p1.as_memref_output()?;
+    let p2 = p2.as_memref_output()?;
+    let message = p0.get_buffer();
+    trace_println!("[+] message: {:?}", message);
 
     let rsa_key = TransientObject::allocate(TransientObjectType::RsaKeypair, 
2048_usize)?;
 
     rsa_key.generate_key(2048_usize, &[])?;
 
-    match rsa_key.ref_attribute(AttributeId::RsaModulus, p1.buffer()) {
-        Ok(len) => {
-            pub_key_size += len;
-            Ok(())
-        }
-        Err(e) => Err(e),
-    }?;
-
-    match rsa_key.ref_attribute(
-        AttributeId::RsaPublicExponent,
-        &mut p1.buffer()[pub_key_size..],
-    ) {
-        Ok(len) => {
-            pub_key_size += len;
-            Ok(())
-        }
-        Err(e) => Err(e),
-    }?;
-
-    p1.set_updated_size(pub_key_size);
+    {
+        let buffer = p1.get_buffer_mut();
+        let modulus_len = rsa_key.ref_attribute(AttributeId::RsaModulus, 
buffer)?;
+        let exp_len =
+            rsa_key.ref_attribute(AttributeId::RsaPublicExponent, &mut 
buffer[modulus_len..])?;
+        p1.set_updated_size(modulus_len + exp_len)?;
+    };
 
     let mut hash = [0u8; 32];
     let dig = Digest::allocate(AlgorithmId::Sha256)?;
@@ -102,40 +86,31 @@ fn sign(params: &mut Parameters) -> Result<()> {
     dig.do_final(message, &mut hash)?;
 
     let key_info = rsa_key.info()?;
-    let signature = p2.buffer();
 
-    let rsa = Asymmetric::allocate(
+    let mut rsa = Asymmetric::allocate(
         AlgorithmId::RsassaPkcs1V15Sha256,
         OperationMode::Sign,
         key_info.object_size(),
     )?;
 
     rsa.set_key(&rsa_key)?;
-    match rsa.sign_digest(&[], &hash, signature) {
-        Ok(len) => {
-            trace_println!("[+] signature: {:?}", p2.buffer());
-            p2.set_updated_size(len);
-            Ok(())
-        }
-        Err(e) => {
-            trace_println!("[+] error: {:?}", e);
-            Err(ErrorKind::SignatureInvalid.into())
-        }
-    }
+    let len = rsa.sign_digest(&[], &hash, p2.get_buffer_mut())?;
+    p2.set_updated_size(len)?;
+    Ok(())
 }
 
-fn verify(params: &mut Parameters) -> Result<()> {
-    let mut p0 = unsafe { params.0.as_memref()? };
-    let mut p1 = unsafe { params.1.as_memref()? };
-    let mut p2 = unsafe { params.2.as_memref()? };
+fn verify((p0, p1, p2, _): &mut ParametersAny<'_>) -> Result<()> {
+    let p0 = p0.as_memref_input()?;
+    let p1 = p1.as_memref_input()?;
+    let p2 = p2.as_memref_input()?;
 
-    let message = p0.buffer();
+    let message = p0.get_buffer();
     let mut pub_key_mod = vec![0u8; 256];
-    let mut pub_key_exp = vec![0u8; p1.buffer().len() - 256];
-    let signature = p2.buffer();
+    let mut pub_key_exp = vec![0u8; p1.get_buffer().len() - 256];
+    let signature = p2.get_buffer();
 
-    pub_key_mod.copy_from_slice(&p1.buffer()[..256]);
-    pub_key_exp.copy_from_slice(&p1.buffer()[256..]);
+    pub_key_mod.copy_from_slice(&p1.get_buffer()[..256]);
+    pub_key_exp.copy_from_slice(&p1.get_buffer()[256..]);
 
     trace_println!("[+] message: {:?}", &message);
     trace_println!("[+] public_key_mod: {:?}", &pub_key_mod);
@@ -156,7 +131,7 @@ fn verify(params: &mut Parameters) -> Result<()> {
 
     let key_info = rsa_pub_key.info()?;
 
-    let rsa = Asymmetric::allocate(
+    let mut rsa = Asymmetric::allocate(
         AlgorithmId::RsassaPkcs1V15Sha256,
         OperationMode::Verify,
         key_info.object_size(),
@@ -176,7 +151,7 @@ fn verify(params: &mut Parameters) -> Result<()> {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, params: &mut ParametersAny<'_>) -> Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
         Command::Sign => sign(params),
diff --git a/examples/supp_plugin-rs/ta/src/main.rs 
b/examples/supp_plugin-rs/ta/src/main.rs
index 89f09cc..2379a4f 100644
--- a/examples/supp_plugin-rs/ta/src/main.rs
+++ b/examples/supp_plugin-rs/ta/src/main.rs
@@ -20,11 +20,9 @@
 
 extern crate alloc;
 
+use optee_utee::prelude::*;
 use optee_utee::LoadablePlugin;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result, Uuid};
+use optee_utee::{ErrorKind, Result, Uuid};
 use proto::{Command, PluginCommand, PLUGIN_SUBCMD_NULL, PLUGIN_UUID};
 
 #[ta_create]
@@ -34,7 +32,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> Result<()> {
+fn open_session(_params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -50,20 +48,23 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, (p0, _, _, _): &mut ParametersAny<'_>) -> 
Result<()> {
     trace_println!("[+] TA invoke command");
-    let mut p0 = unsafe { params.0.as_memref()? };
-    let inbuf = p0.buffer().to_vec();
+    let p0 = p0.as_memref_input()?;
     trace_println!(
         "[+] TA received value {:?} then send to plugin",
-        p0.buffer()
+        p0.get_buffer()
     );
     let uuid = Uuid::parse_str(PLUGIN_UUID)?;
 
     match Command::from(cmd_id) {
         Command::Ping => {
             let plugin = LoadablePlugin::new(&uuid);
-            let outbuf = plugin.invoke(PluginCommand::Print as u32, 
PLUGIN_SUBCMD_NULL, &inbuf)?;
+            let outbuf = plugin.invoke(
+                PluginCommand::Print as u32,
+                PLUGIN_SUBCMD_NULL,
+                p0.get_buffer(),
+            )?;
 
             trace_println!(
                 "[+] TA received out value {:?} outlen {:?}",
diff --git a/examples/tcp_client-rs/ta/src/main.rs 
b/examples/tcp_client-rs/ta/src/main.rs
index b86f092..be0abd9 100644
--- a/examples/tcp_client-rs/ta/src/main.rs
+++ b/examples/tcp_client-rs/ta/src/main.rs
@@ -38,10 +38,8 @@ cfg_block::cfg_block! {
 }
 
 use optee_utee::net::TcpStream;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::prelude::*;
+use optee_utee::{ErrorKind, Result};
 use proto::{Command, IpVersion};
 
 #[ta_create]
@@ -51,7 +49,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> Result<()> {
+fn open_session(_params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -67,26 +65,26 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, (p0, p1, p2, _): &mut ParametersAny<'_>) -> 
Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
         Command::Start => {
             use core::convert::TryFrom;
 
-            let mut param0 = unsafe { params.0.as_memref()? };
-            let param1 = unsafe { params.1.as_value()? };
-            let mut param2 = unsafe { params.2.as_memref()? };
+            let p0 = p0.as_memref_input()?;
+            let p1 = p1.as_value_input()?;
+            let p2 = p2.as_memref_input()?;
 
-            let address = core::str::from_utf8(param0.buffer()).map_err(|e| {
+            let address = core::str::from_utf8(p0.get_buffer()).map_err(|e| {
                 trace_println!("Failed to parse address from UTF-8: {}", e);
                 ErrorKind::BadParameters
             })?;
-            let port = param1.a() as u16;
-            let ip_version = IpVersion::try_from(param1.b()).map_err(|_| {
+            let port = p1.get_a() as u16;
+            let ip_version = IpVersion::try_from(p1.get_b()).map_err(|_| {
                 trace_println!("Invalid IP version parameter");
                 ErrorKind::BadParameters
             })?;
-            let http_data = param2.buffer();
+            let http_data = p2.get_buffer();
 
             tcp_client(address, port, ip_version, http_data)
         }
diff --git a/examples/time-rs/ta/src/main.rs b/examples/time-rs/ta/src/main.rs
index 7b12a80..f7d0932 100644
--- a/examples/time-rs/ta/src/main.rs
+++ b/examples/time-rs/ta/src/main.rs
@@ -18,11 +18,9 @@
 #![cfg_attr(not(feature = "std"), no_std)]
 #![no_main]
 
+use optee_utee::prelude::*;
 use optee_utee::Time;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::{ErrorKind, Result};
 use proto::Command;
 
 #[ta_create]
@@ -32,7 +30,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> Result<()> {
+fn open_session(_params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -48,7 +46,7 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, _params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, _params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
         Command::Test => {
diff --git a/examples/tls_client-rs/ta/Cargo.lock 
b/examples/tls_client-rs/ta/Cargo.lock
index bf87f03..adcde52 100644
--- a/examples/tls_client-rs/ta/Cargo.lock
+++ b/examples/tls_client-rs/ta/Cargo.lock
@@ -515,6 +515,7 @@ dependencies = [
  "document-features",
  "hex",
  "libc_alloc",
+ "num_enum",
  "optee-utee-macros",
  "optee-utee-sys",
  "strum",
diff --git a/examples/tls_client-rs/ta/src/main.rs 
b/examples/tls_client-rs/ta/src/main.rs
index 5690627..cc6c4f5 100644
--- a/examples/tls_client-rs/ta/src/main.rs
+++ b/examples/tls_client-rs/ta/src/main.rs
@@ -18,11 +18,9 @@
 #![no_main]
 
 use anyhow::Context;
+use optee_utee::prelude::*;
 use optee_utee::net::TcpStream;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::{ErrorKind, Result};
 use proto::Command;
 use rustls::RootCertStore;
 use std::convert::TryInto;
@@ -46,7 +44,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> Result<()> {
+fn open_session(_params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -62,7 +60,7 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, _params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, _params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
         Command::Start => match tls_client() {
@@ -91,7 +89,6 @@ fn tls_client() -> anyhow::Result<()> {
     let root_store = RootCertStore {
         roots: webpki_roots::TLS_SERVER_ROOTS.into(),
     };
-
     let config = rustls::ClientConfig::builder_with_details(crypto_provider, 
time_provider)
         .with_safe_default_protocol_versions()
         .context("Failed to create client config with safe default protocol 
versions")?
diff --git a/examples/tls_server-rs/host/src/main.rs 
b/examples/tls_server-rs/host/src/main.rs
index 099d96d..706003c 100644
--- a/examples/tls_server-rs/host/src/main.rs
+++ b/examples/tls_server-rs/host/src/main.rs
@@ -84,10 +84,9 @@ fn do_tls_write(
 ) -> optee_teec::Result<usize> {
     let p0 = ParamValue::new(session_id, 0, ParamType::ValueInput);
     let p1 = ParamTmpRef::new_output(buf);
-    let p2 = ParamValue::new(0, 0, ParamType::ValueOutput);
-    let mut operation = Operation::new(0, p0, p1, p2, ParamNone);
+    let mut operation = Operation::new(0, p0, p1, ParamNone, ParamNone);
     ta_session.invoke_command(Command::DoTlsWrite as u32, &mut operation)?;
-    Ok(operation.parameters().2.a() as usize)
+    Ok(operation.parameters().1.updated_size())
 }
 
 fn handle_client(
diff --git a/examples/tls_server-rs/ta/Cargo.lock 
b/examples/tls_server-rs/ta/Cargo.lock
index 14ffcdf..752dffd 100644
--- a/examples/tls_server-rs/ta/Cargo.lock
+++ b/examples/tls_server-rs/ta/Cargo.lock
@@ -515,6 +515,7 @@ dependencies = [
  "document-features",
  "hex",
  "libc_alloc",
+ "num_enum",
  "optee-utee-macros",
  "optee-utee-sys",
  "strum",
diff --git a/examples/tls_server-rs/ta/src/main.rs 
b/examples/tls_server-rs/ta/src/main.rs
index 12f7562..251deab 100644
--- a/examples/tls_server-rs/ta/src/main.rs
+++ b/examples/tls_server-rs/ta/src/main.rs
@@ -17,14 +17,11 @@
 
 #![no_main]
 
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result};
-use proto::Command;
-
 use anyhow::Context;
 use lazy_static::lazy_static;
+use optee_utee::prelude::*;
+use optee_utee::{ErrorKind, Result};
+use proto::Command;
 use rustls::pki_types::{pem::PemObject, CertificateDer, PrivateKeyDer};
 use std::collections::HashMap;
 use std::io::{Cursor, Read, Write};
@@ -52,7 +49,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> Result<()> {
+fn open_session(_params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -68,9 +65,9 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, params: &mut ParametersAny<'_>) -> Result<()> {
     trace_println!("[+] TA invoke command");
-    let session_id = unsafe { params.0.as_value()?.a() };
+    let session_id = params.0.as_value_input()?.get_a();
     trace_println!("[+] session id: {}", session_id);
     match Command::from(cmd_id) {
         Command::NewTlsSession => {
@@ -81,8 +78,8 @@ fn invoke_command(cmd_id: u32, params: &mut Parameters) -> 
Result<()> {
             })
         }
         Command::DoTlsRead => {
-            let mut p1 = unsafe { params.1.as_memref()? };
-            let buffer = p1.buffer();
+            let p1 = params.1.as_memref_input()?;
+            let buffer = p1.get_buffer();
             trace_println!("[+] do_tls_read");
             do_tls_read(session_id, buffer).map_err(|e| {
                 trace_println!("[-] Failed to read TLS data: {:?}", e);
@@ -91,17 +88,12 @@ fn invoke_command(cmd_id: u32, params: &mut Parameters) -> 
Result<()> {
         }
         Command::DoTlsWrite => {
             trace_println!("[+] do_tls_write");
-            let mut p1 = unsafe { params.1.as_memref()? };
-            let mut p2 = unsafe { params.2.as_value()? };
-            let buffer = p1.buffer();
-            do_tls_write(session_id, buffer)
-                .map(|n| {
-                    p2.set_a(n as u32);
-                })
-                .map_err(|e| {
-                    trace_println!("[-] Failed to write TLS data: {:?}", e);
-                    ErrorKind::Generic.into()
-                })
+            let p1 = params.1.as_memref_output()?;
+            let lens = do_tls_write(session_id, 
p1.get_buffer_mut()).map_err(|e| {
+                trace_println!("[-] Failed to write TLS data: {:?}", e);
+                ErrorKind::Generic
+            })?;
+            p1.set_updated_size(lens)
         }
         Command::CloseTlsSession => {
             trace_println!("[+] close_tls_session");
diff --git a/examples/udp_socket-rs/ta/src/main.rs 
b/examples/udp_socket-rs/ta/src/main.rs
index 8e41e38..b814f06 100644
--- a/examples/udp_socket-rs/ta/src/main.rs
+++ b/examples/udp_socket-rs/ta/src/main.rs
@@ -39,10 +39,8 @@ cfg_block::cfg_block! {
 
 use core::convert::TryFrom;
 use optee_utee::net::UdpSocket;
-use optee_utee::{
-    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
-};
-use optee_utee::{ErrorKind, Parameters, Result};
+use optee_utee::prelude::*;
+use optee_utee::{ErrorKind, Result};
 use proto::{Command, IpVersion};
 
 #[ta_create]
@@ -52,7 +50,7 @@ fn create() -> Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> Result<()> {
+fn open_session(_params: &mut ParametersNone) -> Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -68,19 +66,19 @@ fn destroy() {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, params: &mut ParametersAny<'_>) -> Result<()> {
     trace_println!("[+] TA invoke command");
     match Command::from(cmd_id) {
         Command::Start => {
-            let mut param0 = unsafe { params.0.as_memref()? };
-            let param1 = unsafe { params.1.as_value()? };
+            let param0 = params.0.as_memref_input()?;
+            let param1 = params.1.as_value_input()?;
 
-            let address = core::str::from_utf8(param0.buffer()).map_err(|e| {
+            let address = 
core::str::from_utf8(param0.get_buffer()).map_err(|e| {
                 trace_println!("Failed to parse address from UTF-8: {}", e);
                 ErrorKind::BadParameters
             })?;
-            let port = param1.a() as u16;
-            let ip_version = IpVersion::try_from(param1.b()).map_err(|_| {
+            let port = param1.get_a() as u16;
+            let ip_version = IpVersion::try_from(param1.get_b()).map_err(|_| {
                 trace_println!("Invalid IP version parameter");
                 ErrorKind::BadParameters
             })?;
diff --git a/projects/web3/eth_wallet/host/src/main.rs 
b/projects/web3/eth_wallet/host/src/main.rs
index 6c4d71a..a788d01 100644
--- a/projects/web3/eth_wallet/host/src/main.rs
+++ b/projects/web3/eth_wallet/host/src/main.rs
@@ -18,10 +18,10 @@
 mod cli;
 mod tests;
 
-use optee_teec::{Context, Operation, ParamType, Uuid};
-use optee_teec::{ParamNone, ParamTmpRef, ParamValue};
+use optee_teec::{Context, Operation, Uuid};
+use optee_teec::{ParamNone, ParamTmpRef};
 
-use anyhow::{bail, Result};
+use anyhow::Result;
 use structopt::StructOpt;
 
 const OUTPUT_MAX_SIZE: usize = 1024;
@@ -38,18 +38,16 @@ fn invoke_command(command: proto::Command, input: &[u8]) -> 
optee_teec::Result<V
     // 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);
+    let mut operation = Operation::new(0, p0, p1, ParamNone, 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;
+            let output_len = operation.parameters().1.updated_size();
             Ok(output[..output_len].to_vec())
         }
         Err(e) => {
-            let output_len = operation.parameters().2.a() as usize;
+            let output_len = operation.parameters().1.updated_size();
             let err_message = String::from_utf8_lossy(&output[..output_len]);
             println!("CA: invoke_command failed: {:?}", err_message);
             Err(e)
@@ -144,9 +142,6 @@ fn main() -> Result<()> {
             tests::tests::test_workflow();
             println!("Tests passed");
         }
-        _ => {
-            bail!("Unsupported command");
-        }
     }
     Ok(())
 }
diff --git a/projects/web3/eth_wallet/ta/Cargo.lock 
b/projects/web3/eth_wallet/ta/Cargo.lock
index 318983b..6274f3a 100644
--- a/projects/web3/eth_wallet/ta/Cargo.lock
+++ b/projects/web3/eth_wallet/ta/Cargo.lock
@@ -474,6 +474,7 @@ dependencies = [
  "document-features",
  "hex",
  "libc_alloc",
+ "num_enum",
  "optee-utee-macros",
  "optee-utee-sys",
  "strum",
diff --git a/projects/web3/eth_wallet/ta/src/main.rs 
b/projects/web3/eth_wallet/ta/src/main.rs
index c61142a..69e3a96 100644
--- a/projects/web3/eth_wallet/ta/src/main.rs
+++ b/projects/web3/eth_wallet/ta/src/main.rs
@@ -20,15 +20,12 @@
 mod hash;
 mod wallet;
 
-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 optee_utee::prelude::*;
+use optee_utee::{Error, ErrorKind};
 use proto::Command;
 use secure_db::SecureStorageClient;
 
 use anyhow::{anyhow, bail, Result};
-use std::io::Write;
 use wallet::Wallet;
 
 const DB_NAME: &str = "eth_wallet_db";
@@ -40,7 +37,7 @@ fn create() -> optee_utee::Result<()> {
 }
 
 #[ta_open_session]
-fn open_session(_params: &mut Parameters) -> optee_utee::Result<()> {
+fn open_session(_params: &mut ParametersNone) -> optee_utee::Result<()> {
     trace_println!("[+] TA open session");
     Ok(())
 }
@@ -142,28 +139,27 @@ fn handle_invoke(command: Command, serialized_input: 
&[u8]) -> Result<Vec<u8>> {
 }
 
 #[ta_invoke_command]
-fn invoke_command(cmd_id: u32, params: &mut Parameters) -> 
optee_utee::Result<()> {
+fn invoke_command(
+    cmd_id: u32,
+    (p0, p1, _, _): &mut (
+        ParameterMemrefInput<'_>,
+        ParameterMemrefOutput<'_>,
+        ParameterNone,
+        ParameterNone,
+    ),
+) -> optee_utee::Result<()> {
     dbg_println!("[+] TA invoke command");
-    let mut p0 = unsafe { params.0.as_memref()? };
-    let mut p1 = unsafe { params.1.as_memref()? };
-    let mut p2 = unsafe { params.2.as_value()? };
 
-    let output_vec = match handle_invoke(Command::from(cmd_id), p0.buffer()) {
+    p1.set_updated_size(0)?;
+    let output_vec = match handle_invoke(Command::from(cmd_id), 
p0.get_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);
+            let err_message = format!("{:?}", e);
+            p1.set_output(err_message)?;
             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);
-
+    p1.set_output(output_vec)?;
     Ok(())
 }
 


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

Reply via email to