Was ist der Gastnachweis für vertrauliche VMs?

Mit dem Gastnachweisfeature können Sie bestätigen, dass eine vertrauliche VM in einer hardwarebasierten vertrauenswürdigen Ausführungsumgebung (Trusted Execution Environment, TEE) ausgeführt wird, in der Sicherheitsfeatures für Isolation und Integrität aktiviert sind.

Sie können den Gastnachweis für Folgendes verwenden:

  • Sicherstellen, dass die vertrauliche VM auf der erwarteten Hardwareplattform ausgeführt wird
  • Überprüfen Sie, ob für eine vertrauliche VM der sichere Start aktiviert ist. Diese Einstellung schützt die unteren Ebenen der VM (Firmware, Bootloader, Kernel) vor Schadsoftware (Rootkits, Bootkits).
  • Beweisen einer vertrauenden Seite, dass die VM auf einer vertraulichen Hardware ausgeführt wird.

Hinweis

Um einen Gastnachweis für DCesv5- und ECesv5-VMs durchzuführen, die von Intel TDX unterstützt werden, ist hier ein Anleitungshandbuch verfügbar. Die Verwendung der Intel Trust Authority erfordert die Registrierung bei Intel.

Szenarien

Die wichtigsten beteiligten Komponenten und Dienste am Gastnachweis sind:

Diagramm des Gastnachweisszenarios für eine vertrauliche VM.

Typische Betriebsszenarien nutzen die Clientbibliothek, um wie folgt Nachweisanforderungen vorzunehmen.

Szenario: Anforderung in separater Workload

In diesem Beispielszenario werden Nachweisanforderungen in einer separaten Workload vorgenommen. Die Anforderungen bestimmen, ob die vertrauliche VM auf der richtigen Hardwareplattform ausgeführt wird, bevor eine Workload gestartet wird.

Eine Workload (Plattformprüfungsclient im Diagramm) muss mit der Bestätigungsbibliothek kombiniert und in der vertraulichen VM ausgeführt werden, um den Nachweis durchzuführen. Nachdem das Programm eine Anforderung an die Nachweisbibliothek erstellt hat, analysiert die Workload die Antwort, um festzustellen, ob die VM auf der richtigen Hardwareplattform ausgeführt wird und/oder der sichere Start aktiviert ist, bevor die vertrauliche Workload gestartet wird.

Diagramm einer Bestätigungsanforderung, die in einer separaten Workload vorgenommen wird.

Dieses Szenario ähnelt dem folgenden Szenario. Der Hauptunterschied besteht darin, wie jedes Szenario das gleiche Ziel abhängig vom Ausgangspunkt der Anforderung erreicht.

Szenario: Anforderung innerhalb der Workload

In diesem Beispielszenario werden Nachweisanforderungen am Anfang des Programms innerhalb der Workload vorgenommen. Die Anforderungen überprüfen, ob die vertrauliche VM auf der richtigen Hardwareplattform ausgeführt wird, bevor eine Workload gestartet wird.

Dieses Szenario ähnelt dem vorherigen Szenario. Der Hauptunterschied besteht darin, wie jedes Szenario das gleiche Ziel abhängig vom Ausgangspunkt der Anforderung erreicht.

Die Kundenworkload muss mit der Nachweisbibliothek kombiniert und innerhalb der vertraulichen VM ausgeführt werden. Nachdem die Kundenworkload eine Anforderung an die Nachweisbibliothek erstellt hat, analysiert die Kundenworkload die Antwort, um festzustellen, ob die VM auf der richtigen Hardwareplattform ausgeführt wird und/oder der sichere Start aktiviert ist, bevor die vertrauliche Workload vollständig eingerichtet wird.

Diagramm einer Nachweisanforderung, die innerhalb einer Workload in einer vertraulichen VM vorgenommen wird.

Szenario: Handshake mit der vertrauenden Seite

In diesem Beispielszenario muss die vertrauliche VM nachweisen, dass sie auf einer vertraulichen Plattform ausgeführt wird, bevor eine vertrauende Seite ein Engagement durchführt. Die vertrauliche VM stellt der vertrauenden Seite ein Nachweistoken zur Verfügung, um das Engagement zu starten.

Einige Beispiele für Engagements sind:

  • Die vertrauliche VM benötigt Geheimnisse von einem Geheimnisverwaltungsdienst.
  • Ein Client möchte sicherstellen, dass die vertrauliche VM auf einer vertraulichen Plattform ausgeführt wird, bevor der vertraulichen VM personenbezogene Daten zur Verarbeitung zur Verfügung gestellt werden.

Das folgende Diagramm veranschaulicht den Handshake zwischen einer vertraulichen VM und der vertrauenden Seite.

Diagramm der Durchführung einer Nachweisanforderung in einem Szenario mit einer vertrauenden Seite.

Das folgende Sequenzdiagramm erläutert das Szenario mit einer vertrauenden Seite weiter. Die Anforderung/Antwort zwischen den beteiligten Systemen verwendet die Gastnachweisbibliothek-APIs. Die vertrauliche VM interagiert mit dem Geheimnis-Manager, um sich selbst mit den empfangenen Geheimnissen zu starten.

Diagramm der VM der vertrauenden Seite mit einem Geheimnisverwaltungsdienst.

APIs

Microsoft stellt die Gastnachweisbibliothek mit APIs bereit, um Nachweise durchzuführen und Daten sowohl zu verschlüsseln als auch zu entschlüsseln. Es gibt auch eine API zum Zurückfordern von Arbeitsspeicher.

Sie können diese APIs für die oben beschriebenen unterschiedlichen Szenarien verwenden.

Attest-API

Die Attest-API verwendet das ClientParameters-Objekt als Eingabe und gibt ein entschlüsseltes Nachweistoken zurück. Zum Beispiel:

AttestationResult Attest([in] ClientParameters client_params,  

  				 [out] buffer jwt_token); 
Parameter Informationen
ClientParameters (Typ: Objekt) Objekt, das die Version (Typ: uint32_t), Nachweismandanten-URI (Typ: vorzeichenloses Zeichen) und Clientnutzlast (Typ: vorzeichenloses Zeichen) übernimmt. Die Clientnutzlast kann (muss aber nicht) mehrere Schlüssel-Wert-Paare für einen Client oder Kundenmetadaten umfassen, die in der Antwortnutzlast zurückgegeben werden. Die Schlüssel-Wert-Paare müssen das JSON-Zeichenfolgenformat "{\"key1\":\"value1\",\"key2\":\"value2\"}" verwenden. Das Schlüssel-Wert-Paar für die Nachweisaktualität kann beispielsweise wie {\”Nonce\”:\”011510062022\”} aussehen.
buffer JSON-Webtoken, das Nachweisinformationen enthält.

Die Attest-API gibt ein AttestationResult (Typ: Struktur) zurück.

Encrypt-API

Die Encrypt-API übernimmt Daten, die verschlüsselt werden sollen, und ein JSON-Webtoken als Eingabe. Die API verschlüsselt die Daten mit einem öffentlichen kurzlebigen Schlüssel, der im JSON-Webtoken vorhanden ist. Zum Beispiel:

AttestationResult Encrypt(

  [enum] encryption_type, 

  [in] const unsigned char* jwt_token, 

  [in] const unsigned char* data, 

  [in] uint32_t data_size, 

  [out] unsigned char** encrypted_data, 

  [out] uint32_t* encrypted_data_size, 

  [out] unsigned char** encryption_metadata,  

  [out] uint32_t encryption_metadata_size); 
Parameter Erklärung
encryption_type Keine.
const unsigned char* jwt_token JSON-Webtoken, das Nachweisinformationen enthält.
const unsigned char* data Die zu verschlüsselnden Daten.
uint32_t data_size Größe der Daten, die verschlüsselt werden sollen.
unsigned char** encrypted_data Verschlüsselte Daten.
uint32_t* encrypted_data_size Größe der verschlüsselten Daten.
unsigned char** encryption_metadata Verschlüsselungsmetadaten.
uint32_t encryption_metadata_size Größe der Verschlüsselungsmetadaten.

Die Encrypt-API gibt ein AttestationResult (Typ: Struktur) zurück.

Decrypt-API

Die Decrypt-API verwendet verschlüsselte Daten als Eingabe und entschlüsselt die Daten mit dem privaten kurzlebigen Schlüssel, der im Trusted Platform Module (TPM) versiegelt ist. Zum Beispiel:

AttestationResult Decrypt([enum] encryption_type, 

  [in] const unsigned char* encrypted_data, 

  [in] uint32_t encrypted_data_size, 

  [in] const unsigned char* encryption_metadata, 

  [in] unit32_t encryption_metadata_size, 

  [out] unsigned char** decrypted_data,  

  [out] unit32_t decrypted_data_size); 
Parameter Erklärung
encryption_type Keine.
const unsigned char* encrypted_data Die zu entschlüsselnden Daten.
uint32_t encrypted_data_size Größe der Daten, die entschlüsselt werden sollen.
const unsigned char* encryption_metadata Verschlüsselungsmetadaten.
unit32_t encryption_metadata_size Größe der Verschlüsselungsmetadaten.
unsigned char** decrypted_data Die entschlüsselten Daten.
unit32_t decrypted_data_size Größe der entschlüsselten Daten.

Die Decrypt-API gibt ein AttestationResult (Typ: Struktur) zurück.

Free-API

Die Free-API gibt Arbeitsspeicher frei, der von Daten genutzt wird. Zum Beispiel:

Free([in] buffer data); 
Parameter Erklärung
data Zurückfordern des Speichers, der von Daten genutzt wird.

Die Free-API gibt nichts zurück.

Fehlercodes

Die APIs können die folgenden Fehlercodes zurückgeben:

Fehlercode BESCHREIBUNG
1 Fehler bei der Initialisierung.
2 Fehler beim Analysieren der Antwort.
3 Token für verwaltete Identitäten für Azure-Ressourcen nicht gefunden.
4 Anzahl der Wiederholungen für Anforderung überschritten.
5 Anforderung fehlgeschlagen.
6 Nachweis fehlgeschlagen.
7 Senden der Anforderung fehlgeschlagen.
8 Ungültiger Eingabeparameter.
9 Überprüfung von Nachweisparametern fehlgeschlagen.
10 Die Speicherbelegung hat einen Fehler erzeugt.
11 Abrufen von Betriebssysteminformationen fehlgeschlagen.
12 Interner TPM-Fehler.
13 TPM-Vorgang fehlgeschlagen.
14 JSON-Webtokenentschlüsselung fehlgeschlagen.
15 TPM-Fehler bei JSON-Webtokentschlüsselung.
16 Ungültige JSON-Antwort.
17 Leeres VCEK-Zertifikat (Versioned Chip Endorsement Key).
18 Leere Antwort.
19 Leerer Anforderungstext.
20 Fehler beim Analysieren des Berichts.
21 Bericht leer.
22 Fehler beim Extrahieren der JSON-Webtokeninformationen.
23 Fehler beim Konvertieren des JSON-Webtokens in einen öffentlichen RSA-Schlüssel.
24 Initialisierung der EVP_PKEY-Verschlüsselung fehlgeschlagen.
25 EVP_PKEY-Verschlüsselung fehlgeschlagen.
26 TPM-Fehler bei Datenentschlüsselung.
27 Fehler beim Analysieren von DNS-Informationen.

JSON Web Token

Sie können verschiedene Teile des JSON-Webtokens für die verschiedenen oben beschriebenen API-Szenarien extrahieren. Wichtige Felder für das Gastnachweisfeature sind:

Anspruch Attribut Beispielswert
- x-ms-azurevm-vmid 2DEDC52A-6832-46CE-9910-E8C9980BF5A7
AMD SEV-SNP-Hardware x-ms-isolation-tee sevsnpvm
AMD SEV-SNP-Hardware x-ms-compliance-status (unter x-ms-isolation-tee) azure-compliant-cvm
Sicherer Start secure-boot (unter x-ms-runtime>vm-configuration) true
Virtuelles TPM tpm-enabled (unter x-ms-runtime>vm-configuration) true
Virtuelles TPM kid (unter x-ms-runtime>keys) TpmEphemeralEncryptionKey
{
  "exp": 1653021894,
  "iat": 1652993094,
  "iss": "https://sharedeus.eus.test.attest.azure.net",
  "jti": "<value>",
  "nbf": 1652993094,
  "secureboot": true,
  "x-ms-attestation-type": "azurevm",
  "x-ms-azurevm-attestation-protocol-ver": "2.0",
  "x-ms-azurevm-attested-pcrs": [
    0,
    1,
    2,
    3,
    4,
    5,
    6,
    7,
    11,
    12,
    13
  ],
  "x-ms-azurevm-bootdebug-enabled": false,
  "x-ms-azurevm-dbvalidated": true,
  "x-ms-azurevm-dbxvalidated": true,
  "x-ms-azurevm-debuggersdisabled": true,
  "x-ms-azurevm-default-securebootkeysvalidated": true,
  "x-ms-azurevm-elam-enabled": true,
  "x-ms-azurevm-flightsigning-enabled": false,
  "x-ms-azurevm-hvci-policy": 0,
  "x-ms-azurevm-hypervisordebug-enabled": false,
  "x-ms-azurevm-is-windows": true,
  "x-ms-azurevm-kerneldebug-enabled": false,
  "x-ms-azurevm-osbuild": "NotApplicable",
  "x-ms-azurevm-osdistro": "Microsoft",
  "x-ms-azurevm-ostype": "Windows",
  "x-ms-azurevm-osversion-major": 10,
  "x-ms-azurevm-osversion-minor": 0,
  "x-ms-azurevm-signingdisabled": true,
  "x-ms-azurevm-testsigning-enabled": false,
  "x-ms-azurevm-vmid": "<value>",
  "x-ms-isolation-tee": {
    "x-ms-attestation-type": "sevsnpvm",
    "x-ms-compliance-status": "azure-compliant-cvm",
    "x-ms-runtime": {
      "keys": [
        {
          "e": "AQAB",
          "key_ops": [
            "encrypt"
          ],
          "kid": "HCLAkPub",
          "kty": "RSA",
          "n": "<value>"
        }
      ],
      "vm-configuration": {
        "console-enabled": true,
        "current-time": 1652993091,
        "secure-boot": true,
        "tpm-enabled": true,
        "vmUniqueId": "<value>"
      }
    },
    "x-ms-sevsnpvm-authorkeydigest": "<value>",
    "x-ms-sevsnpvm-bootloader-svn": 2,
    "x-ms-sevsnpvm-familyId": "<value>",
    "x-ms-sevsnpvm-guestsvn": 1,
    "x-ms-sevsnpvm-hostdata": "<value>",
    "x-ms-sevsnpvm-idkeydigest": "<value>",
    "x-ms-sevsnpvm-imageId": "<value>",
    "x-ms-sevsnpvm-is-debuggable": false,
    "x-ms-sevsnpvm-launchmeasurement": "<value>",
    "x-ms-sevsnpvm-microcode-svn": 55,
    "x-ms-sevsnpvm-migration-allowed": false,
    "x-ms-sevsnpvm-reportdata": "<value>",
    "x-ms-sevsnpvm-reportid": "<value>",
    "x-ms-sevsnpvm-smt-allowed": true,
    "x-ms-sevsnpvm-snpfw-svn": 2,
    "x-ms-sevsnpvm-tee-svn": 0,
    "x-ms-sevsnpvm-vmpl": 0
  },
  "x-ms-policy-hash": "<value>",
  "x-ms-runtime": {
    "keys": [
      {
        "e": "AQAB",
        "key_ops": [
          "encrypt"
        ],
        "kid": "TpmEphemeralEncryptionKey",
        "kty": "RSA",
        "n": "<value>"
      }
    ]
  },
  "x-ms-ver": "1.0"
}

Nächste Schritte