syntax = "proto3";

package attest;

import "proto/sevsnp.proto";
import "proto/tdx.proto";
import "tpm.proto";

option go_package = "github.com/google/go-tpm-tools/proto/attest";

// Information uniquely identifying a GCE instance. Can be used to create an
// instance URL, which can then be used with GCE APIs. Formatted like:
//   https://www.googleapis.com/compute/v1/projects/{project_id}/zones/{zone}/instances/{instance_name}
message GCEInstanceInfo {
  string zone = 1;
  string project_id = 2;
  uint64 project_number = 3;
  string instance_name = 4;
  uint64 instance_id = 5;
}

message Attestation {
  // Attestation Key (AK) Public Area, encoded as a TPMT_PUBLIC
  bytes ak_pub = 1;
  // Quotes over all supported PCR banks
  repeated tpm.Quote quotes = 2;
  // TCG Event Log, encoded in the raw binary format.
  // Can be SHA-1 or crypto-agile.
  bytes event_log = 3;
  // Optional information about a GCE instance, unused outside of GCE
  GCEInstanceInfo instance_info = 4;
  // A TCG Canonical Event Log.
  bytes canonical_event_log = 5;
  // Attestation Key (AK) Certificate, encoded as ASN.1 DER.
  // Optional.
  bytes ak_cert = 6;
  // Intermediate Certificates for verifying the AK Certificate, encoded as
  // ASN.1 DER. Optional.
  repeated bytes intermediate_certs = 7;
  // Trusted execution environment attestation is a secondary platform
  // attestation that the machine is running within a particular confidential
  // environment.
  oneof tee_attestation {
    sevsnp.Attestation sev_snp_attestation = 8;
    tdx.QuoteV4 tdx_attestation = 9;
  }
}

// Type of hardware technology used to protect this instance
enum GCEConfidentialTechnology {
  NONE = 0;
  AMD_SEV = 1;
  AMD_SEV_ES = 2;
  INTEL_TDX = 3;
  AMD_SEV_SNP = 4;
}

// The platform/firmware state for this instance
message PlatformState {
  oneof firmware {
    // Raw S-CRTM version identifier (EV_S_CRTM_VERSION)
    bytes scrtm_version_id = 1;
    // Virtual GCE firmware version (parsed from S-CRTM version id)
    uint32 gce_version = 2;
  }
  // Set to NONE on non-GCE instances or non-Confidential Shielded GCE instances
  GCEConfidentialTechnology technology = 3;
  // Only set for GCE instances
  GCEInstanceInfo instance_info = 4;
}

message GrubFile {
  // The digest of the file (pulled from the raw event digest).
  bytes digest = 1;
  // The event data. This is not measured, so it is untrusted.
  bytes untrusted_filename = 2;
}

message GrubState {
  // All GRUB-read and measured files, including grub.cfg.
  repeated GrubFile files = 1;
  // A list of executed GRUB commands and command lines passed to the kernel
  // and kernel modules.
  repeated string commands = 2;
}

// The state of the Linux kernel.
// At the moment, parsing LinuxKernelState relies on parsing the GrubState.
// To do so, use ParseOpts{Loader: GRUB} when calling ParseMachineState.
message LinuxKernelState {
  // The kernel command line.
  string command_line = 1;
}

// A parsed event from the TCG event log
message Event {
  // The Platform Control Register (PCR) this event was extended into.
  uint32 pcr_index = 1;
  // The type of this event. Note that this value is not verified, so it should
  // only be used as a hint during event parsing.
  uint32 untrusted_type = 2;
  // The raw data associated to this event. The meaning of this data is
  // specific to the type of the event.
  bytes data = 3;
  // The event digest actually extended into the TPM. This is often the hash of
  // the data field, but in some cases it may have a type-specific calculation.
  bytes digest = 4;
  // This is true if hash(data) == digest.
  bool digest_verified = 5;
}

// Common, publicly-listed certificates by different vendors.
enum WellKnownCertificate {
  UNKNOWN = 0;

  // Microsoft certs:
  // https://go.microsoft.com/fwlink/p/?linkid=321192
  MS_WINDOWS_PROD_PCA_2011 = 1;
  // https://go.microsoft.com/fwlink/p/?linkid=321194
  MS_THIRD_PARTY_UEFI_CA_2011 = 2;
}

message Certificate {
  // The representation of the certificate. If the certificate matches a
  // well-known certificate above, representation should contain the value in
  // the enum. Otherwise, it will contain the raw DER.
  oneof representation {
    // DER representation of the certificate.
    bytes der = 1;
    WellKnownCertificate well_known = 2;
  }
}

// A Secure Boot database containing lists of hashes and certificates,
// as defined by section 32.4.1 Signature Database in the UEFI spec.
message Database {
  repeated Certificate certs = 1;
  repeated bytes hashes = 2;
}

// The Secure Boot state for this instance.
message SecureBootState {
  // Whether Secure Boot is enabled.
  bool enabled = 1;
  // The Secure Boot signature (allowed) database.
  Database db = 2;
  // The Secure Boot revoked signature (forbidden) database.
  Database dbx = 3;
  // Authority events post-separator. Pre-separator authorities
  // are currently not supported.
  Database authority = 4;
}

// The container's restart policy.
// See the following Kubernetes documentation for more details:
// https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy
// Note that these enum variants do not conform to the standard Protocol Buffers
// Style Guide so that RestartPolicy_name, RestartPolicy_value, and
// RestartPolicy.String() match the values used by Kubernetes and others.
enum RestartPolicy {
  Always = 0;
  OnFailure = 1;
  Never = 2;
}

message ContainerState {
  string image_reference = 1;
  // Digest of the registry's image manifest, which contains a list of the
  // layers comprising the image.
  string image_digest = 2;
  RestartPolicy restart_policy = 3;
  // Digest of the local image configuration object, containing config items
  // such as local layer digests.
  string image_id = 4;
  repeated string args = 5;
  map<string, string> env_vars = 6;
  // Record operator input Env Vars and Args, should be subsets of the above
  // Env Vars and Args.
  repeated string overridden_args = 7;
  map<string, string> overridden_env_vars = 8;
}

message SemanticVersion {
  uint32 major = 1;
  uint32 minor = 2;
  uint32 patch = 3;
}

message HealthMonitoringState {
  // Whether memory monitoring is enabled.
  optional bool memory_enabled = 1;
}

message AttestedCosState {
  ContainerState container = 1;
  SemanticVersion cos_version = 2;
  SemanticVersion launcher_version = 3;
  HealthMonitoringState health_monitoring = 4;
}

message EfiApp {
  // The PE/COFF digest of the EFI application (pulled from the raw event digest).
  bytes digest = 1;
}

// The verified state of EFI Applications. Policy usage on this machine state
// should check the entire set of EFI App digests matches, not a subset.
message EfiState {
  // UEFI's OS Loader code is required to measure attempts to load and execute
  // UEFI applications.
  // UEFI applications are typically bootloaders such as shim and GRUB.
  // These run and are measured using the UEFI LoadImage() service.
  repeated EfiApp apps = 1;
}

// The verified state of a booted machine, obtained from an Attestation
message MachineState {
  PlatformState platform = 1;

  SecureBootState secure_boot = 2;

  // The complete parsed TCG Event Log, including those events used to
  // create the PlatformState.
  repeated Event raw_events = 3;
  // The hash algorithm used when verifying the Attestation. This indicates:
  //   - which PCR bank was used for for quote validation and event log replay
  //   - the hash algorithm used to calculate event digests
  tpm.HashAlgo hash = 4;

  GrubState grub = 5;

  LinuxKernelState linux_kernel = 6;

  AttestedCosState cos = 7;

  EfiState efi = 8;
}

// A policy dictating which values of PlatformState to allow
message PlatformPolicy {
  // If PlatformState.firmware contains a scrtm_version_id, it must appear
  // in this list. For use with a GCE VM, minimum_gce_firmware_version is
  // often a better alternative.
  repeated bytes allowed_scrtm_version_ids = 1;
  // If PlatformState.firmware contains a minimum_gce_firmware_version, it must
  // be greater than or equal to this value. Currently, the max version is 1.
  uint32 minimum_gce_firmware_version = 2;
  // The PlatformState's technology must be at least as secure as
  // the specified minimum_technology (i.e. AMD_SEV_ES > AMD_SEV > NONE).
  GCEConfidentialTechnology minimum_technology = 3;
}

// A policy dictating which type of MachineStates to allow
message Policy {
  PlatformPolicy platform = 1;

  // SecureBootPolicy secure_boot = 2;
}
