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