O que é o atestado de convidado para VMs confidenciais?
O atestado de convidado ajuda você a confirmar que seu ambiente de VM confidencial está protegido por um TEE (Trusted Execution Environment) genuíno apoiado por hardware com recursos de segurança habilitados para isolamento e integridade.
Você pode usar o atestado de convidado para:
- Certifique-se de que a VM confidencial é executada na plataforma de hardware esperada
- Verifique se a VM confidencial tem a inicialização segura habilitada. Esta configuração protege as camadas inferiores da VM (firmware, carregador de inicialização, kernel) contra malware (rootkits, bootkits).
- Obter evidências para uma terceira parte confiável de que a VM confidencial é executada em hardware confidencial
Nota
Para executar o atestado de convidado para VMs DCesv5 e ECesv5 apoiadas pelo Intel TDX, um guia de instruções está disponível aqui. O uso da Intel Trust Authority requer registro na Intel.
Cenários
Os principais componentes e serviços envolvidos no certificado de hóspedes são:
- A carga de trabalho
- A biblioteca de certificados de convidados
- Hardware (para relatórios). Por exemplo, AMD-SEVSNP.
- O serviço de Atestado do Microsoft Azure
- Resposta do token da Web JSON
Os cenários operacionais típicos incorporam a biblioteca do cliente para fazer solicitações de atestado da seguinte 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 que uma carga de trabalho seja iniciada.
Uma carga de trabalho (cliente verificador de plataforma no diagrama) deve se integrar à biblioteca de atestados e ser executada dentro da VM confidencial para fazer o atestado. Depois que o programa faz uma solicitação à biblioteca de atestados, 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.
Este cenário é semelhante ao seguinte. A principal diferença é como cada cenário atinge o mesmo objetivo com base na localização da solicitação.
Cenário: solicitação de 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 que uma carga de trabalho seja iniciada.
Este cenário é semelhante ao cenário anterior. A principal diferença é como cada cenário atinge o mesmo objetivo com base na localização da solicitação.
A carga de trabalho do cliente deve integrar-se à biblioteca de atestados e ser executada dentro da VM confidencial. Depois que a carga de trabalho do cliente faz uma solicitação à biblioteca de atestados, 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 totalmente a carga de trabalho confidencial.
Cenário: handshake de terceira parte confiável
Neste cenário de exemplo, a VM confidencial deve provar que é executada em uma plataforma confidencial antes que uma terceira parte confiável seja envolvida. A VM confidencial apresenta um token de atestado à terceira parte confiável para iniciar o contrato.
Alguns exemplos de compromissos são:
- A VM confidencial quer segredos de um serviço de gerenciamento secreto.
- Um cliente deseja certificar-se de que a VM confidencial é executada em uma plataforma confidencial antes de revelar dados pessoais à VM confidencial para processamento.
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 melhor o cenário da terceira parte confiável. A solicitação/resposta entre os sistemas envolvidos usa as APIs da biblioteca de atestado convidado. A VM confidencial interage com o gerenciador de segredos para inicializar a si mesma usando os segredos recebidos.
APIs
A Microsoft fornece à biblioteca de atestados de convidado APIs para executar atestados e criptografar e descriptografar dados. Há também uma API para recuperar memória.
Você pode usar essas APIs para os diferentes cenários descritos anteriormente.
Atestar API
A API Attest usa o ClientParameters
objeto como entrada e retorna um token de atestado descriptografado. Por exemplo:
AttestationResult Attest([in] ClientParameters client_params,
[out] buffer jwt_token);
Parâmetro | Informação |
---|---|
ClientParameters (tipo: objeto) |
Objeto que usa a versão (tipo: uint32_t ), URI do locatário de atestado (tipo: caractere não assinado) e carga útil do cliente (tipo: caractere não assinado). A carga útil do cliente é zero ou mais pares chave-valor para qualquer cliente ou metadados do cliente que são retornados na carga útil de resposta. Os pares chave-valor devem estar no formato "{\"key1\":\"value1\",\"key2\":\"value2\"}" de cadeia de caracteres JSON. Por exemplo, o valor-chave de atualização do atestado pode se parecer com {\”Nonce\”:\”011510062022\”} . |
buffer |
Token da Web JSON que contém informações de atestado. |
A API Attest retorna um AttestationResult
(type: structure).
Criptografar API
A API Encrypt usa dados para serem criptografados e um token da Web JSON como entrada. A API criptografa os dados usando a chave efêmera pública que está presente no token da 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 da Web JSON que contém informações de atestado. |
const unsigned char* data |
Dados a encriptar |
uint32_t data_size |
Tamanho dos dados a serem criptografados. |
unsigned char** encrypted_data |
Dados encriptados. |
uint32_t* encrypted_data_size |
Tamanho dos dados encriptados. |
unsigned char** encryption_metadata |
Metadados de encriptação. |
uint32_t encryption_metadata_size |
Tamanho dos metadados de criptografia. |
A API Encrypt retorna um AttestationResult
(type: structure).
API de desencriptação
A API de descriptografia usa dados criptografados como entrada e descriptografa os dados usando a chave efêmera privada que é selada para o Trusted Platform Module (TPM). 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 desencriptar. |
uint32_t encrypted_data_size |
Tamanho dos dados a serem desencriptados. |
const unsigned char* encryption_metadata |
Metadados de encriptação. |
unit32_t encryption_metadata_size |
Tamanho dos metadados de criptografia. |
unsigned char** decrypted_data |
Dados desencriptados. |
unit32_t decrypted_data_size |
Tamanho dos dados desencriptados. |
A API de desencriptação devolve um AttestationResult
(tipo: estrutura).
API gratuita
A API Livre recupera a memória que é mantida pelos dados. Por exemplo:
Free([in] buffer data);
Parâmetro | Explicação |
---|---|
data |
Recupere a memória mantida pelos dados. |
A API gratuita não retorna nada.
Códigos de erro
As APIs podem retornar os seguintes códigos de erro:
Código de erro | Description |
---|---|
5 | Erro ao inicializar falha. |
2 | Erro ao analisar a resposta. |
3 | Identidades gerenciadas para token de recursos do Azure não encontradas. |
4 | Tentativas de solicitação excedidas. |
5 | Falha na solicitação. |
6 | O atestado falhou. |
7 | Falha no envio da 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 sistema operacional (SO). |
12 | Falha interna do TPM. |
13 | Falha na operação do TPM. |
14 | Falha na descriptografia do token da Web JSON. |
15 | Erro TPM de desencriptação de token web JSON. |
16 | Resposta JSON inválida. |
17 | Certificado VCEK (Versioned Chip Endorsement Key) vazio. |
18 | Resposta vazia. |
19 | Corpo de solicitação vazio. |
20 | Relatar falha na análise. |
21 | Relatório vazio. |
22 | Erro ao extrair informações de token da Web JSON. |
23 | Erro ao converter token da Web JSON em chave pública RSA. |
24 | EVP_PKEY inicialização da criptografia falhou. |
25 | EVP_PKEY falha na encriptação. |
26 | Erro TPM de desencriptação de dados. |
27 | Erro ao analisar informações de DNS. |
Token da Web JSON
Você pode extrair diferentes partes do token da Web JSON para os diferentes cenários de API descritos anteriormente. A seguir estão campos importantes para o recurso de atestado de convidado:
Afirmaçã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 |
Arranque seguro | secure-boot (em x-ms-runtime >vm-configuration ) |
true |
Virtual TPM | tpm-enabled (em x-ms-runtime >vm-configuration ) |
true |
Virtual TPM | 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"
}