diff --git a/ChangeLog b/ChangeLog index ec8398093..2fc01debd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2012-04-07 Vladimir Serbinenko + + * grub-core/lib/adler32.c: Recode due to license unclearness. + 2012-04-07 Vladimir Serbinenko * grub-core/io/lzopio.c (read_block_header): Fix incorrect byte swapping diff --git a/grub-core/lib/adler32.c b/grub-core/lib/adler32.c index 2a2464db3..43b68af62 100644 --- a/grub-core/lib/adler32.c +++ b/grub-core/lib/adler32.c @@ -1,7 +1,6 @@ -/* adler32.c - adler32 check. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. + * Copyright (C) 2012 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 @@ -17,117 +16,50 @@ * along with GRUB. If not, see . */ -#include + #include #include 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) +struct adler32_context { - 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; + grub_uint16_t a, b; + grub_uint32_t c; +}; static void adler32_init (void *context) { - adler32_context *ctx = (adler32_context *) context; - ctx->adler = 1; + struct adler32_context *ctx = context; + + ctx->a = 1; + ctx->b = 0; +} + +#define MOD 65521 + +static grub_uint16_t +mod_add (grub_uint16_t a, grub_uint16_t b) +{ + if ((grub_uint32_t) a + (grub_uint32_t) b >= MOD) + return a + b - MOD; + return a + b; } 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); -} + struct adler32_context *ctx = context; + const grub_uint8_t *ptr = inbuf; -static grub_uint8_t * -adler32_read (void *context) -{ - adler32_context *ctx = (adler32_context *) context; - return (grub_uint8_t *) &ctx->adler; + while (inlen) + { + ctx->a = mod_add (ctx->a, *ptr); + ctx->b = mod_add (ctx->a, ctx->b); + inlen--; + ptr++; + } } static void @@ -135,19 +67,36 @@ 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 -}; +static grub_uint8_t * +adler32_read (void *context) +{ + struct adler32_context *ctx = context; + if (ctx->a > MOD) + ctx->a -= MOD; + if (ctx->b > MOD) + ctx->b -= MOD; + ctx->c = grub_cpu_to_be32 (ctx->a | (ctx->b << 16)); + return (grub_uint8_t *) &ctx->c; +} + +static gcry_md_spec_t spec_adler32 = + { + "ADLER32", 0, 0, 0, 4, + adler32_init, adler32_write, adler32_final, adler32_read, + sizeof (struct adler32_context), +#ifdef GRUB_UTIL + .modname = "adler32", +#endif + .blocksize = 64 + }; + GRUB_MOD_INIT(adler32) { - grub_md_register (&_gcry_digest_spec_adler32); + grub_md_register (&spec_adler32); } GRUB_MOD_FINI(adler32) { - grub_md_unregister (&_gcry_digest_spec_adler32); + grub_md_unregister (&spec_adler32); }