RaspberryPiにTPMを接続しOpenSSLから使用する

はじめに

こんにちは。CTO室のringoです。早いもので私が入社して1年が過ぎました。最近は出社するついでに映画館へ行くことが楽しみになっています。

さて、今回の記事ではWindows11のインストールに必要とのことで耳に入ることも多くなったTPMについて取り上げたいと思います。TPMとはTrusted Platform Moduleの略称で秘密鍵の生成や機密情報の保護などの機能をもつセキュリティチップのことです。PCのマザーボードに搭載されていてOSと連携してセキュアブートやストレージの暗号化を行うことができます。

TPMを使用することのメリットは、暗号化に使用する鍵の管理をデバイスのストレージとは別のハードウェア上で行うことで鍵の漏洩を防ぐことができます。
例えば今回の記事で紹介する例では、暗号化された鍵をデバイス内に保存し、使用するときはTPM内で複合して使用します。鍵を生成したデバイスと使用したTPMの組み合わせでしか鍵をアクティベートして使用することはできません。そのためデバイス内の鍵を盗られて別の場所で使用するということは不可能になります。この仕組によって鍵を安全に使用することを実現しています。
ただ現状ラズパイではブートローダーが公開されていないためセキュアブートはできません。

今回の記事ではラズベリーパイにInfineon製のTPMを接続しOpenSSLとの連携を試します。

用意するもの

  • RaspberryPi 3b+
  • Infineon OPTIGA™ TPM SLM 9670 TPM2.0

TPMについてはDigi-KeyやMouserで購入できます。今回使用するラズパイにそのまま刺して使えるモジュールだと7000円ぐらいで、チップ単体だと500円程度で購入できます。

RaspberryPiとTPMのセットアップ

Infineon社が公開しているアプリケーションノートを参考にセットアップを行います。
Get started with OPTIGA™ TPM

Raspbianのインストール

アプリケーションノートのカーネルとバージョンを合わせたいので最新ではなく、古いイメージを使用します。
raspbian-2020-02-14

細かい説明は他のサイトに任せるとして、SDカードにRaspbianを書き込んだあと、最低限の設定としてSSHの有効化とWiFiの設定、パスワードの変更やパッケージのアップデート等を行います。
使用するTPMがSPIで接続されるのでraspi-config -> InterfaceOptions -> SPIを選択してSPIを有効化します。
インストールしたOSとカーネルのバーションは次のようになりました。

$ lsb_release  -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 10 (buster)
Release:        10
Codename:       buster
$ uname -r
4.19.97-v7+

TPMのドライバをインストールする

kernelのコンパイルが必要だと思っていましたが、どうやら初期から入ってるドライバで認識するようです。
/boot/config.txtdtoverlay=tpm-slb9670を追記して再起動します。TPMモジュールを接続していない場合はラズパイのピンに接続して起動します。

ls /dev/tpm0 コマンドでtpmが表示されたらTPMがラズパイから認識されています。

テスト

Infineon Embedded Linux TPM Toolbox 2 for TPM 2.0でテストできます。

git clone https://github.com/Infineon/eltt2
make
./eltt2 -gc
TPM capability information of fixed properties:
=========================================================
TPM_PT_FAMILY_INDICATOR:        2.0
TPM_PT_LEVEL:                   0
...
...
...
TPM Reset since the last TPM2_Clear:            10
Number of times that TPM2_Shutdown:             0
Safe:                                           1 = Yes

TPM Software Stack(TSS)ついて

TPMを使用するためのAPIを定めた標準仕様でTrusted Computing Groupによって公開されています。


OPTIGATM TPM Application Noteより

階層が上のAPI(Feature API (FAPI))ほど抽象化されておりソフトウェア開発者が使いやすいように設計されています。逆にESAPI(Enhabced System API)だとTPMの機能に直接アクセスできますがTPMの仕様を理解する必要があります。

ソフトウェアのセットアップ

今回の記事でTPMを使用するのに必要なソフトウェア一覧は以下になります。
インストール手順は各リポジトリに書いている通りで特別苦戦するところはないと思います。

最終的に以下のコマンドでOpenSSLからTPMを使えるようになればOKです。

openssl engine -t -c tpm2tss
(tpm2tss) TPM2-TSS engine for OpenSSL
 [RSA, RAND]
     [ available ]

OpenSSLの暗号化エンジンにTPMを使用する

ここまででOpenSSLからTPMを使用する準備が整いました。
試しにrandコマンドを試してみます。-engineでtpm2tssを指定することでTPMのランダム生成機能を使用できます。

openssl rand -engine tpm2tss -hex 8
engine "tpm2tss" set.
523e4fc6206666a5

公開鍵で暗号化 -> 秘密鍵で復号

流れとしては秘密鍵と公開鍵のペアを作成し、公開鍵で暗号化したあと、秘密鍵でデータを複合し確認します。

ポイントとしてはtpm2tss-genkeyで生成した鍵はTPMの中に保存されディレクトリには暗号化された鍵が保存されます。key.pairを見てみると——BEGIN TSS2 PRIVATE KEY——で始まることが確認できます。

cat key.pair
-----BEGIN TSS2 PRIVATE KEY-----
MIICEgYGZ4EFCgEDoAMBAQACBEAAAAEEggEYAR

鍵はパスワードで保護されるだけでなくPCR値(Platform Configuration Registers Value)と言われる値で保護されています。そのためここで生成した鍵は別のデバイスで使用することはできません。

電子署名の生成と検証

OpenSSLではopenssl dgst -sha256 -signコマンドで電子署名を生成できます。電子署名にTPMで生成した鍵を使いました。

暗号化のときと同じようにengineコマンドでtpm2tssを指定することでTPMで生成した鍵を使用することができます。

終わりに

RaspberryPiでTPMを使う手順とOpenSSLからTPMを使用する方法についてまとめました。
PKCS11を使用する方法やFAPIからTPMを使うことなど深堀りしたかったのですが勉強しながらで思ったより時間がかかってしまいました。
また、ラズパイを使うのであればIoTにおけるTPMの活用だったり、linux上ではなくマイコンレベルでのTPMについても今後調査していけたらと思います。