1*8411e6adSJerome Forissier /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2*8411e6adSJerome Forissier /* SPDX-License-Identifier: Unlicense */
35a913ee7SJerome Forissier #include "tomcrypt_private.h"
45a913ee7SJerome Forissier
55a913ee7SJerome Forissier /**
65a913ee7SJerome Forissier @file crc32.c
75a913ee7SJerome Forissier CRC-32 checksum algorithm
85a913ee7SJerome Forissier Written and placed in the public domain by Wei Dai
95a913ee7SJerome Forissier Adapted for libtomcrypt by Steffen Jaeckel
105a913ee7SJerome Forissier */
115a913ee7SJerome Forissier #ifdef LTC_CRC32
125a913ee7SJerome Forissier
13*8411e6adSJerome Forissier static const ulong32 CRC32_NEGL = 0xffffffffUL;
145a913ee7SJerome Forissier
155a913ee7SJerome Forissier #if defined(ENDIAN_LITTLE)
165a913ee7SJerome Forissier #define CRC32_INDEX(c) (c & 0xff)
175a913ee7SJerome Forissier #define CRC32_SHIFTED(c) (c >> 8)
185a913ee7SJerome Forissier #elif defined(ENDIAN_BIG)
195a913ee7SJerome Forissier #define CRC32_INDEX(c) (c >> 24)
205a913ee7SJerome Forissier #define CRC32_SHIFTED(c) (c << 8)
215a913ee7SJerome Forissier #else
225a913ee7SJerome Forissier #error The existing CRC32 implementation only works properly when the endianness of the target platform is known.
235a913ee7SJerome Forissier #endif
245a913ee7SJerome Forissier
255a913ee7SJerome Forissier /* Table of CRC-32's of all single byte values (made by makecrc.c) */
265a913ee7SJerome Forissier static const ulong32 crc32_m_tab[] =
275a913ee7SJerome Forissier {
285a913ee7SJerome Forissier #if defined(ENDIAN_LITTLE)
295a913ee7SJerome Forissier 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
305a913ee7SJerome Forissier 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
315a913ee7SJerome Forissier 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
325a913ee7SJerome Forissier 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
335a913ee7SJerome Forissier 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
345a913ee7SJerome Forissier 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
355a913ee7SJerome Forissier 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
365a913ee7SJerome Forissier 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
375a913ee7SJerome Forissier 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
385a913ee7SJerome Forissier 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
395a913ee7SJerome Forissier 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
405a913ee7SJerome Forissier 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
415a913ee7SJerome Forissier 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
425a913ee7SJerome Forissier 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
435a913ee7SJerome Forissier 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
445a913ee7SJerome Forissier 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
455a913ee7SJerome Forissier 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
465a913ee7SJerome Forissier 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
475a913ee7SJerome Forissier 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
485a913ee7SJerome Forissier 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
495a913ee7SJerome Forissier 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
505a913ee7SJerome Forissier 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
515a913ee7SJerome Forissier 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
525a913ee7SJerome Forissier 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
535a913ee7SJerome Forissier 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
545a913ee7SJerome Forissier 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
555a913ee7SJerome Forissier 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
565a913ee7SJerome Forissier 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
575a913ee7SJerome Forissier 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
585a913ee7SJerome Forissier 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
595a913ee7SJerome Forissier 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
605a913ee7SJerome Forissier 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
615a913ee7SJerome Forissier 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
625a913ee7SJerome Forissier 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
635a913ee7SJerome Forissier 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
645a913ee7SJerome Forissier 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
655a913ee7SJerome Forissier 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
665a913ee7SJerome Forissier 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
675a913ee7SJerome Forissier 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
685a913ee7SJerome Forissier 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
695a913ee7SJerome Forissier 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
705a913ee7SJerome Forissier 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
715a913ee7SJerome Forissier 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
725a913ee7SJerome Forissier 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
735a913ee7SJerome Forissier 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
745a913ee7SJerome Forissier 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
755a913ee7SJerome Forissier 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
765a913ee7SJerome Forissier 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
775a913ee7SJerome Forissier 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
785a913ee7SJerome Forissier 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
795a913ee7SJerome Forissier 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
805a913ee7SJerome Forissier 0x2d02ef8dL
815a913ee7SJerome Forissier #else
825a913ee7SJerome Forissier 0x00000000L, 0x96300777L, 0x2c610eeeL, 0xba510999L, 0x19c46d07L,
835a913ee7SJerome Forissier 0x8ff46a70L, 0x35a563e9L, 0xa395649eL, 0x3288db0eL, 0xa4b8dc79L,
845a913ee7SJerome Forissier 0x1ee9d5e0L, 0x88d9d297L, 0x2b4cb609L, 0xbd7cb17eL, 0x072db8e7L,
855a913ee7SJerome Forissier 0x911dbf90L, 0x6410b71dL, 0xf220b06aL, 0x4871b9f3L, 0xde41be84L,
865a913ee7SJerome Forissier 0x7dd4da1aL, 0xebe4dd6dL, 0x51b5d4f4L, 0xc785d383L, 0x56986c13L,
875a913ee7SJerome Forissier 0xc0a86b64L, 0x7af962fdL, 0xecc9658aL, 0x4f5c0114L, 0xd96c0663L,
885a913ee7SJerome Forissier 0x633d0ffaL, 0xf50d088dL, 0xc8206e3bL, 0x5e10694cL, 0xe44160d5L,
895a913ee7SJerome Forissier 0x727167a2L, 0xd1e4033cL, 0x47d4044bL, 0xfd850dd2L, 0x6bb50aa5L,
905a913ee7SJerome Forissier 0xfaa8b535L, 0x6c98b242L, 0xd6c9bbdbL, 0x40f9bcacL, 0xe36cd832L,
915a913ee7SJerome Forissier 0x755cdf45L, 0xcf0dd6dcL, 0x593dd1abL, 0xac30d926L, 0x3a00de51L,
925a913ee7SJerome Forissier 0x8051d7c8L, 0x1661d0bfL, 0xb5f4b421L, 0x23c4b356L, 0x9995bacfL,
935a913ee7SJerome Forissier 0x0fa5bdb8L, 0x9eb80228L, 0x0888055fL, 0xb2d90cc6L, 0x24e90bb1L,
945a913ee7SJerome Forissier 0x877c6f2fL, 0x114c6858L, 0xab1d61c1L, 0x3d2d66b6L, 0x9041dc76L,
955a913ee7SJerome Forissier 0x0671db01L, 0xbc20d298L, 0x2a10d5efL, 0x8985b171L, 0x1fb5b606L,
965a913ee7SJerome Forissier 0xa5e4bf9fL, 0x33d4b8e8L, 0xa2c90778L, 0x34f9000fL, 0x8ea80996L,
975a913ee7SJerome Forissier 0x18980ee1L, 0xbb0d6a7fL, 0x2d3d6d08L, 0x976c6491L, 0x015c63e6L,
985a913ee7SJerome Forissier 0xf4516b6bL, 0x62616c1cL, 0xd8306585L, 0x4e0062f2L, 0xed95066cL,
995a913ee7SJerome Forissier 0x7ba5011bL, 0xc1f40882L, 0x57c40ff5L, 0xc6d9b065L, 0x50e9b712L,
1005a913ee7SJerome Forissier 0xeab8be8bL, 0x7c88b9fcL, 0xdf1ddd62L, 0x492dda15L, 0xf37cd38cL,
1015a913ee7SJerome Forissier 0x654cd4fbL, 0x5861b24dL, 0xce51b53aL, 0x7400bca3L, 0xe230bbd4L,
1025a913ee7SJerome Forissier 0x41a5df4aL, 0xd795d83dL, 0x6dc4d1a4L, 0xfbf4d6d3L, 0x6ae96943L,
1035a913ee7SJerome Forissier 0xfcd96e34L, 0x468867adL, 0xd0b860daL, 0x732d0444L, 0xe51d0333L,
1045a913ee7SJerome Forissier 0x5f4c0aaaL, 0xc97c0dddL, 0x3c710550L, 0xaa410227L, 0x10100bbeL,
1055a913ee7SJerome Forissier 0x86200cc9L, 0x25b56857L, 0xb3856f20L, 0x09d466b9L, 0x9fe461ceL,
1065a913ee7SJerome Forissier 0x0ef9de5eL, 0x98c9d929L, 0x2298d0b0L, 0xb4a8d7c7L, 0x173db359L,
1075a913ee7SJerome Forissier 0x810db42eL, 0x3b5cbdb7L, 0xad6cbac0L, 0x2083b8edL, 0xb6b3bf9aL,
1085a913ee7SJerome Forissier 0x0ce2b603L, 0x9ad2b174L, 0x3947d5eaL, 0xaf77d29dL, 0x1526db04L,
1095a913ee7SJerome Forissier 0x8316dc73L, 0x120b63e3L, 0x843b6494L, 0x3e6a6d0dL, 0xa85a6a7aL,
1105a913ee7SJerome Forissier 0x0bcf0ee4L, 0x9dff0993L, 0x27ae000aL, 0xb19e077dL, 0x44930ff0L,
1115a913ee7SJerome Forissier 0xd2a30887L, 0x68f2011eL, 0xfec20669L, 0x5d5762f7L, 0xcb676580L,
1125a913ee7SJerome Forissier 0x71366c19L, 0xe7066b6eL, 0x761bd4feL, 0xe02bd389L, 0x5a7ada10L,
1135a913ee7SJerome Forissier 0xcc4add67L, 0x6fdfb9f9L, 0xf9efbe8eL, 0x43beb717L, 0xd58eb060L,
1145a913ee7SJerome Forissier 0xe8a3d6d6L, 0x7e93d1a1L, 0xc4c2d838L, 0x52f2df4fL, 0xf167bbd1L,
1155a913ee7SJerome Forissier 0x6757bca6L, 0xdd06b53fL, 0x4b36b248L, 0xda2b0dd8L, 0x4c1b0aafL,
1165a913ee7SJerome Forissier 0xf64a0336L, 0x607a0441L, 0xc3ef60dfL, 0x55df67a8L, 0xef8e6e31L,
1175a913ee7SJerome Forissier 0x79be6946L, 0x8cb361cbL, 0x1a8366bcL, 0xa0d26f25L, 0x36e26852L,
1185a913ee7SJerome Forissier 0x95770cccL, 0x03470bbbL, 0xb9160222L, 0x2f260555L, 0xbe3bbac5L,
1195a913ee7SJerome Forissier 0x280bbdb2L, 0x925ab42bL, 0x046ab35cL, 0xa7ffd7c2L, 0x31cfd0b5L,
1205a913ee7SJerome Forissier 0x8b9ed92cL, 0x1daede5bL, 0xb0c2649bL, 0x26f263ecL, 0x9ca36a75L,
1215a913ee7SJerome Forissier 0x0a936d02L, 0xa906099cL, 0x3f360eebL, 0x85670772L, 0x13570005L,
1225a913ee7SJerome Forissier 0x824abf95L, 0x147ab8e2L, 0xae2bb17bL, 0x381bb60cL, 0x9b8ed292L,
1235a913ee7SJerome Forissier 0x0dbed5e5L, 0xb7efdc7cL, 0x21dfdb0bL, 0xd4d2d386L, 0x42e2d4f1L,
1245a913ee7SJerome Forissier 0xf8b3dd68L, 0x6e83da1fL, 0xcd16be81L, 0x5b26b9f6L, 0xe177b06fL,
1255a913ee7SJerome Forissier 0x7747b718L, 0xe65a0888L, 0x706a0fffL, 0xca3b0666L, 0x5c0b0111L,
1265a913ee7SJerome Forissier 0xff9e658fL, 0x69ae62f8L, 0xd3ff6b61L, 0x45cf6c16L, 0x78e20aa0L,
1275a913ee7SJerome Forissier 0xeed20dd7L, 0x5483044eL, 0xc2b30339L, 0x612667a7L, 0xf71660d0L,
1285a913ee7SJerome Forissier 0x4d476949L, 0xdb776e3eL, 0x4a6ad1aeL, 0xdc5ad6d9L, 0x660bdf40L,
1295a913ee7SJerome Forissier 0xf03bd837L, 0x53aebca9L, 0xc59ebbdeL, 0x7fcfb247L, 0xe9ffb530L,
1305a913ee7SJerome Forissier 0x1cf2bdbdL, 0x8ac2bacaL, 0x3093b353L, 0xa6a3b424L, 0x0536d0baL,
1315a913ee7SJerome Forissier 0x9306d7cdL, 0x2957de54L, 0xbf67d923L, 0x2e7a66b3L, 0xb84a61c4L,
1325a913ee7SJerome Forissier 0x021b685dL, 0x942b6f2aL, 0x37be0bb4L, 0xa18e0cc3L, 0x1bdf055aL,
1335a913ee7SJerome Forissier 0x8def022dL
1345a913ee7SJerome Forissier #endif
1355a913ee7SJerome Forissier };
1365a913ee7SJerome Forissier
crc32_init(crc32_state * ctx)1375a913ee7SJerome Forissier void crc32_init(crc32_state *ctx)
1385a913ee7SJerome Forissier {
1395a913ee7SJerome Forissier LTC_ARGCHKVD(ctx != NULL);
140*8411e6adSJerome Forissier ctx->crc = CRC32_NEGL;
1415a913ee7SJerome Forissier }
1425a913ee7SJerome Forissier
crc32_update(crc32_state * ctx,const unsigned char * input,unsigned long length)1435a913ee7SJerome Forissier void crc32_update(crc32_state *ctx, const unsigned char *input, unsigned long length)
1445a913ee7SJerome Forissier {
1455a913ee7SJerome Forissier ulong32 crc;
1465a913ee7SJerome Forissier LTC_ARGCHKVD(ctx != NULL);
1475a913ee7SJerome Forissier LTC_ARGCHKVD(input != NULL);
1485a913ee7SJerome Forissier crc = ctx->crc;
1495a913ee7SJerome Forissier
1505a913ee7SJerome Forissier while (length--) {
1515a913ee7SJerome Forissier crc = crc32_m_tab[CRC32_INDEX(crc) ^ *input++] ^ CRC32_SHIFTED(crc);
1525a913ee7SJerome Forissier }
1535a913ee7SJerome Forissier
1545a913ee7SJerome Forissier ctx->crc = crc;
1555a913ee7SJerome Forissier }
1565a913ee7SJerome Forissier
crc32_finish(const crc32_state * ctx,void * hash,unsigned long size)1575a913ee7SJerome Forissier void crc32_finish(const crc32_state *ctx, void *hash, unsigned long size)
1585a913ee7SJerome Forissier {
1595a913ee7SJerome Forissier unsigned long i;
1605a913ee7SJerome Forissier unsigned char* h;
1615a913ee7SJerome Forissier ulong32 crc;
1625a913ee7SJerome Forissier LTC_ARGCHKVD(ctx != NULL);
1635a913ee7SJerome Forissier LTC_ARGCHKVD(hash != NULL);
1645a913ee7SJerome Forissier
1655a913ee7SJerome Forissier h = hash;
1665a913ee7SJerome Forissier crc = ctx->crc;
167*8411e6adSJerome Forissier crc ^= CRC32_NEGL;
1685a913ee7SJerome Forissier
1695a913ee7SJerome Forissier if (size > 4) size = 4;
1705a913ee7SJerome Forissier for (i = 0; i < size; i++) {
1715a913ee7SJerome Forissier h[i] = ((unsigned char*)&(crc))[size-i-1];
1725a913ee7SJerome Forissier }
1735a913ee7SJerome Forissier }
1745a913ee7SJerome Forissier
crc32_test(void)1755a913ee7SJerome Forissier int crc32_test(void)
1765a913ee7SJerome Forissier {
1775a913ee7SJerome Forissier #ifndef LTC_TEST
1785a913ee7SJerome Forissier return CRYPT_NOP;
1795a913ee7SJerome Forissier #else
1805a913ee7SJerome Forissier const void* in = "libtomcrypt";
1815a913ee7SJerome Forissier const unsigned char crc32[] = { 0xb3, 0x73, 0x76, 0xef };
1825a913ee7SJerome Forissier unsigned char out[4];
1835a913ee7SJerome Forissier crc32_state ctx;
1845a913ee7SJerome Forissier crc32_init(&ctx);
185*8411e6adSJerome Forissier crc32_update(&ctx, in, XSTRLEN(in));
1865a913ee7SJerome Forissier crc32_finish(&ctx, out, 4);
1875a913ee7SJerome Forissier if (compare_testvector(crc32, 4, out, 4, "CRC32", 0)) {
1885a913ee7SJerome Forissier return CRYPT_FAIL_TESTVECTOR;
1895a913ee7SJerome Forissier }
1905a913ee7SJerome Forissier return CRYPT_OK;
1915a913ee7SJerome Forissier #endif
1925a913ee7SJerome Forissier }
1935a913ee7SJerome Forissier #endif
194