X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fcrypto_crc.c;h=ea50b636c0913e4fcf1761abf485db1e70366686;hb=72c8645af31896829b674b575c5375706f362a30;hp=5920ddc938425444259683cde39306ccabce8568;hpb=d9d94d0e53d26af75ec8241383d166544ebd79f3;p=oweals%2Fgnunet.git diff --git a/src/util/crypto_crc.c b/src/util/crypto_crc.c index 5920ddc93..ea50b636c 100644 --- a/src/util/crypto_crc.c +++ b/src/util/crypto_crc.c @@ -17,17 +17,16 @@ Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - For the actual CRC code: + For the actual CRC-32 code: Copyright abandoned; this code is in the public domain. Provided to GNUnet by peter@horizon.com */ /** * @file util/crypto_crc.c - * @brief implementation of CRC32 + * @brief implementation of CRC16 and CRC32 * @author Christian Grothoff */ - #include "platform.h" #include "gnunet_common.h" #include "gnunet_crypto_lib.h" @@ -51,7 +50,7 @@ static uLong crc_table[256]; /* * This routine writes each crc_table entry exactly once, - * with the ccorrect final value. Thus, it is safe to call + * with the correct final value. Thus, it is safe to call * even on a table that someone else is using concurrently. */ static void @@ -66,12 +65,12 @@ crc_init () once = 1; crc_table[0] = 0; for (i = 128; i; i >>= 1) - { - h = (h >> 1) ^ ((h & 1) ? POLYNOMIAL : 0); - /* h is now crc_table[i] */ - for (j = 0; j < 256; j += 2 * i) - crc_table[i + j] = crc_table[j] ^ h; - } + { + h = (h >> 1) ^ ((h & 1) ? POLYNOMIAL : 0); + /* h is now crc_table[i] */ + for (j = 0; j < 256; j += 2 * i) + crc_table[i + j] = crc_table[j] ^ h; + } } /* @@ -113,4 +112,59 @@ GNUNET_CRYPTO_crc32_n (const void *buf, size_t len) return crc; } + +/** + * Perform an incremental step in a CRC16 (for TCP/IP) calculation. + * + * @param sum current sum, initially 0 + * @param buf buffer to calculate CRC over (must be 16-bit aligned) + * @param len number of bytes in hdr, must be multiple of 2 + * @return updated crc sum (must be subjected to GNUNET_CRYPTO_crc16_finish to get actual crc16) + */ +uint32_t +GNUNET_CRYPTO_crc16_step (uint32_t sum, const void *buf, size_t len) +{ + const uint16_t *hdr = buf; + for (; len >= 2; len -= 2) + sum += *(hdr++); + if (len == 1) + sum += (*hdr) & ntohs(0xFF00); + return sum; +} + + +/** + * Convert results from GNUNET_CRYPTO_crc16_step to final crc16. + * + * @param sum cummulative sum + * @return crc16 value + */ +uint16_t +GNUNET_CRYPTO_crc16_finish (uint32_t sum) +{ + sum = (sum >> 16) + (sum & 0xFFFF); + sum += (sum >> 16); + + return ~sum; +} + + +/** + * Calculate the checksum of a buffer in one step. + * + * @param buf buffer to calculate CRC over (must be 16-bit aligned) + * @param len number of bytes in hdr, must be multiple of 2 + * @return crc16 value + */ +uint16_t +GNUNET_CRYPTO_crc16_n (const void *buf, size_t len) +{ + const uint16_t *hdr = buf; + uint32_t sum = GNUNET_CRYPTO_crc16_step (0, hdr, len); + + return GNUNET_CRYPTO_crc16_finish (sum); +} + + + /* end of crypto_crc.c */