]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[rt33746] use CRC64 for map file error detection
authorEvan Hunt <each@isc.org>
Mon, 10 Jun 2013 21:19:22 +0000 (14:19 -0700)
committerEvan Hunt <each@isc.org>
Mon, 10 Jun 2013 21:19:22 +0000 (14:19 -0700)
3591. [func] Use CRC-64 to detect map file corruption at load
time. [RT #33746]

12 files changed:
CHANGES
lib/dns/include/dns/rbt.h
lib/dns/rbt.c
lib/dns/rbtdb.c
lib/dns/tests/rbt_test.c
lib/isc/Makefile.in
lib/isc/crc64.c [new file with mode: 0644]
lib/isc/include/isc/crc64.h [new file with mode: 0644]
lib/isc/tests/hash_test.c
lib/isc/win32/libisc.def
lib/isc/win32/libisc.dsp
lib/isc/win32/libisc.mak

diff --git a/CHANGES b/CHANGES
index 4d7ed093f910d69854ff3f5f624272f355826f90..5bb157cf9a89f9d4f07358825cbe2baf42f1e187 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+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
index 85976506086106c38998428fd07fc4d0daaa3411..85c3479df83b558638e01c73893e7191a6f71bbe 100644 (file)
 
 /*! \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
index 5692bca78aabefdf85204d4084396fa191cdd429..7bc31cd60a91ac27acdf98d00abdf1a5228c0b57 100644 (file)
 #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;
        }
index eb7221b521f7f3f0f607519cb450abbcc2ac8e7e..de78f75361ed95dc9de07e666f52ca953bb59635 100644 (file)
@@ -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)
index d74c502e0ce576dbc9b3f9b64c7b469fb201118a..0fef45897b79d18700e73326998cecdb33cf0227 100644 (file)
@@ -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);
 }
index b6b206f21633f0a62e2fbc56ef7ac1b744b83355..7dff06cc7d07dda0333cab0dbe6a84cb11490c72 100644 (file)
@@ -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 \
diff --git a/lib/isc/crc64.c b/lib/isc/crc64.c
new file mode 100644 (file)
index 0000000..e83cdc0
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * 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;
+}
diff --git a/lib/isc/include/isc/crc64.h b/lib/isc/include/isc/crc64.h
new file mode 100644 (file)
index 0000000..0403fec
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ * * 'data' is not NULL.
+ */
+
+void
+isc_crc64_final(isc_uint64_t *crc);
+/*%
+ * Finalize the CRC.
+ *
+ * Requires:
+ * * 'crc' is not NULL.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_CRC64_H */
index 836d7b67abc744aaa6f99a5d2ac02bf82e840054..b3dc1d2d5012ac6a7253a1abc4c1c0ca1937b512 100644 (file)
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <string.h>
 
+#include <isc/crc64.h>
 #include <isc/hmacmd5.h>
 #include <isc/hmacsha.h>
 #include <isc/md5.h>
@@ -1784,6 +1785,67 @@ ATF_TC_BODY(isc_hmacmd5, tc) {
        }
 }
 
+/* CRC64 Test */
+ATF_TC(isc_crc64);
+ATF_TC_HEAD(isc_crc64, tc) {
+       atf_tc_set_md_var(tc, "descr", "64-bit cyclic redundancy check");
+}
+ATF_TC_BODY(isc_crc64, tc) {
+       isc_uint64_t crc;
+
+       UNUSED(tc);
+
+       hash_testcase_t testcases[] = {
+               {
+                       TEST_INPUT(""),
+                       "0x0000000000000000", 1
+               },
+               {
+                       TEST_INPUT("a"),
+                       "0x9AA9C0AC27F473CE", 1
+               },
+               {
+                       TEST_INPUT("abc"),
+                       "0x0297F4F93A818B04", 1
+               },
+               {
+                       TEST_INPUT("message digest"),
+                       "0xF47B357AEAF97352", 1
+               },
+               {
+                       TEST_INPUT("abcdefghijklmnopqrstuvwxyz"),
+                       "0xA1AA8B21F979F059", 1
+               },
+               {
+                       TEST_INPUT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm"
+                                  "nopqrstuvwxyz0123456789"),
+                       "0xFBB6781EF7A86DA3", 1
+               },
+               {
+                       TEST_INPUT("123456789012345678901234567890123456789"
+                                  "01234567890123456789012345678901234567890"),
+                       "0x4A87E7C873EBE581", 1
+               },
+               { NULL, 0, NULL, 1 }
+       };
+
+       hash_testcase_t *testcase = testcases;
+
+       while (testcase->input != NULL && testcase->result != NULL) {
+               isc_crc64_init(&crc);
+               for(i = 0; i < testcase->repeats; i++) {
+                       isc_crc64_update(&crc,
+                                      (const isc_uint8_t *) testcase->input,
+                                      testcase->input_len);
+               }
+               isc_crc64_final(&crc);
+               tohexstr((unsigned char *) &crc, sizeof(crc), str);
+               ATF_CHECK_STREQ(str, testcase->result);
+
+               testcase++;
+       }
+}
+
 /*
  * Main
  */
@@ -1800,6 +1862,7 @@ ATF_TP_ADD_TCS(tp) {
        ATF_TP_ADD_TC(tp, isc_sha256);
        ATF_TP_ADD_TC(tp, isc_sha384);
        ATF_TP_ADD_TC(tp, isc_sha512);
+       ATF_TP_ADD_TC(tp, isc_crc64);
        return (atf_no_error());
 }
 
index 8a0b1f3d74c55572781e1e51a913bee42b84d9e9..5b383634a3f21503e3f6717b48cd64385658ae12 100644 (file)
@@ -192,6 +192,9 @@ isc_condition_init
 isc_condition_signal
 isc_condition_wait
 isc_condition_waituntil
+isc_crc64_init
+isc_crc64_update
+isc_crc64_final
 isc_dir_chdir
 isc_dir_chroot
 isc_dir_close
index 13fc7f132243ed85c79aff0fd5b7fe5c5ac9323b..33519ae4d8c1bb1b4e5fb3773f906d5693976082 100644 (file)
@@ -103,6 +103,10 @@ SOURCE=.\condition.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\crc64.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\dir.c
 # End Source File
 # Begin Source File
@@ -259,6 +263,10 @@ SOURCE=..\..\..\config.h
 # End Source File
 # Begin Source File
 
+SOURCE=.\include\isc\crc64.h
+# End Source File
+# Begin Source File
+
 SOURCE=.\include\isc\dir.h
 # End Source File
 # Begin Source File
index 4e0766c08fcda061f99f565b0d0a3cfba0b9d35d..714723699df513a0dfa8ea397011aba92fcda1fb 100644 (file)
@@ -125,6 +125,7 @@ CLEAN :
        -@erase "$(INTDIR)\bufferlist.obj"
        -@erase "$(INTDIR)\commandline.obj"
        -@erase "$(INTDIR)\condition.obj"
+       -@erase "$(INTDIR)\crc64.obj"
        -@erase "$(INTDIR)\dir.obj"
        -@erase "$(INTDIR)\DLLMain.obj"
        -@erase "$(INTDIR)\entropy.obj"
@@ -215,6 +216,7 @@ DEF_FILE= \
 LINK32_OBJS= \
        "$(INTDIR)\app.obj" \
        "$(INTDIR)\condition.obj" \
+       "$(INTDIR)\crc64.obj" \
        "$(INTDIR)\dir.obj" \
        "$(INTDIR)\DLLMain.obj" \
        "$(INTDIR)\entropy.obj" \
@@ -333,6 +335,8 @@ CLEAN :
        -@erase "$(INTDIR)\commandline.sbr"
        -@erase "$(INTDIR)\condition.obj"
        -@erase "$(INTDIR)\condition.sbr"
+       -@erase "$(INTDIR)\crc64.obj"
+       -@erase "$(INTDIR)\crc64.sbr"
        -@erase "$(INTDIR)\dir.obj"
        -@erase "$(INTDIR)\dir.sbr"
        -@erase "$(INTDIR)\DLLMain.obj"
@@ -490,6 +494,7 @@ BSC32_FLAGS=/nologo /o"$(OUTDIR)\libisc.bsc"
 BSC32_SBRS= \
        "$(INTDIR)\app.sbr" \
        "$(INTDIR)\condition.sbr" \
+       "$(INTDIR)\crc64.sbr" \
        "$(INTDIR)\dir.sbr" \
        "$(INTDIR)\DLLMain.sbr" \
        "$(INTDIR)\entropy.sbr" \
@@ -580,6 +585,7 @@ DEF_FILE= \
 LINK32_OBJS= \
        "$(INTDIR)\app.obj" \
        "$(INTDIR)\condition.obj" \
+       "$(INTDIR)\crc64.obj" \
        "$(INTDIR)\dir.obj" \
        "$(INTDIR)\DLLMain.obj" \
        "$(INTDIR)\entropy.obj" \
@@ -737,6 +743,22 @@ SOURCE=.\condition.c
 "$(INTDIR)\condition.obj"      "$(INTDIR)\condition.sbr" : $(SOURCE) "$(INTDIR)"
 
 
+!ENDIF 
+
+SOURCE=.\crc64.c
+
+!IF  "$(CFG)" == "libisc - Win32 Release"
+
+
+"$(INTDIR)\crc64.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF  "$(CFG)" == "libisc - Win32 Debug"
+
+
+"$(INTDIR)\crc64.obj"  "$(INTDIR)\crc64.sbr" : $(SOURCE) "$(INTDIR)"
+
+
 !ENDIF 
 
 SOURCE=.\dir.c