Co to jest zaświadczenie gościa dla poufnych maszyn wirtualnych?

Zaświadczenie gościa pomaga potwierdzić, że poufne środowisko maszyny wirtualnej jest zabezpieczone przez oryginalne oparte na sprzęcie zaufane środowisko wykonawcze (TEE) z funkcjami zabezpieczeń włączonymi pod kątem izolacji i integralności.

Za pomocą zaświadczania gościa można wykonywać następujące czynności:

  • Upewnij się, że poufne maszyny wirtualne działają na oczekiwanej platformie sprzętowej
  • Sprawdź, czy poufna maszyna wirtualna ma włączony bezpieczny rozruch. To ustawienie chroni niższe warstwy maszyny wirtualnej (oprogramowanie układowe, moduł ładujący rozruch, jądro) przed złośliwym oprogramowaniem (rootkits, bootkits).
  • Uzyskiwanie dowodów dla jednostki uzależnionej, że poufne maszyny wirtualne działają na poufnym sprzęcie

Uwaga

Aby wykonać zaświadczenie gościa dla maszyn wirtualnych DCesv5 i ECesv5 wspieranych przez intel TDX, przewodnik z instrukcjami jest dostępny tutaj. Korzystanie z urzędu zaufania Intel wymaga rejestracji w środowisku Intel.

Scenariusze

Główne składniki i usługi związane z zaświadczeniem gościa to:

Diagram of guest attestation scenario for a confidential VM.

Typowe scenariusze operacyjne obejmują bibliotekę klienta, aby wysyłać żądania zaświadczania w następujący sposób.

Scenariusz: żądanie w oddzielnym obciążeniu

W tym przykładowym scenariuszu żądania zaświadczania są wykonywane w osobnym obciążeniu. Żądania określają, czy poufne maszyny wirtualne działają na odpowiedniej platformie sprzętowej przed uruchomieniem obciążenia.

Obciążenie (klient modułu sprawdzania platformy na diagramie) musi zostać zintegrowane z biblioteką zaświadczania i uruchomić wewnątrz poufnej maszyny wirtualnej, aby przeprowadzić zaświadczenie. Gdy program wysyła żądanie do biblioteki zaświadczania, obciążenie analizuje odpowiedź, aby ustalić, czy maszyna wirtualna działa na odpowiedniej platformie sprzętowej i/lub bezpiecznym rozruchu przed uruchomieniem poufnego obciążenia.

Diagram of an attestation request being made in a separate workload.

Ten scenariusz jest podobny do poniższego scenariusza. Główna różnica polega na tym, jak każdy scenariusz osiąga ten sam cel w oparciu o lokalizację żądania.

Scenariusz: żądanie z wewnątrz obciążenia

W tym przykładowym scenariuszu żądania zaświadczania są wysyłane wewnątrz obciążenia na początku programu. Żądania sprawdzają, czy poufne maszyny wirtualne działają na odpowiedniej platformie sprzętowej przed uruchomieniem obciążenia.

Ten scenariusz jest podobny do poprzedniego scenariusza. Główna różnica polega na tym, jak każdy scenariusz osiąga ten sam cel w oparciu o lokalizację żądania.

Obciążenie klienta musi zostać zintegrowane z biblioteką zaświadczania i uruchomić je wewnątrz poufnej maszyny wirtualnej. Gdy obciążenie klienta wysyła żądanie do biblioteki zaświadczania, obciążenie klienta analizuje odpowiedź, aby ustalić, czy maszyna wirtualna działa na odpowiedniej platformie sprzętowej i/lub bezpiecznym ustawieniu rozruchu przed pełnym skonfigurowaniem poufnego obciążenia.

Diagram of an attestation request being made from within a workload inside a confidential VM.

Scenariusz: uzgadnianie jednostki uzależnionej

W tym przykładowym scenariuszu poufne maszyny wirtualne muszą udowodnić, że działa na platformie poufnej, zanim jednostka uzależniona zostanie włączona. Poufne maszyny wirtualnej przedstawia token zaświadczania jednostki uzależnionej w celu rozpoczęcia zakontraktowania.

Oto kilka przykładów zakontraktowania:

  • Poufne maszyny wirtualne chcą wpisów tajnych z usługi zarządzania wpisami tajnymi.
  • Klient chce się upewnić, że poufne maszyny wirtualne działają na platformie poufnej przed ujawnieniem poufnych danych poufnych maszynie wirtualnej do przetwarzania.

Na poniższym diagramie przedstawiono uzgadnianie między poufnej maszyny wirtualnej i jednostki uzależnionej.

Diagram of an attestation request being made in a relying party scenario.

Poniższy diagram sekwencji dodatkowo wyjaśnia scenariusz jednostki uzależnionej. Żądanie/odpowiedź między zaangażowanymi systemami korzystają z interfejsów API bibliotek zaświadczania gościa. Poufne maszyny wirtualnej współdziałają z menedżerem wpisów tajnych, aby uruchomić się przy użyciu odebranych wpisów tajnych.

Diagram of the relying party VM with a secrets manager service.

Interfejsy API

Firma Microsoft udostępnia bibliotekę zaświadczania gościa za pomocą interfejsów API do wykonywania zaświadczeń oraz szyfrowania i odszyfrowywania danych. Istnieje również interfejs API do odzyskania pamięci.

Możesz użyć tych interfejsów API dla różnych scenariuszy opisanych wcześniej.

Interfejs API zaświadczywania

Interfejs API zaświadczania przyjmuje ClientParameters obiekt jako dane wejściowe i zwraca odszyfrowany token zaświadczania. Na przykład:

AttestationResult Attest([in] ClientParameters client_params,  

  				 [out] buffer jwt_token); 
Parametr Informacja
ClientParameters (typ: obiekt) Obiekt, który przyjmuje wersję (typ: uint32_t), identyfikator URI dzierżawy zaświadczania (typ: znak niepodpisany) i ładunek klienta (typ: znak niepodpisany). Ładunek klienta to zero lub więcej par klucz-wartość dla dowolnego klienta lub metadanych klienta, które są zwracane w ładunku odpowiedzi. Pary klucz-wartość muszą mieć format "{\"key1\":\"value1\",\"key2\":\"value2\"}"ciągu JSON. Na przykład wartość klucza aktualności zaświadczania może wyglądać następująco: {\”Nonce\”:\”011510062022\”} .
buffer Token internetowy JSON zawierający informacje o zaświadczania.

Interfejs API zaświadcza zwraca wartość AttestationResult (typ: struktura).

Szyfrowanie interfejsu API

Interfejs API szyfrowania pobiera dane do szyfrowania i token internetowy JSON jako dane wejściowe. Interfejs API szyfruje dane przy użyciu publicznego klucza efemerycznego, który znajduje się w tokenie internetowym JSON. Na przykład:

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); 
Parametr Wyjaśnienie
encryption_type Brak.
const unsigned char* jwt_token Token internetowy JSON zawierający informacje o zaświadczaniach.
const unsigned char* data Dane do zaszyfrowania
uint32_t data_size Rozmiar danych do zaszyfrowania.
unsigned char** encrypted_data Zaszyfrowane dane.
uint32_t* encrypted_data_size Rozmiar zaszyfrowanych danych.
unsigned char** encryption_metadata Metadane szyfrowania.
uint32_t encryption_metadata_size Rozmiar metadanych szyfrowania.

Interfejs API szyfrowania zwraca wartość AttestationResult (typ: struktura).

Odszyfrowywanie interfejsu API

Interfejs API odszyfrowywania pobiera zaszyfrowane dane jako dane wejściowe i odszyfrowuje dane przy użyciu prywatnego klucza efemerycznego, który jest zapieczętowany w module Trusted Platform Module (TPM). Na przykład:

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); 
Parametr Wyjaśnienie
encryption_type Brak.
const unsigned char* encrypted_data Dane do odszyfrowywania.
uint32_t encrypted_data_size Rozmiar danych do odszyfrowywania.
const unsigned char* encryption_metadata Metadane szyfrowania.
unit32_t encryption_metadata_size Rozmiar metadanych szyfrowania.
unsigned char** decrypted_data Odszyfrowane dane.
unit32_t decrypted_data_size Rozmiar odszyfrowanych danych.

Interfejs API odszyfrowywania zwraca element AttestationResult (typ: struktura).

Bezpłatny interfejs API

Bezpłatny interfejs API odzyskuje pamięć przechowywaną przez dane. Na przykład:

Free([in] buffer data); 
Parametr Wyjaśnienie
data Odzyskiwanie pamięci przechowywanej przez dane.

Bezpłatny interfejs API nie zwraca żadnych elementów.

Kody błędów

Interfejsy API mogą zwracać następujące kody błędów:

Kod błędu opis
1 Błąd inicjowania błędu.
2 Błąd podczas analizowania odpowiedzi.
3 Nie można odnaleźć tożsamości zarządzanych dla tokenu zasobów platformy Azure.
100 Żądanie przekroczyło ponowną próbę.
5 Żądanie nie powiodło się.
6 Zaświadczenie nie powiodło się.
7 Żądanie wysyłania nie powiodło się.
8 Nieprawidłowy parametr wejściowy.
9 Sprawdzanie poprawności parametrów zaświadczania nie powiodło się.
10 Alokacja pamięci nie powiodła się.
11 Nie można pobrać informacji o systemie operacyjnym.
12 Wewnętrzny błąd modułu TPM.
13 Operacja modułu TPM nie powiodła się.
14 Odszyfrowywanie tokenu internetowego JSON nie powiodło się.
15 Błąd modułu TPM odszyfrowywania tokenu internetowego JSON.
16 Nieprawidłowa odpowiedź JSON.
17 Pusty certyfikat klucza poręczenia mikroukładu w wersji (VCEK).
18 Pusta odpowiedź.
19 Pusta treść żądania.
20 Niepowodzenie analizowania raportu.
21 Raport jest pusty.
22 Błąd podczas wyodrębniania informacji o tokenie internetowym JSON.
23 Błąd podczas konwertowania tokenu internetowego JSON na klucz publiczny RSA.
24 EVP_PKEY inicjowanie szyfrowania nie powiodło się.
25 EVP_PKEY szyfrowanie nie powiodło się.
26 Błąd modułu TPM odszyfrowywania danych.
27 Błąd podczas analizowania informacji DNS.

Token internetowy JSON

Możesz wyodrębnić różne części tokenu internetowego JSON dla różnych scenariuszy interfejsu API opisanych wcześniej. Poniżej przedstawiono ważne pola dla funkcji zaświadczania gościa:

Oświadczenie Atrybut Przykładowa wartość
- x-ms-azurevm-vmid 2DEDC52A-6832-46CE-9910-E8C9980BF5A7
Sprzęt AMD SEV-SNP x-ms-isolation-tee sevsnpvm
Sprzęt AMD SEV-SNP x-ms-compliance-status (w obszarze x-ms-isolation-tee) azure-compliant-cvm
Bezpieczny rozruch secure-boot (w obszarze x-ms-runtime>vm-configuration) true
Wirtualny moduł TPM tpm-enabled (w obszarze x-ms-runtime>vm-configuration) true
Wirtualny moduł TPM kid (w obszarze 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"
}

Następne kroki