[BACK]Return to deflate.c CVS log [TXT][DIR] Up to [local] / sys / crypto

Annotation of sys/crypto/deflate.c, Revision 1.1.1.1

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

CVSweb