neo_crypto/
padding.rs

1use std::usize;
2
3use rand::random;
4
5#[cfg(test)]
6mod padding_tests {
7    use super::*;
8    #[test]
9    fn asnix923_test() {
10        let plaintext: [u8; 13] = [
11            0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01,
12        ];
13        let paded_plaintext: Vec<u8> = standard_padding(&plaintext, 16, &PaddingMode::ASNIX923);
14        assert_eq!(
15            paded_plaintext,
16            [
17                0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x00,
18                0x00, 0x03
19            ]
20        );
21    }
22    #[test]
23    fn pkcs5_test() {
24        let plaintext: [u8; 13] = [
25            0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01,
26        ];
27        let paded_plaintext: Vec<u8> = standard_padding(&plaintext, 16, &PaddingMode::PKCS5);
28        assert_eq!(
29            paded_plaintext,
30            [
31                0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x03,
32                0x03, 0x03
33            ]
34        );
35    }
36    #[test]
37    fn isoiec7816_4_test() {
38        let plaintext: [u8; 13] = [
39            0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01,
40        ];
41        let paded_plaintext: Vec<u8> = standard_padding(&plaintext, 16, &PaddingMode::ISOIEC7816_4);
42        assert_eq!(
43            paded_plaintext,
44            [
45                0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x80,
46                0x00, 0x00
47            ]
48        );
49    }
50    #[test]
51    fn zeropadding_test() {
52        let plaintext: [u8; 13] = [
53            0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01,
54        ];
55        let paded_plaintext: Vec<u8> = standard_padding(&plaintext, 16, &PaddingMode::ZeroPadding);
56        assert_eq!(
57            paded_plaintext,
58            [
59                0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x00,
60                0x00, 0x00
61            ]
62        );
63    }
64}
65
66pub enum PaddingMode {
67    NoPadding,
68    ASNIX923,
69    ISO10126,
70    PKCS5,
71    PKCS7,
72    ISOIEC7816_4,
73    ZeroPadding,
74}
75
76pub fn standard_padding(
77    plaintext: &[u8],
78    expected_len: usize,
79    padding_mode: &PaddingMode,
80) -> Vec<u8> {
81    let mut paded_plaintext: Vec<u8> = plaintext.to_vec();
82    let bytes_rem: usize = paded_plaintext.len() % expected_len;
83    let bytes_to_pad: usize = if bytes_rem != 0 {
84        expected_len - bytes_rem
85    } else {
86        0
87    };
88
89    match padding_mode {
90        PaddingMode::NoPadding => {}
91        PaddingMode::ASNIX923 => {
92            for _ in 1..bytes_to_pad {
93                paded_plaintext.push(0x00);
94            }
95            paded_plaintext.push(bytes_to_pad as u8);
96        }
97        PaddingMode::ISO10126 => {
98            for _ in 1..bytes_to_pad {
99                paded_plaintext.push(random::<u8>());
100            }
101            paded_plaintext.push(bytes_to_pad as u8);
102        }
103        PaddingMode::PKCS5 | PaddingMode::PKCS7 => {
104            for _ in 0..bytes_to_pad {
105                paded_plaintext.push(bytes_to_pad as u8);
106            }
107        }
108        PaddingMode::ISOIEC7816_4 => {
109            paded_plaintext.push(0x80);
110            for _ in 1..bytes_to_pad {
111                paded_plaintext.push(0x00);
112            }
113        }
114        PaddingMode::ZeroPadding => {
115            for _ in 0..bytes_to_pad {
116                paded_plaintext.push(0x00);
117            }
118        }
119    }
120    paded_plaintext
121}