Skip to content

Commit

Permalink
igzip: Create flag for inflate to return crc of the decompressed data
Browse files Browse the repository at this point in the history
Change-Id: I2d966f2d4ca135e3c938a9501bf5d2e11d8e92fe
Signed-off-by: Roy Oursler <[email protected]>
  • Loading branch information
rjoursler authored and gbtucker committed Dec 6, 2016
1 parent 4ea4f81 commit e569ff7
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 11 deletions.
20 changes: 18 additions & 2 deletions igzip/igzip_inflate.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "huff_codes.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 {
Expand Down Expand Up @@ -1037,6 +1038,8 @@ void isal_inflate_init(struct inflate_state *state)
state->total_out = 0;
state->block_state = ISAL_BLOCK_NEW_HDR;
state->bfinal = 0;
state->crc_flag = 0;
state->crc = 0;
state->type0_block_len = 0;
state->copy_overflow_length = 0;
state->copy_overflow_distance = 0;
Expand All @@ -1048,11 +1051,13 @@ void isal_inflate_init(struct inflate_state *state)
int isal_inflate_stateless(struct inflate_state *state)
{
uint32_t ret = 0;
uint8_t *start_out = state->next_out;

state->read_in = 0;
state->read_in_length = 0;
state->block_state = ISAL_BLOCK_NEW_HDR;
state->bfinal = 0;
state->crc = 0;
state->total_out = 0;

while (state->block_state != ISAL_BLOCK_FINISH) {
Expand All @@ -1074,6 +1079,9 @@ 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);

/* 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;
Expand All @@ -1084,7 +1092,7 @@ int isal_inflate_stateless(struct inflate_state *state)
int isal_inflate(struct inflate_state *state)
{

uint8_t *next_out = state->next_out;
uint8_t *start_out = state->next_out;
uint32_t avail_out = state->avail_out;
uint32_t copy_size = 0;
int32_t shift_size = 0;
Expand Down Expand Up @@ -1138,7 +1146,7 @@ int isal_inflate(struct inflate_state *state)
state->tmp_out_valid = state->next_out - state->tmp_out_buffer;

/* Setup state for decompressing into out_buffer */
state->next_out = next_out;
state->next_out = start_out;
state->avail_out = avail_out;
}

Expand All @@ -1158,6 +1166,10 @@ int isal_inflate(struct inflate_state *state)
|| ret == ISAL_INVALID_SYMBOL) {
/* 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);
return ret;
}

Expand All @@ -1184,6 +1196,10 @@ int isal_inflate(struct inflate_state *state)
}
}

if (state->crc_flag)
state->crc =
crc32_gzip(state->crc, start_out, state->next_out - start_out);

if (state->block_state != ISAL_BLOCK_INPUT_DONE) {
/* Save decompression history in tmp_out buffer */
if (state->tmp_out_valid == state->tmp_out_processed
Expand Down
19 changes: 11 additions & 8 deletions igzip/igzip_rand_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,15 +291,16 @@ uint32_t check_gzip_header(uint8_t * z_buf)
return ret;
}

uint32_t check_gzip_trl(uint64_t gzip_crc, uint8_t * uncompress_buf, uint32_t uncompress_len)
uint32_t check_gzip_trl(uint64_t gzip_trl, uint32_t inflate_crc, uint8_t * uncompress_buf,
uint32_t uncompress_len)
{
uint64_t crc, ret = 0;
uint64_t trl, ret = 0;
uint32_t crc;

crc = find_crc(uncompress_buf, uncompress_len);
trl = ((uint64_t) uncompress_len << 32) | crc;

crc = ((uint64_t) uncompress_len << 32) | crc;

if (crc != gzip_crc)
if (crc != inflate_crc || trl != gzip_trl)
ret = INCORRECT_GZIP_TRAILER;

return ret;
Expand All @@ -316,6 +317,7 @@ int inflate_stateless_pass(uint8_t * compress_buf, uint64_t compress_len,
state.avail_in = compress_len;
state.next_out = uncompress_buf;
state.avail_out = *uncompress_len;
state.crc_flag = gzip_flag;

ret = isal_inflate_stateless(&state);

Expand All @@ -324,8 +326,8 @@ int inflate_stateless_pass(uint8_t * compress_buf, uint64_t compress_len,
if (gzip_flag) {
if (!ret)
ret =
check_gzip_trl(*(uint64_t *) state.next_in, uncompress_buf,
*uncompress_len);
check_gzip_trl(*(uint64_t *) state.next_in, state.crc,
uncompress_buf, *uncompress_len);
state.avail_in -= 8;
}

Expand Down Expand Up @@ -357,6 +359,7 @@ int inflate_multi_pass(uint8_t * compress_buf, uint64_t compress_len,
state->next_out = NULL;
state->avail_in = 0;
state->avail_out = 0;
state->crc_flag = gzip_flag;

if (gzip_flag)
compress_len -= 8;
Expand Down Expand Up @@ -451,7 +454,7 @@ int inflate_multi_pass(uint8_t * compress_buf, uint64_t compress_len,
if (!ret)
ret =
check_gzip_trl(*(uint64_t *) & compress_buf[compress_len],
uncompress_buf, *uncompress_len);
state->crc, uncompress_buf, *uncompress_len);
}
if (ret == 0 && state->avail_in != 0)
ret = INFLATE_LEFTOVER_INPUT;
Expand Down
2 changes: 2 additions & 0 deletions igzip/inflate_data_structs.asm
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ FIELD _lit_huff_code, _inflate_huff_code_large_size, _inflate_huff_code_large_al
FIELD _dist_huff_code,_inflate_huff_code_small_size, _inflate_huff_code_small_align
FIELD _block_state, 4, 4
FIELD _bfinal, 4, 4
FIELD _crc_flag, 4, 4
FIELD _crc, 4, 4
FIELD _type0_block_len, 4, 4
FIELD _copy_overflow_len, 4, 4
FIELD _copy_overflow_dist, 4, 4
Expand Down
5 changes: 4 additions & 1 deletion include/igzip_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ struct inflate_state {
struct inflate_huff_code_small dist_huff_code; //!< Structure for decoding dist symbols
enum isal_block_state block_state; //!< Current decompression state
uint32_t bfinal; //!< Flag identifying final block
uint32_t crc_flag; //!< Flag identifying whether to track of crc
uint32_t crc; //!< Contains crc of output if crc_flag is set
int32_t type0_block_len; //!< Length left to read of type 0 block when outbuffer overflow occured
int32_t copy_overflow_length; //!< Length left to copy when outbuffer overflow occured
int32_t copy_overflow_distance; //!< Lookback distance when outbuffer overlow occured
Expand Down Expand Up @@ -501,7 +503,8 @@ void isal_inflate_init(struct inflate_state *state);
* next_in, avail_in and write a decompressed stream to the output buffer
* (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.
* 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.
*
* @param state Structure holding state information on the compression streams.
* @return ISAL_DECOMP_OK (if everything is ok),
Expand Down

0 comments on commit e569ff7

Please sign in to comment.