[rkp] Generalize CBOR conversion functions for reuse

This cl generalizes the CBOR conversion functions to make them
compatible with types other than Value. This will allow them to be
reused for the serialization and deserialization of the keyblob in
the future.

Bug: 279425980
Test: atest rialto_test
Change-Id: Ie5e16c6fae6ceef6c69911c2ce4d7d75325eef96
diff --git a/service_vm/requests/src/cbor.rs b/service_vm/requests/src/cbor.rs
new file mode 100644
index 0000000..36492e5
--- /dev/null
+++ b/service_vm/requests/src/cbor.rs
@@ -0,0 +1,37 @@
+// Copyright 2023, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Utility functions for CBOR serialization/deserialization.
+
+use alloc::vec::Vec;
+use coset::{CoseError, Result};
+use serde::{de::DeserializeOwned, Serialize};
+
+/// Serializes the given data to a CBOR-encoded byte vector.
+pub(crate) fn serialize<T: ?Sized + Serialize>(v: &T) -> Result<Vec<u8>> {
+    let mut data = Vec::new();
+    ciborium::into_writer(v, &mut data)?;
+    Ok(data)
+}
+
+/// Deserializes the given type from a CBOR-encoded byte slice, failing if any extra
+/// data remains after the type has been read.
+pub(crate) fn deserialize<T: DeserializeOwned>(mut data: &[u8]) -> Result<T> {
+    let res = ciborium::from_reader(&mut data)?;
+    if data.is_empty() {
+        Ok(res)
+    } else {
+        Err(CoseError::ExtraneousData)
+    }
+}
diff --git a/service_vm/requests/src/lib.rs b/service_vm/requests/src/lib.rs
index fc0c87d..eec0253 100644
--- a/service_vm/requests/src/lib.rs
+++ b/service_vm/requests/src/lib.rs
@@ -19,6 +19,7 @@
 extern crate alloc;
 
 mod api;
+mod cbor;
 mod pub_key;
 mod rkp;
 
diff --git a/service_vm/requests/src/rkp.rs b/service_vm/requests/src/rkp.rs
index f96b85d..bbb688e 100644
--- a/service_vm/requests/src/rkp.rs
+++ b/service_vm/requests/src/rkp.rs
@@ -15,7 +15,8 @@
 //! This module contains functions related to the attestation of the
 //! service VM via the RKP (Remote Key Provisioning) server.
 
-use super::pub_key::{build_maced_public_key, validate_public_key};
+use crate::cbor;
+use crate::pub_key::{build_maced_public_key, validate_public_key};
 use alloc::string::String;
 use alloc::vec;
 use alloc::vec::Vec;
@@ -80,7 +81,7 @@
         // TODO(b/299256925): Add device info in CBOR format here.
         Value::Array(public_keys),
     ])?;
-    let csr_payload = cbor_to_vec(&csr_payload)?;
+    let csr_payload = cbor::serialize(&csr_payload)?;
 
     // Builds `SignedData`.
     let signed_data_payload =
@@ -91,17 +92,15 @@
     // Currently `UdsCerts` is left empty because it is only needed for Samsung devices.
     // Check http://b/301574013#comment3 for more information.
     let uds_certs = Value::Map(Vec::new());
-    let dice_cert_chain = dice_artifacts
-        .bcc()
-        .map(read_to_value)
-        .ok_or(RequestProcessingError::MissingDiceChain)??;
+    let dice_cert_chain = dice_artifacts.bcc().ok_or(RequestProcessingError::MissingDiceChain)?;
+    let dice_cert_chain: Value = cbor::deserialize(dice_cert_chain)?;
     let auth_req = cbor!([
         Value::Integer(AUTH_REQ_SCHEMA_V1.into()),
         uds_certs,
         dice_cert_chain,
         signed_data,
     ])?;
-    cbor_to_vec(&auth_req)
+    Ok(cbor::serialize(&auth_req)?)
 }
 
 fn derive_hmac_key(dice_artifacts: &dyn DiceArtifacts) -> Result<Zeroizing<[u8; HMAC_KEY_LENGTH]>> {
@@ -123,7 +122,7 @@
     let protected = HeaderBuilder::new().algorithm(signing_algorithm).build();
     let signed_data = CoseSign1Builder::new()
         .protected(protected)
-        .payload(cbor_to_vec(payload)?)
+        .payload(cbor::serialize(payload)?)
         .try_create_signature(&[], |message| sign_message(message, &cdi_leaf_priv))?
         .build();
     Ok(signed_data)
@@ -142,24 +141,3 @@
         })?
         .to_vec())
 }
-
-fn cbor_to_vec(v: &Value) -> Result<Vec<u8>> {
-    let mut data = Vec::new();
-    ciborium::into_writer(v, &mut data).map_err(coset::CoseError::from)?;
-    Ok(data)
-}
-
-/// Read a CBOR `Value` from a byte slice, failing if any extra data remains
-/// after the `Value` has been read.
-fn read_to_value(mut data: &[u8]) -> Result<Value> {
-    let value = ciborium::from_reader(&mut data).map_err(|e| {
-        error!("Failed to deserialize the data into CBOR value: {e}");
-        RequestProcessingError::CborValueError
-    })?;
-    if data.is_empty() {
-        Ok(value)
-    } else {
-        error!("CBOR input has extra data.");
-        Err(RequestProcessingError::CborValueError)
-    }
-}