LPC55S69板Rust调用C库crypto_sign_keypair接口卡死问题求助
问题:Rust调用LPC55S69上的C加密库接口时永久卡死
我在LPC55S69开发板上用Rust调用一个C加密库,目标接口来自pqm4项目中dilithium2的m4f实现:
int crypto_sign_keypair(uint8_t *pk, uint8_t *sk);
我的Rust代码如下,调用crypto_sign_keypair时程序永久卡死:
#![no_std] #![no_main] pub const PUBLICKEYBYTES: usize = 1312; pub const SECRETKEYBYTES: usize = 2558; extern "C" { pub fn crypto_sign_keypair(pk: *mut u8, sk: *mut u8) -> cty::c_int; } #[cortex_m_rt::entry] fn main() -> ! { let mut public_key: [u8; PUBLICKEYBYTES] = [0u8; PUBLICKEYBYTES]; let mut secret_key: [u8; SECRETKEYBYTES] = [0u8; SECRETKEYBYTES]; let res = unsafe { crypto_sign_keypair(public_key.as_mut_ptr(), secret_key.as_mut_ptr()) }; // 此处卡死 }
相同的接口在C程序中运行正常,C调用示例:
#define SECRETKEYBYTES 2558 #define PUBLICKEYBYTES 1312 int main(void) { uint8_t sk[SECRETKEYBYTES], pk[PUBLICKEYBYTES]; crypto_sign_keypair(pk, sk); }
请问Rust代码哪里出错了?
排查方向与解决方案
1. 栈空间不足导致溢出
LPC55S69的默认栈空间通常较小(比如2KB),而Rust代码中public_key和secret_key两个数组合计占用3870字节(1312+2558),直接分配在栈上会触发栈溢出,导致程序卡死。
解决方法:
- 将数组改为静态分配(存放在RAM的静态区域):
#![no_std] #![no_main] pub const PUBLICKEYBYTES: usize = 1312; pub const SECRETKEYBYTES: usize = 2558; extern "C" { pub fn crypto_sign_keypair(pk: *mut u8, sk: *mut u8) -> cty::c_int; } // 静态分配数组,避免栈溢出 static mut PUBLIC_KEY: [u8; PUBLICKEYBYTES] = [0u8; PUBLICKEYBYTES]; static mut SECRET_KEY: [u8; SECRETKEYBYTES] = [0u8; SECRETKEYBYTES]; #[cortex_m_rt::entry] fn main() -> ! { let res = unsafe { crypto_sign_keypair(PUBLIC_KEY.as_mut_ptr(), SECRET_KEY.as_mut_ptr()) }; loop {} // 必须添加死循环,符合no_main的要求 }
- 或者修改项目链接脚本,增大栈的分配大小。
2. 编译目标与C库ABI不匹配
C库是针对Cortex-M4F编译的,需要确保Rust的编译目标和C库的编译选项一致,尤其是浮点ABI设置:
- 检查
.cargo/config.toml中是否指定了正确的硬浮点目标:
[build] target = "thumbv7em-none-eabihf"
- 确保C库编译时启用了
-mfloat-abi=hard、-mfpu=fpv4-sp-d16等对应选项,否则会因寄存器调用约定不匹配导致程序卡死。
3. 未初始化硬件随机数发生器(RNG)
crypto_sign_keypair生成密钥依赖硬件随机数,C程序中可能已经初始化了LPC55S69的RNG模块,但Rust代码中缺少这一步,导致C库卡在等待随机数据的环节。
解决方法:
调用C接口前,用Rust HAL库初始化RNG:
#![no_std] #![no_main] pub const PUBLICKEYBYTES: usize = 1312; pub const SECRETKEYBYTES: usize = 2558; use lpc55_hal::peripherals::RNG; use lpc55_hal::prelude::*; use cortex_m_rt::entry; extern "C" { pub fn crypto_sign_keypair(pk: *mut u8, sk: *mut u8) -> cty::c_int; } #[entry] fn main() -> ! { // 初始化HAL和RNG let hal = lpc55_hal::new(); let _rng = hal.RNG.enabled(); let mut public_key: [u8; PUBLICKEYBYTES] = [0u8; PUBLICKEYBYTES]; let mut secret_key: [u8; SECRETKEYBYTES] = [0u8; SECRETKEYBYTES]; let res = unsafe { crypto_sign_keypair(public_key.as_mut_ptr(), secret_key.as_mut_ptr()) }; loop {} }
4. 内存对齐问题(可能性较低)
虽然u8数组默认是1字节对齐,但部分加密库可能要求指针按4字节或8字节对齐。可以尝试强制数组对齐:
#[repr(align(4))] struct AlignedPublicKey([u8; PUBLICKEYBYTES]); #[repr(align(4))] struct AlignedSecretKey([u8; SECRETKEYBYTES]); // 在main中使用: let mut public_key = AlignedPublicKey([0u8; PUBLICKEYBYTES]); let mut secret_key = AlignedSecretKey([0u8; SECRETKEYBYTES]); let res = unsafe { crypto_sign_keypair(public_key.0.as_mut_ptr(), secret_key.0.as_mut_ptr()) };
内容的提问来源于stack exchange,提问作者tarun14110
相关产品推荐
相关产品推荐

