/src/botan/src/fuzzer/mode_padding.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * (C) 2018 Jack Lloyd |
3 | | * |
4 | | * Botan is released under the Simplified BSD License (see license.txt) |
5 | | */ |
6 | | |
7 | | #include "fuzzers.h" |
8 | | #include <botan/internal/mode_pad.h> |
9 | | #include <botan/internal/tls_cbc.h> |
10 | | |
11 | | namespace { |
12 | | |
13 | | size_t ref_pkcs7_unpad(const uint8_t in[], size_t len) |
14 | 135 | { |
15 | 135 | if(len <= 2) |
16 | 0 | return len; |
17 | | |
18 | 135 | const size_t padding_length = in[len-1]; |
19 | | |
20 | 135 | if(padding_length == 0 || padding_length > len) |
21 | 40 | return len; |
22 | | |
23 | 95 | const size_t padding_start = len - padding_length; |
24 | | |
25 | 688 | for(size_t i = padding_start; i != len; ++i) |
26 | 665 | { |
27 | 665 | if(in[i] != padding_length) |
28 | 72 | return len; |
29 | 665 | } |
30 | | |
31 | 23 | return len - padding_length; |
32 | 95 | } |
33 | | |
34 | | size_t ref_x923_unpad(const uint8_t in[], size_t len) |
35 | 135 | { |
36 | 135 | if(len <= 2) |
37 | 0 | return len; |
38 | | |
39 | 135 | const size_t padding_length = in[len-1]; |
40 | | |
41 | 135 | if(padding_length == 0 || padding_length > len) |
42 | 40 | return len; |
43 | 95 | const size_t padding_start = len - padding_length; |
44 | | |
45 | 456 | for(size_t i = padding_start; i != len - 1; ++i) |
46 | 440 | { |
47 | 440 | if(in[i] != 0) |
48 | 79 | { |
49 | 79 | return len; |
50 | 79 | } |
51 | 440 | } |
52 | | |
53 | 16 | return len - padding_length; |
54 | 95 | } |
55 | | |
56 | | size_t ref_oneandzero_unpad(const uint8_t in[], size_t len) |
57 | 172 | { |
58 | 172 | if(len <= 2) |
59 | 0 | return len; |
60 | | |
61 | 172 | size_t idx = len - 1; |
62 | | |
63 | 172 | for(;;) |
64 | 1.27k | { |
65 | 1.27k | if(in[idx] == 0) |
66 | 1.10k | { |
67 | 1.10k | if(idx == 0) |
68 | 3 | return len; |
69 | 1.09k | idx -= 1; |
70 | 1.09k | continue; |
71 | 1.10k | } |
72 | 169 | else if(in[idx] == 0x80) |
73 | 3 | { |
74 | 3 | return idx; |
75 | 3 | } |
76 | 166 | else |
77 | 166 | return len; |
78 | 1.27k | } |
79 | | |
80 | 0 | return len; |
81 | 172 | } |
82 | | |
83 | | size_t ref_esp_unpad(const uint8_t in[], size_t len) |
84 | 135 | { |
85 | 135 | if(len <= 2) |
86 | 0 | return len; |
87 | | |
88 | 135 | const size_t padding_bytes = in[len - 1]; |
89 | | |
90 | 135 | if(padding_bytes == 0 || padding_bytes > len) |
91 | 40 | { |
92 | 40 | return len; |
93 | 40 | } |
94 | | |
95 | 95 | const size_t padding_start = len - padding_bytes; |
96 | 208 | for(size_t i = padding_start; i != len; ++i) |
97 | 192 | { |
98 | 192 | if(in[i] != (i - padding_start + 1)) |
99 | 79 | { |
100 | 79 | return len; |
101 | 79 | } |
102 | 192 | } |
103 | | |
104 | 16 | return len - padding_bytes; |
105 | 95 | } |
106 | | |
107 | | uint16_t ref_tls_cbc_unpad(const uint8_t in[], size_t len) |
108 | 187 | { |
109 | 187 | if(len == 0) |
110 | 0 | return 0; |
111 | | |
112 | 187 | const size_t padding_length = in[(len-1)]; |
113 | | |
114 | 187 | if(padding_length >= len) |
115 | 76 | return 0; |
116 | | |
117 | | /* |
118 | | * TLS v1.0 and up require all the padding bytes be the same value |
119 | | * and allows up to 255 bytes. |
120 | | */ |
121 | 739 | for(size_t i = 0; i != 1 + padding_length; ++i) |
122 | 705 | { |
123 | 705 | if(in[(len-i-1)] != padding_length) |
124 | 77 | return 0; |
125 | 705 | } |
126 | 34 | return padding_length + 1; |
127 | 111 | } |
128 | | |
129 | | } |
130 | | |
131 | | void fuzz(const uint8_t in[], size_t len) |
132 | 187 | { |
133 | 187 | static Botan::PKCS7_Padding pkcs7; |
134 | 187 | static Botan::ANSI_X923_Padding x923; |
135 | 187 | static Botan::OneAndZeros_Padding oneandzero; |
136 | 187 | static Botan::ESP_Padding esp; |
137 | | |
138 | 187 | if(pkcs7.valid_blocksize(len)) |
139 | 135 | { |
140 | 135 | const size_t ct_pkcs7 = pkcs7.unpad(in, len); |
141 | 135 | const size_t ref_pkcs7 = ref_pkcs7_unpad(in, len); |
142 | 135 | FUZZER_ASSERT_EQUAL(ct_pkcs7, ref_pkcs7); |
143 | 135 | } |
144 | | |
145 | 187 | if(x923.valid_blocksize(len)) |
146 | 135 | { |
147 | 135 | const size_t ct_x923 = x923.unpad(in, len); |
148 | 135 | const size_t ref_x923 = ref_x923_unpad(in, len); |
149 | 135 | FUZZER_ASSERT_EQUAL(ct_x923, ref_x923); |
150 | 135 | } |
151 | | |
152 | 187 | if(oneandzero.valid_blocksize(len)) |
153 | 172 | { |
154 | 172 | const size_t ct_oneandzero = oneandzero.unpad(in, len); |
155 | 172 | const size_t ref_oneandzero = ref_oneandzero_unpad(in, len); |
156 | 172 | FUZZER_ASSERT_EQUAL(ct_oneandzero, ref_oneandzero); |
157 | 172 | } |
158 | | |
159 | 187 | if(esp.valid_blocksize(len)) |
160 | 135 | { |
161 | 135 | const size_t ct_esp = esp.unpad(in, len); |
162 | 135 | const size_t ref_esp = ref_esp_unpad(in, len); |
163 | 135 | FUZZER_ASSERT_EQUAL(ct_esp, ref_esp); |
164 | 135 | } |
165 | | |
166 | 187 | const uint16_t ct_cbc = Botan::TLS::check_tls_cbc_padding(in, len); |
167 | 187 | const uint16_t ref_cbc = ref_tls_cbc_unpad(in, len); |
168 | 187 | FUZZER_ASSERT_EQUAL(ct_cbc, ref_cbc); |
169 | 187 | } |