xform_ipcomp.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /* $OpenBSD: xform_ipcomp.c,v 1.7 2015/03/16 20:26:24 miod Exp $ */
  2. /*
  3. * Copyright (c) 2001 Jean-Jacques Bernard-Gundol (jj@wabbitt.org)
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. The name of the author may not be used to endorse or promote products
  15. * derived from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. /*
  29. * This file contains a wrapper around the deflate algo compression
  30. * functions using the zlib library
  31. */
  32. #include <sys/param.h>
  33. #include <sys/malloc.h>
  34. #include <sys/systm.h>
  35. #include <lib/libz/zutil.h>
  36. #define Z_METHOD 8
  37. #define Z_MEMLEVEL 8
  38. #define ZBUF 10
  39. u_int32_t deflate_global(u_int8_t *, u_int32_t, int, u_int8_t **);
  40. struct deflate_buf {
  41. u_int8_t *out;
  42. u_int32_t size;
  43. int flag;
  44. };
  45. int window_inflate = -1 * MAX_WBITS;
  46. int window_deflate = -12;
  47. /*
  48. * This function takes a block of data and (de)compress it using the deflate
  49. * algorithm
  50. */
  51. u_int32_t
  52. deflate_global(u_int8_t *data, u_int32_t size, int decomp, u_int8_t **out)
  53. {
  54. z_stream zbuf;
  55. u_int8_t *output;
  56. u_int32_t count, result;
  57. int error, i = 0, j;
  58. struct deflate_buf buf[ZBUF];
  59. bzero(&zbuf, sizeof(z_stream));
  60. for (j = 0; j < ZBUF; j++)
  61. buf[j].flag = 0;
  62. zbuf.next_in = data; /* data that is going to be processed */
  63. zbuf.zalloc = zcalloc;
  64. zbuf.zfree = zcfree;
  65. zbuf.opaque = Z_NULL;
  66. zbuf.avail_in = size; /* Total length of data to be processed */
  67. if (decomp) {
  68. /*
  69. * Choose a buffer with 4x the size of the input buffer
  70. * for the size of the output buffer in the case of
  71. * decompression. If it's not sufficient, it will need to be
  72. * updated while the decompression is going on
  73. */
  74. if (size < 32 * 1024)
  75. size *= 4;
  76. }
  77. buf[i].out = malloc((u_long)size, M_CRYPTO_DATA, M_NOWAIT);
  78. if (buf[i].out == NULL)
  79. goto bad;
  80. buf[i].size = size;
  81. buf[i].flag = 1;
  82. i++;
  83. zbuf.next_out = buf[0].out;
  84. zbuf.avail_out = buf[0].size;
  85. error = decomp ?
  86. inflateInit2(&zbuf, window_inflate) :
  87. deflateInit2(&zbuf, Z_DEFAULT_COMPRESSION, Z_METHOD,
  88. window_deflate, Z_MEMLEVEL, Z_DEFAULT_STRATEGY);
  89. if (error != Z_OK)
  90. goto bad;
  91. for (;;) {
  92. error = decomp ?
  93. inflate(&zbuf, Z_PARTIAL_FLUSH) :
  94. deflate(&zbuf, Z_FINISH);
  95. if (error == Z_STREAM_END)
  96. break;
  97. if (error != Z_OK)
  98. goto bad;
  99. if (zbuf.avail_out == 0 && i < (ZBUF - 1)) {
  100. /* we need more output space, allocate size */
  101. if (size < 32 * 1024)
  102. size *= 2;
  103. buf[i].out = malloc((u_long)size, M_CRYPTO_DATA,
  104. M_NOWAIT);
  105. if (buf[i].out == NULL)
  106. goto bad;
  107. zbuf.next_out = buf[i].out;
  108. buf[i].size = size;
  109. buf[i].flag = 1;
  110. zbuf.avail_out = buf[i].size;
  111. i++;
  112. } else
  113. goto bad; /* out of buffers */
  114. }
  115. result = count = zbuf.total_out;
  116. *out = malloc((u_long)result, M_CRYPTO_DATA, M_NOWAIT);
  117. if (*out == NULL)
  118. goto bad;
  119. if (decomp)
  120. inflateEnd(&zbuf);
  121. else
  122. deflateEnd(&zbuf);
  123. output = *out;
  124. for (j = 0; buf[j].flag != 0; j++) {
  125. if (count > buf[j].size) {
  126. bcopy(buf[j].out, *out, buf[j].size);
  127. *out += buf[j].size;
  128. free(buf[j].out, M_CRYPTO_DATA, 0);
  129. count -= buf[j].size;
  130. } else {
  131. /* it should be the last buffer */
  132. bcopy(buf[j].out, *out, count);
  133. *out += count;
  134. free(buf[j].out, M_CRYPTO_DATA, 0);
  135. count = 0;
  136. }
  137. }
  138. *out = output;
  139. return result;
  140. bad:
  141. *out = NULL;
  142. for (j = 0; buf[j].flag != 0; j++)
  143. free(buf[j].out, M_CRYPTO_DATA, 0);
  144. if (decomp)
  145. inflateEnd(&zbuf);
  146. else
  147. deflateEnd(&zbuf);
  148. return 0;
  149. }