tf_gunzip.c 2.6 KB

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