リモート認証の概要

リモート認証は、Confidential VM インスタンスの ID が正当であり、想定どおりの状態で動作していることを確認するプロセスです。構成証明は、保護されたリソースへのアクセス権を付与する前に、システムの信頼性を評価するのに役立ちます。

構成証明の当事者とモデル

通常、構成証明プロセスには次の 3 つの当事者が存在します。

  • 証明者。On Google Cloudは、保護されたリソースへのアクセスを必要とする Confidential VM インスタンス上のワークロードです。Confidential VM インスタンスが不正使用されておらず、偽装されていないという信頼性を高めるため、VM とそのホストはブートプロセス中に VM の仮想ハードウェアとソフトウェアの状態を測定します。

  • 検証ツール。検証ツールは、Confidential VM インスタンスからの証拠を検証し、証明書ポリシーと照合して、VM 構成が想定どおりであることを確認する外部システムです。証拠が必須のチェックに合格すると、検証ツールは、構成証明結果と呼ばれる証拠の署名付きバージョンを返します。

    検証ツールは、Google Cloud AttestationIntel Trust Authority などの既存のサービスにすることも、自分で構築することもできます。

  • 証明書利用者。証明書発行者は、証明書発行者が必要とする保護されたリソースへのアクセスを制御します。証明書の結果を受け取ると、証明書利用者(RP)は証拠の値をアクセス ポリシーと照合します。値が一致すると、証明書発行者はリソースへのアクセスを許可されます。

    On Google Cloud では、通常、証明書利用者は Workload Identity プールであり、検証ツールは OpenID Connect(OIDC)プロバイダとして追加されます。

当事者間のやり取りは、アーキテクチャが準拠する構成証明モデルによって異なります。Remote ATtestation procedureS(RATS)アーキテクチャ RFC では、パスポート モデルと身元確認モデルという 2 つの主要な構成証明モデルを定義しています。この 2 つの主な違いは、証明者の検証済み ID を所有しているのが証明者か、証明書利用者かという点です。

Passport モデル

パスポート モデルは、次のプロセスを使用して、証明書の ID を確認し、リクエストされたリソースへのアクセスを許可します。

  1. 証明者は、自身の ID の証拠を検証者に送信します。

  2. 証拠が信頼できると判断された場合、検証ツールは証明書発行者に証明書の結果を送信します。これは、証明書トークンの形式で送信されることがあります。

  3. 証明者は証明結果を証明書利用者(RP)に送信します。

  4. 証明書利用者側で、構成証明の結果が特定の条件を満たしていることを確認します。結果が期待どおりであれば、証明書発行者はリクエストされたリソースへのアクセスを許可します。

パスポート モデルでは、証明者と信頼当事者は、証明結果がどのようなものになるかについて合意する必要があります。つまり、検証者について合意する必要があります。

証明書パスポート モデル

バックグラウンド チェックモデル

バックグラウンド チェックモデルは、次のプロセスを使用して、証明者の身元を確認し、リクエストされたリソースへのアクセス権を付与します。

  1. 証明者は、自身の ID の証拠を証明書利用者(RP)に送信します。

  2. 証明書利用者は証拠を検証者に転送します。

  3. 証拠が信頼できると判断された場合、検証ツールは証明書の結果を証明書トークンとして利用者に送信します。

  4. 証明書利用者側で、構成証明の結果が特定の条件を満たしていることを確認します。結果が期待どおりであれば、証明書発行者はリクエストされたリソースへのアクセスを許可します。

証明書のバックグラウンド チェック モデル

バックグラウンド チェックモデルでは、証明書発行者は必要な構成証明証拠を決定し、検証者を選択します。

証明者のアーキテクチャと証拠

このセクションでは、証明書発行者としての Confidential VM インスタンスが、改ざん防止された ID の証拠を提供する仕組みについて説明します。

ルート オブ トラスト

Confidential VM インスタンスなどの高信頼実行環境(TEE)では、信頼のルートは、他の信頼が確立される基盤となるセキュリティ コンポーネントです。ルート オブ トラストは、暗号機能を提供し、改ざん防止機能があり、ホスト オペレーティング システムによって変更できません。

ルート オブ トラストは、トラステッド コンピューティング ベース(TCB)と呼ばれる TEE 内の信頼境界内にあります。TCB は、ゲスト VM とそのホストにまたがるハードウェアとソフトウェアの集合体であり、環境の分離(メモリ暗号化やハイパーバイザ分離などのメカニズムによる)や、環境の完全性を維持するための測定などの役割を担います。

TEE は、測定、ストレージ、レポート機能の信頼のルートをサポートします。

  • 測定用のルート オブ トラストは、TEE ブート プロセスの測定を開始するコードです。

  • ストレージのルート オブ トラストは、測定レジスタの形式で測定用のシールド メモリを提供します。

  • レポート用のルート オブ トラストは、測定チェーンの完全性と信頼性を保護します。信頼のルートから測定値を取得して、引用または構成証明レポートと呼ばれる署名付きの証拠パッケージにバンドルします。このパッケージは TEE 常駐の認証鍵で署名され、証拠の鮮度を確保し、リプレイ攻撃から保護するための暗号ノンスを含めることができます。

次の情報は、さまざまな Confidential Computing テクノロジーの信頼のルートに対するさまざまなアプローチについて詳しく説明しています。

AMD SEV

AMD SEV を使用する Confidential VM インスタンスは、Shielded VM vTPM ベースの測定を使用して、環境と構成を証明します。AMD Secure Processor と AMD SEV は、メモリの暗号化にのみ使用されます。

ルート オブ トラストは次のとおりです。

  • 測定用のルート オブ トラスト: VM インスタンスのファームウェア

  • ストレージのルート オブ トラスト: Shielded VM vTPM

  • レポートの信頼のルート: Shielded VM vTPM。非公開の構成証明鍵を使用して構成証明レポートに署名します。

SEV ルート オブ トラスト

Shielded VM vTPM のどこにどのような測定値が記録されるかについては、vTPM プラットフォーム構成レジスタをご覧ください。

AMD SEV-SNP

AMD SEV-SNP を使用する Confidential VM インスタンスは、主に AMD Secure Processor を介して環境と構成を証明します。AMD Secure Processor は、初期起動測定を処理します。

ブートローダー、カーネル、ユーザー空間の測定には、Shielded VM vTPM ベースの測定を使用できます。

ルート オブ トラストは次のとおりです。

  • 測定用のルート オブ トラスト: AMD Secure Processor + VM インスタンス ファームウェア

  • ストレージのルート オブ トラスト: AMD Secure Processor + Shielded VM vTPM

  • レポートのルート オブ トラスト:

    • 初期起動の測定: チップ常駐の Version Chip Endorsement Key(VCEK)を使用して構成証明レポートに署名する AMD Secure Processor

    • ブートローダー、カーネル、ユーザー空間の測定: Shielded VM vTPM

SNP ルート オブ トラスト

AMD Secure Processor に記録される測定値については、AMD SEV-SNP 測定レジスタをご覧ください。

Shielded VM vTPM のどこにどのような測定値が記録されるかについては、vTPM プラットフォーム構成レジスタをご覧ください。

Intel TDX

インテル TDX を搭載した Confidential VM インスタンスは、インテル TDX モジュールを介して環境と構成を証明します。インテル TDX モジュールは、分離された信頼ドメイン内で VM ゲストのファームウェアを測定し、その測定値を Measurement of the Trust Domain(MRTD)に保存します。ブートチェーンの後続の測定は、ランタイム測定レジスタ(RTMR)に測定されます。

ルート オブ トラストは次のとおりです。

  • 測定用のルート オブ トラスト: Intel TDX モジュール

  • ストレージのルート オブ トラスト: 信頼ドメインの測定(MRTD)とランタイム測定レジスタ(RTMR)

  • レポートの信頼のルート: インテル TDX モジュール内の Trust Domain Quoting Enclave(TDQE)。認証引用符に署名するための認証鍵を生成します。

TDX ルート オブ トラスト

TDX 測定レジスタのどこにどのような測定値が記録されるかについては、インテル TDX 測定レジスタをご覧ください。

ソフトウェアとハードウェアの証明書

Google Cloud の Confidential Computing テクノロジーは、ルート オブ トラストに応じて、ソフトウェアまたはハードウェアのいずれかとして証明できます。

ソフトウェア認証済みとは、信頼のルートがソフトウェアに基づいていることを意味します。仮想ファームウェアは測定の信頼のルートであり、ストレージの信頼のルートは Shielded VM vTPM です。vTPM はホストのハイパーバイザによって管理され、ファームウェアはゲスト VM によって管理されます。On Google Cloudでは、これらのコンポーネントは両方とも Google によって制御されます。

ハードウェア証明とは、測定がサービス プロバイダの制御外の専用ハードウェアによって管理および保護されることを意味します。オン Google Cloudの場合、このハードウェアには、AMD SEV-SNP 用の AMD Secure Processor(起動測定専用)と、インテル TDX 用のインテル TDX モジュールが含まれます。

ハードウェア構成証明により、測定とストレージの信頼のルートからサービス プロバイダのハイパーバイザが削除され、測定が専用ハードウェアで分離されます。悪意のある行為者がホストのハイパーバイザを制御できたとしても、専用ハードウェアのレジスタを変更する権限がないため、構成証明レポートや引用を偽造することはできません。

Google Cloud が提供する Confidential Computing テクノロジーは、次のように分類されます。

  • AMD SEV: ソフトウェアが証明されます。仮想ファームウェアは自身を測定し、測定値は Shielded VM vTPM に保存されます。

  • AMD SEV-SNP: ハイブリッド ハードウェアとソフトウェアが証明されます。仮想ファームウェアの測定を含む起動測定は、AMD Secure Processor によって記録され、保存されるため、ハードウェアで証明されます。ブートローダー、カーネル、ユーザー空間の測定値は Shielded VM vTPM に保存され、ソフトウェアで構成証明されます。ハードウェア証明測定値のみ、ソフトウェア証明測定値のみ、または両方を使用するように選択できます。

  • Intel TDX: ハードウェアが証明されます。TDX モジュールは仮想ファームウェアを測定し、すべての測定値は Intel TDX モジュールに保存されます。Shielded VM vTPM はシステムの一部ですが、TPM インターフェースを必要とするソフトウェアを実行しない限り、TCB の一部ではありません。

測定レジスタ

Confidential VM のルート オブ トラストは、測定レジスタ(MR)の形式で、測定用のシールドされた改ざん防止ストレージを提供します。これらの測定レジスタの名前は、使用中の Confidential Computing テクノロジーによって異なります。

  • AMD SEV: プラットフォーム構成レジスタ(PCR)。これらは Shielded VM vTPM 内にあります。

    シールドされた VM の vTPM は、同じ測定値を保存する 3 つの PCR バンクを使用しますが、SHA-1、SHA-256、SHA-384 という異なるアルゴリズムでハッシュ化されます。

  • AMD SEV-SNP: 起動 MEASUREMENT レジスタ。これは AMD Secure Processor の内部にあります。

    Shielded VM vTPM 内の PCR は、ブートローダー、カーネル、ユーザー空間の測定値を保存するためにも使用されます。

  • インテル TDX: ビルド時の Trust Domain の測定(MRTD)とランタイム測定レジスタ(RTMR)。

    測定は、TPM インターフェースを必要とするソフトウェアの Shielded VM vTPM PCR でも利用できます。

レジスタ値を変更できるのは信頼のルートのみです。測定レジスタは通常、単一の暗号化ダイジェストを保持します。これは、単一のイベントまたは一連のイベントを表します。

VM の起動測定やビルド時の測定などの単一イベントの場合、通常、信頼のルートはレジスタに直接書き込み、TEE の残りのライフタイムの間、レジスタを不変にします。

ブートローダー、カーネル、ユーザースペースなど、ブートチェーンで後から読み込まれるコンポーネントは、複数のイベントの測定値を 1 つのレジスタに記録する場合があります。イベントのセットの測定値を保存するために、測定レジスタは、既存のレジスタ値と新しいイベント ダイジェストを連結し、連結された値をハッシュ化して、結果のダイジェストを保存する extend コマンドを公開します。このプロセスは次の式で表されます。

\(MR_{new}=hash(MR_{old}\;∥\;hash(measured\;data))\)

ハッシュ関数は一方向であるため、同じ測定値を同じ順序で提供せずに同じ測定レジスタ値を複製することは困難です。このプロパティは VM の完全性を判断するのに役立ちますが、特定の測定レジスタ値に基づいてポリシーを作成することが難しくなる可能性があります。これは、ソフトウェアやファームウェアの更新、測定順序の変更など、測定入力のわずかな変更によってレジスタ値が異なるため、ポリシーの基準として不安定になる可能性があり、メンテナンスの負担が増加するためです。測定レジスタの値に基づいてポリシーを設定する必要がある場合は、vTPM の PCR 0 または PCR 7 など、より安定したレジスタ値を選択してください。

イベントログ

測定値が測定レジスタに書き込まれるか、拡張されると、1 つ以上のログがゲスト オペレーティング システムのファイル システムに書き込まれ、発生した測定イベントが記録されます。

これらのイベントログは次の目的で使用されます。

  • 検証ツールは、イベントログを再生して、シミュレートされた測定レジスタを使用して Confidential VM インスタンスの測定プロセスをステップ実行できます。検証ツールによって計算された最終ダイジェストが、証明書発行者によって報告された最終ダイジェストと一致する場合、イベントログと Confidential VM インスタンスのブートプロセスが改ざんされていないという信頼性が高まります。

  • 再生後、検証ツールはイベントログを解析して、証拠と構成証明ポリシーを比較できます。検証ツールは、安全なブートが有効になっている、特定の Confidential Computing テクノロジーを使用しているなどの特定の条件を証明ツールが満たしていることを、証明結果が返される前に要求する場合があります。

イベントログは、ゲスト オペレーティング システムのファイル システムの次の場所に保存されます。

Confidential Computing テクノロジー 確認する MR ログタイプ イベントログの再生用のゲスト OS パス
AMD SEV、AMD SEV-SNP、インテル TDX vTPM プラットフォーム構成レジスタ(PCR) Trusted Computing Group(TCG)イベントログ /sys/kernel/security/tpm0/binary_bios_measurements
インテル TDX RTMR[0]RTMR[1]RTMR[2] Confidential Computing Event Log(CCEL) /sys/firmware/acpi/tables/data/CCEL

詳しくは、イベントログの再生と解析をご覧ください。

引用と構成証明レポート

レポートの信頼のルートは、測定値を構成証明鍵で署名することで、測定レジスタに保存されているダイジェストの完全性と真正性を保護します。結果として得られるバイナリ BLOB は、vTPM の場合は PCR 引用、AMD SEV-SNP の場合は認証レポート、Intel TDX の場合は引用と呼ばれます。

バイナリ BLOB の内容は、Confidential Computing のテクノロジーによって異なります。

  • AMD SEV: Shielded VM vTPM は、PCR バンク(SHA-1、SHA-256、SHA-384 のいずれか)から値を読み取り、それらの値を数値順に連結し、PCR バンクで使用されているのと同じハッシュ アルゴリズムで結果をハッシュして、概要ダイジェストを作成します。この概要ダイジェストは、検証ツールが提供するオプションのノンスとともに TPMS_ATTEST 構造に配置され、vTPM のプライベート認証鍵によって署名されて PCR 引用が作成されます。

    TPMS_ATTEST 構造の詳細については、トラステッド プラットフォーム モジュール ライブラリ パート 2: 構造(PDF)をご覧ください。

  • AMD SEV-SNP: AMD Secure Processor は、Confidential VM インスタンスの UEFI が実行される前に取得された初期の起動測定に基づいて、SHA-384 ダイジェストを生成します。

    このダイジェスト、他の VM データ、検証ツールによって提供されるオプションのノンスは ATTESTATION_REPORT 構造に配置され、AMD Secure Processor の Version Chip Endorsement Key(VCEK)によって署名されて、構成証明レポートが作成されます。

    ATTESTATION_REPORT 構造の詳細については、SEV Secure Nested Paging ファームウェア ABI 仕様(PDF)をご覧ください。

  • インテル TDX: TDX モジュールは、MRTD 値と RTMR 値、他の VM データ、検証ツールによって提供されるオプションのノンスを TDREPORT_STRUCT 構造に配置します。

    見積もりを作成する手順は次のとおりです。まず、CPU 内のプロビジョニング認証エンクレーブが、CPU に融合された暗号シークレットからプロビジョニング認証鍵(PCK)を導出します。次に、CPU 内の Quoting Enclave が秘密の証明書鍵を生成し、プロビジョニング証明書鍵で署名します。次に、TDREPORT_STRUCT は秘密証明書鍵で署名され、引用が作成されます。

    TDREPORT_STRUCT 構造の詳細については、Intel Trust Domain Extensions(インテル TDX)モジュール ベース アーキテクチャ仕様(PDF)をご覧ください。

おすすめ情報

さまざまなタイプの署名が、Confidential VM インスタンスが想定どおりのハードウェア、vTPM、ファームウェア構成で実行されていることを証明する証拠として使用されます。

証明書

X.509 v3 証明書は、ホストで本物の AMD または Intel ハードウェアが使用されていること、または Confidential VM インスタンスが Shielded VM vTPM を使用していることの証拠として使用されます。

証明書の名前は、Confidential Computing テクノロジーごとに異なります。

  • AMD SEV: 構成証明鍵(AK)証明書

  • AMD SEV-SNP: バージョン チップ エンドースメント キー(VCEK)証明書

  • Intel TDX: プロビジョニング認証鍵(PCK)証明書

AMD SEV の場合、証明書は Shielded VM vTPM を検証します。ホストが Google の認証局サーバーにリクエストを送信し、証明書を Confidential VM インスタンスの vTPM 不揮発性ストレージに直接自動プロビジョニングします。ゲストは、go-tpm-tools などのソフトウェアを使用して vTPM からリクエストすることで、この証明書を個別に取得できます。

AMD SEV-SNP と Intel TDX の場合、ホストは CPU からハードウェア証拠を抽出し、Google マネージド キャッシュに提示します。このキャッシュには、以前に AMD 鍵配布サービスと Intel プロビジョニング証明書サービスから取得した証明書が保存されます。ハードウェア証明書の提示に成功すると、証明書はホストのディスクにキャッシュ保存され、ゲストと共有されます。ゲストはこれらの証明書を個別に取得して、go-sev-guestgo-tdx-guest などのソフトウェアでハードウェアを検証できます。

証明書には次の情報が含まれています。

  • 証明書発行者の ID(AMD、Google、Intel のいずれか)。

  • PCR 引用(vTPM)、構成証明レポート(SEV-SNP)、構成証明引用(Intel TDX)の署名を検証する公開構成証明鍵。

  • ハードウェア構成証明のみ: ホストのファームウェアが実行されているハードウェア マイクロコードとファームウェアの TCB バージョン。

  • ハードウェア構成証明のみ: 証明書を特定の物理プロセッサにバインドする証拠。プロセッサの秘密鍵で署名されており、抽出できません。AMD SEV-SNP の場合、この証拠はプラットフォーム ID です。Intel TDX の場合、証拠はプラットフォーム マニフェストです。

ファームウェア

ハードウェア構成証明の場合、ファームウェアの起動保証は VM インスタンスから直接取得するか、オンラインでダウンロードできます。起動保証は、Confidential VM インスタンスの仮想ファームウェアが改ざんされていないことを確認するために使用される、署名付きのバイナリ シリアル化プロトコル バッファです。

VM が起動すると、AMD Secure Processor または Intel TDX モジュールは、ファームウェア バイナリを実行する前にハッシュします。この SHA-384 ダイジェストは、AMD SEV-SNP の場合は MEASUREMENT フィールドに、インテル TDX の場合は MRTD に保存されます。

このダイジェストを使用して、Google から起動保証をダウンロードし、gcetcbendorsement などのツールで署名が Google にルートされていることを確認してから、ファームウェア測定と保証に記録されている SHA-384 ダイジェストが一致することを確認できます。

ファームウェアの検証以外にも、起動保証で特定のプロパティを使用して、最小セキュリティ バージョン番号(SVN)、vCPU 数、メモリ構成、UEFI のファミリー ID などのアクセス ポリシーを適用できます。

詳細については、Confidential VMs インスタンスのファームウェアを確認するをご覧ください。

検証ツール イベントログの再生と解析

検証ツールは、証明者が提供した証拠を直接検証するだけでなく、証明者が提供したイベントログを再生して、測定レジスタの値に対する完全性を検証することもできます。

これを行うため、検証ツールは、構成証明ポリシーの一部としてチェックする必要がある各測定レジスタのシミュレートされたバージョンを作成します。次に、イベントログのイベントを使用して、シミュレートされたレジスタに入力します。シミュレートされたレジスタの最終値が、同等の実際の測定レジスタに保存されている値と一致する場合、イベントログと Confidential VM インスタンスのブートプロセスが改ざんされていないという信頼性が高まります。

このようにしてログが検証されると、検証者または信頼当事者がポリシーのベースにできる個々の測定値を解析できます。

独自のイベントログ再生ツールと解析ツールを構築する

イベントログを再生して解析する独自のソフトウェアを構築することもできますが、go-eventlog などの確立されたソフトウェアを使用することをおすすめします。これにより、Trusted Computing Group と Confidential Computing Event Log 形式の EventType の脆弱性などの一般的な落とし穴を回避できます。

独自の再生ソフトウェアと解析ソフトウェアを構築する場合は、次の vTPM ベースの例が初期の理解に役立ちます。ただし、実装は独自の Confidential VM インスタンスで生成されたイベントログに基づいて行う必要があります。

次の例は、PCR 0 に測定される Ubuntu 24.04 vTPM イベントログから選択されたイベントを示しています。イベントログは、次のコマンドを使用して tpm2_eventlog でバイナリから ASCII に変換されています。

sudo tpm2_eventlog /sys/kernel/security/tpm0/binary_bios_measurements

ログの PCR 0 イベントは次のとおりです。

---
version: 1
events:
- EventNum: 0
  PCRIndex: 0
  EventType: EV_NO_ACTION
  Digest: "0000000000000000000000000000000000000000"
  EventSize: 41
  SpecID:
  - Signature: Spec ID Event03
    platformClass: 0
    specVersionMinor: 0
    specVersionMajor: 2
    specErrata: 0
    uintnSize: 2
    numberOfAlgorithms: 3
    Algorithms:
    - Algorithm[0]:
      algorithmId: sha1
      digestSize: 20
    - Algorithm[1]:
      algorithmId: sha256
      digestSize: 32
    - Algorithm[2]:
      algorithmId: sha384
      digestSize: 48
    vendorInfoSize: 0
- EventNum: 1
  PCRIndex: 0
  EventType: EV_NO_ACTION
  DigestCount: 3
  Digests:
  - AlgorithmId: sha1
    Digest: "0000000000000000000000000000000000000000"
  - AlgorithmId: sha256
    Digest: "0000000000000000000000000000000000000000000000000000000000000000"
  - AlgorithmId: sha384
    Digest: "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
  EventSize: 160
  Event: "53503830302d313535204576656e7433792b000056aca511a145224ba54128607dac543b0d476f6f676c652c20496e632e0016476f6f676c6520436f6d7075746520456e67696e650001000d476f6f676c652c20496e632e00792b000004322e37000300000028000000468e85a27fa36a458c790c1fe48b65ff4600690072006d007700610072006500520049004d0000000000000000000000000000000000"
- EventNum: 2
  PCRIndex: 0
  EventType: EV_NO_ACTION
  DigestCount: 3
  Digests:
  - AlgorithmId: sha1
    Digest: "0000000000000000000000000000000000000000"
  - AlgorithmId: sha256
    Digest: "0000000000000000000000000000000000000000000000000000000000000000"
  - AlgorithmId: sha384
    Digest: "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
  EventSize: 288
  Event: "53503830302d313535204576656e7433792b000056aca511a145224ba54128607dac543b0d476f6f676c652c20496e632e0016476f6f676c6520436f6d7075746520456e67696e650001000d476f6f676c652c20496e632e00792b000004322e370001000000a800000068747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f6763655f7463625f696e746567726974792f6f766d665f7836345f63736d2f3834383939616564336339653837363735666638303966356665613365366638383733353533643166303130306464623961653333323639323832356163636537333866343562646563323738613430393864316332376534393533373134332e66642e7369676e65640000000000000000000000000000"
- EventNum: 3
  PCRIndex: 0
  EventType: EV_S_CRTM_VERSION
  DigestCount: 3
  Digests:
  - AlgorithmId: sha1
    Digest: "4031fe1129fb826f12dcad169992cca9f4f56aa3"
  - AlgorithmId: sha256
    Digest: "fa129a8f82b65bcbce8f9e8e5f6de509beff9b1df33714116bf918c5a3bba45d"
  - AlgorithmId: sha384
    Digest: "21d340a4a30bb8865486d150cd9ceb46100662b92f336d38b87d70b373ca15c4c60878336924baa818dc2aceaeb40ea6"
  EventSize: 48
  Event: "47004300450020005600690072007400750061006c0020004600690072006d0077006100720065002000760032000000"
- EventNum: 4
  PCRIndex: 0
  EventType: EV_NONHOST_INFO
  DigestCount: 3
  Digests:
  - AlgorithmId: sha1
    Digest: "2b106cedd1631981619790bbc1afaa80cc6ecd3e"
  - AlgorithmId: sha256
    Digest: "6ac9241348a80c5755a63bcd1865b9f6d5720f6e925dc869bb4694281c1510c5"
  - AlgorithmId: sha384
    Digest: "1167e32c3814259ea4809234cccfbd2785c32bde882833bb199d6df6bd989a49f45663e63ce11699fcd01250050f042c"
  EventSize: 32
  Event: "474345204e6f6e486f7374496e666f0001000000000000000000000000000000"
- EventNum: 19
  PCRIndex: 0
  EventType: EV_SEPARATOR
  DigestCount: 3
  Digests:
  - AlgorithmId: sha1
    Digest: "9069ca78e7450a285173431b3e52c5c25299e473"
  - AlgorithmId: sha256
    Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
  - AlgorithmId: sha384
    Digest: "394341b7182cd227c5c6b07ef8000cdfd86136c4292b8e576573ad7ed9ae41019f5818b4b971c9effc60e1ad9f1289f0"
  EventSize: 4
  Event: "00000000"

Confidential VM インスタンスがリセットされると、その PCR はゼロに初期化されます。イベントが発生すると、PCR 0(PCRIndex: 0)の SHA-256 バンクの値は次のように変化します(EV_NO_ACTION イベントはレジスタを拡張しません)。

  1. レジスタの値は、PCR 0 に割り当てられた次のイベントの SHA-256 ダイジェスト EV_S_CRTM_VERSION と連結されます。連結された結果は再度 SHA-256 ハッシュ化され、レジスタに保存されます。PCR 0 の SHA-256 hexdigest が 0c3684a7571193d76a68e489ded7bf186fc2fb1efe0c6dd9ce147960bbc57365 になりました。

  2. EV_NONHOST_INFO イベントでも同じプロセスが使用されます。PCR 0 の SHA-256 hexdigest が 509f590b71fb22c9a6eef647e3c23611d13e599a6e15fdbb4db56ea4c2cb878d になりました。

  3. 特定のレジスタへの測定拡張が完了したことを示す EV_SEPARATOR イベントにも同じプロセスが使用されます。EV_SEPARATOR は 32 ビットのゼロ値(\x00*4)です。これにより、PCR 0 の最終的な SHA-256 ヘキサダイジェストは a0b5ff3383a1116bd7dc6df177c0c2d433b9ee1813ea958fa5d166a202cb2a85 になります。

次の Python コードは、シミュレートされた Compute Engine PCR 0 を作成して、上記の手順を示しています。このコードは、既知の値からイベント ダイジェストを導出するため、イベントログの再生ではありません。適切なイベントログの再生を作成する場合は、VM インスタンスのイベントログからダイジェストを読み取る必要があります。

import hashlib

def CalculatePCR0(version_num: int, mem_encrypt_enum: int):
  """Calculates the expected SHA-256 PCR 0 value given the
  Compute Engine firmware version and Confidential Computing technology
  that's in use.

  This code uses derived values for events instead of reading digests from an
  event log. It's intended to demonstrate how to simulate the extend function
  used in measurement registers.

  While the code should provide correct values for PCR 0 in
  Compute Engine VM instances, for other PCRs and true event log replay
  you should read in digests from an event log instead of using derived values.

  PCR 0 measurements include:
    * EV_S_CRTM_VERSION: The firmware version string, in UTF-16 little-endian
      form. This value remains stable as long as the firmware version stays the
      same.
    * EV_NONHOST_INFO: This value changes based on the Confidential Computing
      technology that's in use.
    * EV_SEPARATOR: A 32-bit zero value to split UEFI and bootloader
      measurements.

  Args:
    version_num (int): The Compute Engine firmware version number. The
      value is 2.

    mem_encrypt_enum (int): The type of Confidential Computing technology used
      on the VM:

      0: None
      1: AMD SEV
      2: AMD SEV-ES
      3: Intel TDX
      4: AMD SEV-SNP

  Returns:
    A hexstring representing the expected PCR 0 digest.
  """
  # Create a hash object to act as PCR 0, and initialize it with zeroes.
  h = hashlib.sha256()
  h.update(b'\x00' * h.digest_size)

  # Update the hash object with the EV_S_CRTM_VERSION event, with a hard-coded
  # firmware version `version_num`.
  #
  # This code uses derived values for events. To use the digest supplied in an
  # event log for event log replay, you need to read in the event digest, and
  # then convert it to bytes before updating the hash object, similar to the
  # following:
  #
  # h.update(bytes.fromhex('fa129a8f82b65bcbce8f9e8e5f6de509beff9b1df33714116bf918c5a3bba45d'))
  #
  h.update(
          hashlib.sha256(
              # The firmware uses UCS-2 encoding, so we match it by encoding to
              # the equivalent UTF-16 little-endian. An extra null byte is
              # needed to match the required byte length.
              f'GCE Virtual Firmware v{version_num}\x00'.encode('utf-16-le')).digest()
          )

  # Create a new hash object to act as PCR 0 and update it with the previous
  # hash object's digest. This simulates the first part of the register EXTEND
  # function.
  h2 = hashlib.sha256()

  h2.update(h.digest())

  # Update the hash object with the EV_NONHOST_INFO event, which includes
  # `mem_encrypt_enum`, the Confidential Computing technology in use. Performing
  # this update completes the simulated EXTEND function.

  h2.update(
          hashlib.sha256(
              b'GCE NonHostInfo\x00'
              + (mem_encrypt_enum).to_bytes(1, byteorder='little')
              + (b'\x00' * 15)
              ).digest()
          )

  # Create a new hash object to act as PCR 0 and update it with the previous
  # hash object's digest. This simulates the first part of the register EXTEND
  # function.
  h3 = hashlib.sha256()
  h3.update(h2.digest())

  # Update the hash object with the EV_SEPARATOR event. Performing this update
  # completes the simulated EXTEND function.
  h3.update(hashlib.sha256(b'\x00' * 4).digest())

  # There are more PCR 0 events, but they're all `EV_NO_ACTION` and don't
  # affect the register value. Return the final simulated register value.
  digest = h3.hexdigest()
  return digest

print('\nPCR 0 simulation')
print('\nConfidential Computing type\tDigest')
# Compute Engine firmware version 2, no Confidential Computing
# Expected hexdigest: d0c70a9310cd0b55767084333022ce53f42befbb69c059ee6c0a32766f160783
print(f'None\t\t\t\t{CalculatePCR0(2, 0)}')

# Compute Engine firmware version 2, AMD SEV
# Expected hexdigest: a0b5ff3383a1116bd7dc6df177c0c2d433b9ee1813ea958fa5d166a202cb2a85
print(f'AMD SEV\t\t\t\t{CalculatePCR0(2, 1)}')

# Compute Engine firmware version 2, AMD SEV-SNP
# Expected hexdigest: 50597a27846e91d025eef597abbc89f72bff9af849094db97b0684d8bc4c515e
print(f'AMD SEV-SNP\t\t\t{CalculatePCR0(2, 4)}')

# Compute Engine firmware version 2, Intel TDX
# Expected hexdigest: 0cca9ec161b09288802e5a112255d21340ed5b797f5fe29cecccfd8f67b9f802
print(f'Intel TDX\t\t\t{CalculatePCR0(2, 3)}')

print()

証明書利用者の構成

パスポート モデルまたは身元確認モデルのどちらが使用されるかに応じて、証明書発行者または検証者のいずれかから証明書の結果が受け渡されます。

次に、証明書利用者側で、証明書の結果で受け取ったクレームが想定される値と一致することを確認します。値が一致する場合、証明書利用者は証明書発行者がローカル ID としてリソースにアクセスすることを許可します。

Google Cloud で証明書利用者(RP)を構成する一般的なパターンは、Workload Identity 連携を使用し、証明書発行者をフェデレーション ID として扱うことです。

  1. 検証ツールを Workload Identity プールの OIDC プロバイダとして追加します。これにより、Confidential VM インスタンスのワークロードに接続されたサービス アカウントがフェデレーション ID として機能し、必要なリソースにアクセスできるようになります。

  2. リソースへのアクセス権を付与するために、検証ツールの構成証明クレームが一致する必要がある値を定義します。

    Google Cloudでは、Identity and Access Management(IAM)がフェデレーション ID がプリンシパルとして認証されるために満たす必要のある条件として処理できるように、証明書クレームを属性にマッピングします。

    次に、必要なリソースの許可ポリシーに、フェデレーション プリンシパルのロール バインディングを追加して、証明書発行者にリソースへの直接アクセス権を付与します。フェデレーション ID をサポートしていないサービスの場合は、サービス アカウントの権限借用を使用してリソースへのアクセスを提供できます。

Workload Identity 連携の代わりに、構成証明トークンのクレームを直接解析するコードを記述することもできます。例については、Confidential Virtual Machine での vTPM リモート証明をご覧ください。