Commit e59937c7 authored by Evan Hunt's avatar Evan Hunt
Browse files

[rt33746] use CRC64 for map file error detection

3591.	[func]		Use CRC-64 to detect map file corruption at load
			time. [RT #33746]
parent 1ec9fe2c
3591. [func] Use CRC-64 to detect map file corruption at load
time. [RT #33746]
3590. [bug] When using RRL on recursive servers, defer
rate-limiting until after recursion is complete;
also, use correct rcode for slipped NXDOMAIN
......
......@@ -22,10 +22,10 @@
/*! \file dns/rbt.h */
#include <isc/crc64.h>
#include <isc/lang.h>
#include <isc/magic.h>
#include <isc/refcount.h>
#include <isc/sha1.h>
#include <dns/types.h>
......@@ -154,11 +154,11 @@ typedef isc_result_t (*dns_rbtfindcallback_t)(dns_rbtnode_t *node,
typedef isc_result_t (*dns_rbtdatawriter_t)(FILE *file,
unsigned char *data,
isc_uint32_t version,
isc_sha1_t *sha1);
isc_uint64_t *crc);
typedef isc_result_t (*dns_rbtdatafixer_t)(dns_rbtnode_t *rbtnode,
void *base, size_t offset,
isc_sha1_t *sha1);
isc_uint64_t *crc);
/*****
***** Chain Info
......
......@@ -28,13 +28,13 @@
#include <inttypes.h> /* uintptr_t */
#endif
#include <isc/crc64.h>
#include <isc/file.h>
#include <isc/hex.h>
#include <isc/mem.h>
#include <isc/platform.h>
#include <isc/print.h>
#include <isc/refcount.h>
#include <isc/sha1.h>
#include <isc/socket.h>
#include <isc/stdio.h>
#include <isc/string.h>
......@@ -119,7 +119,7 @@ struct file_header {
unsigned int bigendian:1; /* big or little endian system */
unsigned int rdataset_fixed:1; /* compiled with --enable-rrset-fixed */
unsigned int nodecount; /* shadow from rbt structure */
unsigned char digest[ISC_SHA1_DIGESTLENGTH];
isc_uint64_t crc;
char version2[32]; /* repeated; must match version1 */
};
......@@ -147,17 +147,17 @@ dns_rbt_zero_header(FILE *file);
static isc_result_t
write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset,
unsigned char *digest);
isc_uint64_t crc);
static isc_result_t
serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
uintptr_t right, uintptr_t down, uintptr_t parent,
uintptr_t data, isc_sha1_t *sha1);
uintptr_t data, isc_uint64_t *crc);
static isc_result_t
serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
dns_rbtdatawriter_t datawriter, isc_uint32_t serial,
uintptr_t *where, isc_sha1_t *sha1);
uintptr_t *where, isc_uint64_t *crc);
/*
* The following functions allow you to get the actual address of a pointer
* without having to use an if statement to check to see if that address is
......@@ -370,7 +370,7 @@ deletefromlevel(dns_rbtnode_t *delete, dns_rbtnode_t **rootp);
static isc_result_t
treefix(dns_rbt_t *rbt, void *base, size_t size,
dns_rbtnode_t *n, dns_name_t *name,
dns_rbtdatafixer_t datafixer, isc_sha1_t *sha1);
dns_rbtdatafixer_t datafixer, isc_uint64_t *crc);
static isc_result_t
deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node);
......@@ -415,7 +415,7 @@ dns_rbt_zero_header(FILE *file) {
*/
static isc_result_t
write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset,
unsigned char *digest)
isc_uint64_t crc)
{
file_header_t header;
isc_result_t result;
......@@ -442,7 +442,7 @@ write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset,
header.nodecount = rbt->nodecount;
memcpy(header.digest, digest, sizeof(header.digest));
header.crc = crc;
location = ftell(file);
if (location < 0)
......@@ -462,7 +462,7 @@ write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset,
static isc_result_t
serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
uintptr_t right, uintptr_t down, uintptr_t parent,
uintptr_t data, isc_sha1_t *sha1)
uintptr_t data, isc_uint64_t *crc)
{
dns_rbtnode_t temp_node;
long file_position;
......@@ -535,9 +535,9 @@ serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
hexdump("node data", node_data, datasize);
#endif
isc_sha1_update(sha1, (const isc_uint8_t *) &temp_node,
isc_crc64_update(crc, (const isc_uint8_t *) &temp_node,
sizeof(dns_rbtnode_t));
isc_sha1_update(sha1, (const isc_uint8_t *) node_data, datasize);
isc_crc64_update(crc, (const isc_uint8_t *) node_data, datasize);
cleanup:
return (result);
......@@ -546,7 +546,7 @@ serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
static isc_result_t
serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
dns_rbtdatawriter_t datawriter, isc_uint32_t serial,
uintptr_t *where, isc_sha1_t *sha1)
uintptr_t *where, isc_uint64_t *crc)
{
uintptr_t left = 0, right = 0, down = 0, data = 0;
long location = 0;
......@@ -576,14 +576,14 @@ serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
* Serialize the rest of the tree.
*
* WARNING: A change in the order (from left, right, down)
* will break the way the sha1 hash is computed.
* will break the way the crc hash is computed.
*/
CHECK(serialize_nodes(file, getleft(node, NULL), location,
datawriter, serial, &left, sha1));
datawriter, serial, &left, crc));
CHECK(serialize_nodes(file, getright(node, NULL), location,
datawriter, serial, &right, sha1));
datawriter, serial, &right, crc));
CHECK(serialize_nodes(file, getdown(node, NULL), location,
datawriter, serial, &down, sha1));
datawriter, serial, &down, crc));
if (node->data != NULL) {
long ret;
......@@ -600,15 +600,14 @@ serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
return (ISC_R_FAILURE);
data = ret;
datawriter(file, node->data, serial, sha1);
datawriter(file, node->data, serial, crc);
}
/* Seek back to reserved space. */
CHECK(isc_stdio_seek(file, location, SEEK_SET));
/* Serialize the current node. */
CHECK(serialize_node(file, node, left, right, down, parent, data,
sha1));
CHECK(serialize_node(file, node, left, right, down, parent, data, crc));
/* Ensure we are always at the end of the file. */
CHECK(isc_stdio_seek(file, 0, SEEK_END));
......@@ -637,14 +636,13 @@ dns_rbt_serialize_tree(FILE *file, dns_rbt_t *rbt,
{
isc_result_t result;
long header_position, node_position, end_position;
unsigned char digest[ISC_SHA1_DIGESTLENGTH];
isc_sha1_t sha1;
isc_uint64_t crc;
REQUIRE(file != NULL);
CHECK(isc_file_isplainfilefd(fileno(file)));
isc_sha1_init(&sha1);
isc_crc64_init(&crc);
header_position = ftell(file);
if (header_position < 0)
......@@ -658,8 +656,8 @@ dns_rbt_serialize_tree(FILE *file, dns_rbt_t *rbt,
if (node_position < 0)
return (ISC_R_FAILURE);
CHECK(serialize_nodes(file, rbt->root, 0, datawriter, serial, NULL,
&sha1));
CHECK(serialize_nodes(file, rbt->root, 0, datawriter,
serial, NULL, &crc));
end_position = ftell(file);
if (end_position < 0)
return (ISC_R_FAILURE);
......@@ -670,14 +668,14 @@ dns_rbt_serialize_tree(FILE *file, dns_rbt_t *rbt,
return (ISC_R_SUCCESS);
}
isc_sha1_final(&sha1, digest);
isc_crc64_final(&crc);
#ifdef DEBUG
hexdump("serializing digest", digest, sizeof(digest));
hexdump("serializing CRC", crc, sizeof(crc));
#endif
/* Serialize header */
CHECK(isc_stdio_seek(file, header_position, SEEK_SET));
CHECK(write_header(file, rbt, HEADER_LENGTH, digest));
CHECK(write_header(file, rbt, HEADER_LENGTH, crc));
/* Ensure we are always at the end of the file. */
CHECK(isc_stdio_seek(file, 0, SEEK_END));
......@@ -696,7 +694,7 @@ dns_rbt_serialize_tree(FILE *file, dns_rbt_t *rbt,
static isc_result_t
treefix(dns_rbt_t *rbt, void *base, size_t filesize, dns_rbtnode_t *n,
dns_name_t *name, dns_rbtdatafixer_t datafixer, isc_sha1_t *sha1)
dns_name_t *name, dns_rbtdatafixer_t datafixer, isc_uint64_t *crc)
{
isc_result_t result = ISC_R_SUCCESS;
dns_fixedname_t fixed;
......@@ -774,16 +772,16 @@ treefix(dns_rbt_t *rbt, void *base, size_t filesize, dns_rbtnode_t *n,
/* a change in the order (from left, right, down) will break hashing*/
if (n->left != NULL)
CHECK(treefix(rbt, base, filesize, n->left, name,
datafixer, sha1));
datafixer, crc));
if (n->right != NULL)
CHECK(treefix(rbt, base, filesize, n->right, name,
datafixer, sha1));
datafixer, crc));
if (n->down != NULL)
CHECK(treefix(rbt, base, filesize, n->down, fullname,
datafixer, sha1));
datafixer, crc));
if (datafixer != NULL && n->data != NULL)
CHECK(datafixer(n, base, filesize, sha1));
CHECK(datafixer(n, base, filesize, crc));
rbt->nodecount++;
node_data = (unsigned char *) n + sizeof(dns_rbtnode_t);
......@@ -797,9 +795,9 @@ treefix(dns_rbt_t *rbt, void *base, size_t filesize, dns_rbtnode_t *n,
sizeof(dns_rbtnode_t));
hexdump("node data", node_data, datasize);
#endif
isc_sha1_update(sha1, (const isc_uint8_t *) &header,
isc_crc64_update(crc, (const isc_uint8_t *) &header,
sizeof(dns_rbtnode_t));
isc_sha1_update(sha1, (const isc_uint8_t *) node_data,
isc_crc64_update(crc, (const isc_uint8_t *) node_data,
datasize);
cleanup:
......@@ -816,14 +814,13 @@ dns_rbt_deserialize_tree(void *base_address, size_t filesize,
{
isc_result_t result = ISC_R_SUCCESS;
file_header_t *header;
unsigned char digest[ISC_SHA1_DIGESTLENGTH];
dns_rbt_t *rbt = NULL;
isc_sha1_t sha1;
isc_uint64_t crc;
REQUIRE(originp == NULL || *originp == NULL);
REQUIRE(rbtp != NULL && *rbtp == NULL);
isc_sha1_init(&sha1);
isc_crc64_init(&crc);
CHECK(dns_rbt_create(mctx, deleter, deleter_arg, &rbt));
......@@ -864,15 +861,15 @@ dns_rbt_deserialize_tree(void *base_address, size_t filesize,
rehash(rbt, header->nodecount);
CHECK(treefix(rbt, base_address, filesize, rbt->root,
dns_rootname, datafixer, &sha1));
dns_rootname, datafixer, &crc));
isc_sha1_final(&sha1, digest);
isc_crc64_final(&crc);
#ifdef DEBUG
hexdump("deserializing digest", digest, sizeof(digest));
hexdump("deserializing CRC", crc, sizeof(crc));
#endif
/* Check file hash */
if (memcmp(header->digest, digest, sizeof(digest)) != 0) {
if (header->crc != crc) {
result = ISC_R_INVALIDFILE;
goto cleanup;
}
......
......@@ -27,6 +27,7 @@
/* #define inline */
#include <isc/crc64.h>
#include <isc/event.h>
#include <isc/heap.h>
#include <isc/file.h>
......@@ -6997,7 +6998,7 @@ loading_addrdataset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset) {
static isc_result_t
rbt_datafixer(dns_rbtnode_t *rbtnode, void *base, size_t filesize,
isc_sha1_t *sha1)
isc_uint64_t *crc)
{
rdatasetheader_t *header;
unsigned char *limit = ((unsigned char *) base) + filesize;
......@@ -7010,7 +7011,7 @@ rbt_datafixer(dns_rbtnode_t *rbtnode, void *base, size_t filesize,
p = (unsigned char *) header;
size = dns_rdataslab_size(p, sizeof(*header));
isc_sha1_update(sha1, p, size);
isc_crc64_update(crc, p, size);
#ifdef DEBUG
hexdump("hashing header", p, sizeof(rdatasetheader_t));
hexdump("hashing slab", p + sizeof(rdatasetheader_t),
......@@ -7224,7 +7225,8 @@ endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
*/
static isc_result_t
rbt_datawriter(FILE *rbtfile, unsigned char *data, isc_uint32_t serial,
isc_sha1_t *sha1) {
isc_uint64_t *crc)
{
rdatasetheader_t newheader;
rdatasetheader_t *header = (rdatasetheader_t *) data, *next;
size_t where, size, cooked;
......@@ -7277,16 +7279,16 @@ rbt_datawriter(FILE *rbtfile, unsigned char *data, isc_uint32_t serial,
hexdump("writing slab", p + sizeof(rdatasetheader_t),
size - sizeof(rdatasetheader_t));
#endif
isc_sha1_update(sha1, (unsigned char *) &newheader,
sizeof(rdatasetheader_t));
isc_crc64_update(crc, (unsigned char *) &newheader,
sizeof(rdatasetheader_t));
result = isc_stdio_write(&newheader,
sizeof(rdatasetheader_t), 1,
rbtfile, NULL);
if (result != ISC_R_SUCCESS)
return (result);
isc_sha1_update(sha1, p + sizeof(rdatasetheader_t),
size - sizeof(rdatasetheader_t));
isc_crc64_update(crc, p + sizeof(rdatasetheader_t),
size - sizeof(rdatasetheader_t));
result = isc_stdio_write(p + sizeof(rdatasetheader_t),
size - sizeof(rdatasetheader_t), 1, rbtfile, NULL);
if (result != ISC_R_SUCCESS)
......
......@@ -107,7 +107,7 @@ delete_data(void *data, void *arg) {
static isc_result_t
write_data(FILE *file, unsigned char *datap, isc_uint32_t serial,
isc_sha1_t *sha1) {
isc_uint64_t *crc) {
size_t ret = 0;
data_holder_t *data = (data_holder_t *)datap;
data_holder_t temp;
......@@ -115,7 +115,7 @@ write_data(FILE *file, unsigned char *datap, isc_uint32_t serial,
UNUSED(serial);
REQUIRE(sha1 != NULL);
REQUIRE(crc != NULL);
REQUIRE(data != NULL);
REQUIRE((data->len == 0 && data->data == NULL) ||
(data->len != 0 && data->data != NULL));
......@@ -125,12 +125,12 @@ write_data(FILE *file, unsigned char *datap, isc_uint32_t serial,
? NULL
: (char *)(where + sizeof(data_holder_t)));
isc_sha1_update(sha1, (void *)&temp, sizeof(temp));
isc_crc64_update(crc, (void *)&temp, sizeof(temp));
ret = fwrite(&temp, sizeof(data_holder_t), 1, file);
if (ret != 1)
return (ISC_R_FAILURE);
if (data->len > 0) {
isc_sha1_update(sha1, (const void *)data->data, data->len);
isc_crc64_update(crc, (const void *)data->data, data->len);
ret = fwrite(data->data, data->len, 1, file);
if (ret != 1)
return (ISC_R_FAILURE);
......@@ -140,14 +140,14 @@ write_data(FILE *file, unsigned char *datap, isc_uint32_t serial,
}
static isc_result_t
fix_data(dns_rbtnode_t *p, void *base, size_t max, isc_sha1_t *sha1) {
fix_data(dns_rbtnode_t *p, void *base, size_t max, isc_uint64_t *crc) {
data_holder_t *data = p->data;
size_t size;
UNUSED(base);
UNUSED(max);
REQUIRE(sha1 != NULL);
REQUIRE(crc != NULL);
REQUIRE(p != NULL);
......@@ -168,14 +168,14 @@ fix_data(dns_rbtnode_t *p, void *base, size_t max, isc_sha1_t *sha1) {
return (ISC_R_INVALIDFILE);
}
isc_sha1_update(sha1, (void *)data, sizeof(*data));
isc_crc64_update(crc, (void *)data, sizeof(*data));
data->data = (data->len == 0)
? NULL
: (char *)data + sizeof(data_holder_t);
if (data->len > 0)
isc_sha1_update(sha1, (const void *)data->data, data->len);
isc_crc64_update(crc, (const void *)data->data, data->len);
return (ISC_R_SUCCESS);
}
......
......@@ -53,7 +53,7 @@ WIN32OBJS = win32/condition.@O@ win32/dir.@O@ win32/file.@O@ \
OBJS = @ISC_EXTRA_OBJS@ \
assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \
bind9.@O@ bitstring.@O@ buffer.@O@ bufferlist.@O@ \
commandline.@O@ error.@O@ event.@O@ \
commandline.@O@ crc64.@O@ error.@O@ event.@O@ \
hash.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \
httpd.@O@ inet_aton.@O@ iterated_hash.@O@ \
lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \
......@@ -70,7 +70,7 @@ SYMTBLOBJS = backtrace-emptytbl.@O@
# Alphabetically
SRCS = @ISC_EXTRA_SRCS@ \
assertions.c backtrace.c base32.c base64.c bind9.c \
bitstring.c buffer.c bufferlist.c commandline.c \
bitstring.c buffer.c bufferlist.c commandline.c crc64.c \
error.c event.c heap.c hex.c hmacmd5.c hmacsha.c \
httpd.c inet_aton.c iterated_hash.c \
lex.c lfsr.c lib.c log.c \
......
/*
* Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.h"
#include <isc/assertions.h>
#include <isc/crc64.h>
#include <isc/string.h>
#include <isc/types.h>
#include <isc/util.h>
/*%<
* ECMA-182 CRC64 polynomial.
*/
static const isc_uint64_t crc64_table[256] = {
0x0000000000000000ULL, 0x42F0E1EBA9EA3693ULL, 0x85E1C3D753D46D26ULL,
0xC711223CFA3E5BB5ULL, 0x493366450E42ECDFULL, 0x0BC387AEA7A8DA4CULL,
0xCCD2A5925D9681F9ULL, 0x8E224479F47CB76AULL, 0x9266CC8A1C85D9BEULL,
0xD0962D61B56FEF2DULL, 0x17870F5D4F51B498ULL, 0x5577EEB6E6BB820BULL,
0xDB55AACF12C73561ULL, 0x99A54B24BB2D03F2ULL, 0x5EB4691841135847ULL,
0x1C4488F3E8F96ED4ULL, 0x663D78FF90E185EFULL, 0x24CD9914390BB37CULL,
0xE3DCBB28C335E8C9ULL, 0xA12C5AC36ADFDE5AULL, 0x2F0E1EBA9EA36930ULL,
0x6DFEFF5137495FA3ULL, 0xAAEFDD6DCD770416ULL, 0xE81F3C86649D3285ULL,
0xF45BB4758C645C51ULL, 0xB6AB559E258E6AC2ULL, 0x71BA77A2DFB03177ULL,
0x334A9649765A07E4ULL, 0xBD68D2308226B08EULL, 0xFF9833DB2BCC861DULL,
0x388911E7D1F2DDA8ULL, 0x7A79F00C7818EB3BULL, 0xCC7AF1FF21C30BDEULL,
0x8E8A101488293D4DULL, 0x499B3228721766F8ULL, 0x0B6BD3C3DBFD506BULL,
0x854997BA2F81E701ULL, 0xC7B97651866BD192ULL, 0x00A8546D7C558A27ULL,
0x4258B586D5BFBCB4ULL, 0x5E1C3D753D46D260ULL, 0x1CECDC9E94ACE4F3ULL,
0xDBFDFEA26E92BF46ULL, 0x990D1F49C77889D5ULL, 0x172F5B3033043EBFULL,
0x55DFBADB9AEE082CULL, 0x92CE98E760D05399ULL, 0xD03E790CC93A650AULL,
0xAA478900B1228E31ULL, 0xE8B768EB18C8B8A2ULL, 0x2FA64AD7E2F6E317ULL,
0x6D56AB3C4B1CD584ULL, 0xE374EF45BF6062EEULL, 0xA1840EAE168A547DULL,
0x66952C92ECB40FC8ULL, 0x2465CD79455E395BULL, 0x3821458AADA7578FULL,
0x7AD1A461044D611CULL, 0xBDC0865DFE733AA9ULL, 0xFF3067B657990C3AULL,
0x711223CFA3E5BB50ULL, 0x33E2C2240A0F8DC3ULL, 0xF4F3E018F031D676ULL,
0xB60301F359DBE0E5ULL, 0xDA050215EA6C212FULL, 0x98F5E3FE438617BCULL,
0x5FE4C1C2B9B84C09ULL, 0x1D14202910527A9AULL, 0x93366450E42ECDF0ULL,
0xD1C685BB4DC4FB63ULL, 0x16D7A787B7FAA0D6ULL, 0x5427466C1E109645ULL,
0x4863CE9FF6E9F891ULL, 0x0A932F745F03CE02ULL, 0xCD820D48A53D95B7ULL,
0x8F72ECA30CD7A324ULL, 0x0150A8DAF8AB144EULL, 0x43A04931514122DDULL,
0x84B16B0DAB7F7968ULL, 0xC6418AE602954FFBULL, 0xBC387AEA7A8DA4C0ULL,
0xFEC89B01D3679253ULL, 0x39D9B93D2959C9E6ULL, 0x7B2958D680B3FF75ULL,
0xF50B1CAF74CF481FULL, 0xB7FBFD44DD257E8CULL, 0x70EADF78271B2539ULL,
0x321A3E938EF113AAULL, 0x2E5EB66066087D7EULL, 0x6CAE578BCFE24BEDULL,
0xABBF75B735DC1058ULL, 0xE94F945C9C3626CBULL, 0x676DD025684A91A1ULL,
0x259D31CEC1A0A732ULL, 0xE28C13F23B9EFC87ULL, 0xA07CF2199274CA14ULL,
0x167FF3EACBAF2AF1ULL, 0x548F120162451C62ULL, 0x939E303D987B47D7ULL,
0xD16ED1D631917144ULL, 0x5F4C95AFC5EDC62EULL, 0x1DBC74446C07F0BDULL,
0xDAAD56789639AB08ULL, 0x985DB7933FD39D9BULL, 0x84193F60D72AF34FULL,
0xC6E9DE8B7EC0C5DCULL, 0x01F8FCB784FE9E69ULL, 0x43081D5C2D14A8FAULL,
0xCD2A5925D9681F90ULL, 0x8FDAB8CE70822903ULL, 0x48CB9AF28ABC72B6ULL,
0x0A3B7B1923564425ULL, 0x70428B155B4EAF1EULL, 0x32B26AFEF2A4998DULL,
0xF5A348C2089AC238ULL, 0xB753A929A170F4ABULL, 0x3971ED50550C43C1ULL,
0x7B810CBBFCE67552ULL, 0xBC902E8706D82EE7ULL, 0xFE60CF6CAF321874ULL,
0xE224479F47CB76A0ULL, 0xA0D4A674EE214033ULL, 0x67C58448141F1B86ULL,
0x253565A3BDF52D15ULL, 0xAB1721DA49899A7FULL, 0xE9E7C031E063ACECULL,
0x2EF6E20D1A5DF759ULL, 0x6C0603E6B3B7C1CAULL, 0xF6FAE5C07D3274CDULL,
0xB40A042BD4D8425EULL, 0x731B26172EE619EBULL, 0x31EBC7FC870C2F78ULL,
0xBFC9838573709812ULL, 0xFD39626EDA9AAE81ULL, 0x3A28405220A4F534ULL,
0x78D8A1B9894EC3A7ULL, 0x649C294A61B7AD73ULL, 0x266CC8A1C85D9BE0ULL,
0xE17DEA9D3263C055ULL, 0xA38D0B769B89F6C6ULL, 0x2DAF4F0F6FF541ACULL,
0x6F5FAEE4C61F773FULL, 0xA84E8CD83C212C8AULL, 0xEABE6D3395CB1A19ULL,
0x90C79D3FEDD3F122ULL, 0xD2377CD44439C7B1ULL, 0x15265EE8BE079C04ULL,
0x57D6BF0317EDAA97ULL, 0xD9F4FB7AE3911DFDULL, 0x9B041A914A7B2B6EULL,
0x5C1538ADB04570DBULL, 0x1EE5D94619AF4648ULL, 0x02A151B5F156289CULL,
0x4051B05E58BC1E0FULL, 0x87409262A28245BAULL, 0xC5B073890B687329ULL,
0x4B9237F0FF14C443ULL, 0x0962D61B56FEF2D0ULL, 0xCE73F427ACC0A965ULL,
0x8C8315CC052A9FF6ULL, 0x3A80143F5CF17F13ULL, 0x7870F5D4F51B4980ULL,
0xBF61D7E80F251235ULL, 0xFD913603A6CF24A6ULL, 0x73B3727A52B393CCULL,
0x31439391FB59A55FULL, 0xF652B1AD0167FEEAULL, 0xB4A25046A88DC879ULL,
0xA8E6D8B54074A6ADULL, 0xEA16395EE99E903EULL, 0x2D071B6213A0CB8BULL,
0x6FF7FA89BA4AFD18ULL, 0xE1D5BEF04E364A72ULL, 0xA3255F1BE7DC7CE1ULL,
0x64347D271DE22754ULL, 0x26C49CCCB40811C7ULL, 0x5CBD6CC0CC10FAFCULL,
0x1E4D8D2B65FACC6FULL, 0xD95CAF179FC497DAULL, 0x9BAC4EFC362EA149ULL,
0x158E0A85C2521623ULL, 0x577EEB6E6BB820B0ULL, 0x906FC95291867B05ULL,
0xD29F28B9386C4D96ULL, 0xCEDBA04AD0952342ULL, 0x8C2B41A1797F15D1ULL,
0x4B3A639D83414E64ULL, 0x09CA82762AAB78F7ULL, 0x87E8C60FDED7CF9DULL,
0xC51827E4773DF90EULL, 0x020905D88D03A2BBULL, 0x40F9E43324E99428ULL,
0x2CFFE7D5975E55E2ULL, 0x6E0F063E3EB46371ULL, 0xA91E2402C48A38C4ULL,
0xEBEEC5E96D600E57ULL, 0x65CC8190991CB93DULL, 0x273C607B30F68FAEULL,
0xE02D4247CAC8D41BULL, 0xA2DDA3AC6322E288ULL, 0xBE992B5F8BDB8C5CULL,
0xFC69CAB42231BACFULL, 0x3B78E888D80FE17AULL, 0x7988096371E5D7E9ULL,
0xF7AA4D1A85996083ULL, 0xB55AACF12C735610ULL, 0x724B8ECDD64D0DA5ULL,
0x30BB6F267FA73B36ULL, 0x4AC29F2A07BFD00DULL, 0x08327EC1AE55E69EULL,
0xCF235CFD546BBD2BULL, 0x8DD3BD16FD818BB8ULL, 0x03F1F96F09FD3CD2ULL,
0x41011884A0170A41ULL, 0x86103AB85A2951F4ULL, 0xC4E0DB53F3C36767ULL,
0xD8A453A01B3A09B3ULL, 0x9A54B24BB2D03F20ULL, 0x5D45907748EE6495ULL,
0x1FB5719CE1045206ULL, 0x919735E51578E56CULL, 0xD367D40EBC92D3FFULL,
0x1476F63246AC884AULL, 0x568617D9EF46BED9ULL, 0xE085162AB69D5E3CULL,
0xA275F7C11F7768AFULL, 0x6564D5FDE549331AULL, 0x279434164CA30589ULL,
0xA9B6706FB8DFB2E3ULL, 0xEB46918411358470ULL, 0x2C57B3B8EB0BDFC5ULL,
0x6EA7525342E1E956ULL, 0x72E3DAA0AA188782ULL, 0x30133B4B03F2B111ULL,
0xF7021977F9CCEAA4ULL, 0xB5F2F89C5026DC37ULL, 0x3BD0BCE5A45A6B5DULL,
0x79205D0E0DB05DCEULL, 0xBE317F32F78E067BULL, 0xFCC19ED95E6430E8ULL,
0x86B86ED5267CDBD3ULL, 0xC4488F3E8F96ED40ULL, 0x0359AD0275A8B6F5ULL,
0x41A94CE9DC428066ULL, 0xCF8B0890283E370CULL, 0x8D7BE97B81D4019FULL,
0x4A6ACB477BEA5A2AULL, 0x089A2AACD2006CB9ULL, 0x14DEA25F3AF9026DULL,
0x562E43B4931334FEULL, 0x913F6188692D6F4BULL, 0xD3CF8063C0C759D8ULL,
0x5DEDC41A34BBEEB2ULL, 0x1F1D25F19D51D821ULL,
0xD80C07CD676F8394ULL, 0x9AFCE626CE85B507ULL
};
void
isc_crc64_init(isc_uint64_t *crc) {
REQUIRE(crc != NULL);
*crc = 0xffffffffffffffffULL;
}
void
isc_crc64_update(isc_uint64_t *crc, const isc_uint8_t *data, size_t len) {
unsigned char *p = data;
int i;
REQUIRE(crc != NULL);
REQUIRE(data != NULL);
while (len-- > 0) {
i = ((int) (*crc >> 56) ^ *p++) & 0xff;
*crc = crc64_table[i] ^ (*crc << 8);
}
}
void
isc_crc64_final(isc_uint64_t *crc) {
REQUIRE(crc != NULL);
*crc ^= 0xffffffffffffffffULL;
}
/*
* Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef ISC_CRC64_H
#define ISC_CRC64_H 1
/*! \file isc/crc64.h
* \brief CRC64 in C
*/
#include <isc/lang.h>
#include <isc/types.h>
ISC_LANG_BEGINDECLS
void
isc_crc64_init(isc_uint64_t *crc);
/*%
* Initialize a new CRC.
*
* Requires:
* * 'crc' is not NULL.
*/
void
isc_crc64_update(isc_uint64_t *crc, const isc_uint8_t *data, size_t len);
/*%
* Add data to the CRC.
*
* Requires:
* * 'crc' is not NULL.