跳转至

OTP使用参考


REVISION HISTORY

Revision No.
Description
Date
1.00
  • Initial release
  • 06/09/2025
    1.01
  • 添加OTP基本介绍和使用指南
  • 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主要用于以下场景:

    1. 安全启动:存储公钥、加密密钥,确保系统启动安全性
    2. 密钥管理:保存AES、RSA等加密密钥
    3. 设备标识:存储UUID、设备ID等唯一标识符
    4. 安全防护:配置防攻击、防篡改等安全功能
    5. 调试保护:设置调试接口的访问控制
    6. 用户数据:存储客户自定义的配置信息

    1.3 OTP使用方法

    1.3.1 基本操作命令

    • 读取OTPotpctrl -r <command_id>
    • 写入OTPotpctrl -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修改流程

    1. 确认修改内容:明确需要配置的功能和参数
    2. 准备数据:生成密钥文件、证书等必要数据
    3. 转换为烧录格式:使用工具将原始数据转换为otpctrl命令
    4. 执行烧录:在UBOOT环境下执行烧录命令
    5. 验证结果:读取OTP确认烧录成功
    6. 启用保护(可选):根据需要启用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内容如下:

    otp-sca-protect-enable

        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内容如下:

    otp-sca-protect-enable

        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-sca-protect-enable

    如果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