Partilhar via


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:

Diagrama do cenário de atestado de convidado para uma VM confidencial.

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.

Diagrama de uma solicitação de atestado sendo feita em uma carga de trabalho separada.

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.

Diagrama de uma solicitação de atestado sendo feita de dentro de uma carga de trabalho dentro de uma VM 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.

Diagrama de uma solicitação de atestado que está sendo feita em um cenário de 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.

Diagrama da VM da terceira parte confiável com um serviço de gerenciador de segredos.

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"
}

Próximos passos