1c43d6851SMasahiro Yamada /*
2*4c700c15SGovindraj Raja * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved.
3c43d6851SMasahiro Yamada *
4c43d6851SMasahiro Yamada * SPDX-License-Identifier: BSD-3-Clause
5c43d6851SMasahiro Yamada */
6c43d6851SMasahiro Yamada
7c43d6851SMasahiro Yamada #include <assert.h>
8c43d6851SMasahiro Yamada #include <errno.h>
9c43d6851SMasahiro Yamada #include <string.h>
1009d40e0eSAntonio Nino Diaz
1109d40e0eSAntonio Nino Diaz #include <common/debug.h>
12f2169370SManish V Badarkhe #include <common/tf_crc32.h>
1309d40e0eSAntonio Nino Diaz #include <lib/utils.h>
14c43d6851SMasahiro Yamada #include <tf_gunzip.h>
15c43d6851SMasahiro Yamada
16c43d6851SMasahiro Yamada #include "zutil.h"
17c43d6851SMasahiro Yamada
18c43d6851SMasahiro Yamada /*
19c43d6851SMasahiro Yamada * memory allocated by malloc() is supposed to be aligned for any built-in type
20c43d6851SMasahiro Yamada */
21c43d6851SMasahiro Yamada #define ZALLOC_ALIGNMENT sizeof(void *)
22c43d6851SMasahiro Yamada
23c43d6851SMasahiro Yamada static uintptr_t zalloc_start;
24c43d6851SMasahiro Yamada static uintptr_t zalloc_end;
25c43d6851SMasahiro Yamada static uintptr_t zalloc_current;
26c43d6851SMasahiro Yamada
zcalloc(void * opaque,unsigned int items,unsigned int size)27c43d6851SMasahiro Yamada static void * ZLIB_INTERNAL zcalloc(void *opaque, unsigned int items,
28c43d6851SMasahiro Yamada unsigned int size)
29c43d6851SMasahiro Yamada {
30c43d6851SMasahiro Yamada uintptr_t p, p_end;
31c43d6851SMasahiro Yamada
32c43d6851SMasahiro Yamada size *= items;
33c43d6851SMasahiro Yamada
34c43d6851SMasahiro Yamada p = round_up(zalloc_current, ZALLOC_ALIGNMENT);
35c43d6851SMasahiro Yamada p_end = p + size;
36c43d6851SMasahiro Yamada
37c43d6851SMasahiro Yamada if (p_end > zalloc_end)
38c43d6851SMasahiro Yamada return NULL;
39c43d6851SMasahiro Yamada
40c43d6851SMasahiro Yamada memset((void *)p, 0, size);
41c43d6851SMasahiro Yamada
42c43d6851SMasahiro Yamada zalloc_current = p_end;
43c43d6851SMasahiro Yamada
44c43d6851SMasahiro Yamada return (void *)p;
45c43d6851SMasahiro Yamada }
46c43d6851SMasahiro Yamada
zfree(void * opaque,void * ptr)47c43d6851SMasahiro Yamada static void ZLIB_INTERNAL zfree(void *opaque, void *ptr)
48c43d6851SMasahiro Yamada {
49c43d6851SMasahiro Yamada }
50c43d6851SMasahiro Yamada
51c43d6851SMasahiro Yamada /*
52c43d6851SMasahiro Yamada * gunzip - decompress gzip data
53c43d6851SMasahiro Yamada * @in_buf: source of compressed input. Upon exit, the end of input.
54c43d6851SMasahiro Yamada * @in_len: length of in_buf
55c43d6851SMasahiro Yamada * @out_buf: destination of decompressed output. Upon exit, the end of output.
56c43d6851SMasahiro Yamada * @out_len: length of out_buf
57c43d6851SMasahiro Yamada * @work_buf: workspace
58c43d6851SMasahiro Yamada * @work_len: length of workspace
59c43d6851SMasahiro Yamada */
gunzip(uintptr_t * in_buf,size_t in_len,uintptr_t * out_buf,size_t out_len,uintptr_t work_buf,size_t work_len)60c43d6851SMasahiro Yamada int gunzip(uintptr_t *in_buf, size_t in_len, uintptr_t *out_buf,
61c43d6851SMasahiro Yamada size_t out_len, uintptr_t work_buf, size_t work_len)
62c43d6851SMasahiro Yamada {
63c43d6851SMasahiro Yamada z_stream stream;
64c43d6851SMasahiro Yamada int zret, ret;
65c43d6851SMasahiro Yamada
66c43d6851SMasahiro Yamada zalloc_start = work_buf;
67c43d6851SMasahiro Yamada zalloc_end = work_buf + work_len;
68c43d6851SMasahiro Yamada zalloc_current = zalloc_start;
69c43d6851SMasahiro Yamada
70c43d6851SMasahiro Yamada stream.next_in = (typeof(stream.next_in))*in_buf;
71c43d6851SMasahiro Yamada stream.avail_in = in_len;
72c43d6851SMasahiro Yamada stream.next_out = (typeof(stream.next_out))*out_buf;
73c43d6851SMasahiro Yamada stream.avail_out = out_len;
74c43d6851SMasahiro Yamada stream.zalloc = zcalloc;
75c43d6851SMasahiro Yamada stream.zfree = zfree;
76c43d6851SMasahiro Yamada stream.opaque = (voidpf)0;
77c43d6851SMasahiro Yamada
78c43d6851SMasahiro Yamada zret = inflateInit(&stream);
79c43d6851SMasahiro Yamada if (zret != Z_OK) {
80c43d6851SMasahiro Yamada ERROR("zlib: inflate init failed (ret = %d)\n", zret);
81c43d6851SMasahiro Yamada return (zret == Z_MEM_ERROR) ? -ENOMEM : -EIO;
82c43d6851SMasahiro Yamada }
83c43d6851SMasahiro Yamada
84c43d6851SMasahiro Yamada zret = inflate(&stream, Z_NO_FLUSH);
85c43d6851SMasahiro Yamada if (zret == Z_STREAM_END) {
86c43d6851SMasahiro Yamada ret = 0;
87c43d6851SMasahiro Yamada } else {
88c43d6851SMasahiro Yamada if (stream.msg)
89c43d6851SMasahiro Yamada ERROR("%s\n", stream.msg);
90c43d6851SMasahiro Yamada ERROR("zlib: inflate failed (ret = %d)\n", zret);
91c43d6851SMasahiro Yamada ret = (zret == Z_MEM_ERROR) ? -ENOMEM : -EIO;
92c43d6851SMasahiro Yamada }
93c43d6851SMasahiro Yamada
9457546074SSandrine Bailleux VERBOSE("zlib: %lu byte input\n", stream.total_in);
9557546074SSandrine Bailleux VERBOSE("zlib: %lu byte output\n", stream.total_out);
96c43d6851SMasahiro Yamada
97c43d6851SMasahiro Yamada *in_buf = (uintptr_t)stream.next_in;
98c43d6851SMasahiro Yamada *out_buf = (uintptr_t)stream.next_out;
99c43d6851SMasahiro Yamada
100c43d6851SMasahiro Yamada inflateEnd(&stream);
101c43d6851SMasahiro Yamada
102c43d6851SMasahiro Yamada return ret;
103c43d6851SMasahiro Yamada }
104f2169370SManish V Badarkhe
105f2169370SManish V Badarkhe /* Wrapper function to calculate CRC
106f2169370SManish V Badarkhe * @crc: previous accumulated CRC
107f2169370SManish V Badarkhe * @buf: buffer base address
108f2169370SManish V Badarkhe * @size: size of the buffer
109f2169370SManish V Badarkhe *
110f2169370SManish V Badarkhe * Return calculated CRC32 value
111f2169370SManish V Badarkhe */
tf_crc32(uint32_t crc,const unsigned char * buf,size_t size)112f2169370SManish V Badarkhe uint32_t tf_crc32(uint32_t crc, const unsigned char *buf, size_t size)
113f2169370SManish V Badarkhe {
114f2169370SManish V Badarkhe return (uint32_t)crc32((unsigned long)crc, buf, size);
115f2169370SManish V Badarkhe }
116