diff --git a/ChangeLog b/ChangeLog index 9ec293dda..983b7e9e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2011-11-03 Vladimir Serbinenko + + XZ CRC64 and SHA256 support. + + * Makefile.util.def (libgrubmods): Add crc64.c. + * grub-core/Makefile.core.def (crc64): New module. + * grub-core/lib/crc64.c: New file. + * grub-core/lib/xzembed/xz_dec_stream.c (xz_dec_hash) + [!GRUB_EMBED_DECOMPRESSOR]: Rename crc32_context to hash_context. + Fix the type. + (MAX_HASH_SIZE): New define. + (xz_dec) [!GRUB_EMBED_DECOMPRESSOR]: Add generic hash fields. + (dec_block) [!GRUB_EMBED_DECOMPRESSOR]: Handle non-crc32 hashes. + (index_update) [!GRUB_EMBED_DECOMPRESSOR]: Likewise. + (dec_index) [!GRUB_EMBED_DECOMPRESSOR]: Likewise. + (crc32_validate) [!GRUB_EMBED_DECOMPRESSOR]: Rename to ... + (hash_validate) [!GRUB_EMBED_DECOMPRESSOR]: ... this. + Handle non-crc32 hashes. + (hashes) [!GRUB_EMBED_DECOMPRESSOR]: New variable. + (dec_stream_header): Handle non-crc32 hashes. + (dec_stream_footer): Likewise. + (dec_block_header): Likewise. + (dec_main): Likewise. + (xz_dec_init): Likewise. + (xz_dec_reset): Likewise. + (xz_dec_end): Likewise. + * util/import_gcry.py: Add CRC64 line. + 2011-11-03 Vladimir Serbinenko * grub-core/fs/ufs.c (grub_ufs_mtime) [MODE_UFS2]: Check mtime field diff --git a/Makefile.util.def b/Makefile.util.def index a839920d5..17894b1d2 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -93,6 +93,7 @@ library = { common = grub-core/lib/LzmaEnc.c; common = grub-core/lib/crc.c; common = grub-core/lib/adler32.c; + common = grub-core/lib/crc64.c; common = grub-core/normal/datetime.c; common = grub-core/normal/misc.c; common = grub-core/partmap/acorn.c; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 2b72d8429..b2e8e7aa2 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -1698,3 +1698,8 @@ module = { name = adler32; common = lib/adler32.c; }; + +module = { + name = crc64; + common = lib/crc64.c; +}; diff --git a/grub-core/lib/crc64.c b/grub-core/lib/crc64.c new file mode 100644 index 000000000..92c398d1e --- /dev/null +++ b/grub-core/lib/crc64.c @@ -0,0 +1,111 @@ +/* crc64.c - crc64 function */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +static grub_uint64_t crc64_table [256]; + +static void +init_crc64_table (void) +{ + auto grub_uint64_t reflect (grub_uint64_t ref, int len); + grub_uint64_t reflect (grub_uint64_t ref, int len) + { + grub_uint64_t result = 0; + int i; + + for (i = 1; i <= len; i++) + { + if (ref & 1) + result |= 1ULL << (len - i); + ref >>= 1; + } + + return result; + } + + grub_uint64_t polynomial = 0x42f0e1eba9ea3693ULL; + int i, j; + + for(i = 0; i < 256; i++) + { + crc64_table[i] = reflect(i, 8) << 56; + for (j = 0; j < 8; j++) + { + crc64_table[i] = (crc64_table[i] << 1) ^ + (crc64_table[i] & (1ULL << 63) ? polynomial : 0); + } + crc64_table[i] = reflect(crc64_table[i], 64); + } +} + +static void +crc64_init (void *context) +{ + if (! crc64_table[1]) + init_crc64_table (); + *(grub_uint64_t *) context = 0; +} + +static void +crc64_write (void *context, const void *buf, grub_size_t size) +{ + unsigned i; + const grub_uint8_t *data = buf; + grub_uint64_t crc = ~grub_le_to_cpu64 (*(grub_uint64_t *) context); + + for (i = 0; i < size; i++) + { + crc = (crc >> 8) ^ crc64_table[(crc & 0xFF) ^ *data]; + data++; + } + + *(grub_uint64_t *) context = grub_cpu_to_le64 (~crc); +} + +static grub_uint8_t * +crc64_read (void *context) +{ + return context; +} + +static void +crc64_final (void *context __attribute__ ((unused))) +{ +} + +gcry_md_spec_t _gcry_digest_spec_crc64 = + { + "CRC64", 0, 0, 0, 8, + crc64_init, crc64_write, crc64_final, crc64_read, + sizeof (grub_uint64_t), + .blocksize = 64 + }; + +GRUB_MOD_INIT(crc64) +{ + grub_md_register (&_gcry_digest_spec_crc64); +} + +GRUB_MOD_FINI(crc64) +{ + grub_md_unregister (&_gcry_digest_spec_crc64); +} diff --git a/grub-core/lib/xzembed/xz_dec_stream.c b/grub-core/lib/xzembed/xz_dec_stream.c index 3bf201d50..383c29a2f 100644 --- a/grub-core/lib/xzembed/xz_dec_stream.c +++ b/grub-core/lib/xzembed/xz_dec_stream.c @@ -32,10 +32,13 @@ struct xz_dec_hash { vli_type unpadded; vli_type uncompressed; #ifndef GRUB_EMBED_DECOMPRESSOR - uint8_t *crc32_context; + uint64_t *hash_context; #endif }; +/* Enough for up to 512 bits. */ +#define MAX_HASH_SIZE 64 + struct xz_dec { /* Position in dec_main() */ enum { @@ -62,11 +65,22 @@ struct xz_dec { size_t out_start; /* CRC32 value in Block or Index */ - uint32_t crc32_temp; /* need for crc32_validate*/ - uint8_t *crc32_context; +#ifndef GRUB_EMBED_DECOMPRESSOR + uint8_t hash_value[MAX_HASH_SIZE]; /* need for crc32_validate*/ +#endif + int have_hash_value; +#ifndef GRUB_EMBED_DECOMPRESSOR + uint64_t *hash_context; + uint64_t *crc32_context; +#endif - /* True if CRC32 is calculated from uncompressed data */ - bool has_crc32; + /* Hash function calculated from uncompressed data */ +#ifndef GRUB_EMBED_DECOMPRESSOR + const gcry_md_spec_t *hash; + const gcry_md_spec_t *crc32; +#endif + grub_size_t hash_size; + grub_uint8_t hash_id; /* True if we are operating in single-call mode. */ bool single_call; @@ -250,9 +264,12 @@ static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b) return XZ_DATA_ERROR; #ifndef GRUB_EMBED_DECOMPRESSOR - if (s->has_crc32) - GRUB_MD_CRC32->write(s->crc32_context,b->out + s->out_start, - b->out_pos - s->out_start); + if (s->hash) + s->hash->write(s->hash_context,b->out + s->out_start, + b->out_pos - s->out_start); + if (s->crc32) + s->crc32->write(s->crc32_context,b->out + s->out_start, + b->out_pos - s->out_start); #endif if (ret == XZ_STREAM_END) { @@ -268,14 +285,15 @@ static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b) s->block.hash.unpadded += s->block_header.size + s->block.compressed; - if (s->has_crc32) - s->block.hash.unpadded += 4; + s->block.hash.unpadded += s->hash_size; s->block.hash.uncompressed += s->block.uncompressed; #ifndef GRUB_EMBED_DECOMPRESSOR - GRUB_MD_CRC32->write(s->block.hash.crc32_context, - (const uint8_t *)&s->block.hash, 2 * sizeof(vli_type)); + if (s->hash) + s->hash->write(s->block.hash.hash_context, + (const uint8_t *)&s->block.hash, + 2 * sizeof(vli_type)); #endif ++s->block.count; @@ -290,7 +308,10 @@ static void index_update(struct xz_dec *s, const struct xz_buf *b) size_t in_used = b->in_pos - s->in_start; s->index.size += in_used; #ifndef GRUB_EMBED_DECOMPRESSOR - GRUB_MD_CRC32->write(s->crc32_context,b->in + s->in_start, in_used); + if (s->hash) + s->hash->write(s->hash_context,b->in + s->in_start, in_used); + if (s->crc32) + s->crc32->write(s->crc32_context,b->in + s->in_start, in_used); #endif } @@ -337,8 +358,9 @@ static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b) s->index.hash.uncompressed += s->vli; #ifndef GRUB_EMBED_DECOMPRESSOR - GRUB_MD_CRC32->write(s->index.hash.crc32_context, - (const uint8_t *)&s->index.hash, 2 * sizeof(vli_type)); + if (s->hash) + s->hash->write(s->index.hash.hash_context, + (const uint8_t *)&s->index.hash, 2 * sizeof(vli_type)); #endif --s->index.count; @@ -354,13 +376,30 @@ static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b) * Validate that the next four input bytes match the value of s->crc32. * s->pos must be zero when starting to validate the first byte. */ -static enum xz_ret crc32_validate(struct xz_dec *s, struct xz_buf *b) +static enum xz_ret hash_validate(struct xz_dec *s, struct xz_buf *b, + int crc32) { #ifndef GRUB_EMBED_DECOMPRESSOR - if(s->crc32_temp == 0) + const gcry_md_spec_t *hash = crc32 ? s->crc32 : s->hash; + grub_uint64_t *hash_context = crc32 ? s->crc32_context + : s->hash_context; + if(!s->have_hash_value && hash + && sizeof (s->hash_value) >= hash->mdlen) { - GRUB_MD_CRC32->final(s->crc32_context); - s->crc32_temp = get_unaligned_be32(GRUB_MD_CRC32->read(s->crc32_context)); + hash->final(hash_context); + grub_memcpy (s->hash_value, hash->read(hash_context), + hash->mdlen); + s->have_hash_value = 1; + if (s->hash_id == 1 || crc32) + { + grub_uint8_t t; + t = s->hash_value[0]; + s->hash_value[0] = s->hash_value[3]; + s->hash_value[3] = t; + t = s->hash_value[1]; + s->hash_value[1] = s->hash_value[2]; + s->hash_value[2] = t; + } } #endif @@ -369,23 +408,38 @@ static enum xz_ret crc32_validate(struct xz_dec *s, struct xz_buf *b) return XZ_OK; #ifndef GRUB_EMBED_DECOMPRESSOR - if (((s->crc32_temp >> s->pos) & 0xFF) != b->in[b->in_pos++]) + if (hash && s->hash_value[s->pos / 8] != b->in[b->in_pos++]) return XZ_DATA_ERROR; #endif s->pos += 8; - } while (s->pos < 32); + } while (s->pos < (crc32 ? 32 : s->hash_size * 8)); #ifndef GRUB_EMBED_DECOMPRESSOR - GRUB_MD_CRC32->init(s->crc32_context); + if (s->hash) + s->hash->init(s->hash_context); + if (s->crc32) + s->crc32->init(s->crc32_context); #endif - s->crc32_temp = 0; + s->have_hash_value = 0; s->pos = 0; return XZ_STREAM_END; } +#ifndef GRUB_EMBED_DECOMPRESSOR +static struct +{ + const char *name; + grub_size_t size; +} hashes[] = { + [0x01] = { "CRC32", 4}, + [0x04] = { "CRC64", 8}, + [0x0A] = { "SHA256", 32}, +}; +#endif + /* Decode the Stream Header field (the first 12 bytes of the .xz Stream). */ static enum xz_ret dec_stream_header(struct xz_dec *s) { @@ -393,17 +447,27 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) return XZ_FORMAT_ERROR; #ifndef GRUB_EMBED_DECOMPRESSOR - uint8_t crc32_context[GRUB_MD_CRC32->contextsize]; + if (s->crc32) + { + uint64_t hash_context[(s->crc32->contextsize + 7) / 8]; + uint8_t resulthash[s->crc32->mdlen]; + uint8_t readhash[4]; - GRUB_MD_CRC32->init(crc32_context); - GRUB_MD_CRC32->write(crc32_context,s->temp.buf + HEADER_MAGIC_SIZE, 2); - GRUB_MD_CRC32->final(crc32_context); + s->crc32->init(hash_context); + s->crc32->write(hash_context,s->temp.buf + HEADER_MAGIC_SIZE, 2); + s->crc32->final(hash_context); - uint32_t resultcrc = get_unaligned_be32(GRUB_MD_CRC32->read(crc32_context)); - uint32_t readcrc = get_unaligned_le32(s->temp.buf + HEADER_MAGIC_SIZE + 2); + grub_memcpy (resulthash, s->crc32->read(hash_context), + s->crc32->mdlen); + readhash[0] = s->temp.buf[HEADER_MAGIC_SIZE + 5]; + readhash[1] = s->temp.buf[HEADER_MAGIC_SIZE + 4]; + readhash[2] = s->temp.buf[HEADER_MAGIC_SIZE + 3]; + readhash[3] = s->temp.buf[HEADER_MAGIC_SIZE + 2]; - if(resultcrc != readcrc) - return XZ_DATA_ERROR; + if(4 != s->crc32->mdlen + || grub_memcmp (readhash, resulthash, s->crc32->mdlen) != 0) + return XZ_DATA_ERROR; + } #endif /* @@ -411,10 +475,77 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) * only none (Check ID = 0) and CRC32 (Check ID = 1). */ if (s->temp.buf[HEADER_MAGIC_SIZE] != 0 - || s->temp.buf[HEADER_MAGIC_SIZE + 1] > 1) + || s->temp.buf[HEADER_MAGIC_SIZE + 1] >= ARRAY_SIZE (hashes) + || (hashes[s->temp.buf[HEADER_MAGIC_SIZE + 1]].name == 0 + && s->temp.buf[HEADER_MAGIC_SIZE + 1] != 0)) return XZ_OPTIONS_ERROR; - s->has_crc32 = s->temp.buf[HEADER_MAGIC_SIZE + 1]; + s->hash_id = s->temp.buf[HEADER_MAGIC_SIZE + 1]; + +#ifndef GRUB_EMBED_DECOMPRESSOR + if (s->crc32) + { + s->crc32_context = kmalloc(s->crc32->contextsize, GFP_KERNEL); + if (s->crc32_context == NULL) + return XZ_MEMLIMIT_ERROR; + s->crc32->init(s->crc32_context); + } +#endif + + if (s->temp.buf[HEADER_MAGIC_SIZE + 1]) + { + s->hash_size = hashes[s->temp.buf[HEADER_MAGIC_SIZE + 1]].size; +#ifndef GRUB_EMBED_DECOMPRESSOR + s->hash = grub_crypto_lookup_md_by_name (hashes[s->temp.buf[HEADER_MAGIC_SIZE + 1]].name); + if (s->hash) + { + if (s->hash->mdlen != s->hash_size) + return XZ_OPTIONS_ERROR; + s->hash_context = kmalloc(s->hash->contextsize, GFP_KERNEL); + if (s->hash_context == NULL) + { + kfree(s->crc32_context); + return XZ_MEMLIMIT_ERROR; + } + + s->index.hash.hash_context = kmalloc(s->hash->contextsize, + GFP_KERNEL); + if (s->index.hash.hash_context == NULL) + { + kfree(s->hash_context); + kfree(s->crc32_context); + return XZ_MEMLIMIT_ERROR; + } + + s->block.hash.hash_context = kmalloc(s->hash->contextsize, GFP_KERNEL); + if (s->block.hash.hash_context == NULL) + { + kfree(s->index.hash.hash_context); + kfree(s->hash_context); + kfree(s->crc32_context); + return XZ_MEMLIMIT_ERROR; + } + + s->hash->init(s->hash_context); + s->hash->init(s->index.hash.hash_context); + s->hash->init(s->block.hash.hash_context); + } +#else + s->hash = 0; +#endif +#if 1 + if (!s->hash) + return XZ_OPTIONS_ERROR; +#endif + } + else + { + s->hash = 0; + s->hash_size = 0; + } + + s->have_hash_value = 0; + return XZ_OK; } @@ -426,19 +557,30 @@ static enum xz_ret dec_stream_footer(struct xz_dec *s) return XZ_DATA_ERROR; #ifndef GRUB_EMBED_DECOMPRESSOR - uint8_t crc32_context[GRUB_MD_CRC32->contextsize]; + if (s->crc32) + { + uint64_t hash_context[(s->crc32->contextsize + 7) / 8]; + uint8_t resulthash[s->crc32->mdlen]; + uint8_t readhash[4]; - GRUB_MD_CRC32->init(crc32_context); - GRUB_MD_CRC32->write(crc32_context, s->temp.buf + 4, 6); - GRUB_MD_CRC32->final(crc32_context); + s->crc32->init(hash_context); + s->crc32->write(hash_context,s->temp.buf + 4, 6); + s->crc32->final(hash_context); - uint32_t resultcrc = get_unaligned_be32(GRUB_MD_CRC32->read(crc32_context)); - uint32_t readcrc = get_unaligned_le32(s->temp.buf); + grub_memcpy (resulthash, s->crc32->read(hash_context), + s->crc32->mdlen); + readhash[0] = s->temp.buf[3]; + readhash[1] = s->temp.buf[2]; + readhash[2] = s->temp.buf[1]; + readhash[3] = s->temp.buf[0]; - if(resultcrc != readcrc) - return XZ_DATA_ERROR; + if(4 != s->crc32->mdlen + || grub_memcmp (readhash, resulthash, s->crc32->mdlen) != 0) + return XZ_DATA_ERROR; + } #endif + /* * Validate Backward Size. Note that we never added the size of the * Index CRC32 field to s->index.size, thus we use s->index.size / 4 @@ -447,7 +589,7 @@ static enum xz_ret dec_stream_footer(struct xz_dec *s) if ((s->index.size >> 2) != get_le32(s->temp.buf + 4)) return XZ_DATA_ERROR; - if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->has_crc32) + if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->hash_id) return XZ_DATA_ERROR; /* @@ -468,17 +610,27 @@ static enum xz_ret dec_block_header(struct xz_dec *s) */ s->temp.size -= 4; #ifndef GRUB_EMBED_DECOMPRESSOR - uint8_t crc32_context[GRUB_MD_CRC32->contextsize]; + if (s->crc32) + { + uint64_t hash_context[(s->crc32->contextsize + 7) / 8]; + uint8_t resulthash[s->crc32->mdlen]; + uint8_t readhash[4]; - GRUB_MD_CRC32->init(crc32_context); - GRUB_MD_CRC32->write(crc32_context, s->temp.buf, s->temp.size); - GRUB_MD_CRC32->final(crc32_context); + s->crc32->init(hash_context); + s->crc32->write(hash_context,s->temp.buf, s->temp.size); + s->crc32->final(hash_context); - uint32_t resultcrc = get_unaligned_be32(GRUB_MD_CRC32->read(crc32_context)); - uint32_t readcrc = get_unaligned_le32(s->temp.buf + s->temp.size); + grub_memcpy (resulthash, s->crc32->read(hash_context), + s->crc32->mdlen); + readhash[3] = s->temp.buf[s->temp.size]; + readhash[2] = s->temp.buf[s->temp.size + 1]; + readhash[1] = s->temp.buf[s->temp.size + 2]; + readhash[0] = s->temp.buf[s->temp.size + 3]; - if (resultcrc != readcrc) - return XZ_DATA_ERROR; + if(4 != s->crc32->mdlen + || grub_memcmp (readhash, resulthash, s->crc32->mdlen) != 0) + return XZ_DATA_ERROR; + } #endif s->temp.pos = 2; @@ -659,11 +811,9 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) s->sequence = SEQ_BLOCK_CHECK; case SEQ_BLOCK_CHECK: - if (s->has_crc32) { - ret = crc32_validate(s, b); - if (ret != XZ_STREAM_END) - return ret; - } + ret = hash_validate(s, b, 0); + if (ret != XZ_STREAM_END) + return ret; s->sequence = SEQ_BLOCK_START; break; @@ -691,24 +841,31 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) index_update(s, b); #ifndef GRUB_EMBED_DECOMPRESSOR - /* Compare the hashes to validate the Index field. */ - GRUB_MD_CRC32->final(s->block.hash.crc32_context); - GRUB_MD_CRC32->final(s->index.hash.crc32_context); - uint32_t block_crc = *(uint32_t*)GRUB_MD_CRC32->read(s->block.hash.crc32_context); - uint32_t index_crc = *(uint32_t*)GRUB_MD_CRC32->read(s->index.hash.crc32_context); - - if (s->block.hash.unpadded != s->index.hash.unpadded - || s->block.hash.uncompressed != s->index.hash.uncompressed - || block_crc != index_crc) + if (s->hash) { - return XZ_DATA_ERROR; + uint8_t block_hash[s->hash->mdlen]; + uint8_t index_hash[s->hash->mdlen]; + /* Compare the hashes to validate the Index field. */ + s->hash->final(s->block.hash.hash_context); + s->hash->final(s->index.hash.hash_context); + grub_memcpy (block_hash, + s->hash->read(s->block.hash.hash_context), + s->hash->mdlen); + grub_memcpy (index_hash, + s->hash->read(s->index.hash.hash_context), + s->hash->mdlen); + + if (s->block.hash.unpadded != s->index.hash.unpadded + || s->block.hash.uncompressed != s->index.hash.uncompressed + || grub_memcmp (block_hash, index_hash, s->hash->mdlen) != 0) + return XZ_DATA_ERROR; } #endif s->sequence = SEQ_INDEX_CRC32; case SEQ_INDEX_CRC32: - ret = crc32_validate(s, b); + ret = hash_validate(s, b, 1); if (ret != XZ_STREAM_END) return ret; @@ -802,46 +959,12 @@ struct xz_dec * xz_dec_init(uint32_t dict_max) return NULL; #endif + memset (s, 0, sizeof (*s)); + #ifndef GRUB_EMBED_DECOMPRESSOR - /* prepare CRC32 calculators */ - if(GRUB_MD_CRC32 == NULL) - { - kfree(s); - return NULL; - } - - s->crc32_context = kmalloc(GRUB_MD_CRC32->contextsize, GFP_KERNEL); - if (s->crc32_context == NULL) - { - kfree(s); - return NULL; - } - - s->index.hash.crc32_context = kmalloc(GRUB_MD_CRC32->contextsize, GFP_KERNEL); - if (s->index.hash.crc32_context == NULL) - { - kfree(s->crc32_context); - kfree(s); - return NULL; - } - - s->block.hash.crc32_context = kmalloc(GRUB_MD_CRC32->contextsize, GFP_KERNEL); - if (s->block.hash.crc32_context == NULL) - { - kfree(s->index.hash.crc32_context); - kfree(s->crc32_context); - kfree(s); - return NULL; - } - - - GRUB_MD_CRC32->init(s->crc32_context); - GRUB_MD_CRC32->init(s->index.hash.crc32_context); - GRUB_MD_CRC32->init(s->block.hash.crc32_context); + s->crc32 = grub_crypto_lookup_md_by_name ("CRC32"); #endif - s->crc32_temp = 0; - s->single_call = dict_max == 0; #ifdef XZ_DEC_BCJ @@ -876,28 +999,31 @@ void xz_dec_reset(struct xz_dec *s) { #ifndef GRUB_EMBED_DECOMPRESSOR - uint8_t *t; - t = s->block.hash.crc32_context; + uint64_t *t; + t = s->block.hash.hash_context; #endif memzero(&s->block, sizeof(s->block)); #ifndef GRUB_EMBED_DECOMPRESSOR - s->block.hash.crc32_context = t; - t = s->index.hash.crc32_context; + s->block.hash.hash_context = t; + t = s->index.hash.hash_context; #endif memzero(&s->index, sizeof(s->index)); #ifndef GRUB_EMBED_DECOMPRESSOR - s->index.hash.crc32_context = t; + s->index.hash.hash_context = t; #endif } s->temp.pos = 0; s->temp.size = STREAM_HEADER_SIZE; #ifndef GRUB_EMBED_DECOMPRESSOR - GRUB_MD_CRC32->init(s->crc32_context); - GRUB_MD_CRC32->init(s->index.hash.crc32_context); - GRUB_MD_CRC32->init(s->block.hash.crc32_context); + if (s->hash) + { + s->hash->init(s->hash_context); + s->hash->init(s->index.hash.hash_context); + s->hash->init(s->block.hash.hash_context); + } #endif - s->crc32_temp = 0; + s->have_hash_value = 0; } void xz_dec_end(struct xz_dec *s) @@ -905,8 +1031,9 @@ void xz_dec_end(struct xz_dec *s) if (s != NULL) { xz_dec_lzma2_end(s->lzma2); #ifndef GRUB_EMBED_DECOMPRESSOR - kfree(s->index.hash.crc32_context); - kfree(s->block.hash.crc32_context); + kfree(s->index.hash.hash_context); + kfree(s->block.hash.hash_context); + kfree(s->hash_context); kfree(s->crc32_context); #endif #ifdef XZ_DEC_BCJ diff --git a/util/import_gcry.py b/util/import_gcry.py index 7591d8f0e..ec34d16b5 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -83,6 +83,7 @@ cryptolist.write ("AES-192: gcry_rijndael\n"); cryptolist.write ("AES-256: gcry_rijndael\n"); cryptolist.write ("ADLER32: adler32\n"); +cryptolist.write ("CRC64: crc64\n"); for cipher_file in cipher_files: infile = os.path.join (cipher_dir_in, cipher_file)