前言

概述

本文档主要描述了CIPHER DRIVER的结构及其软件接口的使用方法。

产品版本

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

产品名称

产品版本

WS63

V100

读者对象

本文档主要适用于以下工程师:

  • 技术支持工程师

  • 软件开发工程师

符号约定

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

符号

说明

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

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

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

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

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

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

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

修改记录

文档版本

发布日期

修改说明

02

2024-06-27

更新“使用流程”章节内容。

更新“错误类型”章节内容。

01

2024-04-10

第一次正式版本发布。

00B01

2024-03-29

第一次临时版本发布。

概述

功能描述

CIPHER DRIVER为安全算法模块,对外提供mbedtls API 和service layer两类接口,如图1所示。

  • mbedtls API

    • 安全驱动对接开源第三方mbedtls接口,可以通过调用mbedtls API使用硬件安全能力。

    • 对于硬件支持的规格,均完成mbedtls对接,硬化范围及API使用具体参考《WS63V100 TLS&DTLS 开发指南》。

  • service layer

    • 自研安全驱动接口,为上层业务提供直接使用硬件安全的能力,支持LiteOS/FreeRTOS/AliOS等OS环境,及flashboot/bootrom等无OS环境。

  • CIPHER DRIVER提供如下算法:

    • AES、SM4等对称加解密算法.

    • HASH、SM3及HASH-MAC、SM3-MAC摘要算法.

    • RSA、ECC、SM2签名验签、密钥协商、加解密,大数运算等非对称算法.

    • 硬件密钥管理.

    • 随机数算法.

    • FLASH在线解密.

    • 主要用于AIOT产品安全启动、安全存储、安全通讯等场景。

  • CIPHER DRIVER包括5个子模块:SPACC(symc、hash)、PKE、KM、TRNG、FAPC。

图 1 CIPHER DRIVER上下文关系图

SPACC

SPACC(Security Protocol Accelerator,安全协议加速器)模块实现了cipher对称加解密算法、HASH及HMAC摘要算法。

对称加解密算法

  • AES:支持ECB/CBC/CFB/OFB/CTR/CCM/GCM/CMAC/CBC_MAC共9种工作模式。其中:

    • CFB模式支持的加密数据位宽可为8/128bit。

    • OFB模式支持的加密数据位宽可为128bit。

    • CCM/GCM模式下,加解密结束后需获取一次TAG值。

    • ECB、CBC、CBC_MAC模式加密数据长度必须为16Byte对齐,CMAC允许最后一块加密数据长度非16Byte对齐。

    • 支持AES-128、AES-192、AES-256(128、192、256均指传入的密钥长度,单位为bit)。

  • SM4:支持ECB/CBC/CTR/CFB/OFB共5种工作模式。支持SM4-128;除CTR模式外,加密数据长度须为16Byte对齐。

cipher驱动支持软件多通道,各芯片可以根据自己需要在porting文件中配置;支持低功耗模式,默认开启低功耗;支持轮询和wait_event模式,若注册了wait func则走wait_event模式,否则走轮询模式。

说明: ECB模式属于非安全算法,不建议使用。

摘要算法

  • HASH:支持SHA1/SHA224/SHA256/SHA384/SHA512/SM3。

  • HMAC:支持HMAC-SHA1/HMAC-SHA224/HMAC-SHA256/HMAC-SHA384/HMAC-SHA512/HMAC-SM3。

HASH和HMAC支持中途传入非block size对齐的数据块;支持软件多通道,各芯片可以根据自己需要在porting文件中配置;支持低功耗模式,默认开启低功耗;支持轮询和wait_event模式,若注册了wait func则走wait_event模式,否则走轮询模式。HASH支持重试机制,即中间过程调用接口出错可重新调用该接口直至成功,而不需要从头开始整个计算流程,具体内容请参见《WS63V100 SECURITY DRIVER API manual》中uapi_drv_cipher_hash_start、uapi_drv_cipher_hash_update 和uapi_drv_cipher_hash_finish接口使用说明。

说明: SHA1/SHA224属于非安全算法,不建议使用。

PKE

PKE(Public Key Encryption,公钥加密),即非对称加解密算法。常用于文件的签名和验签,以及对对称密钥的加解密,主要包括以下算法:

  • RSA

    • 支持PKCS#1 v1.5和 PKCS#1 v2.1PSS两种模式的私钥签名和公钥验签。

    • 支持PKCS#1 v1.5 和 PKCS#1 v2.1OAEP两种模式的公钥加密和私钥解密。

    • 支持密钥位宽1024/2048/3072/4096。

  • ECC

    • 支持 RFC 5639-Brainpool P256/384/512r1、NIST FIPS 186-4 P192/224/256/384/521 和 RFC 8032-ED25519(即EDDSA)的私钥签名和公钥验签。

    • 支持密钥位宽192/224/256/384/512(521)。

  • SM2

    • 支持SM2公钥加密和私钥解密。

    • 支持SM2私钥签名和公钥验签。

  • 密钥协商

    • 支持RFC 5639-Brainpool P256/384/512r1、NIST FIPS 186-4 P192/224/256/384/521、RFC 7748-Curve25519/Curve448、 RFC 8032 - ED25519(即EDDSA)和SM2的公私钥对生成,及由给定的私钥生成其对应的公钥。

    • 支持RFC 5639-Brainpool P256/384/512r1、NIST FIPS 186-4 P192/224/256/384/521、RFC 7748-Curve25519/Curve448和SM2的密钥交换(ECDH)。

    • 支持192/224/256/384/512/521/1024/2048/3072/4096比特DH密钥协商。

  • 曲线上点的验证

    • 支持RFC 5639-Brainpool P256/384/512r1、NIST FIPS 186-4 P192/224/256/384/521和SM2的点是否在曲线上的验证。

  • 大数运算

    • 支持小于等于4096位的模加、模减、模乘、模逆、模幂和模运算。

    • 支持小于等于2048位的常规大数乘运算。

PKE支持低功耗模式,并默认开启低功耗。支持轮询和wait_event模式,若注册了wait func则走wait_event模式,否则走轮询模式。

说明: NIST FIPS 186-4 P192/224/256/384/521,PKCS#1 v1.5,RSA1024/2048,低于256比特的ECDH及低于2048bit的DH为不安全算法,不建议使用。

KM

KM是密钥管理模块,增加密钥安全强度,用于将key加载到keyslot中,供SPACC和Flash在线解密使用。支持硬件key和软件key;支持8个cipher keyslot通道和2个hmac keyslot通道。

TRNG

随机数获取模块,获取硬件产生的真随机数。

FAPC

通过fapc控制器,配置flash在线解密操作相关的参数。fapc支持配置4个region,支持region使用相同的IV值,flash在线解密使用AES-128-CTR算法。

使用流程

系统初始化时会主动调用uapi_drv_cipher_env_init完成CIPHER DRIVER基础的初始化环境配置,用户不需要再单独调用。

密钥配置

场景说明

生成和配置SPACC、在线解密模块所需要的软件key和硬件Key,软件key可由PBKDF2和HKDF算法生成。keyslot存放最终的软件或硬件key,供SPACC和在线解密使用。支持 AES 128/192/256bits加解密,支持HMAC。

软件密钥配置工作流程

  1. 调用uapi_drv_km_init初始化KM模块。

  2. 创建keyslot通道,FLASH在线解密不需要此操作,调用uapi_drv_keyslot_create接口完成。(若配置的key供SPACC模块调用,则该步骤在调用者调用SPACC模块接口绑定keyslot通道前完成)。

  3. 创建一路klad,并获取klad句柄。调用uapi_drv_klad_create接口完成。

  4. 绑定keyslot通道与klad句柄,调用uapi_drv_klad_attach接口完成。步骤2、步骤4的顺序可以调换。

  5. 配置klad属性。包含:

    • 密钥对应的root_key类型。

    • 密码可用于的算法。

    • 密钥可用于加密还是解密操作。

    • 密钥是安全还是非安全密钥。

    • 密钥是否仅可被配置该密钥的CPU使用。

    • 源和目的buffer类型是安全还是非安全(详见下方说明)。

    调用uapi_drv_klad_set_attr接口完成。

  6. 配置软件key,调用uapi_drv_klad_set_clear_key接口完成。SPACC

  7. 解绑keyslot与klad句柄,对于FLASH在线解密操作则是指定对应操作类型,调用uapi_drv_klad_detach接口完成。

  8. 销毁klad句柄,调用uapi_drv_klad_destroy接口完成。

  9. 销毁keyslot句柄,调用uapi_drv_keyslot_destroy接口完成。

  10. 调用uapi_drv_km_deinit去初始化KM模块。

    说明: klad配置的源和目的buffer类型与SPACC模块 buffer类型相对应,如果此处配置源数据buffer为仅支持安全buffer,而SPACC模块源buffer配置为非安全buffer,则计算过程中会报错。步骤9、步骤10的操作需要在SPACC、HMAC、FLASH在线解密使用完keyslot之后再执行,不然后导致计算报错。

硬件密钥配置工作流程

  1. 调用uapi_drv_km_init初始化KM模块。

  2. 创建keyslot通道,FLASH在线解密不需要此操作,调用uapi_drv_keyslot_create接口完成。(若配置的key供SPACC模块调用,则该步骤在调用者调用SPACC模块接口绑定keyslot通道前完成)。

  3. 创建一路klad,并获取klad句柄。调用uapi_drv_klad_create接口完成。

  4. 绑定keyslot通道与klad句柄,对于在FLASH线解密操作则是指定对应操作类型,调用uapi_drv_klad_attach接口完成。步骤2、步骤4的顺序可以调换。

  5. 配置klad属性。包含:

    • 密钥对应的root_key类型。

    • 密码可用于的算法。

    • 密钥可用于加密还是解密操作。

    • 密钥是安全还是非安全密钥。

    • 密钥是否仅可被配置该密钥的CPU使用。

    • 源和目的buffer类型是安全还是非安全(详见下方说明)。

    调用uapi_drv_klad_set_attr接口完成。

  6. 配置硬件key,调用uapi_drv_klad_set_effective_key接口完成。

  7. 解绑keyslot与klad句柄,对于FLASH在线解密操作则是指定对应操作类型,调用uapi_drv_klad_detach接口完成。

  8. 销毁klad句柄,调用uapi_drv_klad_destroy接口完成。

  9. 销毁keyslot句柄,调用uapi_drv_keyslot_destroy接口完成。

  10. 调用uapi_drv_km_deinit去初始化KM模块。

    说明:

    • klad配置的源和目的buffer类型与SPACC模块 buffer类型相对应,如果此处配置源数据buffer为仅支持安全buffer,而SPACC模块源buffer配置为非安全buffer,则计算过程中会报错。步骤9、步骤10的操作需要在SPACC、HMAC、FLASH在线解密使用完keyslot之后再执行,不然后导致计算报错。

    • 硬件key配置需要烧写对应efuse才可在keyslot通道中获得其对应的正确的工作key,否则此key用于计算得到的结果是错误的,具体efuse烧写过程请参见“1.2.16 安全相关efuse烧写建议”小节。

注意事项

硬件密钥配置依赖对应EFUSE,具体efuse烧写方式详见“安全相关efuse烧写建议”小节。

对称加解密

场景说明

对数据进行加密或解密,支持以下场景数据的加解密操作:

  • 源数据所在位置为DDR、RAM、flash。

  • 目的数据所在位置为DDR、RAM。

支持原地加解密操作,即输入和输出使用同一块buffer地址。

工作流程

  1. 调用uapi_drv_cipher_symc_init初始化SYMC模块

  2. 建一路symc,并获取symc句柄。调用uapi_drv_cipher_symc_create接口完成。

  3. 创建keyslot通道,调用uapi_drv_keyslot_create接口完成。

  4. 绑定keyslot通道与symc句柄。调用uapi_drv_cipher_symc_attach接口完成。keyslot通道创建可参考KEYSLOT&KLAD相关接口说明。

  5. 配置symc算法参数信息。包含:

    • 密钥基本属性(长度、奇偶属性)。

    • 初始向量。

    • 加解密位宽(CFB/OFB模式)。

    • 密钥更新方式(每次重新设置IV/使用上个数据包配置的IV)。

    • Additional Authenticated Data(GCM/CCM模式)。

    调用接口uapi_drv_cipher_symc_set_config接口完成。

  6. 对数据进行加解密。用户可以调用以下任一接口进行加解密。

    • 加密:uapi_drv_cipher_symc_encrypt

    • 解密:uapi_drv_cipher_symc_decrypt

  7. 如果是CCM、GCM模式,则需要继续调用uapi_drv_cipher_symc_get_tag接口获取TAG值,否则直接执行步骤8

  8. 解绑keyslot通道与cipher句柄,调用uapi_drv_cipher_symc_detach接口完成。

  9. 销毁symc句柄,调用uapi_drv_cipher_symc_destroy接口完成。

  10. 调用uapi_drv_cipher_symc_deinit去初始化SYMC模块

    说明: 步骤5配置好后,允许多包使用相同的配置信息,步骤6的操作可在此基础上连续进行。此时场景类似于步骤5配置IV更新方式为使用上个数据包配置的IV(CRYPTO_SYMC_CCM_IV_DO_NOT_CHANGE/UAPI_DRV_CIPHER_SYMC_GCM_IV_DO_NOT_CHANGE/UAPI_DRV_CIPHER_SYMC_CCM_IV_DO_NOT_CHANGE)的场景。

注意事项

  • 支持 AES ECB/CBC/CFB/OFB/CTR/CCM/GCM共7种模式。

    • 对于ECB/CBC/CFB/OFB/CTR模式,支持重试,即在调用uapi_drv_cipher_symc_encrypt/uapi_drv_cipher_symc_decrypt接口失败时,仍可配置正确参数后继续重新调用该接口,完成后续数据加解密。

    • 对于CCM/GCM模式支持重试,即在调用uapi_drv_cipher_symc_encrypt/uapi_drv_cipher_symc_decrypt或uapi_drv_cipher_symc_get_tag接口失败时,仍可配置正确参数后继续重新调用该接口,完成后续数据加解密。

  • 支持软件多通道。

    • 可同时进行多个数据加解密操作,即执行步骤2启动运算,在本次运算未完成(即未执行步骤8)之前,可申请一个新通道,启动另一个数据加解密运算,直到申请不到通道为止。

    • 最多支持的软件通道数,可由各芯片在porting文件中自己配置。

MAC值获取

场景说明

获取数据mac值,支持以下场景:源数据所在位置为DDR、RAM、flash。

工作流程

  1. 调用uapi_drv_cipher_symc_init初始化SYMC模块。

  2. 创建一路symc,并获取symc句柄,配置mac计算需要的参数信息。包含:

    • 密钥基本属性(长度、奇偶属性)。

    • 加解密位宽。

    • 使用的keyslot通道,keyslot通道创建可参考KEYSLOT&KLAD相关接口说明。

    调用uapi_drv_cipher_mac_start接口完成。

  3. 对数据进行加密,调用uapi_drv_cipher_mac_update接口完成(可调用一次或多次)。

  4. 获取MAC值,并销毁句柄,调用uapi_drv_cipher_mac_finish接口完成。

  5. 调用uapi_drv_cipher_symc_deinit接口,去初始化SYMC模块。

注意事项

  • 支持AES CBC_MAC 和 AES CMAC两种模式。

  • 支持软件多通道。

    • 可同时进行多个数据加解密操作。即执行步骤2启动运算,在本次运算未完成(即未执行步骤4)之前,可申请一个新通道,启动另一个数据加解密运算,直到申请不到通道为止。

    • 最多支持的软件通道数,可由各芯片在porting文件中自己配置。

HASH计算

场景说明

获取消息摘要,支持以下场景:源数据所在位置为DDR、RAM、flash。

工作流程

  1. 调用uapi_drv_cipher_hash_init初始化HASH模块。

  2. 创建一路hash,配置当前hash计算类型,并获取hash句柄。调用uapi_drv_cipher_hash_start接口完成。

  3. 传入消息数据,对消息进行摘要计算,调用uapi_drv_cipher_hash_update接口完成。

  4. 获取消息摘要,调用uapi_drv_cipher_hash_finish接口完成。

  5. 调用uapi_drv_cipher_hash_deinit去初始化HASH模块。

    说明: 步骤4如果成功会自己销毁hash句柄,不需要额外调用hash接口。步骤2启动成功后,无论后续步骤成功或失败,均可调用uapi_drv_cipher_hash_destroy接口销毁hash句柄(步骤4成功除外)。

注意事项

  • 在调用uapi_drv_cipher_hash_finish接口获取消息摘要时,传入的result buffer需要调用者申请,其大小为result_len,且result_len不应小于当前hash类型对应的摘要计算结果长度。

  • 支持多段数据连续update,结果与多段数据一次性update结果一致。

  • 支持hash clone操作,即通过uapi_drv_cipher_hash_get接口拷贝当前hash handle1信息,通过uapi_drv_cipher_hash_set接口设置至另一个hash handle2,由新的hash handle2继续完成后续计算操作。若hash handle1与hash handle2后续计算操作一致,则两者最终得到的hash摘要结果一致。

  • 支持重试,即在调用uapi_drv_cipher_hash_update/uapi_drv_cipher_hash_finish接口失败时,仍可配置正确参数后继续重新调用该接口,完成后续摘要计算操作。

HMAC计算

场景说明

依赖调用者传入的密钥数据,获取消息摘要,该密钥数据由消息交换双方提前协商好。支持以下场景:源数据所在位置为DDR、RAM、flash。

工作流程

  1. 调用uapi_drv_cipher_hash_init初始化HASH模块。

  2. 创建一路hash,配置当前hash计算类型和密钥所在keyslot通道,并获取hash句柄。调用uapi_drv_cipher_hash_start接口完成。

  3. 传入消息数据,对消息进行摘要计算,调用uapi_drv_cipher_hash_update接口完成。

  4. 获取消息摘要,调用uapi_drv_cipher_hash_finish接口完成。

  5. 调用uapi_drv_cipher_hash_deinit去初始化HASH模块。

    说明: 步骤4如果成功会自己销毁hash句柄,不需要额外调用hash接口。步骤2启动成功后,无论后续步骤成功或失败,均可调用uapi_drv_cipher_hash_destroy接口销毁hash句柄(步骤5成功除外)。

注意事项

在调用uapi_drv_cipher_hash_finish接口获取消息摘要时,传入的result buffer需要调用者申请,其大小为result_len,且result_len不应小于当前hash类型对应的摘要计算结果长度。

调用者传入的密钥数据,如果是明文密钥,则要求密钥长度不能大于当前hash类型的block_size大小,如果密钥长度大于当前hash类型的block_size大小,则需要调用者先对密钥进行hash计算,使得其长度小于block_size。如果是密文密钥,则密钥长度只能为16 bytes、24bytes或32 bytes。

RSA加解密

场景说明

RSA加解密应用场景为公钥加密私钥解密。

工作流程

  1. 公钥加密,调用uapi_drv_cipher_pke_rsa_public_encrypt接口完成。

  2. 私钥解密,调用uapi_drv_cipher_pke_rsa_private_decrypt接口完成。

    说明: 调用加密接口时,存储加密结果的buffer,其缓冲区大小不能小于密钥N的位宽。

注意事项

支持PKCS#1 v1.5 和 PKCS#1 v2.1 OAEP两种模式,且用户标签数据(label)可选,该label仅在PKCS#1 v2.1 OAEP模式下使用。PKCS#1 v1.5为不安全算法,不建议使用。

RSA签名验签

场景说明

RSA签名验签主要应用场景是私钥签名公钥验签。

工作流程

  1. 私钥签名,调用uapi_drv_cipher_pke_rsa_sign接口完成。

  2. 公钥验签,调用uapi_drv_cipher_pke_rsa_verify接口完成。

注意事项

支持 PKCS#1 v1.5和 PKCS#1 v2.1 PSS两种模式的私钥签名和公钥验签。PKCS#1 v1.5为不安全算法,不建议使用。

SM2加解密

场景说明

SM2加解密应用场景是公钥加密私钥解密。

工作流程

  1. 公钥加密,调用uapi_drv_cipher_pke_sm2_public_encrypt接口完成。

  2. 私钥解密,调用uapi_drv_cipher_pke_sm2_private_decrypt接口完成。

    说明: 加解密所需要的公私钥对可调用uapi_drv_cipher_pke_ecc_gen_key生成。

SM2签名验签

场景说明

SM2签名验签主要应用场景是私钥签名公钥验签。

工作流程

  1. 生成消息对应的hash摘要,调用uapi_drv_cipher_pke_sm2_dsa_hash接口完成。

  2. 私钥签名,调用uapi_drv_cipher_pke_ecdsa_sign接口完成。

  3. 公钥验签,调用uapi_drv_cipher_pke_ecdsa_verify接口完成。

    说明: 签名验签所需要的公私钥对可调用uapi_drv_cipher_pke_ecc_gen_key接口生成,可以调用uapi_drv_cipher_pke_check_dot_on_curve接口以确认公钥确实是曲线上的点。

ECC签名验签

场景说明

ECC签名验签主要应用场景是私钥签名公钥验签。

工作流程

  1. 生成消息对应的hash摘要,调用HASH/HMAC相应接口完成。

  2. 私钥签名,调用uapi_drv_cipher_pke_ecdsa_sign接口完成。

  3. 公钥验签,调用uapi_drv_cipher_pke_ecdsa_verify接口完成。

    说明: 签名验签所需要的公私钥对可调用uapi_drv_cipher_pke_ecc_gen_key接口生成,可以调用uapi_drv_cipher_pke_check_dot_on_curve接口以确认公钥确实是曲线上的点,签名需要先计算hash摘要,签名过程是对摘要进行签名。

注意事项

支持 RFC 5639 - Brainpool P256/384/512r1、NIST FIPS 186 - 4 P192/224/256/384/521的私钥签名和公钥验签。

EDDSA签名验签

场景说明

EDDSA签名验签主要应用场景是私钥签名公钥验签,是使用ed25519这种特殊曲线签名验签。

工作流程

  1. 私钥签名,调用uapi_drv_cipher_pke_eddsa_sign接口完成。

  2. 公钥验签,调用uapi_drv_cipher_pke_eddsa_verify接口完成。

    说明: 签名验签所需要的公私钥对可调用uapi_drv_cipher_pke_ecc_gen_key接口生成,可以调用uapi_drv_cipher_pke_check_dot_on_curve接口以确认公钥确实是曲线上的点,EDDSA签名不需要提前计算hash,直接传入消息进行签名即可。

注意事项

支持 RFC 8032 - ED25519的私钥签名和公钥验签。

大数运算

场景说明

大数运算主要用于非对称加解密和签名验签的计算过程。

工作流程

直接调用大数计算接口完成相应类型的大数计算即可,例如模加可直接调用uapi_drv_cipher_pke_add_mod接口完成。

ECDH 密钥协商

场景说明

密钥协商主要用于消息传递双方在生成各自的公私钥对之后进行密钥交换。

工作流程

  1. 消息传递者a生成自己的公私钥对,调用uapi_drv_cipher_pke_ecc_gen_key接口完成。

  2. 消息接收者b生成自己的公私钥对,调用uapi_drv_cipher_pke_ecc_gen_key接口完成。

  3. 密钥协商,消息传递者a/消息接收者b使用自己的私钥和对方的公钥生成共享密钥,调用uapi_drv_cipher_pke_ecc_gen_ecdh_key接口完成。

    说明:

    • 对于给定的私钥uapi_drv_cipher_pke_ecc_gen_key生成的公钥总是固定的;对于未给定私钥的情况下,uapi_drv_cipher_pke_ecc_gen_key生成的公私钥对是随机的。

    • 共享密钥生成后,消息传递者双方可对生成的共享密钥做比较,以验证共享密钥的正确性。

注意事项

  • 支持RFC 5639 - Brainpool P256/384/512r1、NIST FIPS 186 - 4 P192/224/256/384/521、RFC 7748 - Curve448/Curve25519、RFC 8032 - ED25519(即EDDSA)和SM2的公私钥对生成,及由给定的私钥生成其对应的公钥。

  • 支持RFC 5639 - Brainpool P256/384/512r1、NIST FIPS 186 - 4 P192/224/256/384/521、RFC 7748 - Curve448/Curve25519和SM2的密钥交换(ECDH),低于256bit的ECDH及NIST FIPS对应的曲线为不安全算法,不建议使用。

DH 密钥协商

场景说明

密钥协商主要用于消息传递双方在生成各自的公私钥对之后进行密钥交换,DH密钥协商用于非曲线类型。

工作流程

  1. 消息传递者a生成自己的公私钥对,调用uapi_drv_cipher_pke_dh_gen_key接口完成。

  2. 消息接收者b生成自己的公私钥对,调用uapi_drv_cipher_pke_dh_gen_key接口完成。

  3. 密钥协商,消息传递者a/消息接收者b使用自己的私钥和对方的公钥生成共享密钥,调用uapi_drv_cipher_pke_dh_compute_key接口完成。

    说明:

    • 对于给定的私钥uapi_drv_cipher_pke_dh_gen_key生成的公钥总是固定的;对于未给定私钥的情况下,uapi_drv_cipher_pke_dh_gen_key生成的公私钥对是随机的。

    • 共享密钥生成后,消息传递者双方可对生成的共享密钥做比较,以验证共享密钥的正确性。

注意事项

  • 支持192/224/256/384/512/521/1024/2048/3072/4096比特DH密钥协商,低于3072bits的DH为不安全算法,不建议使用。

FLASH在线解密

场景说明

由于运行在CPU上的OS和应用程序,都是加密且运行在FLASH上。所以,安全启动过程中, Boot需要配置OS镜像的FLASH在线解密。该模块主要暴露给boot使用,上层业务不使用。

工作流程

  1. 配置要执行在线解密操作的region及其对应flash区域的起始地址,调用drv_fapc_set_config接口完成。

  2. 配置在线解密操作使用的iv,调用drv_fapc_set_iv接口完成。

  3. 配置在线解密操作使用的key,详见“密钥配置”小节。

  4. 直接读取已配置在线解密操作的flash区域内容,读取结果即为解密之后的结果。

注意事项

FLASH在线解密使用的算法是AES_128_CTR,因此在使用该功能时,对应flash区域的加密方式也应是AES_128_CTR。

boot配置镜像的FLASH在线解密时,使用的root key类型由对应芯片自行选择。

安全相关efuse烧写建议

安全特性相关的efuse位较多,涉及到安全特性的正确使用,此处将逐一列出相关efuse及对应使用场景和烧写建议供参考,各项目根据具体需求及实际efuse排布表单进行合理配置。表1是OEM不同场景下使用的efuse,及其建议烧写阶段和建议烧写值。

表 1 安全特性efuse使用场景及烧写建议

使用场景

关键项

烧写阶段

烧写完是否需要lock

烧写方式及烧写值

安全启动

sec_verify_enable

OEM

Burntool烧写工具,根据是否开启安全启动功能确定。

mcu_ver

OEM

若支持防回滚功能,则通过Burntool烧写工具,根据实际情况烧写正确的镜像版本号信息。

flashboot_ver

OEM

若支持防回滚功能,则通过Burntool烧写工具,根据实际情况烧写正确的镜像版本号信息。

params_ver

OEM

若支持防回滚功能,则通过Burntool烧写工具,根据实际情况烧写正确的镜像版本号信息。

Hash_root_public_key

OEM

Burntool烧写工具,根公钥镜像HASH值。

MSID

OEM

Burntool烧写工具,市场ID。

安全驱动

otp_crc_rd_disable(KM)

OEM

Burntool烧写工具,根据是否保留CRC debug功能确定烧写值。

sha1_disable

OEM

Burntool烧写工具,根据是否关闭SHA1来确定。

rkp_deob_alg_sel

OEM

Burntool烧写工具,配置DEOB算法。

sm_disable

OEM

Burntool烧写工具,根据是否关闭国密来确定。

AES/SM4加解密,HMAC

obfu_mrk1_owner_id

OEM

Burntool烧写工具,16bit随机值。

obfu_mrk

OEM

Burntool烧写工具,128bit随机值,加解密和HMAC硬件密钥派生。

安全存储

obfu_rusk

OEM

Burntool烧写工具,128bit随机值,用于派生安全存储密钥。

错误码

说明: 本章描述了CIPHER DRIVER的错误码,便于开发人员理解与定位所发生的错误。

CIPHER DRIVER 错误码结构与说明

Cipher驱动返回值通常有成功和失败两种类型,如表1所示。

表 1 Cipher驱动返回值

成员名称

枚举值

CRYPTO_SUCCESS

0

CRYPTO_FAILURE

0xFFFFFFFF

为了通过错误码更加清晰的标识错误发生的具体信息,采用了层级结构信息拼接。其结构为:

Env(4 bits) | Layer(4 bits) | Modules(4 bits) | Reserved(12 bits) | Error Code(8 bits)

ENV

【描述】

错误码发生的操作系统环境。

【定义】

#define ERROR_ENV_LINUX         0x1 
#define ERROR_ENV_ITRUSTEE      0x2 
#define ERROR_ENV_OPTEE         0x3 
#define ERROR_ENV_LITEOS        0x4 
#define ERROR_ENV_SELITEOS      0x5 
#define ERROR_ENV_NOOS          0x6 

【成员】

成员名称

枚举值

ERROR_ENV_LINUX

LINUX

ERROR_ENV_ITRUSTEE

ITRUSTEE

ERROR_ENV_OPTEE

OPTEE

ERROR_ENV_LITEOS

LITEOS

ERROR_ENV_SELITEOS

SELITEOS

ERROR_ENV_NOOS

无OS环境

【注意】

LAYER

【描述】

错误码发生的代码层级。

【定义】

enum { 
    ERROR_LAYER_UAPI = 0x1, 
    ERROR_LAYER_DISPATCH, 
    ERROR_LAYER_KAPI, 
    ERROR_LAYER_DRV, 
    ERROR_LAYER_HAL, 
};

【成员】

成员名称

枚举值

ERROR_LAYER_UAPI

用户接口层

ERROR_LAYER_DISPATCH

指令分发层

ERROR_LAYER_KAPI

内核接口层

ERROR_LAYER_DRV

驱动逻辑层

ERROR_LAYER_HAL

硬件适配层

【注意】

MODULE

【描述】

错误码发生的CIPHER模块。

【定义】

enum { 
    ERROR_MODULE_SYMC = 0x1, 
    ERROR_MODULE_HASH, 
    ERROR_MODULE_PKE, 
    ERROR_MODULE_TRNG, 
    ERROR_MODULE_OTHER 
};

【成员】

成员名称

枚举值

ERROR_MODULE_SYMC

对称加解密模块

ERROR_MODULE_HASH

摘要算法模块

ERROR_MODULE_PKE

非对称加解密模块

ERROR_MODULE_TRNG

随机数模块

ERROR_MODULE_OTHER

其他模块

【注意】

错误类型

【描述】

错误码发生的具体错误类型。

【定义】

/* Common Error Code. 0x00 ~ 0x3F. */
ERROR_INVALID_PARAM = 0x0,      /* return when the input param's value is not in the valid range. */
ERROR_PARAM_IS_NULL,            /* return when the input param is NULL and required not NULL. */
ERROR_NOT_INIT,                 /* return when call other functions before call init function. */
ERROR_UNSUPPORT,                /* return when some configuration is unsupport. */
ERROR_UNEXPECTED,               /* reture when unexpected error occurs. */
ERROR_CHN_BUSY,                 /* return when try to create one channel but all channels are busy. */
ERROR_CTX_CLOSED,               /* return when using one ctx to do something but has been closed. */
ERROR_NOT_SET_CONFIG,           /* return when not set_config but need for symc. */
ERROR_NOT_ATTACHED,             /* return when not attach but need for symc. */
ERROR_NOT_MAC_START,            /* return when not mac_start but need for symc. */
ERROR_INVALID_HANDLE,           /* return when pass one invalid handle. */
ERROR_GET_PHYS_ADDR,            /* return when transfer from virt_addr to phys_addr failed. */
ERROR_SYMC_LEN_NOT_ALIGNED,     /* return when length isn't aligned to 16-Byte except CTR/CCM/GCM.  */
ERROR_SYMC_ADDR_NOT_ALIGNED,    /* return when the phys_addr writing to register is not aligned to 4-Byte. */
ERROR_PKE_RSA_SAME_DATA,        /* return when rsa exp_mod, the input is equal to output. */
ERROR_PKE_RSA_CRYPTO_V15_CHECK, /* return when rsa crypto v15 padding check failed. */
ERROR_PKE_RSA_CRYPTO_OAEP_CHECK,    /* return when rsa crypto oaep padding check failed. */
ERROR_PKE_RSA_VERIFY_V15_CHECK,     /* return when rsa verify v15 padding check failed. */
ERROR_PKE_RSA_VERIFY_PSS_CHECK,     /* return when rsa verify pss padding check failed. */
ERROR_PKE_RSA_GEN_KEY,          /* return when rsa generate key failed. */
ERROR_PKE_ECDSA_VERIFY_CHECK,   /* return when ecdsa verify check failed. */
/* Outer's Error Code. 0x40 ~ 0x5F. */
ERROR_MEMCPY_S      = 0x40,     /* return when call memcpy_s failed. */
ERROR_MALLOC,                   /* return when call xxx_malloc failed. */
ERROR_MUTEX_INIT,               /* return when call xxx_mutex_init failed. */
ERROR_MUTEX_LOCK,               /* return when call xxx_lock failed. */
/* Specific Error Code for UAPI. 0x60 ~ 0x6F. */
ERROR_DEV_OPEN_FAILED,          /* return when open dev failed. */
ERROR_COUNT_OVERFLOW,           /* return when call init too many times. */
/* Specific Error Code for Dispatch. 0x70 ~ 0x7F. */
ERROR_CMD_DISMATCH  = 0x70,     /* return when cmd is dismatched. */
ERROR_COPY_FROM_USER,           /* return when call copy_from_user failed. */
ERROR_COPY_TO_USER,             /* return when call copy_to_user failed. */
ERROR_MEM_HANDLE_GET,           /* return when parse user's mem handle to kernel's mem handle failed. */
ERROR_GET_OWNER,                /* return when call crypto_get_owner failed. */
/* Specific Error Code for KAPI. 0x80 ~ 0x8F. */
ERROR_PROCESS_NOT_INIT = 0x80,  /* return when one process not call kapi_xxx_init first. */
ERROR_MAX_PROCESS,              /* return when process's num is over the limit. */
ERROR_MEMORY_ACCESS,            /* return when access the memory that does not belong to itself.  */
ERROR_INVALID_PROCESS,          /* return when the process accesses resources of other processes. */
/* Specific Error Code for DRV. 0x90 ~ 0x9F. */
/* Specific Error Code for HAL. 0xA0 ~ 0xAF. */
ERROR_HASH_LOGIC    = 0xA0,     /* return when hash logic's error occurs. */
ERROR_PKE_LOGIC,                /* return when pke logic's error occurs. */
ERROR_INVALID_CPU_TYPE,         /* return when logic get the invalid cpu type. */
ERROR_INVALID_REGISTER_VALUE,   /* return when value in register is invalid. */
ERROR_INVALID_PHYS_ADDR,        /* return when phys_addr is invalid. */
/* Specific Error Code for Timeout. 0xB0 ~ 0xBF. */
ERROR_GET_TRNG_TIMEOUT = 0xB0,  /* return when logic get rnd timeout. */
ERROR_HASH_CLEAR_CHN_TIMEOUT,   /* return when clear hash channel timeout. */
ERROR_HASH_CALC_TIMEOUT,        /* return when hash calculation timeout. */
ERROR_SYMC_CLEAR_CHN_TIMEOUT,   /* return when clear symc channel timeout. */
ERROR_SYMC_CALC_TIMEOUT,        /* return when symc crypto timeout. */
ERROR_SYMC_GET_TAG_TIMEOUT,     /* return when symc get tag timeout. */
ERROR_PKE_LOCK_TIMEOUT,         /* return when pke lock timeout. */
ERROR_PKE_WAIT_DONE_TIMEOUT,    /* return when pke wait done timeout. */
ERROR_PKE_ROBUST_WARNING,    /* return when pke get robust warning. */

【成员】

类型

描述

COMMON

ERROR_INVALID_PARAM

输入参数在无效范围

ERROR_PARAM_IS_NULL

输入非法空指针参数

ERROR_NOT_INIT

未调用初始化函数

ERROR_UNSUPPORT

算法或配置未支持

ERROR_UNEXPECTED

预期之外的错误

ERROR_CHN_BUSY

通道均被占用时尝试创建通道

ERROR_CTX_CLOSED

尝试使用已关闭的CTX

ERROR_NOT_SET_CONFIG

SYMC未调用set_config函数

ERROR_NOT_ATTACHED

SYMC未绑定KEYSLOT

ERROR_NOT_MAC_START

SYMC未调用mac_start函数

ERROR_INVALID_HANDLE

传入了无效的handle

ERROR_GET_PHYS_ADDR

获取物理地址失败

ERROR_SYMC_LEN_NOT_ALIGNED

SYMC长度未对其到16Byte除了(CTR/CCM/GCM)模式

ERROR_SYMC_ADDR_NOT_ALIGNED

SYMC写到寄存器的物理地址没有按照4Byte对齐

ERROR_PKE_RSA_SAME_DATA

RSA模密运算时,输入和输出相等

ERROR_PKE_RSA_CRYPTO_V15_CHECK

RSA PKCSV15 解密 Padding校验失败

ERROR_PKE_RSA_CRYPTO_OAEP_CHECK

RSA OAEP 解密 Padding校验失败

ERROR_PKE_RSA_VERIFY_V15_CHECK

RSA PKCSV15 验签 Padding校验失败

ERROR_PKE_RSA_VERIFY_PSS_CHECK

RSA PSS 验签 Padding校验失败

ERROR_PKE_RSA_GEN_KEY

RSA 密钥生成失败

该功能暂不支持

ERROR_PKE_ECDSA_VERIFY_CHECK

ECDSA 验签失败

OUTER

ERROR_MEMCPY_S

调用memcpy_s失败

ERROR_MALLOC

调用xxx_malloc失败

ERROR_MUTEX_INIT

调用xxx_mutex_init失败

ERROR_MUTEX_LOCK

调用xxx_lock失败

SPECIFIC UAPI

ERROR_DEV_OPEN_FAILED

打开设备失败

ERROR_COUNT_OVERFLOW

调用太多次初始化

SPECIFIC DISPATCH

ERROR_CMD_DISMATCHED

CMD无匹配项

ERROR_COPY_FROM_USER

从用户态拷贝发生错误

ERROR_COPY_TO_USER

向用户态拷贝发生错误

ERROR_MEM_HANDLE_GET

获取句柄发生错误

ERROR_GET_OWNER

获取使用者发生错误

SPECIFIC KAPI

ERROR_PROCESS_NOT_INIT

进程未初始化

ERROR_MAX_PROCESS

数值超过了最大值

ERROR_MEMORY_ACCESS

没有该内存的访问权限

ERROR_INVALID_PROCESS

没有访问资源权限的进程访问了该资源

SPECIFIC HAL

ERROR_HASH_LOGIC

HASH发生硬件逻辑错误

ERROR_PKE_LOGIC

PKE发生硬件逻辑错误

ERROR_INVALID_CPU_TYPE

逻辑拿到了无效的CPU类型

ERROR_INVALID_REGISTER_VALUE

寄存器中的值是无效的

ERROR_INVALID_PHYS_ADDR

无效的物理地址

TIMEOUT

ERROR_GET_TRNG_TIMEOUT

获取随机数超时

ERROR_HASH_CLEAR_CHN_TIMEOUT

HASH清通道超时

ERROR_HASH_CALC_TIMEOUT

HASH计算超时

ERROR_SYMC_CLEAR_CHN_TIMEOUT

SYMC清通道超时

ERROR_SYMC_CALC_TIMEOUT

SYMC计算超时

ERROR_SYMC_GET_TAG_TIMEOUT

获取tag值超时

ERROR_PKE_LOCK_TIMEOUT

PKE锁超时

ERROR_PKE_WAIT_DONE_TIMEOUT

PKE计算超时

ERROR_PKE_ROBUST_WARNING

PKE鲁棒性告警

说明: security_unified对错误码进行了层级设计,方便debug时快速定位。用户调用service层接口时返回的错误的错误码不带层级信息,其错误含义与上述表格中的错误码一一对应,具体参见API手册security_unified模块错误码相关定义,错误码段为0x80001500~0x8001600.

网络安全注意事项

安全驱动

  • Cipher驱动实现了标准的对称加密AES/ SM4算法,非对称RSA、ECDSA/SM2/ED25519算法,摘要算法SHA/SM3/HMAC_SHA/SM3,密钥协商算法ECDH,密钥派生算法PBKDF2,没有使用任何私有算法。

  • 对称算法使用建议:

    • AES/SM4算法ECB模式为非安全算法,不建议使用。

    • 对称算法的密钥的长度越长,安全等级越高,建议用户使用AES 128bit及以上的密钥。

  • 非对称算法使用建议:

    • RSA算法建议使用密钥长度3072bit及以上的密钥。

    • RSA签名算法padding方式建议使用PSS padding方式。

    • RSA加解密算法padding方式建议使用OAEP padding方式。

    • ECDSA算法建议使用密钥长度256bit及以上的密钥。

    • ECDSA算法曲线不建议使用NIST P256/384/521曲线。

  • 摘要算法使用建议:

    • SHA1/SHA224算法安全性低,不建议用户使用。

    • SHA/HMAC_SHA算法建议使用SHA256/HMAC_SHA256及以上的算法。

  • 密钥协商算法使用建议:

    • ECDH算法建议使用密钥长度256bits及以上的密钥。

    • DH算法建议使用密钥长度3072bits及以上的密钥。

  • 密钥派生算法使用建议:

    • 迭代次数和安全性成正比例,也与计算时间成正比例,迭代次数越大,意味着计算密钥花费时间越长,同时抗暴力破解能力越强。对于性能不敏感或高安全性要求场景推荐迭代次数至少需要10000000次,其他场景迭代次数默认推荐至少10000次;对于性能有特殊要求的产品最低可以迭代1000次(NIST SP 800 132)。

    • 哈希函数推荐选择SHA256或更安全的哈希算法。

    • 盐值至少16Byte,应使用安全的随机数。

    • 用于口令单向哈希时,其输出长度应该不小于256bit。

其他使用安全注意事项

JTAG接口

恶意者可通过JTAG接口,篡改系统和配置,恶意破坏系统。

建议用户采用以下措施:

  • 产品出厂时,将JTAG接口从物理上删除。

  • 芯片提供JTAG disable功能,软件通过写EFUSE,可从芯片层面直接永久关闭JTAG。