ReactOS 0.4.17-dev-1005-g171e1de
tlsCbcVerify.c File Reference
#include "precomp.h"
Include dependency graph for tlsCbcVerify.c:

Go to the source code of this file.

Macros

#define NATIVE_01   (0x01010101)
 
#define MASK32_LT(_a, _b)   ((UINT32)( ( (INT32)((_a)-(_b)) ) >> 31 ) )
 
#define MASK32_EQ(_a, _b)   (~(UINT32)(-(INT32)((_a) ^ (_b)) >> 31))
 
#define MASKNB_INWORD_RELEVANTBITS   (~(NATIVE_BYTES - 1) & 0x0fffffff)
 
#define MASKNB_BROADCAST(_b)   ((NATIVE_UINT)(_b) * NATIVE_01)
 

Functions

FORCEINLINE NATIVE_UINT SymCryptNMaskGe (UINT32 wordStart, UINT32 boundary)
 
FORCEINLINE NATIVE_UINT SymCryptNMaskEq (UINT32 wordStart, UINT32 boundary)
 
FORCEINLINE NATIVE_UINT SymCryptNMaskEq80 (UINT32 wordStart, UINT32 boundary)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptTlsCbcHmacVerifyCore (_In_ PCSYMCRYPT_HASH pHash, _Inout_ PSYMCRYPT_COMMON_HASH_STATE pState, _In_reads_bytes_(cbData) PCBYTE pbData, SIZE_T cbData, _Inout_updates_(pHash->inputBlockSize/2) PBYTE pbMacValue, _Inout_updates_(pHash->resultSize) PBYTE pbHashResult, _Out_ PUINT32 pu32PaddingError)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptTlsCbcHmacVerify (_In_ PCSYMCRYPT_MAC pMacAlgorithm, _In_ PVOID pExpandedKey, _Inout_ PVOID pState, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData)
 

Macro Definition Documentation

◆ MASK32_EQ

#define MASK32_EQ (   _a,
  _b 
)    (~(UINT32)(-(INT32)((_a) ^ (_b)) >> 31))

Definition at line 34 of file tlsCbcVerify.c.

◆ MASK32_LT

#define MASK32_LT (   _a,
  _b 
)    ((UINT32)( ( (INT32)((_a)-(_b)) ) >> 31 ) )

Definition at line 31 of file tlsCbcVerify.c.

◆ MASKNB_BROADCAST

#define MASKNB_BROADCAST (   _b)    ((NATIVE_UINT)(_b) * NATIVE_01)

Definition at line 49 of file tlsCbcVerify.c.

◆ MASKNB_INWORD_RELEVANTBITS

#define MASKNB_INWORD_RELEVANTBITS   (~(NATIVE_BYTES - 1) & 0x0fffffff)

Definition at line 47 of file tlsCbcVerify.c.

◆ NATIVE_01

#define NATIVE_01   (0x01010101)

Definition at line 21 of file tlsCbcVerify.c.

Function Documentation

◆ SymCryptNMaskEq()

FORCEINLINE NATIVE_UINT SymCryptNMaskEq ( UINT32  wordStart,
UINT32  boundary 
)

Definition at line 76 of file tlsCbcVerify.c.

78{
79 INT32 diff32;
80 NATIVE_UINT inWord;
81
82 // 32-bit signed difference
83 diff32 = (INT32)boundary - (INT32)wordStart;
84
85 // inWord = (-1) if boundary is within the word, 0 otherwise
86 // Cast to NATIVE_UINT is free on AMD64, as is subsequent cast to NATIVE_INT
87 // A direct cast from INT32 to NATIVE_INT requires a sign extension instruction, so this is faster.
88 inWord = ~ ((-(NATIVE_INT)(NATIVE_UINT)(diff32 & MASKNB_INWORD_RELEVANTBITS)) >> (NATIVE_BITS -1));
89
90 return inWord & ((NATIVE_UINT)0xff << 8 * (diff32 & (NATIVE_BYTES - 1)) );
91}
INT32 NATIVE_INT
Definition: sc_lib.h:76
UINT32 NATIVE_UINT
Definition: sc_lib.h:77
#define NATIVE_BYTES
Definition: sc_lib.h:79
#define NATIVE_BITS
Definition: sc_lib.h:78
#define MASKNB_INWORD_RELEVANTBITS
Definition: tlsCbcVerify.c:47
int32_t INT32
Definition: typedefs.h:58

◆ SymCryptNMaskEq80()

FORCEINLINE NATIVE_UINT SymCryptNMaskEq80 ( UINT32  wordStart,
UINT32  boundary 
)

Definition at line 95 of file tlsCbcVerify.c.

97{
98 INT32 diff32;
99 NATIVE_UINT inWord;
100
101 // 32-bit signed difference
102 diff32 = (INT32)boundary - (INT32)wordStart;
103
104 // inWord = (-1) if boundary is within the word, 0 otherwise
105 inWord = ~ ((-(NATIVE_INT)(NATIVE_UINT)(diff32 & MASKNB_INWORD_RELEVANTBITS)) >> (NATIVE_BITS -1));
106
107 return inWord & ((NATIVE_UINT)0x80 << 8 * (diff32 & (NATIVE_BYTES - 1)) );
108}

Referenced by SymCryptTlsCbcHmacVerifyCore().

◆ SymCryptNMaskGe()

FORCEINLINE NATIVE_UINT SymCryptNMaskGe ( UINT32  wordStart,
UINT32  boundary 
)

Definition at line 53 of file tlsCbcVerify.c.

55{
56 INT32 diff32;
57 NATIVE_INT anySet;
59
60 // Mask that is -1 if boundary < wordStart + 8
61 anySet = ((NATIVE_INT) boundary - (NATIVE_INT) wordStart - NATIVE_BYTES) >> (NATIVE_BITS - 1);
62
63 // Compute the index of boundary into the word, possibly negative
64 diff32 = (INT32)boundary - (INT32)wordStart;
65 // Compute the necessary shift when the result will be partially set
66 shift = 8 * (diff32 & (NATIVE_BYTES - 1));
67
68 // Mask the shift to 0 if the word is to be all set as boundary < wordStart
69 shift &= (INT32)~diff32 >> 31;
70
71 return (NATIVE_UINT) anySet << shift;
72}
#define shift
Definition: input.c:3280
uint32_t UINT32
Definition: typedefs.h:59

Referenced by SymCryptTlsCbcHmacVerifyCore().

◆ SymCryptTlsCbcHmacVerify()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptTlsCbcHmacVerify ( _In_ PCSYMCRYPT_MAC  pMacAlgorithm,
_In_ PVOID  pExpandedKey,
_Inout_ PVOID  pState,
_In_reads_(cbData) PCBYTE  pbData,
SIZE_T  cbData 
)

Definition at line 403 of file tlsCbcVerify.c.

409{
410 BYTE abMacValue[64];
411 BYTE abHashResult[48];
412 UINT32 u32PaddingError;
414 PCSYMCRYPT_HASH pHashAlgorithm = *(pMacAlgorithm->ppHashAlgorithm);
415 UINT32 i;
416
418 pMacAlgorithm == SymCryptHmacSha256Algorithm ||
419 pMacAlgorithm == SymCryptHmacSha384Algorithm );
420 SYMCRYPT_ASSERT(((*(pMacAlgorithm->ppHashAlgorithm))->inputBlockSize)/2 <= 64);
421 SYMCRYPT_ASSERT((*(pMacAlgorithm->ppHashAlgorithm))->resultSize <= 48);
422
425 pHashState,
426 pbData,
427 cbData,
428 abMacValue,
429 abHashResult,
430 &u32PaddingError );
431
432 // We have the hash value, convert it to a MAC value
433 // First we set up the chaining value
434 memcpy( ((PBYTE)pHashState + pHashAlgorithm->chainOffset),
435 (PBYTE)pExpandedKey + pMacAlgorithm->outerChainingStateOffset,
436 pHashAlgorithm->chainSize );
437 // Then copy the data & set the length
438 // The hash result wasn't BSWAPPED yet...
439 if( pMacAlgorithm->resultSize <= 32 )
440 {
441 SymCryptUint32ToMsbFirst( (UINT32 *) abHashResult, pHashState->buffer, pHashAlgorithm->resultSize / 4 );
442 } else {
443 SymCryptUint64ToMsbFirst( (UINT64 *) abHashResult, pHashState->buffer, pHashAlgorithm->resultSize / 8 );
444 }
445 pHashState->bytesInBuffer = pHashAlgorithm->resultSize;
446 pHashState->dataLengthL = pHashAlgorithm->resultSize + pHashAlgorithm->inputBlockSize;
447
448 (*pHashAlgorithm->resultFunc)( pHashState, abHashResult );
449
450 // Verify in 32-bit chunks to support SHA-1 without further problems
451 for( i=0; i<pHashAlgorithm->resultSize / 4; i++ )
452 {
453 u32PaddingError |= *(PUINT32)&abHashResult[4*i] ^ *(PUINT32)&abMacValue[4*i];
454 }
455
456 // We may reveal the final error-or-no-error as that will be visible anyway
457 return u32PaddingError == 0 ? SYMCRYPT_NO_ERROR : SYMCRYPT_AUTHENTICATION_FAILURE;
458}
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
unsigned int * PUINT32
Definition: basetsd.h:119
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
BYTE * PBYTE
Definition: pedump.c:66
FORCEINLINE VOID SYMCRYPT_CALL SymCryptUint32ToMsbFirst(_In_reads_(cuData) PCUINT32 puData, _Out_writes_(4 *cuData) PBYTE pbResult, SIZE_T cuData)
Definition: sc_lib.h:405
FORCEINLINE VOID SYMCRYPT_CALL SymCryptUint64ToMsbFirst(_In_reads_(cuData) PCUINT64 puData, _Out_writes_(8 *cuData) PBYTE pbResult, SIZE_T cuData)
Definition: sc_lib.h:576
#define SYMCRYPT_ASSERT(_x)
Definition: symcrypt.h:10807
const PCSYMCRYPT_MAC SymCryptHmacSha1Algorithm
Definition: hmacsha1.c:36
const PCSYMCRYPT_MAC SymCryptHmacSha256Algorithm
Definition: hmacsha256.c:29
const PCSYMCRYPT_MAC SymCryptHmacSha384Algorithm
Definition: hmacsha384.c:31
const SYMCRYPT_HASH * PCSYMCRYPT_HASH
PCBYTE PBYTE SIZE_T cbData
* PSYMCRYPT_COMMON_HASH_STATE
PSYMCRYPT_COMMON_HASH_STATE pState
PCBYTE pbData
PCSYMCRYPT_HASH pHashAlgorithm
PCVOID pExpandedKey
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptTlsCbcHmacVerifyCore(_In_ PCSYMCRYPT_HASH pHash, _Inout_ PSYMCRYPT_COMMON_HASH_STATE pState, _In_reads_bytes_(cbData) PCBYTE pbData, SIZE_T cbData, _Inout_updates_(pHash->inputBlockSize/2) PBYTE pbMacValue, _Inout_updates_(pHash->resultSize) PBYTE pbHashResult, _Out_ PUINT32 pu32PaddingError)
Definition: tlsCbcVerify.c:113
unsigned char BYTE
Definition: xxhash.c:193

◆ SymCryptTlsCbcHmacVerifyCore()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptTlsCbcHmacVerifyCore ( _In_ PCSYMCRYPT_HASH  pHash,
_Inout_ PSYMCRYPT_COMMON_HASH_STATE  pState,
_In_reads_bytes_(cbData) PCBYTE  pbData,
SIZE_T  cbData,
_Inout_updates_(pHash->inputBlockSize/2) PBYTE  pbMacValue,
_Inout_updates_(pHash->resultSize) PBYTE  pbHashResult,
_Out_ PUINT32  pu32PaddingError 
)

Definition at line 113 of file tlsCbcVerify.c.

126{
127 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
128
129 UINT32 cbPad;
130 UINT32 maxPadLength;
131 UINT32 u32;
132 UINT32 i;
133 UINT32 iPaddingStart; // using 'i' for index
134 UINT32 iMacStart;
135 NATIVE_UINT mInData;
136 NATIVE_UINT mInMac;
137 NATIVE_UINT mInPadding;
139 NATIVE_UINT nPaddingError = 0; // nonzero if a padding byte value is wrong.
140 UINT32 next;
141 UINT32 cbHashPrefix;
142 UINT32 cbExtendedData;
143 UINT32 totalBytesHashed;
144 UINT32 hashPaddingFinal;
145 UINT32 resultHashBlockIndex;
146 UINT32 lastHashBlockIndex;
149 UINT32 backOffset;
150 NATIVE_UINT * bufferLocation;
151 NATIVE_UINT padBytes;
152 UINT32 m32ResultBlock;
153 NATIVE_UINT mResultBlock;
154 SIZE_T tmp;
155 const UINT32 cbMacValue = pHash->inputBlockSize / 2;
156
157 SYMCRYPT_ASSERT( cbMacValue == SymCryptRoundUpPow2Sizet(pHash->resultSize) );
158
159 // Process all the data up to the part where the MAC value might appear
160 // The if() is safe as both cbData and u32 are public values.
161 u32 = pHash->resultSize + 256;
162 if( cbData > u32 )
163 {
164 (*pHash->appendFunc)(pState, pbData, cbData-u32 );
165 pbData += cbData - u32;
166 cbData = u32;
167 }
168
169 // Check that we have enough data for a valid record.
170 // We need one MAC value plus one padding_length byte
171 if (cbData < pHash->resultSize + 1)
172 {
173 scError = SYMCRYPT_BUFFER_TOO_SMALL;
174 goto cleanup;
175 }
176
177 // We OR our results into the result buffers, so we must init them to zero
178 SymCryptWipe( pbMacValue, cbMacValue );
179 SymCryptWipe( pbHashResult, pHash->resultSize );
180
181 // Pick up the padding_length. Note that this is the value we have to keep secret from
182 // side-channel attacks.
183 cbPad = pbData[cbData - 1];
184
185 // We reduce cbData so that the padding_length byte is no longer under consideration.
186 cbData -= 1;
187
188 // Bound the padding length to cbData - mac_length
189 // This doesn't reveal data as we treat all cbPad values the same, but it makes our
190 // further computations easier
191 maxPadLength = (UINT32)cbData - pHash->resultSize; // We checked this is >= 0
192 u32 = MASK32_LT( maxPadLength, cbPad ); // mask: maxPadLength < cbPad
193 cbPad = cbPad + ((maxPadLength - cbPad) & u32);
194 nPaddingError |= u32; // mark as padding error
195
196 // From here on out we maintain indices into a conceptual extended buffer with length cbExtendedData,
197 // and index 0 at the start of the hash computation.
198 // This aligns us with the hash input block, and simplifies hash padding computations and word
199 // accesses.
200 // However, we must always subtract cbHashPrefix from indices before using them to access bytes
201 // in pbData, as the HashPrefix was already hashed into the MAC state.
202
203 cbHashPrefix = (UINT32)pState->dataLengthL; // # bytes already hashed into the MAC state
204 cbExtendedData = (UINT32)cbData + cbHashPrefix; // total # bytes that the conceptual extended buffer has
205 next = cbHashPrefix; // next index we will consider for processing (start of pbData)
206
207 totalBytesHashed = cbExtendedData - pHash->resultSize - cbPad;
208 SYMCRYPT_STORE_MSBFIRST32( &hashPaddingFinal, totalBytesHashed * 8 ); // Length padding for result hash block
209
210 // We need to figure out what the index is of the last hash input block in the computation
211 // (including any phantom blocks after the actual hash is done) and the index of the result
212 // hash block of the actual hash computation.
213 // We've limited the max input for simplicity (everything fits in 32 bits)
214 // We also avoid 64-bit operations as their implementation on 32-bit architectures might not
215 // always be constant-time.
216 // This computation works for SHA-1, SHA-256, and SHA-384 which is all we care about
217 // We avoid using % as the runtime isn't constant and our inputs are secret.
218
219 // First the actual # bytes in the real and phantom computation
220 resultHashBlockIndex = totalBytesHashed + 1 + pHash->inputBlockSize / 8; // 1 byte 0x80 + length padding in last block
221 lastHashBlockIndex = resultHashBlockIndex + cbPad; // The furthest any hash could go
222
223 // round up to a whole # blocks
224 resultHashBlockIndex = (resultHashBlockIndex + pHash->inputBlockSize - 1) & ~(pHash->inputBlockSize - 1);
225 lastHashBlockIndex = (lastHashBlockIndex + pHash->inputBlockSize - 1) & ~(pHash->inputBlockSize - 1);
226
227 // Compute the indices where the MAC and padding start
228 iPaddingStart = cbExtendedData - cbPad;
229 iMacStart = iPaddingStart - pHash->resultSize;
230
231 SYMCRYPT_ASSERT( iMacStart < cbExtendedData ); // Fail if the last computation underflowed.
232
233 // Align our handling to the native word size so that we can safely use native words
234 if( (next & (NATIVE_BYTES - 1)) != 0 )
235 {
236 backOffset = next & (NATIVE_BYTES - 1);
237
238 // Process a partial word
239 SYMCRYPT_ASSERT( ( (next ^ pState->bytesInBuffer) & (NATIVE_BYTES - 1) ) == 0 );
240
241 // Read a word; as the MAC value is > 8 bytes this won't overflow the buffer
242 w = *(NATIVE_UINT *) &pbData[0];
243 m = SymCryptNMaskGe( next, iMacStart );
244 mInData = ~m;
245 mInMac = m;
246
247 data = w & mInData;
248 data |= SymCryptNMaskEq80( next, iMacStart ); // add 0x80 byte @ iMacStart
249
250 // Now we put the data into the hash buffer
251 bufferLocation = (NATIVE_UINT *)&pState->buffer[ pState->bytesInBuffer - backOffset ];
252 *bufferLocation = (*bufferLocation & (((NATIVE_UINT)1 << 8*backOffset) - 1)) | (data << 8*backOffset);
253 pState->bytesInBuffer += NATIVE_BYTES - backOffset;
254
255 // And the MAC data in the mac buffer
256 *(NATIVE_UINT *)&pbMacValue[(next - backOffset) & (cbMacValue - 1)] |= (w & mInMac) << 8*backOffset;
257
258 if( pState->bytesInBuffer == pHash->inputBlockSize )
259 {
260 // Block is full. This can't be the result block as we didn't have room for the padding yet.
261 (*pHash->appendBlockFunc)( (PBYTE)pState + pHash->chainOffset, &pState->buffer[0], pHash->inputBlockSize, &tmp );
262 pState->bytesInBuffer = 0;
263 }
264
265 next += NATIVE_BYTES - backOffset;
266 }
267
268 padBytes = MASKNB_BROADCAST( cbPad );
269
270 // Now we can loop over the data in whole words
271 while( next <= cbExtendedData - NATIVE_BYTES )
272 {
273 w = *(NATIVE_UINT *) &pbData[next - cbHashPrefix];
274
275 m = SymCryptNMaskGe( next, iMacStart );
276 mInMac = m;
277 mInData = ~m;
278
279 m = SymCryptNMaskGe( next, iPaddingStart );
280 mInPadding = m;
281 mInMac &= ~m;
282
283 data = w & mInData;
284 data |= SymCryptNMaskEq80( next, iMacStart ); // add 0x80 byte @ iMacStart
285
286 *(NATIVE_UINT *)(&pState->buffer[ pState->bytesInBuffer ]) = data;
287 pState->bytesInBuffer += NATIVE_BYTES;
288
289 if (pState->bytesInBuffer == pHash->inputBlockSize)
290 {
291 // Insert the length component of the hash padding (only in result block)
292 m32ResultBlock = MASK32_EQ( next, resultHashBlockIndex - NATIVE_BYTES );
293 *(UINT32*) &pState->buffer[ pHash->inputBlockSize - 4 ] |= hashPaddingFinal & m32ResultBlock;
294
295 (*pHash->appendBlockFunc)( (PBYTE)pState + pHash->chainOffset, &pState->buffer[0], pHash->inputBlockSize, &tmp );
296 SYMCRYPT_ASSERT( tmp == 0 );
297
298 mResultBlock = (NATIVE_UINT)(NATIVE_INT)(INT32) m32ResultBlock; // Convert 32-bit mask to native mask
299
300 // Masked copy of result to result buffer
301 // We do whole words, and then an optional UINT32 to handle the 20-byte SHA-1 result on AMD64.
302 // The for() and if() are side-channel safe as the resultSize and NATIVE_BYTES values are public.
303 for ( i = 0; i < pHash->resultSize / NATIVE_BYTES; i++)
304 {
305 ((NATIVE_UINT *)pbHashResult)[i] |= ((NATIVE_UINT *)((PBYTE)pState + pHash->chainOffset))[i] & mResultBlock;
306 }
307 if( (pHash->resultSize & (NATIVE_BYTES - 1)) != 0 )
308 {
309 *(UINT32 *) (&pbHashResult[ pHash->resultSize - 4 ]) |= *(UINT32 *) ((PBYTE) pState + pHash->chainOffset + pHash->resultSize - 4) & (UINT32) mResultBlock;
310 }
311 pState->bytesInBuffer = 0;
312 }
313
314 *(NATIVE_UINT *)&pbMacValue[next & (cbMacValue - 1)] |= w & mInMac;
315
316 nPaddingError |= (w ^ padBytes) & mInPadding;
317
319 }
320
321 if( next < cbExtendedData )
322 {
323 // Process the remaining bytes. This can't be data so we only do the MAC and padding...
324 // The main difference is that we read the last full word in pbData and then align it
325 // as if we read the next word starting at pbData[next - cbHashPrefix]
326 w = *(NATIVE_UINT *) &pbData[ cbData - NATIVE_BYTES ]; // last word
327 w >>= 8 * (next - cbExtendedData + NATIVE_BYTES ); // Shift to right location
328 padBytes >>= 8 * (next - cbExtendedData + NATIVE_BYTES ); // Zero padBytes that are never read
329
330 m = SymCryptNMaskGe( next, iPaddingStart );
331 mInPadding = m;
332 mInMac = ~m;
333
334 *(NATIVE_UINT *)&pbMacValue[next & (cbMacValue - 1)] |= w & mInMac;
335
336 nPaddingError |= (w ^ padBytes) & mInPadding;
337 next = cbExtendedData;
338 }
339
340 // At this point we still have to potentially do one more hash block.
341 // The data is all copied into the hash input buffer, as is the 0x80 padding byte.
342
343 if (next < lastHashBlockIndex)
344 {
345 // there is still one more hash block to compute. This could either be the actual last block of the hash
346 // computation, or a phantom block for side-channel hiding.
347 // This IF depends only on the cbData, the # bytes hashed before this final pbData buffer, and the hash algorithm
348 // properties.
349 // We never need to compute more than 1 additional hash block as we are at least pHash->resultSize bytes beyond the
350 // actual data.
351 SymCryptWipe( &pState->buffer[ pState->bytesInBuffer], pHash->inputBlockSize - pState->bytesInBuffer );
352
353 // Just put in the padding, no need to mask this
354 *(UINT32*) &pState->buffer[ pHash->inputBlockSize - 4 ] = hashPaddingFinal;
355
356 (*pHash->appendBlockFunc)( (PBYTE)pState + pHash->chainOffset, &pState->buffer[0], pHash->inputBlockSize, &tmp );
357 SYMCRYPT_ASSERT( tmp == 0 );
358
359 // Masked copy of the result
360 mResultBlock = (NATIVE_UINT)(NATIVE_INT)(INT32) MASK32_EQ( lastHashBlockIndex, resultHashBlockIndex );
361
362 // Masked copy of result to result buffer
363 // We do whole words, and then an optional UINT32 to handle the 20-byte SHA-1 result on AMD64.
364 for ( i = 0; i < pHash->resultSize / NATIVE_BYTES; i++)
365 {
366 ((NATIVE_UINT *)pbHashResult)[i] |= ((NATIVE_UINT *)((PBYTE)pState + pHash->chainOffset))[i] & mResultBlock;
367 }
368 if( (pHash->resultSize & (NATIVE_BYTES - 1)) != 0 )
369 {
370 *(UINT32 *) (&pbHashResult[ pHash->resultSize - 4 ]) |= *(UINT32 *) ((PBYTE) pState + pHash->chainOffset + pHash->resultSize - 4) & (UINT32) mResultBlock;
371 }
372 pState->bytesInBuffer = 0;
373 }
374
375 // Now we have the hash result, and the Mac value buffer is filled with a rotated copy of the Mac value.
376 // We have to un-rotate the Mac value.
377
378 // Check that we have the right hash result
379 //for( SIZE_T t=0; t < cbMacValue; t++ )
380 //{
381 // SYMCRYPT_ASSERT( pbMacValue[ (iMacStart + t) & (cbMacValue - 1 ) ] == (t >= pHash->resultSize ? 0 : pbData[iMacStart - cbHashPrefix + t] ));
382 //}
383
384 SymCryptScsRotateBuffer( pbMacValue, cbMacValue, iMacStart & (cbMacValue - 1) );
385
386 //for( SIZE_T t=0; t < cbMacValue; t++ )
387 //{
388 // SYMCRYPT_ASSERT( pbMacValue[ t ] == (t >= pHash->resultSize ? 0 : pbData[iMacStart - cbHashPrefix + t] ));
389 //}
390
391cleanup:
392
393 nPaddingError |= nPaddingError >> (NATIVE_BITS/2); // Map possibly 64 bits down to 32
394
395 *pu32PaddingError = (UINT32) nPaddingError;
396
397 return scError;
398}
ULONG32 u32
Definition: btrfs.h:14
static void cleanup(void)
Definition: main.c:1335
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
const GLfloat * m
Definition: glext.h:10848
#define u32
Definition: types.h:9
VOID SYMCRYPT_CALL SymCryptWipe(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
Definition: libmain.c:137
#define SYMCRYPT_STORE_MSBFIRST32(p, v)
Definition: symcrypt.h:311
SYMCRYPT_ERROR
Definition: symcrypt.h:227
UINT32 resultSize
PSYMCRYPT_PARALLEL_HASH_OPERATION next
VOID SYMCRYPT_CALL SymCryptScsRotateBuffer(_Inout_updates_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, SIZE_T lshift)
Definition: scsTools.c:179
SIZE_T SYMCRYPT_CALL SymCryptRoundUpPow2Sizet(SIZE_T v)
Definition: scsTools.c:76
#define MASKNB_BROADCAST(_b)
Definition: tlsCbcVerify.c:49
FORCEINLINE NATIVE_UINT SymCryptNMaskEq80(UINT32 wordStart, UINT32 boundary)
Definition: tlsCbcVerify.c:95
#define MASK32_LT(_a, _b)
Definition: tlsCbcVerify.c:31
FORCEINLINE NATIVE_UINT SymCryptNMaskGe(UINT32 wordStart, UINT32 boundary)
Definition: tlsCbcVerify.c:53
#define MASK32_EQ(_a, _b)
Definition: tlsCbcVerify.c:34
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by SymCryptTlsCbcHmacVerify().