Better API for creating a DICE config descriptor

Instead of listing all the possible parameters, put them in a struct
(as the C API does).

This means callers only have to list the ones they use, and a new
parameter doesn't require all clients to change.

Bug: 291241882
Test: atest -p in diced
Change-Id: I7c4925385e30ba9fcec0dc188747a23d7df614d7
diff --git a/diced/open_dice/Android.bp b/diced/open_dice/Android.bp
index 3d904ea..b87be7f 100644
--- a/diced/open_dice/Android.bp
+++ b/diced/open_dice/Android.bp
@@ -185,9 +185,7 @@
         "--allowlist-function=DiceAndroidHandoverParse",
 
         // We also need some constants in addition to the functions.
-        "--allowlist-var=DICE_ANDROID_CONFIG_COMPONENT_NAME",
-        "--allowlist-var=DICE_ANDROID_CONFIG_COMPONENT_VERSION",
-        "--allowlist-var=DICE_ANDROID_CONFIG_RESETTABLE",
+        "--allowlist-var=DICE_ANDROID_CONFIG_.*",
 
         // Prevent DiceInputValues from being generated a second time and
         // import it instead from open_dice_cbor_bindgen.
diff --git a/diced/open_dice/src/bcc.rs b/diced/open_dice/src/bcc.rs
index 543cb57..199e1a9 100644
--- a/diced/open_dice/src/bcc.rs
+++ b/diced/open_dice/src/bcc.rs
@@ -20,34 +20,47 @@
     DiceAndroidConfigValues, DiceAndroidFormatConfigDescriptor, DiceAndroidHandoverMainFlow,
     DiceAndroidHandoverParse, DiceAndroidMainFlow, DICE_ANDROID_CONFIG_COMPONENT_NAME,
     DICE_ANDROID_CONFIG_COMPONENT_VERSION, DICE_ANDROID_CONFIG_RESETTABLE,
+    DICE_ANDROID_CONFIG_SECURITY_VERSION,
 };
 use std::{ffi::CStr, ptr};
 
+/// Contains the input values used to construct the Android Profile for DICE
+/// configuration descriptor.
+#[derive(Default, Debug)]
+pub struct DiceConfigValues<'a> {
+    /// Name of the component.
+    pub component_name: Option<&'a CStr>,
+    /// Version of the component.
+    pub component_version: Option<u64>,
+    /// Whether the key changes on factory reset.
+    pub resettable: bool,
+    /// Monotonically increasing version of the component.
+    pub security_version: Option<u64>,
+}
+
 /// Formats a configuration descriptor following the Android Profile for DICE specification.
-/// See https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/android.md
-pub fn bcc_format_config_descriptor(
-    name: Option<&CStr>,
-    version: Option<u64>,
-    resettable: bool,
-    buffer: &mut [u8],
-) -> Result<usize> {
+/// See https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/android.md.
+pub fn bcc_format_config_descriptor(values: &DiceConfigValues, buffer: &mut [u8]) -> Result<usize> {
     let mut configs = 0;
-    if name.is_some() {
+
+    let component_name = values.component_name.map_or(ptr::null(), |name| {
         configs |= DICE_ANDROID_CONFIG_COMPONENT_NAME;
-    }
-    if version.is_some() {
+        name.as_ptr()
+    });
+    let component_version = values.component_version.map_or(0, |version| {
         configs |= DICE_ANDROID_CONFIG_COMPONENT_VERSION;
-    }
-    if resettable {
+        version
+    });
+    if values.resettable {
         configs |= DICE_ANDROID_CONFIG_RESETTABLE;
     }
+    let security_version = values.security_version.map_or(0, |version| {
+        configs |= DICE_ANDROID_CONFIG_SECURITY_VERSION;
+        version
+    });
 
-    let values = DiceAndroidConfigValues {
-        configs,
-        component_name: name.map_or(ptr::null(), |p| p.as_ptr()),
-        component_version: version.unwrap_or(0),
-        security_version: 0,
-    };
+    let values =
+        DiceAndroidConfigValues { configs, component_name, component_version, security_version };
 
     let mut buffer_size = 0;
     check_result(
diff --git a/diced/open_dice/src/lib.rs b/diced/open_dice/src/lib.rs
index 4a85a1e..6d082b8 100644
--- a/diced/open_dice/src/lib.rs
+++ b/diced/open_dice/src/lib.rs
@@ -29,7 +29,7 @@
 
 pub use bcc::{
     bcc_format_config_descriptor, bcc_handover_main_flow, bcc_handover_parse, bcc_main_flow,
-    BccHandover,
+    BccHandover, DiceConfigValues,
 };
 pub use dice::{
     derive_cdi_certificate_id, derive_cdi_private_key_seed, dice_main_flow, Cdi, CdiValues, Config,
diff --git a/diced/open_dice/src/retry.rs b/diced/open_dice/src/retry.rs
index 3db4781..84ca5f5 100644
--- a/diced/open_dice/src/retry.rs
+++ b/diced/open_dice/src/retry.rs
@@ -17,13 +17,12 @@
 //! memory allocation on heap, currently we only expose these functions in
 //! std environment.
 
-use crate::bcc::{bcc_format_config_descriptor, bcc_main_flow};
+use crate::bcc::{bcc_format_config_descriptor, bcc_main_flow, DiceConfigValues};
 use crate::dice::{
     dice_main_flow, Cdi, CdiValues, DiceArtifacts, InputValues, CDI_SIZE, PRIVATE_KEY_SEED_SIZE,
 };
 use crate::error::{DiceError, Result};
 use crate::ops::generate_certificate;
-use std::ffi::CStr;
 
 /// Artifacts stores a set of dice artifacts comprising CDI_ATTEST, CDI_SEAL,
 /// and the BCC formatted attestation certificate chain.
@@ -69,14 +68,8 @@
 }
 
 /// Formats a configuration descriptor following the BCC's specification.
-pub fn retry_bcc_format_config_descriptor(
-    name: Option<&CStr>,
-    version: Option<u64>,
-    resettable: bool,
-) -> Result<Vec<u8>> {
-    retry_with_measured_buffer(|buffer| {
-        bcc_format_config_descriptor(name, version, resettable, buffer)
-    })
+pub fn retry_bcc_format_config_descriptor(values: &DiceConfigValues) -> Result<Vec<u8>> {
+    retry_with_measured_buffer(|buffer| bcc_format_config_descriptor(values, buffer))
 }
 
 /// Executes the main BCC flow.
diff --git a/diced/sample_inputs/src/sample_inputs.rs b/diced/sample_inputs/src/sample_inputs.rs
index c665eb3..6ad15cd 100644
--- a/diced/sample_inputs/src/sample_inputs.rs
+++ b/diced/sample_inputs/src/sample_inputs.rs
@@ -20,8 +20,8 @@
 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, DiceMode, InputValues,
-    OwnedDiceArtifacts, CDI_SIZE, HASH_SIZE, HIDDEN_SIZE,
+    retry_bcc_main_flow, retry_dice_main_flow, Config, DiceArtifacts, DiceConfigValues, DiceMode,
+    InputValues, OwnedDiceArtifacts, CDI_SIZE, HASH_SIZE, HIDDEN_SIZE,
 };
 use std::ffi::CStr;
 
@@ -106,11 +106,13 @@
     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.
-    let config_descriptor = retry_bcc_format_config_descriptor(
-        Some(CStr::from_bytes_with_nul(b"ABL\0").unwrap()),
-        Some(1), // version
-        true,
-    )?;
+    let config_values = DiceConfigValues {
+        component_name: Some(CStr::from_bytes_with_nul(b"ABL\0").unwrap()),
+        component_version: Some(1),
+        resettable: true,
+        ..Default::default()
+    };
+    let config_descriptor = retry_bcc_format_config_descriptor(&config_values)?;
     let input_values = InputValues::new(
         CODE_HASH_ABL,
         Config::Descriptor(config_descriptor.as_slice()),
@@ -128,11 +130,13 @@
     ser::into_writer(&bcc_value, &mut bcc)?;
 
     // Appends AVB certificate to DICE chain.
-    let config_descriptor = retry_bcc_format_config_descriptor(
-        Some(CStr::from_bytes_with_nul(b"AVB\0").unwrap()),
-        Some(1), // version
-        true,
-    )?;
+    let config_values = DiceConfigValues {
+        component_name: Some(CStr::from_bytes_with_nul(b"AVB\0").unwrap()),
+        component_version: Some(1),
+        resettable: true,
+        ..Default::default()
+    };
+    let config_descriptor = retry_bcc_format_config_descriptor(&config_values)?;
     let input_values = InputValues::new(
         CODE_HASH_AVB,
         Config::Descriptor(config_descriptor.as_slice()),
@@ -145,11 +149,13 @@
             .context("In make_sample_bcc_and_cdis: Trying to run first bcc main flow.")?;
 
     // Appends Android certificate to DICE chain.
-    let config_descriptor = retry_bcc_format_config_descriptor(
-        Some(CStr::from_bytes_with_nul(b"Android\0").unwrap()),
-        Some(12), // version
-        true,
-    )?;
+    let config_values = DiceConfigValues {
+        component_name: Some(CStr::from_bytes_with_nul(b"Android\0").unwrap()),
+        component_version: Some(12),
+        resettable: true,
+        ..Default::default()
+    };
+    let config_descriptor = retry_bcc_format_config_descriptor(&config_values)?;
     let input_values = InputValues::new(
         [0u8; HASH_SIZE], // code_hash
         Config::Descriptor(config_descriptor.as_slice()),