diff --git a/security/see/hwcrypto/aidl/vts/functional/Android.bp b/security/see/hwcrypto/aidl/vts/functional/Android.bp
index 2aea077..eb2eba1 100644
--- a/security/see/hwcrypto/aidl/vts/functional/Android.bp
+++ b/security/see/hwcrypto/aidl/vts/functional/Android.bp
@@ -65,3 +65,19 @@
         "vts",
     ],
 }
+
+rust_test {
+    name: "VtsAidlHwCryptoOperationsTests",
+    srcs: ["hwcrypto_operations_tests.rs"],
+    require_root: true,
+    defaults: [
+        "hw_crypto_hal_aidl_rust_defaults",
+    ],
+    rustlibs: [
+        "libhwcryptohal_vts_test",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/security/see/hwcrypto/aidl/vts/functional/hwcrypto_operations_tests.rs b/security/see/hwcrypto/aidl/vts/functional/hwcrypto_operations_tests.rs
new file mode 100644
index 0000000..521fb73
--- /dev/null
+++ b/security/see/hwcrypto/aidl/vts/functional/hwcrypto_operations_tests.rs
@@ -0,0 +1,586 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed 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.
+ */
+
+//! HwCryptoOperations tests.
+
+use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::types::{
+    AesKey::AesKey, ExplicitKeyMaterial::ExplicitKeyMaterial, KeyType::KeyType, KeyLifetime::KeyLifetime,
+    KeyUse::KeyUse, OperationData::OperationData, HmacOperationParameters::HmacOperationParameters,
+    SymmetricOperationParameters::SymmetricOperationParameters, SymmetricOperation::SymmetricOperation,
+    HmacKey::HmacKey, CipherModeParameters::CipherModeParameters, AesCipherMode::AesCipherMode,
+    SymmetricCryptoParameters::SymmetricCryptoParameters,
+};
+use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::{
+    KeyPolicy::KeyPolicy,CryptoOperation::CryptoOperation,CryptoOperationSet::CryptoOperationSet,
+    OperationParameters::OperationParameters, PatternParameters::PatternParameters,
+};
+
+#[test]
+fn test_hwcrypto_key_operations_connection() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let hw_crypto_operations = hw_crypto_key.getHwCryptoOperations();
+    assert!(hw_crypto_operations.is_ok(), "Couldn't get back a hwcrypto operations binder object");
+}
+
+#[test]
+fn test_hwcrypto_key_operations_simple_aes_test() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let hw_crypto_operations = hw_crypto_key
+        .getHwCryptoOperations()
+        .expect("Couldn't get back a hwcryptokey operations binder object");
+    let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
+    let policy = KeyPolicy {
+        usage: KeyUse::ENCRYPT_DECRYPT,
+        keyLifetime: KeyLifetime::PORTABLE,
+        keyPermissions: Vec::new(),
+        keyManagementKey: false,
+        keyType: KeyType::AES_128_CBC_PKCS7_PADDING,
+    };
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+    let nonce = [0u8; 16];
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::ENCRYPT;
+    let sym_op_params =
+        SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    let input_data = OperationData::DataBuffer("string to be encrypted".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    let mut op_result = hw_crypto_operations
+        .processCommandList(&mut crypto_sets)
+        .expect("couldn't process commands");
+    // Extracting the vector from the command list because of ownership
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+    let context = op_result.remove(0).context;
+    // Separating the finish call on a different command set to test the returned context
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(encrypted_data);
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+
+    // Decrypting
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::DECRYPT;
+    let sym_op_params = SymmetricOperationParameters { key: Some(key), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::DataInput(OperationData::DataBuffer(encrypted_data)));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+    // Extracting the vector from the command list because of ownership
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(decrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+    let decrypted_msg =
+        String::from_utf8(decrypted_data).expect("couldn't decode received message");
+    assert_eq!(decrypted_msg, "string to be encrypted", "couldn't retrieve original message");
+}
+
+#[test]
+fn test_hwcrypto_key_operations_simple_hmac_test() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let hw_crypto_operations = hw_crypto_key
+        .getHwCryptoOperations()
+        .expect("Couldn't get back a hwcryptokey operations binder object");
+    let clear_key = ExplicitKeyMaterial::Hmac(HmacKey::Sha256([0; 32]));
+    let policy = KeyPolicy {
+        usage: KeyUse::SIGN,
+        keyLifetime: KeyLifetime::PORTABLE,
+        keyPermissions: Vec::new(),
+        keyManagementKey: false,
+        keyType: KeyType::HMAC_SHA256,
+    };
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+    let hmac_parameters = HmacOperationParameters { key: Some(key.clone()) };
+    let op_parameters = OperationParameters::Hmac(hmac_parameters);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_parameters));
+    let input_data = OperationData::DataBuffer("text to be mac'ed".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+    // Extracting the vector from the command list because of ownership
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(mac)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+
+    //Getting a second mac to compare
+    let hmac_parameters = HmacOperationParameters { key: Some(key) };
+    let op_parameters = OperationParameters::Hmac(hmac_parameters);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_parameters));
+    let input_data = OperationData::DataBuffer("text to be mac'ed".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+    // Extracting the vector from the command list because of ownership
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(mac2)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+    assert_eq!(mac, mac2, "got a different mac");
+}
+
+#[test]
+fn test_hwcrypto_key_operations_aes_simple_cbcs_test_non_block_multiple() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let hw_crypto_operations = hw_crypto_key
+        .getHwCryptoOperations()
+        .expect("Couldn't get back a hwcryptokey operations binder object");
+
+    let usage = KeyUse::ENCRYPT_DECRYPT;
+    let key_type = KeyType::AES_128_CBC_NO_PADDING;
+    let policy = KeyPolicy {
+        usage,
+        keyLifetime: KeyLifetime::PORTABLE,
+        keyPermissions: Vec::new(),
+        keyType: key_type,
+        keyManagementKey: false,
+    };
+    let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+    let nonce = [0u8; 16];
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::ENCRYPT;
+    let sym_op_params =
+        SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+        numberBlocksProcess: 1,
+        numberBlocksCopy: 0,
+    }));
+    let input_data =
+        OperationData::DataBuffer("encryption data.0123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let input_data =
+        OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let input_data = OperationData::DataBuffer("unencrypted".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+
+    let clear_encrypted_msg =
+        String::from_utf8(encrypted_data[encrypted_data.len() - "unencrypted".len()..].to_vec())
+            .expect("couldn't decode message");
+    assert_eq!(clear_encrypted_msg, "unencrypted");
+
+    // Decrypting
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::DECRYPT;
+    let sym_op_params =
+        SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+        numberBlocksProcess: 1,
+        numberBlocksCopy: 0,
+    }));
+    cmd_list.push(CryptoOperation::DataInput(OperationData::DataBuffer(encrypted_data)));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(decrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+    let decrypted_msg =
+        String::from_utf8(decrypted_data).expect("couldn't decode received message");
+    assert_eq!(
+        decrypted_msg,
+        "encryption data.0123456789abcdeffedcba9876543210\
+        0123456789abcdefunencrypted",
+        "couldn't retrieve original message"
+    );
+}
+
+#[test]
+fn test_hwcrypto_key_operations_aes_simple_all_encrypted_cbcs_test() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let hw_crypto_operations = hw_crypto_key
+        .getHwCryptoOperations()
+        .expect("Couldn't get back a hwcryptokey operations binder object");
+
+    let usage = KeyUse::ENCRYPT_DECRYPT;
+    let key_type = KeyType::AES_128_CBC_NO_PADDING;
+    let policy = KeyPolicy {
+        usage,
+        keyLifetime: KeyLifetime::PORTABLE,
+        keyPermissions: Vec::new(),
+        keyType: key_type,
+        keyManagementKey: false,
+    };
+    let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+    let nonce = [0u8; 16];
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::ENCRYPT;
+    let sym_op_params =
+        SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+        numberBlocksProcess: 1,
+        numberBlocksCopy: 0,
+    }));
+    let input_data =
+        OperationData::DataBuffer("encryption data.0123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let input_data =
+        OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+
+    // Checking that encrypting with patter 0,0 is equivalent to pattern 1,0
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::ENCRYPT;
+    let sym_op_params =
+        SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+        numberBlocksProcess: 0,
+        numberBlocksCopy: 0,
+    }));
+    let input_data =
+        OperationData::DataBuffer("encryption data.0123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let input_data =
+        OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data1)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+    assert_eq!(encrypted_data, encrypted_data1, "encrypted data should match");
+
+    // Decrypting
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::DECRYPT;
+    let sym_op_params =
+        SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::DataInput(OperationData::DataBuffer(encrypted_data)));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(decrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+    let decrypted_msg =
+        String::from_utf8(decrypted_data).expect("couldn't decode received message");
+    assert_eq!(
+        decrypted_msg,
+        "encryption data.0123456789abcdeffedcba9876543210\
+        0123456789abcdef",
+        "couldn't retrieve original message"
+    );
+}
+
+#[test]
+fn check_cbcs_wrong_key_types() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let hw_crypto_operations = hw_crypto_key
+        .getHwCryptoOperations()
+        .expect("Couldn't get back a hwcryptokey operations binder object");
+
+    let usage = KeyUse::ENCRYPT_DECRYPT;
+    let key_type = KeyType::AES_128_CBC_PKCS7_PADDING;
+    let policy = KeyPolicy {
+        usage,
+        keyLifetime: KeyLifetime::PORTABLE,
+        keyPermissions: Vec::new(),
+        keyType: key_type,
+        keyManagementKey: false,
+    };
+    let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+    let nonce = [0u8; 16];
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::ENCRYPT;
+    let sym_op_params = SymmetricOperationParameters { key: Some(key), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+        numberBlocksProcess: 1,
+        numberBlocksCopy: 9,
+    }));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    let process_result = hw_crypto_operations.processCommandList(&mut crypto_sets);
+    assert!(process_result.is_err(), "Should not be able to use cbcs mode with this key type");
+
+    let policy = KeyPolicy {
+        usage,
+        keyLifetime: KeyLifetime::PORTABLE,
+        keyPermissions: Vec::new(),
+        keyType: KeyType::AES_256_CBC_NO_PADDING,
+        keyManagementKey: false,
+    };
+    let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes256([0; 32]));
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let sym_op_params = SymmetricOperationParameters { key: Some(key), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+        numberBlocksProcess: 1,
+        numberBlocksCopy: 9,
+    }));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    let process_result = hw_crypto_operations.processCommandList(&mut crypto_sets);
+
+    assert!(process_result.is_err(), "Should not be able to use cbcs mode with this key type");
+}
+
+#[test]
+fn aes_simple_cbcs_test() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let hw_crypto_operations = hw_crypto_key
+        .getHwCryptoOperations()
+        .expect("Couldn't get back a hwcryptokey operations binder object");
+
+    let usage = KeyUse::ENCRYPT_DECRYPT;
+    let key_type = KeyType::AES_128_CBC_NO_PADDING;
+    let policy = KeyPolicy {
+        usage,
+        keyLifetime: KeyLifetime::PORTABLE,
+        keyPermissions: Vec::new(),
+        keyType: key_type,
+        keyManagementKey: false,
+    };
+    let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+    let nonce = [0u8; 16];
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::ENCRYPT;
+    let sym_op_params =
+        SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+        numberBlocksProcess: 1,
+        numberBlocksCopy: 9,
+    }));
+    let input_data =
+        OperationData::DataBuffer("encryption data.0123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let input_data =
+        OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let input_data =
+        OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let input_data =
+        OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let input_data = OperationData::DataBuffer(
+        "fedcba98765432100123456789abcdefProtectedSection".as_bytes().to_vec(),
+    );
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+    let clear_encrypted_msg =
+        String::from_utf8(encrypted_data[16..encrypted_data.len() - 16].to_vec())
+            .expect("couldn't decode received message");
+    assert_eq!(
+        clear_encrypted_msg,
+        "0123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210\
+        0123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdef",
+        "couldn't retrieve clear portion"
+    );
+
+    // Decrypting
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::DECRYPT;
+    let sym_op_params =
+        SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+        numberBlocksProcess: 1,
+        numberBlocksCopy: 9,
+    }));
+    cmd_list.push(CryptoOperation::DataInput(OperationData::DataBuffer(encrypted_data)));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(decrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+    let decrypted_msg =
+        String::from_utf8(decrypted_data).expect("couldn't decode received message");
+    assert_eq!(
+        decrypted_msg,
+        "encryption data.0123456789abcdeffedcba9876543210\
+        0123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210\
+        0123456789abcdeffedcba98765432100123456789abcdefProtectedSection",
+        "couldn't retrieve original message"
+    );
+}
diff --git a/security/see/hwcrypto/aidl/vts/functional/lib.rs b/security/see/hwcrypto/aidl/vts/functional/lib.rs
index 81ae3fa..465dde7 100644
--- a/security/see/hwcrypto/aidl/vts/functional/lib.rs
+++ b/security/see/hwcrypto/aidl/vts/functional/lib.rs
@@ -17,61 +17,11 @@
 //! VTS test library for HwCrypto functionality.
 //! It provides the base clases necessaries to write HwCrypto VTS tests
 
-#[cfg(target_arch = "x86_64")]
-use anyhow::Context;
 use anyhow::Result;
-#[cfg(target_arch = "x86_64")]
-use binder::{ExceptionCode, FromIBinder, IntoBinderResult, ParcelFileDescriptor};
-#[cfg(target_arch = "x86_64")]
-use rpcbinder::RpcSession;
-#[cfg(target_arch = "x86_64")]
-use vsock::VsockStream;
-#[cfg(target_arch = "x86_64")]
-use std::os::fd::{FromRawFd, IntoRawFd};
-#[cfg(target_arch = "x86_64")]
-use std::fs::File;
-#[cfg(target_arch = "x86_64")]
-use std::io::Read;
-#[cfg(target_arch = "x86_64")]
-use rustutils::system_properties;
-#[cfg(target_arch = "aarch64")]
 use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::IHwCryptoKey::BpHwCryptoKey;
 use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::IHwCryptoKey::IHwCryptoKey;
 
-#[cfg(target_arch = "x86_64")]
-const HWCRYPTO_SERVICE_PORT: u32 = 4;
-
-/// Local function to connect to service
-#[cfg(target_arch = "x86_64")]
-pub fn connect_service<T: FromIBinder + ?Sized>(
-    cid: u32,
-    port: u32,
-) -> Result<binder::Strong<T>, binder::StatusCode> {
-    RpcSession::new().setup_preconnected_client(|| {
-        let mut stream = VsockStream::connect_with_cid_port(cid, port).ok()?;
-        let mut buffer = [0];
-        let _ = stream.read(&mut buffer);
-        // SAFETY: ownership is transferred from stream to f
-        let f = unsafe { File::from_raw_fd(stream.into_raw_fd()) };
-        Some(ParcelFileDescriptor::new(f).into_raw_fd())
-    })
-}
-
-/// Get a HwCryptoKey binder service object using a direct vsock connection
-#[cfg(target_arch = "x86_64")]
-pub fn get_hwcryptokey() -> Result<binder::Strong<dyn IHwCryptoKey>, binder::Status> {
-    let cid = system_properties::read("trusty.test_vm.vm_cid")
-        .context("couldn't get vm cid")
-        .or_binder_exception(ExceptionCode::ILLEGAL_STATE)?
-        .ok_or(ExceptionCode::ILLEGAL_STATE)?
-        .parse::<u32>()
-        .context("couldn't parse vm cid")
-        .or_binder_exception(ExceptionCode::ILLEGAL_ARGUMENT)?;
-    Ok(connect_service(cid, HWCRYPTO_SERVICE_PORT)?)
-}
-
 /// Get a HwCryptoKey binder service object using the service manager
-#[cfg(target_arch = "aarch64")]
 pub fn get_hwcryptokey() -> Result<binder::Strong<dyn IHwCryptoKey>, binder::Status> {
     let interface_name = <BpHwCryptoKey as IHwCryptoKey>::get_descriptor().to_owned() + "/default";
     Ok(binder::get_interface(&interface_name)?)
diff --git a/security/see/hwcrypto/default/hwcryptokeyimpl.h b/security/see/hwcrypto/default/hwcryptokeyimpl.h
index 19be8b4..7d3ade7 100644
--- a/security/see/hwcrypto/default/hwcryptokeyimpl.h
+++ b/security/see/hwcrypto/default/hwcryptokeyimpl.h
@@ -46,30 +46,33 @@
 
     ndk::ScopedAStatus deriveCurrentDicePolicyBoundKey(
             const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey& derivationKey,
-            ndk_hwcrypto::IHwCryptoKey::DiceCurrentBoundKeyResult* aidl_return);
+            ndk_hwcrypto::IHwCryptoKey::DiceCurrentBoundKeyResult* aidl_return) override;
 
     ndk::ScopedAStatus deriveDicePolicyBoundKey(
             const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey& derivationKey,
             const ::std::vector<uint8_t>& dicePolicyForKeyVersion,
-            ndk_hwcrypto::IHwCryptoKey::DiceBoundKeyResult* aidl_return);
+            ndk_hwcrypto::IHwCryptoKey::DiceBoundKeyResult* aidl_return) override;
     ndk::ScopedAStatus deriveKey(const ndk_hwcrypto::IHwCryptoKey::DerivedKeyParameters& parameters,
-                                 ndk_hwcrypto::IHwCryptoKey::DerivedKey* aidl_return);
+                                 ndk_hwcrypto::IHwCryptoKey::DerivedKey* aidl_return) override;
 
     ndk::ScopedAStatus getHwCryptoOperations(
-            std::shared_ptr<ndk_hwcrypto::IHwCryptoOperations>* aidl_return);
+            std::shared_ptr<ndk_hwcrypto::IHwCryptoOperations>* aidl_return) override;
 
-    ndk::ScopedAStatus importClearKey(const ndk_hwcrypto::types::ExplicitKeyMaterial& keyMaterial,
-                                      const ndk_hwcrypto::KeyPolicy& newKeyPolicy,
-                                      std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return);
+    ndk::ScopedAStatus importClearKey(
+            const ndk_hwcrypto::types::ExplicitKeyMaterial& keyMaterial,
+            const ndk_hwcrypto::KeyPolicy& newKeyPolicy,
+            std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return) override;
 
-    ndk::ScopedAStatus getCurrentDicePolicy(std::vector<uint8_t>* aidl_return);
+    ndk::ScopedAStatus getCurrentDicePolicy(std::vector<uint8_t>* aidl_return) override;
 
-    ndk::ScopedAStatus keyTokenImport(const ndk_hwcrypto::types::OpaqueKeyToken& requestedKey,
-                                      const ::std::vector<uint8_t>& sealingDicePolicy,
-                                      std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return);
+    ndk::ScopedAStatus keyTokenImport(
+            const ndk_hwcrypto::types::OpaqueKeyToken& requestedKey,
+            const ::std::vector<uint8_t>& sealingDicePolicy,
+            std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return) override;
 
-    ndk::ScopedAStatus getKeyslotData(ndk_hwcrypto::IHwCryptoKey::KeySlot slotId,
-                                      std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return);
+    ndk::ScopedAStatus getKeyslotData(
+            ndk_hwcrypto::IHwCryptoKey::KeySlot slotId,
+            std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return) override;
 };
 
 template <typename LHP, typename RHP>
@@ -79,9 +82,10 @@
     policy.keyLifetime = static_cast<decltype(policy.keyLifetime)>(policyToConvert.keyLifetime);
     policy.keyType = static_cast<decltype(policy.keyType)>(policyToConvert.keyType);
     policy.keyManagementKey = policyToConvert.keyManagementKey;
+    policy.keyPermissions.reserve(policyToConvert.keyPermissions.size());
     for (auto permission : policyToConvert.keyPermissions) {
         policy.keyPermissions.push_back(
-                std::move(reinterpret_cast<decltype(policy.keyPermissions[0])>(permission)));
+                std::move(static_cast<decltype(policy.keyPermissions)::value_type>(permission)));
     }
     return policy;
 }
diff --git a/security/see/hwcrypto/default/hwcryptolib.cpp b/security/see/hwcrypto/default/hwcryptolib.cpp
index b168707..5babc23 100644
--- a/security/see/hwcrypto/default/hwcryptolib.cpp
+++ b/security/see/hwcrypto/default/hwcryptolib.cpp
@@ -115,11 +115,14 @@
 class HwCryptoOperationContextNdk : public ndk_hwcrypto::BnCryptoOperationContext {
   private:
     sp<cpp_hwcrypto::ICryptoOperationContext> mContext;
+    std::weak_ptr<ndk_hwcrypto::ICryptoOperationContext> self;
 
   public:
     HwCryptoOperationContextNdk(sp<cpp_hwcrypto::ICryptoOperationContext> operations)
         : mContext(std::move(operations)) {}
 
+    ~HwCryptoOperationContextNdk() { contextMapping.erase(self); }
+
     static std::shared_ptr<HwCryptoOperationContextNdk> Create(
             sp<cpp_hwcrypto::ICryptoOperationContext> operations) {
         if (operations == nullptr) {
@@ -132,18 +135,18 @@
             LOG(ERROR) << "failed to allocate HwCryptoOperationContext";
             return nullptr;
         }
+        contextNdk->self = contextNdk;
         return contextNdk;
     }
 };
 
-// TODO: Check refactoring opportunities like returning a Result<cpp_hwcrypto::types::OperationData>
-//       once we add the code that uses this function.
-Result<void> setOperationData(const ndk_hwcrypto::types::OperationData& ndkOperationData,
-                              cpp_hwcrypto::types::OperationData* cppOperationData) {
+std::optional<cpp_hwcrypto::types::OperationData> convertOperationData(
+        const ndk_hwcrypto::types::OperationData& ndkOperationData) {
+    cpp_hwcrypto::types::OperationData cppOperationData = cpp_hwcrypto::types::OperationData();
     cpp_hwcrypto::types::MemoryBufferReference cppMemBuffRef;
     switch (ndkOperationData.getTag()) {
         case ndk_hwcrypto::types::OperationData::dataBuffer:
-            cppOperationData->set<cpp_hwcrypto::types::OperationData::dataBuffer>(
+            cppOperationData.set<cpp_hwcrypto::types::OperationData::dataBuffer>(
                     ndkOperationData.get<ndk_hwcrypto::types::OperationData::dataBuffer>());
             break;
         case ndk_hwcrypto::types::OperationData::memoryBufferReference:
@@ -155,14 +158,223 @@
                     ndkOperationData
                             .get<ndk_hwcrypto::types::OperationData::memoryBufferReference>()
                             .sizeBytes;
-            cppOperationData->set<cpp_hwcrypto::types::OperationData::memoryBufferReference>(
+            cppOperationData.set<cpp_hwcrypto::types::OperationData::memoryBufferReference>(
                     std::move(cppMemBuffRef));
             break;
         default:
-            // This shouldn't happen with the current definitions
-            return ErrnoError() << "received unknown operation data type";
+            LOG(ERROR) << "received unknown operation data type";
+            return std::nullopt;
     }
-    return {};
+    return cppOperationData;
+}
+
+std::optional<cpp_hwcrypto::PatternParameters> convertPatternParameters(
+        const ndk_hwcrypto::PatternParameters& ndkpatternParameters) {
+    int64_t numberBlocksProcess = ndkpatternParameters.numberBlocksProcess;
+    int64_t numberBlocksCopy = ndkpatternParameters.numberBlocksCopy;
+    if ((numberBlocksProcess < 0) || (numberBlocksCopy < 0)) {
+        LOG(ERROR) << "received invalid pattern parameters";
+        return std::nullopt;
+    }
+    cpp_hwcrypto::PatternParameters patternParameters = cpp_hwcrypto::PatternParameters();
+    patternParameters.numberBlocksProcess = numberBlocksProcess;
+    patternParameters.numberBlocksCopy = numberBlocksCopy;
+    return patternParameters;
+}
+
+std::optional<cpp_hwcrypto::types::SymmetricOperation> convertSymmetricOperation(
+        const ndk_hwcrypto::types::SymmetricOperation& ndkSymmetricOperation) {
+    cpp_hwcrypto::types::SymmetricOperation symmetricOperation =
+            cpp_hwcrypto::types::SymmetricOperation();
+    switch (ndkSymmetricOperation) {
+        case ndk_hwcrypto::types::SymmetricOperation::ENCRYPT:
+            symmetricOperation = cpp_hwcrypto::types::SymmetricOperation::ENCRYPT;
+            break;
+        case ndk_hwcrypto::types::SymmetricOperation::DECRYPT:
+            symmetricOperation = cpp_hwcrypto::types::SymmetricOperation::DECRYPT;
+            break;
+        default:
+            LOG(ERROR) << "invalid symmetric operation type";
+            return std::nullopt;
+    }
+    return symmetricOperation;
+}
+
+cpp_hwcrypto::types::CipherModeParameters convertSymmetricModeParameters(
+        const ndk_hwcrypto::types::CipherModeParameters& ndkcipherModeParameters) {
+    cpp_hwcrypto::types::CipherModeParameters cipherModeParameters =
+            cpp_hwcrypto::types::CipherModeParameters();
+    cipherModeParameters.nonce = ndkcipherModeParameters.nonce;
+    return cipherModeParameters;
+}
+
+cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters convertSymmetricModeParameters(
+        const ndk_hwcrypto::types::AesGcmMode::AesGcmModeParameters& ndkgcmModeParameters) {
+    cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters gcmModeParameters =
+            cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters();
+    gcmModeParameters.nonce = ndkgcmModeParameters.nonce;
+    return gcmModeParameters;
+}
+
+std::optional<cpp_hwcrypto::OperationParameters> convertOperationParameters(
+        const ndk_hwcrypto::OperationParameters& ndkOperationParameters) {
+    cpp_hwcrypto::OperationParameters operationParameters = cpp_hwcrypto::OperationParameters();
+    sp<cpp_hwcrypto::IOpaqueKey> opaqueKey;
+    cpp_hwcrypto::types::HmacOperationParameters hmacParameters =
+            cpp_hwcrypto::types::HmacOperationParameters();
+    std::optional<cpp_hwcrypto::types::SymmetricOperation> cppSymmetricOperation;
+    cpp_hwcrypto::types::CipherModeParameters cipherModeParameters;
+    cpp_hwcrypto::types::AesCipherMode cppAesCipherMode = cpp_hwcrypto::types::AesCipherMode();
+    cpp_hwcrypto::types::SymmetricOperationParameters cppSymmetricOperationParameters =
+            cpp_hwcrypto::types::SymmetricOperationParameters();
+    cpp_hwcrypto::types::SymmetricAuthOperationParameters cppSymmetricAuthOperationParameters =
+            cpp_hwcrypto::types::SymmetricAuthOperationParameters();
+    cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters cppAesGcmModeParameters =
+            cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters();
+    cpp_hwcrypto::types::AesGcmMode cppAesGcmMode = cpp_hwcrypto::types::AesGcmMode();
+    switch (ndkOperationParameters.getTag()) {
+        case ndk_hwcrypto::OperationParameters::symmetricAuthCrypto:
+            opaqueKey = retrieveCppBinder<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey,
+                                          keyMapping>(
+                    ndkOperationParameters
+                            .get<ndk_hwcrypto::OperationParameters::symmetricAuthCrypto>()
+                            .key);
+            if (!opaqueKey) {
+                LOG(ERROR) << "couldn't get aes key";
+                return std::nullopt;
+            }
+            cppSymmetricAuthOperationParameters.key = std::move(opaqueKey);
+            cppSymmetricOperation = convertSymmetricOperation(
+                    ndkOperationParameters
+                            .get<ndk_hwcrypto::OperationParameters::symmetricAuthCrypto>()
+                            .direction);
+            if (!cppSymmetricOperation.has_value()) {
+                LOG(ERROR) << "couldn't get aes direction";
+                return std::nullopt;
+            }
+            cppSymmetricAuthOperationParameters.direction =
+                    std::move(cppSymmetricOperation.value());
+            switch (ndkOperationParameters
+                            .get<ndk_hwcrypto::OperationParameters::symmetricAuthCrypto>()
+                            .parameters.getTag()) {
+                case ndk_hwcrypto::types::SymmetricAuthCryptoParameters::aes:
+                    switch (ndkOperationParameters
+                                    .get<ndk_hwcrypto::OperationParameters::symmetricAuthCrypto>()
+                                    .parameters
+                                    .get<ndk_hwcrypto::types::SymmetricAuthCryptoParameters::aes>()
+                                    .getTag()) {
+                        case ndk_hwcrypto::types::AesGcmMode::gcmTag16:
+                            cppAesGcmModeParameters = convertSymmetricModeParameters(
+                                    ndkOperationParameters
+                                            .get<ndk_hwcrypto::OperationParameters::
+                                                         symmetricAuthCrypto>()
+                                            .parameters
+                                            .get<ndk_hwcrypto::types::
+                                                         SymmetricAuthCryptoParameters::aes>()
+                                            .get<ndk_hwcrypto::types::AesGcmMode::gcmTag16>());
+                            cppAesGcmMode.set<cpp_hwcrypto::types::AesGcmMode::gcmTag16>(
+                                    std::move(cppAesGcmModeParameters));
+                            cppSymmetricAuthOperationParameters.parameters
+                                    .set<cpp_hwcrypto::types::SymmetricAuthCryptoParameters::aes>(
+                                            std::move(cppAesGcmMode));
+                            break;
+                        default:
+                            LOG(ERROR) << "received invalid aes gcm parameters";
+                            return std::nullopt;
+                    }
+                    break;
+                default:
+                    LOG(ERROR) << "received invalid symmetric auth crypto parameters";
+                    return std::nullopt;
+            }
+            operationParameters.set<cpp_hwcrypto::OperationParameters::symmetricAuthCrypto>(
+                    std::move(cppSymmetricAuthOperationParameters));
+            break;
+        case ndk_hwcrypto::OperationParameters::symmetricCrypto:
+            opaqueKey = retrieveCppBinder<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey,
+                                          keyMapping>(
+                    ndkOperationParameters.get<ndk_hwcrypto::OperationParameters::symmetricCrypto>()
+                            .key);
+            if (!opaqueKey) {
+                LOG(ERROR) << "couldn't get aes key";
+                return std::nullopt;
+            }
+            cppSymmetricOperationParameters.key = std::move(opaqueKey);
+            cppSymmetricOperation = convertSymmetricOperation(
+                    ndkOperationParameters.get<ndk_hwcrypto::OperationParameters::symmetricCrypto>()
+                            .direction);
+            if (!cppSymmetricOperation.has_value()) {
+                LOG(ERROR) << "couldn't get aes direction";
+                return std::nullopt;
+            }
+            cppSymmetricOperationParameters.direction = std::move(cppSymmetricOperation.value());
+            switch (ndkOperationParameters.get<ndk_hwcrypto::OperationParameters::symmetricCrypto>()
+                            .parameters.getTag()) {
+                case ndk_hwcrypto::types::SymmetricCryptoParameters::aes:
+                    switch (ndkOperationParameters
+                                    .get<ndk_hwcrypto::OperationParameters::symmetricCrypto>()
+                                    .parameters
+                                    .get<ndk_hwcrypto::types::SymmetricCryptoParameters::aes>()
+                                    .getTag()) {
+                        case ndk_hwcrypto::types::AesCipherMode::cbc:
+                            cipherModeParameters = convertSymmetricModeParameters(
+                                    ndkOperationParameters
+                                            .get<ndk_hwcrypto::OperationParameters::
+                                                         symmetricCrypto>()
+                                            .parameters
+                                            .get<ndk_hwcrypto::types::SymmetricCryptoParameters::
+                                                         aes>()
+                                            .get<ndk_hwcrypto::types::AesCipherMode::cbc>());
+                            cppAesCipherMode.set<cpp_hwcrypto::types::AesCipherMode::cbc>(
+                                    std::move(cipherModeParameters));
+                            cppSymmetricOperationParameters.parameters
+                                    .set<cpp_hwcrypto::types::SymmetricCryptoParameters::aes>(
+                                            std::move(cppAesCipherMode));
+                            break;
+                        case ndk_hwcrypto::types::AesCipherMode::ctr:
+                            cipherModeParameters = convertSymmetricModeParameters(
+                                    ndkOperationParameters
+                                            .get<ndk_hwcrypto::OperationParameters::
+                                                         symmetricCrypto>()
+                                            .parameters
+                                            .get<ndk_hwcrypto::types::SymmetricCryptoParameters::
+                                                         aes>()
+                                            .get<ndk_hwcrypto::types::AesCipherMode::ctr>());
+                            cppAesCipherMode.set<cpp_hwcrypto::types::AesCipherMode::ctr>(
+                                    std::move(cipherModeParameters));
+                            cppSymmetricOperationParameters.parameters
+                                    .set<cpp_hwcrypto::types::SymmetricCryptoParameters::aes>(
+                                            std::move(cppAesCipherMode));
+                            break;
+                        default:
+                            LOG(ERROR) << "received invalid aes parameters";
+                            return std::nullopt;
+                    }
+                    break;
+                default:
+                    LOG(ERROR) << "received invalid symmetric crypto parameters";
+                    return std::nullopt;
+            }
+            operationParameters.set<cpp_hwcrypto::OperationParameters::symmetricCrypto>(
+                    std::move(cppSymmetricOperationParameters));
+            break;
+        case ndk_hwcrypto::OperationParameters::hmac:
+            opaqueKey = retrieveCppBinder<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey,
+                                          keyMapping>(
+                    ndkOperationParameters.get<ndk_hwcrypto::OperationParameters::hmac>().key);
+            if (!opaqueKey) {
+                LOG(ERROR) << "couldn't get hmac key";
+                return std::nullopt;
+            }
+            hmacParameters.key = opaqueKey;
+            operationParameters.set<cpp_hwcrypto::OperationParameters::hmac>(
+                    std::move(hmacParameters));
+            break;
+        default:
+            LOG(ERROR) << "received invalid operation parameters";
+            return std::nullopt;
+    }
+    return operationParameters;
 }
 
 class HwCryptoOperationsNdk : public ndk_hwcrypto::BnHwCryptoOperations {
@@ -189,19 +401,208 @@
     }
 
     ndk::ScopedAStatus processCommandList(
-            std::vector<ndk_hwcrypto::CryptoOperationSet>* /*operationSets*/,
-            std::vector<ndk_hwcrypto::CryptoOperationResult>* /*aidl_return*/) {
-        return ndk::ScopedAStatus::ok();
+            std::vector<ndk_hwcrypto::CryptoOperationSet>* operationSets,
+            std::vector<ndk_hwcrypto::CryptoOperationResult>* aidl_return) {
+        Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+        if (operationSets == nullptr) {
+            LOG(ERROR) << "received a null operation set";
+            return convertStatus(status);
+        }
+        if (aidl_return == nullptr) {
+            LOG(ERROR) << "received a null CryptoOperationResult set";
+            return convertStatus(status);
+        }
+        std::vector<cpp_hwcrypto::CryptoOperationResult> binderResult;
+        std::vector<cpp_hwcrypto::CryptoOperationSet> cppOperationSets;
+        for (ndk_hwcrypto::CryptoOperationSet& operationSet : *operationSets) {
+            cpp_hwcrypto::CryptoOperationSet cppSingleOperation =
+                    cpp_hwcrypto::CryptoOperationSet();
+            cppSingleOperation.context =
+                    retrieveCppBinder<cpp_hwcrypto::ICryptoOperationContext,
+                                      ndk_hwcrypto::ICryptoOperationContext, contextMapping>(
+                            operationSet.context);
+            for (ndk_hwcrypto::CryptoOperation& operation : operationSet.operations) {
+                cpp_hwcrypto::CryptoOperation cppOperation;
+                cpp_hwcrypto::types::Void voidObj;
+                std::optional<cpp_hwcrypto::types::OperationData> cppOperationData;
+                std::optional<cpp_hwcrypto::PatternParameters> cppPatternParameters;
+                std::optional<cpp_hwcrypto::OperationParameters> cppOperationParameters;
+                switch (operation.getTag()) {
+                    case ndk_hwcrypto::CryptoOperation::setMemoryBuffer:
+                        // TODO: finish this case
+                        exit(1);
+                        break;
+                    case ndk_hwcrypto::CryptoOperation::setOperationParameters:
+                        cppOperationParameters = convertOperationParameters(
+                                operation.get<
+                                        ndk_hwcrypto::CryptoOperation::setOperationParameters>());
+                        if (cppOperationParameters.has_value()) {
+                            cppOperation.set<cpp_hwcrypto::CryptoOperation::setOperationParameters>(
+                                    std::move(cppOperationParameters.value()));
+                        } else {
+                            LOG(ERROR) << "couldn't convert operation parameters";
+                            return convertStatus(status);
+                        }
+                        break;
+                    case ndk_hwcrypto::CryptoOperation::setPattern:
+                        cppPatternParameters = convertPatternParameters(
+                                operation.get<ndk_hwcrypto::CryptoOperation::setPattern>());
+                        if (cppPatternParameters.has_value()) {
+                            cppOperation.set<cpp_hwcrypto::CryptoOperation::setPattern>(
+                                    std::move(cppPatternParameters.value()));
+                        } else {
+                            LOG(ERROR) << "couldn't convert pattern parameters";
+                            return convertStatus(status);
+                        }
+                        break;
+                    case ndk_hwcrypto::CryptoOperation::copyData:
+                        cppOperationData = convertOperationData(
+                                operation.get<ndk_hwcrypto::CryptoOperation::copyData>());
+                        if (cppOperationData.has_value()) {
+                            cppOperation.set<cpp_hwcrypto::CryptoOperation::copyData>(
+                                    std::move(cppOperationData.value()));
+                        } else {
+                            LOG(ERROR) << "couldn't convert CryptoOperation::copyData";
+                            return convertStatus(status);
+                        }
+                        break;
+                    case ndk_hwcrypto::CryptoOperation::aadInput:
+                        cppOperationData = convertOperationData(
+                                operation.get<ndk_hwcrypto::CryptoOperation::aadInput>());
+                        if (cppOperationData.has_value()) {
+                            cppOperation.set<cpp_hwcrypto::CryptoOperation::aadInput>(
+                                    std::move(cppOperationData.value()));
+                        } else {
+                            LOG(ERROR) << "couldn't convert CryptoOperation::aadInput";
+                            return convertStatus(status);
+                        }
+                        break;
+                    case ndk_hwcrypto::CryptoOperation::dataInput:
+                        cppOperationData = convertOperationData(
+                                operation.get<ndk_hwcrypto::CryptoOperation::dataInput>());
+                        if (cppOperationData.has_value()) {
+                            cppOperation.set<cpp_hwcrypto::CryptoOperation::dataInput>(
+                                    std::move(cppOperationData.value()));
+                        } else {
+                            LOG(ERROR) << "couldn't convert CryptoOperation::dataInput";
+                            return convertStatus(status);
+                        }
+                        break;
+                    case ndk_hwcrypto::CryptoOperation::dataOutput:
+                        cppOperationData = convertOperationData(
+                                operation.get<ndk_hwcrypto::CryptoOperation::dataOutput>());
+                        if (cppOperationData.has_value()) {
+                            cppOperation.set<cpp_hwcrypto::CryptoOperation::dataOutput>(
+                                    std::move(cppOperationData.value()));
+                        } else {
+                            LOG(ERROR) << "couldn't convert CryptoOperation::dataOutput";
+                            return convertStatus(status);
+                        }
+                        break;
+                    case ndk_hwcrypto::CryptoOperation::destroyContext:
+                        cppOperation.set<cpp_hwcrypto::CryptoOperation::destroyContext>(
+                                std::move(voidObj));
+                        break;
+                    case ndk_hwcrypto::CryptoOperation::finish:
+                        cppOperation.set<cpp_hwcrypto::CryptoOperation::finish>(std::move(voidObj));
+                        break;
+                    default:
+                        // This shouldn't happen
+                        LOG(ERROR) << "received unknown crypto operation";
+                        return convertStatus(status);
+                }
+                cppSingleOperation.operations.push_back(std::move(cppOperation));
+            }
+            cppOperationSets.push_back(std::move(cppSingleOperation));
+        }
+        status = mHwCryptoOperations->processCommandList(&cppOperationSets, &binderResult);
+        if (status.isOk()) {
+            *aidl_return = std::vector<ndk_hwcrypto::CryptoOperationResult>();
+            for (cpp_hwcrypto::CryptoOperationResult& result : binderResult) {
+                ndk_hwcrypto::CryptoOperationResult ndkResult =
+                        ndk_hwcrypto::CryptoOperationResult();
+                if (result.context != nullptr) {
+                    insertBinderMapping<cpp_hwcrypto::ICryptoOperationContext,
+                                        ndk_hwcrypto::ICryptoOperationContext,
+                                        HwCryptoOperationContextNdk, contextMapping>(
+                            result.context, &ndkResult.context);
+                } else {
+                    ndkResult.context = nullptr;
+                }
+                aidl_return->push_back(std::move(ndkResult));
+            }
+        } else {
+            // No reason to copy back the data output vectors if this failed
+            LOG(ERROR) << "couldn't process command list";
+            return convertStatus(status);
+        }
+        // We need to copy the vectors from the cpp operations back to the ndk one
+        if (cppOperationSets.size() != operationSets->size()) {
+            LOG(ERROR) << "ndk and cpp operation sets had a different number of elements";
+            return convertStatus(Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT));
+        }
+        for (unsigned setIdx = 0; setIdx < cppOperationSets.size(); ++setIdx) {
+            if (cppOperationSets[setIdx].operations.size() !=
+                (*operationSets)[setIdx].operations.size()) {
+                LOG(ERROR) << "ndk and cpp operations on set " << setIdx
+                           << " had a different number of elements";
+                return convertStatus(Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT));
+            }
+            for (unsigned operationIdx = 0;
+                 operationIdx < cppOperationSets[setIdx].operations.size(); ++operationIdx) {
+                if (cppOperationSets[setIdx].operations[operationIdx].getTag() ==
+                    cpp_hwcrypto::CryptoOperation::dataOutput) {
+                    if ((*operationSets)[setIdx].operations[operationIdx].getTag() !=
+                        ndk_hwcrypto::CryptoOperation::dataOutput) {
+                        LOG(ERROR)
+                                << "ndk and cpp operations on set " << setIdx << " and operation "
+                                << operationIdx << " had a different operation type";
+                        return convertStatus(
+                                Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT));
+                    }
+                    if (cppOperationSets[setIdx]
+                                .operations[operationIdx]
+                                .get<cpp_hwcrypto::CryptoOperation::dataOutput>()
+                                .getTag() == cpp_hwcrypto::types::OperationData::dataBuffer) {
+                        // This is the only case on which we need to move the data backto the
+                        // original array
+                        if ((*operationSets)[setIdx]
+                                    .operations[operationIdx]
+                                    .get<ndk_hwcrypto::CryptoOperation::dataOutput>()
+                                    .getTag() != ndk_hwcrypto::types::OperationData::dataBuffer) {
+                            LOG(ERROR) << "ndk and cpp operations on set " << setIdx
+                                       << " and operation " << operationIdx
+                                       << " had a different operation data output type";
+                            return convertStatus(
+                                    Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT));
+                        }
+                        (*operationSets)[setIdx]
+                                .operations[operationIdx]
+                                .get<ndk_hwcrypto::CryptoOperation::dataOutput>()
+                                .set<ndk_hwcrypto::types::OperationData::dataBuffer>(
+                                        cppOperationSets[setIdx]
+                                                .operations[operationIdx]
+                                                .get<cpp_hwcrypto::CryptoOperation::dataOutput>()
+                                                .get<cpp_hwcrypto::types::OperationData::
+                                                             dataBuffer>());
+                    }
+                }
+            }
+        }
+        return convertStatus(status);
     }
 };
 
 class OpaqueKeyNdk : public ndk_hwcrypto::BnOpaqueKey {
   private:
     sp<cpp_hwcrypto::IOpaqueKey> mOpaqueKey;
+    std::weak_ptr<ndk_hwcrypto::IOpaqueKey> self;
 
   public:
     OpaqueKeyNdk(sp<cpp_hwcrypto::IOpaqueKey> opaqueKey) : mOpaqueKey(std::move(opaqueKey)) {}
 
+    ~OpaqueKeyNdk() { keyMapping.erase(self); }
+
     static std::shared_ptr<OpaqueKeyNdk> Create(sp<cpp_hwcrypto::IOpaqueKey> opaqueKey) {
         if (opaqueKey == nullptr) {
             return nullptr;
@@ -213,6 +614,7 @@
             LOG(ERROR) << "failed to allocate HwCryptoKey";
             return nullptr;
         }
+        opaqueKeyNdk->self = opaqueKeyNdk;
         return opaqueKeyNdk;
     }
 
