おしぼりの日常

低レイヤが好きです.

論文メモ:Software Grand Exposure: SGX Cache Attacks Are Practical

はじめに

aos さんの資料(攻撃編 ①)と「プログラマーのための CPU 入門」の 5 章(キャッシュメモリ)を読んだので、試しにどれくらいキャッシュ関連の論文が読めるのか試してみた.読んだ論文は SGX に対するキャッシュを用いた攻撃を行うものであり、aos さんの資料でも簡単に触れられているものです.

論文のリンク

前提知識

キャッシュのアーキテクチャ

論文の 2.2 節を読むか、プログラマーのための CPU 入門の 5.5 節を読みましょう.おそらく後者を呼んでから前者を読むと一番理解できます.僕も 5 章だけを読んだ上で論文を読んでいますが、

  • キャッシュヒット / ミス
  • キャッシュライン
  • L1 / L2 / L3 キャッシュ
  • full / set associative
  • way

あたりの単語が理解できるだけで基本的には理解できる内容だと思います.雑に選んだ論文にしてはあまりにも丁度良い論文で運が良いですね.

Performance Monitoring Counters

論文の説明をそのまま DeepL に突っ込んだものを貼ります.

パフォーマンス・モニタリング・カウンタ(PMC)は、ハードウェア・イベントを記録するためのCPUの機能である。PMCの主な目的は、ソフトウェア開発者がプログラムを最適化するために、プログラムがハードウェアに与える影響を把握できるようにすることである。CPUには一連のPMCがあり、例えば、実行されたサイクル、異なるキャッシュのキャッシュヒットやキャッシュミス、予測ミスの分岐など、さまざまなイベントを監視するように設定できる。PMCは、監視するイベントと動作モードを選択することで構成される。これはモデル固有レジスタ(MSR)への書き込みによって行われ、特権ソフトウェアによってのみ実行可能です。PMCはRDPMC命令(リード・パフォーマンス・モニタリング・カウンタ)を介して読み出され、非特権モードで使用できるように設定できる。PMC によって記録されたハードウェアイベントは、サイドチャネルとして悪用される可能性 があります。そのため、SGX エンクレーブは、「Anti Side-channel Interference」(ASCI)[26]と呼ばれる機能を有効にすることで、エントリー時に PMC を無効にすることができます。これにより、固定サイクル・カウンターを除く、すべてのスレッド固有のパフォーマンス監視が抑制されます。そのため、エンクレーブによってトリガされるハードウェア・イベントは、PMC機能によって監視することができません。例えば、エンクレーブによってロードされたメモリのキャッシュミスは PMC に記録されません。

DeepL.com(無料版)で翻訳しました.

Prime+Probe 型の攻撃

aos さんの資料を読むか、論文の 4.1 節を読みましょう.適当(雑という意味)に説明するなら、

  1. キャッシュ (の特定の範囲)を埋め尽くす (prime)
  2. victim の攻撃対象の関数が実行される
  3. キャッシュにアクセスする (probe)

という 3 ステップで行う攻撃です.set associative なキャッシュではアドレスの一部(下位 1 バイトなど)がキャッシュライン上のインデックスになっており、これによりアクセス先のアドレスの値がキャッシュに載っているか高速に検索ができます.しかし、この方式だとインデックスが同じアドレスの値を 1 つしか格納できないため、インデックスが被ると過去にキャッシュに載った値が evict されることになります(そもそもキャッシュサイズ以上のデータを載せたら普通に溢れて evict されますがこれはまた別の話な気がする).これを利用すると、攻撃者が特定のアドレス範囲がどのキャッシュラインに載るかを知っているとき、そこを事前に埋め尽くした上で (これが 1) 、2 で victim の関数を実行し、3 でキャッシュにアクセスすることで、evict されたアドレスへのアクセスだけが遅くなることを確認できます.説明が下手すぎるので、やはり詳細は他の資料に頼みます ... .論文中の図が普通に分かりやすかったので引用しておきます.

Prime+Probe 型攻撃のイメージ(論文から引用)

この Prime+Probe 型の攻撃はキャッシュ汚染(cache pollution) に悩まされがちらしいのですが、SGX の脅威モデルである OS が侵害された状況を考慮すると、色々とキャッシュ汚染を引き起こさないための対策ができるから、依然として Prime+Probe 型の攻撃は SGX に有効だぜ、という趣旨の論文です.

状況設定

攻撃手法に入る前に、簡単に状況設定を説明します.この論文では攻撃者のプロセスと victim プロセスは別のプロセスであり、同じコアの別スレッド (hyper-threading 使う前提)で動きます.つまり、攻撃者のスレッドと victim のスレッドは並列に実行されます(以下の図を参照).hyper-threading ではキャッシュが共有されます.

状況設定(論文から引用)

攻撃手法:キャッシュ汚染に対する対策

基本的には Prime+Probe 型の攻撃なのですが、キャッシュ汚染を防ぐために色々と工夫をしています.キャッシュ汚染は、Prime+Probe コードと victim の攻撃対象コード以外の様々なコードがキャッシュを利用することです.キャッシュ汚染が起きると、victim によるキャッシュの evict を特定しずらくなります.この論文の貢献は SGX が想定するような脅威モデルにおいて、従来の Prime+Probe 型の攻撃を行いやすくするめに、様々なノイズ軽減(noise reduction)のテクニックを提案している点だと思います.以降では一部を紹介します.

Isolated attack core

Prime+Probe 型の攻撃はキャッシュ eviction を観察することにより機密データを特定するものです.しかし、キャッシュというのは複数のコアにより共有されているため、一般的な状況では攻撃者は evict が victim により発生させられたのか、他のコアで実行されている別のプログラムにより実行されたのかを判別できません.しかし、この研究(というか SGX の脅威モデル)では攻撃者が OS を完全に掌握しているため、特定のプログラムを特定のコアでのみ実行するように細工できます.具体的には、攻撃者が用意する Prime+Probe コードと victim のコードのみが実行されるコア(論文では attacker core と呼んでいるため以降はそれに従います)を用意します.これにより evict が発生した場合にはそれが victim からのアクセスにより引き起こされたことが確定します.

Self-pollution

攻撃者は特定のアドレスに紐づくキャッシュラインを観察しますが、このキャッシュラインが Prime+Probe コードと victim の攻撃対象のコード以外からもアクセスされるとキャッシュが汚染されやすくなってしまいます.この研究ではデータキャッシュと命令キャッシュが分離されている L1 キャッシュを利用することでキャッシュ汚染を軽減しています.攻撃者が関心があるのはデータキャッシュであるため、L1 キャッシュを使うだけで少なくとも他の命令が観察対象のキャッシュラインにキャッシュされることによる汚染は防げます.依然として victim の他の部分で発生したデータアクセスによりデータキャッシュが汚染される可能性はあります.

Uninterrupted execution

割り込み(interrupt) も攻撃者にとっては都合が悪いです.SGX の AEX に限らず割り込みが発生すると対応する割り込みハンドラが呼ばれますが、これらのプログラムも通常のプログラムと同様にキャッシュを利用するため、やはりキャッシュ汚染が起きます.論文ではこれを防ぐために攻撃者のプログラム及び victim プログラムを可能な限り割り込みを発生せずに実行させます. 対策としてはシンプルで、割り込みが発生するとその割り込みを処理するコアが割り当てられますが、そのコアに attacker core が割り当てられないように割り込みコントローラを設定します.唯一の例外は各コアが持つタイマーからの割り込みらしいですが、これはタイマーの周波数を下げることで、10 ms はタイマー割り込みが入らないようにして影響を軽減していて、この時間(10 ms) は割と十分に長いらしいです.

Monitoring cache evictions

従来の研究はキャッシュの evict をメモリアクセスのレイテンシにより判断していましたが、これはかなり難しい作業らしいです.例えば、L1 キャッシュへのアクセスが 4 サイクルで、L2 キャッシュへのアクセスが 12 サイクルの場合、その差は非常に小さいです.そのため、従来の研究は L3 キャッシュを観測することで L3 キャッシュへのアクセスと DRAM へのアクセス速度の差が分かりやすい状況を利用していました.しかし、この研究は L1 キャッシュを利用しているため、そうもいきません.そこで、この研究では上述の PMC を利用することで確実にキャッシュミスのイベントを取得できます.ASCI による対策があるじゃないかと思うかもしれませんが、あくまで PMC により取得するのは攻撃者が用意した Prime+Probe コードのイベントなので、ASCI は意味を成しません.

既存研究との違い

基本的には Prime+Probe 型のキャッシュを対象としたサイドチャネル攻撃です.論文の Parallel work on SGX cache attacks で直接言及されているのは Gotzfried et al , Schwarz et al, CacheZoom の 3 つでした. Gotzfried の研究は攻撃手法自体はこの研究と似ているのですが、あまり現実的ではない仮定を置いていたようです.具体的には、(1) 攻撃者と victim のコードは同じプロセス内の別スレッドとして動作する (2) 攻撃者と victim のコードは共有バッファを利用する(このバッファを介して攻撃者は復号したいデータを victim に渡せる) (3) 攻撃者と victim は協調して動いていて、prime と probe を完璧なタイミングで一度で行える、というものです.個人的には (2) は Switchless Call があるので割と現実的な気もしますが、(1) と (3) はあまり現実的ではない気がします.ただ、SGX の脅威モデル的には (1) は一応整合している(untrusted なメモリのコードは同一プロセスでも信頼できない)気もしますし、(3) も AES の最終ラウンドの終了が関数の終了であれば、あとは何回も攻撃を行えるのであればもしかしたらそういった状況もあり得るのか ... ?という気もします.このあたりは専門家でないと分からないと思いますが. Schwarz の研究はそもそも対象が L3 キャッシュらしいです.CacheZoom は詳しくは分かりませんが、割り込みによって victim プロセスを頻繁に中断させるらしく、これは既存のサイドチャネル攻撃の検知技術に引っかかりやすいという問題があるらしいです.

上記を総括すると

  • L1 キャッシュを対象としてる
  • 割と現実的な(?)仮定の元で攻撃が成立する
  • 既存の割り込みを用いた攻撃よりも検知されにくい

などの違いがあるということみたいです.

おわりに

割と理解できるものだなと思いました.おもしろかった.暇だったら評価などを追記するかもしれないです.