/* 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 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); }