持久内存 - 🔐 DH-HMAC-CHAP_Reply(主机 → 控制器) (第394页)
NVME2.0协议解读 1 min read

持久内存 - 🔐 DH-HMAC-CHAP_Reply(主机 → 控制器) (第394页)

Blog Author

这一节我们继续深入讲解 NVMe 2.0b 规范第 8.13.5.4 节:DH-HMAC-CHAP_Reply 消息结构,它是主机发给控制器的 响应消息,用于回应控制器的认证挑战,可能还会发起双向认证安全信道协商(PSK)预生成


🔐 DH-HMAC-CHAP_Reply(主机 → 控制器)

该消息在 DH-HMAC-CHAP 协议认证过程中是第二个消息(主机发起第一个消息是 AUTH_Negotiate)。它对控制器的 Challenge C1 做出回应,同时(如果需要)发起自己的质询 C2,请求控制器也自证身份。


📘 消息结构详解(参见 Figure 449)

字节范围 字段名 说明
0 AUTH_TYPE = 01h 表示这是 DH-HMAC-CHAP 协议消息
1 AUTH_ID = 02h 表示该消息类型为 Reply
4–5 T_ID 与协商阶段的事务 ID 保持一致
6 HL 哈希长度,表示所选哈希函数的输出字节数(如 SHA-256 为 32)
8 CVALID 01h 表示携带 Challenge C2(启用双向认证或用于生成 PSK)
00h 表示未启用
10–11 DHVLEN DH 值长度,单位字节,为 0 表示未使用 DH(即 NULL DH group)
12–15 SEQNUM S2 主机生成的序列号(用于双向认证),0 表示仅用于 PSK
16–16+HL R1(Response Value) 主机对控制器挑战 C1 的应答值
16+HL–16+2HL C2(Challenge) 可选,主机发给控制器的挑战(CVALID=01h 时有效)
... DHV(DH 值) 可选,主机的 DH 指数 (g^y \mod p),DHVLEN > 0 时存在

R1 的计算方式(Response Value)

这是本节的重点,是用于认证的核心:

▶ 若使用 NULL DH(即 HMAC-CHAP):

  • Ca1 = C1(直接使用控制器的挑战)
  • R1 = HMAC(Kh, Ca1 || S1 || T_ID || SC_C || "HostHost" || NQNh || 00h)

▶ 若使用了 DH(即 DH-HMAC-CHAP):

  1. 计算会话密钥: [ K_{DH} = H\left((g^x)^y \mod p\right) = H(g^{xy} \mod p) ]
  2. 用它计算增强质询: [ Ca1 = \text{HMAC}(K_{DH}, C1) ]
  3. 最终 R1 计算为: [ R1 = \text{HMAC}(K_h, Ca1 || S1 || T_ID || SC_C || \text{"HostHost"} || NQNh || 00h) ]

⚠️ 关键安全注意点

  • 若启用了双向认证,C2 的值必须不同于 C1。
  • 若仅用于建立 PSK(安全信道),可设置 SEQNUM = 0CVALID = 01h,但不继续发 R2。
  • DHVLEN 的值必须与所选 DH group 匹配(为 0 时不允许存在 DH 值字段)。

🎯 用途小结

应用场景 配置字段
单向认证 CVALID=00h,不带 C2
双向认证 CVALID=01h,带 C2 和 S2
安全信道预协商(TLS) CVALID=01hSEQNUM=0,带 C2

✅ 下一步建议

我们可以继续解析:

  • 8.13.5.5 DH-HMAC-CHAP_Success1
  • 8.13.5.6 DH-HMAC-CHAP_Success2
  • 或总结一张 DH-HMAC-CHAP 全流程图(含字段 + 安全点)

你想深入哪一部分?或者我来整理一个整体认证过程的「图文流程解析」?