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