[dice] Optimize retry_with_bigger_buffer in dice's Rust wrapper

This cl replaces the loop of buffer size request in the rust
wrapper of the open-dice library with a single request as the
latter is now supported in DICE.

Test: atest libdiced_sample_inputs.integration_test
Bug: 272787330
Change-Id: I3d4ea3b89d30476e6a16b5fbdf155ebd1c23525d
diff --git a/diced/open_dice/src/bcc.rs b/diced/open_dice/src/bcc.rs
index 1575113..f9c6a34 100644
--- a/diced/open_dice/src/bcc.rs
+++ b/diced/open_dice/src/bcc.rs
@@ -50,9 +50,12 @@
     let mut buffer_size = 0;
     // SAFETY: The function writes to the buffer, within the given bounds, and only reads the
     // input values. It writes its result to buffer_size.
-    check_result(unsafe {
-        BccFormatConfigDescriptor(&values, buffer.len(), buffer.as_mut_ptr(), &mut buffer_size)
-    })?;
+    check_result(
+        unsafe {
+            BccFormatConfigDescriptor(&values, buffer.len(), buffer.as_mut_ptr(), &mut buffer_size)
+        },
+        buffer_size,
+    )?;
     Ok(buffer_size)
 }
 
@@ -73,21 +76,24 @@
     // to `next_bcc` and next CDI values within its bounds. It also reads
     // `input_values` as a constant input and doesn't store any pointer.
     // The first argument can be null and is not used in the current implementation.
-    check_result(unsafe {
-        BccMainFlow(
-            ptr::null_mut(), // context
-            current_cdi_attest.as_ptr(),
-            current_cdi_seal.as_ptr(),
-            current_bcc.as_ptr(),
-            current_bcc.len(),
-            input_values.as_ptr(),
-            next_bcc.len(),
-            next_bcc.as_mut_ptr(),
-            &mut next_bcc_size,
-            next_cdi_values.cdi_attest.as_mut_ptr(),
-            next_cdi_values.cdi_seal.as_mut_ptr(),
-        )
-    })?;
+    check_result(
+        unsafe {
+            BccMainFlow(
+                ptr::null_mut(), // context
+                current_cdi_attest.as_ptr(),
+                current_cdi_seal.as_ptr(),
+                current_bcc.as_ptr(),
+                current_bcc.len(),
+                input_values.as_ptr(),
+                next_bcc.len(),
+                next_bcc.as_mut_ptr(),
+                &mut next_bcc_size,
+                next_cdi_values.cdi_attest.as_mut_ptr(),
+                next_cdi_values.cdi_seal.as_mut_ptr(),
+            )
+        },
+        next_bcc_size,
+    )?;
     Ok(next_bcc_size)
 }
 
@@ -106,17 +112,20 @@
     // within its bounds,
     // It also reads `input_values` as a constant input and doesn't store any pointer.
     // The first argument can be null and is not used in the current implementation.
-    check_result(unsafe {
-        BccHandoverMainFlow(
-            ptr::null_mut(), // context
-            current_bcc_handover.as_ptr(),
-            current_bcc_handover.len(),
-            input_values.as_ptr(),
-            next_bcc_handover.len(),
-            next_bcc_handover.as_mut_ptr(),
-            &mut next_bcc_handover_size,
-        )
-    })?;
+    check_result(
+        unsafe {
+            BccHandoverMainFlow(
+                ptr::null_mut(), // context
+                current_bcc_handover.as_ptr(),
+                current_bcc_handover.len(),
+                input_values.as_ptr(),
+                next_bcc_handover.len(),
+                next_bcc_handover.as_mut_ptr(),
+                &mut next_bcc_handover_size,
+            )
+        },
+        next_bcc_handover_size,
+    )?;
 
     Ok(next_bcc_handover_size)
 }
@@ -158,16 +167,19 @@
     let mut bcc_size = 0;
     // SAFETY: The `bcc_handover` is only read and never stored and the returned pointers should all
     // point within the address range of the `bcc_handover` or be NULL.
-    check_result(unsafe {
-        BccHandoverParse(
-            bcc_handover.as_ptr(),
-            bcc_handover.len(),
-            &mut cdi_attest,
-            &mut cdi_seal,
-            &mut bcc,
-            &mut bcc_size,
-        )
-    })?;
+    check_result(
+        unsafe {
+            BccHandoverParse(
+                bcc_handover.as_ptr(),
+                bcc_handover.len(),
+                &mut cdi_attest,
+                &mut cdi_seal,
+                &mut bcc,
+                &mut bcc_size,
+            )
+        },
+        bcc_size,
+    )?;
     let cdi_attest = sub_slice(bcc_handover, cdi_attest, CDI_SIZE)?;
     let cdi_seal = sub_slice(bcc_handover, cdi_seal, CDI_SIZE)?;
     let bcc = sub_slice(bcc_handover, bcc, bcc_size).ok();
diff --git a/diced/open_dice/src/dice.rs b/diced/open_dice/src/dice.rs
index 6e2df81..0704d21 100644
--- a/diced/open_dice/src/dice.rs
+++ b/diced/open_dice/src/dice.rs
@@ -219,13 +219,16 @@
     let mut seed = PrivateKeySeed::default();
     // SAFETY: The function writes to the buffer within the given bounds, and only reads the
     // input values. The first argument context is not used in this function.
-    check_result(unsafe {
-        DiceDeriveCdiPrivateKeySeed(
-            ptr::null_mut(), // context
-            cdi_attest.as_ptr(),
-            seed.as_mut_ptr(),
-        )
-    })?;
+    check_result(
+        unsafe {
+            DiceDeriveCdiPrivateKeySeed(
+                ptr::null_mut(), // context
+                cdi_attest.as_ptr(),
+                seed.as_mut_ptr(),
+            )
+        },
+        seed.0.len(),
+    )?;
     Ok(seed)
 }
 
@@ -234,14 +237,17 @@
     let mut id = [0u8; ID_SIZE];
     // SAFETY: The function writes to the buffer within the given bounds, and only reads the
     // input values. The first argument context is not used in this function.
-    check_result(unsafe {
-        DiceDeriveCdiCertificateId(
-            ptr::null_mut(), // context
-            cdi_public_key.as_ptr(),
-            cdi_public_key.len(),
-            id.as_mut_ptr(),
-        )
-    })?;
+    check_result(
+        unsafe {
+            DiceDeriveCdiCertificateId(
+                ptr::null_mut(), // context
+                cdi_public_key.as_ptr(),
+                cdi_public_key.len(),
+                id.as_mut_ptr(),
+            )
+        },
+        id.len(),
+    )?;
     Ok(id)
 }
 
@@ -261,18 +267,21 @@
     // SAFETY: The function only reads the current CDI values and inputs and writes
     // to `next_cdi_certificate` and next CDI values within its bounds.
     // The first argument can be null and is not used in the current implementation.
-    check_result(unsafe {
-        DiceMainFlow(
-            ptr::null_mut(), // context
-            current_cdi_attest.as_ptr(),
-            current_cdi_seal.as_ptr(),
-            input_values.as_ptr(),
-            next_cdi_certificate.len(),
-            next_cdi_certificate.as_mut_ptr(),
-            &mut next_cdi_certificate_actual_size,
-            next_cdi_values.cdi_attest.as_mut_ptr(),
-            next_cdi_values.cdi_seal.as_mut_ptr(),
-        )
-    })?;
+    check_result(
+        unsafe {
+            DiceMainFlow(
+                ptr::null_mut(), // context
+                current_cdi_attest.as_ptr(),
+                current_cdi_seal.as_ptr(),
+                input_values.as_ptr(),
+                next_cdi_certificate.len(),
+                next_cdi_certificate.as_mut_ptr(),
+                &mut next_cdi_certificate_actual_size,
+                next_cdi_values.cdi_attest.as_mut_ptr(),
+                next_cdi_values.cdi_seal.as_mut_ptr(),
+            )
+        },
+        next_cdi_certificate_actual_size,
+    )?;
     Ok(next_cdi_certificate_actual_size)
 }
diff --git a/diced/open_dice/src/error.rs b/diced/open_dice/src/error.rs
index 4c67335..53ffd2d 100644
--- a/diced/open_dice/src/error.rs
+++ b/diced/open_dice/src/error.rs
@@ -26,7 +26,7 @@
     /// Provided input was invalid.
     InvalidInput,
     /// Provided buffer was too small.
-    BufferTooSmall,
+    BufferTooSmall(usize),
     /// Platform error.
     PlatformError,
 }
@@ -39,7 +39,9 @@
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
             Self::InvalidInput => write!(f, "invalid input"),
-            Self::BufferTooSmall => write!(f, "buffer too small"),
+            Self::BufferTooSmall(buffer_required_size) => {
+                write!(f, "buffer too small. Required {buffer_required_size} bytes.")
+            }
             Self::PlatformError => write!(f, "platform error"),
         }
     }
@@ -49,11 +51,13 @@
 pub type Result<T> = result::Result<T, DiceError>;
 
 /// Checks the given `DiceResult`. Returns an error if it's not OK.
-pub fn check_result(result: DiceResult) -> Result<()> {
+pub(crate) fn check_result(result: DiceResult, buffer_required_size: usize) -> Result<()> {
     match result {
         DiceResult::kDiceResultOk => Ok(()),
         DiceResult::kDiceResultInvalidInput => Err(DiceError::InvalidInput),
-        DiceResult::kDiceResultBufferTooSmall => Err(DiceError::BufferTooSmall),
+        DiceResult::kDiceResultBufferTooSmall => {
+            Err(DiceError::BufferTooSmall(buffer_required_size))
+        }
         DiceResult::kDiceResultPlatformError => Err(DiceError::PlatformError),
     }
 }
diff --git a/diced/open_dice/src/lib.rs b/diced/open_dice/src/lib.rs
index e7ec56b..4a85a1e 100644
--- a/diced/open_dice/src/lib.rs
+++ b/diced/open_dice/src/lib.rs
@@ -36,7 +36,7 @@
     DiceArtifacts, DiceMode, Hash, Hidden, InlineConfig, InputValues, PrivateKey, PrivateKeySeed,
     PublicKey, Signature, CDI_SIZE, HASH_SIZE, HIDDEN_SIZE, ID_SIZE, PRIVATE_KEY_SEED_SIZE,
 };
-pub use error::{check_result, DiceError, Result};
+pub use error::{DiceError, Result};
 pub use ops::{generate_certificate, hash, kdf, keypair_from_seed, sign, verify};
 #[cfg(feature = "std")]
 pub use retry::{
diff --git a/diced/open_dice/src/ops.rs b/diced/open_dice/src/ops.rs
index 8222b26..d978f86 100644
--- a/diced/open_dice/src/ops.rs
+++ b/diced/open_dice/src/ops.rs
@@ -31,14 +31,17 @@
     let mut output: Hash = [0; HASH_SIZE];
     // SAFETY: DiceHash takes a sized input buffer and writes to a constant-sized output buffer.
     // The first argument context is not used in this function.
-    check_result(unsafe {
-        DiceHash(
-            ptr::null_mut(), // context
-            input.as_ptr(),
-            input.len(),
-            output.as_mut_ptr(),
-        )
-    })?;
+    check_result(
+        unsafe {
+            DiceHash(
+                ptr::null_mut(), // context
+                input.as_ptr(),
+                input.len(),
+                output.as_mut_ptr(),
+            )
+        },
+        output.len(),
+    )?;
     Ok(output)
 }
 
@@ -47,19 +50,22 @@
 pub fn kdf(ikm: &[u8], salt: &[u8], info: &[u8], derived_key: &mut [u8]) -> Result<()> {
     // SAFETY: The function writes to the `derived_key`, within the given bounds, and only reads the
     // input values. The first argument context is not used in this function.
-    check_result(unsafe {
-        DiceKdf(
-            ptr::null_mut(), // context
-            derived_key.len(),
-            ikm.as_ptr(),
-            ikm.len(),
-            salt.as_ptr(),
-            salt.len(),
-            info.as_ptr(),
-            info.len(),
-            derived_key.as_mut_ptr(),
-        )
-    })
+    check_result(
+        unsafe {
+            DiceKdf(
+                ptr::null_mut(), // context
+                derived_key.len(),
+                ikm.as_ptr(),
+                ikm.len(),
+                salt.as_ptr(),
+                salt.len(),
+                info.as_ptr(),
+                info.len(),
+                derived_key.as_mut_ptr(),
+            )
+        },
+        derived_key.len(),
+    )
 }
 
 /// Deterministically generates a public and private key pair from `seed`.
@@ -70,14 +76,17 @@
     let mut private_key = PrivateKey::default();
     // SAFETY: The function writes to the `public_key` and `private_key` within the given bounds,
     // and only reads the `seed`. The first argument context is not used in this function.
-    check_result(unsafe {
-        DiceKeypairFromSeed(
-            ptr::null_mut(), // context
-            seed.as_ptr(),
-            public_key.as_mut_ptr(),
-            private_key.as_mut_ptr(),
-        )
-    })?;
+    check_result(
+        unsafe {
+            DiceKeypairFromSeed(
+                ptr::null_mut(), // context
+                seed.as_ptr(),
+                public_key.as_mut_ptr(),
+                private_key.as_mut_ptr(),
+            )
+        },
+        public_key.len(),
+    )?;
     Ok((public_key, private_key))
 }
 
@@ -86,15 +95,18 @@
     let mut signature = [0u8; SIGNATURE_SIZE];
     // SAFETY: The function writes to the `signature` within the given bounds, and only reads the
     // message and the private key. The first argument context is not used in this function.
-    check_result(unsafe {
-        DiceSign(
-            ptr::null_mut(), // context
-            message.as_ptr(),
-            message.len(),
-            private_key.as_ptr(),
-            signature.as_mut_ptr(),
-        )
-    })?;
+    check_result(
+        unsafe {
+            DiceSign(
+                ptr::null_mut(), // context
+                message.as_ptr(),
+                message.len(),
+                private_key.as_ptr(),
+                signature.as_mut_ptr(),
+            )
+        },
+        signature.len(),
+    )?;
     Ok(signature)
 }
 
@@ -102,15 +114,18 @@
 pub fn verify(message: &[u8], signature: &Signature, public_key: &PublicKey) -> Result<()> {
     // SAFETY: only reads the messages, signature and public key as constant values.
     // The first argument context is not used in this function.
-    check_result(unsafe {
-        DiceVerify(
-            ptr::null_mut(), // context
-            message.as_ptr(),
-            message.len(),
-            signature.as_ptr(),
-            public_key.as_ptr(),
-        )
-    })
+    check_result(
+        unsafe {
+            DiceVerify(
+                ptr::null_mut(), // context
+                message.as_ptr(),
+                message.len(),
+                signature.as_ptr(),
+                public_key.as_ptr(),
+            )
+        },
+        0,
+    )
 }
 
 /// Generates an X.509 certificate from the given `subject_private_key_seed` and
@@ -127,16 +142,19 @@
     let mut certificate_actual_size = 0;
     // SAFETY: The function writes to the `certificate` within the given bounds, and only reads the
     // input values and the key seeds. The first argument context is not used in this function.
-    check_result(unsafe {
-        DiceGenerateCertificate(
-            ptr::null_mut(), // context
-            subject_private_key_seed.as_ptr(),
-            authority_private_key_seed.as_ptr(),
-            input_values.as_ptr(),
-            certificate.len(),
-            certificate.as_mut_ptr(),
-            &mut certificate_actual_size,
-        )
-    })?;
+    check_result(
+        unsafe {
+            DiceGenerateCertificate(
+                ptr::null_mut(), // context
+                subject_private_key_seed.as_ptr(),
+                authority_private_key_seed.as_ptr(),
+                input_values.as_ptr(),
+                certificate.len(),
+                certificate.as_mut_ptr(),
+                &mut certificate_actual_size,
+            )
+        },
+        certificate_actual_size,
+    )?;
     Ok(certificate_actual_size)
 }
diff --git a/diced/open_dice/src/retry.rs b/diced/open_dice/src/retry.rs
index 76a214c..3db4781 100644
--- a/diced/open_dice/src/retry.rs
+++ b/diced/open_dice/src/retry.rs
@@ -51,35 +51,21 @@
     }
 }
 
-/// Retries the given function with bigger output buffer size.
-fn retry_with_bigger_buffer<F>(mut f: F) -> Result<Vec<u8>>
+/// Retries the given function with bigger measured buffer size.
+fn retry_with_measured_buffer<F>(mut f: F) -> Result<Vec<u8>>
 where
     F: FnMut(&mut Vec<u8>) -> Result<usize>,
 {
-    const INITIAL_BUFFER_SIZE: usize = 256;
-    const MAX_BUFFER_SIZE: usize = 64 * 1024 * 1024;
-
-    let mut buffer = vec![0u8; INITIAL_BUFFER_SIZE];
-    while buffer.len() <= MAX_BUFFER_SIZE {
-        match f(&mut buffer) {
-            Err(DiceError::BufferTooSmall) => {
-                let new_size = buffer.len() * 2;
-                buffer.resize(new_size, 0);
-            }
-            Err(e) => return Err(e),
-            Ok(actual_size) => {
-                if actual_size > buffer.len() {
-                    panic!(
-                        "actual_size larger than buffer size: open-dice function
-                         may have written past the end of the buffer."
-                    );
-                }
-                buffer.truncate(actual_size);
-                return Ok(buffer);
-            }
+    let mut buffer = Vec::new();
+    match f(&mut buffer) {
+        Err(DiceError::BufferTooSmall(actual_size)) => {
+            buffer.resize(actual_size, 0);
+            f(&mut buffer)?;
         }
-    }
-    Err(DiceError::PlatformError)
+        Err(e) => return Err(e),
+        Ok(_) => {}
+    };
+    Ok(buffer)
 }
 
 /// Formats a configuration descriptor following the BCC's specification.
@@ -88,7 +74,7 @@
     version: Option<u64>,
     resettable: bool,
 ) -> Result<Vec<u8>> {
-    retry_with_bigger_buffer(|buffer| {
+    retry_with_measured_buffer(|buffer| {
         bcc_format_config_descriptor(name, version, resettable, buffer)
     })
 }
@@ -104,7 +90,7 @@
     input_values: &InputValues,
 ) -> Result<OwnedDiceArtifacts> {
     let mut next_cdi_values = CdiValues::default();
-    let next_bcc = retry_with_bigger_buffer(|next_bcc| {
+    let next_bcc = retry_with_measured_buffer(|next_bcc| {
         bcc_main_flow(
             current_cdi_attest,
             current_cdi_seal,
@@ -127,7 +113,7 @@
     input_values: &InputValues,
 ) -> Result<(CdiValues, Vec<u8>)> {
     let mut next_cdi_values = CdiValues::default();
-    let next_cdi_certificate = retry_with_bigger_buffer(|next_cdi_certificate| {
+    let next_cdi_certificate = retry_with_measured_buffer(|next_cdi_certificate| {
         dice_main_flow(
             current_cdi_attest,
             current_cdi_seal,
@@ -149,7 +135,7 @@
     authority_private_key_seed: &[u8; PRIVATE_KEY_SEED_SIZE],
     input_values: &InputValues,
 ) -> Result<Vec<u8>> {
-    retry_with_bigger_buffer(|certificate| {
+    retry_with_measured_buffer(|certificate| {
         generate_certificate(
             subject_private_key_seed,
             authority_private_key_seed,