blob: bceb2c273c7643c6e9982a3b38be75ad0962faf4 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Kees Cook3153e912013-08-16 07:59:11 -07002/*
3 * Copyright (c) 2013, The Chromium Authors
Kees Cook3153e912013-08-16 07:59:11 -07004 */
5
Kees Cook3153e912013-08-16 07:59:11 -07006#include <common.h>
Simon Glass6ed4dc72014-12-02 13:17:35 -07007#include <bootm.h>
Kees Cook3153e912013-08-16 07:59:11 -07008#include <command.h>
Simon Glass0c670fc2019-08-01 09:46:36 -06009#include <gzip.h>
Simon Glass4d72caa2020-05-10 11:40:01 -060010#include <image.h>
Simon Glass6c03f9e2019-11-14 12:57:25 -070011#include <lz4.h>
Kees Cook3153e912013-08-16 07:59:11 -070012#include <malloc.h>
Joe Hershberger0eb25b62015-03-22 17:08:59 -050013#include <mapmem.h>
Simon Glass6ed4dc72014-12-02 13:17:35 -070014#include <asm/io.h>
Kees Cook3153e912013-08-16 07:59:11 -070015
16#include <u-boot/zlib.h>
17#include <bzlib.h>
18
19#include <lzma/LzmaTypes.h>
20#include <lzma/LzmaDec.h>
21#include <lzma/LzmaTools.h>
22
23#include <linux/lzo.h>
Simon Glass0aac10f2017-11-25 11:57:33 -070024#include <test/compression.h>
25#include <test/suites.h>
26#include <test/ut.h>
Kees Cook3153e912013-08-16 07:59:11 -070027
28static const char plain[] =
29 "I am a highly compressable bit of text.\n"
30 "I am a highly compressable bit of text.\n"
31 "I am a highly compressable bit of text.\n"
32 "There are many like me, but this one is mine.\n"
33 "If I were any shorter, there wouldn't be much sense in\n"
34 "compressing me in the first place. At least with lzo, anyway,\n"
35 "which appears to behave poorly in the face of short text\n"
36 "messages.\n";
37
38/* bzip2 -c /tmp/plain.txt > /tmp/plain.bz2 */
39static const char bzip2_compressed[] =
40 "\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\xe5\x63\xdd\x09\x00\x00"
41 "\x28\x57\x80\x00\x10\x40\x85\x20\x20\x04\x00\x3f\xef\xdf\xf0\x30"
42 "\x00\xd6\xd0\x34\x91\x89\xa6\xf5\x4d\x19\x1a\x19\x0d\x02\x34\xd4"
43 "\xc9\x00\x34\x34\x00\x02\x48\x41\x35\x4f\xd4\xc6\x88\xd3\x50\x3d"
44 "\x4f\x51\x82\x4f\x88\xc3\x0d\x05\x62\x4f\x91\xa3\x52\x1b\xd0\x52"
45 "\x41\x4a\xa3\x98\xc2\x6b\xca\xa3\x82\xa5\xac\x8b\x15\x99\x68\xad"
46 "\xdf\x29\xd6\xf1\xf7\x5a\x10\xcd\x8c\x26\x61\x94\x95\xfe\x9e\x16"
47 "\x18\x28\x69\xd4\x23\x64\xcc\x2b\xe5\xe8\x5f\x00\xa4\x70\x26\x2c"
48 "\xee\xbd\x59\x6d\x6a\xec\xfc\x31\xda\x59\x0a\x14\x2a\x60\x1c\xf0"
49 "\x04\x86\x73\x9a\xc5\x5b\x87\x3f\x5b\x4c\x93\xe6\xb5\x35\x0d\xa6"
50 "\xb1\x2e\x62\x7b\xab\x67\xe7\x99\x2a\x14\x5e\x9f\x64\xcb\x96\xf4"
51 "\x0d\x65\xd4\x39\xe6\x8b\x7e\xea\x1c\x03\x69\x97\x83\x58\x91\x96"
52 "\xe1\xf0\x9d\xa4\x15\x8b\xb8\xc6\x93\xdc\x3d\xd9\x3c\x22\x55\xef"
53 "\xfb\xbb\x2a\xd3\x87\xa2\x8b\x04\xd9\x19\xf8\xe2\xfd\x4f\xdb\x1a"
54 "\x07\xc8\x60\xa3\x3f\xf8\xbb\x92\x29\xc2\x84\x87\x2b\x1e\xe8\x48";
55static const unsigned long bzip2_compressed_size = 240;
56
57/* lzma -z -c /tmp/plain.txt > /tmp/plain.lzma */
58static const char lzma_compressed[] =
59 "\x5d\x00\x00\x80\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x24\x88"
60 "\x08\x26\xd8\x41\xff\x99\xc8\xcf\x66\x3d\x80\xac\xba\x17\xf1\xc8"
61 "\xb9\xdf\x49\x37\xb1\x68\xa0\x2a\xdd\x63\xd1\xa7\xa3\x66\xf8\x15"
62 "\xef\xa6\x67\x8a\x14\x18\x80\xcb\xc7\xb1\xcb\x84\x6a\xb2\x51\x16"
63 "\xa1\x45\xa0\xd6\x3e\x55\x44\x8a\x5c\xa0\x7c\xe5\xa8\xbd\x04\x57"
64 "\x8f\x24\xfd\xb9\x34\x50\x83\x2f\xf3\x46\x3e\xb9\xb0\x00\x1a\xf5"
65 "\xd3\x86\x7e\x8f\x77\xd1\x5d\x0e\x7c\xe1\xac\xde\xf8\x65\x1f\x4d"
66 "\xce\x7f\xa7\x3d\xaa\xcf\x26\xa7\x58\x69\x1e\x4c\xea\x68\x8a\xe5"
67 "\x89\xd1\xdc\x4d\xc7\xe0\x07\x42\xbf\x0c\x9d\x06\xd7\x51\xa2\x0b"
68 "\x7c\x83\x35\xe1\x85\xdf\xee\xfb\xa3\xee\x2f\x47\x5f\x8b\x70\x2b"
69 "\xe1\x37\xf3\x16\xf6\x27\x54\x8a\x33\x72\x49\xea\x53\x7d\x60\x0b"
70 "\x21\x90\x66\xe7\x9e\x56\x61\x5d\xd8\xdc\x59\xf0\xac\x2f\xd6\x49"
71 "\x6b\x85\x40\x08\x1f\xdf\x26\x25\x3b\x72\x44\xb0\xb8\x21\x2f\xb3"
72 "\xd7\x9b\x24\x30\x78\x26\x44\x07\xc3\x33\xd1\x4d\x03\x1b\xe1\xff"
73 "\xfd\xf5\x50\x8d\xca";
74static const unsigned long lzma_compressed_size = 229;
75
76/* lzop -c /tmp/plain.txt > /tmp/plain.lzo */
77static const char lzo_compressed[] =
78 "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a\x10\x30\x20\x60\x09\x40\x01"
79 "\x05\x03\x00\x00\x09\x00\x00\x81\xb4\x52\x09\x54\xf1\x00\x00\x00"
80 "\x00\x09\x70\x6c\x61\x69\x6e\x2e\x74\x78\x74\x65\xb1\x07\x9c\x00"
81 "\x00\x01\x5e\x00\x00\x01\x0f\xc3\xc7\x7a\xe0\x00\x16\x49\x20\x61"
82 "\x6d\x20\x61\x20\x68\x69\x67\x68\x6c\x79\x20\x63\x6f\x6d\x70\x72"
83 "\x65\x73\x73\x61\x62\x6c\x65\x20\x62\x69\x74\x20\x6f\x66\x20\x74"
84 "\x65\x78\x74\x2e\x0a\x20\x2f\x9c\x00\x00\x22\x54\x68\x65\x72\x65"
85 "\x20\x61\x72\x65\x20\x6d\x61\x6e\x79\x20\x6c\x69\x6b\x65\x20\x6d"
86 "\x65\x2c\x20\x62\x75\x74\x20\x74\x68\x69\x73\x20\x6f\x6e\x65\x20"
87 "\x69\x73\x20\x6d\x69\x6e\x65\x2e\x0a\x49\x66\x20\x49\x20\x77\x84"
88 "\x06\x0a\x6e\x79\x20\x73\x68\x6f\x72\x74\x65\x72\x2c\x20\x74\x90"
89 "\x08\x00\x08\x77\x6f\x75\x6c\x64\x6e\x27\x74\x20\x62\x65\x20\x6d"
90 "\x75\x63\x68\x20\x73\x65\x6e\x73\x65\x20\x69\x6e\x0a\xf8\x19\x02"
91 "\x69\x6e\x67\x20\x6d\x64\x02\x64\x06\x00\x5a\x20\x66\x69\x72\x73"
92 "\x74\x20\x70\x6c\x61\x63\x65\x2e\x20\x41\x74\x20\x6c\x65\x61\x73"
93 "\x74\x20\x77\x69\x74\x68\x20\x6c\x7a\x6f\x2c\x20\x61\x6e\x79\x77"
94 "\x61\x79\x2c\x0a\x77\x68\x69\x63\x68\x20\x61\x70\x70\x65\x61\x72"
95 "\x73\x20\x74\x6f\x20\x62\x65\x68\x61\x76\x65\x20\x70\x6f\x6f\x72"
96 "\x6c\x79\x20\x69\x6e\x20\x74\x68\x65\x20\x66\x61\x63\x65\x20\x6f"
97 "\x66\x20\x73\x68\x6f\x72\x74\x20\x74\x65\x78\x74\x0a\x6d\x65\x73"
98 "\x73\x61\x67\x65\x73\x2e\x0a\x11\x00\x00\x00\x00\x00\x00";
99static const unsigned long lzo_compressed_size = 334;
100
Julius Werner027b7282015-10-06 20:03:53 -0700101/* lz4 -z /tmp/plain.txt > /tmp/plain.lz4 */
102static const char lz4_compressed[] =
103 "\x04\x22\x4d\x18\x64\x70\xb9\x01\x01\x00\x00\xff\x19\x49\x20\x61"
104 "\x6d\x20\x61\x20\x68\x69\x67\x68\x6c\x79\x20\x63\x6f\x6d\x70\x72"
105 "\x65\x73\x73\x61\x62\x6c\x65\x20\x62\x69\x74\x20\x6f\x66\x20\x74"
106 "\x65\x78\x74\x2e\x0a\x28\x00\x3d\xf1\x25\x54\x68\x65\x72\x65\x20"
107 "\x61\x72\x65\x20\x6d\x61\x6e\x79\x20\x6c\x69\x6b\x65\x20\x6d\x65"
108 "\x2c\x20\x62\x75\x74\x20\x74\x68\x69\x73\x20\x6f\x6e\x65\x20\x69"
109 "\x73\x20\x6d\x69\x6e\x65\x2e\x0a\x49\x66\x20\x49\x20\x77\x32\x00"
110 "\xd1\x6e\x79\x20\x73\x68\x6f\x72\x74\x65\x72\x2c\x20\x74\x45\x00"
111 "\xf4\x0b\x77\x6f\x75\x6c\x64\x6e\x27\x74\x20\x62\x65\x20\x6d\x75"
112 "\x63\x68\x20\x73\x65\x6e\x73\x65\x20\x69\x6e\x0a\xcf\x00\x50\x69"
113 "\x6e\x67\x20\x6d\x12\x00\x00\x32\x00\xf0\x11\x20\x66\x69\x72\x73"
114 "\x74\x20\x70\x6c\x61\x63\x65\x2e\x20\x41\x74\x20\x6c\x65\x61\x73"
115 "\x74\x20\x77\x69\x74\x68\x20\x6c\x7a\x6f\x2c\x63\x00\xf5\x14\x77"
116 "\x61\x79\x2c\x0a\x77\x68\x69\x63\x68\x20\x61\x70\x70\x65\x61\x72"
117 "\x73\x20\x74\x6f\x20\x62\x65\x68\x61\x76\x65\x20\x70\x6f\x6f\x72"
118 "\x6c\x79\x4e\x00\x30\x61\x63\x65\x27\x01\x01\x95\x00\x01\x2d\x01"
119 "\xb0\x0a\x6d\x65\x73\x73\x61\x67\x65\x73\x2e\x0a\x00\x00\x00\x00"
120 "\x9d\x12\x8c\x9d";
121static const unsigned long lz4_compressed_size = 276;
122
Kees Cook3153e912013-08-16 07:59:11 -0700123
124#define TEST_BUFFER_SIZE 512
125
Simon Glass0aac10f2017-11-25 11:57:33 -0700126typedef int (*mutate_func)(struct unit_test_state *uts, void *, unsigned long,
127 void *, unsigned long, unsigned long *);
Kees Cook3153e912013-08-16 07:59:11 -0700128
Simon Glass0aac10f2017-11-25 11:57:33 -0700129static int compress_using_gzip(struct unit_test_state *uts,
130 void *in, unsigned long in_size,
Kees Cook3153e912013-08-16 07:59:11 -0700131 void *out, unsigned long out_max,
132 unsigned long *out_size)
133{
134 int ret;
135 unsigned long inout_size = out_max;
136
137 ret = gzip(out, &inout_size, in, in_size);
138 if (out_size)
139 *out_size = inout_size;
140
141 return ret;
142}
143
Simon Glass0aac10f2017-11-25 11:57:33 -0700144static int uncompress_using_gzip(struct unit_test_state *uts,
145 void *in, unsigned long in_size,
Kees Cook3153e912013-08-16 07:59:11 -0700146 void *out, unsigned long out_max,
147 unsigned long *out_size)
148{
149 int ret;
150 unsigned long inout_size = in_size;
151
152 ret = gunzip(out, out_max, in, &inout_size);
153 if (out_size)
154 *out_size = inout_size;
155
156 return ret;
157}
158
Simon Glass0aac10f2017-11-25 11:57:33 -0700159static int compress_using_bzip2(struct unit_test_state *uts,
160 void *in, unsigned long in_size,
Wolfgang Denk93e14592013-10-04 17:43:24 +0200161 void *out, unsigned long out_max,
162 unsigned long *out_size)
Kees Cook3153e912013-08-16 07:59:11 -0700163{
164 /* There is no bzip2 compression in u-boot, so fake it. */
Simon Glass0aac10f2017-11-25 11:57:33 -0700165 ut_asserteq(in_size, strlen(plain));
166 ut_asserteq(0, memcmp(plain, in, in_size));
Kees Cook3153e912013-08-16 07:59:11 -0700167
168 if (bzip2_compressed_size > out_max)
169 return -1;
170
171 memcpy(out, bzip2_compressed, bzip2_compressed_size);
172 if (out_size)
173 *out_size = bzip2_compressed_size;
174
175 return 0;
176}
177
Simon Glass0aac10f2017-11-25 11:57:33 -0700178static int uncompress_using_bzip2(struct unit_test_state *uts,
179 void *in, unsigned long in_size,
Kees Cook3153e912013-08-16 07:59:11 -0700180 void *out, unsigned long out_max,
181 unsigned long *out_size)
182{
183 int ret;
184 unsigned int inout_size = out_max;
185
186 ret = BZ2_bzBuffToBuffDecompress(out, &inout_size, in, in_size,
187 CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
188 if (out_size)
189 *out_size = inout_size;
190
191 return (ret != BZ_OK);
192}
193
Simon Glass0aac10f2017-11-25 11:57:33 -0700194static int compress_using_lzma(struct unit_test_state *uts,
195 void *in, unsigned long in_size,
Kees Cook3153e912013-08-16 07:59:11 -0700196 void *out, unsigned long out_max,
197 unsigned long *out_size)
198{
199 /* There is no lzma compression in u-boot, so fake it. */
Simon Glass0aac10f2017-11-25 11:57:33 -0700200 ut_asserteq(in_size, strlen(plain));
201 ut_asserteq(0, memcmp(plain, in, in_size));
Kees Cook3153e912013-08-16 07:59:11 -0700202
203 if (lzma_compressed_size > out_max)
204 return -1;
205
206 memcpy(out, lzma_compressed, lzma_compressed_size);
207 if (out_size)
208 *out_size = lzma_compressed_size;
209
210 return 0;
211}
212
Simon Glass0aac10f2017-11-25 11:57:33 -0700213static int uncompress_using_lzma(struct unit_test_state *uts,
214 void *in, unsigned long in_size,
Kees Cook3153e912013-08-16 07:59:11 -0700215 void *out, unsigned long out_max,
216 unsigned long *out_size)
217{
218 int ret;
219 SizeT inout_size = out_max;
220
221 ret = lzmaBuffToBuffDecompress(out, &inout_size, in, in_size);
222 if (out_size)
223 *out_size = inout_size;
224
225 return (ret != SZ_OK);
226}
227
Simon Glass0aac10f2017-11-25 11:57:33 -0700228static int compress_using_lzo(struct unit_test_state *uts,
229 void *in, unsigned long in_size,
Kees Cook3153e912013-08-16 07:59:11 -0700230 void *out, unsigned long out_max,
231 unsigned long *out_size)
232{
233 /* There is no lzo compression in u-boot, so fake it. */
Simon Glass0aac10f2017-11-25 11:57:33 -0700234 ut_asserteq(in_size, strlen(plain));
235 ut_asserteq(0, memcmp(plain, in, in_size));
Kees Cook3153e912013-08-16 07:59:11 -0700236
237 if (lzo_compressed_size > out_max)
238 return -1;
239
240 memcpy(out, lzo_compressed, lzo_compressed_size);
241 if (out_size)
242 *out_size = lzo_compressed_size;
243
244 return 0;
245}
246
Simon Glass0aac10f2017-11-25 11:57:33 -0700247static int uncompress_using_lzo(struct unit_test_state *uts,
248 void *in, unsigned long in_size,
Kees Cook3153e912013-08-16 07:59:11 -0700249 void *out, unsigned long out_max,
250 unsigned long *out_size)
251{
252 int ret;
253 size_t input_size = in_size;
254 size_t output_size = out_max;
255
256 ret = lzop_decompress(in, input_size, out, &output_size);
257 if (out_size)
258 *out_size = output_size;
259
260 return (ret != LZO_E_OK);
261}
262
Simon Glass0aac10f2017-11-25 11:57:33 -0700263static int compress_using_lz4(struct unit_test_state *uts,
264 void *in, unsigned long in_size,
Julius Werner027b7282015-10-06 20:03:53 -0700265 void *out, unsigned long out_max,
266 unsigned long *out_size)
267{
268 /* There is no lz4 compression in u-boot, so fake it. */
Simon Glass0aac10f2017-11-25 11:57:33 -0700269 ut_asserteq(in_size, strlen(plain));
270 ut_asserteq(0, memcmp(plain, in, in_size));
Julius Werner027b7282015-10-06 20:03:53 -0700271
272 if (lz4_compressed_size > out_max)
273 return -1;
274
275 memcpy(out, lz4_compressed, lz4_compressed_size);
276 if (out_size)
277 *out_size = lz4_compressed_size;
278
279 return 0;
280}
281
Simon Glass0aac10f2017-11-25 11:57:33 -0700282static int uncompress_using_lz4(struct unit_test_state *uts,
283 void *in, unsigned long in_size,
Julius Werner027b7282015-10-06 20:03:53 -0700284 void *out, unsigned long out_max,
285 unsigned long *out_size)
286{
287 int ret;
288 size_t input_size = in_size;
289 size_t output_size = out_max;
290
291 ret = ulz4fn(in, input_size, out, &output_size);
292 if (out_size)
293 *out_size = output_size;
294
295 return (ret != 0);
296}
297
Kees Cook3153e912013-08-16 07:59:11 -0700298#define errcheck(statement) if (!(statement)) { \
299 fprintf(stderr, "\tFailed: %s\n", #statement); \
300 ret = 1; \
301 goto out; \
302}
303
Simon Glass49f22c32017-11-25 11:57:31 -0700304struct buf_state {
305 ulong orig_size;
306 ulong compressed_size;
307 ulong uncompressed_size;
Kees Cook3153e912013-08-16 07:59:11 -0700308 void *orig_buf;
Simon Glass49f22c32017-11-25 11:57:31 -0700309 void *compressed_buf;
310 void *uncompressed_buf;
311 void *compare_buf;
312};
313
Simon Glass0aac10f2017-11-25 11:57:33 -0700314static int run_test_internal(struct unit_test_state *uts, char *name,
Simon Glass49f22c32017-11-25 11:57:31 -0700315 mutate_func compress, mutate_func uncompress,
316 struct buf_state *buf)
317{
Kees Cook3153e912013-08-16 07:59:11 -0700318 int ret;
319
Kees Cook3153e912013-08-16 07:59:11 -0700320 /* Compress works as expected. */
Simon Glass49f22c32017-11-25 11:57:31 -0700321 printf("\torig_size:%lu\n", buf->orig_size);
322 memset(buf->compressed_buf, 'A', TEST_BUFFER_SIZE);
Simon Glass0aac10f2017-11-25 11:57:33 -0700323 errcheck(compress(uts, buf->orig_buf, buf->orig_size,
324 buf->compressed_buf, buf->compressed_size,
325 &buf->compressed_size) == 0);
Simon Glass49f22c32017-11-25 11:57:31 -0700326 printf("\tcompressed_size:%lu\n", buf->compressed_size);
327 errcheck(buf->compressed_size > 0);
328 errcheck(buf->compressed_size < buf->orig_size);
329 errcheck(((char *)buf->compressed_buf)[buf->compressed_size - 1] !=
330 'A');
331 errcheck(((char *)buf->compressed_buf)[buf->compressed_size] == 'A');
Kees Cook3153e912013-08-16 07:59:11 -0700332
333 /* Uncompresses with space remaining. */
Simon Glass0aac10f2017-11-25 11:57:33 -0700334 errcheck(uncompress(uts, buf->compressed_buf, buf->compressed_size,
Simon Glass49f22c32017-11-25 11:57:31 -0700335 buf->uncompressed_buf, buf->uncompressed_size,
336 &buf->uncompressed_size) == 0);
337 printf("\tuncompressed_size:%lu\n", buf->uncompressed_size);
338 errcheck(buf->uncompressed_size == buf->orig_size);
339 errcheck(memcmp(buf->orig_buf, buf->uncompressed_buf,
340 buf->orig_size) == 0);
Kees Cook3153e912013-08-16 07:59:11 -0700341
342 /* Uncompresses with exactly the right size output buffer. */
Simon Glass49f22c32017-11-25 11:57:31 -0700343 memset(buf->uncompressed_buf, 'A', TEST_BUFFER_SIZE);
Simon Glass0aac10f2017-11-25 11:57:33 -0700344 errcheck(uncompress(uts, buf->compressed_buf, buf->compressed_size,
Simon Glass49f22c32017-11-25 11:57:31 -0700345 buf->uncompressed_buf, buf->orig_size,
346 &buf->uncompressed_size) == 0);
347 errcheck(buf->uncompressed_size == buf->orig_size);
348 errcheck(memcmp(buf->orig_buf, buf->uncompressed_buf,
349 buf->orig_size) == 0);
350 errcheck(((char *)buf->uncompressed_buf)[buf->orig_size] == 'A');
Kees Cook3153e912013-08-16 07:59:11 -0700351
352 /* Make sure compression does not over-run. */
Simon Glass49f22c32017-11-25 11:57:31 -0700353 memset(buf->compare_buf, 'A', TEST_BUFFER_SIZE);
Simon Glass0aac10f2017-11-25 11:57:33 -0700354 ret = compress(uts, buf->orig_buf, buf->orig_size,
Simon Glass49f22c32017-11-25 11:57:31 -0700355 buf->compare_buf, buf->compressed_size - 1,
Kees Cook3153e912013-08-16 07:59:11 -0700356 NULL);
Simon Glass49f22c32017-11-25 11:57:31 -0700357 errcheck(((char *)buf->compare_buf)[buf->compressed_size] == 'A');
Kees Cook3153e912013-08-16 07:59:11 -0700358 errcheck(ret != 0);
359 printf("\tcompress does not overrun\n");
360
361 /* Make sure decompression does not over-run. */
Simon Glass49f22c32017-11-25 11:57:31 -0700362 memset(buf->compare_buf, 'A', TEST_BUFFER_SIZE);
Simon Glass0aac10f2017-11-25 11:57:33 -0700363 ret = uncompress(uts, buf->compressed_buf, buf->compressed_size,
Simon Glass49f22c32017-11-25 11:57:31 -0700364 buf->compare_buf, buf->uncompressed_size - 1,
Kees Cook3153e912013-08-16 07:59:11 -0700365 NULL);
Simon Glass49f22c32017-11-25 11:57:31 -0700366 errcheck(((char *)buf->compare_buf)[buf->uncompressed_size - 1] == 'A');
Kees Cook3153e912013-08-16 07:59:11 -0700367 errcheck(ret != 0);
368 printf("\tuncompress does not overrun\n");
369
370 /* Got here, everything is fine. */
371 ret = 0;
372
373out:
Simon Glass49f22c32017-11-25 11:57:31 -0700374 return ret;
375}
376
Simon Glass0aac10f2017-11-25 11:57:33 -0700377static int run_test(struct unit_test_state *uts, char *name,
378 mutate_func compress, mutate_func uncompress)
Simon Glass49f22c32017-11-25 11:57:31 -0700379{
380 struct buf_state sbuf, *buf = &sbuf;
381 int ret;
382
383 printf(" testing %s ...\n", name);
384
385 buf->orig_buf = (void *)plain;
386 buf->orig_size = strlen(buf->orig_buf); /* Trailing NUL not included */
387 errcheck(buf->orig_size > 0);
388
389 buf->compressed_size = TEST_BUFFER_SIZE;
390 buf->uncompressed_size = TEST_BUFFER_SIZE;
391 buf->compressed_buf = malloc(buf->compressed_size);
392 errcheck(buf->compressed_buf);
393 buf->uncompressed_buf = malloc(buf->uncompressed_size);
394 errcheck(buf->uncompressed_buf);
395 buf->compare_buf = malloc(buf->uncompressed_size);
396 errcheck(buf->compare_buf);
397
Simon Glass0aac10f2017-11-25 11:57:33 -0700398 ret = run_test_internal(uts, name, compress, uncompress, buf);
Simon Glass49f22c32017-11-25 11:57:31 -0700399out:
Kees Cook3153e912013-08-16 07:59:11 -0700400 printf(" %s: %s\n", name, ret == 0 ? "ok" : "FAILED");
401
Simon Glass49f22c32017-11-25 11:57:31 -0700402 free(buf->compare_buf);
403 free(buf->uncompressed_buf);
404 free(buf->compressed_buf);
Kees Cook3153e912013-08-16 07:59:11 -0700405
406 return ret;
407}
408
Simon Glass0aac10f2017-11-25 11:57:33 -0700409static int compression_test_gzip(struct unit_test_state *uts)
Kees Cook3153e912013-08-16 07:59:11 -0700410{
Simon Glass0aac10f2017-11-25 11:57:33 -0700411 return run_test(uts, "gzip", compress_using_gzip,
412 uncompress_using_gzip);
Kees Cook3153e912013-08-16 07:59:11 -0700413}
Simon Glass0aac10f2017-11-25 11:57:33 -0700414COMPRESSION_TEST(compression_test_gzip, 0);
Kees Cook3153e912013-08-16 07:59:11 -0700415
Simon Glass0aac10f2017-11-25 11:57:33 -0700416static int compression_test_bzip2(struct unit_test_state *uts)
417{
418 return run_test(uts, "bzip2", compress_using_bzip2,
419 uncompress_using_bzip2);
420}
421COMPRESSION_TEST(compression_test_bzip2, 0);
422
423static int compression_test_lzma(struct unit_test_state *uts)
424{
425 return run_test(uts, "lzma", compress_using_lzma,
426 uncompress_using_lzma);
427}
428COMPRESSION_TEST(compression_test_lzma, 0);
429
430static int compression_test_lzo(struct unit_test_state *uts)
431{
432 return run_test(uts, "lzo", compress_using_lzo, uncompress_using_lzo);
433}
434COMPRESSION_TEST(compression_test_lzo, 0);
435
436static int compression_test_lz4(struct unit_test_state *uts)
437{
438 return run_test(uts, "lz4", compress_using_lz4, uncompress_using_lz4);
439}
440COMPRESSION_TEST(compression_test_lz4, 0);
441
442static int compress_using_none(struct unit_test_state *uts,
443 void *in, unsigned long in_size,
Simon Glass6ed4dc72014-12-02 13:17:35 -0700444 void *out, unsigned long out_max,
445 unsigned long *out_size)
446{
447 /* Here we just copy */
448 memcpy(out, in, in_size);
449 *out_size = in_size;
450
451 return 0;
452}
453
454/**
Heinrich Schuchardt6cc8e542020-03-23 18:47:47 +0100455 * run_bootm_test() - Run tests on the bootm decompression function
Simon Glass6ed4dc72014-12-02 13:17:35 -0700456 *
457 * @comp_type: Compression type to test
458 * @compress: Our function to compress data
459 * @return 0 if OK, non-zero on failure
460 */
Simon Glass0aac10f2017-11-25 11:57:33 -0700461static int run_bootm_test(struct unit_test_state *uts, int comp_type,
462 mutate_func compress)
Simon Glass6ed4dc72014-12-02 13:17:35 -0700463{
464 ulong compress_size = 1024;
465 void *compress_buff;
466 int unc_len;
467 int err = 0;
468 const ulong image_start = 0;
469 const ulong load_addr = 0x1000;
470 ulong load_end;
471
472 printf("Testing: %s\n", genimg_get_comp_name(comp_type));
473 compress_buff = map_sysmem(image_start, 0);
474 unc_len = strlen(plain);
Simon Glass0aac10f2017-11-25 11:57:33 -0700475 compress(uts, (void *)plain, unc_len, compress_buff, compress_size,
Simon Glass6ed4dc72014-12-02 13:17:35 -0700476 &compress_size);
Julius Werner20908542019-07-24 19:37:54 -0700477 err = image_decomp(comp_type, load_addr, image_start,
478 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
479 compress_buff, compress_size, unc_len,
480 &load_end);
Simon Glass0aac10f2017-11-25 11:57:33 -0700481 ut_assertok(err);
Julius Werner20908542019-07-24 19:37:54 -0700482 err = image_decomp(comp_type, load_addr, image_start,
483 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
484 compress_buff, compress_size, unc_len - 1,
485 &load_end);
Simon Glass0aac10f2017-11-25 11:57:33 -0700486 ut_assert(err);
Simon Glass6ed4dc72014-12-02 13:17:35 -0700487
488 /* We can't detect corruption when not decompressing */
489 if (comp_type == IH_COMP_NONE)
490 return 0;
491 memset(compress_buff + compress_size / 2, '\x49',
492 compress_size / 2);
Julius Werner20908542019-07-24 19:37:54 -0700493 err = image_decomp(comp_type, load_addr, image_start,
494 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
495 compress_buff, compress_size, 0x10000,
496 &load_end);
Simon Glass0aac10f2017-11-25 11:57:33 -0700497 ut_assert(err);
Simon Glass6ed4dc72014-12-02 13:17:35 -0700498
499 return 0;
500}
501
Simon Glass0aac10f2017-11-25 11:57:33 -0700502static int compression_test_bootm_gzip(struct unit_test_state *uts)
Simon Glass6ed4dc72014-12-02 13:17:35 -0700503{
Simon Glass0aac10f2017-11-25 11:57:33 -0700504 return run_bootm_test(uts, IH_COMP_GZIP, compress_using_gzip);
Simon Glass6ed4dc72014-12-02 13:17:35 -0700505}
Simon Glass0aac10f2017-11-25 11:57:33 -0700506COMPRESSION_TEST(compression_test_bootm_gzip, 0);
Simon Glass6ed4dc72014-12-02 13:17:35 -0700507
Simon Glass0aac10f2017-11-25 11:57:33 -0700508static int compression_test_bootm_bzip2(struct unit_test_state *uts)
509{
510 return run_bootm_test(uts, IH_COMP_BZIP2, compress_using_bzip2);
511}
512COMPRESSION_TEST(compression_test_bootm_bzip2, 0);
Simon Glass6ed4dc72014-12-02 13:17:35 -0700513
Simon Glass0aac10f2017-11-25 11:57:33 -0700514static int compression_test_bootm_lzma(struct unit_test_state *uts)
515{
516 return run_bootm_test(uts, IH_COMP_LZMA, compress_using_lzma);
517}
518COMPRESSION_TEST(compression_test_bootm_lzma, 0);
519
520static int compression_test_bootm_lzo(struct unit_test_state *uts)
521{
522 return run_bootm_test(uts, IH_COMP_LZO, compress_using_lzo);
523}
524COMPRESSION_TEST(compression_test_bootm_lzo, 0);
525
526static int compression_test_bootm_lz4(struct unit_test_state *uts)
527{
528 return run_bootm_test(uts, IH_COMP_LZ4, compress_using_lz4);
529}
530COMPRESSION_TEST(compression_test_bootm_lz4, 0);
531
532static int compression_test_bootm_none(struct unit_test_state *uts)
533{
534 return run_bootm_test(uts, IH_COMP_NONE, compress_using_none);
535}
536COMPRESSION_TEST(compression_test_bootm_none, 0);
537
538int do_ut_compression(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
539{
540 struct unit_test *tests = ll_entry_start(struct unit_test,
541 compression_test);
542 const int n_ents = ll_entry_count(struct unit_test, compression_test);
543
Philippe Reynes4ad4edf2019-12-17 19:07:04 +0100544 return cmd_ut_category("compression", "compression_test_",
545 tests, n_ents, argc, argv);
Simon Glass0aac10f2017-11-25 11:57:33 -0700546}