From 50e4bdfd9cdb2f123d48a6fbacf9e2d2ffb657fe Mon Sep 17 00:00:00 2001 From: Love Westlund Date: Mon, 27 May 2024 21:46:23 +0200 Subject: [PATCH 1/2] Add test for AES256 CCM with 12 byte nonce --- openssl/src/symm.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/openssl/src/symm.rs b/openssl/src/symm.rs index 0ff9d874e2..af010569ef 100644 --- a/openssl/src/symm.rs +++ b/openssl/src/symm.rs @@ -1535,6 +1535,35 @@ mod tests { assert_eq!(pt, hex::encode(out)); } + #[test] + #[cfg(not(boringssl))] + fn test_aes256_ccm_12_byte_nonce() { + // This tests that using an IV with the recommended length of 12 bytes + // works as expected. + let cipher = Cipher::aes_256_ccm(); + assert_eq!(cipher.iv_len(), Some(12)); + + let key = Vec::from_hex("7f4af6765cad1d511db07e33aaafd57646ec279db629048aa6770af24849aa0d") + .unwrap(); + let nonce = Vec::from_hex("dde2a362ce81b2b6913abc30").unwrap(); + assert_eq!(nonce.len(), 12); + let aad = Vec::from_hex("404f5df97ece7431987bc098cce994fc3c063b519ffa47b0365226a0015ef695") + .unwrap(); + + let pt = Vec::from_hex("7ebef26bf4ecf6f0ebb2eb860edbf900f27b75b4a6340fdb").unwrap(); + let ct = Vec::from_hex("9dc19f567998982177db86a985eeff5002df9c7812687fc2").unwrap(); + let tag = Vec::from_hex("54f3a6a0ab9c4161e57cc1c4").unwrap(); + + let mut actual_tag = [0; 12]; + let out = encrypt_aead(cipher, &key, Some(&nonce), &aad, &pt, &mut actual_tag).unwrap(); + + assert_eq!(ct, out); + assert_eq!(tag, actual_tag); + + let out = decrypt_aead(cipher, &key, Some(&nonce), &aad, &ct, &tag).unwrap(); + assert_eq!(pt, out); + } + #[test] #[cfg(not(boringssl))] fn test_aes256_ccm_verify_fail() { From 542b783a5cf109e3b82d26b22707bd75124895ed Mon Sep 17 00:00:00 2001 From: Love Westlund Date: Mon, 27 May 2024 21:48:56 +0200 Subject: [PATCH 2/2] Always set IV length for AES CCM ciphers This fixes an issue where the IV length would not be set if the length was equal to the recommended length. The issue shows up at least when an IV of length 12 (which is returned by `t.iv_len()`) is used with the AES256 CCM cipher, as OpenSSL defaults the IV length to 7 bytes [^1] and it would not be correctly set to 12. [^1]: https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption Closes sfackler/rust-openssl#2244. --- openssl/src/symm.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/openssl/src/symm.rs b/openssl/src/symm.rs index af010569ef..8ad525f2c4 100644 --- a/openssl/src/symm.rs +++ b/openssl/src/symm.rs @@ -627,7 +627,12 @@ impl Crypter { ctx.set_key_length(key.len())?; if let (Some(iv), Some(iv_len)) = (iv, t.iv_len()) { - if iv.len() != iv_len { + if iv.len() != iv_len + || matches!( + t.nid(), + Nid::AES_128_CCM | Nid::AES_192_CCM | Nid::AES_256_CCM + ) + { ctx.set_iv_length(iv.len())?; } }