Raspberry Pi 3 + Raspbian Jessie (2017-07-05) でTPMを使う


#### updates
- 2017-08-23 9:50 dd のエラーが macOS 特有の問題である旨を追記
- 2017-08-23 10:14 カーネルビルド終わった
- 2017-08-24 5:57 TSSセットアップ完了
- 2017-08-25 5:52 デバイスツリー追加とリグレッションテスト（失敗）
- 2017-08-25 8:55 リグレッションテスト成功、TSS 2.0 デモ成功

----

### はじめに

http://qiita.com/mune10/items/5f565fcd8f010179d529 を追っかけてTPMを使えるようにする。このページには書いてないけどひっかかりそうなポイントは以下。

- **macOS限定**: 最新版（2017年6月、7月版）の Raspbian Jessie のイメージにはバグがある→ `dd` コマンドに `conv=sync` オプションを付ける
- IBM版Software TPMをビルドする前に `libssl-dev` を導入しておく必要がある
- regression test する前に、 `gawk` を導入しておく必要がある (new! 2017-08-25)

### Jessie のインストール
最新版を **macOSの** `dd` で焼くとコケる。どうもイメージ作成時にミスが発生して、ブロック数の誤ったイメージが公開されているらしい。2017-06版にも同様のミスがあって、ふつうに `dd` するとうまくいかない。やっかいなことに、Ubuntu の `dd` では特に問題が発生しないとのことなので、当分（今後ずっと？）こういう状態になると思われる。m

```shell-session
$ sudo dd bs=1024m if=2017-06-21-raspbian-jessie.img of=/dev/rdisk2
Password:
dd: /dev/rdisk2: Invalid argument
4+1 records in
4+0 records out
4294967296 bytes transferred in 250.730429 secs (17129821 bytes/sec)
```

対策は `dd` に `conv=sync` というパラメタを付けること。右記参照→ [Latest Raspbian (2017-07-05-raspbian-jessie) dd: /dev/rdiskX: Invalid argument on OSX and other potential issues with “apt-get” post install – NERDlogger.com](http://nerdlogger.com/2017/08/17/latest-raspbian-2017-07-05-raspbian-jessie-dd-devrdiskx-invalid-argument-on-osx-and-other-potential-issues-with-apt-get-post-install/)

```shell-session
$ sudo dd bs=1024m if=2017-07-05-raspbian-jessie.img of=/dev/rdisk2 conv=sync
Password:
4+1 records in
5+0 records out
5368709120 bytes transferred in 309.039708 secs (17372231 bytes/sec)
tmishina@tmishina-mbp:~/workspace/raspbian
```

### IBM版 Software TPM をビルド
何も考えずに `make` すると `openssl/evp.h` が存在しない、というエラー。

```shell-session
pi@pi3:~/ibmtpm/src $ make
/usr/bin/gcc -Wall -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Werror -Wsign-compare -c -ggdb -O0 -DTPM_POSIX -D_POSIX_ -I../utils -I. AlgorithmCap.c -o AlgorithmCap.o
In file included from LibSupport.h:90:0,
                 from Tpm.h:67,
                 from AlgorithmCap.c:67:
TpmToOsslHash.h:72:25: fatal error: openssl/evp.h: No such file or directory
 #include <openssl/evp.h>
                         ^
compilation terminated.
makefile:79: recipe for target 'AlgorithmCap.o' failed
make: *** [AlgorithmCap.o] Error 1
```

`openssl-devel` が必要そう。

```shell-session
pi@pi3:~/ibmtpm/src $ sudo apt-get install -y libssl-dev
（後略）
```

改めて make する。

```shell-session
pi@pi3:~/ibmtpm/src $ make
/usr/bin/gcc -Wall -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Werror -Wsign-compare -c -ggdb -O0 -DTPM_POSIX -D_POSIX_ -I../utils -I. AlgorithmCap.c -o AlgorithmCap.o
（後略）
```

うまくいったっぽい。

```shell-session
pi@pi3:~/ibmtpm/src $ ls -l tpm_server 
-rwxr-xr-x 1 pi pi 985172 Aug 22 23:38 tpm_server
```

起動。

```shell-session
pi@pi3:~/ibmtpm/src $ sudo cp tpm_server /sbin
pi@pi3:~/ibmtpm/src $ tpm_server > /dev/null 2>&1 &
[1] 4945
pi@pi3:~/ibmtpm/src $ jobs
[1]+  Running                 tpm_server > /dev/null 2>&1 &
```

OK、生きてる。

### Linux カーネルの再コンパイル

いろいろインストール。

```shell-session
pi@pi3:~ $ sudo apt-get install bc libncurses5-dev i2c-tools
Reading package lists... Done
（後略）
```

このあとカーネルを取得してカーネルビルド。 `git clone` して、まず設定のための `make` は1分くらいで終了。次にconfig 変更。

```
pi@pi3:~/linux $ less .config
（中略）
CONFIG_MAX_RAW_DEVS=256
CONFIG_TCG_TPM=y
CONFIG_TCG_TIS_CORE=m
CONFIG_TCG_TIS_SPI=m
CONFIG_TCG_TIS_I2C_ATMEL=m
CONFIG_TCG_TIS_I2C_INFINEON=m
CONFIG_TCG_TIS_I2C_NUVOTON=m
CONFIG_TCG_ATMEL=m
CONFIG_TCG_VTPM_PROXY=m
CONFIG_TCG_TIS_ST33ZP24=m
CONFIG_TCG_TIS_ST33ZP24_I2C=m
CONFIG_TCG_TIS_ST33ZP24_SPI=m
# CONFIG_XILLYBUS is not set
（後略）
```

よし。ビルド開始。温度怖いので一応監視。せいぜい60度といったところ。

```shell-session
pi@pi3:~ $ while [ 1 ] ; do vcgencmd measure_temp ; sleep 60 ; done
temp=55.8'C
（中略）
temp=58.5'C
temp=59.6'C
temp=60.7'C
```

ビルド中の風景。
![IMG_7931.JPG](https://qiita-image-store.s3.amazonaws.com/0/68614/0c2ec1c7-4e3a-2bab-ca55-f73555aa5adb.jpeg)

ビルド完了！　記録は1時間8分16秒でした。

```shell-session
pi@pi3:~/linux $ time make -j4 zImage modules dtbs
scripts/kconfig/conf  --silentoldconfig Kconfig
  CHK     include/config/kernel.release
  WRAP    arch/arm/include/generated/asm/clkdev.h
（中略）
  IHEX2FW firmware/keyspan_pda/keyspan_pda.fw
  IHEX2FW firmware/keyspan_pda/xircom_pgs.fw

real    68m16.419s
user    247m19.270s
sys     11m39.660s
```

インストールして再起動したら無事カーネル更新完了。

```shell-session
pi@pi3:~ $ uname -r
4.9.44-v7+
```

### TPM デバイスツリーの追加

~~これは…ハンズオンで物理的にどんなチップを使うかがわからないと、どっちを組み込めばいいのかわからない？　とりあえずスキップ（2017-08-24 5:39）。次項の TSS は間違いなく SWTPM でも必要なはず。~~
参考ページが更新されていたので、Nuvoton のチップを I2C 経由で使う、という前提でデバイスツリーを追加してみる（Update 2017-08-25 5:32）。

```shell-session
pi@pi3:~/tpm_device_tree $ dtc -@ -I dts -O dtb -o i2c-nuvoton.dtb i2c-nuvoton.dts
Warning (unit_address_vs_reg): Node /fragment@0 has a unit name, but no reg property
```
大丈夫！？

```shell-session
pi@pi3:~/tpm_device_tree $ sudo cp i2c-nuvoton.dtb /boot/overlays/
pi@pi3:~/tpm_device_tree $ echo 'dtoverlay=i2c-nuvoton' | sudo tee /boot/config.txt 
dtoverlay=i2c-nuvoton
pi@pi3:~/tpm_device_tree $ tail -5 /boot/config.txt 
dtoverlay=i2c-nuvoton
```
**tee に -a 付け忘れた！** 破壊してしまった…。別の microSD から引っ張ってきて復旧させよ。

```shell-session
tmishina@tmishina-mbp:~/tmp
 $ scp /Volumes/boot/config.txt pi3:/home/pi/
config.txt                          100% 1664   329.5KB/s   00:00    
```
`enable_uart` と `core_freq` の設定と、上記の `dtoverlay=i2c-nuvoton` をセットして `/boot/` へコピー。復旧できている気がする…。大丈夫かな。

```shell-session
pi@pi3:~ $ sudo modprobe tpm_i2c_nuvoton
pi@pi3:~ $ 
```
`modprobe` までは問題なし。実機ではどう出るか？


### TSSのセットアップ

ibmtss1045.tar.gz をダウンロードしてビルド。特に問題なく完了。テストするときに SWTPM を起動しておくことを忘れずに！（ここに来るまでの間に何度も再起動しているので止まっているはず）→ `tpmserver > /dev/null 2>&1`

テスト結果。ずらずら出てきたので途中省略。

```shell-session
pi@pi3:~ $ head -3 tss_test_result 
46 properties
TPM_PT 00000100 value 322e3000 TPM_PT_FAMILY_INDICATOR - a 4-octet character string containing the TPM Family value (TPM_SPEC_FAMILY)
TPM_PT 00000101 value 00000000 TPM_PT_LEVEL - the level of the specification
pi@pi3:~ $ tail -3 tss_test_result 
TPM_PT 0000012c value 00000400 TPM_PT_NV_BUFFER_MAX - the maximum data size in one NV write command
TPM_PT 0000012d value 00000000 TPM_PT_MODES - a TPMA_MODES value, indicating that the TPM is designed for these modes
TPM_PT 0000012e value 00000400 TPM_PT_MAX_CAP_BUFFER - the maximum size of a TPMS_CAPABILITY_DATA structure returned in TPM2_GetCapability
```

PCR Extendしてみる。正しいかどうかよくわからない…と思ったら、値は [参考ページ](http://qiita.com/mune10/items/5f565fcd8f010179d529) と全く同じになってた。

```shell-session
pi@pi3:~ $ cd ibmtss/utils/
pi@pi3:~/ibmtss/utils $ ./pcrextend -ha 10 -ic ddddd
pi@pi3:~/ibmtss/utils $ ./pcrread -ha 10
count 1
 digest length 32
 94 51 0c 61 2e 79 ce d7 07 51 3d 2b c6 99 3a 7f 
 09 f3 0b 98 44 95 4b 9e 2d ab ed 0b 36 86 62 c1 
```

### Regression Test

これを書いている午前5時、今日はなぜか子どもが泣き出した…お母さんの機転により、牛乳飲ませたら寝た。あやうい…。

閑話休題、デモのセットアップと Regression Test やります。

```shell-session
pi@pi3:~/ibmtss/utils $ sudo cp libtss.so /usr/lib/
pi@pi3:~/ibmtss/utils $ sudo ln -s /usr/lib/libtss.so /usr/lib/libtss.so.0
pi@pi3:~/ibmtss/utils $ sudo ln -s /usr/lib/libtss.so /usr/lib/libtss.so.0.1
```

ではテストを。結構時間がかかる、2-3分くらい？　大量のメッセージが流れる（screenのバッファを超えてしまいそう）。

```shell-session
pi@pi3:~/ibmtss/utils $　./reg.sh -a
（中略）
clockset: failed, rc 000001c4
TPM_RC_VALUE - value is out of range or is not correct for the context Parameter number 1
```

こけた。がーん…。理由がわからない…あ、これか！？ `gawk` がないエラー。

```shell-session
./regtests/testclocks.sh: line 59: gawk: command not found
```

`apt-get install -y gawk` してから再挑戦。

```shell-session
pi@pi3:~/ibmtss/utils $　time ./reg.sh -a
（中略）
Success - 31 Tests 0 Warnings


real    3m18.112s
user    0m25.980s
sys     0m7.570s
```
成功！

### デモ

apache等々をインストールしてからデモをインストール。

```shell-session
pi@pi3:~/ibmtss $ ls
demo  ibmtss1045.tar.gz  ibmtss.doc  ibmtss.html  LICENSE  tpmutils  utils
pi@pi3:~/ibmtss $ cd demo
pi@pi3:~/ibmtss/demo $ ls
admin.php  demo.css     halgsha1.inc    handles.php  IBM-TSS-Demo.doc  keycreate.php  makefile-common  makefilesha1      navdev.html  nv.php     pcr.php    sign.php
block.png  footer.html  halgsha256.inc  ibm.png      index.php         makefile       makefile_dev     makefilesha1_dev  nav.html     nvram.php  quote.php  unseal.php
pi@pi3:~/ibmtss/demo $ sudo mkdir /var/www/html/tpm2
pi@pi3:~/ibmtss/demo $ sudo make
（後略）
```

特に問題なく完了。さてアクセス。

![スクリーンショット 2017-08-25 6.34.46.png](https://qiita-image-store.s3.amazonaws.com/0/68614/4ef460f1-47cb-8432-f8b7-1cf4c4f9fc33.png)

あれ、左側の　navbar が出ない…と思ったら php 入れ忘れてただけだった。入れ直したら無事に画面が表示された。


### デモ (TBD)