UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
SecureHash.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Containers/Array.h"
6#include "Containers/Map.h"
11#include "CoreTypes.h"
12#include "HAL/PlatformCrt.h"
14#include "HAL/UnrealMemory.h"
16#include "Misc/CString.h"
17#include "Misc/Guid.h"
21#include "Stats/Stats.h"
22#include "String/BytesToHex.h"
23#include "String/HexToBytes.h"
25
26class FCbFieldView;
27class FCbWriter;
31class FSHA1;
32struct FMD5Hash;
33
34/*-----------------------------------------------------------------------------
35 MD5 functions.
36-----------------------------------------------------------------------------*/
37
40//
41// MD5 Context.
42//
43
44
45//
46// MD5 functions.
48// FArchive.
49//
50// CORE_API void appMD5Init( FMD5Context* context );
51// CORE_API void appMD5Update( FMD5Context* context, uint8* input, int32 inputLen );
52// CORE_API void appMD5Final( uint8* digest, FMD5Context* context );
53// CORE_API void appMD5Transform( uint32* state, uint8* block );
54// CORE_API void appMD5Encode( uint8* output, uint32* input, int32 len );
55// CORE_API void appMD5Decode( uint32* output, uint8* input, int32 len );
56
57class FMD5
58{
59public:
60 CORE_API FMD5();
62
71
80
86 static FString HashAnsiString(const TCHAR* String)
87 {
88 return HashBytes((unsigned char*)TCHAR_TO_ANSI(String), FCString::Strlen(String));
89 }
90
96 static FString HashBytes(const uint8* input, uint64 inputLen)
97 {
98 uint8 Digest[16];
99
100 FMD5 Md5Gen;
101
103 Md5Gen.Final(Digest);
104
105 FString MD5;
106 for (int32 i = 0; i < 16; i++)
107 {
108 MD5 += FString::Printf(TEXT("%02x"), Digest[i]);
109 }
110 return MD5;
111 }
112
113private:
114 struct FContext
115 {
116 uint32 state[4];
117 uint32 count[2];
118 uint8 buffer[64];
119 };
120
121 CORE_API void Transform( uint32* state, const uint8* block );
122 CORE_API void Encode( uint8* output, const uint32* input, int32 len );
123 CORE_API void Decode( uint32* output, const uint8* input, int32 len );
124
125 FContext Context;
126};
128
129struct FMD5Hash;
130
133{
135 FMD5Hash() : bIsValid(false) {}
136
138 bool IsValid() const { return bIsValid; }
139
141 void Set(FMD5& MD5)
142 {
143 MD5.Final(Bytes);
144 bIsValid = true;
145 }
146
148 friend bool operator==(const FMD5Hash& LHS, const FMD5Hash& RHS)
149 {
150 return LHS.bIsValid == RHS.bIsValid && (!LHS.bIsValid || FMemory::Memcmp(LHS.Bytes, RHS.Bytes, 16) == 0);
151 }
152
154 friend bool operator!=(const FMD5Hash& LHS, const FMD5Hash& RHS)
155 {
156 return LHS.bIsValid != RHS.bIsValid || (LHS.bIsValid && FMemory::Memcmp(LHS.Bytes, RHS.Bytes, 16) != 0);
157 }
158
161 {
162 Ar << Hash.bIsValid;
163 if (Hash.bIsValid)
164 {
165 Ar.Serialize(Hash.Bytes, 16);
166 }
167
168 return Ar;
169 }
170
172 CORE_API static FMD5Hash HashFile(const TCHAR* InFilename, TArray<uint8>* Buffer = nullptr);
174
175 const uint8* GetBytes() const { return Bytes; }
176 const int32 GetSize() const { return sizeof(Bytes); }
177
178private:
180 bool bIsValid;
181
183 uint8 Bytes[16];
184
185 friend inline FCbWriter& operator<<(FCbWriter& Writer, const FMD5Hash& Hash) // Hidden friends must be inlined to be performant
186 {
187 return Hash.WriteCompactBinary(Writer);
188 }
189 friend bool LoadFromCompactBinary(const FCbFieldView& Field, FMD5Hash& OutHash) { return OutHash.LoadFromCompactBinary(Field); }
190 friend FString LexToString(const FMD5Hash& InHash) { return InHash.LexToString(); }
191 friend void LexFromString(FMD5Hash& Hash, const TCHAR* InString) { Hash.LexFromString(InString); }
192
193 CORE_API FCbWriter& WriteCompactBinary(FCbWriter& Writer) const;
194 CORE_API bool LoadFromCompactBinary(const FCbFieldView& Field); // inlining not available because we don't want FCbFieldView defined
195 CORE_API FString LexToString() const;
196 CORE_API void LexFromString(const TCHAR*);
197};
198
204{
205 FGuid Result;
206 FMemory::Memcpy(&Result, Hash.GetBytes(), sizeof(FGuid));
207 return Result;
208}
209
210/*-----------------------------------------------------------------------------
211 SHA-1 functions.
212-----------------------------------------------------------------------------*/
213
214/*
215 * NOTE:
216 * 100% free public domain implementation of the SHA-1 algorithm
217 * by Dominik Reichl <dominik.reichl@t-online.de>
218 * Web: http://www.dominik-reichl.de/
219 */
220
222#define HASHES_SHA_DIVIDER "+++"
223
226{
227public:
228 alignas(uint32) uint8 Hash[20];
229
231 {
232 FMemory::Memset(Hash, 0, sizeof(Hash));
233 }
234
235 static constexpr int32 GetStringLen() { return UE_ARRAY_COUNT(Hash) * 2; }
236
237 inline void AppendString(FString& Out) const
238 {
239 BytesToHex((const uint8*)Hash, sizeof(Hash), Out);
240 }
241
242 inline FString ToString() const
243 {
244 return BytesToHex((const uint8*)Hash, sizeof(Hash));
245 }
246
247 inline void ToString(TCHAR* Dest, bool bNullTerminate) const
248 {
249 constexpr auto Count = UE_ARRAY_COUNT(Hash);
250 for (int i = 0; i < Count; ++i)
251 {
252 uint8 Val = Hash[i];
253 Dest[i * 2] = NibbleToTChar(Val >> 4);
254 Dest[i * 2 + 1] = NibbleToTChar(Val & 15);
255 }
256
257 if (bNullTerminate)
258 {
259 Dest[Count * 2] = TEXT('\0');
260 }
261 }
262
263 inline void FromString(const FStringView& Src)
264 {
265 check(Src.Len() == GetStringLen());
267 }
268
269 friend bool operator==(const FSHAHash& X, const FSHAHash& Y)
270 {
271 return FMemory::Memcmp(&X.Hash, &Y.Hash, sizeof(X.Hash)) == 0;
272 }
273
274 friend bool operator!=(const FSHAHash& X, const FSHAHash& Y)
275 {
276 return FMemory::Memcmp(&X.Hash, &Y.Hash, sizeof(X.Hash)) != 0;
277 }
278
279 friend bool operator<(const FSHAHash& X, const FSHAHash& Y)
280 {
281 return FMemory::Memcmp(&X.Hash, &Y.Hash, sizeof(X.Hash)) < 0;
282 }
283
285 {
286 Ar.Serialize(&G.Hash, sizeof(G.Hash));
287 return Ar;
288 }
289
291 {
292 return *reinterpret_cast<const uint32*>(InKey.Hash);
293 }
294
295 friend FString LexToString(const FSHAHash& InHash) { return InHash.ToString(); }
296 friend void LexFromString(FSHAHash& InHash, const TCHAR* InString) { InHash.FromString(InString); }
297 friend FStringBuilderBase& operator<<(FStringBuilderBase& Builder, const FSHAHash& InHash) { UE::String::BytesToHex(InHash.Hash, Builder); return Builder; }
298 friend FAnsiStringBuilderBase& operator<<(FAnsiStringBuilderBase& Builder, const FSHAHash& InHash) { UE::String::BytesToHex(InHash.Hash, Builder); return Builder; }
299 friend FCbWriter& operator<<(FCbWriter& Writer, const FSHAHash& InHash) { return InHash.WriteCompactBinary(Writer); }
300 friend bool LoadFromCompactBinary(const FCbFieldView& Field, FSHAHash& OutHash) { return OutHash.LoadFromCompactBinary(Field); }
301
304};
305
306namespace Freeze
307{
309}
310
312
313class FSHA1
314{
315public:
316
317 enum {DigestSize=20};
318 // Constructor and Destructor
319 CORE_API FSHA1();
321
328
329 CORE_API void Reset();
330
331 // Update the hash value
332 CORE_API void Update(const uint8 *data, uint64 len);
333
334 // Update the hash value with string
335 CORE_API void UpdateWithString(const TCHAR *data, uint32 len);
336
337 // Update with POD data.
338 template <typename Type UE_REQUIRES(TIsPODType<Type>::Value)>
339 void Update(const Type& InData)
340 {
341 Update(reinterpret_cast<const uint8*>(&InData), sizeof(Type));
342 }
343
344 // Finalize hash and report
345 CORE_API void Final();
346
347 // Finalize hash and return it
349 {
350 Final();
351 FSHAHash Digest;
352 GetHash(reinterpret_cast<uint8*>(&Digest));
353 return Digest;
354 }
355
356 // Report functions: as pre-formatted and raw data
357 CORE_API void GetHash(uint8 *puDest) const;
358
366 static CORE_API void HashBuffer(const void* Data, uint64 DataSize, uint8* OutHash);
367
375 static FSHAHash HashBuffer(const void* Data, uint64 DataSize)
376 {
378 HashBuffer(Data, DataSize, Hash.Hash);
379 return Hash;
380 }
381
392 static CORE_API void HMACBuffer(const void* Key, uint32 KeySize, const void* Data, uint64 DataSize, uint8* OutHash);
393
403
414 static CORE_API bool GetFileSHAHash(const TCHAR* Pathname, uint8 Hash[20], bool bIsFullPackageHash=true);
415
416private:
417 // Private SHA-1 transformation
418 CORE_API void Transform(const uint8* buffer, uint64 len);
419
421 static CORE_API TMap<FString, uint8*> FullFileSHAHashMap;
422
424 static CORE_API TMap<FString, uint8*> ScriptSHAHashMap;
425};
426
427
432{
433protected:
435 void* Buffer;
436
439
442
444 FString Pathname;
445
448
451
452public:
453
477
481 CORE_API void DoWork();
482
487 {
488 return true;
489 }
490
494 void Abandon()
495 {
497 {
499 Buffer = 0;
500 }
501 }
502
507};
508
519
525{
526public:
538 void* Data,
539 int64 Size,
540 bool bInFreeOnClose,
541 const TCHAR* SHASourcePathname,
542 bool bIsPersistent=false,
543 bool bInIsUnfoundHashAnError=false
544 )
545 // we force the base class to NOT free buffer on close, as we will let the SHA task do it if needed
546 : FBufferReaderBase(Data, Size, bInFreeOnClose, bIsPersistent)
549 {
550 }
551
553
554 CORE_API bool Close() override;
555
562 virtual FString GetArchiveName() const { return TEXT("FBufferReaderWithSHA"); }
563
564protected:
569};
570
571
572
#define check(expr)
Definition AssertionMacros.h:314
void BytesToHex(const uint8 *In, int32 Count, FString &Out)
Definition BytesToHex.cpp:97
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
#define RETURN_QUICK_DECLARE_CYCLE_STAT(StatId, GroupId)
Definition Stats.h:655
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define X(Name, Desc)
Definition FormatStringSan.h:47
#define DECLARE_INTRINSIC_TYPE_LAYOUT(T)
Definition MemoryLayout.h:760
CORE_API void appOnFailSHAVerification(const TCHAR *FailedPathname, bool bFailedDueToMissingHash)
Definition SecureHash.cpp:1507
FGuid MD5HashToGuid(const FMD5Hash &Hash)
Definition SecureHash.h:203
#define TCHAR_TO_ANSI(str)
Definition StringConv.h:1019
float Val(const FString &Value)
Definition UnrealMath.cpp:3163
TCHAR NibbleToTChar(uint8 Num)
Definition UnrealString.h:70
#define UE_ARRAY_COUNT(array)
Definition UnrealTemplate.h:212
uint32 Size
Definition VulkanMemory.cpp:4034
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Archive.h:1208
virtual void Serialize(void *V, int64 Length)
Definition Archive.h:1689
Definition SecureHash.h:432
bool CanAbandon()
Definition SecureHash.h:486
void Abandon()
Definition SecureHash.h:494
bool bIsUnfoundHashAnError
Definition SecureHash.h:447
uint8 Hash[20]
Definition SecureHash.h:441
CORE_API void DoWork()
Definition SecureHash.cpp:1441
FAsyncSHAVerify(void *InBuffer, uint64 InBufferSize, bool bInShouldDeleteBuffer, const TCHAR *InPathname, bool bInIsUnfoundHashAnError)
Definition SecureHash.h:464
void * Buffer
Definition SecureHash.h:435
uint64 BufferSize
Definition SecureHash.h:438
UE_FORCEINLINE_HINT TStatId GetStatId() const
Definition SecureHash.h:503
FString Pathname
Definition SecureHash.h:444
bool bShouldDeleteBuffer
Definition SecureHash.h:450
Definition BufferReader.h:16
Definition SecureHash.h:525
bool bIsUnfoundHashAnError
Definition SecureHash.h:568
virtual CORE_API ~FBufferReaderWithSHA()
Definition SecureHash.cpp:1520
CORE_API bool Close() override
Definition SecureHash.cpp:1525
FBufferReaderWithSHA(void *Data, int64 Size, bool bInFreeOnClose, const TCHAR *SHASourcePathname, bool bIsPersistent=false, bool bInIsUnfoundHashAnError=false)
Definition SecureHash.h:537
virtual FString GetArchiveName() const
Definition SecureHash.h:562
FString SourcePathname
Definition SecureHash.h:566
Definition CompactBinary.h:610
Definition CompactBinaryWriter.h:68
!it would be cool if these were implemented as subclasses of
Definition SecureHash.h:58
CORE_API ~FMD5()
Definition SecureHash.cpp:130
static FString HashBytes(const uint8 *input, uint64 inputLen)
Definition SecureHash.h:96
static FString HashAnsiString(const TCHAR *String)
Definition SecureHash.h:86
CORE_API FMD5()
Definition SecureHash.cpp:120
CORE_API void Final(uint8 *digest)
Definition SecureHash.cpp:170
CORE_API void Update(const uint8 *input, uint64 inputLen)
Definition SecureHash.cpp:135
Definition MemoryImageWriter.h:14
Definition MemoryImageWriter.h:78
Definition MemoryImage.h:49
Definition SecureHash.h:314
@ DigestSize
Definition SecureHash.h:317
static CORE_API void HMACBuffer(const void *Key, uint32 KeySize, const void *Data, uint64 DataSize, uint8 *OutHash)
Definition SecureHash.cpp:1290
static CORE_API void HashBuffer(const void *Data, uint64 DataSize, uint8 *OutHash)
Definition SecureHash.cpp:1281
FSHAHash Finalize()
Definition SecureHash.h:348
uint32 __reserved1[1]
Definition SecureHash.h:324
CORE_API FSHA1()
Definition SecureHash.cpp:684
CORE_API ~FSHA1()
Definition SecureHash.cpp:689
CORE_API void UpdateWithString(const TCHAR *data, uint32 len)
Definition SecureHash.cpp:1240
uint64 m_count
Definition SecureHash.h:323
uint32 m_state[5]
Definition SecureHash.h:322
static FSHAHash HashBuffer(const void *Data, uint64 DataSize)
Definition SecureHash.h:375
CORE_API void Reset()
Definition SecureHash.cpp:694
uint8 m_buffer[64]
Definition SecureHash.h:325
static CORE_API void InitializeFileHashesFromBuffer(uint8 *Buffer, uint64 BufferSize, bool bDuplicateKeyMemory=false)
Definition SecureHash.cpp:1353
CORE_API void GetHash(uint8 *puDest) const
Definition SecureHash.cpp:1269
void Update(const Type &InData)
Definition SecureHash.h:339
static CORE_API bool GetFileSHAHash(const TCHAR *Pathname, uint8 Hash[20], bool bIsFullPackageHash=true)
Definition SecureHash.cpp:1417
uint8 m_digest[20]
Definition SecureHash.h:326
uint32 __reserved2[3]
Definition SecureHash.h:327
CORE_API void Final()
Definition SecureHash.cpp:1245
Definition SecureHash.h:226
friend uint32 GetTypeHash(const FSHAHash &InKey)
Definition SecureHash.h:290
friend FCbWriter & operator<<(FCbWriter &Writer, const FSHAHash &InHash)
Definition SecureHash.h:299
FString ToString() const
Definition SecureHash.h:242
friend FArchive & operator<<(FArchive &Ar, FSHAHash &G)
Definition SecureHash.h:284
void FromString(const FStringView &Src)
Definition SecureHash.h:263
friend FStringBuilderBase & operator<<(FStringBuilderBase &Builder, const FSHAHash &InHash)
Definition SecureHash.h:297
void ToString(TCHAR *Dest, bool bNullTerminate) const
Definition SecureHash.h:247
static constexpr int32 GetStringLen()
Definition SecureHash.h:235
friend bool operator<(const FSHAHash &X, const FSHAHash &Y)
Definition SecureHash.h:279
friend FString LexToString(const FSHAHash &InHash)
Definition SecureHash.h:295
friend bool operator==(const FSHAHash &X, const FSHAHash &Y)
Definition SecureHash.h:269
friend bool operator!=(const FSHAHash &X, const FSHAHash &Y)
Definition SecureHash.h:274
FSHAHash()
Definition SecureHash.h:230
friend bool LoadFromCompactBinary(const FCbFieldView &Field, FSHAHash &OutHash)
Definition SecureHash.h:300
uint8 Hash[20]
Definition SecureHash.h:228
friend void LexFromString(FSHAHash &InHash, const TCHAR *InString)
Definition SecureHash.h:296
void AppendString(FString &Out) const
Definition SecureHash.h:237
friend FAnsiStringBuilderBase & operator<<(FAnsiStringBuilderBase &Builder, const FSHAHash &InHash)
Definition SecureHash.h:298
CORE_API FCbWriter & WriteCompactBinary(FCbWriter &Writer) const
Definition SecureHash.cpp:673
Definition Array.h:670
Definition UnrealString.h.inl:34
constexpr int32 Len() const
Definition StringView.h:174
Definition FieldSystemNoiseAlgo.cpp:6
Definition Array.h:3955
UE_NODEBUG void IntrinsicToString(const TArray< T, AllocatorType > &Object, const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams, FMemoryToStringContext &OutContext)
Definition Array.h:3983
void BytesToHex(TConstArrayView< uint8 > Bytes, ANSICHAR *OutHex)
Definition BytesToHex.cpp:27
int32 HexToBytes(FWideStringView Hex, uint8 *OutBytes)
Definition HexToBytes.cpp:30
@ false
Definition radaudio_common.h:23
Definition Guid.h:109
Definition SecureHash.h:133
static CORE_API FMD5Hash HashFile(const TCHAR *InFilename, TArray< uint8 > *Buffer=nullptr)
Definition SecureHash.cpp:563
const uint8 * GetBytes() const
Definition SecureHash.h:175
const int32 GetSize() const
Definition SecureHash.h:176
friend bool operator!=(const FMD5Hash &LHS, const FMD5Hash &RHS)
Definition SecureHash.h:154
friend FArchive & operator<<(FArchive &Ar, FMD5Hash &Hash)
Definition SecureHash.h:160
friend bool operator==(const FMD5Hash &LHS, const FMD5Hash &RHS)
Definition SecureHash.h:148
bool IsValid() const
Definition SecureHash.h:138
void Set(FMD5 &MD5)
Definition SecureHash.h:141
friend void LexFromString(FMD5Hash &Hash, const TCHAR *InString)
Definition SecureHash.h:191
static CORE_API FMD5Hash HashFileFromArchive(FArchive *Ar, TArray< uint8 > *ScratchPad=nullptr)
Definition SecureHash.cpp:572
friend bool LoadFromCompactBinary(const FCbFieldView &Field, FMD5Hash &OutHash)
Definition SecureHash.h:189
FMD5Hash()
Definition SecureHash.h:135
friend FCbWriter & operator<<(FCbWriter &Writer, const FMD5Hash &Hash)
Definition SecureHash.h:185
friend FString LexToString(const FMD5Hash &InHash)
Definition SecureHash.h:190
Definition MemoryLayout.h:51
static FORCENOINLINE CORE_API void Free(void *Original)
Definition UnrealMemory.cpp:685
static UE_FORCEINLINE_HINT int32 Memcmp(const void *Buf1, const void *Buf2, SIZE_T Count)
Definition UnrealMemory.h:114
static UE_FORCEINLINE_HINT void * Memcpy(void *Dest, const void *Src, SIZE_T Count)
Definition UnrealMemory.h:160
static UE_FORCEINLINE_HINT void * Memset(void *Dest, uint8 Char, SIZE_T Count)
Definition UnrealMemory.h:119
Definition MemoryLayout.h:799
Definition MemoryLayout.h:108
static int32 Strlen(const CharType *String)
Definition CString.h:1047
Definition LightweightStats.h:416