持久内存与安全机制 - 第395页
我们现在继续深入分析 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)
你想继续深入哪部分?也可以为你画出一张完整的 认证过程流程图!