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