Jetson Nano Dev Boardを使ってSDカード暗号化をテスト(Jetson Nano secureboot編)


Jetson Nanoのセキュリティ機能

ルートファイルシステムの暗号化を検討するにあたり、まずJetson Nano単体で持つセキュリティ機能を確認する。

NVIDIA Jetson Linux Developer Guideが基本のドキュメントとなる。
現在最新のR32.4.2をベースに確認した。

Security項目の確認をしてみると、大きくセキュアブート(FUSE機能)、およびTrusted Execution Environment(TEE)の項目がある。
Trusted Execution Environment(TEE)はARMアーキテクチャのTrustzoneに関するドキュメントだが、Jetson Nanoは対応していないので、セキュアブート(FUSE機能)を確認する。

ドキュメントおよび試行した結果、Jetson Nanoでは256ビットのRSA公開鍵ハッシュ(PKCキーと呼んでいる)をFUSEへ書き込み、odm_production_modeのFUSEを書き込むと
署名を検証してファームウェアを起動するセキュアブートモードに入るようだ。

最近発売されたJetson Xavier NXでは、上記と合わせて、SBKキーという128ビットAES鍵を保存できるFUSEがあるようで、これを使ってブートローダーの暗号化もできるようだ。
こういうところでエントリーモデルのJetson NanoとJetson Xavier NXの差があるということだろう。

基本の操作としては、

$ openssl genrsa -out rsa_priv.pem 2048

上記で秘密鍵を作って、
odmfuse.shというコマンドでFUSE書き込み、flash.shでファームウェアイメージを作成、秘密鍵で署名してJetson NanoのUSBポートから送り込むという手順となる。

注意点

Securebootについて議論されているフォーラム内にて、
“For more information, please confirm if you use production module of Jetson Nano(with eMMC). The developer kit(with micro SD) does not support the function.”との記載があり、
セキュアブートをサポートするのは”Jetson Nano production module”であると記載がある。

Jetson Nanoにはいくつか種類があるそうだが一度整理する。
わかりやすい説明がseeedstudioのサイトにある。

まず、Jetson Nano Dev Boardに2種類ある。
これは、A02リビジョンとB01リビジョンの2種類で、B01だとJetson Nano production moduleを起動できるのと、カメラコネクタが2つになった点である。
Jetson Nano production moduleは、Dev Board上に載っているSO-DIMMスロットに接続されているボード部分のみの単体製品となる。
製品サイトによると16GBのeMMCを搭載している。
eMMCが載っている分、Jetson Nano Dev Boardより若干高いということだろう。
手元にあるJetson Nano Dev Boardに搭載されているモジュールと見比べてみる。

写真によると、Dev Boardに付属のJetson NanoはSDカードスロットが搭載されているが、
Jetson Nano production moduleは、SDカードスロットの代わりにeMMCチップが搭載されている。
本来、secureboot操作は、このeMMCが貼ってあるJetson Nano production module向けというのが正式な情報のようだ。
つまりB01 Dev Boardにもともと載っているモジュールは、Jetson Nano production moduleではないことに注意。
AUVIDEAのサイトにモジュールの裏面の写真がある。

Jetson Nano Dev Boardではサポートがないそうだが、いったん自己責任でやった結果を記載していく。
もしここで紹介される内容の追試を検討される場合、FUSE操作でJetson Nanoへ不可逆的な変更を加え、失敗すると戻せない操作が含まれていることと、メーカーサポートがないことを確認の上行ってください。

環境構築

以下の品物を用意した。
Jetson Nanoファームウェア構築用環境:
Ubuntu 18.04が入ったPC1台、HDD1TB
USB-MicroUSBケーブル

Jetson Nano Dev board B01版
インテルWifi付き、秋月電子5V4Aアダプターで動作
冷却用4cmファン 
ジャンパーピン2個
Sandisk Extreme 128GB MicroSD
過去作成した、オーディオコーデックボード搭載のATECC608A

MicroSD-USB変換
USBシリアル変換ケーブル

セキュアブート環境構築

32.4.2のL4T Driver packageをダウンロードする。

$ wget https://developer.nvidia.com/embedded/L4T/r32_Release_v4.2/t210ref_release_aarch64/Tegra210_Linux_R32.4.2_aarch64.tbz2

$ tar xvjf Tegra210_Linux_R32.4.2_aarch64.tbz2
$ cd Linux_for_Tegra
$ ./source_sync.sh

途中でTag nameを何度か聞いてくるので、”tegra-l4t-r32.4.2”と入力

Please enter a tag to sync /media/km/hdd/nvidia/NEW/Tegra210_Linux_R32.4.2_aarch64/Linux_for_Tegra/sources/kernel/kernel-4.9 source to
(enter nothing to skip): tegra-l4t-r32.4.2

$ cd ..

これでLinux_for_Tegra/sources以下にカーネルとu-bootのソースをダウンロードできた。

セキュアブート用ファイルの設定。

$ wget https://developer.download.nvidia.com/embedded/L4T/r32_Release_v4.2/t210ref_release_aarch64/secureboot_R32.4.2_aarch64.tbz2
$ tar xvjf secureboot_R32.4.2_aarch64.tbz2

秘密鍵生成。

$ openssl genrsa -out rsa_priv.pem 2048
$ cd Linux_for_Tegra

Jetson Nanoをリカバリーモードに入れる。

ジャンパーピンを図のように刺し、電源アダプターを抜き差ししてリカバリーモードへ入れる。
ケーブルはシリアルコンソールの接続に使っている。

③の端子へ、MicroUSBケーブルをつなぎ、もう一方をJetson Nanoファームウェア構築用PC(Ububtu)に接続した。

ubuntu側のdmesgで下記が確認できればOK

[……] usb x-x.x: Product: APX
[……] usb x-x.x: Manufacturer: NVIDIA Corp.

この状態で、FUSEを書き込める状態。

$ sudo bash ./odmfuse.sh -i 0x21 -c PKC -k ../rsa_priv.pem -p

*** Calculating HASH from keyfile 
/Tegra210_Linux_R32.4.2_aarch64/rsa_priv.pem ... done
PKC HASH: 0x…….
*** Generating fuse configuration ... done.
done.
*** Start fusing  ...
$ ./tegraflash.py --chip 0x21 --applet nvtboot_recovery.bin --cmd "blowfuses odmfuse_pkc.xml;"
Welcome to Tegra Flash
version 1.0.0
Type ? or help for help and q or quit to exit
Use ! to execute system commands

[   0.0025 ] Parsing fuse info as per xml file
[   0.0172 ] tegraparser --fuse_info odmfuse_pkc.xml blow_fuse_data.bin
[   0.0206 ]
[   0.0206 ] Generating RCM messages
[   0.0320 ] tegrarcm --listrcm rcm_list.xml --chip 0x21 0 --download rcm nvtboot_recovery.bin 0 0
[   0.0335 ] RCM 0 is saved as rcm_0.rcm
[   0.0417 ] RCM 1 is saved as rcm_1.rcm
[   0.0418 ] List of rcm files are saved in rcm_list.xml
[   0.0418 ]
[   0.0418 ] Signing RCM messages
[   0.0463 ] tegrasign --key None --list rcm_list.xml --pubkeyhash pub_key.key
[   0.0481 ] Assuming zero filled SBK key
[   0.0594 ]
[   0.0594 ] Copying signature to RCM mesages
[   0.0613 ] tegrarcm --chip 0x21 0 --updatesig rcm_list_signed.xml
[   0.0639 ]
[   0.0640 ] Boot Rom communication
[   0.0657 ] tegrarcm --chip 0x21 0 --rcm rcm_list_signed.xml
[   0.0671 ] BR_CID: 0x32101001644577851400000002038200
[   0.2396 ] RCM version 0X210001
[   0.4114 ] Boot Rom communication completed
[   1.4201 ]
[   1.4201 ] Blowing fuses
[   1.4221 ] tegrarcm --oem blowfuses blow_fuse_data.bin
[   1.4237 ] Applet version 00.01.0000
[   1.7879 ] Successfully burnt fuses as per fuse info blob
[   1.8070 ]
*** The fuse configuration is saved in bootloader/odmfuse_pkc.xml
*** The ODM fuse has been secured with PKC keys.
*** Flash "signed BCT and bootloader(s)".
*** done.

秘密鍵で署名したファームを書き込む。下記のコマンドで必要となるファームウェアイメージが生成され、署名されて書き込まれる。

$ sudo ./flash.sh -x 0x21 -y PKC -u ../rsa_priv.pem jetson-nano-qspi-sd mmcblk0p1

……
[  34.9999 ] Cboot version 00.01.0000
[  35.2421 ] Writing partition GPT with gpt.bin
[  35.2426 ] [................................................] 100%
[  35.2480 ] Writing partition BCT with P3448_A00_4GB_Micron_4GB_lpddr4_204Mhz_P987.bct
[  51.4808 ] [................................................] 100%
[  51.4867 ] Writing partition NVC with nvtboot.bin.signed
[  58.1388 ] [................................................] 100%
[  58.1502 ] Writing partition PT with flash.xml.bin
[  68.1618 ] [................................................] 100%
[  68.1671 ] Writing partition NVC_R with nvtboot.bin.signed
[  68.4179 ] [................................................] 100%
[  68.4361 ] Writing partition VER_b with qspi_bootblob_ver.txt
[  78.4594 ] [................................................] 100%
[  78.4710 ] Writing partition VER with qspi_bootblob_ver.txt
[  78.7336 ] [................................................] 100%
[  78.7450 ] Writing partition APP with system.img
[  79.0076 ] [................................................] 100%
[ 1433.4688 ] Writing partition TBC with nvtboot_cpu.bin.signed
[ 1440.6952 ] [................................................] 100%
[ 1440.7171 ] Writing partition RP1 with tegra210-p3448-0000-p3449-0000-a02.dtb.signed
[ 1440.7635 ] [................................................] 100%
[ 1440.7800 ] Writing partition EBT with cboot.bin.signed
[ 1440.8358 ] [................................................] 100%
[ 1440.8691 ] Writing partition WB0 with warmboot.bin.signed
[ 1440.9482 ] [................................................] 100%
[ 1440.9665 ] Writing partition BPF with sc7entry-firmware.bin.signed
[ 1441.0020 ] [................................................] 100%
[ 1441.0105 ] Writing partition TOS with tos-mon-only.img.signed
[ 1441.0460 ] [................................................] 100%
[ 1441.0587 ] Writing partition DTB with tegra210-p3448-0000-p3449-0000-a02.dtb.signed
[ 1441.1018 ] [................................................] 100%
[ 1441.1174 ] Writing partition LNX with boot.img.signed
[ 1441.1726 ] [................................................] 100%
[ 1441.2166 ] Warning: EKS partition magic header mismatch!
[ 1441.2803 ] Writing partition EKS with eks.img
[ 1441.2805 ] [................................................] 100%
[ 1441.2884 ] Writing partition BMP with bmp.blob
[ 1441.3238 ] [................................................] 100%
[ 1441.3483 ] Writing partition RP4 with rp4.blob
[ 1441.3915 ] [................................................] 100%
……

上記のようにいくつかのパーティションが、signedという末尾で署名付きになっていることがわかる。

これで書き込みが終了し再起動すると、SDカードにetcherで書き込んで起動させたように初回設定の画面になり、通常通り使用ができる状態となる。

ここまででどういう状態になったか確認すると、今回flash.shで指定したjetson-nano-qspi-sdに対応するパーティション定義が下記の通り

https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%2520Linux%2520Driver%2520Package%2520Development%2520Guide%2Fpart_config.html%23wwp116074

Jetson Nano Boot Flowによると、下記の流れでブートしている。

これに関連する署名された項目は、
Tegraboot,Cboot,TOS,U-Bootまでとなり、あとはSC7(DeepSleep)、warmbootとなる。

つまり、セキュアブートの設定で、BootROMからu-bootまでは、FUSEの鍵で署名され、改ざんを防止した状態になった。

最終的にルートファイルシステムが暗号化できるまで進めていく。
次はJetson Nano Dev Boardを使ってSDカード暗号化をテスト(LUKS 調査編)

Jetson Nano Dev Boardを使ってSDカード暗号化をテスト 記事インデックス

概要編
Jetson Nano secureboot編 <いまここ
LUKS 調査編
initramfs 調査編
起動シーケンス作成編