xref: /optee_os/core/lib/libtomcrypt/src/misc/crc32.c (revision 8411e6ad673d20c4742ed30c785e3f5cdea54dfa)
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