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:
- Die Arbeitslast
- Die Gastnachweisbibliothek
- Hardware (für Berichterstellung). Beispielsweise AMD-SEVSNP.
- Der Microsoft Azure Attestation-Dienst
- JSON-Webtokenantwort
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.
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.
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.
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.
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"
}