[dice] Move DiceGenerateCertificate nostd/std versions to diced_open_dice

As a step of merging the existing diced_open_dice_cbor library into
the new open-dice wrapper diced_open_dice.

Bug: 267575445
Test: atest diced_utils_test diced_sample_inputs_test \
diced_vendor_test diced_open_dice_cbor_test \
libdiced_open_dice_nostd.integration_test \
libdiced_open_dice.integration_test diced_open_dice_cbor_test

Change-Id: Id50648f12be6cb236e8ea268bbbe791a30d5269b
diff --git a/diced/open_dice/src/lib.rs b/diced/open_dice/src/lib.rs
index f76494e..7e8c59a 100644
--- a/diced/open_dice/src/lib.rs
+++ b/diced/open_dice/src/lib.rs
@@ -34,9 +34,9 @@
     HIDDEN_SIZE, ID_SIZE, PRIVATE_KEY_SEED_SIZE,
 };
 pub use error::{check_result, DiceError, Result};
-pub use ops::{hash, kdf};
+pub use ops::{generate_certificate, hash, kdf};
 #[cfg(feature = "std")]
 pub use retry::{
     retry_bcc_format_config_descriptor, retry_bcc_main_flow, retry_dice_main_flow,
-    OwnedDiceArtifacts,
+    retry_generate_certificate, OwnedDiceArtifacts,
 };
diff --git a/diced/open_dice/src/ops.rs b/diced/open_dice/src/ops.rs
index 0eab116..3c0ef23 100644
--- a/diced/open_dice/src/ops.rs
+++ b/diced/open_dice/src/ops.rs
@@ -16,9 +16,9 @@
 //! It contains the set of functions that implement various operations that the
 //! main DICE functions depend on.
 
-use crate::dice::{Hash, HASH_SIZE};
+use crate::dice::{Hash, InputValues, HASH_SIZE, PRIVATE_KEY_SEED_SIZE};
 use crate::error::{check_result, Result};
-use open_dice_cbor_bindgen::{DiceHash, DiceKdf};
+use open_dice_cbor_bindgen::{DiceGenerateCertificate, DiceHash, DiceKdf};
 use std::ptr;
 
 /// Hashes the provided input using DICE's hash function `DiceHash`.
@@ -56,3 +56,31 @@
         )
     })
 }
+
+/// Generates an X.509 certificate from the given `subject_private_key_seed` and
+/// `input_values`, and signed by `authority_private_key_seed`.
+/// The subject private key seed is supplied here so the implementation can choose
+/// between asymmetric mechanisms, for example ECDSA vs Ed25519.
+/// Returns the actual size of the generated certificate.
+pub fn generate_certificate(
+    subject_private_key_seed: &[u8; PRIVATE_KEY_SEED_SIZE],
+    authority_private_key_seed: &[u8; PRIVATE_KEY_SEED_SIZE],
+    input_values: &InputValues,
+    certificate: &mut [u8],
+) -> Result<usize> {
+    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,
+        )
+    })?;
+    Ok(certificate_actual_size)
+}
diff --git a/diced/open_dice/src/retry.rs b/diced/open_dice/src/retry.rs
index 58648b8..c28b691 100644
--- a/diced/open_dice/src/retry.rs
+++ b/diced/open_dice/src/retry.rs
@@ -18,8 +18,9 @@
 //! std environment.
 
 use crate::bcc::{bcc_format_config_descriptor, bcc_main_flow};
-use crate::dice::{dice_main_flow, Cdi, CdiValues, InputValues};
+use crate::dice::{dice_main_flow, Cdi, CdiValues, InputValues, 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,
@@ -120,3 +121,23 @@
     })?;
     Ok((next_cdi_values, next_cdi_certificate))
 }
+
+/// Generates an X.509 certificate from the given `subject_private_key_seed` and
+/// `input_values`, and signed by `authority_private_key_seed`.
+/// The subject private key seed is supplied here so the implementation can choose
+/// between asymmetric mechanisms, for example ECDSA vs Ed25519.
+/// Returns the generated certificate.
+pub fn retry_generate_certificate(
+    subject_private_key_seed: &[u8; PRIVATE_KEY_SEED_SIZE],
+    authority_private_key_seed: &[u8; PRIVATE_KEY_SEED_SIZE],
+    input_values: &InputValues,
+) -> Result<Vec<u8>> {
+    retry_with_bigger_buffer(|certificate| {
+        generate_certificate(
+            subject_private_key_seed,
+            authority_private_key_seed,
+            input_values,
+            certificate,
+        )
+    })
+}
diff --git a/diced/open_dice_cbor/lib.rs b/diced/open_dice_cbor/lib.rs
index 4bcb93a..8af903f 100644
--- a/diced/open_dice_cbor/lib.rs
+++ b/diced/open_dice_cbor/lib.rs
@@ -39,8 +39,8 @@
 use keystore2_crypto::ZVec;
 pub use open_dice_cbor_bindgen::DiceMode;
 use open_dice_cbor_bindgen::{
-    DiceGenerateCertificate, DiceKeypairFromSeed, DiceSign, DiceVerify, DICE_PRIVATE_KEY_SIZE,
-    DICE_PUBLIC_KEY_SIZE, DICE_SIGNATURE_SIZE,
+    DiceKeypairFromSeed, DiceSign, DiceVerify, DICE_PRIVATE_KEY_SIZE, DICE_PUBLIC_KEY_SIZE,
+    DICE_SIGNATURE_SIZE,
 };
 use std::ffi::c_void;
 
@@ -51,60 +51,6 @@
 /// The size of a signature.
 pub const SIGNATURE_SIZE: usize = DICE_SIGNATURE_SIZE as usize;
 
-/// Multiple of the open dice function required preallocated output buffer
-/// which may be too small, this function implements the retry logic to handle
-/// too small buffer allocations.
-/// The callback `F` must expect a mutable reference to a buffer and a size hint
-/// field. The callback is called repeatedly as long as it returns
-/// `Err(Error::BufferTooSmall)`. If the size hint remains 0, the buffer size is
-/// doubled with each iteration. If the size hint is set by the callback, the buffer
-/// will be set to accommodate at least this many bytes.
-/// If the callback returns `Ok(())`, the buffer is truncated to the size hint
-/// exactly.
-/// The function panics if the callback returns `Ok(())` and the size hint is
-/// larger than the buffer size.
-/// TODO(b/267575445): Remove this method once we migrate all its callers to
-/// `retry_with_bigger_buffer` in `diced_open_dice`.
-fn retry_while_adjusting_output_buffer<F>(mut f: F) -> Result<Vec<u8>>
-where
-    F: FnMut(&mut Vec<u8>, &mut usize) -> Result<()>,
-{
-    let mut buffer = vec![0; INITIAL_OUT_BUFFER_SIZE];
-    let mut actual_size: usize = 0;
-    loop {
-        match f(&mut buffer, &mut actual_size) {
-            // If Error::BufferTooSmall was returned, the allocated certificate
-            // buffer was to small for the output. So the buffer is resized to the actual
-            // size, and a second attempt is made with the new buffer.
-            Err(DiceError::BufferTooSmall) => {
-                let new_size = if actual_size == 0 {
-                    // Due to an off spec implementation of open dice cbor, actual size
-                    // does not return the required size if the buffer was too small. So
-                    // we have to try and approach it gradually.
-                    buffer.len() * 2
-                } else {
-                    actual_size
-                };
-                buffer.resize(new_size, 0);
-                continue;
-            }
-            Err(e) => return Err(e),
-            Ok(()) => {
-                if actual_size > buffer.len() {
-                    panic!(
-                        "actual_size larger than buffer size: open-dice function
-                         may have written past the end of the buffer."
-                    );
-                }
-                // Truncate the certificate buffer to the actual size because it may be
-                // smaller than the original allocation.
-                buffer.truncate(actual_size);
-                return Ok(buffer);
-            }
-        }
-    }
-}
-
 /// Some libopen-dice variants use a context. Developers that want to customize these
 /// bindings may want to implement their own Context factory that creates a context
 /// useable by their preferred backend.
@@ -151,8 +97,6 @@
 /// Type alias for Vec<u8> indicating that it holds a BCC certificate chain.
 pub type Bcc = Vec<u8>;
 
-const INITIAL_OUT_BUFFER_SIZE: usize = 1024;
-
 /// ContextImpl is a mixin trait that implements the safe wrappers around the open dice
 /// library calls. Implementations must implement Context::get_context(). As of
 /// this writing, the only implementation is OpenDiceCborContext, which returns NULL.
@@ -238,43 +182,6 @@
             )
         })
     }
-
-    /// Safe wrapper around open-dice DiceGenerateCertificate, see open dice
-    /// documentation for details.
-    fn generate_certificate(
-        &mut self,
-        subject_private_key_seed: &[u8; PRIVATE_KEY_SEED_SIZE],
-        authority_private_key_seed: &[u8; PRIVATE_KEY_SEED_SIZE],
-        input_values: &InputValues,
-    ) -> Result<Vec<u8>> {
-        // SAFETY (DiceGenerateCertificate):
-        // * The first context argument may be NULL and is unused by the wrapped
-        //   implementation.
-        // * The second argument and the third argument are const arrays of size
-        //   `PRIVATE_KEY_SEED_SIZE`. This is fulfilled as per the definition of the arguments.
-        // * The fourth argument is a pointer to `DiceInputValues` it, and its indirect
-        //   references must be valid for the duration of the function call.
-        // * The fifth argument and the sixth argument are the length of and the pointer to the
-        //   allocated certificate buffer respectively. They are used to return
-        //   the generated certificate.
-        // * The seventh argument is a pointer to a mutable usize object. It is
-        //   used to return the actual size of the output certificate.
-        // * All pointers must be valid for the duration of the function call but not beyond.
-        let cert = retry_while_adjusting_output_buffer(|cert, actual_size| {
-            check_result(unsafe {
-                DiceGenerateCertificate(
-                    self.get_context(),
-                    subject_private_key_seed.as_ptr(),
-                    authority_private_key_seed.as_ptr(),
-                    input_values.as_ptr(),
-                    cert.len(),
-                    cert.as_mut_ptr(),
-                    actual_size as *mut _,
-                )
-            })
-        })?;
-        Ok(cert)
-    }
 }
 
 #[cfg(test)]