1111#include "precomp.h"
1212
1313#define SYMCRYPT_RNG_AES_KEY_SIZE (32)
14- #define SYMCRYPT_RNG_AES_INTERNAL_SEED_SIZE (32 + 16)
1514#define SYMCRYPT_RNG_AES_KEY_AND_V_SIZE (32 + 16)
1615#define SYMCRYPT_RNG_AES_MAX_REQUEST_SIZE (1<<16)
1716#define SYMCRYPT_RNG_AES_MAX_REQUESTS_PER_RESEED ((UINT64)1<<48)
380379SYMCRYPT_CALL
381380SymCryptRngAesUpdate (
382381 _Inout_ PSYMCRYPT_RNG_AES_STATE pState ,
383- _In_reads_opt_ ( SYMCRYPT_RNG_AES_INTERNAL_SEED_SIZE ) PBYTE pbProvidedData ,
382+ _In_reads_opt_ ( SYMCRYPT_RNG_AES_INTERNAL_SEED_SIZE ) PCBYTE pbProvidedData ,
384383 _In_opt_ PSYMCRYPT_AES_EXPANDED_KEY pAesKey )
385384//
386385// Implement the CTR_DRBG Update function.
@@ -435,26 +434,19 @@ SymCryptRngAesUpdate(
435434SYMCRYPT_ERROR
436435SYMCRYPT_CALL
437436SymCryptRngAesGenerateSmall (
438- _Inout_ PSYMCRYPT_RNG_AES_STATE pRngState ,
439- _Out_writes_ (cbRandom ) PBYTE pbRandom ,
440- SIZE_T cbRandom )
437+ _Inout_ PSYMCRYPT_RNG_AES_STATE pRngState ,
438+ _Out_writes_ ( cbRandom ) PBYTE pbRandom ,
439+ SIZE_T cbRandom ,
440+ _In_reads_opt_ ( cbAdditionalInput ) PCBYTE pbAdditionalInput ,
441+ SIZE_T cbAdditionalInput )
441442//
442- // The core generation function that produces upto 64 kB at a time
443- // This function returns an error code so that we can test the
444- // error handling of having done more than 2^48 requests between reseeds,
445- // as required by SP 800-90.
446- // This is also the Generate function of our SP800-90 compliant implementation.
447- // If fips140-2Check is true, this function runs the continuous self test required
448- // by FIPS 140-2 (but not by FIPS 140-3 as far as we know).
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
449445//
450446{
451447 SYMCRYPT_AES_EXPANDED_KEY aesKey ;
452448 SYMCRYPT_ALIGN BYTE buf [SYMCRYPT_AES_BLOCK_SIZE ];
453-
454- if ( cbRandom == 0 )
455- {
456- return SYMCRYPT_NO_ERROR ;
457- }
449+ SYMCRYPT_ALIGN BYTE abSeed [SYMCRYPT_RNG_AES_INTERNAL_SEED_SIZE ];
458450
459451 //
460452 // SP 800-90 9.3.1 requires a check on the length of the request.
@@ -466,14 +458,24 @@ SymCryptRngAesGenerateSmall(
466458 //
467459 // The requestCounter test is useless as it can never happen. (It would require
468460 // 2^48 calls to this function to trigger this error.)
469- // Unfortunatly , SP800-90 section 11 requires a test of this error, so we have
470- // to impelement the error.
461+ // Unfortunately , SP800-90 section 11 requires a test of this error, so we have
462+ // to implement the error.
471463 //
472464 if ( pRngState -> requestCounter > SYMCRYPT_RNG_AES_MAX_REQUESTS_PER_RESEED )
473465 {
474466 return SYMCRYPT_FIPS_FAILURE ;
475467 }
476468
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+
477479 SymCryptAesExpandKeyEncryptOnly ( & aesKey , pRngState -> keyAndV , SYMCRYPT_RNG_AES_KEY_SIZE );
478480
479481 if ( cbRandom >= SYMCRYPT_AES_BLOCK_SIZE )
@@ -507,11 +509,12 @@ SymCryptRngAesGenerateSmall(
507509 SymCryptWipeKnownSize ( buf , sizeof ( buf ) );
508510 }
509511
510- SymCryptRngAesUpdate ( pRngState , NULL , & aesKey );
512+ SymCryptRngAesUpdate ( pRngState , pbAdditionalInput , & aesKey );
511513
512514 ++ pRngState -> requestCounter ;
513515
514516 SymCryptWipeKnownSize ( & aesKey , sizeof ( aesKey ) );
517+ SymCryptWipeKnownSize ( abSeed , sizeof ( abSeed ) );
515518
516519 return SYMCRYPT_NO_ERROR ;
517520}
@@ -574,7 +577,7 @@ SymCryptRngAesGenerate( PSYMCRYPT_RNG_AES_STATE pRngState,
574577 while ( cbRandom > SYMCRYPT_RNG_AES_MAX_REQUEST_SIZE )
575578 {
576579
577- scError = SymCryptRngAesGenerateSmall ( pRngState , pbRandom , SYMCRYPT_RNG_AES_MAX_REQUEST_SIZE );
580+ scError = SymCryptRngAesGenerateSmall ( pRngState , pbRandom , SYMCRYPT_RNG_AES_MAX_REQUEST_SIZE , NULL , 0 );
578581 if ( scError != SYMCRYPT_NO_ERROR )
579582 {
580583 SymCryptFatal ( 'acdx' );
@@ -583,10 +586,13 @@ SymCryptRngAesGenerate( PSYMCRYPT_RNG_AES_STATE pRngState,
583586 cbRandom -= SYMCRYPT_RNG_AES_MAX_REQUEST_SIZE ;
584587 }
585588
586- scError = SymCryptRngAesGenerateSmall ( pRngState , pbRandom , cbRandom );
587- if ( scError != SYMCRYPT_NO_ERROR )
589+ if ( cbRandom > 0 )
588590 {
589- SymCryptFatal ( 'acdx' );
591+ scError = SymCryptRngAesGenerateSmall ( pRngState , pbRandom , cbRandom , NULL , 0 );
592+ if ( scError != SYMCRYPT_NO_ERROR )
593+ {
594+ SymCryptFatal ( 'acdx' );
595+ }
590596 }
591597}
592598
@@ -811,7 +817,7 @@ SymCryptRngAesTestGenerate( PSYMCRYPT_RNG_AES_STATE pRngState )
811817 //
812818
813819 pRngState -> requestCounter = SYMCRYPT_RNG_AES_MAX_REQUESTS_PER_RESEED + 1 ;
814- scError = SymCryptRngAesGenerateSmall ( pRngState , abOutput , sizeof ( g_abOutput1 ) );
820+ scError = SymCryptRngAesGenerateSmall ( pRngState , abOutput , sizeof ( g_abOutput1 ), NULL , 0 );
815821
816822 if ( scError == SYMCRYPT_NO_ERROR )
817823 {
@@ -820,7 +826,7 @@ SymCryptRngAesTestGenerate( PSYMCRYPT_RNG_AES_STATE pRngState )
820826 pRngState -> requestCounter = 7 ;
821827
822828#pragma prefast( suppress: 6202 26000, "buffer size of cbOutput is purposely incorrect");
823- scError = SymCryptRngAesGenerateSmall ( pRngState , abOutput , SYMCRYPT_RNG_AES_MAX_REQUEST_SIZE + 1 );
829+ scError = SymCryptRngAesGenerateSmall ( pRngState , abOutput , SYMCRYPT_RNG_AES_MAX_REQUEST_SIZE + 1 , NULL , 0 );
824830
825831 if ( scError == SYMCRYPT_NO_ERROR )
826832 {
@@ -830,7 +836,7 @@ SymCryptRngAesTestGenerate( PSYMCRYPT_RNG_AES_STATE pRngState )
830836 //
831837 // Now test for correct output data.
832838 //
833- scError = SymCryptRngAesGenerateSmall ( pRngState , abOutput , sizeof ( g_abOutput1 ) );
839+ scError = SymCryptRngAesGenerateSmall ( pRngState , abOutput , sizeof ( g_abOutput1 ), NULL , 0 );
834840
835841 SymCryptInjectError ( abOutput , sizeof ( abOutput ) );
836842
0 commit comments