wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers compress.c Source File

compress.c

00001 /* compress.c
00002  *
00003  * Copyright (C) 2006-2020 wolfSSL Inc.
00004  *
00005  * This file is part of wolfSSL.
00006  *
00007  * wolfSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * wolfSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
00020  */
00021 
00022 
00023 
00024 #ifdef HAVE_CONFIG_H
00025     #include <config.h>
00026 #endif
00027 
00028 #include <wolfssl/wolfcrypt/settings.h>
00029 
00030 #ifdef HAVE_LIBZ
00031 
00032 
00033 #include <wolfssl/wolfcrypt/compress.h >
00034 #include <wolfssl/wolfcrypt/error-crypt.h >
00035 #include <wolfssl/wolfcrypt/logging.h >
00036 #ifdef NO_INLINE
00037     #include <wolfssl/wolfcrypt/misc.h>
00038 #else
00039     #define WOLFSSL_MISC_INCLUDED
00040     #include <wolfcrypt/src/misc.c>
00041 #endif
00042 
00043 #include <zlib.h>
00044 
00045 
00046 /* alloc user allocs to work with zlib */
00047 static void* myAlloc(void* opaque, unsigned int item, unsigned int size)
00048 {
00049     (void)opaque;
00050     return XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ);
00051 }
00052 
00053 
00054 static void myFree(void* opaque, void* memory)
00055 {
00056     (void)opaque;
00057     XFREE(memory, opaque, DYNAMIC_TYPE_LIBZ);
00058 }
00059 
00060 
00061 #ifdef HAVE_MCAPI
00062     #define DEFLATE_DEFAULT_WINDOWBITS  11
00063     #define DEFLATE_DEFAULT_MEMLEVEL     1
00064 #else
00065     #define DEFLATE_DEFAULT_WINDOWBITS 15
00066     #define DEFLATE_DEFAULT_MEMLEVEL    8
00067 #endif
00068 
00069 
00070 /*
00071  * out - pointer to destination buffer
00072  * outSz - size of destination buffer
00073  * in - pointer to source buffer to compress
00074  * inSz - size of source to compress
00075  * flags - flags to control how compress operates
00076  *
00077  * return:
00078  *    negative - error code
00079  *    positive - bytes stored in out buffer
00080  *
00081  * Note, the output buffer still needs to be larger than the input buffer.
00082  * The right chunk of data won't compress at all, and the lookup table will
00083  * add to the size of the output. The libz code says the compressed
00084  * buffer should be srcSz + 0.1% + 12.
00085  */
00086 int wc_Compress_ex(byte* out, word32 outSz, const byte* in, word32 inSz,
00087     word32 flags, word32 windowBits)
00088 {
00089     z_stream stream;
00090     int result = 0;
00091 
00092     stream.next_in = (Bytef*)in;
00093     stream.avail_in = (uInt)inSz;
00094 #ifdef MAXSEG_64K
00095     /* Check for source > 64K on 16-bit machine: */
00096     if ((uLong)stream.avail_in != inSz) return COMPRESS_INIT_E;
00097 #endif
00098     stream.next_out = out;
00099     stream.avail_out = (uInt)outSz;
00100     if ((uLong)stream.avail_out != outSz) return COMPRESS_INIT_E;
00101 
00102     stream.zalloc = (alloc_func)myAlloc;
00103     stream.zfree = (free_func)myFree;
00104     stream.opaque = (voidpf)0;
00105 
00106     if (deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
00107                      DEFLATE_DEFAULT_WINDOWBITS | windowBits,
00108                      DEFLATE_DEFAULT_MEMLEVEL,
00109                      flags ? Z_FIXED : Z_DEFAULT_STRATEGY) != Z_OK)
00110         return COMPRESS_INIT_E;
00111 
00112     if (deflate(&stream, Z_FINISH) != Z_STREAM_END) {
00113         deflateEnd(&stream);
00114         return COMPRESS_E;
00115     }
00116 
00117     result = (int)stream.total_out;
00118 
00119     if (deflateEnd(&stream) != Z_OK)
00120         result = COMPRESS_E;
00121 
00122     return result;
00123 }
00124 
00125 int wc_Compress(byte* out, word32 outSz, const byte* in, word32 inSz, word32 flags)
00126 {
00127     return wc_Compress_ex(out, outSz, in, inSz, flags, 0);
00128 }
00129 
00130 
00131 /* windowBits:
00132 * deflateInit() and inflateInit(), as well as deflateInit2() and inflateInit2()
00133     with windowBits in 0..15 all process zlib-wrapped deflate data.
00134     (See RFC 1950 and RFC 1951.)
00135 * deflateInit2() and inflateInit2() with negative windowBits in -1..-15 process
00136     raw deflate data with no header or trailer.
00137 * deflateInit2() and inflateInit2() with windowBits in 16..31, i.e. 16
00138     added to 0..15, process gzip-wrapped deflate data (RFC 1952).
00139 * inflateInit2() with windowBits in 32..47 (32 added to 0..15) will
00140     automatically detect either a gzip or zlib header (but not raw deflate
00141     data), and decompress accordingly.
00142 */
00143 int wc_DeCompress_ex(byte* out, word32 outSz, const byte* in, word32 inSz,
00144     int windowBits)
00145 /*
00146  * out - pointer to destination buffer
00147  * outSz - size of destination buffer
00148  * in - pointer to source buffer to compress
00149  * inSz - size of source to compress
00150  * windowBits - flags to control how decompress operates
00151  *
00152  * return:
00153  *    negative - error code
00154  *    positive - bytes stored in out buffer
00155  */
00156 {
00157     z_stream stream;
00158     int result = 0;
00159 
00160     stream.next_in = (Bytef*)in;
00161     stream.avail_in = (uInt)inSz;
00162     /* Check for source > 64K on 16-bit machine: */
00163     if ((uLong)stream.avail_in != inSz) return DECOMPRESS_INIT_E;
00164 
00165     stream.next_out = out;
00166     stream.avail_out = (uInt)outSz;
00167     if ((uLong)stream.avail_out != outSz) return DECOMPRESS_INIT_E;
00168 
00169     stream.zalloc = (alloc_func)myAlloc;
00170     stream.zfree = (free_func)myFree;
00171     stream.opaque = (voidpf)0;
00172 
00173     if (inflateInit2(&stream, DEFLATE_DEFAULT_WINDOWBITS | windowBits) != Z_OK)
00174         return DECOMPRESS_INIT_E;
00175 
00176     result = inflate(&stream, Z_FINISH);
00177     if (result != Z_STREAM_END) {
00178         inflateEnd(&stream);
00179         return DECOMPRESS_E;
00180     }
00181 
00182     result = (int)stream.total_out;
00183 
00184     if (inflateEnd(&stream) != Z_OK)
00185         result = DECOMPRESS_E;
00186 
00187     return result;
00188 }
00189 
00190 
00191 int wc_DeCompress(byte* out, word32 outSz, const byte* in, word32 inSz)
00192 {
00193     return wc_DeCompress_ex(out, outSz, in, inSz, 0);
00194 }
00195 
00196 
00197 #endif /* HAVE_LIBZ */
00198 
00199