Tamas Ban | a49698c | 2023-06-06 13:14:45 +0200 | [diff] [blame] | 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_ |