Line | Count | Source (jump to first uncovered line) |
1 | | // |
2 | | // Sha1.c |
3 | | // |
4 | | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. |
5 | | // |
6 | | // This revised implementation is based on the older one in RSA32LIB by |
7 | | // Scott Field and Dan Shumow. It is not based on any 3rd party code. |
8 | | // |
9 | | |
10 | | #include "precomp.h" |
11 | | |
12 | | // |
13 | | // See the symcrypt.h file for documentation on what the various functions do. |
14 | | // |
15 | | |
16 | | const SYMCRYPT_HASH SymCryptSha1Algorithm_default = { |
17 | | &SymCryptSha1Init, |
18 | | &SymCryptSha1Append, |
19 | | &SymCryptSha1Result, |
20 | | &SymCryptSha1AppendBlocks, |
21 | | &SymCryptSha1StateCopy, |
22 | | sizeof( SYMCRYPT_SHA1_STATE ), |
23 | | SYMCRYPT_SHA1_RESULT_SIZE, |
24 | | SYMCRYPT_SHA1_INPUT_BLOCK_SIZE, |
25 | | SYMCRYPT_FIELD_OFFSET( SYMCRYPT_SHA1_STATE, chain ), |
26 | | SYMCRYPT_FIELD_SIZE( SYMCRYPT_SHA1_STATE, chain ), |
27 | | }; |
28 | | |
29 | | const PCSYMCRYPT_HASH SymCryptSha1Algorithm = &SymCryptSha1Algorithm_default; |
30 | | |
31 | | |
32 | | // |
33 | | // The round constants used by SHA-1 |
34 | | // |
35 | | static const UINT32 Sha1K[4] = { |
36 | | 0x5a827999UL, 0x6ed9eba1UL, 0x8f1bbcdcUL, 0xca62c1d6UL, |
37 | | }; |
38 | | |
39 | | // |
40 | | // Initial state |
41 | | // |
42 | | static const UINT32 sha1InitialState[5] = { |
43 | | 0x67452301UL, |
44 | | 0xefcdab89UL, |
45 | | 0x98badcfeUL, |
46 | | 0x10325476UL, |
47 | | 0xc3d2e1f0UL, |
48 | | }; |
49 | | |
50 | | // |
51 | | // SymCryptSha1 |
52 | | // |
53 | | #define ALG SHA1 |
54 | | #define Alg Sha1 |
55 | | #include "hash_pattern.c" |
56 | | #undef ALG |
57 | | #undef Alg |
58 | | |
59 | | |
60 | | |
61 | | |
62 | | // |
63 | | // SymCryptSha1Init |
64 | | // |
65 | | SYMCRYPT_NOINLINE |
66 | | VOID |
67 | | SYMCRYPT_CALL |
68 | | SymCryptSha1Init( _Out_ PSYMCRYPT_SHA1_STATE pState ) |
69 | 22.8k | { |
70 | 22.8k | SYMCRYPT_SET_MAGIC( pState ); |
71 | | |
72 | 22.8k | pState->dataLengthL = 0; |
73 | 22.8k | pState->dataLengthH = 0; |
74 | 22.8k | pState->bytesInBuffer = 0; |
75 | | |
76 | 22.8k | memcpy( &pState->chain.H[0], &sha1InitialState[0], sizeof( sha1InitialState ) ); |
77 | | |
78 | | // |
79 | | // There is no need to initialize the buffer part of the state as that will be |
80 | | // filled before it is used. |
81 | | // |
82 | 22.8k | } |
83 | | |
84 | | |
85 | | // |
86 | | // SymCryptSha1Append |
87 | | // |
88 | | SYMCRYPT_NOINLINE |
89 | | VOID |
90 | | SYMCRYPT_CALL |
91 | | SymCryptSha1Append( |
92 | | _Inout_ PSYMCRYPT_SHA1_STATE pState, |
93 | | _In_reads_( cbData ) PCBYTE pbData, |
94 | | SIZE_T cbData ) |
95 | 71.6k | { |
96 | 71.6k | SymCryptHashAppendInternal( SymCryptSha1Algorithm, (PSYMCRYPT_COMMON_HASH_STATE)pState, pbData, cbData ); |
97 | 71.6k | } |
98 | | |
99 | | |
100 | | // |
101 | | // SymCryptSha1Result |
102 | | // |
103 | | SYMCRYPT_NOINLINE |
104 | | VOID |
105 | | SYMCRYPT_CALL |
106 | | SymCryptSha1Result( |
107 | | _Inout_ PSYMCRYPT_SHA1_STATE pState, |
108 | | _Out_writes_( SYMCRYPT_SHA1_RESULT_SIZE ) PBYTE pbResult ) |
109 | 22.4k | { |
110 | 22.4k | UINT32 bytesInBuffer; |
111 | 22.4k | SIZE_T tmp; |
112 | | |
113 | | // |
114 | | // SHA-1 uses almost the MD4 padding, except that the length in the padding is stored |
115 | | // MSBFirst, rather than LSBFirst. |
116 | | // As SHA-256 has a dedicated (fast) padding anyway, there is no gain to create a |
117 | | // common padding routine for SHA-1 as it wouldn't be shared by anyone right now. |
118 | | // |
119 | 22.4k | SYMCRYPT_CHECK_MAGIC( pState ); |
120 | | |
121 | 22.4k | bytesInBuffer = (UINT32)(pState->bytesInBuffer); |
122 | | |
123 | | // |
124 | | // The buffer is never completely full, so we can always put the first |
125 | | // padding byte in. |
126 | | // |
127 | 22.4k | pState->buffer[bytesInBuffer++] = 0x80; |
128 | | |
129 | 22.4k | if( bytesInBuffer > 64-8 ) { |
130 | | // |
131 | | // No room for the rest of the padding. Pad with zeroes & process block |
132 | | // bytesInBuffer is at most 64, so we do not have an integer underflow |
133 | | // |
134 | 682 | memset( &pState->buffer[bytesInBuffer], 0, 64-bytesInBuffer ); |
135 | 682 | SymCryptSha1AppendBlocks( &pState->chain, pState->buffer, 64, &tmp ); |
136 | 682 | bytesInBuffer = 0; |
137 | 682 | } |
138 | | |
139 | | // |
140 | | // Set rest of padding |
141 | | // At this point bytesInBuffer <= 64-8, so we don't have an underflow |
142 | | // We wipe to the end of the buffer as it is 16-aligned, |
143 | | // and it is faster to wipe to an aligned point |
144 | | // |
145 | 22.4k | memset( &pState->buffer[bytesInBuffer], 0, 64-bytesInBuffer ); |
146 | 22.4k | SYMCRYPT_STORE_MSBFIRST64( &pState->buffer[64-8], pState->dataLengthL * 8 ); |
147 | | |
148 | | // |
149 | | // Process the final block |
150 | | // |
151 | 22.4k | SymCryptSha1AppendBlocks( &pState->chain, pState->buffer, 64, &tmp ); |
152 | | |
153 | | // |
154 | | // Write the output in the correct byte order |
155 | | // |
156 | 22.4k | SymCryptUint32ToMsbFirst( &pState->chain.H[0], pbResult, 5 ); |
157 | | |
158 | | // |
159 | | // Wipe & re-initialize |
160 | | // We have to wipe the whole state because the Init call |
161 | | // might be optimized away by a smart compiler. |
162 | | // |
163 | 22.4k | SymCryptWipeKnownSize( pState, sizeof( *pState ) ); |
164 | 22.4k | SymCryptSha1Init( pState ); |
165 | 22.4k | } |
166 | | |
167 | | |
168 | | // |
169 | | // For documentation on these function see FIPS 180-2 |
170 | | // |
171 | | // CH, MAJ and PARITY are the functions Ch, Maj, and Parity from the standard. |
172 | | // |
173 | | //#define CH( x, y, z ) (((x) & (y)) ^ ((~(x)) & (z))) |
174 | | //#define MAJ( x, y, z ) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) |
175 | 16.4M | #define MAJ( x, y, z ) ((((x) | (y)) & (z) ) | ((x) & (y))) |
176 | 16.4M | #define CH( x, y, z ) ((((z) ^ (y)) & (x)) ^ (z)) |
177 | | |
178 | 32.9M | #define PARITY( x, y, z ) ((x) ^ (y) ^ (z) ) |
179 | | |
180 | | |
181 | | // |
182 | | // The values a-e are stored in an array called ae. |
183 | | // We have unrolled the code completely. This makes both the indices into |
184 | | // the ae array constant, and it makes the message addressing constant. |
185 | | // |
186 | | |
187 | | // |
188 | | // Initial round macro |
189 | | // |
190 | | // r is the round number |
191 | | // ae[(r+0)%5] = e; |
192 | | // ae[(r+1)%5] = d; |
193 | | // ae[(r+2)%5] = c; |
194 | | // ae[(r+3)%5] = b; |
195 | | // ae[(r+4)%5] = a; |
196 | | // After that incrementing the round number will automatically map a->b, b->c, etc. |
197 | | // |
198 | | |
199 | | // |
200 | | // The core round routine (excluding the message schedule) |
201 | | // |
202 | | // In more readable form this macro does the following: |
203 | | // e = ROL(a,5) + F(b,c,d) + e + K[r/20] + W[round] |
204 | | // b = ROL( b, 30 ) |
205 | | // |
206 | | |
207 | 65.8M | #define CROUND( a, b, c, d, e, r, F ) {\ |
208 | 65.8M | W[r%16] = Wt; \ |
209 | 65.8M | e += ROL32( a, 5 ) + F(b, c, d) + Sha1K[r/20] + Wt;\ |
210 | 65.8M | b = ROR32( b, 2 );\ |
211 | 65.8M | } |
212 | | |
213 | 13.1M | #define IROUND( a, b, c, d, e, r, F ) { \ |
214 | 13.1M | Wt = SYMCRYPT_LOAD_MSBFIRST32( &pbData[ 4*r ] ); \ |
215 | 13.1M | CROUND( a, b, c, d, e, r, F ); \ |
216 | 13.1M | } |
217 | | |
218 | | // |
219 | | // Subsequent rounds. |
220 | | // This is the same as the IROUND except that it adds the message schedule, |
221 | | // and takes the message word from the intermediate |
222 | | // |
223 | 52.6M | #define FROUND( a, b, c, d, e, r, F ) { \ |
224 | 52.6M | Wt = ROL32( W[(r+13)%16] ^ W[(r+8)%16] ^ W[(r+2)%16] ^ W[r%16], 1 );\ |
225 | 52.6M | CROUND( a, b, c, d, e, r, F ); \ |
226 | 52.6M | } |
227 | | |
228 | | VOID |
229 | | SYMCRYPT_CALL |
230 | | SymCryptSha1AppendBlocks( |
231 | | _Inout_ SYMCRYPT_SHA1_CHAINING_STATE * pChain, |
232 | | _In_reads_( cbData ) PCBYTE pbData, |
233 | | SIZE_T cbData, |
234 | | _Out_ SIZE_T * pcbRemaining ) |
235 | 38.5k | { |
236 | | |
237 | 38.5k | SYMCRYPT_ALIGN UINT32 W[16]; |
238 | 38.5k | UINT32 A, B, C, D, E; |
239 | 38.5k | UINT32 Wt; |
240 | | |
241 | 38.5k | A = pChain->H[0]; |
242 | 38.5k | B = pChain->H[1]; |
243 | 38.5k | C = pChain->H[2]; |
244 | 38.5k | D = pChain->H[3]; |
245 | 38.5k | E = pChain->H[4]; |
246 | | |
247 | 861k | while( cbData >= 64 ) |
248 | 823k | { |
249 | | // |
250 | | // initial rounds 1 to 16 |
251 | | // |
252 | | |
253 | 823k | IROUND( A, B, C, D, E, 0, CH ); |
254 | 823k | IROUND( E, A, B, C, D, 1, CH ); |
255 | 823k | IROUND( D, E, A, B, C, 2, CH ); |
256 | 823k | IROUND( C, D, E, A, B, 3, CH ); |
257 | 823k | IROUND( B, C, D, E, A, 4, CH ); |
258 | 823k | IROUND( A, B, C, D, E, 5, CH ); |
259 | 823k | IROUND( E, A, B, C, D, 6, CH ); |
260 | 823k | IROUND( D, E, A, B, C, 7, CH ); |
261 | 823k | IROUND( C, D, E, A, B, 8, CH ); |
262 | 823k | IROUND( B, C, D, E, A, 9, CH ); |
263 | 823k | IROUND( A, B, C, D, E, 10, CH ); |
264 | 823k | IROUND( E, A, B, C, D, 11, CH ); |
265 | 823k | IROUND( D, E, A, B, C, 12, CH ); |
266 | 823k | IROUND( C, D, E, A, B, 13, CH ); |
267 | 823k | IROUND( B, C, D, E, A, 14, CH ); |
268 | 823k | IROUND( A, B, C, D, E, 15, CH ); |
269 | | |
270 | | // |
271 | | // Full rounds (including msg expansion) from here on |
272 | | // |
273 | 823k | FROUND( E, A, B, C, D, 16, CH ); |
274 | 823k | FROUND( D, E, A, B, C, 17, CH ); |
275 | 823k | FROUND( C, D, E, A, B, 18, CH ); |
276 | 823k | FROUND( B, C, D, E, A, 19, CH ); |
277 | | |
278 | | |
279 | 823k | FROUND( A, B, C, D, E, 20, PARITY ); |
280 | 823k | FROUND( E, A, B, C, D, 21, PARITY ); |
281 | 823k | FROUND( D, E, A, B, C, 22, PARITY ); |
282 | 823k | FROUND( C, D, E, A, B, 23, PARITY ); |
283 | 823k | FROUND( B, C, D, E, A, 24, PARITY ); |
284 | 823k | FROUND( A, B, C, D, E, 25, PARITY ); |
285 | 823k | FROUND( E, A, B, C, D, 26, PARITY ); |
286 | 823k | FROUND( D, E, A, B, C, 27, PARITY ); |
287 | 823k | FROUND( C, D, E, A, B, 28, PARITY ); |
288 | 823k | FROUND( B, C, D, E, A, 29, PARITY ); |
289 | 823k | FROUND( A, B, C, D, E, 30, PARITY ); |
290 | 823k | FROUND( E, A, B, C, D, 31, PARITY ); |
291 | 823k | FROUND( D, E, A, B, C, 32, PARITY ); |
292 | 823k | FROUND( C, D, E, A, B, 33, PARITY ); |
293 | 823k | FROUND( B, C, D, E, A, 34, PARITY ); |
294 | 823k | FROUND( A, B, C, D, E, 35, PARITY ); |
295 | 823k | FROUND( E, A, B, C, D, 36, PARITY ); |
296 | 823k | FROUND( D, E, A, B, C, 37, PARITY ); |
297 | 823k | FROUND( C, D, E, A, B, 38, PARITY ); |
298 | 823k | FROUND( B, C, D, E, A, 39, PARITY ); |
299 | | |
300 | | |
301 | 823k | FROUND( A, B, C, D, E, 40, MAJ ); |
302 | 823k | FROUND( E, A, B, C, D, 41, MAJ ); |
303 | 823k | FROUND( D, E, A, B, C, 42, MAJ ); |
304 | 823k | FROUND( C, D, E, A, B, 43, MAJ ); |
305 | 823k | FROUND( B, C, D, E, A, 44, MAJ ); |
306 | 823k | FROUND( A, B, C, D, E, 45, MAJ ); |
307 | 823k | FROUND( E, A, B, C, D, 46, MAJ ); |
308 | 823k | FROUND( D, E, A, B, C, 47, MAJ ); |
309 | 823k | FROUND( C, D, E, A, B, 48, MAJ ); |
310 | 823k | FROUND( B, C, D, E, A, 49, MAJ ); |
311 | 823k | FROUND( A, B, C, D, E, 50, MAJ ); |
312 | 823k | FROUND( E, A, B, C, D, 51, MAJ ); |
313 | 823k | FROUND( D, E, A, B, C, 52, MAJ ); |
314 | 823k | FROUND( C, D, E, A, B, 53, MAJ ); |
315 | 823k | FROUND( B, C, D, E, A, 54, MAJ ); |
316 | 823k | FROUND( A, B, C, D, E, 55, MAJ ); |
317 | 823k | FROUND( E, A, B, C, D, 56, MAJ ); |
318 | 823k | FROUND( D, E, A, B, C, 57, MAJ ); |
319 | 823k | FROUND( C, D, E, A, B, 58, MAJ ); |
320 | 823k | FROUND( B, C, D, E, A, 59, MAJ ); |
321 | | |
322 | 823k | FROUND( A, B, C, D, E, 60, PARITY ); |
323 | 823k | FROUND( E, A, B, C, D, 61, PARITY ); |
324 | 823k | FROUND( D, E, A, B, C, 62, PARITY ); |
325 | 823k | FROUND( C, D, E, A, B, 63, PARITY ); |
326 | 823k | FROUND( B, C, D, E, A, 64, PARITY ); |
327 | 823k | FROUND( A, B, C, D, E, 65, PARITY ); |
328 | 823k | FROUND( E, A, B, C, D, 66, PARITY ); |
329 | 823k | FROUND( D, E, A, B, C, 67, PARITY ); |
330 | 823k | FROUND( C, D, E, A, B, 68, PARITY ); |
331 | 823k | FROUND( B, C, D, E, A, 69, PARITY ); |
332 | 823k | FROUND( A, B, C, D, E, 70, PARITY ); |
333 | 823k | FROUND( E, A, B, C, D, 71, PARITY ); |
334 | 823k | FROUND( D, E, A, B, C, 72, PARITY ); |
335 | 823k | FROUND( C, D, E, A, B, 73, PARITY ); |
336 | 823k | FROUND( B, C, D, E, A, 74, PARITY ); |
337 | 823k | FROUND( A, B, C, D, E, 75, PARITY ); |
338 | 823k | FROUND( E, A, B, C, D, 76, PARITY ); |
339 | 823k | FROUND( D, E, A, B, C, 77, PARITY ); |
340 | 823k | FROUND( C, D, E, A, B, 78, PARITY ); |
341 | 823k | FROUND( B, C, D, E, A, 79, PARITY ); |
342 | | |
343 | | |
344 | 823k | pChain->H[0] = A = A + pChain->H[0]; |
345 | 823k | pChain->H[1] = B = B + pChain->H[1]; |
346 | 823k | pChain->H[2] = C = C + pChain->H[2]; |
347 | 823k | pChain->H[3] = D = D + pChain->H[3]; |
348 | 823k | pChain->H[4] = E = E + pChain->H[4]; |
349 | | |
350 | 823k | pbData += 64; |
351 | 823k | cbData -= 64; |
352 | 823k | } |
353 | | |
354 | 38.5k | *pcbRemaining = cbData; |
355 | | |
356 | | // |
357 | | // Wipe the variables; |
358 | | // |
359 | 38.5k | SymCryptWipeKnownSize( W, sizeof( W ) ); |
360 | 38.5k | SYMCRYPT_FORCE_WRITE32( &A, 0 ); |
361 | 38.5k | SYMCRYPT_FORCE_WRITE32( &B, 0 ); |
362 | 38.5k | SYMCRYPT_FORCE_WRITE32( &C, 0 ); |
363 | 38.5k | SYMCRYPT_FORCE_WRITE32( &D, 0 ); |
364 | 38.5k | SYMCRYPT_FORCE_WRITE32( &E, 0 ); |
365 | 38.5k | SYMCRYPT_FORCE_WRITE32( &Wt, 0 ); |
366 | 38.5k | } |
367 | | |
368 | | |
369 | | VOID |
370 | | SYMCRYPT_CALL |
371 | | SymCryptSha1StateExport( |
372 | | _In_ PCSYMCRYPT_SHA1_STATE pState, |
373 | | _Out_writes_bytes_( SYMCRYPT_SHA1_STATE_EXPORT_SIZE ) PBYTE pbBlob ) |
374 | 0 | { |
375 | 0 | SYMCRYPT_ALIGN SYMCRYPT_SHA1_STATE_EXPORT_BLOB blob; // local copy to have proper alignment. |
376 | 0 | C_ASSERT( sizeof( blob ) == SYMCRYPT_SHA1_STATE_EXPORT_SIZE ); |
377 | |
|
378 | 0 | SYMCRYPT_CHECK_MAGIC( pState ); |
379 | |
|
380 | 0 | SymCryptWipeKnownSize( &blob, sizeof( blob ) ); // wipe to avoid any data leakage |
381 | |
|
382 | 0 | blob.header.magic = SYMCRYPT_BLOB_MAGIC; |
383 | 0 | blob.header.size = SYMCRYPT_SHA1_STATE_EXPORT_SIZE; |
384 | 0 | blob.header.type = SymCryptBlobTypeSha1State; |
385 | | |
386 | | // |
387 | | // Copy the relevant data. Buffer will be 0-padded. |
388 | | // |
389 | |
|
390 | 0 | SymCryptUint32ToMsbFirst( &pState->chain.H[0], &blob.chain[0], 5 ); |
391 | 0 | blob.dataLength = pState->dataLengthL; |
392 | 0 | memcpy( &blob.buffer[0], &pState->buffer[0], blob.dataLength & 0x3f ); |
393 | |
|
394 | 0 | SYMCRYPT_ASSERT( (PCBYTE) &blob + sizeof( blob ) - sizeof( SYMCRYPT_BLOB_TRAILER ) == (PCBYTE) &blob.trailer ); |
395 | 0 | SymCryptMarvin32( SymCryptMarvin32DefaultSeed, (PCBYTE) &blob, sizeof( blob ) - sizeof( SYMCRYPT_BLOB_TRAILER ), &blob.trailer.checksum[0] ); |
396 | |
|
397 | 0 | memcpy( pbBlob, &blob, sizeof( blob ) ); |
398 | | |
399 | | //cleanup: |
400 | 0 | SymCryptWipeKnownSize( &blob, sizeof( blob ) ); |
401 | 0 | return; |
402 | 0 | } |
403 | | |
404 | | SYMCRYPT_ERROR |
405 | | SYMCRYPT_CALL |
406 | | SymCryptSha1StateImport( |
407 | | _Out_ PSYMCRYPT_SHA1_STATE pState, |
408 | | _In_reads_bytes_( SYMCRYPT_SHA1_STATE_EXPORT_SIZE) PCBYTE pbBlob ) |
409 | 0 | { |
410 | 0 | SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR; |
411 | 0 | SYMCRYPT_ALIGN SYMCRYPT_SHA1_STATE_EXPORT_BLOB blob; // local copy to have proper alignment. |
412 | 0 | BYTE checksum[8]; |
413 | |
|
414 | 0 | C_ASSERT( sizeof( blob ) == SYMCRYPT_SHA1_STATE_EXPORT_SIZE ); |
415 | 0 | memcpy( &blob, pbBlob, sizeof( blob ) ); |
416 | |
|
417 | 0 | if( blob.header.magic != SYMCRYPT_BLOB_MAGIC || |
418 | 0 | blob.header.size != SYMCRYPT_SHA1_STATE_EXPORT_SIZE || |
419 | 0 | blob.header.type != SymCryptBlobTypeSha1State ) |
420 | 0 | { |
421 | 0 | scError = SYMCRYPT_INVALID_BLOB; |
422 | 0 | goto cleanup; |
423 | 0 | } |
424 | | |
425 | 0 | SymCryptMarvin32( SymCryptMarvin32DefaultSeed, (PCBYTE) &blob, sizeof( blob ) - sizeof( SYMCRYPT_BLOB_TRAILER ), checksum ); |
426 | 0 | if( memcmp( checksum, &blob.trailer.checksum[0], 8 ) != 0 ) |
427 | 0 | { |
428 | 0 | scError = SYMCRYPT_INVALID_BLOB; |
429 | 0 | goto cleanup; |
430 | 0 | } |
431 | | |
432 | 0 | SymCryptMsbFirstToUint32( &blob.chain[0], &pState->chain.H[0], 5 ); |
433 | 0 | pState->dataLengthL = blob.dataLength; |
434 | 0 | pState->dataLengthH = 0; |
435 | 0 | pState->bytesInBuffer = blob.dataLength & 0x3f; |
436 | 0 | memcpy( &pState->buffer[0], &blob.buffer[0], pState->bytesInBuffer ); |
437 | |
|
438 | 0 | SYMCRYPT_SET_MAGIC( pState ); |
439 | |
|
440 | 0 | cleanup: |
441 | 0 | SymCryptWipeKnownSize( &blob, sizeof(blob) ); |
442 | 0 | return scError; |
443 | 0 | } |
444 | | |
445 | | |
446 | | |
447 | | // |
448 | | // Simple test vector for FIPS module testing |
449 | | // |
450 | | |
451 | | static const BYTE sha1KATAnswer[ 20 ] = { |
452 | | 0xa9, 0x99, 0x3e, 0x36, |
453 | | 0x47, 0x06, 0x81, 0x6a, |
454 | | 0xba, 0x3e, 0x25, 0x71, |
455 | | 0x78, 0x50, 0xc2, 0x6c, |
456 | | 0x9c, 0xd0, 0xd8, 0x9d |
457 | | } ; |
458 | | |
459 | | VOID |
460 | | SYMCRYPT_CALL |
461 | | SymCryptSha1Selftest(void) |
462 | 0 | { |
463 | 0 | BYTE result[SYMCRYPT_SHA1_RESULT_SIZE]; |
464 | |
|
465 | 0 | SymCryptSha1( SymCryptTestMsg3, sizeof( SymCryptTestMsg3 ), result ); |
466 | |
|
467 | 0 | SymCryptInjectError( result, sizeof( result ) ); |
468 | |
|
469 | 0 | if( memcmp( result, sha1KATAnswer, sizeof( result ) ) != 0 ) { |
470 | 0 | SymCryptFatal( 'SHA1' ); |
471 | 0 | } |
472 | 0 | } |
473 | | |