Skip to content

Commit 1558fe8

Browse files
Rust wrapper: rsa: fix sha224/sha384 cfg guards for hash type constants
Normalize cargo:: directives in build.rs. Fixes F-10088.
1 parent 9e0d389 commit 1558fe8

2 files changed

Lines changed: 42 additions & 22 deletions

File tree

wrapper/rust/wolfssl-wolfcrypt/build.rs

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ fn wolfssl_user_prefix() -> Option<String> {
4343
if !prefix.is_empty() && !prefix.contains('\n') {
4444
Some(prefix)
4545
} else {
46-
println!("cargo:warning=ignoring WOLFSSL_PREFIX");
46+
println!("cargo::warning=ignoring WOLFSSL_PREFIX");
4747
None
4848
}
4949
}
@@ -60,7 +60,7 @@ fn wolfssl_include_dir() -> Result<Option<String>> {
6060
let include_dir = format!("{}/include", prefix);
6161
let wolfssl_dir = Path::new(&include_dir).join("wolfssl");
6262
if !wolfssl_dir.is_dir() {
63-
println!("cargo:warning=WOLFSSL_PREFIX is set but {} is not a directory", wolfssl_dir.display());
63+
println!("cargo::warning=WOLFSSL_PREFIX is set but {} is not a directory", wolfssl_dir.display());
6464
return Ok(None);
6565
}
6666
Ok(Some(include_dir))
@@ -87,7 +87,7 @@ fn wolfssl_lib_dir() -> Result<Option<String>> {
8787
let lib_dir = format!("{}/lib", prefix);
8888
let lib_path = Path::new(&lib_dir);
8989
if !lib_path.is_dir() {
90-
println!("cargo:warning=WOLFSSL_PREFIX is set but {} is not a directory", lib_dir);
90+
println!("cargo::warning=WOLFSSL_PREFIX is set but {} is not a directory", lib_dir);
9191
return Ok(None);
9292
}
9393
Ok(Some(lib_dir))
@@ -117,7 +117,7 @@ fn rust_target_to_clang_target(rust_target: &str) -> String {
117117
return rust_target.to_string();
118118
}
119119

120-
// Strip ISA extensions: riscv64imac riscv64, riscv32imac riscv32
120+
// Strip ISA extensions: riscv64imac -> riscv64, riscv32imac -> riscv32
121121
let arch = if parts[0].starts_with("riscv64") {
122122
"riscv64"
123123
} else if parts[0].starts_with("riscv32") {
@@ -130,7 +130,7 @@ fn rust_target_to_clang_target(rust_target: &str) -> String {
130130
let os = parts[2];
131131
let abi = parts.get(3).copied().unwrap_or("");
132132

133-
// Bare-metal: (os=none, abi=elf) <arch>-<vendor>-elf
133+
// Bare-metal: (os=none, abi=elf) -> <arch>-<vendor>-elf
134134
if os == "none" && abi == "elf" {
135135
format!("{}-{}-elf", arch, vendor)
136136
} else if abi.is_empty() {
@@ -279,7 +279,7 @@ fn generate_fips_aliases() -> Result<()> {
279279
"wc_AesCcmEncrypt",
280280
];
281281
if !known_both.contains(&base_name) {
282-
println!("cargo:warning=Skipping FIPS symbols alias for {}", base_name);
282+
println!("cargo::warning=Skipping FIPS symbols alias for {}", base_name);
283283
}
284284
} else {
285285
// Only alias if the base name doesn't already exist
@@ -297,24 +297,24 @@ fn generate_fips_aliases() -> Result<()> {
297297
/// Returns `Ok(())` if successful, or an error if any step fails.
298298
fn setup_wolfssl_link() -> Result<()> {
299299
if let Some(lib_dir) = wolfssl_lib_dir()? {
300-
println!("cargo:rustc-link-search={}", lib_dir);
300+
println!("cargo::rustc-link-search={}", lib_dir);
301301

302302
// Prefer a shared library if present, otherwise fall back to static.
303303
let has_shared = Path::new(&lib_dir).join("libwolfssl.so").exists()
304304
|| Path::new(&lib_dir).join("libwolfssl.dylib").exists();
305305
if has_shared {
306-
println!("cargo:rustc-link-lib=wolfssl");
306+
println!("cargo::rustc-link-lib=wolfssl");
307307
// Only set rpath where a dynamic linker exists (not bare-metal).
308308
let target = env::var("TARGET").unwrap();
309309
if !target.ends_with("-none-elf") {
310-
println!("cargo:rustc-link-arg=-Wl,-rpath,{}", lib_dir);
310+
println!("cargo::rustc-link-arg=-Wl,-rpath,{}", lib_dir);
311311
}
312312
} else {
313-
println!("cargo:rustc-link-lib=static=wolfssl");
313+
println!("cargo::rustc-link-lib=static=wolfssl");
314314
}
315315
} else {
316316
// No local lib dir found; rely on whatever is installed system-wide.
317-
println!("cargo:rustc-link-lib=wolfssl");
317+
println!("cargo::rustc-link-lib=wolfssl");
318318
}
319319

320320
Ok(())
@@ -327,7 +327,9 @@ fn read_file(path: String) -> Result<String> {
327327
Ok(content)
328328
}
329329

330-
fn check_cfg(binding: &str, function_name: &str, cfg_name: &str) -> bool {
330+
/// Returns true if `function_name` (or its `_fips` variant) is present in the
331+
/// generated bindings.
332+
fn has_symbol(binding: &str, function_name: &str) -> bool {
331333
let pattern = format!(r"\b{}(_fips)?\b", function_name);
332334
let re = match Regex::new(&pattern) {
333335
Ok(r) => r,
@@ -336,9 +338,22 @@ fn check_cfg(binding: &str, function_name: &str, cfg_name: &str) -> bool {
336338
std::process::exit(1);
337339
}
338340
};
341+
re.is_match(binding)
342+
}
343+
344+
fn check_cfg(binding: &str, function_name: &str, cfg_name: &str) -> bool {
345+
check_cfg_if(binding, function_name, cfg_name, true)
346+
}
347+
348+
/// Like `check_cfg()`, but only enables `cfg_name` when `cond` also holds.
349+
///
350+
/// Needed where the probed symbol is declared unconditionally by the wolfSSL
351+
/// headers and so cannot by itself prove that the feature is built in.
352+
fn check_cfg_if(binding: &str, function_name: &str, cfg_name: &str,
353+
cond: bool) -> bool {
339354
println!("cargo::rustc-check-cfg=cfg({})", cfg_name);
340-
if re.is_match(binding) {
341-
println!("cargo:rustc-cfg={}", cfg_name);
355+
if cond && has_symbol(binding, function_name) {
356+
println!("cargo::rustc-cfg={}", cfg_name);
342357
true
343358
} else {
344359
false
@@ -461,7 +476,7 @@ fn scan_cfg() -> Result<()> {
461476

462477
// When WOLFSSL_NO_MALLOC is set without WOLFSSL_STATIC_MEMORY, the
463478
// WC_RNG struct contains an inline `drbg_data` field and wolfCrypt sets
464-
// `rng->drbg = &rng->drbg_data` a self-referential pointer. Rust
479+
// `rng->drbg = &rng->drbg_data` - a self-referential pointer. Rust
465480
// moves values by memcpy, which would silently invalidate that pointer.
466481
// Detect this configuration and refuse to build.
467482
if binding.contains("drbg_data") {
@@ -482,13 +497,18 @@ fn scan_cfg() -> Result<()> {
482497
check_cfg(&binding, "wc_RsaPSS_Sign", "rsa_pss");
483498
check_cfg(&binding, "wc_RsaPublicEncrypt_ex", "rsa_oaep");
484499
check_cfg(&binding, "wc_RsaSetRNG", "rsa_setrng");
485-
check_cfg(&binding, "WC_MGF1SHA512_224", "rsa_mgf1sha512_224");
486-
check_cfg(&binding, "WC_MGF1SHA512_256", "rsa_mgf1sha512_256");
500+
// WC_MGF1SHA512_224 and WC_MGF1SHA512_256 are unconditional #defines in
501+
// rsa.h, so their presence says nothing about whether SHA-512/224 and
502+
// SHA-512/256 are actually built in. Require the hash as well.
503+
check_cfg_if(&binding, "WC_MGF1SHA512_224", "rsa_mgf1sha512_224",
504+
has_symbol(&binding, "wc_InitSha512_224"));
505+
check_cfg_if(&binding, "WC_MGF1SHA512_256", "rsa_mgf1sha512_256",
506+
has_symbol(&binding, "wc_InitSha512_256"));
487507
// Detect whether wc_RsaExportKey takes a const first arg (new API) or non-const (old API)
488508
let re = Regex::new(r"pub fn wc_RsaExportKey(_fips)?\s*\(\s*\w+\s*:\s*\*\s*const").unwrap();
489509
println!("cargo::rustc-check-cfg=cfg(rsa_const_api)");
490510
if re.is_match(&binding) {
491-
println!("cargo:rustc-cfg=rsa_const_api");
511+
println!("cargo::rustc-cfg=rsa_const_api");
492512
}
493513

494514
/* mldsa */
@@ -520,8 +540,8 @@ fn scan_cfg() -> Result<()> {
520540
check_cfg(&binding, "wc_InitSha256", "sha256");
521541
check_cfg(&binding, "wc_InitSha384", "sha384");
522542
check_cfg(&binding, "wc_InitSha512", "sha512");
523-
check_cfg(&binding, "wc_HashType_WC_HASH_TYPE_SHA512_224", "sha512_224");
524-
check_cfg(&binding, "wc_HashType_WC_HASH_TYPE_SHA512_256", "sha512_256");
543+
check_cfg(&binding, "wc_InitSha512_224", "sha512_224");
544+
check_cfg(&binding, "wc_InitSha512_256", "sha512_256");
525545
check_cfg(&binding, "wc_InitSha3_224", "sha3_224");
526546
check_cfg(&binding, "wc_InitSha3_256", "sha3_256");
527547
check_cfg(&binding, "wc_InitSha3_384", "sha3_384");

wrapper/rust/wolfssl-wolfcrypt/src/rsa.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ impl RSA {
8686
pub const HASH_TYPE_MD5 : u32 = sys::wc_HashType_WC_HASH_TYPE_MD5;
8787
#[cfg(sha)]
8888
pub const HASH_TYPE_SHA : u32 = sys::wc_HashType_WC_HASH_TYPE_SHA;
89-
#[cfg(sha256)]
89+
#[cfg(sha224)]
9090
pub const HASH_TYPE_SHA224 : u32 = sys::wc_HashType_WC_HASH_TYPE_SHA224;
9191
#[cfg(sha256)]
9292
pub const HASH_TYPE_SHA256 : u32 = sys::wc_HashType_WC_HASH_TYPE_SHA256;
93-
#[cfg(sha512)]
93+
#[cfg(sha384)]
9494
pub const HASH_TYPE_SHA384 : u32 = sys::wc_HashType_WC_HASH_TYPE_SHA384;
9595
#[cfg(sha512)]
9696
pub const HASH_TYPE_SHA512 : u32 = sys::wc_HashType_WC_HASH_TYPE_SHA512;

0 commit comments

Comments
 (0)