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:
- Obciążenie
- Biblioteka zaświadczania gościa
- Sprzęt (na potrzeby raportowania). Na przykład AMD-SEVSNP.
- Usługa zaświadczania platformy Microsoft Azure
- Odpowiedź na token internetowy w formacie JSON
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.
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.
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.
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.
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"
}