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}