Merge pull request #676 from hughsie/hughsie/sbom
[libtomcrypt.git] / tests / padding_test.c
blobb111cc848a9b6b18b7496953fbe315d3cfabcbda
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
4 #include <tomcrypt_test.h>
6 #ifdef LTC_PADDING
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;
14 const char* name;
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);
25 #else
26 LTC_UNUSED_PARAM(s_a);
27 LTC_UNUSED_PARAM(s_b);
28 #endif
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);
39 return CRYPT_OK;
42 #ifdef LTC_RNG_GET_BYTES
43 static int s_cmp_iso_10126(const padding_testcase* t, const unsigned char* p, unsigned long len)
45 LTC_UNUSED_PARAM(p);
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);
49 #endif
50 return CRYPT_FAIL_TESTVECTOR;
52 DOX(EQ(p[len - 1], len - t->is), t->name);
53 return CRYPT_OK;
55 #endif
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);
65 return CRYPT_OK;
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);
72 n = len - diff;
73 DOX(EQ(p[n], 0x80), t->name);
74 n++;
75 for (; n < len; ++n) {
76 DOX(EQ(p[n], 0x0), t->name);
78 return CRYPT_OK;
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);
88 return CRYPT_OK;
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);
98 pad++;
100 return CRYPT_OK;
103 static int s_padding_testrun(const padding_testcase* t)
105 unsigned long len;
106 unsigned char buf[1024];
108 len = sizeof(buf);
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));
113 DO(EQ(len, t->is));
114 return CRYPT_OK;
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 },
133 #endif
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 },
169 unsigned i;
170 /* Examples from https://en.wikipedia.org/w/index.php?title=Padding_(cryptography)&oldid=823057951#Byte_padding */
171 const struct {
172 unsigned char data[16];
173 unsigned long len;
174 unsigned long mode;
175 } tv[] = {
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 },
180 #endif
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];
189 unsigned long l;
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);
200 l = sizeof(buf);
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)
204 #endif
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)));
218 return CRYPT_OK;
220 #endif