/* * Attestation Request Control Block related functions * * Copyright IBM Corp. 2022 * * s390-tools is free software; you can redistribute it and/or modify * it under the terms of the MIT license. See LICENSE for details. */ #ifndef PVATTEST_ARCB_H #define PVATTEST_ARCB_H /* Must be included before any other header */ #include "config.h" #include "libpv/glib-helper.h" #include "lib/zt_common.h" #include "libpv/crypto.h" #include "libpv/macros.h" #include "types.h" #define MAI_HMAC_RESERVED_INVALID 0 #define MAI_HMAC_SHA512 0x1 #define HMAC_SHA512_KEY_SIZE 64 #define ARCB_V1_ATTEST_PROT_KEY_SIZE 32 #define ARCB_V1_NONCE_SIZE 16 #define ARCB_V1_TAG_SIZE 16 #define ARCB_V1_IV_SIZE 12 #define ARCB_V1_PHKH_SIZE 32 /* Optional nonce in ARCB */ #define ARCB_V1_PAF_NONCE PV_MSB(1) /* Public host key hash used to unseal SE header added to additional data to be measured */ #define ARCB_V1_PAF_AAD_PHKH_HEADER PV_MSB(2) /* Public host key hash used to unseal this attestation added to additional data to be measured */ #define ARCB_V1_PAF_AAD_PHKH_ATTEST PV_MSB(3) /* Temporary backup-host-key use allowed */ #define ARCB_V1_PAF_TMP_BACKUP_ALLOWED PV_MSB(62) /* Global not-host-specific key allowed */ #define ARCB_V1_PAF_GLOBAL_NHS_KEY_ALLOWED PV_MSB(63) #define ARCB_V1_PAF_ALL \ (ARCB_V1_PAF_NONCE | ARCB_V1_PAF_AAD_PHKH_HEADER | ARCB_V1_PAF_AAD_PHKH_ATTEST | \ ARCB_V1_PAF_TMP_BACKUP_ALLOWED | ARCB_V1_PAF_GLOBAL_NHS_KEY_ALLOWED) typedef struct arcb_v1 arcb_v1_t; /** arcb_v1_new: * * @arpk: Attestation Request Protection key. AES-GCM-256 key to * protect Measurement Key and Nonce. * Must be ´ARCB_V1_ATTEST_PROT_KEY_SIZE´ bytes long. * @iv: IV for protecting Measuremt Key and Nonce. * Should be random for each new ARPK. * Must be ´ARCB_V1_IV_SIZE´ bytes long. * @mai: Measurement Algorithm Identifier for the attestation measurement. * See ´enum mai´ * @evp_cpk: Customer key in EVP_PKEY format. Must contain private and public key pair. * @mkey: Measurement key to calculate the Measurement. * Must be ´HMAC_SHA512_KEY_SIZE´ bytes long. * @paf: Plain text Attestation Flags. See ´enum plaintext_attestattion_flags´. * ´ARCB_V1_PAF_NONCE´ must not be set. * @error: GError. *error will != NULL if error occours. * * arpk, mkey, and iv must me correct size * If not this is considered as a programming error (No warning; * Results in Assertion or undefined behavior). * * GBytes will be ref'ed. * * All numbers must be in system byte order and will be converted to big endian * if needed. * * Returns: (nullable) (transfer full): new ARCB context. */ arcb_v1_t *arcb_v1_new(GBytes *arpk, GBytes *iv, uint32_t mai, EVP_PKEY *evp_cpk, GBytes *mkey, uint64_t paf, GError **error) PV_NONNULL(1, 2, 4, 5); void arcb_v1_clear_free(arcb_v1_t *arcb); WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(arcb_v1_t, arcb_v1_clear_free) /** arcb_v1_add_key_slot: * * @arcb: ARCB context. * @evp_host: Host public key. * @error: GError. *error will != NULL if error occours. * * Builds a key slot. Calculates exchange key, wraps ARPK with the exchange key. * Calculates the public host key hash. Calculates the key slot tag. * Adds it to the ARCB. * * Returns: 0 in case of success, -1 otherwise */ int arcb_v1_add_key_slot(arcb_v1_t *arcb, EVP_PKEY *evp_host, GError **error) PV_NONNULL(1, 2); void arcb_v1_set_nonce(arcb_v1_t *arcb, GBytes *nonce) PV_NONNULL(1, 2); void arcb_v1_rm_nonce(arcb_v1_t *arcb) PV_NONNULL(1); /** arcb_v1_serialize: * * @arcb: ARCB context. * @error: GError. *error will != NULL if error occurs. * * Will create a valid ARCB for the UV. Including encrypting confidential data. * At least one key_slot must be added beforehand. * * Returns: (nullable) (transfer full): The serialized ARCB which can be added to the * Retrieve Attestation Measurement UVC as GBytes. */ GBytes *arcb_v1_serialize(const arcb_v1_t *arcb, GError **error) PV_NONNULL(1, 2); uint32_t arcb_v1_get_required_measurement_size(const arcb_v1_t *arcb, GError **error) PV_NONNULL(1, 2); uint32_t arcb_v1_get_required_additional_size(const arcb_v1_t *arcb) PV_NONNULL(1); gboolean arcb_v1_use_nonce(const arcb_v1_t *arcb) PV_NONNULL(1); gboolean arcb_v1_additional_has_phkh_image(const arcb_v1_t *arcb) PV_NONNULL(1); gboolean arcb_v1_additional_has_phkh_attest(const arcb_v1_t *arcb) PV_NONNULL(1); GBytes *arcb_v1_get_measurement_key(const arcb_v1_t *arcb) PV_NONNULL(1); GBytes *arcb_v1_get_nonce(const arcb_v1_t *arcb) PV_NONNULL(1); GBytes *arcb_v1_get_arp_key(const arcb_v1_t *arcb) PV_NONNULL(1); /** arcb_v1_verify_serialized_arcb: * * @serialized_arcb: binary ARCB in UV readable format. * @arpk: Attestation Request Protection key that was used to create serialized_arpk * @measurement_key: Output parameter: decrypted measurement key if no error. * May be NULL if not interested for this output. * @optional_nonce: Output parameter: decrypted nonce if no error. * May be NULL if not interested for this output. * @error: GError. *error will != NULL if error occurs. * * * Checks if sizes are sound and flags are known by this implementation. * Decrypts Measurement key and nonce (if given) and verifies ARCB tag. * * Returns: TRUE if ARCB is valid, including matching ARCB tag. Otherwise FALSE. * */ gboolean arcb_v1_verify_serialized_arcb(GBytes *serialized_arcb, GBytes *arpk, GBytes **measurement_key, GBytes **optional_nonce, GError **error) PV_NONNULL(1, 2); #define ARCB_ERROR g_quark_from_static_string("pv-arcb_error-quark") typedef enum arcb_error { ARCB_ERR_INVALID_ARCB, ARCB_ERR_INVALID_PAF, ARCB_ERR_INVALID_MAI, ARCB_ERR_UNABLE_ENCR_ARPK, } arcb_error_e; #endif /* PVATTEST_ARCB_H */