ReactOS 0.4.17-dev-1005-g171e1de
hash.c
Go to the documentation of this file.
1//
2// hash.c generic code used in many hash implementations.
3// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
4//
5
6#include "precomp.h"
7
15{
17 UINT32 freeInBuffer;
18 SIZE_T tmp;
19
21
22 pState->dataLengthL += cbData;
23 if( pState->dataLengthL < cbData ) {
24 pState->dataLengthH ++; // This is almost-unreachable code as it requires 2^64 bytes to be hashed.
25 }
26
27 bytesInBuffer = pState->bytesInBuffer;
28
29 //
30 // If previous data in buffer, buffer new input and transform if possible.
31 //
32 if( bytesInBuffer > 0 )
33 {
34 SYMCRYPT_ASSERT( pHash->inputBlockSize > bytesInBuffer );
35
36 freeInBuffer = pHash->inputBlockSize - bytesInBuffer;
37 if( cbData < freeInBuffer )
38 {
39 //
40 // All the data will fit in the buffer.
41 // We don't do anything here.
42 // As cbData < inputBlockSize the bulk data processing is skipped,
43 // and the data will be copied to the buffer at the end
44 // of this code.
45 } else {
46 //
47 // Enough data to fill the whole buffer & process it
48 //
49 memcpy(&pState->buffer[bytesInBuffer], pbData, freeInBuffer);
50 pbData += freeInBuffer;
51 cbData -= freeInBuffer;
52 (*pHash->appendBlockFunc)( (PBYTE)pState + pHash->chainOffset, &pState->buffer[0], pHash->inputBlockSize, &tmp );
53
54 bytesInBuffer = 0;
55 }
56 }
57
58 //
59 // Internal buffer is empty; process all remaining whole blocks in the input
60 //
61 if( cbData >= pHash->inputBlockSize )
62 {
63 (*pHash->appendBlockFunc)( (PBYTE)pState + pHash->chainOffset, pbData, cbData, &tmp );
64 SYMCRYPT_ASSERT( tmp < pHash->inputBlockSize );
65 pbData += cbData - tmp;
66 cbData = tmp;
67 }
68
69 SYMCRYPT_ASSERT( cbData < pHash->inputBlockSize );
70
71 //
72 // buffer remaining input if necessary.
73 //
74 if( cbData > 0 )
75 {
78 }
79
80 pState->bytesInBuffer = bytesInBuffer;
81}
82
83VOID
88{
89 SIZE_T tmp;
90 SIZE_T bytesInBuffer = pState->bytesInBuffer;
91
93 SYMCRYPT_ASSERT( pHash->inputBlockSize == 64 );
94 SYMCRYPT_ASSERT( bytesInBuffer == (pState->dataLengthL & 0x3f) );
95
96 //
97 // The buffer is never completely full, so we can always put the first
98 // padding byte in.
99 //
100 pState->buffer[bytesInBuffer++] = 0x80;
101
102 if( bytesInBuffer > 64-8 ) {
103 //
104 // No room for the rest of the padding. Pad with zeroes & process block
105 // bytesInBuffer is at most 64, so we do not have an integer underflow
106 //
108 (*pHash->appendBlockFunc)( (PBYTE)pState + pHash->chainOffset, pState->buffer, 64, &tmp );
109 SYMCRYPT_ASSERT( tmp == 0 );
110 bytesInBuffer = 0;
111 }
112
113 //
114 // Set rest of padding
115 // At this point bytesInBuffer <= 64-8, so we don't have an underflow
116 // We wipe to the end of the buffer as it is 16-aligned,
117 // and it is faster to wipe to an aligned point
118 //
120 SYMCRYPT_STORE_LSBFIRST64( &pState->buffer[64-8], pState->dataLengthL * 8 );
121
122 //
123 // Process the final block
124 //
125 (*pHash->appendBlockFunc)( (PBYTE)pState + pHash->chainOffset, pState->buffer, 64, &tmp );
126}
127
128
129
130SIZE_T
133{
134 return pHash->resultSize;
135}
136
137
138SIZE_T
141{
142 return pHash->inputBlockSize;
143}
144
145SIZE_T
148{
149 return pHash->stateSize;
150}
151
152
153VOID
156 _In_ PCSYMCRYPT_HASH pHash,
159 _Out_writes_( SYMCRYPT_MIN( cbResult, pHash->resultSize ) ) PBYTE pbResult,
160 SIZE_T cbResult )
161{
163
164 _Analysis_assume_( pHash->stateSize <= sizeof( hash ) );
165 SymCryptHashInit( pHash, &hash );
167 SymCryptHashResult( pHash, &hash, pbResult, cbResult );
168 SymCryptWipe( &hash, pHash->stateSize );
169}
170
171VOID
174 _In_ PCSYMCRYPT_HASH pHash,
175 _Out_writes_bytes_( pHash->stateSize ) PVOID pState )
176{
177 (*pHash->initFunc)( pState );
178}
179
180VOID
183 _In_ PCSYMCRYPT_HASH pHash,
184 _Inout_updates_bytes_( pHash->stateSize ) PVOID pState,
186 SIZE_T cbData )
187{
188 (*pHash->appendFunc)( pState, pbData, cbData );
189}
190
191VOID
194 _In_ PCSYMCRYPT_HASH pHash,
195 _Inout_updates_bytes_( pHash->stateSize ) PVOID pState,
196 _Out_writes_( SYMCRYPT_MIN( cbResult, pHash->resultSize ) ) PBYTE pbResult,
197 SIZE_T cbResult )
198{
200
201 _Analysis_assume_( pHash->resultSize <= SYMCRYPT_HASH_MAX_RESULT_SIZE );
202
203 (*pHash->resultFunc)( pState, buf );
204 memcpy( pbResult, buf, SYMCRYPT_MIN( cbResult, pHash->resultSize ));
205 SymCryptWipe( buf, pHash->resultSize );
206}
207
208VOID
211 _In_ PCSYMCRYPT_HASH pHash,
212 _In_reads_( pHash->stateSize ) PCVOID pSrc,
213 _Out_writes_( pHash->stateSize ) PVOID pDst)
214{
215 (*pHash->stateCopyFunc)( pSrc, pDst );
216}
CONST VOID * PCVOID
Definition: cfgmgr32.h:44
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define _In_reads_bytes_(s)
Definition: no_sal2.h:170
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Inout_
Definition: no_sal2.h:162
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _In_
Definition: no_sal2.h:158
#define _Analysis_assume_
Definition: no_sal2.h:388
#define _Inout_updates_bytes_(s)
Definition: no_sal2.h:184
#define _Out_writes_bytes_(s)
Definition: no_sal2.h:178
BYTE * PBYTE
Definition: pedump.c:66
SIZE_T SYMCRYPT_CALL SymCryptHashInputBlockSize(_In_ PCSYMCRYPT_HASH pHash)
Definition: hash.c:140
VOID SYMCRYPT_CALL SymCryptHashAppendInternal(_In_ PCSYMCRYPT_HASH pHash, _Inout_ PSYMCRYPT_COMMON_HASH_STATE pState, _In_reads_bytes_(cbData) PCBYTE pbData, SIZE_T cbData)
Definition: hash.c:10
VOID SYMCRYPT_CALL SymCryptHashAppend(_In_ PCSYMCRYPT_HASH pHash, _Inout_updates_bytes_(pHash->stateSize) PVOID pState, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData)
Definition: hash.c:182
VOID SYMCRYPT_CALL SymCryptHashInit(_In_ PCSYMCRYPT_HASH pHash, _Out_writes_bytes_(pHash->stateSize) PVOID pState)
Definition: hash.c:173
SIZE_T SYMCRYPT_CALL SymCryptHashResultSize(_In_ PCSYMCRYPT_HASH pHash)
Definition: hash.c:132
VOID SYMCRYPT_CALL SymCryptHashStateCopy(_In_ PCSYMCRYPT_HASH pHash, _In_reads_(pHash->stateSize) PCVOID pSrc, _Out_writes_(pHash->stateSize) PVOID pDst)
Definition: hash.c:210
VOID SYMCRYPT_CALL SymCryptHashCommonPaddingMd4Style(_In_ PCSYMCRYPT_HASH pHash, _Inout_ PSYMCRYPT_COMMON_HASH_STATE pState)
Definition: hash.c:85
VOID SYMCRYPT_CALL SymCryptHash(_In_ PCSYMCRYPT_HASH pHash, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData, _Out_writes_(SYMCRYPT_MIN(cbResult, pHash->resultSize)) PBYTE pbResult, SIZE_T cbResult)
Definition: hash.c:155
VOID SYMCRYPT_CALL SymCryptHashResult(_In_ PCSYMCRYPT_HASH pHash, _Inout_updates_bytes_(pHash->stateSize) PVOID pState, _Out_writes_(SYMCRYPT_MIN(cbResult, pHash->resultSize)) PBYTE pbResult, SIZE_T cbResult)
Definition: hash.c:193
SIZE_T SYMCRYPT_CALL SymCryptHashStateSize(_In_ PCSYMCRYPT_HASH pHash)
Definition: hash.c:147
static const BYTE pbResult[]
#define SYMCRYPT_ASSERT(_x)
Definition: symcrypt.h:10807
VOID SYMCRYPT_CALL SymCryptWipe(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
Definition: libmain.c:137
#define SYMCRYPT_STORE_LSBFIRST64(p, v)
Definition: symcrypt.h:308
#define SYMCRYPT_CALL
#define SYMCRYPT_HASH_MAX_RESULT_SIZE
SIZE_T bytesInBuffer
const SYMCRYPT_HASH * PCSYMCRYPT_HASH
#define SYMCRYPT_MIN(_a, _b)
PCBYTE PBYTE SIZE_T cbData
* PSYMCRYPT_COMMON_HASH_STATE
UINT32 inputBlockSize
PSYMCRYPT_COMMON_HASH_STATE pState
const BYTE * PCBYTE
PCBYTE pbData
#define SYMCRYPT_CHECK_MAGIC(p)
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t UINT32
Definition: typedefs.h:59
unsigned char BYTE
Definition: xxhash.c:193