AES128-GCM 在 ESP32 解密上使用 mbedtls 不起作用
AES128-GCM using mbedtls on ESP32 decryption not working
我目前正在开展一个项目,使用带有 ESP-IDF 工具链的 ESP32 解密来自智能电表的字节流。 (这里有感兴趣的智能电表规范:P1PortSpecification.pdf,第 2.6 章第 9 页)。
我正在使用状态机将流拆分为文档中的不同部分,当将它们打印到终端时,我得到了预期的结果,因此我认为当前输入是正确的。
到达解密有效负载的最终状态我不确定我是否正确使用了 mbedtls 库,因为我无法让它正常工作。使用的加密是 AES128-GCM,因此我使用 gcm.h。这是我当前的功能:
int decrypt_next_telegram(unsigned char *output) {
//Run the state machine, and get pointers to the IV, cipher and length, GCM tag
Encrypted_Data ed = get_next_telegram();
//Key specific to my smart meter I use for testing purposes and the Auth data
const unsigned char key[] = {0xD4, 0x91, 0x47, 0x0F, 0x47, 0x12, 0x63,
0x32, 0xB0, 0x7D, 0x19, 0x23, 0xB3, 0x50, 0x41, 0x88};
const unsigned char aad[] = {0x30, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}
mbedtls_gcm_context ctx;
mbedtls_gcm_init(&ctx);
int err1 = mbedtls_gcm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, 128);
int err2 = mbedtls_gcm_auth_decrypt(&ctx, ed.payload_length, ed.initial_value, 12, aad, 17, ed.gcm_tag, 12, ed.payload, output);
mbedtls_gcm_free(&ctx);
return err1 + err2;
}
为您提供 Encrypted_Data 的更多详细信息:
typedef struct Encrypted_Data Encrypted_Data;
struct Encrypted_Data {
unsigned char * initial_value;
unsigned char * payload;
unsigned int payload_length;
unsigned char * gcm_tag;
};
将两个错误打印到终端时,我看到 err1 = 0 和 err2 = -0x0012,即:
#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */
所以我深入研究了 gcm.c 文件,发现只有 1 个地方使用了该定义 (here),但是其他事情引起了我的注意。我怀疑这是一个错误,但我无法真正理解
中这部分背后的原因
int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
mbedtls_cipher_id_t cipher,
const unsigned char *key,
unsigned int keybits )
{
int ret;
const mbedtls_cipher_info_t *cipher_info;
cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
...
}
找到 here。为什么使用该模式?如果我正在查看 cipher_info
的内容,它告诉我它正在使用 MBEDTLS_CIPHER_AES_128_ECB
作为 mbedtls_cipher_type_t
,而不是我最初预期的 MBEDTLS_CIPHER_AES_128_GCM
。这是个问题吗?
总结一下我的主要问题:
- 这出乎意料
mbedtls_cipher_type_t
有问题吗?
- 我是否正确使用了 mbedtls 函数?
- 欢迎提出解决问题的建议,因为我对这个平台还没有经验。
感谢阅读。
好吧,我找到了解决我个人问题的方法。
我使用了预先录制的电报,通过 USB 将其发送到 UART 引脚。不幸的是,我 PC 的 USB 控制器时不时出现一些问题。
将电报硬编码到代码中效果非常好...
我目前正在开展一个项目,使用带有 ESP-IDF 工具链的 ESP32 解密来自智能电表的字节流。 (这里有感兴趣的智能电表规范:P1PortSpecification.pdf,第 2.6 章第 9 页)。
我正在使用状态机将流拆分为文档中的不同部分,当将它们打印到终端时,我得到了预期的结果,因此我认为当前输入是正确的。
到达解密有效负载的最终状态我不确定我是否正确使用了 mbedtls 库,因为我无法让它正常工作。使用的加密是 AES128-GCM,因此我使用 gcm.h。这是我当前的功能:
int decrypt_next_telegram(unsigned char *output) {
//Run the state machine, and get pointers to the IV, cipher and length, GCM tag
Encrypted_Data ed = get_next_telegram();
//Key specific to my smart meter I use for testing purposes and the Auth data
const unsigned char key[] = {0xD4, 0x91, 0x47, 0x0F, 0x47, 0x12, 0x63,
0x32, 0xB0, 0x7D, 0x19, 0x23, 0xB3, 0x50, 0x41, 0x88};
const unsigned char aad[] = {0x30, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}
mbedtls_gcm_context ctx;
mbedtls_gcm_init(&ctx);
int err1 = mbedtls_gcm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, 128);
int err2 = mbedtls_gcm_auth_decrypt(&ctx, ed.payload_length, ed.initial_value, 12, aad, 17, ed.gcm_tag, 12, ed.payload, output);
mbedtls_gcm_free(&ctx);
return err1 + err2;
}
为您提供 Encrypted_Data 的更多详细信息:
typedef struct Encrypted_Data Encrypted_Data;
struct Encrypted_Data {
unsigned char * initial_value;
unsigned char * payload;
unsigned int payload_length;
unsigned char * gcm_tag;
};
将两个错误打印到终端时,我看到 err1 = 0 和 err2 = -0x0012,即:
#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */
所以我深入研究了 gcm.c 文件,发现只有 1 个地方使用了该定义 (here),但是其他事情引起了我的注意。我怀疑这是一个错误,但我无法真正理解
中这部分背后的原因int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
mbedtls_cipher_id_t cipher,
const unsigned char *key,
unsigned int keybits )
{
int ret;
const mbedtls_cipher_info_t *cipher_info;
cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
...
}
找到 here。为什么使用该模式?如果我正在查看 cipher_info
的内容,它告诉我它正在使用 MBEDTLS_CIPHER_AES_128_ECB
作为 mbedtls_cipher_type_t
,而不是我最初预期的 MBEDTLS_CIPHER_AES_128_GCM
。这是个问题吗?
总结一下我的主要问题:
- 这出乎意料
mbedtls_cipher_type_t
有问题吗? - 我是否正确使用了 mbedtls 函数?
- 欢迎提出解决问题的建议,因为我对这个平台还没有经验。
感谢阅读。
好吧,我找到了解决我个人问题的方法。 我使用了预先录制的电报,通过 USB 将其发送到 UART 引脚。不幸的是,我 PC 的 USB 控制器时不时出现一些问题。
将电报硬编码到代码中效果非常好...