O que é atestado de convidado para VMs confidenciais?
O atestado de convidado o ajuda a confirmar que o ambiente da sua VM confidencial esteja protegido por um Ambiente de Execução Confiável (TEE) com recursos de segurança habilitados para isolamento e integridade.
Você pode usar o atestado de convidado para:
- Verifique se a VM confidencial é executada na plataforma de hardware esperada
- Verifique se a VM confidencial está com a inicialização segura habilitada. Essa configuração protege camadas inferiores da VM (firmware, carregador de inicialização, kernel) contra malware (rootkits, bootkits).
- Obter prova para uma terceira parte confiável de que a VM confidencial é executada em hardware confidencial
Observação
Para executar o atestado de convidado nas VMs DCesv5 e ECesv5 com suporte do Intel TDX, um guia de instruções está disponível aqui. Usar o Intel Trust Authority requer registro na Intel.
Cenários
Os principais componentes e serviços envolvidos no atestado de convidado são:
- A carga de trabalho
- A biblioteca de atestados de convidado
- Hardware (para relatórios). Por exemplo, AMD-SEVSNP.
- O serviço Atestado do Microsoft Azure
- Resposta do token Web JSON
Os cenários operacionais típicos incorporam a biblioteca de clientes para fazer solicitações de atestado desta maneira.
Cenário: solicitação em carga de trabalho separada
Neste cenário de exemplo, as solicitações de atestado são feitas em uma carga de trabalho separada. As solicitações determinam se a VM confidencial é executada na plataforma de hardware correta antes de uma carga de trabalho ser iniciada.
Uma carga de trabalho (Cliente verificador da plataforma no diagrama) precisa se integrar à biblioteca de atestados e ser executada na VM confidencial para fazer o atestado. Depois que o programa faz uma solicitação à biblioteca de atestado, a carga de trabalho analisa a resposta para determinar se a VM é executada na plataforma de hardware correta e/ou na configuração de inicialização segura antes de iniciar a carga de trabalho confidencial.
Esse cenário é semelhante ao cenário a seguir. A principal diferença é como cada cenário atinge a mesma meta com base no local da solicitação.
Cenário: solicitação dentro da carga de trabalho
Neste cenário de exemplo, as solicitações de atestado são feitas dentro da carga de trabalho no início do programa. As solicitações verificam se a VM confidencial é executada na plataforma de hardware correta antes de uma carga de trabalho ser iniciada.
Esse cenário é semelhante ao cenário anterior. A principal diferença é como cada cenário atinge a mesma meta com base no local da solicitação.
A carga de trabalho do cliente precisa se integrar à biblioteca de atestados e ser executada dentro da VM confidencial. Depois que a carga de trabalho do cliente faz uma solicitação à biblioteca de atestado, a carga de trabalho do cliente analisa a resposta para determinar se a VM é executada na plataforma de hardware correta e/ou na configuração de inicialização segura antes de configurar a carga de trabalho confidencial por completo.
Cenário: handshake com terceira parte confiável
Neste cenário de exemplo, a VM confidencial deve provar que ela é executada em uma plataforma confidencial antes que uma terceira parte confiável se envolva. A VM confidencial apresenta um token de atestado à terceira parte confiável para iniciar a participação.
Alguns exemplos de participação são:
- A VM confidencial quer segredos de um serviço de gerenciamento de segredos.
- Um cliente deseja garantir que a VM confidencial será executada em uma plataforma confidencial antes de revelar dados pessoais para processamento pela VM confidencial.
O diagrama a seguir mostra o handshake entre uma VM confidencial e a terceira parte confiável.
O diagrama de sequência a seguir explica ainda mais o cenário de terceira parte confiável. A solicitação/resposta entre os sistemas envolvidos usa as APIs de biblioteca de atestados de convidado. A VM confidencial interage com o gerenciador de segredos para se inicializar usando os segredos recebidos.
APIs
A Microsoft fornece a biblioteca de atestados de convidado com APIs para fazer atestados, criptografar e descriptografar dados. Também há uma API para recuperar memória.
Você pode usar essas APIs nos vários cenários descritos anteriormente.
API de atestado
A API de atestado usa o objeto ClientParameters
como entrada e retorna um token de atestado descriptografado. Por exemplo:
AttestationResult Attest([in] ClientParameters client_params,
[out] buffer jwt_token);
Parâmetro | Informações |
---|---|
ClientParameters (type: object) |
Objeto que usa a versão (type: uint32_t ), o URI de locatário do atestado (type: unsigned character) e o conteúdo do cliente (type: unsigned character). O conteúdo do cliente é zero ou mais pares chave-valor de algum cliente ou metadados de cliente retornados no conteúdo de resposta. Os pares chave-valor precisam estar no formato de cadeia de caracteres JSON "{\"key1\":\"value1\",\"key2\":\"value2\"}" . Por exemplo, a chave-valor de atualização de atestado pode ser parecida com {\”Nonce\”:\”011510062022\”} . |
buffer |
Token Web JSON que contém informações de atestado. |
A API de atestado retorna um AttestationResult
(type: structure).
API de criptografia
A API de criptografia usa dados para criptografia e um token Web JSON como entrada. A API criptografa os dados usando a chave efêmera pública presente no token Web JSON. Por exemplo:
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);
Parâmetro | Explicação |
---|---|
encryption_type |
Nenhum. |
const unsigned char* jwt_token |
Token Web JSON que contém informações de atestado. |
const unsigned char* data |
Dados a serem criptografados |
uint32_t data_size |
Tamanho dos dados a serem criptografados. |
unsigned char** encrypted_data |
Dados criptografados. |
uint32_t* encrypted_data_size |
Tamanho dos dados criptografados. |
unsigned char** encryption_metadata |
Metadados de criptografia. |
uint32_t encryption_metadata_size |
Tamanho dos metadados de criptografia. |
A API de criptografia retorna um AttestationResult
(type: structure).
API de descriptografia
A API de descriptografia usa dados criptografados como entrada e os descriptografa usando a chave efêmera privada selada para a o TPM (Trusted Platform Module). Por exemplo:
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);
Parâmetro | Explicação |
---|---|
encryption_type |
Nenhum. |
const unsigned char* encrypted_data |
Dados a serem descriptografados. |
uint32_t encrypted_data_size |
Tamanho dos dados a serem descriptografados. |
const unsigned char* encryption_metadata |
Metadados de criptografia. |
unit32_t encryption_metadata_size |
Tamanho dos metadados de criptografia. |
unsigned char** decrypted_data |
Dados descriptografados. |
unit32_t decrypted_data_size |
Tamanho dos dados descriptografados. |
A API de descriptografia retorna um AttestationResult
(type: structure).
API de liberação
A API de liberação recupera memória retida pelos dados. Por exemplo:
Free([in] buffer data);
Parâmetro | Explicação |
---|---|
data |
Recupera memória retida pelos dados. |
A API de liberação não retorna nada.
Códigos do Erro
As APIs podem retornar os seguintes códigos de erro:
Código do erro | Descrição |
---|---|
1 | Erro ao inicializar a falha. |
2 | Erro ao analisar resposta. |
3 | Token Gerenciar identidades para recursos do Azure não encontrado. |
4 | A solicitação excedeu a quantidade de tentativas. |
5 | Falha na solicitação. |
6 | Falha no atestado. |
7 | Falha no envio de solicitação. |
8 | Parâmetro de entrada inválido. |
9 | Falha na validação dos parâmetros de atestado. |
10 | Falha na alocação de memória. |
11 | Falha ao obter informações do SO (sistema operacional). |
12 | Falha interna do TPM. |
13 | Falha na operação do TPM. |
14 | Falha na descriptografia do token Web JSON. |
15 | Erro de TPM de descriptografia do token Web JSON. |
16 | Resposta JSON inválida. |
17 | Certificado VCEK (Chave de Endosso de Chip com Versão Vazia). |
18 | Resposta vazia. |
19 | Corpo da solicitação vazio. |
20 | Falha na análise de relatórios. |
21 | Relatório vazio. |
22 | Erro ao extrair informações do token Web JSON. |
23 | Erro ao converter o token Web JSON em chave pública RSA. |
24 | Falha na inicialização da criptografia de EVP_PKEY. |
25 | Falha na criptografia de EVP_PKEY. |
26 | Erro de TPM de descriptografia de dados. |
27 | Erro ao analisar informações de DNS. |
Token Web JSON
Você pode extrair várias partes do token Web JSON para os diferentes cenários de API descritos anteriormente. Veja abaixo campos importantes para o recurso de atestado de convidado:
Declaração | Atributo | Valor de exemplo |
---|---|---|
- | x-ms-azurevm-vmid |
2DEDC52A-6832-46CE-9910-E8C9980BF5A7 |
Hardware AMD SEV-SNP | x-ms-isolation-tee |
sevsnpvm |
Hardware AMD SEV-SNP | x-ms-compliance-status (em x-ms-isolation-tee ) |
azure-compliant-cvm |
Inicialização Segura | secure-boot (em x-ms-runtime >vm-configuration ) |
true |
TPM Virtual | tpm-enabled (em x-ms-runtime >vm-configuration ) |
true |
TPM Virtual | kid (em 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"
}