igzip: Modify inflate to optionally calculate adler32 hash

Change-Id: I314617b89b59d53608e464c7d2cf299faa3528b5
Signed-off-by: Roy Oursler <roy.j.oursler@intel.com>
This commit is contained in:
Roy Oursler 2017-05-08 10:40:05 -07:00 committed by Xiaodong Liu
parent 0cc3d93758
commit 87652b4489
4 changed files with 53 additions and 19 deletions

View File

@ -127,7 +127,7 @@ struct slver isal_deflate_set_hufftables_slver = { 0x008b, 0x01, 0x00 };
/*****************************************************************/
void update_checksum(struct isal_zstream *stream, uint8_t * start_in, uint64_t length)
static void update_checksum(struct isal_zstream *stream, uint8_t * start_in, uint64_t length)
{
struct isal_zstate *state = &stream->internal_state;
switch (stream->gzip_flag) {

View File

@ -30,9 +30,9 @@
#include <stdint.h>
#include "igzip_lib.h"
#include "huff_codes.h"
#include "igzip_checksums.h"
extern int decode_huffman_code_block_stateless(struct inflate_state *);
extern uint32_t crc32_gzip(uint32_t init_crc, const unsigned char *buf, uint64_t len);
/* structure contain lookup data based on RFC 1951 */
struct rfc1951_tables {
@ -98,6 +98,26 @@ static void inline byte_copy(uint8_t * dest, uint64_t lookback_distance, int rep
*dest++ = *src++;
}
static void update_checksum(struct inflate_state *state, uint8_t * start_in, uint64_t length)
{
switch (state->crc_flag) {
case ISAL_GZIP:
case ISAL_GZIP_NO_HDR:
state->crc = crc32_gzip(state->crc, start_in, length);
break;
case ISAL_ZLIB:
case ISAL_ZLIB_NO_HDR:
state->crc = isal_adler32(state->crc, start_in, length);
break;
}
}
static void finalize_adler32(struct inflate_state *state)
{
state->crc = (state->crc & 0xffff0000) | (((state->crc & 0xffff) + 1) % ADLER_MOD);
}
/*
* Returns integer with first length bits reversed and all higher bits zeroed
*/
@ -1126,9 +1146,11 @@ int isal_inflate_stateless(struct inflate_state *state)
state->block_state = ISAL_BLOCK_FINISH;
}
if (state->crc_flag)
state->crc = crc32_gzip(state->crc, start_out, state->next_out - start_out);
if (state->crc_flag) {
update_checksum(state, start_out, state->next_out - start_out);
if (state->crc_flag == ISAL_ZLIB || state->crc_flag == ISAL_ZLIB_NO_HDR)
finalize_adler32(state);
}
/* Undo count stuff of bytes read into the read buffer */
state->next_in -= state->read_in_length / 8;
state->avail_in += state->read_in_length / 8;
@ -1175,8 +1197,9 @@ int isal_inflate(struct inflate_state *state)
if (ret)
break;
if (state->bfinal != 0
&& state->block_state == ISAL_BLOCK_NEW_HDR)
&& state->block_state == ISAL_BLOCK_NEW_HDR) {
state->block_state = ISAL_BLOCK_INPUT_DONE;
}
}
/* Copy valid data from internal buffer into out_buffer */
@ -1214,9 +1237,7 @@ int isal_inflate(struct inflate_state *state)
/* Set total_out to not count data in tmp_out_buffer */
state->total_out -= state->tmp_out_valid - state->tmp_out_processed;
if (state->crc_flag)
state->crc =
crc32_gzip(state->crc, start_out,
state->next_out - start_out);
update_checksum(state, start_out, state->next_out - start_out);
return ret;
}
@ -1244,8 +1265,7 @@ int isal_inflate(struct inflate_state *state)
}
if (state->crc_flag)
state->crc =
crc32_gzip(state->crc, start_out, state->next_out - start_out);
update_checksum(state, start_out, state->next_out - start_out);
if (state->block_state != ISAL_BLOCK_INPUT_DONE) {
/* Save decompression history in tmp_out buffer */
@ -1284,8 +1304,12 @@ int isal_inflate(struct inflate_state *state)
|| ret == ISAL_INVALID_SYMBOL)
return ret;
} else if (state->tmp_out_valid == state->tmp_out_processed)
} else if (state->tmp_out_valid == state->tmp_out_processed) {
state->block_state = ISAL_BLOCK_FINISH;
if (state->crc_flag == ISAL_ZLIB
|| state->crc_flag == ISAL_ZLIB_NO_HDR)
finalize_adler32(state);
}
}
return ISAL_DECOMP_OK;

View File

@ -335,18 +335,18 @@ uint32_t check_gzip_trl(uint64_t gzip_trl, uint32_t inflate_crc, uint8_t * uncom
return ret;
}
uint32_t check_zlib_trl(uint32_t zlib_trl, uint32_t inflate_crc, uint8_t * uncompress_buf,
uint32_t check_zlib_trl(uint32_t zlib_trl, uint32_t inflate_adler, uint8_t * uncompress_buf,
uint32_t uncompress_len)
{
uint32_t trl, ret = 0;
uint32_t crc;
uint32_t adler;
crc = find_adler(uncompress_buf, uncompress_len);
adler = find_adler(uncompress_buf, uncompress_len);
trl = (crc >> 24) | ((crc >> 8) & 0xFF00) | (crc << 24) | ((crc & 0xFF00) << 8);
trl = (adler >> 24) | ((adler >> 8) & 0xFF00) | (adler << 24) | ((adler & 0xFF00) << 8);
if (trl != zlib_trl)
ret = INCORRECT_ZLIB_TRAILER;
if (adler != inflate_adler || trl != zlib_trl){
ret = INCORRECT_ZLIB_TRAILER;}
return ret;
}

View File

@ -208,6 +208,14 @@ enum isal_block_state {
ISAL_BLOCK_FINISH /* Decompression of input is completed and all data has been flushed to output */
};
/* Inflate Flags */
#define ISAL_DEFLATE 0 /* Default */
#define ISAL_GZIP 1
#define ISAL_GZIP_NO_HDR 2
#define ISAL_ZLIB 3
#define ISAL_ZLIB_NO_HDR 4
/* Inflate Return values */
#define ISAL_DECOMP_OK 0 /* No errors encountered while decompressing */
#define ISAL_END_INPUT 1 /* End of input reached */
@ -603,7 +611,9 @@ void isal_inflate_init(struct inflate_state *state);
* (updating next_out and avail_out). The function returns when the input buffer
* is empty, the output buffer is full or invalid data is found. The current
* state of the decompression on exit can be read from state->block-state. If
* the crc_flag is set, the gzip crc of the output is stored in state->crc.
* the crc_flag is set to ISAL_GZIP_NO_HDR the gzip crc of the output is stored
* in state->crc. Alternatively, if the crc_flag is set to ISAL_ZLIB_NO_HDR the
* adler32 of the output is stored in state->crc.
*
* @param state Structure holding state information on the compression streams.
* @return ISAL_DECOMP_OK (if everything is ok),