forked from libtom/libtomcrypt
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpadding_test.c
More file actions
220 lines (195 loc) · 9.32 KB
/
padding_test.c
File metadata and controls
220 lines (195 loc) · 9.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include <tomcrypt_test.h>
#ifdef LTC_PADDING
typedef struct padding_testcase_ padding_testcase;
typedef int (*cmp_padding_testcase)(const padding_testcase*, const unsigned char*, unsigned long);
struct padding_testcase_ {
unsigned long is, should, max, mode;
const char* name;
cmp_padding_testcase cmp;
};
#define EQ(a, b) s_eq((a), (b), #a, #b)
static int s_eq(unsigned long a, unsigned long b, const char* s_a, const char* s_b)
{
if (a == b) return CRYPT_OK;
#if defined(LTC_TEST) && defined(LTC_TEST_DBG)
else fprintf(stderr, "'%s == %s' failed, %lu is not equal to %lu\n", s_a, s_b, a, b);
#else
LTC_UNUSED_PARAM(s_a);
LTC_UNUSED_PARAM(s_b);
#endif
return CRYPT_FAIL_TESTVECTOR;
}
static int s_cmp_pkcs7(const padding_testcase* t, const unsigned char* p, unsigned long len)
{
unsigned long n, diff = len - t->is;
DOX(EQ(len, t->should), t->name);
for (n = len - diff; n < len; ++n) {
DOX(EQ(p[n], diff), t->name);
}
return CRYPT_OK;
}
#ifdef LTC_RNG_GET_BYTES
static int s_cmp_iso_10126(const padding_testcase* t, const unsigned char* p, unsigned long len)
{
LTC_UNUSED_PARAM(p);
if (len < t->should || len > t->max) {
#if defined(LTC_TEST) && defined(LTC_TEST_DBG)
fprintf(stderr, "(%lu < %lu || %lu > %lu) failed, %s\n", len, t->should, len, t->max, t->name);
#endif
return CRYPT_FAIL_TESTVECTOR;
}
DOX(EQ(p[len - 1], len - t->is), t->name);
return CRYPT_OK;
}
#endif
static int s_cmp_x923(const padding_testcase* t, const unsigned char* p, unsigned long len)
{
unsigned long n, diff = len - t->is;
DOX(EQ(len, t->should), t->name);
for (n = len - diff; n < len - 1; ++n) {
DOX(EQ(p[n], 0x0), t->name);
}
DOX(EQ(p[len - 1], diff), t->name);
return CRYPT_OK;
}
static int s_cmp_oaz(const padding_testcase* t, const unsigned char* p, unsigned long len)
{
unsigned long n, diff = len - t->is;
DOX(EQ(len, t->should), t->name);
n = len - diff;
DOX(EQ(p[n], 0x80), t->name);
n++;
for (; n < len; ++n) {
DOX(EQ(p[n], 0x0), t->name);
}
return CRYPT_OK;
}
static int s_cmp_zero(const padding_testcase* t, const unsigned char* p, unsigned long len)
{
unsigned long n, diff = len - t->is;
DOX(EQ(len, t->should), t->name);
for (n = len - diff; n < len; ++n) {
DOX(EQ(p[n], 0x0), t->name);
}
return CRYPT_OK;
}
static int s_cmp_ssh(const padding_testcase* t, const unsigned char* p, unsigned long len)
{
unsigned long n, diff = len - t->is;
unsigned char pad = 0x1;
DOX(EQ(len, t->should), t->name);
for (n = len - diff; n < len; ++n) {
DOX(EQ(p[n], pad), t->name);
pad++;
}
return CRYPT_OK;
}
static int s_padding_testrun(const padding_testcase* t)
{
unsigned long len;
unsigned char buf[1024];
len = sizeof(buf);
XMEMSET(buf, 0xAA, t->is);
DO(padding_pad(buf, t->is, &len, t->mode));
DO(t->cmp(t, buf, len));
DO(padding_depad(buf, &len, t->mode));
DO(EQ(len, t->is));
return CRYPT_OK;
}
int padding_test(void)
{
const padding_testcase cases[] = {
{ 0, 16, 0, LTC_PAD_PKCS7 | 16, "0-pkcs7", s_cmp_pkcs7 },
{ 1, 16, 0, LTC_PAD_PKCS7 | 16, "1-pkcs7", s_cmp_pkcs7 },
{ 15, 16, 0, LTC_PAD_PKCS7 | 16, "15-pkcs7", s_cmp_pkcs7 },
{ 16, 32, 0, LTC_PAD_PKCS7 | 16, "16-pkcs7", s_cmp_pkcs7 },
{ 255, 256, 0, LTC_PAD_PKCS7 | 16, "255-pkcs7", s_cmp_pkcs7 },
{ 256, 272, 0, LTC_PAD_PKCS7 | 16, "256-pkcs7", s_cmp_pkcs7 },
#ifdef LTC_RNG_GET_BYTES
{ 0, 16, 256, LTC_PAD_ISO_10126 | 16, "0-rand", s_cmp_iso_10126 },
{ 1, 16, 272, LTC_PAD_ISO_10126 | 16, "1-rand", s_cmp_iso_10126 },
{ 15, 16, 272, LTC_PAD_ISO_10126 | 16, "15-rand", s_cmp_iso_10126 },
{ 16, 32, 288, LTC_PAD_ISO_10126 | 16, "16-rand", s_cmp_iso_10126 },
{ 255, 256, 512, LTC_PAD_ISO_10126 | 16, "255-rand", s_cmp_iso_10126 },
{ 256, 272, 528, LTC_PAD_ISO_10126 | 16, "256-rand", s_cmp_iso_10126 },
#endif
{ 0, 16, 0, LTC_PAD_ANSI_X923 | 16, "0-x923", s_cmp_x923 },
{ 1, 16, 0, LTC_PAD_ANSI_X923 | 16, "1-x923", s_cmp_x923 },
{ 15, 16, 0, LTC_PAD_ANSI_X923 | 16, "15-x923", s_cmp_x923 },
{ 16, 32, 0, LTC_PAD_ANSI_X923 | 16, "16-x923", s_cmp_x923 },
{ 255, 256, 0, LTC_PAD_ANSI_X923 | 16, "255-x923", s_cmp_x923 },
{ 256, 272, 0, LTC_PAD_ANSI_X923 | 16, "256-x923", s_cmp_x923 },
{ 0, 16, 0, LTC_PAD_SSH | 16, "0-ssh", s_cmp_ssh },
{ 1, 16, 0, LTC_PAD_SSH | 16, "1-ssh", s_cmp_ssh },
{ 15, 16, 0, LTC_PAD_SSH | 16, "15-ssh", s_cmp_ssh },
{ 16, 32, 0, LTC_PAD_SSH | 16, "16-ssh", s_cmp_ssh },
{ 255, 256, 0, LTC_PAD_SSH | 16, "255-ssh", s_cmp_ssh },
{ 256, 272, 0, LTC_PAD_SSH | 16, "256-ssh", s_cmp_ssh },
{ 0, 16, 0, LTC_PAD_ONE_AND_ZERO | 16, "0-one-and-zero", s_cmp_oaz },
{ 1, 16, 0, LTC_PAD_ONE_AND_ZERO | 16, "1-one-and-zero", s_cmp_oaz },
{ 15, 16, 0, LTC_PAD_ONE_AND_ZERO | 16, "15-one-and-zero", s_cmp_oaz },
{ 16, 32, 0, LTC_PAD_ONE_AND_ZERO | 16, "16-one-and-zero", s_cmp_oaz },
{ 255, 256, 0, LTC_PAD_ONE_AND_ZERO | 16, "255-one-and-zero", s_cmp_oaz },
{ 256, 272, 0, LTC_PAD_ONE_AND_ZERO | 16, "256-one-and-zero", s_cmp_oaz },
{ 0, 0, 0, LTC_PAD_ZERO | 16, "0-zero", s_cmp_zero },
{ 1, 16, 0, LTC_PAD_ZERO | 16, "1-zero", s_cmp_zero },
{ 15, 16, 0, LTC_PAD_ZERO | 16, "15-zero", s_cmp_zero },
{ 16, 16, 0, LTC_PAD_ZERO | 16, "16-zero", s_cmp_zero },
{ 255, 256, 0, LTC_PAD_ZERO | 16, "255-zero", s_cmp_zero },
{ 256, 256, 0, LTC_PAD_ZERO | 16, "256-zero", s_cmp_zero },
{ 0, 16, 0, LTC_PAD_ZERO_ALWAYS | 16, "0-zero-always", s_cmp_zero },
{ 1, 16, 0, LTC_PAD_ZERO_ALWAYS | 16, "1-zero-always", s_cmp_zero },
{ 15, 16, 0, LTC_PAD_ZERO_ALWAYS | 16, "15-zero-always", s_cmp_zero },
{ 16, 32, 0, LTC_PAD_ZERO_ALWAYS | 16, "16-zero-always", s_cmp_zero },
{ 255, 256, 0, LTC_PAD_ZERO_ALWAYS | 16, "255-zero-always", s_cmp_zero },
{ 256, 272, 0, LTC_PAD_ZERO_ALWAYS | 16, "256-zero-always", s_cmp_zero },
};
unsigned i;
/* Examples from https://en.wikipedia.org/w/index.php?title=Padding_(cryptography)&oldid=823057951#Byte_padding */
const struct {
unsigned char data[16];
unsigned long len;
unsigned long mode;
} tv[] = {
{ { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04, 0x04, 0x04, 0x04 }, 12, LTC_PAD_PKCS7 | 16 },
{ { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x00, 0x00, 0x00, 0x04 }, 12, LTC_PAD_ANSI_X923 | 16 },
#ifdef LTC_RNG_GET_BYTES
{ { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x81, 0xA6, 0x23, 0x04 }, 12, LTC_PAD_ISO_10126 | 16 },
#endif
{ { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x80, 0x00, 0x00, 0x00 }, 12, LTC_PAD_ONE_AND_ZERO | 16 },
{ { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x80 }, 15, LTC_PAD_ONE_AND_ZERO | 16 },
{ { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x00, 0x00, 0x00, 0x00 }, 12, LTC_PAD_ZERO | 16 },
};
/* we need a big buffer like that as LTC_PAD_ISO_10126
* is allowed to add 1-255 bytes of padding
*/
unsigned char buf[256 + 16];
unsigned long l;
for (i = 0; i < LTC_ARRAY_SIZE(cases); ++i) {
DOX(s_padding_testrun(&cases[i]), cases[i].name);
}
for (i = 0; i < LTC_ARRAY_SIZE(tv); ++i) {
XMEMCPY(buf, tv[i].data, sizeof(tv[i].data));
l = sizeof(tv[i].data);
DO(padding_depad(buf, &l, tv[i].mode));
XMEMSET(buf, 0xDD, 16);
l = sizeof(buf);
DO(padding_pad(buf, tv[i].len, &l, tv[i].mode));
#ifdef LTC_RNG_GET_BYTES
if ((tv[i].mode & LTC_PAD_MASK) != LTC_PAD_ISO_10126)
#endif
{
COMPARE_TESTVECTOR(tv[i].data, sizeof(tv[i].data), buf, l, "padding fixed TV", i);
}
}
/* wycheproof failing test - https://github.com/libtom/libtomcrypt/pull/454 */
{
unsigned char data[] = { 0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
unsigned long len = sizeof(data);
SHOULD_FAIL(padding_depad(data, &len, (LTC_PAD_PKCS7 | 16)));
}
return CRYPT_OK;
}
#endif