【TPM2.0】TPMに脆弱性が発見される。影響範囲は数十億台

先日[TCG TPM2.0 implementations vulnerable to memory corruption](https://kb.cert.org/vuls/id/782720)という脆弱性が発表されました。

CVEは[CVE-2023-1017](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-1017)と[CVE-2023-1018](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-1018)のふたつです。

日本語では[JVNの発表](https://jvn.jp/vu/JVNVU95600622/)、および[impressの紹介記事](https://pc.watch.impress.co.jp/docs/news/1483855.html)等がありますが、では具体的にどういう影響があるんだよってのがいまいちよくわかりません。
ということで自分で調べてみたものです。


# そもそもTPMってなに？

[仕様書](https://trustedcomputinggroup.org/work-groups/trusted-platform-module/)
[Wikipedia](https://ja.wikipedia.org/wiki/Trusted_Platform_Module)
[Microsoft](https://learn.microsoft.com/ja-jp/windows-hardware/design/device-experiences/oem-tpm)

何言ってるのかさっぱりわかんねえ！

まあ要するにハードウェア暗号生成器です。
最近のPCには標準実装されているみたいで、さらにWindows11はTPM2.0がないとインストールすらできないので、知らなくても裏で使われています。


# [CVE-2023-1017](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-1017)

TPM2.0のモジュールライブラリのCryptParameterDecryptionルーチンには、本来の範囲を2バイト超えてデータを書き込むことができる境界外書き込みの脆弱性が存在します。
この脆弱性により、サービス拒否攻撃、任意コード実行に利用される可能性があります。


# [CVE-2023-1018](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-1018)

TPM2.0のモジュールライブラリのCryptParameterDecryptionルーチンには、本来の範囲を2バイト超えてデータを読み込むことができる境界外読み取りの脆弱性が存在します。
この脆弱性により、TPM上の機密データにアクセスされる可能性があります。



# [TCG TPM2.0 implementations vulnerable to memory corruption](https://kb.cert.org/vuls/id/782720)

## Overview

[Revision 01.59 November 2019](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part4_SuppRoutines_code_pub.pdf)というバージョンのTPM2.0仕様書に、バッファオーバーフローの脆弱性が2件発見されました。
TPMのコマンドインターフェイスにアクセスできる場合、悪意を持ったコマンドを送ることで脆弱性を利用することができます。
これによって、機密データの読み込み専用アクセス、および本来ならTPMのみが書き込み可能である保護されたデータ(暗号鍵など)の上書き、といった操作が可能になります。

## Description

Trusted Platform Moduleは、最近のコンピュータのOSに安全な暗号技術を提供し、改竄体制を持たせるための、ハードウェアベースのソリューションです。
近年はクラウドコンピューティングや仮想化の普及に伴い、ソフトウェアベースのTPM実装も市民権を得つつあります。

ハードウェアベースのTPMはDiscrete、Integrated、Firmwareのいずれかの形で実装することができます。
仮想TPMは、Hypervisor形式、もしくは[swtpm](https://github.com/stefanberger/swtpm/wiki)など純粋なソフトウェア実装形式が存在します。

[Trusted Computing Group (TCG)](https://trustedcomputinggroup.org/)はハードウェア・ソフトウェアメーカーの双方から支援を受け、TPMの仕様を策定しています。
TCGは2014年10月に初めてTPM 2.0の仕様を公開し、その後幾度かの改定を行っています。
現在の最新版であるRevision 01.59は2019年11月にリリースされました。
多くのTPMハードウェア・ソフトウェアメーカーは、この仕様に従って、安全性の高い機器を構築しています。
TPMはエンタープライズユースの特殊なハードウェア向けから、IoT機器まで、様々なデバイスに採用されています。

[TPM Library Specification Architecture](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part1_Architecture_pub.pdf)は、クライアントソフトウェアが[パラメータの暗号化](https://www.wolfssl.com/tpm-parameter-encryption/)を含む様々な機能を実行できるようにする『セッションベース暗号化』の仕様です。
セッションベース暗号化は、パラメータの機密性を確保するために使用されます。
OSやクライアントソフトウェアは、Cipher Feedback(CFB)あるいはhash-based XOR obfuscationなどのアルゴリズムで、パラメータの暗号化を安全に提供します。

Quarkslabのセキュリティ研究者は、TPMの仕様書から、一部のコマンドにおいてパラメータを処理する部分にふたつの脆弱性を発見しました。
`CryptParameterDecryption()`には境界外読み取りの脆弱性が存在し、領域外の2バイトからのリードアクセスが可能でした。
また領域外の2バイトに書き込むことも可能であり、メモリの破壊を引き起こします。

脆弱なバージョンのTPMにアクセスできる場合、攻撃者は細工したコマンドを送信することでこの脆弱性を利用し、意図されていない領域にアクセスできる可能性があります。
OSはこれらの機能をTPMファームウェアに依存しているため、従来のホストベースのセキュリティ機能ではこのアクセスの検出・防止は困難です。


## Impact

脆弱なTPMに細工されたコマンドを送信することで、機密データへのアクセスが可能です。
場合によってはTPMファームウェアの上書きも可能です。
これにより、TPMのクラッシュ、任意コード実行を行える可能性があります。
攻撃コードはTPM内で実行されるため、デバイス内のコンポーネントからは検出が困難である可能性があります


## Solution

アップデートを適用する。

Trusted Computing Groupは、この脆弱性への対応を含む[エラッタをリリース](https://trustedcomputinggroup.org/resource/errata-for-tpm-library-specification-2-0/)しました。
ユーザは、システムの安全性を確保するために、ハードウェアメーカーもしくはソフトウェアメーカーが提供するアップデートをできるだけ早く適用しなければなりません。
TPMチップについてはファームウェアアップデートが必要となる場合があり、これはOSベンダーやOEMが提供することがあります。
場合によっては、TPMのアップデートプロセスの一環として、各設定値を工場出荷時のデフォルト値にリセットすることを要求するかもしれません。

[TCGのエラッタ](https://trustedcomputinggroup.org/resource/errata-for-tpm-library-specification-2-0/)は、本記事が取り上げた以外のセキュリティ問題にも対処しています。


## Acknowledgements

これらの脆弱性を発見・調査してくれたFrancisco FalconとIvan Arceに感謝します。
TGCのメンバーは、これら脆弱性の対処について、我々や他のベンダーと緊密に連携してくれました。


## Vendor Information

ここ『View all 1609 vendors』を押すとChromeが死ぬ。


## References

https://trustedcomputinggroup.org/resource/tpm-library-specification/
https://trustedcomputinggroup.org/membership/member-companies/
https://trustedcomputinggroup.org/membership/certification/tpm-certified-products/
https://www.intel.com/content/www/us/en/business/enterprise-computers/resources/trusted-platform-module.html
https://learn.microsoft.com/en-us/windows/security/information-protection/tpm/trusted-platform-module-overview
https://google.github.io/tpm-js/
https://learn.microsoft.com/en-us/windows/security/information-protection/tpm/tpm-recommendations


# エラッタ

[エラッタ](https://trustedcomputinggroup.org/resource/errata-for-tpm-library-specification-2-0/)のうち、該当部分への言及はほんの数行です。

ちなみに関数定義は[このへんにある](https://trustedcomputinggroup.org/wp-content/uploads/TCG_TPM2_r1p59_Part4_SuppRoutines_code_pub.pdf)っぽいですが、PDFのソースとか差分とか読むとかつらすぎてつらいのでGitHubとかでやってほしい。


## 2.6 Size Checks

### 2.6.1 CryptParameterEncryption/Decryption [code]

関数`CryptParameterEncryption()`および`CryptParameterDecryption()`において、暗号化および復号されるパラメータのサイズが正しくチェックされていません。
この問題の修正には、パラメータバッファの長さが少なくとも2バイトであることをチェックし、そしてバッファサイズを読み取るために`BYTE_ARRAY_TO_UINT16()`ではなく`UINT16_Unmarshal()`を使うように修正する必要があります。

修正後の`CryptParameterDecryption()`関数は、入力バッファが十分なデータを持っていないときに`TPM_RC_INSUFFICIENT`を返します。
修正後の`CryptParameterEncryption()`関数は、内部レスポンスバッファに十分なデータがないときは失敗し、`TPM_RC_FAILURE`を返します。



# 感想

専門的なところはさっぱりわからないので、わりと雰囲気で訳しているところが多々あります。
誰かが修正してくれるはず。
`hash-based XOR obfuscation`とか何。


さてこのバグは、関数の引数における、典型的な[境界外読み取り](https://jvndb.jvn.jp/ja/cwe/CWE-125.html)および[境界外書き込み](https://jvndb.jvn.jp/ja/cwe/CWE-787.html)の脆弱性ですね。
理屈は単純ながら、XSSやSQLインジェクションといった強豪たちと毎年[ランキングの最上位を争っている](https://cwe.mitre.org/top25/archive/2022/2022_cwe_top25.html)危険な脆弱性です。
影響範囲は、リファレンスに従ってTPMを実装している全ての機器であり、すなわち現在使用されているほぼ全てのPCということです。
とんでもない影響範囲ですね。

ていうか、C言語は未だに引数を安全に受け取ることすらできないのかよ。
PHPを使えばこんな心配全くしなくていいのにね。 [^1]

それにしても、こんなセキュリティの中枢ともいえる部分にまで深刻なセキュリティバグが入り込んでいるとは驚きです。
世界トップレベルの頭脳が集っているはずのところですらこれなのですから、一般人レベルでのバグ根絶なんて不可能だってことがよくわかります。
そう、私がバグを仕込んでしまうのも仕方ないってわけですよ。

[^1]: 言いたいことはわかってるので言わなくていい。