面向汽车电子 MCU FAE 的密码学心智模型 | 芯片:CCFC3008PCSN | HSM 固件:V229_20260608 目标:把算法按「能干什么」归类,建立心智模型,不要求手算。 本笔记中所有「3008PCSN 是否支持 / 怎么调」均来自固件源码 hsm_common_type.h / hsm_srv_type.h 的枚举定义,非臆造。
0. 先记住一张总表(心智模型的骨架)
密码学只解决四类问题,对应四类算法。这是整个 HSM 学习的地基:
|--------------------|------------|-----------------------|------------------------------------|
| 要解决的问题 | 用什么技术 | 代表算法 | 3008PCSN 固件里的枚举 |
| 机密性(只给该看的人看) | 对称加密 | AES、SM4 | hsmCipherAlgo_t:AES / SM4 |
| 完整性(没被篡改) | 哈希 / MAC | SHA-256、SM3、CMAC、HMAC | hsmHashAlgo_t / hsmMacAlgo_t |
| 真实性(确实是声称的发送方) | MAC / 数字签名 | HMAC、ECDSA、SM2 签名 | hsmMacAlgo_t / hsmSignScheme_t |
| 不可否认性(发过不能抵赖) | 数字签名 | RSA 签名、ECDSA、SM2 签名 | hsmSignScheme_t |
记忆锚点:机密性用对称,身份用非对称,完整性用哈希/MAC,随机数是地基。
一条重要认知(对应 AUTOSAR 加密栈文档结论):算法本身不解决"安全",算法只提供"密码服务"。用对算法、管好密钥、选对模式,安全才成立。阶段 1 只解决「算法怎么归类、怎么选」,密钥管理在阶段 3。
1. 对称加密(Symmetric Encryption)------ 解决机密性
1.1 是什么
一把钥匙既能锁又能开(加密解密用同一把密钥)。速度快,适合加密大量数据,但密钥分发困难(双方要先安全共享同一把钥)。
1.2 3008PCSN 支持什么(来自 hsmCipherAlgo_t)
|---------|---------------------|----------------|-------------|
| 算法 | 密钥长度 | 块大小 | 说明 |
| AES | 128 / 192 / 256 bit | 128 bit(16 字节) | 国际标准,车规最常用 |
| SM4 | 128 bit | 128 bit(16 字节) | 国密标准,国内项目必用 |
1.3 五种分组模式(来自 hsmCipherBlockMode_t)------ 重点,最易踩坑
先理解一个前提:分组密码一次只能"搅拌" 16 字节
AES/SM4 本身是一个"块加密器":一次只能处理固定的 16 字节(一个"块"),而且同样的明文 + 同样的钥匙,永远出同样的密文。
所以加密一大段数据时,要把它切成很多 16 字节的块。问题是:这些块之间怎么"搅拌",才能不泄露规律? 这就是"分组模式"要解决的。五种模式的区别,本质就是"每一块加密时,掺入了什么额外的料"。
核心概念:密钥流(keystream) = 一串看似随机的字节,用来和明文做异或(⊕)得到密文。CTR/CFB/OFB 三种模式都是"先造密钥流、再用密钥流 ⊕ 明文",所以它们不需要填充。记住这个词,下面很多地方用它。
① ECB(Electronic Codebook,电子密码本)------ 最简单,也最危险
做法 :每一块都用同一把钥匙独立加密,块与块之间没有任何联系。
明文块1 →[加密]→ 密文块1
明文块2 →[加密]→ 密文块2 (两者互不影响)
类比 :把一段英文逐词替换成密码词,同一个词永远替换成同一个密词。比如 "attack at dawn, attack again",两个 "attack" 会变成两个一模一样的密文,敌人一看就知道有重复、能猜出结构。
致命缺点 :相同明文块 → 相同密文块,明文的重复模式原样暴露在密文里。经典案例:把一张 BMP 企鹅图用 ECB 加密,结果企鹅的轮廓依然清晰可见。
结论 :只在加密"单个 16 字节的随机数据"(比如加密一把密钥本身)时能用;加密任何有规律的数据都别用。
② CBC(Cipher Block Chaining,密码块链接)------ 经典通用方案
做法 :第 N 块明文,先和"第 N-1 块的密文 "做异或,再加密。第一块没有"上一块密文",就用 IV 顶上。
明文块1 ⊕ IV →[加密]→ 密文块1
明文块2 ⊕ 密文块1 →[加密]→ 密文块2 (链式,一块扣一块)
类比:多米诺骨牌------每块的结果都取决于前一块,改任意一块,后面全部连锁改变。
好处:同样的明文块,因为"前面那块的密文"每次不同,加密结果也不同,重复模式被抹掉了。
代价:
- 只能串行(一块算完才能算下一块,不能并行加速);
- 长度必须正好是 16 字节的整数倍,否则应用层要自己补 padding(如 PKCS#7)。
用途:经典通用方案,加密存储、文件加密常用。
③ CTR(Counter,计数器)------ 不搅拌明文,改搅拌计数器(变相流密码)
做法 :不直接加密明文 。而是拿一个"计数器"(从 IV 开始,每块 +1)去加密,加密结果是密钥流,再用密钥流去 ⊕ 明文。解密时用同样的计数器算出同样的密钥流,⊕ 密文还原。
计数器 →[加密]→ 密钥流1 ⊕ 明文块1 = 密文块1
计数器+1 →[加密]→ 密钥流2 ⊕ 明文块2 = 密文块2
类比:先造一把"一次性的乱码尺子",用这把尺子去盖在明文上。
好处:
- 不需要填充(明文多长就盖多长,密文长度 = 明文长度);
- 可并行(每块的密钥流独立,可同时算);
- 可随机访问(想解密第 N 块,直接用 counter+N 算出那段密钥流即可,不用从头算)。
致命前提 :同一把钥匙下,计数器绝不能重复------一旦重复,两段密文异或就直接泄露两段明文的异或结果(后面 1.4 详讲)。
用途 :性能敏感、随机访问存储;GCM 认证加密内部就是用它(所以 GCM 也忌讳 nonce 重复)。
④ CFB(Cipher Feedback,密文反馈)------ 流式,逐字节加密
做法 :把"上一块密文"喂回加密器,得到密钥流,再 ⊕ 明文。第一块用 IV 顶上。
IV →[加密]→ 密钥流1 ⊕ 明文块1 = 密文块1
密文块1 →[加密]→ 密钥流2 ⊕ 明文块2 = 密文块2
和 CBC 的区别 :CBC 是把"前块密文"拿去和明文异或 ;CFB 是把"前块密文"拿去生成密钥流。
好处 :不需要填充,适合流式------固件支持 1 / 8 / 16 / 32 / 64 / 128 bit 的流宽度(hsmCipherStreambits_t),能逐字节甚至逐位加密。
代价:串行。
小知识:CFB 的"解密"其实用的也是"加密"运算(只是 ⊕ 方向反一下),硬件实现能省一半电路。
⑤ OFB(Output Feedback,输出反馈)------ 密钥流可提前算好
做法 :把"上一轮加密器的输出"(而不是密文)喂回加密器,得到密钥流,再 ⊕ 明文。
IV →[加密]→ 密钥流1 ⊕ 明文块1 = 密文块1
密钥流1 →[加密]→ 密钥流2 ⊕ 明文块2 = 密文块2
关键特点 :密钥流只取决于 IV 和钥匙,完全不依赖明文/密文 。所以密钥流可以提前算好存着,等数据来了直接 ⊕,省时间。
好处:不需要填充;密钥流可预计算。
代价:串行;IV 一旦重复,和 CTR 一样致命(两段密文异或 → 泄露明文异或)。
五种模式速记表(收口)
|-----|---------------|-------|----|---------------|
| 模式 | 核心机制 | 需填充 | 并行 | 致命禁忌 |
| ECB | 各块独立 | 是 | 能 | 相同明文泄露,勿用 |
| CBC | 前块密文 ⊕ 明文再加密 | 是 | 否 | IV 需随机不可预测 |
| CTR | 计数器造密钥流 ⊕ 明文 | 否 | 能 | 计数器不可重复 |
| CFB | 前块密文造密钥流 ⊕ 明文 | 否 | 否 | 串行 |
| OFB | 前轮输出造密钥流 ⊕ 明文 | 否 | 否 | IV 不可重复 |
工程经验:要加密可变长数据、追求性能,用 CTR(或直接上 GCM) ;要兼容老系统/加密存储,用 CBC ;ECB 只用于加密单块随机密钥。CFB/OFB 在车规里用得少,知道原理即可。
1.4 IV / Nonce(初始化向量)------ 它是什么、谁来保证不重复
IV 是干嘛的
给链式/流式模式一个"起点":让同样的钥匙 + 同样的明文,每次加密出不同的密文 。IV 本身不需要保密 (可以明文传输),但绝不能在同一把钥匙下重复使用。
先厘清:"应用层"是谁?
这里容易绕晕,先定死概念:"应用层"指的是主核(z425n3/z710n3 应用核)上跑的客户软件,不是 HSM。
在 3008PCSN 里,客户自己的协议栈、App 代码、调度逻辑,全都跑在主核 ;HSM 是独立的 HSN 安全核,只被动接收请求、返回结果。所以"IV 防重入是应用层的责任"翻译过来就是:
发起加密的那一方(主核上的客户软件),负责每次给 HSM 送一个不重复的 IV;HSM 只照你给的 IV 去算,不帮你判断"这个 IV 是不是用过了"。
类比:HSM 是"保险柜里的计算器",主核是"柜外填单子的人"。填单子的人每次要写新的"流水号"(IV),计算器只负责按单子算,它不查"这个流水号上个月是不是用过"。
关键问题:HSM 会自动生成 IV 吗?会校验 IV 重复吗?
答案:都不会。 依据固件源码(已核实):
hsmSymCipherSrv_t结构体里pIV字段的注释是INPUT(输入) ------IV 是应用层通过指针传进来的;
- 服务层
hsm_crypto.c里,只是把srvReq->pIV原样传给CRYPTO_FRM_Aes*底层函数,再写进硬件引擎的 IV 寄存器(AES_IV0~IV3)。没有任何"IV 去重""IV 历史记录"的机制;
- 随机数服务
HSM_SRV_GetTRNGNumber()是独立服务 ,加密服务不会自动调它来生成 IV。
⚠️ 别误会:HSM 有随机数生成器 ≠ 加密会自动生成 IV。 你说得对,HSM 固件确实带真随机数生成器 ------硬件 TRNG(基址
0xA3F80000),对应服务HSM_SRV_GetTRNGNumber()。但这里要分清"能力 "和"流程":
- IV 的"值" :推荐就是随机数------应用层先调
GetTRNGNumber()取一段真随机数,再把它当 IV 用;
- IV 的"产生动作" :必须应用层显式走完"取随机数 → 填
pIV指针 → 调加密服务"三步。加密服务内部不会偷偷调 TRNG 帮你填 IV。所以两条都对、不冲突:IV 通常"是"随机数 (值来自 TRNG),但IV 不是加密服务"自动"生成的(要应用层自己去取、去传)。换句话说------TRNG 是 HSM 的"能力",但"加密时用不用随机 IV、怎么取"是应用层决定的"流程"。
为什么 HSM 校验不了重复? 因为"重复"是相对"同一把钥匙 + 历史上所有会话"而言的。HSM 要校验,就得永久记住这把钥匙用过的所有 IV------掉电就丢、资源也不允许,工程上做不到也没必要。
那怎么保证 IV 不重复?------ 责任在应用层,两种主流做法
|----------------|--------------------------------------------------|------------------------------------------------------|
| 做法 | 怎么做 | 适用场景 |
| 随机 IV(最常用) | 每次加密前,应用层调 HSM_SRV_GetTRNGNumber() 取一段真随机数当 IV | 通用;GCM 推荐 96-bit nonce,碰撞概率低到可忽略(要加密约 2^48 次才可能撞一次) |
| 单调计数器 | 用严格递增的计数器当 IV/nonce,同一钥匙下绝不回头 | "固定会话密钥 + 海量报文"场景(如 SecOC 的 freshness 值) |
一句话给客户 :IV 防重入是应用层协议设计 的责任,HSM 只"照你给的 IV 去算",它既不会拦、也拦不住你传重复的 IV。FAE 要盯住客户:别用固定 IV、别用可预测的 IV(比如简单递增但攻击者能推算的),用 TRNG 或严格计数器。
应用层具体怎么设计 IV 防重?(两条路线 + 一个关键边界)
关键边界先记住 :IV 不重复,是**针对"同一把钥匙"**而言的。换一把新钥匙,IV 就可以从头再来。
路线一:随机 IV(最常用)
- 每次加密前,主核调
HSM_SRV_GetTRNGNumber()取一段真随机数当 IV;
- 原理:真随机的碰撞概率低到可忽略------GCM 96-bit nonce 要加密约 2⁴⁸ 次才可能撞一次;
- 优点:简单、无需维护状态;缺点:纯随机在极端海量报文下仍有极小理论碰撞可能。
路线二:单调计数器(数学上绝对不重)
- 主核维护一个严格递增的计数(或单调时间戳),每次加密 +1,同一把钥匙下绝不回头;
- 原理:数学上保证"这把钥匙的这辈子,每个值只用一次";
- 优点:零碰撞;缺点:要持久化计数(掉电不能丢、不能回滚)。
工程上的最优组合 :"会话密钥 + 会话内计数器" ------每次会话先用 TRNG/密钥协商生成一把新的会话密钥 ,会话内用计数器当 IV。这样既绝对防重、又不需要长期维护全局计数。
车规实例:SecOC 的 freshness value(新鲜度值)就是"会话内单调计数器"的落地------每条安全报文带一个递增的 freshness,配合 MAC 防重放,收发双方各维护一份。
1.5 在固件里怎么对应
hsmSymCipherSrv_t 结构体:cipherAlgo(AES/SM4)+ cipherBlockMode(五种模式)+ cipherDir(加密/解密)+ keyHandle + pIV + pInput/pOutput。一次加密 = 填好这个结构体 → 调 HSM_SRV_SymCipher()。
2. 哈希(Hash)------ 解决完整性的"无密钥"版
2.1 是什么
把任意长度 输入,压缩成固定长度的"指纹"。特点:
- 单向:从指纹推不回原文;
- 抗碰撞:找不到两段不同内容产生同一指纹;
- 雪崩:改一个 bit,指纹天翻地覆。
2.2 3008PCSN 支持什么(来自 hsmHashAlgo_t)
|-----------------------------|-------------|--------------------|
| 算法 | 输出长度 | 备注 |
| SHA-256 | 32 字节 | 车规/国际最常用 |
| SHA-224 / SHA-384 / SHA-512 | 28/48/64 字节 | SHA-2 家族其他档位 |
| SM3 | 32 字节 | 国密哈希,与 SM2/SM4 配套 |
| SHA-1 | 20 字节 | 已不安全,仅兼容遗留 |
| MD5 / SHA0 / RIPEMD160 | --- | 仅兼容遗留,勿用于新设计 |
| SHA3-224/256/384/512 | --- | 枚举里存在(固件软实现,非硬件加速) |
2.3 用途
- 完整性校验(文件/固件有没有被改);
- 作为签名前的预处理(签名其实是对"哈希值"签,见第 7 节);
- 安全启动里计算固件镜像摘要。
哈希 vs MAC (最易混,见第 11 节):哈希无密钥,谁都能算,只能证明"没被意外损坏";不能证明"没被恶意篡改"(攻击者改了内容可以重算哈希)。要证明恶意篡改,用 MAC。
2.4 在固件里怎么对应
hsmHashSrv_t 结构体:hashAlgo + pInput/inputLength + pHash。调 HSM_SRV_Hash()。
3. MAC(消息认证码)------ 解决完整性 + 真实性的"带密钥"版
3.1 是什么
哈希 + 密钥 = MAC。只有持钥方才能算出正确的 MAC,所以能证明"消息来自持钥方、且没被篡改"。
3.2 3008PCSN 支持什么(来自 hsmMacAlgo_t)
|----------|---------------|---------------------------|
| MAC | 底层 | 说明 |
| CMAC | 基于 AES | 车规最常见(SHE 协议、安全启动验签常用) |
| HMAC | 基于哈希(SHA-2 等) | 通用,hsmHmacScheme_t 指定哈希 |
| GMAC | GCM 的认证部分 | 只认证不加密,常用于只保完整性不保密的场景 |
3.3 生成 vs 验证
MAC 服务有两个方向(hsmAuthDir_t):
- GENERATE:发送方算出 tag,附在消息后;
- VERIFY:接收方重算 tag 并比对,一致则消息可信。
3.4 在固件里怎么对应
hsmMacSrv_t 结构体:macScheme(CMAC/HMAC/GMAC)+ authDir(生成/验证)+ keyHandle + pInput + pTag。调 HSM_SRV_Mac()。
4. AEAD(认证加密)------ 机密性 + 完整性一步到位
4.1 是什么
"认证加密":一次操作同时完成加密 + 认证。传统做法是"先加密再算 MAC"(Encrypt-then-MAC)两步走,AEAD 把它合成一个标准原语,避免手工组合出错。
这里的"认证"到底指什么?
"认证"(Authentication)= 证明"这串数据没被改过、且确实来自持有密钥的对方"。 注意:这不是"登录认证"(输密码验身份),而是消息认证------给一段数据盖一个"防伪戳"。
- 加密 解决"别人看不到"(机密性);
- 认证 解决"别人没动手脚"(完整性 + 真实性)。
什么情况需要认证? 只要你在意"数据有没有被篡改、是不是对方发的"。车规最典型是 CAN 报文认证(SecOC):攻击者不一定要偷看报文内容,他只要篡改一个信号、或重放一段旧报文就能造成事故------认证就是防这个的。
认证具体做什么? 发送方用密钥对数据算出一个"标签(tag)"附在后面;接收方用同一把钥匙重算一遍,比对一致就认定"没被改、是对方发的"。
AEAD 为什么一步到位? 传统要"先加密、再单独算 tag"两步,容易组合错(先加密还是先算 MAC 的顺序都有讲究);AEAD(GCM/CCM)把两者合成一个标准操作,一次调用同时保证"机密 + 完整"。
4.2 3008PCSN 支持什么(来自 hsmAuthCipherMode_t,仅 AES)
|---------|------|---------|--------------|
| AEAD | 加密方式 | 认证方式 | 说明 |
| GCM | CTR | GHASH | 车规首选,速度快、可并行 |
| CCM | CTR | CBC-MAC | 资源受限场景,速度慢些 |
4.3 三个关键参数
- Nonce/IV:绝不能重复(GCM 重 nonce 是灾难);
- AAD(Additional Authenticated Data):只认证、不加密的关联数据(如报文头、地址);
- Tag:认证标签,解密时用于验真。
车规典型场景:SecOC 报文认证、诊断服务安全访问。GCM 的 tag 常用 12/16 字节。
4.4 在固件里怎么对应
hsmAeadSrv_t 结构体:authCipherMode(GCM/CCM)+ keyHandle + pIV/ivLength + pAad/aadLength + pInput + pTag/tagLength + pOutput。调 HSM_SRV_Aead()。
5. 非对称密码(Asymmetric)------ 解决密钥分发 + 身份
5.1 是什么
两把不同的钥匙:公钥公开、私钥保密。用公钥加密的只能用私钥解;用私钥签名的只能用公钥验。速度慢(比对称慢几个数量级),但天然解决"密钥怎么安全分发"。
5.2 3008PCSN 支持什么
|---------|---------------|-------------------------------|-----------------------------------------------------|
| 算法 | 基于的数学难题 | 密钥长度 | 用途 |
| RSA | 大整数分解 | 1024 / 2048 / 3072 / 4096 bit | 加解密(RSAES-OAEP/PKCS1-v1.5)、签名(RSASSA-PKCS1-V15/PSS) |
| ECC | 椭圆曲线离散对数 | 256 / 384 / 521 bit | ECDSA 签名;曲线:SECP256R1/384R1/521R1、Brainpool 系列 |
| SM2 | 椭圆曲线(国密曲线) | 256 bit | 加解密 + 签名(国密首选) |
| Ed25519 | 椭圆曲线(Edwards) | 256 bit | CONFIG_ALG_ED25519=0,本固件已关闭 |
核心洞察(密钥配送问题的解法) :对称加密的痛点是"双方先安全共享一把钥";非对称用"公钥公开"解决------任何人都能用公钥给 A 加密,只有 A 的私钥能解。所以工程上:非对称做签名/密钥协商,对称做海量数据加密,这叫混合密码系统。
5.3 在固件里怎么对应
- 加解密:
hsmRsaCipherSrv_t(RSA)/hsmSm2CipherSrv_t(SM2),调HSM_SRV_RsaCipher()/HSM_SRV_Sm2Cipher();
- 密钥对生成:
hsmKeyGenerateSrv_t+hsmKeyGenScheme_t(RSA/ECC/SM2 密钥对),调HSM_SRV_KeyGenerate()。
6. 数字签名(Signature)------ 解决真实性 + 不可否认性
6.1 是什么,方向别记反(最关键的一条)
- 签名 :签名者用自己的私钥签(私钥只有他有);
- 验签 :验证方用签名者的公钥验(公钥公开分发)。
口诀:加密怕人看(用对方公钥加密),签名怕人假冒(用自己私钥签名)。 方向完全相反。
对应到安全启动:OEM 用私钥给固件签名,芯片里只烧 OEM 公钥用来验签------私钥永不进芯片,所以拆解芯片也伪造不了签名。
6.2 为什么签名之前先哈希
直接对整段固件做非对称运算太慢。实际流程是:先算固件的哈希值(第 2 节),再用私钥对这个哈希值签名。验签时:重算哈希 + 用公钥验签名,两者都对才通过。
6.3 3008PCSN 支持什么(来自 hsmSignScheme_t)
|----------------------|-----------------------------------------------------|
| 签名方案 | 说明 |
| SM2 签名 | 国密签名(HSM_SIGN_SM2) |
| ECDSA | 椭圆曲线签名(HSM_SIGN_ECDSA,配套 hsmEcdsaScheme_t 指定哈希) |
| RSASSA-PKCS1-V15 | RSA 经典签名(HSM_SIGN_RSASSA_PKCS1_V15) |
| RSASSA-PSS | RSA 更安全的签名(HSM_SIGN_RSASSA_PSS,带 salt) |
6.4 在固件里怎么对应
hsmSignSrv_t 结构体:signScheme + authDir(生成/验证)+ keyHandle + pInput/inputLength + pSignature。调 HSM_SRV_Sign()。
7. 非对称的"加密 vs 签名"两种用途对照(收口)
RSA/SM2/ECC 既能加密又能签名,方向不同,一张表收口:
|----------|-------------------------------------------|------------------|
| | 加密/解密 | 签名/验签 |
| 用谁的钥加密/签 | 用对方公钥加密 | 用自己私钥签名 |
| 用谁的钥解密/验 | 用自己私钥解密 | 用对方公钥验签 |
| 解决什么 | 机密性(内容不泄露) | 真实性 + 不可否认(来源可信) |
| 固件服务 | HSM_SRV_RsaCipher / HSM_SRV_Sm2Cipher | HSM_SRV_Sign |
8. 随机数(RNG)------ 一切安全的地基
8.1 是什么
- TRNG(真随机):基于物理熵源(电路噪声/抖动),不可预测;
- PRNG(伪随机):确定性算法从种子展开,可预测但快。
8.2 用途
会话密钥、IV/Nonce、challenge(质询)、SHE 协议随机数------几乎每个密码操作都离不开随机数。
8.3 在固件里怎么对应
hsmGetRandomNumSrv_t:randomNumLength(必须是 4 字节整数倍 )+ pRandomNum。调 HSM_SRV_GetTRNGNumber()(真随机)/ HSM_SRV_GetPRNGNumber()(伪随机)。
随机数服务的输出,最常见的消费场景之一就是当 IV/Nonce :应用层
GetTRNGNumber()取一段真随机数 → 填进加密服务的pIV指针 → 再调HSM_SRV_SymCipher()。注意是两步、两个服务,不是加密服务里自动完成(详见 §1.4)。
9. 密钥派生(KDF)------ 从一把主钥派生子钥
9.1 是什么
从一把主密钥(Master Key)按规则派生出多把子密钥,实现"一钥多用途、子钥互不关联"。
9.2 3008PCSN 支持什么(来自 hsmKdfType_t)
固件当前只定义了 SHE KDF (HSM_KDF_TYPE_SHE),参数结构体 hsmKdfSheScheme_t:mainkey + salt + saltlen。调 HSM_SRV_KeyDerive()。
这也是 SHE 规范里的密钥派生(配合 M1M2M3 协议用,阶段 3 详讲)。
10. 3008PCSN 固件「算法 → 服务」总对照表(本阶段最有价值的一张表)
|---------|-------------------------------------------|------------------------|-------------------------------------------------------------------------|
| 能力 | 固件服务(API) | 关键结构体 | 关键枚举 |
| 哈希 | HSM_SRV_Hash | hsmHashSrv_t | hsmHashAlgo_t(SHA-256/SM3...) |
| 对称加密 | HSM_SRV_SymCipher | hsmSymCipherSrv_t | hsmCipherAlgo_t(AES/SM4)+ hsmCipherBlockMode_t(ECB/CBC/CTR/CFB/OFB) |
| MAC | HSM_SRV_Mac | hsmMacSrv_t | hsmMacAlgo_t(CMAC/HMAC/GMAC) |
| AEAD | HSM_SRV_Aead | hsmAeadSrv_t | hsmAuthCipherMode_t(GCM/CCM) |
| 签名/验签 | HSM_SRV_Sign | hsmSignSrv_t | hsmSignScheme_t(SM2/ECDSA/RSA-PSS/RSA-PKCS1V15) |
| RSA 加解密 | HSM_SRV_RsaCipher | hsmRsaCipherSrv_t | hsmRsaAlgo_t(NO_PADDING/OAEP/PKCS1_V15) |
| SM2 加解密 | HSM_SRV_Sm2Cipher | hsmSm2CipherSrv_t | hsmSm2Algo_t(CIPHER/SIGN) |
| 随机数 | HSM_SRV_GetTRNGNumber / GetPRNGNumber | hsmGetRandomNumSrv_t | --- |
| 密钥派生 | HSM_SRV_KeyDerive | hsmKeyDeriveSrv_t | hsmKdfType_t(SHE) |
| 密钥生成 | HSM_SRV_KeyGenerate | hsmKeyGenerateSrv_t | hsmKeyGenScheme_t(对称随机/RSA/ECC/SM2 密钥对) |
上表所有枚举名、结构体名都能在固件
hsm_common_type.h/hsm_srv_type.h/hsm_interface.h里直接 grep 到,阶段 3 会逐个深挖参数细节。
11. 三组最易混淆的关系(务必主动澄清)
11.1 对称 vs 非对称
|------|------------|----------------|
| | 对称 | 非对称 |
| 密钥 | 一把(加解密同钥) | 一对(公钥+私钥) |
| 速度 | 快(适合大数据) | 慢(慢几个数量级) |
| 密钥分发 | 难(要先安全共享) | 易(公钥公开) |
| 典型用途 | 海量数据加密、MAC | 签名、密钥协商、小数据加解密 |
| 代表 | AES、SM4 | RSA、ECC、SM2 |
11.2 哈希 vs MAC
|-------|-------------|----------------|
| | 哈希 | MAC |
| 有无密钥 | 无 | 有 |
| 谁都能算? | 是 | 否(仅持钥方) |
| 防什么 | 意外损坏 | 恶意篡改 |
| 代表 | SHA-256、SM3 | CMAC、HMAC、GMAC |
一句话:哈希证明"没变",MAC 证明"没被人改过 + 确实来自持钥方"。
11.3 加密 vs 认证 vs 签名(最容易绕晕的一组)
三个东西解决三个不同的问题,务必分开:
|-----------|-----------------------|---------------------|----------------------|
| | 加密 | 认证(MAC) | 签名 |
| 解决什么 | 机密性(怕人看) | 完整性 + 真实性(怕人改、怕人冒充) | 真实性 + 不可否认(证明是某人发的) |
| 用谁的钥 | 对方公钥加密 / 自己私钥解 | 双方共享同一把对称钥 | 自己私钥签 / 对方公钥验 |
| 谁能验证 | 只有收件人(持私钥) | 只有通信双方(共享钥) | 任何人(公钥公开) |
| 能证明"谁发的"吗 | 不能 | 能,但只有对方能证 | 能,且全世界都能证 |
| 代表 | AES / SM4 / RSA / SM2 | CMAC / HMAC / GMAC | ECDSA / SM2 / RSA 签名 |
一句话收口:加密 = 锁进只有收件人能开的箱子(怕人看);认证(MAC) = 盖个双方才知道的暗号戳(证明没被改、是对方发的);签名 = 盖个全世界都能验证的私章(证明就是某人发的,赖不掉)。
附:签名不是加密(纠正一个经典误区)
历史上确有"签名 = 用私钥加密"的说法,因为 RSA 这个算法特殊------它的"签名"和"解密"在数学上是同一个模幂运算 ,老教材就笼统说"签名就是私钥加密"。但这是过时且危险的理解:
- 目的相反:加密求"别人看不懂";签名求"别人能证明是你"。
- 操作不同:签名先算哈希、再对哈希值运算;加密对原文运算。
- 很多算法只能签名、不能加密 :ECDSA、Ed25519 天生只能签名,根本没有加密功能。SM2 是少数"既能加密又能签名"的。所以"签名=加密"在这类算法上直接不成立。
正确表述:私钥用于「签名」或「解密」,公钥用于「验证签名」或「加密」。私钥做什么取决于场景(怕人看→加密方向;怕假冒→签名方向),不是"私钥操作就叫加密"。
12. 车规场景「怎么选算法」决策清单(FAE 实战视角)
|-------------------------|--------------------------------|----------------|
| 场景 | 选什么 | 理由 |
| 固件安全启动验签 | ECDSA / RSA 签名 / SM2 签名 | 证明固件来自 OEM,防篡改 |
| CAN/FlexRay 报文认证(SecOC) | CMAC(或 GMAC) | 带密钥、开销小、实时性好 |
| 敏感数据加密存储(如 VIN、里程) | AES-GCM / AES-CCM | 加密+认证一步到位 |
| 加密 CAN 报文传输 | AES-CTR(或 SM4-CTR) | 流式、无需填充、随机访问 |
| 会话密钥生成 | TRNG | 不可预测是真随机 |
| 一机一密 / 密钥分级 | SHE KDF 密钥派生 | 从主钥派生,子钥互不关联 |
| 调试解锁、设备认证 | RSA/SM2 签名(challenge-response) | 公钥验签,私钥不出芯片 |
13. 阶段 1 自测清单(答案仅交流,不写进文档)
- 机密性 / 完整性 / 真实性 / 不可否认性,分别靠哪类算法?
- AES 五种分组模式里,哪两种要求 16 字节对齐?哪种"相同明文→相同密文"不能用于真实数据?
- 哈希和 MAC 的本质区别是什么?为什么安全启动里常用 CMAC/Sign 而不是裸哈希?
- "加密怕人看、签名怕人假冒"------加密和签名各用谁的哪把钥?
- 非对称为什么能解决对称的密钥分发难题?工程上为什么"非对称做签名、对称做加密"?
- AEAD(GCM)相比"先加密再算 MAC"有什么优势?GCM 最忌讳什么被重用?
- 3008PCSN 上做一次 AES-GCM 加密,调哪个固件服务、填哪个结构体、传哪些关键字段?
- TRNG 和 PRNG 区别?HSM 里随机数长度有什么限制(对齐)?
14. 本阶段事实核对记录(重要,避免后续踩坑)
学习时发现固件 V229(CCFC3008PCSN 平台)有几个编译开关与"通用认知"不一致,务必注意:
|----------------------|-------|----------------------------------------------------------------------------------------------|
| 编译开关(hsm_config.h) | 实际值 | 含义 |
| HSM_SHE_COMPATIBLE | 0 | SHE 兼容层本固件默认关闭 (HSM_SRV_SheLoadKey 等 API 虽在头文件里,但 #if HSM_SHE_COMPATIBLE 保护,实际不参与编译) |
| NEW_SECURITY_BOOT | 1 | 走新安全启动方案(PreSecureBootCheck / IgnoreSecureBoot / ConfigSecureBoot_SWP) |
| CONFIG_ALG_ED25519 | 0 | Ed25519 签名/密钥类型未启用 |
| CONFIG_OTA_ENABLE | 0 | OTA 相关 ImportOtaParam 服务未启用(3008PCSN 固定 bank,无 A/B 升级) |
| CONFIG_SMPU_ENABLE | 0 | 3008PCSN 平台 SMPU 关闭 |
结论:之前"固件含 SHE 兼容层"的说法需要修正 ------头文件里 SHE API 都在,但 3008PCSN 这个固件包编译时
HSM_SHE_COMPATIBLE=0,SHE 那套(M1M2M3 注入协议、SHE KDF)在当前固件里是关闭的。若要启用需原厂改配置重出固件。这是阶段 3 讲 SHE 时必须澄清的点,先在这里埋个伏笔。
阶段 1 小结:算法分四类------对称(机密)、哈希/MAC(完整)、非对称/签名(身份+不可否认)、随机数(地基)。所有算法最终都落到固件 hsm_interface.h 的某个 HSM_SRV_* 服务上。下一阶段 2 讲芯片硬件架构,看这些算法到底跑在哪些硬件引擎上。