Fusing OemK1 for Disk Encryption

I have managed to get basic disk encryption working on a Jetson Orin NX running on Hadron Carrier for NVIDIA® Jetson Orin™ NX

I realized while doing that the value of the OemK1 fuse is used to decrypt the EKS partition (A_eks). Since the default value of that fuse is 0000000000000000000000000000000000000000000000000000000000000000, optee/samples/hwkey-agent/host/tool/gen_ekb/example.sh recommends keeping that value when first trying out Disk Encryption.

Now that it works, I understand, we should generate a random key is fused into OemK1 so that it’s not trivial to decrypt the EKS partition.

So I would like to understand if it’s possible to JUST fuse the OemK1 without fusing ANY of the other fuses.

Would a fuse file like this be sufficient to have secure disk encryption working?

<genericfuse MagicId="0x45535546" version="1.0.0">
    <fuse name="OemK1" size="32" value="0xf3bedbff9cea44c05b08124e8242a71ec1871d55ef4841eb4e59a56b5f88fb2b"/>
</genericfuse>

And then fuse it using this command

sudo ./odmfuse.sh -i 0x23 -X fuse.xml cti/orin-nx/hadron/base

Since I understand fusing is a irreversible, I am asking the question before trying it out.

hello chinmaypen,

it’s possible, however, we strongly recommended users enable bootloader secure boot so that the root-of-trust can start from the BootROM.

BTW, you may see-also Topic 309032 for more details about OEM_K1/OEM_K2.

Thanks! I understand.

Even with Disk Encryption setup with a custom OemK1, if bootloader (and UEFI) secure boot is not enabled, then a threat actor could flash a custom bootloader or kernel image and still be able to read out the EKB and decrypt it right?

I am trying go about this step by step. So once I can get disk encryption working with a custom OemK1, I will look at setting up secure boot.

hello chinmaypen,

that’s correct, if someone can manipulate contents of QSPI out of band, FW can be erased to cause denial of service attacks. UEFI variables can be manipulated to use.
please see-also The Threat Model for more details.

1 Like

Hello @JerryChang

I tried this. I have a Jetson Nano setup with disk encryption using a non-zero oem_k1.key (using steps here) . Then I fused the OemK1 fuse using the fuse.xml and omdfuse command above. Here is the output from FSKP when the actual fuse was burnt.

I> FSKP (version: 0.0.0.0-t234-54845784-8e9545b6)
I> t234-A01-1-Silicon (0x12347)
I> Emulation:
I> Entry timestamp: 0x008bedb3
I> Regular heap: [base:0x40040000, size:0x10000]
I> DMA heap: [base:0x173800000, size:0x800000]
I> Task: Crypto init
I> Task: Program CBB PCIE AMAP regions
I> Task: Burn fuses
I> Index : 1    OemK1    size: 32
I> Fuse Blob found
I>
I> Burning fuses
I> 1. Start OemK1 burn
I> 1. OemK1 burnt successfully
W> No handling of CRC-32 for OemK1
I>
I> Successfully burnt fuses as per fuse info
I> Index : 1    OemK1    size: 32
I> Fuse Blob found
I> No RPMB provisioning details is found. Skip RPMB Provisioning.
I> FSKP finished

And now it fails to decrypt the rootfs.

ERROR: fail to unlock the encrypted dev /dev/nvme0n1p2.

Then I was wondering if I needed to change the order and tried to re-flash the EKB image using

sudo ./tools/kernel_flash/l4t_initrd_flash.sh -k A_eks --flash-only --showlogs

And now it won’t even let me flash the EKB (or any partition for that matter) and gives this error.

[   0.0386 ] BR_CID: 0x80012344705DE6C04000000018FE8080
[   0.0444 ] Sending bct_br
[   0.0493 ] Sending mb1
[   0.0498 ] ERROR: might be timeout in USB write.
Error: Return value 3

I tried a bunch of things including rebooting the host and re-connecting the carrier board, but I always get this error.

Once the board is fused with ONLY the OemK1 key, do the flashing commands have to change?

hello chinmaypen,

you cannot perform a partition update (i.e. -k A_eks) once you’ve fused the target.
please full-flash your target for verification.

1 Like

OK. That explains.

A full flash would be something like this right?

sudo ./tools/kernel_flash/l4t_initrd_flash.sh --network usb0 --showlogs --flash-only

hello chinmaypen,

you’ve to re-generate EKS image since you’re changing oem_k1.key,
besides, please ensure you’re using the updated eks_t234.img for image flashing.

1 Like

Thanks @JerryChang

I did manage to do a full flash.

Even doing a full flash (using steps here) with the correct oem_k1.key and the eks_t234.img derived from the correct oem_k1.key I am unable to decrypt the disk.

ERROR: fail to unlock the encrypted dev /dev/nvme0n1p2.

I’m attaching the UART boot log. boot-uart.txt (69.7 KB)

What am I missing?

it’s due to an incorrect EKS image has used, may I confirm the L4T release version you’re working with now?

I am using Jetson Linux 36.3

# Jetpack 6 (Jetson Linux 36.3)
BSP_URL=https://developer.nvidia.com/downloads/embedded/l4t/r36_release_v3.0/release/jetson_linux_r36.3.0_aarch64.tbz2
ROOT_FS_URL=https://developer.nvidia.com/downloads/embedded/l4t/r36_release_v3.0/release/tegra_linux_sample-root-filesystem_r36.3.0_aarch64.tbz2
SOURCES_URL=https://developer.nvidia.com/downloads/embedded/l4t/r36_release_v3.0/sources/public_sources.tbz2

hello chinmaypen,

is it possible for moving forward to the latest JP-6.1/r36.4.0 for verification?

FYI,
there’re OEM_K1/K2 to derive a root key which is itself used to sign and encrypt the EKB.
in r36.3.0 release version, it was using OEM_K2,
in r36.4.0 (the latest release version) they are both used to open EKB.
furthermore,
OEM_K1, it is the root of trust of EKB, and it is used to derive the RPMB key too.
OEM_K2, it is to derive the PV encryption key. If you don’t need to encrypt CPUBL with a PV key, you don’t need to care about OEM_K2.

Oh! So with r36.3.0 I should have been using OEM_K2!! That would explain why I am unable to decrypt.

I will try to move up to JP-6.1/r36.4.0 and report back in a short while.

OK. I moved up to JP-6.1/r36.4.0 but I’m getting the same error.

��NOTICE:  BL31: v2.8(release):e12e3fa93
NOTICE:  BL31: Built : 21:01:44, Sep 12 2024
I/TC:
I/TC: Non-secure external DT found
I/TC: OP-TEE version: 4.2 (gcc version 11.3.0 (Buildroot 2022.08)) #2 Fri Sep 13 04:10:17 UTC 2024 aarch64
I/TC: WARNING: This OP-TEE configuration might be insecure!
I/TC: WARNING: Please check https://optee.readthedocs.io/en/latest/architecture/porting_guidelines.html
I/TC: Primary CPU initializing
I/TC: Test OEM keys are being used. This is insecure for shipping products!
E/TC:00 00 ekb_extraction_process:404 Tried all EKB_RKs but still can't extract the EKB image.
E/TC:00 00 jetson_user_key_pta_init:1154 jetson_user_key_pta_init: Failed (ffff000f).
E/TC:00 00 call_initcalls:43 Initcall __text_start + 0x001ad560 failed
I/TC: fTPM ID is not enabled.
I/TC: ftpm-helper PTA: fTPM DT or EKB is not available. fTPM provisioning is not supported.
I/TC: Primary CPU switching to normal world boot
��
  Jetson UEFI firmware (version 36.4.0-gcid-37537400 built on 2024-09-13T04:02:39+00:00)

....

[   13.156787] tegra-xudc 3550000.usb: Adding to iommu group 7
[   13.189660] Cryptsetup version: 2.4.3
[   18.314325] ERROR: fail to unlock the encrypted dev /dev/nvme0n1p2.
[   18.316975] Kernel panic - not syncing:
[   18.316978] Attempted to kill init! exitcode=0x00007f00
[   18.316983] CPU: 3 PID: 1 Comm: bash Not tainted 5.15.148-tegra #125

hello chinmaypen,

may I know how you moving to JP-6.1/r36.4.0?
for instance, did you re-flash with SDKManager or using OTA update?

please double check you’ve downloaded r36.4.0 public release package, and using the same release version gen_ekb to re-generate EKS image.

besides,
we’ve test locally to confirm disk encryption is working.
here’re our test steps for your reference,
Generate images for QSPI:
$ sudo ./tools/kernel_flash/l4t_initrd_flash.sh --showlogs -p "-c bootloader/t186ref/cfg/flash_t234_qspi.xml" --no-flash --network usb0 jetson-orin-nano-devkit internal
Generate the key:
$ echo "f0e0d0c0b0a001020304050607080900" > ekb.key
Generate images for external storage device:
$ sudo ROOTFS_ENC=1 ./tools/kernel_flash/l4t_initrd_flash.sh --showlogs --no-flash --external-device nvme0n1p1 -i ./ekb.key -c ./tools/kernel_flash/flash_l4t_t234_nvme_rootfs_enc.xml --external-only --append --network usb0 jetson-orin-nano-devkit external
Flash images into the both storage devices:
$ sudo ./tools/kernel_flash/l4t_initrd_flash.sh --showlogs --network usb0 --flash-only
Verification after flash and booting up:
$ df -h

/dev/mapper/crypt_root 54G 5.6G 46G 12% /
/dev/mapper/crypt_UDA 374M 14K 350M 1% /mnt/crypt_UDA
/dev/nvme0n1p1 371M 97M 247M 29% /boot

@JerryChang

Here are the steps I took to move to JP-6.1/r36.4.0.

  • Downloaded all of these sources and installed them into a new directory.
BSP_URL=https://developer.nvidia.com/downloads/embedded/l4t/r36_release_v4.0/release/jetson_linux_r36.4.0_aarch64.tbz2
ROOT_FS_URL=https://developer.nvidia.com/downloads/embedded/l4t/r36_release_v4.0/release/tegra_linux_sample-root-filesystem_r36.4.0_aarch64.tbz2
SOURCES_URL=https://developer.nvidia.com/downloads/embedded/l4t/r36_release_v4.0/sources/public_sources.tbz2
CTI_URL=https://connecttech.com/ftp/Drivers/CTI-L4T-ORIN-NX-NANO-36.4.0-V002.tgz
  • Ran the install.sh which intern run apply_binaries.sh
  • Created a new default user using l4t_create_default_user.sh
  • Extracted the new gen_ekb from sources for JP-6.1/r36.4.0.
  • Using the keys used and fused previously, I regenerated the ekb using
python3 gen_ekb.py -chip t234 -oem_k1_key oem_k1.key \
        -in_sym_key sym_t234.key \
        -in_sym_key2 sym2_t234.key \
        -in_auth_key auth_t234.key \
        -out eks_t234.img`
  • Copied the keys over
cd Linux_for_Tegra
cp ../gen_ekb/sym2_t234.key ./sym2_t234.key
rm ./bootloader/eks_t234.img
cp ../gen_ekb/eks_t234.img ./bootloader/eks_t234.img
  • Generated the encrypted images
sudo ./flash.sh --no-flash -k A_eks -i "sym2_t234.key" cti/orin-nx/hadron/base nvme0n1p1
sudo ./tools/kernel_flash/l4t_initrd_flash.sh --showlogs -p "-c bootloader/generic/cfg/flash_t234_qspi.xml" --no-flash --network usb0 cti/orin-nx/hadron/base internal
sudo cp ./bootloader/eks_t234_sigheader.img.encrypt ./tools/kernel_flash/images/internal/eks_t234_sigheader.img.encrypt
sudo ROOTFS_ENC=1 ./tools/kernel_flash/l4t_initrd_flash.sh --showlogs --no-flash --external-device nvme0n1p1 -i ./sym2_t234.key -c ./tools/kernel_flash/flash_l4t_t234_nvme_rootfs_enc.xml --external-only --append --network usb0 cti/orin-nx/hadron/base external
  • Flashed them in
sudo ./tools/kernel_flash/l4t_initrd_flash.sh --network usb0 --showlogs --flash-only

we’ve test locally to confirm disk encryption is working.

I also have disk encryption working without fusing. I am seeing the issue when I fuse the OEM_K1 key using odmfuse.sh and then the encryption stopped working.

hello chinmaypen,

please also examine your EKS image,
there are 4 magic bytes at the beginning of the EKS image, they are: “EEKB”, if these 4 bytes are wrong, you will see “eks image not correct”.
for instance,

$ hexdump -C -n 4 -s 0x24 eks_t234.img
00000024  45 45 4b 42                                       |EEKB|

anyways,
let me arrange fused Orin platform for testing disk encryption on JP-6.1 release version.

This is the eks_t234.img from the output of the gen_ekb

python3 gen_ekb.py -chip t234 -oem_k1_key oem_k1.key \
        -in_sym_key sym_t234.key \
        -in_sym_key2 sym2_t234.key \
        -in_auth_key auth_t234.key \
        -out eks_t234.img
>  $ hexdump -C -n 4 -s 0x24 eks_t234.img
00000024  56 6e 26 54                                       |Vn&T|
00000028

Infact if I run gen_ekb again, the output changes…

  hexdump -C -n 4 -s 0x24 eks_t234.img
00000024  32 46 ee 0e                                       |2F..|
00000028

Looking at the full hexdump, I do see EEKB at 0x34 offset even when I run gen_ekb again and again.

hexdump -C -n 4 -s 0x34 eks_t234.img
00000034  45 45 4b 42                                       |EEKB|
00000038