64
67
/* CRC32 value in Block or Index */
65
uint32_t crc32_temp; /* need for crc32_validate*/
66
uint8_t *crc32_context;
68
#ifndef GRUB_EMBED_DECOMPRESSOR
69
uint8_t hash_value[MAX_HASH_SIZE]; /* need for crc32_validate*/
72
#ifndef GRUB_EMBED_DECOMPRESSOR
73
uint64_t *hash_context;
74
uint64_t *crc32_context;
68
/* True if CRC32 is calculated from uncompressed data */
77
/* Hash function calculated from uncompressed data */
78
#ifndef GRUB_EMBED_DECOMPRESSOR
79
const gcry_md_spec_t *hash;
80
const gcry_md_spec_t *crc32;
83
grub_size_t hash_size;
71
85
/* True if we are operating in single-call mode. */
250
264
return XZ_DATA_ERROR;
252
266
#ifndef GRUB_EMBED_DECOMPRESSOR
254
GRUB_MD_CRC32->write(s->crc32_context,b->out + s->out_start,
255
b->out_pos - s->out_start);
268
s->hash->write(s->hash_context,b->out + s->out_start,
269
b->out_pos - s->out_start);
271
s->crc32->write(s->crc32_context,b->out + s->out_start,
272
b->out_pos - s->out_start);
258
275
if (ret == XZ_STREAM_END) {
269
286
s->block.hash.unpadded += s->block_header.size
270
287
+ s->block.compressed;
272
s->block.hash.unpadded += 4;
288
s->block.hash.unpadded += s->hash_size;
274
290
s->block.hash.uncompressed += s->block.uncompressed;
276
292
#ifndef GRUB_EMBED_DECOMPRESSOR
277
GRUB_MD_CRC32->write(s->block.hash.crc32_context,
278
(const uint8_t *)&s->block.hash, 2 * sizeof(vli_type));
294
s->hash->write(s->block.hash.hash_context,
295
(const uint8_t *)&s->block.hash,
296
2 * sizeof(vli_type));
281
299
++s->block.count;
290
308
size_t in_used = b->in_pos - s->in_start;
291
309
s->index.size += in_used;
292
310
#ifndef GRUB_EMBED_DECOMPRESSOR
293
GRUB_MD_CRC32->write(s->crc32_context,b->in + s->in_start, in_used);
312
s->hash->write(s->hash_context,b->in + s->in_start, in_used);
314
s->crc32->write(s->crc32_context,b->in + s->in_start, in_used);
354
376
* Validate that the next four input bytes match the value of s->crc32.
355
377
* s->pos must be zero when starting to validate the first byte.
357
static enum xz_ret crc32_validate(struct xz_dec *s, struct xz_buf *b)
379
static enum xz_ret hash_validate(struct xz_dec *s, struct xz_buf *b,
359
382
#ifndef GRUB_EMBED_DECOMPRESSOR
360
if(s->crc32_temp == 0)
383
const gcry_md_spec_t *hash = crc32 ? s->crc32 : s->hash;
384
void *hash_context = crc32 ? s->crc32_context
386
if(!s->have_hash_value && hash
387
&& sizeof (s->hash_value) >= hash->mdlen)
362
GRUB_MD_CRC32->final(s->crc32_context);
363
s->crc32_temp = get_unaligned_be32(GRUB_MD_CRC32->read(s->crc32_context));
389
hash->final(hash_context);
390
grub_memcpy (s->hash_value, hash->read(hash_context),
392
s->have_hash_value = 1;
393
if (s->hash_id == 1 || crc32)
396
t = s->hash_value[0];
397
s->hash_value[0] = s->hash_value[3];
398
s->hash_value[3] = t;
399
t = s->hash_value[1];
400
s->hash_value[1] = s->hash_value[2];
401
s->hash_value[2] = t;
371
410
#ifndef GRUB_EMBED_DECOMPRESSOR
372
if (((s->crc32_temp >> s->pos) & 0xFF) != b->in[b->in_pos++])
411
if (hash && s->hash_value[s->pos / 8] != b->in[b->in_pos++])
373
412
return XZ_DATA_ERROR;
378
} while (s->pos < 32);
417
} while (s->pos < (crc32 ? 32 : s->hash_size * 8));
380
419
#ifndef GRUB_EMBED_DECOMPRESSOR
381
GRUB_MD_CRC32->init(s->crc32_context);
421
s->hash->init(s->hash_context);
423
s->crc32->init(s->crc32_context);
425
s->have_hash_value = 0;
386
428
return XZ_STREAM_END;
436
[0x01] = { "CRC32", 4},
437
[0x04] = { "CRC64", 8},
438
[0x0A] = { "SHA256", 32},
389
441
/* Decode the Stream Header field (the first 12 bytes of the .xz Stream). */
390
442
static enum xz_ret dec_stream_header(struct xz_dec *s)
393
445
return XZ_FORMAT_ERROR;
395
447
#ifndef GRUB_EMBED_DECOMPRESSOR
396
uint8_t crc32_context[GRUB_MD_CRC32->contextsize];
398
GRUB_MD_CRC32->init(crc32_context);
399
GRUB_MD_CRC32->write(crc32_context,s->temp.buf + HEADER_MAGIC_SIZE, 2);
400
GRUB_MD_CRC32->final(crc32_context);
402
uint32_t resultcrc = get_unaligned_be32(GRUB_MD_CRC32->read(crc32_context));
403
uint32_t readcrc = get_unaligned_le32(s->temp.buf + HEADER_MAGIC_SIZE + 2);
405
if(resultcrc != readcrc)
406
return XZ_DATA_ERROR;
448
s->crc32 = grub_crypto_lookup_md_by_name ("CRC32");
452
uint64_t hash_context[(s->crc32->contextsize + 7) / 8];
453
uint8_t resulthash[s->crc32->mdlen];
456
s->crc32->init(hash_context);
457
s->crc32->write(hash_context,s->temp.buf + HEADER_MAGIC_SIZE, 2);
458
s->crc32->final(hash_context);
460
grub_memcpy (resulthash, s->crc32->read(hash_context),
462
readhash[0] = s->temp.buf[HEADER_MAGIC_SIZE + 5];
463
readhash[1] = s->temp.buf[HEADER_MAGIC_SIZE + 4];
464
readhash[2] = s->temp.buf[HEADER_MAGIC_SIZE + 3];
465
readhash[3] = s->temp.buf[HEADER_MAGIC_SIZE + 2];
467
if(4 != s->crc32->mdlen
468
|| grub_memcmp (readhash, resulthash, s->crc32->mdlen) != 0)
469
return XZ_DATA_ERROR;
473
#ifndef GRUB_EMBED_DECOMPRESSOR
410
* Decode the Stream Flags field. Of integrity checks, we support
411
* only none (Check ID = 0) and CRC32 (Check ID = 1).
475
* Decode the Stream Flags field.
413
477
if (s->temp.buf[HEADER_MAGIC_SIZE] != 0
414
|| s->temp.buf[HEADER_MAGIC_SIZE + 1] > 1)
478
|| s->temp.buf[HEADER_MAGIC_SIZE + 1] >= ARRAY_SIZE (hashes)
479
|| (hashes[s->temp.buf[HEADER_MAGIC_SIZE + 1]].name == 0
480
&& s->temp.buf[HEADER_MAGIC_SIZE + 1] != 0))
415
481
return XZ_OPTIONS_ERROR;
417
s->has_crc32 = s->temp.buf[HEADER_MAGIC_SIZE + 1];
483
s->hash_id = s->temp.buf[HEADER_MAGIC_SIZE + 1];
487
s->crc32_context = kmalloc(s->crc32->contextsize, GFP_KERNEL);
488
if (s->crc32_context == NULL)
489
return XZ_MEMLIMIT_ERROR;
490
s->crc32->init(s->crc32_context);
494
if (s->temp.buf[HEADER_MAGIC_SIZE + 1])
496
s->hash_size = hashes[s->temp.buf[HEADER_MAGIC_SIZE + 1]].size;
497
#ifndef GRUB_EMBED_DECOMPRESSOR
498
s->hash = grub_crypto_lookup_md_by_name (hashes[s->temp.buf[HEADER_MAGIC_SIZE + 1]].name);
501
if (s->hash->mdlen != s->hash_size)
502
return XZ_OPTIONS_ERROR;
503
s->hash_context = kmalloc(s->hash->contextsize, GFP_KERNEL);
504
if (s->hash_context == NULL)
506
kfree(s->crc32_context);
507
return XZ_MEMLIMIT_ERROR;
510
s->index.hash.hash_context = kmalloc(s->hash->contextsize,
512
if (s->index.hash.hash_context == NULL)
514
kfree(s->hash_context);
515
kfree(s->crc32_context);
516
return XZ_MEMLIMIT_ERROR;
519
s->block.hash.hash_context = kmalloc(s->hash->contextsize, GFP_KERNEL);
520
if (s->block.hash.hash_context == NULL)
522
kfree(s->index.hash.hash_context);
523
kfree(s->hash_context);
524
kfree(s->crc32_context);
525
return XZ_MEMLIMIT_ERROR;
528
s->hash->init(s->hash_context);
529
s->hash->init(s->index.hash.hash_context);
530
s->hash->init(s->block.hash.hash_context);
533
return XZ_OPTIONS_ERROR;
538
#ifndef GRUB_EMBED_DECOMPRESSOR
544
s->have_hash_value = 0;
426
554
return XZ_DATA_ERROR;
428
556
#ifndef GRUB_EMBED_DECOMPRESSOR
429
uint8_t crc32_context[GRUB_MD_CRC32->contextsize];
431
GRUB_MD_CRC32->init(crc32_context);
432
GRUB_MD_CRC32->write(crc32_context, s->temp.buf + 4, 6);
433
GRUB_MD_CRC32->final(crc32_context);
435
uint32_t resultcrc = get_unaligned_be32(GRUB_MD_CRC32->read(crc32_context));
436
uint32_t readcrc = get_unaligned_le32(s->temp.buf);
438
if(resultcrc != readcrc)
439
return XZ_DATA_ERROR;
559
uint64_t hash_context[(s->crc32->contextsize + 7) / 8];
560
uint8_t resulthash[s->crc32->mdlen];
563
s->crc32->init(hash_context);
564
s->crc32->write(hash_context,s->temp.buf + 4, 6);
565
s->crc32->final(hash_context);
567
grub_memcpy (resulthash, s->crc32->read(hash_context),
569
readhash[0] = s->temp.buf[3];
570
readhash[1] = s->temp.buf[2];
571
readhash[2] = s->temp.buf[1];
572
readhash[3] = s->temp.buf[0];
574
if(4 != s->crc32->mdlen
575
|| grub_memcmp (readhash, resulthash, s->crc32->mdlen) != 0)
576
return XZ_DATA_ERROR;
443
582
* Validate Backward Size. Note that we never added the size of the
444
583
* Index CRC32 field to s->index.size, thus we use s->index.size / 4
469
610
s->temp.size -= 4;
470
611
#ifndef GRUB_EMBED_DECOMPRESSOR
471
uint8_t crc32_context[GRUB_MD_CRC32->contextsize];
473
GRUB_MD_CRC32->init(crc32_context);
474
GRUB_MD_CRC32->write(crc32_context, s->temp.buf, s->temp.size);
475
GRUB_MD_CRC32->final(crc32_context);
477
uint32_t resultcrc = get_unaligned_be32(GRUB_MD_CRC32->read(crc32_context));
478
uint32_t readcrc = get_unaligned_le32(s->temp.buf + s->temp.size);
480
if (resultcrc != readcrc)
481
return XZ_DATA_ERROR;
614
uint64_t hash_context[(s->crc32->contextsize + 7) / 8];
615
uint8_t resulthash[s->crc32->mdlen];
618
s->crc32->init(hash_context);
619
s->crc32->write(hash_context,s->temp.buf, s->temp.size);
620
s->crc32->final(hash_context);
622
grub_memcpy (resulthash, s->crc32->read(hash_context),
624
readhash[3] = s->temp.buf[s->temp.size];
625
readhash[2] = s->temp.buf[s->temp.size + 1];
626
readhash[1] = s->temp.buf[s->temp.size + 2];
627
readhash[0] = s->temp.buf[s->temp.size + 3];
629
if(4 != s->crc32->mdlen
630
|| grub_memcmp (readhash, resulthash, s->crc32->mdlen) != 0)
631
return XZ_DATA_ERROR;
691
840
index_update(s, b);
693
842
#ifndef GRUB_EMBED_DECOMPRESSOR
694
/* Compare the hashes to validate the Index field. */
695
GRUB_MD_CRC32->final(s->block.hash.crc32_context);
696
GRUB_MD_CRC32->final(s->index.hash.crc32_context);
697
uint32_t block_crc = *(uint32_t*)GRUB_MD_CRC32->read(s->block.hash.crc32_context);
698
uint32_t index_crc = *(uint32_t*)GRUB_MD_CRC32->read(s->index.hash.crc32_context);
700
if (s->block.hash.unpadded != s->index.hash.unpadded
701
|| s->block.hash.uncompressed != s->index.hash.uncompressed
702
|| block_crc != index_crc)
704
return XZ_DATA_ERROR;
845
uint8_t block_hash[s->hash->mdlen];
846
uint8_t index_hash[s->hash->mdlen];
847
/* Compare the hashes to validate the Index field. */
848
s->hash->final(s->block.hash.hash_context);
849
s->hash->final(s->index.hash.hash_context);
850
grub_memcpy (block_hash,
851
s->hash->read(s->block.hash.hash_context),
853
grub_memcpy (index_hash,
854
s->hash->read(s->index.hash.hash_context),
857
if (s->block.hash.unpadded != s->index.hash.unpadded
858
|| s->block.hash.uncompressed != s->index.hash.uncompressed
859
|| grub_memcmp (block_hash, index_hash, s->hash->mdlen) != 0)
860
return XZ_DATA_ERROR;
708
864
s->sequence = SEQ_INDEX_CRC32;
710
866
case SEQ_INDEX_CRC32:
711
ret = crc32_validate(s, b);
867
ret = hash_validate(s, b, 1);
712
868
if (ret != XZ_STREAM_END)
805
#ifndef GRUB_EMBED_DECOMPRESSOR
806
/* prepare CRC32 calculators */
807
if(GRUB_MD_CRC32 == NULL)
813
s->crc32_context = kmalloc(GRUB_MD_CRC32->contextsize, GFP_KERNEL);
814
if (s->crc32_context == NULL)
820
s->index.hash.crc32_context = kmalloc(GRUB_MD_CRC32->contextsize, GFP_KERNEL);
821
if (s->index.hash.crc32_context == NULL)
823
kfree(s->crc32_context);
828
s->block.hash.crc32_context = kmalloc(GRUB_MD_CRC32->contextsize, GFP_KERNEL);
829
if (s->block.hash.crc32_context == NULL)
831
kfree(s->index.hash.crc32_context);
832
kfree(s->crc32_context);
838
GRUB_MD_CRC32->init(s->crc32_context);
839
GRUB_MD_CRC32->init(s->index.hash.crc32_context);
840
GRUB_MD_CRC32->init(s->block.hash.crc32_context);
961
memset (s, 0, sizeof (*s));
845
963
s->single_call = dict_max == 0;
878
996
#ifndef GRUB_EMBED_DECOMPRESSOR
880
t = s->block.hash.crc32_context;
998
t = s->block.hash.hash_context;
882
1000
memzero(&s->block, sizeof(s->block));
883
1001
#ifndef GRUB_EMBED_DECOMPRESSOR
884
s->block.hash.crc32_context = t;
885
t = s->index.hash.crc32_context;
1002
s->block.hash.hash_context = t;
1003
t = s->index.hash.hash_context;
887
1005
memzero(&s->index, sizeof(s->index));
888
1006
#ifndef GRUB_EMBED_DECOMPRESSOR
889
s->index.hash.crc32_context = t;
1007
s->index.hash.hash_context = t;
892
1010
s->temp.pos = 0;
893
1011
s->temp.size = STREAM_HEADER_SIZE;
895
1013
#ifndef GRUB_EMBED_DECOMPRESSOR
896
GRUB_MD_CRC32->init(s->crc32_context);
897
GRUB_MD_CRC32->init(s->index.hash.crc32_context);
898
GRUB_MD_CRC32->init(s->block.hash.crc32_context);
1016
s->hash->init(s->hash_context);
1017
s->hash->init(s->index.hash.hash_context);
1018
s->hash->init(s->block.hash.hash_context);
1021
s->have_hash_value = 0;
903
1024
void xz_dec_end(struct xz_dec *s)