はじめに
前回の記事では、いくつか存在するTEE技術の全般的な解説を行いました。
今回は、その中でもIntel SGXというTEE技術に焦点を当て、SGXのごく簡単な概要を説明した後、SGXの秘密計算の実装への応用について議論していきます。
前回に引き続き、筆者が別の機会で作成した外部記事を適宜自己引用しながら解説・議論を進めていきます。
Intel SGXの概要
SGXは、メモリ上に暗号学的に保護された保護領域である「Enclave」を生成し、その中で秘密情報を取り扱う事で安全な計算を行う事が出来る、前回記事の表現を取るならば「部分隔離型」のTEEの一つです。
Enclaveは、比較的よく使われている暗号利用モードであるCTRモードの128bit AES暗号をさらに微調整したものがベースとなっており[3]、そこにいくつもの技術を織り交ぜる事によって生成され、非常に堅牢な隔離保護領域として機能します。
このEnclaveの生成処理は、SGX対応のIntel製CPUであればどれも有している、メモリ暗号化エンジン(Memory Encryption Engine; MEE)というパーツが実際に執り行ってくれますが、このMEEはユーザがアクセス・操作・改竄する事は不可能なものとなっています。
さらに、Enclaveの操作(例えば、生成、破棄、進入、脱出)命令は専用のCPU命令によってのみ可能となります。このCPU命令自体は、通常予め定義が固定されているプログラムから特定のAPIを呼び出す事でのみ発出可能です。
よって、このMEEと専用CPU命令の特性から、Enclaveは暗号学的だけでなく、アクセス方法的にも厳重であると言えます。

SGXにおいて、秘密情報にとってTrusted(信頼可能)、即ち安全である領域は、上記のメモリ上のEnclaveと、暗号化された状態で通過するメモリとCPUとの通信路、そしてCPU内となります(CPU内が安全であるという話は、あくまでもIntelによる主張であり、具体的な根拠としてはブラックボックスです)。
よって、秘密情報を暗号化した状態でEnclaveに入れてその中で復号し、必要な計算・処理を実行後、何かしらのデータをEnclaveの外に出す際は、秘密情報を特定できない形にしてあげる事で、前回の記事で述べたように、TEEのメインのユースケースである「信頼可能な領域内でのみ秘密情報を取り扱う事による安全な計算」を行うことが可能です。
Remote Attestation(リモート・アテステーション)
ここまで、SGXを利用すれば安心して秘密情報を保護しながら処理を進められるというお話をしましたが、それはあくまでも作成したEnclaveイメージ(※1)をローカルに配置し処理を実行するような、即ちローカルマシン上で完結する場合の議論となります。
(※1: ここでは、Enclaveで動作させる処理のイメージファイルをEnclaveイメージと呼びます。より厳密には、Enclaveイメージは署名済み共有ライブラリの形を取っています)
これがもしEnclaveをリモートマシンにデプロイし、遠隔から通信し実行する場合、話は一気に変わってきます。
何故ならば、もしEnclaveイメージをデプロイした(はずの)リモートマシンが悪性であり、Enclaveイメージの改竄やすり替えを行ったり、悪性のCPUを用いる事で本来不可能な異常な処理を行う事を画策している場合、そこに無思慮に繋ぎに行って秘密情報を送り込んでしまえば、その秘密情報が漏洩されたり悪用されたりし放題になるリスクがあるからです。
このような、SGXのリモート利用を考えた場合の問題点を解決する機能(プロトコル)として、「Remote Attestation」(以下、RA)と呼ばれる機能(プロトコル)が用意されています。
このRA、一見複雑怪奇極まりないプロトコルに見えたり、実際に自力に実装に落とし込んだりすると極悪な難易度になるなど、とにかく詳しい部分は触らず敬遠したくなるような代物なのですが、目的のエッセンスだけを抜き出して整理すると大分明快になります。
これを踏まえて、RAの目的を完結に列挙すると、
- リモートのマシンのCPUやSGXのコアコンポネントが危殆化していない事
- リモートマシン上のEnclaveが、ユーザの意図しているものと一致しており、改竄などもされていない事
- 上記2点の認証後、安全に二者間で通信するために、共通鍵の鍵交換を行う(要するに、TLSセッションを確立する)事
の3点にまとめる事が出来ます。
これらを実現するために、RAでは楕円曲線ディフィー・ヘルマン鍵共有プロトコル(ECDHKE)をベースとし、そこにSGX特有の構造体や各情報を利用した検証処理を織り交ぜるという方法を取っています。
ECDHKEや各検証処理などのRAに関連する詳しい説明は、本記事で説明してしまうと長くなってしまいますので、気になる方は筆者自著記事の文献[2]をご参照ください。
MRENCLAVE
さて、このRAの目的の中で、本記事の本題に入るにあたって重要なものが、「リモートマシン上のEnclaveイメージの検証」です。
本当に意図している動作をしてくれる、正当なEnclaveが起動しているかを確認するため、RAでは様々な情報を検証していますが、その検証対象の中でも有力な値として、「MRENCLAVE」というものがあります。
MRENCLAVE(Measurement Register of ENCLAVE)は、一言で表すのであればEnclaveイメージ自体に固有なハッシュ値です。
つまり、極論この値さえ検証で一致確認が取れれば、意図しているEnclaveが展開されている事が確認できますし、反対にこの値が一致しないようであれば、Enclaveが意図しないものにすり替えられていたり、改竄されていたりするであろう、と断定する事が出来ます。
2019年にIntelに問い合わせて得られた返答[4]によれば、MRENCLAVEの値は以下の要素によって決定されます。
- 署名前のEnclaveイメージ(Enclave.so)
- 設定用xmlファイル(Enclave.config.xml)
- Enclaveイメージへの署名鍵
- Enclaveイメージへの署名ツールである「sgx_sign」のバージョン
従って、これらのいずれか一つがわずかにでも違ってくると、同一のMRENCLAVEにはならないという事になります。これがもたらす影響については、次の本題にて説明いたします。
SGXを秘密計算利用する際の問題点
SGXを用いた秘密計算利用モデル
前置きが長くなりましたが、ここで一度秘密計算に話題を変えます。
秘密計算を実際に利用しようと考えた場合、最も一般的であろう利用モデルは、
- データ所有者は、保護されていない状態では提供できないセンシティブな情報を有している
- データの中身を見たり判別したりせずに計算を行い、個々のデータを特定できない形の計算結果を出力出来る、即ち秘密計算機構を備えたリモートマシンが存在する
- データ所有者は、安全な方法で秘密計算機構を有するリモートマシンにデータを送信・提供し、リモートマシンはそのデータを用いて秘密計算を実行する
といったものになるのではないかと思われます。
一見SGXを利用すれば非常に効率的に実装できそうな印象を受けるモデルですが、実はこれをSGXで実現しようとした場合、大きな困難に直面する事になります。
何故ならば、上記のようなモデルをSGXで実現する事を考えると、「秘密情報を有するデータ所有者が、本当にサーバのEnclaveが正当であるかを確実に認められる手段がない」という問題が発生するからです。
SGXが元々想定していたモデル
そもそもSGXは、元々はDRM(デジタル著作権管理)処理のような用途を想定して開発された技術です。
例えば、SGXを利用した技術で恐らく世間で最も広く使われているものとしてUltra HD Blu-rayのDRM処理があります。
この利用モデルでは、保護したい情報である著作物(映像データ)を有するコンテンツ配信者が、そのコンテンツを視聴したいユーザにEnclaveイメージを提供し、そこに映像データを送り込みDRM処理(暗号処理)を行う、といったSGXの使い方をします。
このモデルが秘密計算利用時と決定的に異なるのは、「秘密情報を有する主体と、Enclaveイメージを作成しデプロイする主体が同一である」という点です。
この場合の流れとしては、
- 配信元は、自身の有する秘密情報を安全な状態で相手(配信先)に配信したい
- DRM処理を行うEnclaveを作成し、配信先に送付する
- 配信先は、配信元から送られてきたEnclaveイメージからEnclaveを起動する
- 配信元は、配信先が起動したEnclave(や勿論CPU等)が意図している正当なものであるかをRAで確認後、実際に映像データを送信する
というものになります。
要は、上記のようなモデルの場合、「自分の持つ秘密情報を、自分が用意した通りのEnclaveをきちんと起動してくれている安全な相手に送りたいから、RAで本当に相手のEnclaveが正しいかを確かめる」といった検証が出来るので、何事も問題なく手続きが進んでいくわけです。
「検証しようがない」事による問題点
しかし、前述のようなSGXの一般的な秘密計算利用を考えた場合はそうは行きません。
この秘密計算利用の場合、「秘密計算サーバ側が計算定義を実装したEnclaveを用意し、同じくサーバ側がそのEnclaveのMRENCLAVEを提示し、データ所有者はそのMRENCLAVEを用いて正当性の検証を行う」事になります。
つまり、秘密計算サーバ側が自身で用意したEnclaveイメージのハッシュ値をオレオレで正しいと主張しているに過ぎないため、そのハッシュ値を根拠にRAをした所で、その結果も所詮はオレオレの域を出ません。
また、少し細かい話をしますと、RAではEnclaveの検証としてQUOTE構造体というものをチェックしますが(ややこしいですが、この中に含まれるREPORT構造体のさらに中にMRENCLAVEが入っています)、MRENCLAVE以外の値で代わりにこの正当性の検証に上手く使えるようなものも存在していません。
データ所有者からしてみれば「このEnclaveはそもそも本当にちゃんとした処理をしてくれる定義になっているのか?」という疑問を全く解決できない状況になっている事になります。
解決策はあるのか?
この問題に関しては、過去に筆者も少なくない時間を考察に費やしましたが、その中で挙がった候補としては以下の4つがあります(ただ、先に言ってしまうといずれもあまり有力ではありません)。
クライアント側がEnclaveイメージを作成する
まず真っ先に出てくるであろう案が、それならDRM処理のようなモデルに合わせてしまえばいい、という考え方です。
クライアントが秘密計算定義を実装し、それをサーバに配備してしまえば、前述のような問題を根本的に解決できそうです。
しかしながら、このアプローチはサーバ・クライアント共にあまりにも負担が大きく、快適かつ現実的な運用を望むのは厳しい側面があります。
まずサーバ側から見てみると、不特定多数のクライアントから送られてくるEnclaveイメージや設定ファイル等をもとに、実行可能な状態まで持っていくための、自動デプロイシステムのようなものの開発は必要になるでしょう。
わずかでも定義に変更が発生した場合は、その都度デプロイし直しになりますから、それに対応しうるだけのリソースは必然的に要求されます。
さらに、秘密計算の場合、様々な主体から送られた秘密情報を同時に計算に使用するケースも多いですが、いくらEnclaveの動作がユーザ権限(Ring-3)レベルに制限されており、OS等でアクセス制限する手段があるとは言え、秘密の山であるサーバにクライアントが勝手に書いたEnclaveコードを動作させるのは、あまりにもリスクが高すぎます。
勿論、DRM処理のケースでも、「クライアントのローカルデータなどを盗むEnclave定義を書けてしまうのでは?」という議論があります。
ただ、これは完全に筆者の所感ですが、DRM処理の方は仮にも規格化(AACS 2.0)されている一環であり、かつ対象が秘密情報の山である秘密計算サーバである場合に比べると、攻撃モチベーションの側面で大なり小なり抑制される側面もあるのではないか、とは考えています(周辺状況からの事実上の状況に甘えるのはSGX的には気持ち悪いですが)。
次いで、クライアント側の負担についてですが、これは圧倒的に「利用者(データ所有者)がSGXプログラミングをしなければならない」の1つに尽きます。
ここまでの説明では、SGXは手軽かつ高効率に安全な処理を実現してくれる魔法の技術、のような印象を受けた方もいらっしゃるかも知れませんが、実態はそんな輝かしいものではありません。
前回記事を読んでくださった方は目にしたかも知れませんが、複雑怪奇な仕様やライブラリ、API、ツールを交えた、これを提供している人間の正気を疑うようなSGX開発は、およそ人道的な範疇ではありません。
これも前回記事に書いた通りですが、行数だけで見ても、412行の一般的なコードをSGXで動作できるように改修した所、3523行まで膨れ上がったという報告が上がっています。
筆者のようにある意味ではSGXに取り憑かれているような人間であれば何とか開発するかも知れませんが、普通のデータ所有者はそもそもITに精通しているとも限りませんし、開発委託するにしてもセンシティブ性が故に今度はレビューに莫大な労力が必要になるでしょう(そもそもそんな酔狂な委託先がいるかという話もあります)。
従って、どう足掻いてもSGX開発について多少なりとも触れなければならないわけですが、大部分のデータ所有者はこの時点でSGXを選ぶ事は無いでしょう。開発は勿論、その後の運用の事も考えると、あまりにも負担が大きすぎます。
Enclaveイメージを逆アセンブルして解析・検証する
言うまでもなく非現実的な手段ですが、参考のため記載しました。
SGXでは、Enclaveにより秘密にしたい情報を保護する事は出来ますが、原則としてそのコード自体は保護されません。
よって、Enclaveイメージ(前述の通り共有ライブラリの形を取ります)を逆アセンブルし解析する事で、理論上は意図している動作に一致しているかを検証する事が出来ます。
しかし、実運用でこのような方法を取る事が無理難題であるのは自明です。
ただでさえ前述の通りSGXプログラミングやそのコードレビューの負担が苛烈であるというのに、それをビルドして生成されたバイナリを逆アセンブルしたものの検証など、正気の沙汰ではありません。
クライアント側で検証しようが、クライアントに作らせてサーバ側で検証しようが、または何らかの神がかり的な手段で自動検証システムを作るにせよ、その負担は大きすぎる所の話ではありません。
何らかの非人道的な懲罰として誰かしらにこれをやらせるのであればピッタリかも知れませんが、秘密計算利用の実運用でこの選択肢が取られる事はまず無いでしょう。
サーバと同一の実行環境のコンテナを提供し、そこで検証する
秘密計算サーバのEnclaveの正当性ですが、極論提示されたMRENCLAVEをデータ所有者側で再現できてしまえば、言うまでもなく完全な確証が取れる事になります。
MRENCLAVEを決定する要素は、前述の通り「署名前のEnclaveイメージ」「Enclave設定XML」「署名鍵」「署名ツール」の4つですが、厄介なのは1つ目の「署名前のEnclaveイメージ(Enclave.so)」です。
この署名前Enclaveイメージは、SGXSDKの用意する様々なツールや機能(例:Edger8r Tool)を交えながら、コンパイラを通して生成します。
Enclaveイメージはバイナリですので、例え使用されたソースコードが完全に同一であっても、SGXSDKに含まれる機能の1つでもバージョンが違えば、動作機能的には差異は無くとも微妙にそのバイナリの構成は変わる可能性が高いでしょう。
同様の話がコンパイラにも言えますし、そのコンパイラにも複雑に絡む依存関係が存在します。より引いて見てみれば、OSの種類も影響を及ぼす可能性を否定できません。
このように、プログラミング言語による抽象化が全く届かないバイナリの世界まで一致させるとなると、文字通りサーバとデータ所有者で完全に同一の環境でEnclaveイメージをビルドする必要性が出てきます。
これを実現できるであろう最も有力な手段は、秘密計算サーバが自身と全く同じコンテナイメージを提供し、データ所有者がそのイメージ内でEnclaveイメージをビルド後、MRENCLAVEを照合する、というものです。
今回挙げる候補の中では、妥協の線引きさえ決めてしまえば最も現実的な選択肢ではあります。
しかし、今度はそのコンテナイメージが信頼できるのか、細工されていないのか等が気になりだしたりしてしまうので、ただでさえ疑り深くなりがちなSGXを利用したモデルにおいては、完全にスッキリと解決、とまではいけない部分があります。
CAからコード一式のデジタル証明書をもらう
最後に、ソースコードやEnclaveイメージ、MRENCLAVE等について、それら一式の電子証明書(コードサイニング証明書)をCAからもらい証拠にする、という方法も考えられます。
ただでさえ外部の機関に頼るので、TEE的にはあまり気持ちの良いものではありませんが、これについて筆者が他の研究者の方々とお話しした所、そもそも電子証明書は一般的に年単位のスパンである、という根本的な問題の指摘を頂きました。
計算定義の変更や追加、ひいては設定を変更するだけでも更新が発生するため、年単位のスパンを前提としているCAによる電子証明書とは絶望的に相性が悪い、という現実があります。
まとめ
今回は、Intel SGXに焦点を当て、秘密計算利用を考えた場合の難しさについて説明しました。
しかしながら、このような問題は、必ずしもSGXだけの問題であるとは限らない部分があります。
例えば、AWSのNitro Enclavesでは、EnclaveイメージのMRENCLAVEに相当するPCR(Platform Configuration Register;プラットフォーム構成レジスタ)というハッシュ値を用いて、AWSが第三者的にEnclaveの正当性を検証するようです。
しかし、全体保護型(VM型)のTEEの宿命として、クラウドベンダを信頼しなければならない(加えてNitro Enclavesの場合は、完全にAWSに依存する必要もあります)以上、SGXよりも対応できる脅威モデルは弱くなりますし、VM型である以上、ソースコードとは違って本当に意図している正当な挙動だけを行うか検証するのは難しくなるでしょう。
結局の所、妥協の線引きを要する状況から脱するのは難しいという現状があります。
とは言うものの、TEEの思想的な部分は別として、ある程度の部分でスパッと線引きしてしまい、一定の妥協の下で秘密計算利用を利用するのでも、現実問題としては十分に強力な安全性を誇りますので、現状ではそういったTEEとの付き合い方が最適なのかも知れません。
参考文献
[1] “Intel SGX入門 – SGX基礎知識編”, 自己引用, https://qiita.com/Cliffford/items/2f155f40a1c3eec288cf
[2] “Intel SGX – Remote Attestation概説”, 自己引用, https://qiita.com/Cliffford/items/095b1df450583b4803f2
[3] “A Memory Encryption Engine Suitable for General Purpose Processors”, Shay Gueron, https://eprint.iacr.org/2016/204.pdf
[4] “Question about uniqueness of MRENCLAVE”, https://community.intel.com/t5/Intel-Software-Guard-Extensions/Question-about-uniqueness-of-MRENCLAVE/m-p/1159777