/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/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 | 155 | { |
15 | 155 | if(len <= 2) |
16 | 0 | return len; |
17 | 155 | |
18 | 155 | const size_t padding_length = in[len-1]; |
19 | 155 | |
20 | 155 | if(padding_length == 0 || padding_length > len) |
21 | 43 | return len; |
22 | 112 | |
23 | 112 | const size_t padding_start = len - padding_length; |
24 | 112 | |
25 | 978 | for(size_t i = padding_start; i != len; ++i) |
26 | 950 | { |
27 | 950 | if(in[i] != padding_length) |
28 | 84 | return len; |
29 | 950 | } |
30 | 112 | |
31 | 112 | return len - padding_length; |
32 | 112 | } |
33 | | |
34 | | size_t ref_x923_unpad(const uint8_t in[], size_t len) |
35 | 155 | { |
36 | 155 | if(len <= 2) |
37 | 0 | return len; |
38 | 155 | |
39 | 155 | const size_t padding_length = in[len-1]; |
40 | 155 | |
41 | 155 | if(padding_length == 0 || padding_length > len) |
42 | 43 | return len; |
43 | 112 | const size_t padding_start = len - padding_length; |
44 | 112 | |
45 | 630 | for(size_t i = padding_start; i != len - 1; ++i) |
46 | 611 | { |
47 | 611 | if(in[i] != 0) |
48 | 93 | { |
49 | 93 | return len; |
50 | 93 | } |
51 | 611 | } |
52 | 112 | |
53 | 112 | return len - padding_length; |
54 | 112 | } |
55 | | |
56 | | size_t ref_oneandzero_unpad(const uint8_t in[], size_t len) |
57 | 212 | { |
58 | 212 | if(len <= 2) |
59 | 0 | return len; |
60 | 212 | |
61 | 212 | size_t idx = len - 1; |
62 | 212 | |
63 | 212 | for(;;) |
64 | 6.08k | { |
65 | 6.08k | if(in[idx] == 0) |
66 | 5.87k | { |
67 | 5.87k | if(idx == 0) |
68 | 1 | return len; |
69 | 5.87k | idx -= 1; |
70 | 5.87k | continue; |
71 | 5.87k | } |
72 | 211 | else if(in[idx] == 0x80) |
73 | 9 | { |
74 | 9 | return idx; |
75 | 9 | } |
76 | 202 | else |
77 | 202 | return len; |
78 | 6.08k | } |
79 | 212 | |
80 | 212 | return len; |
81 | 212 | } |
82 | | |
83 | | size_t ref_esp_unpad(const uint8_t in[], size_t len) |
84 | 155 | { |
85 | 155 | if(len <= 2) |
86 | 0 | return len; |
87 | 155 | |
88 | 155 | const size_t padding_bytes = in[len - 1]; |
89 | 155 | |
90 | 155 | if(padding_bytes == 0 || padding_bytes > len) |
91 | 43 | { |
92 | 43 | return len; |
93 | 43 | } |
94 | 112 | |
95 | 112 | const size_t padding_start = len - padding_bytes; |
96 | 230 | for(size_t i = padding_start; i != len; ++i) |
97 | 217 | { |
98 | 217 | if(in[i] != (i - padding_start + 1)) |
99 | 99 | { |
100 | 99 | return len; |
101 | 99 | } |
102 | 217 | } |
103 | 112 | |
104 | 112 | return len - padding_bytes; |
105 | 112 | } |
106 | | |
107 | | uint16_t ref_tls_cbc_unpad(const uint8_t in[], size_t len) |
108 | 228 | { |
109 | 228 | if(len == 0) |
110 | 0 | return 0; |
111 | 228 | |
112 | 228 | const size_t padding_length = in[(len-1)]; |
113 | 228 | |
114 | 228 | if(padding_length >= len) |
115 | 79 | return 0; |
116 | 149 | |
117 | 149 | /* |
118 | 149 | * TLS v1.0 and up require all the padding bytes be the same value |
119 | 149 | * and allows up to 255 bytes. |
120 | 149 | */ |
121 | 1.14k | for(size_t i = 0; i != 1 + padding_length; ++i) |
122 | 1.09k | { |
123 | 1.09k | if(in[(len-i-1)] != padding_length) |
124 | 98 | return 0; |
125 | 1.09k | } |
126 | 149 | return padding_length + 1; |
127 | 149 | } |
128 | | |
129 | | } |
130 | | |
131 | | void fuzz(const uint8_t in[], size_t len) |
132 | 228 | { |
133 | 228 | static Botan::PKCS7_Padding pkcs7; |
134 | 228 | static Botan::ANSI_X923_Padding x923; |
135 | 228 | static Botan::OneAndZeros_Padding oneandzero; |
136 | 228 | static Botan::ESP_Padding esp; |
137 | 228 | |
138 | 228 | if(pkcs7.valid_blocksize(len)) |
139 | 155 | { |
140 | 155 | const size_t ct_pkcs7 = pkcs7.unpad(in, len); |
141 | 155 | const size_t ref_pkcs7 = ref_pkcs7_unpad(in, len); |
142 | 155 | FUZZER_ASSERT_EQUAL(ct_pkcs7, ref_pkcs7); |
143 | 155 | } |
144 | 228 | |
145 | 228 | if(x923.valid_blocksize(len)) |
146 | 155 | { |
147 | 155 | const size_t ct_x923 = x923.unpad(in, len); |
148 | 155 | const size_t ref_x923 = ref_x923_unpad(in, len); |
149 | 155 | FUZZER_ASSERT_EQUAL(ct_x923, ref_x923); |
150 | 155 | } |
151 | 228 | |
152 | 228 | if(oneandzero.valid_blocksize(len)) |
153 | 212 | { |
154 | 212 | const size_t ct_oneandzero = oneandzero.unpad(in, len); |
155 | 212 | const size_t ref_oneandzero = ref_oneandzero_unpad(in, len); |
156 | 212 | FUZZER_ASSERT_EQUAL(ct_oneandzero, ref_oneandzero); |
157 | 212 | } |
158 | 228 | |
159 | 228 | if(esp.valid_blocksize(len)) |
160 | 155 | { |
161 | 155 | const size_t ct_esp = esp.unpad(in, len); |
162 | 155 | const size_t ref_esp = ref_esp_unpad(in, len); |
163 | 155 | FUZZER_ASSERT_EQUAL(ct_esp, ref_esp); |
164 | 155 | } |
165 | 228 | |
166 | 228 | const uint16_t ct_cbc = Botan::TLS::check_tls_cbc_padding(in, len); |
167 | 228 | const uint16_t ref_cbc = ref_tls_cbc_unpad(in, len); |
168 | 228 | FUZZER_ASSERT_EQUAL(ct_cbc, ref_cbc); |
169 | 228 | } |