blob: 48dccc0e891ba3734b6703559c3e1ce7ca5f61f3 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Kees Cook5d3bca82013-08-16 07:59:11 -07002/*
3 * Copyright (c) 2013, The Chromium Authors
Kees Cook5d3bca82013-08-16 07:59:11 -07004 */
5
Kees Cook5d3bca82013-08-16 07:59:11 -07006#include <common.h>
Simon Glass6d084ce2014-12-02 13:17:35 -07007#include <bootm.h>
Kees Cook5d3bca82013-08-16 07:59:11 -07008#include <command.h>
Simon Glass1a974af2019-08-01 09:46:36 -06009#include <gzip.h>
Simon Glasse1aba1e2019-11-14 12:57:25 -070010#include <lz4.h>
Kees Cook5d3bca82013-08-16 07:59:11 -070011#include <malloc.h>
Joe Hershberger65b905b2015-03-22 17:08:59 -050012#include <mapmem.h>
Simon Glass6d084ce2014-12-02 13:17:35 -070013#include <asm/io.h>
Kees Cook5d3bca82013-08-16 07:59:11 -070014
15#include <u-boot/zlib.h>
16#include <bzlib.h>
17
18#include <lzma/LzmaTypes.h>
19#include <lzma/LzmaDec.h>
20#include <lzma/LzmaTools.h>
21
22#include <linux/lzo.h>
Simon Glass1edaed02017-11-25 11:57:33 -070023#include <test/compression.h>
24#include <test/suites.h>
25#include <test/ut.h>
Kees Cook5d3bca82013-08-16 07:59:11 -070026
27static const char plain[] =
28 "I am a highly compressable bit of text.\n"
29 "I am a highly compressable bit of text.\n"
30 "I am a highly compressable bit of text.\n"
31 "There are many like me, but this one is mine.\n"
32 "If I were any shorter, there wouldn't be much sense in\n"
33 "compressing me in the first place. At least with lzo, anyway,\n"
34 "which appears to behave poorly in the face of short text\n"
35 "messages.\n";
36
37/* bzip2 -c /tmp/plain.txt > /tmp/plain.bz2 */
38static const char bzip2_compressed[] =
39 "\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\xe5\x63\xdd\x09\x00\x00"
40 "\x28\x57\x80\x00\x10\x40\x85\x20\x20\x04\x00\x3f\xef\xdf\xf0\x30"
41 "\x00\xd6\xd0\x34\x91\x89\xa6\xf5\x4d\x19\x1a\x19\x0d\x02\x34\xd4"
42 "\xc9\x00\x34\x34\x00\x02\x48\x41\x35\x4f\xd4\xc6\x88\xd3\x50\x3d"
43 "\x4f\x51\x82\x4f\x88\xc3\x0d\x05\x62\x4f\x91\xa3\x52\x1b\xd0\x52"
44 "\x41\x4a\xa3\x98\xc2\x6b\xca\xa3\x82\xa5\xac\x8b\x15\x99\x68\xad"
45 "\xdf\x29\xd6\xf1\xf7\x5a\x10\xcd\x8c\x26\x61\x94\x95\xfe\x9e\x16"
46 "\x18\x28\x69\xd4\x23\x64\xcc\x2b\xe5\xe8\x5f\x00\xa4\x70\x26\x2c"
47 "\xee\xbd\x59\x6d\x6a\xec\xfc\x31\xda\x59\x0a\x14\x2a\x60\x1c\xf0"
48 "\x04\x86\x73\x9a\xc5\x5b\x87\x3f\x5b\x4c\x93\xe6\xb5\x35\x0d\xa6"
49 "\xb1\x2e\x62\x7b\xab\x67\xe7\x99\x2a\x14\x5e\x9f\x64\xcb\x96\xf4"
50 "\x0d\x65\xd4\x39\xe6\x8b\x7e\xea\x1c\x03\x69\x97\x83\x58\x91\x96"
51 "\xe1\xf0\x9d\xa4\x15\x8b\xb8\xc6\x93\xdc\x3d\xd9\x3c\x22\x55\xef"
52 "\xfb\xbb\x2a\xd3\x87\xa2\x8b\x04\xd9\x19\xf8\xe2\xfd\x4f\xdb\x1a"
53 "\x07\xc8\x60\xa3\x3f\xf8\xbb\x92\x29\xc2\x84\x87\x2b\x1e\xe8\x48";
54static const unsigned long bzip2_compressed_size = 240;
55
56/* lzma -z -c /tmp/plain.txt > /tmp/plain.lzma */
57static const char lzma_compressed[] =
58 "\x5d\x00\x00\x80\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x24\x88"
59 "\x08\x26\xd8\x41\xff\x99\xc8\xcf\x66\x3d\x80\xac\xba\x17\xf1\xc8"
60 "\xb9\xdf\x49\x37\xb1\x68\xa0\x2a\xdd\x63\xd1\xa7\xa3\x66\xf8\x15"
61 "\xef\xa6\x67\x8a\x14\x18\x80\xcb\xc7\xb1\xcb\x84\x6a\xb2\x51\x16"
62 "\xa1\x45\xa0\xd6\x3e\x55\x44\x8a\x5c\xa0\x7c\xe5\xa8\xbd\x04\x57"
63 "\x8f\x24\xfd\xb9\x34\x50\x83\x2f\xf3\x46\x3e\xb9\xb0\x00\x1a\xf5"
64 "\xd3\x86\x7e\x8f\x77\xd1\x5d\x0e\x7c\xe1\xac\xde\xf8\x65\x1f\x4d"
65 "\xce\x7f\xa7\x3d\xaa\xcf\x26\xa7\x58\x69\x1e\x4c\xea\x68\x8a\xe5"
66 "\x89\xd1\xdc\x4d\xc7\xe0\x07\x42\xbf\x0c\x9d\x06\xd7\x51\xa2\x0b"
67 "\x7c\x83\x35\xe1\x85\xdf\xee\xfb\xa3\xee\x2f\x47\x5f\x8b\x70\x2b"
68 "\xe1\x37\xf3\x16\xf6\x27\x54\x8a\x33\x72\x49\xea\x53\x7d\x60\x0b"
69 "\x21\x90\x66\xe7\x9e\x56\x61\x5d\xd8\xdc\x59\xf0\xac\x2f\xd6\x49"
70 "\x6b\x85\x40\x08\x1f\xdf\x26\x25\x3b\x72\x44\xb0\xb8\x21\x2f\xb3"
71 "\xd7\x9b\x24\x30\x78\x26\x44\x07\xc3\x33\xd1\x4d\x03\x1b\xe1\xff"
72 "\xfd\xf5\x50\x8d\xca";
73static const unsigned long lzma_compressed_size = 229;
74
75/* lzop -c /tmp/plain.txt > /tmp/plain.lzo */
76static const char lzo_compressed[] =
77 "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a\x10\x30\x20\x60\x09\x40\x01"
78 "\x05\x03\x00\x00\x09\x00\x00\x81\xb4\x52\x09\x54\xf1\x00\x00\x00"
79 "\x00\x09\x70\x6c\x61\x69\x6e\x2e\x74\x78\x74\x65\xb1\x07\x9c\x00"
80 "\x00\x01\x5e\x00\x00\x01\x0f\xc3\xc7\x7a\xe0\x00\x16\x49\x20\x61"
81 "\x6d\x20\x61\x20\x68\x69\x67\x68\x6c\x79\x20\x63\x6f\x6d\x70\x72"
82 "\x65\x73\x73\x61\x62\x6c\x65\x20\x62\x69\x74\x20\x6f\x66\x20\x74"
83 "\x65\x78\x74\x2e\x0a\x20\x2f\x9c\x00\x00\x22\x54\x68\x65\x72\x65"
84 "\x20\x61\x72\x65\x20\x6d\x61\x6e\x79\x20\x6c\x69\x6b\x65\x20\x6d"
85 "\x65\x2c\x20\x62\x75\x74\x20\x74\x68\x69\x73\x20\x6f\x6e\x65\x20"
86 "\x69\x73\x20\x6d\x69\x6e\x65\x2e\x0a\x49\x66\x20\x49\x20\x77\x84"
87 "\x06\x0a\x6e\x79\x20\x73\x68\x6f\x72\x74\x65\x72\x2c\x20\x74\x90"
88 "\x08\x00\x08\x77\x6f\x75\x6c\x64\x6e\x27\x74\x20\x62\x65\x20\x6d"
89 "\x75\x63\x68\x20\x73\x65\x6e\x73\x65\x20\x69\x6e\x0a\xf8\x19\x02"
90 "\x69\x6e\x67\x20\x6d\x64\x02\x64\x06\x00\x5a\x20\x66\x69\x72\x73"
91 "\x74\x20\x70\x6c\x61\x63\x65\x2e\x20\x41\x74\x20\x6c\x65\x61\x73"
92 "\x74\x20\x77\x69\x74\x68\x20\x6c\x7a\x6f\x2c\x20\x61\x6e\x79\x77"
93 "\x61\x79\x2c\x0a\x77\x68\x69\x63\x68\x20\x61\x70\x70\x65\x61\x72"
94 "\x73\x20\x74\x6f\x20\x62\x65\x68\x61\x76\x65\x20\x70\x6f\x6f\x72"
95 "\x6c\x79\x20\x69\x6e\x20\x74\x68\x65\x20\x66\x61\x63\x65\x20\x6f"
96 "\x66\x20\x73\x68\x6f\x72\x74\x20\x74\x65\x78\x74\x0a\x6d\x65\x73"
97 "\x73\x61\x67\x65\x73\x2e\x0a\x11\x00\x00\x00\x00\x00\x00";
98static const unsigned long lzo_compressed_size = 334;
99
Julius Wernerf41a3ca2015-10-06 20:03:53 -0700100/* lz4 -z /tmp/plain.txt > /tmp/plain.lz4 */
101static const char lz4_compressed[] =
102 "\x04\x22\x4d\x18\x64\x70\xb9\x01\x01\x00\x00\xff\x19\x49\x20\x61"
103 "\x6d\x20\x61\x20\x68\x69\x67\x68\x6c\x79\x20\x63\x6f\x6d\x70\x72"
104 "\x65\x73\x73\x61\x62\x6c\x65\x20\x62\x69\x74\x20\x6f\x66\x20\x74"
105 "\x65\x78\x74\x2e\x0a\x28\x00\x3d\xf1\x25\x54\x68\x65\x72\x65\x20"
106 "\x61\x72\x65\x20\x6d\x61\x6e\x79\x20\x6c\x69\x6b\x65\x20\x6d\x65"
107 "\x2c\x20\x62\x75\x74\x20\x74\x68\x69\x73\x20\x6f\x6e\x65\x20\x69"
108 "\x73\x20\x6d\x69\x6e\x65\x2e\x0a\x49\x66\x20\x49\x20\x77\x32\x00"
109 "\xd1\x6e\x79\x20\x73\x68\x6f\x72\x74\x65\x72\x2c\x20\x74\x45\x00"
110 "\xf4\x0b\x77\x6f\x75\x6c\x64\x6e\x27\x74\x20\x62\x65\x20\x6d\x75"
111 "\x63\x68\x20\x73\x65\x6e\x73\x65\x20\x69\x6e\x0a\xcf\x00\x50\x69"
112 "\x6e\x67\x20\x6d\x12\x00\x00\x32\x00\xf0\x11\x20\x66\x69\x72\x73"
113 "\x74\x20\x70\x6c\x61\x63\x65\x2e\x20\x41\x74\x20\x6c\x65\x61\x73"
114 "\x74\x20\x77\x69\x74\x68\x20\x6c\x7a\x6f\x2c\x63\x00\xf5\x14\x77"
115 "\x61\x79\x2c\x0a\x77\x68\x69\x63\x68\x20\x61\x70\x70\x65\x61\x72"
116 "\x73\x20\x74\x6f\x20\x62\x65\x68\x61\x76\x65\x20\x70\x6f\x6f\x72"
117 "\x6c\x79\x4e\x00\x30\x61\x63\x65\x27\x01\x01\x95\x00\x01\x2d\x01"
118 "\xb0\x0a\x6d\x65\x73\x73\x61\x67\x65\x73\x2e\x0a\x00\x00\x00\x00"
119 "\x9d\x12\x8c\x9d";
120static const unsigned long lz4_compressed_size = 276;
121
Kees Cook5d3bca82013-08-16 07:59:11 -0700122
123#define TEST_BUFFER_SIZE 512
124
Simon Glass1edaed02017-11-25 11:57:33 -0700125typedef int (*mutate_func)(struct unit_test_state *uts, void *, unsigned long,
126 void *, unsigned long, unsigned long *);
Kees Cook5d3bca82013-08-16 07:59:11 -0700127
Simon Glass1edaed02017-11-25 11:57:33 -0700128static int compress_using_gzip(struct unit_test_state *uts,
129 void *in, unsigned long in_size,
Kees Cook5d3bca82013-08-16 07:59:11 -0700130 void *out, unsigned long out_max,
131 unsigned long *out_size)
132{
133 int ret;
134 unsigned long inout_size = out_max;
135
136 ret = gzip(out, &inout_size, in, in_size);
137 if (out_size)
138 *out_size = inout_size;
139
140 return ret;
141}
142
Simon Glass1edaed02017-11-25 11:57:33 -0700143static int uncompress_using_gzip(struct unit_test_state *uts,
144 void *in, unsigned long in_size,
Kees Cook5d3bca82013-08-16 07:59:11 -0700145 void *out, unsigned long out_max,
146 unsigned long *out_size)
147{
148 int ret;
149 unsigned long inout_size = in_size;
150
151 ret = gunzip(out, out_max, in, &inout_size);
152 if (out_size)
153 *out_size = inout_size;
154
155 return ret;
156}
157
Simon Glass1edaed02017-11-25 11:57:33 -0700158static int compress_using_bzip2(struct unit_test_state *uts,
159 void *in, unsigned long in_size,
Wolfgang Denkec7fbf52013-10-04 17:43:24 +0200160 void *out, unsigned long out_max,
161 unsigned long *out_size)
Kees Cook5d3bca82013-08-16 07:59:11 -0700162{
163 /* There is no bzip2 compression in u-boot, so fake it. */
Simon Glass1edaed02017-11-25 11:57:33 -0700164 ut_asserteq(in_size, strlen(plain));
165 ut_asserteq(0, memcmp(plain, in, in_size));
Kees Cook5d3bca82013-08-16 07:59:11 -0700166
167 if (bzip2_compressed_size > out_max)
168 return -1;
169
170 memcpy(out, bzip2_compressed, bzip2_compressed_size);
171 if (out_size)
172 *out_size = bzip2_compressed_size;
173
174 return 0;
175}
176
Simon Glass1edaed02017-11-25 11:57:33 -0700177static int uncompress_using_bzip2(struct unit_test_state *uts,
178 void *in, unsigned long in_size,
Kees Cook5d3bca82013-08-16 07:59:11 -0700179 void *out, unsigned long out_max,
180 unsigned long *out_size)
181{
182 int ret;
183 unsigned int inout_size = out_max;
184
185 ret = BZ2_bzBuffToBuffDecompress(out, &inout_size, in, in_size,
186 CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
187 if (out_size)
188 *out_size = inout_size;
189
190 return (ret != BZ_OK);
191}
192
Simon Glass1edaed02017-11-25 11:57:33 -0700193static int compress_using_lzma(struct unit_test_state *uts,
194 void *in, unsigned long in_size,
Kees Cook5d3bca82013-08-16 07:59:11 -0700195 void *out, unsigned long out_max,
196 unsigned long *out_size)
197{
198 /* There is no lzma compression in u-boot, so fake it. */
Simon Glass1edaed02017-11-25 11:57:33 -0700199 ut_asserteq(in_size, strlen(plain));
200 ut_asserteq(0, memcmp(plain, in, in_size));
Kees Cook5d3bca82013-08-16 07:59:11 -0700201
202 if (lzma_compressed_size > out_max)
203 return -1;
204
205 memcpy(out, lzma_compressed, lzma_compressed_size);
206 if (out_size)
207 *out_size = lzma_compressed_size;
208
209 return 0;
210}
211
Simon Glass1edaed02017-11-25 11:57:33 -0700212static int uncompress_using_lzma(struct unit_test_state *uts,
213 void *in, unsigned long in_size,
Kees Cook5d3bca82013-08-16 07:59:11 -0700214 void *out, unsigned long out_max,
215 unsigned long *out_size)
216{
217 int ret;
218 SizeT inout_size = out_max;
219
220 ret = lzmaBuffToBuffDecompress(out, &inout_size, in, in_size);
221 if (out_size)
222 *out_size = inout_size;
223
224 return (ret != SZ_OK);
225}
226
Simon Glass1edaed02017-11-25 11:57:33 -0700227static int compress_using_lzo(struct unit_test_state *uts,
228 void *in, unsigned long in_size,
Kees Cook5d3bca82013-08-16 07:59:11 -0700229 void *out, unsigned long out_max,
230 unsigned long *out_size)
231{
232 /* There is no lzo compression in u-boot, so fake it. */
Simon Glass1edaed02017-11-25 11:57:33 -0700233 ut_asserteq(in_size, strlen(plain));
234 ut_asserteq(0, memcmp(plain, in, in_size));
Kees Cook5d3bca82013-08-16 07:59:11 -0700235
236 if (lzo_compressed_size > out_max)
237 return -1;
238
239 memcpy(out, lzo_compressed, lzo_compressed_size);
240 if (out_size)
241 *out_size = lzo_compressed_size;
242
243 return 0;
244}
245
Simon Glass1edaed02017-11-25 11:57:33 -0700246static int uncompress_using_lzo(struct unit_test_state *uts,
247 void *in, unsigned long in_size,
Kees Cook5d3bca82013-08-16 07:59:11 -0700248 void *out, unsigned long out_max,
249 unsigned long *out_size)
250{
251 int ret;
252 size_t input_size = in_size;
253 size_t output_size = out_max;
254
255 ret = lzop_decompress(in, input_size, out, &output_size);
256 if (out_size)
257 *out_size = output_size;
258
259 return (ret != LZO_E_OK);
260}
261
Simon Glass1edaed02017-11-25 11:57:33 -0700262static int compress_using_lz4(struct unit_test_state *uts,
263 void *in, unsigned long in_size,
Julius Wernerf41a3ca2015-10-06 20:03:53 -0700264 void *out, unsigned long out_max,
265 unsigned long *out_size)
266{
267 /* There is no lz4 compression in u-boot, so fake it. */
Simon Glass1edaed02017-11-25 11:57:33 -0700268 ut_asserteq(in_size, strlen(plain));
269 ut_asserteq(0, memcmp(plain, in, in_size));
Julius Wernerf41a3ca2015-10-06 20:03:53 -0700270
271 if (lz4_compressed_size > out_max)
272 return -1;
273
274 memcpy(out, lz4_compressed, lz4_compressed_size);
275 if (out_size)
276 *out_size = lz4_compressed_size;
277
278 return 0;
279}
280
Simon Glass1edaed02017-11-25 11:57:33 -0700281static int uncompress_using_lz4(struct unit_test_state *uts,
282 void *in, unsigned long in_size,
Julius Wernerf41a3ca2015-10-06 20:03:53 -0700283 void *out, unsigned long out_max,
284 unsigned long *out_size)
285{
286 int ret;
287 size_t input_size = in_size;
288 size_t output_size = out_max;
289
290 ret = ulz4fn(in, input_size, out, &output_size);
291 if (out_size)
292 *out_size = output_size;
293
294 return (ret != 0);
295}
296
Kees Cook5d3bca82013-08-16 07:59:11 -0700297#define errcheck(statement) if (!(statement)) { \
298 fprintf(stderr, "\tFailed: %s\n", #statement); \
299 ret = 1; \
300 goto out; \
301}
302
Simon Glass053f8012017-11-25 11:57:31 -0700303struct buf_state {
304 ulong orig_size;
305 ulong compressed_size;
306 ulong uncompressed_size;
Kees Cook5d3bca82013-08-16 07:59:11 -0700307 void *orig_buf;
Simon Glass053f8012017-11-25 11:57:31 -0700308 void *compressed_buf;
309 void *uncompressed_buf;
310 void *compare_buf;
311};
Kees Cook5d3bca82013-08-16 07:59:11 -0700312
Simon Glass1edaed02017-11-25 11:57:33 -0700313static int run_test_internal(struct unit_test_state *uts, char *name,
Simon Glass053f8012017-11-25 11:57:31 -0700314 mutate_func compress, mutate_func uncompress,
315 struct buf_state *buf)
316{
317 int ret;
Kees Cook5d3bca82013-08-16 07:59:11 -0700318
319 /* Compress works as expected. */
Simon Glass053f8012017-11-25 11:57:31 -0700320 printf("\torig_size:%lu\n", buf->orig_size);
321 memset(buf->compressed_buf, 'A', TEST_BUFFER_SIZE);
Simon Glass1edaed02017-11-25 11:57:33 -0700322 errcheck(compress(uts, buf->orig_buf, buf->orig_size,
323 buf->compressed_buf, buf->compressed_size,
324 &buf->compressed_size) == 0);
Simon Glass053f8012017-11-25 11:57:31 -0700325 printf("\tcompressed_size:%lu\n", buf->compressed_size);
326 errcheck(buf->compressed_size > 0);
327 errcheck(buf->compressed_size < buf->orig_size);
328 errcheck(((char *)buf->compressed_buf)[buf->compressed_size - 1] !=
329 'A');
330 errcheck(((char *)buf->compressed_buf)[buf->compressed_size] == 'A');
Kees Cook5d3bca82013-08-16 07:59:11 -0700331
332 /* Uncompresses with space remaining. */
Simon Glass1edaed02017-11-25 11:57:33 -0700333 errcheck(uncompress(uts, buf->compressed_buf, buf->compressed_size,
Simon Glass053f8012017-11-25 11:57:31 -0700334 buf->uncompressed_buf, buf->uncompressed_size,
335 &buf->uncompressed_size) == 0);
336 printf("\tuncompressed_size:%lu\n", buf->uncompressed_size);
337 errcheck(buf->uncompressed_size == buf->orig_size);
338 errcheck(memcmp(buf->orig_buf, buf->uncompressed_buf,
339 buf->orig_size) == 0);
Kees Cook5d3bca82013-08-16 07:59:11 -0700340
341 /* Uncompresses with exactly the right size output buffer. */
Simon Glass053f8012017-11-25 11:57:31 -0700342 memset(buf->uncompressed_buf, 'A', TEST_BUFFER_SIZE);
Simon Glass1edaed02017-11-25 11:57:33 -0700343 errcheck(uncompress(uts, buf->compressed_buf, buf->compressed_size,
Simon Glass053f8012017-11-25 11:57:31 -0700344 buf->uncompressed_buf, buf->orig_size,
345 &buf->uncompressed_size) == 0);
346 errcheck(buf->uncompressed_size == buf->orig_size);
347 errcheck(memcmp(buf->orig_buf, buf->uncompressed_buf,
348 buf->orig_size) == 0);
349 errcheck(((char *)buf->uncompressed_buf)[buf->orig_size] == 'A');
Kees Cook5d3bca82013-08-16 07:59:11 -0700350
351 /* Make sure compression does not over-run. */
Simon Glass053f8012017-11-25 11:57:31 -0700352 memset(buf->compare_buf, 'A', TEST_BUFFER_SIZE);
Simon Glass1edaed02017-11-25 11:57:33 -0700353 ret = compress(uts, buf->orig_buf, buf->orig_size,
Simon Glass053f8012017-11-25 11:57:31 -0700354 buf->compare_buf, buf->compressed_size - 1,
Kees Cook5d3bca82013-08-16 07:59:11 -0700355 NULL);
Simon Glass053f8012017-11-25 11:57:31 -0700356 errcheck(((char *)buf->compare_buf)[buf->compressed_size] == 'A');
Kees Cook5d3bca82013-08-16 07:59:11 -0700357 errcheck(ret != 0);
358 printf("\tcompress does not overrun\n");
359
360 /* Make sure decompression does not over-run. */
Simon Glass053f8012017-11-25 11:57:31 -0700361 memset(buf->compare_buf, 'A', TEST_BUFFER_SIZE);
Simon Glass1edaed02017-11-25 11:57:33 -0700362 ret = uncompress(uts, buf->compressed_buf, buf->compressed_size,
Simon Glass053f8012017-11-25 11:57:31 -0700363 buf->compare_buf, buf->uncompressed_size - 1,
Kees Cook5d3bca82013-08-16 07:59:11 -0700364 NULL);
Simon Glass053f8012017-11-25 11:57:31 -0700365 errcheck(((char *)buf->compare_buf)[buf->uncompressed_size - 1] == 'A');
Kees Cook5d3bca82013-08-16 07:59:11 -0700366 errcheck(ret != 0);
367 printf("\tuncompress does not overrun\n");
368
369 /* Got here, everything is fine. */
370 ret = 0;
371
Simon Glass053f8012017-11-25 11:57:31 -0700372out:
373 return ret;
374}
375
Simon Glass1edaed02017-11-25 11:57:33 -0700376static int run_test(struct unit_test_state *uts, char *name,
377 mutate_func compress, mutate_func uncompress)
Simon Glass053f8012017-11-25 11:57:31 -0700378{
379 struct buf_state sbuf, *buf = &sbuf;
380 int ret;
381
382 printf(" testing %s ...\n", name);
383
384 buf->orig_buf = (void *)plain;
385 buf->orig_size = strlen(buf->orig_buf); /* Trailing NUL not included */
386 errcheck(buf->orig_size > 0);
387
388 buf->compressed_size = TEST_BUFFER_SIZE;
389 buf->uncompressed_size = TEST_BUFFER_SIZE;
390 buf->compressed_buf = malloc(buf->compressed_size);
391 errcheck(buf->compressed_buf);
392 buf->uncompressed_buf = malloc(buf->uncompressed_size);
393 errcheck(buf->uncompressed_buf);
394 buf->compare_buf = malloc(buf->uncompressed_size);
395 errcheck(buf->compare_buf);
396
Simon Glass1edaed02017-11-25 11:57:33 -0700397 ret = run_test_internal(uts, name, compress, uncompress, buf);
Kees Cook5d3bca82013-08-16 07:59:11 -0700398out:
399 printf(" %s: %s\n", name, ret == 0 ? "ok" : "FAILED");
400
Simon Glass053f8012017-11-25 11:57:31 -0700401 free(buf->compare_buf);
402 free(buf->uncompressed_buf);
403 free(buf->compressed_buf);
Kees Cook5d3bca82013-08-16 07:59:11 -0700404
405 return ret;
406}
407
Simon Glass1edaed02017-11-25 11:57:33 -0700408static int compression_test_gzip(struct unit_test_state *uts)
Kees Cook5d3bca82013-08-16 07:59:11 -0700409{
Simon Glass1edaed02017-11-25 11:57:33 -0700410 return run_test(uts, "gzip", compress_using_gzip,
411 uncompress_using_gzip);
412}
413COMPRESSION_TEST(compression_test_gzip, 0);
Kees Cook5d3bca82013-08-16 07:59:11 -0700414
Simon Glass1edaed02017-11-25 11:57:33 -0700415static int compression_test_bzip2(struct unit_test_state *uts)
416{
417 return run_test(uts, "bzip2", compress_using_bzip2,
418 uncompress_using_bzip2);
419}
420COMPRESSION_TEST(compression_test_bzip2, 0);
421
422static int compression_test_lzma(struct unit_test_state *uts)
423{
424 return run_test(uts, "lzma", compress_using_lzma,
425 uncompress_using_lzma);
426}
427COMPRESSION_TEST(compression_test_lzma, 0);
Kees Cook5d3bca82013-08-16 07:59:11 -0700428
Simon Glass1edaed02017-11-25 11:57:33 -0700429static int compression_test_lzo(struct unit_test_state *uts)
430{
431 return run_test(uts, "lzo", compress_using_lzo, uncompress_using_lzo);
432}
433COMPRESSION_TEST(compression_test_lzo, 0);
Kees Cook5d3bca82013-08-16 07:59:11 -0700434
Simon Glass1edaed02017-11-25 11:57:33 -0700435static int compression_test_lz4(struct unit_test_state *uts)
436{
437 return run_test(uts, "lz4", compress_using_lz4, uncompress_using_lz4);
Kees Cook5d3bca82013-08-16 07:59:11 -0700438}
Simon Glass1edaed02017-11-25 11:57:33 -0700439COMPRESSION_TEST(compression_test_lz4, 0);
Kees Cook5d3bca82013-08-16 07:59:11 -0700440
Simon Glass1edaed02017-11-25 11:57:33 -0700441static int compress_using_none(struct unit_test_state *uts,
442 void *in, unsigned long in_size,
Simon Glass6d084ce2014-12-02 13:17:35 -0700443 void *out, unsigned long out_max,
444 unsigned long *out_size)
445{
446 /* Here we just copy */
447 memcpy(out, in, in_size);
448 *out_size = in_size;
449
450 return 0;
451}
452
453/**
454 * run_bootm_test() - Run tests on the bootm decopmression function
455 *
456 * @comp_type: Compression type to test
457 * @compress: Our function to compress data
458 * @return 0 if OK, non-zero on failure
459 */
Simon Glass1edaed02017-11-25 11:57:33 -0700460static int run_bootm_test(struct unit_test_state *uts, int comp_type,
461 mutate_func compress)
Simon Glass6d084ce2014-12-02 13:17:35 -0700462{
463 ulong compress_size = 1024;
464 void *compress_buff;
465 int unc_len;
466 int err = 0;
467 const ulong image_start = 0;
468 const ulong load_addr = 0x1000;
469 ulong load_end;
470
471 printf("Testing: %s\n", genimg_get_comp_name(comp_type));
472 compress_buff = map_sysmem(image_start, 0);
473 unc_len = strlen(plain);
Simon Glass1edaed02017-11-25 11:57:33 -0700474 compress(uts, (void *)plain, unc_len, compress_buff, compress_size,
Simon Glass6d084ce2014-12-02 13:17:35 -0700475 &compress_size);
Julius Werner47ef9862019-07-24 19:37:54 -0700476 err = image_decomp(comp_type, load_addr, image_start,
477 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
478 compress_buff, compress_size, unc_len,
479 &load_end);
Simon Glass1edaed02017-11-25 11:57:33 -0700480 ut_assertok(err);
Julius Werner47ef9862019-07-24 19:37:54 -0700481 err = image_decomp(comp_type, load_addr, image_start,
482 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
483 compress_buff, compress_size, unc_len - 1,
484 &load_end);
Simon Glass1edaed02017-11-25 11:57:33 -0700485 ut_assert(err);
Simon Glass6d084ce2014-12-02 13:17:35 -0700486
487 /* We can't detect corruption when not decompressing */
488 if (comp_type == IH_COMP_NONE)
489 return 0;
490 memset(compress_buff + compress_size / 2, '\x49',
491 compress_size / 2);
Julius Werner47ef9862019-07-24 19:37:54 -0700492 err = image_decomp(comp_type, load_addr, image_start,
493 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
494 compress_buff, compress_size, 0x10000,
495 &load_end);
Simon Glass1edaed02017-11-25 11:57:33 -0700496 ut_assert(err);
Simon Glass6d084ce2014-12-02 13:17:35 -0700497
498 return 0;
499}
500
Simon Glass1edaed02017-11-25 11:57:33 -0700501static int compression_test_bootm_gzip(struct unit_test_state *uts)
Simon Glass6d084ce2014-12-02 13:17:35 -0700502{
Simon Glass1edaed02017-11-25 11:57:33 -0700503 return run_bootm_test(uts, IH_COMP_GZIP, compress_using_gzip);
504}
505COMPRESSION_TEST(compression_test_bootm_gzip, 0);
Simon Glass6d084ce2014-12-02 13:17:35 -0700506
Simon Glass1edaed02017-11-25 11:57:33 -0700507static int compression_test_bootm_bzip2(struct unit_test_state *uts)
508{
509 return run_bootm_test(uts, IH_COMP_BZIP2, compress_using_bzip2);
510}
511COMPRESSION_TEST(compression_test_bootm_bzip2, 0);
Simon Glass6d084ce2014-12-02 13:17:35 -0700512
Simon Glass1edaed02017-11-25 11:57:33 -0700513static int compression_test_bootm_lzma(struct unit_test_state *uts)
514{
515 return run_bootm_test(uts, IH_COMP_LZMA, compress_using_lzma);
516}
517COMPRESSION_TEST(compression_test_bootm_lzma, 0);
Simon Glass6d084ce2014-12-02 13:17:35 -0700518
Simon Glass1edaed02017-11-25 11:57:33 -0700519static int compression_test_bootm_lzo(struct unit_test_state *uts)
520{
521 return run_bootm_test(uts, IH_COMP_LZO, compress_using_lzo);
Simon Glass6d084ce2014-12-02 13:17:35 -0700522}
Simon Glass1edaed02017-11-25 11:57:33 -0700523COMPRESSION_TEST(compression_test_bootm_lzo, 0);
Simon Glass6d084ce2014-12-02 13:17:35 -0700524
Simon Glass1edaed02017-11-25 11:57:33 -0700525static int compression_test_bootm_lz4(struct unit_test_state *uts)
526{
527 return run_bootm_test(uts, IH_COMP_LZ4, compress_using_lz4);
528}
529COMPRESSION_TEST(compression_test_bootm_lz4, 0);
Simon Glass6d084ce2014-12-02 13:17:35 -0700530
Simon Glass1edaed02017-11-25 11:57:33 -0700531static int compression_test_bootm_none(struct unit_test_state *uts)
532{
533 return run_bootm_test(uts, IH_COMP_NONE, compress_using_none);
534}
535COMPRESSION_TEST(compression_test_bootm_none, 0);
536
537int do_ut_compression(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
538{
539 struct unit_test *tests = ll_entry_start(struct unit_test,
540 compression_test);
541 const int n_ents = ll_entry_count(struct unit_test, compression_test);
542
543 return cmd_ut_category("compression", tests, n_ents, argc, argv);
544}