blob: 350237d87f97f027a29a27874af6fc01e36f21bb [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,
Alice Wang8722d9e2023-02-13 14:56:56 +000023 DICE_INLINE_CONFIG_SIZE, DICE_PRIVATE_KEY_SEED_SIZE, DICE_PRIVATE_KEY_SIZE,
24 DICE_PUBLIC_KEY_SIZE, DICE_SIGNATURE_SIZE,
Alice Wang0b9e1102023-02-02 09:57:06 +000025};
Alice Wang856d6562023-02-03 13:51:08 +000026use std::ptr;
Alice Wangf4bd1c62023-02-08 08:38:44 +000027use zeroize::{Zeroize, ZeroizeOnDrop};
Alice Wang0b9e1102023-02-02 09:57:06 +000028
29/// The size of a DICE hash.
30pub const HASH_SIZE: usize = DICE_HASH_SIZE as usize;
31/// The size of the DICE hidden value.
32pub const HIDDEN_SIZE: usize = DICE_HIDDEN_SIZE as usize;
33/// The size of a DICE inline config.
34const INLINE_CONFIG_SIZE: usize = DICE_INLINE_CONFIG_SIZE as usize;
Alice Wang3213d492023-02-03 15:52:18 +000035/// The size of a CDI.
36pub const CDI_SIZE: usize = DICE_CDI_SIZE as usize;
Alice Wang7cc59562023-02-08 13:17:10 +000037/// The size of a private key seed.
38pub const PRIVATE_KEY_SEED_SIZE: usize = DICE_PRIVATE_KEY_SEED_SIZE as usize;
Alice Wang8722d9e2023-02-13 14:56:56 +000039/// The size of a private key.
40pub const PRIVATE_KEY_SIZE: usize = DICE_PRIVATE_KEY_SIZE as usize;
41/// The size of a public key.
42pub const PUBLIC_KEY_SIZE: usize = DICE_PUBLIC_KEY_SIZE as usize;
43/// The size of a signature.
44pub const SIGNATURE_SIZE: usize = DICE_SIGNATURE_SIZE as usize;
Alice Wang7cc59562023-02-08 13:17:10 +000045/// The size of an ID.
46pub const ID_SIZE: usize = DICE_ID_SIZE as usize;
Alice Wang0b9e1102023-02-02 09:57:06 +000047
48/// Array type of hashes used by DICE.
49pub type Hash = [u8; HASH_SIZE];
50/// Array type of additional input.
51pub type Hidden = [u8; HIDDEN_SIZE];
52/// Array type of inline configuration values.
53pub type InlineConfig = [u8; INLINE_CONFIG_SIZE];
Alice Wang3213d492023-02-03 15:52:18 +000054/// Array type of CDIs.
55pub type Cdi = [u8; CDI_SIZE];
Alice Wang7cc59562023-02-08 13:17:10 +000056/// Array type of private key seeds.
57pub type PrivateKeySeed = [u8; PRIVATE_KEY_SEED_SIZE];
Alice Wang8722d9e2023-02-13 14:56:56 +000058/// Array type of the public key.
59pub type PublicKey = [u8; PUBLIC_KEY_SIZE];
60/// Array type of the signature.
61pub type Signature = [u8; SIGNATURE_SIZE];
Alice Wang7cc59562023-02-08 13:17:10 +000062/// Array type of DICE ID.
63pub type DiceId = [u8; ID_SIZE];
Alice Wang0b9e1102023-02-02 09:57:06 +000064
Alice Wangf4bd1c62023-02-08 08:38:44 +000065/// CDI Values.
Alice Wangacee4fb2023-02-15 09:42:07 +000066#[derive(Debug, Zeroize, ZeroizeOnDrop, Default)]
Alice Wangf4bd1c62023-02-08 08:38:44 +000067pub struct CdiValues {
68 /// Attestation CDI.
69 pub cdi_attest: Cdi,
70 /// Sealing CDI.
71 pub cdi_seal: Cdi,
72}
73
Alice Wang0b9e1102023-02-02 09:57:06 +000074/// Configuration descriptor for DICE input values.
75#[derive(Debug, Clone, PartialEq, Eq)]
76pub enum Config<'a> {
77 /// Reference to an inline descriptor.
78 Inline(&'a InlineConfig),
79 /// Reference to a free form descriptor that will be hashed by the implementation.
80 Descriptor(&'a [u8]),
81}
82
83impl Config<'_> {
84 fn dice_config_type(&self) -> DiceConfigType {
85 match self {
86 Self::Inline(_) => DiceConfigType::kDiceConfigTypeInline,
87 Self::Descriptor(_) => DiceConfigType::kDiceConfigTypeDescriptor,
88 }
89 }
90
91 fn inline_config(&self) -> InlineConfig {
92 match self {
93 Self::Inline(inline) => **inline,
94 Self::Descriptor(_) => [0u8; INLINE_CONFIG_SIZE],
95 }
96 }
97
98 fn descriptor_ptr(&self) -> *const u8 {
99 match self {
100 Self::Descriptor(descriptor) => descriptor.as_ptr(),
101 _ => ptr::null(),
102 }
103 }
104
105 fn descriptor_size(&self) -> usize {
106 match self {
107 Self::Descriptor(descriptor) => descriptor.len(),
108 _ => 0,
109 }
110 }
111}
112
113/// Wrap of `DiceInputValues`.
114#[derive(Clone, Debug)]
115pub struct InputValues(DiceInputValues);
116
117impl InputValues {
118 /// Creates a new `InputValues`.
119 pub fn new(
Alice Wangb68814b2023-02-02 13:15:32 +0000120 code_hash: Hash,
Alice Wang0b9e1102023-02-02 09:57:06 +0000121 config: Config,
Alice Wangb68814b2023-02-02 13:15:32 +0000122 authority_hash: Hash,
Alice Wang0b9e1102023-02-02 09:57:06 +0000123 mode: DiceMode,
Alice Wangb68814b2023-02-02 13:15:32 +0000124 hidden: Hidden,
Alice Wang0b9e1102023-02-02 09:57:06 +0000125 ) -> Self {
126 Self(DiceInputValues {
Alice Wangb68814b2023-02-02 13:15:32 +0000127 code_hash,
128 code_descriptor: ptr::null(),
129 code_descriptor_size: 0,
Alice Wang0b9e1102023-02-02 09:57:06 +0000130 config_type: config.dice_config_type(),
131 config_value: config.inline_config(),
132 config_descriptor: config.descriptor_ptr(),
133 config_descriptor_size: config.descriptor_size(),
Alice Wangb68814b2023-02-02 13:15:32 +0000134 authority_hash,
135 authority_descriptor: ptr::null(),
136 authority_descriptor_size: 0,
Alice Wang0b9e1102023-02-02 09:57:06 +0000137 mode,
Alice Wangb68814b2023-02-02 13:15:32 +0000138 hidden,
Alice Wang0b9e1102023-02-02 09:57:06 +0000139 })
140 }
141
142 /// Returns a raw pointer to the wrapped `DiceInputValues`.
143 pub fn as_ptr(&self) -> *const DiceInputValues {
144 &self.0 as *const DiceInputValues
145 }
146}
Alice Wang7cc59562023-02-08 13:17:10 +0000147
148/// Derives a CDI private key seed from a `cdi_attest` value.
149pub fn derive_cdi_private_key_seed(cdi_attest: &Cdi) -> Result<PrivateKeySeed> {
150 let mut seed = [0u8; PRIVATE_KEY_SEED_SIZE];
151 // SAFETY: The function writes to the buffer within the given bounds, and only reads the
152 // input values. The first argument context is not used in this function.
153 check_result(unsafe {
154 DiceDeriveCdiPrivateKeySeed(
155 ptr::null_mut(), // context
156 cdi_attest.as_ptr(),
157 seed.as_mut_ptr(),
158 )
159 })?;
160 Ok(seed)
161}
162
163/// Derives an ID from the given `cdi_public_key` value.
164pub fn derive_cdi_certificate_id(cdi_public_key: &[u8]) -> Result<DiceId> {
165 let mut id = [0u8; ID_SIZE];
166 // SAFETY: The function writes to the buffer within the given bounds, and only reads the
167 // input values. The first argument context is not used in this function.
168 check_result(unsafe {
169 DiceDeriveCdiCertificateId(
170 ptr::null_mut(), // context
171 cdi_public_key.as_ptr(),
172 cdi_public_key.len(),
173 id.as_mut_ptr(),
174 )
175 })?;
176 Ok(id)
177}
Alice Wang44f48b22023-02-09 09:51:22 +0000178
179/// Executes the main DICE flow.
180///
181/// Given a full set of input values and the current CDI values, computes the
182/// next CDI values and a matching certificate.
183/// Returns the actual size of the next CDI certificate.
184pub fn dice_main_flow(
185 current_cdi_attest: &Cdi,
186 current_cdi_seal: &Cdi,
187 input_values: &InputValues,
188 next_cdi_certificate: &mut [u8],
189 next_cdi_values: &mut CdiValues,
190) -> Result<usize> {
191 let mut next_cdi_certificate_actual_size = 0;
192 // SAFETY: The function only reads the current CDI values and inputs and writes
193 // to `next_cdi_certificate` and next CDI values within its bounds.
194 // The first argument can be null and is not used in the current implementation.
195 check_result(unsafe {
196 DiceMainFlow(
197 ptr::null_mut(), // context
198 current_cdi_attest.as_ptr(),
199 current_cdi_seal.as_ptr(),
200 input_values.as_ptr(),
201 next_cdi_certificate.len(),
202 next_cdi_certificate.as_mut_ptr(),
203 &mut next_cdi_certificate_actual_size,
204 next_cdi_values.cdi_attest.as_mut_ptr(),
205 next_cdi_values.cdi_seal.as_mut_ptr(),
206 )
207 })?;
208 Ok(next_cdi_certificate_actual_size)
209}