前言

概述

OTP是一种非易失性存储器。其主要特性是对应存储空间的位内容由0写为1后,或根据锁机制,锁定对应的区域后,就不能再修改。OTP主要用于保存一些特定的数据,如用于CIPHER模块的root key,安全使能标志等信息。

说明: 未有特殊说明,SS528V100与SS625V100、SS524V100与SS522V100、SS927V100与SS928V100内容一致。

产品版本

与本文档相对应的产品版本如下。

产品名称

产品版本

SS928

V100

SS626

V100

SS524

V100

SS522

V100

SS528

V100

SS625

V100

SS927

V100

读者对象

本文档(本指南)主要适用于以下工程师:

  • 技术支持工程师

  • 软件开发工程师

符号约定

在本文中可能出现下列标志,它们所代表的含义如下。

符号

说明

表示如不避免则将会导致死亡或严重伤害的具有高等级风险的危害。

表示如不避免则可能导致死亡或严重伤害的具有中等级风险的危害。

表示如不避免则可能导致轻微或中度伤害的具有低等级风险的危害。

用于传递设备或环境安全警示信息。如不避免则可能会导致设备损坏、数据丢失、设备性能降低或其它不可预知的结果。

“须知”不涉及人身伤害。

对正文中重点信息的补充说明。

“说明”不是安全警示信息,不涉及人身、设备及环境伤害信息。

修订记录

修订记录累积了每次文档更新的说明。最新版本的文档包含以前所有文档版本的更新内容。

文档版本

发布日期

修改说明

00B01

2025-09-15

第1次临时版本发布。

概述

OTP模块提供驱动一次性编程的MPI接口,实现CIPHER模块root key烧写,jtag key烧写,key烧写状态校验,用户预留空间数据读写等功能。

OTP中密钥使用机制

图 1 SS528V100、SS524V100 OTP中密钥使用机制

图 2 SS928V100、SS626V100 OTP中密钥使用机制

OTP使用注意事项

OTP部署在不同场景下时,使用方式可能会有所不同。

  • 在Linux环境下

    • 用户态使用OTP可以通过链接静态库libss_otp.a或动态库libss_otp.so的方式,依赖libsecurec.a或libsecurec.so。

    • 内核态OTP使用模块插入方式,即insmod ot_otp.ko,需要依赖ot_osal.ko,ot_base.ko,sys_config.ko,ot_sys.ko。

  • 在OPTEE环境下,用户态调用OTP对外接口由Linux环境下的ss_mpi_xxx命名形式对应更改为ot_tee_xxx。

  • 在UBOOT环境下,用户态调用OTP对外接口由Linux环境下的ss_mpi_xxx命名形式对应变更为ot_mpi_xxx。

API参考

OTP提供以下API:

  • ss_mpi_otp_init:初始化OTP模块。

  • ss_mpi_otp_deinit:去初始化OTP模块。

  • ss_mpi_otp_set_user_data:设置OTP用户空间数据。

  • ss_mpi_otp_get_user_data:读取OTP用户空间数据。

  • ss_mpi_otp_set_user_data_lock:设置OTP用户数据锁

  • ss_mpi_otp_get_user_data_lock:获取OTP用户数据锁

  • ss_mpi_otp_burn_product_pv:烧写PV的数据和锁标志到芯片内部OTP。

  • ss_mpi_otp_read_product_pv:获取芯片内部OTP的PV数据或锁标志。

  • ss_mpi_otp_get_key_verify_status:获取芯片内部OTP中存储KEY的校验状态。

ss_mpi_otp_init

【描述】

初始化OTP模块。

【语法】

td_s32 ss_mpi_otp_init(td_void);

【参数】

无。

【返回值】

返回值

描述

0

成功。

非0

参见错误码。

【需求】

  • 头文件:ot_common_otp.h、ss_mpi_otp.h

  • 库文件:libss_otp.a

【注意】

初始化和去初始化必须成对存在。

【举例】

无。

ss_mpi_otp_deinit

【描述】

去初始化OTP模块。

【语法】

td_s32 ss_mpi_otp_deinit(td_void);

【参数】

无。

【返回值】

返回值

描述

0

成功。

非0

参见错误码。

【需求】

  • 头文件:ot_common_otp.h、ss_mpi_otp.h

  • 库文件:libss_otp.a

【注意】

初始化和去初始化必须成对存在。

【举例】

无。

ss_mpi_otp_set_user_data

【描述】

设置OTP用户空间数据。

【语法】

td_s32 ss_mpi_otp_set_user_data(const td_char *field_name, td_u32 offset, const td_u8 *value, td_u32 value_len);

【参数】

参数名称

描述

输入/输出

field_name

字段名称。

输入

offset

OTP用户空间地址偏移。

输入

value

设置的用户空间数据。

输入

value_len

设置的用户空间数据长度(单位:byte)。

输入

【返回值】

返回值

描述

0

成功。

非0

参见错误码。

【需求】

  • 头文件:ot_common_otp.h、ss_mpi_otp.h

  • 库文件:libss_otp.a

【注意】

  • 参数field_name设定参考《安全子系统使用说明》2.2章节“SSxxxx OTP字段定义”中“字段名称”列。

  • offset必须 4 字节对齐。

  • value_len为value的字节长度。

  • 参数offset,value_len取值范围参考《安全子系统使用说明》2.2章节“SSxxxx OTP字段定义”中“位宽”列。offset + value_len不能大于最大字节长度。

【举例】

无。

ss_mpi_otp_get_user_data

【描述】

获取OTP用户空间数据。

【语法】

td_s32 ss_mpi_otp_get_user_data(const td_char *field_name, td_u32 offset, td_u8 *value, td_u32 value_len);

【参数】

参数名称

描述

输入/输出

field_name

字段名称。

输入

offset

OTP用户空间地址偏移。

输入

value

获取的用户空间数据。

输出

value_len

获取的用户空间数据长度(单位:byte)。

输入

【返回值】

返回值

描述

0

成功。

非0

参见错误码。

【需求】

  • 头文件:ot_common_otp.h、ss_mpi_otp.h

  • 库文件:libss_otp.a

【注意】

  • 参数field_name设定参考《安全子系统使用说明》2.2章节“SSxxxx OTP字段定义”中“字段名称”列。

  • offset 必须 4 字节对齐。

  • value_len 为value字节长度。

  • 参数offset,value_len取值范围参考《安全子系统使用说明》2.2章节“SSxxxx OTP字段定义”中“位宽”列。offset + value_len 不能大于最大取值。

【举例】

无。

ss_mpi_otp_set_user_data_lock

【描述】

设置OTP用户空间数据锁。

【语法】

td_s32 ss_mpi_otp_set_user_data_lock(const td_char *field_name, td_u32 offset, td_u32 value_len);

【参数】

参数名称

描述

输入/输出

field_name

字段名称。

输入

offset

OTP用户空间地址偏移。

输入

value_len

获取的用户空间数据锁长度(单位:byte)。

输入

【返回值】

返回值

描述

0

成功。

非0

参见错误码。

【需求】

  • 头文件:ot_common_otp.h、ss_mpi_otp.h

  • 库文件:libss_otp.a

【注意】

  • 参数field_name设定参考《安全子系统使用说明》2.2章节“SSxxxx OTP字段定义”中“字段名称”列。

  • offset 必须 4 字节对齐。

  • 参数offset,value_len取值范围参考《安全子系统使用说明》2.2章节“SSxxxx OTP字段定义定义”中“位宽”列。offset + value_len 不能大于最大取值。

  • SS528V100、SS524V100 不支持该接口。

【举例】

无。

ss_mpi_otp_get_user_data_lock

【描述】

获取OTP用户空间数据锁。

【语法】

td_s32 ss_mpi_otp_get_user_data_lock(const td_char *field_name, td_u32 offset, td_u32 value_len, ot_otp_lock_status *lock);

【参数】

参数名称

描述

输入/输出

field_name

字段名称。

输入

offset

OTP用户空间地址偏移。

输入

value_len

获取的用户空间数据锁长度(单位:byte)。

输入

lock

获取的锁状态。

输出

【返回值】

返回值

描述

0

成功。

非0

参见错误码。

【需求】

  • 头文件:ot_common_otp.h、ss_mpi_otp.h

  • 库文件:libss_otp.a

【注意】

  • 参数field_name设定参考《安全子系统使用说明》2.2章节“SSxxxx OTP字段定义”中“字段名称”列。

  • offset 必须 4 字节对齐。

  • 参数offset,value_len取值范围参考《安全子系统使用说明》2.2章节“SSxxxx OTP字段定义”中“位宽”列。offset + value_len 不能大于最大取值。

  • SS528V100、SS524V100 不支持该接口。

【举例】

无。

ss_mpi_otp_burn_product_pv

【描述】

烧写PV的数据和锁标志到芯片内部OTP。

【语法】

td_s32 ss_mpi_otp_burn_product_pv(const ot_otp_burn_pv_item *pv, td_u32 num);

【参数】

参数名称

描述

输入/输出

pv

烧写的 pv 数据组。

输入

num

烧写的 pv 数据组数量。

输入

【返回值】

返回值

描述

0

成功。

非0

参见错误码。

【需求】

  • 头文件:ot_common_otp.h、ss_mpi_otp.h

  • 库文件:libss_otp.a

【注意】

  • 参数pv的成员burn必须设为TD_TRUE。

  • 参数pv的成员field_name设定参考《安全子系统使用说明》2.2章节“SSxxxx OTP字段定义”中“字段名称”列。

  • 参数pv的成员value_len为 value 的位长度,取值参考《安全子系统使用说明》2.2章节“SSxxxx OTP字段定义”中“位宽”列。

  • 参数pv的成员value取值参考《安全子系统使用说明》2.2章节“SSxxxx OTP字段定义”中“说明”列。

  • 参数pv的成员lock取值为TD_TRUE或TD_FALSE,《安全子系统使用说明》2.2章节“SSxxxx OTP字段定义”中“说明”列,自动lock的field_name配置任何值均会锁定。

  • 参数num有效取值范围是1~500。

【举例】

无。

ss_mpi_otp_read_product_pv

【描述】

获取芯片内部OTP的PV数据或锁标志。

【语法】

td_s32 ss_mpi_otp_read_product_pv(ot_otp_burn_pv_item *pv, td_u32 num);

【参数】

参数名称

描述

输入/输出

pv

获取的 pv 数据组。

输入和输出

num

获取的 pv 数据组数量。

输入

【返回值】

返回值

描述

0

成功。

非0

参见错误码。

【需求】

  • 头文件:ot_common_otp.h、ss_mpi_otp.h

  • 库文件:libss_otp.a

【注意】

  • 参数pv的成员burn必须设为TD_FALSE。

  • 参数pv的成员field_name设定《安全子系统使用说明》2.2章节“SSxxxx OTP字段定义”中“字段名称”列。

  • 参数pv的成员value_len为value的位长度,取值参考《安全子系统使用说明》2.2章节“SSxxxx OTP字段定义”中“位宽”列。

  • 参数pv的成员value取值参考《安全子系统使用说明》2.2章节“SSxxxx OTP字段定义”中“说明”列。

  • 参数num有效取值范围是1~500。

【举例】

无。

ss_mpi_otp_get_key_verify_status

【描述】

获取芯片内部OTP中存储KEY的校验状态。

【语法】

td_s32 ss_mpi_otp_get_key_verify_status(const td_char *key_name, td_bool *status);

【参数】

参数名称

描述

输入/输出

key_name

验证的 KEY 字段名称。

输入

status

获取的 KEY 检验状态。

输出

【返回值】

返回值

描述

0

成功。

非0

参见错误码。

【需求】

  • 头文件:ot_common_otp.h、ss_mpi_otp.h

  • 库文件:libss_otp.a

【注意】

参数key_name设定《安全子系统使用说明》2.2章节“SSxxxx OTP字段定义”中“字段名称”列。

【举例】

无。

数据类型

相关数据类型、数据结构定义如下:

  • ot_otp_burn_pv_item:OTP PV数据类型。

  • ot_otp_lock_status:定义OTP数据锁状态。

  • OT_OTP_PV_NAME_MAX_LEN:字段名称最大字节长度(单位:byte)。

  • OT_OTP_PV_VALUE_MAX_LEN:ot_otp_burn_pv_item成员value最大字节长度(单位:byte)。

ot_otp_burn_pv_item

【说明】

OTP PV数据类型。

【定义】

typedef struct {
    td_bool burn;
    td_char field_name[OT_OTP_PV_NAME_MAX_LEN];
    td_u32  value_len;
    td_u8   value[OT_OTP_PV_VALUE_MAX_LEN];
    td_bool lock;
} ot_otp_burn_pv_item;

【成员】

成员名称

描述

burn

是否烧写,TD_TRUE烧写,TD_FALSE读取。

field_name

字段名称。

value_len

数据位宽长度(单位:bit)。

value

数据缓冲区。

lock

是否锁定。

【注意事项】

value_len指向value的位宽长度。

【相关数据类型及接口】

ot_otp_lock_status

【说明】

定义OTP数据锁状态。

【定义】

typedef enum {
    OT_OTP_STA_ALL_UNLOCKED = 0,                    /**< user data area is all unlock. */
    OT_OTP_STA_PARTIAL_LOCKED,                      /**< user data area is partial unlock. */
    OT_OTP_STA_ALL_LOCKED,                          /**< user data area is all lock. */
    OT_OTP_STA_BUTT,                                /**< invalid param. */
} ot_otp_lock_status;

【成员】

成员名称

描述

OT_OTP_STA_ALL_UNLOCKED

当前获取的用户空间全部未锁定。

OT_OTP_STA_PARTIAL_LOCKED

当前获取的用户空间部分锁定。

OT_OTP_STA_ALL_LOCKED

当前获取的用户空间全部锁定。

OT_OTP_STA_BUTT

数据缓冲区。

【注意事项】

无。

【相关数据类型及接口】

ss_mpi_otp_get_user_data_lock

OT_OTP_PV_NAME_MAX_LEN

【说明】

字段名称最大字节长度(单位:byte)。

【定义】

#define OT_OTP_PV_NAME_MAX_LEN                           32

【成员】

无。

【注意事项】

无。

【相关数据类型及接口】

OT_OTP_PV_VALUE_MAX_LEN

【说明】

ot_otp_burn_pv_item成员value最大字节长度(单位:byte)。

【定义】

#define OT_OTP_PV_VALUE_MAX_LEN                          32

【成员】

无。

【注意事项】

无。

【相关数据类型及接口】

错误码

OTP提供的错误码如下所示。

表 1 OTP模块的错误码

错误代码

宏定义

描述

0x804e0001

OT_ERR_OTP_NOT_INIT

设备未初始化

0x804e0002

OT_ERR_OTP_NULL_PTR

参数中有空指针

0x804e0003

OT_ERR_OTP_BUSY

设备忙

0x804e0004

OT_ERR_OTP_FAILED_INIT

初始化失败

0x804e0005

OT_ERR_OTP_FAILED_MEM

分配内存失败

0x804e0006

OT_ERR_OTP_FAILED_SEC_FUNC

安全函数调用失败

0x804e0007

OT_ERR_OTP_INVALID_PARAM

无效参数

0x804e0008

OT_ERR_OTP_INVALID_FIELD_NAME

字段名称不匹配

0x804e0009

OT_ERR_OTP_ZONE_ALREADY_SET

用户空间已设置

0x804e000a

OT_ERR_OTP_ZONE_LOCKED

用户空间已锁定

0x804e000b

OT_ERR_OTP_ZONE_NO_PERMIT

无用户空间权限

0x804e000c

OT_ERR_OTP_WAIT_TIMEOUT

等待超时

0x804e000d

OT_ERR_OTP_FUNC_UNSUPPORT

功能不支持

缩略语

A

AES

Advanced Encryption Standard

高级加密标准

K

KLAD

Key Ladder

层级密钥

O

OTP

One Time Programmable

一次性编程

S

SPACC

Security Protocol Accelerator

安全协议加速器