「機密コンピューティング」を活用する方法を実機検証を通して学ぶ

1. 利用者が主体となった「機密コンピューティング」の活用

1-1. クラウドの責任共有モデルの範囲では対処しきれないリスク

世間一般に言うクラウドコンピューティングはそのセキュリティ(機密性・完全性・可用性)の維持において、その構成要素ごとにクラウド事業者が運用責任を負う部分と利用者が担保する箇所を分ける、いわゆる「責任共有モデル (shared responsibility model)」(参考:クラウドコンピューティングのためのセキュリティガイダンス v4.01)の下、はじめて成立するサービスです。

そのクラウドコンピューティングの中でも IaaS 型クラウドサービスは、貸し出されたコンピュータ上で動作する OS、ミドルウェア、ソフトウェアなどの選定、セットアップ、アップデートを利用者にて実施いただくモデルであり、その性質からも該当コンピュータ上で生成・保存された利用者データの漏洩・滅失の予防、失われた場合の復旧について事業者は責任を負えないものとなっている場合が多くあります。

当社さくらインターネットで提供している「さくらのVPS」「さくらのクラウド サーバ」も、そのご利用にあたっては約款 2 で定めたデータ保護の条件に同意の上、お客様にて適切なデータ保護・バックアップの措置を講じて利用していただくものです。

利用者でのデータ消失の予防、及び失われた場合の復旧は OS 上にて適切なシステム監視を行うこと、定期的なバックアップの実行などで実現可能です。また、データ漏洩や改ざん防止のためには、ストレージやデータベース保存などの際に適切に暗号化を行うことでその一部を対策することができます。これらはクラウドを使用してシステムを構築するベストプラクティスとしてノウハウが共有されています。

一方、IaaS 型クラウドサービスの多くで提供される VM(Virtual Machine、仮想マシン、すなわちソフトウェア的に再現されたコンピュータ)は、それが動作しているホストマシンのホスト OS 上ではアプリケーションの一つとして見えることが一般的で、クラウド事業者からその動作中のメインメモリを読み取るような行為も技術的には可能です。

この時クラウド事業者は VM の提供において、運用者(例えば従業員)や他の利用者による利用者データ等への不正アクセスが起こらないようセキュリティ対策を講じますが、万一ホスト OS に外部の攻撃者の侵入を許してしまった場合、VM のメインメモリを読み取るなどの行為を通して「利用者データの漏洩」が発生する可能性があり、その際の被害による補償はクラウド事業者から受けられるとは限らないものとなります。

この部分はこれまで、クラウドを利用する限りは低確率ながら残ってしまう、機密性・完全性の面での利用者リスクでした。

1-2. 機密コンピューティング

そもそも、「ホストマシンからはどうやっても見れない」VM は作成できないものでしょうか?

近年機密コンピューティング、もしくはコンフィデンシャル・コンピューティングと呼ばれる分野が開拓されており、共通する概念として「ハードウェアに装備された機能を用い、実行されるアプリケーションと取り扱うデータが外部から保護された領域、すなわち TEE (Trusted Execution Environment)を作成し、その中でアプリケーションなどを実行する」というものがあります。

この中でも最近開発が進んでいるものが「VM を丸ごと TEE とすることで任意の OS 、ソフトウェアをそのまま実行できる」Virtualization-based TEE とも呼ばれる方式であり、AMD 社プロセッサに搭載された SEV (Secure Encrypted Virtualization) 機能3 、Intel 社プロセッサに搭載された TDX (Trusted Domain Execution)4 機能などを使用して VM (これ以後機密 VM と呼びます)を作成する方式が著名です。

機密 VM においては、そのメインメモリやそのアプリケーションを実行する仮想 CPU の動作状態を表すレジスタ群は、ホストマシンに装備された物理的なプロセッサ内の保護領域で生成される暗号鍵によって暗号化されます。プロセッサの保護領域にはホスト OS からはアクセスできないため、仮に攻撃者がホスト OS を乗っ取り VM のメインメモリを読み取ったとしても、その中身を復号することはできません。

ここで、前項でも触れたように VM とはソフトウェア的に再現されたコンピュータであり、その中からホストマシンの状態を見る事はできず、「この VM が間違いなく機密 VM であること」は通常の手順では確認できません。そのため、現在自身が実行されている VM の構成証明レポート(Attestation Report)を取得する機能がプロセッサの機能として提供されており、メインメモリの暗号化が間違いなく有効になっていること(機密性)の確認が可能です。

また、多くの IaaS 型クラウドサービスにおいて、利用者の利便のため、VM はその上で動作するゲスト OS イメージがセットアップされた状態で提供されることが一般的です。もしもクラウド事業者の基盤がサイバー攻撃などによる侵害などを受けた場合、VM の起動に用いる(いわゆる)BIOS ファームウェアやそのゲスト OS イメージにはユーザの意図しない改ざんがなされたり、マルウェアなどが混入される可能性があります。

機密 VM の起動においては、構成証明レポートに含まれる情報を用いて(いわゆる)BIOS ファームウェアが改ざんを受けていないことを確認することと、Measured Boot というゲスト OS の起動手順を取ることで、機密 VM 内で実行されたソフトウェアが意図しない改ざんを受けていないこと、すなわち完全性の確認が行えるようになっています。

よって、「プロセッサ製造メーカーは信頼する前提」と「機密 VM を使用する時の正しい手順(構成証明レポートの内容確認と Measured Boot)」を揃えれば、万一クラウド事業者が侵害されたとしても真に「利用者データの漏洩」リスクが生じない状態でクラウド利用ができることになります。

1-3. 当記事の目的

ここでポイントとなるのは、「機密 VM を使用する時の正しい手順」はクラウドの責任共有モデルに従って、利用者の責任での実行が求められる点です。しかし、現在はまだ OS の標準機能などとして簡単に利用できる状況とは言い難い状況です。

そこで当記事では、AMD 社製プロセッサを用いたホストマシンの上で SEV-SNP (Secure Encrypted Virtualization - Secure Nested Paging) 機能を有効にした機密 VM を起動し、その中で起動された Linux OS において構成証明レポートの取得と Measured Boot の確認を行う手順を実際に試行します(但し、簡易なアクセス方法が未実装のためスキップする点が1つあることに注意してください)。

当記事をお読みの方がクラウド事業者が提供する「機密コンピューティング」を謳う VM を利用する時、ご自身でも実際の機密性・完全性を検証してから使用する一助になれば幸いです。

2.検証の前提となる理論

2-1. 当記事のスコープ

1-2 で述べた「機密 VM を使用する時の正しい手順」を行う目的は、「機密 VM の機密性と完全性が検証されない限り、絶対にその中で重要なデータを取り扱わない」ことと表現することができます。

前提として、主要な OS はその機能として FDE (Full Disk Encryption)5 と呼ばれる機能を備えており、例えば Linux OS における FDE の実装ではその OS の中核プログラム(カーネル)及び OS ブートに必要な最低限のファイルシステムイメージ(initrd もしくは initramfs)を除いた OS のルートファイルシステムを全て暗号化できることを挙げます。

そこで、機密 VM にインストールしたゲスト OS で FDE を有効にした環境を構築し、最低限の OS ブートを行った後、 OS ルートファイルシステムの暗号化を解除する鍵の入力を待ってブートプロセスを一旦停止させるようにします。次に、ブートプロセスが一旦停止したタイミングで利用者が一旦ゲスト OS にログインし、機密 VM の機密性と完全性をチェックし、チェックが成功した場合に限って OS ルートファイルシステム復号鍵を入力する手順とします。

このようにすることで、例えばこの機密 VM がサービスするものが「何らかのデータベースを用い、エンドユーザに Web システムを提供する」ようなものであった場合、データベースおよび該当 Web システムのアプリケーションを OS ルートファイルシステムの範囲に保存しておけば、暗号鍵を入力しない限りその環境で重要なデータを扱わないシステムとすることが可能と考えられます。

一方、最低限の OS ブートだけが行われた環境は色々なサービス(SSH を用いたネットワークログイン機能)などが動いておらず説明に適しないため、この記事では FDE を使用せず、ブートプロセスの一旦停止も行わない通常環境を用い、「機密性の検証」「完全性の検証」は Linux OS 全体のブート後に行います。

実際には、その検証手順に必要な OS サービスやソフトウェアのみを別途 OS 部に必要な最低限のファイルシステムイメージに追加し、ブートプロセスの一旦停止を行う仕組みと FDE を有効にすることで、「機密 VM の検証を行ったのちに OS ルートファイルシステムを復号する」方式とすることが可能と考えられます。

また、検証が完了するまでゲスト OS は改ざんされていない保証ができないため、検証アルゴリズムを実行するツールは本来信頼できるリモートのシステム上で実行する必要があります。当記事では説明上の簡単化のため機密性・完全性の検証ツールをゲスト OS で動作させている場合がありますが、ご了承下さい。

2-2. 機密性の検証方式(暗号化されていることを確認する)

機密 VM 内での構成証明レポート取得の手順は、コミュニティベースで運営されている VirTEE 6 の提供するオープンソースリポジトリ群という形で提供されており、現在は AMD 社 SEV 機能用のツール群が中心であるものの、今後の Intel 社製チップ、ARM アーキテクチャチップなどへの展開を想定した運営がされているようです。

現在、SEV-SNP 機能をサポートした第三世代以降の AMD EPYCTM Processor 上での構成証明レポートの取得フローはドキュメント7 及び OSS ツールキット(snpguest 8) の形で提供されています。

SEV-SNP 構成証明レポートにはそのホストマシン固有のチップ ID、リクエスト者が入力したノンス(使い捨ての値)、VM 起動に用いられたファームウェアバイナリのハッシュ値などが含まれており、AMD プロセッサ内の保護領域から取り出せないように保存された秘密鍵によって作成された電子署名が付与されています。

snpguest ツールキットを使い、ノンスを入力してレポートを取得した後、AMD 社が運営するインターネット上のサーバからダウンロードできるチップ ID ごとの証明書を取得、証明書に含まれる公開鍵によってレポートの内容が正しい事を検証することで、レポート自体が間違いなく機密 VM からのリクエストに応じて作成されたものであり、間違いなく当 VM は SEV-SNP の仕組みで暗号化されていることを確認することができます。

2-3. 完全性の検証方式(ブートプロセスの改ざんを防ぐ)

OS のブートプロセスで使用されるソフトウェア群が意図しない改ざんを受けていないことを検証する方法としては、Secure Boot や Verified Boot などと呼ばれる「次のブートプロセスで実行するプログラムが改ざんされていないか検証してから実行する」方式と、Measured Boot や Trusted Boot などと呼ばれる「ブートに使われたプログラムのハッシュ値と、ブートパラメータを含むブート中に起こったイベントのハッシュ値を記録しながらブートを行い、後から検証を行う」方式の、大きく2 通り9 があります。

一般に Secure Boot / Verified Boot 方式は「ハードウェアなどに設けられた Root of Trust」と「外部の証明機関への信頼」をベースにした方式です。Root of Trust が必要なのは、「次のブートプロセスで実行するプログラムを検証するためには今動作しているプロセスが改ざんされていないことを保証しなければならない」事情があり、その最初の起点となる部分は変更のできない ROM に書き込むなどして改ざんに耐える状態としなければならないためです。

Secure Boot において次のブートプロセスで実行するプログラムは、該当プログラムの完全性を証明する外部の団体が予め非対称鍵ペアの秘密鍵を用いて電子署名を付与しておき、それをシステムにインストールされた証明書、それに含まれる非対称鍵ペアの公開鍵を用いて検証してから実行される仕組みです。一方、ホスト OS 上のアプリケーションの一つとして実行される VM、しかもホスト OS の管理者と VM の利用者が異なる IaaS 型のクラウドサービスにおいては、VM が書き換え可能なソフトウェア的なものである以上、この Root of Trust の確立が困難です。

他方 Measured Boot / Trusted Boot 方式は、外部の信頼されたシステムによってブートプロセスの最後に検証を行う方式であり、ブートプロセスは途中での検証を挟むことなく次々と実行されるものの、外部からの改ざんを受けない対策を施したシステムへの情報記録を行いながら実行されます。記録するデータにはブート時に実際に使用されたプログラムのハッシュ値や、ブートパラメータを含むブート中に起こったイベントのハッシュ値などが含まれており、ブートプロセスの最後でそれらの値が望ましい値と一致しているかを確認することで検証を完了します。

これは利用者自身が「ログインして操作」という形で行うこともできる、リモート構成証明 (Remote Attestation) と呼ばれる操作です。この方式は VM の Root of Trust が作成困難な課題を解決する方法の一つと考えられますが、悪意のあるソフトウェアが埋め込まれていたとしてそれを実行前に完全に停止させることは困難であること、外部からの改ざんを受けない対策を施したログ記録システムの装備が必須であることに留意する必要があります。

物理マシンにおける「外部からの改ざんを受けない対策を施したログ記録システム」は TPM (Trusted Platform Module) の装備によって比較的容易に達成できるものの、VM においてはこれらを vTPM (仮想 TPM)などの形でソフトウェア実装することが想定されるため、その改ざんを防ぐ方法の確立が課題でした。

しかし、現在では AMD 社プロセッサの SEV-SNP 機能の範囲において実装された VMPL (VM Permission Level) の仕組みと、ゲスト OS よりも特権レベルの高い VMPL で動作する SVSM (Secure Boot Service Module10 ) の仕組みを用いることで、後者 Measured Boot で用いる vTPM の改ざんを防ぎつつ実行する方式が考案されています。そこで当記事ではブートプロセスの改ざんを防ぐ方式として vTPM を用いた Measured Boot を前提に検証を進めるものとし、次項でその SVSM を用いた vTPM の構成方式について触れます。

2-4. vTPM の構成方式

一般に TPM は前述の Measured Boot のログ記録システムとしての役割ともに、FDE に用いる永続的な暗号化鍵保管庫としての役割を持っています。これをソフトウェア実装の vTPM で代用する場合、「いかにホストOS・ゲスト OS の両面からの改ざんに耐えるか」と、「TPM 内の永続的なストレージをどのように確保するか」の大きく二つの課題があります。

前者を達成するために、① vTPM 自体も機密 VM で動かすことと、② SEV-SNP で導入された新しい特権分離のレイヤ (VMPL) の仕組みを用い、 VMPL0(最も高い特権レベル)で vTPM を実装した SVSM バイナリを動作させ、それよりも低い特権レベル (VMPL1以上) で従来の UEFI ファームウェアから始まるゲスト OS の組を起動すること、の2つを行います。こうすることで、ホスト OS からは vTPM は暗号化されているため見ることができず、またゲスト OS からも特権レベルが分離されているためアクセスできないという状態を両立することができます。

一方、後者の達成には VM を終了した後もデータが永続化される vTPM の実装が必要ですが、AMD SEV-SNP 機能を用いて起動された機密 VM のメモリ暗号化鍵は VM の終了時に破棄されてしまうため、そのままでは永続化はできません。

そこで、FDE の実装方法として、「TPM 内に保存した暗号鍵によって OS のルートファイルシステムを復号するのではなく、Measured Boot の検証が完了した後に外部の信頼されたシステムから都度暗号鍵を入力して復号する」という制限を設けます。既に Measured Boot の検証のため信頼された外部システムの介入が必要な仕組みであるため、その外部システムに鍵の管理機能も同時に持たせようというものです。

この「VMPL0 で動作する SVSM バイナリであり、FDE 用のデータ永続化機能をオミットして Measured Boot の支援に特化した vTPM 実装」 はオープンソースソフトウェア COCONUT-SVSM11という形で提供されているため、当記事ではこれのセットアップと検証を行っています。

2-5. vTPM との通信の検証方式(今回未検証項目)

通常専用ハードウェアなどの形で実装される TPM との通信においては、その途中での改ざんを防ぐために電子署名の仕組みが用いられます12 。これは TPM から返される応答メッセージに、 TPM 内でだけ保持されている EK (Endorsement Key) に紐づけられた AK (Attestation Key) ペアの、その秘密鍵(AKpriv)を用いた電子署名が付与されており、対になる公開鍵(AKpub)を用いて応答メッセージを検証することによって行われます。

検証ではまず、OS からのリクエストに応じ TPM 内に永続的に記録されたシード値を元に EK ペアを生成、EKpriv を TPM 内に保管したまま、EKpub のみを OS に返します。その EKpub が TPM との通信経路で改ざんされていないことを確認する必要があり、それには ①(ユーザの明示指定により)信頼できるものとして扱う、②信頼できる外部機関(ここでは該当 TPM のメーカー)などが発行する EKcert によって検証した上で信頼する、③信頼できる外部機関が提供する EKpub のリストに含まれるかどうかを検証した上で信頼するなどの方式が用いられます。

EKpub が検証された後、続けて AK ペアの生成を TPM にリクエストし、TPM 内 に AKpriv、OS 側に AKpub が生成された状態としますが、ここで AKpub が通信路上で改ざんされていないことを EK に証明させるためのチャレンジを行います。チャレンジは任意の検証用データを AKpub、EKpub の順で暗号化した後 TPM に送信し、平文の検証用データが返ってくることを確認することで行います。

この手順により、TPM が持っている AKpriv が間違いなく手元の AKpub とペアであり、かつ EK の信頼により経路で改ざんされていないことの両方を証明でき、TPM から返される応答メッセージに付与された電子署名の検証に AKpub が使える状態となります。

さて、SVSM バイナリとして動作する vTPM においても物理的な TPM と同様に EKpub の検証を可能とする仕組みが必要ですが、2-4 の制約によりソフトウェア実装された vTPM には永続化領域がなく、VM を起動した時に乱数ベースで EK の元となるシード値を生成する方式のため、あらかじめ外部で証明書を作成して提供するような方式が使用できません。

その代わりにRemote attestation of confidential VMs using ephemeral vTPMs13で提案されているのは「vTPM 内で SEV-SNP 構成証明レポートのリクエストを行う時、そのユーザデータとして vTPM 内で生成された EKpub を埋め込み、AMD 社の秘密鍵で署名された EKpub を含む構成証明レポートを取得、それをゲスト OS からの EKpub のリクエストに応じて返す」という方式です。このようにすることで、ゲスト OS において SEV-SNP 構成証明レポートの検証を行うことで EKpub の信頼が同時に獲得されます。

この方式では EKpub は小さな公開鍵一つではなく、SEV-SNP 構成証明レポートの形で渡されるため、TPM との通信によく用いられるツール(tpm2-tools など)で取り扱うには適さず、任意フォーマットのデータ通信に適した、別の VMPL 間を渡る通信方式が必要です。VMPL 間を跨るこの通信は SVSM で定義されているSVSM_ATTEST_SERVICES コールおよび SVSM_ATTEST_SINGLE_SERVICE コールによってなされることが想定されていますが、これらを簡単に利用できるツールキットは筆者の調べた限りではまだ無いようです。

しかし、現在 Linux Kernel の開発において、SEV-SNP 構成証明レポートを Linux ConfigFS の仕組みを用いてリクエストする仕組み、及びゲスト OS が VMPL1 を含む特権レベルが低い階梯で動作しているときはその取得を VMPL0 で動作している SVSM に依頼する仕組みの提案14 が進んでおり、今後は Linux の標準機能として利用できるようになる可能性があると思われます。

そこで当記事では vTPM との通信の検証は未検証項目としてスキップした形での実施を行っています。今後利用できる環境に変化が生まれたとき、そのアップデートを加えた改稿を行いたいと考えています。

3. セットアップ手順

3-1. 試験環境

当試験は AMD EPYCTM Processor を採用した下記サーバ上で行いました。

マザーボードSupermicro HH12SSW-NTR
(BIOS version 2.6a / CPLD Version F0.A3.4B)
CPUAMD EPYCTM 7313P Processor
(Microcode Patch Level : A0011D1)
PSP
Firmware
BootLoader Version = 0.13.0.75,
SMU FW Version = 0.45.93.0,
ABL Version = 100A5010
Memory128GiB
(Registered DDR4-3200 16GiB x 8)
Storage960GB NVMe U.2 SSD x 2
(mdraid-1)
表1: セットアップに用いたサーバ情報

3-2. ホストマシンの BIOS 設定

SEV-SNP 機能を使用するにはマザーボード BIOS の設定によるプロセッサ機能の有効化が必要であり、参考となる設定が GitHub AMDSEV リポジトリ15 に示されています。マザーボードの品種・BIOS のバージョンなどによっては項目名が違ったり、設定が不可となっている可能性があるため、事前に設定機能の有無を確認した上で購入し、適切な項目の読み替えが必要と思われます。今回使用した Supermicro 社製マザーボード上では下記設定としました。

Advanced->
NB config->
SEV-SNP Support
Enable
Advanced->
CPU Configuration->
SMEE
Enable
Advanced->
CPU Configuration->
SEV-ES ASID Count
509 ASIDs
Advanced->
CPU Configuration->
SEV-ES ASID Space Limit Control
Manual
Advanced->
CPU Configuration->
SEV-ES ASID Space Limit
10
表2: セットアップに用いたマザーボード BIOS 上の SEV-SNP 機能に関する設定

なお、ここで SEV-ES ASID Space Limit の数値は「そのホストマシン上で同時に実行できる機密 VM の数」に影響し、具体的には「ASID Space Limit - 1」個の機密 VM の実行が可能です。こちらの検証についても後ほど触れます。

3-3. ホスト OS の準備

3-3-1. 基本方針

ホスト OS として Ubuntu 24.04 LTS server を使用し、ISO インストールイメージを用いてインストールします。ここから機密 VM の起動までは、COCONUT-SVSM のインストールガイド16 を参考に進めます。

3-3-2. Rust コンパイル・動作環境の準備

COCONUT-SVSM ソフトウェアの構築には随所で Rust が用いられているため、Rustup.rs17 を参考に下記手順でのセットアップを行います。

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
$ sudo apt install libcunit1-dev
$ source ${HOME}/.cargo/env
$ cargo install --force cbindgen

公式の手順では単に最新の Rust ツールチェインのインストール手順が紹介されていますが、後の項で触れるコード修正が必要な場合があり、 Rust ツールチェインのバージョン違いに起因する可能性があると筆者は考えています。そのため、実際にはインストールしたツールチェインのバージョン管理の上実行することを推奨いたします。当記事では下記のバージョンのツールチェインを用いていることを付記します。

$ rustc --version
rustc 1.78.0 (9b00956e5 2024-04-29)

3-3-3. linux カーネルを SEV-SNP 対応に入れ替え

coconut-svsm プロジェクトで変更が加えられている Linux バージョン 6.8.0 svsm ブランチのビルドを行います。

$ sudo apt install build-essential bison libssl-dev flex libelf-dev libncurses-dev python3-venv ninja-build libglib2.0-dev python-is-python3 nasm device-tree-compiler debhelper acpica-tools
$ git clone https://github.com/coconut-svsm/linux
$ cd linux
$ git checkout svsm
$ cp /boot/config-${uname -r} .config

ここで現行システムからコピーされた .config に下記変更を加えます。Ubuntu の generic カーネルビルドには Secure Boot のため Canonical 社の秘密鍵で署名する工程が入りますが、今回は Secure Boot を行わないため CONFIG_SYSTEM_TRUSTED_KEYS, CONFIG_SYSTEM_REVOCATION_KEYS を空欄としました。

CONFIG_TCG_PLATFORM の指定は同じ Linux イメージをゲスト OS でも使用し、vTPM との VMPL 間を跨った通信を tpm2-tools から使用するためのものであり、ホスト OS では厳密には設定不要です。

CONFIG_SYSTEM_TRUSTED_KEYS=""
CONFIG_SYSTEM_REVOCATION_KEYS=""
CONFIG_LOCALVERSION="-coconut-svsm-sevsnp"
CONFIG_TCG_PLATFORM=y

変更したコンフィグを加えてのビルド作業を行い、出来上がった deb 形式のパッケージファイルを用いてシステムにインストールします。

$ make olddefconfig
$ make -j32
$ make bindeb-pkg
$ cd ..
$ sudo dpkg -i linux-image-6.8.0-coconut-svsm-sevsnp+_6.8.0-{適宜バージョンを読み替えてください}_amd64.deb
$ sudo dpkg -i linux-headers-6.8.0-coconut-svsm-sevsnp+_6.8.0-{適宜バージョンを読み替えてください}_amd64.deb
$ sudo dpkg -i linux-libc-dev_6.8.0-{適宜バージョンを読み替えてください}_amd64.deb

今回ビルドした Linux イメージが起動に使用されるよう、/etc/default/grub の下記設定を書き換えます。

GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 6.8.0-coconut-svsm-sevsnp+"
GRUB_CMDLINE_LINUX="mem_encrypt=on"

起動時に新しい Linux カーネルが使用されるよう、下記コマンドで設定を適用します。

$ sudo update-grub

システム再起動ののち、ビルドしたカーネルでの起動が行われており、ホストのメモリ暗号化が有効になっていることを確認します。

$ uname -r
6.8.0-coconut-svsm-sevsnp+
$ sudo dmesg | grep SME
[    0.320689] Memory Encryption Features active: AMD SME

3-3-4. IGVM のインストール

IGVM はゲスト VM の BIOS ファームウェアバイナリのフォーマットの一つであり、今回は vTPM の起動に用いられる SVSM バイナリと、代表的なオープンの UEFI BIOS である OVMF とを結合して1つのファイルとして取り扱うために使用します。下記の手順にてシステムにインストールが実行されます。

$ git clone https://github.com/microsoft/igvm
$ cd igvm/igvm_c
$ make -f Makefile
$ sudo make -f Makefile install

下記ファイル群がインストールされ、後の手順で使用されます。

/usr/lib64/libigvm.a
/usr/include/igvm/igvm.h
/usr/include/igvm/igvm_defs.h
/usr/lib64/pkgconfig/igvm.pc
/usr/bin/dump_igvm

3-3-5. SVSM 起動対応の QEMU をビルド

coconut-svsm プロジェクトで変更が加えられ、SEV-SNP における VMPL の違いを認識して起動を行える QEMU のビルドを行います。

$ git clone https://github.com/coconut-svsm/qemu
$ cd qemu
$ git checkout svsm-igvm

ここで筆者の環境では backends/igvm.c に下記の変更を加えました。この変更は読み込まれている IGVM 用のヘッダファイルの変更に関連しており、現時点では Rust ツールチェインのバージョン違いなどに起因する可能性があると考えております。バージョンが異なる環境を用いる場合はご注意ください。

diff --git a/backends/igvm.c b/backends/igvm.c
index aba5586bc0..d599cbe942 100644
--- a/backends/igvm.c
+++ b/backends/igvm.c
@@ -28,6 +28,27 @@
 #include <igvm/igvm_defs.h>
 #include <linux/kvm.h>
 
+#define HEADER_SECTION_PLATFORM IGVM_HEADER_SECTION_PLATFORM
+#define HEADER_SECTION_INITIALIZATION IGVM_HEADER_SECTION_INITIALIZATION
+#define HEADER_SECTION_DIRECTIVE IGVM_HEADER_SECTION_DIRECTIVE
+
+#define NORMAL IGVM_PAGE_DATA_TYPE_NORMAL
+#define SECRETS IGVM_PAGE_DATA_TYPE_SECRETS
+#define CPUID_DATA IGVM_PAGE_DATA_TYPE_CPUID_DATA
+#define CPUID_XF IGVM_PAGE_DATA_TYPE_CPUID_XF
+
+#define NATIVE IGVM_PLATFORM_TYPE_NATIVE
+#define VSM_ISOLATION IGVM_PLATFORM_TYPE_VSM_ISOLATION
+#define SEV_SNP IGVM_PLATFORM_TYPE_SEV_SNP
+#define TDX IGVM_PLATFORM_TYPE_TDX
+#define SEV IGVM_PLATFORM_TYPE_SEV
+#define SEV_ES IGVM_PLATFORM_TYPE_SEV_ES
+
+#define MEMORY IGVM_MEMORY_MAP_ENTRY_TYPE_MEMORY
+#define PLATFORM_RESERVED IGVM_MEMORY_MAP_ENTRY_TYPE_PLATFORM_RESERVED
+#define PERSISTENT IGVM_MEMORY_MAP_ENTRY_TYPE_PERSISTENT
+#define VTL2_PROTECTABLE IGVM_MEMORY_MAP_ENTRY_TYPE_VTL2_PROTECTABLE
+
 typedef struct IgvmParameterData {
     QTAILQ_ENTRY(IgvmParameterData) next;
     uint8_t *data;

修正されたファイルを用い、ビルドとインストールを行います。

$ export PKG_CONFIG_PATH=/usr/lib64/pkgconfig
$ ./configure --prefix=$HOME/bin/qemu-svsm/ --target-list=x86_64-softmmu --enable-igvm
$ ninja -C build/
$ make install

コンパイル後、~/bin/qemu-svsm 以下にバイナリ群が作成されます。システムワイドにインストールされた qemu-system-x86_64 とは別となることに留意ください。

3-3-6. SVSM 対応 OVMF の準備

coconut-svsm プロジェクトで変更が加えられ、VMPL0 で起動した vTPM に対してハッシュ値を書き込みながら次のプロセスのブートを行う機能を持った OVMF をビルドします。

$ git clone https://github.com/coconut-svsm/edk2.git
$ cd edk2/
$ git checkout svsm
$ git submodule update --init
$ make -j16 -C BaseTools/
$ source ./edksetup.sh --reconfig
$ build -a X64 -b DEBUG -t GCC5 -D DEBUG_ON_SERIAL_PORT -D DEBUG_VERBOSE -DTPM2_ENABLE -p OvmfPkg/OvmfPkgX64.dsc
$ cp Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fd ~/

作成された OVMF.fd はホームディレクトリに配置されます。

3-3-7. COCONUT-SVSM の準備

本丸となる vTPM モジュール、及びそれと OVMF を結合した IGVM ファイルを下記手順でビルドします。

$ sudo apt install autoconf-archive
$ git clone https://github.com/coconut-svsm/svsm
$ cd svsm
$ git submodule update --init
$ cargo install bindgen-cli
$ export PKG_CONFIG_PATH=/usr/lib64/pkgconfig
$ FW_FILE=${HOME}/OVMF.fd make

cbit 取得ユーティリティのコンパイルと実行を行い、このシステム固有の cbit (メモリ暗号化フラグのビット位置、参考18 )位置を取得します。この数値は機密 VM を起動する時の QEMU コマンドラインパラメータに用います。例示する出力値は筆者の環境における例であり、システムごとに異なる事に留意してください。

$ make utils/cbit
$ ./utils/cbit
51

出来上がった IGVM ファイルを用いて起動を行った時の Measured Boot ハッシュ値を下記手順で取得します。この値は後ほどの Measured Boot の検証で用います。

$ cd bin
$ ./igvmmeasure coconut-qemu.igvm measure
===============================================================================================================
igvmmeasure 'coconut-qemu.igvm'
Launch Digest: A3A4D5E40A5D27FD5733930CC95813C861DD8D7077B12585E5E46F10192C679974B8B0AD5979F02E5867FEE41A576FCC
===============================================================================================================

3-4. ゲスト OS の準備

3-4-1. OS インストール

ゲスト OS としてホストと同様に Ubuntu 24.04 LTS server を使用します。下記コマンドラインで QEMU/KVM を SEV-SNP 無し(システム標準の qemu-system-x86_64 使用)、libvirtd 導入で作成される標準の OVMF.fd を用いた環境で起動します。なお、virbr0 (NAT)への tap0 接続は仮想マシンへの簡易な ssh アクセスを確保するために実施しています。

$ sudo apt install qemu-kvm libvirt-daemon libvirt-clients bridge-utils virt-manager ovmf
$ qemu-img create -o preallocation=full -f qcow2 guest.qcow2 128G
$ sudo ip tuntap add dev tap0 mode tap
$ sudo ip link set tap0 master virbr0
$ sudo ip link set dev tap0 up
$ sudo qemu-system-x86_64 \
  -enable-kvm \
  -cpu EPYC-v4 \
  -machine q35 \
  -smp cpus=4 \
  -m 8192M \
  -no-reboot \
  -bios /usr/share/qemu/OVMF.fd \
  -device virtio-scsi-pci,id=scsi0,disable-legacy=on,iommu_platform=on \
  -device scsi-hd,drive=disk0 \
  -drive file=ubuntu-24.04-live-server-amd64.iso,media=cdrom \
  -drive file=guest.qcow2,if=none,id=disk0,format=qcow2 \
  -boot d \
  -netdev tap,id=nd0,ifname=tap0,script=no,downscript=no \
  -device virtio-net-pci,netdev=nd0 \
  -nographic \
  -monitor unix:/tmp/monitor.sock,server,nowait \
  -serial mon:stdio

コンソール環境でのインストールを行うため、インストーラ ISO により grub が起動したら "try or install..." で e を押下、下記のようにコマンドラインの一部を変更し、Ctrl + X でブートさせます。

linux /casper/vmlinuz console=ttyS0 ---

インストール完了後はインストーラ ISO を除いた下記のコマンドでシステム起動が行えます。ここで、ホストマシン内の NAT (virbr0) を通じて DHCP での IPアドレス取得が行えることと、インターネットアクセスが確保されていることを確認します。

$ sudo qemu-system-x86_64 \
  -enable-kvm \
  -cpu EPYC-v4 \
  -machine q35 \
  -smp cpus=4 \
  -m 8192M \
  -no-reboot \
  -bios /usr/share/qemu/OVMF.fd \
  -device virtio-scsi-pci,id=scsi0,disable-legacy=on,iommu_platform=on \
  -device scsi-hd,drive=disk0 \
  -drive file=guest.qcow2,if=none,id=disk0,format=qcow2 \
  -boot c \
  -netdev tap,id=nd0,ifname=tap0,script=no,downscript=no \
  -device virtio-net-pci,netdev=nd0 \
  -nographic \
  -monitor unix:/tmp/monitor.sock,server,nowait \
  -serial mon:stdio

3-4-2. Linux カーネル入れ替え

ホスト側で作成した Linux カーネルパッケージをゲスト OS に転送します。

$ scp linux-image-6.8.0-snp-host-05b10142ac6a+_6.8.0-{適宜バージョンを読み替えてください}_amd64.deb {ゲストOS IP}:.
$ scp linux-headers-6.8.0-snp-host-05b10142ac6a+_6.8.0-{適宜バージョンを読み替えてください}_amd64.deb {ゲストOS IP}:.
$ scp linux-image-6.8.0-snp-host-05b10142ac6a+_6.8.0-{適宜バージョンを読み替えてください}_amd64.deb {ゲストOS IP}:.

ゲスト OS にてインストールを行います。

$ sudo dpkg -i linux-image-6.8.0-coconut-svsm-sevsnp+_6.8.0-{適宜バージョンを読み替えてください}_amd64.deb
$ sudo dpkg -i linux-headers-6.8.0-coconut-svsm-sevsnp+_6.8.0-{適宜バージョンを読み替えてください}_amd64.deb
$ sudo dpkg -i linux-libc-dev_6.8.0-{適宜バージョンを読み替えてください}_amd64.deb

今回ビルドした Linux イメージがゲスト OS の起動に使用されるよう、/etc/default/grub の下記設定を書き換えます。

GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 6.8.0-coconut-svsm-sevsnp+"

下記コマンドで設定を適用します。

$ sudo update-grub

ここまでで作成した guest.qcow2 イメージは COCONUT-SVSM vTPM を有効にした SEV-SNP 機密 VM、及び通常の VM、どちらでも起動できる構成となっています。

4. 動作と性能の確認

4-1. ゲスト OS の機密性・完全性の検証

4-1-1. SEV 状態確認

下記コマンドで「カスタムした QEMU コマンド」「 作成した IGVM ファイル(SVSM バイナリとカスタム OVMF バイナリを含む)」「cbit の値」を指定して vTPM を有効にした機密 VM のブートを行えます。

$ sudo ${HOME}/bin/qemu-svsm/bin/qemu-system-x86_64 \
  -enable-kvm \
  -cpu EPYC-v4 \
  -machine q35,confidential-guest-support=sev0,memory-backend=mem0 \
  -smp cpus=4 \
  -object memory-backend-memfd,size=8192M,id=mem0,share=true,prealloc=false,reserve=false \
  -object sev-snp-guest,id=sev0,cbitpos={取得した cbit の値},reduced-phys-bits=1,init-flags=5,igvm-file=${HOME}/coconut/svsm/bin/coconut-qemu.igvm \
  -no-reboot \
  -device virtio-scsi-pci,id=scsi0,disable-legacy=on,iommu_platform=on \
  -device scsi-hd,drive=disk0,bootindex=0 \
  -drive file=guest.qcow2,if=none,id=disk0,format=qcow2 \
  -netdev tap,id=nd0,ifname=tap0,script=no,downscript=no \
  -device virtio-net-pci,netdev=nd0 \
  -nographic \
  -monitor unix:/tmp/monitor.sock,server,nowait \
  -serial mon:stdio

起動後、下記コマンドで AMD SEV-SNP 動作が有効になっていることを確認します。

$ sudo dmesg | grep SEV
[    0.333193] Memory Encryption Features active: AMD SEV SEV-ES SEV-SNP
[    0.447965] SEV: APIC: wakeup_secondary_cpu() replaced with wakeup_cpu_via_vmgexit()
[    0.502538] SEV: SNP running at VMPL2.
[    0.502954] SEV: Using SNP CPUID table, 31 entries present.
[    0.849327] SEV: SNP guest platform device initialized.
[    0.853242] SEV: SNP SVSM VTPM platform device initialized
[    3.071664] sev-guest sev-guest: Initialized SEV guest driver (using vmpck_id 2)

4-1-2. SEV 構成証明の取得と検証

下記コマンドで SEV 構成証明(report.bin)の取得が行えます。

$ sudo apt install -y cargo make libssl-dev
$ git clone https://github.com/virtee/snpguest.git
$ cd snpguest
$ cargo build -r
$ cd target/release
$ sudo ./snpguest report report.bin request-file.txt --random -v {先ほど取得した VMPL 値を入れる}

AMD が配布する署名検証用公開鍵の取得を行います。ARK(AMD Root Key)とASK(AMD Sign Key)はどの環境で取得しても同様ですが、VCEK (Versioned Chip Endorsement Key) は該当マシンの Chip ID を元に発行されるもののため、下記手順でゲスト OS より取得し、snpguest verify コマンドで完全性検証を行います。

$ ./snpguest fetch ca -e vcek der milan certs
$ ls certs
ark.der  ask.der
$ ./snpguest fetch vcek der milan certs report.bin
$ ls certs
ark.der  ask.der  vcek.der
$ ./snpguest verify certs certs
The AMD ARK was self-signed!
The AMD ASK was signed by the AMD ARK!
The VCEK was signed by the AMD ASK

署名検証用公開鍵を用い、構成証明レポートの検証を行います。このコマンドの成功により、このゲスト OS が正しく機密 VM 内で動作していることが検証できます。なお、本来は report.bin を外部の信頼されたシステムに送信し、そこで取得した AMD 公開鍵を用いて行うことが望ましい操作であることに留意ください。

$ ./snpguest verify attestation certs report.bin
Reported TCB Boot Loader from certificate matches the attestation report.
Reported TCB TEE from certificate matches the attestation report.
Reported TCB SNP from certificate matches the attestation report.
Reported TCB Microcode from certificate matches the attestation report.
Chip ID from certificate matches the attestation report.
VEK signed the Attestation Report!

4-1-3. 起動に用いられた IGVM ファイルの完全性検証

SEV 構成証明レポートを下記コマンドで人間が読める形でコンソール出力します。この中で現れる Measurement の値は 「3-3-7. COCONUT-SVSM の準備」で確認した IGVM ファイルのロードを行った時の望ましいハッシュ値と同じになることが期待されるため、これの一致を持って機密 VM 起動に用いられた IGVM ファイル、すなわち COCONUT-SVSM vTPM ソフトウェアと、OVMF が改ざんされていないことを検証できます。

(ホストでの結果再掲)
$ ./igvmmeasure coconut-qemu.igvm measure
===============================================================================================================
igvmmeasure 'coconut-qemu.igvm'
Launch Digest: A3A4D5E40A5D27FD5733930CC95813C861DD8D7077B12585E5E46F10192C679974B8B0AD5979F02E5867FEE41A576FCC
===============================================================================================================
 
$ ./snpguest display report report.bin
---- (省略) ----
Measurement:                
a3 a4 d5 e4 0a 5d 27 fd 57 33 93 0c c9 58 13 c8
61 dd 8d 70 77 b1 25 85 e5 e4 6f 10 19 2c 67 99
74 b8 b0 ad 59 79 f0 2e 58 67 fe e4 1a 57 6f cc
---- (省略) ----

4-1-4. vTPM のセットアップ

vTPM がゲスト OS に認識されていることを確認します。ConfigFS 上では /sys/class/tpm/ 以下に tpm0 (数値は環境によって変化)が出現することで認識されます。

$ sudo dmesg | grep TPM
[    0.000000] efi: TPMFinalLog=0x7f3f7000 SMBIOS=0x7f13f000 SMBIOS 3.0=0x7f13d000 ACPI=0x7f37d000 ACPI 2.0=0x7f37d014 MEMATTR=0x7d3df318 MOKvar=0x7f139000 INITRD=0x7d3de698 TPMEventLog=0x7d2c8018 Unaccepted=0x7f37eb18
[    1.025631] SEV: SNP SVSM VTPM platform device initialized
[    1.117423] tpm tpm: TPM 2.0 platform device
[    2.709814] systemd[1]: systemd 255.4-1ubuntu8.1 running in system mode (+PAM +AUDIT +SELINUX +APPARMOR +IMA +SMACK +SECCOMP +GCRYPT -GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 -PWQUALITY +P11KIT +QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD -BPF_FRAMEWORK -XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified)
[    3.040438] systemd[1]: systemd-pcrextend.socket - TPM2 PCR Extension (Varlink) was skipped because of an unmet condition check (ConditionSecurity=measured-uki).
[    3.152876] systemd[1]: systemd-pcrmachine.service - TPM2 PCR Machine ID Measurement was skipped because of an unmet condition check (ConditionSecurity=measured-uki).
[    3.159572] systemd[1]: systemd-tpm2-setup-early.service - TPM2 SRK Setup (Early) was skipped because of an unmet condition check (ConditionSecurity=measured-uki).

vTPM 内には当 VM の終了までの間だけ有効なシード値が既に生成されているので、それをもとに EK (Endorsement Key) ペアを生成します。EKpriv (EK秘密鍵)は vTPM のレジスタ(0x81000000)にのみ保持されており、そのペアとなる EKpub(EK公開鍵)は手元に ek.pub ファイルという形で生成されます。

今回この EKpub (EK公開鍵)は既に信頼されたものとして取り扱いますが、2-5 で述べたように本来は vTPM に対して SEV-SNP 構成証明レポートをリクエストし、その中に含める形で受け取ることが望ましいものとなります。なお、これ以後使用する tpm2-tools ユーティリティ群の使用法は Remote Attestation With Tpm2 Tools 19などを参考にして進めます。

$ sudo tpm2_createek \
  --ek-context=0x81000000 \
  --key-algorithm=rsa \
  --public=ek.pub

vTPM からの応答は EK ではなく、EK によって検証された AK(Attestation Key, もしくは Attestation Identity Key とも)によって署名されますので、続けて AK の作成を行います。

$ sudo tpm2_createak \
  --ek-context=0x81000000 \
  --ak-context=ak.ctx \
  --key-algorithm=rsa \
  --hash-algorithm=sha256 \
  --signing-algorithm=rsassa \
  --public=ak.pub \
  --ak-name=ak.name
loaded-key:
name: 000b410c3bd19a9b0a12192b0fc56a36009cf0d44c58fac2ec53f553b5d1f17fddd6
qualified name: 000b323723a8b14d3418ddd16d6630c1fcf62365cba8cb798929d7c0c299ab677380

EK からの信用チェーンに AK を乗せるため、ak_secret ファイルにチャレンジ用のデータを入力し、AKpub(AK公開鍵)及び EKpub (EK公開鍵)で暗号化(tpm2_makecredential)したのち、これを vTPM に送信して EKpriv(EK秘密鍵)及び AKpriv(AK秘密鍵)にて復号(tpm2_activatecredential)させます。チャレンジ用の文字列 (ak_secret)と、vTPM によってデコードさせた actcred.out が同じ内容であることによって、EKpub の信用によって AKpub が通信経路で改ざんされていないことを証明させます。

この手順は Narayanan論文 の Figure 3: Remote attestation of a confidential VM using kelime and SVSM-vTPM を参考に構築しており、当該文献では予め信頼された外部システムで実行される Keylime Registrar によって自動化された手順であるところを、利用者の手作業によって代えたものです。 AKpub/EKpub による暗号化も、本来はゲスト OS 上での実行ではなく、外部の信頼されたシステム上で行うことが望ましいことに注意下さい。

$ dd if=/dev/urandom of=ak_secret bs=16 count=1
$ sudo tpm2_makecredential \
  --public=ek.pub \
  --secret=ak_secret \
  --credential-blob=mkcred.out \
  --name=$(sudo cat ak.name | xxd -p -c $(stat --printf="%s" ak.name))
$ sudo tpm2_startauthsession --policy-session -S session.ctx
$ sudo tpm2_policysecret -S session.ctx -c e
$ sudo tpm2_activatecredential \
  -c ak.ctx \
  -C 0x81000000 \
  -i mkcred.out \
  -o actcred.out \
  -P "session:session.ctx"
$ sudo tpm2_flushcontext session.ctx
$ sudo diff ak_secret actcred.out

4-1-5. Measured Boot の結果確認

ここまでの準備によって、vTPM からの応答に付与された署名を AKpub(AK 公開鍵)検証することが可能となりますので、早速ブートプロセスで記録したハッシュ値などを記録している PCR (Platform Configuration Register)Quote をtpm2_quote で取得します。

応答が途中で改ざんされていないことの検証のため、付与された電子署名 pcr_quote.signature を tpm2_checkquote で AKpub(AK公開鍵)を用いて検証します。tpm2_checkquote コマンドが正常終了することで vTPM からの応答が途中で改ざんされていないことを保証できます。説明上ゲスト OS 上で両コマンドを実行していますが、本来は tpm2_checkquote を信頼された外部システムにて行うことが必要です。

ここで出てくる PCR の値は UEFI ファームウェアの更新、GRUB ブートローダの更新、Linux カーネルの更新、ブートパラメータの変更などがあった際には全く違うものとなるため、リファレンスとなるプラットフォームでの値を記録しておき、それと同じとなっているかを確認するという手順になります。

計算方法の例として、PCR 9 番には OVMF 以後にブートされる Linux Kernel、Initramfs、及びそのブートに使用されたパラメータ群などをハッシュ化したものを順番に Extend と呼ばれる操作で結合したものが格納されます。値が同じであることが確認できた時、これまでの手順を合わせて当機密 VM の機密性・完全性を全て確認できたこととなります。

$ dd if=/dev/urandom of=service_provider_nonce bs=16 count=1
$ sudo tpm2_quote \
  --key-context ak.ctx \
  --pcr-list sha1:0,1,2,3,4,5,6,7,8,9 \
  --message pcr_quote.plain \
  --signature pcr_quote.signature \
  --qualification service_provider_nonce \
  --hash-algorithm sha256 \
  --pcr pcr.bin
quoted: ff54434780180022000b323723a8b14d3418ddd16d6630c1fcf62365cba8cb798929d7c0c299ab6773800010385dcfe8ab297d6a74ff3cf1e3278f390000000000ac16ae000000010000000001201706190016363600000001000403ff03000020cc0de4d2d704a9ad47a72eb7e795d26281bb15492a5dfc7f85e76a4f267acb9b
signature:
  alg: rsassa
  sig: 11b1218978757cb8f41c56ff5fb909933d1e1e79b42531c24891734cd40ef924cdfbc01aea0324d2ca977decf558ff71a0c7ac0365ec3943a6458fe5e0d09c832d7b0782d4f8b60207af753cc4001f110ce25d6da4542a9701e360fe49fc8642fff8a43eaeb79ad2076ec7af3a299e1c23bcd099b0316576488348f98b480429b489802ba429c8e7416683d2ca0fb5d38402f772400a3e3057915367e41262c4eb8da2fdc6ad3c453b62f75c7690b45398f7321ee4bc3c8cabbacbfa0fd7b8070f675266e84cf16df2f222b4a9f773ff7b31ef627e77f4d146f10382f01fa4cba4afdc35251b923911f14ddcc9f34249323887d532efcb9f2f45c20348b7aa33
pcrs:
  sha1:
    0 : 0x1A9995D2E91C691AEF5FC31402EF148282A3F3E0
    1 : 0xD7CB1339ABD7102B96DD3065D7A4F9B855D11627
    2 : 0xB2A83B0EBF2F8374299A5B2BDFC31EA955AD7236
    3 : 0xB2A83B0EBF2F8374299A5B2BDFC31EA955AD7236
    4 : 0x175F4319FD7AC683BF49F2E7B837630E4FA8603F
    5 : 0xAF89C2B1B2BD820136F21212B995E1A09FDBBA5F
    6 : 0xB2A83B0EBF2F8374299A5B2BDFC31EA955AD7236
    7 : 0x1DBFFD353397AFBE91B5F90BFC53AF84D3E6B234
    8 : 0x7DDA10A3335D4D2740EF136CF8CE24231F6607D0
    9 : 0x55BD91ECD760C07984E5A1AF58C772F13525CD28
calcDigest: cc0de4d2d704a9ad47a72eb7e795d26281bb15492a5dfc7f85e76a4f267acb9b
 
$ sudo tpm2_checkquote \
  --public ak.pub \
  --message pcr_quote.plain \
  --signature pcr_quote.signature \
  --qualification service_provider_nonce
sig: 11b1218978757cb8f41c56ff5fb909933d1e1e79b42531c24891734cd40ef924cdfbc01aea0324d2ca977decf558ff71a0c7ac0365ec3943a6458fe5e0d09c832d7b0782d4f8b60207af753cc4001f110ce25d6da4542a9701e360fe49fc8642fff8a43eaeb79ad2076ec7af3a299e1c23bcd099b0316576488348f98b480429b489802ba429c8e7416683d2ca0fb5d38402f772400a3e3057915367e41262c4eb8da2fdc6ad3c453b62f75c7690b45398f7321ee4bc3c8cabbacbfa0fd7b8070f675266e84cf16df2f222b4a9f773ff7b31ef627e77f4d146f10382f01fa4cba4afdc35251b923911f14ddcc9f34249323887d532efcb9f2f45c20348b7aa33

備考として、tpm2_eventlog コマンドを活用することで PCR 値の変動などを含むイベントログを vTPM から収集することができます。この中には Linux Kernel のハッシュ値やブートパラメータの値などが個別に記録されています。

$ sudo sha1sum /boot/vmlinuz-6.8.0-coconut-svsm-sevsnp+
271cfb16deaaca64fe42f7fc4b7d1a8691d6a3d6  /boot/vmlinuz-6.8.0-coconut-svsm-sevsnp+
$ sudo tpm2_eventlog /sys/kernel/security/tpm0/binary_bios_measurements
---- (省略) ----
- EventNum: 113
  PCRIndex: 9
  EventType: EV_IPL
  DigestCount: 3
  Digests:
  - AlgorithmId: sha1
    Digest: "271cfb16deaaca64fe42f7fc4b7d1a8691d6a3d6"
  - AlgorithmId: sha256
    Digest: "363951fd7db397dd8881618fe1abd7db0613a37c998843d9a04be4de9ca7b69d"
  - AlgorithmId: sha384
    Digest: "7918eb4bbdc1443867c37998674441bfe4a7471d2e42f8e35f33e13006f090683548fb1abd0c84a19df9e722f5751dfe"
  EventSize: 41
  Event:
    String: "/boot/vmlinuz-6.8.0-coconut-svsm-sevsnp+\0"
---- (省略) ----

4-2. 実際の暗号化が行われていることの確認

SEV-SNP 構成証明レポートを取得することでゲスト OS のメインメモリが機密 VM 内で暗号化されていることは確認できていますが、実際にホスト OS から VM メインメモリのダンプを取ることによって実際に確認してみます。試験用には Using AMD Secure Memory Encryption with Oracle Linux20に示されているような、暗号化対象となっている機密 VM のメインメモリの範囲にのみ秘密情報を置くプログラムを準備します。

当プログラムで生成した文字列は標準出力などには出力しないようにしています。これは QEMU を実行しているホストのコンソールログ、virtio-blk の共有バッファなどは機密 VM の中ではなくホスト OS ・ゲスト OS で共有されたメモリ空間の中に置かれるためであり、QEMU の VM メモリダンプ機能ではその部分も合わせて取得されてしまうためです。

#include <stdio.h>
#include <stdlib.h>
main(int argc, char *argv[])
{
    char str[32];
    int secret = -1;
    if (argc > 1)
        secret = atoi(argv[1]);
    sprintf(str, "My secret is %d\n", secret);
    sleep(10000);
}

上記コードを下記のようにゲスト OS でコンパイルし、好きな数値を引数として入力して実行するとしばらくの間 sleep に入って動作を停止します。

$ gcc test.c
$ ./a.out 8492 &

その間にホスト OS 側で QEMU を起動しているコンソールとは別のコンソールから、QEMU Monitor の仕組みを用いて動作している QEMU に接続、メモリダンプのコマンドを発行したのち、そのダンプファイルの中に特定の検索用文字列が出現するかをチェックします。暗号化を行っていない VM の場合は、下記のようにテストコマンドに入力した数値が検出されます。

$ sudo nc -U /tmp/monitor.sock
QEMU 8.2.0 monitor - type 'help' for more information
(qemu) dump-guest-memory guest-memory-raw.bin
(qemu) quit
quit
 
$ sudo strings guest-memory-raw.bin | grep "My secret"
My secret is %d
My secret is 8492
My secret is %d

暗号化が行われているとき、下記のような出力になり、テストコマンドに入力した値は正しく暗号化されて検索できなくなっていることが確認できました。

$ sudo nc -U /tmp/monitor.sock
QEMU 8.2.0 monitor - type 'help' for more information
(qemu) dump-guest-memory guest-memory-enc.bin
(qemu) quit
quit
 
$ sudo strings guest-memory-enc.bin | grep "My secret"
My secret is %d
My secret is %d

4-3. ASID の限界まで VM が起動することの確認

ASID は独立した暗号鍵によって保護された VM のメモリ領域と1対1で紐づく ID であり、今回使用した環境では最大で 509 ID までが設定可能でした。また、マザーボード BIOS にて SEV-ES ASID Space Limit Control の設定を行うことで、実際に使用可能な上限の値を設定可能でした。

当試験ではこの値を 10 に設定し、複数のコンソールで異なるゲストを複数ブートさせることで正しく上限が設定されるかをテストしました。

qemu-system-x86_64: sev_kvm_init: failed to initialize ret=-16 fw_error=0 ''
qemu-system-x86_64: failed to initialize kvm: Operation not permitted

その結果、9台目の SEV-SNP 機密 VM までは正常にブートするものの、10台目の起動を行おうとすると上記メッセージにより qemu-system-x86_64 コマンドがエラー終了する結果となりました。一方、9台まで機密 VM が起動している状態で通常の VM を起動した場合、問題なく10台目を起動することが可能です。

4-4. 性能試験

コンピューティングにおいて暗号化処理を行うことは一般に性能低下が避けられないものです。現代においては暗号化アルゴリズムが専用のハードウェア回路として、CPU に負荷を掛けないように実装されることも一般的ですが、それでも暗号化のレイテンシは完全には無視できず、メインメモリのように 10~100 ナノ秒オーダでの応答(参考:21) が期待される装置を暗号化する場合の影響は不可避と思われます。

また、SEV-ES 以降の機密 VM における VMExit によるコンテキストスイッチは、仮想 CPU のレジスタ群をホスト OS から暗号化した状態のまま取り扱えるよう、一旦 VC# 例外を発生させ、必要な処理を行った後に新設された VMGEXIT 命令で改めて VMExit を発生させる仕組み(参考 : 22 23)となっており、コンテキストスイッチに関連する性能低下の可能性も考えられます。

既に Performance Evaluation of AMD SEV 24 などで AMD SEV / SEV-ES 機能を用いた機密 VM の性能試験が試行されており、①CPU ネックの処理(コンパイル)では数%程度の性能低下、②メモリ・IOネックの処理(データベースや圧縮処理など)では 8~9 %の性能低下、③ストレージ IOPS、平均レイテンシの観点では 20% 程度、Sequential な読み取り帯域幅に限っては 50% 以上の大きな低下がある、といった点が報告されています。

当記事では Performance Evaluation of AMD SEV でも今後の取り組みとされている、SEV-SNP 下で VMPL による分離と SVSM による VMPL 間通信を有効にした機密 VM の起動を行っているので、簡単にこれら性能の追試を行いました。

なお、前項までの考察から既に「SVSM の導入自体は vTPM 等を保護されたメモリ空間で実行する」ことが主軸であり、機密 VM の動作原理そのものへの大きな変更はなされていないため、おおむね先行した測定結果と類似した傾向となることが予想されます。

4-4-1. 項目と動作条件

比較対象となる通常 VMと今回作成した機密 VM は当記事で使用した同一のホストマシン上で動かすものとし、詳細な仕様は下記の通りとします。測定回数は各1回です。

通常VM機密VM
ホスト
CPU
機密VMと
同じ
AMD EPYCTM 7313P Processor
(16-core, 32-threads)
ホスト
Memory
機密VMと
同じ
Registered DDR4-3200
16GiB x 8
ホスト
Storage
機密VMと
同じ
NVMe U.2 SSD x2
(mdraid-1)
ホスト
マザーボード
機密VMと
同じ
Supermicro HH12SSW-NTR
(BIOS version 2.6a / CPLD Version F0.A3.4B)
マザーボード
BIOS
SMEE 有効
無効有効
ホストOS
Linux
Kernel
バージョン
Linux
6.8.0-36
-generic
※1
Linux 6.8.0-coconut-svsm-sevsnp+
https://github.com/coconut-svsm/linux
branch:svsm (commit: bc4de28)
QEMU
バージョン
QEMU
emulator
v8.2.2
※1
QEMU emulator version 8.2.0
(v8.2.0-81-g260df2b36b-dirty)
https://github.com/coconut-svsm/qemu
branch:svsm-igvm (commit: 260df2b)
vTPM不使用https://github.com/coconut-svsm/svsm
branch:main (commit: be9d426)
OVMF
バージョン
2024.02-2
※1
https://github.com/coconut-svsm/edk2
branch:svsm (commit: d965a1bd)
ゲスト
vCPU数
機密VMと
同じ
4
ゲスト
Memory
機密VMと
同じ
8 GiB
ゲスト
Storage
機密VMと
同じ
virtio-scsi-pci (128GB)
ゲスト
Network
機密VMと
同じ
virtio-net-pci
(ホスト内の virbr0 ブリッジに接続)
ゲストOS
Linux
Kernel
バージョン
Linux
6.8.0-36
-generic
※1
Linux 6.8.0-coconut-svsm-sevsnp+
https://github.com/coconut-svsm/linux
branch:svsm (commit: bc4de28)
システム
負荷状況
機密VMと
同じ
・ゲスト VM はテスト対象1つのみ
・ホストはアイドル状態
表2:比較対象とする VM のセットアップ条件

※1: Ubuntu Server 24.04 LTS 標準パッケージ

当記事では Ubuntu に含まれる sysbench ユーティリティを用いた単純な CPU / メモリ性能のテストから始まり、CPU ネックな処理として Linux カーネルのコンパイル時間の測定、メモリ・IOネックの処理として sysbench を用いた TPC-C ライクな DB ワークロードを処理させる試験、iperf を用いたネットワーク性能試験の大きく4項目を行いました。これら下記にまとめます。

sysbench CPU

`$ sysbench cpu run --time=60 --threads={vCPU数}` を実行し、秒間実行 event 数を測定します。(高いほどよい)

sysbench Memory

`$ sysbench memory run --memory-total-size=0 --time=60 --threads={vCPU数}` を実行し、平均転送速度を測定します。(高いほどよい)

Kernel Build

本記事で用いた Linux Kernel (linux 6.8.0 based svsm branch (bc4de28) ) のコンパイル環境を準備し、config が済んだ後の `$ make -j {vCPU数}` に掛かった実時間を測定します。(低いほどよい)

sysbench TPC-C like

システムに MySQL をセットアップ、https://github.com/Percona-Lab/sysbench-tpcc を元に tables=4、warehouses=40 のテストデータを準備し、スレッド数 {vCPU数 / 2}、600 秒間測定を実施、秒間トランザクション数の平均を記録します。(高いほどよい)

詳しいコマンド列を下記に記載します。

$ sudo apt install mysql-server libmysqlclient-dev
$ git clone https://github.com/Percona-Lab/sysbench-tpcc.git
$ sudo mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '{password}';"
$ mysql -h localhost -u root -p -e "GRANT ALL PRIVILEGES ON *.* TO root@localhost;"
$ mysql -h localhost -u root -p -e "FLUSH PRIVILEGES;"
$ mysql -h localhost -u root -p -e "create database sbt;"
$ ./tpcc.lua --mysql-host=127.0.0.1 --mysql-user=root --mysql-password={password} --mysql-db=sbt --tables=4 --scale=40 --threads=4 prepare
$ ./tpcc.lua --mysql-host=127.0.0.1 --mysql-user=root --mysql-password={password} --mysql-db=sbt --tables=4 --scale=40 --time=600 --threads=2 --report-interval=30 run
iperf

ホスト OS で `$ iperf3 -s`、ゲスト OS で `$ iperf3 -c 192.168.122.1 -t 60`、`$iperf3 -c 192.168.122.1 -t 60 -R` を順に実行し、「guest -> host 転送」 Gbps、「host -> guest 転送」 Gbps として記録します。(高いほどよい)

fio

下記コマンドを順に実行し、128k Seq. Read MiB/s、128k Seq. Write MiB/s,  4k Rand ReadWrite IOPS を記録します。(高いほどよい)

$ sudo fio --group_reporting --name=test --direct=1 --norandommap --bs=128k --rw=read --iodepth=1 --numjobs=1 --time_based --ramp_time=10 --runtime=60 --size=4GB --filename=/fio.img
$ sudo fio --group_reporting --name=test --direct=1 --norandommap --bs=128k --rw=write --iodepth=1 --numjobs=1 --time_based --ramp_time=10 --runtime=60 --size=4GB --filename=/fio.img
$ sudo fio --group_reporting --name=test --direct=1 --norandommap --bs=4k --rw=randrw --rwmixread=50 --iodepth=1 --numjobs=4 --time_based --ramp_time=10 --runtime=60 --size=4GB --filename=/fio.img

4-4-2. 測定結果

sysbench
CPU
(events/s)
sysbench
Memory
(MiB/s)
Kernel Build
elapsed time
(min. sec.)
通常 VM16801.89
(4 threads)
7234.19
(4 threads)
65m44.549s
(make -j4)
機密 VM16725.94
(4 threads)
7305.38
(4 threads)
67m44.723s
(make -j4)
(参考)
機密 VM の

性能低下差分
(%)
ほぼなしほぼなし3.0%
表3 : 性能測定結果と機密 VM の性能差分
sysbench
TPC-C like
(trans/s)
fioiperf
通常 VM157.16
(2 threads)
・128k seq. read :
 1150MiB/s
・128k seq. write :
 669MiB/s
・4k randrw :
 r=36.9k IOPS
 w=36.9k IOPS
・guest -> host :
 24.1 Gbps
・host -> guest :
 16.8 Gbps
機密 VM145.76
(2 threads)
・128k seq. read :
 775MiB/s
・128k seq. write :
 610MiB/s
・4k randrw :
 r=31.0k IOPS
 w=31.0k IOPS
・guest -> host :
 21.3 Gbps
・host -> guest :
 16.9 Gbps
(参考)
機密 VM の

性能低下差分
(%)
7.3%・128k seq. read :
 33%
・128k seq. write :
 9%
・4k randrw :
 16%
・guest -> host :
 12%
・host -> guest :
 ほぼなし
表4 : 性能測定結果と機密 VM の性能差分(続)

4-4-3. 性能面の考察

詳しい分析を伴わない推定となりますが、ストレージ IO やホストOS <-> ゲストOS 間でのメモリコピーの際の性能低下が比較的大きいことから、ゲスト OS のシステムコールに際してコンテキストスイッチを処理する機構が機密 VM を使用する際の性能ペナルティの大きな割合を占めており、データベースやネットワークなど、外部とのデータやり取りが主となるワークロードを苦手とする可能性が考えられます。

これらの用途に使用する場合は、クラウド事業者基盤に信用をおくことを許容し、通常 VM をあえて採用するモチベーションもあると言えるでしょう。また、今回は FDE を有効化しての測定を行っていないため、実使用ではその差分が課題となる可能性もあります。

一方、コンピューティングを中心とした使い方に限れば大きな性能低下を感じることはなさそうです。サイバー攻撃等が多発する昨今のクラウド環境においては、クラウド事業者側で機密 VM をデフォルト有効で提供することで、不意の情報流出のリスクを抑えられる可能性もあると考えられます。

万一ホスト OS が侵害されたとして、ゲスト OS ごとにブートプロセスの個別の改ざんを行うようなサイバー攻撃は複雑なものとなるため、利用者からはシンプルにゲスト OS のメモリ暗号化がされていることを確認するだけでも、ある程度の保護を得られる可能性があります。

5. クラウドとして活用していくために

当記事ではここまで物理マシンを用いての手順を検証してきましたが、クラウドとして提供された機密 VM があった場合、利用者はどのような点に気を付けて活用していけばよいでしょうか。下記に例示する内容は物理マシンでの手順に置き換えたものですので、実際には各社のサービス仕様を読み込み、相当する操作に置き換えて実行する必要があることに留意ください。

5-1. ファームウェアとゲスト OS イメージのハッシュ値確認

通常 IaaS 型のクラウドサービスとして提供される VM において、「VM の起動に用いられるファームウェア」の内容が利用者に提供されているケースは少ないものと思われます。しかし、「4-1. ゲスト OS の機密性・完全性の検証」で述べたように、機密 VM の機密性・完全性検証において「VM 起動に用いられるファームウェアの確認」は大事な一手順です。

幸いなことに、今回使用した AMD EPYCTM Processor ベースの環境で QEMU/KVM などを用いた仮想化基盤を構築した場合、VM 起動に用いるファームウェアはオープンソースソフトウェアが元となる可能性が高いものとなります。OSS の性質上、そのソースコードは Web 上でホスティングされていることが多いものであり、クラウド事業者としても実際にサービスに使用しているソースコードのバージョン、コンパイル環境などを公開しやすいものと考えられます。

これは一例ですが、仮にクラウド事業者にて「実際に VM の起動に使用している BIOS ファームウェアのソースコード、コンパイル環境、コンパイル後のハッシュ値」が公開されている環境が提供された場合、利用者は手元でもそのコード内容をレビューして悪意のあるコードが含まれていないか確認したのち、同じ環境でコンパイルしてハッシュ値が一致することを確認できれば、最後に入手した機密 VM 環境内からの構成検証レポート取得により間違いなくそのファームウェアが使用されていることが確認できるでしょう。

ゲスト OS イメージについてはこれより少し複雑です。というのも VM の BIOS ファームウェアと異なりゲスト OS は「利用者責任で管理」するものであり利用者ごとに環境は千差万別であること、また OS は日々セキュリティ面を含めたアップデートが提供されること、OS そのもののコードを全てレビューするようなことはあまりに膨大で非現実的と考えられるためです。

現実的な手段としては、Linux ディストリビューションからの公式イメージは信頼するものとしてそれを利用者にてダウンロード、検証に用いるソフトウェア等を加えた状態で OS イメージを作成し PCR 値などの Measured Boot で用いられる値を取得、その後にクラウド事業者の提供する「カスタム OS イメージのアップロード機能」を通してアップロードして使用するなどが適当でしょう。

なお、ブート環境の違いによって PCR 値が変わる可能性があるため、手元での環境での理想 PCR 値の取得が適切ではない可能性も考えられます。その場合、PCR 値の検証の他に、TPM から取得できる個別のイベントリスト内で Linux Kernel などの主要なソフトウェアのハッシュ値のみを検証するなど、ある程度完全性の検証を妥協しつつも合理的な範囲で確認を行うようなアーキテクチャも考えられます。

5-2. 検証手順の自動化

「4-1. ゲスト OS の機密性・完全性の検証」で行った手順は手作業の煩雑な手順であり、リソースのリクエスト後すぐに VM の割り当てが行われる IaaS 型クラウドサービスで実施するにはその利便性を損なってしまうものです。実際にはこれは外部の信頼されたシステムにおいて動作する自動化ソフトウェアなどから実行することが利便性向上には望ましいでしょう。例として python スクリプトから SSH によって機密 VM にログインし、検証完了までを自動化した例を作成しましたので、参考までにご利用下さい。25

5-3. 外部の信頼されたシステムと利用者鍵管理の考え方

検証手順で用いられ、また FDE の鍵を保管する「外部の信頼されたシステム」とは実際の所どのように構築すべきなのでしょうか?少なくとも当記事で話題にしている「クラウド事業者が侵害されるリスク」に対しては、利用者の管理下にあるオンプレミスのコンピュータなどは利用者による正しい運用が行われている限り「信頼されたシステム」とみなしてもよいでしょう。

ここで、FDE 等に用いられる暗号鍵を利用者責任で管理する方式は昨今「利用者鍵管理」と呼ばれる文脈で議論されており、各クラウドサービスでも利用者鍵管理を提供するケースが出てきています。但し、データの暗号化における利用者鍵管理について 26でも触れられているように、利用者鍵管理の実装方式の一つである BYOK (Bring Your Own Key)方式は「利用者が鍵を生成し、それをクラウド事業者に渡して管理する」のみに過ぎず、仮に「クラウド事業者が使用している鍵生成方式が適切ではない」場合に利用者にてそれを補完できる可能性があるものの、本稿でも話題にしている「クラウド事業者のシステム基盤が侵害された場合のリスク」を回避することはできません。

なお、鍵管理においては総当たり攻撃などに対する対策のために定期的な鍵の再生成が有効な場合があり、クラウド事業者によっては定期的な鍵の再生成機能を提供している場合もあります。BYOK においては鍵の再生成も利用者の責任やスケジュールにて行う必要があるため、そのスケジュールが適切に実行されない場合は「クラウド事業者に暗号鍵生成管理を全て委託する」モデルよりもセキュリティレベルとして下がる可能性があることに注意が必要です。

データの暗号化における利用者鍵管理について では BYOK 方式と対になる概念として HYOK (Hold Your Own Key)方式が紹介されています。これは暗号鍵の生成、保管ともにクラウドサービスとは外部の利用者管理のシステムにて管理するという概念であり、それは本稿での FDE の鍵保管に用いる「外部の信頼されたシステム」と同等と考えられます。

HYOK の実装方式の一例は利用者管理のシステム内にいわゆる KMS (Key Management Service) を構築することであり、単に暗号鍵を平文でシステム内に保存するのではなく、KEK (Key Encryption Key, いわゆるマスターキー) で暗号化した状態で保存すること、そのマスターキーは HSM (Hardware Security Module) と呼ばれる耐タンパ性のある装置内で生成し、HSM の外部(勿論 KMS に対しても)に平文の状態では取り出せない構成とするものです。

KMS 及び HSM はこの「クラウドサービスにおける鍵保管」に用いる点では必ずしも高い性能を必要とするわけではないため、小型のコンピュータ(例えば Raspberry Pi など)と小型で安価な HSM(YubiHSM27 など)などで構成するようなことも可能と思われます。

当記事に続く発展課題として、クラウド事業者の機密コンピューティングサービスと組み合わせて使える手軽な HYOK 用の KMS を構築する方法を検討したいと考えています。

6. まとめ

当記事では、広く利用されている IaaS 型クラウドサービスを責任共有モデルの下で利用する際に残留する「クラウド事業者が侵害された時のリスク」と、それを補完するために利用者の新たな選択肢となる可能性のある「機密コンピューティング」を話題とし、その一つの実装方式である機密 VM を物理マシンの上で実際に実行し、その機密性・完全性を検証する手順をご紹介しました。

一部未実装のためスキップした手順を除いて、オープンソースで提供されるツールチェイン群を用い、あくまで利用者の立場で検証を行い、検証が完了した後に OS のルートファイルシステム暗号化を解除する手順とすることで実際にリスク回避が行えることを示しました。

さらに構築した機密 VM に対して性能測定を行い、ワークロード種別ごとに通常 VM に対してどの程度の性能低下があるかの一例を示しました。最後にこの知識を用いて各社が提供する「機密コンピューティング」 IaaS 型クラウドサービスを正しく活用するための知見についてご紹介しました。

今後ともこれら知見のより正確化と適切な発信を行うことで、クラウドサービスを利用する方がより手軽に、より安全なコンピューティング環境を利用できるようにしていきたいと考えています。

引用文献

  1. ''クラウドコンピューティングのためのセキュリティガイダンス v4.0,'' 一般社団法人日本クラウドセキュリティアライアンス(CSA ジャパン) . ↩︎
  2. "約款," さくらインターネット. ↩︎
  3. ''AMD Secure Encrypted Virtualization (SEV),'' Advanced Micro Devices, Inc. ↩︎
  4. ''Intel® Trust Domain Extensions (Intel® TDX),'' Intel Corporation. ↩︎
  5. ''Disk Encryption,'' Wikipedia, (last edited on 15 May 2024, at 23:48 (UTC).) ↩︎
  6. ''VirTEE : A Community for building Virt-based TEEs,'' VirTEE. ↩︎
  7. ''SEV-SNP Platform Attestation Using VirTEE/SEV,'' Advanced Micro Devices, Inc. ↩︎
  8. ''snpguest (branch: main),'' github.com/virtee ↩︎
  9. ''Boot with TPM: Secure vs Verified vs Measured,'' github.com/tpm2dev/tpm.dev.tutorials. ↩︎
  10. ''Secure VM Service Module for SEV-SNP Guests,'' Advanced Micro Devices, Inc. ↩︎
  11. ''svsm (branch: main)'', github.com/coconut-svsm ↩︎
  12. ''TPM Key Attestation'', Microsoft Corporation. ↩︎
  13. V Narayanan, et al., ''Remote attestation of confidential VMs using ephemeral vTPMs,'' Proceedings of the 39th Annual Computer Security Applications Conference 2023. ↩︎
  14. ''[svsm-devel] [PATCH v5 00/13] Provide SEV-SNP support for running under an SVSM,'' Linux kernel Lore.
    ↩︎
  15. ''AMDSEV (branch: snp-latest),'' github.com/AMDESE. ↩︎
  16. ''INSTALL.md,'' github.com/coconut-svsm/svsm. ↩︎
  17. ''Rustup.rs,'' official Rust project. ↩︎
  18. ''AMD Secure Encrypted Virtualization (AMD-SEV) Guide,'' SUSE. ↩︎
  19. ''Remote Attestation With Tpm2 Tools,'' tpm2-software community. ↩︎
  20. ''Using AMD Secure Memory Encryption with Oracle Linux,'' Oracle Corporation. ↩︎
  21. 星野喬, ''10分で分かるデータストレージ,'' サイボウズ・ラボ. ↩︎
  22. 瀧口和樹, et al., "AMD SEV-ES によるネストした VM の保護.", 研究報告システムソフトウェアとオペレーティング・システム (OS) 2023.11 (2023): 1-10.  ↩︎
  23. ''SEV-ES Guest-Hypervisor Communication Block Standardization,''Advanced Micro Devices, Inc. ↩︎
  24. R. Castellotti, ''Performance Evaluation of AMD SEV'', rcastellotti.dev. ↩︎
  25. ''SEV-SNP / COCONUT-SVSM Remote Attestation Demo,'' gist.github.com/chibiegg ↩︎
  26. ''データの暗号化における利用者鍵管理について,'' 一般社団法人日本クラウドセキュリティアライアンス(CSA ジャパン). ↩︎
  27. ''YubiHSM2,'' Yubico. ↩︎

共著