Полный перевод английского 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. Значения не исправлены догадками.
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 Процесс безопасной загрузки

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

Рисунок 1-2 Порядок безопасной загрузки
2.3 MaskRom запускает первый загрузчик (RKminiLoader/U-Boot)

Рисунок 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 (необязательный второй загрузчик)

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

Область 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

Рисунок 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. Общий порядок операций
Порядок включения безопасной загрузки:
-
Упакуйте update.img
-
Подпишите update.img
-
Запрограммируйте eFuse или OTP
-
Обновите прошивку update.img
-
Проверьте включение безопасной загрузки

Рисунок 3-1 Порядок операций
5. Создание update.img
5.1 Создание образов
После сборки Android создайте образы командой ./mkimage.sh ota.

./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.

# 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.

Рисунок 4-3 Сценарий упаковки
6. Подписание прошивки
Инструкция относится к инструментам Windows; для Linux есть отдельные инструменты.
6.1 Создание ключа RSA

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

Рисунок 5-2 Сохранение ключа
6.3 Загрузка ключа RSA

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

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

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

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

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

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

./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: команда упаковки. Откройте образ прошивки:

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

Рисунок 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 не выделен, источник требует обратиться к производителю или использовать внешнее питание.

Рисунок 6-1 Схема eFuse
7.1.2 Программирование OTP
RK3328 и RK3228H поддерживают OTP без внешней схемы питания. OTP_VCC18 (PIN16) постоянно питается от VCC_18; достаточно специальной временной последовательности OTP без дополнительных аппаратных изменений.

Рисунок 6-2 Схема OTP
7.2 Интерфейс инструмента

Рисунок 6-3 Интерфейс инструмента
7.3 Загрузка подписанной прошивки

Рисунок 6-4 Загрузка подписанной прошивки
7.4 Нажмите Run для запуска

Рисунок 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 следующим образом:
-
Сначала запишите подписанную прошивку описанным способом. Нормальный запуск подтверждает процесс подписи; затем можно программировать OTP.
-
Используйте SecureBootTool V1.9 или новее. В config.ini каталога инструмента найдите sign_flag= и задайте sign_flag=0x20 (bit5=1), разрешив запись OTP в RKMiniLoader. Сохраните, снова откройте SecureBootTool.exe и подпишите прошивку или RKMiniLoader.

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

[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
- Запишите заново подписанную прошивку или RKMiniLoader и перезагрузите. При запуске RKMiniLoader создаёт хеш открытого ключа, записывает его в OTP и включает безопасную загрузку.

Рисунок 6-6-3 Процесс OTP
- При успехе UART выводит
otp write key success!!!, при ошибке —otp write error: !!!.
8. Обновление прошивки
8.1 Обновление прошивки
Откройте подписанную прошивку и подключите устройство с запрограммированным eFuse к ПК по USB.

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

Рисунок 7-2 Инструмент обновления 2
9. Проверка
9.1 Проверка флага безопасности
Считайте журнал запуска через UART, например SecureCRT. Secure Boot Mode: 0x1 или SecureMode = 0x1 указывает на включённую безопасную загрузку.

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

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

Рисунок 8-3 Ошибка обновления 2
10. Защищённая отладка
10.1 Введение
Secure Debug лишь отключает проверку безопасной загрузки для обновления неподписанного ядра и ускорения отладки. Каждый SoC имеет уникальный 128-битный CPU ID. Инструмент читает ID и выполняет названную источником Decryption операцию закрытым RSA-ключом, создавая сертификат. Устройство проверяет его открытым RSA-ключом; после успеха U-Boot отключает проверку загрузки. Это контролируемый процесс производителя, не разрешение обходить авторизацию чужих устройств.
10.2 Процесс защищённой отладки

