hash.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #include "rar.hpp"
  2. void HashValue::Init(HASH_TYPE Type)
  3. {
  4. HashValue::Type=Type;
  5. // Zero length data CRC32 is 0. It is important to set it when creating
  6. // headers with no following data like directories or symlinks.
  7. if (Type==HASH_RAR14 || Type==HASH_CRC32)
  8. CRC32=0;
  9. if (Type==HASH_BLAKE2)
  10. {
  11. // dd0e891776933f43c7d032b08a917e25741f8aa9a12c12e1cac8801500f2ca4f
  12. // is BLAKE2sp hash of empty data. We init the structure to this value,
  13. // so if we create a file or service header with no following data like
  14. // "file copy" or "symlink", we set the checksum to proper value avoiding
  15. // additional header type or size checks when extracting.
  16. static byte EmptyHash[32]={
  17. 0xdd, 0x0e, 0x89, 0x17, 0x76, 0x93, 0x3f, 0x43,
  18. 0xc7, 0xd0, 0x32, 0xb0, 0x8a, 0x91, 0x7e, 0x25,
  19. 0x74, 0x1f, 0x8a, 0xa9, 0xa1, 0x2c, 0x12, 0xe1,
  20. 0xca, 0xc8, 0x80, 0x15, 0x00, 0xf2, 0xca, 0x4f
  21. };
  22. memcpy(Digest,EmptyHash,sizeof(Digest));
  23. }
  24. }
  25. bool HashValue::operator == (const HashValue &cmp)
  26. {
  27. if (Type==HASH_NONE || cmp.Type==HASH_NONE)
  28. return true;
  29. if (Type==HASH_RAR14 && cmp.Type==HASH_RAR14 ||
  30. Type==HASH_CRC32 && cmp.Type==HASH_CRC32)
  31. return CRC32==cmp.CRC32;
  32. if (Type==HASH_BLAKE2 && cmp.Type==HASH_BLAKE2)
  33. return memcmp(Digest,cmp.Digest,sizeof(Digest))==0;
  34. return false;
  35. }
  36. DataHash::DataHash()
  37. {
  38. blake2ctx=NULL;
  39. HashType=HASH_NONE;
  40. #ifdef RAR_SMP
  41. ThPool=NULL;
  42. MaxThreads=0;
  43. #endif
  44. }
  45. DataHash::~DataHash()
  46. {
  47. #ifdef RAR_SMP
  48. delete ThPool;
  49. #endif
  50. cleandata(&CurCRC32, sizeof(CurCRC32));
  51. if (blake2ctx!=NULL)
  52. {
  53. cleandata(blake2ctx, sizeof(blake2sp_state));
  54. delete blake2ctx;
  55. }
  56. }
  57. void DataHash::Init(HASH_TYPE Type,uint MaxThreads)
  58. {
  59. if (blake2ctx==NULL)
  60. blake2ctx=new blake2sp_state;
  61. HashType=Type;
  62. if (Type==HASH_RAR14)
  63. CurCRC32=0;
  64. if (Type==HASH_CRC32)
  65. CurCRC32=0xffffffff; // Initial CRC32 value.
  66. if (Type==HASH_BLAKE2)
  67. blake2sp_init(blake2ctx);
  68. #ifdef RAR_SMP
  69. DataHash::MaxThreads=Min(MaxThreads,MaxHashThreads);
  70. #endif
  71. }
  72. void DataHash::Update(const void *Data,size_t DataSize)
  73. {
  74. #ifndef SFX_MODULE
  75. if (HashType==HASH_RAR14)
  76. CurCRC32=Checksum14((ushort)CurCRC32,Data,DataSize);
  77. #endif
  78. if (HashType==HASH_CRC32)
  79. CurCRC32=CRC32(CurCRC32,Data,DataSize);
  80. if (HashType==HASH_BLAKE2)
  81. {
  82. #ifdef RAR_SMP
  83. if (MaxThreads>1 && ThPool==NULL)
  84. ThPool=new ThreadPool(BLAKE2_THREADS_NUMBER);
  85. blake2ctx->ThPool=ThPool;
  86. blake2ctx->MaxThreads=MaxThreads;
  87. #endif
  88. blake2sp_update( blake2ctx, (byte *)Data, DataSize);
  89. }
  90. }
  91. void DataHash::Result(HashValue *Result)
  92. {
  93. Result->Type=HashType;
  94. if (HashType==HASH_RAR14)
  95. Result->CRC32=CurCRC32;
  96. if (HashType==HASH_CRC32)
  97. Result->CRC32=CurCRC32^0xffffffff;
  98. if (HashType==HASH_BLAKE2)
  99. {
  100. // Preserve the original context, so we can continue hashing if necessary.
  101. blake2sp_state res=*blake2ctx;
  102. blake2sp_final(&res,Result->Digest);
  103. }
  104. }
  105. uint DataHash::GetCRC32()
  106. {
  107. return HashType==HASH_CRC32 ? CurCRC32^0xffffffff : 0;
  108. }
  109. bool DataHash::Cmp(HashValue *CmpValue,byte *Key)
  110. {
  111. HashValue Final;
  112. Result(&Final);
  113. if (Key!=NULL)
  114. ConvertHashToMAC(&Final,Key);
  115. return Final==*CmpValue;
  116. }