1 ポイント 投稿者 GN⁺ 2024-03-23 | 1件のコメント | WhatsAppで共有
  • データメモリ依存プリフェッチャ(DMP) が暗号コードのデータ値をアドレスのように扱うことで、定数時間(constant-time)実装でも秘密鍵が漏えいしうる
  • Apple m-series CPUでは、メモリから読み込まれた値がポインタのように見えるとDMPが逆参照を試みるため、データとアドレスの分離という定数時間プログラミングの前提が揺らぐ
  • 研究チームはApple m1で、OpenSSL Diffie-Hellman、Go RSA復号、CRYSTALS-Kyber、CRYSTALS-Dilithiumのエンドツーエンド鍵抽出を実演し、m2・m3でも同様のDMP動作を確認した
  • m3ではDIT bitがDMPを効果的に無効化するが、m1・m2には当てはまらず、2024年4月に発見されたHID設定ビットもmacOSカーネルのサポートがないためすぐには使いにくい
  • 緩和策には、最新ソフトウェアの維持、一部CPUでのDIT/DOIT bitの使用、入力ブラインディング、ハードウェア共有の回避が含まれ、脆弱性評価には暗号解析とコード検査が必要

GoFetch攻撃の核心

  • GoFetch は、データメモリ依存プリフェッチャ(DMP)を利用するマイクロアーキテクチャ・サイドチャネル攻撃である
  • 定数時間で書かれた暗号実装からでも秘密鍵を抽出できる
  • 研究チームが実演した対象は次のとおり
    • OpenSSL Diffie-Hellman Key Exchange
    • Go RSA decryption
    • CRYSTALS-Kyber
    • CRYSTALS-Dilithium
  • 論文とツールはそれぞれ PaperTools で公開されている

DMPが定数時間の前提を破る仕組み

  • Apple m-series CPUのDMPは、メモリから読み込まれたデータがポインタのように見える値である場合に起動し、逆参照を試みる
  • 定数時間プログラミングでは、秘密値に応じて分岐、ループ、メモリアクセス、配列インデックスが変化しないよう、データとアドレスを分離する必要がある
  • 被害側コードがこの規則を守っていても、DMPがハードウェアレベルで秘密依存のメモリアクセスを代わりに生み出してしまう可能性がある
  • その結果、本来は定数時間であるはずのコードに観測可能な時間差が生じ、鍵抽出攻撃にさらされる

攻撃手順

  • 攻撃者は暗号演算への選択入力を構成し、秘密鍵の一部を正しく推測した場合にのみ中間状態にポインタのように見える値が現れるようにする
  • その後、キャッシュタイミング解析によってDMPが逆参照を実行したかどうかを確認し、推測が正しいかを検証する
  • 正しい推測が確認されると、同じ方法で次の鍵ビット群を推測する
  • この手順により、古典暗号およびポスト量子暗号実装からエンドツーエンドの鍵抽出が可能になる

影響を受けるプロセッサと観測結果

  • エンドツーエンドのGoFetch攻撃は、Apple m1 プロセッサを搭載したハードウェア上で実行された
  • m2およびm3 CPUでも同様に悪用可能なDMP起動パターンが見られた
  • m2 Proのような他のm-series派生品はテストされていないが、無印モデルと同じマイクロアーキテクチャを使うため、悪用可能なDMPを備えている可能性がある
  • Intel第13世代 Raptor Lake マイクロアーキテクチャにもDMPが存在する
    • ただし起動条件がより限定的であるため、GoFetch攻撃には耐性がある

Auguryとの違い

  • Apple m-series DMPは Augury が最初に発見した
  • Auguryは、DMPが一部条件下でデータとアドレスを混在させうると見ていた
  • GoFetchの研究チームは、Auguryが整理したDMP起動条件が過度に限定的だと判断した
  • 実際の動作では、メモリから読み込まれたどの値でも逆参照候補になりうるため、実際の定数時間暗号コードに対するエンドツーエンド攻撃へとつながる

キャッシュとプリフェッチャの背景

  • 最新のプロセッサは、メモリアクセス遅延を減らすためにキャッシュを使用する
  • 以前にアクセスしたデータはキャッシュに残るため、その後のアクセスは高速になる
  • 同じマシン上で同時実行される攻撃者は、共有キャッシュの状態を観測して被害者のアクセスパターンを推測できる
  • 一般的なプリフェッチャは、過去のメモリアクセスアドレスの追跡に基づいて、今後アクセスされるアドレスを予測する
  • DMPは、連結リスト走査のような不規則アクセスパターンを処理するため、メモリ内容まで考慮して取得すべきデータを決定する
  • この動作はハードウェアレベルでデータとメモリアドレスを混在させるため、計算スタック全体を非定数時間(non-constant-time)のようにしてしまう可能性がある

脆弱性の判断と緩和策

  • 実装が脆弱かどうかを判断するには、中間値が秘密依存でポインタのように見える状態を、どの時点でどのように作り出せるかを把握する必要がある
  • この評価には暗号解析とコード検査が必要であり、手作業で遅いうえ、他の攻撃手法を排除できるわけでもない
  • 一部のプロセッサではDMPを無効化できる
    • m3 CPUでは DIT bit の設定がDMPを効果的に無効化する
    • m1とm2には当てはまらない
    • Intel Raptor Lakeでは DOIT bit によってDMPを無効化できる
  • 2024年4月、Hector Martin(marcan)がm1・m2 CPUでDMPを無効化するHID設定ビット SYS_APL_HID11_EL1[30] を発見した
    • この chicken bit 設定にはカーネルサポートが必要
    • 現在のmacOSにはそのサポートがない
    • 関連情報は @marcanの投稿 にある
  • ユーザーには最新ソフトウェアの利用と定期的な更新が推奨される
  • 暗号ライブラリ開発者は、対応するCPUであればDIT/DOIT bitを設定できる
  • 入力ブラインディング は、一部の暗号スキームで攻撃者制御の中間値を避ける助けになる可能性がある
  • 攻撃者がDMPの起動を測定できないようハードウェア共有を避ければ、暗号プロトコルの安全性をさらに高められる

公開とその後の更新

  • 研究チームは2023年12月5日にAppleへ結果を開示しており、これは公開リリースの107日前だった
  • 2024年8月、GoFetchは Pwnie Award 2024 Best Cryptographic Attack を受賞した
  • 2024年12月の後続研究では、Intel DMPのセマンティクスをリバースエンジニアリングし、DMPが無効なポインタを逆参照する場合でも情報を漏えいさせうる手法を示した

1件のコメント

 
GN⁺ 2024-03-23
Hacker News のコメント
  • 効率コアのようなものが入る時代なら、現代アーキテクチャには 暗号化コア も必要かもしれない
    こうしたコアは定数時間アルゴリズムに関する保証を明示的に提供し、プリフェッチや分岐予測などを行わないようにすべきだろう
    Itanium に似ているが「暗号化プロセッサ」に限定した形なら、省かれる機能も多いので、原理的にはコア自体のシリコン面積もそれほど大きくならないはず
    暗号化コードを実装する立場なら、こういう問題は酒でも飲みたくなるほどつらそうだ。最善の状況でも難しい戦いなのに、正しく実装しても現在そして将来の無数のプロセッサ機能がいつでもコードを壊しうる

    • 暗号実装者の立場から見ると、こういう問題は本当に気が狂いそうになる
      でも 暗号化コプロセッサ はあまりに破壊的な解決策だ。そのコアへ切り替えて戻ってきて、メモリを共有して、などという基盤を山ほど作らなければならない
      さらに深刻なのは、RSA の乗算だけをそのコアに移して終わりにはできないことだ。鍵はどこかでパースされたはずだが、そのパーサも暗号化コアで動かすのか? ネットワークから入ってきたらどうする? 鍵をすべて保護しても、CPU サイドチャネルが暗号化されたメッセージを漏らしたら問題ないのか? 鍵でないなら大丈夫だと見なせるのか?
      非暗号コードでこうした攻撃があまり見られないのは、標的を見つける作業がアプリケーションごとに違いすぎるからであり、暗号ライブラリでは誰もが鍵漏えいは良くないと認識しているからだ
      結局のところ、プロセッサ設計者は前提を壊すべきではないし、少なくとも壊す前に私たちと話すべきだ
    • より現実的な方向は、実行コードの特定区間で CPU のこうした構成要素を無効化できる モード切り替え だろう
      抽象化の単位はおそらくスレッドレベルになる可能性が高い
    • それって Secure Enclave の存在理由では?
      https://support.apple.com/guide/security/secure-enclave-sec5...
    • 暗号化バス MMU は 1990 年代から存在していた
      だが、コスト最適化されたクラウドアーキテクチャがコンシューマ向けハードウェアへ偏ることで CPU 市場を飲み込み、今では大規模アプリケーションでも現実的な選択肢はコンシューマ向け CPU しかない
    • 多くの現代アーキテクチャには、通常いくつかの一般的なアルゴリズムを高速化する 暗号化拡張 がある
      新しいアルゴリズムを可能にするには、いくつかの暗号プリミティブ命令を追加するのも良いかもしれない
  • 論文によれば、「OpenSSL はローカルなサイドチャネル攻撃は脅威モデルの外にあると見ており、Go Crypto チームはこの攻撃の深刻度を低く見積もっている」とのこと

  • こうしたサイドチャネル攻撃の最終的な帰結は、いかなる最適化もなく、すべての命令があらゆる状況で同じサイクル数で実行される CPU ということになるだろう
    だが、そんなものは決して実現しない。遅い CPU を望む人はいない
    リモートから悪用できないなら心配する問題ではないと思う。もちろん マルチテナントなクラウド仮想化 は別だが

    • 信頼できないコードは全部、ひどい 逐次実行コア に投げ込むべきだ
      投機実行もなく、プリフェッチもなく、コンピュータアーキテクチャ 101 の授業に出てくる 5 段パイプラインみたいなコアのことだ
    • 「マルチテナントなクラウド仮想化」という点では、数年前の Intel チップにあった同種の脆弱性ほどは心配していない
      ラックマウント Mac Mini の計算時間を貸し出すクラウド事業者はいくらかあるが多くはなく、それも非常に特定のワークロードやビルド作業向けだ
      そうしたサービスに大金を払う人には問題かもしれないが、Apple Silicon デバイスの圧倒的大多数がクラウドサービスをホストすることは決してないだろう
    • だからこそ 多数のコア と分離が重要になる
      コードを特定コアに隔離すれば、すべてが意図どおり動作するという前提では、エクスプロイトが他のテナントを侵害できなくなる
  • 「DMP を無効化できるか?」については、「可能だが一部のプロセッサでのみ可能。M3 CPU では DIT ビットの設定が DMP を事実上無効化するが、M1 と M2 ではそうではない」とある
    きっとどこかにこれを切る チキンビット があるのでは?

    • こういうビットをどう設定するのか、前から気になっていた
      Swift でできるのか、それともアセンブリが必要なのか?
  • 読んでみると、libsodium のようなライブラリは M3 以降では機密性の高い暗号演算の前に 無効化ビット を設定すればよさそうだ
    また、鍵のいくつかの側面を事前に知っておく必要があるようにも見える
    とてもクールだが、あまり実用的には見えない

  • 2022 年の Augury 攻撃 を思い出した。これも Apple Silicon CPU の DMP プリフェッチを悪用していた
    [1]: https://www.prefetchers.info

    • ちなみに、GoFetch の著者 3 人は Augury にも参加していた
    • そう、本文と FAQ でそれを具体的に言及している
  • Apple にはなぜこんなにハードウェアのバックドア……いや、純粋なバグが多いのだろう?

    • そもそもなぜキャッシュが必要なのか? なぜプリフェッチが必要なのか?
      そのくだらないバックドア陰謀論に答えるなら、人々が速い CPU を求めるからこそ、プロセッサにはキャッシュと時間差がある。定数時間 と高速性能を同時に手に入れることはできないし、Apple だけがプリフェッチを持っている会社でもない
      Apple が暗号化のために定数時間演算を有効にする方法を文書化している資料がある。まるでハードウェアに意図的に設計されていたかのようだ。不思議だね: https://developer.apple.com/documentation/xcode/writing-arm6...
    • Intel と AMD に MeltdownSpectre があったのと同じ理由だ
  • 暗号ルーチンを書くなら、プラットフォームの暗号ライブラリを使うか、ドキュメントに従うべきだ
    https://developer.apple.com/documentation/xcode/writing-arm6...

  • これで Mac や iPad でもマルウェア検査や ウイルススキャナ に意味が出てきた
    攻撃者は同じハードウェア上で実行されている必要がある