IBM Cloud: vSphere 7.0U3 + AMD SEV-ESを使ったConfidential Computing

# 1. はじめに

IBM CloudのClassic Infrastructureでは、Intel CPUだけでなく、AMDのCPUも利用できる。vSphere 7.0では、SEV-ES (Secure Encrypted Virtualization-Encrypted State) というCPU自身が持つハードウェア機能を用いて、ゲスト OS のメモリおよびレジスタの状態を暗号化して保持することで、ハイパーバイザーからのアクセスから保護することができる。VMレベルでのメモリおよびレジスタの暗号化を実施してくれるので、アプリケーションの改変が不要であるのも魅力的である。

本稿ではIBM CloudのClassic Infrastructureを利用して、AMD SEV-ESを有効化したゲストOSを準備する手順を紹介する。

参考資料

- https://blogs.vmware.com/vsphere/2020/09/vsphere-7-update-1-amd-sev-es.html
- https://lenovopress.lenovo.com/lp1545.pdf
- https://docs.vmware.com/jp/VMware-vSphere/7.0/com.vmware.vsphere.security.doc/GUID-F1F913CB-05F9-4D4F-B8A7-970A43532003.html
- https://www.amd.com/en/developer/sev.html

# 2. 用語


- SME(Secure Memory Encryption)
    - CPUやデバイスがメモリにデータを書き込む時に暗号化し、メモリからデータを読み込む時に復号する。
    - 暗号化・復号化はメモリコントローラー（ハードウェア）で行う。
    - どのアプリケーションもSMEの保護対象となり、完全な透過性がある。
- SEV(Secure Encrypted Virtualization)
    - VMのメモリの透過的な暗号化を可能にする技術。
    - VMを暗号化する鍵は、AMDセキュアプロセッサーによって管理され、VMごとに個別に割り当てられる。よって、暗号化されたVMのメモリはそのVM内部でのみ復号可能となる。
    - VMのメモリは暗号化するが、CPUレジスタなどの状態は暗号化されない。CPUがあるVMでの実行を停止して、コンテキストスイッチを行って別の処理を行う際には、CPUレジスタの内容がハイパーバイザーのメモリにコピーされる。よって、攻撃者はハイパーバイザー上の暗号化されていない機密データにアクセスできる可能性がある。SEVだけではこうした危険は防げない。
- SEV-ES(Secure Encrypted Virtualization – Encrypted State)
    - SEVの拡張機能。
    - CPUレジスタの状態も暗号化する（CPU内部で使用されるデータも暗号化される）。
   

# 3. 前提条件のまとめ

- CPU
    - AMD SEV-ESでサポートされるのは、AMD EPYC 7xx2 CPU（コード ネーム「Rome」）以降の CPUである必要がある（[参考](https://docs.vmware.com/jp/VMware-vSphere/7.0/com.vmware.vsphere.security.doc/GUID-FB511CBA-4B89-469F-9799-D1347E1F2B0A.html)）。
    - 今回はIBM Cloud上にある`AMD Epyc 7763`を選択
- BIOS設定
    - 詳細は後述
- GuestOS設定
    - Hardware version: VM Versionが18以上
    - Reserve all guest memory: Enabled
    - Encryption: AMD SEV-ES: Enabled
    - Boot options
        - Firmware: EFI
        - Secure Boot: Disabled
- OS種類
    - SEV-ES の特定のサポート機能を備えたバージョンの Linux カーネル
    - [この資料](https://lenovopress.lenovo.com/lp1545.pdf)には、以下のOSがサポートされている旨の記述あり。
        - RHEL 8.5
        - RHEL 9.0
        - Photon OS version 3.0 or later
    - ただし、AMDの[User Guides](https://www.amd.com/content/dam/amd/en/documents/developer/58207-using-sev-with-amd-epyc-processors.pdf)によると、SEV-ESをGuestとしてサポートするのはLinux Kernel 5.10以降という記載あり（こっちの記載の方が正確？）。
    - 今回は`Photon OS 4.0 Rev2`を利用（Linux Kernel 5.10)

# 4. サーバーのプロビジョニング

- 今回はIBM Cloud上にある`AMD Epyc 7763`を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/885edefc-2217-bbe1-40eb-3c190c5eaecd.png)
- OSとしてvSphereは選択できないので、いったんCentOSを選択してプロビジョニングする。プロビジョニング結果は以下の通り。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/dc693079-02d3-7956-c03f-e0dcfabe16a2.png)

# 5. IPMIにおけるRemote Consoleの有効化

IPMIにアクセスして、ESXiのISOイメージをマウントしてインストールを開始するためには、Remote Consoleの権限が必要である。デフォルトではIPMIにアクセスしても以下のようにRemote Consoleが利用できない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/70dbfc56-bd6f-18a2-8986-6198ac553786.png)

そのため、Caseを起票して、Remote Consoleを利用できるようにしてもらう。

```txt:Caseの起票例
I'd like to install OS with our own iso image, but found that we're not allowed to use remote console in the IPMI(See attached).
Could you give us the permission?
```
対応してもらうと、以下のようにアクセス可能になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/7514a240-2424-6f32-9257-792eed6c66cf.png)

# 6. BIOS/UEFIの設定変更

- 各パラメーターの意味は[こちら](https://pubs.lenovo.com/uefi_amd_2p_3rd/memory)の通り。
- [このガイド](https://lenovopress.lenovo.com/lp1545.pdf)に従い、以下のように変更する。

| パラメーター| 初期値 | 今回の設定値 |意味|
|:-|:-|:-|:-|
| SMEE  | Disable  |  Enable |Control secure memory encryption enable.|
| SEV ASID Count  |  AUTO |  253 ASIDs(509 ASIDsも選択できたが、今回はこちらを選択） |This fields specifies the maximum valid ASID, which affects the maximum system physical address space. 16TB of physical address space is available for systems that support 253 ASIDs, while 8TB of physical address space is available for systems that support 509 ASIDs.|
|SEV-ES ASID Space Limit Control|AUTO|Manual|Customize SEV-ES ASID space limit.|
|SEV-ES ASID Space Limit|1|100（SEV-ESを有効にするVMの数を目安に決める。今回は暫定で100を指定）|SEV VMs using ASIDs below the SEV-ES ASID Space Limit must enable the SEV-ES feature. ASIDs from SEV-ES ASID Space Limit to (SEV ASID Count + 1) can only be used with SEV VMs. If this field is set to (SEV ASID Count + 1), all ASIDs are forced to be SEV-ES ASIDs. Hence, the valid values for this field is 1 - (SEV ASID Count + 1).|

なお、IBM Cloudのバグのためか今回はIPMIからBIOS/UEFIに以下からアクセスできていた。しかし、念の為Caseを起票して確認したところ、本来はパスワードがかかっており、ユーザーには開放していないとのことだった。よって、この操作はCaseを起票してサポートチームによって実施してもらう必要がある。念の為Caseで確認したところ、今回のパラメーター変更は許容される旨の回答を得た。また、実施結果のキャプチャー画像を要求しておくと良い。
- System Setupの起動 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/95fd5b0c-f218-f4c4-bd39-19d3cf102afe.png)
- System Settings -> Memory ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/79e8deba-a62b-a6ff-b63f-37089e491579.png)



# 7. ESXi/vCenterの導入

- vSphere 7.0 Update 1 以降でSEV-ESをサポートしているが、CLIの操作が必要である（[参考](https://docs.vmware.com/jp/VMware-vSphere/7.0/com.vmware.vsphere.security.doc/GUID-FB511CBA-4B89-469F-9799-D1347E1F2B0A.html)）。
- vSphere 7.0 Update 2 以降でvSphere Clientを利用してSEV-ESを有効にできる（[参考](https://docs.vmware.com/jp/VMware-vSphere/7.0/com.vmware.vsphere.security.doc/GUID-EA396482-9165-43A0-A9E3-396F2597A371.html)）。

今回は、以下のバージョンを導入した。具体的なESXi/vCenterの導入は省略する。

```txt:CPUモデル
[root@esxi07:~] vim-cmd hostsvc/hostsummary | grep cpuModel
      cpuModel = "AMD EPYC 7763 64-Core Processor
```
```txt:ESXiのバージョン
[root@esxi07:~] vmware -vl
VMware ESXi 7.0.3 build-20328353
VMware ESXi 7.0 Update 3
```
```txt:vCenterのバージョン
[root@syasudacentos7 ~]# pwsh
PS /root> Connect-VIServer 10.44.35.2 -Force
PS /root> $global:DefaultVIServers | Select Version, Build, Name, Port

Version Build    Name       Port
------- -----    ----       ----
7.0.3   20990077 10.44.35.2  443
```

また、BIOSの設定が正しく構成されていれば、以下のような結果が得られる。

```txt:SEV-ES ASID Space Limitを100にした結果(成功ケース)
[root@esxi07:~] dmesg|grep -i sev
TSC: 454671 cpu0:1)BootConfig: 711: visorfsEvictUserPages = TRUE (1)
TSC: 475055 cpu0:1)BootConfig: 711: useVmkperfTSXForceAbort = FALSE (0)
0:00:00:08.495 cpu0:2097152)Initializing InitVMKernel: (57/186) SEV_Init ...
0:00:00:08.497 cpu0:2097152)SysInitTable: 112: Finished sysInit step: SEV_Init in 1640 us.
2023-03-29T07:32:06.963Z cpu166:2099035)Loading module sev ...
2023-03-29T07:32:06.968Z cpu166:2099035)Elf: 2119: module sev has license VMware
2023-03-29T07:32:06.976Z cpu166:2099035)Device: 211: Registered driver 'AMD SEV driver' from 51
2023-03-29T07:32:06.976Z cpu166:2099035)Mod: 4821: Initialization of sev succeeded with module ID 51.
2023-03-29T07:32:06.976Z cpu166:2099035)sev loaded successfully.
2023-03-29T07:32:06.982Z cpu166:2099035)DMA: 687: DMA Engine 'AMD SEV driver' created using mapper 'DMANull'.
2023-03-29T07:32:07.258Z cpu166:2099035)Device: 395: AMD SEV driver:driver->ops.attachDevice :276 ms
2023-03-29T07:32:07.258Z cpu166:2099035)Device: 400: Found driver AMD SEV driver for device 0x3bd64309e6e0891c
2023-03-29T07:32:07.258Z cpu166:2099035)Device: 685: AMD SEV driver:driver->ops.startDevice:0 ms
2023-03-29T07:32:07.258Z cpu166:2099035)Device: 507: AMD SEV driver:driver->ops.scanDevice:0 ms
```
```txt:SEV-ES ASID Space Limitが1の結果。SEV-ESのためのASIDが確保できていない（失敗ケース）
[root@esxi07:~] dmesg|grep -i sev
TSC: 441662 cpu0:1)BootConfig: 711: visorfsEvictUserPages = TRUE (1)
TSC: 461335 cpu0:1)BootConfig: 711: useVmkperfTSXForceAbort = FALSE (0)
0:00:00:08.560 cpu0:2097152)Initializing InitVMKernel: (57/186) SEV_Init ...
0:00:00:08.561 cpu0:2097152)SysInitTable: 112: Finished sysInit step: SEV_Init in 1626 us.
2023-03-29T04:17:11.892Z cpu24:2099034)Loading module sev ...
2023-03-29T04:17:11.899Z cpu24:2099034)Elf: 2119: module sev has license VMware
2023-03-29T04:17:11.901Z cpu24:2099034)WARNING: SEV: 1297: Not enough SEV-ES ASIDs. Minimum SEV-only ASID: 1
2023-03-29T04:17:11.901Z cpu24:2099034)sev failed to load.
2023-03-29T04:17:11.903Z cpu24:2099034)WARNING: Elf: 3139: Kernel based module load of sev failed: Failure <Mod_LoadDone failed>
2023-03-29T04:17:19.954Z cpu226:2099119)Loading module sev ...
2023-03-29T04:17:19.956Z cpu226:2099119)Elf: 2119: module sev has license VMware
2023-03-29T04:17:19.957Z cpu226:2099119)WARNING: SEV: 1297: Not enough SEV-ES ASIDs. Minimum SEV-only ASID: 1
2023-03-29T04:17:19.957Z cpu226:2099119)sev failed to load.
2023-03-29T04:17:19.958Z cpu226:2099119)WARNING: Elf: 3139: Kernel based module load of sev failed: Failure <Mod_LoadDone failed>
2023-03-29T04:17:19.966Z cpu226:2099119)Loading module sev ...
2023-03-29T04:17:19.968Z cpu226:2099119)Elf: 2119: module sev has license VMware
2023-03-29T04:17:19.969Z cpu226:2099119)WARNING: SEV: 1297: Not enough SEV-ES ASIDs. Minimum SEV-only ASID: 1
2023-03-29T04:17:19.969Z cpu226:2099119)sev failed to load.
2023-03-29T04:17:19.970Z cpu226:2099119)WARNING: Elf: 3139: Kernel based module load of sev failed: Failure <Mod_LoadDone failed>
```

# 8. Guest OSの作成

今回は無料でサイズも小さい`Photon OS 4.0 Rev2`を利用する。Photon OSの導入手順は[こちら](https://qiita.com/testnin2/items/2103bbda72e08de8fe2f)を参照。

AMD SEV-ESを有効にするため、以下の設定の確認および変更を実施する。

- Hardware version: VM Versionが18以上 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/f15289ae-05a1-6f38-011b-ca6ddb8bc2ef.png)
- Reserve all guest memory: Enabled。 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/25b8fcb0-4ce8-bc37-15be-90f652645a2a.png)
- Encryption
    - AMD SEV-ES: Enabled
- Boot options
    - Firmware: EFI
    - Secure Boot: Disabled ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/115323e4-781a-76bb-5f24-4d07062f6847.png)


CLIでの一括確認方法は以下の通り。


```txt:Power CLIでのログインおよびVMの一覧取得
[root@syasudacentos7 ~]# pwsh
PS /root> Connect-VIServer 10.44.35.2 -Force
PS /root> $global:DefaultVIServers | Select Version, Build, Name, Port

Version Build    Name       Port
------- -----    ----       ----
7.0.3   20990077 10.44.35.2  443

PS /root> Get-VM

Name                 PowerState Num CPUs MemoryGB
----                 ---------- -------- --------
photon01-nocc        PoweredOff 1        2.000
photon01             PoweredOff 1        2.000
photon01-cc          PoweredOff 1        2.000
vcsa1                PoweredOn  2        12.000
```
```txt:SEV-ESを有効にしたVM
PS /root> Get-VM -Name photon01-cc | select Name, HardwareVersion, SEVEnabled, {$_.ExtensionData.Config.Firmware}, {$_.ExtensionData.Config.memoryReservationLockedToMax}, {$_.ExtensionData.Config.BootOptions.EfiSecureBootEnabled}

Name                                                     : photon01-cc
HardwareVersion                                          : vmx-19
SEVEnabled                                               : True
$_.ExtensionData.Config.Firmware                         : efi
$_.ExtensionData.Config.memoryReservationLockedToMax     : True
$_.ExtensionData.Config.BootOptions.EfiSecureBootEnabled : False
```

# 9. テスト

## 9-1. コマンド比較
```txt:SEV-ESを有効にしたGuest OS
root@photon01-cc [ ~ ]# uname -a
Linux photon01-cc 5.10.168-2.ph4-esx #1-photon SMP Thu Mar 2 03:44:00 UTC 2023 x86_64 GNU/Linux

root@photon01-cc [ ~ ]# cat /etc/photon-release
VMware Photon OS 4.0
PHOTON_BUILD_NUMBER=2f5aad892

root@photon01-cc [ ~ ]# vmware-toolbox-cmd -v
12.2.0.41219 (build-21223074)

root@photon01-cc [ ~ ]# dmesg|grep -i -e amd -e sev
[    0.028268] AMD Memory Encryption Features active: SEV SEV-ES
[    0.041900] smpboot: CPU0: AMD EPYC 7763 64-Core Processor (family: 0x19, model: 0x1, stepping: 0x1)
[    0.042182] Performance Events: AMD PMU driver.


root@photon01-cc [ ~ ]# export http_proxy=10.212.15.57:3128
root@photon01-cc [ ~ ]# export https_proxy=10.212.15.57:3128
root@photon01-cc [ ~ ]# tdnf install msr-tools
root@photon01-cc [ ~ ]# rdmsr -a 0xc0010131
3

```

```txt:一般のGuest OS
root@photon01-nocc [ ~ ]# uname -a
Linux photon01-nocc 5.10.168-2.ph4-esx #1-photon SMP Thu Mar 2 03:44:00 UTC 2023 x86_64 GNU/Linux

root@photon01-nocc [ ~ ]# cat /etc/photon-release
VMware Photon OS 4.0
PHOTON_BUILD_NUMBER=2f5aad892

root@photon01-nocc [ ~ ]# vmware-toolbox-cmd -v
12.2.0.41219 (build-21223074)

root@photon01-nocc [ ~ ]# dmesg|grep -i -e amd -e sev
[    0.023282] smpboot: CPU0: AMD EPYC 7763 64-Core Processor (family: 0x19, model: 0x1, stepping: 0x1)
[    0.023495] Performance Events: AMD PMU driver.

root@photon01-nocc [ ~ ]# export http_proxy=10.212.15.57:3128
root@photon01-nocc [ ~ ]# export https_proxy=10.212.15.57:3128
root@photon01-nocc [ ~ ]# tdnf install rdmsr
root@photon01-nocc [ ~ ]# rdmsr -a 0xc0010131
0
```

## 9-2. SEV-ESでサポートされていない操作の試行

- サポートされない操作は[ここ](https://docs.vmware.com/jp/VMware-vSphere/7.0/com.vmware.vsphere.security.doc/GUID-FB511CBA-4B89-469F-9799-D1347E1F2B0A.html)に記載されている。
    - システム管理モード
    - vMotion
    - パワーオン状態のスナップショット（ただし、非メモリ スナップショットはサポートされます）
    - CPU またはメモリのホット アドまたはホット リムーブ
    - サスペンド/レジューム
    - VMware フォールト トレランス
    - クローンとインスタント クローン
    - ゲストの整合性
    - UEFI セキュア ブート
- Snapshotの取得（失敗）![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/34dc6991-c615-7475-3889-4d6cb07debe6.png)
- Suspendの実行（失敗）![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/c496cdd2-b658-fefd-54c4-c8437c9668f9.png)
- cloneの実行（失敗）![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/df4677d7-954c-2ef1-af4a-d365a95efd70.png)


## 9-3. Guest OSに対するメモリダンプによる解析

- SnapshotやSuspendが実行できれば、[vSphere(ESXi)でGuest OSのメモリダンプを取得する方法](https://qiita.com/testnin2/items/1f6f23e5be9ba0c4b9c1)で解析したような、ダンプ解析がHypervisro管理者から実施可能である。
- しかし、SEV-ESを有効にしたGuest OSではSnapshotやSuspendを管理者といえども実施できないため、同様の手法を使った解析はできない。