| // Copyright 2020 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| // use this file except in compliance with the License. You may obtain a copy of |
| // the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| // License for the specific language governing permissions and limitations under |
| // the License. |
| |
| #ifndef DICE_DICE_H_ |
| #define DICE_DICE_H_ |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| #define DICE_CDI_SIZE 32 |
| #define DICE_HASH_SIZE 64 |
| #define DICE_HIDDEN_SIZE 64 |
| #define DICE_INLINE_CONFIG_SIZE 64 |
| #define DICE_PRIVATE_KEY_SEED_SIZE 32 |
| #define DICE_ID_SIZE 20 |
| |
| typedef enum { |
| kDiceResultOk, |
| kDiceResultInvalidInput, |
| kDiceResultBufferTooSmall, |
| kDiceResultPlatformError, |
| } DiceResult; |
| |
| typedef enum { |
| kDiceModeNotInitialized, |
| kDiceModeNormal, |
| kDiceModeDebug, |
| kDiceModeMaintenance, |
| } DiceMode; |
| |
| typedef enum { |
| kDiceConfigTypeInline, |
| kDiceConfigTypeDescriptor, |
| } DiceConfigType; |
| |
| // Contains a full set of input values describing the target program or system. |
| // See the Open Profile for DICE specification for a detailed explanation of |
| // these inputs. |
| // |
| // Fields: |
| // code_hash: A hash or similar representation of the target code. |
| // code_descriptor: An optional descriptor to be included in the certificate. |
| // This descriptor is opaque to the DICE flow and is included verbatim |
| // in the certificate with no validation. May be null. |
| // code_descriptor_size: The size in bytes of |code_descriptor|. |
| // config_type: Indicates how to interpret the remaining config-related |
| // fields. If the type is 'inline', then the 64 byte configuration input |
| // value must be provided in |config_value| and |config_descriptor| is |
| // ignored. If the type is 'descriptor', then |config_descriptor| is |
| // hashed to get the configuration input value and |config_value| is |
| // ignored. |
| // config_value: A 64-byte configuration input value when |config_type| is |
| // kDiceConfigTypeInline. Otherwise, this field is ignored. |
| // config_descriptor: A descriptor to be hashed for the configuration input |
| // value when |config_type| is kDiceConfigTypeDescriptor. Otherwise, |
| // this field is ignored and may be null. |
| // config_descriptor_size: The size in bytes of |config_descriptor|. |
| // authority_hash: A hash or similar representation of the authority used to |
| // verify the target code. If the code is not verified or the authority |
| // is implicit, for example hard coded as part of the code currently |
| // executing, then this value should be set to all zero bytes. |
| // authority_descriptor: An optional descriptor to be included in the |
| // certificate. This descriptor is opaque to the DICE flow and is |
| // included verbatim in the certificate with no validation. May be null. |
| // authority_descriptor_size: The size in bytes of |authority_descriptor|. |
| // mode: The current operating mode. |
| // hidden: Additional input which will not appear in certificates. If this is |
| // not used it should be set to all zero bytes. |
| typedef struct DiceInputValues_ { |
| uint8_t code_hash[DICE_HASH_SIZE]; |
| const uint8_t* code_descriptor; |
| size_t code_descriptor_size; |
| DiceConfigType config_type; |
| uint8_t config_value[DICE_INLINE_CONFIG_SIZE]; |
| const uint8_t* config_descriptor; |
| size_t config_descriptor_size; |
| uint8_t authority_hash[DICE_HASH_SIZE]; |
| const uint8_t* authority_descriptor; |
| size_t authority_descriptor_size; |
| DiceMode mode; |
| uint8_t hidden[DICE_HIDDEN_SIZE]; |
| } DiceInputValues; |
| |
| // Derives a |cdi_private_key_seed| from a |cdi_attest| value. On success |
| // populates |cdi_private_key_seed| and returns kDiceResultOk. |
| DiceResult DiceDeriveCdiPrivateKeySeed( |
| void* context, const uint8_t cdi_attest[DICE_CDI_SIZE], |
| uint8_t cdi_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE]); |
| |
| // Derives an |id| from a |cdi_public_key| value. Because public keys can vary |
| // in length depending on the algorithm, the |cdi_public_key_size| in bytes must |
| // be provided. When interpreted as an integer, |id| is big-endian. On success |
| // populates |id| and returns kDiceResultOk. |
| DiceResult DiceDeriveCdiCertificateId(void* context, |
| const uint8_t* cdi_public_key, |
| size_t cdi_public_key_size, |
| uint8_t id[DICE_ID_SIZE]); |
| |
| // Executes the main DICE flow. |
| // |
| // Given a full set of input values and the current CDI values, computes the |
| // next CDI values and a matching certificate. See the Open Profile for DICE |
| // specification for a detailed explanation of this flow. |
| // In certain cases, the caller may not need to generate the CDI certificate. |
| // The caller should signal this by setting the certificate parameters to |
| // null/zero values appropriately. |
| // |
| // Parameters: |
| // context: Context provided by the caller that is opaque to this library |
| // but is passed through to the integration-provided operations in |
| // dice/ops.h. The value is, therefore, integration-specific and may be |
| // null. |
| // current_cdi_attest, current_cdi_seal: The current CDI values as produced |
| // by a previous DICE flow. If this is the first DICE flow in a system, |
| // the Unique Device Secret (UDS) should be used for both of these |
| // arguments. |
| // input_values: A set of input values describing the target program or |
| // system. |
| // next_cdi_certificate_buffer_size: The size in bytes of the buffer pointed |
| // to by the |next_cdi_certificate| argument. This should be set to zero |
| // if next CDI certificate should not be computed. |
| // next_cdi_certificate: On success, will be populated with the generated |
| // certificate, up to |next_cdi_certificate_buffer_size| in size. If the |
| // certificate cannot fit in the buffer, |next_cdi_certificate_size| is |
| // populated with the required size and kDiceResultBufferTooSmall is |
| // returned. This should be set to NULL if next CDI certificate should |
| // not be computed. |
| // next_cdi_certificate_actual_size: On success, will be populated with the |
| // size, in bytes, of the certificate data written to |
| // |next_cdi_certificate|. If kDiceResultBufferTooSmall is returned, will |
| // be populated with the required buffer size. This should be set to NULL |
| // if next CDI certificate should not be computed. |
| // next_cdi_attest: On success, will be populated with the next CDI value for |
| // attestation. |
| // next_cdi_seal: On success, will be populated with the next CDI value for |
| // sealing. |
| DiceResult DiceMainFlow(void* context, |
| const uint8_t current_cdi_attest[DICE_CDI_SIZE], |
| const uint8_t current_cdi_seal[DICE_CDI_SIZE], |
| const DiceInputValues* input_values, |
| size_t next_cdi_certificate_buffer_size, |
| uint8_t* next_cdi_certificate, |
| size_t* next_cdi_certificate_actual_size, |
| uint8_t next_cdi_attest[DICE_CDI_SIZE], |
| uint8_t next_cdi_seal[DICE_CDI_SIZE]); |
| |
| #ifdef __cplusplus |
| } // extern "C" |
| #endif |
| |
| #endif // DICE_DICE_H_ |