merge mainline into net

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-12-15 20:51:35 +01:00
commit bd67ad0f70
335 changed files with 22289 additions and 5940 deletions

View file

@ -1994,13 +1994,15 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
{
UInt32 beforeSize = kNumOpts;
#ifdef COMPRESS_MF_MT
Bool btMode;
#endif
if (!RangeEnc_Alloc(&p->rc, alloc))
return SZ_ERROR_MEM;
#ifdef COMPRESS_MF_MT
btMode = (p->matchFinderBase.btMode != 0);
#ifdef COMPRESS_MF_MT
p->mtMode = (p->multiThread && !p->fastMode && btMode);
#endif
#endif
{
unsigned lclp = p->lc + p->lp;

153
grub-core/lib/adler32.c Normal file
View file

@ -0,0 +1,153 @@
/* adler32.c - adler32 check. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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 <http://www.gnu.org/licenses/>.
*/
#include <grub/types.h>
#include <grub/dl.h>
#include <grub/crypto.h>
GRUB_MOD_LICENSE ("GPLv3+");
/* Based on adler32() from adler32.c of zlib-1.2.5 library. */
#define BASE 65521UL
#define NMAX 5552
#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf,0); DO8(buf,8);
static grub_uint32_t
update_adler32 (grub_uint32_t adler, const grub_uint8_t *buf, grub_size_t len)
{
unsigned long sum2;
unsigned int n;
sum2 = (adler >> 16) & 0xffff;
adler &= 0xffff;
if (len == 1)
{
adler += buf[0];
if (adler >= BASE)
adler -= BASE;
sum2 += adler;
if (sum2 >= BASE)
sum2 -= BASE;
return adler | (sum2 << 16);
}
if (len < 16)
{
while (len--)
{
adler += *buf++;
sum2 += adler;
}
if (adler >= BASE)
adler -= BASE;
sum2 %= BASE;
return adler | (sum2 << 16);
}
while (len >= NMAX)
{
len -= NMAX;
n = NMAX / 16;
do
{
DO16 (buf);
buf += 16;
}
while (--n);
adler %= BASE;
sum2 %= BASE;
}
if (len)
{
while (len >= 16)
{
len -= 16;
DO16 (buf);
buf += 16;
}
while (len--)
{
adler += *buf++;
sum2 += adler;
}
adler %= BASE;
sum2 %= BASE;
}
return adler | (sum2 << 16);
}
typedef struct
{
grub_uint32_t adler;
}
adler32_context;
static void
adler32_init (void *context)
{
adler32_context *ctx = (adler32_context *) context;
ctx->adler = 1;
}
static void
adler32_write (void *context, const void *inbuf, grub_size_t inlen)
{
adler32_context *ctx = (adler32_context *) context;
if (!inbuf)
return;
ctx->adler = update_adler32 (ctx->adler, inbuf, inlen);
}
static grub_uint8_t *
adler32_read (void *context)
{
adler32_context *ctx = (adler32_context *) context;
return (grub_uint8_t *) &ctx->adler;
}
static void
adler32_final (void *context __attribute__ ((unused)))
{
}
gcry_md_spec_t _gcry_digest_spec_adler32 = {
"ADLER32",0 , 0, 0 , 4,
adler32_init, adler32_write, adler32_final, adler32_read,
sizeof (adler32_context),
.blocksize = 64
};
GRUB_MOD_INIT(adler32)
{
grub_md_register (&_gcry_digest_spec_adler32);
}
GRUB_MOD_FINI(adler32)
{
grub_md_unregister (&_gcry_digest_spec_adler32);
}

113
grub-core/lib/crc64.c Normal file
View file

@ -0,0 +1,113 @@
/* 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 <http://www.gnu.org/licenses/>.
*/
#include <grub/types.h>
#include <grub/dl.h>
#include <grub/crypto.h>
GRUB_MOD_LICENSE ("GPLv3+");
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);
}

View file

@ -169,28 +169,6 @@ grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher,
return cipher->cipher->setkey (cipher->ctx, key, keylen);
}
void
grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher)
{
grub_free (cipher);
}
void
grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size)
{
const grub_uint8_t *in1ptr = in1, *in2ptr = in2;
grub_uint8_t *outptr = out;
while (size--)
{
*outptr = *in1ptr ^ *in2ptr;
in1ptr++;
in2ptr++;
outptr++;
}
}
gcry_err_code_t
grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher,
void *out, const void *in, grub_size_t size)
@ -210,9 +188,10 @@ grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher,
gcry_err_code_t
grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher,
void *out, void *in, grub_size_t size)
void *out, const void *in, grub_size_t size)
{
grub_uint8_t *inptr, *outptr, *end;
const grub_uint8_t *inptr;
grub_uint8_t *outptr, *end;
if (!cipher->cipher->encrypt)
return GPG_ERR_NOT_SUPPORTED;
if (size % cipher->cipher->blocksize != 0)

View file

@ -0,0 +1,32 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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 <http://www.gnu.org/licenses/>.
*/
#include <grub/efi/api.h>
#include <grub/efi/efi.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/kernel.h>
void
grub_reboot (void)
{
grub_machine_fini ();
efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL);
for (;;) ;
}

View file

@ -19,6 +19,7 @@
#include <grub/cpu/io.h>
#include <grub/misc.h>
#include <grub/acpi.h>
#include <grub/i18n.h>
const char bochs_shutdown[] = "Shutdown";
@ -52,7 +53,7 @@ grub_halt (void)
for (i = 0; i < sizeof (bochs_shutdown) - 1; i++)
grub_outb (bochs_shutdown[i], 0x8900);
grub_printf ("GRUB doesn't know how to halt this machine yet!\n");
grub_puts_ (N_("GRUB doesn't know how to halt this machine yet!"));
/* In order to return we'd have to check what the previous status of IF
flag was. But user most likely doesn't want to return anyway ... */

View file

@ -24,7 +24,7 @@
static int
grub_get_root_biosnumber_default (void)
{
char *biosnum;
const char *biosnum;
int ret = -1;
grub_device_t dev;

View file

@ -0,0 +1,60 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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 <http://www.gnu.org/licenses/>.
*/
#include <grub/relocator.h>
#include <grub/cpu/relocator.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/cpu/reboot.h>
#include <grub/i386/floppy.h>
void
grub_reboot (void)
{
struct grub_relocator *relocator = NULL;
grub_relocator_chunk_t ch;
grub_err_t err;
void *buf;
struct grub_relocator16_state state;
grub_uint16_t segment;
relocator = grub_relocator_new ();
if (!relocator)
while (1);
err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000, 0x1000,
grub_reboot_end - grub_reboot_start,
16, GRUB_RELOCATOR_PREFERENCE_NONE);
if (err)
while (1);
buf = get_virtual_current_address (ch);
grub_memcpy (buf, grub_reboot_start, grub_reboot_end - grub_reboot_start);
segment = ((grub_addr_t) get_physical_target_address (ch)) >> 4;
state.gs = state.fs = state.es = state.ds = state.ss = segment;
state.sp = 0;
state.cs = segment;
state.ip = 0;
state.a20 = 0;
grub_stop_floppy ();
err = grub_relocator16_boot (relocator, state);
while (1);
}

View file

@ -0,0 +1,34 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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 <http://www.gnu.org/licenses/>.
*/
#include <grub/symbol.h>
#include <grub/i386/reboot.h>
.p2align 4
VARIABLE(grub_reboot_start)
.code16
/* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */
movw $0x0472, %di
xorw %ax, %ax
movw %ax, (%di)
ljmp $0xf000, $0xfff0
.code32
VARIABLE(grub_reboot_end)

View file

@ -51,6 +51,9 @@ extern grub_uint16_t grub_relocator16_ss;
extern grub_uint16_t grub_relocator16_sp;
extern grub_uint32_t grub_relocator16_edx;
extern grub_uint32_t grub_relocator16_ebx;
extern grub_uint32_t grub_relocator16_esi;
extern grub_uint16_t grub_relocator16_keep_a20_enabled;
extern grub_uint8_t grub_relocator32_start;
extern grub_uint8_t grub_relocator32_end;
@ -195,7 +198,8 @@ grub_relocator16_boot (struct grub_relocator *rel,
void *relst;
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
/* Put it higher than the byte it checks for A20 check. */
err = grub_relocator_alloc_chunk_align (rel, &ch, 0x8010,
0xa0000 - RELOCATOR_SIZEOF (16),
RELOCATOR_SIZEOF (16), 16,
GRUB_RELOCATOR_PREFERENCE_NONE);
@ -215,6 +219,9 @@ grub_relocator16_boot (struct grub_relocator *rel,
grub_relocator16_ebx = state.ebx;
grub_relocator16_edx = state.edx;
grub_relocator16_esi = state.esi;
grub_relocator16_keep_a20_enabled = state.a20;
grub_memmove (get_virtual_current_address (ch), &grub_relocator16_start,
RELOCATOR_SIZEOF (16));

View file

@ -93,6 +93,85 @@ LOCAL(segment):
.word 0
LOCAL(cont3):
/* movw imm16, %ax. */
.byte 0xb8
VARIABLE(grub_relocator16_keep_a20_enabled)
.word 0
test %ax, %ax
jnz LOCAL(gate_a20_done)
/* first of all, test if already in a good state */
call LOCAL(gate_a20_check_state)
testb %al, %al
jz LOCAL(gate_a20_done)
/* second, try a BIOS call */
movw $0x2400, %ax
int $0x15
call LOCAL(gate_a20_check_state)
testb %al, %al
jz LOCAL(gate_a20_done)
/*
* In macbook, the keyboard test would hang the machine, so we move
* this forward.
*/
/* fourth, try the system control port A */
inb $0x92
andb $(~0x03), %al
outb $0x92
/* When turning off Gate A20, do not check the state strictly,
because a failure is not fatal usually, and Gate A20 is always
on some modern machines. */
jmp LOCAL(gate_a20_done)
LOCAL(gate_a20_check_state):
/* iterate the checking for a while */
movw $100, %cx
1:
call 3f
testb %al, %al
jz 2f
loop 1b
2:
ret
3:
xorw %ax, %ax
movw %ax, %ds
decw %ax
movw %ax, %es
xorw %ax, %ax
movw $0x8000, %ax
/* compare the byte at ADDR with that at 0x100000 + ADDR */
movw %ax, %si
addw $0x10, %ax
movw %ax, %di
/* save the original byte in DL */
movb %ds:(%si), %dl
movb %es:(%di), %al
/* try to set one less value at ADDR */
movb %al, %dh
decb %dh
movb %dh, %ds:(%si)
/* serialize */
outb %al, $0x80
outb %al, $0x80
/* obtain the value at 0x100000 + ADDR in CH */
movb %es:(%di), %dh
/* this result is 1 if A20 is on or 0 if it is off */
subb %dh, %al
xorb $1, %al
/* restore the original */
movb %dl, %es:(%di)
ret
LOCAL(gate_a20_done):
/* we are in real mode now
* set up the real mode segment registers : DS, SS, ES
*/
@ -132,6 +211,12 @@ VARIABLE(grub_relocator16_sp)
.word 0
movzwl %ax, %esp
/* movw imm32, %eax. */
.byte 0x66, 0xb8
VARIABLE(grub_relocator16_esi)
.long 0
movl %eax, %esi
/* movw imm32, %edx. */
.byte 0x66, 0xba
VARIABLE(grub_relocator16_edx)

View file

@ -0,0 +1,27 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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 <http://www.gnu.org/licenses/>.
*/
#include <grub/ieee1275/ieee1275.h>
#include <grub/misc.h>
void
grub_reboot (void)
{
grub_ieee1275_interpret ("reset-all", 0);
for (;;) ;
}

View file

@ -59,6 +59,9 @@ struct legacy_command
const char *longdesc;
};
/* Help texts are kept here mostly for reference. They are never shown. So
no need to gettextize.
*/
static struct legacy_command legacy_commands[] =
{
{"blocklist", "blocklist '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILE",
@ -412,7 +415,7 @@ adjust_file (const char *in, grub_size_t len)
}
static int
check_option (const char *a, char *b, grub_size_t len)
check_option (const char *a, const char *b, grub_size_t len)
{
if (grub_strlen (b) != len)
return 0;

View file

@ -101,7 +101,8 @@ transform ( MD4_CONTEXT *ctx, const unsigned char *data )
#ifdef WORDS_BIGENDIAN
{
int i;
byte *p2, *p1;
byte *p2;
const byte *p1;
for(i=0, p1=data, p2=(byte*)in; i < 16; i++, p2 += 4 )
{
p2[3] = *p1++;

View file

@ -92,7 +92,8 @@ transform ( MD5_CONTEXT *ctx, const unsigned char *data )
#ifdef WORDS_BIGENDIAN
{
int i;
byte *p2, *p1;
byte *p2;
const byte *p1;
for(i=0, p1=data, p2=(byte*)correct_words; i < 16; i++, p2 += 4 )
{
p2[3] = *p1++;

View file

@ -169,7 +169,8 @@ transform ( RMD160_CONTEXT *hd, const unsigned char *data )
u32 x[16];
{
int i;
byte *p2, *p1;
byte *p2;
const byte *p1;
for (i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 )
{
p2[3] = *p1++;

View file

@ -585,22 +585,19 @@ serpent_key_prepare (const byte *key, unsigned int key_length,
int i;
/* Copy key. */
for (i = 0; i < key_length / 4; i++)
{
memcpy (key_prepared, key, key_length);
#ifdef WORDS_BIGENDIAN
key_prepared[i] = byte_swap_32 (((u32 *) key)[i]);
#else
key_prepared[i] = ((u32 *) key)[i];
for (i = 0; i < key_length / 4; i++)
key_prepared[i] = byte_swap_32 (key_prepared[i]);
#endif
}
if (i < 8)
if (key_length < 32)
{
/* Key must be padded according to the Serpent
specification. */
key_prepared[i] = 0x00000001;
key_prepared[key_length / 4] = 0x00000001;
for (i++; i < 8; i++)
for (i = key_length / 4 + 1; i < 8; i++)
key_prepared[i] = 0;
}
}
@ -707,21 +704,17 @@ serpent_setkey (void *ctx,
static void
serpent_encrypt_internal (serpent_context_t *context,
const serpent_block_t input, serpent_block_t output)
const byte *input, byte *output)
{
serpent_block_t b, b_next;
int round = 0;
memcpy (b, input, sizeof (b));
#ifdef WORDS_BIGENDIAN
b[0] = byte_swap_32 (input[0]);
b[1] = byte_swap_32 (input[1]);
b[2] = byte_swap_32 (input[2]);
b[3] = byte_swap_32 (input[3]);
#else
b[0] = input[0];
b[1] = input[1];
b[2] = input[2];
b[3] = input[3];
b[0] = byte_swap_32 (b[0]);
b[1] = byte_swap_32 (b[1]);
b[2] = byte_swap_32 (b[2]);
b[3] = byte_swap_32 (b[3]);
#endif
ROUND (0, context->keys, b, b_next);
@ -759,35 +752,27 @@ serpent_encrypt_internal (serpent_context_t *context,
ROUND_LAST (7, context->keys, b, b_next);
#ifdef WORDS_BIGENDIAN
output[0] = byte_swap_32 (b_next[0]);
output[1] = byte_swap_32 (b_next[1]);
output[2] = byte_swap_32 (b_next[2]);
output[3] = byte_swap_32 (b_next[3]);
#else
output[0] = b_next[0];
output[1] = b_next[1];
output[2] = b_next[2];
output[3] = b_next[3];
b_next[0] = byte_swap_32 (b_next[0]);
b_next[1] = byte_swap_32 (b_next[1]);
b_next[2] = byte_swap_32 (b_next[2]);
b_next[3] = byte_swap_32 (b_next[3]);
#endif
memcpy (output, b_next, sizeof (b_next));
}
static void
serpent_decrypt_internal (serpent_context_t *context,
const serpent_block_t input, serpent_block_t output)
const byte *input, byte *output)
{
serpent_block_t b, b_next;
int round = ROUNDS;
memcpy (b, input, sizeof (b));
#ifdef WORDS_BIGENDIAN
b_next[0] = byte_swap_32 (input[0]);
b_next[1] = byte_swap_32 (input[1]);
b_next[2] = byte_swap_32 (input[2]);
b_next[3] = byte_swap_32 (input[3]);
#else
b_next[0] = input[0];
b_next[1] = input[1];
b_next[2] = input[2];
b_next[3] = input[3];
b[0] = byte_swap_32 (b[0]);
b[1] = byte_swap_32 (b[1]);
b[2] = byte_swap_32 (b[2]);
b[3] = byte_swap_32 (b[3]);
#endif
ROUND_FIRST_INVERSE (7, context->keys, b_next, b);
@ -824,18 +809,13 @@ serpent_decrypt_internal (serpent_context_t *context,
ROUND_INVERSE (1, context->keys, b, b_next);
ROUND_INVERSE (0, context->keys, b, b_next);
#ifdef WORDS_BIGENDIAN
output[0] = byte_swap_32 (b_next[0]);
output[1] = byte_swap_32 (b_next[1]);
output[2] = byte_swap_32 (b_next[2]);
output[3] = byte_swap_32 (b_next[3]);
#else
output[0] = b_next[0];
output[1] = b_next[1];
output[2] = b_next[2];
output[3] = b_next[3];
b_next[0] = byte_swap_32 (b_next[0]);
b_next[1] = byte_swap_32 (b_next[1]);
b_next[2] = byte_swap_32 (b_next[2]);
b_next[3] = byte_swap_32 (b_next[3]);
#endif
memcpy (output, b_next, sizeof (b_next));
}
static void
@ -843,8 +823,7 @@ serpent_encrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
{
serpent_context_t *context = ctx;
serpent_encrypt_internal (context,
(const u32 *) buffer_in, (u32 *) buffer_out);
serpent_encrypt_internal (context, buffer_in, buffer_out);
_gcry_burn_stack (2 * sizeof (serpent_block_t));
}
@ -853,9 +832,7 @@ serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
{
serpent_context_t *context = ctx;
serpent_decrypt_internal (context,
(const u32 *) buffer_in,
(u32 *) buffer_out);
serpent_decrypt_internal (context, buffer_in, buffer_out);
_gcry_burn_stack (2 * sizeof (serpent_block_t));
}
@ -915,8 +892,8 @@ serpent_test (void)
serpent_setkey_internal (&context, test_data[i].key,
test_data[i].key_length);
serpent_encrypt_internal (&context,
(const u32 *) test_data[i].text_plain,
(u32 *) scratch);
test_data[i].text_plain,
scratch);
if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t)))
switch (test_data[i].key_length)
@ -930,8 +907,8 @@ serpent_test (void)
}
serpent_decrypt_internal (&context,
(const u32 *) test_data[i].text_cipher,
(u32 *) scratch);
test_data[i].text_cipher,
scratch);
if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t)))
switch (test_data[i].key_length)
{

View file

@ -87,6 +87,25 @@ fips_mode (void)
return 0;
}
#define memset grub_memset
#ifdef GRUB_UTIL
static inline void *
memcpy (void *dest, const void *src, grub_size_t n)
{
return grub_memcpy (dest, src, n);
}
static inline void *
memset (void *s, int c, grub_size_t n)
{
return grub_memset (s, c, n);
}
static inline int
memcmp (const void *s1, const void *s2, grub_size_t n)
{
return grub_memcmp (s1, s2, n);
}
#endif
#endif

View file

@ -0,0 +1,446 @@
/* lzoconf.h -- configuration of the LZO data compression library
This file is part of the LZO real-time data compression library.
Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
The LZO library 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 2 of
the License, or (at your option) any later version.
The LZO library 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 the LZO library; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Markus F.X.J. Oberhumer
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/lzo/
*/
#ifndef __LZOCONF_H_INCLUDED
#define __LZOCONF_H_INCLUDED 1
#define LZO_VERSION 0x2050
#define LZO_VERSION_STRING "2.05"
#define LZO_VERSION_DATE "Apr 23 2011"
/* internal Autoconf configuration file - only used when building LZO */
#if defined(LZO_HAVE_CONFIG_H)
# include <config.h>
#endif
#include <limits.h>
#include <stddef.h>
/***********************************************************************
// LZO requires a conforming <limits.h>
************************************************************************/
#if !defined(CHAR_BIT) || (CHAR_BIT != 8)
# error "invalid CHAR_BIT"
#endif
#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX)
# error "check your compiler installation"
#endif
#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1)
# error "your limits.h macros are broken"
#endif
/* get OS and architecture defines */
#ifndef __LZODEFS_H_INCLUDED
#include "lzodefs.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/***********************************************************************
// some core defines
************************************************************************/
#if !defined(LZO_UINT32_C)
# if (UINT_MAX < LZO_0xffffffffL)
# define LZO_UINT32_C(c) c ## UL
# else
# define LZO_UINT32_C(c) ((c) + 0U)
# endif
#endif
/* memory checkers */
#if !defined(__LZO_CHECKER)
# if defined(__BOUNDS_CHECKING_ON)
# define __LZO_CHECKER 1
# elif defined(__CHECKER__)
# define __LZO_CHECKER 1
# elif defined(__INSURE__)
# define __LZO_CHECKER 1
# elif defined(__PURIFY__)
# define __LZO_CHECKER 1
# endif
#endif
/***********************************************************************
// integral and pointer types
************************************************************************/
/* lzo_uint should match size_t */
#if !defined(LZO_UINT_MAX)
# if defined(LZO_ABI_LLP64) /* WIN64 */
# if defined(LZO_OS_WIN64)
typedef unsigned __int64 lzo_uint;
typedef __int64 lzo_int;
# else
typedef unsigned long long lzo_uint;
typedef long long lzo_int;
# endif
# define LZO_UINT_MAX 0xffffffffffffffffull
# define LZO_INT_MAX 9223372036854775807LL
# define LZO_INT_MIN (-1LL - LZO_INT_MAX)
# elif defined(LZO_ABI_IP32L64) /* MIPS R5900 */
typedef unsigned int lzo_uint;
typedef int lzo_int;
# define LZO_UINT_MAX UINT_MAX
# define LZO_INT_MAX INT_MAX
# define LZO_INT_MIN INT_MIN
# elif (ULONG_MAX >= LZO_0xffffffffL)
typedef unsigned long lzo_uint;
typedef long lzo_int;
# define LZO_UINT_MAX ULONG_MAX
# define LZO_INT_MAX LONG_MAX
# define LZO_INT_MIN LONG_MIN
# else
# error "lzo_uint"
# endif
#endif
/* Integral types with 32 bits or more. */
#if !defined(LZO_UINT32_MAX)
# if (UINT_MAX >= LZO_0xffffffffL)
typedef unsigned int lzo_uint32;
typedef int lzo_int32;
# define LZO_UINT32_MAX UINT_MAX
# define LZO_INT32_MAX INT_MAX
# define LZO_INT32_MIN INT_MIN
# elif (ULONG_MAX >= LZO_0xffffffffL)
typedef unsigned long lzo_uint32;
typedef long lzo_int32;
# define LZO_UINT32_MAX ULONG_MAX
# define LZO_INT32_MAX LONG_MAX
# define LZO_INT32_MIN LONG_MIN
# else
# error "lzo_uint32"
# endif
#endif
/* Integral types with exactly 64 bits. */
#if !defined(LZO_UINT64_MAX)
# if (LZO_UINT_MAX >= LZO_0xffffffffL)
# if ((((LZO_UINT_MAX) >> 31) >> 31) == 3)
# define lzo_uint64 lzo_uint
# define lzo_int64 lzo_int
# define LZO_UINT64_MAX LZO_UINT_MAX
# define LZO_INT64_MAX LZO_INT_MAX
# define LZO_INT64_MIN LZO_INT_MIN
# endif
# elif (ULONG_MAX >= LZO_0xffffffffL)
# if ((((ULONG_MAX) >> 31) >> 31) == 3)
typedef unsigned long lzo_uint64;
typedef long lzo_int64;
# define LZO_UINT64_MAX ULONG_MAX
# define LZO_INT64_MAX LONG_MAX
# define LZO_INT64_MIN LONG_MIN
# endif
# endif
#endif
/* The larger type of lzo_uint and lzo_uint32. */
#if (LZO_UINT_MAX >= LZO_UINT32_MAX)
# define lzo_xint lzo_uint
#else
# define lzo_xint lzo_uint32
#endif
/* Memory model that allows to access memory at offsets of lzo_uint. */
#if !defined(__LZO_MMODEL)
# if (LZO_UINT_MAX <= UINT_MAX)
# define __LZO_MMODEL /*empty*/
# elif defined(LZO_HAVE_MM_HUGE_PTR)
# define __LZO_MMODEL_HUGE 1
# define __LZO_MMODEL __huge
# else
# define __LZO_MMODEL /*empty*/
# endif
#endif
/* no typedef here because of const-pointer issues */
#define lzo_bytep unsigned char __LZO_MMODEL *
#define lzo_charp char __LZO_MMODEL *
#define lzo_voidp void __LZO_MMODEL *
#define lzo_shortp short __LZO_MMODEL *
#define lzo_ushortp unsigned short __LZO_MMODEL *
#define lzo_uint32p lzo_uint32 __LZO_MMODEL *
#define lzo_int32p lzo_int32 __LZO_MMODEL *
#if defined(LZO_UINT64_MAX)
#define lzo_uint64p lzo_uint64 __LZO_MMODEL *
#define lzo_int64p lzo_int64 __LZO_MMODEL *
#endif
#define lzo_uintp lzo_uint __LZO_MMODEL *
#define lzo_intp lzo_int __LZO_MMODEL *
#define lzo_xintp lzo_xint __LZO_MMODEL *
#define lzo_voidpp lzo_voidp __LZO_MMODEL *
#define lzo_bytepp lzo_bytep __LZO_MMODEL *
/* deprecated - use 'lzo_bytep' instead of 'lzo_byte *' */
#define lzo_byte unsigned char __LZO_MMODEL
typedef int lzo_bool;
/***********************************************************************
// function types
************************************************************************/
/* name mangling */
#if !defined(__LZO_EXTERN_C)
# ifdef __cplusplus
# define __LZO_EXTERN_C extern "C"
# else
# define __LZO_EXTERN_C extern
# endif
#endif
/* calling convention */
#if !defined(__LZO_CDECL)
# define __LZO_CDECL __lzo_cdecl
#endif
/* DLL export information */
#if !defined(__LZO_EXPORT1)
# define __LZO_EXPORT1 /*empty*/
#endif
#if !defined(__LZO_EXPORT2)
# define __LZO_EXPORT2 /*empty*/
#endif
/* __cdecl calling convention for public C and assembly functions */
#if !defined(LZO_PUBLIC)
# define LZO_PUBLIC(_rettype) __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL
#endif
#if !defined(LZO_EXTERN)
# define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype)
#endif
#if !defined(LZO_PRIVATE)
# define LZO_PRIVATE(_rettype) static _rettype __LZO_CDECL
#endif
/* function types */
typedef int
(__LZO_CDECL *lzo_compress_t) ( const lzo_bytep src, lzo_uint src_len,
lzo_bytep dst, lzo_uintp dst_len,
lzo_voidp wrkmem );
typedef int
(__LZO_CDECL *lzo_decompress_t) ( const lzo_bytep src, lzo_uint src_len,
lzo_bytep dst, lzo_uintp dst_len,
lzo_voidp wrkmem );
typedef int
(__LZO_CDECL *lzo_optimize_t) ( lzo_bytep src, lzo_uint src_len,
lzo_bytep dst, lzo_uintp dst_len,
lzo_voidp wrkmem );
typedef int
(__LZO_CDECL *lzo_compress_dict_t)(const lzo_bytep src, lzo_uint src_len,
lzo_bytep dst, lzo_uintp dst_len,
lzo_voidp wrkmem,
const lzo_bytep dict, lzo_uint dict_len );
typedef int
(__LZO_CDECL *lzo_decompress_dict_t)(const lzo_bytep src, lzo_uint src_len,
lzo_bytep dst, lzo_uintp dst_len,
lzo_voidp wrkmem,
const lzo_bytep dict, lzo_uint dict_len );
/* Callback interface. Currently only the progress indicator ("nprogress")
* is used, but this may change in a future release. */
struct lzo_callback_t;
typedef struct lzo_callback_t lzo_callback_t;
#define lzo_callback_p lzo_callback_t __LZO_MMODEL *
/* malloc & free function types */
typedef lzo_voidp (__LZO_CDECL *lzo_alloc_func_t)
(lzo_callback_p self, lzo_uint items, lzo_uint size);
typedef void (__LZO_CDECL *lzo_free_func_t)
(lzo_callback_p self, lzo_voidp ptr);
/* a progress indicator callback function */
typedef void (__LZO_CDECL *lzo_progress_func_t)
(lzo_callback_p, lzo_uint, lzo_uint, int);
struct lzo_callback_t
{
/* custom allocators (set to 0 to disable) */
lzo_alloc_func_t nalloc; /* [not used right now] */
lzo_free_func_t nfree; /* [not used right now] */
/* a progress indicator callback function (set to 0 to disable) */
lzo_progress_func_t nprogress;
/* NOTE: the first parameter "self" of the nalloc/nfree/nprogress
* callbacks points back to this struct, so you are free to store
* some extra info in the following variables. */
lzo_voidp user1;
lzo_xint user2;
lzo_xint user3;
};
/***********************************************************************
// error codes and prototypes
************************************************************************/
/* Error codes for the compression/decompression functions. Negative
* values are errors, positive values will be used for special but
* normal events.
*/
#define LZO_E_OK 0
#define LZO_E_ERROR (-1)
#define LZO_E_OUT_OF_MEMORY (-2) /* [lzo_alloc_func_t failure] */
#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */
#define LZO_E_INPUT_OVERRUN (-4)
#define LZO_E_OUTPUT_OVERRUN (-5)
#define LZO_E_LOOKBEHIND_OVERRUN (-6)
#define LZO_E_EOF_NOT_FOUND (-7)
#define LZO_E_INPUT_NOT_CONSUMED (-8)
#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */
#define LZO_E_INVALID_ARGUMENT (-10)
#ifndef lzo_sizeof_dict_t
# define lzo_sizeof_dict_t ((unsigned)sizeof(lzo_bytep))
#endif
/* lzo_init() should be the first function you call.
* Check the return code !
*
* lzo_init() is a macro to allow checking that the library and the
* compiler's view of various types are consistent.
*/
#define lzo_init() __lzo_init_v2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\
(int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\
(int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\
(int)sizeof(lzo_callback_t))
LZO_EXTERN(int) __lzo_init_v2(unsigned,int,int,int,int,int,int,int,int,int);
/* version functions (useful for shared libraries) */
LZO_EXTERN(unsigned) lzo_version(void);
LZO_EXTERN(const char *) lzo_version_string(void);
LZO_EXTERN(const char *) lzo_version_date(void);
LZO_EXTERN(const lzo_charp) _lzo_version_string(void);
LZO_EXTERN(const lzo_charp) _lzo_version_date(void);
/* string functions */
LZO_EXTERN(int)
lzo_memcmp(const lzo_voidp a, const lzo_voidp b, lzo_uint len);
LZO_EXTERN(lzo_voidp)
lzo_memcpy(lzo_voidp dst, const lzo_voidp src, lzo_uint len);
LZO_EXTERN(lzo_voidp)
lzo_memmove(lzo_voidp dst, const lzo_voidp src, lzo_uint len);
LZO_EXTERN(lzo_voidp)
lzo_memset(lzo_voidp buf, int c, lzo_uint len);
/* checksum functions */
LZO_EXTERN(lzo_uint32)
lzo_adler32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len);
LZO_EXTERN(lzo_uint32)
lzo_crc32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len);
LZO_EXTERN(const lzo_uint32p)
lzo_get_crc32_table(void);
/* misc. */
LZO_EXTERN(int) _lzo_config_check(void);
typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u;
typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u;
typedef union { void *vp; lzo_bytep bp; lzo_uint u; lzo_uint32 u32; unsigned long l; } lzo_align_t;
/* align a char pointer on a boundary that is a multiple of 'size' */
LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size);
#define LZO_PTR_ALIGN_UP(p,size) \
((p) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(p),(lzo_uint)(size)))
/***********************************************************************
// deprecated macros - only for backward compatibility with LZO v1.xx
************************************************************************/
#if defined(LZO_CFG_COMPAT)
#define __LZOCONF_H 1
#if defined(LZO_ARCH_I086)
# define __LZO_i386 1
#elif defined(LZO_ARCH_I386)
# define __LZO_i386 1
#endif
#if defined(LZO_OS_DOS16)
# define __LZO_DOS 1
# define __LZO_DOS16 1
#elif defined(LZO_OS_DOS32)
# define __LZO_DOS 1
#elif defined(LZO_OS_WIN16)
# define __LZO_WIN 1
# define __LZO_WIN16 1
#elif defined(LZO_OS_WIN32)
# define __LZO_WIN 1
#endif
#define __LZO_CMODEL /*empty*/
#define __LZO_DMODEL /*empty*/
#define __LZO_ENTRY __LZO_CDECL
#define LZO_EXTERN_CDECL LZO_EXTERN
#define LZO_ALIGN LZO_PTR_ALIGN_UP
#define lzo_compress_asm_t lzo_compress_t
#define lzo_decompress_asm_t lzo_decompress_t
#endif /* LZO_CFG_COMPAT */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* already included */
/* vim:set ts=4 et: */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,109 @@
/* minilzo.h -- mini subset of the LZO real-time data compression library
This file is part of the LZO real-time data compression library.
Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
The LZO library 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 2 of
the License, or (at your option) any later version.
The LZO library 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 the LZO library; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Markus F.X.J. Oberhumer
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/lzo/
*/
/*
* NOTE:
* the full LZO package can be found at
* http://www.oberhumer.com/opensource/lzo/
*/
#ifndef __MINILZO_H
#define __MINILZO_H 1
#define MINILZO_VERSION 0x2050
#ifdef __LZOCONF_H
# error "you cannot use both LZO and miniLZO"
#endif
#undef LZO_HAVE_CONFIG_H
#include "lzoconf.h"
#if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION)
# error "version mismatch in header files"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/***********************************************************************
//
************************************************************************/
/* Memory required for the wrkmem parameter.
* When the required size is 0, you can also pass a NULL pointer.
*/
#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS
#define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t))
#define LZO1X_MEM_DECOMPRESS (0)
/* compression */
LZO_EXTERN(int)
lzo1x_1_compress ( const lzo_bytep src, lzo_uint src_len,
lzo_bytep dst, lzo_uintp dst_len,
lzo_voidp wrkmem );
/* decompression */
LZO_EXTERN(int)
lzo1x_decompress ( const lzo_bytep src, lzo_uint src_len,
lzo_bytep dst, lzo_uintp dst_len,
lzo_voidp wrkmem /* NOT USED */ );
/* safe decompression with overrun testing */
LZO_EXTERN(int)
lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len,
lzo_bytep dst, lzo_uintp dst_len,
lzo_voidp wrkmem /* NOT USED */ );
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* already included */

View file

@ -0,0 +1,35 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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 <http://www.gnu.org/licenses/>.
*/
#include <grub/arc/arc.h>
#include <grub/misc.h>
#include <grub/time.h>
#include <grub/term.h>
#include <grub/i18n.h>
void
grub_reboot (void)
{
GRUB_ARC_FIRMWARE_VECTOR->restart ();
grub_millisleep (1500);
grub_puts_ (N_("Reboot failed"));
grub_refresh ();
while (1);
}

View file

@ -0,0 +1,58 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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 <http://www.gnu.org/licenses/>.
*/
#include <grub/machine/ec.h>
#include <grub/machine/kernel.h>
#include <grub/machine/memory.h>
#include <grub/misc.h>
#include <grub/pci.h>
#include <grub/cs5536.h>
#include <grub/time.h>
#include <grub/term.h>
#include <grub/i18n.h>
void
grub_reboot (void)
{
switch (grub_arch_machine)
{
case GRUB_ARCH_MACHINE_FULOONG2E:
grub_outb (grub_inb (0xbfe00104) & ~4, 0xbfe00104);
grub_outb (grub_inb (0xbfe00104) | 4, 0xbfe00104);
break;
case GRUB_ARCH_MACHINE_FULOONG2F:
{
grub_pci_device_t dev;
if (!grub_cs5536_find (&dev))
break;
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_RESET,
grub_cs5536_read_msr (dev,
GRUB_CS5536_MSR_DIVIL_RESET)
| 1);
break;
}
case GRUB_ARCH_MACHINE_YEELOONG:
grub_write_ec (GRUB_MACHINE_EC_COMMAND_REBOOT);
break;
}
grub_millisleep (1500);
grub_puts_ (N_("Reboot failed"));
grub_refresh ();
while (1);
}

View file

@ -0,0 +1,25 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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 <http://www.gnu.org/licenses/>.
*/
#include <grub/misc.h>
void
grub_reboot (void)
{
while (1);
}

View file

@ -42,20 +42,25 @@ isdigit (int c)
static inline int
islower (int c)
{
return (c >= 'a' && c <= 'z');
return grub_islower (c);
}
static inline int
isascii (int c)
{
return !(c & ~0x7f);
}
static inline int
isupper (int c)
{
return (c >= 'A' && c <= 'Z');
return grub_isupper (c);
}
static inline int
isxdigit (int c)
{
return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')
|| (c >= '0' && c <= '9');
return grub_isxdigit (c);
}
static inline int

View file

@ -23,7 +23,7 @@
typedef enum { CODESET } nl_item;
static inline char *
static inline const char *
nl_langinfo (nl_item item)
{
switch (item)

View file

@ -0,0 +1,31 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2010 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 <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_POSIX_LIMITS_H
#define GRUB_POSIX_LIMITS_H
#include <grub/types.h>
#define UCHAR_MAX GRUB_UCHAR_MAX
#define USHRT_MAX GRUB_USHRT_MAX
#define UINT_MAX GRUB_UINT_MAX
#define ULONG_MAX GRUB_ULONG_MAX
#define CHAR_BIT 8
#endif

View file

@ -46,7 +46,7 @@ realloc (void *ptr, grub_size_t size)
return grub_realloc (ptr, size);
}
static inline void
static inline void __attribute__ ((noreturn))
abort (void)
{
grub_abort ();

View file

@ -39,4 +39,12 @@ strcasecmp (const char *s1, const char *s2)
return grub_strcasecmp (s1, s2);
}
#ifdef GRUB_UTIL
static inline void *
memcpy (void *dest, const void *src, grub_size_t n)
{
return grub_memcpy (dest, src, n);
}
#endif
#endif

View file

@ -24,9 +24,6 @@
typedef grub_size_t size_t;
typedef enum { false = 0, true = 1 } bool;
#define ULONG_MAX GRUB_ULONG_MAX
#define UCHAR_MAX 0xff
typedef grub_uint8_t uint8_t;
typedef grub_uint16_t uint16_t;
typedef grub_uint32_t uint32_t;

View file

@ -19,7 +19,92 @@
#ifndef GRUB_POSIX_WCHAR_H
#define GRUB_POSIX_WCHAR_H 1
#include <grub/charset.h>
/* UCS-4. */
typedef grub_uint32_t wchar_t;
typedef grub_int32_t wint_t;
enum
{
WEOF = -1
};
#define MB_LEN_MAX 4
/* UCS-4. */
typedef grub_int32_t wchar_t;
typedef struct mbstate {
grub_uint32_t code;
int count;
} mbstate_t;
static inline size_t
mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
{
const char *ptr;
if (!s)
{
pwc = 0;
s = "";
n = 1;
}
for (ptr = s; ptr < s + n; ptr++)
{
if (!grub_utf8_process (*ptr, &ps->code, &ps->count))
return -1;
if (ps->count)
continue;
if (pwc)
*pwc = ps->code;
if (ps->code == 0)
return 0;
return ptr - s + 1;
}
return -2;
}
static inline int
mbsinit(const mbstate_t *ps)
{
return ps->count == 0;
}
static inline size_t
wcrtomb (char *s, wchar_t wc, mbstate_t *ps __attribute__ ((unused)))
{
if (s == 0)
return 1;
return grub_encode_utf8_character ((grub_uint8_t *) s,
(grub_uint8_t *) s + MB_LEN_MAX,
wc);
}
static inline wint_t btowc (int c)
{
if (c & ~0x7f)
return WEOF;
return c;
}
static inline int
wcscoll (const wchar_t *s1, const wchar_t *s2)
{
while (*s1 && *s2)
{
if (*s1 != *s2)
break;
s1++;
s2++;
}
if (*s1 < *s2)
return -1;
if (*s1 > *s2)
return +1;
return 0;
}
#endif

View file

@ -0,0 +1,106 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009, 2010, 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 <http://www.gnu.org/licenses/>.
*/
#ifndef GRUB_POSIX_WCTYPE_H
#define GRUB_POSIX_WCTYPE_H 1
#include <grub/misc.h>
#include <wchar.h>
typedef enum { GRUB_CTYPE_INVALID,
GRUB_CTYPE_ALNUM, GRUB_CTYPE_CNTRL, GRUB_CTYPE_LOWER,
GRUB_CTYPE_SPACE, GRUB_CTYPE_ALPHA, GRUB_CTYPE_DIGIT,
GRUB_CTYPE_PRINT, GRUB_CTYPE_UPPER, GRUB_CTYPE_BLANK,
GRUB_CTYPE_GRAPH, GRUB_CTYPE_PUNCT, GRUB_CTYPE_XDIGIT,
GRUB_CTYPE_MAX} wctype_t;
static inline wctype_t
wctype (const char *name)
{
wctype_t i;
static const char names[][10] = { "",
"alnum", "cntrl", "lower",
"space", "alpha", "digit",
"print", "upper", "blank",
"graph", "punct", "xdigit" };
for (i = GRUB_CTYPE_INVALID; i < GRUB_CTYPE_MAX; i++)
if (grub_strcmp (names[i], name) == 0)
return i;
return GRUB_CTYPE_INVALID;
}
/* FIXME: take into account international lowercase characters. */
static inline int
iswlower (wint_t wc)
{
return grub_islower (wc);
}
static inline wint_t
towlower (wint_t c)
{
return grub_tolower (c);
}
static inline wint_t
towupper (wint_t c)
{
return grub_toupper (c);
}
static inline int
iswalnum (wint_t c)
{
return grub_isalpha (c) || grub_isdigit (c);
}
static inline int
iswctype (wint_t wc, wctype_t desc)
{
switch (desc)
{
case GRUB_CTYPE_ALNUM:
return iswalnum (wc);
case GRUB_CTYPE_CNTRL:
return grub_iscntrl (wc);
case GRUB_CTYPE_LOWER:
return iswlower (wc);
case GRUB_CTYPE_SPACE:
return grub_isspace (wc);
case GRUB_CTYPE_ALPHA:
return grub_isalpha (wc);
case GRUB_CTYPE_DIGIT:
return grub_isdigit (wc);
case GRUB_CTYPE_PRINT:
return grub_isprint (wc);
case GRUB_CTYPE_UPPER:
return grub_isupper (wc);
case GRUB_CTYPE_BLANK:
return wc == ' ' || wc == '\t';
case GRUB_CTYPE_GRAPH:
return grub_isgraph (wc);
case GRUB_CTYPE_PUNCT:
return grub_isprint (wc) && !grub_isspace (wc) && !iswalnum (wc);
case GRUB_CTYPE_XDIGIT:
return grub_isxdigit (wc);
default:
return 0;
}
}
#endif

View file

@ -29,7 +29,6 @@
#ifdef TEST
typedef unsigned int grub_size_t;
typedef unsigned char grub_uint8_t;
typedef unsigned short grub_uint16_t;
#else
#include <grub/types.h>
#include <grub/reed_solomon.h>
@ -42,7 +41,6 @@ typedef unsigned short grub_uint16_t;
#ifdef TEST
typedef unsigned int grub_size_t;
typedef unsigned char grub_uint8_t;
typedef unsigned short grub_uint16_t;
#else
#include <grub/types.h>
#include <grub/misc.h>
@ -53,65 +51,73 @@ grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs);
#define GF_SIZE 8
typedef grub_uint8_t gf_single_t;
typedef grub_uint16_t gf_double_t;
#define GF_POLYNOMIAL 0x1d
#define GF_INVERT2 0x8e
#if defined (STANDALONE) && !defined (TEST)
static char *gf_invert __attribute__ ((section(".text"))) = (void *) 0x100000;
static char *scratch __attribute__ ((section(".text"))) = (void *) 0x100100;
static gf_single_t * const gf_powx __attribute__ ((section(".text"))) = (void *) 0x100000;
static gf_single_t * const gf_powx_inv __attribute__ ((section(".text"))) = (void *) 0x100200;
static char *scratch __attribute__ ((section(".text"))) = (void *) 0x100300;
#else
#if defined (STANDALONE)
static char *scratch;
#endif
static grub_uint8_t gf_invert[256];
static gf_single_t gf_powx[255 * 2];
static gf_single_t gf_powx_inv[256];
#endif
#define SECTOR_SIZE 512
#define MAX_BLOCK_SIZE (200 * SECTOR_SIZE)
static gf_single_t
gf_reduce (gf_double_t a)
{
int i;
for (i = GF_SIZE - 1; i >= 0; i--)
if (a & (1ULL << (i + GF_SIZE)))
a ^= (((gf_double_t) GF_POLYNOMIAL) << i);
return a & ((1ULL << GF_SIZE) - 1);
}
static gf_single_t
gf_mul (gf_single_t a, gf_single_t b)
{
gf_double_t res = 0;
int i;
for (i = 0; i < GF_SIZE; i++)
if (b & (1 << i))
res ^= ((gf_double_t) a) << i;
return gf_reduce (res);
if (a == 0 || b == 0)
return 0;
return gf_powx[(int) gf_powx_inv[a] + (int) gf_powx_inv[b]];
}
static inline gf_single_t
gf_invert (gf_single_t a)
{
return gf_powx[255 - (int) gf_powx_inv[a]];
}
static void
init_inverts (void)
init_powx (void)
{
gf_single_t a = 1, ai = 1;
do
int i;
grub_uint8_t cur = 1;
gf_powx_inv[0] = 0;
for (i = 0; i < 255; i++)
{
a = gf_mul (a, 2);
ai = gf_mul (ai, GF_INVERT2);
gf_invert[a] = ai;
gf_powx[i] = cur;
gf_powx[i + 255] = cur;
gf_powx_inv[cur] = i;
if (cur & (1ULL << (GF_SIZE - 1)))
cur = (cur << 1) ^ GF_POLYNOMIAL;
else
cur <<= 1;
}
while (a != 1);
}
static gf_single_t
pol_evaluate (gf_single_t *pol, grub_size_t degree, gf_single_t x)
{
int i;
gf_single_t xn = 1, s = 0;
gf_single_t s = 0;
int log_xn = 0, log_x;
if (x == 0)
return pol[0];
log_x = gf_powx_inv[x];
for (i = degree; i >= 0; i--)
{
s ^= gf_mul (pol[i], xn);
xn = gf_mul (x, xn);
if (pol[i])
s ^= gf_powx[(int) gf_powx_inv[pol[i]] + log_xn];
log_xn += log_x;
if (log_xn >= ((1 << GF_SIZE) - 1))
log_xn -= ((1 << GF_SIZE) - 1);
}
return s;
}
@ -120,7 +126,7 @@ pol_evaluate (gf_single_t *pol, grub_size_t degree, gf_single_t x)
static void
rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs)
{
gf_single_t *rs_polynomial, a = 1;
gf_single_t *rs_polynomial;
int i, j;
gf_single_t *m;
m = xmalloc ((s + rs) * sizeof (gf_single_t));
@ -132,16 +138,14 @@ rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs)
/* Multiply with X - a^r */
for (j = 0; j < rs; j++)
{
if (a & (1 << (GF_SIZE - 1)))
{
a <<= 1;
a ^= GF_POLYNOMIAL;
}
else
a <<= 1;
for (i = 0; i < rs; i++)
rs_polynomial[i] = rs_polynomial[i + 1] ^ gf_mul (a, rs_polynomial[i]);
rs_polynomial[rs] = gf_mul (a, rs_polynomial[rs]);
if (rs_polynomial[i])
rs_polynomial[i] = (rs_polynomial[i + 1]
^ gf_powx[j + (int) gf_powx_inv[rs_polynomial[i]]]);
else
rs_polynomial[i] = rs_polynomial[i + 1];
if (rs_polynomial[rs])
rs_polynomial[rs] = gf_powx[j + (int) gf_powx_inv[rs_polynomial[rs]]];
}
for (j = 0; j < s; j++)
if (m[j])
@ -162,7 +166,8 @@ syndroms (gf_single_t *m, grub_size_t s, grub_size_t rs,
{
gf_single_t xn = 1;
unsigned i;
for (i = 0; i < rs; i++)
sy[0] = pol_evaluate (m, s + rs - 1, xn);
for (i = 1; i < rs; i++)
{
if (xn & (1 << (GF_SIZE - 1)))
{
@ -190,7 +195,7 @@ gauss_eliminate (gf_single_t *eq, int n, int m, int *chosen)
if (nzidx == m)
continue;
chosen[i] = nzidx;
r = gf_invert [eq[i * (m + 1) + nzidx]];
r = gf_invert (eq[i * (m + 1) + nzidx]);
for (j = 0; j < m + 1; j++)
eq[i * (m + 1) + j] = gf_mul (eq[i * (m + 1) + j], r);
for (j = i + 1; j < n; j++)
@ -341,7 +346,7 @@ rs_recover (gf_single_t *m, grub_size_t s, grub_size_t rs)
#endif
for (j = 0; j < errnum; j++)
eq[j] = errpot[j];
eq[j] = 1;
eq[errnum] = sy[0];
for (i = 1; i < (int) rs; i++)
{
@ -385,12 +390,19 @@ decode_block (gf_single_t *ptr, grub_size_t s,
{
grub_size_t ds = (s + SECTOR_SIZE - 1 - i) / SECTOR_SIZE;
grub_size_t rr = (rs + SECTOR_SIZE - 1 - i) / SECTOR_SIZE;
gf_single_t m[ds + rr];
gf_single_t *m;
/* Nothing to do. */
if (!ds || !rr)
continue;
#ifndef STANDALONE
m = xmalloc (ds + rr);
#else
m = (gf_single_t *) scratch;
scratch += ds + rr;
#endif
for (j = 0; j < (int) ds; j++)
m[j] = ptr[SECTOR_SIZE * j + i];
for (j = 0; j < (int) rr; j++)
@ -400,6 +412,12 @@ decode_block (gf_single_t *ptr, grub_size_t s,
for (j = 0; j < (int) ds; j++)
ptr[SECTOR_SIZE * j + i] = m[j];
#ifndef STANDALONE
free (m);
#else
scratch -= ds + rr;
#endif
}
}
@ -413,12 +431,18 @@ encode_block (gf_single_t *ptr, grub_size_t s,
{
grub_size_t ds = (s + SECTOR_SIZE - 1 - i) / SECTOR_SIZE;
grub_size_t rr = (rs + SECTOR_SIZE - 1 - i) / SECTOR_SIZE;
gf_single_t m[ds + rr];
gf_single_t *m;
if (!ds || !rr)
continue;
m = xmalloc (ds + rr);
for (j = 0; j < ds; j++)
m[j] = ptr[SECTOR_SIZE * j + i];
rs_encode (m, ds, rr);
for (j = 0; j < rr; j++)
rptr[SECTOR_SIZE * j + i] = m[j + ds];
free (m);
}
}
#endif
@ -437,6 +461,8 @@ grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size,
if (!rs)
return;
init_powx ();
while (s > 0)
{
grub_size_t tt;
@ -468,9 +494,7 @@ grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs)
if (!rs)
return;
#if defined (STANDALONE)
init_inverts ();
#endif
init_powx ();
while (s > 0)
{
@ -500,12 +524,15 @@ main (int argc, char **argv)
grub_size_t s, rs;
char *buf;
grub_memset (gf_powx, 0xee, sizeof (gf_powx));
grub_memset (gf_powx_inv, 0xdd, sizeof (gf_powx_inv));
#ifdef STANDALONE
scratch = xmalloc (1048576);
#endif
#ifndef STANDALONE
init_inverts ();
init_powx ();
#endif
in = fopen ("tst.bin", "rb");
@ -514,7 +541,7 @@ main (int argc, char **argv)
fseek (in, 0, SEEK_END);
s = ftell (in);
fseek (in, 0, SEEK_SET);
rs = s / 3;
rs = 0x7007;
buf = xmalloc (s + rs + SECTOR_SIZE);
fread (buf, 1, s, in);
fclose (in);
@ -524,8 +551,9 @@ main (int argc, char **argv)
out = fopen ("tst_rs.bin", "wb");
fwrite (buf, 1, s + rs, out);
fclose (out);
#if 1
grub_memset (buf + 512 * 15, 0, 512);
#endif
out = fopen ("tst_dam.bin", "wb");
fwrite (buf, 1, s + rs, out);

View file

@ -10,6 +10,7 @@
#include "./powerpc/setjmp.S"
#elif defined(__ia64__)
#include "./ia64/setjmp.S"
#include "./ia64/longjmp.S"
#else
#error "Unknown target cpu type"
#endif

View file

@ -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;
grub_uint8_t hash_id;
#endif
grub_size_t hash_size;
/* 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,36 @@ 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;
}
static const struct
{
const char *name;
grub_size_t size;
} hashes[] = {
[0x01] = { "CRC32", 4},
[0x04] = { "CRC64", 8},
[0x0A] = { "SHA256", 32},
};
/* 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,28 +445,102 @@ 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
#ifndef GRUB_EMBED_DECOMPRESSOR
/*
* Decode the Stream Flags field. Of integrity checks, we support
* only none (Check ID = 0) and CRC32 (Check ID = 1).
* Decode the Stream Flags field.
*/
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];
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);
}
if (!s->hash)
return XZ_OPTIONS_ERROR;
#endif
}
else
{
#ifndef GRUB_EMBED_DECOMPRESSOR
s->hash = 0;
#endif
s->hash_size = 0;
}
s->have_hash_value = 0;
return XZ_OK;
}
@ -426,19 +552,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,8 +584,10 @@ 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)
#ifndef GRUB_EMBED_DECOMPRESSOR
if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->hash_id)
return XZ_DATA_ERROR;
#endif
/*
* Use XZ_STREAM_END instead of XZ_OK to be more convenient
@ -468,17 +607,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 +808,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 +838,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 +956,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 +996,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 +1028,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