use libaes::{Cipher, AES_128_KEY_LEN, AES_192_KEY_LEN, AES_256_KEY_LEN}; const NIST_AES_128_KEY: &[u8; AES_128_KEY_LEN] = b"\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c"; const NIST_AES_192_KEY: &[u8; AES_192_KEY_LEN] = b"\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5\ \x62\xf8\xea\xd2\x52\x2c\x6b\x7b"; const NIST_AES_256_KEY: &[u8; AES_256_KEY_LEN] = b"\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81\ \x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4"; const NIST_IV: &[u8; 16] = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"; #[test] fn nist_verify_aes_128_cbc() { // Verify the implementation's correctness using NIST Special Publication 800-38A: // http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf // Appendix F.2.1 and F.2.2 CBC Example Vectors let plaintext = b"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\ \xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\ \x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\ \xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10"; let ciphertext = b"\x76\x49\xab\xac\x81\x19\xb2\x46\xce\xe9\x8e\x9b\x12\xe9\x19\x7d\ \x50\x86\xcb\x9b\x50\x72\x19\xee\x95\xdb\x11\x3a\x91\x76\x78\xb2\ \x73\xbe\xd6\xb8\xe3\xc1\x74\x3b\x71\x16\xe6\x9e\x22\x22\x95\x16\ \x3f\xf1\xca\xa1\x68\x1f\xac\x09\x12\x0e\xca\x30\x75\x86\xe1\xa7"; let cipher = Cipher::new_128(NIST_AES_128_KEY); let encrypted = cipher.cbc_encrypt(NIST_IV, plaintext); let len_without_padding = 16 * 4; let padding_size = 16; assert_eq!(encrypted.len(), len_without_padding + padding_size); assert_eq!(encrypted[..len_without_padding], ciphertext[..]); let decrypted = cipher.cbc_decrypt(NIST_IV, &encrypted[..]); assert_eq!(decrypted[..], plaintext[..]); } #[test] fn nist_verify_aes_192_cbc() { // Verify the implementation's correctness using NIST Special Publication 800-38A: // http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf // Appendix F.2.3 and F.2.4 CBC Example Vectors for 192-bit let plaintext = b"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\ \xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\ \x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\ \xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10"; let ciphertext = b"\x4f\x02\x1d\xb2\x43\xbc\x63\x3d\x71\x78\x18\x3a\x9f\xa0\x71\xe8\ \xb4\xd9\xad\xa9\xad\x7d\xed\xf4\xe5\xe7\x38\x76\x3f\x69\x14\x5a\ \x57\x1b\x24\x20\x12\xfb\x7a\xe0\x7f\xa9\xba\xac\x3d\xf1\x02\xe0\ \x08\xb0\xe2\x79\x88\x59\x88\x81\xd9\x20\xa9\xe6\x4f\x56\x15\xcd"; let cipher = Cipher::new_192(NIST_AES_192_KEY); let encrypted = cipher.cbc_encrypt(NIST_IV, plaintext); let len_without_padding = 16 * 4; let padding_size = 16; assert_eq!(encrypted.len(), len_without_padding + padding_size); assert_eq!(encrypted[..len_without_padding], ciphertext[..]); let decrypted = cipher.cbc_decrypt(NIST_IV, &encrypted[..]); assert_eq!(decrypted[..], plaintext[..]); } #[test] fn nist_verify_aes_256_cbc() { // Verify the implementation's correctness using NIST Special Publication 800-38A: // http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf // Appendix F.2.5 and F.2.6 CBC Example Vectors let plaintext = b"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\ \xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\ \x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\ \xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10"; let ciphertext = b"\xf5\x8c\x4c\x04\xd6\xe5\xf1\xba\x77\x9e\xab\xfb\x5f\x7b\xfb\xd6\ \x9c\xfc\x4e\x96\x7e\xdb\x80\x8d\x67\x9f\x77\x7b\xc6\x70\x2c\x7d\ \x39\xf2\x33\x69\xa9\xd9\xba\xcf\xa5\x30\xe2\x63\x04\x23\x14\x61\ \xb2\xeb\x05\xe2\xc3\x9b\xe9\xfc\xda\x6c\x19\x07\x8c\x6a\x9d\x1b"; let cipher = Cipher::new_256(NIST_AES_256_KEY); let encrypted = cipher.cbc_encrypt(NIST_IV, plaintext); let len_without_padding = 16 * 4; let padding_size = 16; assert_eq!(encrypted.len(), len_without_padding + padding_size); assert_eq!(encrypted[..len_without_padding], ciphertext[..]); let decrypted = cipher.cbc_decrypt(NIST_IV, &encrypted[..]); assert_eq!(decrypted[..], plaintext[..]); } #[test] fn nist_verify_aes_128_cfb_128() { // Verify the implementation's correctness using NIST Special Publication 800-38A: // http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf // Appendix F.3.13 and F.3.14 CFB_128 AES-128 Examples let plaintext = b"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\ \xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\ \x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\ \xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10"; let ciphertext = b"\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20\x33\x34\x49\xf8\xe8\x3c\xfb\x4a\ \xc8\xa6\x45\x37\xa0\xb3\xa9\x3f\xcd\xe3\xcd\xad\x9f\x1c\xe5\x8b\ \x26\x75\x1f\x67\xa3\xcb\xb1\x40\xb1\x80\x8c\xf1\x87\xa4\xf4\xdf\ \xc0\x4b\x05\x35\x7c\x5d\x1c\x0e\xea\xc4\xc6\x6f\x9f\xf7\xf2\xe6"; let cipher = Cipher::new_128(NIST_AES_128_KEY); let encrypted = cipher.cfb128_encrypt(NIST_IV, plaintext); assert_eq!(encrypted[..], ciphertext[..]); let decrypted = cipher.cfb128_decrypt(NIST_IV, ciphertext); assert_eq!(decrypted[..], plaintext[..]); } #[test] fn nist_verify_aes_192_cfb_128() { // Verify the implementation's correctness using NIST Special Publication 800-38A: // http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf // Appendix F.3.15 and F.3.16 CFB_128 AES-192 Examples let plaintext = b"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\ \xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\ \x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\ \xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10"; let ciphertext = b"\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab\x34\xc2\x59\x09\xc9\x9a\x41\x74\ \x67\xce\x7f\x7f\x81\x17\x36\x21\x96\x1a\x2b\x70\x17\x1d\x3d\x7a\ \x2e\x1e\x8a\x1d\xd5\x9b\x88\xb1\xc8\xe6\x0f\xed\x1e\xfa\xc4\xc9\ \xc0\x5f\x9f\x9c\xa9\x83\x4f\xa0\x42\xae\x8f\xba\x58\x4b\x09\xff"; let cipher = Cipher::new_192(NIST_AES_192_KEY); let encrypted = cipher.cfb128_encrypt(NIST_IV, plaintext); assert_eq!(encrypted[..], ciphertext[..]); let decrypted = cipher.cfb128_decrypt(NIST_IV, ciphertext); assert_eq!(decrypted[..], plaintext[..]); } #[test] fn nist_verify_aes_256_cfb_128() { // Verify the implementation's correctness using NIST Special Publication 800-38A: // http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf // Appendix F.3.17 and F.3.18 CFB_128 AES-256 Examples let plaintext = b"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a\ \xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51\ \x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef\ \xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10"; let ciphertext = b"\xdc\x7e\x84\xbf\xda\x79\x16\x4b\x7e\xcd\x84\x86\x98\x5d\x38\x60\ \x39\xff\xed\x14\x3b\x28\xb1\xc8\x32\x11\x3c\x63\x31\xe5\x40\x7b\ \xdf\x10\x13\x24\x15\xe5\x4b\x92\xa1\x3e\xd0\xa8\x26\x7a\xe2\xf9\ \x75\xa3\x85\x74\x1a\xb9\xce\xf8\x20\x31\x62\x3d\x55\xb1\xe4\x71"; let cipher = Cipher::new_256(NIST_AES_256_KEY); let encrypted = cipher.cfb128_encrypt(NIST_IV, plaintext); assert_eq!(encrypted[..], ciphertext[..]); let decrypted = cipher.cfb128_decrypt(NIST_IV, ciphertext); assert_eq!(decrypted[..], plaintext[..]); } #[test] fn empty_data() { // Encrypt an input that is empty, i.e. zero bytes. let key_128 = b"This is the key!"; // key is 16 bytes let cipher = Cipher::new_128(key_128); let plaintext = b""; // less than 16 bytes let iv = b"This is 16 bytes"; let encrypted_128 = cipher.cbc_encrypt(iv, plaintext); assert_eq!(encrypted_128.len(), 16); // Verify padding let decrypted_128 = cipher.cbc_decrypt(iv, &encrypted_128[..]); assert_eq!(decrypted_128, plaintext); } #[test] fn small_data() { // Encrypt and decrypt data that is smaller than 1 AES block size. let key_128 = b"This is the key!"; // key is 16 bytes let cipher = Cipher::new_128(key_128); let plaintext = b"A plaintext"; // less than 16 bytes let iv = b"This is 16 bytes"; let encrypted_128 = cipher.cbc_encrypt(iv, plaintext); assert_eq!(encrypted_128.len(), 16); // Verify padding let decrypted_128 = cipher.cbc_decrypt(iv, &encrypted_128[..]); assert_eq!(decrypted_128[..], plaintext[..]); // Test with AES-256 CBC let key_256 = b"This is the key!This is the key!"; let cipher = Cipher::new_256(key_256); let encrypted_256 = cipher.cbc_encrypt(iv, plaintext); assert_eq!(encrypted_256.len(), 16); // Verify padding assert_ne!(encrypted_256[..], encrypted_128[..]); // Verify AES-256 is different from AES-128 let decrypted_256 = cipher.cbc_decrypt(iv, &encrypted_256[..]); assert_eq!(decrypted_256[..], plaintext[..]); // Test with AES-192 CBC let key_192 = b"This is the key! 192 bit"; let cipher = Cipher::new_192(key_192); let encrypted_192 = cipher.cbc_encrypt(iv, plaintext); assert_eq!(encrypted_192.len(), 16); // Verify padding assert_ne!(encrypted_192[..], encrypted_256[..]); // Verify AES-192 is different from AES-256 let decrypted_192 = cipher.cbc_decrypt(iv, &encrypted_192[..]); assert_eq!(decrypted_192[..], plaintext[..]); // Test with AES-128 CFB128 let cipher = Cipher::new_128(key_128); let encrypted_cfb128 = cipher.cfb128_encrypt(iv, plaintext); assert_eq!(encrypted_cfb128.len(), plaintext.len()); assert_ne!(encrypted_128[..], encrypted_cfb128[..]); let decrypted_cfb128 = cipher.cfb128_decrypt(iv, &encrypted_cfb128[..]); assert_eq!(decrypted_cfb128[..], plaintext[..]); // Test with AES-192 CFB128 let cipher = Cipher::new_192(key_192); let encrypted_192 = cipher.cfb128_encrypt(iv, plaintext); assert_eq!(encrypted_192.len(), plaintext.len()); assert_ne!(encrypted_192[..], encrypted_cfb128[..]); let decrypted_192 = cipher.cfb128_decrypt(iv, &encrypted_192[..]); assert_eq!(decrypted_192[..], plaintext[..]); // Test with AES-256 CFB128 let cipher = Cipher::new_256(key_256); let encrypted_256 = cipher.cfb128_encrypt(iv, plaintext); assert_eq!(encrypted_256.len(), plaintext.len()); assert_ne!(encrypted_256[..], encrypted_192[..]); let decrypted_256 = cipher.cfb128_decrypt(iv, &encrypted_256[..]); assert_eq!(decrypted_256[..], plaintext[..]); } #[test] fn large_data() { // Encrypt and decrypt data that is larger than 10 blocks. let key_128 = b"This is the key!"; let iv = b"This is 16 bytes"; let plaintext = b"The Road Not Taken - by Robert Frost\ Two roads diverged in a yellow wood,\ And sorry I could not travel both\ And be one traveler, long I stood\ And looked down one as far as I could\ To where it bent in the undergrowth;\ Then took the other, as just as fair,\ And having perhaps the better claim,\ Because it was grassy and wanted wear;\ Though as for that the passing there\ Had worn them really about the same,\ And both that morning equally lay\ In leaves no step had trodden black.\ Oh, I kept the first for another day!\ Yet knowing how way leads on to way,\ I doubted if I should ever come back.\ I shall be telling this with a sigh\ Somewhere ages and ages hence:\ Two roads diverged in a wood, and I\ I took the one less traveled by,\ And that has made all the difference."; let cipher = Cipher::new_128(key_128); let encrypted_128 = cipher.cbc_encrypt(iv, plaintext); let decrypted_128 = cipher.cbc_decrypt(iv, &encrypted_128[..]); assert_eq!(decrypted_128[..], plaintext[..]); // Test with AES-256 let key_256 = b"This is the key!This is the key!"; let cipher = Cipher::new_256(key_256); let encrypted_256 = cipher.cbc_encrypt(iv, plaintext); assert_eq!(encrypted_256.len(), encrypted_128.len()); assert_ne!(encrypted_256[..], encrypted_128[..]); let decrypted_256 = cipher.cbc_decrypt(iv, &encrypted_256[..]); assert_eq!(decrypted_256[..], plaintext[..]); // Test with AES-192 let key_192 = b"This is the key! 192 bit"; let cipher = Cipher::new_192(key_192); let encrypted_192 = cipher.cbc_encrypt(iv, plaintext); assert_eq!(encrypted_192.len(), encrypted_256.len()); assert_ne!(encrypted_192[..], encrypted_256[..]); let decrypted_192 = cipher.cbc_decrypt(iv, &encrypted_192[..]); assert_eq!(decrypted_192[..], plaintext[..]); // Test with AES-128 CFB128 let cipher = Cipher::new_128(key_128); let encrypted_cfb128 = cipher.cfb128_encrypt(iv, plaintext); assert_eq!(encrypted_cfb128.len(), plaintext.len()); let decrypted_cfb128 = cipher.cfb128_decrypt(iv, &encrypted_cfb128); assert_eq!(decrypted_cfb128[..], plaintext[..]); // Test with AES-192 CFB128 let cipher = Cipher::new_192(key_192); let encrypted_192 = cipher.cfb128_encrypt(iv, plaintext); assert_eq!(encrypted_192.len(), plaintext.len()); assert_ne!(encrypted_192[..], encrypted_cfb128[..]); let decrypted_192 = cipher.cfb128_decrypt(iv, &encrypted_192); assert_eq!(decrypted_192[..], plaintext[..]); // Test with AES-256 CFB128 let cipher = Cipher::new_256(key_256); let encrypted_256 = cipher.cfb128_encrypt(iv, plaintext); assert_eq!(encrypted_256.len(), plaintext.len()); assert_ne!(encrypted_256[..], encrypted_192[..]); let decrypted_256 = cipher.cfb128_decrypt(iv, &encrypted_256); assert_eq!(decrypted_256[..], plaintext[..]); } #[test] fn invalid_key_decrypt() { // Encrypt with the original key let key_128 = b"k123456789012345"; // key is 16 bytes let cipher = Cipher::new_128(key_128); let plaintext = b"m2"; // a very small message let iv = b"v123456789012345"; let encrypted_128 = cipher.cbc_encrypt(iv, plaintext); assert_eq!(encrypted_128.len(), 16); // Verify padding // Try to decrypt with an invalid key let invalid_key = b"k123456789012347"; let cipher = Cipher::new_128(invalid_key); let decrypted_128 = cipher.cbc_decrypt(iv, &encrypted_128[..]); assert!(decrypted_128.is_empty()); } #[test] fn invalid_input_decrypt() { let key_128 = b"k123456789012345"; let cipher = Cipher::new_128(key_128); let iv = b"v123456789012345"; let bad_ciphertext = b"foo"; let decrypted = cipher.cbc_decrypt(iv, &bad_ciphertext[..]); assert!(decrypted.is_empty()); let empty_ciphertext = b""; let decrypted = cipher.cbc_decrypt(iv, &empty_ciphertext[..]); assert!(decrypted.is_empty()); } #[test] fn cbc_without_auto_padding() { let plaintext: &[u8; 16] = b"\x59\xf9\x62\x18\xd8\xec\xca\xb2\x77\xed\x47\x7a\x33\xdc\xb7\xf3"; let ciphertext: &[u8; 16] = b"\x9f\x27\x07\xbc\x98\xbb\x57\x81\xd4\xe7\xb4\x61\xbf\xfe\x62\x70"; let key: &[u8; 16] = b"\x64\xc5\xfd\x55\xdd\x3a\xd9\x88\x32\x5b\xaa\xec\x52\x43\xdb\x98"; let iv: &[u8; 16] = b"\x00\x04\x00\x8c\x00\x16\x58\x00\x00\x00\x00\x00\x00\x00\x00\x00"; // create a cipher and disable its auto_padding. let mut aes: Cipher = Cipher::new_128(key); aes.set_auto_padding(false); // verify decrypt. let decrypted = aes.cbc_decrypt(iv, ciphertext); assert_eq!(&decrypted, plaintext); // verify encrypt. let encrypted = aes.cbc_encrypt(iv, plaintext); assert_eq!(&encrypted, ciphertext); // encrypt returns empty if the plaintext is not valid block-sized. let invalidblock: &[u8; 10] = b"\x59\xf9\x62\x18\xd8\xec\xca\xb2\x77\xed"; let encrypted = aes.cbc_encrypt(iv, invalidblock); assert!(encrypted.is_empty()); }