2012-06-01

FedoraでUEFIセキュアブートを実装すること

mjg59 | Implementing UEFI Secure Boot in Fedora

Fedora 17が今週リリースされた。便利かつ自由であり、万人におすすめできる。ぜひとも試すべきだ。ところで、今回のリリースは興味深いリリースでもある。これは、UEFIセキュアブート以前の時代の最後のFedoraだからだ。Fedora 18は、Windows 8と同時期にリリースされる。すでにご存知のように、Windows 8用のハードウェアはすべて、デフォルトでセキュアブートが有効になる。Microsoftは当初の計画から思い直して、全てのWindows用x86機は、ファームウェア上でこの機能を無効にするオプションと、ユーザーに独自のキーを追加する機能を提供しなければならないとしたものの、Fedoraを実行させるために、ユーザーに自力でファームウェア設定をいじらせるというのは、現実的ではない。我々はこの事態に対処するべく動いていた。最終的な方法は、理想ではないが、しかしあらゆる方法を考慮した結果、これが一番まともな選択であるように思う。すなわち、ユーザーにFedoraをインストールさせ、かつ、ユーザーの自由を保証する方法だ。

マシンをブートせよ

今年末に買うハードウェアは、ほとんどがWindows 8認証を受けたものになる。つまり、ハードウェアはあらかじめ、いくつかのセキュアブートキー搭載している。もしWindows 8がインストール済みならば、セキュアブートはデフォルトで有効になっている。キーは固定ではないなく、マニュファクチャーごとに異なるキーを搭載しているだろう。しかし、Windowsロゴを持つハードウェアはすべて、Microsoftキーを搭載している。[1]

我々は、Fedoraキーを作成して、ハードウェアベンダーに搭載するという方法を考えた。しかし、問題もあるのでやめることにした。第一に、ベンダーからは積極的な反応が得られたものの、全ベンダーがキーを搭載するというのは現実的ではない。つまり、大昔の、ハードウェアを購入するまえに互換リストに載っているかどうかを確かめる時代に逆戻りだ。ユーザーの反感を買うだけだ。第二に、Fedoraを特権階級に引き上げてしまうという事だ。大規模なディストリビューションであるがために、我々は他のディストリビューションより、ハードウェアベンダーとの意思疎通が図りやすい。Fedoraキーを搭載するシステムはFedoraを問題なく起動できる。ではMandrivaは? Archは? Mintは? Mepisは? ディストリビューション専用のキーを作成してハードウェアベンダーに取り込むよう働きかけるのは、他のディストリビューションの反感を買う。我々は実力で競争すべきであって、OEMとコネによって競争すべきではない。

別の方法としては、統一的なLinuxキーを作成することだ。これも難しい。なぜならば、まず署名と鍵の配布に責任を持つ団体を見つけなければならない。つまり、完璧にセキュアに保たれたルートキーを保持し、署名の求めに応じなければならないのだ。これは高くつく。何百万ドルの規模で高くつく。また、そのような機構の起ち上げには時間がかかる。そんな時間はどこにもない。そもそも、そんな仕事を引き受けようというボランティアなどどこにもいない。汎用的なLinuxキーという選択もない。

最後の選択肢は、あまり喜ばしいものではないが、まあ、一番マシな方法だ。Microsoftはsysdev portalで署名サービスを提供している。完全に無料というわけではない。99ドルの利用料がかかる。しかし、現実的な選択肢の中で、一番安い方法だ。ハードウェアとの最大の互換性を保証できるし、Fedoraを他のディストリビューションに比べて特権的な地位に押し上げることもない。もし、もっといい方法があるのだとしたら、まだ我々は発見していないのだ。そういうわけで、これが我々の選ぶ道だ。我々の最初のブートローダーは、Microsoftキーで署名される。

ブートローダー

我々は、至極単純な理由から、署名をマルチレイヤー化することにした。Microsoftの署名サービスを使って署名するのは手作業であり、重荷だからだ。ブートローダーのアップデートが、IEとスマートカードと手作業のパッケージ化という理由によって遅れることがあってはならない。代わりに、我々は非常に単純なブートローダー[2]を書いた。これは、単に本物のブートローダー(grub 2)をロードして、Fedoraによる署名キーで署名されているかどうかを確認してから、実行するだけのものだ。Fedoraの署名キーを使うという事は、grubのビルドとアップデートのプロセスを、既存のFedoraのビルドシステムで、我々の手で行えるという事だ。最初のブートローダーは、稀にしか更新されない。

[1] 実際、すべてのハードウェアはMicrosoftキー搭載しているであろう。セキュアブートにおいては、UEFIドライバーも署名されていなければならない。署名フォーマットの都合上、ひとつのバイナリに対して、ひとつの署名しか用意できない。互換性のために、おそらくkほとんどの拡張ハードウェアは、Microsoftキーによって署名されるだろうから、すべてのシステムベンダーは、ハードウェアの動作のために、Microsoftキーを認識しなければならないだろう。

[2] ソースはここにある。UEFIに移植されたcryptoライブラリとOpenSSLに依存している。それらは、できるだけ早く、追ってアップロードする予定だ。我々は、最低でもリリースサイクルごとにしか更新しないつもりだ。これなら、それほどの重荷にはならないだろう。

grubはどうするのか。我々はすでに、EFIシステム上のFedora 18では、デフォルトでgrub 2に移行した。しかし、セキュアブートに対応するための作業は、まだ少し残っている。まずはじめに、モジュールのロードを無効にしなければならない。現在、grub 2では任意のコードを実行時にロード可能だ。これはセキュアブートの目的が台無しだ。だから無効にする。次に、ブートするカーネルが信頼されているキーで署名されているかどうかを検証する機能をつける。最後に、カーネルコマンドラインを検証することにより、攻撃者が署名されたカーネルに、任意のコードの実行させないことを保証する。この制限は、セキュアブートを無効にすれば消え去る。

カーネル

セキュアブートとは、ハードウェアに直接触れるコードはすべて信頼できるものにするという思想で成り立っている。信頼できないコードは、すべて信頼できるコードを介さなければならない。これは、ユーザーがカーネルで任意のコードを実行できる場合、破られてしまう。そのため、我々はカーネルモジュールに署名を必須にし、カーネルの一部の機能を無効にする。もっとも明白な例として、もはやユーザー空間からPCI領域に直接アクセスすることはできなくなる。すなわち、グラフィックカードはカーネルドライバーが必須になる。ユーザー空間によるmodesettingは過去のものになる。もちろん、セキュアブートを無効にすれば、これらの制限も無効になる。

署名されたモジュールというのは、ユーザー側からみれば、やや面倒に感じるだろう。我々が提供するドライバーは、すべて署名されるが、外部のドライバーはどうすればいいのか。我々はまだ、其の問題に対する良い解決方法を思いついていない。先にも述べたように、他のディストリビューションでは動かない方法を採用したくはあに。Fedora限定とか、Ubuntu限定のドライバーなどというのは、誰も欲しがるはずがない。これはどうにかして、ディストリビューション互換な方法を構築する必要がある。

待てよ、何を署名するんだ

セキュアブートは、オペレーティングシステムの前にマルウェアのコードが実行されることを防ぐために設計されている。これは何も、机上の空論による脅威ではない。ブート以前のマルウェアというのは実際に存在するし、思っている以上に事態は深刻である。明らかに、ブートローダーは署名されなければならない。さもなければ、署名されたブートローダーを未署名のものに差し替えて、マルウェアをインストールした上で、OSをブートされる。

ではカーネルはどうなのか。カーネルは単なるコードだ。もし、署名されたLinuxのブートローダーを使い、未署名のLinuxカーネルをブートした場合、それはマルウェアである可能性がある。そのマルウェアがWindowsを攻撃できるのであれば、署名されたLinuxのブートローダーとは、もはや単に、署名されたLinuxのブートローダーではない。それは、署名されたWindowsマルウェアのランチャーである。すなわち、そのブートローダーのバイナリはブラックリスト入りになる。もはや、署名されたLinuxのブートローダーは、署名されたLinuxのブートローダーではなくなるのだ。そのため、カーネルは署名されていなければならない。

モジュールはどうか。これも同じ事だ。モジュールは単なるコードだ。少々難しくはなるものの、署名されたカーネルが未署名のモジュールをロードしたならば、未署名のモジュールは偽のUEFI環境を構築して、悪意あるOSのブートローダーに処理を引き渡せる。攻撃者は、署名されたカーネルとマルウェアモジュールを読み込む最小のinitramfsを同梱すればいいだけだ。ブート時間を数秒ほど遅らせることを除けば、検出不可能だ。Xはどうか。GPUのレジスタにアクセスできるのならば、GPUにカーネルの領域をDMAで上書きさせ、任意のコードを実行可能だ。これも難しいものの、実装可能である。もし、他の攻撃方法が制限されているのならば、これだって魅力的な攻撃方法である。

もし、我々が、他のオペレーティングシステムを攻撃可能な署名されたコードを発行したならば、他のオペレーティングシステムが、我々をブラックリスト化する口実となる。これはいい結果をもたらさない。

カスタマイズ

多くのユーザーは、自前でカーネルをビルドしたいと考えている。あるものは、自前のディストリビューションを構築したいとさえ考えている。我々のブートローダーとカーネルを署名するのは、障害となる。我々はバイナリを署名するのに使っている全てのツールを提供する。しかし、明白な理由により、我々はキーを提供するわけにはいかない。そこで、方法はみっつある。まず第一に、ユーザーが自前のキーを生成し、システムファームウェアに設定すること。我々は、ファームウェアに設定されているキーを信頼する。第二に、自前のキーで最初のブートローダーを署名し、Microsoftに99ドル払って署名してもらうこと。そうすれば、他人にコピーを渡して、なにか特別な設定をしなくても、インストールさせることができる。第三には、単にセキュアブートを無効にすることだ。その時点で、機械は現在と同じ自由を提供するようになる。

でも、俺はMicrosoftなんて信用しねぇぞ

システムをカスタムモードにすれば、既存のキーをすべて消去して、独自のキーに差し替えることが可能になるはずである。その後は、単にFedoraのブートローダー(先に述べたように、我々はツールとドキュメントを公開する)を再署名すれば、Fedoraはブートできるが、Microsoftのコードは拒否するコンピューターが完成する。デスクトップ機としては、少々使いづらいかもしれない。何しろ、Microsoftによって署名されたグラフィックやネットワークカードのUEFIドライバーがあるからだが、これも解決可能だ。今、インストールされたドライバーを自動的にホワイトリストに追加するツールの実装方法について検証している。ファームウェアのバックドアさえ考慮に入れなければ、コンピューターが自分が信頼するソフトウェアだけを実行するように、セキュアブートを設定できるのだ。自由とは、実行したいソフトウェアを実行することであるが、実行したくないソフトウェアを選べることでもある。

悪魔に魂を売り渡したのかFedora

我々はこの問題に何ヶ月も取り組んできた。これは、あまりいい解決方法ではないが、実現可能な方法だ。我々は、他の選択肢はすべて、実現不可能であると結論した。スキルのないユーザーがLinuxを実行するのを難しくしては、自由なソフトウェアは少しも発展しない。この方法は欠点もあるものの、90年代に逆戻りすることを防げる。ユーザーは改変したソフトウェアを実行できる自由を保持できる。我々はそのような自由を不可能にする方法は受け入れない。

これは裏切りだろうか。そのとおりである。すでに、Fedoraとユーザーとの間では、不公平が生じている。商標により、改変したディストリビューションにFedoraのアートワークを含めることを禁じている。Fedoraのインフラはすでに、ある者が他の者より、より強い力を持つライセンスで提供されている。これが不公平の元だ。理想ではないが、より良い解決方法が思いつかないことを申し訳なく思う。これは私が恐れていたほど悪くはないが、思っていたほど良くもない。

ARMはどうなる

MicrosoftのARMハードウェアの認証要件では、ベンダーがセキュアブートを無効にしたり、ユーザーにキーを設定したりする機能を提供することを禁じている。我々は、x86と同じようにセキュアブートをサポートできるものの、署名に金を払わなければ、ユーザーは改変版ソフトウェアを実行することができなくなる。我々はこれを受け入れがたい。よってサポートする予定はない。

幸運なことに、これはx86ほど問題にはならない。MicrosoftのARM市場への影響力は、x86に比べれば、極端に低い。この影響を受ける機械は、Windows専用に設計されたハードウェアだけだ。LinuxをARMで実行したいのならば、ハードウェアがないという事態には陥らない。

これは最終決定なのか

違う。我々はこれらの方法をFedora 18の納期までに実装できることに満足しているが、まだ我々が気がついていない解決方法はあるかもしれない。もし、我々が変なことをせずに、ユーザーの自由を増加させられる方法があるのならば、我々はそれを行うつもりだ。

果たして、セキュアブートはうまく行くのだろうか。結局、UEFIという低レイヤーでもコード署名が必要なために、共通のキーが必要になる。現在、その役割はMicrosoftのキーが果たしている。しかし、およそブートレベルでのマルウェアを開発するほどの規模(国家や大企業)ならば、善良なるハードウェアベンダーやソフトウェアベンダーを装って、Microsoftに署名させることは可能である。攻撃が一回きりの目的(ウラン処理施設の破壊など)であれば、存在と目的が判明する前に攻撃が成功することだってあり得る。バイナリにブラックリストを設けるのは間に合わない。

それに、Microsoftのキーが漏れてしまった場合、どうするのだろうか。もちろん、DVDやブルーレイの秘密鍵を信頼された不自由なソフトウェアに同梱する、暗号の初歩もなっていないアホくさい電子制限管理方法とは違い、実装を解析してキーを判明ではないにしても、やはり一つのマスターキーに頼るのは不安がある。

更に問題なのは、カーネルをデバッグする場合、セキュアブートは問題になる。とすると、カーネルハッカーはセキュアブートを無効にした環境で開発することになる。開発者とユーザーの環境が離れていて、果たしてまともなものが出来上がるだろうか。

また、読者の中には、GPLv3準拠なのかどうかを疑う人もいるかもしれない。これはGPLv3準拠である。なぜならば、改変版のソフトウェアを実行する方法があるからだ。独自のキーで署名してファームウェアに設定するか、あるいは単にセキュアブートを無効にしてしまえばよい。そもそも、Tivoizationの主な問題は、GPLなソフトウェアをハードウェアと一体化して出荷して、ハードウェアで改変版のソフトウェアを実行する方法を提供していない場合だ。このように一体化して出荷した場合、ハードウェアは、改変版のソフトウェアを実行できる方法を提供していなければならない。今回の場合、ハードウェアはユーザーが用意するものだから、GPLv3の条件には当てはまらない。

No comments: