diff --git a/wolfcrypt/src/kdf.c b/wolfcrypt/src/kdf.c index c6be3afc992..d8fcafbeff6 100644 --- a/wolfcrypt/src/kdf.c +++ b/wolfcrypt/src/kdf.c @@ -984,7 +984,7 @@ static int wc_srtp_kdf_derive_key(byte* block, int idxSz, byte label, * @param [in] saltSz Size of random in bytes. * @param [in] kdrIdx Key derivation rate. kdr = 0 when -1, otherwise * kdr = 2^kdrIdx. - * @param [in] index Index value to XOR in. + * @param [in] idx Index value to XOR in. * @param [out] key1 First key. Label value of 0x00. * @param [in] key1Sz Size of first key in bytes. * @param [out] key2 Second key. Label value of 0x01. @@ -1069,7 +1069,7 @@ int wc_SRTP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz, * @param [in] saltSz Size of random in bytes. * @param [in] kdrIdx Key derivation rate index. kdr = 0 when -1, otherwise * kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx() - * @param [in] index Index value to XOR in. + * @param [in] idx Index value to XOR in. * @param [out] key1 First key. Label value of 0x03. * @param [in] key1Sz Size of first key in bytes. * @param [out] key2 Second key. Label value of 0x04. @@ -1171,7 +1171,7 @@ int wc_SRTCP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz, * @param [in] saltSz Size of random in bytes. * @param [in] kdrIdx Key derivation rate index. kdr = 0 when -1, otherwise * kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx() - * @param [in] index Index value to XOR in. + * @param [in] idx Index value to XOR in. * @param [in] label Label to use when deriving key. * @param [out] outKey Derived key. * @param [in] outKeySz Size of derived key in bytes. @@ -1244,7 +1244,7 @@ int wc_SRTP_KDF_label(const byte* key, word32 keySz, const byte* salt, * @param [in] saltSz Size of random in bytes. * @param [in] kdrIdx Key derivation rate index. kdr = 0 when -1, otherwise * kdr = 2^kdrIdx. See wc_SRTP_KDF_kdr_to_idx() - * @param [in] index Index value to XOR in. + * @param [in] idx Index value to XOR in. * @param [in] label Label to use when deriving key. * @param [out] outKey Derived key. * @param [in] outKeySz Size of derived key in bytes. diff --git a/wrapper/rust/wolfssl-wolfcrypt/Cargo.lock b/wrapper/rust/wolfssl-wolfcrypt/Cargo.lock index 3a6dbadd24d..9fe8a696815 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/Cargo.lock +++ b/wrapper/rust/wolfssl-wolfcrypt/Cargo.lock @@ -393,4 +393,25 @@ dependencies = [ "cipher", "rand_core 0.10.0", "regex", + "zeroize", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] diff --git a/wrapper/rust/wolfssl-wolfcrypt/Cargo.toml b/wrapper/rust/wolfssl-wolfcrypt/Cargo.toml index 7dca3510e0f..08ee5ac62b2 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/Cargo.toml +++ b/wrapper/rust/wolfssl-wolfcrypt/Cargo.toml @@ -20,6 +20,7 @@ cipher = ["dep:cipher"] rand_core = { version = "0.10", optional = true, default-features = false } aead = { version = "0.5", optional = true, default-features = false } cipher = { version = "0.5", optional = true, default-features = false } +zeroize = { version = "1.3", default-features = false, features = ["derive"] } [dev-dependencies] aead = { version = "0.5", features = ["alloc", "dev"] } diff --git a/wrapper/rust/wolfssl-wolfcrypt/build.rs b/wrapper/rust/wolfssl-wolfcrypt/build.rs index da1b55d358a..6f275d3a3b5 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/build.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/build.rs @@ -461,8 +461,6 @@ fn scan_cfg() -> Result<()> { check_cfg(&binding, "DILITHIUM_LEVEL2_KEY_SIZE", "dilithium_level2"); check_cfg(&binding, "DILITHIUM_LEVEL3_KEY_SIZE", "dilithium_level3"); check_cfg(&binding, "DILITHIUM_LEVEL5_KEY_SIZE", "dilithium_level5"); - check_cfg(&binding, "DILITHIUM_SEED_SZ", "dilithium_make_key_seed_sz"); - check_cfg(&binding, "DILITHIUM_RND_SZ", "dilithium_rnd_sz"); /* mlkem / ML-KEM */ check_cfg(&binding, "wc_MlKemKey_Init", "mlkem"); diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/aes.rs b/wrapper/rust/wolfssl-wolfcrypt/src/aes.rs index 7b58b25f260..9aede174186 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/aes.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/aes.rs @@ -26,7 +26,8 @@ Encryption Standard (AES) functionality. #![cfg(aes)] use crate::sys; -use core::mem::{size_of_val, MaybeUninit}; +use core::mem::MaybeUninit; +use zeroize::{Zeroize, ZeroizeOnDrop}; #[cfg(feature = "aead")] use aead::{AeadCore, AeadInPlace, KeyInit, KeySizeUser}; @@ -44,8 +45,10 @@ use cipher::typenum::consts::U24; use cipher::{ BlockModeDecBackend, BlockModeDecClosure, BlockModeDecrypt, BlockModeEncBackend, BlockModeEncClosure, BlockModeEncrypt, - IvSizeUser, KeyIvInit, ParBlocksSizeUser, StreamCipher, StreamCipherError, + IvSizeUser, KeyIvInit, ParBlocksSizeUser, }; +#[cfg(all(any(aes_ctr, aes_ofb), feature = "cipher"))] +use cipher::{StreamCipher,StreamCipherError}; #[cfg(aes_wc_block_size)] pub const AES_BLOCK_SIZE: usize = sys::WC_AES_BLOCK_SIZE as usize; @@ -114,7 +117,7 @@ impl CBC { } fn init(&mut self, key: &[u8], iv: &[u8], dir: i32) -> Result<(), i32> { - let key_size = key.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; if iv.len() != AES_BLOCK_SIZE { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } @@ -181,16 +184,14 @@ impl CBC { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn encrypt(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn encrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesCbcEncrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) + sys::wc_AesCbcEncrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size) }; if rc != 0 { return Err(rc); @@ -213,16 +214,14 @@ impl CBC { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn decrypt(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn decrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesCbcDecrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) + sys::wc_AesCbcDecrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size) }; if rc != 0 { return Err(rc); @@ -231,10 +230,17 @@ impl CBC { } } #[cfg(aes_cbc)] +impl CBC { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.ws_aes); } + } +} +#[cfg(aes_cbc)] impl Drop for CBC { /// Safely free the wolfSSL resources. fn drop(&mut self) { unsafe { sys::wc_AesFree(&mut self.ws_aes); } + self.zeroize(); } } @@ -331,7 +337,7 @@ impl CCM { /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. pub fn init(&mut self, key: &[u8]) -> Result<(), i32> { - let key_size = key.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; let rc = unsafe { sys::wc_AesCcmSetKey(&mut self.ws_aes, key.as_ptr(), key_size) }; @@ -358,24 +364,19 @@ impl CCM { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn encrypt(&mut self, din: &[I], dout: &mut [O], nonce: &[N], auth: &[A], auth_tag: &mut [A]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; - let nonce_ptr = nonce.as_ptr() as *const u8; - let nonce_size = size_of_val(nonce) as u32; - let auth_ptr = auth.as_ptr() as *const u8; - let auth_size = size_of_val(auth) as u32; - let auth_tag_ptr = auth_tag.as_mut_ptr() as *mut u8; - let auth_tag_size = size_of_val(auth_tag) as u32; + pub fn encrypt(&mut self, din: &[u8], dout: &mut [u8], nonce: &[u8], auth: &[u8], auth_tag: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; + let nonce_size = crate::buffer_len_to_u32(nonce.len())?; + let auth_size = crate::buffer_len_to_u32(auth.len())?; + let auth_tag_size = crate::buffer_len_to_u32(auth_tag.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesCcmEncrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size, - nonce_ptr, nonce_size, auth_tag_ptr, auth_tag_size, - auth_ptr, auth_size) + sys::wc_AesCcmEncrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size, + nonce.as_ptr(), nonce_size, auth_tag.as_mut_ptr(), auth_tag_size, + auth.as_ptr(), auth_size) }; if rc != 0 { return Err(rc); @@ -400,24 +401,19 @@ impl CCM { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn decrypt(&mut self, din: &[I], dout: &mut [O], nonce: &[N], auth: &[A], auth_tag: &[A]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; - let nonce_ptr = nonce.as_ptr() as *const u8; - let nonce_size = size_of_val(nonce) as u32; - let auth_ptr = auth.as_ptr() as *const u8; - let auth_size = size_of_val(auth) as u32; - let auth_tag_ptr = auth_tag.as_ptr() as *const u8; - let auth_tag_size = size_of_val(auth_tag) as u32; + pub fn decrypt(&mut self, din: &[u8], dout: &mut [u8], nonce: &[u8], auth: &[u8], auth_tag: &[u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; + let nonce_size = crate::buffer_len_to_u32(nonce.len())?; + let auth_size = crate::buffer_len_to_u32(auth.len())?; + let auth_tag_size = crate::buffer_len_to_u32(auth_tag.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesCcmDecrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size, - nonce_ptr, nonce_size, auth_tag_ptr, auth_tag_size, - auth_ptr, auth_size) + sys::wc_AesCcmDecrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size, + nonce.as_ptr(), nonce_size, auth_tag.as_ptr(), auth_tag_size, + auth.as_ptr(), auth_size) }; if rc != 0 { return Err(rc); @@ -426,10 +422,17 @@ impl CCM { } } #[cfg(aes_ccm)] +impl CCM { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.ws_aes); } + } +} +#[cfg(aes_ccm)] impl Drop for CCM { /// Safely free the wolfSSL resources. fn drop(&mut self) { unsafe { sys::wc_AesFree(&mut self.ws_aes); } + self.zeroize(); } } @@ -446,6 +449,10 @@ fn ccm_encrypt_in_place( buffer: &mut [u8], tag: &mut [u8], ) -> Result<(), aead::Error> { + if buffer.len() > u32::MAX as usize || nonce.len() > u32::MAX as usize + || tag.len() > u32::MAX as usize || aad.len() > u32::MAX as usize { + return Err(aead::Error); + } let mut ccm = CCM::new().map_err(|_| aead::Error)?; ccm.init(key).map_err(|_| aead::Error)?; // wolfCrypt CCM supports in-place operation (out == in). @@ -475,6 +482,10 @@ fn ccm_decrypt_in_place( buffer: &mut [u8], tag: &[u8], ) -> Result<(), aead::Error> { + if buffer.len() > u32::MAX as usize || nonce.len() > u32::MAX as usize + || tag.len() > u32::MAX as usize || aad.len() > u32::MAX as usize { + return Err(aead::Error); + } let mut ccm = CCM::new().map_err(|_| aead::Error)?; ccm.init(key).map_err(|_| aead::Error)?; let buf_ptr = buffer.as_mut_ptr(); @@ -496,6 +507,7 @@ fn ccm_decrypt_in_place( /// AES-128-CCM authenticated encryption (12-byte nonce, 16-byte tag). #[cfg(all(aes_ccm, feature = "aead"))] +#[derive(Zeroize, ZeroizeOnDrop)] pub struct Aes128Ccm { key: [u8; 16], } @@ -547,6 +559,7 @@ impl AeadInPlace for Aes128Ccm { /// AES-256-CCM authenticated encryption (12-byte nonce, 16-byte tag). #[cfg(all(aes_ccm, feature = "aead"))] +#[derive(Zeroize, ZeroizeOnDrop)] pub struct Aes256Ccm { key: [u8; 32], } @@ -692,7 +705,7 @@ impl CFB { /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. pub fn init(&mut self, key: &[u8], iv: &[u8]) -> Result<(), i32> { - let key_size = key.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; if iv.len() != AES_BLOCK_SIZE { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } @@ -720,16 +733,14 @@ impl CFB { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn encrypt(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn encrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesCfbEncrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) + sys::wc_AesCfbEncrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size) }; if rc != 0 { return Err(rc); @@ -751,16 +762,14 @@ impl CFB { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn encrypt1(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn encrypt1(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesCfb1Encrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) + sys::wc_AesCfb1Encrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size) }; if rc != 0 { return Err(rc); @@ -782,16 +791,14 @@ impl CFB { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn encrypt8(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn encrypt8(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesCfb8Encrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) + sys::wc_AesCfb8Encrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size) }; if rc != 0 { return Err(rc); @@ -814,16 +821,14 @@ impl CFB { /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. #[cfg(aes_decrypt)] - pub fn decrypt(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn decrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesCfbDecrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) + sys::wc_AesCfbDecrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size) }; if rc != 0 { return Err(rc); @@ -846,16 +851,14 @@ impl CFB { /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. #[cfg(aes_decrypt)] - pub fn decrypt1(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn decrypt1(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesCfb1Decrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) + sys::wc_AesCfb1Decrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size) }; if rc != 0 { return Err(rc); @@ -878,16 +881,14 @@ impl CFB { /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. #[cfg(aes_decrypt)] - pub fn decrypt8(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn decrypt8(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesCfb8Decrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) + sys::wc_AesCfb8Decrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size) }; if rc != 0 { return Err(rc); @@ -896,10 +897,17 @@ impl CFB { } } #[cfg(aes_cfb)] +impl CFB { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.ws_aes); } + } +} +#[cfg(aes_cfb)] impl Drop for CFB { /// Safely free the wolfSSL resources. fn drop(&mut self) { unsafe { sys::wc_AesFree(&mut self.ws_aes); } + self.zeroize(); } } @@ -998,7 +1006,7 @@ impl CTR { /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. pub fn init(&mut self, key: &[u8], iv: &[u8]) -> Result<(), i32> { - let key_size = key.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; if iv.len() != AES_BLOCK_SIZE { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } @@ -1012,16 +1020,14 @@ impl CTR { Ok(()) } - fn encrypt_decrypt(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + fn encrypt_decrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesCtrEncrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) + sys::wc_AesCtrEncrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size) }; if rc != 0 { return Err(rc); @@ -1043,7 +1049,7 @@ impl CTR { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn encrypt(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { + pub fn encrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { self.encrypt_decrypt(din, dout) } @@ -1061,15 +1067,22 @@ impl CTR { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn decrypt(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { + pub fn decrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { self.encrypt_decrypt(din, dout) } } #[cfg(aes_ctr)] +impl CTR { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.ws_aes); } + } +} +#[cfg(aes_ctr)] impl Drop for CTR { /// Safely free the wolfSSL resources. fn drop(&mut self) { unsafe { sys::wc_AesFree(&mut self.ws_aes); } + self.zeroize(); } } @@ -1137,22 +1150,20 @@ impl EAX { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn encrypt(din: &[I], dout: &mut [O], key: &[u8], nonce: &[u8], + pub fn encrypt(din: &[u8], dout: &mut [u8], key: &[u8], nonce: &[u8], auth: &[u8], auth_tag: &mut [u8]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; - let key_size = key.len() as u32; - let nonce_size = nonce.len() as u32; - let auth_size = auth.len() as u32; - let auth_tag_size = auth_tag.len() as u32; + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; + let key_size = crate::buffer_len_to_u32(key.len())?; + let nonce_size = crate::buffer_len_to_u32(nonce.len())?; + let auth_size = crate::buffer_len_to_u32(auth.len())?; + let auth_tag_size = crate::buffer_len_to_u32(auth_tag.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesEaxEncryptAuth(key.as_ptr(), key_size, out_ptr, - in_ptr, in_size, nonce.as_ptr(), nonce_size, + sys::wc_AesEaxEncryptAuth(key.as_ptr(), key_size, dout.as_mut_ptr(), + din.as_ptr(), in_size, nonce.as_ptr(), nonce_size, auth_tag.as_mut_ptr(), auth_tag_size, auth.as_ptr(), auth_size) }; if rc != 0 { @@ -1178,22 +1189,20 @@ impl EAX { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn decrypt(din: &[I], dout: &mut [O], key: &[u8], nonce: &[u8], + pub fn decrypt(din: &[u8], dout: &mut [u8], key: &[u8], nonce: &[u8], auth: &[u8], auth_tag: &[u8]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; - let key_size = key.len() as u32; - let nonce_size = nonce.len() as u32; - let auth_size = auth.len() as u32; - let auth_tag_size = auth_tag.len() as u32; + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; + let key_size = crate::buffer_len_to_u32(key.len())?; + let nonce_size = crate::buffer_len_to_u32(nonce.len())?; + let auth_size = crate::buffer_len_to_u32(auth.len())?; + let auth_tag_size = crate::buffer_len_to_u32(auth_tag.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesEaxDecryptAuth(key.as_ptr(), key_size, out_ptr, - in_ptr, in_size, nonce.as_ptr(), nonce_size, + sys::wc_AesEaxDecryptAuth(key.as_ptr(), key_size, dout.as_mut_ptr(), + din.as_ptr(), in_size, nonce.as_ptr(), nonce_size, auth_tag.as_ptr(), auth_tag_size, auth.as_ptr(), auth_size) }; if rc != 0 { @@ -1264,7 +1273,7 @@ impl ECB { } fn init(&mut self, key: &[u8], dir: i32) -> Result<(), i32> { - let key_size = key.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; let rc = unsafe { sys::wc_AesSetKey(&mut self.ws_aes, key.as_ptr(), key_size, core::ptr::null(), dir) @@ -1324,16 +1333,14 @@ impl ECB { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn encrypt(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn encrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesEcbEncrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) + sys::wc_AesEcbEncrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size) }; if rc != 0 { return Err(rc); @@ -1356,16 +1363,14 @@ impl ECB { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn decrypt(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn decrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesEcbDecrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) + sys::wc_AesEcbDecrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size) }; if rc != 0 { return Err(rc); @@ -1374,10 +1379,17 @@ impl ECB { } } #[cfg(aes_ecb)] +impl ECB { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.ws_aes); } + } +} +#[cfg(aes_ecb)] impl Drop for ECB { /// Safely free the wolfSSL resources. fn drop(&mut self) { unsafe { sys::wc_AesFree(&mut self.ws_aes); } + self.zeroize(); } } @@ -1478,7 +1490,7 @@ impl GCM { /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. pub fn init(&mut self, key: &[u8]) -> Result<(), i32> { - let key_size = key.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; let rc = unsafe { sys::wc_AesGcmSetKey(&mut self.ws_aes, key.as_ptr(), key_size) }; @@ -1505,20 +1517,18 @@ impl GCM { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn encrypt(&mut self, din: &[I], dout: &mut [O], iv: &[u8], + pub fn encrypt(&mut self, din: &[u8], dout: &mut [u8], iv: &[u8], auth: &[u8], auth_tag: &mut [u8]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; - let iv_size = iv.len() as u32; - let auth_size = auth.len() as u32; - let auth_tag_size = auth_tag.len() as u32; + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; + let iv_size = crate::buffer_len_to_u32(iv.len())?; + let auth_size = crate::buffer_len_to_u32(auth.len())?; + let auth_tag_size = crate::buffer_len_to_u32(auth_tag.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesGcmEncrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size, + sys::wc_AesGcmEncrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size, iv.as_ptr(), iv_size, auth_tag.as_mut_ptr(), auth_tag_size, auth.as_ptr(), auth_size) }; @@ -1545,20 +1555,18 @@ impl GCM { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn decrypt(&mut self, din: &[I], dout: &mut [O], iv: &[u8], + pub fn decrypt(&mut self, din: &[u8], dout: &mut [u8], iv: &[u8], auth: &[u8], auth_tag: &[u8]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; - let iv_size = iv.len() as u32; - let auth_size = auth.len() as u32; - let auth_tag_size = auth_tag.len() as u32; + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; + let iv_size = crate::buffer_len_to_u32(iv.len())?; + let auth_size = crate::buffer_len_to_u32(auth.len())?; + let auth_tag_size = crate::buffer_len_to_u32(auth_tag.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesGcmDecrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size, + sys::wc_AesGcmDecrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size, iv.as_ptr(), iv_size, auth_tag.as_ptr(), auth_tag_size, auth.as_ptr(), auth_size) }; @@ -1569,10 +1577,17 @@ impl GCM { } } #[cfg(aes_gcm)] +impl GCM { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.ws_aes); } + } +} +#[cfg(aes_gcm)] impl Drop for GCM { /// Safely free the wolfSSL resources. fn drop(&mut self) { unsafe { sys::wc_AesFree(&mut self.ws_aes); } + self.zeroize(); } } @@ -1591,6 +1606,10 @@ fn gcm_encrypt_in_place( buffer: &mut [u8], tag: &mut [u8], ) -> Result<(), aead::Error> { + if buffer.len() > u32::MAX as usize || nonce.len() > u32::MAX as usize + || tag.len() > u32::MAX as usize || aad.len() > u32::MAX as usize { + return Err(aead::Error); + } let mut gcm = GCM::new().map_err(|_| aead::Error)?; gcm.init(key).map_err(|_| aead::Error)?; let buf_ptr = buffer.as_mut_ptr(); @@ -1619,6 +1638,10 @@ fn gcm_decrypt_in_place( buffer: &mut [u8], tag: &[u8], ) -> Result<(), aead::Error> { + if buffer.len() > u32::MAX as usize || nonce.len() > u32::MAX as usize + || tag.len() > u32::MAX as usize || aad.len() > u32::MAX as usize { + return Err(aead::Error); + } let mut gcm = GCM::new().map_err(|_| aead::Error)?; gcm.init(key).map_err(|_| aead::Error)?; let buf_ptr = buffer.as_mut_ptr(); @@ -1640,6 +1663,7 @@ fn gcm_decrypt_in_place( /// AES-128-GCM authenticated encryption (12-byte nonce, 16-byte tag). #[cfg(all(aes_gcm, feature = "aead"))] +#[derive(Zeroize, ZeroizeOnDrop)] pub struct Aes128Gcm { key: [u8; 16], } @@ -1691,6 +1715,7 @@ impl AeadInPlace for Aes128Gcm { /// AES-256-GCM authenticated encryption (12-byte nonce, 16-byte tag). #[cfg(all(aes_gcm, feature = "aead"))] +#[derive(Zeroize, ZeroizeOnDrop)] pub struct Aes256Gcm { key: [u8; 32], } @@ -1867,8 +1892,8 @@ impl GCMStream { /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. pub fn init(&mut self, key: &[u8], iv: &[u8]) -> Result<(), i32> { - let key_size = key.len() as u32; - let iv_size = iv.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; + let iv_size = crate::buffer_len_to_u32(iv.len())?; let rc = unsafe { sys::wc_AesGcmInit(&mut self.ws_aes, key.as_ptr(), key_size, iv.as_ptr(), iv_size) @@ -1900,19 +1925,17 @@ impl GCMStream { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn encrypt_update(&mut self, din: &[I], dout: &mut [O], + pub fn encrypt_update(&mut self, din: &[u8], dout: &mut [u8], auth: &[u8]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; - let auth_size = auth.len() as u32; + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; + let auth_size = crate::buffer_len_to_u32(auth.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesGcmEncryptUpdate(&mut self.ws_aes, out_ptr, - in_ptr, in_size, auth.as_ptr(), auth_size) + sys::wc_AesGcmEncryptUpdate(&mut self.ws_aes, dout.as_mut_ptr(), + din.as_ptr(), in_size, auth.as_ptr(), auth_size) }; if rc != 0 { return Err(rc); @@ -1936,7 +1959,7 @@ impl GCMStream { /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. pub fn encrypt_final(&mut self, auth_tag: &mut [u8]) -> Result<(), i32> { - let auth_tag_size = auth_tag.len() as u32; + let auth_tag_size = crate::buffer_len_to_u32(auth_tag.len())?; let rc = unsafe { sys::wc_AesGcmEncryptFinal(&mut self.ws_aes, auth_tag.as_mut_ptr(), auth_tag_size) @@ -1968,19 +1991,17 @@ impl GCMStream { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn decrypt_update(&mut self, din: &[I], dout: &mut [O], + pub fn decrypt_update(&mut self, din: &[u8], dout: &mut [u8], auth: &[u8]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; - let auth_size = auth.len() as u32; + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; + let auth_size = crate::buffer_len_to_u32(auth.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesGcmDecryptUpdate(&mut self.ws_aes, out_ptr, - in_ptr, in_size, auth.as_ptr(), auth_size) + sys::wc_AesGcmDecryptUpdate(&mut self.ws_aes, dout.as_mut_ptr(), + din.as_ptr(), in_size, auth.as_ptr(), auth_size) }; if rc != 0 { return Err(rc); @@ -2004,7 +2025,7 @@ impl GCMStream { /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. pub fn decrypt_final(&mut self, auth_tag: &[u8]) -> Result<(), i32> { - let auth_tag_size = auth_tag.len() as u32; + let auth_tag_size = crate::buffer_len_to_u32(auth_tag.len())?; let rc = unsafe { sys::wc_AesGcmDecryptFinal(&mut self.ws_aes, auth_tag.as_ptr(), auth_tag_size) @@ -2016,10 +2037,17 @@ impl GCMStream { } } #[cfg(aes_gcm_stream)] +impl GCMStream { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.ws_aes); } + } +} +#[cfg(aes_gcm_stream)] impl Drop for GCMStream { /// Safely free the wolfSSL resources. fn drop(&mut self) { unsafe { sys::wc_AesFree(&mut self.ws_aes); } + self.zeroize(); } } @@ -2119,7 +2147,7 @@ impl OFB { /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. pub fn init(&mut self, key: &[u8], iv: &[u8]) -> Result<(), i32> { - let key_size = key.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; if iv.len() != AES_BLOCK_SIZE { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } @@ -2147,16 +2175,14 @@ impl OFB { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn encrypt(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn encrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesOfbEncrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) + sys::wc_AesOfbEncrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size) }; if rc != 0 { return Err(rc); @@ -2179,16 +2205,14 @@ impl OFB { /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. #[cfg(aes_decrypt)] - pub fn decrypt(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn decrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesOfbDecrypt(&mut self.ws_aes, out_ptr, in_ptr, in_size) + sys::wc_AesOfbDecrypt(&mut self.ws_aes, dout.as_mut_ptr(), din.as_ptr(), in_size) }; if rc != 0 { return Err(rc); @@ -2197,10 +2221,17 @@ impl OFB { } } #[cfg(aes_ofb)] +impl OFB { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.ws_aes); } + } +} +#[cfg(aes_ofb)] impl Drop for OFB { /// Safely free the wolfSSL resources. fn drop(&mut self) { unsafe { sys::wc_AesFree(&mut self.ws_aes); } + self.zeroize(); } } @@ -2298,7 +2329,7 @@ impl XTS { } fn init(&mut self, key: &[u8], dir: i32) -> Result<(), i32> { - let key_size = key.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; let rc = unsafe { sys::wc_AesXtsSetKeyNoInit(&mut self.ws_xtsaes, key.as_ptr(), key_size, dir) @@ -2358,18 +2389,16 @@ impl XTS { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn encrypt(&mut self, din: &[I], dout: &mut [O], tweak: &[u8]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; - let tweak_size = tweak.len() as u32; + pub fn encrypt(&mut self, din: &[u8], dout: &mut [u8], tweak: &[u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; + let tweak_size = crate::buffer_len_to_u32(tweak.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesXtsEncrypt(&mut self.ws_xtsaes, out_ptr, - in_ptr, in_size, tweak.as_ptr(), tweak_size) + sys::wc_AesXtsEncrypt(&mut self.ws_xtsaes, dout.as_mut_ptr(), + din.as_ptr(), in_size, tweak.as_ptr(), tweak_size) }; if rc != 0 { return Err(rc); @@ -2397,17 +2426,15 @@ impl XTS { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn encrypt_sector(&mut self, din: &[I], dout: &mut [O], sector: u64) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn encrypt_sector(&mut self, din: &[u8], dout: &mut [u8], sector: u64) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesXtsEncryptSector(&mut self.ws_xtsaes, out_ptr, - in_ptr, in_size, sector) + sys::wc_AesXtsEncryptSector(&mut self.ws_xtsaes, dout.as_mut_ptr(), + din.as_ptr(), in_size, sector) }; if rc != 0 { return Err(rc); @@ -2436,18 +2463,16 @@ impl XTS { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn encrypt_consecutive_sectors(&mut self, din: &[I], dout: &mut [O], + pub fn encrypt_consecutive_sectors(&mut self, din: &[u8], dout: &mut [u8], sector: u64, sector_size: u32) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { sys::wc_AesXtsEncryptConsecutiveSectors(&mut self.ws_xtsaes, - out_ptr, in_ptr, in_size, sector, sector_size) + dout.as_mut_ptr(), din.as_ptr(), in_size, sector, sector_size) }; if rc != 0 { return Err(rc); @@ -2470,18 +2495,16 @@ impl XTS { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn decrypt(&mut self, din: &[I], dout: &mut [O], tweak: &[u8]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; - let tweak_size = tweak.len() as u32; + pub fn decrypt(&mut self, din: &[u8], dout: &mut [u8], tweak: &[u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; + let tweak_size = crate::buffer_len_to_u32(tweak.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesXtsDecrypt(&mut self.ws_xtsaes, out_ptr, - in_ptr, in_size, tweak.as_ptr(), tweak_size) + sys::wc_AesXtsDecrypt(&mut self.ws_xtsaes, dout.as_mut_ptr(), + din.as_ptr(), in_size, tweak.as_ptr(), tweak_size) }; if rc != 0 { return Err(rc); @@ -2509,17 +2532,15 @@ impl XTS { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn decrypt_sector(&mut self, din: &[I], dout: &mut [O], sector: u64) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn decrypt_sector(&mut self, din: &[u8], dout: &mut [u8], sector: u64) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesXtsDecryptSector(&mut self.ws_xtsaes, out_ptr, - in_ptr, in_size, sector) + sys::wc_AesXtsDecryptSector(&mut self.ws_xtsaes, dout.as_mut_ptr(), + din.as_ptr(), in_size, sector) }; if rc != 0 { return Err(rc); @@ -2548,18 +2569,16 @@ impl XTS { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn decrypt_consecutive_sectors(&mut self, din: &[I], dout: &mut [O], + pub fn decrypt_consecutive_sectors(&mut self, din: &[u8], dout: &mut [u8], sector: u64, sector_size: u32) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_mut_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { sys::wc_AesXtsDecryptConsecutiveSectors(&mut self.ws_xtsaes, - out_ptr, in_ptr, in_size, sector, sector_size) + dout.as_mut_ptr(), din.as_ptr(), in_size, sector, sector_size) }; if rc != 0 { return Err(rc); @@ -2568,10 +2587,17 @@ impl XTS { } } #[cfg(aes_xts)] +impl XTS { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.ws_xtsaes); } + } +} +#[cfg(aes_xts)] impl Drop for XTS { /// Safely free the wolfSSL resources. fn drop(&mut self) { unsafe { sys::wc_AesXtsFree(&mut self.ws_xtsaes); } + self.zeroize(); } } @@ -2655,7 +2681,7 @@ impl XTSStream { /// wolfSSL library return code on failure. pub fn new_ex(heap: Option<*mut core::ffi::c_void>, dev_id: Option) -> Result { let ws_xtsaes = new_ws_xtsaes(heap, dev_id)?; - let ws_xtsaesstreamdata: MaybeUninit = MaybeUninit::uninit(); + let ws_xtsaesstreamdata: MaybeUninit = MaybeUninit::zeroed(); let ws_xtsaesstreamdata = unsafe { ws_xtsaesstreamdata.assume_init() }; let xtsstream = XTSStream {ws_xtsaes, ws_xtsaesstreamdata}; Ok(xtsstream) @@ -2676,7 +2702,7 @@ impl XTSStream { /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. pub fn init_encrypt(&mut self, key: &[u8], tweak: &[u8]) -> Result<(), i32> { - let key_size = key.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; let rc = unsafe { sys::wc_AesXtsSetKeyNoInit(&mut self.ws_xtsaes, key.as_ptr(), key_size, sys::AES_ENCRYPTION as i32) @@ -2684,7 +2710,7 @@ impl XTSStream { if rc != 0 { return Err(rc); } - let tweak_size = tweak.len() as u32; + let tweak_size = crate::buffer_len_to_u32(tweak.len())?; let rc = unsafe { sys::wc_AesXtsEncryptInit(&mut self.ws_xtsaes, tweak.as_ptr(), tweak_size, &mut self.ws_xtsaesstreamdata) @@ -2710,7 +2736,7 @@ impl XTSStream { /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. pub fn init_decrypt(&mut self, key: &[u8], tweak: &[u8]) -> Result<(), i32> { - let key_size = key.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; let rc = unsafe { sys::wc_AesXtsSetKeyNoInit(&mut self.ws_xtsaes, key.as_ptr(), key_size, sys::AES_DECRYPTION as i32) @@ -2718,7 +2744,7 @@ impl XTSStream { if rc != 0 { return Err(rc); } - let tweak_size = tweak.len() as u32; + let tweak_size = crate::buffer_len_to_u32(tweak.len())?; let rc = unsafe { sys::wc_AesXtsDecryptInit(&mut self.ws_xtsaes, tweak.as_ptr(), tweak_size, &mut self.ws_xtsaesstreamdata) @@ -2747,17 +2773,15 @@ impl XTSStream { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn encrypt_update(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn encrypt_update(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesXtsEncryptUpdate(&mut self.ws_xtsaes, out_ptr, - in_ptr, in_size, &mut self.ws_xtsaesstreamdata) + sys::wc_AesXtsEncryptUpdate(&mut self.ws_xtsaes, dout.as_mut_ptr(), + din.as_ptr(), in_size, &mut self.ws_xtsaesstreamdata) }; if rc != 0 { return Err(rc); @@ -2782,17 +2806,15 @@ impl XTSStream { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn encrypt_final(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn encrypt_final(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesXtsEncryptFinal(&mut self.ws_xtsaes, out_ptr, - in_ptr, in_size, &mut self.ws_xtsaesstreamdata) + sys::wc_AesXtsEncryptFinal(&mut self.ws_xtsaes, dout.as_mut_ptr(), + din.as_ptr(), in_size, &mut self.ws_xtsaesstreamdata) }; if rc != 0 { return Err(rc); @@ -2818,17 +2840,15 @@ impl XTSStream { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn decrypt_update(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn decrypt_update(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesXtsDecryptUpdate(&mut self.ws_xtsaes, out_ptr, - in_ptr, in_size, &mut self.ws_xtsaesstreamdata) + sys::wc_AesXtsDecryptUpdate(&mut self.ws_xtsaes, dout.as_mut_ptr(), + din.as_ptr(), in_size, &mut self.ws_xtsaesstreamdata) }; if rc != 0 { return Err(rc); @@ -2853,17 +2873,15 @@ impl XTSStream { /// /// A Result which is Ok(()) on success or an Err containing the wolfSSL /// library return code on failure. - pub fn decrypt_final(&mut self, din: &[I], dout: &mut [O]) -> Result<(), i32> { - let in_ptr = din.as_ptr() as *const u8; - let in_size = size_of_val(din) as u32; - let out_ptr = dout.as_ptr() as *mut u8; - let out_size = size_of_val(dout) as u32; + pub fn decrypt_final(&mut self, din: &[u8], dout: &mut [u8]) -> Result<(), i32> { + let in_size = crate::buffer_len_to_u32(din.len())?; + let out_size = crate::buffer_len_to_u32(dout.len())?; if in_size != out_size { return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); } let rc = unsafe { - sys::wc_AesXtsDecryptFinal(&mut self.ws_xtsaes, out_ptr, - in_ptr, in_size, &mut self.ws_xtsaesstreamdata) + sys::wc_AesXtsDecryptFinal(&mut self.ws_xtsaes, dout.as_mut_ptr(), + din.as_ptr(), in_size, &mut self.ws_xtsaesstreamdata) }; if rc != 0 { return Err(rc); @@ -2872,10 +2890,17 @@ impl XTSStream { } } #[cfg(aes_xts_stream)] +impl XTSStream { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.ws_xtsaes); } + } +} +#[cfg(aes_xts_stream)] impl Drop for XTSStream { /// Safely free the wolfSSL resources. fn drop(&mut self) { unsafe { sys::wc_AesXtsFree(&mut self.ws_xtsaes); } + self.zeroize(); } } @@ -3254,6 +3279,7 @@ impl StreamCipher for Aes128Ctr { fn unchecked_apply_keystream_inout(&mut self, mut buf: cipher::InOutBuf<'_, '_, u8>) { let len = buf.len(); if len == 0 { return; } + assert!(len <= u32::MAX as usize, "buffer too large for wc_AesCtrEncrypt"); // wolfCrypt AES-CTR supports in-place operation (out == in). let in_ptr = buf.get_in().as_ptr(); let out_ptr = buf.get_out().as_mut_ptr(); @@ -3303,6 +3329,7 @@ impl StreamCipher for Aes192Ctr { fn unchecked_apply_keystream_inout(&mut self, mut buf: cipher::InOutBuf<'_, '_, u8>) { let len = buf.len(); if len == 0 { return; } + assert!(len <= u32::MAX as usize, "buffer too large for wc_AesCtrEncrypt"); let in_ptr = buf.get_in().as_ptr(); let out_ptr = buf.get_out().as_mut_ptr(); // SAFETY: CTR in-place is valid; C function called directly to avoid @@ -3351,6 +3378,7 @@ impl StreamCipher for Aes256Ctr { fn unchecked_apply_keystream_inout(&mut self, mut buf: cipher::InOutBuf<'_, '_, u8>) { let len = buf.len(); if len == 0 { return; } + assert!(len <= u32::MAX as usize, "buffer too large for wc_AesCtrEncrypt"); let in_ptr = buf.get_in().as_ptr(); let out_ptr = buf.get_out().as_mut_ptr(); // SAFETY: CTR in-place is valid; C function called directly to avoid @@ -3407,6 +3435,7 @@ impl StreamCipher for Aes128Ofb { fn unchecked_apply_keystream_inout(&mut self, mut buf: cipher::InOutBuf<'_, '_, u8>) { let len = buf.len(); if len == 0 { return; } + assert!(len <= u32::MAX as usize, "buffer too large for wc_AesOfbEncrypt"); // wolfCrypt AES-OFB supports in-place operation (out == in). let in_ptr = buf.get_in().as_ptr(); let out_ptr = buf.get_out().as_mut_ptr(); @@ -3456,6 +3485,7 @@ impl StreamCipher for Aes192Ofb { fn unchecked_apply_keystream_inout(&mut self, mut buf: cipher::InOutBuf<'_, '_, u8>) { let len = buf.len(); if len == 0 { return; } + assert!(len <= u32::MAX as usize, "buffer too large for wc_AesOfbEncrypt"); let in_ptr = buf.get_in().as_ptr(); let out_ptr = buf.get_out().as_mut_ptr(); // SAFETY: OFB in-place is valid; C function called directly to avoid @@ -3504,6 +3534,7 @@ impl StreamCipher for Aes256Ofb { fn unchecked_apply_keystream_inout(&mut self, mut buf: cipher::InOutBuf<'_, '_, u8>) { let len = buf.len(); if len == 0 { return; } + assert!(len <= u32::MAX as usize, "buffer too large for wc_AesOfbEncrypt"); let in_ptr = buf.get_in().as_ptr(); let out_ptr = buf.get_out().as_mut_ptr(); // SAFETY: OFB in-place is valid; C function called directly to avoid diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/blake2.rs b/wrapper/rust/wolfssl-wolfcrypt/src/blake2.rs index 3afef945971..a357088f1e2 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/blake2.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/blake2.rs @@ -54,7 +54,7 @@ impl BLAKE2b { /// let blake2b = BLAKE2b::new(64).expect("Error with new()"); /// ``` pub fn new(digest_size: usize) -> Result { - let digest_size = digest_size as u32; + let digest_size = crate::buffer_len_to_u32(digest_size)?; let mut wc_blake2b: MaybeUninit = MaybeUninit::uninit(); let rc = unsafe { sys::wc_InitBlake2b(wc_blake2b.as_mut_ptr(), digest_size) @@ -87,9 +87,9 @@ impl BLAKE2b { /// let blake2b = BLAKE2b::new_with_key(64, &key).expect("Error with new()"); /// ``` pub fn new_with_key(digest_size: usize, key: &[u8]) -> Result { - let digest_size = digest_size as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; + let digest_size = crate::buffer_len_to_u32(digest_size)?; let mut wc_blake2b: MaybeUninit = MaybeUninit::uninit(); - let key_size = key.len() as u32; let rc = unsafe { sys::wc_InitBlake2b_WithKey(wc_blake2b.as_mut_ptr(), digest_size, key.as_ptr(), key_size) @@ -124,7 +124,7 @@ impl BLAKE2b { /// blake2b.update(&[0u8; 16]).expect("Error with update()"); /// ``` pub fn update(&mut self, data: &[u8]) -> Result<(), i32> { - let data_size = data.len() as u32; + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { sys::wc_Blake2bUpdate(&mut self.wc_blake2b, data.as_ptr(), data_size) }; @@ -156,7 +156,13 @@ impl BLAKE2b { /// blake2b.finalize(&mut hash).expect("Error with finalize()"); /// ``` pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> { - let hash_size = hash.len() as u32; + let hash_size = crate::buffer_len_to_u32(hash.len())?; + if hash_size == 0 { + // The C function uses the internal state configured digest size + // if hash_size is passed in as 0. We do not want to allow a + // buffer overrun, so do not allow an empty hash buffer here. + return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); + } let rc = unsafe { sys::wc_Blake2bFinal(&mut self.wc_blake2b, hash.as_mut_ptr(), hash_size) }; @@ -168,6 +174,20 @@ impl BLAKE2b { } +#[cfg(blake2b)] +impl BLAKE2b { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_blake2b); } + } +} + +#[cfg(blake2b)] +impl Drop for BLAKE2b { + fn drop(&mut self) { + self.zeroize(); + } +} + /// Context for HMAC-BLAKE2b computation. #[cfg(blake2b_hmac)] pub struct BLAKE2bHmac { @@ -305,6 +325,20 @@ impl BLAKE2bHmac { } +#[cfg(blake2b_hmac)] +impl BLAKE2bHmac { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_blake2b); } + } +} + +#[cfg(blake2b_hmac)] +impl Drop for BLAKE2bHmac { + fn drop(&mut self) { + self.zeroize(); + } +} + /// Context for BLAKE2s computation. #[cfg(blake2s)] pub struct BLAKE2s { @@ -331,7 +365,7 @@ impl BLAKE2s { /// let blake2s = BLAKE2s::new(32).expect("Error with new()"); /// ``` pub fn new(digest_size: usize) -> Result { - let digest_size = digest_size as u32; + let digest_size = crate::buffer_len_to_u32(digest_size)?; let mut wc_blake2s: MaybeUninit = MaybeUninit::uninit(); let rc = unsafe { sys::wc_InitBlake2s(wc_blake2s.as_mut_ptr(), digest_size) @@ -364,9 +398,9 @@ impl BLAKE2s { /// let blake2s = BLAKE2s::new_with_key(32, &key).expect("Error with new()"); /// ``` pub fn new_with_key(digest_size: usize, key: &[u8]) -> Result { - let digest_size = digest_size as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; + let digest_size = crate::buffer_len_to_u32(digest_size)?; let mut wc_blake2s: MaybeUninit = MaybeUninit::uninit(); - let key_size = key.len() as u32; let rc = unsafe { sys::wc_InitBlake2s_WithKey(wc_blake2s.as_mut_ptr(), digest_size, key.as_ptr(), key_size) @@ -401,7 +435,7 @@ impl BLAKE2s { /// blake2s.update(&[0u8; 16]).expect("Error with update()"); /// ``` pub fn update(&mut self, data: &[u8]) -> Result<(), i32> { - let data_size = data.len() as u32; + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { sys::wc_Blake2sUpdate(&mut self.wc_blake2s, data.as_ptr(), data_size) }; @@ -433,7 +467,13 @@ impl BLAKE2s { /// blake2s.finalize(&mut hash).expect("Error with finalize()"); /// ``` pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> { - let hash_size = hash.len() as u32; + let hash_size = crate::buffer_len_to_u32(hash.len())?; + if hash_size == 0 { + // The C function uses the internal state configured digest size + // if hash_size is passed in as 0. We do not want to allow a + // buffer overrun, so do not allow an empty hash buffer here. + return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); + } let rc = unsafe { sys::wc_Blake2sFinal(&mut self.wc_blake2s, hash.as_mut_ptr(), hash_size) }; @@ -445,6 +485,20 @@ impl BLAKE2s { } +#[cfg(blake2s)] +impl BLAKE2s { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_blake2s); } + } +} + +#[cfg(blake2s)] +impl Drop for BLAKE2s { + fn drop(&mut self) { + self.zeroize(); + } +} + /// Context for HMAC-BLAKE2s computation. #[cfg(blake2s_hmac)] pub struct BLAKE2sHmac { @@ -580,3 +634,17 @@ impl BLAKE2sHmac { Ok(()) } } + +#[cfg(blake2s_hmac)] +impl BLAKE2sHmac { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_blake2s); } + } +} + +#[cfg(blake2s_hmac)] +impl Drop for BLAKE2sHmac { + fn drop(&mut self) { + self.zeroize(); + } +} diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/chacha20_poly1305.rs b/wrapper/rust/wolfssl-wolfcrypt/src/chacha20_poly1305.rs index a7002eef0e0..ae4e69b8334 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/chacha20_poly1305.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/chacha20_poly1305.rs @@ -27,6 +27,7 @@ ChaCha20-Poly1305 functionality. use crate::sys; use core::mem::MaybeUninit; +use zeroize::{Zeroize, ZeroizeOnDrop}; pub struct ChaCha20Poly1305 { wc_ccp: sys::ChaChaPoly_Aead, @@ -73,8 +74,8 @@ impl ChaCha20Poly1305 { if auth_tag.len() != Self::AUTH_TAG_SIZE { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } - let aad_size = aad.len() as u32; - let ciphertext_size = ciphertext.len() as u32; + let aad_size = crate::buffer_len_to_u32(aad.len())?; + let ciphertext_size = crate::buffer_len_to_u32(ciphertext.len())?; let rc = unsafe { sys::wc_ChaCha20Poly1305_Decrypt(key.as_ptr(), iv.as_ptr(), aad.as_ptr(), aad_size, ciphertext.as_ptr(), @@ -115,8 +116,8 @@ impl ChaCha20Poly1305 { if auth_tag.len() != Self::AUTH_TAG_SIZE { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } - let aad_size = aad.len() as u32; - let plaintext_size = plaintext.len() as u32; + let aad_size = crate::buffer_len_to_u32(aad.len())?; + let plaintext_size = crate::buffer_len_to_u32(plaintext.len())?; let rc = unsafe { sys::wc_ChaCha20Poly1305_Encrypt(key.as_ptr(), iv.as_ptr(), aad.as_ptr(), aad_size, plaintext.as_ptr(), plaintext_size, @@ -171,7 +172,7 @@ impl ChaCha20Poly1305 { /// Returns either Ok(()) on success or Err(e) containing the wolfSSL /// library error code value. pub fn update_aad(&mut self, aad: &[u8]) -> Result<(), i32> { - let aad_size = aad.len() as u32; + let aad_size = crate::buffer_len_to_u32(aad.len())?; let rc = unsafe { sys::wc_ChaCha20Poly1305_UpdateAad(&mut self.wc_ccp, aad.as_ptr(), aad_size) @@ -203,7 +204,7 @@ impl ChaCha20Poly1305 { if din.len() != dout.len() { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } - let din_size = din.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; let rc = unsafe { sys::wc_ChaCha20Poly1305_UpdateData(&mut self.wc_ccp, din.as_ptr(), dout.as_mut_ptr(), din_size) @@ -243,6 +244,18 @@ impl ChaCha20Poly1305 { } } +impl ChaCha20Poly1305 { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_ccp); } + } +} + +impl Drop for ChaCha20Poly1305 { + fn drop(&mut self) { + self.zeroize(); + } +} + // --------------------------------------------------------------------------- // ChaCha20-Poly1305 aead trait implementations // --------------------------------------------------------------------------- @@ -250,6 +263,7 @@ impl ChaCha20Poly1305 { /// ChaCha20-Poly1305 AEAD instance holding a key for use with the /// `aead::KeyInit` and `aead::AeadInPlace` traits. #[cfg(feature = "aead")] +#[derive(Zeroize, ZeroizeOnDrop)] pub struct ChaCha20Poly1305Aead { key: [u8; 32], } @@ -283,6 +297,9 @@ impl aead::AeadInPlace for ChaCha20Poly1305Aead { associated_data: &[u8], buffer: &mut [u8], ) -> Result, aead::Error> { + if associated_data.len() > u32::MAX as usize || buffer.len() > u32::MAX as usize { + return Err(aead::Error); + } let mut tag = aead::Tag::::default(); // wc_ChaCha20Poly1305_Encrypt supports in-place (out == in). let buf_ptr = buffer.as_mut_ptr(); @@ -310,6 +327,9 @@ impl aead::AeadInPlace for ChaCha20Poly1305Aead { buffer: &mut [u8], tag: &aead::Tag, ) -> Result<(), aead::Error> { + if associated_data.len() > u32::MAX as usize || buffer.len() > u32::MAX as usize { + return Err(aead::Error); + } let buf_ptr = buffer.as_mut_ptr(); let in_ptr = buf_ptr as *const u8; let nonce_bytes: &[u8] = nonce; @@ -432,6 +452,7 @@ impl XChaCha20Poly1305 { /// XChaCha20-Poly1305 AEAD instance holding a key for use with the /// `aead::KeyInit` and `aead::AeadInPlace` traits. #[cfg(all(xchacha20_poly1305, feature = "aead"))] +#[derive(Zeroize, ZeroizeOnDrop)] pub struct XChaCha20Poly1305Aead { key: [u8; 32], } diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/cmac.rs b/wrapper/rust/wolfssl-wolfcrypt/src/cmac.rs index 6261f01eb2f..f99c7c96878 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/cmac.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/cmac.rs @@ -70,9 +70,9 @@ impl CMAC { /// ``` #[cfg(aes)] pub fn generate(key: &[u8], data: &[u8], dout: &mut [u8]) -> Result<(), i32> { - let key_size = key.len() as u32; - let data_size = data.len() as u32; - let mut dout_size = dout.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; + let data_size = crate::buffer_len_to_u32(data.len())?; + let mut dout_size = crate::buffer_len_to_u32(dout.len())?; let rc = unsafe { sys::wc_AesCmacGenerate(dout.as_mut_ptr(), &mut dout_size, data.as_ptr(), data_size, @@ -134,7 +134,7 @@ impl CMAC { /// let mut cmac = CMAC::new_ex(&key, None, None).expect("Error with new_ex()"); /// ``` pub fn new_ex(key: &[u8], heap: Option<*mut core::ffi::c_void>, dev_id: Option) -> Result { - let key_size = key.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; let mut ws_cmac: MaybeUninit = MaybeUninit::uninit(); let typ = sys::CmacType_WC_CMAC_AES as i32; let heap = match heap { @@ -193,9 +193,9 @@ impl CMAC { /// ``` #[cfg(aes)] pub fn verify(key: &[u8], data: &[u8], check: &[u8]) -> Result { - let key_size = key.len() as u32; - let data_size = data.len() as u32; - let check_size = check.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; + let data_size = crate::buffer_len_to_u32(data.len())?; + let check_size = crate::buffer_len_to_u32(check.len())?; let rc = unsafe { sys::wc_AesCmacVerify(check.as_ptr(), check_size, data.as_ptr(), data_size, @@ -243,9 +243,9 @@ impl CMAC { /// ``` #[cfg(aes)] pub fn generate_ex(&mut self, key: &[u8], data: &[u8], dout: &mut [u8], heap: Option<*mut core::ffi::c_void>, dev_id: Option) -> Result<(), i32> { - let key_size = key.len() as u32; - let data_size = data.len() as u32; - let mut dout_size = dout.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; + let data_size = crate::buffer_len_to_u32(data.len())?; + let mut dout_size = crate::buffer_len_to_u32(dout.len())?; let heap = match heap { Some(heap) => heap, None => core::ptr::null_mut(), @@ -293,7 +293,7 @@ impl CMAC { /// cmac.update(&message).expect("Error with update()"); /// ``` pub fn update(&mut self, data: &[u8]) -> Result<(), i32> { - let data_size = data.len() as u32; + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { sys::wc_CmacUpdate(&mut self.ws_cmac, data.as_ptr(), data_size) }; @@ -335,7 +335,7 @@ impl CMAC { /// cmac.finalize(&mut finalize_out).expect("Error with finalize()"); /// ``` pub fn finalize(mut self, dout: &mut [u8]) -> Result<(), i32> { - let mut dout_size = dout.len() as u32; + let mut dout_size = crate::buffer_len_to_u32(dout.len())?; let rc = unsafe { sys::wc_CmacFinalNoFree(&mut self.ws_cmac, dout.as_mut_ptr(), &mut dout_size) @@ -385,9 +385,9 @@ impl CMAC { /// ``` #[cfg(aes)] pub fn verify_ex(&mut self, key: &[u8], data: &[u8], check: &[u8], heap: Option<*mut core::ffi::c_void>, dev_id: Option) -> Result { - let key_size = key.len() as u32; - let data_size = data.len() as u32; - let check_size = check.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; + let data_size = crate::buffer_len_to_u32(data.len())?; + let check_size = crate::buffer_len_to_u32(check.len())?; let heap = match heap { Some(heap) => heap, None => core::ptr::null_mut(), @@ -408,9 +408,16 @@ impl CMAC { Ok(rc == 0) } } +impl CMAC { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.ws_cmac); } + } +} + impl Drop for CMAC { /// Safely free the wolfSSL resources. fn drop(&mut self) { unsafe { sys::wc_CmacFree(&mut self.ws_cmac); } + self.zeroize(); } } diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/curve25519.rs b/wrapper/rust/wolfssl-wolfcrypt/src/curve25519.rs index 6a472e2c788..ef3c3ca8bd4 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/curve25519.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/curve25519.rs @@ -50,7 +50,7 @@ impl Curve25519Key { /// Returns either Ok(()) on success or Err(e) containing the wolfSSL /// library error code value. pub fn check_public(public: &[u8], big_endian: bool) -> Result<(), i32> { - let public_size = public.len() as u32; + let public_size = crate::buffer_len_to_u32(public.len())?; let endian = if big_endian {sys::EC25519_BIG_ENDIAN} else {sys::EC25519_LITTLE_ENDIAN}; let rc = unsafe { sys::wc_curve25519_check_public(public.as_ptr(), public_size, @@ -128,6 +128,7 @@ impl Curve25519Key { /// Returns either Ok(curve25519key) on success or Err(e) containing the /// wolfSSL library error code value. pub fn import_private(private: &[u8]) -> Result { + let private_size = crate::buffer_len_to_u32(private.len())?; let mut wc_key: MaybeUninit = MaybeUninit::uninit(); let rc = unsafe { sys::wc_curve25519_init(wc_key.as_mut_ptr()) @@ -137,7 +138,6 @@ impl Curve25519Key { } let wc_key = unsafe { wc_key.assume_init() }; let mut curve25519key = Curve25519Key { wc_key }; - let private_size = private.len() as u32; let rc = unsafe { sys::wc_curve25519_import_private(private.as_ptr(), private_size, &mut curve25519key.wc_key) @@ -160,6 +160,7 @@ impl Curve25519Key { /// Returns either Ok(curve25519key) on success or Err(e) containing the /// wolfSSL library error code value. pub fn import_private_ex(private: &[u8], big_endian: bool) -> Result { + let private_size = crate::buffer_len_to_u32(private.len())?; let mut wc_key: MaybeUninit = MaybeUninit::uninit(); let rc = unsafe { sys::wc_curve25519_init(wc_key.as_mut_ptr()) @@ -169,7 +170,6 @@ impl Curve25519Key { } let wc_key = unsafe { wc_key.assume_init() }; let mut curve25519key = Curve25519Key { wc_key }; - let private_size = private.len() as u32; let endian = if big_endian {sys::EC25519_BIG_ENDIAN} else {sys::EC25519_LITTLE_ENDIAN}; let rc = unsafe { sys::wc_curve25519_import_private_ex(private.as_ptr(), @@ -193,6 +193,8 @@ impl Curve25519Key { /// Returns either Ok(curve25519key) on success or Err(e) containing the /// wolfSSL library error code value. pub fn import_private_raw(private: &[u8], public: &[u8]) -> Result { + let private_size = crate::buffer_len_to_u32(private.len())?; + let public_size = crate::buffer_len_to_u32(public.len())?; let mut wc_key: MaybeUninit = MaybeUninit::uninit(); let rc = unsafe { sys::wc_curve25519_init(wc_key.as_mut_ptr()) @@ -202,8 +204,6 @@ impl Curve25519Key { } let wc_key = unsafe { wc_key.assume_init() }; let mut curve25519key = Curve25519Key { wc_key }; - let private_size = private.len() as u32; - let public_size = public.len() as u32; let rc = unsafe { sys::wc_curve25519_import_private_raw(private.as_ptr(), private_size, public.as_ptr(), public_size, @@ -228,6 +228,8 @@ impl Curve25519Key { /// Returns either Ok(curve25519key) on success or Err(e) containing the /// wolfSSL library error code value. pub fn import_private_raw_ex(private: &[u8], public: &[u8], big_endian: bool) -> Result { + let private_size = crate::buffer_len_to_u32(private.len())?; + let public_size = crate::buffer_len_to_u32(public.len())?; let mut wc_key: MaybeUninit = MaybeUninit::uninit(); let rc = unsafe { sys::wc_curve25519_init(wc_key.as_mut_ptr()) @@ -237,8 +239,6 @@ impl Curve25519Key { } let wc_key = unsafe { wc_key.assume_init() }; let mut curve25519key = Curve25519Key { wc_key }; - let private_size = private.len() as u32; - let public_size = public.len() as u32; let endian = if big_endian {sys::EC25519_BIG_ENDIAN} else {sys::EC25519_LITTLE_ENDIAN}; let rc = unsafe { sys::wc_curve25519_import_private_raw_ex(private.as_ptr(), @@ -262,6 +262,7 @@ impl Curve25519Key { /// Returns either Ok(curve25519key) on success or Err(e) containing the /// wolfSSL library error code value. pub fn import_public(public: &[u8]) -> Result { + let public_size = crate::buffer_len_to_u32(public.len())?; let mut wc_key: MaybeUninit = MaybeUninit::uninit(); let rc = unsafe { sys::wc_curve25519_init(wc_key.as_mut_ptr()) @@ -271,7 +272,6 @@ impl Curve25519Key { } let wc_key = unsafe { wc_key.assume_init() }; let mut curve25519key = Curve25519Key { wc_key }; - let public_size = public.len() as u32; let rc = unsafe { sys::wc_curve25519_import_public(public.as_ptr(), public_size, &mut curve25519key.wc_key) @@ -294,6 +294,7 @@ impl Curve25519Key { /// Returns either Ok(curve25519key) on success or Err(e) containing the /// wolfSSL library error code value. pub fn import_public_ex(public: &[u8], big_endian: bool) -> Result { + let public_size = crate::buffer_len_to_u32(public.len())?; let mut wc_key: MaybeUninit = MaybeUninit::uninit(); let rc = unsafe { sys::wc_curve25519_init(wc_key.as_mut_ptr()) @@ -303,7 +304,6 @@ impl Curve25519Key { } let wc_key = unsafe { wc_key.assume_init() }; let mut curve25519key = Curve25519Key { wc_key }; - let public_size = public.len() as u32; let endian = if big_endian {sys::EC25519_BIG_ENDIAN} else {sys::EC25519_LITTLE_ENDIAN}; let rc = unsafe { sys::wc_curve25519_import_public_ex(public.as_ptr(), public_size, @@ -327,8 +327,8 @@ impl Curve25519Key { /// Returns either Ok(()) on success or Err(e) containing the wolfSSL /// library error code value. pub fn make_pub(private: &[u8], public: &mut [u8]) -> Result<(), i32> { - let private_size = private.len() as i32; - let public_size = public.len() as i32; + let private_size = crate::buffer_len_to_i32(private.len())?; + let public_size = crate::buffer_len_to_i32(public.len())?; let rc = unsafe { sys::wc_curve25519_make_pub(public_size, public.as_mut_ptr(), private_size, private.as_ptr()) @@ -354,8 +354,8 @@ impl Curve25519Key { /// library error code value. #[cfg(all(curve25519_blinding, random))] pub fn make_pub_blind(private: &[u8], public: &mut [u8], rng: &mut RNG) -> Result<(), i32> { - let private_size = private.len() as i32; - let public_size = public.len() as i32; + let private_size = crate::buffer_len_to_i32(private.len())?; + let public_size = crate::buffer_len_to_i32(public.len())?; let rc = unsafe { sys::wc_curve25519_make_pub_blind(public_size, public.as_mut_ptr(), private_size, private.as_ptr(), &mut rng.wc_rng) @@ -380,9 +380,9 @@ impl Curve25519Key { /// Returns either Ok(()) on success or Err(e) containing the wolfSSL /// library error code value. pub fn make_pub_generic(private: &[u8], public: &mut [u8], basepoint: &[u8]) -> Result<(), i32> { - let private_size = private.len() as i32; - let public_size = public.len() as i32; - let basepoint_size = basepoint.len() as i32; + let private_size = crate::buffer_len_to_i32(private.len())?; + let public_size = crate::buffer_len_to_i32(public.len())?; + let basepoint_size = crate::buffer_len_to_i32(basepoint.len())?; let rc = unsafe { sys::wc_curve25519_generic(public_size, public.as_mut_ptr(), private_size, private.as_ptr(), basepoint_size, basepoint.as_ptr()) @@ -409,9 +409,9 @@ impl Curve25519Key { /// library error code value. #[cfg(all(curve25519_blinding, random))] pub fn make_pub_generic_blind(private: &[u8], public: &mut [u8], basepoint: &[u8], rng: &mut RNG) -> Result<(), i32> { - let private_size = private.len() as i32; - let public_size = public.len() as i32; - let basepoint_size = basepoint.len() as i32; + let private_size = crate::buffer_len_to_i32(private.len())?; + let public_size = crate::buffer_len_to_i32(public.len())?; + let basepoint_size = crate::buffer_len_to_i32(basepoint.len())?; let rc = unsafe { sys::wc_curve25519_generic_blind(public_size, public.as_mut_ptr(), private_size, private.as_ptr(), basepoint_size, basepoint.as_ptr(), @@ -438,7 +438,7 @@ impl Curve25519Key { /// Returns either Ok(size) containing the number of bytes written to `out` /// on success or Err(e) containing the wolfSSL library error code value. pub fn shared_secret(private_key: &mut Curve25519Key, public_key: &mut Curve25519Key, out: &mut [u8]) -> Result { - let mut outlen = out.len() as u32; + let mut outlen = crate::buffer_len_to_u32(out.len())?; let rc = unsafe { sys::wc_curve25519_shared_secret(&mut private_key.wc_key, &mut public_key.wc_key, out.as_mut_ptr(), &mut outlen) @@ -491,7 +491,7 @@ impl Curve25519Key { /// Returns either Ok(size) containing the number of bytes written to `out` /// on success or Err(e) containing the wolfSSL library error code value. pub fn shared_secret_ex(private_key: &mut Curve25519Key, public_key: &mut Curve25519Key, out: &mut [u8], big_endian: bool) -> Result { - let mut outlen = out.len() as u32; + let mut outlen = crate::buffer_len_to_u32(out.len())?; let endian = if big_endian {sys::EC25519_BIG_ENDIAN} else {sys::EC25519_LITTLE_ENDIAN}; let rc = unsafe { sys::wc_curve25519_shared_secret_ex(&mut private_key.wc_key, @@ -516,8 +516,8 @@ impl Curve25519Key { /// Returns either Ok(()) on success or Err(e) containing the wolfSSL /// library error code value. pub fn export_key_raw(&mut self, private: &mut [u8], public: &mut [u8]) -> Result<(), i32> { - let mut private_size = private.len() as u32; - let mut public_size = public.len() as u32; + let mut private_size = crate::buffer_len_to_u32(private.len())?; + let mut public_size = crate::buffer_len_to_u32(public.len())?; let rc = unsafe { sys::wc_curve25519_export_key_raw(&mut self.wc_key, private.as_mut_ptr(), &mut private_size, @@ -543,8 +543,8 @@ impl Curve25519Key { /// Returns either Ok(()) on success or Err(e) containing the wolfSSL /// library error code value. pub fn export_key_raw_ex(&mut self, private: &mut [u8], public: &mut [u8], big_endian: bool) -> Result<(), i32> { - let mut private_size = private.len() as u32; - let mut public_size = public.len() as u32; + let mut private_size = crate::buffer_len_to_u32(private.len())?; + let mut public_size = crate::buffer_len_to_u32(public.len())?; let endian = if big_endian {sys::EC25519_BIG_ENDIAN} else {sys::EC25519_LITTLE_ENDIAN}; let rc = unsafe { sys::wc_curve25519_export_key_raw_ex(&mut self.wc_key, @@ -569,7 +569,7 @@ impl Curve25519Key { /// Returns either Ok(size) containing the number of bytes written to `out` /// on success or Err(e) containing the wolfSSL library error code value. pub fn export_private_raw(&mut self, out: &mut [u8]) -> Result { - let mut outlen = out.len() as u32; + let mut outlen = crate::buffer_len_to_u32(out.len())?; let rc = unsafe { sys::wc_curve25519_export_private_raw(&mut self.wc_key, out.as_mut_ptr(), &mut outlen) @@ -593,7 +593,7 @@ impl Curve25519Key { /// Returns either Ok(size) containing the number of bytes written to `out` /// on success or Err(e) containing the wolfSSL library error code value. pub fn export_private_raw_ex(&mut self, out: &mut [u8], big_endian: bool) -> Result { - let mut outlen = out.len() as u32; + let mut outlen = crate::buffer_len_to_u32(out.len())?; let endian = if big_endian {sys::EC25519_BIG_ENDIAN} else {sys::EC25519_LITTLE_ENDIAN}; let rc = unsafe { sys::wc_curve25519_export_private_raw_ex(&mut self.wc_key, @@ -617,7 +617,7 @@ impl Curve25519Key { /// Returns either Ok(size) containing the number of bytes written to `out` /// on success or Err(e) containing the wolfSSL library error code value. pub fn export_public(&mut self, out: &mut [u8]) -> Result { - let mut outlen = out.len() as u32; + let mut outlen = crate::buffer_len_to_u32(out.len())?; let rc = unsafe { sys::wc_curve25519_export_public(&mut self.wc_key, out.as_mut_ptr(), &mut outlen) @@ -641,7 +641,7 @@ impl Curve25519Key { /// Returns either Ok(size) containing the number of bytes written to `out` /// on success or Err(e) containing the wolfSSL library error code value. pub fn export_public_ex(&mut self, out: &mut [u8], big_endian: bool) -> Result { - let mut outlen = out.len() as u32; + let mut outlen = crate::buffer_len_to_u32(out.len())?; let endian = if big_endian {sys::EC25519_BIG_ENDIAN} else {sys::EC25519_LITTLE_ENDIAN}; let rc = unsafe { sys::wc_curve25519_export_public_ex(&mut self.wc_key, @@ -654,6 +654,12 @@ impl Curve25519Key { } } +impl Curve25519Key { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_key); } + } +} + impl Drop for Curve25519Key { /// Safely free the underlying wolfSSL Curve25519Key context. /// @@ -664,5 +670,6 @@ impl Drop for Curve25519Key { /// preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_curve25519_free(&mut self.wc_key); } + self.zeroize(); } } diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/dh.rs b/wrapper/rust/wolfssl-wolfcrypt/src/dh.rs index 022bd7a7556..36c4fca3fac 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/dh.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/dh.rs @@ -98,8 +98,8 @@ impl DH { /// } /// ``` pub fn check_pub_value(prime: &[u8], public: &[u8]) -> Result<(), i32> { - let prime_size = prime.len() as u32; - let public_size = public.len() as u32; + let prime_size = crate::buffer_len_to_u32(prime.len())?; + let public_size = crate::buffer_len_to_u32(public.len())?; let rc = unsafe { sys::wc_DhCheckPubValue(prime.as_ptr(), prime_size, public.as_ptr(), public_size) @@ -144,6 +144,13 @@ impl DH { /// } /// ``` pub fn compare_named_key(name: i32, p: &[u8], g: &[u8], q: Option<&[u8]>) -> bool { + if p.len() > u32::MAX as usize || g.len() > u32::MAX as usize { + return false; + } + if let Some(qv) = q + && qv.len() > u32::MAX as usize { + return false; + } let p_size = p.len() as u32; let g_size = g.len() as u32; let mut no_q = 1i32; @@ -556,8 +563,8 @@ impl DH { /// } /// ``` pub fn new_from_pg_ex(p: &[u8], g: &[u8], heap: Option<*mut core::ffi::c_void>, dev_id: Option) -> Result { - let p_size = p.len() as u32; - let g_size = g.len() as u32; + let p_size = crate::buffer_len_to_u32(p.len())?; + let g_size = crate::buffer_len_to_u32(g.len())?; let mut wc_dhkey: MaybeUninit = MaybeUninit::uninit(); let heap = match heap { Some(heap) => heap, @@ -784,9 +791,9 @@ impl DH { /// } /// ``` pub fn new_from_pgq_ex(p: &[u8], g: &[u8], q: &[u8], heap: Option<*mut core::ffi::c_void>, dev_id: Option) -> Result { - let p_size = p.len() as u32; - let g_size = g.len() as u32; - let q_size = q.len() as u32; + let p_size = crate::buffer_len_to_u32(p.len())?; + let g_size = crate::buffer_len_to_u32(g.len())?; + let q_size = crate::buffer_len_to_u32(q.len())?; let mut wc_dhkey: MaybeUninit = MaybeUninit::uninit(); let heap = match heap { Some(heap) => heap, @@ -1024,9 +1031,9 @@ impl DH { /// ``` #[cfg(random)] pub fn new_from_pgq_with_check_ex(p: &[u8], g: &[u8], q: &[u8], trusted: i32, rng: &mut RNG, heap: Option<*mut core::ffi::c_void>, dev_id: Option) -> Result { - let p_size = p.len() as u32; - let g_size = g.len() as u32; - let q_size = q.len() as u32; + let p_size = crate::buffer_len_to_u32(p.len())?; + let g_size = crate::buffer_len_to_u32(g.len())?; + let q_size = crate::buffer_len_to_u32(q.len())?; let mut wc_dhkey: MaybeUninit = MaybeUninit::uninit(); let heap = match heap { Some(heap) => heap, @@ -1084,8 +1091,8 @@ impl DH { /// } /// ``` pub fn check_key_pair(&mut self, public: &[u8], private: &[u8]) -> Result<(), i32> { - let public_size = public.len() as u32; - let private_size = private.len() as u32; + let public_size = crate::buffer_len_to_u32(public.len())?; + let private_size = crate::buffer_len_to_u32(private.len())?; let rc = unsafe { sys::wc_DhCheckKeyPair(&mut self.wc_dhkey, public.as_ptr(), public_size, @@ -1129,7 +1136,7 @@ impl DH { /// } /// ``` pub fn check_priv_key(&mut self, private: &[u8]) -> Result<(), i32> { - let private_size = private.len() as u32; + let private_size = crate::buffer_len_to_u32(private.len())?; let rc = unsafe { sys::wc_DhCheckPrivKey(&mut self.wc_dhkey, private.as_ptr(), private_size) @@ -1249,12 +1256,12 @@ impl DH { /// } /// ``` pub fn check_priv_key_ex(&mut self, private: &[u8], prime: Option<&[u8]>) -> Result<(), i32> { - let private_size = private.len() as u32; + let private_size = crate::buffer_len_to_u32(private.len())?; let mut prime_ptr: *const u8 = core::ptr::null(); let mut prime_size = 0u32; if let Some(prime) = prime { prime_ptr = prime.as_ptr(); - prime_size = prime.len() as u32; + prime_size = crate::buffer_len_to_u32(prime.len())?; } let rc = unsafe { sys::wc_DhCheckPrivKey_ex(&mut self.wc_dhkey, @@ -1299,7 +1306,7 @@ impl DH { /// } /// ``` pub fn check_pub_key(&mut self, public: &[u8]) -> Result<(), i32> { - let public_size = public.len() as u32; + let public_size = crate::buffer_len_to_u32(public.len())?; let rc = unsafe { sys::wc_DhCheckPubKey(&mut self.wc_dhkey, public.as_ptr(), public_size) }; @@ -1423,8 +1430,8 @@ impl DH { /// } /// ``` pub fn check_pub_key_ex(&mut self, public: &[u8], prime: &[u8]) -> Result<(), i32> { - let public_size = public.len() as u32; - let prime_size = prime.len() as u32; + let public_size = crate::buffer_len_to_u32(public.len())?; + let prime_size = crate::buffer_len_to_u32(prime.len())?; let rc = unsafe { sys::wc_DhCheckPubKey_ex(&mut self.wc_dhkey, public.as_ptr(), public_size, @@ -1455,9 +1462,9 @@ impl DH { p: &mut [u8], p_size: &mut u32, q: &mut [u8], q_size: &mut u32, g: &mut [u8], g_size: &mut u32) -> Result<(), i32> { - *p_size = p.len() as u32; - *q_size = q.len() as u32; - *g_size = g.len() as u32; + *p_size = crate::buffer_len_to_u32(p.len())?; + *q_size = crate::buffer_len_to_u32(q.len())?; + *g_size = crate::buffer_len_to_u32(g.len())?; let rc = unsafe { sys::wc_DhExportParamsRaw(&mut self.wc_dhkey, p.as_mut_ptr(), p_size, @@ -1505,8 +1512,8 @@ impl DH { pub fn generate_key_pair(&mut self, rng: &mut RNG, private: &mut [u8], private_size: &mut u32, public: &mut [u8], public_size: &mut u32) -> Result<(), i32> { - *private_size = private.len() as u32; - *public_size = public.len() as u32; + *private_size = crate::buffer_len_to_u32(private.len())?; + *public_size = crate::buffer_len_to_u32(public.len())?; let rc = unsafe { sys::wc_DhGenerateKeyPair(&mut self.wc_dhkey, &mut rng.wc_rng, private.as_mut_ptr(), private_size, @@ -1556,9 +1563,9 @@ impl DH { /// } /// ``` pub fn shared_secret(&mut self, dout: &mut [u8], private: &[u8], other_pub: &[u8]) -> Result { - let mut dout_size = dout.len() as u32; - let private_size = private.len() as u32; - let other_pub_size = other_pub.len() as u32; + let mut dout_size = crate::buffer_len_to_u32(dout.len())?; + let private_size = crate::buffer_len_to_u32(private.len())?; + let other_pub_size = crate::buffer_len_to_u32(other_pub.len())?; let rc = unsafe { sys::wc_DhAgree(&mut self.wc_dhkey, dout.as_mut_ptr(), &mut dout_size, @@ -1572,6 +1579,12 @@ impl DH { } } +impl DH { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_dhkey); } + } +} + impl Drop for DH { /// Safely free the underlying wolfSSL DhKey context. /// @@ -1582,5 +1595,6 @@ impl Drop for DH { /// resources and preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_FreeDhKey(&mut self.wc_dhkey); } + self.zeroize(); } } diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/dilithium.rs b/wrapper/rust/wolfssl-wolfcrypt/src/dilithium.rs index e3ba4756ec0..00051478594 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/dilithium.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/dilithium.rs @@ -84,13 +84,11 @@ impl Dilithium { /// Required size in bytes of the seed passed to /// [`Dilithium::generate_from_seed()`] (`DILITHIUM_SEED_SZ`). - #[cfg(dilithium_make_key_seed_sz)] pub const DILITHIUM_SEED_SZ: usize = sys::DILITHIUM_SEED_SZ as usize; /// Required size in bytes of the seed passed to signing-with-seed /// functions such as [`Dilithium::sign_msg_with_seed()`] /// (`DILITHIUM_RND_SZ`). - #[cfg(dilithium_rnd_sz)] pub const SIGN_SEED_SIZE: usize = sys::DILITHIUM_RND_SZ as usize; /// Private (secret) key size in bytes for ML-DSA-44. @@ -277,7 +275,6 @@ impl Dilithium { heap: Option<*mut core::ffi::c_void>, dev_id: Option, ) -> Result { - #[cfg(dilithium_make_key_seed_sz)] if seed.len() != Self::DILITHIUM_SEED_SZ { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } @@ -598,7 +595,7 @@ impl Dilithium { /// ``` #[cfg(dilithium_import)] pub fn import_public(&mut self, public: &[u8]) -> Result<(), i32> { - let public_size = public.len() as u32; + let public_size = crate::buffer_len_to_u32(public.len())?; let rc = unsafe { sys::wc_dilithium_import_public(public.as_ptr(), public_size, &mut self.ws_key) }; @@ -641,7 +638,7 @@ impl Dilithium { /// ``` #[cfg(dilithium_import)] pub fn import_private(&mut self, private: &[u8]) -> Result<(), i32> { - let private_size = private.len() as u32; + let private_size = crate::buffer_len_to_u32(private.len())?; let rc = unsafe { sys::wc_dilithium_import_private(private.as_ptr(), private_size, &mut self.ws_key) }; @@ -683,8 +680,8 @@ impl Dilithium { /// ``` #[cfg(dilithium_import)] pub fn import_key(&mut self, private: &[u8], public: &[u8]) -> Result<(), i32> { - let private_size = private.len() as u32; - let public_size = public.len() as u32; + let private_size = crate::buffer_len_to_u32(private.len())?; + let public_size = crate::buffer_len_to_u32(public.len())?; let rc = unsafe { sys::wc_dilithium_import_key( private.as_ptr(), private_size, @@ -727,7 +724,7 @@ impl Dilithium { /// ``` #[cfg(dilithium_export)] pub fn export_public(&mut self, public: &mut [u8]) -> Result { - let mut public_size = public.len() as u32; + let mut public_size = crate::buffer_len_to_u32(public.len())?; let rc = unsafe { sys::wc_dilithium_export_public(&mut self.ws_key, public.as_mut_ptr(), &mut public_size) }; @@ -766,7 +763,7 @@ impl Dilithium { /// ``` #[cfg(dilithium_export)] pub fn export_private(&mut self, private: &mut [u8]) -> Result { - let mut private_size = private.len() as u32; + let mut private_size = crate::buffer_len_to_u32(private.len())?; let rc = unsafe { sys::wc_dilithium_export_private( &mut self.ws_key, private.as_mut_ptr(), &mut private_size, @@ -810,8 +807,8 @@ impl Dilithium { /// ``` #[cfg(dilithium_export)] pub fn export_key(&mut self, private: &mut [u8], public: &mut [u8]) -> Result<(), i32> { - let mut private_size = private.len() as u32; - let mut public_size = public.len() as u32; + let mut private_size = crate::buffer_len_to_u32(private.len())?; + let mut public_size = crate::buffer_len_to_u32(public.len())?; let rc = unsafe { sys::wc_dilithium_export_key( &mut self.ws_key, @@ -864,8 +861,8 @@ impl Dilithium { sig: &mut [u8], rng: &mut RNG, ) -> Result { - let msg_len = msg.len() as u32; - let mut sig_len = sig.len() as u32; + let msg_len = crate::buffer_len_to_u32(msg.len())?; + let mut sig_len = crate::buffer_len_to_u32(sig.len())?; let rc = unsafe { sys::wc_dilithium_sign_ctx_msg( core::ptr::null(), 0, @@ -926,8 +923,8 @@ impl Dilithium { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } let ctx_len = ctx.len() as u8; - let msg_len = msg.len() as u32; - let mut sig_len = sig.len() as u32; + let msg_len = crate::buffer_len_to_u32(msg.len())?; + let mut sig_len = crate::buffer_len_to_u32(sig.len())?; let rc = unsafe { sys::wc_dilithium_sign_ctx_msg( ctx.as_ptr(), ctx_len, @@ -975,8 +972,8 @@ impl Dilithium { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } let ctx_len = ctx.len() as u8; - let hash_len = hash.len() as u32; - let mut sig_len = sig.len() as u32; + let hash_len = crate::buffer_len_to_u32(hash.len())?; + let mut sig_len = crate::buffer_len_to_u32(sig.len())?; let rc = unsafe { sys::wc_dilithium_sign_ctx_hash( ctx.as_ptr(), ctx_len, @@ -1032,12 +1029,11 @@ impl Dilithium { sig: &mut [u8], seed: &[u8], ) -> Result { - #[cfg(dilithium_rnd_sz)] if seed.len() != sys::DILITHIUM_RND_SZ as usize { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } - let msg_len = msg.len() as u32; - let mut sig_len = sig.len() as u32; + let msg_len = crate::buffer_len_to_u32(msg.len())?; + let mut sig_len = crate::buffer_len_to_u32(sig.len())?; let rc = unsafe { sys::wc_dilithium_sign_ctx_msg_with_seed( core::ptr::null(), 0, @@ -1077,13 +1073,12 @@ impl Dilithium { if ctx.len() > 255 { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } - #[cfg(dilithium_rnd_sz)] if seed.len() != sys::DILITHIUM_RND_SZ as usize { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } let ctx_len = ctx.len() as u8; - let msg_len = msg.len() as u32; - let mut sig_len = sig.len() as u32; + let msg_len = crate::buffer_len_to_u32(msg.len())?; + let mut sig_len = crate::buffer_len_to_u32(sig.len())?; let rc = unsafe { sys::wc_dilithium_sign_ctx_msg_with_seed( ctx.as_ptr(), ctx_len, @@ -1126,13 +1121,12 @@ impl Dilithium { if ctx.len() > 255 { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } - #[cfg(dilithium_rnd_sz)] if seed.len() != sys::DILITHIUM_RND_SZ as usize { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } let ctx_len = ctx.len() as u8; - let hash_len = hash.len() as u32; - let mut sig_len = sig.len() as u32; + let hash_len = crate::buffer_len_to_u32(hash.len())?; + let mut sig_len = crate::buffer_len_to_u32(sig.len())?; let rc = unsafe { sys::wc_dilithium_sign_ctx_hash_with_seed( ctx.as_ptr(), ctx_len, @@ -1182,8 +1176,8 @@ impl Dilithium { /// ``` #[cfg(dilithium_verify)] pub fn verify_msg(&mut self, sig: &[u8], msg: &[u8]) -> Result { - let sig_len = sig.len() as u32; - let msg_len = msg.len() as u32; + let sig_len = crate::buffer_len_to_u32(sig.len())?; + let msg_len = crate::buffer_len_to_u32(msg.len())?; let mut res = 0i32; let rc = unsafe { sys::wc_dilithium_verify_ctx_msg( @@ -1238,9 +1232,9 @@ impl Dilithium { if ctx.len() > 255 { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } - let sig_len = sig.len() as u32; + let sig_len = crate::buffer_len_to_u32(sig.len())?; let ctx_len = ctx.len() as u8; - let msg_len = msg.len() as u32; + let msg_len = crate::buffer_len_to_u32(msg.len())?; let mut res = 0i32; let rc = unsafe { sys::wc_dilithium_verify_ctx_msg( @@ -1284,9 +1278,9 @@ impl Dilithium { if ctx.len() > 255 { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } - let sig_len = sig.len() as u32; + let sig_len = crate::buffer_len_to_u32(sig.len())?; let ctx_len = ctx.len() as u8; - let hash_len = hash.len() as u32; + let hash_len = crate::buffer_len_to_u32(hash.len())?; let mut res = 0i32; let rc = unsafe { sys::wc_dilithium_verify_ctx_hash( @@ -1305,6 +1299,12 @@ impl Dilithium { } } +impl Dilithium { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.ws_key); } + } +} + impl Drop for Dilithium { /// Safely free the underlying wolfSSL Dilithium key context. /// @@ -1312,5 +1312,6 @@ impl Drop for Dilithium { /// is called when the `Dilithium` struct goes out of scope. fn drop(&mut self) { unsafe { sys::wc_dilithium_free(&mut self.ws_key); } + self.zeroize(); } } diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/ecc.rs b/wrapper/rust/wolfssl-wolfcrypt/src/ecc.rs index 7504a1f944e..e8a2e3700b8 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/ecc.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/ecc.rs @@ -85,7 +85,7 @@ impl ECCPoint { return Err(sys::wolfCrypt_ErrorCodes_MEMORY_E); } let eccpoint = ECCPoint { wc_ecc_point, heap }; - let din_size = din.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; let rc = unsafe { sys::wc_ecc_import_point_der(din.as_ptr(), din_size, curve_idx, eccpoint.wc_ecc_point) @@ -143,7 +143,7 @@ impl ECCPoint { return Err(sys::wolfCrypt_ErrorCodes_MEMORY_E); } let eccpoint = ECCPoint { wc_ecc_point, heap }; - let din_size = din.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; let rc = unsafe { sys::wc_ecc_import_point_der_ex(din.as_ptr(), din_size, curve_idx, wc_ecc_point, short_key_size) @@ -190,7 +190,7 @@ impl ECCPoint { if curve_idx < 0 { return Err(curve_idx); } - let mut dout_size = dout.len() as u32; + let mut dout_size = crate::buffer_len_to_u32(dout.len())?; let rc = unsafe { sys::wc_ecc_export_point_der(curve_idx, self.wc_ecc_point, dout.as_mut_ptr(), &mut dout_size) @@ -235,7 +235,7 @@ impl ECCPoint { if curve_idx < 0 { return Err(curve_idx); } - let mut dout_size = dout.len() as u32; + let mut dout_size = crate::buffer_len_to_u32(dout.len())?; let rc = unsafe { sys::wc_ecc_export_point_der_ex(curve_idx, self.wc_ecc_point, dout.as_mut_ptr(), &mut dout_size, 1) @@ -267,6 +267,13 @@ impl ECCPoint { } } +impl ECCPoint { + fn zeroize(&mut self) { + self.wc_ecc_point = core::ptr::null_mut(); + self.heap = core::ptr::null_mut(); + } +} + impl Drop for ECCPoint { /// Safely free the underlying wolfSSL ecc_point context. /// @@ -277,6 +284,7 @@ impl Drop for ECCPoint { /// resources and preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_ecc_del_point_h(self.wc_ecc_point, self.heap); } + self.zeroize(); } } @@ -427,15 +435,14 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let rc = unsafe { - sys::wc_ecc_make_key(&mut rng.wc_rng, size, &mut wc_ecc_key) + sys::wc_ecc_make_key(&mut rng.wc_rng, size, &mut ecc.wc_ecc_key) }; if rc != 0 { - unsafe { sys::wc_ecc_free(&mut wc_ecc_key); } return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -485,15 +492,14 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let rc = unsafe { - sys::wc_ecc_make_key_ex(&mut rng.wc_rng, size, &mut wc_ecc_key, curve_id) + sys::wc_ecc_make_key_ex(&mut rng.wc_rng, size, &mut ecc.wc_ecc_key, curve_id) }; if rc != 0 { - unsafe { sys::wc_ecc_free(&mut wc_ecc_key); } return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -544,15 +550,14 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let rc = unsafe { - sys::wc_ecc_make_key_ex2(&mut rng.wc_rng, size, &mut wc_ecc_key, curve_id, flags) + sys::wc_ecc_make_key_ex2(&mut rng.wc_rng, size, &mut ecc.wc_ecc_key, curve_id, flags) }; if rc != 0 { - unsafe { sys::wc_ecc_free(&mut wc_ecc_key); } return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -632,16 +637,16 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let mut idx = 0u32; - let der_size = der.len() as u32; + let der_size = crate::buffer_len_to_u32(der.len())?; let rc = unsafe { - sys::wc_EccPrivateKeyDecode(der.as_ptr(), &mut idx, &mut wc_ecc_key, der_size) + sys::wc_EccPrivateKeyDecode(der.as_ptr(), &mut idx, &mut ecc.wc_ecc_key, der_size) }; if rc != 0 { return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -695,16 +700,16 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let mut idx = 0u32; - let der_size = der.len() as u32; + let der_size = crate::buffer_len_to_u32(der.len())?; let rc = unsafe { - sys::wc_EccPublicKeyDecode(der.as_ptr(), &mut idx, &mut wc_ecc_key, der_size) + sys::wc_EccPublicKeyDecode(der.as_ptr(), &mut idx, &mut ecc.wc_ecc_key, der_size) }; if rc != 0 { return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -764,18 +769,18 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; - let priv_size = priv_buf.len() as u32; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; + let priv_size = crate::buffer_len_to_u32(priv_buf.len())?; let pub_ptr = if pub_buf.is_empty() {core::ptr::null()} else {pub_buf.as_ptr()}; - let pub_size = pub_buf.len() as u32; + let pub_size = crate::buffer_len_to_u32(pub_buf.len())?; let rc = unsafe { sys::wc_ecc_import_private_key(priv_buf.as_ptr(), priv_size, - pub_ptr, pub_size, &mut wc_ecc_key) + pub_ptr, pub_size, &mut ecc.wc_ecc_key) }; if rc != 0 { return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -838,18 +843,18 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; - let priv_size = priv_buf.len() as u32; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; + let priv_size = crate::buffer_len_to_u32(priv_buf.len())?; let pub_ptr = if pub_buf.is_empty() {core::ptr::null()} else {pub_buf.as_ptr()}; - let pub_size = pub_buf.len() as u32; + let pub_size = crate::buffer_len_to_u32(pub_buf.len())?; let rc = unsafe { sys::wc_ecc_import_private_key_ex(priv_buf.as_ptr(), priv_size, - pub_ptr, pub_size, &mut wc_ecc_key, curve_id) + pub_ptr, pub_size, &mut ecc.wc_ecc_key, curve_id) }; if rc != 0 { return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -897,19 +902,19 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let qx_ptr = qx.as_ptr() as *const core::ffi::c_char; let qy_ptr = qy.as_ptr() as *const core::ffi::c_char; let d_ptr = d.as_ptr() as *const core::ffi::c_char; let curve_name_ptr = curve_name.as_ptr() as *const core::ffi::c_char; let rc = unsafe { - sys::wc_ecc_import_raw(&mut wc_ecc_key, qx_ptr, qy_ptr, d_ptr, + sys::wc_ecc_import_raw(&mut ecc.wc_ecc_key, qx_ptr, qy_ptr, d_ptr, curve_name_ptr) }; if rc != 0 { return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -957,18 +962,18 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let qx_ptr = qx.as_ptr() as *const core::ffi::c_char; let qy_ptr = qy.as_ptr() as *const core::ffi::c_char; let d_ptr = d.as_ptr() as *const core::ffi::c_char; let rc = unsafe { - sys::wc_ecc_import_raw_ex(&mut wc_ecc_key, qx_ptr, qy_ptr, d_ptr, - curve_id) + sys::wc_ecc_import_raw_ex(&mut ecc.wc_ecc_key, qx_ptr, qy_ptr, + d_ptr, curve_id) }; if rc != 0 { return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -1025,15 +1030,15 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let rc = unsafe { - sys::wc_ecc_import_unsigned(&mut wc_ecc_key, qx.as_ptr(), qy.as_ptr(), - d.as_ptr(), curve_id) + sys::wc_ecc_import_unsigned(&mut ecc.wc_ecc_key, qx.as_ptr(), + qy.as_ptr(), d.as_ptr(), curve_id) }; if rc != 0 { return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -1070,7 +1075,7 @@ impl ECC { /// ``` #[cfg(ecc_import)] pub fn import_x963(din: &[u8], heap: Option<*mut core::ffi::c_void>, dev_id: Option) -> Result { - let din_size = din.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; let mut wc_ecc_key: MaybeUninit = MaybeUninit::uninit(); let heap = match heap { Some(heap) => heap, @@ -1084,15 +1089,14 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let rc = unsafe { - sys::wc_ecc_import_x963(din.as_ptr(), din_size, &mut wc_ecc_key) + sys::wc_ecc_import_x963(din.as_ptr(), din_size, &mut ecc.wc_ecc_key) }; if rc != 0 { - unsafe { sys::wc_ecc_free(&mut wc_ecc_key); } return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -1134,7 +1138,7 @@ impl ECC { /// ``` #[cfg(ecc_import)] pub fn import_x963_ex(din: &[u8], curve_id: i32, heap: Option<*mut core::ffi::c_void>, dev_id: Option) -> Result { - let din_size = din.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; let mut wc_ecc_key: MaybeUninit = MaybeUninit::uninit(); let heap = match heap { Some(heap) => heap, @@ -1148,15 +1152,14 @@ impl ECC { if rc != 0 { return Err(rc); } - let mut wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let wc_ecc_key = unsafe { wc_ecc_key.assume_init() }; + let mut ecc = ECC { wc_ecc_key }; let rc = unsafe { - sys::wc_ecc_import_x963_ex(din.as_ptr(), din_size, &mut wc_ecc_key, curve_id) + sys::wc_ecc_import_x963_ex(din.as_ptr(), din_size, &mut ecc.wc_ecc_key, curve_id) }; if rc != 0 { - unsafe { sys::wc_ecc_free(&mut wc_ecc_key); } return Err(rc); } - let ecc = ECC { wc_ecc_key }; Ok(ecc) } @@ -1216,7 +1219,7 @@ impl ECC { /// } /// ``` pub fn rs_hex_to_sig(r: &[u8], s: &[u8], dout: &mut [u8]) -> Result { - let mut dout_size = dout.len() as u32; + let mut dout_size = crate::buffer_len_to_u32(dout.len())?; let r_ptr = r.as_ptr() as *const core::ffi::c_char; let s_ptr = s.as_ptr() as *const core::ffi::c_char; let rc = unsafe { @@ -1273,9 +1276,9 @@ impl ECC { /// } /// ``` pub fn rs_bin_to_sig(r: &[u8], s: &[u8], dout: &mut [u8]) -> Result { - let r_size = r.len() as u32; - let s_size = s.len() as u32; - let mut dout_size = dout.len() as u32; + let r_size = crate::buffer_len_to_u32(r.len())?; + let s_size = crate::buffer_len_to_u32(s.len())?; + let mut dout_size = crate::buffer_len_to_u32(dout.len())?; let rc = unsafe { sys::wc_ecc_rs_raw_to_sig(r.as_ptr(), r_size, s.as_ptr(), s_size, dout.as_mut_ptr(), &mut dout_size) @@ -1326,9 +1329,9 @@ impl ECC { /// } /// ``` pub fn sig_to_rs(sig: &[u8], r: &mut [u8], r_size: &mut u32, s: &mut [u8], s_size: &mut u32) -> Result<(), i32> { - let sig_len = sig.len() as u32; - *r_size = r.len() as u32; - *s_size = s.len() as u32; + let sig_len = crate::buffer_len_to_u32(sig.len())?; + *r_size = crate::buffer_len_to_u32(r.len())?; + *s_size = crate::buffer_len_to_u32(s.len())?; let rc = unsafe { sys::wc_ecc_sig_to_rs(sig.as_ptr(), sig_len, r.as_mut_ptr(), r_size, s.as_mut_ptr(), s_size) @@ -1404,9 +1407,9 @@ impl ECC { #[cfg(ecc_import)] pub fn export(&mut self, qx: &mut [u8], qx_len: &mut u32, qy: &mut [u8], qy_len: &mut u32, d: &mut [u8], d_len: &mut u32) -> Result<(), i32> { - *qx_len = qx.len() as u32; - *qy_len = qy.len() as u32; - *d_len = d.len() as u32; + *qx_len = crate::buffer_len_to_u32(qx.len())?; + *qy_len = crate::buffer_len_to_u32(qy.len())?; + *d_len = crate::buffer_len_to_u32(d.len())?; let rc = unsafe { sys::wc_ecc_export_private_raw(&mut self.wc_ecc_key, qx.as_mut_ptr(), qx_len, @@ -1461,9 +1464,9 @@ impl ECC { pub fn export_ex(&mut self, qx: &mut [u8], qx_len: &mut u32, qy: &mut [u8], qy_len: &mut u32, d: &mut [u8], d_len: &mut u32, hex: bool) -> Result<(), i32> { - *qx_len = qx.len() as u32; - *qy_len = qy.len() as u32; - *d_len = d.len() as u32; + *qx_len = crate::buffer_len_to_u32(qx.len())?; + *qy_len = crate::buffer_len_to_u32(qy.len())?; + *d_len = crate::buffer_len_to_u32(d.len())?; let enc_type = if hex { sys::WC_TYPE_HEX_STR as i32 @@ -1510,7 +1513,7 @@ impl ECC { /// ``` #[cfg(ecc_export)] pub fn export_private(&mut self, d: &mut [u8]) -> Result { - let mut d_size = d.len() as u32; + let mut d_size = crate::buffer_len_to_u32(d.len())?; let rc = unsafe { sys::wc_ecc_export_private_only(&mut self.wc_ecc_key, d.as_mut_ptr(), &mut d_size) @@ -1554,8 +1557,8 @@ impl ECC { #[cfg(ecc_export)] pub fn export_public(&mut self, qx: &mut [u8], qx_len: &mut u32, qy: &mut [u8], qy_len: &mut u32) -> Result<(), i32> { - *qx_len = qx.len() as u32; - *qy_len = qy.len() as u32; + *qx_len = crate::buffer_len_to_u32(qx.len())?; + *qy_len = crate::buffer_len_to_u32(qy.len())?; let rc = unsafe { sys::wc_ecc_export_public_raw(&mut self.wc_ecc_key, qx.as_mut_ptr(), qx_len, @@ -1593,7 +1596,7 @@ impl ECC { /// ``` #[cfg(ecc_export)] pub fn export_x963(&mut self, dout: &mut [u8]) -> Result { - let mut out_len: u32 = dout.len() as u32; + let mut out_len = crate::buffer_len_to_u32(dout.len())?; let rc = unsafe { sys::wc_ecc_export_x963(&mut self.wc_ecc_key, dout.as_mut_ptr(), &mut out_len) }; @@ -1629,7 +1632,7 @@ impl ECC { /// ``` #[cfg(all(ecc_export, ecc_comp_key))] pub fn export_x963_compressed(&mut self, dout: &mut [u8]) -> Result { - let mut out_len: u32 = dout.len() as u32; + let mut out_len = crate::buffer_len_to_u32(dout.len())?; let rc = unsafe { sys::wc_ecc_export_x963_ex(&mut self.wc_ecc_key, dout.as_mut_ptr(), &mut out_len, 1) }; @@ -1812,7 +1815,7 @@ impl ECC { /// ``` #[cfg(ecc_dh)] pub fn shared_secret(&mut self, peer_key: &mut ECC, dout: &mut [u8]) -> Result { - let mut out_len = dout.len() as u32; + let mut out_len = crate::buffer_len_to_u32(dout.len())?; let rc = unsafe { sys::wc_ecc_shared_secret(&mut self.wc_ecc_key, &mut peer_key.wc_ecc_key, dout.as_mut_ptr(), &mut out_len) @@ -1862,7 +1865,7 @@ impl ECC { /// ``` #[cfg(ecc_dh)] pub fn shared_secret_ex(&mut self, peer: &ECCPoint, dout: &mut [u8]) -> Result { - let mut out_len = dout.len() as u32; + let mut out_len = crate::buffer_len_to_u32(dout.len())?; let rc = unsafe { sys::wc_ecc_shared_secret_ex(&mut self.wc_ecc_key, peer.wc_ecc_point, dout.as_mut_ptr(), &mut out_len) @@ -1905,8 +1908,8 @@ impl ECC { /// ``` #[cfg(all(ecc_sign, random))] pub fn sign_hash(&mut self, din: &[u8], dout: &mut [u8], rng: &mut RNG) -> Result { - let din_size = din.len() as u32; - let mut dout_size = dout.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; + let mut dout_size = crate::buffer_len_to_u32(dout.len())?; let rc = unsafe { sys::wc_ecc_sign_hash(din.as_ptr(), din_size, dout.as_mut_ptr(), &mut dout_size, &mut rng.wc_rng, &mut self.wc_ecc_key) @@ -1949,8 +1952,8 @@ impl ECC { #[cfg(ecc_verify)] pub fn verify_hash(&mut self, sig: &[u8], hash: &[u8]) -> Result { let mut res: i32 = 0; - let sig_len = sig.len() as u32; - let hash_len = hash.len() as u32; + let sig_len = crate::buffer_len_to_u32(sig.len())?; + let hash_len = crate::buffer_len_to_u32(hash.len())?; let rc = unsafe { sys::wc_ecc_verify_hash(sig.as_ptr(), sig_len, hash.as_ptr(), hash_len, &mut res, &mut self.wc_ecc_key) @@ -1962,6 +1965,12 @@ impl ECC { } } +impl ECC { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_ecc_key); } + } +} + impl Drop for ECC { /// Safely free the underlying wolfSSL ECC context. /// @@ -1972,5 +1981,6 @@ impl Drop for ECC { /// preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_ecc_free(&mut self.wc_ecc_key); } + self.zeroize(); } } diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/ed25519.rs b/wrapper/rust/wolfssl-wolfcrypt/src/ed25519.rs index de834801425..d0e7e4f1dfb 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/ed25519.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/ed25519.rs @@ -242,8 +242,8 @@ impl Ed25519 { /// ``` #[cfg(ed25519_export)] pub fn export_key(&self, private: &mut [u8], public: &mut [u8]) -> Result<(), i32> { - let mut private_size = private.len() as u32; - let mut public_size = public.len() as u32; + let mut private_size = crate::buffer_len_to_u32(private.len())?; + let mut public_size = crate::buffer_len_to_u32(public.len())?; let rc = unsafe { sys::wc_ed25519_export_key(&self.ws_key, private.as_mut_ptr(), &mut private_size, @@ -283,7 +283,7 @@ impl Ed25519 { /// ``` #[cfg(ed25519_export)] pub fn export_public(&self, public: &mut [u8]) -> Result<(), i32> { - let mut public_size = public.len() as u32; + let mut public_size = crate::buffer_len_to_u32(public.len())?; let rc = unsafe { sys::wc_ed25519_export_public(&self.ws_key, public.as_mut_ptr(), &mut public_size) @@ -322,7 +322,7 @@ impl Ed25519 { /// ``` #[cfg(ed25519_export)] pub fn export_private(&self, keyout: &mut [u8]) -> Result<(), i32> { - let mut keyout_size = keyout.len() as u32; + let mut keyout_size = crate::buffer_len_to_u32(keyout.len())?; let rc = unsafe { sys::wc_ed25519_export_private(&self.ws_key, keyout.as_mut_ptr(), &mut keyout_size) @@ -361,7 +361,7 @@ impl Ed25519 { /// ``` #[cfg(ed25519_export)] pub fn export_private_only(&self, private: &mut [u8]) -> Result<(), i32> { - let mut private_size = private.len() as u32; + let mut private_size = crate::buffer_len_to_u32(private.len())?; let rc = unsafe { sys::wc_ed25519_export_private_only(&self.ws_key, private.as_mut_ptr(), &mut private_size) @@ -405,7 +405,7 @@ impl Ed25519 { /// ``` #[cfg(ed25519_import)] pub fn import_public(&mut self, public: &[u8]) -> Result<(), i32> { - let public_size = public.len() as u32; + let public_size = crate::buffer_len_to_u32(public.len())?; let rc = unsafe { sys::wc_ed25519_import_public(public.as_ptr(), public_size, &mut self.ws_key) }; @@ -449,7 +449,7 @@ impl Ed25519 { /// ``` #[cfg(ed25519_import)] pub fn import_public_ex(&mut self, public: &[u8], trusted: bool) -> Result<(), i32> { - let public_size = public.len() as u32; + let public_size = crate::buffer_len_to_u32(public.len())?; let rc = unsafe { sys::wc_ed25519_import_public_ex(public.as_ptr(), public_size, &mut self.ws_key, if trusted {1} else {0}) @@ -488,7 +488,7 @@ impl Ed25519 { /// ``` #[cfg(ed25519_import)] pub fn import_private_only(&mut self, private: &[u8]) -> Result<(), i32> { - let private_size = private.len() as u32; + let private_size = crate::buffer_len_to_u32(private.len())?; let rc = unsafe { sys::wc_ed25519_import_private_only(private.as_ptr(), private_size, &mut self.ws_key) @@ -533,12 +533,12 @@ impl Ed25519 { /// ``` #[cfg(ed25519_import)] pub fn import_private_key(&mut self, private: &[u8], public: Option<&[u8]>) -> Result<(), i32> { - let private_size = private.len() as u32; + let private_size = crate::buffer_len_to_u32(private.len())?; let mut public_ptr: *const u8 = core::ptr::null(); let mut public_size = 0u32; if let Some(public) = public { public_ptr = public.as_ptr(); - public_size = public.len() as u32; + public_size = crate::buffer_len_to_u32(public.len())?; } let rc = unsafe { sys::wc_ed25519_import_private_key(private.as_ptr(), private_size, @@ -584,12 +584,12 @@ impl Ed25519 { /// ``` #[cfg(ed25519_import)] pub fn import_private_key_ex(&mut self, private: &[u8], public: Option<&[u8]>, trusted: bool) -> Result<(), i32> { - let private_size = private.len() as u32; + let private_size = crate::buffer_len_to_u32(private.len())?; let mut public_ptr: *const u8 = core::ptr::null(); let mut public_size = 0u32; if let Some(public) = public { public_ptr = public.as_ptr(); - public_size = public.len() as u32; + public_size = crate::buffer_len_to_u32(public.len())?; } let rc = unsafe { sys::wc_ed25519_import_private_key_ex(private.as_ptr(), private_size, @@ -630,7 +630,7 @@ impl Ed25519 { /// ed.make_public(&mut public).expect("Error with make_public()"); /// ``` pub fn make_public(&mut self, pubkey: &mut [u8]) -> Result<(), i32> { - let pubkey_size = pubkey.len() as u32; + let pubkey_size = crate::buffer_len_to_u32(pubkey.len())?; let rc = unsafe { sys::wc_ed25519_make_public(&mut self.ws_key, pubkey.as_mut_ptr(), pubkey_size) @@ -670,8 +670,8 @@ impl Ed25519 { /// ``` #[cfg(ed25519_sign)] pub fn sign_msg(&mut self, message: &[u8], signature: &mut [u8]) -> Result { - let message_size = message.len() as u32; - let mut signature_size = signature.len() as u32; + let message_size = crate::buffer_len_to_u32(message.len())?; + let mut signature_size = crate::buffer_len_to_u32(signature.len())?; let rc = unsafe { sys::wc_ed25519_sign_msg(message.as_ptr(), message_size, signature.as_mut_ptr(), &mut signature_size, &mut self.ws_key) @@ -715,9 +715,12 @@ impl Ed25519 { /// ``` #[cfg(ed25519_sign)] pub fn sign_msg_ctx(&mut self, message: &[u8], context: &[u8], signature: &mut [u8]) -> Result { - let message_size = message.len() as u32; + let message_size = crate::buffer_len_to_u32(message.len())?; + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } let context_size = context.len() as u8; - let mut signature_size = signature.len() as u32; + let mut signature_size = crate::buffer_len_to_u32(signature.len())?; let rc = unsafe { sys::wc_ed25519ctx_sign_msg(message.as_ptr(), message_size, signature.as_mut_ptr(), &mut signature_size, &mut self.ws_key, @@ -772,14 +775,17 @@ impl Ed25519 { /// ``` #[cfg(ed25519_sign)] pub fn sign_hash_ph(&mut self, hash: &[u8], context: Option<&[u8]>, signature: &mut [u8]) -> Result { - let hash_size = hash.len() as u32; + let hash_size = crate::buffer_len_to_u32(hash.len())?; let mut context_ptr: *const u8 = core::ptr::null(); let mut context_size = 0u8; if let Some(context) = context { context_ptr = context.as_ptr(); + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } context_size = context.len() as u8; } - let mut signature_size = signature.len() as u32; + let mut signature_size = crate::buffer_len_to_u32(signature.len())?; let rc = unsafe { sys::wc_ed25519ph_sign_hash(hash.as_ptr(), hash_size, signature.as_mut_ptr(), &mut signature_size, &mut self.ws_key, @@ -825,14 +831,17 @@ impl Ed25519 { /// ``` #[cfg(ed25519_sign)] pub fn sign_msg_ph(&mut self, message: &[u8], context: Option<&[u8]>, signature: &mut [u8]) -> Result { - let message_size = message.len() as u32; + let message_size = crate::buffer_len_to_u32(message.len())?; let mut context_ptr: *const u8 = core::ptr::null(); let mut context_size = 0u8; if let Some(context) = context { context_ptr = context.as_ptr(); + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } context_size = context.len() as u8; } - let mut signature_size = signature.len() as u32; + let mut signature_size = crate::buffer_len_to_u32(signature.len())?; let rc = unsafe { sys::wc_ed25519ph_sign_msg(message.as_ptr(), message_size, signature.as_mut_ptr(), &mut signature_size, &mut self.ws_key, @@ -878,14 +887,17 @@ impl Ed25519 { /// ``` #[cfg(ed25519_sign)] pub fn sign_msg_ex(&mut self, din: &[u8], context: Option<&[u8]>, typ: u8, signature: &mut [u8]) -> Result { - let din_size = din.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; let mut context_ptr: *const u8 = core::ptr::null(); let mut context_size = 0u8; if let Some(context) = context { context_ptr = context.as_ptr(); + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } context_size = context.len() as u8; } - let mut signature_size = signature.len() as u32; + let mut signature_size = crate::buffer_len_to_u32(signature.len())?; let rc = unsafe { sys::wc_ed25519_sign_msg_ex(din.as_ptr(), din_size, signature.as_mut_ptr(), &mut signature_size, &mut self.ws_key, @@ -927,8 +939,8 @@ impl Ed25519 { /// ``` #[cfg(ed25519_verify)] pub fn verify_msg(&mut self, signature: &[u8], message: &[u8]) -> Result { - let signature_size = signature.len() as u32; - let message_size = message.len() as u32; + let signature_size = crate::buffer_len_to_u32(signature.len())?; + let message_size = crate::buffer_len_to_u32(message.len())?; let mut res = 0i32; let rc = unsafe { sys::wc_ed25519_verify_msg(signature.as_ptr(), signature_size, @@ -974,8 +986,11 @@ impl Ed25519 { /// ``` #[cfg(ed25519_verify)] pub fn verify_msg_ctx(&mut self, signature: &[u8], message: &[u8], context: &[u8]) -> Result { - let signature_size = signature.len() as u32; - let message_size = message.len() as u32; + let signature_size = crate::buffer_len_to_u32(signature.len())?; + let message_size = crate::buffer_len_to_u32(message.len())?; + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } let context_size = context.len() as u8; let mut res = 0i32; let rc = unsafe { @@ -1034,12 +1049,15 @@ impl Ed25519 { /// ``` #[cfg(ed25519_verify)] pub fn verify_hash_ph(&mut self, signature: &[u8], hash: &[u8], context: Option<&[u8]>) -> Result { - let signature_size = signature.len() as u32; - let hash_size = hash.len() as u32; + let signature_size = crate::buffer_len_to_u32(signature.len())?; + let hash_size = crate::buffer_len_to_u32(hash.len())?; let mut context_ptr: *const u8 = core::ptr::null(); let mut context_size = 0u8; if let Some(context) = context { context_ptr = context.as_ptr(); + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } context_size = context.len() as u8; } let mut res = 0i32; @@ -1089,12 +1107,15 @@ impl Ed25519 { /// ``` #[cfg(ed25519_verify)] pub fn verify_msg_ph(&mut self, signature: &[u8], message: &[u8], context: Option<&[u8]>) -> Result { - let signature_size = signature.len() as u32; - let message_size = message.len() as u32; + let signature_size = crate::buffer_len_to_u32(signature.len())?; + let message_size = crate::buffer_len_to_u32(message.len())?; let mut context_ptr: *const u8 = core::ptr::null(); let mut context_size = 0u8; if let Some(context) = context { context_ptr = context.as_ptr(); + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } context_size = context.len() as u8; } let mut res = 0i32; @@ -1144,12 +1165,15 @@ impl Ed25519 { /// ``` #[cfg(ed25519_verify)] pub fn verify_msg_ex(&mut self, signature: &[u8], din: &[u8], context: Option<&[u8]>, typ: u8) -> Result { - let signature_size = signature.len() as u32; - let din_size = din.len() as u32; + let signature_size = crate::buffer_len_to_u32(signature.len())?; + let din_size = crate::buffer_len_to_u32(din.len())?; let mut context_ptr: *const u8 = core::ptr::null(); let mut context_size = 0u8; if let Some(context) = context { context_ptr = context.as_ptr(); + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } context_size = context.len() as u8; } let mut res = 0i32; @@ -1198,11 +1222,14 @@ impl Ed25519 { /// ``` #[cfg(ed25519_streaming_verify)] pub fn verify_msg_init(&mut self, signature: &[u8], context: Option<&[u8]>, typ: u8) -> Result<(), i32> { - let signature_size = signature.len() as u32; + let signature_size = crate::buffer_len_to_u32(signature.len())?; let mut context_ptr: *const u8 = core::ptr::null(); let mut context_size = 0u8; if let Some(context) = context { context_ptr = context.as_ptr(); + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } context_size = context.len() as u8; } let rc = unsafe { @@ -1247,7 +1274,7 @@ impl Ed25519 { /// ``` #[cfg(ed25519_streaming_verify)] pub fn verify_msg_update(&mut self, din: &[u8]) -> Result<(), i32> { - let din_size = din.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; let rc = unsafe { sys::wc_ed25519_verify_msg_update(din.as_ptr(), din_size, &mut self.ws_key) @@ -1290,7 +1317,7 @@ impl Ed25519 { /// ``` #[cfg(ed25519_streaming_verify)] pub fn verify_msg_final(&mut self, signature: &[u8]) -> Result { - let signature_size = signature.len() as u32; + let signature_size = crate::buffer_len_to_u32(signature.len())?; let mut res = 0i32; let rc = unsafe { sys::wc_ed25519_verify_msg_final(signature.as_ptr(), signature_size, @@ -1403,9 +1430,16 @@ impl Ed25519 { } } +impl Ed25519 { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.ws_key); } + } +} + impl Drop for Ed25519 { /// Safely free the wolfSSL resources. fn drop(&mut self) { unsafe { sys::wc_ed25519_free(&mut self.ws_key); } + self.zeroize(); } } diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/ed448.rs b/wrapper/rust/wolfssl-wolfcrypt/src/ed448.rs index a19caf35e5e..9191bed6880 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/ed448.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/ed448.rs @@ -241,8 +241,8 @@ impl Ed448 { /// ``` #[cfg(ed448_export)] pub fn export_key(&self, private: &mut [u8], public: &mut [u8]) -> Result<(), i32> { - let mut private_size = private.len() as u32; - let mut public_size = public.len() as u32; + let mut private_size = crate::buffer_len_to_u32(private.len())?; + let mut public_size = crate::buffer_len_to_u32(public.len())?; let rc = unsafe { sys::wc_ed448_export_key(&self.ws_key, private.as_mut_ptr(), &mut private_size, @@ -281,7 +281,7 @@ impl Ed448 { /// ``` #[cfg(ed448_export)] pub fn export_public(&self, public: &mut [u8]) -> Result<(), i32> { - let mut public_size = public.len() as u32; + let mut public_size = crate::buffer_len_to_u32(public.len())?; let rc = unsafe { sys::wc_ed448_export_public(&self.ws_key, public.as_mut_ptr(), &mut public_size) @@ -319,7 +319,7 @@ impl Ed448 { /// ``` #[cfg(ed448_export)] pub fn export_private(&self, keyout: &mut [u8]) -> Result<(), i32> { - let mut keyout_size = keyout.len() as u32; + let mut keyout_size = crate::buffer_len_to_u32(keyout.len())?; let rc = unsafe { sys::wc_ed448_export_private(&self.ws_key, keyout.as_mut_ptr(), &mut keyout_size) @@ -357,7 +357,7 @@ impl Ed448 { /// ``` #[cfg(ed448_export)] pub fn export_private_only(&self, private: &mut [u8]) -> Result<(), i32> { - let mut private_size = private.len() as u32; + let mut private_size = crate::buffer_len_to_u32(private.len())?; let rc = unsafe { sys::wc_ed448_export_private_only(&self.ws_key, private.as_mut_ptr(), &mut private_size) @@ -401,7 +401,7 @@ impl Ed448 { /// ``` #[cfg(ed448_import)] pub fn import_public(&mut self, public: &[u8]) -> Result<(), i32> { - let public_size = public.len() as u32; + let public_size = crate::buffer_len_to_u32(public.len())?; let rc = unsafe { sys::wc_ed448_import_public(public.as_ptr(), public_size, &mut self.ws_key) }; @@ -445,7 +445,7 @@ impl Ed448 { /// ``` #[cfg(ed448_import)] pub fn import_public_ex(&mut self, public: &[u8], trusted: bool) -> Result<(), i32> { - let public_size = public.len() as u32; + let public_size = crate::buffer_len_to_u32(public.len())?; let rc = unsafe { sys::wc_ed448_import_public_ex(public.as_ptr(), public_size, &mut self.ws_key, if trusted {1} else {0}) @@ -484,7 +484,7 @@ impl Ed448 { /// ``` #[cfg(ed448_import)] pub fn import_private_only(&mut self, private: &[u8]) -> Result<(), i32> { - let private_size = private.len() as u32; + let private_size = crate::buffer_len_to_u32(private.len())?; let rc = unsafe { sys::wc_ed448_import_private_only(private.as_ptr(), private_size, &mut self.ws_key) @@ -529,12 +529,12 @@ impl Ed448 { /// ``` #[cfg(ed448_import)] pub fn import_private_key(&mut self, private: &[u8], public: Option<&[u8]>) -> Result<(), i32> { - let private_size = private.len() as u32; + let private_size = crate::buffer_len_to_u32(private.len())?; let mut public_ptr: *const u8 = core::ptr::null(); let mut public_size = 0u32; if let Some(public) = public { public_ptr = public.as_ptr(); - public_size = public.len() as u32; + public_size = crate::buffer_len_to_u32(public.len())?; } let rc = unsafe { sys::wc_ed448_import_private_key(private.as_ptr(), private_size, @@ -580,12 +580,12 @@ impl Ed448 { /// ``` #[cfg(ed448_import)] pub fn import_private_key_ex(&mut self, private: &[u8], public: Option<&[u8]>, trusted: bool) -> Result<(), i32> { - let private_size = private.len() as u32; + let private_size = crate::buffer_len_to_u32(private.len())?; let mut public_ptr: *const u8 = core::ptr::null(); let mut public_size = 0u32; if let Some(public) = public { public_ptr = public.as_ptr(); - public_size = public.len() as u32; + public_size = crate::buffer_len_to_u32(public.len())?; } let rc = unsafe { sys::wc_ed448_import_private_key_ex(private.as_ptr(), private_size, @@ -626,7 +626,7 @@ impl Ed448 { /// ed.make_public(&mut public).expect("Error with make_public()"); /// ``` pub fn make_public(&mut self, pubkey: &mut [u8]) -> Result<(), i32> { - let pubkey_size = pubkey.len() as u32; + let pubkey_size = crate::buffer_len_to_u32(pubkey.len())?; let rc = unsafe { sys::wc_ed448_make_public(&mut self.ws_key, pubkey.as_mut_ptr(), pubkey_size) @@ -670,14 +670,17 @@ impl Ed448 { /// ``` #[cfg(ed448_sign)] pub fn sign_msg(&mut self, message: &[u8], context: Option<&[u8]>, signature: &mut [u8]) -> Result { - let message_size = message.len() as u32; + let message_size = crate::buffer_len_to_u32(message.len())?; let mut context_ptr: *const u8 = core::ptr::null(); let mut context_size = 0u8; if let Some(context) = context { context_ptr = context.as_ptr(); + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } context_size = context.len() as u8; } - let mut signature_size = signature.len() as u32; + let mut signature_size = crate::buffer_len_to_u32(signature.len())?; let rc = unsafe { sys::wc_ed448_sign_msg(message.as_ptr(), message_size, signature.as_mut_ptr(), &mut signature_size, &mut self.ws_key, @@ -732,14 +735,17 @@ impl Ed448 { /// ``` #[cfg(ed448_sign)] pub fn sign_hash_ph(&mut self, hash: &[u8], context: Option<&[u8]>, signature: &mut [u8]) -> Result { - let hash_size = hash.len() as u32; + let hash_size = crate::buffer_len_to_u32(hash.len())?; let mut context_ptr: *const u8 = core::ptr::null(); let mut context_size = 0u8; if let Some(context) = context { context_ptr = context.as_ptr(); + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } context_size = context.len() as u8; } - let mut signature_size = signature.len() as u32; + let mut signature_size = crate::buffer_len_to_u32(signature.len())?; let rc = unsafe { sys::wc_ed448ph_sign_hash(hash.as_ptr(), hash_size, signature.as_mut_ptr(), &mut signature_size, &mut self.ws_key, @@ -785,14 +791,17 @@ impl Ed448 { /// ``` #[cfg(ed448_sign)] pub fn sign_msg_ph(&mut self, message: &[u8], context: Option<&[u8]>, signature: &mut [u8]) -> Result { - let message_size = message.len() as u32; + let message_size = crate::buffer_len_to_u32(message.len())?; let mut context_ptr: *const u8 = core::ptr::null(); let mut context_size = 0u8; if let Some(context) = context { context_ptr = context.as_ptr(); + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } context_size = context.len() as u8; } - let mut signature_size = signature.len() as u32; + let mut signature_size = crate::buffer_len_to_u32(signature.len())?; let rc = unsafe { sys::wc_ed448ph_sign_msg(message.as_ptr(), message_size, signature.as_mut_ptr(), &mut signature_size, &mut self.ws_key, @@ -838,14 +847,17 @@ impl Ed448 { /// ``` #[cfg(ed448_sign)] pub fn sign_msg_ex(&mut self, din: &[u8], context: Option<&[u8]>, typ: u8, signature: &mut [u8]) -> Result { - let din_size = din.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; let mut context_ptr: *const u8 = core::ptr::null(); let mut context_size = 0u8; if let Some(context) = context { context_ptr = context.as_ptr(); + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } context_size = context.len() as u8; } - let mut signature_size = signature.len() as u32; + let mut signature_size = crate::buffer_len_to_u32(signature.len())?; let rc = unsafe { sys::wc_ed448_sign_msg_ex(din.as_ptr(), din_size, signature.as_mut_ptr(), &mut signature_size, &mut self.ws_key, @@ -891,12 +903,15 @@ impl Ed448 { /// ``` #[cfg(ed448_verify)] pub fn verify_msg(&mut self, signature: &[u8], message: &[u8], context: Option<&[u8]>) -> Result { - let signature_size = signature.len() as u32; - let message_size = message.len() as u32; + let signature_size = crate::buffer_len_to_u32(signature.len())?; + let message_size = crate::buffer_len_to_u32(message.len())?; let mut context_ptr: *const u8 = core::ptr::null(); let mut context_size = 0u8; if let Some(context) = context { context_ptr = context.as_ptr(); + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } context_size = context.len() as u8; } let mut res = 0i32; @@ -956,12 +971,15 @@ impl Ed448 { /// ``` #[cfg(ed448_verify)] pub fn verify_hash_ph(&mut self, signature: &[u8], hash: &[u8], context: Option<&[u8]>) -> Result { - let signature_size = signature.len() as u32; - let hash_size = hash.len() as u32; + let signature_size = crate::buffer_len_to_u32(signature.len())?; + let hash_size = crate::buffer_len_to_u32(hash.len())?; let mut context_ptr: *const u8 = core::ptr::null(); let mut context_size = 0u8; if let Some(context) = context { context_ptr = context.as_ptr(); + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } context_size = context.len() as u8; } let mut res = 0i32; @@ -1011,12 +1029,15 @@ impl Ed448 { /// ``` #[cfg(ed448_verify)] pub fn verify_msg_ph(&mut self, signature: &[u8], message: &[u8], context: Option<&[u8]>) -> Result { - let signature_size = signature.len() as u32; - let message_size = message.len() as u32; + let signature_size = crate::buffer_len_to_u32(signature.len())?; + let message_size = crate::buffer_len_to_u32(message.len())?; let mut context_ptr: *const u8 = core::ptr::null(); let mut context_size = 0u8; if let Some(context) = context { context_ptr = context.as_ptr(); + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } context_size = context.len() as u8; } let mut res = 0i32; @@ -1066,12 +1087,15 @@ impl Ed448 { /// ``` #[cfg(ed448_verify)] pub fn verify_msg_ex(&mut self, signature: &[u8], din: &[u8], context: Option<&[u8]>, typ: u8) -> Result { - let signature_size = signature.len() as u32; - let din_size = din.len() as u32; + let signature_size = crate::buffer_len_to_u32(signature.len())?; + let din_size = crate::buffer_len_to_u32(din.len())?; let mut context_ptr: *const u8 = core::ptr::null(); let mut context_size = 0u8; if let Some(context) = context { context_ptr = context.as_ptr(); + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } context_size = context.len() as u8; } let mut res = 0i32; @@ -1121,11 +1145,14 @@ impl Ed448 { /// ``` #[cfg(ed448_streaming_verify)] pub fn verify_msg_init(&mut self, signature: &[u8], context: Option<&[u8]>, typ: u8) -> Result<(), i32> { - let signature_size = signature.len() as u32; + let signature_size = crate::buffer_len_to_u32(signature.len())?; let mut context_ptr: *const u8 = core::ptr::null(); let mut context_size = 0u8; if let Some(context) = context { context_ptr = context.as_ptr(); + if context.len() > 255 { + return Err(sys::wolfCrypt_ErrorCodes_BAD_FUNC_ARG); + } context_size = context.len() as u8; } let rc = unsafe { @@ -1171,7 +1198,7 @@ impl Ed448 { /// ``` #[cfg(ed448_streaming_verify)] pub fn verify_msg_update(&mut self, din: &[u8]) -> Result<(), i32> { - let din_size = din.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; let rc = unsafe { sys::wc_ed448_verify_msg_update(din.as_ptr(), din_size, &mut self.ws_key) @@ -1215,7 +1242,7 @@ impl Ed448 { /// ``` #[cfg(ed448_streaming_verify)] pub fn verify_msg_final(&mut self, signature: &[u8]) -> Result { - let signature_size = signature.len() as u32; + let signature_size = crate::buffer_len_to_u32(signature.len())?; let mut res = 0i32; let rc = unsafe { sys::wc_ed448_verify_msg_final(signature.as_ptr(), signature_size, @@ -1328,9 +1355,16 @@ impl Ed448 { } } +impl Ed448 { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.ws_key); } + } +} + impl Drop for Ed448 { /// Safely free the wolfSSL resources. fn drop(&mut self) { unsafe { sys::wc_ed448_free(&mut self.ws_key); } + self.zeroize(); } } diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/hkdf.rs b/wrapper/rust/wolfssl-wolfcrypt/src/hkdf.rs index b1d26ec2551..ecccbf0f656 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/hkdf.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/hkdf.rs @@ -97,9 +97,9 @@ pub fn hkdf_extract_ex(typ: i32, salt: Option<&[u8]>, key: &[u8], out: &mut [u8] let mut salt_size = 0u32; if let Some(salt) = salt { salt_ptr = salt.as_ptr(); - salt_size = salt.len() as u32; + salt_size = crate::buffer_len_to_u32(salt.len())?; } - let key_size = key.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; if out.len() != HMAC::get_hmac_size_by_type(typ)? { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } @@ -192,14 +192,14 @@ pub fn hkdf_expand(typ: i32, key: &[u8], info: Option<&[u8]>, out: &mut [u8]) -> /// hkdf_expand_ex(HMAC::TYPE_SHA256, &extract_out, Some(info), &mut expand_out, None, None).expect("Error with hkdf_expand_ex()"); /// ``` pub fn hkdf_expand_ex(typ: i32, key: &[u8], info: Option<&[u8]>, out: &mut [u8], heap: Option<*mut core::ffi::c_void>, dev_id: Option) -> Result<(), i32> { - let key_size = key.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; let mut info_ptr = core::ptr::null(); let mut info_size = 0u32; if let Some(info) = info { info_ptr = info.as_ptr(); - info_size = info.len() as u32; + info_size = crate::buffer_len_to_u32(info.len())?; } - let out_size = out.len() as u32; + let out_size = crate::buffer_len_to_u32(out.len())?; let heap = match heap { Some(heap) => heap, None => core::ptr::null_mut(), @@ -250,20 +250,20 @@ pub fn hkdf_expand_ex(typ: i32, key: &[u8], info: Option<&[u8]>, out: &mut [u8], /// hkdf(HMAC::TYPE_SHA256, ikm, Some(salt), Some(info), &mut out).expect("Error with hkdf()"); /// ``` pub fn hkdf(typ: i32, key: &[u8], salt: Option<&[u8]>, info: Option<&[u8]>, out: &mut[u8]) -> Result<(), i32> { - let key_size = key.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; let mut salt_ptr = core::ptr::null(); let mut salt_size = 0u32; if let Some(salt) = salt { salt_ptr = salt.as_ptr(); - salt_size = salt.len() as u32; + salt_size = crate::buffer_len_to_u32(salt.len())?; } let mut info_ptr = core::ptr::null(); let mut info_size = 0u32; if let Some(info) = info { info_ptr = info.as_ptr(); - info_size = info.len() as u32; + info_size = crate::buffer_len_to_u32(info.len())?; } - let out_size = out.len() as u32; + let out_size = crate::buffer_len_to_u32(out.len())?; let rc = unsafe { sys::wc_HKDF(typ, key.as_ptr(), key_size, salt_ptr, salt_size, info_ptr, info_size, out.as_mut_ptr(), out_size) diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/hmac.rs b/wrapper/rust/wolfssl-wolfcrypt/src/hmac.rs index 24e53089fef..b1d004006ce 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/hmac.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/hmac.rs @@ -113,7 +113,7 @@ impl HMAC { /// let mut hmac = HMAC::new_ex(HMAC::TYPE_SHA256, &key, None, None).expect("Error with new_ex()"); /// ``` pub fn new_ex(typ: i32, key: &[u8], heap: Option<*mut core::ffi::c_void>, dev_id: Option) -> Result { - let key_size = key.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; let mut wc_hmac: MaybeUninit = MaybeUninit::uninit(); let heap = match heap { Some(heap) => heap, @@ -191,7 +191,7 @@ impl HMAC { /// ``` #[cfg(hmac_setkey_ex)] pub fn new_allow_short_key_ex(typ: i32, key: &[u8], heap: Option<*mut core::ffi::c_void>, dev_id: Option) -> Result { - let key_size = key.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; let mut wc_hmac: MaybeUninit = MaybeUninit::uninit(); let heap = match heap { Some(heap) => heap, @@ -241,7 +241,7 @@ impl HMAC { /// hmac.update(b"input").expect("Error with update()"); /// ``` pub fn update(&mut self, data: &[u8]) -> Result<(), i32> { - let data_size = data.len() as u32; + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { sys::wc_HmacUpdate(&mut self.wc_hmac, data.as_ptr(), data_size) }; @@ -324,6 +324,12 @@ impl HMAC { } } +impl HMAC { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_hmac); } + } +} + impl Drop for HMAC { /// Safely free the underlying wolfSSL Hmac context. /// @@ -334,5 +340,6 @@ impl Drop for HMAC { /// resources and preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_HmacFree(&mut self.wc_hmac); } + self.zeroize(); } } diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/kdf.rs b/wrapper/rust/wolfssl-wolfcrypt/src/kdf.rs index 9f586730693..ab294f1a50a 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/kdf.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/kdf.rs @@ -43,6 +43,10 @@ pub const SRTCP_LABEL_SALT: u8 = sys::WC_SRTCP_LABEL_SALT as u8; pub const SRTP_LABEL_HDR_ENCRYPTION: u8 = sys::WC_SRTP_LABEL_HDR_ENCRYPTION as u8; #[cfg(kdf_srtp)] pub const SRTP_LABEL_HDR_SALT: u8 = sys::WC_SRTP_LABEL_HDR_SALT as u8; +#[cfg(kdf_srtp)] +pub const SRTP_INDEX_LEN: usize = sys::WC_SRTP_INDEX_LEN as usize; +#[cfg(kdf_srtp)] +pub const SRTCP_INDEX_LEN: usize = sys::WC_SRTCP_INDEX_LEN as usize; /// Implement Password Based Key Derivation Function 2 (PBKDF2) converting an /// input password with a concatenated salt into a more secure key which is @@ -126,9 +130,9 @@ pub fn pbkdf2(password: &[u8], salt: &[u8], iterations: i32, typ: i32, out: &mut /// ``` #[cfg(kdf_pbkdf2)] pub fn pbkdf2_ex(password: &[u8], salt: &[u8], iterations: i32, typ: i32, heap: Option<*mut core::ffi::c_void>, dev_id: Option, out: &mut [u8]) -> Result<(), i32> { - let password_size = password.len() as i32; - let salt_size = salt.len() as i32; - let out_size = out.len() as i32; + let password_size = crate::buffer_len_to_i32(password.len())?; + let salt_size = crate::buffer_len_to_i32(salt.len())?; + let out_size = crate::buffer_len_to_i32(out.len())?; let heap = match heap { Some(heap) => heap, None => core::ptr::null_mut(), @@ -248,9 +252,9 @@ pub fn pkcs12_pbkdf(password: &[u8], salt: &[u8], iterations: i32, typ: i32, id: /// ``` #[cfg(kdf_pkcs12)] pub fn pkcs12_pbkdf_ex(password: &[u8], salt: &[u8], iterations: i32, typ: i32, id: i32, heap: Option<*mut core::ffi::c_void>, out: &mut [u8]) -> Result<(), i32> { - let password_size = password.len() as i32; - let salt_size = salt.len() as i32; - let out_size = out.len() as i32; + let password_size = crate::buffer_len_to_i32(password.len())?; + let salt_size = crate::buffer_len_to_i32(salt.len())?; + let out_size = crate::buffer_len_to_i32(out.len())?; let heap = match heap { Some(heap) => heap, None => core::ptr::null_mut(), @@ -335,14 +339,14 @@ pub fn tls13_hkdf_extract_ex(typ: i32, salt: Option<&[u8]>, key: Option<&mut [u8 let mut salt_size = 0u32; if let Some(salt) = salt { salt_ptr = salt.as_ptr(); - salt_size = salt.len() as u32; + salt_size = crate::buffer_len_to_u32(salt.len())?; } let mut ikm_buf = [0u8; sys::WC_MAX_DIGEST_SIZE as usize]; let mut ikm_ptr = ikm_buf.as_mut_ptr(); let mut ikm_size = 0u32; if let Some(key) = key && !key.is_empty() { ikm_ptr = key.as_mut_ptr(); - ikm_size = key.len() as u32; + ikm_size = crate::buffer_len_to_u32(key.len())?; } if out.len() != HMAC::get_hmac_size_by_type(typ)? { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); @@ -474,11 +478,11 @@ pub fn tls13_hkdf_expand_label(typ: i32, key: &[u8], protocol: &[u8], label: &[u #[cfg(all(hmac, kdf_tls13))] #[allow(clippy::too_many_arguments)] pub fn tls13_hkdf_expand_label_ex(typ: i32, key: &[u8], protocol: &[u8], label: &[u8], info: &[u8], out: &mut [u8], heap: Option<*mut core::ffi::c_void>, dev_id: Option) -> Result<(), i32> { - let key_size = key.len() as u32; - let protocol_size = protocol.len() as u32; - let label_size = label.len() as u32; - let info_size = info.len() as u32; - let out_size = out.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; + let protocol_size = crate::buffer_len_to_u32(protocol.len())?; + let label_size = crate::buffer_len_to_u32(label.len())?; + let info_size = crate::buffer_len_to_u32(info.len())?; + let out_size = crate::buffer_len_to_u32(out.len())?; let heap = match heap { Some(heap) => heap, None => core::ptr::null_mut(), @@ -531,10 +535,10 @@ pub fn tls13_hkdf_expand_label_ex(typ: i32, key: &[u8], protocol: &[u8], label: /// ``` #[cfg(kdf_ssh)] pub fn ssh_kdf(typ: i32, key_id: u8, k: &[u8], h: &[u8], session_id: &[u8], key: &mut [u8]) -> Result<(), i32> { - let key_size = key.len() as u32; - let k_size = k.len() as u32; - let h_size = h.len() as u32; - let session_size = session_id.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; + let k_size = crate::buffer_len_to_u32(k.len())?; + let h_size = crate::buffer_len_to_u32(h.len())?; + let session_size = crate::buffer_len_to_u32(session_id.len())?; let rc = unsafe { sys::wc_SSH_KDF(typ as u8, key_id, key.as_mut_ptr(), key_size, @@ -582,13 +586,13 @@ pub fn ssh_kdf(typ: i32, key_id: u8, k: &[u8], h: &[u8], session_id: &[u8], key: /// } /// ``` #[cfg(kdf_srtp)] -pub fn srtp_kdf(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8], +pub fn srtp_kdf(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8; SRTP_INDEX_LEN], key1: &mut [u8], key2: &mut [u8], key3: &mut [u8]) -> Result<(), i32> { - let key_size = key.len() as u32; - let salt_size = salt.len() as u32; - let key1_size = key1.len() as u32; - let key2_size = key2.len() as u32; - let key3_size = key3.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; + let salt_size = crate::buffer_len_to_u32(salt.len())?; + let key1_size = crate::buffer_len_to_u32(key1.len())?; + let key2_size = crate::buffer_len_to_u32(key2.len())?; + let key3_size = crate::buffer_len_to_u32(key3.len())?; let rc = unsafe { sys::wc_SRTP_KDF(key.as_ptr(), key_size, salt.as_ptr(), salt_size, kdr_index, idx.as_ptr(), key1.as_mut_ptr(), key1_size, @@ -632,11 +636,11 @@ pub fn srtp_kdf(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8], /// } /// ``` #[cfg(kdf_srtp)] -pub fn srtp_kdf_label(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8], +pub fn srtp_kdf_label(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8; SRTP_INDEX_LEN], label: u8, keyout: &mut [u8]) -> Result<(), i32> { - let key_size = key.len() as u32; - let salt_size = salt.len() as u32; - let keyout_size = keyout.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; + let salt_size = crate::buffer_len_to_u32(salt.len())?; + let keyout_size = crate::buffer_len_to_u32(keyout.len())?; let rc = unsafe { sys::wc_SRTP_KDF_label(key.as_ptr(), key_size, salt.as_ptr(), salt_size, kdr_index, idx.as_ptr(), label, keyout.as_mut_ptr(), keyout_size) @@ -674,7 +678,7 @@ pub fn srtp_kdf_label(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8], /// 0x8e, 0x26, 0xad, 0xb5, 0x32, 0x12, 0x98, 0x90]; /// let salt = [0x0eu8, 0x23, 0x00, 0x6c, 0x6c, 0x04, 0x4f, 0x56, /// 0x62, 0x40, 0x0e, 0x9d, 0x1b, 0xd6]; -/// let index = [0x48u8, 0x71, 0x65, 0x64, 0x9c, 0xca]; +/// let index = [0x48u8, 0x71, 0x65, 0x64]; /// let mut key_e = [0u8; 16]; /// let mut key_a = [0u8; 20]; /// let mut key_s = [0u8; 14]; @@ -682,13 +686,13 @@ pub fn srtp_kdf_label(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8], /// } /// ``` #[cfg(kdf_srtp)] -pub fn srtcp_kdf(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8], +pub fn srtcp_kdf(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8; SRTCP_INDEX_LEN], key1: &mut [u8], key2: &mut [u8], key3: &mut [u8]) -> Result<(), i32> { - let key_size = key.len() as u32; - let salt_size = salt.len() as u32; - let key1_size = key1.len() as u32; - let key2_size = key2.len() as u32; - let key3_size = key3.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; + let salt_size = crate::buffer_len_to_u32(salt.len())?; + let key1_size = crate::buffer_len_to_u32(key1.len())?; + let key2_size = crate::buffer_len_to_u32(key2.len())?; + let key3_size = crate::buffer_len_to_u32(key3.len())?; let rc = unsafe { sys::wc_SRTCP_KDF(key.as_ptr(), key_size, salt.as_ptr(), salt_size, kdr_index, idx.as_ptr(), key1.as_mut_ptr(), key1_size, @@ -726,17 +730,17 @@ pub fn srtcp_kdf(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8], /// 0x8e, 0x26, 0xad, 0xb5, 0x32, 0x12, 0x98, 0x90]; /// let salt = [0x0eu8, 0x23, 0x00, 0x6c, 0x6c, 0x04, 0x4f, 0x56, /// 0x62, 0x40, 0x0e, 0x9d, 0x1b, 0xd6]; -/// let index = [0x48u8, 0x71, 0x65, 0x64, 0x9c, 0xca]; +/// let index = [0x48u8, 0x71, 0x65, 0x64]; /// let mut key_a = [0u8; 20]; /// srtcp_kdf_label(&key, &salt, -1, &index, SRTCP_LABEL_MSG_AUTH, &mut key_a).expect("Error with srtcp_kdf_label()"); /// } /// ``` #[cfg(kdf_srtp)] -pub fn srtcp_kdf_label(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8], +pub fn srtcp_kdf_label(key: &[u8], salt: &[u8], kdr_index: i32, idx: &[u8; SRTCP_INDEX_LEN], label: u8, keyout: &mut [u8]) -> Result<(), i32> { - let key_size = key.len() as u32; - let salt_size = salt.len() as u32; - let keyout_size = keyout.len() as u32; + let key_size = crate::buffer_len_to_u32(key.len())?; + let salt_size = crate::buffer_len_to_u32(salt.len())?; + let keyout_size = crate::buffer_len_to_u32(keyout.len())?; let rc = unsafe { sys::wc_SRTCP_KDF_label(key.as_ptr(), key_size, salt.as_ptr(), salt_size, kdr_index, idx.as_ptr(), label, keyout.as_mut_ptr(), keyout_size) diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/lib.rs b/wrapper/rust/wolfssl-wolfcrypt/src/lib.rs index 7f1d1e3f96c..729c7cff968 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/lib.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/lib.rs @@ -23,6 +23,23 @@ /* bindgen-generated bindings to the C library */ pub mod sys; +/// Zeroize the raw bytes of a value. For use in `zeroize()` methods on C FFI +/// structs where `#[derive(Zeroize)]` cannot be used. +/// +/// # Safety +/// +/// `val` must be a valid, initialized value whose entire `size_of_val` byte +/// representation is safe to overwrite with zeroes. +pub(crate) unsafe fn zeroize_raw(val: &mut T) { + use zeroize::Zeroize; + unsafe { + core::slice::from_raw_parts_mut( + val as *mut T as *mut u8, + core::mem::size_of_val(val), + ).zeroize(); + } +} + pub mod aes; pub mod blake2; pub mod chacha20_poly1305; @@ -44,6 +61,16 @@ pub mod random; pub mod rsa; pub mod sha; +/// Convert a buffer length to `u32`, returning `BUFFER_E` if it overflows. +pub(crate) fn buffer_len_to_u32(len: usize) -> Result { + u32::try_from(len).map_err(|_| sys::wolfCrypt_ErrorCodes_BUFFER_E) +} + +/// Convert a buffer length to `i32`, returning `BUFFER_E` if it overflows. +pub(crate) fn buffer_len_to_i32(len: usize) -> Result { + i32::try_from(len).map_err(|_| sys::wolfCrypt_ErrorCodes_BUFFER_E) +} + /// Initialize resources used by wolfCrypt. /// /// # Returns diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/lms.rs b/wrapper/rust/wolfssl-wolfcrypt/src/lms.rs index dd12c2409e9..f76f82a7db5 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/lms.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/lms.rs @@ -528,14 +528,15 @@ impl Lms { if sig.len() < expected_sig_len { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } - let mut sig_sz = sig.len() as u32; + let mut sig_sz = crate::buffer_len_to_u32(sig.len())?; + let msg_sz = crate::buffer_len_to_i32(msg.len())?; let rc = unsafe { sys::wc_LmsKey_Sign( &mut self.ws_key, sig.as_mut_ptr(), &mut sig_sz, msg.as_ptr(), - msg.len() as core::ffi::c_int, + msg_sz, ) }; if rc != 0 { @@ -670,7 +671,7 @@ impl Lms { /// } /// ``` pub fn export_pub_raw(&self, out: &mut [u8]) -> Result { - let mut out_len = out.len() as u32; + let mut out_len = crate::buffer_len_to_u32(out.len())?; let rc = unsafe { sys::wc_LmsKey_ExportPubRaw(&self.ws_key, out.as_mut_ptr(), &mut out_len) }; @@ -704,8 +705,9 @@ impl Lms { /// key.import_pub_raw(&pub_buf).expect("Error with import_pub_raw()"); /// ``` pub fn import_pub_raw(&mut self, data: &[u8]) -> Result<(), i32> { + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { - sys::wc_LmsKey_ImportPubRaw(&mut self.ws_key, data.as_ptr(), data.len() as u32) + sys::wc_LmsKey_ImportPubRaw(&mut self.ws_key, data.as_ptr(), data_size) }; if rc != 0 { return Err(rc); @@ -735,13 +737,15 @@ impl Lms { if sig.len() != expected_sig_len { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } + let sig_sz = crate::buffer_len_to_u32(sig.len())?; + let msg_sz = crate::buffer_len_to_i32(msg.len())?; let rc = unsafe { sys::wc_LmsKey_Verify( &mut self.ws_key, sig.as_ptr(), - sig.len() as u32, + sig_sz, msg.as_ptr(), - msg.len() as core::ffi::c_int, + msg_sz, ) }; if rc != 0 { @@ -752,13 +756,17 @@ impl Lms { /// Get the Key ID (I value) for this LMS/HSS key. /// - /// Returns a slice pointing into the key's internal storage. + /// Copies the key ID into the provided buffer. + /// + /// # Parameters + /// + /// * `kid`: Buffer in which to store the key ID. /// /// # Returns /// - /// Returns either Ok(&[u8]) containing the key ID on success, or Err(e) - /// containing the wolfSSL library error code value. - pub fn get_kid(&mut self) -> Result<&[u8], i32> { + /// Returns either Ok(usize) containing the key ID length on success, + /// or Err(e) containing the wolfSSL library error code value. + pub fn get_kid(&mut self, kid: &mut [u8]) -> Result { let mut kid_ptr: *const u8 = core::ptr::null(); let mut kid_sz: u32 = 0; let rc = unsafe { @@ -767,8 +775,18 @@ impl Lms { if rc != 0 { return Err(rc); } - let slice = unsafe { core::slice::from_raw_parts(kid_ptr, kid_sz as usize) }; - Ok(slice) + let src = unsafe { core::slice::from_raw_parts(kid_ptr, kid_sz as usize) }; + if kid.len() < src.len() { + return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); + } + kid[..src.len()].copy_from_slice(src); + Ok(src.len()) + } +} + +impl Lms { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.ws_key); } } } @@ -781,5 +799,6 @@ impl Drop for Lms { unsafe { sys::wc_LmsKey_Free(&mut self.ws_key); } + self.zeroize(); } } diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/mlkem.rs b/wrapper/rust/wolfssl-wolfcrypt/src/mlkem.rs index c2615dffb0f..bedd6f2d8e2 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/mlkem.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/mlkem.rs @@ -72,6 +72,10 @@ use crate::random::RNG; /// /// An instance is created with [`MlKem::generate()`], /// [`MlKem::generate_with_random()`], or [`MlKem::new()`]. +/// +/// This struct does not implement Send or Sync because it is not safe in the +/// general case to access the underlying C API from multiple threads +/// concurrently. pub struct MlKem { ws_key: *mut sys::MlKemKey, } @@ -608,12 +612,13 @@ impl MlKem { if ss.len() != Self::SHARED_SECRET_SIZE { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } + let ct_size = crate::buffer_len_to_u32(ct.len())?; let rc = unsafe { sys::wc_MlKemKey_Decapsulate( self.ws_key, ss.as_mut_ptr(), ct.as_ptr(), - ct.len() as u32, + ct_size, ) }; if rc != 0 { @@ -653,8 +658,9 @@ impl MlKem { /// } /// ``` pub fn encode_public_key(&self, out: &mut [u8]) -> Result { + let out_size = crate::buffer_len_to_u32(out.len())?; let rc = unsafe { - sys::wc_MlKemKey_EncodePublicKey(self.ws_key, out.as_mut_ptr(), out.len() as u32) + sys::wc_MlKemKey_EncodePublicKey(self.ws_key, out.as_mut_ptr(), out_size) }; if rc != 0 { return Err(rc); @@ -693,8 +699,9 @@ impl MlKem { /// } /// ``` pub fn encode_private_key(&self, out: &mut [u8]) -> Result { + let out_size = crate::buffer_len_to_u32(out.len())?; let rc = unsafe { - sys::wc_MlKemKey_EncodePrivateKey(self.ws_key, out.as_mut_ptr(), out.len() as u32) + sys::wc_MlKemKey_EncodePrivateKey(self.ws_key, out.as_mut_ptr(), out_size) }; if rc != 0 { return Err(rc); @@ -731,8 +738,9 @@ impl MlKem { /// } /// ``` pub fn decode_public_key(&mut self, data: &[u8]) -> Result<(), i32> { + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { - sys::wc_MlKemKey_DecodePublicKey(self.ws_key, data.as_ptr(), data.len() as u32) + sys::wc_MlKemKey_DecodePublicKey(self.ws_key, data.as_ptr(), data_size) }; if rc != 0 { return Err(rc); @@ -769,8 +777,9 @@ impl MlKem { /// } /// ``` pub fn decode_private_key(&mut self, data: &[u8]) -> Result<(), i32> { + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { - sys::wc_MlKemKey_DecodePrivateKey(self.ws_key, data.as_ptr(), data.len() as u32) + sys::wc_MlKemKey_DecodePrivateKey(self.ws_key, data.as_ptr(), data_size) }; if rc != 0 { return Err(rc); @@ -779,6 +788,12 @@ impl MlKem { } } +impl MlKem { + fn zeroize(&mut self) { + self.ws_key = core::ptr::null_mut(); + } +} + impl Drop for MlKem { /// Safely free the underlying wolfSSL ML-KEM key context. /// @@ -788,5 +803,6 @@ impl Drop for MlKem { unsafe { sys::wc_MlKemKey_Delete(self.ws_key, core::ptr::null_mut()); } + self.zeroize(); } } diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/prf.rs b/wrapper/rust/wolfssl-wolfcrypt/src/prf.rs index a4deadc428f..2358c28f477 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/prf.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/prf.rs @@ -120,9 +120,9 @@ pub fn prf(secret: &[u8], seed: &[u8], hash_type: i32, dout: &mut [u8]) -> Resul /// } /// ``` pub fn prf_ex(secret: &[u8], seed: &[u8], hash_type: i32, heap: Option<*mut core::ffi::c_void>, dev_id: Option, dout: &mut [u8]) -> Result<(), i32> { - let secret_size = secret.len() as u32; - let seed_size = seed.len() as u32; - let dout_size = dout.len() as u32; + let secret_size = crate::buffer_len_to_u32(secret.len())?; + let seed_size = crate::buffer_len_to_u32(seed.len())?; + let dout_size = crate::buffer_len_to_u32(dout.len())?; let heap = match heap { Some(heap) => heap, None => core::ptr::null_mut(), diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/random.rs b/wrapper/rust/wolfssl-wolfcrypt/src/random.rs index 7d3bb8a79ab..5fb54294469 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/random.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/random.rs @@ -96,7 +96,7 @@ impl RNG { return Err(rc); } } - let mut rng: MaybeUninit = MaybeUninit::uninit(); + let mut wc_rng: MaybeUninit = MaybeUninit::uninit(); let heap = match heap { Some(heap) => heap, None => core::ptr::null_mut(), @@ -106,10 +106,11 @@ impl RNG { None => sys::INVALID_DEVID, }; let rc = unsafe { - sys::wc_InitRng_ex(&mut (*rng.as_mut_ptr()).wc_rng, heap, dev_id) + sys::wc_InitRng_ex(wc_rng.as_mut_ptr(), heap, dev_id) }; if rc == 0 { - let rng = unsafe { rng.assume_init() }; + let wc_rng = unsafe { wc_rng.assume_init() }; + let rng = RNG {wc_rng}; Ok(rng) } else { Err(rc) @@ -156,8 +157,8 @@ impl RNG { } } let ptr = nonce.as_mut_ptr() as *mut u8; - let size: u32 = size_of_val(nonce) as u32; - let mut rng: MaybeUninit = MaybeUninit::uninit(); + let size = crate::buffer_len_to_u32(size_of_val(nonce))?; + let mut wc_rng: MaybeUninit = MaybeUninit::uninit(); let heap = match heap { Some(heap) => heap, None => core::ptr::null_mut(), @@ -167,10 +168,11 @@ impl RNG { None => sys::INVALID_DEVID, }; let rc = unsafe { - sys::wc_InitRngNonce_ex(&mut (*rng.as_mut_ptr()).wc_rng, ptr, size, heap, dev_id) + sys::wc_InitRngNonce_ex(wc_rng.as_mut_ptr(), ptr, size, heap, dev_id) }; if rc == 0 { - let rng = unsafe { rng.assume_init() }; + let wc_rng = unsafe { wc_rng.assume_init() }; + let rng = RNG {wc_rng}; Ok(rng) } else { Err(rc) @@ -242,16 +244,16 @@ impl RNG { let mut nonce_size = 0u32; if let Some(nonce) = nonce { nonce_ptr = nonce.as_ptr(); - nonce_size = nonce.len() as u32; + nonce_size = crate::buffer_len_to_u32(nonce.len())?; } - let seed_a_size = seed_a.len() as u32; + let seed_a_size = crate::buffer_len_to_u32(seed_a.len())?; let mut seed_b_ptr = core::ptr::null(); let mut seed_b_size = 0u32; if let Some(seed_b) = seed_b { seed_b_ptr = seed_b.as_ptr(); - seed_b_size = seed_b.len() as u32; + seed_b_size = crate::buffer_len_to_u32(seed_b.len())?; } - let output_size = output.len() as u32; + let output_size = crate::buffer_len_to_u32(output.len())?; let heap = match heap { Some(heap) => heap, None => core::ptr::null_mut(), @@ -295,7 +297,7 @@ impl RNG { /// ``` #[cfg(random_hashdrbg)] pub fn test_seed(seed: &[u8]) -> Result<(), i32> { - let seed_size = seed.len() as u32; + let seed_size = crate::buffer_len_to_u32(seed.len())?; let rc = unsafe { sys::wc_RNG_TestSeed(seed.as_ptr(), seed_size) }; if rc != 0 { return Err(rc); @@ -338,7 +340,7 @@ impl RNG { /// library return code on failure. pub fn generate_block(&mut self, buf: &mut [T]) -> Result<(), i32> { let ptr = buf.as_mut_ptr() as *mut u8; - let size: u32 = size_of_val(buf) as u32; + let size = crate::buffer_len_to_u32(size_of_val(buf))?; let rc = unsafe { sys::wc_RNG_GenerateBlock(&mut self.wc_rng, ptr, size) }; if rc == 0 { Ok(()) @@ -369,7 +371,7 @@ impl RNG { /// ``` #[cfg(random_hashdrbg)] pub fn reseed(&mut self, seed: &[u8]) -> Result<(), i32> { - let seed_size = seed.len() as u32; + let seed_size = crate::buffer_len_to_u32(seed.len())?; let rc = unsafe { sys::wc_RNG_DRBG_Reseed(&mut self.wc_rng, seed.as_ptr(), seed_size) }; @@ -408,6 +410,12 @@ impl rand_core::TryRng for RNG { #[cfg(feature = "rand_core")] impl rand_core::TryCryptoRng for RNG {} +impl RNG { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_rng); } + } +} + impl Drop for RNG { /// Safely free the underlying wolfSSL RNG context. /// @@ -418,5 +426,6 @@ impl Drop for RNG { /// preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_FreeRng(&mut self.wc_rng); } + self.zeroize(); } } diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/rsa.rs b/wrapper/rust/wolfssl-wolfcrypt/src/rsa.rs index 74b4d674046..56526f34abd 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/rsa.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/rsa.rs @@ -218,6 +218,7 @@ impl RSA { /// } /// ``` pub fn new_from_der_ex(der: &[u8], heap: Option<*mut core::ffi::c_void>, dev_id: Option) -> Result { + let der_size = crate::buffer_len_to_u32(der.len())?; let mut wc_rsakey: MaybeUninit = MaybeUninit::uninit(); let heap = match heap { Some(heap) => heap, @@ -232,7 +233,6 @@ impl RSA { return Err(rc); } let mut wc_rsakey = unsafe { wc_rsakey.assume_init() }; - let der_size = der.len() as u32; let mut idx: u32 = 0; let rc = unsafe { sys::wc_RsaPrivateKeyDecode(der.as_ptr(), &mut idx, &mut wc_rsakey, der_size) @@ -335,6 +335,7 @@ impl RSA { /// } /// ``` pub fn new_public_from_der_ex(der: &[u8], heap: Option<*mut core::ffi::c_void>, dev_id: Option) -> Result { + let der_size = crate::buffer_len_to_u32(der.len())?; let mut wc_rsakey: MaybeUninit = MaybeUninit::uninit(); let heap = match heap { Some(heap) => heap, @@ -349,7 +350,6 @@ impl RSA { return Err(rc); } let mut wc_rsakey = unsafe { wc_rsakey.assume_init() }; - let der_size = der.len() as u32; let mut idx: u32 = 0; let rc = unsafe { sys::wc_RsaPublicKeyDecode(der.as_ptr(), &mut idx, &mut wc_rsakey, der_size) @@ -527,11 +527,11 @@ impl RSA { d: &mut [u8], d_size: &mut u32, p: &mut [u8], p_size: &mut u32, q: &mut [u8], q_size: &mut u32) -> Result<(), i32> { - *e_size = e.len() as u32; - *n_size = n.len() as u32; - *d_size = d.len() as u32; - *p_size = p.len() as u32; - *q_size = q.len() as u32; + *e_size = crate::buffer_len_to_u32(e.len())?; + *n_size = crate::buffer_len_to_u32(n.len())?; + *d_size = crate::buffer_len_to_u32(d.len())?; + *p_size = crate::buffer_len_to_u32(p.len())?; + *q_size = crate::buffer_len_to_u32(q.len())?; #[cfg(rsa_const_api)] let key_ptr = &self.wc_rsakey; #[cfg(not(rsa_const_api))] @@ -584,8 +584,8 @@ impl RSA { pub fn export_public_key(&mut self, e: &mut [u8], e_size: &mut u32, n: &mut [u8], n_size: &mut u32) -> Result<(), i32> { - *e_size = e.len() as u32; - *n_size = n.len() as u32; + *e_size = crate::buffer_len_to_u32(e.len())?; + *n_size = crate::buffer_len_to_u32(n.len())?; #[cfg(rsa_const_api)] let key = &self.wc_rsakey; #[cfg(not(rsa_const_api))] @@ -705,8 +705,8 @@ impl RSA { /// ``` #[cfg(random)] pub fn public_encrypt(&mut self, din: &[u8], dout: &mut [u8], rng: &mut RNG) -> Result { - let din_size = din.len() as u32; - let dout_size = dout.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; + let dout_size = crate::buffer_len_to_u32(dout.len())?; let rc = unsafe { sys::wc_RsaPublicEncrypt(din.as_ptr(), din_size, dout.as_mut_ptr(), dout_size, &mut self.wc_rsakey, @@ -763,8 +763,8 @@ impl RSA { /// } /// ``` pub fn private_decrypt(&mut self, din: &[u8], dout: &mut [u8]) -> Result { - let din_size = din.len() as u32; - let dout_size = dout.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; + let dout_size = crate::buffer_len_to_u32(dout.len())?; let rc = unsafe { sys::wc_RsaPrivateDecrypt(din.as_ptr(), din_size, dout.as_mut_ptr(), dout_size, &mut self.wc_rsakey) @@ -829,8 +829,8 @@ impl RSA { /// ``` #[cfg(all(random, rsa_pss))] pub fn pss_sign(&mut self, din: &[u8], dout: &mut [u8], hash_algo: u32, mgf: i32, rng: &mut RNG) -> Result { - let din_size = din.len() as u32; - let dout_size = dout.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; + let dout_size = crate::buffer_len_to_u32(dout.len())?; let rc = unsafe { sys::wc_RsaPSS_Sign(din.as_ptr(), din_size, dout.as_mut_ptr(), dout_size, hash_algo, mgf, &mut self.wc_rsakey, &mut rng.wc_rng) @@ -892,8 +892,8 @@ impl RSA { /// ``` #[cfg(all(rsa_pss, rsa_const_api))] pub fn pss_check_padding(&mut self, din: &[u8], sig: &[u8], hash_algo: u32) -> Result<(), i32> { - let din_size = din.len() as u32; - let sig_size = sig.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; + let sig_size = crate::buffer_len_to_u32(sig.len())?; let rc = unsafe { sys::wc_RsaPSS_CheckPadding(din.as_ptr(), din_size, sig.as_ptr(), sig_size, hash_algo) @@ -958,8 +958,8 @@ impl RSA { /// ``` #[cfg(all(rsa_pss, rsa_const_api))] pub fn pss_verify(&mut self, din: &[u8], dout: &mut [u8], hash_algo: u32, mgf: i32) -> Result { - let din_size = din.len() as u32; - let dout_size = dout.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; + let dout_size = crate::buffer_len_to_u32(dout.len())?; let rc = unsafe { sys::wc_RsaPSS_Verify(din.as_ptr(), din_size, dout.as_mut_ptr(), dout_size, @@ -1029,9 +1029,9 @@ impl RSA { /// ``` #[cfg(all(rsa_pss, rsa_const_api))] pub fn pss_verify_check(&mut self, din: &[u8], dout: &mut [u8], digest: &[u8], hash_algo: u32, mgf: i32) -> Result { - let din_size = din.len() as u32; - let dout_size = dout.len() as u32; - let digest_size = digest.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; + let dout_size = crate::buffer_len_to_u32(dout.len())?; + let digest_size = crate::buffer_len_to_u32(digest.len())?; let rc = unsafe { sys::wc_RsaPSS_VerifyCheck(din.as_ptr(), din_size, dout.as_mut_ptr(), dout_size, digest.as_ptr(), digest_size, @@ -1092,8 +1092,8 @@ impl RSA { /// ``` #[cfg(all(rsa_direct, rsa_const_api))] pub fn rsa_direct(&mut self, din: &[u8], dout: &mut [u8], typ: i32, rng: &mut RNG) -> Result { - let din_size = din.len() as u32; - let mut dout_size = dout.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; + let mut dout_size = crate::buffer_len_to_u32(dout.len())?; let rc = unsafe { sys::wc_RsaDirect(din.as_ptr(), din_size, dout.as_mut_ptr(), &mut dout_size, @@ -1209,8 +1209,8 @@ impl RSA { /// ``` #[cfg(random)] pub fn ssl_sign(&mut self, din: &[u8], dout: &mut [u8], rng: &mut RNG) -> Result { - let din_size = din.len() as u32; - let dout_size = dout.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; + let dout_size = crate::buffer_len_to_u32(dout.len())?; let rc = unsafe { sys::wc_RsaSSL_Sign(din.as_ptr(), din_size, dout.as_mut_ptr(), dout_size, @@ -1270,8 +1270,8 @@ impl RSA { /// } /// ``` pub fn ssl_verify(&mut self, din: &[u8], dout: &mut [u8]) -> Result { - let din_size = din.len() as u32; - let dout_size = dout.len() as u32; + let din_size = crate::buffer_len_to_u32(din.len())?; + let dout_size = crate::buffer_len_to_u32(dout.len())?; let rc = unsafe { sys::wc_RsaSSL_Verify(din.as_ptr(), din_size, dout.as_mut_ptr(), dout_size, &mut self.wc_rsakey) @@ -1283,6 +1283,12 @@ impl RSA { } } +impl RSA { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_rsakey); } + } +} + impl Drop for RSA { /// Safely free the underlying wolfSSL RSA context. /// @@ -1293,5 +1299,6 @@ impl Drop for RSA { /// preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_FreeRsaKey(&mut self.wc_rsakey); } + self.zeroize(); } } diff --git a/wrapper/rust/wolfssl-wolfcrypt/src/sha.rs b/wrapper/rust/wolfssl-wolfcrypt/src/sha.rs index e8964a72f8a..2de688b39d2 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/src/sha.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/src/sha.rs @@ -170,7 +170,7 @@ impl SHA { /// sha.update(b"input").expect("Error with update()"); /// ``` pub fn update(&mut self, data: &[u8]) -> Result<(), i32> { - let data_size = data.len() as u32; + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { sys::wc_ShaUpdate(&mut self.wc_sha, data.as_ptr(), data_size) }; @@ -215,6 +215,13 @@ impl SHA { } } +#[cfg(sha)] +impl SHA { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_sha); } + } +} + #[cfg(sha)] impl Drop for SHA { /// Safely free the underlying wolfSSL SHA context. @@ -226,6 +233,7 @@ impl Drop for SHA { /// preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_ShaFree(&mut self.wc_sha); } + self.zeroize(); } } @@ -373,7 +381,7 @@ impl SHA224 { /// sha.update(b"input").expect("Error with update()"); /// ``` pub fn update(&mut self, data: &[u8]) -> Result<(), i32> { - let data_size = data.len() as u32; + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { sys::wc_Sha224Update(&mut self.wc_sha224, data.as_ptr(), data_size) }; @@ -418,6 +426,13 @@ impl SHA224 { } } +#[cfg(sha224)] +impl SHA224 { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_sha224); } + } +} + #[cfg(sha224)] impl Drop for SHA224 { /// Safely free the underlying wolfSSL SHA224 context. @@ -429,6 +444,7 @@ impl Drop for SHA224 { /// and preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_Sha224Free(&mut self.wc_sha224); } + self.zeroize(); } } @@ -576,7 +592,7 @@ impl SHA256 { /// sha.update(b"input").expect("Error with update()"); /// ``` pub fn update(&mut self, data: &[u8]) -> Result<(), i32> { - let data_size = data.len() as u32; + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { sys::wc_Sha256Update(&mut self.wc_sha256, data.as_ptr(), data_size) }; @@ -621,6 +637,13 @@ impl SHA256 { } } +#[cfg(sha256)] +impl SHA256 { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_sha256); } + } +} + #[cfg(sha256)] impl Drop for SHA256 { /// Safely free the underlying wolfSSL SHA256 context. @@ -632,6 +655,7 @@ impl Drop for SHA256 { /// and preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_Sha256Free(&mut self.wc_sha256); } + self.zeroize(); } } @@ -779,7 +803,7 @@ impl SHA384 { /// sha.update(b"input").expect("Error with update()"); /// ``` pub fn update(&mut self, data: &[u8]) -> Result<(), i32> { - let data_size = data.len() as u32; + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { sys::wc_Sha384Update(&mut self.wc_sha384, data.as_ptr(), data_size) }; @@ -824,6 +848,13 @@ impl SHA384 { } } +#[cfg(sha384)] +impl SHA384 { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_sha384); } + } +} + #[cfg(sha384)] impl Drop for SHA384 { /// Safely free the underlying wolfSSL SHA384 context. @@ -835,6 +866,7 @@ impl Drop for SHA384 { /// and preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_Sha384Free(&mut self.wc_sha384); } + self.zeroize(); } } @@ -982,7 +1014,7 @@ impl SHA512 { /// sha.update(b"input").expect("Error with update()"); /// ``` pub fn update(&mut self, data: &[u8]) -> Result<(), i32> { - let data_size = data.len() as u32; + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { sys::wc_Sha512Update(&mut self.wc_sha512, data.as_ptr(), data_size) }; @@ -1027,6 +1059,13 @@ impl SHA512 { } } +#[cfg(sha512)] +impl SHA512 { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_sha512); } + } +} + #[cfg(sha512)] impl Drop for SHA512 { /// Safely free the underlying wolfSSL SHA512 context. @@ -1038,6 +1077,7 @@ impl Drop for SHA512 { /// and preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_Sha512Free(&mut self.wc_sha512); } + self.zeroize(); } } @@ -1185,7 +1225,7 @@ impl SHA3_224 { /// sha.update(b"input").expect("Error with update()"); /// ``` pub fn update(&mut self, data: &[u8]) -> Result<(), i32> { - let data_size = data.len() as u32; + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { sys::wc_Sha3_224_Update(&mut self.wc_sha3, data.as_ptr(), data_size) }; @@ -1230,6 +1270,13 @@ impl SHA3_224 { } } +#[cfg(sha3)] +impl SHA3_224 { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_sha3); } + } +} + #[cfg(sha3)] impl Drop for SHA3_224 { /// Safely free the underlying wolfSSL SHA3_224 context. @@ -1241,6 +1288,7 @@ impl Drop for SHA3_224 { /// and preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_Sha3_224_Free(&mut self.wc_sha3); } + self.zeroize(); } } @@ -1388,7 +1436,7 @@ impl SHA3_256 { /// sha.update(b"input").expect("Error with update()"); /// ``` pub fn update(&mut self, data: &[u8]) -> Result<(), i32> { - let data_size = data.len() as u32; + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { sys::wc_Sha3_256_Update(&mut self.wc_sha3, data.as_ptr(), data_size) }; @@ -1433,6 +1481,13 @@ impl SHA3_256 { } } +#[cfg(sha3)] +impl SHA3_256 { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_sha3); } + } +} + #[cfg(sha3)] impl Drop for SHA3_256 { /// Safely free the underlying wolfSSL SHA3_256 context. @@ -1444,6 +1499,7 @@ impl Drop for SHA3_256 { /// and preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_Sha3_256_Free(&mut self.wc_sha3); } + self.zeroize(); } } @@ -1591,7 +1647,7 @@ impl SHA3_384 { /// sha.update(b"input").expect("Error with update()"); /// ``` pub fn update(&mut self, data: &[u8]) -> Result<(), i32> { - let data_size = data.len() as u32; + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { sys::wc_Sha3_384_Update(&mut self.wc_sha3, data.as_ptr(), data_size) }; @@ -1636,6 +1692,13 @@ impl SHA3_384 { } } +#[cfg(sha3)] +impl SHA3_384 { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_sha3); } + } +} + #[cfg(sha3)] impl Drop for SHA3_384 { /// Safely free the underlying wolfSSL SHA3_384 context. @@ -1647,6 +1710,7 @@ impl Drop for SHA3_384 { /// and preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_Sha3_384_Free(&mut self.wc_sha3); } + self.zeroize(); } } @@ -1794,7 +1858,7 @@ impl SHA3_512 { /// sha.update(b"input").expect("Error with update()"); /// ``` pub fn update(&mut self, data: &[u8]) -> Result<(), i32> { - let data_size = data.len() as u32; + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { sys::wc_Sha3_512_Update(&mut self.wc_sha3, data.as_ptr(), data_size) }; @@ -1839,6 +1903,13 @@ impl SHA3_512 { } } +#[cfg(sha3)] +impl SHA3_512 { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_sha3); } + } +} + #[cfg(sha3)] impl Drop for SHA3_512 { /// Safely free the underlying wolfSSL SHA3_512 context. @@ -1850,6 +1921,7 @@ impl Drop for SHA3_512 { /// and preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_Sha3_512_Free(&mut self.wc_sha3); } + self.zeroize(); } } @@ -2001,7 +2073,7 @@ impl SHAKE128 { /// sha.update(b"input").expect("Error with update()"); /// ``` pub fn update(&mut self, data: &[u8]) -> Result<(), i32> { - let data_size = data.len() as u32; + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { sys::wc_Shake128_Update(&mut self.wc_shake, data.as_ptr(), data_size) }; @@ -2032,7 +2104,7 @@ impl SHAKE128 { /// sha.finalize(&mut hash).expect("Error with finalize()"); /// ``` pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> { - let hash_size = hash.len() as u32; + let hash_size = crate::buffer_len_to_u32(hash.len())?; let rc = unsafe { sys::wc_Shake128_Final(&mut self.wc_shake, hash.as_mut_ptr(), hash_size) }; @@ -2061,7 +2133,7 @@ impl SHAKE128 { /// sha.absorb(b"input").expect("Error with absorb()"); /// ``` pub fn absorb(&mut self, data: &[u8]) -> Result<(), i32> { - let data_size = data.len() as u32; + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { sys::wc_Shake128_Absorb(&mut self.wc_shake, data.as_ptr(), data_size) }; @@ -2094,7 +2166,7 @@ impl SHAKE128 { /// sha.squeeze_blocks(&mut buffer).expect("Error with squeeze_blocks()"); /// ``` pub fn squeeze_blocks(&mut self, dout: &mut [u8]) -> Result<(), i32> { - let dout_size = dout.len() as u32; + let dout_size = crate::buffer_len_to_u32(dout.len())?; if dout_size % (Self::SQUEEZE_BLOCK_SIZE as u32) != 0 { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } @@ -2109,6 +2181,13 @@ impl SHAKE128 { } } +#[cfg(shake128)] +impl SHAKE128 { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_shake); } + } +} + #[cfg(shake128)] impl Drop for SHAKE128 { /// Safely free the underlying wolfSSL SHAKE128 context. @@ -2120,6 +2199,7 @@ impl Drop for SHAKE128 { /// and preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_Shake128_Free(&mut self.wc_shake); } + self.zeroize(); } } @@ -2271,7 +2351,7 @@ impl SHAKE256 { /// sha.update(b"input").expect("Error with update()"); /// ``` pub fn update(&mut self, data: &[u8]) -> Result<(), i32> { - let data_size = data.len() as u32; + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { sys::wc_Shake256_Update(&mut self.wc_shake, data.as_ptr(), data_size) }; @@ -2302,7 +2382,7 @@ impl SHAKE256 { /// sha.finalize(&mut hash).expect("Error with finalize()"); /// ``` pub fn finalize(&mut self, hash: &mut [u8]) -> Result<(), i32> { - let hash_size = hash.len() as u32; + let hash_size = crate::buffer_len_to_u32(hash.len())?; let rc = unsafe { sys::wc_Shake256_Final(&mut self.wc_shake, hash.as_mut_ptr(), hash_size) }; @@ -2331,7 +2411,7 @@ impl SHAKE256 { /// sha.absorb(b"input").expect("Error with absorb()"); /// ``` pub fn absorb(&mut self, data: &[u8]) -> Result<(), i32> { - let data_size = data.len() as u32; + let data_size = crate::buffer_len_to_u32(data.len())?; let rc = unsafe { sys::wc_Shake256_Absorb(&mut self.wc_shake, data.as_ptr(), data_size) }; @@ -2364,7 +2444,7 @@ impl SHAKE256 { /// sha.squeeze_blocks(&mut buffer).expect("Error with squeeze_blocks()"); /// ``` pub fn squeeze_blocks(&mut self, dout: &mut [u8]) -> Result<(), i32> { - let dout_size = dout.len() as u32; + let dout_size = crate::buffer_len_to_u32(dout.len())?; if dout_size % (Self::SQUEEZE_BLOCK_SIZE as u32) != 0 { return Err(sys::wolfCrypt_ErrorCodes_BUFFER_E); } @@ -2379,6 +2459,13 @@ impl SHAKE256 { } } +#[cfg(shake256)] +impl SHAKE256 { + fn zeroize(&mut self) { + unsafe { crate::zeroize_raw(&mut self.wc_shake); } + } +} + #[cfg(shake256)] impl Drop for SHAKE256 { /// Safely free the underlying wolfSSL SHAKE256 context. @@ -2390,5 +2477,6 @@ impl Drop for SHAKE256 { /// and preventing memory leaks. fn drop(&mut self) { unsafe { sys::wc_Shake256_Free(&mut self.wc_shake); } + self.zeroize(); } } diff --git a/wrapper/rust/wolfssl-wolfcrypt/tests/test_blake2.rs b/wrapper/rust/wolfssl-wolfcrypt/tests/test_blake2.rs index 4b8bff27feb..4f7126d14d5 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/tests/test_blake2.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/tests/test_blake2.rs @@ -1,5 +1,7 @@ #[cfg(any(blake2b, blake2s))] use wolfssl_wolfcrypt::blake2::*; +#[cfg(any(blake2b, blake2s))] +use wolfssl_wolfcrypt::sys; #[test] #[cfg(blake2b)] @@ -50,6 +52,15 @@ fn test_blake2b() { } } +#[test] +#[cfg(blake2b)] +fn test_blake2b_finalize_empty_buffer() { + let mut blake2b = BLAKE2b::new(64).expect("Error with new()"); + let mut hash: [u8; 0] = []; + let rc = blake2b.finalize(&mut hash).expect_err("finalize() should fail"); + assert_eq!(rc, sys::wolfCrypt_ErrorCodes_BUFFER_E); +} + #[test] #[cfg(blake2b_hmac)] fn test_blake2b_hmac() { @@ -151,6 +162,15 @@ fn test_blake2s() { } } +#[test] +#[cfg(blake2s)] +fn test_blake2s_finalize_empty_buffer() { + let mut blake2s = BLAKE2s::new(32).expect("Error with new()"); + let mut hash: [u8; 0] = []; + let rc = blake2s.finalize(&mut hash).expect_err("finalize() should fail"); + assert_eq!(rc, sys::wolfCrypt_ErrorCodes_BUFFER_E); +} + #[test] #[cfg(blake2s_hmac)] fn test_blake2s_hmac() { diff --git a/wrapper/rust/wolfssl-wolfcrypt/tests/test_lms.rs b/wrapper/rust/wolfssl-wolfcrypt/tests/test_lms.rs index 16a51c3c9e7..842c435669f 100644 --- a/wrapper/rust/wolfssl-wolfcrypt/tests/test_lms.rs +++ b/wrapper/rust/wolfssl-wolfcrypt/tests/test_lms.rs @@ -386,8 +386,10 @@ fn test_get_kid() { setup_callbacks(&mut key, ctx); key.make_key(&mut rng).expect("Error with make_key()"); - let kid = key.get_kid().expect("Error with get_kid()"); - assert_eq!(kid.len(), Lms::KEY_ID_LEN, "kid must be KEY_ID_LEN bytes"); + let mut kid = [0u8; Lms::KEY_ID_LEN]; + let kid_len = key.get_kid(&mut kid).expect("Error with get_kid()"); + assert_eq!(kid_len, Lms::KEY_ID_LEN, "get_kid() must write KEY_ID_LEN bytes"); + assert!(kid.iter().any(|&b| b != 0), "get_kid() must populate the output buffer"); let _ = store; }