前言¶
KLAD是密钥管理模块,集成密钥派生、明文KEY传递、ROOTKEY层级传递。
说明: 本文未有特殊说明,SS927V100与SS928V100内容完全一致。
与本文档相对应的产品版本如下。
本文档(本指南)主要适用于以下工程师:
技术支持工程师
软件开发工程师
在本文中可能出现下列标志,它们所代表的含义如下。
概述¶
概述¶
KLAD是密钥管理模块。支持密钥派生、明文KEY传递和ROOTKEY层级传递。支持16个KLAD软件通道。
密钥派生¶
用户可根据不同的应用场景生成不同的密钥,最多可以派生232个ROOTKEY。
密钥派生出的 work key 可通过提供的派生工具计算,使用方法请参考 “密钥派生工具说明”。
明文KEY传递¶
明文KEY即加解密引擎使用的工作密钥由用户妥善保存。
支持 AES 128/192/256bits加解密。
支持 SM4 128bits加解密。
SS928V100、SS626V100不支持 SM4。
ROOTKEY传递¶
ROOTKEY即通过OTP模块的根密钥,经密钥解混淆、密钥派生后产生的KEY。ROOTKEY存储在硬件中,用户不可读取。加解密的工作密钥是KLAD多次层级传递后得到的KEY,该KEY也是存储在硬件中,用户不可读取。该方案多用于安全要求较高的场景,OTP的根密钥由用户妥善保存。
支持 AES 128/256bits加解密。
支持 SM4 128bits加解密。
SS928V100、SS626V100不支持 SM4。
SS928V100、SS626V100支持2级KLAD传递。
KLAD使用注意事项¶
KLAD部署在不同场景下时,使用方式可能会有所不同。
在Linux环境下
用户态使用KLAD可以通过链接静态库libss_klad.a或动态库libss_klad.so的方式,依赖libsecurec.a或libsecurec.so。
内核态KLAD使用模块插入方式,即insmod ot_klad.ko,需要依赖ot_osal.ko,ot_base.ko,sys_config.ko,ot_sys.ko。
在OPTEE环境下
用户态调用KLAD对外接口,由Linux环境下的ss_mpi_xxx命名形式更改为ot_tee_xxx;
内核态调用KLAD对外接口,由Linux环境下的ss_mpi_xxx命名形式更改为ot_drv_xxx。
在UBOOT环境下,用户态调用KLAD对外接口由Linux环境下的ss_mpi_xxx命名形式变更为ot_mpi_xxx。
使用流程¶
明文KEY传递¶
场景说明¶
当用于加解密的工作密钥由用户自己传入时,需使用明文KEY相关的接口。KLAD将工作密钥传递给一个KEYSLOT。加解密时,加解密引擎取对应KEYSLOT中的KEY用于加解密。
工作流程¶
明文KEY传递开发操作步骤如下:
KLAD设备初始化。调用接口ss_mpi_klad_init。
创建KLAD句柄。调用接口ss_mpi_klad_create。
绑定KLAD和KEYSLOT句柄。调用接口ss_mpi_klad_attach。
设置KLAD属性。调用接口ss_mpi_klad_set_attr。
设置明文KEY。调用接口ss_mpi_klad_set_clear_key。
解绑定KLAD和KEYSLOT句柄。调用接口ss_mpi_klad_detach。
销毁KLAD句柄。调用接口ss_mpi_klad_destroy。
去初始化KLAD设备。调用接口ss_mpi_klad_deinit。
注意事项¶
使用明文KEY传递时,请特别注意以下几点。
KEYSLOT句柄在配置KLAD之前,必须已通过CIPHER模块创建。
传递明文KEY,KLAD类型必须配置为明文KLAD(OT_KLAD_TYPE_CLEARCW)。
ROOTKEY传递¶
场景说明¶
当安全方案要求高的场景下采用,ROOTKEY经密钥解混淆、密钥派生后产生,经多级KLAD传递后得到一个真正的工作密钥。工作密钥存储在硬件中,用户不可读取。KLAD将工作密钥传递给一个KEYSLOT。加解密时,加解密引擎取对应KEYSLOT中的KEY用于加解密。
工作流程¶
ROOTKEY传递开发操作步骤如下:
KLAD设备初始化。调用接口ss_mpi_klad_init。
创建KLAD句柄。调用接口ss_mpi_klad_create。
绑定KLAD和KEYSLOT句柄。调用接口ss_mpi_klad_attach。
设置KLAD属性。调用接口ss_mpi_klad_set_attr。
设置第1~n-1级KLAD密钥信息。调用接口ss_mpi_klad_set_session_key。
设置第n级KLAD密钥信息。调用接口ss_mpi_klad_set_content_key。
解绑定KLAD和KEYSLOT句柄。调用接口ss_mpi_klad_detach。
销毁KLAD句柄。调用接口ss_mpi_klad_destroy。
去初始化KLAD设备。调用接口ss_mpi_klad_deinit。
注意事项¶
使用ROOTKEY传递时,请特别注意以下几点。
KEYSLOT句柄在配置KLAD之前,必须已通过CIPHER模块创建。
传递ROOTKEY,KLAD类型必须配置为通用KLAD(OT_KLAD_TYPE_COMMON)。
密钥派生工具说明¶
密钥派生工具位于 osdrv/tools/pc/kdf_customer 目录下。使用命令请参考目录下的 readme.txt 文件,下面主要说明 key.ini 文件相关字段的配置。
表 1 key.ini 字段说明
content_key,若使用 128 bit,则派生出的 work_key 也为 128bit;若使用 256 bit,则派生出的 work_key 也为 256bit。 |
|
注:
除上述字段外,其他字段无需修改。
若 content_key 为128 bit,则work_key 为生成的 out.bin 文件的前16 Bytes;若 content_key 为 256 bit,则 work_key 为生成的整个 out.bin 文件。
API参考¶
KLAD提供以下API:
ss_mpi_klad_init:初始化KLAD模块。
ss_mpi_klad_deinit:去初始化KLAD模块。
ss_mpi_klad_create:创建一路的KLAD句柄。
ss_mpi_klad_destroy:销毁已存在的KLAD句柄。
ss_mpi_klad_attach:绑定KLAD句柄和KEYSLOT句柄。
ss_mpi_klad_detach:解绑定KLAD句柄和KEYSLOT句柄。
ss_mpi_klad_set_attr:设置KLAD属性。
ss_mpi_klad_get_attr:获取KLAD属性。
ss_mpi_klad_set_session_key:配置第1~n-1级KLAD KEY。
ss_mpi_klad_set_content_key:配置最后一级KLAD KEY,同时将key传递给KEYSLOT。
ss_mpi_klad_set_clear_key:配置明文KEY,同时将key传递给KEYSLOT。
ss_mpi_klad_init¶
【描述】
初始化KLAD模块。
【语法】
td_s32 ss_mpi_klad_init(td_void);
【参数】
无。
【返回值】
参见错误码。 |
【需求】
头文件:ot_common_klad.h、ss_mpi_klad.h
库文件:libss_klad.a、libss_klad.so
【注意】
支持多次调用,但需与去初始化成对使用。
【举例】
无。
ss_mpi_klad_deinit¶
【描述】
去初始化KLAD模块。
【语法】
td_s32 ss_mpi_klad_deinit(td_void);
【参数】
无。
【返回值】
参见错误码。 |
【需求】
头文件:ot_common_klad.h、ss_mpi_klad.h
库文件:libss_klad.a、libss_klad.so
【注意】
支持多次调用。
初始化和去初始化成对使用。
【举例】
无。
ss_mpi_klad_create¶
【描述】
创建一路的KLAD句柄。
【语法】
td_s32 ss_mpi_klad_create (td_handle *klad);
【参数】
【返回值】
参见错误码。 |
【需求】
头文件:ot_common_klad.h、ss_mpi_klad.h
库文件:libss_klad.a、libss_klad.so
【注意】
klad不能为空。
使用完通道后,应销毁对应的通道。
创建与销毁通道成对使用。
【举例】
无。
ss_mpi_klad_destroy¶
【描述】
销毁一路KLAD。
【语法】
td_s32 ss_mpi_klad_destroy (td_handle klad);
【参数】
【返回值】
参见错误码。 |
【需求】
头文件:ot_common_klad.h、ss_mpi_klad.h
库文件:libss_klad.a、libss_klad.so
【注意】
KLAD句柄必须已创建。
创建与销毁通道成对使用。
【举例】
无。
ss_mpi_klad_attach¶
【描述】
绑定 KLAD 句柄和 KEYSLOT 句柄。
【语法】
td_s32 ss_mpi_klad_attach(td_handle klad, td_handle target);
【参数】
【返回值】
参见错误码。 |
【需求】
头文件:ot_common_klad.h、ss_mpi_klad.h
库文件:libss_klad.a、libss_klad.so
【注意】
KLAD、KEYSLOT句柄必须已创建,在句柄未创建的情况下,句柄之间的绑定可能成功,但会导致功能执行失败。
绑定和解绑定必须成对使用。
【举例】
无。
ss_mpi_klad_detach¶
【描述】
解绑定KLAD句柄和KEYSLOT句柄。
【语法】
td_s32 ss_mpi_klad_detach(td_handle klad, td_handle target);
【参数】
【返回值】
参见错误码。 |
【需求】
头文件:ot_common_klad.h、ss_mpi_klad.h
库文件:libss_klad.a、libss_klad.so
【注意】
KLAD、KEYSLOT句柄必须已创建。
绑定和解绑定必须成对使用。
【举例】
无。
ss_mpi_klad_set_attr¶
【描述】
设置 KLAD 属性。
【语法】
td_s32 ss_mpi_klad_set_attr(td_handle klad, const ot_klad_attr *attr);
【参数】
【返回值】
参见错误码。 |
【需求】
头文件:ot_common_klad.h、ss_mpi_klad.h
库文件:libss_klad.a、libss_klad.so
【注意】
KLAD句柄必须已创建。
可多次调用,每次调用会覆盖之前的属性配置,以最后一次设置的属性为准。
【举例】
无。
ss_mpi_klad_get_attr¶
【描述】
获取KLAD属性。
【语法】
td_s32 ss_mpi_klad_get_attr(td_handle klad, ot_klad_attr*attr);
【参数】
【返回值】
参见错误码。 |
【需求】
头文件:ot_common_klad.h、ss_mpi_klad.h
库文件:libss_klad.a、libss_klad.so
【注意】
KLAD句柄必须已创建。
【举例】
无。
ss_mpi_klad_set_session_key¶
【描述】
配置第1~n-1 级 KLAD KEY。
【语法】
td_s32 ss_mpi_klad_set_session_key(td_handle klad, const ot_klad_session_key *key);
【参数】
【返回值】
参见错误码。 |
【需求】
头文件:ot_common_klad.h、ss_mpi_klad.h
库文件:libss_klad.a、libss_klad.so
【注意】
KLAD句柄必须已创建。
该接口不可多次调用,重复调用可能导致密钥配置错误或接口返回失败。
【举例】
无。
ss_mpi_klad_set_content_key¶
【描述】
配置最后一级 KLAD KEY,同时将key传递给KEYSLOT。
【语法】
td_s32 ss_mpi_klad_set_content_key(td_handle klad, const ot_klad_content_key *key);
【参数】
【返回值】
参见错误码。 |
【需求】
头文件:ot_common_klad.h、ss_mpi_klad.h
库文件:libss_klad.a、libss_klad.so
【注意】
KLAD句柄必须已创建。
该接口不可多次调用,重复调用可能导致密钥配置错误或接口返回失败。
调用该接口时rootkey不能为0,需要烧写根密钥类型所对应的OTP,参考《安全子系统使用说明》的第2.2.2章节“密钥区域”。
【举例】
无。
ss_mpi_klad_set_clear_key¶
【描述】
配置明文KEY,同时将key传递给KEYSLOT。
【语法】
td_s32 ss_mpi_klad_set_clear_key(td_handle klad, const ot_klad_clear_key *key);
【参数】
【返回值】
参见错误码。 |
【需求】
头文件:ot_common_klad.h、ss_mpi_klad.h
库文件:libss_klad.a、libss_klad.so
【注意】
KLAD句柄必须已创建。
可多次调用,以最后一次设置的属性为准。
【举例】
无。
数据类型¶
相关数据类型、数据结构定义如下(其他公共数据类型定义请参考ot_type.h):
ot_klad_rootkey_sel:定义KLAD ROOTKEY选择枚举。
ot_klad_rootkey_secure:定义KLAD ROOTKEY的静态值枚举。
ot_klad_rootkey_attr:定义KLAD ROOTKEY属性结构体。
ot_klad_type:定义KLAD类型枚举。
ot_klad_cfg:定义KLAD 配置信息结构体。
ot_klad_crypto_alg:定义KEY在加解密引擎用于哪种算法。
ot_klad_attr:定义KLAD属性结构体。
ot_klad_alg_type:定义KLAD算法类型枚举。
ot_klad_level:定义KLAD层级枚举。
ot_klad_session_key:定义第1~n-1级KLAD密钥信息结构体。
ot_klad_content_key:定义第n级KLAD密钥信息结构体。
ot_klad_clear_key:定义明文密钥信息结构体。
OT_KLAD_MAX_KEY_LEN:定义KLAD最大密钥长度。
ot_klad_rootkey_sel¶
【说明】
定义KLAD ROOTKEY选择枚举。
【定义】
/* klad rootkey select */
typedef enum {
OT_KLAD_ROOTKEY_SEL_OEM0 = 0x00,
OT_KLAD_ROOTKEY_SEL_OEM1,
OT_KLAD_ROOTKEY_SEL_OEM2,
OT_KLAD_ROOTKEY_SEL_OEM3,
OT_KLAD_ROOTKEY_SEL_VENDOR,
OT_KLAD_ROOTKEY_SEL_BUTT,
} ot_klad_rootkey_sel;
【成员】
【注意事项】
无。
【相关数据类型及接口】
ot_klad_rootkey_secure¶
【说明】
定义KLAD ROOTKEY的静态值枚举。
【定义】
typedef enum {
OT_KLAD_ROOTKEY_SEC_REE = 0x00, /* REE key, TEE CPU can select ree key */
OT_KLAD_ROOTKEY_SEC_TEE, /* TEE key, REE CPU can't select tee key */
OT_KLAD_ROOTKEY_SEC_BUTT,
} ot_klad_rootkey_secure;
【成员】
【注意事项】
非安全CPU不能选择TEE密钥静态值。
安全CPU能选择REE密钥静态值。
【相关数据类型及接口】
ot_klad_rootkey_attr¶
【说明】
定义KLAD ROOTKEY属性结构体。
【定义】
/* only OT_KLAD_TYPE_COMMON is valid */
typedef struct {
td_u32 owner_id; /* Derivative material, used for mcipher */
ot_klad_rootkey_sel key_sel; /* common klad route select rootkey */
ot_klad_rootkey_secure key_secure; /* Static value select: for ree key or for tee key */
} ot_klad_rootkey_attr;
【成员】
【注意事项】
仅在KLAD类型为OT_KLAD_TYPE_COMMON时有效。
【相关数据类型及接口】
ot_klad_type¶
【说明】
定义KLAD类型枚举。
【定义】
/* klad route select */
typedef enum {
OT_KLAD_TYPE_CLEARCW, /* Used for clear key */
OT_KLAD_TYPE_COMMON, /* Used for root key */
OT_KLAD_TYPE_BUTT,
} ot_klad_type;
【成员】
【注意事项】
无。
【相关数据类型及接口】
ot_klad_cfg¶
【说明】
定义KLAD 配置信息结构体。
【定义】
/* klad config */
typedef struct {
ot_klad_type klad_type; /* klad route select: common/clear */
ot_klad_rootkey_attr rootkey_attr; /* rootkey attr, OT_KLAD_TYPE_COMMON is valid */
} ot_klad_cfg;
【成员】
【注意事项】
rootkey_attr仅在KLAD类型为OT_KLAD_TYPE_COMMON时有效。
【相关数据类型及接口】
ot_klad_crypto_alg¶
【说明】
定义KEY在加解密引擎用于哪种算法。
【定义】
/* The key can be used for which algorithm of the crypto engine. */
typedef enum {
OT_KLAD_CRYPTO_ALG_AES = 0,
OT_KLAD_CRYPTO_ALG_SM4,
OT_KLAD_CRYPTO_ALG_BUTT,
} ot_klad_crypto_alg;
【成员】
【注意事项】
SS928V100、SS626V100不支持SM4。
【相关数据类型及接口】
ot_klad_attr¶
【说明】
定义KLAD属性结构体
【定义】
/* klad attribute */
typedef struct {
ot_klad_cfg klad_cfg;
} ot_klad_attr;
【成员】
【注意事项】
无。
【相关数据类型及接口】
ot_klad_alg_type¶
【说明】
定义KLAD算法类型枚举。
【定义】
/* klad algorithm */
typedef enum {
OT_KLAD_ALG_TYPE_AES = 0,
OT_KLAD_ALG_TYPE_SM4,
OT_KLAD_ALG_TYPE_BUTT,
} ot_klad_alg_type;
【成员】
【注意事项】
SS928V100、SS626V100不支持SM4。
【相关数据类型及接口】
ot_klad_level¶
【说明】
定义KLAD层级枚举。
【定义】
/* klad level */
typedef enum {
OT_KLAD_LEVEL1 = 0,
OT_KLAD_LEVEL2,
OT_KLAD_LEVEL3,
OT_KLAD_LEVEL_BUTT,
} ot_klad_level;
【成员】
【注意事项】
SS928V100、SS626V100支持2级KLAD。
【相关数据类型及接口】
ot_klad_session_key¶
【说明】
定义第1~n-1级KLAD密钥信息结构体。
【定义】
/* session key: set 1~n-1 stage common route klad */
typedef struct {
ot_klad_level level; /* klad level */
ot_klad_alg_type alg; /* klad algorithm */
td_u32 key_size; /* klad key size */
td_u8 key[OT_KLAD_MAX_KEY_LEN]; /* klad key */
} ot_klad_session_key;
【成员】
【注意事项】
key_size只支持128bits,即16byte。
对于SS928V100、SS626V100,level只能配置OT_KLAD_LEVEL1。
【相关数据类型及接口】
ot_klad_content_key¶
【说明】
定义最后一级KLAD密钥信息结构体。
【定义】
/* content key: set n stage common route klad */
typedef struct {
ot_klad_alg_type alg; /* klad algorithm */
ot_klad_crypto_alg crypto_alg; /* allowed target engine algorithm. */
td_u32 key_size; /* klad key size */
td_u8 key[OT_KLAD_MAX_KEY_LEN]; /* klad key */
} ot_klad_content_key;
【成员】
【注意事项】
无。
【相关数据类型及接口】
ot_klad_clear_key¶
【说明】
定义明文密钥信息结构体。
【定义】
/* clear key: set clear route klad */
typedef struct {
ot_klad_crypto_alg crypto_alg; /* allowed target engine algorithm. */
td_u32 key_size; /* klad key size */
td_u8 key[OT_KLAD_MAX_KEY_LEN]; /* klad key */
} ot_klad_clear_key;
【成员】
【注意事项】
无。
【相关数据类型及接口】
OT_KLAD_MAX_KEY_LEN¶
【说明】
定义KLAD最大密钥长度。
【定义】
#define OT_KLAD_MAX_KEY_LEN 32
【注意事项】
无。
【相关数据类型及接口】
错误码¶
KLAD提供的错误码如下所示。
表 1 KLAD模块的错误码




