Move secretkeeper to separate repo
Test: build
Bug: 306364873
Change-Id: I06e819b0e7d5388517b89f53ed347c992df4adc5
diff --git a/secretkeeper/comm/Android.bp b/secretkeeper/comm/Android.bp
deleted file mode 100644
index cb3e713..0000000
--- a/secretkeeper/comm/Android.bp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-rust_defaults {
- name: "libsecretkeeper_comm.defaults",
- crate_name: "secretkeeper_comm",
- defaults: ["avf_build_flags_rust"],
- edition: "2021",
- lints: "android",
- rustlibs: [
- "libciborium",
- "libcoset",
- ],
- proc_macros: ["libenumn"],
- vendor_available: true,
-}
-
-rust_library {
- name: "libsecretkeeper_comm_nostd",
- defaults: ["libsecretkeeper_comm.defaults"],
- srcs: ["src/lib.rs"],
-}
-
-rust_test {
- name: "libsecretkeeper_comm.test",
- defaults: [
- "libsecretkeeper_comm.defaults",
- "rdroidtest.defaults",
- ],
- srcs: ["tests/*.rs"],
- test_suites: ["general-tests"],
- rustlibs: [
- "libsecretkeeper_comm_nostd",
- ],
-}
diff --git a/secretkeeper/comm/src/cbor_convert.rs b/secretkeeper/comm/src/cbor_convert.rs
deleted file mode 100644
index ab6ca3f..0000000
--- a/secretkeeper/comm/src/cbor_convert.rs
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-//! Implements various useful CBOR conversion method.
-
-use crate::data_types::error::Error;
-use alloc::vec::Vec;
-use ciborium::Value;
-
-/// Decodes the provided binary CBOR-encoded value and returns a
-/// [`ciborium::Value`] struct wrapped in Result.
-pub fn value_from_bytes(mut bytes: &[u8]) -> Result<Value, Error> {
- let value = ciborium::de::from_reader(&mut bytes).map_err(|_| Error::ConversionError)?;
- // Ciborium tries to read one Value, but doesn't care if there is trailing data after it. We do
- if !bytes.is_empty() {
- return Err(Error::ConversionError);
- }
- Ok(value)
-}
-
-/// Encodes a [`ciborium::Value`] into bytes.
-pub fn value_to_bytes(value: &Value) -> Result<Vec<u8>, Error> {
- let mut bytes: Vec<u8> = Vec::new();
- ciborium::ser::into_writer(&value, &mut bytes).map_err(|_| Error::UnexpectedError)?;
- Ok(bytes)
-}
-
-// Useful to convert [`ciborium::Value`] to integer, we return largest integer range for
-// convenience, callers should downcast into appropriate type.
-pub fn value_to_integer(value: &Value) -> Result<i128, Error> {
- let num = value.as_integer().ok_or(Error::ConversionError)?.into();
- Ok(num)
-}
diff --git a/secretkeeper/comm/src/data_types/error.rs b/secretkeeper/comm/src/data_types/error.rs
deleted file mode 100644
index 6a5e24f..0000000
--- a/secretkeeper/comm/src/data_types/error.rs
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-//! Error-like data structures. See `ResponsePacketError` in the CDDL
-
-// derive(N) generates a method that is missing a docstring.
-#![allow(missing_docs)]
-
-use crate::cbor_convert::value_to_integer;
-use crate::data_types::response::Response;
-use alloc::boxed::Box;
-use alloc::vec::Vec;
-use ciborium::Value;
-use enumn::N;
-
-/// 'Error code' corresponding to successful response.
-pub const ERROR_OK: u16 = 0; // All real errors must have non-zero error_codes
-
-/// Errors from Secretkeeper API. Keep in sync with `ErrorCode` defined for Secretkeeper HAL
-/// at SecretManagement.cddl
-#[derive(Clone, Copy, Debug, Eq, N, PartialEq)]
-pub enum SecretkeeperError {
- // This is the Error code used if no other error codes explains the issue.
- UnexpectedServerError = 1,
- // Indicates the Request was malformed & hence couldn't be served.
- RequestMalformed = 2,
- // TODO(b/291228655): Add other errors such as DicePolicyError.
-}
-
-// [`SecretkeeperError`] is a valid [`Response`] type.
-// For more information see `ErrorCode` in SecretManagement.cddl alongside ISecretkeeper.aidl
-impl Response for SecretkeeperError {
- fn new(response_cbor: Vec<Value>) -> Result<Box<Self>, Error> {
- // TODO(b/291228655): This method currently discards the second value in response_cbor,
- // which contains additional human-readable context in error. Include it!
- if response_cbor.is_empty() || response_cbor.len() > 2 {
- return Err(Error::ResponseMalformed);
- }
- let error_code: u16 = value_to_integer(&response_cbor[0])?.try_into()?;
- SecretkeeperError::n(error_code)
- .map_or_else(|| Err(Error::ResponseMalformed), |sk_err| Ok(Box::new(sk_err)))
- }
-
- fn error_code(&self) -> u16 {
- *self as u16
- }
-}
-
-/// Errors thrown internally by the library.
-#[derive(Debug, PartialEq)]
-pub enum Error {
- /// Request was malformed.
- RequestMalformed,
- /// Response received from the server was malformed.
- ResponseMalformed,
- /// An error happened when serializing to/from a [`Value`].
- CborValueError,
- /// An error happened while casting a type to different type,
- /// including one [`Value`] type to another.
- ConversionError,
- /// These are unexpected errors, which should never really happen.
- UnexpectedError,
-}
-
-impl From<ciborium::value::Error> for Error {
- fn from(_e: ciborium::value::Error) -> Self {
- Self::CborValueError
- }
-}
-
-impl From<ciborium::Value> for Error {
- fn from(_e: ciborium::Value) -> Self {
- Self::ConversionError
- }
-}
-
-impl From<core::num::TryFromIntError> for Error {
- fn from(_e: core::num::TryFromIntError) -> Self {
- Self::ConversionError
- }
-}
diff --git a/secretkeeper/comm/src/data_types/mod.rs b/secretkeeper/comm/src/data_types/mod.rs
deleted file mode 100644
index 096777f..0000000
--- a/secretkeeper/comm/src/data_types/mod.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-//! Implements the data structures specified by SecretManagement.cddl in Secretkeeper HAL.
-//! Data structures specified by SecretManagement.cddl in Secretkeeper HAL.
-//! Note this library must stay in sync with:
-//! platform/hardware/interfaces/security/\
-//! secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
-
-pub mod error;
-pub mod packet;
-pub mod request;
-pub mod request_response_impl;
-pub mod response;
diff --git a/secretkeeper/comm/src/data_types/packet.rs b/secretkeeper/comm/src/data_types/packet.rs
deleted file mode 100644
index 7a1e575..0000000
--- a/secretkeeper/comm/src/data_types/packet.rs
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-//! Defines the packet structures passed between functional layer & the layer below.
-
-pub use ciborium::Value;
-
-use crate::cbor_convert::{value_from_bytes, value_to_bytes, value_to_integer};
-use crate::data_types::error::Error;
-use crate::data_types::error::ERROR_OK;
-use crate::data_types::request_response_impl::Opcode;
-use alloc::vec::Vec;
-
-/// Encapsulate Request-like data that functional layer operates on. All structures
-/// that implements `data_types::request::Request` can be serialized to [`ResponsePacket`].
-/// Similarly all [`RequestPacket`] can be deserialized to concrete Requests.
-/// Keep in sync with HAL spec (in particular RequestPacket):
-/// security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
-#[derive(Clone, Debug, PartialEq)]
-pub struct RequestPacket(Vec<Value>);
-
-impl RequestPacket {
- /// Construct a [`RequestPacket`] from array of `ciborium::Value`
- pub fn from(request_cbor: Vec<Value>) -> Self {
- Self(request_cbor)
- }
-
- /// Get the containing CBOR. This can be used for getting concrete response objects.
- /// Keep in sync with [`crate::data_types::request::Request::serialize_to_packet()`]
- pub fn into_inner(self) -> Vec<Value> {
- self.0
- }
-
- /// Extract [`Opcode`] corresponding to this packet. As defined in by the spec, this is
- /// the first value in the CBOR array.
- pub fn opcode(&self) -> Result<Opcode, Error> {
- if self.0.is_empty() {
- return Err(Error::RequestMalformed);
- }
- let num: u16 = value_to_integer(&self.0[0])?.try_into()?;
-
- Opcode::n(num).ok_or(Error::RequestMalformed)
- }
-
- /// Serialize the [`ResponsePacket`] to bytes
- pub fn into_bytes(self) -> Result<Vec<u8>, Error> {
- value_to_bytes(&Value::Array(self.0))
- }
-
- /// Deserialize the bytes into [`ResponsePacket`]
- pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
- Ok(RequestPacket(value_from_bytes(bytes)?.into_array()?))
- }
-}
-
-/// Encapsulate Response like data that the functional layer operates on. All structures
-/// that implements `data_types::response::Response` can be serialized to [`ResponsePacket`].
-/// Similarly all [`ResponsePacket`] can be deserialized to concrete Response.
-#[derive(Clone, Debug, PartialEq)]
-pub struct ResponsePacket(Vec<Value>);
-
-impl ResponsePacket {
- /// Construct a [`ResponsePacket`] from array of `ciborium::Value`
- pub fn from(response_cbor: Vec<Value>) -> Self {
- Self(response_cbor)
- }
-
- /// Get raw content. This can be used for getting concrete response objects.
- /// Keep in sync with `crate::data_types::response::Response::serialize_to_packet`
- pub fn into_inner(self) -> Vec<Value> {
- self.0
- }
-
- /// A [`ResponsePacket`] encapsulates different types of responses, find which one!
- pub fn response_type(&self) -> Result<ResponseType, Error> {
- if self.0.is_empty() {
- return Err(Error::ResponseMalformed);
- }
- let error_code: u16 = value_to_integer(&self.0[0])?.try_into()?;
- if error_code == ERROR_OK {
- Ok(ResponseType::Success)
- } else {
- Ok(ResponseType::Error)
- }
- }
-
- /// Serialize the [`ResponsePacket`] to bytes
- pub fn into_bytes(self) -> Result<Vec<u8>, Error> {
- value_to_bytes(&Value::Array(self.0))
- }
-
- /// Deserialize the bytes into [`ResponsePacket`]
- pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
- Ok(ResponsePacket(value_from_bytes(bytes)?.into_array()?))
- }
-}
-
-/// Responses can be different type - `Success`-like or `Error`-like.
-#[derive(Debug, Eq, PartialEq)]
-pub enum ResponseType {
- /// Indicates successful operation. See `ResponsePacketSuccess` in SecretManagement.cddl
- Success,
- /// Indicate failed operation. See `ResponsePacketError` in SecretManagement.cddl
- Error,
-}
diff --git a/secretkeeper/comm/src/data_types/request.rs b/secretkeeper/comm/src/data_types/request.rs
deleted file mode 100644
index 0d54bcd..0000000
--- a/secretkeeper/comm/src/data_types/request.rs
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-//! Defines the shared behaviour of all request like data structures.
-
-use crate::data_types::error::Error;
-use crate::data_types::packet::RequestPacket;
-use crate::data_types::request_response_impl::Opcode;
-use alloc::boxed::Box;
-use alloc::vec::Vec;
-use ciborium::Value;
-
-/// Collection of methods defined for Secretkeeper's request-like data structures,
-/// e.g. `GetVersionRequestPacket` in the HAL spec.
-///
-/// Keep in sync with SecretManagement.cddl, in particular `RequestPacket` type.
-pub trait Request {
- /// [`Opcode`] of the request: Each Request type is associated with an opcode. See `Opcode` in
- /// SecretManagement.cddl.
- const OPCODE: Opcode;
-
- /// Constructor of the [`Request`] object. Implementation of this constructor should check
- /// the args' type adheres to the HAL spec.
- ///
- /// # Arguments
- /// * `args` - The vector of arguments associated with this request. Each argument is a
- /// `ciborium::Value` type. See `Params` in `RequestPacket` in SecretManagement.cddl
- fn new(args: Vec<Value>) -> Result<Box<Self>, Error>;
-
- /// Get the 'arguments' of this request.
- fn args(&self) -> Vec<Value>;
-
- /// Serialize the request to a [`RequestPacket`], which, as per SecretManagement.cddl is:
- /// ```
- /// RequestPacket<Opcode, Params> = [
- /// Opcode,
- /// Params
- /// ]
- /// ```
- fn serialize_to_packet(&self) -> RequestPacket {
- let mut res = self.args();
- res.insert(0, Value::from(Self::OPCODE as u16));
- RequestPacket::from(res)
- }
-
- /// Construct the [`Request`] struct from given [`RequestPacket`].
- fn deserialize_from_packet(packet: RequestPacket) -> Result<Box<Self>, Error> {
- let mut req = packet.into_inner();
- if req.get(0) != Some(&Value::from(Self::OPCODE as u16)) {
- return Err(Error::RequestMalformed);
- }
- req.remove(0);
- Self::new(req)
- }
-}
diff --git a/secretkeeper/comm/src/data_types/request_response_impl.rs b/secretkeeper/comm/src/data_types/request_response_impl.rs
deleted file mode 100644
index a7d29cc..0000000
--- a/secretkeeper/comm/src/data_types/request_response_impl.rs
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-//! Implementation of request & response like data structures.
-
-// derive(N) generates a method that is missing a docstring.
-#![allow(missing_docs)]
-
-use crate::cbor_convert::value_to_integer;
-use crate::data_types::error::Error;
-use crate::data_types::error::ERROR_OK;
-use crate::data_types::request::Request;
-use crate::data_types::response::Response;
-use alloc::boxed::Box;
-use alloc::vec;
-use alloc::vec::Vec;
-use ciborium::Value;
-use enumn::N;
-
-/// Set of all possible `Opcode` supported by SecretManagement API of the HAL.
-/// See `Opcode` in SecretManagement.cddl
-#[derive(Clone, Copy, Debug, N, PartialEq)]
-#[non_exhaustive]
-pub enum Opcode {
- /// Get version of the SecretManagement API.
- GetVersion = 1,
- /// Store a secret
- StoreSecret = 2,
- /// Get the secret
- GetSecret = 3,
-}
-
-/// Corresponds to `GetVersionRequestPacket` defined in SecretManagement.cddl
-#[derive(Debug, Eq, PartialEq)]
-pub struct GetVersionRequest;
-
-impl Request for GetVersionRequest {
- const OPCODE: Opcode = Opcode::GetVersion;
-
- fn new(args: Vec<Value>) -> Result<Box<Self>, Error> {
- if !args.is_empty() {
- return Err(Error::RequestMalformed);
- }
- Ok(Box::new(Self))
- }
-
- fn args(&self) -> Vec<Value> {
- Vec::new()
- }
-}
-
-/// Success response corresponding to `GetVersionResponsePacket`.
-#[derive(Debug, Eq, PartialEq)]
-pub struct GetVersionResponse {
- /// Version of SecretManagement API
- version: u64,
-}
-
-impl GetVersionResponse {
- pub fn new(version: u64) -> Self {
- Self { version }
- }
- pub fn version(&self) -> u64 {
- self.version
- }
-}
-
-impl Response for GetVersionResponse {
- fn new(res: Vec<Value>) -> Result<Box<Self>, Error> {
- if res.len() != 2 {
- return Err(Error::ResponseMalformed);
- }
- let error_code: u16 = value_to_integer(&res[0])?.try_into()?;
- if error_code != ERROR_OK {
- return Err(Error::ResponseMalformed);
- }
- let version: u64 = value_to_integer(&res[1])?.try_into()?;
- Ok(Box::new(Self::new(version)))
- }
-
- fn result(&self) -> Vec<Value> {
- vec![self.version.into()]
- }
-}
diff --git a/secretkeeper/comm/src/data_types/response.rs b/secretkeeper/comm/src/data_types/response.rs
deleted file mode 100644
index e975ebc..0000000
--- a/secretkeeper/comm/src/data_types/response.rs
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-//! Defines the shared behaviour of all response like data structures.
-
-use crate::data_types::error::{Error, ERROR_OK};
-use crate::data_types::packet::ResponsePacket;
-use alloc::boxed::Box;
-use alloc::vec::Vec;
-use ciborium::Value;
-
-/// Shared behaviour of all Secretkeeper's response-like data structures,
-/// e.g. `GetVersionResponsePacket`. Note - A valid [`Response`] can be error as well, like
-/// `SecretkeeperError::RequestMalformed`.
-///
-/// Keep in sync with SecretManagement.cddl, in particular `ResponsePacket` type.
-pub trait Response {
- /// Constructor of the Response object.
- /// # Arguments
- /// * `response_cbor`: A vector of `[ciborium::Value]` such that:
- /// ```
- /// For success-like responses:
- /// ResponsePacketSuccess = [
- /// 0, ; Indicates successful Response
- /// result : Result
- /// ]
- /// For error responses:
- /// ResponsePacketError = [
- /// error_code: ErrorCode, ; Indicate the error
- /// error_message: tstr ; Additional human-readable context
- /// ]
- /// ```
- /// See ResponsePacket<Result> in SecretManagement.cddl alongside ISecretkeeper.aidl
- fn new(response_cbor: Vec<Value>) -> Result<Box<Self>, Error>;
-
- /// The result in the `Response`. By default this is empty, but [`Response`] structures like
- /// `GetVersionResponse` must overwrite these to return the expected non-empty result.
- fn result(&self) -> Vec<Value> {
- Vec::new()
- }
-
- /// Error code corresponding to the response. The default value is 0 but that will work only
- /// for successful responses. Error-like response structures must overwrite this method.
- fn error_code(&self) -> u16 {
- ERROR_OK // Indicates success
- }
-
- /// Serialize the response to a [`ResponsePacket`].
- fn serialize_to_packet(&self) -> ResponsePacket {
- let mut res = self.result();
- res.insert(0, Value::from(self.error_code()));
- ResponsePacket::from(res)
- }
-
- /// Construct the response struct from given [`ResponsePacket`].
- fn deserialize_from_packet(packet: ResponsePacket) -> Result<Box<Self>, Error> {
- let res = packet.into_inner();
- // Empty response packet is not allowed, all responses in Secretkeeper HAL at least
- // have `error_code` or '0'; so throw an error!
- if res.is_empty() {
- return Err(Error::ResponseMalformed);
- }
- Self::new(res)
- }
-}
diff --git a/secretkeeper/comm/src/lib.rs b/secretkeeper/comm/src/lib.rs
deleted file mode 100644
index 9a10ac0..0000000
--- a/secretkeeper/comm/src/lib.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-//! This library exposes data structures and methods that can be used by Secretkeeper HAL & client
-//! implementation. This is compatible with Secretkeeper HAL specification.
-
-#![no_std]
-extern crate alloc;
-
-mod cbor_convert;
-pub mod data_types;
diff --git a/secretkeeper/comm/tests/data_types.rs b/secretkeeper/comm/tests/data_types.rs
deleted file mode 100644
index 68964fd..0000000
--- a/secretkeeper/comm/tests/data_types.rs
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-//! Unit tests for testing serialization & deserialization of exported data_types.
-
-use ciborium::Value;
-use secretkeeper_comm::data_types::error::{Error, SecretkeeperError, ERROR_OK};
-use secretkeeper_comm::data_types::packet::{RequestPacket, ResponsePacket, ResponseType};
-use secretkeeper_comm::data_types::request::Request;
-use secretkeeper_comm::data_types::request_response_impl::Opcode;
-use secretkeeper_comm::data_types::request_response_impl::{GetVersionRequest, GetVersionResponse};
-use secretkeeper_comm::data_types::response::Response;
-
-#[cfg(test)]
-rdroidtest::test_main!();
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use rdroidtest::test;
-
- test!(request_serialization_deserialization);
- fn request_serialization_deserialization() {
- let req = GetVersionRequest {};
- let packet = req.serialize_to_packet();
- assert_eq!(packet.opcode().unwrap(), Opcode::GetVersion);
- assert_eq!(
- RequestPacket::from_bytes(&packet.clone().into_bytes().unwrap()).unwrap(),
- packet
- );
- let req_deserialized = *GetVersionRequest::deserialize_from_packet(packet).unwrap();
- assert_eq!(req, req_deserialized);
- }
-
- test!(success_response_serialization_deserialization);
- fn success_response_serialization_deserialization() {
- let response = GetVersionResponse::new(1);
- let packet = response.serialize_to_packet();
- assert_eq!(packet.response_type().unwrap(), ResponseType::Success);
- assert_eq!(
- ResponsePacket::from_bytes(&packet.clone().into_bytes().unwrap()).unwrap(),
- packet
- );
- let response_deserialized = *GetVersionResponse::deserialize_from_packet(packet).unwrap();
- assert_eq!(response, response_deserialized);
- }
-
- test!(error_response_serialization_deserialization);
- fn error_response_serialization_deserialization() {
- let response = SecretkeeperError::RequestMalformed;
- let packet = response.serialize_to_packet();
- assert_eq!(packet.response_type().unwrap(), ResponseType::Error);
- assert_eq!(
- ResponsePacket::from_bytes(&packet.clone().into_bytes().unwrap()).unwrap(),
- packet
- );
- let response_deserialized = *SecretkeeperError::deserialize_from_packet(packet).unwrap();
- assert_eq!(response, response_deserialized);
- }
-
- test!(request_creation);
- fn request_creation() {
- let req: GetVersionRequest = *Request::new(vec![]).unwrap();
- assert_eq!(req, GetVersionRequest {});
- }
-
- test!(response_creation);
- fn response_creation() {
- let res: GetVersionResponse =
- *Response::new(vec![Value::from(ERROR_OK), Value::from(5)]).unwrap();
- assert_eq!(res.version(), 5);
- }
-
- test!(invalid_get_version_request_creation);
- fn invalid_get_version_request_creation() {
- // A request with non-zero arg is considered invalid.
- assert_eq!(
- <GetVersionRequest as Request>::new(vec![Value::Null]).unwrap_err(),
- Error::RequestMalformed
- );
- }
-
- test!(invalid_get_version_response_creation);
- fn invalid_get_version_response_creation() {
- // A response with non-zero error_code is an invalid success response.
- assert_eq!(
- <GetVersionResponse as Response>::new(vec![
- Value::from(SecretkeeperError::RequestMalformed as u16),
- Value::from(5)
- ])
- .unwrap_err(),
- Error::ResponseMalformed
- );
-
- // A response with incorrect size of array is invalid.
- assert_eq!(
- <GetVersionResponse as Response>::new(vec![
- Value::from(ERROR_OK),
- Value::from(5),
- Value::from(7)
- ])
- .unwrap_err(),
- Error::ResponseMalformed
- );
-
- // A response with incorrect type is invalid.
- <GetVersionResponse as Response>::new(vec![Value::from(ERROR_OK), Value::from("a tstr")])
- .unwrap_err();
- }
-
- test!(invalid_error_response_creation);
- fn invalid_error_response_creation() {
- // A response with ERROR_OK(0) as the error_code is an invalid error response.
- assert_eq!(
- <SecretkeeperError as Response>::new(vec![Value::from(ERROR_OK)]).unwrap_err(),
- Error::ResponseMalformed
- );
- }
-}
diff --git a/secretkeeper/dice_policy/Android.bp b/secretkeeper/dice_policy/Android.bp
deleted file mode 100644
index 4f1e8b6..0000000
--- a/secretkeeper/dice_policy/Android.bp
+++ /dev/null
@@ -1,37 +0,0 @@
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-rust_defaults {
- name: "libdice_policy.defaults",
- crate_name: "dice_policy",
- defaults: ["avf_build_flags_rust"],
- srcs: ["src/lib.rs"],
- edition: "2021",
- prefer_rlib: true,
- rustlibs: [
- "libanyhow",
- "libciborium",
- "libcoset",
- "libnum_traits",
- ],
- proc_macros: ["libnum_derive"],
-}
-
-rust_library {
- name: "libdice_policy",
- defaults: ["libdice_policy.defaults"],
-}
-
-rust_test {
- name: "libdice_policy.test",
- defaults: [
- "libdice_policy.defaults",
- "rdroidtest.defaults",
- ],
- test_suites: ["general-tests"],
- rustlibs: [
- "librustutils",
- "libscopeguard",
- ],
-}
diff --git a/secretkeeper/dice_policy/src/lib.rs b/secretkeeper/dice_policy/src/lib.rs
deleted file mode 100644
index 076ba3b..0000000
--- a/secretkeeper/dice_policy/src/lib.rs
+++ /dev/null
@@ -1,504 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-//! A “DICE policy” is a format for setting constraints on a DICE chain. A DICE chain policy
-//! verifier takes a policy and a DICE chain, and returns a boolean indicating whether the
-//! DICE chain meets the constraints set out on a policy.
-//!
-//! This forms the foundation of Dice Policy aware Authentication (DPA-Auth), where the server
-//! authenticates a client by comparing its dice chain against a set policy.
-//!
-//! Another use is "sealing", where clients can use an appropriately constructed dice policy to
-//! seal a secret. Unsealing is only permitted if dice chain of the component requesting unsealing
-//! complies with the policy.
-//!
-//! A typical policy will assert things like:
-//! # DK_pub must have this value
-//! # The DICE chain must be exactly five certificates long
-//! # authorityHash in the third certificate must have this value
-//! securityVersion in the fourth certificate must be an integer greater than 8
-//!
-//! These constraints used to express policy are (for now) limited to following 2 types:
-//! 1. Exact Match: useful for enforcing rules like authority hash should be exactly equal.
-//! 2. Greater than or equal to: Useful for setting policies that seal
-//! Anti-rollback protected entities (should be accessible to versions >= present).
-//!
-//! Dice Policy CDDL:
-//!
-//! dicePolicy = [
-//! 1, ; dice policy version
-//! + nodeConstraintList ; for each entry in dice chain
-//! ]
-//!
-//! nodeConstraintList = [
-//! * nodeConstraint
-//! ]
-//!
-//! ; We may add a hashConstraint item later
-//! nodeConstraint = exactMatchConstraint / geConstraint
-//!
-//! exactMatchConstraint = [1, keySpec, value]
-//! geConstraint = [2, keySpec, int]
-//!
-//! keySpec = [value+]
-//!
-//! value = bool / int / tstr / bstr
-
-use anyhow::{anyhow, bail, ensure, Context, Result};
-use ciborium::Value;
-use coset::{AsCborValue, CoseSign1};
-use num_derive::FromPrimitive;
-use num_traits::FromPrimitive;
-use std::borrow::Cow;
-use std::iter::zip;
-
-const DICE_POLICY_VERSION: u64 = 1;
-
-/// Constraint Types supported in Dice policy.
-#[repr(u16)]
-#[non_exhaustive]
-#[derive(Clone, Copy, Debug, FromPrimitive, PartialEq)]
-pub enum ConstraintType {
- /// Enforce exact match criteria, indicating the policy should match
- /// if the dice chain has exact same specified values.
- ExactMatch = 1,
- /// Enforce Greater than or equal to criteria. When applied on security_version, this
- /// can be useful to set policy that matches dice chains with same or upgraded images.
- GreaterOrEqual = 2,
-}
-
-/// ConstraintSpec is used to specify which constraint type to apply and
-/// on which all entries in a dice node.
-/// See documentation of `from_dice_chain()` for examples.
-pub struct ConstraintSpec {
- constraint_type: ConstraintType,
- // path is essentially a list of label/int.
- // It identifies which entry (in a dice node) to be applying constraints on.
- path: Vec<i64>,
-}
-
-impl ConstraintSpec {
- /// Construct the ConstraintSpec.
- pub fn new(constraint_type: ConstraintType, path: Vec<i64>) -> Result<Self> {
- Ok(ConstraintSpec { constraint_type, path })
- }
-}
-
-// TODO(b/291238565): Restrict (nested_)key & value type to (bool/int/tstr/bstr).
-// and maybe convert it into struct.
-/// Each constraint (on a dice node) is a tuple: (ConstraintType, constraint_path, value)
-#[derive(Debug, PartialEq)]
-struct Constraint(u16, Vec<i64>, Value);
-
-/// List of all constraints on a dice node.
-#[derive(Debug, PartialEq)]
-struct NodeConstraints(Box<[Constraint]>);
-
-/// Module for working with dice policy.
-#[derive(Debug, PartialEq)]
-pub struct DicePolicy {
- version: u64,
- node_constraints_list: Box<[NodeConstraints]>, // Constraint on each entry in dice chain.
-}
-
-impl DicePolicy {
- /// Construct a dice policy from a given dice chain.
- /// This can be used by clients to construct a policy to seal secrets.
- /// Constraints on all but first dice node is applied using constraint_spec argument.
- /// For the first node (which is a ROT key), the constraint is ExactMatch of the whole node.
- ///
- /// # Arguments
- /// `dice_chain`: The serialized CBOR encoded Dice chain, adhering to Android Profile for DICE.
- /// https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/android.md
- ///
- /// `constraint_spec`: List of constraints to be applied on dice node.
- /// Each constraint is a ConstraintSpec object.
- ///
- /// Note: Dice node is treated as a nested map (& so the lookup is done in that fashion).
- ///
- /// Examples of constraint_spec:
- /// 1. For exact_match on auth_hash & greater_or_equal on security_version
- /// constraint_spec =[
- /// (ConstraintType::ExactMatch, vec![AUTHORITY_HASH]),
- /// (ConstraintType::GreaterOrEqual, vec![CONFIG_DESC, COMPONENT_NAME]),
- /// ];
- ///
- /// 2. For hypothetical (and highly simplified) dice chain:
- ///
- /// [ROT_KEY, [{1 : 'a', 2 : {200 : 5, 201 : 'b'}}]]
- /// The following can be used
- /// constraint_spec =[
- /// ConstraintSpec(ConstraintType::ExactMatch, vec![1]), // exact_matches value 'a'
- /// ConstraintSpec(ConstraintType::GreaterOrEqual, vec![2, 200]),// matches any value >= 5
- /// ];
- pub fn from_dice_chain(dice_chain: &[u8], constraint_spec: &[ConstraintSpec]) -> Result<Self> {
- let dice_chain = deserialize_dice_chain(dice_chain)?;
- let mut constraints_list: Vec<NodeConstraints> = Vec::with_capacity(dice_chain.len());
- let mut it = dice_chain.into_iter();
-
- constraints_list.push(NodeConstraints(Box::new([Constraint(
- ConstraintType::ExactMatch as u16,
- Vec::new(),
- it.next().unwrap(),
- )])));
-
- for (n, value) in it.enumerate() {
- let entry = cbor_value_from_cose_sign(value)
- .with_context(|| format!("Unable to get Cose payload at: {}", n))?;
- constraints_list.push(payload_to_constraints(entry, constraint_spec)?);
- }
-
- Ok(DicePolicy {
- version: DICE_POLICY_VERSION,
- node_constraints_list: constraints_list.into_boxed_slice(),
- })
- }
-
- /// Dice chain policy verifier - Compare the input dice chain against this Dice policy.
- /// The method returns Ok() if the dice chain meets the constraints set in Dice policy,
- /// otherwise returns error in case of mismatch.
- /// TODO(b/291238565) Create a separate error module for DicePolicy mismatches.
- pub fn matches_dice_chain(&self, dice_chain: &[u8]) -> Result<()> {
- let dice_chain = deserialize_dice_chain(dice_chain)?;
- ensure!(
- dice_chain.len() == self.node_constraints_list.len(),
- format!(
- "Dice chain size({}) does not match policy({})",
- dice_chain.len(),
- self.node_constraints_list.len()
- )
- );
-
- for (n, (dice_node, node_constraints)) in
- zip(dice_chain, self.node_constraints_list.iter()).enumerate()
- {
- let dice_node_payload = if n == 0 {
- dice_node
- } else {
- cbor_value_from_cose_sign(dice_node)
- .with_context(|| format!("Unable to get Cose payload at: {}", n))?
- };
- check_constraints_on_node(node_constraints, &dice_node_payload)
- .context(format!("Mismatch found at {}", n))?;
- }
- Ok(())
- }
-}
-
-fn check_constraints_on_node(node_constraints: &NodeConstraints, dice_node: &Value) -> Result<()> {
- for constraint in node_constraints.0.iter() {
- check_constraint_on_node(constraint, dice_node)?;
- }
- Ok(())
-}
-
-fn check_constraint_on_node(constraint: &Constraint, dice_node: &Value) -> Result<()> {
- let Constraint(cons_type, path, value_in_constraint) = constraint;
- let value_in_node = lookup_value_in_nested_map(dice_node, path)?;
- match ConstraintType::from_u16(*cons_type).ok_or(anyhow!("Unexpected Constraint type"))? {
- ConstraintType::ExactMatch => ensure!(value_in_node == *value_in_constraint),
- ConstraintType::GreaterOrEqual => {
- let value_in_node = value_in_node
- .as_integer()
- .ok_or(anyhow!("Mismatch type: expected a CBOR integer"))?;
- let value_min = value_in_constraint
- .as_integer()
- .ok_or(anyhow!("Mismatch type: expected a CBOR integer"))?;
- ensure!(value_in_node >= value_min);
- }
- };
- Ok(())
-}
-
-// Take the payload of a dice node & construct the constraints on it.
-fn payload_to_constraints(
- payload: Value,
- constraint_spec: &[ConstraintSpec],
-) -> Result<NodeConstraints> {
- let mut node_constraints: Vec<Constraint> = Vec::with_capacity(constraint_spec.len());
- for constraint_item in constraint_spec {
- let constraint_path = constraint_item.path.to_vec();
- if constraint_path.is_empty() {
- bail!("Expected non-empty key spec");
- }
- let val = lookup_value_in_nested_map(&payload, &constraint_path)
- .context(format!("Value not found for constraint_path {:?}", constraint_path))?;
- let constraint = Constraint(constraint_item.constraint_type as u16, constraint_path, val);
- node_constraints.push(constraint);
- }
- Ok(NodeConstraints(node_constraints.into_boxed_slice()))
-}
-
-// Lookup value corresponding to constraint path in nested map.
-// This function recursively calls itself.
-// The depth of recursion is limited by the size of constraint_path.
-fn lookup_value_in_nested_map(cbor_map: &Value, constraint_path: &[i64]) -> Result<Value> {
- if constraint_path.is_empty() {
- return Ok(cbor_map.clone());
- }
- let explicit_map = get_map_from_value(cbor_map)?;
- let val = lookup_value_in_map(&explicit_map, constraint_path[0])
- .ok_or(anyhow!("Value not found for constraint key: {:?}", constraint_path[0]))?;
- lookup_value_in_nested_map(val, &constraint_path[1..])
-}
-
-fn get_map_from_value(cbor_map: &Value) -> Result<Cow<Vec<(Value, Value)>>> {
- match cbor_map {
- Value::Bytes(b) => value_from_bytes(b)?
- .into_map()
- .map(Cow::Owned)
- .map_err(|e| anyhow!("Expected a CBOR map: {:?}", e)),
- Value::Map(map) => Ok(Cow::Borrowed(map)),
- _ => bail!("Expected a CBOR map {:?}", cbor_map),
- }
-}
-
-fn lookup_value_in_map(map: &[(Value, Value)], key: i64) -> Option<&Value> {
- let key = Value::Integer(key.into());
- for (k, v) in map.iter() {
- if k == &key {
- return Some(v);
- }
- }
- None
-}
-
-/// Extract the payload from the COSE Sign
-fn cbor_value_from_cose_sign(cbor: Value) -> Result<Value> {
- let sign1 =
- CoseSign1::from_cbor_value(cbor).map_err(|e| anyhow!("Error extracting CoseKey: {}", e))?;
- match sign1.payload {
- None => bail!("Missing payload"),
- Some(payload) => Ok(value_from_bytes(&payload)?),
- }
-}
-fn deserialize_dice_chain(dice_chain_bytes: &[u8]) -> Result<Vec<Value>> {
- // TODO(b/298217847): Check if the given dice chain adheres to Explicit-key DiceCertChain
- // format and if not, convert it.
- let dice_chain =
- value_from_bytes(dice_chain_bytes).context("Unable to decode top-level CBOR")?;
- let dice_chain = match dice_chain {
- Value::Array(array) if array.len() >= 2 => array,
- _ => bail!("Expected an array of at least length 2, found: {:?}", dice_chain),
- };
- Ok(dice_chain)
-}
-
-/// Decodes the provided binary CBOR-encoded value and returns a
-/// ciborium::Value struct wrapped in Result.
-fn value_from_bytes(mut bytes: &[u8]) -> Result<Value> {
- let value = ciborium::de::from_reader(&mut bytes)?;
- // Ciborium tries to read one Value, & doesn't care if there is trailing data after it. We do.
- if !bytes.is_empty() {
- bail!("Unexpected trailing data while converting to CBOR value");
- }
- Ok(value)
-}
-
-#[cfg(test)]
-rdroidtest::test_main!();
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use ciborium::cbor;
- use coset::{CoseKey, Header, ProtectedHeader};
- use rdroidtest::test;
-
- const AUTHORITY_HASH: i64 = -4670549;
- const CONFIG_DESC: i64 = -4670548;
- const COMPONENT_NAME: i64 = -70002;
- const KEY_MODE: i64 = -4670551;
-
- // Helper struct to encapsulate artifacts that are useful for unit tests.
- struct TestArtifacts {
- // A dice chain.
- input_dice: Vec<u8>,
- // A list of ConstraintSpec that can be applied on the input_dice to get a dice policy.
- constraint_spec: Vec<ConstraintSpec>,
- // The expected dice policy if above constraint_spec is applied to input_dice.
- expected_dice_policy: DicePolicy,
- // Another dice chain, which is almost same as the input_dice, but (roughly) imitates
- // an 'updated' one, ie, some int entries are higher than corresponding entry
- // in input_chain.
- updated_input_dice: Vec<u8>,
- }
-
- impl TestArtifacts {
- // Get an example instance of TestArtifacts. This uses a hard coded, hypothetical
- // chain of certificates & a list of constraint_spec on this.
- fn get_example() -> Self {
- const EXAMPLE_NUM_1: i64 = 59765;
- const EXAMPLE_NUM_2: i64 = 59766;
- const EXAMPLE_STRING: &str = "testing_dice_policy";
- const UNCONSTRAINED_STRING: &str = "unconstrained_string";
- const ANOTHER_UNCONSTRAINED_STRING: &str = "another_unconstrained_string";
-
- let rot_key = CoseKey::default().to_cbor_value().unwrap();
- let input_dice = Self::get_dice_chain_helper(
- rot_key.clone(),
- EXAMPLE_NUM_1,
- EXAMPLE_STRING,
- UNCONSTRAINED_STRING,
- );
-
- // Now construct constraint_spec on the input dice, note this will use the keys
- // which are also hardcoded within the get_dice_chain_helper.
-
- let constraint_spec = vec![
- ConstraintSpec::new(ConstraintType::ExactMatch, vec![1]).unwrap(),
- // Notice how key "2" is (deliberately) absent in ConstraintSpec
- // so policy should not constrain it.
- ConstraintSpec::new(ConstraintType::GreaterOrEqual, vec![3, 100]).unwrap(),
- ];
- let expected_dice_policy = DicePolicy {
- version: 1,
- node_constraints_list: Box::new([
- NodeConstraints(Box::new([Constraint(
- ConstraintType::ExactMatch as u16,
- vec![],
- rot_key.clone(),
- )])),
- NodeConstraints(Box::new([
- Constraint(
- ConstraintType::ExactMatch as u16,
- vec![1],
- Value::Text(EXAMPLE_STRING.to_string()),
- ),
- Constraint(
- ConstraintType::GreaterOrEqual as u16,
- vec![3, 100],
- Value::from(EXAMPLE_NUM_1),
- ),
- ])),
- ]),
- };
-
- let updated_input_dice = Self::get_dice_chain_helper(
- rot_key.clone(),
- EXAMPLE_NUM_2,
- EXAMPLE_STRING,
- ANOTHER_UNCONSTRAINED_STRING,
- );
- Self { input_dice, constraint_spec, expected_dice_policy, updated_input_dice }
- }
-
- // Helper method method to generate a dice chain with a given rot_key.
- // Other arguments are ad-hoc values in the nested map. Callers use these to
- // construct appropriate constrains in dice policies.
- fn get_dice_chain_helper(
- rot_key: Value,
- version: i64,
- constrained_string: &str,
- unconstrained_string: &str,
- ) -> Vec<u8> {
- let nested_payload = cbor!({
- 100 => version
- })
- .unwrap();
-
- let payload = cbor!({
- 1 => constrained_string,
- 2 => unconstrained_string,
- 3 => Value::Bytes(value_to_bytes(&nested_payload).unwrap()),
- })
- .unwrap();
- let payload = value_to_bytes(&payload).unwrap();
- let dice_node = CoseSign1 {
- protected: ProtectedHeader::default(),
- unprotected: Header::default(),
- payload: Some(payload),
- signature: b"ddef".to_vec(),
- }
- .to_cbor_value()
- .unwrap();
- let input_dice = Value::Array([rot_key.clone(), dice_node].to_vec());
-
- value_to_bytes(&input_dice).unwrap()
- }
- }
-
- test!(policy_structure_check);
- fn policy_structure_check() {
- let example = TestArtifacts::get_example();
- let policy =
- DicePolicy::from_dice_chain(&example.input_dice, &example.constraint_spec).unwrap();
-
- // Assert policy is exactly as expected!
- assert_eq!(policy, example.expected_dice_policy);
- }
-
- test!(policy_matches_original_dice_chain);
- fn policy_matches_original_dice_chain() {
- let example = TestArtifacts::get_example();
- assert!(
- DicePolicy::from_dice_chain(&example.input_dice, &example.constraint_spec)
- .unwrap()
- .matches_dice_chain(&example.input_dice)
- .is_ok(),
- "The dice chain did not match the policy constructed out of it!"
- );
- }
-
- test!(policy_matches_updated_dice_chain);
- fn policy_matches_updated_dice_chain() {
- let example = TestArtifacts::get_example();
- assert!(
- DicePolicy::from_dice_chain(&example.input_dice, &example.constraint_spec)
- .unwrap()
- .matches_dice_chain(&example.updated_input_dice)
- .is_ok(),
- "The updated dice chain did not match the original policy!"
- );
- }
-
- test!(policy_mismatch_downgraded_dice_chain);
- fn policy_mismatch_downgraded_dice_chain() {
- let example = TestArtifacts::get_example();
- assert!(
- DicePolicy::from_dice_chain(&example.updated_input_dice, &example.constraint_spec)
- .unwrap()
- .matches_dice_chain(&example.input_dice)
- .is_err(),
- "The (downgraded) dice chain matched the policy constructed out of the 'updated'\
- dice chain!!"
- );
- }
-
- test!(policy_dice_size_is_same);
- fn policy_dice_size_is_same() {
- // This is the number of certs in compos bcc (including the first ROT)
- // To analyze a bcc use hwtrust tool from /tools/security/remote_provisioning/hwtrust
- // `hwtrust --verbose dice-chain [path]/composbcc`
- let compos_dice_chain_size: usize = 5;
- let input_dice = include_bytes!("../testdata/composbcc");
- let constraint_spec = [
- ConstraintSpec::new(ConstraintType::ExactMatch, vec![AUTHORITY_HASH]).unwrap(),
- ConstraintSpec::new(ConstraintType::ExactMatch, vec![KEY_MODE]).unwrap(),
- ConstraintSpec::new(ConstraintType::GreaterOrEqual, vec![CONFIG_DESC, COMPONENT_NAME])
- .unwrap(),
- ];
- let policy = DicePolicy::from_dice_chain(input_dice, &constraint_spec).unwrap();
- assert_eq!(policy.node_constraints_list.len(), compos_dice_chain_size);
- }
-
- /// Encodes a ciborium::Value into bytes.
- fn value_to_bytes(value: &Value) -> Result<Vec<u8>> {
- let mut bytes: Vec<u8> = Vec::new();
- ciborium::ser::into_writer(&value, &mut bytes)?;
- Ok(bytes)
- }
-}
diff --git a/secretkeeper/dice_policy/testdata/composbcc b/secretkeeper/dice_policy/testdata/composbcc
deleted file mode 100644
index fb3e006..0000000
--- a/secretkeeper/dice_policy/testdata/composbcc
+++ /dev/null
Binary files differ