Coverage Report

Created: 2020-08-01 06:18

/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
   }