diff --git a/Cargo.toml b/Cargo.toml index 545a78d..4873164 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "shadowsocks-crypto" -version = "0.5.4" +version = "0.5.5" authors = ["luozijun ", "ty "] edition = "2021" license = "MIT" @@ -70,3 +70,7 @@ subtle = { version = "2.5", optional = true } [dev-dependencies] hex = "0.4" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/src/kind.rs b/src/kind.rs index e495702..a0cd6b5 100644 --- a/src/kind.rs +++ b/src/kind.rs @@ -61,15 +61,15 @@ pub enum CipherCategory { None, /// Stream ciphers is used for OLD ShadowSocks protocol, which uses stream ciphers to encrypt data payloads #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] Stream, /// AEAD ciphers is used in modern ShadowSocks protocol, which sends data in separate packets #[cfg(feature = "v1-aead")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-aead")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead")))] Aead, /// AEAD ciphers 2022 with enhanced security #[cfg(feature = "v2")] - #[cfg_attr(docrs, doc(cfg(feature = "v2")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v2")))] Aead2022, } @@ -81,180 +81,180 @@ pub enum CipherKind { NONE, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] SS_TABLE, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] SS_RC4_MD5, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] AES_128_CTR, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] AES_192_CTR, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] AES_256_CTR, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] AES_128_CFB1, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] AES_128_CFB8, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] AES_128_CFB128, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] AES_192_CFB1, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] AES_192_CFB8, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] AES_192_CFB128, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] AES_256_CFB1, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] AES_256_CFB8, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] AES_256_CFB128, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] AES_128_OFB, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] AES_192_OFB, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] AES_256_OFB, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] CAMELLIA_128_CTR, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] CAMELLIA_192_CTR, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] CAMELLIA_256_CTR, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] CAMELLIA_128_CFB1, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] CAMELLIA_128_CFB8, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] CAMELLIA_128_CFB128, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] CAMELLIA_192_CFB1, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] CAMELLIA_192_CFB8, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] CAMELLIA_192_CFB128, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] CAMELLIA_256_CFB1, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] CAMELLIA_256_CFB8, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] CAMELLIA_256_CFB128, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] CAMELLIA_128_OFB, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] CAMELLIA_192_OFB, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] CAMELLIA_256_OFB, #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] RC4, // NOTE: IETF 版本 #[cfg(feature = "v1-stream")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-stream")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-stream")))] CHACHA20, // AEAD Cipher #[cfg(feature = "v1-aead")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-aead")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead")))] /// AEAD_AES_128_GCM AES_128_GCM, #[cfg(feature = "v1-aead")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-aead")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead")))] /// AEAD_AES_256_GCM AES_256_GCM, #[cfg(feature = "v1-aead-extra")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-aead-extra")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))] /// AEAD_AES_128_CCM AES_128_CCM, #[cfg(feature = "v1-aead-extra")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-aead-extra")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))] /// AEAD_AES_256_CCM AES_256_CCM, #[cfg(feature = "v1-aead-extra")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-aead-extra")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))] /// AEAD_AES_128_GCM_SIV AES_128_GCM_SIV, #[cfg(feature = "v1-aead-extra")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-aead-extra")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))] /// AEAD_AES_256_GCM_SIV AES_256_GCM_SIV, // NOTE: IETF 版本 #[cfg(feature = "v1-aead")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-aead")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead")))] /// AEAD_CHACHA20_POLY1305 CHACHA20_POLY1305, #[cfg(feature = "v1-aead-extra")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-aead-extra")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))] /// AEAD_XCHACHA20_POLY1305 XCHACHA20_POLY1305, #[cfg(feature = "v1-aead-extra")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-aead-extra")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))] /// SM4_GCM SM4_GCM, #[cfg(feature = "v1-aead-extra")] - #[cfg_attr(docrs, doc(cfg(feature = "v1-aead-extra")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v1-aead-extra")))] /// SM4_GCM SM4_CCM, #[cfg(feature = "v2")] - #[cfg_attr(docrs, doc(cfg(feature = "v2")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v2")))] /// 2022-blake3-aes-128-gcm AEAD2022_BLAKE3_AES_128_GCM, #[cfg(feature = "v2")] - #[cfg_attr(docrs, doc(cfg(feature = "v2")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v2")))] /// 2022-blake3-aes-128-gcm AEAD2022_BLAKE3_AES_256_GCM, #[cfg(feature = "v2")] - #[cfg_attr(docrs, doc(cfg(feature = "v2")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v2")))] /// 2022-blake3-chacha20-poly1305 AEAD2022_BLAKE3_CHACHA20_POLY1305, #[cfg(feature = "v2-extra")] - #[cfg_attr(docrs, doc(cfg(feature = "v2-extra")))] + #[cfg_attr(docsrs, doc(cfg(feature = "v2-extra")))] /// 2022-blake3-chacha8-poly1305 AEAD2022_BLAKE3_CHACHA8_POLY1305, } diff --git a/src/lib.rs b/src/lib.rs index 41de015..a84a232 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,11 +3,11 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #[cfg(feature = "v1")] -#[cfg_attr(docrs, doc(cfg(feature = "v1")))] +#[cfg_attr(docsrs, doc(cfg(feature = "v1")))] pub mod v1; #[cfg(feature = "v2")] -#[cfg_attr(docrs, doc(cfg(feature = "v2")))] +#[cfg_attr(docsrs, doc(cfg(feature = "v2")))] pub mod v2; pub mod kind; diff --git a/src/v1/streamcipher/table.rs b/src/v1/streamcipher/table.rs index 6d9233c..f1856af 100644 --- a/src/v1/streamcipher/table.rs +++ b/src/v1/streamcipher/table.rs @@ -23,8 +23,9 @@ impl Table { let a = u64::from_le_bytes([h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]]); let mut table = [0u64; Self::TABLE_SIZE]; - for (i, item) in table.iter_mut().enumerate().take(Self::TABLE_SIZE) { - *item = i as u64; + + for i in 0..table.len() { + table[i] = i as u64; } for i in 1..1024 { @@ -74,3 +75,52 @@ fn test_table() { assert_eq!(&cleartext[..], plaintext); } + +#[test] +fn test_table_box() { + let key: &[u8] = b"password"; + let ebox: [u8; 256] = [ + 157, 219, 245, 15, 85, 7, 195, 211, 55, 126, 37, 117, 249, 229, 98, 205, 254, 61, 137, 77, 253, 135, 138, 185, + 45, 100, 75, 97, 46, 22, 28, 84, 143, 160, 175, 136, 194, 2, 201, 173, 132, 155, 23, 174, 95, 54, 0, 239, 6, + 153, 180, 34, 149, 26, 19, 101, 203, 247, 214, 111, 127, 119, 81, 177, 53, 142, 13, 216, 115, 241, 202, 73, 48, + 86, 1, 11, 43, 125, 41, 121, 209, 193, 199, 51, 47, 32, 36, 90, 255, 156, 38, 108, 3, 99, 238, 179, 50, 237, + 158, 186, 110, 217, 76, 223, 118, 196, 107, 83, 39, 63, 9, 129, 72, 5, 56, 234, 91, 250, 224, 228, 251, 146, + 170, 151, 21, 10, 171, 114, 154, 172, 58, 78, 140, 197, 67, 35, 130, 92, 12, 31, 189, 166, 122, 29, 123, 113, + 215, 94, 165, 89, 221, 240, 93, 178, 150, 218, 220, 232, 144, 188, 65, 88, 52, 59, 139, 242, 71, 62, 182, 57, + 225, 147, 30, 17, 68, 243, 80, 44, 141, 4, 200, 42, 16, 102, 134, 246, 70, 244, 145, 124, 213, 8, 187, 66, 183, + 191, 40, 103, 162, 74, 87, 148, 230, 25, 120, 60, 233, 18, 176, 227, 184, 112, 20, 131, 109, 152, 14, 163, 49, + 24, 222, 181, 164, 133, 207, 104, 210, 236, 27, 106, 96, 64, 33, 116, 79, 206, 69, 212, 82, 169, 105, 235, 190, + 128, 226, 208, 168, 192, 167, 159, 161, 231, 204, 198, 248, 252, + ]; + let dbox: [u8; 256] = [ + 46, 74, 37, 92, 179, 113, 48, 5, 191, 110, 125, 75, 138, 66, 216, 3, 182, 173, 207, 54, 212, 124, 29, 42, 219, + 203, 53, 228, 30, 143, 172, 139, 85, 232, 51, 135, 86, 10, 90, 108, 196, 78, 181, 76, 177, 24, 28, 84, 72, 218, + 96, 83, 162, 64, 45, 8, 114, 169, 130, 163, 205, 17, 167, 109, 231, 160, 193, 134, 174, 236, 186, 166, 112, 71, + 199, 26, 102, 19, 131, 234, 176, 62, 238, 107, 31, 4, 73, 200, 161, 149, 87, 116, 137, 152, 147, 44, 230, 27, + 14, 93, 25, 55, 183, 197, 225, 240, 229, 106, 91, 214, 100, 59, 211, 145, 127, 68, 233, 11, 104, 61, 204, 79, + 142, 144, 189, 77, 9, 60, 243, 111, 136, 213, 40, 223, 184, 21, 35, 18, 22, 164, 132, 178, 65, 32, 158, 188, + 121, 171, 201, 52, 154, 123, 215, 49, 128, 41, 89, 0, 98, 249, 33, 250, 198, 217, 222, 148, 141, 248, 246, 239, + 122, 126, 129, 39, 43, 34, 208, 63, 153, 95, 50, 221, 168, 194, 210, 23, 99, 192, 159, 140, 242, 195, 247, 81, + 36, 6, 105, 133, 253, 82, 180, 38, 70, 56, 252, 15, 235, 224, 245, 80, 226, 7, 237, 190, 58, 146, 67, 101, 155, + 1, 156, 150, 220, 103, 118, 170, 244, 209, 119, 13, 202, 251, 157, 206, 115, 241, 227, 97, 94, 47, 151, 69, + 165, 175, 187, 2, 185, 57, 254, 12, 117, 120, 255, 20, 16, 88, + ]; + + let cipher = Table::new(key, b""); + assert_eq!(cipher.ebox, ebox); + assert_eq!(cipher.dbox, dbox); +} + +#[test] +fn test_table_encrypt() { + let key: &[u8] = b"password"; + let plain_text: &[u8] = b"hello world"; + let cipher_text: &[u8] = &[118, 217, 39, 39, 129, 143, 228, 129, 56, 39, 110]; + + let mut cipher = Table::new(key, b""); + + let mut text_buffer = plain_text.to_vec(); + cipher.encrypt_slice(&mut text_buffer); + + assert_eq!(cipher_text, text_buffer); +}