Zephyr下调用mbedtls函数链接失败问题求助
问题:NRF52840 Zephyr应用中mbedtls_hkdf链接失败的解决办法
问题背景
为NRF52840开发Zephyr应用时,尝试通过以下函数派生会话密钥:
int derive_session_key(const uint8_t *device_token_key, const uint8_t *nonce1, const uint8_t *nonce2, uint16_t out_key_len, uint8_t *output_key) { const uint8_t *ikm = device_token_key; const size_t ikm_len = TOKEN_KEY_SIZE; uint8_t salt[NONCE_SIZE]; add_arrays(nonce1, nonce2, salt, NONCE_SIZE); const size_t salt_len = NONCE_SIZE; const uint8_t *info = (const uint8_t *)INFO_STR; const size_t info_len = strlen(INFO_STR); int ret = mbedtls_hkdf(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), salt, salt_len, ikm, ikm_len, info, info_len, output_key, out_key_len); if (ret != 0) { LOG_ERR("Error! Creating session key. Ret : %d", ret); return RET_ERROR; } return RET_OK; }
proj.conf配置如下:
CONFIG_NRF_SECURITY=y CONFIG_MBEDTLS=y CONFIG_MBEDTLS_SHA256_C=y CONFIG_MBEDTLS_PSA_CRYPTO_C=y CONFIG_MBEDTLS_HKDF_C=y CONFIG_MBEDTLS_BUILTIN=y CONFIG_MBEDTLS_CIPHER_MODE_CBC=y CONFIG_MBEDTLS_AES_C=y CONFIG_MBEDTLS_HEAP_SIZE=8192 CONFIG_HEAP_MEM_POOL_SIZE=4096 CONFIG_MBEDTLS_ENABLE_HEAP=y CONFIG_PSA_WANT_KEY_TYPE_AES=y CONFIG_PSA_WANT_AES_KEY_SIZE_128=y CONFIG_PSA_WANT_ALG_CMAC=y CONFIG_PSA_WANT_ALG_ECB_NO_PADDING=y CONFIG_PSA_WANT_ALG_CBC_NO_PADDING=y
但链接失败,无法调用mbedtls_hkdf,出现以下警告:
warning: MBEDTLS_AES_C (defined at /home/user/Belter/top_main/nrf/subsys/nrf_security/Kconfig.legacy:388) was assigned the value 'y' but got the value 'n'. Check these unsatisfied dependencies: MBEDTLS_LEGACY_CRYPTO_C (=n). See http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_MBEDTLS_AES_C and/or look up MBEDTLS_AES_C in the menuconfig/guiconfig interface. The Application Development Primer, Setting Configuration Values, and Kconfig - Tips and Best Practices sections of the manual might be helpful too. warning: MBEDTLS_HKDF_C (defined at /home/user/Belter/top_main/nrf/subsys/nrf_security/Kconfig.legacy:724, modules/mbedtls/Kconfig.tls- generic:140, modules/mbedtls/Kconfig.tls-generic:140) was assigned the value 'y' but got the value 'n'. Check these unsatisfied dependencies: ((MBEDTLS_LEGACY_CRYPTO_C && NRF_SECURITY) || (!(NRF_SECURITY || NORDIC_SECURITY_BACKEND) && MBEDTLS_BUILTIN && MBEDTLS_CFG_FILE = "config-tls- generic.h" && MBEDTLS) || (!(NRF_SECURITY || NORDIC_SECURITY_BACKEND) && MBEDTLS_BUILTIN && MBEDTLS_CFG_FILE = "config-tls-generic.h" && MBEDTLS && 0)) (=n). See http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_MBEDTLS_HKDF_C and/or look up MBEDTLS_HKDF_C in the menuconfig/guiconfig interface. The Application Development Primer, Setting Configuration Values, and Kconfig - Tips and Best Practices sections of the manual might be helpful too. warning: MBEDTLS_SHA256_C (defined at /home/user/Belter/top_main/nrf/subsys/nrf_security/Kconfig.legacy:798) was assigned the value 'y' but got the value 'n'. Check these unsatisfied dependencies: MBEDTLS_LEGACY_CRYPTO_C (=n). See http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_MBEDTLS_SHA256_C and/or look up MBEDTLS_SHA256_C in the menuconfig/guiconfig interface. The Application Development Primer, Setting Configuration Values, and Kconfig - Tips and Best Practices sections of the manual might be helpful too.
手动定义MBEDTLS_HKDF_C也无效,求解决办法。
解决办法
方案1:启用mbedtls Legacy Crypto API
根据警告信息,核心问题是**MBEDTLS_LEGACY_CRYPTO_C未启用**。当启用CONFIG_NRF_SECURITY=y时,mbedtls的传统加密API(如mbedtls_hkdf)依赖该配置项才能激活。
在proj.conf中添加以下配置:
CONFIG_MBEDTLS_LEGACY_CRYPTO_C=y
添加后清理并重新构建项目:
west build -t clean west build
方案2:切换到PSA Crypto API(推荐)
Zephyr推荐使用PSA Crypto API替代mbedtls的传统API,无需依赖legacy配置,同时更符合现代加密标准。
- 首先在proj.conf中添加PSA HKDF支持:
CONFIG_PSA_WANT_ALG_HKDF=y CONFIG_PSA_WANT_ALG_SHA_256=y
- 修改代码使用PSA API实现HKDF:
#include <psa/crypto.h> int derive_session_key(const uint8_t *device_token_key, const uint8_t *nonce1, const uint8_t *nonce2, uint16_t out_key_len, uint8_t *output_key) { psa_status_t status; psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT; psa_key_handle_t key_handle; uint8_t salt[NONCE_SIZE]; add_arrays(nonce1, nonce2, salt, NONCE_SIZE); // 配置临时密钥属性:仅用于派生,算法为HKDF-SHA256 psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_DERIVE); psa_set_key_algorithm(&attr, PSA_ALG_HKDF(PSA_ALG_SHA_256)); psa_set_key_type(&attr, PSA_KEY_TYPE_RAW_DATA); psa_set_key_bits(&attr, TOKEN_KEY_SIZE * 8); // 导入初始密钥材料(IKM) status = psa_import_key(&attr, device_token_key, TOKEN_KEY_SIZE, &key_handle); if (status != PSA_SUCCESS) { LOG_ERR("Import IKM key failed: %d", status); return RET_ERROR; } // 执行HKDF密钥派生 status = psa_key_derive(key_handle, PSA_ALG_HKDF(PSA_ALG_SHA_256), salt, NONCE_SIZE, (const uint8_t *)INFO_STR, strlen(INFO_STR), output_key, out_key_len, NULL); // 销毁临时密钥句柄 psa_destroy_key(key_handle); if (status != PSA_SUCCESS) { LOG_ERR("HKDF derive failed: %d", status); return RET_ERROR; } return RET_OK; }
- 清理并重新构建项目:
west build -t clean west build
原因说明
当启用CONFIG_NRF_SECURITY=y时,Zephyr会使用Nordic提供的安全后端,此时mbedtls的传统API(如mbedtls_hkdf、mbedtls_sha256)默认被禁用,必须通过CONFIG_MBEDTLS_LEGACY_CRYPTO_C=y显式启用。
而PSA Crypto API是Zephyr官方推荐的加密接口,与Nordic安全后端兼容良好,无需依赖legacy配置,同时具备更好的安全性和可移植性。
内容的提问来源于stack exchange,提问作者Engineer999
相关产品推荐
相关产品推荐

