ReactOS 0.4.17-dev-1005-g171e1de
aesCtrDrbg.c
Go to the documentation of this file.
1//
2// aesCtrDrbg.c code for SP 800-90 AES-CTR-DRBG implementation
3//
4// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5//
6
7//
8// This code is derived from the implementation already in use in CNG.
9//
10
11#include "precomp.h"
12
13#define SYMCRYPT_RNG_AES_KEY_SIZE (32)
14#define SYMCRYPT_RNG_AES_KEY_AND_V_SIZE (32 + 16)
15#define SYMCRYPT_RNG_AES_MAX_REQUEST_SIZE (1<<16)
16#define SYMCRYPT_RNG_AES_MAX_REQUESTS_PER_RESEED ((UINT64)1<<48)
17
18VOID
25{
26 //
27 //Length of input should always be multiple of the AES block size
28 //
30
32
34}
35
36
37VOID
43{
44 //maximal input length + IV + padding
46 PBYTE pb;
47 SIZE_T lenIvS;
48
51 PBYTE pX;
52
53 SIZE_T i;
54
55 C_ASSERT( sizeof( temp ) % SYMCRYPT_AES_BLOCK_SIZE == 0 );
56
57 //
58 // See SP800-90 section 10.4.2
59 //
60 // Our buf contains the following data:
61 // - 16 bytes IV
62 // - 4 bytes L
63 // - 4 bytes N
64 // - up to SEEDLEN bytes input data
65 // - 1 byte 0x80
66 // - zeroes to fill to a multiple of 16
67 //
68
71
72 //
73 // Initialize the entire buf to zero
74 //
75 SymCryptWipeKnownSize( buf, sizeof( buf ) );
76
77 //
78 // build the string S in buf[16...]
79 //
81
82 //
83 // Set L; SP800-90 isn't clear, but we'll use MSB first as that is what is used elsewhere.
84 //
86 pb += 4;
87
88 //
89 // Set N
90 //
92 pb += 4;
93
94 //
95 // Set input_string
96 //
97
98 memcpy( pb, pcbData, cbData );
99 pb += cbData;
100
101 //
102 // set padding
103 //
104 *pb++ = 0x80;
105
106 while( (pb - buf) % SYMCRYPT_AES_BLOCK_SIZE != 0 )
107 {
108#pragma prefast( suppress: 26015, "Logic why this doesn't overflow the buf[] array is too complicated for prefast" )
109 *pb++ = 0;
110 }
111
112 lenIvS = pb - buf; // Length of IV & S together
113
114 //
115 // Set up the inital key
116 //
117
118 for( i = 0; i < SYMCRYPT_RNG_AES_KEY_SIZE; i++ )
119 {
120 temp[i] = (BYTE) i;
121 }
123
124
125 //
126 // Produce the 'temp' intermediate result.
127 //
128
130 {
131 //
132 // Update the IV with the right i value.
133 // i is only 0-2, so we only have to set a single byte
134 //
135 buf[3] = (BYTE) i;
136
137 //
138 // Now we perform the BCC function, which is just CbcMac
139 // BCC(K,(IV||S))
140 SymCryptRngAesBcc( &aesKey, buf, lenIvS, &temp[ i * SYMCRYPT_AES_BLOCK_SIZE ] );
141 }
142
143 //
144 // Second phase, produce the actual output
145 //
148
150 {
151 SymCryptAesEncrypt( &aesKey, pX, pX );
153 }
154
155 SymCryptWipeKnownSize( buf, sizeof( buf ) );
156 SymCryptWipeKnownSize( temp, sizeof( temp ) );
157 SymCryptWipeKnownSize( &aesKey, sizeof( aesKey ) );
158}
159
160
161VOID
166 _Out_writes_(cbRandom) PBYTE pbRandom,
167 _In_ SIZE_T cbRandom )
168//
169// Internal function to generate output blocks from the state.
170// cbRandom must be a multiple of the block size.
171//
172{
173 UINT64 v;
174 SIZE_T cBlocks;
175 SIZE_T blocksToDo;
176 SIZE_T bytesToDo;
177
178//
179// The roll-over of the counter is hard to test, especially since our
180// NIST test vectors only cover small outputs.
181// We have an option to test the output against a simpler (older) implementation
182// to validate the proper working of the code.
183//
184#define TEST_AGAINST_OLD_CODE 0
185#if TEST_AGAINST_OLD_CODE
186 BYTE Vcopy[16];
187 BYTE buf[16];
188 PCBYTE pbCheck = pbRandom;
189 SIZE_T cbCheck = cbRandom;
190
191 memcpy( Vcopy, pV, 16 );
192#endif
193
194 //
195 // cbRandom must be a multiple of BLOCK_LEN and > 0.
196 //
197 SYMCRYPT_ASSERT( (cbRandom & (SYMCRYPT_AES_BLOCK_SIZE-1)) == 0 );
198
199 cBlocks = cbRandom / SYMCRYPT_AES_BLOCK_SIZE;
200
201 //
202 // We violate the write-once rule here by wiping the output buffer and then
203 // filling it with the CTR-mode encryption.
204 // This is safe because the caller only learns the proper output anyway.
205 //
206 SymCryptWipe( pbRandom, cbRandom );
207
208 //
209 // This loop is a little complicated because we need to pre-increment the 128-bit value V
210 // and the SymCryptAesCtrMsb64 function does a 64-bit post-increment.
211 //
212 while( cBlocks != 0 )
213 {
214 // Increment V
215 v = SYMCRYPT_LOAD_MSBFIRST64( &pV[8] ) + 1;
216 SYMCRYPT_STORE_MSBFIRST64( &pV[8], v );
217 SYMCRYPT_STORE_MSBFIRST64( &pV[0], SYMCRYPT_LOAD_MSBFIRST64( &pV[0] ) + (v == 0) );
218
219 //
220 // The SymCryptAesCtrMsb64 routine will increment the last 64 bits of the V value,
221 // but not handle the carry to the first 64 bits.
222 // We limit how many block we do so that we never cross this boundary.
223 // SymCryptAesCtrMsb64 does a post-increment, so it may increment the last 64 bits
224 // to zero as long as we don't rely on the V value afterwards.
225 // As one-in-2^64 code is not testable, we terminate the Msb64 call earlier, and
226 // much earlier on CHKed builds.
227 //
228#if SYMCRYPT_DEBUG
229#define MAX_CTRMSB64_BLOCKS (1 << 3) // very small; overflow will be triggered by any reasonable test
230#else
231#define MAX_CTRMSB64_BLOCKS (1 << 10) // increase when we have this well-tested
232#endif
233 //
234 // 1 + (~v & mask) is the value you can add to v so that the mask bits of the sum
235 // end up to be zero. It is in the range 1 .. mask+1
236 //
237 blocksToDo = SYMCRYPT_MIN( cBlocks, 1 + ( (~v) & (MAX_CTRMSB64_BLOCKS - 1) ) );
238
239 bytesToDo = blocksToDo * SYMCRYPT_AES_BLOCK_SIZE;
240 SYMCRYPT_ASSERT( bytesToDo <= cbRandom );
241 SymCryptAesCtrMsb64( pAesKey, &pV[0], pbRandom, pbRandom, bytesToDo );
242 pbRandom += bytesToDo;
243 cbRandom -= bytesToDo; // only used for prefast assertions; optimized away in shipping code
244 cBlocks -= blocksToDo;
245
246 //
247 // Post-decrement the V block to compensate for the post-increment of the Msb64 function
248 //
249 v += blocksToDo - 1;
250 SYMCRYPT_ASSERT( v != 0 );
251
252 SYMCRYPT_STORE_MSBFIRST64( &pV[8], v );
253 // No need to carry to the first half of V here, it cannot happen
254 }
255
256#if TEST_AGAINST_OLD_CODE
257 //
258 // We tried to use the CtrMsb64 mode to generate the blocks, but that leads to
259 // a number of complications.
260 // The lack of carry means we end up with code paths that run once per 2^64 blocks
261 // or so, and that is very hard to test.
262 // Furthermore, CtrMsb64 uses post-increment, whereas AES-CTR_DRBG uses pre-increment.
263 // That adds sufficient extra complications and testing problems that we went back
264 // to the solution below.
265 //
266
267 while( cbCheck != 0 )
268 {
269 SYMCRYPT_ASSERT( cbCheck >= SYMCRYPT_AES_BLOCK_SIZE ); // Keep prefast happy
270 //
271 // Increment the 128-bit block V MSByte first.
272 //
273 v = SYMCRYPT_LOAD_MSBFIRST64( &Vcopy[8] ) + 1;
274 SYMCRYPT_STORE_MSBFIRST64( &Vcopy[8], v );
275 if( v == 0 )
276 {
277 //
278 // This almost never happens.
279 // Using an if() is not side-channel safe, but in this case
280 // the side channel does not reveal anything that actually hurts the
281 // security of the algorithm.
282 //
283 SYMCRYPT_STORE_MSBFIRST64( Vcopy, 1 + LOAD_MSBFIRST64( Vcopy ) );
284 }
285
286 SymCryptAesEncrypt( pAesKey, Vcopy, buf );
287 if( memcmp( buf, pbCheck, 16 ) != 0 )
288 {
289 SymCryptFatal( 'OLD?' );
290 }
291 pbCheck += SYMCRYPT_AES_BLOCK_SIZE;
292 cbCheck -= SYMCRYPT_AES_BLOCK_SIZE;
293 }
294#endif
295}
296
298int
302//
303// return 1 if the blocks are identical, 0 if they are different.
304//
305{
306 SYMCRYPT_UNALIGNED const SIZE_T * p1 = (SYMCRYPT_UNALIGNED const SIZE_T *) pSrc1;
307 SYMCRYPT_UNALIGNED const SIZE_T * p2 = (SYMCRYPT_UNALIGNED const SIZE_T *) pSrc2;
308
309 SIZE_T tmp;
310
311#if SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_ARM
312
313 C_ASSERT( sizeof( SIZE_T ) == 4 );
314 tmp = (p1[0] ^ p2[0]) | (p1[1] ^ p2[1]) | (p1[2] ^ p2[2]) | (p1[3] ^ p2[3]);
315
316#elif SYMCRYPT_CPU_AMD64 | SYMCRYPT_CPU_ARM64
317
318 C_ASSERT( sizeof( SIZE_T ) == 8 );
319 tmp = (p1[0] ^ p2[0]) | (p1[1] ^ p2[1]);
320
321#else
322
323 SIZE_T i;
324
325 C_ASSERT( 16 % sizeof( SIZE_T ) == 0 );
326
327 tmp = 0;
328 for( i=0; i < 16/sizeof( SIZE_T ); i ++ )
329 {
330 tmp |= p1[i] ^ p2[i];
331 }
332
333#endif
334
335 return tmp == 0;
336}
337
338
339VOID
344 SIZE_T cbData )
345{
347 SIZE_T i;
348
349 SYMCRYPT_ASSERT( ((cbData & 15) == 0) && cbData > 0 );
350
352
354 {
357 }
358
360
361 //
362 // The structure of AES-CTR-DRBG makes it impossible for two consecutive blocks of a single request
363 // to be equal. The only way this could happen is if the first block of one request is the same as
364 // the last block of the previous request. But the probability of this happening is 2^{-128}.
365 // This never happens, so the whole check is technically useless.
366 // Nevertheless, it is required by FIPS 140-2, so we have to implement it,
367 // but we don't have to handle the error usefully in any way.
368 // (Trying to handle this error sensibly is far too complicated, and adds far more danger from code
369 // bugs than it is worth. It is much better to just treat it as a fatal occurrence.)
370 //
371
372 if( identical )
373 {
374 SymCryptFatal( 'acdi' );
375 }
376}
377
378VOID
384//
385// Implement the CTR_DRBG Update function.
386// pbProvidedData is optional, but if provided must always be exactly seedlen bits.
387// pAesKey is the already expanded key of the RngState. This is optional, and only has
388// to be provided if the caller already has it.
389//
390{
394
395 if(NULL == pAesKey)
396 {
398 pKey = &aesKey;
399 }
400 else
401 {
402 pKey = pAesKey;
403 }
404
405 //
406 // Copy the V value so that we can overwrite it safely.
407 //
408
409 memcpy( buf, &pState->keyAndV[SYMCRYPT_RNG_AES_KEY_SIZE], sizeof( buf ) );
410
412 pKey,
413 buf, // pV
414 pState->keyAndV, // pbRandom
415 sizeof( pState->keyAndV) ); // cbRandom
416
417 if( pbProvidedData != NULL )
418 {
419 // XOR provided data in
420 SymCryptXorBytes( pState->keyAndV, pbProvidedData, pState->keyAndV, SYMCRYPT_RNG_AES_INTERNAL_SEED_SIZE );
421 }
422
423 SymCryptWipeKnownSize( buf, sizeof( buf ) );
424
425 //
426 // Only wipe the key if necessary.
427 //
428 if( pKey == &aesKey )
429 {
430 SymCryptWipeKnownSize( &aesKey, sizeof( aesKey ));
431 }
432}
433
438 _Out_writes_( cbRandom ) PBYTE pbRandom,
439 SIZE_T cbRandom,
440 _In_reads_opt_( cbAdditionalInput ) PCBYTE pbAdditionalInput,
441 SIZE_T cbAdditionalInput )
442//
443// This is the Generate function of our SP800-90 compliant implementation.
444// It follows the method specified in SP800-90A 10.2.1.5.2
445//
446{
450
451 //
452 // SP 800-90 9.3.1 requires a check on the length of the request.
453 //
454 if( cbRandom > SYMCRYPT_RNG_AES_MAX_REQUEST_SIZE )
455 {
456 return SYMCRYPT_WRONG_DATA_SIZE;
457 }
458 //
459 // The requestCounter test is useless as it can never happen. (It would require
460 // 2^48 calls to this function to trigger this error.)
461 // Unfortunately, SP800-90 section 11 requires a test of this error, so we have
462 // to implement the error.
463 //
464 if( pRngState->requestCounter > SYMCRYPT_RNG_AES_MAX_REQUESTS_PER_RESEED )
465 {
466 return SYMCRYPT_FIPS_FAILURE;
467 }
468
469 if( pbAdditionalInput != NULL )
470 {
471 // Update additional input using Derivation function
472 SymCryptRngAesDf( pbAdditionalInput, cbAdditionalInput, abSeed );
473 pbAdditionalInput = &abSeed[0];
474
475 // Update state with modified additional input
476 SymCryptRngAesUpdate( pRngState, pbAdditionalInput, NULL );
477 }
478
479 SymCryptAesExpandKeyEncryptOnly( &aesKey, pRngState->keyAndV, SYMCRYPT_RNG_AES_KEY_SIZE );
480
481 if( cbRandom >= SYMCRYPT_AES_BLOCK_SIZE )
482 {
483 SIZE_T wholeBlocks = cbRandom & ~(SYMCRYPT_AES_BLOCK_SIZE - 1);
485 &pRngState->keyAndV[ SYMCRYPT_RNG_AES_KEY_SIZE],
486 pbRandom,
487 wholeBlocks );
488 if( pRngState->fips140_2Check )
489 {
490 SymCryptRngAesCheckBlocksNotIdentical( pRngState->previousBlock, pbRandom, wholeBlocks );
491 }
492 pbRandom += wholeBlocks;
493 cbRandom -= wholeBlocks;
494 }
495
496 if( cbRandom > 0 )
497 {
500 &pRngState->keyAndV[ SYMCRYPT_RNG_AES_KEY_SIZE],
501 buf,
502 sizeof( buf ) );
503 if( pRngState->fips140_2Check )
504 {
505 SymCryptRngAesCheckBlocksNotIdentical( pRngState->previousBlock, buf, sizeof( buf ) );
506 }
507
508 memcpy( pbRandom, buf, cbRandom );
509 SymCryptWipeKnownSize( buf, sizeof( buf ) );
510 }
511
512 SymCryptRngAesUpdate( pRngState, pbAdditionalInput, &aesKey );
513
514 ++pRngState->requestCounter;
515
516 SymCryptWipeKnownSize( &aesKey, sizeof( aesKey ) );
517 SymCryptWipeKnownSize( abSeed, sizeof( abSeed ) );
518
519 return SYMCRYPT_NO_ERROR;
520}
521
522
524SYMCRYPT_NOINLINE
528 PCBYTE pcbSeedMaterial,
529 SIZE_T cbSeedMaterial )
530//
531// This function creates a new SP 800-90 AES_CTR_DRBG instance.
532// Our code is structured differently from what SP 800-90 assumes.
533// At this point in time, the entropy has already been collected and it is
534// passed to this function. Thus, there is no check for failing to get
535// the entropy. If entropy collection fails, the caller of this function
536// will generate an error. (Actually, we only choose to instantiate a FIPS-compliant
537// SP 800-90 DRBG when we do have good entropy available, so there is never an
538// error that we don't have the required entropy.)
539//
540{
541 if( cbSeedMaterial < SYMCRYPT_RNG_AES_MIN_INSTANTIATE_SIZE )
542 {
543 return SYMCRYPT_EXTERNAL_FAILURE;
544 }
545
546 //
547 // Instantiation of a new state is identical to setting the state to zero
548 // and then performing a reseed with the same seed material.
549 //
550 // See SP 800-90 10.2.1.3.2 & 10.2.1.4.2
551 //
552 SymCryptWipeKnownSize( pRngState, sizeof( *pRngState ) );
553
554 SYMCRYPT_SET_MAGIC( pRngState );
555
556 return SymCryptRngAesReseed( pRngState, pcbSeedMaterial, cbSeedMaterial );
557}
558
560SYMCRYPT_NOINLINE
561VOID
564 PBYTE pbRandom,
565 SIZE_T cbRandom )
566//
567// For FIPS compliance purposes, this is NOT the generate function of the DRBG.
568// The generate function is SymCryptRngAesGenerateSmall.
569// This is a wrapper around the generate function that supports larger output
570// sizes, and handles any errors by making them fatal.
571//
572{
573 SYMCRYPT_ERROR scError;
574
575 SYMCRYPT_CHECK_MAGIC( pRngState );
576
577 while( cbRandom > SYMCRYPT_RNG_AES_MAX_REQUEST_SIZE )
578 {
579
580 scError = SymCryptRngAesGenerateSmall( pRngState, pbRandom, SYMCRYPT_RNG_AES_MAX_REQUEST_SIZE, NULL, 0 );
581 if( scError != SYMCRYPT_NO_ERROR )
582 {
583 SymCryptFatal( 'acdx' );
584 }
587 }
588
589 if( cbRandom > 0 )
590 {
591 scError = SymCryptRngAesGenerateSmall( pRngState, pbRandom, cbRandom, NULL, 0 );
592 if( scError != SYMCRYPT_NO_ERROR )
593 {
594 SymCryptFatal( 'acdx' );
595 }
596 }
597}
598
600SYMCRYPT_NOINLINE
604 PCBYTE pcbSeedMaterial,
605 SIZE_T cbSeedMaterial )
606{
608
609 SYMCRYPT_CHECK_MAGIC( pRngState );
610
611 //
612 // For a reseed, the minimum # bits is the security strength, or the key size.
613 // We retain the same maximum as that protects our own internal buffers.
614 //
615 if (cbSeedMaterial < SYMCRYPT_RNG_AES_MIN_RESEED_SIZE ||
616 cbSeedMaterial > SYMCRYPT_RNG_AES_MAX_SEED_SIZE )
617 {
618 return SYMCRYPT_EXTERNAL_FAILURE; // bug is external to SymCrypt (i.e. the caller)
619 }
620
621 //
622 // We do not perform the FIPS-required reseed self-test here.
623 // Rather, we have a function that external callers can use to implement that test before
624 // calling this reseed function.
625 // This allows callers that are not interested in FIPS certification to skip the test.
626 //
627
628 SymCryptRngAesDf( pcbSeedMaterial, cbSeedMaterial, abSeed );
629
630 SymCryptRngAesUpdate( pRngState, abSeed, NULL );
631
632 pRngState->requestCounter = 1;
633
634 SymCryptWipeKnownSize( abSeed, sizeof( abSeed ) );
635
636 return SYMCRYPT_NO_ERROR;
637}
638
640SYMCRYPT_NOINLINE
641VOID
644{
645 SymCryptWipeKnownSize( pRngState, sizeof( *pRngState ) );
646}
647
649// Self test
650
651//
652// The test vector is from the NIST DRBG Test Vectors file
653//
655{
656 // Entropy input
657
658 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
659 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
660 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
661 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
662 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
663 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
664
665 // Nonce
666 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
667 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
668
669};
670
671
672static const BYTE g_abReseedEntropy[] =
673{
674
675 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
676 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
677 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
678 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
679 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
680 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF
681};
682
683static const BYTE g_abOutput1[ 32 ] =
684{
685 0xD1,0xE9,0xC7,0x37,0xB6,0xEB,0xAE,0xD7,
686 0x65,0xA0,0xD4,0xE4,0xC6,0xEA,0xEB,0xE2,
687 0x67,0xF5,0xE9,0x19,0x36,0x80,0xFD,0xFF,
688 0xA6,0x2F,0x48,0x65,0xB3,0xF0,0x09,0xEC,
689};
690
692{
693 //key
694 0x8C,0x10,0xB6,0x58,0x44,0x0C,0x71,0x35,
695 0x64,0x9D,0xC7,0x7B,0xE6,0xE5,0x75,0xCE,
696 0x87,0xE7,0x48,0x90,0x83,0x9B,0x89,0x59,
697 0x14,0x17,0xAF,0xAD,0x14,0xB2,0x26,0xD5,
698 //V
699 0xB4,0x03,0x6B,0x1D,0xBA,0x04,0x3A,0xE6,
700 0x55,0xAC,0xD6,0x46,0xEC,0x5A,0xD3,0x5C,
701};
702
704{
705 //key
706 0x17,0x98,0xC0,0xDF,0x09,0x69,0x6A,0x46,
707 0x19,0x46,0xFE,0x6D,0x68,0x7D,0x8C,0xC8,
708 0x3F,0xEE,0xF1,0x22,0xF3,0xBB,0xC5,0xF2,
709 0x9D,0xAC,0x85,0x10,0xF3,0x4A,0xF0,0x15,
710 //V
711 0x0B,0xF3,0x34,0x4D,0xF5,0x29,0x27,0x6B,
712 0x0D,0x5B,0xBC,0x83,0x9B,0xD3,0x65,0x6A,
713};
714
716{
717 //key
718 0x28, 0xbc, 0x65, 0xa8, 0x6a, 0xb7, 0xc7, 0x4e, 0xdf, 0x4b, 0xb8, 0x72, 0x87, 0xd3, 0x4f, 0xbb,
719 0x8d, 0x6f, 0x16, 0xd7, 0xb9, 0x1b, 0x6a, 0xbb, 0xee, 0x7b, 0x88, 0x86, 0x5b, 0x0f, 0xc7, 0xbd,
720 //V
721 0xb7, 0x46, 0x11, 0xf3, 0x92, 0x95, 0xa6, 0x25, 0x7c, 0x39, 0x98, 0x4c, 0x9c, 0x09, 0x9b, 0x30,
722};
723
724
725VOID
728//
729// Test the Instantiate function on the passed instance. Leave it
730// in the initialized state for the test vector.
731//
732{
733 SYMCRYPT_ERROR scError;
734 //
735 // First test the error handling
736 //
737#pragma prefast( suppress: 26060 6309 28020, "Deliberate test of invalid parameter");
738 scError = SymCryptRngAesInstantiate( pRngState, NULL, 327 );
739 if( scError == SYMCRYPT_NO_ERROR )
740 {
741 SymCryptFatal( 'aci1' );
742 }
743
744
745 scError = SymCryptRngAesInstantiate( pRngState,
748 );
749
751
752 if ( scError != SYMCRYPT_NO_ERROR ||
753 0 != memcmp( pRngState->keyAndV,
756 {
757 SymCryptFatal( 'aci2' );
758 }
759}
760
761VOID
764{
765 SYMCRYPT_ERROR scError;
766
767 //
768 // Set the state to a known state
769 //
770 SYMCRYPT_SET_MAGIC( pRngState );
772 pRngState->requestCounter = 7;
773 pRngState->fips140_2Check = FALSE;
774
775 //
776 // Test error handling
777 //
778#pragma prefast(suppress: 26060 6309 28020, "Deliberate test of invalid parameter");
779 scError = SymCryptRngAesReseed( pRngState, NULL, 597 );
780 if( scError == SYMCRYPT_NO_ERROR )
781 {
782 SymCryptFatal( 'acr1' );
783 }
784
785 scError = SymCryptRngAesReseed( pRngState, g_abReseedEntropy, sizeof( g_abReseedEntropy ) );
786
788
789 if ( scError != SYMCRYPT_NO_ERROR ||
790 0 != memcmp( pRngState->keyAndV,
793 {
794 SymCryptFatal( 'acr2' );
795 }
796}
797
798VOID
801{
803 SYMCRYPT_ERROR scError;
804
805 //
806 // Set the state to a known value
807 //
808 SYMCRYPT_SET_MAGIC( pRngState );
810 pRngState->requestCounter = 7;
811 pRngState->fips140_2Check = FALSE;
812
813 //
814 // Test the error handling
815 // - Too many requests since last reseed
816 // - Too many bytes in request
817 //
818
819 pRngState->requestCounter = SYMCRYPT_RNG_AES_MAX_REQUESTS_PER_RESEED + 1;
820 scError = SymCryptRngAesGenerateSmall( pRngState, abOutput, sizeof( g_abOutput1 ), NULL, 0 );
821
822 if( scError == SYMCRYPT_NO_ERROR )
823 {
824 SymCryptFatal( 'acg1' );
825 }
826 pRngState->requestCounter = 7;
827
828#pragma prefast( suppress: 6202 26000, "buffer size of cbOutput is purposely incorrect");
830
831 if( scError == SYMCRYPT_NO_ERROR )
832 {
833 SymCryptFatal( 'acg2' );
834 }
835
836 //
837 // Now test for correct output data.
838 //
839 scError = SymCryptRngAesGenerateSmall( pRngState, abOutput, sizeof( g_abOutput1 ), NULL, 0 );
840
842
843 if( scError != SYMCRYPT_NO_ERROR || memcmp( abOutput, g_abOutput1, sizeof( g_abOutput1 ) ) != 0 )
844 {
845 SymCryptFatal( 'acg3' );
846 }
847
848 //
849 // And test for the correct resulting state
850 //
852
853 if ( 0 != memcmp( pRngState->keyAndV,
856 {
857 SymCryptFatal( 'acg4' );
858 }
859}
860
861
862VOID
865{
866 const SIZE_T * p = (const SIZE_T *) pRngState;
867 SIZE_T t;
868 SIZE_T i;
869
870 C_ASSERT( sizeof( *pRngState ) % sizeof( SIZE_T ) == 0 ); // This is true on all our platforms.
871
872 SYMCRYPT_CHECK_MAGIC( pRngState );
873
874 SymCryptRngAesUninstantiate( pRngState );
875
876 t = 0;
877 for( i=0; i< sizeof( *pRngState ) / sizeof( SIZE_T ); i ++ )
878 {
879 t |= p[i];
880 }
881
882 if( t != 0 )
883 {
884 SymCryptFatal( 'acdu' );
885 }
886}
887
888VOID
891{
893
895
896 //
897 // Uninstantiate has to be tested whenever another function is tested.
898 //
900}
901
902VOID
905{
907
909
910 //
911 // Uninstantiate has to be tested whenever another function is tested.
912 //
914}
915
916VOID
919{
921
923
924 //
925 // Uninstantiate has to be tested whenever another function is tested.
926 //
928}
929
930
932// AES-CTR_DRGB with FIPS 140-2 continuous self-test
933//
934
935
940 PCBYTE pcbSeedMaterial,
941 SIZE_T cbSeedMaterial )
942{
943 SYMCRYPT_ERROR scError;
944
945 scError = SymCryptRngAesInstantiate( &pRngState->rng, pcbSeedMaterial, cbSeedMaterial );
946
947 if( scError == SYMCRYPT_NO_ERROR )
948 {
949 //
950 // Generate the first block of output and store it so that we can compare future blocks.
951 //
952 SymCryptRngAesGenerate( &pRngState->rng, pRngState->rng.previousBlock, sizeof( pRngState->rng.previousBlock ) );
953 pRngState->rng.fips140_2Check = TRUE;
954 }
955
956 return scError;
957}
958
960VOID
963 PBYTE pbRandom,
964 SIZE_T cbRandom )
965{
966 SymCryptRngAesGenerate( &pRngState->rng, pbRandom, cbRandom );
967}
968
973 PCBYTE pcbSeedMaterial,
974 SIZE_T cbSeedMaterial )
975{
976 return SymCryptRngAesReseed( &pRngState->rng, pcbSeedMaterial, cbSeedMaterial );
977}
978
979
981VOID
984{
985 SymCryptRngAesUninstantiate( &pRngState->rng );
986}
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
_Use_decl_annotations_ SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptRngAesUninstantiate(PSYMCRYPT_RNG_AES_STATE pRngState)
Definition: aesCtrDrbg.c:643
#define SYMCRYPT_RNG_AES_MAX_REQUESTS_PER_RESEED
Definition: aesCtrDrbg.c:16
#define SYMCRYPT_RNG_AES_KEY_SIZE
Definition: aesCtrDrbg.c:13
VOID SYMCRYPT_CALL SymCryptRngAesInstantiateSelftest(void)
Definition: aesCtrDrbg.c:890
_Use_decl_annotations_ SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRngAesFips140_2Reseed(PSYMCRYPT_RNG_AES_FIPS140_2_STATE pRngState, PCBYTE pcbSeedMaterial, SIZE_T cbSeedMaterial)
Definition: aesCtrDrbg.c:972
static const BYTE g_expectedStateAfterGenerate[SYMCRYPT_RNG_AES_KEY_AND_V_SIZE]
Definition: aesCtrDrbg.c:715
_Use_decl_annotations_ VOID SYMCRYPT_CALL SymCryptRngAesFips140_2Uninstantiate(PSYMCRYPT_RNG_AES_FIPS140_2_STATE pRngState)
Definition: aesCtrDrbg.c:983
static const BYTE g_abReseedEntropy[]
Definition: aesCtrDrbg.c:672
_Use_decl_annotations_ SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRngAesFips140_2Instantiate(PSYMCRYPT_RNG_AES_FIPS140_2_STATE pRngState, PCBYTE pcbSeedMaterial, SIZE_T cbSeedMaterial)
Definition: aesCtrDrbg.c:939
_Use_decl_annotations_ SYMCRYPT_NOINLINE SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRngAesReseed(PSYMCRYPT_RNG_AES_STATE pRngState, PCBYTE pcbSeedMaterial, SIZE_T cbSeedMaterial)
Definition: aesCtrDrbg.c:603
VOID SYMCRYPT_CALL SymCryptRngAesTestGenerate(PSYMCRYPT_RNG_AES_STATE pRngState)
Definition: aesCtrDrbg.c:800
#define SYMCRYPT_RNG_AES_MAX_REQUEST_SIZE
Definition: aesCtrDrbg.c:15
static const BYTE g_expectedStateAfterReseed[SYMCRYPT_RNG_AES_KEY_AND_V_SIZE]
Definition: aesCtrDrbg.c:703
static const BYTE g_expectedStateAfterInstantiate[SYMCRYPT_RNG_AES_KEY_AND_V_SIZE]
Definition: aesCtrDrbg.c:691
VOID SYMCRYPT_CALL SymCryptRngAesUpdate(_Inout_ PSYMCRYPT_RNG_AES_STATE pState, _In_reads_opt_(SYMCRYPT_RNG_AES_INTERNAL_SEED_SIZE) PCBYTE pbProvidedData, _In_opt_ PSYMCRYPT_AES_EXPANDED_KEY pAesKey)
Definition: aesCtrDrbg.c:380
VOID SYMCRYPT_CALL SymCryptRngAesReseedSelftest(void)
Definition: aesCtrDrbg.c:904
static const BYTE g_abInstantiateEntropyInputPlusNonce[]
Definition: aesCtrDrbg.c:654
VOID SYMCRYPT_CALL SymCryptRngAesGenerateBlocks(_In_ PSYMCRYPT_AES_EXPANDED_KEY pAesKey, _Inout_updates_(SYMCRYPT_AES_BLOCK_SIZE) PBYTE pV, _Out_writes_(cbRandom) PBYTE pbRandom, _In_ SIZE_T cbRandom)
Definition: aesCtrDrbg.c:163
_Use_decl_annotations_ VOID SYMCRYPT_CALL SymCryptRngAesFips140_2Generate(PSYMCRYPT_RNG_AES_FIPS140_2_STATE pRngState, PBYTE pbRandom, SIZE_T cbRandom)
Definition: aesCtrDrbg.c:962
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRngAesGenerateSmall(_Inout_ PSYMCRYPT_RNG_AES_STATE pRngState, _Out_writes_(cbRandom) PBYTE pbRandom, SIZE_T cbRandom, _In_reads_opt_(cbAdditionalInput) PCBYTE pbAdditionalInput, SIZE_T cbAdditionalInput)
Definition: aesCtrDrbg.c:436
_Use_decl_annotations_ SYMCRYPT_NOINLINE SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptRngAesInstantiate(PSYMCRYPT_RNG_AES_STATE pRngState, PCBYTE pcbSeedMaterial, SIZE_T cbSeedMaterial)
Definition: aesCtrDrbg.c:527
VOID SYMCRYPT_CALL SymCryptRngAesBcc(_In_ PSYMCRYPT_AES_EXPANDED_KEY pKey, _In_reads_(cbData) PCBYTE pcbData, _In_ SIZE_T cbData, _Out_writes_(SYMCRYPT_AES_BLOCK_SIZE) PBYTE pbResult)
Definition: aesCtrDrbg.c:20
VOID SYMCRYPT_CALL SymCryptRngAesCheckBlocksNotIdentical(_Inout_updates_(SYMCRYPT_AES_BLOCK_SIZE) PBYTE pbPreviousBlock, _In_reads_(cbData) PCBYTE pcbData, SIZE_T cbData)
Definition: aesCtrDrbg.c:341
static const BYTE g_abOutput1[32]
Definition: aesCtrDrbg.c:683
_Use_decl_annotations_ SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptRngAesGenerate(PSYMCRYPT_RNG_AES_STATE pRngState, PBYTE pbRandom, SIZE_T cbRandom)
Definition: aesCtrDrbg.c:563
#define SYMCRYPT_RNG_AES_KEY_AND_V_SIZE
Definition: aesCtrDrbg.c:14
#define MAX_CTRMSB64_BLOCKS
VOID SYMCRYPT_CALL SymCryptRngAesGenerateSelftest(void)
Definition: aesCtrDrbg.c:918
VOID SYMCRYPT_CALL SymCryptRngAesTestInstantiate(PSYMCRYPT_RNG_AES_STATE pRngState)
Definition: aesCtrDrbg.c:727
FORCEINLINE int SymCryptRngAesAreBlocksIdentical(_In_reads_(SYMCRYPT_AES_BLOCK_SIZE) PCBYTE pSrc1, _In_reads_(SYMCRYPT_AES_BLOCK_SIZE) PCBYTE pSrc2)
Definition: aesCtrDrbg.c:299
VOID SYMCRYPT_CALL SymCryptRngAesDf(_In_reads_(cbData) PCBYTE pcbData, _In_ SIZE_T cbData, _Out_writes_(SYMCRYPT_RNG_AES_INTERNAL_SEED_SIZE) PBYTE pbSeed)
Definition: aesCtrDrbg.c:39
VOID SYMCRYPT_CALL SymCryptRngAesTestUninstantiate(PSYMCRYPT_RNG_AES_STATE pRngState)
Definition: aesCtrDrbg.c:864
VOID SYMCRYPT_CALL SymCryptRngAesTestReseed(PSYMCRYPT_RNG_AES_STATE pRngState)
Definition: aesCtrDrbg.c:763
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
const GLdouble * v
Definition: gl.h:2040
GLdouble GLdouble t
Definition: gl.h:2047
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLenum abOutput
Definition: glext.h:9032
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 C_ASSERT(e)
Definition: intsafe.h:73
int identical(Knot x, Knot y)
Definition: knotvector.h:58
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Inout_updates_(s)
Definition: no_sal2.h:182
#define _Inout_
Definition: no_sal2.h:162
#define _Use_decl_annotations_
Definition: no_sal2.h:92
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _In_reads_opt_(s)
Definition: no_sal2.h:222
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
BYTE * PBYTE
Definition: pedump.c:66
_In_ _Out_writes_opt_ pcchValueName _Inout_opt_ LPDWORD _Out_opt_ _Out_writes_bytes_to_opt_ pcbData _Inout_opt_ LPDWORD pcbData
Definition: shlwapi.h:757
static calc_node_t temp
Definition: rpn_ieee.c:38
VOID SYMCRYPT_CALL SymCryptInjectError(PBYTE pbData, SIZE_T cbData)
BYTE abSeed[SYMCRYPT_LMS_MAX_N]
Definition: sc_lib.h:4735
static const BYTE pbResult[]
#define SYMCRYPT_ASSERT(_x)
Definition: symcrypt.h:10807
FORCEINLINE VOID SYMCRYPT_CALL SymCryptWipeKnownSize(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
VOID SYMCRYPT_CALL SymCryptWipe(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
Definition: libmain.c:137
_Analysis_noreturn_ VOID SYMCRYPT_CALL SymCryptFatal(UINT32 fatalCode)
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptAesExpandKeyEncryptOnly(_Out_ PSYMCRYPT_AES_EXPANDED_KEY pExpandedKey, _In_reads_(cbKey) PCBYTE pbKey, SIZE_T cbKey)
Definition: aes-key.c:230
#define SYMCRYPT_LOAD_MSBFIRST64(p)
Definition: symcrypt.h:304
VOID SYMCRYPT_CALL SymCryptAesEncrypt(_In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey, _In_reads_(SYMCRYPT_AES_BLOCK_SIZE) PCBYTE pbSrc, _Out_writes_(SYMCRYPT_AES_BLOCK_SIZE) PBYTE pbDst)
Definition: aes-default.c:95
VOID SYMCRYPT_CALL SymCryptXorBytes(_In_reads_(cbBytes) PCBYTE pbSrc1, _In_reads_(cbBytes) PCBYTE pbSrc2, _Out_writes_(cbBytes) PBYTE pbResult, SIZE_T cbBytes)
Definition: libmain.c:236
#define SYMCRYPT_RNG_AES_MIN_RESEED_SIZE
Definition: symcrypt.h:6181
#define SYMCRYPT_RNG_AES_MIN_INSTANTIATE_SIZE
Definition: symcrypt.h:6180
#define SYMCRYPT_RNG_AES_MAX_SEED_SIZE
Definition: symcrypt.h:6182
VOID SYMCRYPT_CALL SymCryptAesCtrMsb64(_In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey, _Inout_updates_(SYMCRYPT_AES_BLOCK_SIZE) PBYTE pbChainingValue, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData)
Definition: aes-default.c:404
#define SYMCRYPT_AES_BLOCK_SIZE
Definition: symcrypt.h:4255
#define SYMCRYPT_STORE_MSBFIRST32(p, v)
Definition: symcrypt.h:311
#define SYMCRYPT_STORE_MSBFIRST64(p, v)
Definition: symcrypt.h:312
VOID SYMCRYPT_CALL SymCryptAesCbcMac(_In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey, _Inout_updates_(SYMCRYPT_AES_BLOCK_SIZE) PBYTE pbChainingValue, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData)
Definition: aes-default.c:317
SYMCRYPT_ERROR
Definition: symcrypt.h:227
#define SYMCRYPT_ALIGN
#define SYMCRYPT_CALL
#define SYMCRYPT_MIN(_a, _b)
PCBYTE PBYTE SIZE_T cbData
#define SYMCRYPT_SET_MAGIC(p)
SYMCRYPT_MAGIC_FIELD * PSYMCRYPT_RNG_AES_STATE
SYMCRYPT_MAGIC_FIELD SYMCRYPT_RNG_AES_STATE
SYMCRYPT_MAGIC_FIELD SYMCRYPT_AES_EXPANDED_KEY
PCSYMCRYPT_HMAC_MD5_EXPANDED_KEY pKey
* PSYMCRYPT_RNG_AES_FIPS140_2_STATE
PSYMCRYPT_COMMON_HASH_STATE pState
const BYTE * PCBYTE
SYMCRYPT_MAGIC_FIELD * PSYMCRYPT_AES_EXPANDED_KEY
#define SYMCRYPT_CHECK_MAGIC(p)
PBYTE pbSeed
#define SYMCRYPT_RNG_AES_INTERNAL_SEED_SIZE
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t UINT32
Definition: typedefs.h:59
#define FORCEINLINE
Definition: wdftypes.h:67
unsigned char BYTE
Definition: xxhash.c:193