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