Skip to content

Commit 2ada1a3

Browse files
Rust wrapper: add compatibility with older FIPS v5 package
1 parent f1e8c1b commit 2ada1a3

7 files changed

Lines changed: 127 additions & 21 deletions

File tree

wrapper/rust/wolfssl-wolfcrypt/build.rs

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,11 @@ fn generate_fips_aliases() -> Result<()> {
124124
if non_fips_re.is_match(&binding) {
125125
// Add any new known names defined with both a _fips suffix and not
126126
// here. Warn if any new ones are discovered.
127-
if base_name != "wc_AesGcmEncrypt" {
127+
let known_both = &[
128+
"wc_AesGcmEncrypt",
129+
"wc_AesCcmEncrypt",
130+
];
131+
if !known_both.contains(&base_name) {
128132
println!("cargo:warning=Skipping FIPS symbols alias for {}", base_name);
129133
}
130134
} else {
@@ -166,18 +170,21 @@ fn read_file(path: String) -> Result<String> {
166170
Ok(content)
167171
}
168172

169-
fn check_cfg(binding: &str, function_name: &str, cfg_name: &str) {
173+
fn check_cfg(binding: &str, function_name: &str, cfg_name: &str) -> bool {
170174
let pattern = format!(r"\b{}(_fips)?\b", function_name);
171175
let re = match Regex::new(&pattern) {
172176
Ok(r) => r,
173177
Err(e) => {
174178
eprintln!("Error compiling regex '{}': {}", pattern, e);
175-
return;
179+
std::process::exit(1);
176180
}
177181
};
178182
println!("cargo::rustc-check-cfg=cfg({})", cfg_name);
179183
if re.is_match(binding) {
180184
println!("cargo:rustc-cfg={}", cfg_name);
185+
true
186+
} else {
187+
false
181188
}
182189
}
183190

@@ -199,6 +206,7 @@ fn scan_cfg() -> Result<()> {
199206
check_cfg(&binding, "wc_AesOfbEncrypt", "aes_ofb");
200207
check_cfg(&binding, "wc_AesXtsInit", "aes_xts");
201208
check_cfg(&binding, "wc_AesXtsEncryptInit", "aes_xts_stream");
209+
check_cfg(&binding, "WC_AES_BLOCK_SIZE", "aes_wc_block_size");
202210

203211
/* blake2 */
204212
check_cfg(&binding, "wc_InitBlake2b", "blake2b");
@@ -234,10 +242,19 @@ fn scan_cfg() -> Result<()> {
234242
check_cfg(&binding, "wc_ecc_verify_hash", "ecc_verify");
235243
check_cfg(&binding, "wc_ecc_export_x963", "ecc_export");
236244
check_cfg(&binding, "wc_ecc_import_x963", "ecc_import");
237-
check_cfg(&binding, "ecc_curve_ids_ECC_X25519", "ecc_curve_25519");
238-
check_cfg(&binding, "ecc_curve_ids_ECC_X448", "ecc_curve_448");
239-
check_cfg(&binding, "ecc_curve_ids_ECC_SAKKE_1", "ecc_curve_sakke");
240-
check_cfg(&binding, "ecc_curve_ids_ECC_CURVE_CUSTOM", "ecc_custom_curves");
245+
if check_cfg(&binding, "ecc_curve_ids_ECC_CURVE_INVALID", "ecc_curve_ids") {
246+
check_cfg(&binding, "ecc_curve_ids_ECC_SM2P256V1", "ecc_curve_sm2p256v1");
247+
check_cfg(&binding, "ecc_curve_ids_ECC_X25519", "ecc_curve_25519");
248+
check_cfg(&binding, "ecc_curve_ids_ECC_X448", "ecc_curve_448");
249+
check_cfg(&binding, "ecc_curve_ids_ECC_SAKKE_1", "ecc_curve_sakke");
250+
check_cfg(&binding, "ecc_curve_ids_ECC_CURVE_CUSTOM", "ecc_custom_curves");
251+
} else {
252+
check_cfg(&binding, "ecc_curve_id_ECC_SM2P256V1", "ecc_curve_sm2p256v1");
253+
check_cfg(&binding, "ecc_curve_id_ECC_X25519", "ecc_curve_25519");
254+
check_cfg(&binding, "ecc_curve_id_ECC_X448", "ecc_curve_448");
255+
check_cfg(&binding, "ecc_curve_id_ECC_SAKKE_1", "ecc_curve_sakke");
256+
check_cfg(&binding, "ecc_curve_id_ECC_CURVE_CUSTOM", "ecc_custom_curves");
257+
}
241258

242259
/* ed25519 */
243260
check_cfg(&binding, "wc_ed25519_init", "ed25519");
@@ -263,6 +280,7 @@ fn scan_cfg() -> Result<()> {
263280

264281
/* hmac */
265282
check_cfg(&binding, "wc_HmacSetKey", "hmac");
283+
check_cfg(&binding, "wc_HmacSetKey_ex", "hmac_setkey_ex");
266284

267285
/* kdf */
268286
check_cfg(&binding, "wc_PBKDF2", "kdf_pbkdf2");
@@ -283,6 +301,15 @@ fn scan_cfg() -> Result<()> {
283301
check_cfg(&binding, "wc_RsaDirect", "rsa_direct");
284302
check_cfg(&binding, "wc_MakeRsaKey", "rsa_keygen");
285303
check_cfg(&binding, "wc_RsaPSS_Sign", "rsa_pss");
304+
check_cfg(&binding, "wc_RsaSetRNG", "rsa_setrng");
305+
check_cfg(&binding, "WC_MGF1SHA512_224", "rsa_mgf1sha512_224");
306+
check_cfg(&binding, "WC_MGF1SHA512_256", "rsa_mgf1sha512_256");
307+
// Detect whether wc_RsaExportKey takes a const first arg (new API) or non-const (old API)
308+
let re = Regex::new(r"pub fn wc_RsaExportKey(_fips)?\s*\(\s*\w+\s*:\s*\*\s*const").unwrap();
309+
println!("cargo::rustc-check-cfg=cfg(rsa_const_api)");
310+
if re.is_match(&binding) {
311+
println!("cargo:rustc-cfg=rsa_const_api");
312+
}
286313

287314
/* sha */
288315
check_cfg(&binding, "wc_InitSha", "sha");

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ Encryption Standard (AES) functionality.
2828
use crate::sys;
2929
use std::mem::{size_of_val, MaybeUninit};
3030

31+
#[cfg(aes_wc_block_size)]
32+
pub const AES_BLOCK_SIZE: usize = sys::WC_AES_BLOCK_SIZE as usize;
33+
#[cfg(not(aes_wc_block_size))]
34+
pub const AES_BLOCK_SIZE: usize = sys::AES_BLOCK_SIZE as usize;
35+
3136
/// AES Cipher Block Chaining (CBC) mode.
3237
///
3338
/// # Example
@@ -91,7 +96,7 @@ impl CBC {
9196

9297
fn init(&mut self, key: &[u8], iv: &[u8], dir: i32) -> Result<(), i32> {
9398
let key_size = key.len() as u32;
94-
if iv.len() as u32 != sys::WC_AES_BLOCK_SIZE {
99+
if iv.len() != AES_BLOCK_SIZE {
95100
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
96101
}
97102
let rc = unsafe {
@@ -506,7 +511,7 @@ impl CFB {
506511
/// library return code on failure.
507512
pub fn init(&mut self, key: &[u8], iv: &[u8]) -> Result<(), i32> {
508513
let key_size = key.len() as u32;
509-
if iv.len() as u32 != sys::WC_AES_BLOCK_SIZE {
514+
if iv.len() != AES_BLOCK_SIZE {
510515
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
511516
}
512517
let rc = unsafe {
@@ -812,7 +817,7 @@ impl CTR {
812817
/// library return code on failure.
813818
pub fn init(&mut self, key: &[u8], iv: &[u8]) -> Result<(), i32> {
814819
let key_size = key.len() as u32;
815-
if iv.len() as u32 != sys::WC_AES_BLOCK_SIZE {
820+
if iv.len() != AES_BLOCK_SIZE {
816821
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
817822
}
818823
let rc = unsafe {
@@ -1769,7 +1774,7 @@ impl OFB {
17691774
/// library return code on failure.
17701775
pub fn init(&mut self, key: &[u8], iv: &[u8]) -> Result<(), i32> {
17711776
let key_size = key.len() as u32;
1772-
if iv.len() as u32 != sys::WC_AES_BLOCK_SIZE {
1777+
if iv.len() != AES_BLOCK_SIZE {
17731778
return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG);
17741779
}
17751780
let rc = unsafe {

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ pub struct ECC {
290290
wc_ecc_key: sys::ecc_key,
291291
}
292292

293+
#[cfg(ecc_curve_ids)]
293294
impl ECC {
294295
pub const CURVE_INVALID: i32 = sys::ecc_curve_ids_ECC_CURVE_INVALID;
295296
pub const CURVE_DEF: i32 = sys::ecc_curve_ids_ECC_CURVE_DEF;
@@ -320,6 +321,7 @@ impl ECC {
320321
pub const BRAINPOOLP320R1: i32 = sys::ecc_curve_ids_ECC_BRAINPOOLP320R1;
321322
pub const BRAINPOOLP384R1: i32 = sys::ecc_curve_ids_ECC_BRAINPOOLP384R1;
322323
pub const BRAINPOOLP512R1: i32 = sys::ecc_curve_ids_ECC_BRAINPOOLP512R1;
324+
#[cfg(ecc_curve_sm2p256v1)]
323325
pub const SM2P256V1: i32 = sys::ecc_curve_ids_ECC_SM2P256V1;
324326
#[cfg(ecc_curve_25519)]
325327
pub const X25519: i32 = sys::ecc_curve_ids_ECC_X25519;
@@ -330,7 +332,53 @@ impl ECC {
330332
#[cfg(ecc_custom_curves)]
331333
pub const CURVE_CUSTOM: i32 = sys::ecc_curve_ids_ECC_CURVE_CUSTOM;
332334
pub const CURVE_MAX: i32 = sys::ecc_curve_ids_ECC_CURVE_MAX;
335+
}
333336

337+
#[cfg(not(ecc_curve_ids))]
338+
impl ECC {
339+
pub const CURVE_INVALID: i32 = sys::ecc_curve_id_ECC_CURVE_INVALID;
340+
pub const CURVE_DEF: i32 = sys::ecc_curve_id_ECC_CURVE_DEF;
341+
pub const SECP192R1: i32 = sys::ecc_curve_id_ECC_SECP192R1;
342+
pub const PRIME192V2: i32 = sys::ecc_curve_id_ECC_PRIME192V2;
343+
pub const PRIME192V3: i32 = sys::ecc_curve_id_ECC_PRIME192V3;
344+
pub const PRIME239V1: i32 = sys::ecc_curve_id_ECC_PRIME239V1;
345+
pub const PRIME239V2: i32 = sys::ecc_curve_id_ECC_PRIME239V2;
346+
pub const PRIME239V3: i32 = sys::ecc_curve_id_ECC_PRIME239V3;
347+
pub const SECP256R1: i32 = sys::ecc_curve_id_ECC_SECP256R1;
348+
pub const SECP112R1: i32 = sys::ecc_curve_id_ECC_SECP112R1;
349+
pub const SECP112R2: i32 = sys::ecc_curve_id_ECC_SECP112R2;
350+
pub const SECP128R1: i32 = sys::ecc_curve_id_ECC_SECP128R1;
351+
pub const SECP128R2: i32 = sys::ecc_curve_id_ECC_SECP128R2;
352+
pub const SECP160R1: i32 = sys::ecc_curve_id_ECC_SECP160R1;
353+
pub const SECP160R2: i32 = sys::ecc_curve_id_ECC_SECP160R2;
354+
pub const SECP224R1: i32 = sys::ecc_curve_id_ECC_SECP224R1;
355+
pub const SECP384R1: i32 = sys::ecc_curve_id_ECC_SECP384R1;
356+
pub const SECP521R1: i32 = sys::ecc_curve_id_ECC_SECP521R1;
357+
pub const SECP160K1: i32 = sys::ecc_curve_id_ECC_SECP160K1;
358+
pub const SECP192K1: i32 = sys::ecc_curve_id_ECC_SECP192K1;
359+
pub const SECP224K1: i32 = sys::ecc_curve_id_ECC_SECP224K1;
360+
pub const SECP256K1: i32 = sys::ecc_curve_id_ECC_SECP256K1;
361+
pub const BRAINPOOLP160R1: i32 = sys::ecc_curve_id_ECC_BRAINPOOLP160R1;
362+
pub const BRAINPOOLP192R1: i32 = sys::ecc_curve_id_ECC_BRAINPOOLP192R1;
363+
pub const BRAINPOOLP224R1: i32 = sys::ecc_curve_id_ECC_BRAINPOOLP224R1;
364+
pub const BRAINPOOLP256R1: i32 = sys::ecc_curve_id_ECC_BRAINPOOLP256R1;
365+
pub const BRAINPOOLP320R1: i32 = sys::ecc_curve_id_ECC_BRAINPOOLP320R1;
366+
pub const BRAINPOOLP384R1: i32 = sys::ecc_curve_id_ECC_BRAINPOOLP384R1;
367+
pub const BRAINPOOLP512R1: i32 = sys::ecc_curve_id_ECC_BRAINPOOLP512R1;
368+
#[cfg(ecc_curve_sm2p256v1)]
369+
pub const SM2P256V1: i32 = sys::ecc_curve_id_ECC_SM2P256V1;
370+
#[cfg(ecc_curve_25519)]
371+
pub const X25519: i32 = sys::ecc_curve_id_ECC_X25519;
372+
#[cfg(ecc_curve_448)]
373+
pub const X448: i32 = sys::ecc_curve_id_ECC_X448;
374+
#[cfg(ecc_curve_sakke)]
375+
pub const SAKKE_1: i32 = sys::ecc_curve_id_ECC_SAKKE_1;
376+
#[cfg(ecc_custom_curves)]
377+
pub const CURVE_CUSTOM: i32 = sys::ecc_curve_id_ECC_CURVE_CUSTOM;
378+
pub const CURVE_MAX: i32 = sys::ecc_curve_id_ECC_CURVE_MAX;
379+
}
380+
381+
impl ECC {
334382
pub const FLAG_NONE: i32 = sys::WC_ECC_FLAG_NONE as i32;
335383
pub const FLAG_COFACTOR: i32 = sys::WC_ECC_FLAG_COFACTOR as i32;
336384
pub const FLAG_DEC_SIGN: i32 = sys::WC_ECC_FLAG_DEC_SIGN as i32;

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,12 @@ impl HMAC {
156156
/// # Example
157157
///
158158
/// ```rust
159+
/// #![cfg(hmac_setkey_ex)]
159160
/// use wolfssl_wolfcrypt::hmac::HMAC;
160161
/// let key = [0x42u8; 3];
161162
/// let mut hmac = HMAC::new_allow_short_key(HMAC::TYPE_SHA256, &key).expect("Error with new_allow_short_key()");
162163
/// ```
164+
#[cfg(hmac_setkey_ex)]
163165
pub fn new_allow_short_key(typ: i32, key: &[u8]) -> Result<Self, i32> {
164166
Self::new_allow_short_key_ex(typ, key, None, None)
165167
}
@@ -182,10 +184,12 @@ impl HMAC {
182184
/// # Example
183185
///
184186
/// ```rust
187+
/// #![cfg(hmac_setkey_ex)]
185188
/// use wolfssl_wolfcrypt::hmac::HMAC;
186189
/// let key = [0x42u8; 3];
187190
/// let mut hmac = HMAC::new_allow_short_key_ex(HMAC::TYPE_SHA256, &key, None, None).expect("Error with new_allow_short_key_ex()");
188191
/// ```
192+
#[cfg(hmac_setkey_ex)]
189193
pub fn new_allow_short_key_ex(typ: i32, key: &[u8], heap: Option<*mut std::os::raw::c_void>, dev_id: Option<i32>) -> Result<Self, i32> {
190194
let key_size = key.len() as u32;
191195
let mut wc_hmac: MaybeUninit<sys::Hmac> = MaybeUninit::uninit();

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

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@ impl RSA {
116116
pub const MGF1SHA256 : i32 = sys::WC_MGF1SHA256 as i32;
117117
pub const MGF1SHA384 : i32 = sys::WC_MGF1SHA384 as i32;
118118
pub const MGF1SHA512 : i32 = sys::WC_MGF1SHA512 as i32;
119+
#[cfg(rsa_mgf1sha512_224)]
119120
pub const MGF1SHA512_224 : i32 = sys::WC_MGF1SHA512_224 as i32;
121+
#[cfg(rsa_mgf1sha512_256)]
120122
pub const MGF1SHA512_256 : i32 = sys::WC_MGF1SHA512_256 as i32;
121123

122124
// Type constants used for `rsa_direct()`.
@@ -525,8 +527,12 @@ impl RSA {
525527
*d_size = d.len() as u32;
526528
*p_size = p.len() as u32;
527529
*q_size = q.len() as u32;
530+
#[cfg(rsa_const_api)]
531+
let key_ptr = &self.wc_rsakey;
532+
#[cfg(not(rsa_const_api))]
533+
let key_ptr = &mut self.wc_rsakey;
528534
let rc = unsafe {
529-
sys::wc_RsaExportKey(&self.wc_rsakey,
535+
sys::wc_RsaExportKey(key_ptr,
530536
e.as_mut_ptr(), e_size,
531537
n.as_mut_ptr(), n_size,
532538
d.as_mut_ptr(), d_size,
@@ -575,8 +581,12 @@ impl RSA {
575581
n: &mut [u8], n_size: &mut u32) -> Result<(), i32> {
576582
*e_size = e.len() as u32;
577583
*n_size = n.len() as u32;
584+
#[cfg(rsa_const_api)]
585+
let key = &self.wc_rsakey;
586+
#[cfg(not(rsa_const_api))]
587+
let key = &mut self.wc_rsakey;
578588
let rc = unsafe {
579-
sys::wc_RsaFlattenPublicKey(&self.wc_rsakey,
589+
sys::wc_RsaFlattenPublicKey(key,
580590
e.as_mut_ptr(), e_size, n.as_mut_ptr(), n_size)
581591
};
582592
if rc != 0 {
@@ -843,7 +853,7 @@ impl RSA {
843853
/// # Example
844854
///
845855
/// ```rust
846-
/// #[cfg(all(random, rsa_pss))]
856+
/// #[cfg(all(random, rsa_pss, rsa_const_api))]
847857
/// {
848858
/// use std::fs;
849859
/// use wolfssl_wolfcrypt::random::RNG;
@@ -873,7 +883,7 @@ impl RSA {
873883
/// rsa.pss_verify_check(signature, &mut verify_out, msg, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256).expect("Error with pss_verify_check()");
874884
/// }
875885
/// ```
876-
#[cfg(rsa_pss)]
886+
#[cfg(all(rsa_pss, rsa_const_api))]
877887
pub fn pss_check_padding(&mut self, din: &[u8], sig: &[u8], hash_algo: u32) -> Result<(), i32> {
878888
let din_size = din.len() as u32;
879889
let sig_size = sig.len() as u32;
@@ -909,7 +919,7 @@ impl RSA {
909919
/// # Example
910920
///
911921
/// ```rust
912-
/// #[cfg(all(random, rsa_pss))]
922+
/// #[cfg(all(random, rsa_pss, rsa_const_api))]
913923
/// {
914924
/// use std::fs;
915925
/// use wolfssl_wolfcrypt::random::RNG;
@@ -939,7 +949,7 @@ impl RSA {
939949
/// rsa.pss_verify_check(signature, &mut verify_out, msg, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256).expect("Error with pss_verify_check()");
940950
/// }
941951
/// ```
942-
#[cfg(rsa_pss)]
952+
#[cfg(all(rsa_pss, rsa_const_api))]
943953
pub fn pss_verify(&mut self, din: &[u8], dout: &mut [u8], hash_algo: u32, mgf: i32) -> Result<usize, i32> {
944954
let din_size = din.len() as u32;
945955
let dout_size = dout.len() as u32;
@@ -980,7 +990,7 @@ impl RSA {
980990
/// # Example
981991
///
982992
/// ```rust
983-
/// #[cfg(all(random, rsa_pss))]
993+
/// #[cfg(all(random, rsa_pss, rsa_const_api))]
984994
/// {
985995
/// use std::fs;
986996
/// use wolfssl_wolfcrypt::random::RNG;
@@ -1010,7 +1020,7 @@ impl RSA {
10101020
/// rsa.pss_verify_check(signature, &mut verify_out, msg, RSA::HASH_TYPE_SHA256, RSA::MGF1SHA256).expect("Error with pss_verify_check()");
10111021
/// }
10121022
/// ```
1013-
#[cfg(rsa_pss)]
1023+
#[cfg(all(rsa_pss, rsa_const_api))]
10141024
pub fn pss_verify_check(&mut self, din: &[u8], dout: &mut [u8], digest: &[u8], hash_algo: u32, mgf: i32) -> Result<usize, i32> {
10151025
let din_size = din.len() as u32;
10161026
let dout_size = dout.len() as u32;
@@ -1050,7 +1060,7 @@ impl RSA {
10501060
/// # Example
10511061
///
10521062
/// ```rust
1053-
/// #[cfg(rsa_direct)]
1063+
/// #[cfg(all(rsa_direct, rsa_const_api))]
10541064
/// {
10551065
/// use std::fs;
10561066
/// use wolfssl_wolfcrypt::random::RNG;
@@ -1073,7 +1083,7 @@ impl RSA {
10731083
/// assert_eq!(plain_out, plain);
10741084
/// }
10751085
/// ```
1076-
#[cfg(rsa_direct)]
1086+
#[cfg(all(rsa_direct, rsa_const_api))]
10771087
pub fn rsa_direct(&mut self, din: &[u8], dout: &mut [u8], typ: i32, rng: &mut RNG) -> Result<usize, i32> {
10781088
let din_size = din.len() as u32;
10791089
let mut dout_size = dout.len() as u32;

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,8 @@ include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
1717

1818
/* Include generated FIPS symbol aliases. */
1919
include!(concat!(env!("OUT_DIR"), "/fips_aliases.rs"));
20+
21+
#[cfg(not(rsa_setrng))]
22+
unsafe extern "C" {
23+
pub fn wc_RsaSetRNG(key: *mut RsaKey, rng: *mut WC_RNG) -> core::ffi::c_int;
24+
}

wrapper/rust/wolfssl-wolfcrypt/tests/test_hmac.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ fn test_hmac_sha256() {
3333
];
3434

3535
for i in 0..keys.len() {
36+
#[cfg(not(hmac_setkey_ex))]
37+
if keys[i].len() < 14 {
38+
continue;
39+
}
40+
#[cfg(not(hmac_setkey_ex))]
41+
let mut hmac = HMAC::new(HMAC::TYPE_SHA256, keys[i]).expect("Error with new()");
42+
#[cfg(hmac_setkey_ex)]
3643
let mut hmac =
3744
if keys[i].len() < 14 {
3845
HMAC::new_allow_short_key(HMAC::TYPE_SHA256, keys[i]).expect("Error with new_allow_short_key()")

0 commit comments

Comments
 (0)