• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://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, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #ifndef DICE_DICE_H_
16 #define DICE_DICE_H_
17 
18 #include <stddef.h>
19 #include <stdint.h>
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 #define DICE_CDI_SIZE 32
26 #define DICE_HASH_SIZE 64
27 #define DICE_HIDDEN_SIZE 64
28 #define DICE_INLINE_CONFIG_SIZE 64
29 #define DICE_PRIVATE_KEY_SEED_SIZE 32
30 #define DICE_ID_SIZE 20
31 
32 typedef enum {
33   kDiceResultOk,
34   kDiceResultInvalidInput,
35   kDiceResultBufferTooSmall,
36   kDiceResultPlatformError,
37 } DiceResult;
38 
39 typedef enum {
40   kDiceModeNotInitialized,
41   kDiceModeNormal,
42   kDiceModeDebug,
43   kDiceModeMaintenance,
44 } DiceMode;
45 
46 typedef enum {
47   kDiceConfigTypeInline,
48   kDiceConfigTypeDescriptor,
49 } DiceConfigType;
50 
51 // Contains a full set of input values describing the target program or system.
52 // See the Open Profile for DICE specification for a detailed explanation of
53 // these inputs.
54 //
55 // Fields:
56 //    code_hash: A hash or similar representation of the target code.
57 //    code_descriptor: An optional descriptor to be included in the certificate.
58 //        This descriptor is opaque to the DICE flow and is included verbatim
59 //        in the certificate with no validation. May be null.
60 //    code_descriptor_size: The size in bytes of |code_descriptor|.
61 //    config_type: Indicates how to interpret the remaining config-related
62 //        fields. If the type is 'inline', then the 64 byte configuration input
63 //        value must be provided in |config_value| and |config_descriptor| is
64 //        ignored. If the type is 'descriptor', then |config_descriptor| is
65 //        hashed to get the configuration input value and |config_value| is
66 //        ignored.
67 //    config_value: A 64-byte configuration input value when |config_type| is
68 //        kDiceConfigTypeInline. Otherwise, this field is ignored.
69 //    config_descriptor: A descriptor to be hashed for the configuration input
70 //        value when |config_type| is kDiceConfigTypeDescriptor. Otherwise,
71 //        this field is ignored and may be null.
72 //    config_descriptor_size: The size in bytes of |config_descriptor|.
73 //    authority_hash: A hash or similar representation of the authority used to
74 //        verify the target code. If the code is not verified or the authority
75 //        is implicit, for example hard coded as part of the code currently
76 //        executing, then this value should be set to all zero bytes.
77 //    authority_descriptor: An optional descriptor to be included in the
78 //        certificate. This descriptor is opaque to the DICE flow and is
79 //        included verbatim in the certificate with no validation. May be null.
80 //    authority_descriptor_size: The size in bytes of |authority_descriptor|.
81 //    mode: The current operating mode.
82 //    hidden: Additional input which will not appear in certificates. If this is
83 //        not used it should be set to all zero bytes.
84 typedef struct DiceInputValues_ {
85   uint8_t code_hash[DICE_HASH_SIZE];
86   const uint8_t* code_descriptor;
87   size_t code_descriptor_size;
88   DiceConfigType config_type;
89   uint8_t config_value[DICE_INLINE_CONFIG_SIZE];
90   const uint8_t* config_descriptor;
91   size_t config_descriptor_size;
92   uint8_t authority_hash[DICE_HASH_SIZE];
93   const uint8_t* authority_descriptor;
94   size_t authority_descriptor_size;
95   DiceMode mode;
96   uint8_t hidden[DICE_HIDDEN_SIZE];
97 } DiceInputValues;
98 
99 // Derives a |cdi_private_key_seed| from a |cdi_attest| value. On success
100 // populates |cdi_private_key_seed| and returns kDiceResultOk.
101 DiceResult DiceDeriveCdiPrivateKeySeed(
102     void* context, const uint8_t cdi_attest[DICE_CDI_SIZE],
103     uint8_t cdi_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE]);
104 
105 // Derives an |id| from a |cdi_public_key| value. Because public keys can vary
106 // in length depending on the algorithm, the |cdi_public_key_size| in bytes must
107 // be provided. When interpreted as an integer, |id| is big-endian. On success
108 // populates |id| and returns kDiceResultOk.
109 DiceResult DiceDeriveCdiCertificateId(void* context,
110                                       const uint8_t* cdi_public_key,
111                                       size_t cdi_public_key_size,
112                                       uint8_t id[DICE_ID_SIZE]);
113 
114 // Executes the main DICE flow.
115 //
116 // Given a full set of input values and the current CDI values, computes the
117 // next CDI values and a matching certificate. See the Open Profile for DICE
118 // specification for a detailed explanation of this flow.
119 // In certain cases, the caller may not need to generate the CDI certificate.
120 // The caller should signal this by setting the certificate parameters to
121 // null/zero values appropriately.
122 //
123 // Parameters:
124 //    context: Context provided by the caller that is opaque to this library
125 //        but is passed through to the integration-provided operations in
126 //        dice/ops.h. The value is, therefore, integration-specific and may be
127 //        null.
128 //    current_cdi_attest, current_cdi_seal: The current CDI values as produced
129 //        by a previous DICE flow. If this is the first DICE flow in a system,
130 //        the Unique Device Secret (UDS) should be used for both of these
131 //        arguments.
132 //    input_values: A set of input values describing the target program or
133 //        system.
134 //    next_cdi_certificate_buffer_size: The size in bytes of the buffer pointed
135 //        to by the |next_cdi_certificate| argument. This should be set to zero
136 //        if next CDI certificate should not be computed.
137 //    next_cdi_certificate: On success, will be populated with the generated
138 //        certificate, up to |next_cdi_certificate_buffer_size| in size. If the
139 //        certificate cannot fit in the buffer, |next_cdi_certificate_size| is
140 //        populated with the required size and kDiceResultBufferTooSmall is
141 //        returned. This should be set to NULL if next CDI certificate should
142 //        not be computed.
143 //    next_cdi_certificate_actual_size: On success, will be populated with the
144 //        size, in bytes, of the certificate data written to
145 //        |next_cdi_certificate|. If kDiceResultBufferTooSmall is returned, will
146 //        be populated with the required buffer size. This should be set to NULL
147 //        if next CDI certificate should not be computed.
148 //    next_cdi_attest: On success, will be populated with the next CDI value for
149 //        attestation.
150 //    next_cdi_seal: On success, will be populated with the next CDI value for
151 //        sealing.
152 DiceResult DiceMainFlow(void* context,
153                         const uint8_t current_cdi_attest[DICE_CDI_SIZE],
154                         const uint8_t current_cdi_seal[DICE_CDI_SIZE],
155                         const DiceInputValues* input_values,
156                         size_t next_cdi_certificate_buffer_size,
157                         uint8_t* next_cdi_certificate,
158                         size_t* next_cdi_certificate_actual_size,
159                         uint8_t next_cdi_attest[DICE_CDI_SIZE],
160                         uint8_t next_cdi_seal[DICE_CDI_SIZE]);
161 
162 #ifdef __cplusplus
163 }  // extern "C"
164 #endif
165 
166 #endif  // DICE_DICE_H_
167