このブログはURLが変更になりました

新しいブログはこちら→ https://matsuu.hatenablog.com/

ノートPCのTPMを/dev/randomの乱数生成器として使う

前回のGnukでGPG鍵を生成する際に、/dev/randomからエントロピーを取り出すのが遅い問題の対策を調べていたところ、TPM(Trusted Platform Module)を乱数生成器として使えることが分かったので試してみた。

TPMとは

WikipediaのTrusted Platform Moduleより一部抜粋

概要

RSA暗号演算やSHA-1ハッシュ演算といった機能を有しており、チップ内で暗号化・復号、デジタル署名の生成・検証、プラットフォームの完全性検証を行うことができる。また、TPMの内部でRSAの鍵ペア(公開鍵と秘密鍵)を生成することができる。

TPMの仕様はTCG (= Trusted Computing Group)という国際的な業界団体で策定されており、最新のバージョンは1.2である。

ノートPCだけではなく、デスクトップPCにもTPMは搭載されている。Windows OSとしてはWindows Vistaが初めて正式にサポートした。Intelチップを搭載した初期のMacintoshにもTPMチップを搭載したものがある。

この技術は、さらに発展を遂げている。チップセット等の連携を強化した技術として、Intel Trusted Execution Technology がある。また、仮想機械むけの命令仕様拡張も提案されている。

TPMの機能

TPMは以下の機能を提供する。

また、TPM1.2から以下の機能が追加された。

  • カウンタ
    • 単純増加カウンタ
    • ティックカウンタ
  • オーナー権委任 (パスワードは公開しない)
  • 不揮発性ストレージ保存機能

ビジネス用途のノートパソコンにはTPMが搭載されていることが多い模様。私のメインマシンPanasonic Let's note(CF-Y7)にはこのTPMが載っていた。じゃあとりあえず乱数生成に使ってみましょう。

事前準備

まずBIOSなどでTPMを有効にする必要がある。TPMを有効にする方法はメーカーによって異なるが、Let's noteであれば取扱説明書ダウンロードの内蔵セキュリティチップ(TPM)ご利用の手引きを参照。

カーネルの設定

Linuxカーネルで必要なモジュールを追加。私のノートだとTCG_INFINEONだった。モノによってはTCG_NSCやTCG_ATMELかもしれない。

Device Drivers  --->
 Character devices  --->
  <M> TPM Hardware Support  --->
   <M>   TPM Interface Specification 1.2 Interface
   <M>   National Semiconductor TPM Interface
   <M>   Atmel TPM Interface
   <M>   Infineon Technologies TPM Interface

FedoraやUbuntu、Debianなどの一般的なLinuxディストリビューションなら既にモジュール化されてるかも。未確認。

モジュールを読み込む。/dev/tpm0が生成されることを確認。

# modprobe tpm_infineon
# ls -l /dev/tpm*
lrwxrwxrwx 1 root root       4 2010-11-16 11:44 /dev/tpm -> tpm0
crw-rw---- 1 tss  tss  10, 224 2010-11-16 11:44 /dev/tpm0

こんな感じで表示されたらok。

tpm0が生成されない場合、ドライバが異なるのかも。上記のNational SemiconductorやAtmelを試してみる。

rngdのインストールと設定

ハードウェア乱数生成器と/dev/randomをつなぐrngdを用意するためrng-toolsをインストール。
rngdは--no-tpm=1と指定しなければTPMを/dev/tpm0を自動でみに行くので特に設定はいらない。
Gentooであればrng-toolsをインストール。Debian/Ubuntuもrng-tools。Fedoraもrng-toolsだったと思う。

# emerge rng-tools
# /etc/init.d/rngd start

ベンチマーク

おおよそ24.5kB/s程度生成される模様。このあたりには疎いので、これが速いのか遅いのかわからず。
キーボードやマウスを動かしてエントロピーを形成するよりは遙かに速い。

dd if=/dev/random of=/dev/null count=1000 bs=1024
0+1000 records in
0+1000 records out
124823 bytes (125 kB) copied, 5.07053 s, 24.6 kB/s

ちなみに同じマシンの/dev/urandomは3.9MB/sだった。

$ dd if=/dev/urandom of=/dev/null count=1000 bs=1024
1000+0 records in
1000+0 records out
1024000 bytes (1.0 MB) copied, 0.262949 s, 3.9 MB/s

トラブルシューティング

私のマシンにはTPMを搭載してないようなんですが

intel i8*0チップやAMD/VIA構成であれば、乱数生成器が独自に用意されているかも。詳しくはkernelのRNG周りやman rngdを参照。

rngdが起動できない

/dev/tpm0にアクセスできるか確認する。私がハマったのは、tcsd(trousers)が動いていると/dev/tpm0がbusyになってアクセスできずrngdが起動できなかった。

/dev/randomから取得できない

/var/log/messagesのログを確認。に次のようなログが記録され続ける場合TPM周りで何か問題があるかも。

2010-11-16T02:41:57.068718+09:00 lets rngd: failed fips test
2010-11-16T02:41:57.117682+09:00 lets rngd: failed fips test
...
TPMが載ってるはずなのにBIOSにTPM関連の項目がない

tpm-toolsを使えばLinux上でもTPMの制御は可能。ただしowner passwordがわからないとダメ。owner passwordは自分で調べてください。

tpm-toolsからTPMを有効にするには次のコマンドでいけるはず。

# /etc/init.d/tcsd start
# /usr/sbin/tpm_setenable -e

tcsd(trousers)が動作しているとrngdが/dev/tpm0にアクセスできずRNGを利用できないので、上記が終わったらtcsdは止めておく。

# /etc/init.d/tcsd stop