[dice] Move DiceKeypairFromSeed wrapper to diced_open_dice

This cl moves DiceKeypairFromSeed wrapper to diced_open_dice
and removes the crate diced_open_dice_cbor as it doesn't have
any code after moving out the function.

This cl also sets the type of PrivateKey and PrivateKeySeed to
struct so that their memory will be zeroed out when the struct
variable is dropped for security consideration. This is not
a complete solution for securing the sensitive data access: we
will clean up the memory cache of the sensitive data in a
follow-up cl.

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: I6c9b1190bfc4238adc59b88b6f3ee8fdd5cbd8f0
diff --git a/diced/open_dice/src/ops.rs b/diced/open_dice/src/ops.rs
index 21b7d9e..8222b26 100644
--- a/diced/open_dice/src/ops.rs
+++ b/diced/open_dice/src/ops.rs
@@ -17,11 +17,13 @@
 //! main DICE functions depend on.
 
 use crate::dice::{
-    Hash, InputValues, PublicKey, Signature, HASH_SIZE, PRIVATE_KEY_SEED_SIZE, PRIVATE_KEY_SIZE,
-    SIGNATURE_SIZE,
+    Hash, InputValues, PrivateKey, PublicKey, Signature, HASH_SIZE, PRIVATE_KEY_SEED_SIZE,
+    PRIVATE_KEY_SIZE, PUBLIC_KEY_SIZE, SIGNATURE_SIZE,
 };
 use crate::error::{check_result, Result};
-use open_dice_cbor_bindgen::{DiceGenerateCertificate, DiceHash, DiceKdf, DiceSign, DiceVerify};
+use open_dice_cbor_bindgen::{
+    DiceGenerateCertificate, DiceHash, DiceKdf, DiceKeypairFromSeed, DiceSign, DiceVerify,
+};
 use std::ptr;
 
 /// Hashes the provided input using DICE's hash function `DiceHash`.
@@ -60,6 +62,25 @@
     })
 }
 
+/// Deterministically generates a public and private key pair from `seed`.
+/// Since this is deterministic, `seed` is as sensitive as a private key and can
+/// be used directly as the private key.
+pub fn keypair_from_seed(seed: &[u8; PRIVATE_KEY_SEED_SIZE]) -> Result<(PublicKey, PrivateKey)> {
+    let mut public_key = [0u8; PUBLIC_KEY_SIZE];
+    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(),
+        )
+    })?;
+    Ok((public_key, private_key))
+}
+
 /// Signs the `message` with the give `private_key` using `DiceSign`.
 pub fn sign(message: &[u8], private_key: &[u8; PRIVATE_KEY_SIZE]) -> Result<Signature> {
     let mut signature = [0u8; SIGNATURE_SIZE];