機密 VM のゲスト構成証明とは?
ゲスト構成証明は、機密 VM 環境が、ハードウェアによってサポートされる本物の高信頼実行環境 (TEE) によって、分離と整合性のためのセキュリティ機能が有効な状態でセキュリティ保護されていることを確認するのに役立ちます。
ゲスト構成証明を使用すると、次のことができます:
- 機密 VM が想定されるハードウェア プラットフォーム上で実行されていることを確認する
- 機密 VM でセキュア ブートが有効になっていることを確認します。 この設定により、VM の下位レイヤー (ファームウェア、ブート ローダー、カーネル) がマルウェア (ルートキット、ブートキット) から保護されます。
- 機密 VM が機密ハードウェアで実行されている証明書利用者の証拠を取得する
Note
Intel TDX によってサポートされる DCesv5 および ECesv5 VM のゲスト構成証明を実行するための攻略ガイドはこちらから入手できます。 Intel Trust Authority を使用するには、Intel への登録が必要です。
シナリオ
ゲスト構成証明に関連する主要なコンポーネントとサービスは次のとおりです:
- ワークロード
- ゲスト構成証明ライブラリ
- ハードウェア (レポート用)。 たとえば、AMD-SEVSNP です。
- Microsoft Azure Attestation サービス
- JSON Web トークンの応答
一般的な運用シナリオでは、次のように構成証明要求を行うためにクライアント ライブラリが組み込まれています。
シナリオ: 別のワークロードでの要求
このシナリオ例では、構成証明要求は別のワークロードで行われます。 要求は、ワークロードが起動される前に、機密 VM が正しいハードウェア プラットフォームで実行されているかどうかを判断します。
構成証明を行うには、ワークロード (図のプラットフォーム チェッカー クライアント ) を構成証明ライブラリと統合し、機密 VM 内で実行する必要があります。 プログラムが構成証明ライブラリに要求を行った後、ワークロードは応答を解析して、機密性の高いワークロードを起動する前に、VM が正しいハードウェア プラットフォームまたはセキュア ブート設定で実行されているかどうかを判断します。
このシナリオは、以下のシナリオに似ています。 主な違いは、各シナリオが要求の場所に基づいて同じゴールを達成する方法です。
シナリオ: ワークロード内からの要求
このシナリオ例では、構成証明要求は、プログラムの開始時にワークロード内で行われます。 要求は、ワークロードが起動される前に、機密 VM が正しいハードウェア プラットフォームで実行されているかどうかを確認します。
このシナリオは、前のシナリオに似ています。 主な違いは、各シナリオが要求の場所に基づいて同じゴールを達成する方法です。
顧客ワークロードは構成証明ライブラリと統合し、機密 VM 内で実行する必要があります。 顧客のワークロードが構成証明ライブラリに要求を行った後、顧客のワークロードは応答を解析して、機密性の高いワークロードを完全に設定する前に、VM が正しいハードウェア プラットフォームまたはセキュア ブート設定で実行されているかどうかを判断します。
シナリオ: 証明書利用者ハンドシェイク
この例のシナリオでは、証明書利用者が関与する前に、機密 VM が機密プラットフォーム上で実行されていることを証明する必要があります。 機密 VM は、契約を開始するために証明書利用者に構成証明トークンを提示します。
エンゲージメントの例を次に示します:
- 機密 VM は、シークレット管理サービスからのシークレットを必要とします。
- クライアントは、機密 VM が機密プラットフォーム上で実行されていることを確認してから、個人データを機密 VM に公開して処理したいと考えています。
次の図は、機密 VM と証明書利用者の間のハンドシェイクを示しています。
次のシーケンス図では、証明書利用者のシナリオについてさらに説明します。 関連するシステム間の要求/応答では、ゲスト構成証明ライブラリ API が使用されます。 機密 VM はシークレット マネージャーと対話し、受信したシークレットを使用して自身をブートストラップします。
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 Web トークン。 |
Attest API は AttestationResult
(型: 構造体) を返します。
API の暗号化
Encrypt API は、暗号化されるデータと JSON Web トークンを入力として受け取ります。 API は、JSON Web トークンに存在する公開エフェメラル キーを使用してデータを暗号化します。 次に例を示します。
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 Web トークン。 |
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
(型: 構造体) を返します。
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 Web トークンの暗号化解除に失敗しました。 |
15 | JSON Web トークン暗号化解除 TPM エラー。 |
16 | 無効な JSON 応答です。 |
17 | 空のバージョン管理されたチップ保証キー (VCEK) 証明書。 |
18 | 空の応答。 |
19 | 空の要求本文。 |
20 | 解析失敗を報告します。 |
21 | 空のレポート。 |
22 | JSON Web トークン情報の抽出中にエラーが発生しました。 |
23 | JSON Web トークンを RSA 公開キーに変換中にエラーが発生しました。 |
24 | EVP_PKEY 暗号化の初期化に失敗しました。 |
25 | EVP_PKEY 暗号化に失敗しました。 |
26 | データ暗号化解除 TPM エラー。 |
27 | DNS 情報の解析中にエラーが発生しました。 |
JSON Web トークン
前に説明したさまざまな API シナリオ で、JSON Web トークンのさまざまな部分を抽出できます。 ゲスト構成証明フィーチャーの重要なフィールドを次に示します:
要求 | 属性 | 例値 |
---|---|---|
- | 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"
}