기밀 VM에 대한 게스트 증명이란?

게스트 증명을 사용하면 격리 및 무결성을 위해 사용하도록 설정된 보안 기능을 사용하여 기밀 VM 환경이 진정한 하드웨어 지원 TEE(신뢰할 수 있는 실행 환경)에 의해 보호되는지 확인할 수 있습니다.

게스트 증명을 사용하여 다음을 수행할 수 있습니다.

  • 기밀 VM이 올바른 하드웨어 플랫폼에서 실행되는지 확인합니다.
  • 기밀 VM에 보안 부팅이 사용하도록 설정되어 있는지 확인합니다. 이 설정은 VM(펌웨어, 부팅 로더, 커널)의 하위 계층을 맬웨어(루트킷, 부트킷)로부터 보호합니다.
  • 신뢰 당사자에게 기밀 VM이 기밀 하드웨어에서 실행된다는 증거 제공

참고 항목

Intel TDX에서 지원하는 DCesv5 및 ECesv5 VM에 대한 게스트 증명을 수행하려면 방법 가이드를 여기에서 확인하세요. Intel 보안 기관을 사용하려면 Intel에 등록해야 합니다.

시나리오

게스트 증명과 관련된 주요 구성 요소 및 서비스는 다음과 같습니다.

Diagram of guest attestation scenario for a confidential VM.

일반적인 운영 시나리오는 다음과 같이 클라이언트 라이브러리를 통합하여 증명 요청을 수행합니다.

시나리오: 별도의 워크로드에서 요청

이 예제 시나리오에서는 별도의 워크로드에서 증명 요청이 수행됩니다. 이 요청은 워크로드가 시작되기 전에 기밀 VM이 올바른 하드웨어 플랫폼에서 실행되는지 확인합니다.

워크로드(다이어그램에서 플랫폼 검사기 클라이언트)를 증명 라이브러리와 통합하고 기밀 VM 내에서 실행하여 증명을 수행해야 합니다. 프로그램이 증명 라이브러리에 요청을 보내면 중요한 워크로드를 시작하기 전에 워크로드가 응답을 구문 분석하여 VM이 올바른 하드웨어 플랫폼에서 실행되는지 여부 및/또는 보안 부팅 설정을 확인합니다.

Diagram of an attestation request being made in a separate workload.

이 시나리오는 다음 시나리오와 비슷합니다. 주요 차이점은 각 시나리오가 요청 위치에 따라 동일한 목표를 달성하는 방법입니다.

시나리오: 워크로드 내부에서 요청

이 예제 시나리오에서는 프로그램 시작 시 워크로드 내에서 증명 요청이 수행됩니다. 이 요청은 워크로드가 시작되기 전에 기밀 VM이 올바른 하드웨어 플랫폼에서 실행되는지 확인합니다.

이 시나리오는 이전 시나리오와 비슷합니다. 주요 차이점은 각 시나리오가 요청 위치에 따라 동일한 목표를 달성하는 방법입니다.

고객 워크로드는 증명 라이브러리와 통합되고 기밀 VM 내에서 실행되어야 합니다. 고객 워크로드가 증명 라이브러리에 요청을 보내면 중요한 워크로드를 완전히 설정하기 전에 고객 워크로드가 응답을 구문 분석하여 VM이 올바른 하드웨어 플랫폼에서 실행되는지 여부 및/또는 보안 부팅 설정을 확인합니다.

Diagram of an attestation request being made from within a workload inside a confidential VM.

시나리오: 신뢰 당사자 핸드셰이크

이 예제 시나리오에서 기밀 VM은 신뢰 당사자가 참여하기 전에 기밀 플랫폼에서 실행된다는 것을 증명해야 합니다. 기밀 VM은 신뢰 당사자에게 증명 토큰을 제공하여 참여를 시작합니다.

참여의 몇 가지 예는 다음과 같습니다.

  • 기밀 VM이 비밀 관리 서비스의 비밀을 원합니다.
  • 클라이언트가 처리할 개인 데이터를 기밀 VM에 공개하기 전에 기밀 VM이 기밀 플랫폼에서 실행되는지 확인하려고 합니다.

다음 다이어그램은 기밀 VM과 신뢰 당사자 간의 핸드셰이크를 보여 줍니다.

Diagram of an attestation request being made in a relying party scenario.

다음 시퀀스 다이어그램에서는 신뢰 당사자 시나리오에 대해 자세히 설명합니다. 관련 시스템 간의 요청/응답에는 게스트 증명 라이브러리 API가 사용됩니다. 기밀 VM은 수신된 비밀을 통해 비밀 관리자와 상호 작용하여 자체적으로 부트스트랩합니다.

Diagram of the relying party VM with a secrets manager service.

API

Microsoft는 게스트 증명 라이브러리에 증명, 데이터 암호화암호 해독을 모두 수행할 수 있는 API를 제공합니다. 메모리를 회수하는 API도 있습니다.

앞에서 설명한 다양한 시나리오에서 이러한 API를 사용할 수 있습니다.

Attest API

Attest API는 ClientParameters 개체를 입력으로 사용하고 암호 해독된 증명 토큰을 반환합니다. 예시:

AttestationResult Attest([in] ClientParameters client_params,  

  				 [out] buffer jwt_token); 
매개 변수 정보
ClientParameters(형식: 개체) 버전(형식: uint32_t), 증명 테넌트 URI(형식: 부호 없는 문자) 및 클라이언트 페이로드(형식: 부호 없는 문자)를 사용하는 개체입니다. 클라이언트 페이로드는 응답 페이로드에 반환되는 모든 클라이언트 또는 고객 메타데이터에 대한 0개 이상의 키-값 쌍입니다. 키-값 쌍은 JSON 문자열 형식("{\"key1\":\"value1\",\"key2\":\"value2\"}")이어야 합니다. 예를 들어 증명 새로 고침 키 값은 {\”Nonce\”:\”011510062022\”} 와 같을 수 있습니다.
buffer 증명 정보를 포함하는 JSON 웹 토큰입니다.

Attest API는 AttestationResult(형식: 구조)를 반환합니다.

Encrypt API

Encrypt API는 암호화할 데이터 및 JSON 웹 토큰을 입력으로 사용합니다. API는 JSON 웹 토큰에 있는 공용 임시 키를 사용하여 데이터를 암호화합니다. 예시:

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); 
매개 변수 설명
encryption_type 없음.
const unsigned char* jwt_token 증명 정보를 포함하는 JSON 웹 토큰입니다.
const unsigned char* data 암호화할 데이터입니다.
uint32_t data_size 암호화할 데이터의 크기입니다.
unsigned char** encrypted_data 암호화된 데이터입니다.
uint32_t* encrypted_data_size 암호화된 데이터의 크기입니다.
unsigned char** encryption_metadata 암호화 메타데이터입니다.
uint32_t encryption_metadata_size 암호화 메타데이터의 크기입니다.

Encrypt API는 AttestationResult(형식: 구조)를 반환합니다.

Decrypt API

Decrypt API는 암호화된 데이터를 입력으로 사용하고 TPM(신뢰할 수 있는 플랫폼 모듈)에 봉인된 프라이빗 임시 키를 사용하여 데이터의 암호를 해독합니다. 예시:

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); 
매개 변수 설명
encryption_type 없음.
const unsigned char* encrypted_data 암호를 해독할 데이터입니다.
uint32_t encrypted_data_size 암호를 해독할 데이터의 크기입니다.
const unsigned char* encryption_metadata 암호화 메타데이터입니다.
unit32_t encryption_metadata_size 암호화 메타데이터의 크기입니다.
unsigned char** decrypted_data 암호를 해독한 데이터입니다.
unit32_t decrypted_data_size 암호를 해독한 데이터의 크기입니다.

Decrypt API는 AttestationResult(형식: 구조)를 반환합니다.

Free API

Free API는 데이터가 소유한 메모리를 회수합니다. 예시:

Free([in] buffer data); 
매개 변수 설명
data 데이터가 소유한 메모리를 회수합니다.

Free API는 아무것도 반환하지 않습니다.

오류 코드

이 API는 다음 오류 코드를 반환할 수 있습니다.

오류 코드 설명
1 오류 초기화 중 오류가 발생했습니다.
2 응답 구문 분석 중 오류가 발생했습니다.
3 Azure 리소스에 대한 관리 ID 토큰을 찾을 수 없습니다.
4 요청이 재시도 횟수를 초과했습니다.
5 요청이 실패했습니다.
6 증명이 실패했습니다.
7 요청 보내기가 실패했습니다.
8 입력 매개 변수가 잘못되었습니다.
9 증명 매개 변수 유효성 검사가 실패했습니다.
10 메모리 할당이 실패했습니다.
11 OS(운영 체제) 정보를 가져오지 못했습니다.
12 TPM 내부 오류입니다.
13 TPM 작업이 실패했습니다.
14 JSON 웹 토큰 암호 해독이 실패했습니다.
15 JSON 웹 토큰 암호 해독 TPM 오류입니다.
16 JSON 응답이 잘못되었습니다.
17 VCEK(Versioned Chip Endorsement Key) 인증서가 비어 있습니다.
18 응답이 비어 있습니다.
19 요청 본문이 비어 있습니다.
20 보고서 구문 분석 오류입니다.
21 보고서가 비어 있습니다.
22 JSON 웹 토큰 정보를 추출하는 동안 오류가 발생했습니다.
23 JSON 웹 토큰을 RSA 공개 키로 변환하는 동안 오류가 발생했습니다.
24 EVP_PKEY 암호화 초기화가 실패했습니다.
25 EVP_PKEY 암호화가 실패했습니다.
26 데이터 암호 해독 TPM 오류입니다.
27 DNS 정보를 구문 분석하는 동안 오류가 발생했습니다.

JSON Web Token

앞에서 설명한 여러 API 시나리오에서 JSON 웹 토큰의 여러 부분을 추출할 수 있습니다. 게스트 증명 기능에 대한 중요한 필드는 다음과 같습니다.

클레임 Attribute 예제 값
- x-ms-azurevm-vmid 2DEDC52A-6832-46CE-9910-E8C9980BF5A7
AMD SEV-SNP 하드웨어 x-ms-isolation-tee sevsnpvm
AMD SEV-SNP 하드웨어 x-ms-compliance-status(x-ms-isolation-tee 아래) azure-compliant-cvm
보안 부팅 secure-boot(x-ms-runtime>vm-configuration 아래) true
가상 TPM tpm-enabled(x-ms-runtime>vm-configuration 아래) true
가상 TPM kid(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"
}

다음 단계