Rockchip RK3399 secure eFuse: vì sao kernel Linux đọc vào là panic¶
Secure boot cần một nơi lưu hash của root key mà không ai sửa được sau khi xuất xưởng. Trên SoC Rockchip, nơi đó là eFuse, và Linux không được phép đọc nó.
Bài này tổng hợp và diễn giải lại loạt phân tích của Bootlin về eFuse trên Rockchip, đối chiếu với tài liệu Secure Boot Application Note của chính Rockchip. Câu hỏi trung tâm rất cụ thể: trỏ driver nvmem của kernel vào secure eFuse thì kernel panic, và lý do nằm ở phần cứng chứ không ở driver.
Khái niệm nền (chain of trust, TrustZone, Exception Level, TF-A, OP-TEE) được gom ở trang Secure boot và TrustZone: khái niệm cơ bản.
Write-once memory: OTP và eFuse¶
Cả hai công nghệ đều dùng dòng điện lớn hơn bình thường để thay đổi vĩnh viễn độ dẫn điện của cell nhớ. Khác biệt là chiều thay đổi.
| OTP (anti-fuse) | eFuse | |
|---|---|---|
| Trước khi ghi | Hở mạch | Dẫn điện |
| Sau khi ghi | Dẫn điện | Hở mạch (đứt) |
| Cơ chế | Đổi cấu trúc điện hóa của vật liệu | Electromigration của vật liệu dẫn |
| Chip Rockchip | RK35xx, RK3308, RK3328, RK3228H | RK3399, RK3288, RK3368 và các dòng cũ |
Mục đích phổ biến nhất là lưu hash của public key dùng để verify chữ ký ở bước đầu của bootchain. RK3399 có hai bank eFuse, và đó là chủ đề của phần còn lại.
Hai bank eFuse của RK3399¶
| Bank | Địa chỉ | Nội dung |
|---|---|---|
| EFUSE0 (non-secure) | 0xff690000 |
CPU ID, wafer info, các giá trị leakage |
| EFUSE1 (secure) | 0xfffa0000 |
Cờ secure boot, hash của RSA public key, lock bits |
EFUSE0 có driver nvmem do Rockchip upstream từ kernel 4.3. Nạp module lên là đọc được qua sysfs:
$ ls /sys/bus/nvmem/devices/rockchip-efuse0/cells/
cpu-id@7,0 cpu-leakage@17,0 gpu-leakage@18,0 wafer-info@1c,0 ...
Thử sửa device tree để cùng driver trỏ sang 0xfffa0000 thì kết quả khác hẳn. Chạy hexdump trên node nvmem là kernel báo SError Interrupt rồi dừng với Kernel panic - not syncing: Asynchronous SError Interrupt.
Vì sao lỗi: slave secure cố định¶
SError là ngoại lệ bất đồng bộ của ARM. Một nguyên nhân điển hình là truy cập đã qua hết kiểm tra MMU nhưng bus trả về lỗi. Vậy lỗi bus đến từ đâu?
Chương 16 của TRM RK3399 (System security) chia các APB slave thành bốn loại:
- secure: chỉ truy cập được từ Secure World.
- non-secure: truy cập được từ cả hai world.
- boot-secure: chỉ Secure World truy cập lúc boot, sau đó phần mềm có thể cấu hình mở ra.
- per configure: chọn secure hoặc non-secure qua thanh ghi sGRF.
Theo bảng cấu hình slave của RK3399, EFUSE0 thuộc loại per configure (Bootlin suy ra mặc định là non-secure), còn EFUSE1 thuộc loại secure cố định, không có cách cấu hình để mở cho non-secure. Đây là lựa chọn có chủ ý của Rockchip. Điều hơi lạ là thứ được lưu chỉ là hash của public key, cần bảo vệ tính toàn vẹn chứ không cần giữ bí mật, nhưng bank này vẫn bị khóa kín với Linux.
Linux đọc EFUSE0 bình thường. Truy cập EFUSE1 bị bộ lọc secure slave của APB bus chặn và trả về SError. Mũi tên SMC là hướng đi khả dĩ để Linux nhờ Secure World, chưa được bài gốc xác nhận.
Secure eFuse chứa gì, boot ROM dùng nó thế nào¶
Theo Table 2-1 trong Secure Boot Application Note V1.9, layout 1024 bit dành cho secure boot như sau (tài liệu liệt kê bảng này cho RK3368, RK3288, RK3229, RK3228; Bootlin dẫn cùng mục này khi mô tả RK3399):
| Word | Nội dung |
|---|---|
0x00 |
Security flag: bit [7:0] là cờ enable, bit [31:8] reserved |
0x01 – 0x07 |
Reserved |
0x08 – 0x0F |
Hash SHA256 của RSA public key (256 bit) |
0x10 – 0x1E |
Reserved |
0x1F |
Bit khóa ghi (write lock) |
Lưu ý khi đối chiếu
Bài Bootlin liệt kê 15 word reserved đứng trước hash và 7 word sau hash. Bảng trong Application Note cho hash ở 0x08–0x0F, tức 7 word reserved trước và 15 word sau. Tổng vẫn là 32 word, nhưng nếu đọc eFuse theo offset thì nên kiểm tra lại với tài liệu gốc.
Luồng verify của boot ROM: lấy public key nằm trong first loader, tính SHA256 của key rồi so với hash trong eFuse. Nếu khớp, dùng chính key đó để verify chữ ký RSA2048 trên loader, sau đó chuyển key cho U-Boot để verify boot.img theo cùng cách. Khi secure boot đã bật, log boot hiển thị SecureBootEn = 1, SecureBootLock = 1, và firmware chưa ký hoặc ký sai key đều không boot được.
Lưu ý khi đưa vào sản phẩm¶
- Nguồn eFuse. RK3399 cần 1.8V, dòng trên 50 mA, chân nguồn eFuse là AD23 với điện trở pull-down không quá 1 kΩ. Dùng đúng giá trị trong schematic tham chiếu của từng chip.
- Không cần ghi eFuse trên sản phẩm? Nối chân nguồn xuống GND để tránh ghi nhầm.
- Cách cấp nguồn khi ghi. Rockchip khuyến nghị cấp qua board test ở công đoạn PCBA vì mạch cấp nguồn không nằm trên sản phẩm. Cấp onboard thì cần một GPIO riêng điều khiển LDO để chắc chắn chân này ở 0V khi chạy bình thường.
- Keypair RSA. Mỗi model sinh một lần và phải giữ an toàn suốt vòng đời sản phẩm. Mất hoặc lộ key thì các thiết bị cũ không thể update firmware nữa.
Góc nhìn của người làm firmware¶
Điều đáng nhớ nhất là ranh giới secure và non-secure ở đây do phần cứng thực thi, không phải do driver. Không có patch kernel nào mở được EFUSE1. Muốn đọc hash từ Linux thì phải nhờ firmware chạy ở Secure World, nhiều khả năng qua SMC vào TF-A hoặc OP-TEE. Đây là suy đoán của tác giả, còn Bootlin hứa sẽ trình bày cách truy cập ở bài tiếp theo.
Cách tiếp cận này cũng quen thuộc ở các nền tảng khác. Theo hiểu biết của tác giả, trên Zynq UltraScale+ MPSoC, Linux đọc eFuse thông qua giao diện firmware với PMU thay vì chạm thanh ghi trực tiếp. Cùng một triết lý: root of trust nằm ngoài tầm với của kernel.
Vì vậy khi thiết kế sản phẩm, nên coi việc Linux không đọc được secure eFuse là một đặc tính bảo mật cần có chứ không phải hạn chế. Việc cần lên kế hoạch sớm là provisioning: ghi hash ở công đoạn nào, kiểm tra bằng dòng log boot nào, và cất keypair ở đâu.
Kết luận¶
RK3399 có hai bank eFuse. EFUSE0 lưu thông tin không nhạy cảm và đọc được từ Linux. EFUSE1 lưu hash của public key secure boot và chỉ truy cập được từ TrustZone Secure World. Truy cập sai world không trả về dữ liệu rác mà làm kernel panic do SError.
Nguồn tham khảo¶
- Rockchip SoCs: a foray into eFuse territory, Olivier Benjamin, Bootlin (20/10/2026)
- Rockchip Secure Boot Application Note V1.9 (06/2018)
- Rockchip RK3399 TRM, Part 1 (V1.3), chương 16 System security
