Rockchip · AI & Linux Hub

Linux и загрузка

Полное руководство Rockchip Secure Boot: подпись, eFuse, OTP и проверка

Полное руководство Rockchip Secure Boot: подпись, eFuse, OTP и проверка — RK-SM-YF-024 V2.2.0

· ArmSoM Editorial · Rockchip source documentation · 17 мин чтения

Полный перевод английского RK-SM-YF-024 V2.2.0 с техническим предисловием стр. 2–3 и всем техническим содержанием стр. 8–43. Есть только английский PDF; рисунки всех языков взяты из него, некоторые интерфейсы инструментов в нём китайские. Поддержка ограничена чипами источника, не расширяется на новые SoC или все платы ArmSoM. Проверьте SDK/BSP, Loader/U-Boot, ROM, формат ключей, напряжение программирования и питание платы. Проверка ArmSoM, подпись, прошивка и запись предохранителей не выполнялись.

Программирование eFuse/OTP необратимо; неверные ключи или напряжение могут лишить устройство загрузки и обновлений. Это эталонные процедуры производителя, не готовый рецепт для платы. Сохранены и отмечены противоречия: rsaHash[128] и RSA2048 в §2.5; RK3336 в §7.5 и RK3326 в §7.6; старые ссылки разделов; термины RSA Encryption/Decryption. Значения не исправлены догадками.

ArmSoM Docs · Rockchip U-Boot

1. Предисловие

Термины (определения источника):

Термин Определение
Sector Размер сектора 512 байт
eFuse IP однократно программируемой памяти в SoC
RSA Encryption Шифрование открытым ключом
RSA Decryption Расшифрование закрытым ключом
OTP IP однократно программируемой памяти в SoC
MaskRom BootROM, загрузочная память только для чтения в SoC
loader Загрузчик/первый загрузчик, обычно RKMiniloader или SPL(uboot)
OBM CODE Обычно код, собранный или доверенный OEM/OBM

Документ описывает реализацию безопасной загрузки Rockchip. Проверка действительности прошивки предотвращает недопустимые обновления и загрузку. После программирования eFuse устройство включает secure boot ROM и не загружает неподписанную прошивку; обновление неподписанной прошивкой или подписью другого ключа завершается ошибкой.

Примечание: корректно подписанная прошивка может запускаться на копиях платы или аппаратуре той же CPU-платформы. Secure boot проверяет программное обеспечение, а не аппаратуру.

Область источника: RK3126, RK3128, RK3228, RK3229, RK3288, RK3368, RK3399, RK3228H, RK3328, RK3326, RK3308 и PX30. Возможности: secure boot ROM, SHA256, RSA2048, проверка открытого ключа хешем eFuse/OTP.

Версии инструментов по источнику: Efuse tool V1.35 или новее; SecureBootTool 1.79 или новее; RKBatchTool 1.8 или новее (устарел, заменён FactoryTool); FactoryTool 1.39 или новее. Это исторические требования документа; §7.6 отдельно требует SecureBootTool V1.9 или новее.

2. Архитектура

2.1 Процесс безопасной загрузки

Рисунок английского оригинала, стр. 8

Рисунок 1-1 Процесс безопасной загрузки

2.2 Последовательность безопасной загрузки

Рисунок английского оригинала, стр. 9

Рисунок 1-2 Порядок безопасной загрузки

2.3 MaskRom запускает первый загрузчик (RKminiLoader/U-Boot)

Рисунок английского оригинала, стр. 9

Рисунок 1-3-1: последовательность MaskRom → loader. Размещение первого загрузчика в пользовательском разделе flash. Таблица 1-1: структура данных первого загрузчика.

Range Описание
0–63 sector 64 sector reverse (оригинал)
Первый загрузчик (8128 sector)(5 копий) Раздел загрузчика
0-2047 Заголовок загрузчика
2048-4095 Открытый ключ и цифровая подпись
4096 - Исходный бинарный файл
…  
Раздел копии загрузчика (4)  
0-2047 Заголовок загрузчика
2048-4095 Открытый ключ и цифровая подпись
4096 - Исходный бинарный файл

Структура открытого ключа и цифровой подписи по адресам 2048–4095:

typedef struct tagBOOT_HEADER
{
    uint32 tag;
    uint32 version;
    uint32 flags;
    uint32 size;
    uint32 reserved1[3];
    uint16 HashBits;
    uint16 RSABits;        /* length in bits of modulus */
    uint32 RSA_N[64];      /* RSA public key*/
    uint32 RSA_E[64];
    uint32 RSA_C[64];
    uint32 HashData[(8+1)*2];
    uint32 signature[64];
}BOOT_HEADER, *PBOOT_HEADER;

Открытый ключ: uint32 RSA_N[64], RSA_E[64], RSA_C[64]; Цифровая подпись: uint32 signature[64]. Шаг 1: получите открытый ключ из раздела первого загрузчика. Шаг 2: вычислите SHA256 ключа и сравните с хешем в OTP; при совпадении первый загрузчик успешно загружается, иначе загрузка неуспешна. Шаг 3: вычислите SHA256 исходного бинарного файла и сравните с результатом RSA2048-шифрования подписи с открытым ключом шага 1; совпадение означает успешную загрузку первого загрузчика, иначе отказ. Формулировки шагов 2 и 3 сохранены из источника.

2.4 Первый загрузчик запускает U-Boot (необязательный второй загрузчик)

Рисунок английского оригинала, стр. 11

Рисунок 1-4-1 Запуск U-Boot

Рисунок английского оригинала, стр. 11

Область U-Boot: 4MB, 4 копии. Диапазоны и содержимое источника:

Экземпляр Диапазон Описание
U-Boot 0-2047 Заголовок, Цифровая подпись
U-Boot 2048- Исходный бинарный файл
… … …
U-Boot copy(3) 0-2047 Заголовок, Цифровая подпись
U-Boot copy(3) 2048- Исходный бинарный файл

Таблица 1-4: размещение U-Boot во flash. Структура заголовка с цифровой подписью по адресам 0–2047:

typedef struct tag_second_loader_hdr
{
    unsigned char magic[LOADER_MAGIC_SIZE];
    unsigned int version;
    unsigned int reserved0;
    unsigned int loader_load_addr;         /* load to DDR address */
    unsigned int loader_load_size;         /* size in bytes */
    unsigned int crc32;                    /* crc32 */
    unsigned int hash_len;                 /* 20 or 32 , 0 is no hash */
    unsigned char hash[LOADER_HASH_SIZE];  /* sha256 */
    unsigned int js_hash;                  /* js hsah */
    unsigned char reserved[1024-32-32-4];
    unsigned int signTag;                  /* 0x4E474953, "NGIS" */
    unsigned int signlen;                  /* 256 */
    unsigned char rsaHash[256];            /* digital signature */
    unsigned char reserved2[2048-1024-256-8];
}second_loader_hdr;

Цифровая подпись: unsigned char rsaHash[256]; Шаг 1: получите открытый ключ из первого загрузчика. Шаг 2: сравните SHA256 ключа с хешем OTP; при совпадении продолжите, иначе отказ загрузки. Шаг 3: сравните SHA256 исходного бинарного файла с RSA2048-шифрованием подписи с ключом шага 1; при совпадении загрузка успешна и ключ передаётся U-Boot, иначе отказ.

2.5 U-Boot запускает boot-образ с ядром Linux

Рисунок английского оригинала, стр. 12

Рисунок 1-5: последовательность U-Boot → boot. Таблица 1-2: размещение данных boot.

boot.img Описание
0-2047 Заголовок
2048-4095 Цифровая подпись
4096- kernel,ramdisk,dtb…
…  

Структура заголовка по адресам 0–2047:

#define BOOT_MAGIC_SIZE 8
#define BOOT_NAME_SIZE 16
#define BOOT_ARGS_SIZE 512
typedef struct tag_boot_img_hdr
{
    unsigned char magic[BOOT_MAGIC_SIZE]; /* "ANDROID!" */
    unsigned int kernel_size;             /* size in bytes */
    unsigned int kernel_addr;             /* physical load addr */
    unsigned int ramdisk_size;            /* size in bytes */
    unsigned int ramdisk_addr;            /* physical load addr */
    unsigned int second_size;             /* size in bytes */
    unsigned int second_addr;             /* physical load addr */
    unsigned int tags_addr;               /* physical addr for kernel tags */
    unsigned int page_size;               /* flash page size we assume */
    unsigned int unused[2];               /* future expansion: should be 0 */
    unsigned char name[BOOT_NAME_SIZE];   /* asciiz product name */
    unsigned char cmdline[BOOT_ARGS_SIZE];
    unsigned int id[8];                   /* timestamp / checksum / sha1 / etc */
    unsigned char reserved[0x400-0x260];
    unsigned int signTag;                 /* 0x4E474953 */
    unsigned int signlen;                 /* 128 */
    unsigned char rsaHash[128];
}boot_img_hdr;

Цифровая подпись: unsigned char rsaHash[128]; Шаг 1: U-Boot получает открытый ключ первого загрузчика. Шаг 2: сравните SHA256 ключа с OTP; при совпадении продолжите, иначе отказ. Шаг 3: сравните SHA256 исходного бинарного файла с RSA2048-шифрованием подписи с ключом шага 1; при совпадении запустите ядро Linux, иначе отказ.

2.6 U-Boot запускает Recovery

Аналогично запуску boot-образа; источник ссылается на §1.4 (старый номер сохранён, требует проверки).

3. Разметка eFuse

RK3368, RK3288, RK3229 и RK3228 используют eFuse 1024 bit для безопасной загрузки. Таблица 2-1: размещение данных eFuse.

32-битная адресация словами Описание
0x00 Флаг безопасности Bits[7:0]: включение; Bits[31:8]: резерв
0x01-0x3 Зарезервировано
0x04-0x07 Зарезервировано
0x8-0xF Хеш открытого ключа RSA
0x10-0x17 Зарезервировано
0x18 Зарезервировано
0x19-0x1A Зарезервировано
0x1B-0x1D Зарезервировано
0x1E Зарезервировано
0x1F Биты блокировки записи eFuse

RK3228H и RK3328 используют OTP 7680 bit для безопасной загрузки. Таблица 2-2: размещение OTP.

32-битная адресация словами Описание
0-63 Открытый ключ (N)
64-127 Открытый ключ (E)
128 Bits[7:0]: 0xff — включение; Bits[15:8]: размер RSA_E (в источнике word uint); Bits[31:16]: резерв
129 Счётчик отзыва доверенной прошивки (ID #0)
130-131 Счётчик отзыва недоверенной прошивки (ID #1)
132-239 Зарезервировано

RK3326, PX30 и RK3308 используют OTP 4096 bit для безопасной загрузки. Таблица 2-3: размещение OTP 2.

32-битная адресация словами Описание
0 Флаг включения безопасной загрузки
1-3 Зарезервировано
4-11 Хеш открытого ключа RSA (SHA256)
12-19 Корневой ключ устройства
20-23 Ключ шифрования прошивки
24-25 Счётчик отзыва доверенной прошивки (ID #0)
26-31 Счётчик отзыва недоверенной прошивки (ID #1)
32-97 Резерв для OEM

4. Общий порядок операций

Порядок включения безопасной загрузки:

  1. Упакуйте update.img

  2. Подпишите update.img

  3. Запрограммируйте eFuse или OTP

  4. Обновите прошивку update.img

  5. Проверьте включение безопасной загрузки

Рисунок английского оригинала, стр. 18

Рисунок 3-1 Порядок операций

5. Создание update.img

5.1 Создание образов

После сборки Android создайте образы командой ./mkimage.sh ota.

Рисунок английского оригинала, стр. 21

./mkimage.sh ota
TARGET_PRODUCT=rk3288
TARGET_HARDWARE=rk30board
system filesystem is ext4
make ota images...
create boot.img with kernel... done.
create recovery.img with kernel... done.
create misc.img... done.
create system.img... done.

Рисунок 4-1 Сценарий упаковки

5.2 Упаковка update.img

Файл RKTools/windows/AndroidTool/rockdev/package-file определяет упаковываемые файлы. Для RK3288 измените путь bootloader, закомментируйте строки resource и kernel и задайте backup как RESERVED.

Рисунок английского оригинала, стр. 21

# NAME      Relative path
#
#HWDEF      HWDEF
package-file    package-file
bootloader  Image/RK3288UbootLoader.bin
parameter   rk3288-3.10-uboot.parameter.txt
#uboot      Image/uboot.img
misc        Image/misc.img
#resource   Image/resource.img
#kernel     Image/kernel.img
boot        Image/boot.img
recovery    Image/recovery.img
system      Image/system.img
# 要写入backup分区的文件就是自身(update.img)
# SELF 是关键字,表示升级文件(update.img)自身
# 在生成升级文件时,不加入SELF文件的内容,但在头部信息中有记录
# 在解包升级文件时,不解包SELF文件的内容
# RESERVED不打包backup
backup      RESERVED
update-script   update-script
recover-script  recover-script

Рисунок 4-2: управляющий файл package-file. Скопируйте RKTools/windows в Windows и запустите AndroidTool/rockdev/mkupdate.bat для создания update.img.

Рисунок английского оригинала, стр. 22

Рисунок 4-3 Сценарий упаковки

6. Подписание прошивки

Инструкция относится к инструментам Windows; для Linux есть отдельные инструменты.

6.1 Создание ключа RSA

Рисунок английского оригинала, стр. 24

Рисунок 5-1 Создание ключа

6.2 Сохранение ключа RSA

Ключ используется для подписи прошивок и OTA; сохраните резервную копию в защищённом хранилище. Пара ключей крайне важна: потеря или утечка создаёт высокий риск для продукта, а существующие устройства больше нельзя будет обновлять. Храните ключ весь жизненный цикл продукта.

Рисунок английского оригинала, стр. 25

Рисунок 5-2 Сохранение ключа

6.3 Загрузка ключа RSA

Рисунок английского оригинала, стр. 25

Рисунок 5-3 Загрузка ключа

6.4 Настройка

Рисунок английского оригинала, стр. 26

Выберите платформу SoC.

Рисунок английского оригинала, стр. 26

Параметр efuse сохраняет хеш открытого ключа RSA в eFuse и включает secure boot ROM (рекомендация источника). soft предназначен для особых приложений, не включает secure boot ROM и использует RSA1024 и SHA160.

Рисунок английского оригинала, стр. 26

Для каждой модели продукта RSA KEY создаётся один раз; сохраните резервную копию, иначе обновление прошивки или OTA может стать невозможным.

Рисунок английского оригинала, стр. 26

Загрузите резервный ключ RSA; поддерживается .pem от openssl.

Рисунок английского оригинала, стр. 26

Подпишите прошивку.

6.5 Подпись прошивки

Источник требует «убедиться, что boot.img и recovery.img включены в kernel image»; см. команду упаковки. Формулировка включения сомнительна и сохранена без вывода о структуре образа.

Рисунок английского оригинала, стр. 26

./mkimage.sh ota
TARGET_PRODUCT=rk3288
TARGET_HARDWARE=rk30board
system filesystem is ext4
make ota images...
create boot.img with kernel... done.
create recovery.img with kernel... done.
create misc.img... done.
create system.img... done.

Рисунок 5-4: команда упаковки. Откройте образ прошивки:

Рисунок английского оригинала, стр. 27

Рисунок 5-5: выбор прошивки в SecureBootTool. Подписанная прошивка:

Рисунок английского оригинала, стр. 27

Рисунок 5-6 Подписанная прошивка

7. Программирование eFuse

7.1 Аппаратные условия

Для Rockchip AP есть два способа записи пользовательских защищённых данных: eFuse и OTP, поддерживаемый лишь некоторыми чипами. Описание ниже.

7.1.1 Программирование eFuse

RK3126, RK3128, RK3228, RK3229, RK3288, RK3368 и RK3399 поддерживают программирование eFuse. Общие требования:

A. Если программирование не нужно, рекомендуется напрямую заземлить питание eFuse во избежание случайного изменения данных. У RK3126/RK3126C этот вывод совмещён с SARADC, поэтому заземлять его нельзя.

B. Если программирование нужно, подключите подтягивающий к земле резистор к питанию eFuse, чтобы напряжение не колебалось в обычном режиме и исключалось случайное программирование. Номинал берётся из схемы платформы, обычно 47Ω–10KΩ.

C. Есть два способа питания. a) Питание на основной плате: не нужна PCBA-плата с контактной оснасткой; можно сначала запрограммировать eFuse, затем обновить прошивку. В обычном режиме прошивка должна отключать питание eFuse, удерживая 0V. Недостатки: схема питания занимает плату, увеличивает стоимость компонентов и требует гарантии отсутствия ошибочных действий прошивки. Подходит продуктам без дополнительного PCBA-тестирования, например некоторым BOX с простыми интерфейсами и сборкой, где контактная оснастка не нужна. b) Питание от PCBA-тестовой платы (рекомендация источника): на основной плате нужны лишь тестовые точки, без схемы питания; пользователь не может взломать этот путь питания программно. Недостатки: добавляются этап PCBA-теста и его стоимость. Подходит сложным изделиям, например планшетам, где ремонт и замена дефектной PCBA после сборки трудны и тестирование обычно уже существует; программировать eFuse на этом этапе разумно.

D. Напряжения eFuse различаются по платформам (например 1.5/1.8/2.5V), как и номера выводов и требования по току.

Рекомендуется источник с током более 50mA; напряжение и номинал подтяжки см. в схеме. Таблица 6-1 содержит сводные параметры.

Модель чипа Питание eFuse Способ программирования Требование тока VQPS Номинал резистора к земле Вывод питания eFuse Примечание
RK3126/RK3126C 2.5V Питание от PCBA-тестовой платы >50mA Нет PIN68 Совмещён с ADC
RK3128 2.5V Встроенное или внешнее питание >50mA <=10K R10  
RK3168/RK3188 1.5V Встроенное или внешнее питание >50mA <=510R Y10  
RK3228/RK3229 1.6V Встроенное или внешнее питание >50mA <=100R R10  
RK3288 1.5V Встроенное или внешнее питание >50mA <=510R P19  
RK3368 1.5V Встроенное или внешнее питание >50mA <=47R Y10  
RK3399 1.8V Встроенное или внешнее питание >50mA <=1K AD23  

Рекомендуемая схема показана ниже. a) PartA: питание eFuse; выберите LDO по указанному напряжению, разместив его на основной или PCBA-тестовой плате. b) PartB: резистор R4 (47R–10K) удерживает питание eFuse на низком уровне против случайных операций. При питании от тестовой платы на основной плате SoC нужны тестовые точки для контактов оснастки. Внимание: a) питание eFuse RK3126C совмещено с ADC, резистор к земле недопустим; b) для RK3228/RK3229 рекомендуется 1.55–1.6V для стабильности; c) при onboard-питании назначьте eFuse_PWREN отдельный GPIO для LDO, обеспечив отсутствие напряжения на VCC_eFuse в нормальном режиме. См. эталонную схему Rockchip; если GPIO не выделен, источник требует обратиться к производителю или использовать внешнее питание.

Рисунок английского оригинала, стр. 31

Рисунок 6-1 Схема eFuse

7.1.2 Программирование OTP

RK3328 и RK3228H поддерживают OTP без внешней схемы питания. OTP_VCC18 (PIN16) постоянно питается от VCC_18; достаточно специальной временной последовательности OTP без дополнительных аппаратных изменений.

Рисунок английского оригинала, стр. 31

Рисунок 6-2 Схема OTP

7.2 Интерфейс инструмента

Рисунок английского оригинала, стр. 31

Рисунок 6-3 Интерфейс инструмента

7.3 Загрузка подписанной прошивки

Рисунок английского оригинала, стр. 32

Рисунок 6-4 Загрузка подписанной прошивки

7.4 Нажмите Run для запуска

Рисунок английского оригинала, стр. 32

Рисунок 6-5 Программирование чипа

7.5 Программирование eFuse

Подключите устройство к ПК по USB; инструмент автоматически запишет хеш открытого ключа RSA в eFuse. Требуется внешнее питание, см. DATASHEET SoC. Источник указывает, что RK3228H, RK3328, RK3336, RK3308 и PX30 не требуют шагов 6.2–6.4: программирование выполняется обновлением подписанной прошивки. RK3336 и номера разделов сохранены для проверки.

7.6 Программирование OTP

RK3228H, RK3328, RK3326, RK3308 и PX30 поддерживают OTP. Хеш открытого ключа записывается в OTP следующим образом:

  1. Сначала запишите подписанную прошивку описанным способом. Нормальный запуск подтверждает процесс подписи; затем можно программировать OTP.

  2. Используйте SecureBootTool V1.9 или новее. В config.ini каталога инструмента найдите sign_flag= и задайте sign_flag=0x20 (bit5=1), разрешив запись OTP в RKMiniLoader. Сохраните, снова откройте SecureBootTool.exe и подпишите прошивку или RKMiniLoader.

Рисунок английского оригинала, стр. 33

Рисунок 6-6-1 Инструмент

Рисунок английского оригинала, стр. 34

[System]
support_chip=3308|3326|3399|3228h|3229|3368|3228|3288|3128|3036
new_crypto=3308|3326
#using software to check signature,using sha160 ,belong to "soft_sign"
soft_sign=3128|3036
hard_sign_big_hash=3228h|3368|3228|3288
hard_sign_little_hash=3399
hard_sign_pss=3308|3326|3229

sign_flag=0x20
sign_soft_version=
sign_nonce=

Часть комментариев обрезана справа в оригинальном снимке. Все видимые ключи и значения переписаны выше; окончания комментариев не восстановлены догадками.

Рисунок 6-6-2 Настройка config.ini

  1. Запишите заново подписанную прошивку или RKMiniLoader и перезагрузите. При запуске RKMiniLoader создаёт хеш открытого ключа, записывает его в OTP и включает безопасную загрузку.

Рисунок английского оригинала, стр. 35

Рисунок 6-6-3 Процесс OTP

  1. При успехе UART выводит otp write key success!!!, при ошибке — otp write error: !!!.

8. Обновление прошивки

8.1 Обновление прошивки

Откройте подписанную прошивку и подключите устройство с запрограммированным eFuse к ПК по USB.

Рисунок английского оригинала, стр. 37

Рисунок 7-1: инструмент обновления 1. Выберите Upgrade, нажмите Run и дождитесь окончания.

Рисунок английского оригинала, стр. 38

Рисунок 7-2 Инструмент обновления 2

9. Проверка

9.1 Проверка флага безопасности

Считайте журнал запуска через UART, например SecureCRT. Secure Boot Mode: 0x1 или SecureMode = 0x1 указывает на включённую безопасную загрузку.

Рисунок английского оригинала, стр. 40

Рисунок 8-1 Журнал загрузки

9.2 Тест безопасной загрузки

После программирования eFuse включается secure boot ROM: неподписанная прошивка не загружается. Обновление неподписанной прошивкой или подписью другого ключа должно завершиться ошибкой, совпадающая подпись — успешной загрузкой. RK3128 и RK3126 отказывают на этапе wait for loader.

Рисунок английского оригинала, стр. 41

Рисунок 8-2: ошибка обновления 1. Другие SoC отказывают на Download Boot:

Рисунок английского оригинала, стр. 41

Рисунок 8-3 Ошибка обновления 2

10. Защищённая отладка

10.1 Введение

Secure Debug лишь отключает проверку безопасной загрузки для обновления неподписанного ядра и ускорения отладки. Каждый SoC имеет уникальный 128-битный CPU ID. Инструмент читает ID и выполняет названную источником Decryption операцию закрытым RSA-ключом, создавая сертификат. Устройство проверяет его открытым RSA-ключом; после успеха U-Boot отключает проверку загрузки. Это контролируемый процесс производителя, не разрешение обходить авторизацию чужих устройств.

10.2 Процесс защищённой отладки

Процесс защищённой отладки (английский оригинал)

Другие статьи по теме → · Учебные маршруты →