Compartir a través de


¿Qué es la atestación de invitados para VM confidenciales?

La atestación de invitados le ayuda a confirmar que el entorno de la máquina virtual confidencial está protegido por un entorno de ejecución de confianza (TEE) respaldado por hardware original con características de seguridad habilitadas para aislamiento e integridad.

Puede usar la atestación de invitados para:

  • Asegúrese de que la máquina virtual confidencial se ejecuta en la plataforma de hardware prevista
  • Compruebe que la máquina virtual confidencial tiene habilitado el arranque seguro. Esta configuración protege las capas inferiores de la VM (firmware, cargador de arranque, kernel) del malware (rootkits, bootkits).
  • Obtención de evidencia para un usuario de confianza de que la VM confidencial se ejecuta en hardware confidencial

Nota:

Para realizar la atestación de invitados para las máquinas virtuales DCesv5 y ECesv5 respaldadas por Intel TDX, hay una guía paso a paso disponible aquí. El uso de Intel Trust Authority requiere el registro con Intel.

Escenarios

Los principales componentes y servicios que están implicados en la atestación de invitados son:

  • La carga de trabajo
  • La biblioteca de atestación de invitados
  • El hardware (para informes). Por ejemplo, AMD-SEVSNP.
  • El servicio Microsoft Azure Attestation
  • La respuesta de token web JSON

Diagrama del escenario de atestación de invitados para una VM confidencial.

Los escenarios operativos típicos incorporan la biblioteca cliente para realizar solicitudes de atestación, tal y como se indica a continuación.

Escenario: solicitud en una carga de trabajo independiente

En este escenario de ejemplo, las solicitudes de atestación se realizan en una carga de trabajo independiente. Las solicitudes determinan si la VM confidencial se ejecuta en la plataforma de hardware correcta antes de iniciar una carga de trabajo.

Una carga de trabajo (cliente de comprobador de plataforma en el diagrama) debe integrarse con la biblioteca de atestación y ejecutarse en la VM confidencial para realizar la atestación. Una vez que el programa realiza una solicitud a la biblioteca de atestación, la carga de trabajo analiza la respuesta para determinar si la VM se ejecuta en la plataforma de hardware correcta o en la configuración de arranque seguro antes de iniciar la carga de trabajo confidencial.

Diagrama de una solicitud de atestación que se ha realizado en una carga de trabajo independiente.

Este escenario es similar al siguiente escenario. La principal diferencia está en la manera en que cada escenario logra el mismo objetivo en función de la ubicación de la solicitud.

Escenario: solicitud desde dentro de la carga de trabajo

En este escenario de ejemplo, las solicitudes de atestación se realizan dentro de la carga de trabajo al principio del programa. Las solicitudes comprueban si la VM confidencial se ejecuta en la plataforma de hardware correcta antes de iniciar una carga de trabajo.

Este escenario es similar al escenario anterior. La principal diferencia está en la manera en que cada escenario logra el mismo objetivo en función de la ubicación de la solicitud.

La carga de trabajo del cliente debe integrarse con la biblioteca de atestación y ejecutarse en la VM confidencial. Una vez que la carga de trabajo del cliente realiza una solicitud a la biblioteca de atestación, la carga de trabajo del cliente analiza la respuesta para determinar si la VM se ejecuta en la plataforma de hardware correcta o en la configuración de arranque seguro antes de configurar por completo la carga de trabajo confidencial.

Diagrama de una solicitud de atestación que se ha realizado desde dentro de una carga de trabajo de una VM confidencial.

Escenario: protocolo de enlace de usuario de confianza

En este escenario de ejemplo, la VM confidencial debe demostrar que se ejecuta en una plataforma confidencial antes de que se involucre un usuario de confianza. La VM confidencial presenta un token de atestación al usuario de confianza para iniciar la involucración.

Algunos ejemplos de involucraciones son:

  • La VM confidencial quiere secretos de un servicio de administración de secretos.
  • Un cliente quiere asegurarse de que la VM confidencial se ejecuta en una plataforma confidencial antes de revelar los datos personales a la VM confidencial para su procesamiento.

En el diagrama siguiente se muestra el protocolo de enlace entre una VM confidencial y el usuario de confianza.

Diagrama de una solicitud de atestación que se ha realizado en un escenario de usuario de confianza.

En el siguiente diagrama de secuencia se explica con más detalle el escenario de usuario de confianza. La solicitud o respuesta entre los sistemas que se implican usa las API de la biblioteca de atestación de invitados. La VM confidencial interactúa con el administrador de secretos para arrancarse mediante los secretos que ha recibido.

Diagrama de la VM del usuario de confianza con un servicio de administrador de secretos.

API existentes

Microsoft proporciona la biblioteca de atestación de invitados con las API para realizar atestaciones, así como cifrar y descifrar datos. También existe una API para reclamar memoria.

Puede usar estas API para los distintos escenarios que se han descrito anteriormente.

API de atestación

La API de atestación toma el objeto ClientParameters como entrada y devuelve un token de atestación descifrado. Por ejemplo:

AttestationResult Attest([in] ClientParameters client_params,  

  				 [out] buffer jwt_token); 
Parámetro Información
ClientParameters (tipo: objeto) Objeto que toma la versión (tipo: uint32_t), el URI del inquilino de atestación (tipo: carácter sin signo) y la carga del cliente (tipo: carácter sin signo). La carga del cliente es cero o más pares clave-valor para cualquier cliente o metadatos de cliente que se devuelvan en la carga de respuesta. Los pares clave-valor deben tener el formato "{\"key1\":\"value1\",\"key2\":\"value2\"}" de cadena JSON. Por ejemplo, el valor de clave de actualización de atestación puede ser similar a {\”Nonce\”:\”011510062022\”} .
buffer Token web JSON que contiene información de atestación.

La API de atestación devuelve un AttestationResult (tipo: estructura).

API de cifrado

La API de cifrado API toma los datos que se van a cifran y un token web JSON como entrada. La API cifra los datos mediante la clave efímera pública que está presente en el token web JSON. Por ejemplo:

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 Explicación
encryption_type Ninguno.
const unsigned char* jwt_token Token web JSON que contiene información de atestación.
const unsigned char* data Datos que se van a cifrar
uint32_t data_size Tamaño de los datos que se van a cifrar.
unsigned char** encrypted_data Datos cifrados.
uint32_t* encrypted_data_size Tamaño de los datos cifrados.
unsigned char** encryption_metadata Metadatos de cifrado.
uint32_t encryption_metadata_size Tamaño de los metadatos de cifrado.

La API de cifrado devuelve un AttestationResult (tipo: estructura).

API de descifrado

La API de descifrado toma datos cifrados como entrada y descifra los datos mediante la clave efímera privada que está sellada en el módulo de plataforma segura (TPM). Por ejemplo:

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 Explicación
encryption_type Ninguno.
const unsigned char* encrypted_data Datos que se van a descifrar.
uint32_t encrypted_data_size Tamaño de los datos que se van a descifrar.
const unsigned char* encryption_metadata Metadatos de cifrado.
unit32_t encryption_metadata_size Tamaño de los metadatos de cifrado.
unsigned char** decrypted_data Datos descifrados.
unit32_t decrypted_data_size Tamaño de los datos descifrados.

La API de descifrado devuelve un AttestationResult (tipo: estructura).

API gratuita

La API gratuita recupera la memoria que mantienen los datos. Por ejemplo:

Free([in] buffer data); 
Parámetro Explicación
data Recuperar la memoria que mantienen los datos.

La API gratuita no devuelve nada.

Códigos de error

Las API pueden devolver los siguientes códigos de error:

Código de error Descripción
1 Error al inicializar el error.
2 Respuesta de análisis de errores.
3 No se encontraron las identidades administradas para el token de recursos de Azure.
4 La solicitud superó los reintentos.
5 Error en la solicitud.
6 Error de atestación.
7 Error en el envío de la solicitud.
8 El parámetro de entrada no es válido.
9 Error de validación de parámetros de atestación.
10 Se produjo un error de asignación de memoria.
11 No se pudo obtener información del sistema operativo (SO).
12 Error interno de TPM.
13 Error en la operación de TPM.
14 Error en el descifrado del token web JSON.
15 Error de TPM de descifrado de token web JSON.
16 Respuesta JSON no válida.
17 Certificado vacío de clave de aprobación de chip con versión (VCEK).
18 Respuesta vacía.
19 Cuerpo de la solicitud vacío.
20 Error de análisis del informe.
21 Informe vacío.
22 Error al extraer información del token web JSON.
23 Error al convertir el token web JSON en clave pública RSA.
24 Error de inicialización del cifrado EVP_PKEY.
25 Error de cifrado EVP_PKEY.
26 Error de TPM de descifrado de datos.
27 Error al analizar la información de DNS.

Token web JSON

Puede extraer diferentes elementos del token web JSON para los distintos escenarios de API que se han descrito anteriormente. Los siguientes campos son importantes para la característica de atestación de invitados:

Notificación Attribute Valor de ejemplo
- 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 (en x-ms-isolation-tee) azure-compliant-cvm
Arranque seguro secure-boot (en x-ms-runtime>vm-configuration) true
TPM virtual tpm-enabled (en x-ms-runtime>vm-configuration) true
TPM virtual kid (en 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"
}

Pasos siguientes