Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
427f921
added proper checks against 24 bytes cipher text (aes128/256gcm)
gasbytes Jun 16, 2026
6075ea9
added missing checks in quic.rs against the tag_len, to make sure the…
gasbytes Jun 16, 2026
8a20ba3
run the quic tests in the ci/cd
gasbytes Jun 16, 2026
088672d
added missing checks to validate sample length (quic) before encrypting
gasbytes Jun 16, 2026
54c0bf3
reuse a single raw pointer for the in/out buffer in all aead encrypt…
gasbytes Jun 16, 2026
6172aec
fix heap leak of boxed aes/chacha in quic ciphers by freeing the box …
gasbytes Jun 16, 2026
b4ae459
remove derive(copy) from the chachaobject since no code copies it as …
gasbytes Jun 16, 2026
f62dbb9
fix data race in quic aes/chacha ciphers by allocating a fresh wolfcr…
gasbytes Jun 16, 2026
e759e19
check returned value of wc_SignatureGetSize
gasbytes Jun 16, 2026
e4878fe
removed sha*hmac modules, since they were merged into src/hmac/mod.rs…
gasbytes Jun 16, 2026
a05ad21
free allocated Hmac object in case of failure from wc_HmacSetKey
gasbytes Jun 16, 2026
4390d38
make hmacobject own its cleanup via the define_foreign_type_no_copy! …
gasbytes Jun 16, 2026
91a0ead
removed manual free that was skipped on panic, using again the automa…
gasbytes Jun 16, 2026
26489a3
make error clearer when expanding a slice in expand_block in hkdf.rs
gasbytes Jun 16, 2026
ddec026
remove duplicate entry of RSA_PKCS1_SHA512 from the ALGORITHMS slice
gasbytes Jun 16, 2026
956fe83
zeroize key material in stored in the stack kx modules and not only i…
gasbytes Jun 17, 2026
c23a34d
zeroize der(s) after try_from logic in rsa.rs in case of failure duri…
gasbytes Jun 17, 2026
2c979db
zeroize ecdsa exported scalar in case of exit on error in the case of…
gasbytes Jun 17, 2026
5380da7
propage init() failures to callers instead of panicking, so a failed …
gasbytes Jun 17, 2026
6ad05ae
move test related crates from dependencies to dev-dependencies instead
gasbytes Jun 17, 2026
e3484f4
remove unnecessary bitwise copy of RsaKey(s) and its deferencing, use…
gasbytes Jun 17, 2026
e5bd0e0
check the digest size after getting its size from the hash type
gasbytes Jun 17, 2026
7e494c4
remove unnecessary wc_ecc_curve_id call
gasbytes Jun 17, 2026
29a7fba
cargo fmt formatting
gasbytes Jun 17, 2026
eca9700
Added Ed25519KeyPair to prevent type_complexity warning (cargo clippy…
gasbytes Jun 17, 2026
02837e0
address review: format and print actual_sig_size instead of ret when …
gasbytes Jun 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/macos-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ jobs:
cd rustls-wolfcrypt-provider
make build
make test
make test-quic

- name: Check formatting
run: |
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ubuntu-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ jobs:
cd rustls-wolfcrypt-provider
make build
make test
make test-quic

- name: Check formatting
run: |
Expand Down
12 changes: 5 additions & 7 deletions rustls-wolfcrypt-provider/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ webpki = { package = "rustls-webpki", version = "0.103.13", features = ["alloc"]
foreign-types = { version = "0.5.0", default-features = false }
rustls-pki-types = { version = "1.11.0", default-features = false }
log = { version = "0.4.25", default-features = false }
env_logger = { version = "0.11.6", default-features = false }
wolfcrypt-rs = { path = "../wolfcrypt-rs" }
rustls-pemfile = { version = "2.2.0", default-features = false }
hex = { version = "0.4.3", default-features = false, features = ["alloc"]}
zeroize = { version = "1", default-features = false, features = ["alloc", "derive"] }

[dev-dependencies]
wycheproof = { version = "0.6.0", default-features = false, features = [
"aead",
"hkdf",
Expand All @@ -30,11 +30,9 @@ rayon = "1.10.0"
anyhow = "1.0.95"
num_cpus = "1.16.0"
lazy_static = "1.5.0"
hex = { version = "0.4.3", default-features = false, features = ["alloc"]}
hex-literal = "0.4.1"
zeroize = { version = "1", default-features = false, features = ["alloc", "derive"] }


[dev-dependencies]
env_logger = { version = "0.11.6", default-features = false }
rcgen = { version = "0.13" }
serial_test = { version = "3.2.0", default-features = false }
tokio = { version = "1.43", features = ["macros", "rt", "net", "io-util", "io-std"], default-features = false }
Expand Down
6 changes: 5 additions & 1 deletion rustls-wolfcrypt-provider/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
.PHONY: test
test:
test:
@cargo test

.PHONY: test-quic
test-quic:
@cargo test --features quic

.PHONY: build
build:
@cargo build --release
Expand Down
41 changes: 25 additions & 16 deletions rustls-wolfcrypt-provider/src/aead/aes128gcm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,15 @@ impl MessageEncrypter for WCTls12Encrypter {
// 8 bytes.
let payload_start = GCM_NONCE_LENGTH - 4;
let payload_end = m.payload.len() + (GCM_NONCE_LENGTH - 4);
let buf = &mut payload.as_mut()[payload_start..payload_end];
let buf_len = buf.len() as word32;
let buf_ptr = buf.as_mut_ptr();
ret = unsafe {
wc_AesGcmEncrypt(
aes_object.as_ptr(),
payload.as_mut()[payload_start..payload_end].as_mut_ptr(),
payload.as_ref()[payload_start..payload_end].as_ptr(),
payload.as_ref()[payload_start..payload_end].len() as word32,
buf_ptr,
buf_ptr as *const u8,
buf_len,
nonce.as_ptr(),
nonce.len() as word32,
auth_tag.as_mut_ptr(),
Expand Down Expand Up @@ -173,7 +176,7 @@ impl MessageDecrypter for WCTls12Decrypter {
seq: u64,
) -> Result<InboundPlainMessage<'a>, rustls::Error> {
let payload = &mut m.payload;
if payload.len() < GCM_TAG_LENGTH {
if payload.len() < (GCM_NONCE_LENGTH - 4) + GCM_TAG_LENGTH {
return Err(rustls::Error::DecryptError);
}
let payload_len = payload.len();
Expand Down Expand Up @@ -212,15 +215,15 @@ impl MessageDecrypter for WCTls12Decrypter {
// from the payload.
let payload_start = GCM_NONCE_LENGTH - 4;
let payload_end = payload_len - GCM_TAG_LENGTH;
let buf = &mut payload[payload_start..payload_end];
let buf_len = buf.len() as word32;
let buf_ptr = buf.as_mut_ptr();
ret = unsafe {
wc_AesGcmDecrypt(
aes_object.as_ptr(),
payload[payload_start..payload_end].as_mut_ptr(),
payload[payload_start..payload_end].as_ptr(),
payload[payload_start..payload_end]
.len()
.try_into()
.unwrap(),
buf_ptr,
buf_ptr as *const u8,
buf_len,
nonce.as_ptr(),
nonce.len() as word32,
auth_tag.as_ptr(),
Expand Down Expand Up @@ -318,12 +321,15 @@ impl MessageEncrypter for WCTls13Cipher {
// authIn, into the authentication tag, authTag.
// Apparently we need to also need to include for the encoding type into the encrypted
// payload, hence the + 1 otherwise the rustls returns EoF.
let buf = &mut payload.as_mut()[..payload_len + 1];
let buf_len = buf.len() as word32;
let buf_ptr = buf.as_mut_ptr();
ret = unsafe {
wc_AesGcmEncrypt(
aes_object.as_ptr(),
payload.as_mut()[..payload_len + 1].as_mut_ptr(),
payload.as_ref()[..payload_len + 1].as_ptr(),
payload.as_ref()[..payload_len + 1].len() as word32,
buf_ptr,
buf_ptr as *const u8,
buf_len,
nonce.0.as_ptr(),
nonce.0.len() as word32,
auth_tag.as_mut_ptr(),
Expand Down Expand Up @@ -384,12 +390,15 @@ impl MessageDecrypter for WCTls13Cipher {

// Finally, we have everything to decrypt the message
// from the payload.
let buf = &mut payload[..message_len];
let buf_len = buf.len() as word32;
let buf_ptr = buf.as_mut_ptr();
ret = unsafe {
wc_AesGcmDecrypt(
aes_object.as_ptr(),
payload[..message_len].as_mut_ptr(),
payload[..message_len].as_ptr(),
payload[..message_len].len().try_into().unwrap(),
buf_ptr,
buf_ptr as *const u8,
buf_len,
nonce.0.as_ptr(),
nonce.0.len() as word32,
auth_tag.as_ptr(),
Expand Down
41 changes: 25 additions & 16 deletions rustls-wolfcrypt-provider/src/aead/aes256gcm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,15 @@ impl MessageEncrypter for WCTls12Encrypter {
// 8 bytes.
let payload_start = GCM_NONCE_LENGTH - 4;
let payload_end = m.payload.len() + (GCM_NONCE_LENGTH - 4);
let buf = &mut payload.as_mut()[payload_start..payload_end];
let buf_len = buf.len() as word32;
let buf_ptr = buf.as_mut_ptr();
ret = unsafe {
wc_AesGcmEncrypt(
aes_object.as_ptr(),
payload.as_mut()[payload_start..payload_end].as_mut_ptr(),
payload.as_ref()[payload_start..payload_end].as_ptr(),
payload.as_ref()[payload_start..payload_end].len() as word32,
buf_ptr,
buf_ptr as *const u8,
buf_len,
nonce.as_ptr(),
nonce.len() as word32,
auth_tag.as_mut_ptr(),
Expand Down Expand Up @@ -173,7 +176,7 @@ impl MessageDecrypter for WCTls12Decrypter {
seq: u64,
) -> Result<InboundPlainMessage<'a>, rustls::Error> {
let payload = &mut m.payload;
if payload.len() < GCM_TAG_LENGTH {
if payload.len() < (GCM_NONCE_LENGTH - 4) + GCM_TAG_LENGTH {
return Err(rustls::Error::DecryptError);
}
let payload_len = payload.len();
Expand Down Expand Up @@ -212,15 +215,15 @@ impl MessageDecrypter for WCTls12Decrypter {
// from the payload.
let payload_start = GCM_NONCE_LENGTH - 4;
let payload_end = payload_len - GCM_TAG_LENGTH;
let buf = &mut payload[payload_start..payload_end];
let buf_len = buf.len() as word32;
let buf_ptr = buf.as_mut_ptr();
ret = unsafe {
wc_AesGcmDecrypt(
aes_object.as_ptr(),
payload[payload_start..payload_end].as_mut_ptr(),
payload[payload_start..payload_end].as_ptr(),
payload[payload_start..payload_end]
.len()
.try_into()
.unwrap(),
buf_ptr,
buf_ptr as *const u8,
buf_len,
nonce.as_ptr(),
nonce.len() as word32,
auth_tag.as_ptr(),
Expand Down Expand Up @@ -318,12 +321,15 @@ impl MessageEncrypter for WCTls13Cipher {
// authIn, into the authentication tag, authTag.
// Apparently we need to also need to include for the encoding type into the encrypted
// payload, hence the + 1 otherwise the rustls returns EoF.
let buf = &mut payload.as_mut()[..payload_len + 1];
let buf_len = buf.len() as word32;
let buf_ptr = buf.as_mut_ptr();
ret = unsafe {
wc_AesGcmEncrypt(
aes_object.as_ptr(),
payload.as_mut()[..payload_len + 1].as_mut_ptr(),
payload.as_ref()[..payload_len + 1].as_ptr(),
payload.as_ref()[..payload_len + 1].len() as word32,
buf_ptr,
buf_ptr as *const u8,
buf_len,
nonce.0.as_ptr(),
nonce.0.len() as word32,
auth_tag.as_mut_ptr(),
Expand Down Expand Up @@ -385,12 +391,15 @@ impl MessageDecrypter for WCTls13Cipher {

// Finally, we have everything to decrypt the message
// from the payload.
let buf = &mut payload[..message_len];
let buf_len = buf.len() as word32;
let buf_ptr = buf.as_mut_ptr();
ret = unsafe {
wc_AesGcmDecrypt(
aes_object.as_ptr(),
payload[..message_len].as_mut_ptr(),
payload[..message_len].as_ptr(),
payload[..message_len].len().try_into().unwrap(),
buf_ptr,
buf_ptr as *const u8,
buf_len,
nonce.0.as_ptr(),
nonce.0.len() as word32,
auth_tag.as_ptr(),
Expand Down
15 changes: 9 additions & 6 deletions rustls-wolfcrypt-provider/src/aead/chacha20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,16 +153,17 @@ impl MessageDecrypter for WCTls12Cipher {
// to an authentication generated with the inAAD (arbitrary length additional authentication data).
// Note: If the generated authentication tag does not match the supplied
// authentication tag, the text is not decrypted.
let buf_ptr = payload[..message_len].as_mut_ptr();
let ret = unsafe {
wc_ChaCha20Poly1305_Decrypt(
self.key.as_ptr(),
nonce.0.as_ptr(),
aad.as_ptr(),
aad.len() as word32,
payload[..message_len].as_ptr(), // we decrypt only the payload, we don't include the tag.
buf_ptr as *const u8, // we decrypt only the payload, we don't include the tag.
message_len as word32,
auth_tag.as_ptr(),
payload[..message_len].as_mut_ptr(),
buf_ptr,
)
};

Expand Down Expand Up @@ -245,15 +246,16 @@ impl MessageEncrypter for WCTls13Cipher {
// and stores the generated authentication tag in the output buffer, outAuthTag.
// We need to also need to include for the encoding type, apparently, hence the + 1
// otherwise the rustls returns EoF.
let buf_ptr = payload.as_mut()[..m.payload.len() + 1].as_mut_ptr();
let ret = unsafe {
wc_ChaCha20Poly1305_Encrypt(
self.key.as_ptr(),
nonce.0.as_ptr(),
aad.as_ptr(),
aad.len() as word32,
payload.as_ref()[..m.payload.len() + 1].as_ptr(),
buf_ptr as *const u8,
(m.payload.len() + 1) as word32,
payload.as_mut()[..m.payload.len() + 1].as_mut_ptr(),
buf_ptr,
auth_tag.as_mut_ptr(),
)
};
Expand Down Expand Up @@ -298,6 +300,7 @@ impl MessageDecrypter for WCTls13Cipher {
// to an authentication generated with the inAAD (arbitrary length additional authentication data).
// Note: If the generated authentication tag does not match the supplied
// authentication tag, the text is not decrypted.
let buf_ptr = payload[..message_len].as_mut_ptr();
let ret = unsafe {
wc_ChaCha20Poly1305_Decrypt(
self.key.as_ptr(),
Expand All @@ -306,10 +309,10 @@ impl MessageDecrypter for WCTls13Cipher {
aad.len() as word32,
// [..message_len] since we want to exclude the
// the auth_tag.
payload[..message_len].as_ptr(),
buf_ptr as *const u8,
message_len as word32,
auth_tag.as_ptr(),
payload[..message_len].as_mut_ptr(),
buf_ptr,
)
};

Expand Down
Loading
Loading