1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
4 #include <tomcrypt_test.h>
8 typedef struct padding_testcase_ padding_testcase
;
10 typedef int (*cmp_padding_testcase
)(const padding_testcase
*, const unsigned char*, unsigned long);
12 struct padding_testcase_
{
13 unsigned long is
, should
, max
, mode
;
15 cmp_padding_testcase cmp
;
18 #define EQ(a, b) s_eq((a), (b), #a, #b)
20 static int s_eq(unsigned long a
, unsigned long b
, const char* s_a
, const char* s_b
)
22 if (a
== b
) return CRYPT_OK
;
23 #if defined(LTC_TEST) && defined(LTC_TEST_DBG)
24 else fprintf(stderr
, "'%s == %s' failed, %lu is not equal to %lu\n", s_a
, s_b
, a
, b
);
26 LTC_UNUSED_PARAM(s_a
);
27 LTC_UNUSED_PARAM(s_b
);
29 return CRYPT_FAIL_TESTVECTOR
;
32 static int s_cmp_pkcs7(const padding_testcase
* t
, const unsigned char* p
, unsigned long len
)
34 unsigned long n
, diff
= len
- t
->is
;
35 DOX(EQ(len
, t
->should
), t
->name
);
36 for (n
= len
- diff
; n
< len
; ++n
) {
37 DOX(EQ(p
[n
], diff
), t
->name
);
42 #ifdef LTC_RNG_GET_BYTES
43 static int s_cmp_iso_10126(const padding_testcase
* t
, const unsigned char* p
, unsigned long len
)
46 if (len
< t
->should
|| len
> t
->max
) {
47 #if defined(LTC_TEST) && defined(LTC_TEST_DBG)
48 fprintf(stderr
, "(%lu < %lu || %lu > %lu) failed, %s\n", len
, t
->should
, len
, t
->max
, t
->name
);
50 return CRYPT_FAIL_TESTVECTOR
;
52 DOX(EQ(p
[len
- 1], len
- t
->is
), t
->name
);
57 static int s_cmp_x923(const padding_testcase
* t
, const unsigned char* p
, unsigned long len
)
59 unsigned long n
, diff
= len
- t
->is
;
60 DOX(EQ(len
, t
->should
), t
->name
);
61 for (n
= len
- diff
; n
< len
- 1; ++n
) {
62 DOX(EQ(p
[n
], 0x0), t
->name
);
64 DOX(EQ(p
[len
- 1], diff
), t
->name
);
68 static int s_cmp_oaz(const padding_testcase
* t
, const unsigned char* p
, unsigned long len
)
70 unsigned long n
, diff
= len
- t
->is
;
71 DOX(EQ(len
, t
->should
), t
->name
);
73 DOX(EQ(p
[n
], 0x80), t
->name
);
75 for (; n
< len
; ++n
) {
76 DOX(EQ(p
[n
], 0x0), t
->name
);
81 static int s_cmp_zero(const padding_testcase
* t
, const unsigned char* p
, unsigned long len
)
83 unsigned long n
, diff
= len
- t
->is
;
84 DOX(EQ(len
, t
->should
), t
->name
);
85 for (n
= len
- diff
; n
< len
; ++n
) {
86 DOX(EQ(p
[n
], 0x0), t
->name
);
91 static int s_cmp_ssh(const padding_testcase
* t
, const unsigned char* p
, unsigned long len
)
93 unsigned long n
, diff
= len
- t
->is
;
94 unsigned char pad
= 0x1;
95 DOX(EQ(len
, t
->should
), t
->name
);
96 for (n
= len
- diff
; n
< len
; ++n
) {
97 DOX(EQ(p
[n
], pad
), t
->name
);
103 static int s_padding_testrun(const padding_testcase
* t
)
106 unsigned char buf
[1024];
109 XMEMSET(buf
, 0xAA, t
->is
);
110 DO(padding_pad(buf
, t
->is
, &len
, t
->mode
));
111 DO(t
->cmp(t
, buf
, len
));
112 DO(padding_depad(buf
, &len
, t
->mode
));
117 int padding_test(void)
119 const padding_testcase cases
[] = {
120 { 0, 16, 0, LTC_PAD_PKCS7
| 16, "0-pkcs7", s_cmp_pkcs7
},
121 { 1, 16, 0, LTC_PAD_PKCS7
| 16, "1-pkcs7", s_cmp_pkcs7
},
122 { 15, 16, 0, LTC_PAD_PKCS7
| 16, "15-pkcs7", s_cmp_pkcs7
},
123 { 16, 32, 0, LTC_PAD_PKCS7
| 16, "16-pkcs7", s_cmp_pkcs7
},
124 { 255, 256, 0, LTC_PAD_PKCS7
| 16, "255-pkcs7", s_cmp_pkcs7
},
125 { 256, 272, 0, LTC_PAD_PKCS7
| 16, "256-pkcs7", s_cmp_pkcs7
},
126 #ifdef LTC_RNG_GET_BYTES
127 { 0, 16, 256, LTC_PAD_ISO_10126
| 16, "0-rand", s_cmp_iso_10126
},
128 { 1, 16, 272, LTC_PAD_ISO_10126
| 16, "1-rand", s_cmp_iso_10126
},
129 { 15, 16, 272, LTC_PAD_ISO_10126
| 16, "15-rand", s_cmp_iso_10126
},
130 { 16, 32, 288, LTC_PAD_ISO_10126
| 16, "16-rand", s_cmp_iso_10126
},
131 { 255, 256, 512, LTC_PAD_ISO_10126
| 16, "255-rand", s_cmp_iso_10126
},
132 { 256, 272, 528, LTC_PAD_ISO_10126
| 16, "256-rand", s_cmp_iso_10126
},
134 { 0, 16, 0, LTC_PAD_ANSI_X923
| 16, "0-x923", s_cmp_x923
},
135 { 1, 16, 0, LTC_PAD_ANSI_X923
| 16, "1-x923", s_cmp_x923
},
136 { 15, 16, 0, LTC_PAD_ANSI_X923
| 16, "15-x923", s_cmp_x923
},
137 { 16, 32, 0, LTC_PAD_ANSI_X923
| 16, "16-x923", s_cmp_x923
},
138 { 255, 256, 0, LTC_PAD_ANSI_X923
| 16, "255-x923", s_cmp_x923
},
139 { 256, 272, 0, LTC_PAD_ANSI_X923
| 16, "256-x923", s_cmp_x923
},
141 { 0, 16, 0, LTC_PAD_SSH
| 16, "0-ssh", s_cmp_ssh
},
142 { 1, 16, 0, LTC_PAD_SSH
| 16, "1-ssh", s_cmp_ssh
},
143 { 15, 16, 0, LTC_PAD_SSH
| 16, "15-ssh", s_cmp_ssh
},
144 { 16, 32, 0, LTC_PAD_SSH
| 16, "16-ssh", s_cmp_ssh
},
145 { 255, 256, 0, LTC_PAD_SSH
| 16, "255-ssh", s_cmp_ssh
},
146 { 256, 272, 0, LTC_PAD_SSH
| 16, "256-ssh", s_cmp_ssh
},
148 { 0, 16, 0, LTC_PAD_ONE_AND_ZERO
| 16, "0-one-and-zero", s_cmp_oaz
},
149 { 1, 16, 0, LTC_PAD_ONE_AND_ZERO
| 16, "1-one-and-zero", s_cmp_oaz
},
150 { 15, 16, 0, LTC_PAD_ONE_AND_ZERO
| 16, "15-one-and-zero", s_cmp_oaz
},
151 { 16, 32, 0, LTC_PAD_ONE_AND_ZERO
| 16, "16-one-and-zero", s_cmp_oaz
},
152 { 255, 256, 0, LTC_PAD_ONE_AND_ZERO
| 16, "255-one-and-zero", s_cmp_oaz
},
153 { 256, 272, 0, LTC_PAD_ONE_AND_ZERO
| 16, "256-one-and-zero", s_cmp_oaz
},
155 { 0, 0, 0, LTC_PAD_ZERO
| 16, "0-zero", s_cmp_zero
},
156 { 1, 16, 0, LTC_PAD_ZERO
| 16, "1-zero", s_cmp_zero
},
157 { 15, 16, 0, LTC_PAD_ZERO
| 16, "15-zero", s_cmp_zero
},
158 { 16, 16, 0, LTC_PAD_ZERO
| 16, "16-zero", s_cmp_zero
},
159 { 255, 256, 0, LTC_PAD_ZERO
| 16, "255-zero", s_cmp_zero
},
160 { 256, 256, 0, LTC_PAD_ZERO
| 16, "256-zero", s_cmp_zero
},
162 { 0, 16, 0, LTC_PAD_ZERO_ALWAYS
| 16, "0-zero-always", s_cmp_zero
},
163 { 1, 16, 0, LTC_PAD_ZERO_ALWAYS
| 16, "1-zero-always", s_cmp_zero
},
164 { 15, 16, 0, LTC_PAD_ZERO_ALWAYS
| 16, "15-zero-always", s_cmp_zero
},
165 { 16, 32, 0, LTC_PAD_ZERO_ALWAYS
| 16, "16-zero-always", s_cmp_zero
},
166 { 255, 256, 0, LTC_PAD_ZERO_ALWAYS
| 16, "255-zero-always", s_cmp_zero
},
167 { 256, 272, 0, LTC_PAD_ZERO_ALWAYS
| 16, "256-zero-always", s_cmp_zero
},
170 /* Examples from https://en.wikipedia.org/w/index.php?title=Padding_(cryptography)&oldid=823057951#Byte_padding */
172 unsigned char data
[16];
176 { { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x04, 0x04, 0x04, 0x04 }, 12, LTC_PAD_PKCS7
| 16 },
177 { { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x00, 0x00, 0x00, 0x04 }, 12, LTC_PAD_ANSI_X923
| 16 },
178 #ifdef LTC_RNG_GET_BYTES
179 { { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x81, 0xA6, 0x23, 0x04 }, 12, LTC_PAD_ISO_10126
| 16 },
181 { { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x80, 0x00, 0x00, 0x00 }, 12, LTC_PAD_ONE_AND_ZERO
| 16 },
182 { { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x80 }, 15, LTC_PAD_ONE_AND_ZERO
| 16 },
183 { { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x00, 0x00, 0x00, 0x00 }, 12, LTC_PAD_ZERO
| 16 },
185 /* we need a big buffer like that as LTC_PAD_ISO_10126
186 * is allowed to add 1-255 bytes of padding
188 unsigned char buf
[256 + 16];
191 for (i
= 0; i
< sizeof(cases
)/sizeof(cases
[0]); ++i
) {
192 DOX(s_padding_testrun(&cases
[i
]), cases
[i
].name
);
195 for (i
= 0; i
< sizeof(tv
)/sizeof(tv
[0]); ++i
) {
196 XMEMCPY(buf
, tv
[i
].data
, sizeof(tv
[i
].data
));
197 l
= sizeof(tv
[i
].data
);
198 DO(padding_depad(buf
, &l
, tv
[i
].mode
));
199 XMEMSET(buf
, 0xDD, 16);
201 DO(padding_pad(buf
, tv
[i
].len
, &l
, tv
[i
].mode
));
202 #ifdef LTC_RNG_GET_BYTES
203 if ((tv
[i
].mode
& LTC_PAD_MASK
) != LTC_PAD_ISO_10126
)
206 COMPARE_TESTVECTOR(tv
[i
].data
, sizeof(tv
[i
].data
), buf
, l
, "padding fixed TV", i
);
210 /* wycheproof failing test - https://github.com/libtom/libtomcrypt/pull/454 */
212 unsigned char data
[] = { 0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
213 unsigned long len
= sizeof(data
);
215 SHOULD_FAIL(padding_depad(data
, &len
, (LTC_PAD_PKCS7
| 16)));