NXP社区的各位朋友,大家好!
我正在使用 SE051 安全元件,想请教如何使用 Plug and Trust 中间件将平台 SCP03 密钥正确地恢复到其默认值。
请问有人可以指导我如何修改 se05x_TP_PlatformSCP03keys.c 文件,或者执行此密钥还原的正确步骤是什么吗?
任何建议或代码方面的指导都将不胜感激。
嗨@Uc_S ,
如果您只需要将密钥轮换回默认值,那么 nano 包示例是推荐的更简单的方法——只需要更新三个scp03_*数组(当前身份验证密钥)和三个NEW_scp03_*数组(目标默认密钥),并且需要注释掉 ex_se05x_rotate_scp03_keys() 中的 revert 调用。详情请见下文。
第 38-43 行是传递给ex_set_scp03_keys()的身份验证密钥。请将占位符0xABCD...值替换为您当前的密钥( 0x4041...
uint8_t scp03_enc_key[AES_KEY_LEN_nBYTE] = {
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F };
uint8_t scp03_mac_key[AES_KEY_LEN_nBYTE] = {
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F };
uint8_t scp03_dek_key[AES_KEY_LEN_nBYTE] = {
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F };
第 45-50 行是将通过 PutKey 写入 SE051 的 密钥。将0x4041...占位符替换为 SE051C OEF A8FA 默认值:
uint8_t NEW_scp03_enc_key[AES_KEY_LEN_nBYTE] = {
0xbf, 0xc2, 0xdb, 0xe1, 0x82, 0x8e, 0x03, 0x5d,
0x3e, 0x7f, 0xa3, 0x6b, 0x90, 0x2a, 0x05, 0xc6 };
uint8_t NEW_scp03_mac_key[AES_KEY_LEN_nBYTE] = {
0xbe, 0xf8, 0x5b, 0xd7, 0xba, 0x04, 0x97, 0xd6,
0x28, 0x78, 0x1c, 0xe4, 0x7b, 0x18, 0x8c, 0x96 };
uint8_t NEW_scp03_dek_key[AES_KEY_LEN_nBYTE] = {
0xd8, 0x73, 0xf3, 0x16, 0xbe, 0x29, 0x7f, 0x2f,
0xc9, 0xc0, 0xe4, 0x5f, 0x54, 0x71, 0x06, 0x99 };
在ex_se05x_rotate_scp03_keys()中,注释掉第 85-90 行,这样代码就只会进行一次旋转(当前键 → 默认值),而不会尝试再次旋转回来:
/* -- Comment out the revert block below -- */
// SMLOG_I("Reverting SCP03 keys(version - %02x) to OLD KEYS \n", KEY_VERSION);
// ret = ex_se05x_change_keys(&se05x_session, &scp03_enc_key[0], &scp03_mac_key[0], &scp03_dek_key[0]);
// if (ret != 0) {
// SMLOG_E("Error in ex_se05x_change_keys \n");
// return 1;
// }
祝你有美好的一天,
坎
-------------------------------------------------------------------------------
笔记:
- 如果此回复解答了您的问题,请点击“标记为正确答案”按钮。谢谢你!
- 我们会持续关注帖子,从最后一条回复发出后持续7周,之后的回复将被忽略。
如果您之后有相关问题,请另开新帖并引用已关闭的帖子。
-------------------------------------------------------------------------------
谢谢你的解释。
就我而言,当前密钥是已知的(ENC、MAC 和 DEK 的密钥为 0x4041...),我可以通过 ssscli 使用这些密钥成功建立 SCP03 会话。
由于我目前拥有可用于身份验证的密钥,请问您能否详细说明如何修改 se05x_TP_PlatformSCP03keys.c 文件,以将密钥轮换回默认值?
具体来说,我想知道:
se05x_TP_PlatformSCP03keys.c 中的任何代码片段或特定行引用(或相关的启动/认证标头)将不胜感激。
嗨@Uc_S ,
只有在知道当前密钥的情况下,才能将平台 SCP03 密钥轮换回默认值,因为在向 SE051 发出任何密钥更新 ( PutKey ) 命令之前,需要成功验证 SCP03 会话。
如果当前密钥丢失或遗忘,则无法对 SE051 进行身份验证并执行密钥轮换。没有后门或绕过机制——这是为了维护设备的安全模型而设计的。
此外,恢复出厂设置也无济于事,因为平台 SCP03 密钥明确不受恢复出厂设置程序的影响。
在这种情况下,唯一的选择是用一个仍然带有 NXP 默认配置密钥的新设备替换 SE051 。
祝你有美好的一天,
坎
-------------------------------------------------------------------------------
笔记:
- 如果此回复解答了您的问题,请点击“标记为正确答案”按钮。谢谢你!
- 我们会持续关注帖子,从最后一条回复发出后持续7周,之后的回复将被忽略。
如果您之后有相关问题,请另开新帖并引用已关闭的帖子。
-------------------------------------------------------------------------------
感谢您提供详细指导。
按照您的指示,我更新了密钥,注释掉了还原块,并成功构建和执行了 nano-package 示例。
然而,在执行过程中,SCP03 密钥更新操作在 PUT KEY APDU 命令期间失败,SW 状态代码为 6A80。以下是执行日志的摘要:
Plug and Trust nano package - version: 1.6.1
...
Establish Secure Channel to SE05x !
Sending GP Initialize Update Command !!!
...
CardCryptogram verified successfully...Calculate HostCryptogram
Sending GP External Authenticate Command !!!
APDU Tx> :84 82 33 00 10 ...
APDU Rx< :69 82
Authentication Successful!!!
Created scp03 Session
Changing SCP03 keys(version - 0b) to NEW KEYS
APDU Tx> :84 d8 0b 81 58 ...
APDU Rx< :6a 80
Error in DoAPDUTxRx
Error in ex_se05x_change_keys
SE05x Rotate SCP03 keys Example Failed !关于潜在的根本原因,我怀疑要么是 OpenSSL 版本(构建 PC 和目标评估板上都使用了 OpenSSL 3.x)影响了 PutKey 期间的密钥派生/格式化,要么是 DEK 值之前可能不匹配/被重写。
目前,我没有足够的精力进一步调查或探讨这些可能性。如果时间允许,我会稍后单独调查这些问题。
再次感谢您的帮助。
嗨@Uc_S ,
感谢您提供的详细执行日志——它提供了准确定位问题所需的所有信息。你的两个嫌疑人都合理且有理有据。以下是对最有可能发生的情况的分析。
SW 6A80 (SW_WRONG_DATA)表示 SE051 拒绝了 PUT KEY APDU 的数据字段,认为其在加密上无效。由于您的日志显示身份验证已成功完成(CardCryptogram 已验证 + 外部身份验证已通过),因此确认 ENC 和 MAC 密钥正确。故障仅限于 PUT KEY 步骤,这直接指向DEK 密钥或用于封装新密钥材料的 AES 加密存在问题。
在 PUT KEY 命令中,每个新密钥在发送到 SE 之前都会根据当前的 DEK 进行加密。如果主机代码中的 DEK 值与设备上存储的 DEK 值不完全匹配,则 SE 解密垃圾数据并返回 6A80。
之前一位 SE051C1 客户提出的一个几乎完全相同的案例得出了以下结论:
“如果最小示例能够使用 PlatformSCP,那么 ENC 和 MAC 密钥就是正确的。”由于钥匙旋转仍然失败,这意味着DEK钥匙肯定有问题……DEK钥匙可能以前设置错误过。
鉴于您的历史记录,这是最可能的根本原因——先前不完整或不正确的旋转可能导致 SE051 的 DEK 处于不再与 0x4041... 匹配的状态。
确认步骤:在全新的、出厂时就准备的 SE051 样品上测试相同的代码。如果立即成功,则确认当前设备的 DEK 状态已损坏/未知,芯片应该更换——没有正确的 DEK,就没有恢复路径。
该纳米软件包的 SCP03 加密路径使用传统的底层 OpenSSL API:
AES_set_encrypt_key((uint8_t *)key, keylen * 8, &AESKey);
AES_ecb_encrypt(srcData, destData, &AESKey, AES_ENCRYPT);
该纳米软件包仅使用 OpenSSL 1.1.1进行设计和测试。在 OpenSSL 3.x 中,这些 API 已被弃用,需要在运行时显式加载旧版提供程序。如果未加载,这些调用可能会静默地产生不正确的输出——这将破坏 DEK 加密的有效载荷,并触发信号 6A80。
建议的修复方法:将 nano 包切换为使用mbedTLS作为主机加密后端( -DEX_SE05X_USE_MBEDTLS=1 ),它不依赖于已弃用的 OpenSSL API,并且完全支持此用例。或者,针对 OpenSSL 1.1.1 重新构建,以单独测试 OpenSSL 版本假设。
请注意:如果确认当前设备的 DEK 处于未知状态,则无法恢复——需要更换带有出厂默认密钥的芯片。
请与我们联系新样品的检测结果,我们将很乐意提供进一步的帮助。
祝你有美好的一天,
坎
-------------------------------------------------------------------------------
笔记:
- 如果此回复解答了您的问题,请点击“标记为正确答案”按钮。谢谢你!
- 我们会持续关注帖子,从最后一条回复发出后持续7周,之后的回复将被忽略。
如果您之后有相关问题,请另开新帖并引用已关闭的帖子。
-------------------------------------------------------------------------------
非常感谢您对 6A80 错误的详细解释和分析。
对 DEK 密钥不匹配和 OpenSSL 3.x 兼容性风险的分析(以及使用 mbedTLS 的建议)很有帮助,并阐明了正在发挥作用的确切机制。
我会记住这些建议选项——例如在新样本上进行测试,以及考虑使用 mbedTLS 作为加密后端——以便在资源和带宽允许的情况下进行未来的故障排除。