// 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 #include #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_