Raspberry PiでSDカード暗号化とセキュアブートをテスト


## ■あらすじ
前回、[Raspberry PiでSDカード暗号化をテスト](https://qiita.com/kmitsu76/items/befdb96623f2ca246499)を行い、ルートファイルシステムの暗号化に成功した。
Raspberry Pi 4で使える、セキュアブートを試していきたい。
Raspberry Pi 4を元に戻せない操作が含まれるため、追試される際は注意をお願いしたい。

## ■Raspberry Pi 4のセキュアブートについて

公式Github　[raspberypi/usbboot](https://github.com/raspberrypi/usbboot/blob/master/docs/secure-boot-train-of-trust.pdf)によると、セキュアブートの構造は以下のようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/8b0b5080-e3f4-794a-d3e7-26d5a09518eb.png)

今回、右から左に作業を行い、
①、eeprom.confを設定し、boot.imgとboot.sigを読み込んで起動するように設定し、問題なく起動することを確認し、
②、config.txtの設定で、セキュアブートを強制する設定を行う方針とする。


## ■環境
Raspberry pi 4 4GB　1台(以下Raspberry Pi)
ATECC608B-SSHDA(i2c接続タイプ)(以下ATECC608B)
128GB　MicroSDカード　1枚（暗号化済み）
ここまでは前回の記事をもとに、準備、暗号化が設定できているものとする。

128GB　MicroSDカード　1枚（作業用）
USB-MicroSDカード変換アダプター
Ubuntu22.04のインストールされたPC(以下Ubuntu PC)


Ubuntu PCで鍵ペアを作成しておく。

```
$ openssl genrsa 2048 > private.pem
$ openssl rsa -in private.pem -pubout -out public.pem
```

暗号化済みSDカードを使いRaspberry Piを起動させる。

```
$ sudo rpi-eeprom-update
BOOTLOADER: up to date
   CURRENT: 2023年  1月 11日 水曜日 17:40:52 UTC (1673458852)
    LATEST: 2023年  1月 11日 水曜日 17:40:52 UTC (1673458852)
   RELEASE: default (/lib/firmware/raspberrypi/bootloader/default)
            Use raspi-config to change the release.

  VL805_FW: Dedicated VL805 EEPROM
     VL805: up to date
   CURRENT: 000138c0
    LATEST: 000138c0

$ ls /lib/firmware/raspberrypi/bootloader/default/
pieeprom-2020-04-16.bin  pieeprom-2022-01-25.bin  pieeprom-2023-01-11.bin  vl805-000138c0.bin
pieeprom-2020-09-03.bin  pieeprom-2022-04-26.bin  recovery.bin
pieeprom-2021-03-18.bin  pieeprom-2022-11-25.bin  vl805-000137ad.bin
pieeprom-2021-04-29.bin  pieeprom-2022-12-07.bin  vl805-000138a1.bin
```

raspi-configでブートロムを最新にする。

```
$ sudo rpi-eeprom-update
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/8c0b254f-4bfc-6cf2-9ba1-2d6a9d001415.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/ea278eee-397d-4472-bfe8-0683b316eaee.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/2c4ab6d5-7cb4-2afa-4f5e-34a704ac290c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/1382e990-a052-c9f1-f65e-def9b253c2dc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/5d2f111d-00d4-26c6-6fbe-80f0f82d675a.png)


```
BOOTLOADER: up to date

   CURRENT: 2023年  5月 11日 木曜日 06:26:03 UTC (1683786363)

    LATEST: 2023年  5月 11日 木曜日 06:26:03 UTC (1683786363)

   RELEASE: stable (/lib/firmware/raspberrypi/bootloader/stable)

            Use raspi-config to change the release.



  VL805_FW: Dedicated VL805 EEPROM

     VL805: up to date

   CURRENT: 000138c0

    LATEST: 000138c0
```

[前回の記事](https://qiita.com/kmitsu76/items/befdb96623f2ca246499#%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E4%BD%9C%E6%88%90)を参考に作業用MicroSDカードにイメージを作成する。
終わったらUSB-MicroSDカード変換アダプターに作業用MicroSDカードを差し、Raspberry PiにUSB接続する。


```
[ 2348.323638] usb 1-1.1: new high-speed USB device number 3 using xhci_hcd
[ 2348.426266] usb 1-1.1: New USB device found, idVendor=0bda, idProduct=0109, bcdDevice= 9.59
[ 2348.426297] usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 2348.426314] usb 1-1.1: Product: USB2.0-CRW
[ 2348.426329] usb 1-1.1: Manufacturer: Generic
[ 2348.426343] usb 1-1.1: SerialNumber: 20090815198100000
[ 2348.439883] usb-storage 1-1.1:1.0: USB Mass Storage device detected
[ 2348.440802] scsi host0: usb-storage 1-1.1:1.0
[ 2349.456522] scsi 0:0:0:0: Direct-Access     Generic- SD/MMC           1.00 PQ: 0 ANSI: 0 CCS
[ 2349.473065] sd 0:0:0:0: Attached scsi generic sg0 type 0
[ 2350.167209] sd 0:0:0:0: [sda] 241827840 512-byte logical blocks: (124 GB/115 GiB)
[ 2350.167860] sd 0:0:0:0: [sda] Write Protect is off
[ 2350.167872] sd 0:0:0:0: [sda] Mode Sense: 03 00 00 00
[ 2350.168410] sd 0:0:0:0: [sda] No Caching mode page found
[ 2350.168418] sd 0:0:0:0: [sda] Assuming drive cache: write through
[ 2350.173484]  sda: sda1 sda2
[ 2350.173944] sd 0:0:0:0: [sda] Attached SCSI removable disk
[ 2350.760640] EXT4-fs (sda2): mounted filesystem with ordered data mode. Quota mode: none.

$ df -h

ファイルシス     サイズ  使用  残り 使用% マウント位置
udev               1.6G     0  1.6G    0% /dev
tmpfs              380M  1.3M  379M    1% /run
/dev/mapper/luks   117G  3.9G  109G    4% /
tmpfs              1.9G     0  1.9G    0% /dev/shm
tmpfs              5.0M  4.0K  5.0M    1% /run/lock
/dev/mmcblk0p1     255M   47M  209M   19% /boot
tmpfs              380M   24K  380M    1% /run/user/1000
/dev/sda1          255M   31M  225M   13% /media/km/bootfs
/dev/sda2          3.8G  3.1G  453M   88% /media/km/rootfs
```

## ■boot.img作成

boot.imgを作成する。63MBのFAT32イメージファイルを作り、必要最小限のファイルを置く。
これが署名を確認され、問題ないと起動される。

```
$ dd if=/dev/zero of=boot.img bs=1M count=0 seek=63
0+0 レコード入力

0+0 レコード出力

0 bytes copied, 0.000859678 s, 0.0 kB/s

$ sudo losetup -f boot.img

$ sudo losetup -l

NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE         DIO LOG-SEC

/dev/loop0         0      0         0  0 /home/km/boot.img   0     512

$ sudo mkdir /media/km/boot

$ sudo mkdosfs -F32 /dev/loop0

mkfs.fat 4.2 (2021-01-31)

$ sudo mount /dev/loop0 /media/km/boot


$ sudo cp /boot/bcm2711-rpi-4-b.dtb /media/km/boot/

$ sudo cp /boot/bootcode.bin /media/km/boot/

$ sudo cp /boot/cmdline.txt /media/km/boot/

$ sudo cp /boot/config.txt /media/km/boot/

$ sudo cp /boot/fixup* /media/km/boot/

$ sudo cp /boot/initrd.img-6.1.21-v8+ /media/km/boot/

$ sudo cp /boot/kernel8.img /media/km/boot/

$ sudo cp -R /boot/overlays/ /media/km/boot/

$ sudo cp /boot/start* /media/km/boot/

sudo umount /media/km/boot

sudo losetup -d /dev/loop0
```

## ■boot.img署名

以下コマンドで署名を行う。
```
$ sudo apt install python3-pycryptodome

$ rpi-eeprom-digest -i boot.img -o boot.sig -k private.pem
```

現在起動している暗号化済みのMicroSDカードに、2つのファイルをコピーしておく。
```
$ sudo cp boot.* /boot/
```

作業用MicroSDカードにコピー。
```
$ sudo cp boot.* /media/km/bootfs/
```

## ■eeprom設定

ここで、SIGNED_BOOTを有効にして、署名付きのファイルを起動させるように設定する。
```
$ vi eeprom.conf
[all]

BOOT_UART=1
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0

# Disable self-update mode
ENABLE_SELF_UPDATE=0

# Select signed-boot mode in the EEPROM. This can be used to during development
# to test the signed boot image. Once secure boot is enabled via OTP this setting
# has no effect i.e. it is always 1.
SIGNED_BOOT=1
```

## ■eepromへ署名

設定を反映したeepromファームウェアへ、署名を行い、更新の準備を行う。

```
$ sudo rpi-eeprom-config -c eeprom.conf -p public.pem -o pieeprom.bin /usr/lib/firmware/raspberrypi/bootloader/latest/pieeprom-2023-05-11.bin

$ sudo rpi-eeprom-digest -i pieeprom.bin -o pieeprom.sig

$ sudo ln -f pieeprom.bin pieeprom.upd
```

作業用MicroSDカードにコピー。
```
$ sudo cp pieeprom.upd /media/km/bootfs/

$ sudo cp pieeprom.sig /media/km/bootfs/
```

## ■eeprom設定完了
Raspberry Piを終了させ、作業用MicroSDカードを使って起動すると、eepromの更新が行われ、セキュアブートが有効となった。

作業用MicroSDカードで起動しているため、rootfsがマウントできないエラーが表皮されたところで再度Raspberry Piを終了させ、暗号化済みMicroSDカードを使って起動すると、署名が検証され、OSが起動する。


## ■セキュアブート強制設定

作業用MicroSDカードの /boot/config.txtの中身を下記と入れ替えて起動する。

```
uart_2ndstage=1

# Mark the EEPROM as write protected when the EEPROM /WIP pin is pulled low.
# See https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711_bootloader_config.md#eeprom_write_protect

eeprom_write_protect=1

# Uncomment to write to enable secure-boot by writing. This
# locks the device to the public key in the EEPROM by storing the
# sha256 hash of the public key in OTP.
#
# This option also prevents the ROM from loading recovery.bin from SD/EMMC
# which means that the bootloader can only be updated via RPIBOOT or self-update.
#
# Uncomment program_pubkey=1 to enable this
# WARNING: THIS OPTION MODIFIES THE BCM2711 CHIP AND IS IRREVERSIBLE.

program_pubkey=1

# Uncomment to revoke the ROM development key via OTP preventing older
# bootloader or recovery.bin releases from running on this Pi
# WARNING: THIS OPTION MODIFIES THE BCM2711 CHIP AND IS IRREVERSIBLE.
#
# DO NOT SET THIS OPTION UNTIL THE BOOTLOADER IS SIGNED WITH THE SECURE
# BOOT KEY. IT WILL PREVENT THE PI FROM BOOTING.
revoke_devkey=1

# Pi 4B and Pi400 do not have a dedicated RPIBOOT jumper so a different GPIO
# must be used to enable RPIBOOT if pulled low. The options are 2,4,5,6,7,8.
#
# This option has no effect on CM4.

# WARNING: THIS OPTION MODIFIES THE BCM2711 CHIP AND IS IRREVERSIBLE.
program_rpiboot_gpio=8

# Permanently disable VideoCore JTAG access.
# Warning: This option limits the ability to do failure analysis on 
# boards returned to resellers or Raspberry Pi Trading Ltd.
#program_jtag_lock=1
```

起動後、しばらく置いて電源を落として暗号化済みMicroSDカードを使って起動すると、署名が検証され、OSが起動する。
/bootディレクトリに、recovery.binを置いて行うリカバリーモードもロックされ、ディスプレイに赤い四角が表示されるようになり、署名されたイメージのみが起動するようになる。

これで、署名されたイメージでの信頼の連鎖（Chain of Trust）が完成となる。