OTP使用参考¶
REVISION HISTORY¶
| Revision No. | Description |
Date |
|---|---|---|
| 1.00 | 06/09/2025 | |
| 1.01 | 11/17/2025 |
1. 概述¶
1.1 什么是OTP¶
OTP(One-Time Programmable)是一次性可编程存储器,具有以下特点:
- 一次性写入:每个bit位只能从0编程为1一次,无法从1改回0
- 非易失性:掉电后数据不会丢失
- 高安全性:存储的信息不可篡改,适合保存密钥、配置等敏感数据
- 硬件级别保护:提供LOCK(写保护)和BLOCK(读保护)功能
重要提醒:
- OTP各个bit只能烧写一次,一旦置1后不可置0
- 相同位置烧录相同数据的行为不允许超过三次
- 请在确认需要的场合下执行烧写动作!
1.2 OTP使用场景¶
OTP主要用于以下场景:
- 安全启动:存储公钥、加密密钥,确保系统启动安全性
- 密钥管理:保存AES、RSA等加密密钥
- 设备标识:存储UUID、设备ID等唯一标识符
- 安全防护:配置防攻击、防篡改等安全功能
- 调试保护:设置调试接口的访问控制
- 用户数据:存储客户自定义的配置信息
1.3 OTP使用方法¶
1.3.1 基本操作命令¶
- 读取OTP:
otpctrl -r <command_id> - 写入OTP:
otpctrl -w <command_id> <offset> <data>
1.3.1.1 命令参数说明¶
command_id(命令ID):
- 用于标识不同的OTP存储区域,每个command_id对应一个特定的功能区域
- 例如:
0x0对应RSA公钥N值存储区域,0x2对应安全启动开关 - command_id的取值范围和对应功能详见后续章节的OTP栏位说明表
offset(偏移地址):
- 表示在指定command_id区域内的字节偏移量
- offset以4字节为单位递增(0, 4, 8, 12, ...)
- 例如:offset 0x0表示该区域的起始位置,offset 0x4表示第5个字节位置
data(数据):
- 要写入的32位数据,以16进制格式表示
- 数据大小固定为4字节(32位)
- 例如:
0xFFFFFFFF表示写入32个1
1.3.1.2 命令使用示例¶
示例1:启用安全启动功能
# 写入安全启动开关(command_id=0x2,offset=0x0,data=0xFFFFFFFF)
otpctrl -w 0x2 0x0 0xFFFFFFFF
示例2:配置RSA公钥(分多次写入)
# 写入RSA公钥N值的第一部分(command_id=0x0)
otpctrl -w 0x0 0x0 0x58653431 # offset=0x0,写入第1-4字节
otpctrl -w 0x0 0x4 0x06ba8f4a # offset=0x4,写入第5-8字节
otpctrl -w 0x0 0x8 0x5caee61a # offset=0x8,写入第9-12字节
# ... 继续写入完整的512字节RSA N值
# 写入RSA公钥E值(command_id=0x1,只有4字节)
otpctrl -w 0x1 0x0 0x00010001
示例3:读取验证
# 读取安全启动状态
otpctrl -r 0x2
# 读取RSA公钥E值验证
otpctrl -r 0x1
1.3.2 OTP修改流程¶
- 确认修改内容:明确需要配置的功能和参数
- 准备数据:生成密钥文件、证书等必要数据
- 转换为烧录格式:使用工具将原始数据转换为otpctrl命令
- 执行烧录:在UBOOT环境下执行烧录命令
- 验证结果:读取OTP确认烧录成功
- 启用保护(可选):根据需要启用LOCK或BLOCK保护
1.3.3 完整示例:配置RSA公钥并启用安全启动¶
以下是一个完整的OTP配置示例,演示如何配置RSA公钥并启用安全启动功能:
步骤1:准备RSA公钥文件
假设已有RSA公钥文件 rsa-public.pem:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----
步骤2:转换为烧录格式
cd project/image/security_boot_tools/tools/
./key_proc.py --exportkey_reverse --rsa=public.pem
该命令会生成 rsaKey.txt 文件,包含烧录所需的otpctrl命令。
步骤3:进入UBOOT环境
重启设备并进入UBOOT命令行界面。
步骤4:烧录RSA公钥N值
将 rsaKey.txt 中的RSA N-Key部分复制到UBOOT执行:
####### RSA N-Key ########
otpctrl -w 0x0 0x0 0x58653431;otpctrl -w 0x0 0x4 0x06ba8f4a;otpctrl -w 0x0 0x8 0x5caee61a;otpctrl -w 0x0 0xc 0x1912648d;...
注意:由于UBOOT命令行缓存限制,建议分批执行,每次不超过16条命令。
步骤5:烧录RSA公钥E值
####### RSA E-Key ########
otpctrl -w 0x1 0x0 0x00010001
步骤6:验证烧录结果
# 读取RSA N值
otpctrl -r 0x0
# 读取RSA E值
otpctrl -r 0x1
步骤7:启用安全启动功能
otpctrl -w 0x2 0x0 0xFFFFFFFF
步骤8:验证安全启动状态
otpctrl -r 0x2
步骤9:重启设备验证
重启设备,确认系统正常启动且安全启动功能已生效。
2. OTP栏位详细说明¶
以下根据使用场景详细说明各个OTP栏位的功能、command_id和具体使用方法。每个场景都会提供具体的命令示例,与前面介绍的基本操作命令相对应。
2.1 安全启动相关的OTP栏位¶
使用场景:启用系统的安全启动功能,确保只有经过数字签名的固件才能运行,保护系统免受恶意软件攻击。
对于IFord系统芯片,如果客户使用security boot功能,需要关注OTP以下内容:
| OTP | command ID | length(byte) | Permission | Description |
|---|---|---|---|---|
| OTP_RSA_N | 0X00 | 512 | Read/Write | 保存用于验签IPL的RSA public key的 N 值 |
| OTP_RSA_E | 0X01 | 4 | Read/Write | 保存用于验签IPL的RSA public key的 E 值 |
| OTP_SECURITY_BOOT | 0X02 | 4 | Read/Write | 启动security boot功能开关,需要在确认正确烧录完RSA/AES key才开启 |
| OTP_RSA_KEY_LOCK | 0X03 | 4 | Read/Write | 对OTP内的RSA Public Key栏位进行LOCK的动作,LOCK后不可再修改,客户可根据需求使用 |
| OTP_RSA_KEY_BLOCK | 0X04 | 4 | Read/Write | 对OTP内的RSA Public Key栏位进行BLOCK的动作,BLOCK后CPU无法读出OTP内的RSA Public Key,客户可根据需求使用 |
| OTP_KEY1 | 0X05 | 16 | Read/Write | 第1把AES128 key |
| OTP_KEY2 | 0X06 | 16 | Read/Write | 第2把AES128 key,也可以和OTP_KEY1组合成第1把AES256 key |
| OTP_KEY3 | 0X07 | 16 | Read/Write | 第3把AES128 key |
| OTP_KEY4 | 0X08 | 16 | Read/Write | 第4把AES128 key,也可以和OTP_KEY3组合成第2把AES256 key |
| OTP_KEY5 | 0X09 | 16 | Read/Write | 第5把AES128 key |
| OTP_KEY6 | 0X0A | 16 | Read/Write | 第6把AES128 key,也可以和OTP_KEY5组合成第3把AES256 key |
| OTP_KEY7 | 0X0B | 16 | Read/Write | 第7把AES128 key |
| OTP_KEY8 | 0X0C | 16 | Read/Write | 第8把AES128 key,也可以和OTP_KEY7组合成第4把AES256 key |
| OTP_AES_KEY1_LOCK | 0X0D | 4 | Read/Write | LOCK后不可再修改即16byte OTP内容非0bit也不可置1,客户可根据需求使用 |
| OTP_AES_KEY1_BLOCK | 0X0E | 4 | Read/Write | BLOCK后不可再修改,只有HW aesdma能够访问而CPU无法访问,客户可根据需求使用 |
| OTP_AES_KEY2_LOCK | 0X0F | 4 | Read/Write | LOCK后不可再修改,即16byte OTP内容非0bit也不可置1,客户可根据需求使用 |
| OTP_AES_KEY2_BLOCK | 0X10 | 4 | Read/Write | BLOCK后不可再修改,只有HW aesdma能够访问而CPU无法访问,客户可根据需求使用 |
| OTP_AES_KEY3_LOCK | 0X11 | 4 | Read/Write | LOCK后不可再修改,即16byte OTP内容非0bit也不可置1,客户可根据需求使用 |
| OTP_AES_KEY3_BLOCK | 0X12 | 4 | Read/Write | BLOCK后不可再修改,只有HW aesdma能够访问而CPU无法访问,客户可根据需求使用 |
| OTP_AES_KEY4_LOCK | 0X13 | 4 | Read/Write | LOCK后不可再修改,即16byte OTP内容非0bit也不可置1,客户可根据需求使用 |
| OTP_AES_KEY4_BLOCK | 0X14 | 4 | Read/Write | BLOCK后不可再修改,只有HW aesdma能够访问而CPU无法访问,客户可根据需求使用 |
| OTP_AES_KEY5_LOCK | 0X15 | 4 | Read/Write | LOCK后不可再修改,即16byte OTP内容非0bit也不可置1,客户可根据需求使用 |
| OTP_AES_KEY5_BLOCK | 0X16 | 4 | Read/Write | BLOCK后不可再修改,只有HW aesdma能够访问而CPU无法访问,客户可根据需求使用 |
| OTP_AES_KEY6_LOCK | 0X17 | 4 | Read/Write | LOCK后不可再修改,即16byte OTP内容非0bit也不可置1,客户可根据需求使用 |
| OTP_AES_KEY6_BLOCK | 0X18 | 4 | Read/Write | BLOCK后不可再修改,只有HW aesdma能够访问而CPU无法访问,客户可根据需求使用 |
| OTP_AES_KEY7_LOCK | 0X19 | 4 | Read/Write | LOCK后不可再修改,即16byte OTP内容非0bit也不可置1,客户可根据需求使用 |
| OTP_AES_KEY7_BLOCK | 0X1A | 4 | Read/Write | BLOCK后不可再修改,只有HW aesdma能够访问而CPU无法访问,客户可根据需求使用 |
| OTP_AES_KEY8_LOCK | 0X1B | 4 | Read/Write | LOCK后不可再修改,即16byte OTP内容非0bit也不可置1,客户可根据需求使用 |
| OTP_AES_KEY8_BLOCK | 0X1C | 4 | Read/Write | BLOCK后不可再修改,只有HW aesdma能够访问而CPU无法访问,客户可根据需求使用 |
| OTP_ROM_SELECT_AES_KEY | 0X24 | 4 | Read/Write | 选择OTP中哪一把AESKey对IPL进行解密,一旦写入此OTP,IPL必须使用AES加密 |
| OTP_ROM_SELECT_AES_KEY_LOCK | 0X25 | 4 | Read/Write | LOCK后OTP_ROM_SELECT_AES_KEY不可再修改。 |
| OTP_RSA_KEY_LEN | 0X2F | 4 | Read/Write | 使用RSA4096签章时,必须烧录。如果使用RSA2048签章,不用烧录。 |
各个OTP栏位的烧录方法举例说明如下。
2.1.1 配置RSA公钥N值和E值 (OTP_RSA_N: 0x0, OTP_RSA_E: 0x1)¶
对于现成的需要rsa-public.pem文件,需要先将pem格式转化成可以用于烧录的格式。使用以下cmd生成rsaKey.txt,rsaKey.txt中的command在UBOOT下烧写OTP。
cd project/image/security_boot_tools/tools/
./key_proc.py --exportkey_reverse --rsa=public.pem
举例使用现成的pem文件转化后的rsaKey.txt内容如下,直接复制粘贴到uboot 菜单命令行下执行即可:
####### RSA N-Key ########
otpctrl -w 0x0 0x0 0x58653431;otpctrl -w 0x0 0x4 0x06ba8f4a;otpctrl -w 0x0 0x8 0x5caee61a;otpctrl -w 0x0 0xc 0x1912648d;otpctrl -w 0x0 0x10 0xb3b77f1c;otpctrl -w 0x0 0x14 0xd116e973;otpctrl -w 0x0 0x18 0x74f82967;otpctrl -w 0x0 0x1c 0xf85d78e8;otpctrl -w 0x0 0x20 0x55a92d7a;otpctrl -w 0x0 0x24 0xf807ef92;otpctrl -w 0x0 0x28 0xeaca7ab8;otpctrl -w 0x0 0x2c 0x2d33149a;otpctrl -w 0x0 0x30 0xc47f6cfb;otpctrl -w 0x0 0x34 0x99d0fb2b;otpctrl -w 0x0 0x38 0xb94e529f;otpctrl -w 0x0 0x3c 0x09d1e66a;
otpctrl -w 0x0 0x40 0x93614b62;otpctrl -w 0x0 0x44 0x40db5115;otpctrl -w 0x0 0x48 0x4d37ec4c;otpctrl -w 0x0 0x4c 0xd7ac36da;otpctrl -w 0x0 0x50 0x8bbef7bb;otpctrl -w 0x0 0x54 0x459ffe82;otpctrl -w 0x0 0x58 0xea5aa7ed;otpctrl -w 0x0 0x5c 0x979ac988;otpctrl -w 0x0 0x60 0xd9ad7843;otpctrl -w 0x0 0x64 0xb086c544;otpctrl -w 0x0 0x68 0x75248853;otpctrl -w 0x0 0x6c 0xd0c61f34;otpctrl -w 0x0 0x70 0xd4fd028a;otpctrl -w 0x0 0x74 0x93037bd3;otpctrl -w 0x0 0x78 0x2b3cd0e2;otpctrl -w 0x0 0x7c 0x12b49f2d;
otpctrl -w 0x0 0x80 0x72fc0405;otpctrl -w 0x0 0x84 0xc1fb6cfd;otpctrl -w 0x0 0x88 0xb42fb860;otpctrl -w 0x0 0x8c 0xa06e8c6e;otpctrl -w 0x0 0x90 0x43870bc3;otpctrl -w 0x0 0x94 0xb97ebe88;otpctrl -w 0x0 0x98 0x45113bd1;otpctrl -w 0x0 0x9c 0xb7974436;otpctrl -w 0x0 0xa0 0x47c3d001;otpctrl -w 0x0 0xa4 0x3611716d;otpctrl -w 0x0 0xa8 0x67abc2d5;otpctrl -w 0x0 0xac 0x773ac1cd;otpctrl -w 0x0 0xb0 0x7d1ee609;otpctrl -w 0x0 0xb4 0xc72e97ee;otpctrl -w 0x0 0xb8 0x91af8bd5;otpctrl -w 0x0 0xbc 0xd516243d;
otpctrl -w 0x0 0xc0 0x949b2522;otpctrl -w 0x0 0xc4 0x3d73c4d7;otpctrl -w 0x0 0xc8 0xcf2fde53;otpctrl -w 0x0 0xcc 0xbd35d242;otpctrl -w 0x0 0xd0 0x2362de0f;otpctrl -w 0x0 0xd4 0x8d9f7418;otpctrl -w 0x0 0xd8 0x861f69d5;otpctrl -w 0x0 0xdc 0x0736f5ff;otpctrl -w 0x0 0xe0 0x7655b44e;otpctrl -w 0x0 0xe4 0x06198429;otpctrl -w 0x0 0xe8 0xe0975a88;otpctrl -w 0x0 0xec 0x6fcec320;otpctrl -w 0x0 0xf0 0x49480b57;otpctrl -w 0x0 0xf4 0xea4a5ee3;otpctrl -w 0x0 0xf8 0x6502ddee;otpctrl -w 0x0 0xfc 0xd6d17ae2;
####### RSA E-Key ########
otpctrl -w 0x1 0x0 0x00010001
注意:因为uboot 菜单命令行的buf缓存长度有限制,不可直接将64条otpctrl命令当成一次复制粘贴回车运行。建议至少分成4次执行。
2.1.2 启用安全启动功能 (OTP_SECURE_BOOT: 0x2)¶
确认RSA/AES key都烧录后,启动security boot功能(下次启动才会生效):
otpctrl -w 0x2 0x0 0xFFFFFFFF
检查security boot功能是否已开启:
otpctrl -r 0x2
2.1.3 RSA密钥写保护和读保护 (OTP_RSA_KEY_LOCK: 0x3, OTP_RSA_KEY_BLOCK: 0x4)¶
非必要操作,客户可根据需求使用。
确认LOCK和BLOCK rsa key(下次启动才会生效):
otpctrl -w 0x3 0x0 0xFFFFFFFF
otpctrl -w 0x4 0x0 0xFFFFFFFF
检查LOCK和BLOCK是否已开启:
otpctrl -r 0x3
otpctrl -r 0x4
2.1.4 配置AES加密密钥 (OTP_AES128_KEY: 0x5~0xC)¶
如果客户使用security boot的签章+加密功能,烧录AES KEY是必要操作。
如果是制作AES128 KEY:
echo '000102030405060708090A0B0C0D0E0F' | xxd -r -ps > aesKey128_1.bin
烧录AES key到 OTP_KEY1位置:
otpctrl -w 0x5 0x0 0x03020100
otpctrl -w 0x5 0x4 0x07060504
otpctrl -w 0x5 0x8 0x0B0A0908
otpctrl -w 0x5 0xC 0x0F0E0D0C
如果是制作AES256 KEY:
echo '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F' | xxd -r -ps > aesKey256_1.bin
烧录AES key到 OTP_KEY1和OTP_KEY2位置:
otpctrl -w 0x5 0x0 0x03020100
otpctrl -w 0x5 0x4 0x07060504
otpctrl -w 0x5 0x8 0x0B0A0908
otpctrl -w 0x5 0xC 0x0F0E0D0C
otpctrl -w 0x6 0x0 0x13121110
otpctrl -w 0x6 0x4 0x17161514
otpctrl -w 0x6 0x8 0x1B1A1918
otpctrl -w 0x6 0xC 0x1F1E1D1C
烧录8把AES128 key或者4把AES256 key的操作同理。
2.1.5 AES密钥写保护和读保护 (OTP_AES128_KEY1~8_LOCK: 0xD,0xF,0x11,0x13,0x15,0x17,0x19,0x1B / OTP_AES128_KEY1~8_BLOCK: 0xE,0x10,0x12,0x14,0x16,0x18,0x1A,0x1C)¶
非必要操作,客户可根据需求使用。
确认LOCK和BLOCK 第一把AES128 key(下次启动才会生效):
otpctrl -w 0xD 0x0 0xFFFFFFFF
otpctrl -w 0xE 0x0 0xFFFFFFFF
第一把AES128 key检查LOCK和BLOCK是否已开启:
otpctrl -r 0xD
otpctrl -r 0xE
确认LOCK和BLOCK 第一把AES256 key(下次启动才会生效):
otpctrl -w 0xD 0x0 0xFFFFFFFF
otpctrl -w 0xF 0x0 0xFFFFFFFF
otpctrl -w 0xE 0x0 0xFFFFFFFF
otpctrl -w 0x10 0x0 0xFFFFFFFF
第一把AES256 key检查LOCK和BLOCK是否已开启:
otpctrl -r 0xD
otpctrl -r 0xF
otpctrl -r 0xE
otpctrl -r 0x10
LOCK和BLOCK8把AES128 key或者4把AES256 key的操作同理。
2.1.6 选择IPL解密密钥 (OTP_ROM_SEL_AESKEY: 0x24)¶
如果客户使用security boot的签章+加密功能,烧录OTP_ROM_SEL_AESKEY用来选择OTP中哪一把AESKey对IPL进行解密是必要操作。
如果客户只使用security boot的签章,不可烧录OTP_ROM_SEL_AESKEY。
Example:
-
选择 AESKEY128_1
otpctrl -w 0x24 0x0 0xFF000000 -
选择 AESKEY128_2
otpctrl -w 0x24 0x0 0xFF0000FF -
选择 AESKEY128_3
otpctrl -w 0x24 0x0 0xFF00FF00 -
选择 AESKEY128_4
otpctrl -w 0x24 0x0 0xFF00FFFF -
选择 AESKEY128_5
otpctrl -w 0x24 0x0 0xFFFF0000 -
选择 AESKEY128_6
otpctrl -w 0x24 0x0 0xFFFF00FF -
选择 AESKEY128_7
otpctrl -w 0x24 0x0 0xFFFFFF00 -
选择 AESKEY128_8
otpctrl -w 0x24 0x0 0xFFFFFFFF
另外IPL可以使用AES256解密,OTP中AESKEY256实际上是由OTP中两把AES128组合而成,组合和设置方式举例如下:
-
选择 AESKEY256_1(Composition mode: AES128key1 + AES128key2)
otpctrl -w 0x24 0x0 0x00FF0000 -
选择 AESKEY256_2(Composition mode: AES128key3 + AES128key4)
otpctrl -w 0x24 0x0 0x00FF00FF -
选择 AESKEY256_3(Composition mode: AES128key5 + AES128key6)
otpctrl -w 0x24 0x0 0x00FFFF00 -
选择 AESKEY256_4(Composition mode: AES128key7 + AES128key8)
otpctrl -w 0x24 0x0 0x00FFFFFF
2.1.7 IPL解密密钥选择写保护 (OTP_ROM_SEL_AESKEY_LOCK: 0x25)¶
非必要操作,客户可根据需求使用。
确认LOCK OTP_ROM_SEL_AESKEY里的内容(下次启动才会生效):
otpctrl -w 0x25 0x0 0xFFFFFFFF
检查LOCK是否已开启:
otpctrl -r 0x25
2.1.8 RSA密钥长度配置 (OTP_RSA_KEY_LEN: 0x2F)¶
如果客户使用rsa4096来签章,必须烧录此OTP栏位,使用rsa2048则无需关注。
otpctrl -w 0x2F 0x0 0xFFFFFFFF
2.2 防止错误注入和信号分析功能相关的OTP栏位¶
使用场景:增强系统的硬件安全防护能力,防止通过物理攻击手段(如错误注入、侧信道攻击)获取敏感信息或破坏系统功能。适用于对安全性要求极高的应用场景。
对于IFord系统芯片,如果客户使用防止错误注入和信号分析功能(Multiple Round、SCA、key2sha1),才需要关注OTP以下内容:
| OTP | command ID | length(byte) | Permission | Description |
|---|---|---|---|---|
| OTP_PROTECT_ENABLE | 0x30 | 4 | Read/Write | rsa2sha1和pwd2sha1和aes2sha1的总开关 |
| OTP_RSA_KEY_N_CHK_ENABLE | 0x31 | 4 | Read/Write | 启动rsa2sha1的子开关,表示启动rsa public key的check功能 |
| OTP_PASSWORD_CHK_ENABLE | 0x32 | 4 | Read/Write | 启动pwd2sha1的子开关,表示启动password的check功能 |
| OTP_OTP_KEY_CHK_ENABLE | 0x33 | 4 | Read/Write | 启动aes2sha1的子开关,表示启动AES key的check功能 |
| OTP_AES_MULTIPLE_NUM | 0x34 | 8 | Read/Write | 启动aes multiple num的开关,表示AES内部加解密需要做N(1~4)次,N次结果一致再输出 |
| OTP_SCA_PROTECT_ENABLE | 0x35 | 4 | Read/Write | 启动SCA PROTECT的开关,表示每次HW aes加解密中加入random num打乱aes时序,防止信号分析 |
| OTP_PassWord_chk | 0x36 | 4 | Read/Write | 保存PASSWORD的 SHA1&XOR运算值,用于启动过程校验OTP PASSWORD可靠性 |
| OTP_Key1_chk | 0x37 | 4 | Read/Write | 保存第1把AES128的 SHA1&XOR运算值,用于启动过程校验OTP AESKEY可靠性 |
| OTP_Key2_chk | 0x38 | 4 | Read/Write | 保存第2把AES128的 SHA1&XOR运算值,用于启动过程校验OTP AESKEY可靠性 |
| OTP_Key3_chk | 0x39 | 4 | Read/Write | 保存第3把AES128的 SHA1&XOR运算值,用于启动过程校验OTP AESKEY可靠性 |
| OTP_Key4_chk | 0x3A | 4 | Read/Write | 保存第4把AES128的 SHA1&XOR运算值,用于启动过程校验OTP AESKEY可靠性 |
| OTP_Key5_chk | 0x3B | 4 | Read/Write | 保存第5把AES128的 SHA1&XOR运算值,用于启动过程校验OTP AESKEY可靠性 |
| OTP_Key6_chk | 0x3C | 4 | Read/Write | 保存第6把AES128的 SHA1&XOR运算值,用于启动过程校验OTP AESKEY可靠性 |
| OTP_Key7_chk | 0x3D | 4 | Read/Write | 保存第7把AES128的 SHA1&XOR运算值,用于启动过程校验OTP AESKEY可靠性 |
| OTP_Key8_chk | 0x3E | 4 | Read/Write | 保存第8把AES128的 SHA1&XOR运算值,用于启动过程校验OTP AESKEY可靠性 |
| OTP_RSA_KEY_N_CHK | 0x3F | 4 | Read/Write | 保存RSA public N key的 SHA1&XOR运算值,用于启动过程校验OTP RSAKEY可靠性 |
各个OTP栏位的烧录方法举例说明如下。
2.2.1 启用防护功能总开关 (OTP_PROTECT_ENABLE: 0x30)¶
启动aes2sha1 pwd2sha1 rsa2sha1 check的总开关,烧录后须于下次启动才会生效。
otpctrl -w 0x30 0x0 0xFFFFFFFF
检查总开关是否已开启:
otpctrl -r 0x30
2.2.2 RSA公钥完整性校验 (OTP_RSA_KEY_N_CHK_ENABLE: 0x31, OTP_RSA_KEY_N_CHK: 0x3F)¶
非必要操作,客户可根据需求使用。注意开启 OTP_RSA_KEY_N_CHK_ENABLE 需要搭配烧录OTP_RSA_KEY_N_CHK。
对于现成的rsa-public.pem文件,制作key-SHA1方法如下:
./key_proc.py --key2sha1 -f rsa2048/public-otp.pem
------------------------------------------------------>public-otp.pem_sha1.txt
举例使用现成的pem文件转化后的pem_sha1.txt内容如下:

otpctrl -w 0x3F 0x0 0xa44a2887
再启动rsa2sha1的子开关:
otpctrl -w 0x31 0x0 0xFFFFFFFF
2.2.3 密码完整性校验 (OTP_PASSWORD_CHK_ENABLE: 0x32, OTP_PassWord_chk: 0x36)¶
非必要操作,客户可根据需求使用。注意开启 OTP_PASSWORD_CHK_ENABLE 需要搭配烧录OTP_PassWord_chk。
对于现成的需要pwd.bin文件,制作key-SHA1方法如下:
./key_proc.py --pwd2sha1 -f pwd.bin
------------------------------------------------------>pwd.bin_sha1.txt
举例使用现成的pwd.bin文件转化后的bin_sha1.txt内容如下:

otpctrl -w 0x36 0x0 0xa6a938d1
再启动pwd2sha1的子开关:
otpctrl -w 0x32 0x0 0xFFFFFFFF
2.2.4 AES密钥完整性校验 (OTP_OTP_KEY_CHK_ENABLE: 0x33, OTP_Key1~8_chk: 0x37-0x3E)¶
非必要操作,客户可根据需求使用。注意开启 OTP_OTP_KEY_CHK_ENABLE 需要搭配烧录由OTP_ROM_SELECT_AES_KEY 指定的第n把AES key对应的OTP_Key_chk。
对于现成的需要aesKey.bin文件,制作key-SHA1方法如下:
./key_proc.py --key2sha1 -f aeskey/aesKey1.bin
------------------------------------------------------>aesKey1.bin_sha1.txt
举例使用现成的aesKey.bin文件转化后的bin_sha1.txt内容如下:

如果OTP_ROM_SELECT_AES_KEY 指定的AESDMA使用的AESKey是第1把,则烧录bin_sha1.txt内容到OTP_Key1_chk
otpctrl -w 0x37 0x0 0x35f0f5d7
如果OTP_ROM_SELECT_AES_KEY 指定的AESDMA使用的AESKey是第2把,则烧录bin_sha1.txt内容到OTP_Key2_chk
otpctrl -w 0x38 0x0 0x35f0f5d7
如果OTP_ROM_SELECT_AES_KEY 指定的AESDMA使用的AESKey是第3把,则烧录bin_sha1.txt内容到OTP_Key3_chk
otpctrl -w 0x39 0x0 0x35f0f5d7
以此类推。
再启动aes2sha1的子开关:
otpctrl -w 0x33 0x0 0xFFFFFFFF
2.2.5 AES多重加密配置 (OTP_AES_MULTIPLE_NUM: 0x34)¶
非必要操作,客户可根据需求使用。表示AES内部加解密需要做N(1~4)次,N次结果一致再输出。在设置完该Command后,须于下次启动才会生效。
Example:
MULTIPLE_NUM=1:
otpctrl -w 0x34 0x0 0x00000000
otpctrl -w 0x34 0x4 0x00000000
MULTIPLE_NUM=2:
otpctrl -w 0x34 0x0 0xFFFFFFFF
otpctrl -w 0x34 0x4 0x00000000
MULTIPLE_NUM=3:
otpctrl -w 0x34 0x0 0x00000000
otpctrl -w 0x34 0x4 0xFFFFFFFF
MULTIPLE_NUM=4:
otpctrl -w 0x34 0x0 0xFFFFFFFF
otpctrl -w 0x34 0x4 0xFFFFFFFF
2.2.6 侧信道攻击防护 (OTP_SCA_PROTECT_ENABLE: 0x35)¶
非必要操作,客户可根据需求使用。表示启动SCA PROTECT。SCA是在aes加解密中加入random num打乱aes时序,防止信号分析,在设置完该Command后,须于下次启动才会生效。
Example:
WRITE COMMAND: otpctrl -w 0x35 0x0 0xFFFFFFFF
2.3 用户自定义数据相关的OTP栏位¶
使用场景:存储产品特定的配置信息、序列号、校准参数、许可证信息等用户自定义数据。提供1KB的存储空间,支持分区域写保护。
对于IFord系统芯片,OTP区域有8K bit开放给客户使用保存自定义数据。
| OTP | command ID | length(byte) | Permission | Description |
|---|---|---|---|---|
| OTP_CUSTOMER_AREA | 0XA0 | 1024 | Read/Write | 可用于用户自由烧录自定义数据 |
| OTP_CUSTOMER_AREA_LOCK0 | 0XA1 | 4 | Read/Write | LOCK后,0-127Bytes 自定义数据不可再修改 |
| OTP_CUSTOMER_AREA_LOCK1 | 0XA2 | 4 | Read/Write | LOCK后,128-255Bytes 自定义数据不可再修改 |
| OTP_CUSTOMER_AREA_LOCK2 | 0XA3 | 4 | Read/Write | LOCK后,256-383Bytes 自定义数据不可再修改 |
| OTP_CUSTOMER_AREA_LOCK3 | 0XA4 | 4 | Read/Write | LOCK后,384-511Bytes 自定义数据不可再修改 |
| OTP_CUSTOMER_AREA_LOCK4 | 0XA5 | 4 | Read/Write | LOCK后,512-639Bytes 自定义数据不可再修改 |
| OTP_CUSTOMER_AREA_LOCK5 | 0XA6 | 4 | Read/Write | LOCK后,640-767Bytes 自定义数据不可再修改 |
| OTP_CUSTOMER_AREA_LOCK6 | 0XA7 | 4 | Read/Write | LOCK后,768-895Bytes 自定义数据不可再修改 |
| OTP_CUSTOMER_AREA_LOCK7 | 0XA8 | 4 | Read/Write | LOCK后,896-1023Bytes 自定义数据不可再修改 |
各个OTP栏位的烧录方法举例说明如下。
2.3.1 用户自定义数据存储 (OTP_CUSTOMER_AREA: 0xA0)¶
每次只能写4byte。offset从0x0 - 0x3FF。
Example:
otpctrl -w 0xA0 0x0 0x12345678
otpctrl -w 0xA0 0x4 0x09ABCDEF
otpctrl -w 0xA0 0x8 0x33445566
以此类推。
最后4byte WRITE COMMAND:
otpctrl -w 0xA0 0x3fC 0xAA778899
CUSTOMER_AREA读取:
otpctrl -r 0xA0
2.3.2 用户数据区域写保护 (OTP_CUSTOMER_AREA_LOCK: 0xA1~0xA8)¶
LOCK 0k~1K bits数据(下次启动才会生效):
otpctrl -w 0xA1 0x0 0xFFFFFFFF
LOCK 1k~2K bits数据(下次启动才会生效):
otpctrl -w 0xA2 0x0 0xFFFFFFFF
LOCK 2k~3K bits数据(下次启动才会生效):
otpctrl -w 0xA3 0x0 0xFFFFFFFF
LOCK 3k~4K bits数据(下次启动才会生效):
otpctrl -w 0xA4 0x0 0xFFFFFFFF
LOCK 4k~5K bits数据(下次启动才会生效):
otpctrl -w 0xA5 0x0 0xFFFFFFFF
LOCK 5k~6K bits数据(下次启动才会生效):
otpctrl -w 0xA6 0x0 0xFFFFFFFF
LOCK 6k~7K bits数据(下次启动才会生效):
otpctrl -w 0xA7 0x0 0xFFFFFFFF
LOCK 7k~8K bits数据(下次启动才会生效):
otpctrl -w 0xA8 0x0 0xFFFFFFFF
2.4 PassWord Mode相关的栏位¶
使用场景:控制调试接口(JTAG、I2C)的访问权限,通过密码保护机制防止未授权的调试访问,保护产品的知识产权和敏感信息。
| OTP | command ID | length(byte) | Permission | Description |
|---|---|---|---|---|
| OTP_DISABLE_JTAG_MODE | 0X1F | 4 | Read/Write | 用于永久关闭JTAG模式 |
| OTP_PASSWORD_JTAG_MODE | 0X20 | 4 | Read/Write | 设置保护模式,需要输入正确密码打开JTAG模式 |
| OTP_PASSWORD | 0x21 | 8 | Read/Write | Debugging Ports(I2C/eJTAG) password |
| OTP_PASSWORD_LOCK | 0x22 | 4 | Read/Write | 对OTP内的PASSWORD栏位进行LOCK的动作,LOCK后不可再修改,客户可根据需求使用 |
| OTP_PASSWORD_BLOCK | 0x23 | 4 | Read/Write | 对OTP内的PASSWORD栏位进行BLOCK的动作,BLOCK后CPU无法读出OTP内的PASSWORD,客户可根据需求使用 |
| OTP_DISABLE_IIC_MODE | 0X50 | 4 | Read/Write | 用于永久关闭IIC模式 |
| OTP_PASSWORD_IIC_MODE | 0X51 | 4 | Read/Write | 设置保护模式,需要输入正确密码打开IIC模式 |
2.4.1 永久禁用JTAG调试接口 (OTP_DISABLE_JTAG_MODE: 0x1F)¶
永久关闭JTAG调试端口(下次启动才会生效):
otpctrl -w 0x1F 0x0 0xFFFFFFFF
2.4.2 设置JTAG密码保护模式 (OTP_PASSWORD_JTAG_MODE: 0x20)¶
设置保护模式,需要输入正确密码打开JTAG调试端口(下次启动才会生效):
otpctrl -w 0x20 0x0 0xFFFFFFFF
2.4.3 配置调试密码 (OTP_PASSWORD: 0x21)¶
由用户自行设置,该栏位用于设置保护模式的密码(下次启动才会生效):
otpctrl -w 0x21 0x0 0xXXXXXXXX
otpctrl -w 0x21 0x4 0xXXXXXXXX
2.4.4 调试密码写保护 (OTP_PASSWORD_LOCK: 0x22)¶
LOCK OTP的PASSWORD栏位(下次启动才会生效):
otpctrl -w 0x22 0x0 0xFFFFFFFF
2.4.5 阻止调试密码访问 (OTP_PASSWORD_BLOCK: 0x23)¶
BLOCK OTP的PASSWORD栏位(下次启动才会生效):
otpctrl -w 0x23 0x0 0xFFFFFFFF
2.4.6 永久禁用IIC调试接口 (OTP_DISABLE_IIC_MODE: 0x50)¶
永久关闭IIC调试端口(下次启动才会生效):
otpctrl -w 0x50 0x0 0xFFFFFFFF
2.4.7 设置IIC密码保护模式 (OTP_PASSWORD_IIC_MODE: 0x51)¶
设置保护模式,需要输入正确密码打开IIC调试端口(下次启动才会生效):
otpctrl -w 0x51 0x0 0xFFFFFFFF
2.5 ID相关的OTP栏位¶
使用场景:读取设备的唯一标识符和身份信息,用于设备身份认证、序列号管理、防伪识别等应用。这些标识符在生产时已固化,只能读取不能修改。
| OTP | command ID | length(byte) | Permission |
|---|---|---|---|
| OTP_UUID2 | 0X26 | 8 | Read-Only |
| OTP_DID1 | 0X27 | 8 | Read-Only |
| OTP_DID2 | 0X29 | 8 | Read-Only |
| OTP_UUID | 0X2E | 8 | Read-Only |
2.5.1 读取设备唯一标识符2 (OTP_UUID2: 0x26)¶
otpctrl -r 0x26
2.5.2 读取设备标识符1 (OTP_DID1: 0x27)¶
otpctrl -r 0x27
2.5.3 读取设备标识符2 (OTP_DID2: 0x29)¶
otpctrl -r 0x29
2.5.4 读取设备唯一标识符1 (OTP_UUID1: 0x2E)¶
otpctrl -r 0x2E
2.6 其它OTP栏位¶
使用场景:系统级别的配置选项,包括启动方式选择、安全区域配置、强制启动模式等。这些配置影响系统的启动行为和运行环境。
| OTP | command ID | length(byte) | Permission | Description |
|---|---|---|---|---|
| OTP_FORCE_UARTBOOT | 0X2D | 8 | Read/Write | 强制ROM走UART boot模式 |
| OTP_TZ | 0X40 | 4 | Read/Write | 默认为0,设置为1开启TZ |
| OTP_BOOT_SOURCE | 0XA9 | 4 | Read/Write | OTP_BOOT_SOURCE_ENABLE设置为1之后,通过这一栏确定具体的启动方式 |
| OTP_BOOT_SOURCE_ENABLE | 0XAA | 4 | Read/Write | 0对应通过硬件启动,1对应通过OTP_BOOT_SOURCE栏位确定启动方式 |
| OTP_BOOT_SOURCE_LOCK | 0XAB | 4 | Read/Write | 对OTP内的OTP_BOOT_SOURCE栏位进行LOCK的动作,LOCK后不可再修改,客户可根据需求使用 |
2.6.1 强制UART启动模式 (OTP_FORCE_UARTBOOT: 0x2D)¶
默认为不强制ROM走UARTBOOT模式,如需要强制UARTBOOT模式,使用如下指令(下次启动才会生效):
otpctrl -w 0x2D 0x0 0x00000000
otpctrl -w 0x2D 0x4 0xFFFFFFFF
otpctrl -w 0x2D 0x0 0xFFFFFFFF
otpctrl -w 0x2D 0x4 0x00000000
如需恢复到默认状态,使用如下指令(下次启动才会生效):
otpctrl -w 0x2D 0x0 0xFFFFFFFF
otpctrl -w 0x2D 0x4 0xFFFFFFFF
查看当前FORCE UARTBOOT状态:
otpctrl -r 0x2D
2.6.2 TrustZone安全区域配置 (OTP_TZ: 0x40)¶
设置Trust Zone开关,通常在产品阶段设置(下次启动才会生效):
otpctrl -w 0x40 0x0 0xFFFFFFFF
检查TZ的当前状态:
otpctrl -r 0x40
2.6.3 启动源选择配置 (OTP_BOOT_SOURCE: 0xA9)¶
OTP_BOOT_SOURCE_ENABLE设置为1之后,通过这一栏确定启动方式:
SPI NAND:
otpctrl -w 0xA9 0x0 0x00000f00
SPI NAND (skip SD):
otpctrl -w 0xA9 0x0 0x00000f0f
SPI NOR:
otpctrl -w 0xA9 0x0 0x00000ff0
SPI NOR (skip SD):
otpctrl -w 0xA9 0x0 0x00000fff
USB2.0:
otpctrl -w 0xA9 0x0 0x00000000
UART:
otpctrl -w 0xA9 0x0 0x0000000f
eMMC 4-bit:
otpctrl -w 0xA9 0x0 0x000000ff
2.6.4 启用OTP启动源选择 (OTP_BOOT_SOURCE_ENABLE: 0xAA)¶
通过OTP_BOOT_SOURCE栏位确定启动方式:
otpctrl -w 0xAA 0x0 0xFFFFFFFF
2.6.5 启动源配置写保护 (OTP_BOOT_SOURCE_LOCK: 0xAB)¶
LOCK OTP的BOOT_SOURCE栏位(下次启动才会生效):
otpctrl -w 0xAB 0x0 0xFFFFFFFF