2404351_zh-CN

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

2404351_zh-CN

2404351_zh-CN

SCP03平台在SE050C1上进行钥匙旋转——插入钥匙被拒绝(6A80 / 6982)

我们无法将SE050C1上的SCP03平台密钥从NXP工厂(OEF)密钥更换为我们自己设备生成的密钥。在我们尝试过的所有变体中,无论是使用 Plug&Trust 3.0.6 还是 4.7.1,在全新的零件上,PUT KEY 都被拒绝。

使用工厂密钥的 Platform SCP03 会话可以正常工作——我们可以打开它并成功运行 applet 命令(GetVersion、GetRandom、ReadObject、WriteBinary)。只有 PUT KEY 操作失败。

我们想知道用于轮换此部件上平台 SCP03 密钥的正确 APDU 序列,最好能有一个参考实现。

设置:

安全元件 SE050C1 (SSS_PFSCP_ENABLE_SE050C1 = 1)
ATR 00 A0 00 00 03 96 04 03 E8 00 FE 02 0B 03 E8 08 01 00 00 00 00 64 00 00 0A 4A 43 4F 50 34 20 41 54 50 4F(“JCOP4 ATPO”)
主机MCU ESP32-S3,ESP-IDF v5.3.4
通过 I2C 传输 T=1 (T1oI2C)
中间件 Plug&Trust — 已测试 3.0.6 和 4.7.1 版本,两者的行为完全相同(迷你版)。
身份验证 SE05X_Auth=PlatfSCP03,SSS_HAVE_SE05X_AUTH_PLATFSCP03
主机加密 mbedTLS


该部件是全新的:从未成功旋转过,并且使用 ex_sss_tp_scp03_keys.h 中的 SE050C1 OEF 密钥进行身份验证。

我们想做什么:

将平台 SCP03 密钥集(ENC / MAC / DEK)从工厂 OEF 密钥轮换为在 ESP32 上派生的设备唯一密钥(基于 ESP32 的 eFuse 驻留 HMAC 密钥的 PBKDF2-HMAC-SHA256),以便只有该特定主机 MCU 才能使用其 SE050 打开平台 SCP03 会话。

哪些做法行之有效:

使用出厂密钥成功打开了 Platform SCP03 会话,并且会话内的命令可以正常工作:scp :DEBUG:身份验证成功!!!

APDU:调试:获取版本 [] -> 90 00

APDU:DEBUG:GetRandom [] -> 90 00
APDU:DEBUG:WriteBinary [] -> 90 00
所以通道、密钥和安全消息传递功能都正常。

哪些方面失败了:

案例A:
PUT KEY 被拒绝,错误代码为 6A80(数据错误)。

命令头和纯文本数据字段(SCP03封装之前):

hdr:80 D8 0B 81 Lc=70

数据:0B <- 密钥版本号
88 11 10 <16 字节 ENC 加密。在 DEK> 03<3-byte KCV>
88 11 10 <16 字节 MAC 加密在 DEK> 03<3-byte KCV>
88 11 10 <16 字节 DEK 加密。DEK>下03<3-byte KCV>

密钥值使用当前(工厂)DEK,采用 AES-密码块链接(CBC) 和零 IV 进行加密;KCV 是使用新密钥对 0x01 的 16 字节块进行 AES 加密的前 3 个字节。

案例B:ISD选定
如果我们首先选择ISD:

GP_Select(A0 00 00 01 51 00 00 00) -> 90 00

响应: 6F 10 84 08 A0000001 51000000 A5 04 9F 65 01 FF
然后,同样的 PUT KEY 请求被拒绝,错误代码为 6982(安全性未满足),而不是 6A80。
这表明 ISD 确实识别了该命令,但需要一个安全通道——并且在案例 A 中,该命令是发送到 SE050 小程序,而该小程序没有 D8 指令。

但是,中间件中的 GP_Select() 发送的是明文 APDU,这会破坏现有的 SCP03 通道。在选择 ISD 后,我们尝试重新建立 SCP03(再次调用 nxScp03_AuthenticateChannel(),并重置会话中的 fp_Transform / authType / pdynScp03Ctx),但失败了:

scp :WARN :nxEnsure:'status == kStatus_SSS_Success' 失败。

第 148 行 函数:nxScp03_AuthenticateChannel

案例 C:
通过 DoAPDUTxRx_s_Case4_ext(带 Le)发送返回 6700(长度错误),与 ISD 的 FCI 广告 9F 65 01 FF(最大数据字段 255)一致。

已经排除的:

这些方法都经过测试,结果均未对结果产生影响:

尝试过的变量值
P1 0x00(创建新版本),0x0B(替换当前版本),0x11(目标版本)
数据字段中是否存在前导 KVN 字节
APDU 案例 Case4(简短版)/ Case4_ext(扩展版)
密钥块结构 88 11 10 03
当前 DEK 下的密钥封装 AES-密码块链接(CBC) 零 IV(相当于一个区块的 ECB)
使用新密钥对 16×0x01 字节的 KCV 方法进行 AES 加密,前 3 个字节
中间件版本 Plug&Trust 3.0.6 和 4.7.1
DEK 源已验证 KEK 与打开会话的密钥集相同
选择小程序后,所有变体均显示 6A80;选择 ISD 后,所有短形式变体均显示 6982。

问题:

在SE050C1上,轮换SCP03平台按键的正确APDU序列是什么?具体来说:PUT KEY 是应该发送到颁发者安全域,还是发送到 SE050 小程序?

如果必须连接到 ISD,那么如何使用 Plug&Trust 中间件与 ISD 建立 Platform SCP03 通道?EX_SSS_BOOT_SKIP_SELECT_APPLET 是否是预期的机制?如果是,正确的调用顺序是什么(SELECT ISD → INITIALIZE UPDATE → EXTERNAL AUTHENTICATE → PUT KEY)?

上述关键数据字段格式是否适用于此部分,特别是密钥类型编码、长度编码、DEK 封装模式和 KCV 算法?

我们的 Plug&Trust 包在 nxScp03_Const.h 中定义了 INS_GP_PUT_KEY (0xD8)。以及 global_platf.h,但没有实现,也没有使用它的示例。能否提供平台 SCP03 密钥轮换示例/演示(相当于 se05x_Delete_and_test_provision 的配置示例),或者在完整的 SDK 中指出它的位置?

能否提供 AN12436(在 ex_sss_auth.h 中引用)?作为 OEF 平台 SCP03 密钥的来源),还是记录此部件密钥轮换的 应用笔记?

背景——为什么这件事没有被注意到
坦白地说,这是我们自己造成的问题,而且我们最近才发现。

我们的配置代码调用了 PUT KEY 命令,然后丢弃了返回状态:

sw = gp_put_key_using_nxp_middleware(se, DERIVED_SCP03_KEYVER, ...);

/* 状态从未检查 */
mark_rotated(se, DERIVED_SCP03_KEYVER); /* 写入“已旋转”标记 */
ESP_LOGI(TAG, "SCP03 按键轮换成功"); /* 无条件打印 */

由于标记写入(WriteBinary)成功,每个设备最终都会设置“已轮换”标志,而其平台 SCP03 密钥仍然是出厂密钥,并且配置报告成功。我们后来添加了状态检查,也正是通过状态检查,我们发现 PUT KEY 在任何设备上实际上从未成功执行过。
我们不需要这方面的帮助——它已经修好了。我们提及此事只是为了解释为什么我们现在提出这个问题而不是在启动时提出,并明确指出该部件确实没有旋转,而不是处于某种部分旋转的状态。

SE050Re: Platform SCP03 key rotation on SE050C1 — PUT KEY rejected (6A80 / 6982)

@Rutwik0409


根据所提供的信息,SE050C1 在小程序层面似乎工作正常: SELECT  GetVersion  GetRandom  ReadObject , 和 WriteBinary 全部成功通过 SCP03 平台。因此,这看起来不像是一个基本的传输故障、T=1 故障、SCP03 密钥故障或安全消息传递故障。

由于您使用的是带有自定义 T=1 over I²C 传输的 ESP32-S3,这很可能是 GlobalPlatform 安全域 SCP03 会话的移植/集成问题,而不是 SE050C1 不支持平台 SCP03 密钥轮换的证据。

为了 SCP03平台关键轮换 , 这 PUT KEY 命令是 全球平台安全域操作 这不是 SE050 IoT 小程序命令。记录的序列如下:

  1. 选择安全域/SSD。
  2. 使用以下方式打开平台 SCP03 安全通道 INITIALIZE UPDATE / EXTERNAL AUTHENTICATE 
  3. 发送 PUT KEY 更新平台 SCP03 密钥集。

这也与观察到的现象相符:

  • 选择SE050小程序时, PUT KEY 返回 6A80 这与向错误目标发送 GlobalPlatform 命令的情况一致。
  • 当选择了 ISD 但未与该功能域建立安全通道时, PUT KEY 返回 6982 这与“安全状态未得到满足”相符。

所以,需要检查的主要点是: 不仅要看平台 SCP03 是否能与 SE050 小程序配合使用 但是,中间件在发出命令之前是否针对正确的安全域打开了平台 SCP03? PUT KEY 

NXP 提供了一个针对此操作的参考演示:

  • se05x_RotatePlatformSCP03Keys

该演示明确指出,它演示了如何使用默认平台 SCP 密钥进行身份验证,以及如何将这些密钥轮换为用户定义的密钥。 

我们的建议是避免手动构建 PUT KEY 首先是 APDU,然后是 NXP 参考实现。

首先,我建议您使用 NXP 的官方参考路径(例如 Zephyr + nano 软件包中的 `se05x_RotatePlatformSCP03Keys` 演示)来验证实现,以便您的 ESP32 MCU 能够得到良好的支持,而无需任何移植工作。该演示是 NXP 针对 SCP03 平台按键旋转的参考实现。当前问题表明“PUT KEY”命令被发送到了错误的目标,或者在选择 ISD/SSD 后,相应的平台 SCP03 安全通道没有正确建立。SCP03 与 SE050 小程序的通信正常进行并不能保证 GlobalPlatform 安全域级别的“PUT KEY”进程已正确设置。

更多详情请参阅https://github.com/NXPPlugNTrust/nano-package/blob/master/zephyr/readme.rst

 

希望对您有所帮助。

 

祝你有美好的一天,


-------------------------------------------------------------------------------
笔记:
- 如果此回复解答了您的问题,请点击“标记为正确答案”按钮。谢谢你!
- 我们会持续关注帖子,从最后一条回复发出后持续7周,之后的回复将被忽略。
如果您之后有相关问题,请另开新帖并引用已关闭的帖子。
-------------------------------------------------------------------------------

Re: Platform SCP03 key rotation on SE050C1 — PUT KEY rejected (6A80 / 6982)@Kan_Li

平台 SCP03 外部身份验证失败时,是否存在重试计数器或锁定计数器?

Platform SCP03 是否支持“尝试密钥集 A,回退到密钥集 B”模式?或者 NXP 是否建议对混合集群采用不同的方法,例如在主机端记录密钥集状态,并且永远不要尝试错误的密钥集?

问候,
鲁特维克
Re: Platform SCP03 key rotation on SE050C1 — PUT KEY rejected (6A80 / 6982)

@Rutwik0409

我的评论如下:

平台 SCP03 外部身份验证失败时,是否存在重试或锁定计数器?

不。在 SE050C1 的平台 SCP03(GlobalPlatform ISD)级别上没有暴力锁定计数器。外部身份验证失败时,只会返回一个非 9000 状态字(例如:6300 或 6982),且通道未打开。SE 随后即可立即进行全新的 INITIALIZE UPDATE 操作。未写入持久锁定状态。

请注意,这与 SE05x小程序级别的身份验证对象(AES 密钥、ECKeys、UserID)不同,后者在其对象策略中具有可配置的身份验证尝试计数器。通过 ISD/GlobalPlatform 层的 SCP03 平台不使用该机制。

是否支持“尝试使用键集 A,回退到键集 B”这种模式?

它本身并不支持,我们不建议将其作为正常的操作流程。原因如下:

  • INITIALIZE_UPDATE 命令在 P2 中携带密钥版本号 (KVN)。如果您发送 INITIALIZE UPDATE 时 KVN=0x01,但设备持有 KVN=0x11,则 SE 返回 6A88(未找到引用的密钥)。然后您可以使用正确的 KVN 重试 - 不会锁定 - 但每次 INITIALIZE UPDATE 失败都是一次不完整的身份验证尝试,并且随着时间的推移可能会导致序列计数器不同步。
  • 它还会泄露设备上存在的密钥版本信息。

混合车队推荐方案

最简洁的做法是在主机端跟踪密钥集状态,并且永远不要尝试错误的 KVN:

  1. 成功完成 PUT KEY 轮换后,写入一个标记(例如,主机后端的一个标志,以 SE050 唯一 ID / CPLC 序列号为键),记录哪个 KVN 现在处于活动状态。
  2. 在每次后续启动时,在发出 INITIALIZE UPDATE 之前查找该标记,以便始终使用正确的 KVN 打开会话。
  3. nano-package 中的se05x_rotate_scp03_keys演示( https://github.com/NXPPlugNTrust/nano-package/tree/master/examples/se05x_rotate_scp03_keys )是PUT KEY机制的良好起点,但请注意,根据设计,它在最后会恢复到旧键——第二个ex_se05x_change_keys调用是开发安全回滚。文档中写道: “为了进行开发测试,我们会回滚到原始密钥。客户可以自行注释掉这一行。”在生产环境中使用时,请注释掉第二个调用。完成此操作后,SE 仅保存新密钥,因此必须相应地更新主机固件,以便从那时起始终使用新的 KVN 打开会话。

一个重要的实用提示:在写入旋转标记之前,务必验证 PUT KEY 的返回状态字。如果 PUT KEY 静默失败(例如,返回 6A80(如您所见),无论如何写入“rotated”标记都会导致后续的每次连接尝试使用错误的 KVN。

祝你有美好的一天,


-------------------------------------------------------------------------------
笔记:
- 如果此回复解答了您的问题,请点击“标记为正确答案”按钮。谢谢你!
- 我们会持续关注帖子,从最后一条回复发出后持续7周,之后的回复将被忽略。
如果您之后有相关问题,请另开新帖并引用已关闭的帖子。
-------------------------------------------------------------------------------

タグ(1)
評価なし
バージョン履歴
最終更新日:
1週間前
更新者: