blob: ed7d8431c5e9593ba22fae63da1c2cd56c4e26f2 [file] [log] [blame]
Alice Wang0b9e1102023-02-02 09:57:06 +00001// Copyright 2023, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Structs and functions about the types used in DICE.
16//! This module mirrors the content in open-dice/include/dice/dice.h
17
Alice Wang7cc59562023-02-08 13:17:10 +000018use crate::error::{check_result, Result};
Alice Wang9c40eca2023-02-03 13:10:24 +000019pub use open_dice_cbor_bindgen::DiceMode;
Alice Wang0b9e1102023-02-02 09:57:06 +000020use open_dice_cbor_bindgen::{
Alice Wang7cc59562023-02-08 13:17:10 +000021 DiceConfigType, DiceDeriveCdiCertificateId, DiceDeriveCdiPrivateKeySeed, DiceInputValues,
Alice Wang44f48b22023-02-09 09:51:22 +000022 DiceMainFlow, DICE_CDI_SIZE, DICE_HASH_SIZE, DICE_HIDDEN_SIZE, DICE_ID_SIZE,
23 DICE_INLINE_CONFIG_SIZE, DICE_PRIVATE_KEY_SEED_SIZE,
Alice Wang0b9e1102023-02-02 09:57:06 +000024};
Alice Wang856d6562023-02-03 13:51:08 +000025use std::ptr;
Alice Wangf4bd1c62023-02-08 08:38:44 +000026use zeroize::{Zeroize, ZeroizeOnDrop};
Alice Wang0b9e1102023-02-02 09:57:06 +000027
28/// The size of a DICE hash.
29pub const HASH_SIZE: usize = DICE_HASH_SIZE as usize;
30/// The size of the DICE hidden value.
31pub const HIDDEN_SIZE: usize = DICE_HIDDEN_SIZE as usize;
32/// The size of a DICE inline config.
33const INLINE_CONFIG_SIZE: usize = DICE_INLINE_CONFIG_SIZE as usize;
Alice Wang3213d492023-02-03 15:52:18 +000034/// The size of a CDI.
35pub const CDI_SIZE: usize = DICE_CDI_SIZE as usize;
Alice Wang7cc59562023-02-08 13:17:10 +000036/// The size of a private key seed.
37pub const PRIVATE_KEY_SEED_SIZE: usize = DICE_PRIVATE_KEY_SEED_SIZE as usize;
38/// The size of an ID.
39pub const ID_SIZE: usize = DICE_ID_SIZE as usize;
Alice Wang0b9e1102023-02-02 09:57:06 +000040
41/// Array type of hashes used by DICE.
42pub type Hash = [u8; HASH_SIZE];
43/// Array type of additional input.
44pub type Hidden = [u8; HIDDEN_SIZE];
45/// Array type of inline configuration values.
46pub type InlineConfig = [u8; INLINE_CONFIG_SIZE];
Alice Wang3213d492023-02-03 15:52:18 +000047/// Array type of CDIs.
48pub type Cdi = [u8; CDI_SIZE];
Alice Wang7cc59562023-02-08 13:17:10 +000049/// Array type of private key seeds.
50pub type PrivateKeySeed = [u8; PRIVATE_KEY_SEED_SIZE];
51/// Array type of DICE ID.
52pub type DiceId = [u8; ID_SIZE];
Alice Wang0b9e1102023-02-02 09:57:06 +000053
Alice Wangf4bd1c62023-02-08 08:38:44 +000054/// CDI Values.
55#[derive(Zeroize, ZeroizeOnDrop, Default)]
56pub struct CdiValues {
57 /// Attestation CDI.
58 pub cdi_attest: Cdi,
59 /// Sealing CDI.
60 pub cdi_seal: Cdi,
61}
62
Alice Wang0b9e1102023-02-02 09:57:06 +000063/// Configuration descriptor for DICE input values.
64#[derive(Debug, Clone, PartialEq, Eq)]
65pub enum Config<'a> {
66 /// Reference to an inline descriptor.
67 Inline(&'a InlineConfig),
68 /// Reference to a free form descriptor that will be hashed by the implementation.
69 Descriptor(&'a [u8]),
70}
71
72impl Config<'_> {
73 fn dice_config_type(&self) -> DiceConfigType {
74 match self {
75 Self::Inline(_) => DiceConfigType::kDiceConfigTypeInline,
76 Self::Descriptor(_) => DiceConfigType::kDiceConfigTypeDescriptor,
77 }
78 }
79
80 fn inline_config(&self) -> InlineConfig {
81 match self {
82 Self::Inline(inline) => **inline,
83 Self::Descriptor(_) => [0u8; INLINE_CONFIG_SIZE],
84 }
85 }
86
87 fn descriptor_ptr(&self) -> *const u8 {
88 match self {
89 Self::Descriptor(descriptor) => descriptor.as_ptr(),
90 _ => ptr::null(),
91 }
92 }
93
94 fn descriptor_size(&self) -> usize {
95 match self {
96 Self::Descriptor(descriptor) => descriptor.len(),
97 _ => 0,
98 }
99 }
100}
101
102/// Wrap of `DiceInputValues`.
103#[derive(Clone, Debug)]
104pub struct InputValues(DiceInputValues);
105
106impl InputValues {
107 /// Creates a new `InputValues`.
108 pub fn new(
Alice Wangb68814b2023-02-02 13:15:32 +0000109 code_hash: Hash,
Alice Wang0b9e1102023-02-02 09:57:06 +0000110 config: Config,
Alice Wangb68814b2023-02-02 13:15:32 +0000111 authority_hash: Hash,
Alice Wang0b9e1102023-02-02 09:57:06 +0000112 mode: DiceMode,
Alice Wangb68814b2023-02-02 13:15:32 +0000113 hidden: Hidden,
Alice Wang0b9e1102023-02-02 09:57:06 +0000114 ) -> Self {
115 Self(DiceInputValues {
Alice Wangb68814b2023-02-02 13:15:32 +0000116 code_hash,
117 code_descriptor: ptr::null(),
118 code_descriptor_size: 0,
Alice Wang0b9e1102023-02-02 09:57:06 +0000119 config_type: config.dice_config_type(),
120 config_value: config.inline_config(),
121 config_descriptor: config.descriptor_ptr(),
122 config_descriptor_size: config.descriptor_size(),
Alice Wangb68814b2023-02-02 13:15:32 +0000123 authority_hash,
124 authority_descriptor: ptr::null(),
125 authority_descriptor_size: 0,
Alice Wang0b9e1102023-02-02 09:57:06 +0000126 mode,
Alice Wangb68814b2023-02-02 13:15:32 +0000127 hidden,
Alice Wang0b9e1102023-02-02 09:57:06 +0000128 })
129 }
130
131 /// Returns a raw pointer to the wrapped `DiceInputValues`.
132 pub fn as_ptr(&self) -> *const DiceInputValues {
133 &self.0 as *const DiceInputValues
134 }
135}
Alice Wang7cc59562023-02-08 13:17:10 +0000136
137/// Derives a CDI private key seed from a `cdi_attest` value.
138pub fn derive_cdi_private_key_seed(cdi_attest: &Cdi) -> Result<PrivateKeySeed> {
139 let mut seed = [0u8; PRIVATE_KEY_SEED_SIZE];
140 // SAFETY: The function writes to the buffer within the given bounds, and only reads the
141 // input values. The first argument context is not used in this function.
142 check_result(unsafe {
143 DiceDeriveCdiPrivateKeySeed(
144 ptr::null_mut(), // context
145 cdi_attest.as_ptr(),
146 seed.as_mut_ptr(),
147 )
148 })?;
149 Ok(seed)
150}
151
152/// Derives an ID from the given `cdi_public_key` value.
153pub fn derive_cdi_certificate_id(cdi_public_key: &[u8]) -> Result<DiceId> {
154 let mut id = [0u8; ID_SIZE];
155 // SAFETY: The function writes to the buffer within the given bounds, and only reads the
156 // input values. The first argument context is not used in this function.
157 check_result(unsafe {
158 DiceDeriveCdiCertificateId(
159 ptr::null_mut(), // context
160 cdi_public_key.as_ptr(),
161 cdi_public_key.len(),
162 id.as_mut_ptr(),
163 )
164 })?;
165 Ok(id)
166}
Alice Wang44f48b22023-02-09 09:51:22 +0000167
168/// Executes the main DICE flow.
169///
170/// Given a full set of input values and the current CDI values, computes the
171/// next CDI values and a matching certificate.
172/// Returns the actual size of the next CDI certificate.
173pub fn dice_main_flow(
174 current_cdi_attest: &Cdi,
175 current_cdi_seal: &Cdi,
176 input_values: &InputValues,
177 next_cdi_certificate: &mut [u8],
178 next_cdi_values: &mut CdiValues,
179) -> Result<usize> {
180 let mut next_cdi_certificate_actual_size = 0;
181 // SAFETY: The function only reads the current CDI values and inputs and writes
182 // to `next_cdi_certificate` and next CDI values within its bounds.
183 // The first argument can be null and is not used in the current implementation.
184 check_result(unsafe {
185 DiceMainFlow(
186 ptr::null_mut(), // context
187 current_cdi_attest.as_ptr(),
188 current_cdi_seal.as_ptr(),
189 input_values.as_ptr(),
190 next_cdi_certificate.len(),
191 next_cdi_certificate.as_mut_ptr(),
192 &mut next_cdi_certificate_actual_size,
193 next_cdi_values.cdi_attest.as_mut_ptr(),
194 next_cdi_values.cdi_seal.as_mut_ptr(),
195 )
196 })?;
197 Ok(next_cdi_certificate_actual_size)
198}