blob: 014d5fd0e58b06f029822f1e5f80b8a414a2b4f3 [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,
22 DICE_CDI_SIZE, DICE_HASH_SIZE, DICE_HIDDEN_SIZE, DICE_ID_SIZE, DICE_INLINE_CONFIG_SIZE,
23 DICE_PRIVATE_KEY_SEED_SIZE,
Alice Wang0b9e1102023-02-02 09:57:06 +000024};
Alice Wang856d6562023-02-03 13:51:08 +000025use std::ptr;
Alice Wang0b9e1102023-02-02 09:57:06 +000026
27/// The size of a DICE hash.
28pub const HASH_SIZE: usize = DICE_HASH_SIZE as usize;
29/// The size of the DICE hidden value.
30pub const HIDDEN_SIZE: usize = DICE_HIDDEN_SIZE as usize;
31/// The size of a DICE inline config.
32const INLINE_CONFIG_SIZE: usize = DICE_INLINE_CONFIG_SIZE as usize;
Alice Wang3213d492023-02-03 15:52:18 +000033/// The size of a CDI.
34pub const CDI_SIZE: usize = DICE_CDI_SIZE as usize;
Alice Wang7cc59562023-02-08 13:17:10 +000035/// The size of a private key seed.
36pub const PRIVATE_KEY_SEED_SIZE: usize = DICE_PRIVATE_KEY_SEED_SIZE as usize;
37/// The size of an ID.
38pub const ID_SIZE: usize = DICE_ID_SIZE as usize;
Alice Wang0b9e1102023-02-02 09:57:06 +000039
40/// Array type of hashes used by DICE.
41pub type Hash = [u8; HASH_SIZE];
42/// Array type of additional input.
43pub type Hidden = [u8; HIDDEN_SIZE];
44/// Array type of inline configuration values.
45pub type InlineConfig = [u8; INLINE_CONFIG_SIZE];
Alice Wang3213d492023-02-03 15:52:18 +000046/// Array type of CDIs.
47pub type Cdi = [u8; CDI_SIZE];
Alice Wang7cc59562023-02-08 13:17:10 +000048/// Array type of private key seeds.
49pub type PrivateKeySeed = [u8; PRIVATE_KEY_SEED_SIZE];
50/// Array type of DICE ID.
51pub type DiceId = [u8; ID_SIZE];
Alice Wang0b9e1102023-02-02 09:57:06 +000052
53/// Configuration descriptor for DICE input values.
54#[derive(Debug, Clone, PartialEq, Eq)]
55pub enum Config<'a> {
56 /// Reference to an inline descriptor.
57 Inline(&'a InlineConfig),
58 /// Reference to a free form descriptor that will be hashed by the implementation.
59 Descriptor(&'a [u8]),
60}
61
62impl Config<'_> {
63 fn dice_config_type(&self) -> DiceConfigType {
64 match self {
65 Self::Inline(_) => DiceConfigType::kDiceConfigTypeInline,
66 Self::Descriptor(_) => DiceConfigType::kDiceConfigTypeDescriptor,
67 }
68 }
69
70 fn inline_config(&self) -> InlineConfig {
71 match self {
72 Self::Inline(inline) => **inline,
73 Self::Descriptor(_) => [0u8; INLINE_CONFIG_SIZE],
74 }
75 }
76
77 fn descriptor_ptr(&self) -> *const u8 {
78 match self {
79 Self::Descriptor(descriptor) => descriptor.as_ptr(),
80 _ => ptr::null(),
81 }
82 }
83
84 fn descriptor_size(&self) -> usize {
85 match self {
86 Self::Descriptor(descriptor) => descriptor.len(),
87 _ => 0,
88 }
89 }
90}
91
92/// Wrap of `DiceInputValues`.
93#[derive(Clone, Debug)]
94pub struct InputValues(DiceInputValues);
95
96impl InputValues {
97 /// Creates a new `InputValues`.
98 pub fn new(
Alice Wangb68814b2023-02-02 13:15:32 +000099 code_hash: Hash,
Alice Wang0b9e1102023-02-02 09:57:06 +0000100 config: Config,
Alice Wangb68814b2023-02-02 13:15:32 +0000101 authority_hash: Hash,
Alice Wang0b9e1102023-02-02 09:57:06 +0000102 mode: DiceMode,
Alice Wangb68814b2023-02-02 13:15:32 +0000103 hidden: Hidden,
Alice Wang0b9e1102023-02-02 09:57:06 +0000104 ) -> Self {
105 Self(DiceInputValues {
Alice Wangb68814b2023-02-02 13:15:32 +0000106 code_hash,
107 code_descriptor: ptr::null(),
108 code_descriptor_size: 0,
Alice Wang0b9e1102023-02-02 09:57:06 +0000109 config_type: config.dice_config_type(),
110 config_value: config.inline_config(),
111 config_descriptor: config.descriptor_ptr(),
112 config_descriptor_size: config.descriptor_size(),
Alice Wangb68814b2023-02-02 13:15:32 +0000113 authority_hash,
114 authority_descriptor: ptr::null(),
115 authority_descriptor_size: 0,
Alice Wang0b9e1102023-02-02 09:57:06 +0000116 mode,
Alice Wangb68814b2023-02-02 13:15:32 +0000117 hidden,
Alice Wang0b9e1102023-02-02 09:57:06 +0000118 })
119 }
120
121 /// Returns a raw pointer to the wrapped `DiceInputValues`.
122 pub fn as_ptr(&self) -> *const DiceInputValues {
123 &self.0 as *const DiceInputValues
124 }
125}
Alice Wang7cc59562023-02-08 13:17:10 +0000126
127/// Derives a CDI private key seed from a `cdi_attest` value.
128pub fn derive_cdi_private_key_seed(cdi_attest: &Cdi) -> Result<PrivateKeySeed> {
129 let mut seed = [0u8; PRIVATE_KEY_SEED_SIZE];
130 // SAFETY: The function writes to the buffer within the given bounds, and only reads the
131 // input values. The first argument context is not used in this function.
132 check_result(unsafe {
133 DiceDeriveCdiPrivateKeySeed(
134 ptr::null_mut(), // context
135 cdi_attest.as_ptr(),
136 seed.as_mut_ptr(),
137 )
138 })?;
139 Ok(seed)
140}
141
142/// Derives an ID from the given `cdi_public_key` value.
143pub fn derive_cdi_certificate_id(cdi_public_key: &[u8]) -> Result<DiceId> {
144 let mut id = [0u8; ID_SIZE];
145 // SAFETY: The function writes to the buffer within the given bounds, and only reads the
146 // input values. The first argument context is not used in this function.
147 check_result(unsafe {
148 DiceDeriveCdiCertificateId(
149 ptr::null_mut(), // context
150 cdi_public_key.as_ptr(),
151 cdi_public_key.len(),
152 id.as_mut_ptr(),
153 )
154 })?;
155 Ok(id)
156}