Merge "Include challenge in test_rkpd_attestation_key_upgrade" into main
diff --git a/diced/TEST_MAPPING b/diced/TEST_MAPPING
index 2f6be00..7628d25 100644
--- a/diced/TEST_MAPPING
+++ b/diced/TEST_MAPPING
@@ -15,5 +15,10 @@
     {
       "name": "libdiced_sample_inputs.integration_test"
     }
+  ],
+  "postsubmit": [
+    {
+      "name": "libdiced_sample_inputs_nostd.integration_test"
+    }
   ]
 }
diff --git a/diced/open_dice/Android.bp b/diced/open_dice/Android.bp
index b87be7f..745b86e 100644
--- a/diced/open_dice/Android.bp
+++ b/diced/open_dice/Android.bp
@@ -17,12 +17,16 @@
         "libopen_dice_cbor_bindgen_nostd",
         "libzeroize_nostd",
     ],
+    features: [
+        "alloc",
+    ],
     whole_static_libs: [
         "libopen_dice_cbor",
         "libcrypto_baremetal",
     ],
     visibility: [
         "//packages/modules/Virtualization:__subpackages__",
+        "//system/security/diced/sample_inputs",
     ],
 }
 
@@ -36,6 +40,7 @@
         "libzeroize",
     ],
     features: [
+        "alloc",
         "std",
     ],
     shared_libs: [
diff --git a/diced/open_dice/src/lib.rs b/diced/open_dice/src/lib.rs
index 6d082b8..83ae07f 100644
--- a/diced/open_dice/src/lib.rs
+++ b/diced/open_dice/src/lib.rs
@@ -17,6 +17,9 @@
 
 #![cfg_attr(not(feature = "std"), no_std)]
 
+#[cfg(feature = "alloc")]
+extern crate alloc;
+
 #[cfg(not(feature = "std"))]
 extern crate core as std;
 
@@ -24,7 +27,7 @@
 mod dice;
 mod error;
 mod ops;
-#[cfg(feature = "std")]
+#[cfg(feature = "alloc")]
 mod retry;
 
 pub use bcc::{
@@ -38,7 +41,7 @@
 };
 pub use error::{DiceError, Result};
 pub use ops::{generate_certificate, hash, kdf, keypair_from_seed, sign, verify};
-#[cfg(feature = "std")]
+#[cfg(feature = "alloc")]
 pub use retry::{
     retry_bcc_format_config_descriptor, retry_bcc_main_flow, retry_dice_main_flow,
     retry_generate_certificate, OwnedDiceArtifacts,
diff --git a/diced/open_dice/src/retry.rs b/diced/open_dice/src/retry.rs
index 84ca5f5..a6303bd 100644
--- a/diced/open_dice/src/retry.rs
+++ b/diced/open_dice/src/retry.rs
@@ -23,6 +23,8 @@
 };
 use crate::error::{DiceError, Result};
 use crate::ops::generate_certificate;
+#[cfg(feature = "alloc")]
+use alloc::vec::Vec;
 
 /// Artifacts stores a set of dice artifacts comprising CDI_ATTEST, CDI_SEAL,
 /// and the BCC formatted attestation certificate chain.
diff --git a/diced/sample_inputs/Android.bp b/diced/sample_inputs/Android.bp
index cf6ef5f..e66d436 100644
--- a/diced/sample_inputs/Android.bp
+++ b/diced/sample_inputs/Android.bp
@@ -21,25 +21,61 @@
     default_applicable_licenses: ["system_security_license"],
 }
 
-rust_library {
-    name: "libdiced_sample_inputs",
+rust_defaults {
+    name: "libdiced_sample_inputs_defaults",
     crate_name: "diced_sample_inputs",
     srcs: ["src/lib.rs"],
+}
+
+rust_library {
+    name: "libdiced_sample_inputs",
+    defaults: ["libdiced_sample_inputs_defaults"],
+    features: [
+        "std",
+    ],
     rustlibs: [
-        "libanyhow",
         "libciborium",
         "libcoset",
         "libdiced_open_dice",
+        "liblog_rust",
     ],
 }
 
+rust_library_rlib {
+    name: "libdiced_sample_inputs_nostd",
+    defaults: ["libdiced_sample_inputs_defaults"],
+    rustlibs: [
+        "libciborium_nostd",
+        "libcoset_nostd",
+        "libdiced_open_dice_nostd",
+        "liblog_rust_nostd",
+    ],
+    visibility: [
+        "//packages/modules/Virtualization:__subpackages__",
+    ],
+}
+
+rust_defaults {
+    name: "libdiced_sample_inputs_test_defaults",
+    crate_name: "diced_sample_inputs_test",
+    srcs: ["tests/*.rs"],
+    test_suites: ["general-tests"],
+}
+
 rust_test {
     name: "libdiced_sample_inputs.integration_test",
-    crate_name: "diced_sample_inputs_test",
-    srcs: ["tests/*.rs"],
-    test_suites: ["general-tests"],
+    defaults: ["libdiced_sample_inputs_test_defaults"],
     rustlibs: [
         "libdiced_open_dice",
         "libdiced_sample_inputs",
     ],
 }
+
+rust_test {
+    name: "libdiced_sample_inputs_nostd.integration_test",
+    defaults: ["libdiced_sample_inputs_test_defaults"],
+    rustlibs: [
+        "libdiced_open_dice_nostd",
+        "libdiced_sample_inputs_nostd",
+    ],
+}
diff --git a/diced/sample_inputs/src/lib.rs b/diced/sample_inputs/src/lib.rs
index ebbfd29..9d6deca 100644
--- a/diced/sample_inputs/src/lib.rs
+++ b/diced/sample_inputs/src/lib.rs
@@ -17,6 +17,10 @@
 //! Provides a set of sample inputs for a DICE chain and CDI values derived
 //! from it.
 
+#![cfg_attr(not(feature = "std"), no_std)]
+
+extern crate alloc;
+
 mod sample_inputs;
 
 pub use sample_inputs::make_sample_bcc_and_cdis;
diff --git a/diced/sample_inputs/src/sample_inputs.rs b/diced/sample_inputs/src/sample_inputs.rs
index 6ad15cd..54f551b 100644
--- a/diced/sample_inputs/src/sample_inputs.rs
+++ b/diced/sample_inputs/src/sample_inputs.rs
@@ -15,15 +15,17 @@
 //! This module provides a set of sample input values for a DICE chain, a sample UDS,
 //! as well as tuple of CDIs and BCC derived thereof.
 
-use anyhow::{anyhow, Context, Result};
+use alloc::vec;
+use alloc::vec::Vec;
 use ciborium::{de, ser, value::Value};
+use core::ffi::CStr;
 use coset::{iana, Algorithm, AsCborValue, CoseKey, KeyOperation, KeyType, Label};
 use diced_open_dice::{
     derive_cdi_private_key_seed, keypair_from_seed, retry_bcc_format_config_descriptor,
-    retry_bcc_main_flow, retry_dice_main_flow, Config, DiceArtifacts, DiceConfigValues, DiceMode,
-    InputValues, OwnedDiceArtifacts, CDI_SIZE, HASH_SIZE, HIDDEN_SIZE,
+    retry_bcc_main_flow, retry_dice_main_flow, Config, DiceArtifacts, DiceConfigValues, DiceError,
+    DiceMode, InputValues, OwnedDiceArtifacts, Result, CDI_SIZE, HASH_SIZE, HIDDEN_SIZE,
 };
-use std::ffi::CStr;
+use log::error;
 
 /// Sample UDS used to perform the root dice flow by `make_sample_bcc_and_cdis`.
 const UDS: &[u8; CDI_SIZE] = &[
@@ -88,8 +90,10 @@
         ],
         ..Default::default()
     };
-    key.to_cbor_value()
-        .map_err(|e| anyhow!(format!("Failed to serialize the key to CBOR data. Error: {e}")))
+    key.to_cbor_value().map_err(|e| {
+        error!("Failed to serialize the key to CBOR data: {e}");
+        DiceError::InvalidInput
+    })
 }
 
 /// Makes a DICE chain (BCC) from the sample input.
@@ -97,12 +101,16 @@
 /// The DICE chain is of the following format:
 /// public key derived from UDS -> ABL certificate -> AVB certificate -> Android certificate
 pub fn make_sample_bcc_and_cdis() -> Result<OwnedDiceArtifacts> {
-    let private_key_seed = derive_cdi_private_key_seed(UDS)
-        .context("In make_sample_bcc_and_cdis: Trying to derive private key seed.")?;
+    let private_key_seed = derive_cdi_private_key_seed(UDS).map_err(|e| {
+        error!("In make_sample_bcc_and_cdis: Trying to derive private key seed. Error: {e}");
+        e
+    })?;
 
     // Gets the root public key in DICE chain (BCC).
-    let (public_key, _) = keypair_from_seed(private_key_seed.as_array())
-        .context("In make_sample_bcc_and_cids: Failed to generate key pair.")?;
+    let (public_key, _) = keypair_from_seed(private_key_seed.as_array()).map_err(|e| {
+        error!("In make_sample_bcc_and_cids: Failed to generate key pair. Error: {e}");
+        e
+    })?;
     let ed25519_public_key_value = ed25519_public_key_to_cbor_value(&public_key)?;
 
     // Gets the ABL certificate to as the root certificate of DICE chain.
@@ -120,14 +128,22 @@
         DiceMode::kDiceModeNormal,
         HIDDEN_ABL,
     );
-    let (cdi_values, cert) = retry_dice_main_flow(UDS, UDS, &input_values)
-        .context("In make_sample_bcc_and_cdis: Trying to run first main flow.")?;
+    let (cdi_values, cert) = retry_dice_main_flow(UDS, UDS, &input_values).map_err(|e| {
+        error!("In make_sample_bcc_and_cdis: Trying to run first main flow. Error: {e}");
+        e
+    })?;
     let bcc_value = Value::Array(vec![
         ed25519_public_key_value,
-        de::from_reader(&cert[..]).context("Deserialize root DICE certificate failed")?,
+        de::from_reader(&cert[..]).map_err(|e| {
+            error!("Deserialize root DICE certificate failed: {e}");
+            DiceError::InvalidInput
+        })?,
     ]);
     let mut bcc: Vec<u8> = vec![];
-    ser::into_writer(&bcc_value, &mut bcc)?;
+    ser::into_writer(&bcc_value, &mut bcc).map_err(|e| {
+        error!("Serialize BCC failed: {e}");
+        DiceError::InvalidInput
+    })?;
 
     // Appends AVB certificate to DICE chain.
     let config_values = DiceConfigValues {
@@ -146,7 +162,12 @@
     );
     let dice_artifacts =
         retry_bcc_main_flow(&cdi_values.cdi_attest, &cdi_values.cdi_seal, &bcc, &input_values)
-            .context("In make_sample_bcc_and_cdis: Trying to run first bcc main flow.")?;
+            .map_err(|e| {
+                error!(
+                    "In make_sample_bcc_and_cdis: Trying to run first bcc main flow. Error: {e}"
+                );
+                e
+            })?;
 
     // Appends Android certificate to DICE chain.
     let config_values = DiceConfigValues {
@@ -166,8 +187,14 @@
     retry_bcc_main_flow(
         dice_artifacts.cdi_attest(),
         dice_artifacts.cdi_seal(),
-        dice_artifacts.bcc().ok_or_else(|| anyhow!("bcc is none"))?,
+        dice_artifacts.bcc().ok_or_else(|| {
+            error!("bcc is none");
+            DiceError::InvalidInput
+        })?,
         &input_values,
     )
-    .context("In make_sample_bcc_and_cdis: Trying to run second bcc main flow.")
+    .map_err(|e| {
+        error!("In make_sample_bcc_and_cdis: Trying to run second bcc main flow. Error: {e}");
+        e
+    })
 }
diff --git a/keystore2/src/error.rs b/keystore2/src/error.rs
index d6ae0ce..1a048b6 100644
--- a/keystore2/src/error.rs
+++ b/keystore2/src/error.rs
@@ -13,22 +13,19 @@
 // limitations under the License.
 
 //! Keystore error provides convenience methods and types for Keystore error handling.
-//! Clients of Keystore expect one of two error codes, i.e., a Keystore ResponseCode as
-//! defined by the Keystore AIDL interface, or a Keymint ErrorCode as defined by
-//! the Keymint HAL specification.
-//! This crate provides `Error` which can wrap both. It is to be used
-//! internally by Keystore to diagnose error conditions that need to be reported to
-//! the client. To report the error condition to the client the Keystore AIDL
-//! interface defines a wire type `Result` which is distinctly different from Rust's
-//! `enum Result<T,E>`.
 //!
-//! This crate provides the convenience method `map_or_log_err` to convert `anyhow::Error`
-//! into this wire type. In addition to handling the conversion of `Error`
-//! to the `Result` wire type it handles any other error by mapping it to
-//! `ResponseCode::SYSTEM_ERROR` and logs any error condition.
+//! Here are some important types and helper functions:
 //!
-//! Keystore functions should use `anyhow::Result` to return error conditions, and
-//! context should be added every time an error is forwarded.
+//! `Error` type encapsulate Keystore, Keymint, and Binder errors. It is used internally by
+//! Keystore to diagnose error conditions that need to be reported to the client.
+//!
+//! `SerializedError` is used send error codes on the wire.
+//!
+//! `map_or_log_err` is a convenience method used to convert `anyhow::Error` into `SerializedError`
+//! wire type.
+//!
+//! Keystore functions should use `anyhow::Result` to return error conditions, and context should
+//! be added every time an error is forwarded.
 
 pub use android_hardware_security_keymint::aidl::android::hardware::security::keymint::ErrorCode::ErrorCode;
 pub use android_system_keystore2::aidl::android::system::keystore2::ResponseCode::ResponseCode;
@@ -126,14 +123,6 @@
 ///
 /// All error conditions get logged by this function, except for KEY_NOT_FOUND error.
 ///
-/// All `Error::Rc(x)` and `Error::Km(x)` variants get mapped onto a service specific error
-/// code of x. This is possible because KeyMint `ErrorCode` errors are always negative and
-/// `ResponseCode` codes are always positive.
-/// `selinux::Error::PermissionDenied` is mapped on `ResponseCode::PERMISSION_DENIED`.
-///
-/// All non `Error` error conditions and the Error::Binder variant get mapped onto
-/// ResponseCode::SYSTEM_ERROR`.
-///
 /// `handle_ok` will be called if `result` is `Ok(value)` where `value` will be passed
 /// as argument to `handle_ok`. `handle_ok` must generate a `BinderResult<T>`, but it
 /// typically returns Ok(value).
@@ -200,9 +189,9 @@
     result.map_or_else(
         |e| {
             let e = map_err(e);
-            let rc = get_error_code(&e);
+            let rc = anyhow_error_to_serialized_error(&e);
             Err(BinderStatus::new_service_specific_error(
-                rc,
+                rc.0,
                 anyhow_error_to_cstring(&e).as_deref(),
             ))
         },
@@ -210,21 +199,42 @@
     )
 }
 
-/// Returns the error code given a reference to the error
-pub fn get_error_code(e: &anyhow::Error) -> i32 {
+/// This type is used to send error codes on the wire.
+///
+/// Errors are squashed into one number space using following rules:
+/// - All Keystore and Keymint errors codes are identity mapped. It's possible because by
+///   convention Keystore `ResponseCode` errors are positive, and Keymint `ErrorCode` errors are
+///   negative.
+/// - `selinux::Error::PermissionDenied` is mapped to `ResponseCode::PERMISSION_DENIED`.
+/// - All other error conditions, e.g. Binder errors, are mapped to `ResponseCode::SYSTEM_ERROR`.
+///
+/// The type should be used to forward all error codes to clients of Keystore AIDL interface and to
+/// metrics events.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
+pub struct SerializedError(pub i32);
+
+/// Returns a SerializedError given a reference to Error.
+pub fn error_to_serialized_error(e: &Error) -> SerializedError {
+    match e {
+        Error::Rc(rcode) => SerializedError(rcode.0),
+        Error::Km(ec) => SerializedError(ec.0),
+        // Binder errors are reported as system error.
+        Error::Binder(_, _) | Error::BinderTransaction(_) => {
+            SerializedError(ResponseCode::SYSTEM_ERROR.0)
+        }
+    }
+}
+
+/// Returns a SerializedError given a reference to anyhow::Error.
+pub fn anyhow_error_to_serialized_error(e: &anyhow::Error) -> SerializedError {
     let root_cause = e.root_cause();
     match root_cause.downcast_ref::<Error>() {
-        Some(Error::Rc(rcode)) => rcode.0,
-        Some(Error::Km(ec)) => ec.0,
-        // If an Error::Binder reaches this stage we report a system error.
-        // The exception code and possible service specific error will be
-        // printed in the error log above.
-        Some(Error::Binder(_, _)) | Some(Error::BinderTransaction(_)) => {
-            ResponseCode::SYSTEM_ERROR.0
-        }
+        Some(e) => error_to_serialized_error(e),
         None => match root_cause.downcast_ref::<selinux::Error>() {
-            Some(selinux::Error::PermissionDenied) => ResponseCode::PERMISSION_DENIED.0,
-            _ => ResponseCode::SYSTEM_ERROR.0,
+            Some(selinux::Error::PermissionDenied) => {
+                SerializedError(ResponseCode::PERMISSION_DENIED.0)
+            }
+            _ => SerializedError(ResponseCode::SYSTEM_ERROR.0),
         },
     }
 }
diff --git a/keystore2/src/metrics_store.rs b/keystore2/src/metrics_store.rs
index 5d311f0..6dca74a 100644
--- a/keystore2/src/metrics_store.rs
+++ b/keystore2/src/metrics_store.rs
@@ -17,7 +17,7 @@
 //!    stores them in an in-memory store.
 //! 2. Returns the collected metrics when requested by the statsd proxy.
 
-use crate::error::get_error_code;
+use crate::error::anyhow_error_to_serialized_error;
 use crate::globals::DB;
 use crate::key_parameter::KeyParameterValue as KsKeyParamValue;
 use crate::ks_err;
@@ -202,7 +202,7 @@
     };
 
     if let Err(ref e) = result {
-        key_creation_with_general_info.error_code = get_error_code(e);
+        key_creation_with_general_info.error_code = anyhow_error_to_serialized_error(e).0;
     }
 
     key_creation_with_auth_info.security_level = process_security_level(sec_level);
diff --git a/keystore2/src/operation.rs b/keystore2/src/operation.rs
index 2034a8a..eabc1ab 100644
--- a/keystore2/src/operation.rs
+++ b/keystore2/src/operation.rs
@@ -126,7 +126,10 @@
 //! Either way, we have to revaluate the pruning scores.
 
 use crate::enforcements::AuthInfo;
-use crate::error::{map_err_with, map_km_error, map_or_log_err, Error, ErrorCode, ResponseCode};
+use crate::error::{
+    error_to_serialized_error, map_err_with, map_km_error, map_or_log_err, Error, ErrorCode,
+    ResponseCode, SerializedError,
+};
 use crate::ks_err;
 use crate::metrics_store::log_key_operation_event_stats;
 use crate::utils::watchdog as wd;
@@ -162,7 +165,7 @@
     /// Operation is pruned.
     Pruned,
     /// Operation is failed with the error code.
-    ErrorCode(ErrorCode),
+    ErrorCode(SerializedError),
 }
 
 /// Operation bundles all of the operation related resources and tracks the operation's
@@ -305,8 +308,7 @@
         err: Result<T, Error>,
     ) -> Result<T, Error> {
         match &err {
-            Err(Error::Km(e)) => *locked_outcome = Outcome::ErrorCode(*e),
-            Err(_) => *locked_outcome = Outcome::ErrorCode(ErrorCode::UNKNOWN_ERROR),
+            Err(e) => *locked_outcome = Outcome::ErrorCode(error_to_serialized_error(e)),
             Ok(_) => (),
         }
         err