[rkp] Generalize CBOR conversion functions for reuse am: facc2b82cf am: 6b0c9acb3d am: e5db1963aa

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Virtualization/+/2775150

Change-Id: Icd4666928ed78967cb83c47ce8acf2cd87113486
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
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)
-    }
-}