mirror of
https://github.com/uroni/urbackup_backend.git
synced 2025-10-26 11:36:50 +00:00
On my system, compiling urbackup-client causes error ``` blockalign_src/crc.cpp: In function ‘bool cryptopp_crc::IsAlignedOn(const void*, unsigned int)’: blockalign_src/crc.cpp:191:23: error: ‘uintptr_t’ does not name a type 191 | const uintptr_t x = reinterpret_cast<uintptr_t>(ptr); ``` This change fixes this error
657 lines
22 KiB
C++
657 lines
22 KiB
C++
// crc.cpp - written and placed in the public domain by Wei Dai
|
|
|
|
#include "crc.h"
|
|
#ifndef _WIN32
|
|
#include <signal.h>
|
|
#include <setjmp.h>
|
|
#endif
|
|
|
|
#include <cstdint> // for uintptr_t data type
|
|
|
|
// Visual Studio needs VS2008 (1500)
|
|
// http://msdn.microsoft.com/en-us/library/bb531394%28v=vs.90%29.aspx
|
|
#if defined(_MSC_VER) && (_MSC_VER < 1500)
|
|
# undef CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE
|
|
#endif
|
|
|
|
#if !defined(CRYPTOPP_LITTLE_ENDIAN) && !defined(CRYPTOPP_BIG_ENDIAN) && (defined(__BIG_ENDIAN__) || (defined(__s390__) || defined(__s390x__) || defined(__zarch__)) || (defined(__m68k__) || defined(__MC68K__)) || defined(__sparc) || defined(__sparc__) || defined(__hppa__) || defined(__MIPSEB__) || defined(__ARMEB__) || (defined(__MWERKS__) && !defined(__INTEL__)))
|
|
# define CRYPTOPP_BIG_ENDIAN 1
|
|
#endif
|
|
|
|
// define this if running on a little-endian CPU
|
|
// big endian will be assumed if CRYPTOPP_LITTLE_ENDIAN is not non-0
|
|
#if !defined(CRYPTOPP_BIG_ENDIAN) && !defined(CRYPTOPP_LITTLE_ENDIAN)
|
|
# define CRYPTOPP_LITTLE_ENDIAN 1
|
|
#endif
|
|
|
|
// Intrinsics availible in GCC 4.3 (http://gcc.gnu.org/gcc-4.3/changes.html) and
|
|
// MSVC 2008 (http://msdn.microsoft.com/en-us/library/bb892950%28v=vs.90%29.aspx)
|
|
// SunCC could generate SSE4 at 12.1, but the intrinsics are missing until 12.4.
|
|
#if !defined(CRYPTOPP_DISABLE_ASM) && !defined(CRYPTOPP_DISABLE_SSE4) && !defined(_M_ARM) && ((_MSC_VER >= 1500) || (defined(__SSE4_1__) && defined(__SSE4_2__)))
|
|
#define CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE 1
|
|
#else
|
|
#define CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE 0
|
|
#endif
|
|
|
|
// Requires ARMv8 and ACLE 2.0. For GCC, requires 4.8 and above.
|
|
// Microsoft plans to support ARM-64, but its not clear how to detect it.
|
|
// TODO: Add MSC_VER and ARM-64 platform define when available
|
|
#if !defined(CRYPTOPP_BOOL_ARM_CRC32_INTRINSICS_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
|
|
# if defined(__ARM_FEATURE_CRC32) || defined(_M_ARM64)
|
|
# define CRYPTOPP_BOOL_ARM_CRC32_INTRINSICS_AVAILABLE 1
|
|
#if defined(_MSC_VER)
|
|
#include <intrin.h>
|
|
#else
|
|
# include <stdint.h>
|
|
# include <arm_acle.h>
|
|
#endif
|
|
# endif
|
|
#endif
|
|
|
|
#if CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE
|
|
#if defined(_MSC_VER)
|
|
#include <intrin.h>
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
|
# define CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
|
|
#else
|
|
# define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
|
|
#endif
|
|
#if ((__ILP32__ >= 1) || (_ILP32 >= 1)) && defined(__x86_64__)
|
|
#define CRYPTOPP_BOOL_X32 1
|
|
#else
|
|
#define CRYPTOPP_BOOL_X32 0
|
|
#endif
|
|
// see http://predef.sourceforge.net/prearch.html
|
|
#if (defined(_M_IX86) || defined(__i386__) || defined(__i386) || defined(_X86_) || defined(__I86__) || defined(__INTEL__)) && !CRYPTOPP_BOOL_X32
|
|
#define CRYPTOPP_BOOL_X86 1
|
|
#else
|
|
#define CRYPTOPP_BOOL_X86 0
|
|
#endif
|
|
|
|
#if (defined(_M_X64) || defined(__x86_64__)) && !CRYPTOPP_BOOL_X32
|
|
#define CRYPTOPP_BOOL_X64 1
|
|
#else
|
|
#define CRYPTOPP_BOOL_X64 0
|
|
#endif
|
|
|
|
// Define this to ensure C/C++ standard compliance and respect for GCC aliasing rules and other alignment fodder. If you
|
|
// experience a break with GCC at -O3, you should try this first. Guard it in case its set on the command line (and it differs).
|
|
#ifndef CRYPTOPP_NO_UNALIGNED_DATA_ACCESS
|
|
# define CRYPTOPP_NO_UNALIGNED_DATA_ACCESS
|
|
#endif
|
|
|
|
#if !defined(CRYPTOPP_NO_UNALIGNED_DATA_ACCESS) && !defined(CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS)
|
|
#if (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || defined(__powerpc__) || (__ARM_FEATURE_UNALIGNED >= 1))
|
|
#define CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
|
|
#endif
|
|
#endif
|
|
#ifdef _MSC_VER
|
|
#define CRYPTOPP_MSC_VERSION (_MSC_VER)
|
|
#endif
|
|
#ifdef __GNUC__
|
|
#define CRYPTOPP_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
|
#endif
|
|
#if (CRYPTOPP_MSC_VERSION >= 1900)
|
|
# define CRYPTOPP_CXX11_ALIGNAS 1
|
|
# define CRYPTOPP_CXX11_ALIGNOF 1
|
|
#elif (__INTEL_COMPILER >= 1500)
|
|
# define CRYPTOPP_CXX11_ALIGNAS 1
|
|
# define CRYPTOPP_CXX11_ALIGNOF 1
|
|
#elif defined(__clang__)
|
|
# if __has_feature(cxx_alignas)
|
|
# define CRYPTOPP_CXX11_ALIGNAS 1
|
|
# endif
|
|
# if __has_feature(cxx_alignof)
|
|
# define CRYPTOPP_CXX11_ALIGNOF 1
|
|
# endif
|
|
#elif (CRYPTOPP_GCC_VERSION >= 40800)
|
|
# define CRYPTOPP_CXX11_ALIGNAS 1
|
|
# define CRYPTOPP_CXX11_ALIGNOF 1
|
|
#elif (__SUNPRO_CC >= 0x5130)
|
|
# define CRYPTOPP_CXX11_ALIGNAS 1
|
|
# define CRYPTOPP_CXX11_ALIGNOF 1
|
|
#endif // alignof/alignas
|
|
|
|
// uintptr_t and ptrdiff_t
|
|
#if (__cplusplus < 201103L) && (!defined(_MSC_VER) || (_MSC_VER >= 1700))
|
|
# include <stdint.h>
|
|
#elif defined(_MSC_VER) && (_MSC_VER < 1700)
|
|
# include <stddef.h>
|
|
#endif
|
|
|
|
#if CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE
|
|
#include <smmintrin.h>
|
|
#endif
|
|
|
|
#ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
|
|
extern "C" {
|
|
typedef void(*SigHandler)(int);
|
|
};
|
|
#endif // Not CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
|
|
|
|
namespace cryptopp_crc
|
|
{
|
|
typedef unsigned int word32;
|
|
|
|
/// \brief Tests whether a value is a power of 2
|
|
/// \param value the value to test
|
|
/// \returns true if value is a power of 2, false otherwise
|
|
/// \details The function creates a mask of <tt>value - 1</tt> and returns the result
|
|
/// of an AND operation compared to 0. If value is 0 or less than 0, then the function
|
|
/// returns false.
|
|
template <class T>
|
|
inline bool IsPowerOf2(const T &value)
|
|
{
|
|
return value > 0 && (value & (value - 1)) == 0;
|
|
}
|
|
|
|
/// \brief Performs a saturating subtract clamped at 0
|
|
/// \tparam T1 class or type
|
|
/// \tparam T2 class or type
|
|
/// \param a the minuend
|
|
/// \param b the subtrahend
|
|
/// \returns the difference produced by the saturating subtract
|
|
/// \details Saturating arithmetic restricts results to a fixed range. Results that are
|
|
/// less than 0 are clamped at 0.
|
|
/// \details Use of saturating arithmetic in places can be advantageous because it can
|
|
/// avoid a branch by using an instruction like a conditional move (<tt>CMOVE</tt>).
|
|
template <class T1, class T2>
|
|
inline T1 SaturatingSubtract(const T1 &a, const T2 &b)
|
|
{
|
|
// Generated ASM of a typical clamp, http://gcc.gnu.org/ml/gcc-help/2014-10/msg00112.html
|
|
return T1((a > b) ? (a - b) : 0);
|
|
}
|
|
|
|
/// \brief Reduces a value to a power of 2
|
|
/// \tparam T1 class or type
|
|
/// \tparam T2 class or type
|
|
/// \param a the first value
|
|
/// \param b the second value
|
|
/// \returns ModPowerOf2() returns <tt>a & (b-1)</tt>. <tt>b</tt> must be a power of 2.
|
|
/// Use IsPowerOf2() to determine if <tt>b</tt> is a suitable candidate.
|
|
/// \sa IsPowerOf2
|
|
template <class T1, class T2>
|
|
inline T2 ModPowerOf2(const T1 &a, const T2 &b)
|
|
{
|
|
// Coverity finding CID 170383 Overflowed return value (INTEGER_OVERFLOW)
|
|
return T2(a) & SaturatingSubtract(b, 1U);
|
|
}
|
|
|
|
/// \brief Determines whether ptr is aligned to a minimum value
|
|
/// \param ptr the pointer being checked for alignment
|
|
/// \param alignment the alignment value to test the pointer against
|
|
/// \returns true if <tt>ptr</tt> is aligned on at least <tt>alignment</tt>
|
|
/// boundary, false otherwise
|
|
/// \details Internally the function tests whether alignment is 1. If so,
|
|
/// the function returns true. If not, then the function effectively
|
|
/// performs a modular reduction and returns true if the residue is 0.
|
|
inline bool IsAlignedOn(const void *ptr, unsigned int alignment)
|
|
{
|
|
const uintptr_t x = reinterpret_cast<uintptr_t>(ptr);
|
|
return alignment == 1 || (IsPowerOf2(alignment) ? ModPowerOf2(x, alignment) == 0 : x % alignment == 0);
|
|
}
|
|
|
|
|
|
|
|
//! \brief Returns the minimum alignment requirements of a type
|
|
//! \param dummy an unused Visual C++ 6.0 workaround
|
|
//! \returns the minimum alignment requirements of a type, in bytes
|
|
//! \details Internally the function calls C++11's <tt>alignof</tt> if available. If not available,
|
|
//! then the function uses compiler specific extensions such as <tt>__alignof</tt> and
|
|
//! <tt>_alignof_</tt>. If an extension is not available, then the function uses
|
|
//! <tt>__BIGGEST_ALIGNMENT__</tt> if <tt>__BIGGEST_ALIGNMENT__</tt> is smaller than <tt>sizeof(T)</tt>.
|
|
//! <tt>sizeof(T)</tt> is used if all others are not available.
|
|
//! In <em>all</em> cases, if <tt>CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS</tt> is defined, then the
|
|
//! function returns 1.
|
|
template <class T>
|
|
inline unsigned int GetAlignmentOf(T *dummy = nullptr) // VC60 workaround
|
|
{
|
|
// GCC 4.6 (circa 2008) and above aggressively uses vectorization.
|
|
#if defined(CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS)
|
|
if (sizeof(T) < 16)
|
|
return 1;
|
|
#endif
|
|
#if defined(__GNUC__) && !defined(__clang__)
|
|
return __alignof__(T);
|
|
#elif defined(CRYPTOPP_CXX11_ALIGNOF)
|
|
return alignof(T);
|
|
#elif (_MSC_VER >= 1300)
|
|
return __alignof(T);
|
|
#elif CRYPTOPP_BOOL_SLOW_WORD64
|
|
return UnsignedMin(4U, sizeof(T));
|
|
#else
|
|
# if __BIGGEST_ALIGNMENT__
|
|
if (__BIGGEST_ALIGNMENT__ < sizeof(T))
|
|
return __BIGGEST_ALIGNMENT__;
|
|
else
|
|
# endif
|
|
return sizeof(T);
|
|
#endif
|
|
}
|
|
|
|
/// \brief Determines whether ptr is minimally aligned
|
|
/// \tparam T class or type
|
|
/// \param ptr the pointer to check for alignment
|
|
/// \returns true if <tt>ptr</tt> is aligned to at least <tt>T</tt>
|
|
/// boundary, false otherwise
|
|
/// \details Internally the function calls IsAlignedOn with a second
|
|
/// parameter of GetAlignmentOf<T>.
|
|
template <class T>
|
|
inline bool IsAligned(const void *ptr)
|
|
{
|
|
return IsAlignedOn(ptr, GetAlignmentOf<T>());
|
|
}
|
|
|
|
#if CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE
|
|
#if _MSC_VER >= 1400 && CRYPTOPP_BOOL_X64
|
|
|
|
bool CpuId(word32 input, word32 output[4])
|
|
{
|
|
__cpuid((int *)output, input);
|
|
return true;
|
|
}
|
|
|
|
#else
|
|
|
|
#ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
|
|
extern "C"
|
|
{
|
|
static jmp_buf s_jmpNoCPUID;
|
|
static void SigIllHandlerCPUID(int)
|
|
{
|
|
longjmp(s_jmpNoCPUID, 1);
|
|
}
|
|
|
|
static jmp_buf s_jmpNoSSE2;
|
|
static void SigIllHandlerSSE2(int)
|
|
{
|
|
longjmp(s_jmpNoSSE2, 1);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
bool CpuId(word32 input, word32 output[4])
|
|
{
|
|
#if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY)
|
|
__try
|
|
{
|
|
__asm
|
|
{
|
|
mov eax, input
|
|
mov ecx, 0
|
|
cpuid
|
|
mov edi, output
|
|
mov[edi], eax
|
|
mov[edi + 4], ebx
|
|
mov[edi + 8], ecx
|
|
mov[edi + 12], edx
|
|
}
|
|
}
|
|
// GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION
|
|
__except (1)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// function 0 returns the highest basic function understood in EAX
|
|
if (input == 0)
|
|
return !!output[0];
|
|
|
|
return true;
|
|
#else
|
|
// longjmp and clobber warnings. Volatile is required.
|
|
// http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854
|
|
volatile bool result = true;
|
|
|
|
volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID);
|
|
if (oldHandler == SIG_ERR)
|
|
return false;
|
|
|
|
# ifndef __MINGW32__
|
|
volatile sigset_t oldMask;
|
|
if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
|
|
return false;
|
|
# endif
|
|
|
|
if (setjmp(s_jmpNoCPUID))
|
|
result = false;
|
|
else
|
|
{
|
|
asm volatile
|
|
(
|
|
// save ebx in case -fPIC is being used
|
|
// TODO: this might need an early clobber on EDI.
|
|
# if CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64
|
|
"pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx"
|
|
# else
|
|
"push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx"
|
|
# endif
|
|
: "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d" (output[3])
|
|
: "a" (input), "c" (0)
|
|
);
|
|
}
|
|
|
|
# ifndef __MINGW32__
|
|
sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
|
|
# endif
|
|
|
|
signal(SIGILL, oldHandler);
|
|
return result;
|
|
#endif
|
|
}
|
|
|
|
#endif
|
|
|
|
bool g_x86DetectionDone = false;
|
|
bool g_hasSSE4 = false;
|
|
|
|
void DetectX86Features()
|
|
{
|
|
unsigned int cpuid[4], cpuid1[4];
|
|
if (!CpuId(0, cpuid))
|
|
return;
|
|
if (!CpuId(1, cpuid1))
|
|
return;
|
|
|
|
g_hasSSE4 = ((cpuid1[2] & (1 << 19)) && (cpuid1[2] & (1 << 20)));
|
|
g_x86DetectionDone = true;
|
|
}
|
|
|
|
inline bool HasSSE4()
|
|
{
|
|
if (!g_x86DetectionDone)
|
|
DetectX86Features();
|
|
return g_hasSSE4;
|
|
}
|
|
#elif (CRYPTOPP_BOOL_ARM_CRC32_INTRINSICS_AVAILABLE) //CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE
|
|
bool g_ArmDetectionDone = false;
|
|
bool g_hasCRC32 = false;
|
|
static jmp_buf s_jmpNoCRC32;
|
|
static void SigIllHandlerCRC32(int)
|
|
{
|
|
longjmp(s_jmpNoCRC32, 1);
|
|
}
|
|
bool TryCRC32()
|
|
{
|
|
# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY)
|
|
volatile bool result = true;
|
|
__try
|
|
{
|
|
unsigned int w = 0, x = 1; unsigned short y = 2; unsigned char z = 3;
|
|
w = __crc32cw(w, x);
|
|
w = __crc32ch(w, y);
|
|
w = __crc32cb(w, z);
|
|
|
|
result = !!w;
|
|
}
|
|
__except (1)
|
|
{
|
|
return false;
|
|
}
|
|
return result;
|
|
# else
|
|
// longjmp and clobber warnings. Volatile is required.
|
|
// http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854
|
|
volatile bool result = true;
|
|
|
|
volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerCRC32);
|
|
if (oldHandler == SIG_ERR)
|
|
return false;
|
|
|
|
volatile sigset_t oldMask;
|
|
if (sigprocmask(0, NULL, (sigset_t*)&oldMask))
|
|
return false;
|
|
|
|
if (setjmp(s_jmpNoCRC32))
|
|
result = false;
|
|
else
|
|
{
|
|
unsigned int w = 0, x = 1; unsigned short y = 2; unsigned char z = 3;
|
|
w = __crc32cw(w, x);
|
|
w = __crc32ch(w, y);
|
|
w = __crc32cb(w, z);
|
|
|
|
// Hack... GCC optimizes away the code and returns true
|
|
result = !!w;
|
|
}
|
|
|
|
sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL);
|
|
signal(SIGILL, oldHandler);
|
|
return result;
|
|
# endif
|
|
}
|
|
void DetectArmFeatures()
|
|
{
|
|
g_hasCRC32 = TryCRC32();
|
|
*((volatile bool*)&g_ArmDetectionDone) = true;
|
|
}
|
|
inline bool HasCRC32()
|
|
{
|
|
if (!g_ArmDetectionDone)
|
|
DetectArmFeatures();
|
|
return g_hasCRC32;
|
|
}
|
|
#endif //CRYPTOPP_BOOL_ARM_CRC32_INTRINSICS_AVAILABLE
|
|
|
|
// Castagnoli CRC32C (iSCSI)
|
|
|
|
const unsigned int CRC32C::m_tab[] = {
|
|
#ifdef IS_LITTLE_ENDIAN
|
|
0x00000000L, 0xf26b8303L, 0xe13b70f7L, 0x1350f3f4L, 0xc79a971fL,
|
|
0x35f1141cL, 0x26a1e7e8L, 0xd4ca64ebL, 0x8ad958cfL, 0x78b2dbccL,
|
|
0x6be22838L, 0x9989ab3bL, 0x4d43cfd0L, 0xbf284cd3L, 0xac78bf27L,
|
|
0x5e133c24L, 0x105ec76fL, 0xe235446cL, 0xf165b798L, 0x030e349bL,
|
|
0xd7c45070L, 0x25afd373L, 0x36ff2087L, 0xc494a384L, 0x9a879fa0L,
|
|
0x68ec1ca3L, 0x7bbcef57L, 0x89d76c54L, 0x5d1d08bfL, 0xaf768bbcL,
|
|
0xbc267848L, 0x4e4dfb4bL, 0x20bd8edeL, 0xd2d60dddL, 0xc186fe29L,
|
|
0x33ed7d2aL, 0xe72719c1L, 0x154c9ac2L, 0x061c6936L, 0xf477ea35L,
|
|
0xaa64d611L, 0x580f5512L, 0x4b5fa6e6L, 0xb93425e5L, 0x6dfe410eL,
|
|
0x9f95c20dL, 0x8cc531f9L, 0x7eaeb2faL, 0x30e349b1L, 0xc288cab2L,
|
|
0xd1d83946L, 0x23b3ba45L, 0xf779deaeL, 0x05125dadL, 0x1642ae59L,
|
|
0xe4292d5aL, 0xba3a117eL, 0x4851927dL, 0x5b016189L, 0xa96ae28aL,
|
|
0x7da08661L, 0x8fcb0562L, 0x9c9bf696L, 0x6ef07595L, 0x417b1dbcL,
|
|
0xb3109ebfL, 0xa0406d4bL, 0x522bee48L, 0x86e18aa3L, 0x748a09a0L,
|
|
0x67dafa54L, 0x95b17957L, 0xcba24573L, 0x39c9c670L, 0x2a993584L,
|
|
0xd8f2b687L, 0x0c38d26cL, 0xfe53516fL, 0xed03a29bL, 0x1f682198L,
|
|
0x5125dad3L, 0xa34e59d0L, 0xb01eaa24L, 0x42752927L, 0x96bf4dccL,
|
|
0x64d4cecfL, 0x77843d3bL, 0x85efbe38L, 0xdbfc821cL, 0x2997011fL,
|
|
0x3ac7f2ebL, 0xc8ac71e8L, 0x1c661503L, 0xee0d9600L, 0xfd5d65f4L,
|
|
0x0f36e6f7L, 0x61c69362L, 0x93ad1061L, 0x80fde395L, 0x72966096L,
|
|
0xa65c047dL, 0x5437877eL, 0x4767748aL, 0xb50cf789L, 0xeb1fcbadL,
|
|
0x197448aeL, 0x0a24bb5aL, 0xf84f3859L, 0x2c855cb2L, 0xdeeedfb1L,
|
|
0xcdbe2c45L, 0x3fd5af46L, 0x7198540dL, 0x83f3d70eL, 0x90a324faL,
|
|
0x62c8a7f9L, 0xb602c312L, 0x44694011L, 0x5739b3e5L, 0xa55230e6L,
|
|
0xfb410cc2L, 0x092a8fc1L, 0x1a7a7c35L, 0xe811ff36L, 0x3cdb9bddL,
|
|
0xceb018deL, 0xdde0eb2aL, 0x2f8b6829L, 0x82f63b78L, 0x709db87bL,
|
|
0x63cd4b8fL, 0x91a6c88cL, 0x456cac67L, 0xb7072f64L, 0xa457dc90L,
|
|
0x563c5f93L, 0x082f63b7L, 0xfa44e0b4L, 0xe9141340L, 0x1b7f9043L,
|
|
0xcfb5f4a8L, 0x3dde77abL, 0x2e8e845fL, 0xdce5075cL, 0x92a8fc17L,
|
|
0x60c37f14L, 0x73938ce0L, 0x81f80fe3L, 0x55326b08L, 0xa759e80bL,
|
|
0xb4091bffL, 0x466298fcL, 0x1871a4d8L, 0xea1a27dbL, 0xf94ad42fL,
|
|
0x0b21572cL, 0xdfeb33c7L, 0x2d80b0c4L, 0x3ed04330L, 0xccbbc033L,
|
|
0xa24bb5a6L, 0x502036a5L, 0x4370c551L, 0xb11b4652L, 0x65d122b9L,
|
|
0x97baa1baL, 0x84ea524eL, 0x7681d14dL, 0x2892ed69L, 0xdaf96e6aL,
|
|
0xc9a99d9eL, 0x3bc21e9dL, 0xef087a76L, 0x1d63f975L, 0x0e330a81L,
|
|
0xfc588982L, 0xb21572c9L, 0x407ef1caL, 0x532e023eL, 0xa145813dL,
|
|
0x758fe5d6L, 0x87e466d5L, 0x94b49521L, 0x66df1622L, 0x38cc2a06L,
|
|
0xcaa7a905L, 0xd9f75af1L, 0x2b9cd9f2L, 0xff56bd19L, 0x0d3d3e1aL,
|
|
0x1e6dcdeeL, 0xec064eedL, 0xc38d26c4L, 0x31e6a5c7L, 0x22b65633L,
|
|
0xd0ddd530L, 0x0417b1dbL, 0xf67c32d8L, 0xe52cc12cL, 0x1747422fL,
|
|
0x49547e0bL, 0xbb3ffd08L, 0xa86f0efcL, 0x5a048dffL, 0x8ecee914L,
|
|
0x7ca56a17L, 0x6ff599e3L, 0x9d9e1ae0L, 0xd3d3e1abL, 0x21b862a8L,
|
|
0x32e8915cL, 0xc083125fL, 0x144976b4L, 0xe622f5b7L, 0xf5720643L,
|
|
0x07198540L, 0x590ab964L, 0xab613a67L, 0xb831c993L, 0x4a5a4a90L,
|
|
0x9e902e7bL, 0x6cfbad78L, 0x7fab5e8cL, 0x8dc0dd8fL, 0xe330a81aL,
|
|
0x115b2b19L, 0x020bd8edL, 0xf0605beeL, 0x24aa3f05L, 0xd6c1bc06L,
|
|
0xc5914ff2L, 0x37faccf1L, 0x69e9f0d5L, 0x9b8273d6L, 0x88d28022L,
|
|
0x7ab90321L, 0xae7367caL, 0x5c18e4c9L, 0x4f48173dL, 0xbd23943eL,
|
|
0xf36e6f75L, 0x0105ec76L, 0x12551f82L, 0xe03e9c81L, 0x34f4f86aL,
|
|
0xc69f7b69L, 0xd5cf889dL, 0x27a40b9eL, 0x79b737baL, 0x8bdcb4b9L,
|
|
0x988c474dL, 0x6ae7c44eL, 0xbe2da0a5L, 0x4c4623a6L, 0x5f16d052L,
|
|
0xad7d5351L
|
|
#else
|
|
0x00000000L, 0x03836bf2L, 0xf7703be1L, 0xf4f35013L, 0x1f979ac7L,
|
|
0x1c14f135L, 0xe8e7a126L, 0xeb64cad4L, 0xcf58d98aL, 0xccdbb278L,
|
|
0x3828e26bL, 0x3bab8999L, 0xd0cf434dL, 0xd34c28bfL, 0x27bf78acL,
|
|
0x243c135eL, 0x6fc75e10L, 0x6c4435e2L, 0x98b765f1L, 0x9b340e03L,
|
|
0x7050c4d7L, 0x73d3af25L, 0x8720ff36L, 0x84a394c4L, 0xa09f879aL,
|
|
0xa31cec68L, 0x57efbc7bL, 0x546cd789L, 0xbf081d5dL, 0xbc8b76afL,
|
|
0x487826bcL, 0x4bfb4d4eL, 0xde8ebd20L, 0xdd0dd6d2L, 0x29fe86c1L,
|
|
0x2a7ded33L, 0xc11927e7L, 0xc29a4c15L, 0x36691c06L, 0x35ea77f4L,
|
|
0x11d664aaL, 0x12550f58L, 0xe6a65f4bL, 0xe52534b9L, 0x0e41fe6dL,
|
|
0x0dc2959fL, 0xf931c58cL, 0xfab2ae7eL, 0xb149e330L, 0xb2ca88c2L,
|
|
0x4639d8d1L, 0x45bab323L, 0xaede79f7L, 0xad5d1205L, 0x59ae4216L,
|
|
0x5a2d29e4L, 0x7e113abaL, 0x7d925148L, 0x8961015bL, 0x8ae26aa9L,
|
|
0x6186a07dL, 0x6205cb8fL, 0x96f69b9cL, 0x9575f06eL, 0xbc1d7b41L,
|
|
0xbf9e10b3L, 0x4b6d40a0L, 0x48ee2b52L, 0xa38ae186L, 0xa0098a74L,
|
|
0x54fada67L, 0x5779b195L, 0x7345a2cbL, 0x70c6c939L, 0x8435992aL,
|
|
0x87b6f2d8L, 0x6cd2380cL, 0x6f5153feL, 0x9ba203edL, 0x9821681fL,
|
|
0xd3da2551L, 0xd0594ea3L, 0x24aa1eb0L, 0x27297542L, 0xcc4dbf96L,
|
|
0xcfced464L, 0x3b3d8477L, 0x38beef85L, 0x1c82fcdbL, 0x1f019729L,
|
|
0xebf2c73aL, 0xe871acc8L, 0x0315661cL, 0x00960deeL, 0xf4655dfdL,
|
|
0xf7e6360fL, 0x6293c661L, 0x6110ad93L, 0x95e3fd80L, 0x96609672L,
|
|
0x7d045ca6L, 0x7e873754L, 0x8a746747L, 0x89f70cb5L, 0xadcb1febL,
|
|
0xae487419L, 0x5abb240aL, 0x59384ff8L, 0xb25c852cL, 0xb1dfeedeL,
|
|
0x452cbecdL, 0x46afd53fL, 0x0d549871L, 0x0ed7f383L, 0xfa24a390L,
|
|
0xf9a7c862L, 0x12c302b6L, 0x11406944L, 0xe5b33957L, 0xe63052a5L,
|
|
0xc20c41fbL, 0xc18f2a09L, 0x357c7a1aL, 0x36ff11e8L, 0xdd9bdb3cL,
|
|
0xde18b0ceL, 0x2aebe0ddL, 0x29688b2fL, 0x783bf682L, 0x7bb89d70L,
|
|
0x8f4bcd63L, 0x8cc8a691L, 0x67ac6c45L, 0x642f07b7L, 0x90dc57a4L,
|
|
0x935f3c56L, 0xb7632f08L, 0xb4e044faL, 0x401314e9L, 0x43907f1bL,
|
|
0xa8f4b5cfL, 0xab77de3dL, 0x5f848e2eL, 0x5c07e5dcL, 0x17fca892L,
|
|
0x147fc360L, 0xe08c9373L, 0xe30ff881L, 0x086b3255L, 0x0be859a7L,
|
|
0xff1b09b4L, 0xfc986246L, 0xd8a47118L, 0xdb271aeaL, 0x2fd44af9L,
|
|
0x2c57210bL, 0xc733ebdfL, 0xc4b0802dL, 0x3043d03eL, 0x33c0bbccL,
|
|
0xa6b54ba2L, 0xa5362050L, 0x51c57043L, 0x52461bb1L, 0xb922d165L,
|
|
0xbaa1ba97L, 0x4e52ea84L, 0x4dd18176L, 0x69ed9228L, 0x6a6ef9daL,
|
|
0x9e9da9c9L, 0x9d1ec23bL, 0x767a08efL, 0x75f9631dL, 0x810a330eL,
|
|
0x828958fcL, 0xc97215b2L, 0xcaf17e40L, 0x3e022e53L, 0x3d8145a1L,
|
|
0xd6e58f75L, 0xd566e487L, 0x2195b494L, 0x2216df66L, 0x062acc38L,
|
|
0x05a9a7caL, 0xf15af7d9L, 0xf2d99c2bL, 0x19bd56ffL, 0x1a3e3d0dL,
|
|
0xeecd6d1eL, 0xed4e06ecL, 0xc4268dc3L, 0xc7a5e631L, 0x3356b622L,
|
|
0x30d5ddd0L, 0xdbb11704L, 0xd8327cf6L, 0x2cc12ce5L, 0x2f424717L,
|
|
0x0b7e5449L, 0x08fd3fbbL, 0xfc0e6fa8L, 0xff8d045aL, 0x14e9ce8eL,
|
|
0x176aa57cL, 0xe399f56fL, 0xe01a9e9dL, 0xabe1d3d3L, 0xa862b821L,
|
|
0x5c91e832L, 0x5f1283c0L, 0xb4764914L, 0xb7f522e6L, 0x430672f5L,
|
|
0x40851907L, 0x64b90a59L, 0x673a61abL, 0x93c931b8L, 0x904a5a4aL,
|
|
0x7b2e909eL, 0x78adfb6cL, 0x8c5eab7fL, 0x8fddc08dL, 0x1aa830e3L,
|
|
0x192b5b11L, 0xedd80b02L, 0xee5b60f0L, 0x053faa24L, 0x06bcc1d6L,
|
|
0xf24f91c5L, 0xf1ccfa37L, 0xd5f0e969L, 0xd673829bL, 0x2280d288L,
|
|
0x2103b97aL, 0xca6773aeL, 0xc9e4185cL, 0x3d17484fL, 0x3e9423bdL,
|
|
0x756f6ef3L, 0x76ec0501L, 0x821f5512L, 0x819c3ee0L, 0x6af8f434L,
|
|
0x697b9fc6L, 0x9d88cfd5L, 0x9e0ba427L, 0xba37b779L, 0xb9b4dc8bL,
|
|
0x4d478c98L, 0x4ec4e76aL, 0xa5a02dbeL, 0xa623464cL, 0x52d0165fL,
|
|
0x51537dadL
|
|
#endif
|
|
};
|
|
|
|
CRC32C::CRC32C()
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
cryptopp_crc::CRC32C::CRC32C(unsigned int icrc)
|
|
: m_crc(icrc ^ CRC32_NEGL)
|
|
{
|
|
}
|
|
|
|
void CRC32C::Update(const char *s, size_t n)
|
|
{
|
|
#if CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE
|
|
if (HasSSE4())
|
|
{
|
|
for (; !IsAligned<word32>(s) && n > 0; s++, n--)
|
|
m_crc = _mm_crc32_u8(m_crc, *s);
|
|
|
|
for (; n > 4; s += 4, n -= 4)
|
|
m_crc = _mm_crc32_u32(m_crc, *(const word32 *)(void*)s);
|
|
|
|
for (; n > 0; s++, n--)
|
|
m_crc = _mm_crc32_u8(m_crc, *s);
|
|
|
|
return;
|
|
}
|
|
#elif (CRYPTOPP_BOOL_ARM_CRC32_INTRINSICS_AVAILABLE)
|
|
if (HasCRC32())
|
|
{
|
|
for (; !IsAligned<word32>(s) && n > 0; s++, n--)
|
|
m_crc = __crc32cb(m_crc, *s);
|
|
|
|
for (; n > 4; s += 4, n -= 4)
|
|
m_crc = __crc32cw(m_crc, *(const word32 *)(void*)s);
|
|
|
|
for (; n > 0; s++, n--)
|
|
m_crc = __crc32cb(m_crc, *s);
|
|
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
unsigned int crc = m_crc;
|
|
|
|
for (; !IsAligned<unsigned int>(s) && n > 0; n--)
|
|
crc = m_tab[CRC32_INDEX(crc) ^ *s++] ^ CRC32_SHIFTED(crc);
|
|
|
|
while (n >= 4)
|
|
{
|
|
crc ^= *(const unsigned int *)(void*)s;
|
|
crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc);
|
|
crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc);
|
|
crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc);
|
|
crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc);
|
|
n -= 4;
|
|
s += 4;
|
|
}
|
|
|
|
while (n--)
|
|
crc = m_tab[CRC32_INDEX(crc) ^ *s++] ^ CRC32_SHIFTED(crc);
|
|
|
|
m_crc = crc;
|
|
}
|
|
|
|
void CRC32C::TruncatedFinal(char *hash, size_t size)
|
|
{
|
|
m_crc ^= CRC32_NEGL;
|
|
for (size_t i = 0; i < size; i++)
|
|
hash[i] = GetCrcByte(i);
|
|
|
|
Reset();
|
|
}
|
|
|
|
unsigned int cryptopp_crc::CRC32C::Final()
|
|
{
|
|
m_crc ^= CRC32_NEGL;
|
|
return m_crc;
|
|
}
|
|
|
|
crc32c_alg_type get_crc32c_alg_type()
|
|
{
|
|
#if CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE
|
|
if (HasSSE4())
|
|
{
|
|
return crc32c_alg_type_sse4_crc;
|
|
}
|
|
#elif (CRYPTOPP_BOOL_ARM_CRC32_INTRINSICS_AVAILABLE)
|
|
if (HasCRC32())
|
|
{
|
|
return crc32c_alg_type_arm64_crc;
|
|
}
|
|
#endif
|
|
return crc32c_alg_type_software;
|
|
}
|
|
|
|
unsigned int crc32c_hw(
|
|
unsigned int crc,
|
|
const char *input,
|
|
size_t length)
|
|
{
|
|
CRC32C icrc(crc);
|
|
icrc.Update(input, length);
|
|
return icrc.Final();
|
|
}
|
|
|
|
} //namsepace cryptopp_crc
|