/* * GRUB -- GRand Unified Bootloader * 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 * 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 GRUB_MOD_LICENSE ("GPLv3+"); struct adler32_context { grub_uint16_t a, b; grub_uint32_t c; }; static void adler32_init (void *context) { 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) { struct adler32_context *ctx = context; const grub_uint8_t *ptr = inbuf; while (inlen) { ctx->a = mod_add (ctx->a, *ptr); ctx->b = mod_add (ctx->a, ctx->b); inlen--; ptr++; } } static void adler32_final (void *context __attribute__ ((unused))) { } 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 (&spec_adler32); } GRUB_MOD_FINI(adler32) { grub_md_unregister (&spec_adler32); }