持久内存与安全机制 - 第395页
NVME2.0协议解读 1 min read

持久内存与安全机制 - 第395页

Blog Author

我们现在继续深入分析 NVMe 2.0b 规范第 8.13.5.4–8.13.5.5 节中关于 DH-HMAC-CHAP 协议中的主机回复与控制器认证成功确认的机制。我们重点看两件事:


✅ 主机发送 DH-HMAC-CHAP_Reply 消息后的控制器行为

这是认证流程中的关键验证环节。

✉️ 主机发送内容简述:

主机发送的 DH-HMAC-CHAP_Reply 消息中包含了:

  • 对 C1 的响应 R1
  • 若启用双向认证或后续建立 TLS 安全信道,则携带新挑战 C2
  • 若使用 Diffie-Hellman,则携带主机 DH 指数 g^y mod p

📌 控制器接收后要做的验证:

控制器收到主机的 DH-HMAC-CHAP_Reply 后,按以下步骤执行:


🔒 1. 验证参数正确性:

若以下任意条件满足,说明主机传入 payload 错误,控制器立即中止连接并报错:

  • HL 不等于之前协商的哈希函数长度(如 SHA-256 就是 32)
  • 使用 DH 协议时,DHVLEN 被清零了(应该携带指数)
  • 使用 DH 协议时,主机的 DH 值为 0、1 或 p-1(不合法)

错误返回为:

AUTH_Failure1 {
  Reason Code: 01h "Authentication failure"
  Explanation: 06h "Incorrect payload"
}
 断开连接

🔁 2. 如果主机设置了 CVALID=01h(即启用双向认证或生成 PSK),还要检查:

  • 主机发来的 C2 不能和控制器之前发的 C1 一样
  • 否则会返回错误: Reason: Authentication failure Explanation: Authentication failed (重复的挑战)

🧮 3. 验证主机的响应值 R1 是否正确:

控制器使用与主机协商好的方式计算它期望的 R1

  • 用主机提供的 Diffie-Hellman 值(若使用 DH)和自己保存的 x 算出会话密钥 ( g^{xy} \mod p )
  • 用它生成增强挑战 Ca1
  • 按如下格式拼接字符串后做 HMAC:
R1_expected = HMAC(Kh, Ca1 || S1 || T_ID || SC_C || "HostHost" || NQNh || 00h || NQNc)

如果主机发来的 R1 != R1_expected,说明认证失败,立即报错断开连接。


✉️ 若验证成功,控制器回应 DH-HMAC-CHAP_Success1 消息

下面是该消息的定义。


8.13.5.5 DH-HMAC-CHAP_Success1 消息结构

该消息表示主机认证成功,控制器对主机的身份认可。

字节范围 字段名 说明
0 AUTH_TYPE = 01h 表示使用 DH-HMAC-CHAP 协议
1 AUTH_ID = 03h 表示这是认证成功确认
2–3 Reserved 保留位
4–5 T_ID 事务标识,必须与之前的一致
6–7 Reserved
8–... R2(可选) 控制器对主机挑战 C2 的响应(仅在主机发出 C2 时才包含)

✅ 若启用双向认证或生成 PSK,控制器还需附带 R2:

  • R2 的计算逻辑和 R1 类似,但角色对换。
  • 使用同一个会话密钥 K_DH 和主机发来的 C2。
  • 拼接顺序变为 "CtrlCtrl" + 控制器 NQN + 00h + 主机 NQN。
Ca2 = HMAC(K_DH, C2)
R2 = HMAC(Kc, Ca2 || S2 || T_ID || SC_C || "CtrlCtrl" || NQNc || 00h || NQNh)

总结 ✅

阶段 主体 操作 成功后的下一步
Challenge 控制器 发起认证请求 等待主机回应
Reply 主机 响应 C1,发 C2(可选) 控制器校验并回应 Success1
Success1 控制器 回应 R1 校验通过 主机校验 R2(若双向)或完成认证
Success2 主机(可选) 发出对 R2 的认可 双向认证完成

下一步我们可以继续讲解:

  • DH-HMAC-CHAP_Success2 消息(主机发给控制器,双向认证完成)
  • Session Key 的使用场景(用于建立 TLS)

你想继续深入哪部分?也可以为你画出一张完整的 认证过程流程图