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

Go to the source code of this file.

Macros

#define GCM_MIN_NONCE_SIZE   (1)
 
#define GCM_MIN_TAG_SIZE   (12)
 
#define GCM_MAX_TAG_SIZE   (16)
 

Functions

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptGcmValidateParameters (_In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher, _In_ SIZE_T cbNonce, _In_ UINT64 cbAssociatedData, _In_ UINT64 cbData, _In_ SIZE_T cbTag)
 
VOID SYMCRYPT_CALL SymCryptGcmAddMacData (_Inout_ PSYMCRYPT_GCM_STATE pState, _In_reads_opt_(cbData) PCBYTE pbData, SIZE_T cbData)
 
VOID SYMCRYPT_CALL SymCryptGcmPadMacData (_Inout_ PSYMCRYPT_GCM_STATE pState)
 
VOID SYMCRYPT_CALL SymCryptGcmEncryptDecryptPart (_Inout_ PSYMCRYPT_GCM_STATE pState, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData)
 
FORCEINLINE VOID SYMCRYPT_CALL SymCryptGcmResetCounterBlock (_Inout_ PSYMCRYPT_GCM_STATE pState)
 
VOID SYMCRYPT_CALL SymCryptGcmComputeTag (_Inout_ PSYMCRYPT_GCM_STATE pState, _Out_writes_(SYMCRYPT_GCM_BLOCK_SIZE) PBYTE pbTag)
 
SYMCRYPT_NOINLINE SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptGcmExpandKey (_Out_ PSYMCRYPT_GCM_EXPANDED_KEY pExpandedKey, _In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher, _In_reads_(cbKey) PCBYTE pbKey, SIZE_T cbKey)
 
VOID SYMCRYPT_CALL SymCryptGcmKeyCopy (_In_ PCSYMCRYPT_GCM_EXPANDED_KEY pSrc, _Out_ PSYMCRYPT_GCM_EXPANDED_KEY pDst)
 
VOID SYMCRYPT_CALL SymCryptGcmSetNonce (_Out_ PSYMCRYPT_GCM_STATE pState, _In_reads_(cbNonce) PCBYTE pbNonce, SIZE_T cbNonce)
 
SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmInit (_Out_ PSYMCRYPT_GCM_STATE pState, _In_ PCSYMCRYPT_GCM_EXPANDED_KEY pExpandedKey, _In_reads_(cbNonce) PCBYTE pbNonce, SIZE_T cbNonce)
 
VOID SYMCRYPT_CALL SymCryptGcmStateCopy (_In_ PCSYMCRYPT_GCM_STATE pSrc, _In_opt_ PCSYMCRYPT_GCM_EXPANDED_KEY pExpandedKeyCopy, _Out_ PSYMCRYPT_GCM_STATE pDst)
 
SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmAuthPart (_Inout_ PSYMCRYPT_GCM_STATE pState, _In_reads_opt_(cbData) PCBYTE pbAuthData, SIZE_T cbData)
 
SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmEncryptPart (_Inout_ PSYMCRYPT_GCM_STATE pState, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData)
 
SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmEncryptPartTwoPass (_Inout_ PSYMCRYPT_GCM_STATE pState, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData)
 
SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmDecryptPart (_Inout_ PSYMCRYPT_GCM_STATE pState, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData)
 
SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmDecryptPartTwoPass (_Inout_ PSYMCRYPT_GCM_STATE pState, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData)
 
SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmEncryptFinal (_Inout_ PSYMCRYPT_GCM_STATE pState, _Out_writes_(cbTag) PBYTE pbTag, SIZE_T cbTag)
 
SYMCRYPT_NOINLINE SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptGcmDecryptFinal (_Inout_ PSYMCRYPT_GCM_STATE pState, _In_reads_(cbTag) PCBYTE pbTag, SIZE_T cbTag)
 
SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmEncrypt (_In_ PCSYMCRYPT_GCM_EXPANDED_KEY pExpandedKey, _In_reads_(cbNonce) PCBYTE pbNonce, SIZE_T cbNonce, _In_reads_opt_(cbAuthData) PCBYTE pbAuthData, SIZE_T cbAuthData, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData, _Out_writes_(cbTag) PBYTE pbTag, SIZE_T cbTag)
 
SYMCRYPT_NOINLINE SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptGcmDecrypt (_In_ PCSYMCRYPT_GCM_EXPANDED_KEY pExpandedKey, _In_reads_(cbNonce) PCBYTE pbNonce, SIZE_T cbNonce, _In_reads_opt_(cbAuthData) PCBYTE pbAuthData, SIZE_T cbAuthData, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData, _In_reads_(cbTag) PCBYTE pbTag, SIZE_T cbTag)
 
VOID SYMCRYPT_CALL SymCryptGcmSelftest (void)
 

Variables

static const BYTE SymCryptGcmSelftestResult [3+SYMCRYPT_AES_BLOCK_SIZE]
 

Macro Definition Documentation

◆ GCM_MAX_TAG_SIZE

#define GCM_MAX_TAG_SIZE   (16)

Definition at line 11 of file gcm.c.

◆ GCM_MIN_NONCE_SIZE

#define GCM_MIN_NONCE_SIZE   (1)

Definition at line 9 of file gcm.c.

◆ GCM_MIN_TAG_SIZE

#define GCM_MIN_TAG_SIZE   (12)

Definition at line 10 of file gcm.c.

Function Documentation

◆ SymCryptGcmAddMacData()

VOID SYMCRYPT_CALL SymCryptGcmAddMacData ( _Inout_ PSYMCRYPT_GCM_STATE  pState,
_In_reads_opt_(cbData) PCBYTE  pbData,
SIZE_T  cbData 
)

Definition at line 65 of file gcm.c.

69{
70 SIZE_T bytesToProcess;
71 if( pState->bytesInMacBlock > 0 )
72 {
73 bytesToProcess = SYMCRYPT_MIN( cbData, SYMCRYPT_GCM_BLOCK_SIZE - pState->bytesInMacBlock );
74 memcpy( &pState->macBlock[pState->bytesInMacBlock], pbData, bytesToProcess );
75 pbData += bytesToProcess;
76 cbData -= bytesToProcess;
77 pState->bytesInMacBlock += bytesToProcess;
78
79 if( pState->bytesInMacBlock == SYMCRYPT_GCM_BLOCK_SIZE )
80 {
81 SymCryptGHashAppendData( &pState->pKey->ghashKey,
82 &pState->ghashState,
83 &pState->macBlock[0],
85 pState->bytesInMacBlock = 0;
86 }
87 }
88
90 {
91 bytesToProcess = cbData & SYMCRYPT_GCM_BLOCK_ROUND_MASK;
92
93 SymCryptGHashAppendData( &pState->pKey->ghashKey, &pState->ghashState, pbData, bytesToProcess );
94
95 pbData += bytesToProcess;
96 cbData -= bytesToProcess;
97 }
98
99 if( cbData > 0 )
100 {
101 memcpy( &pState->macBlock[0], pbData, cbData );
102 pState->bytesInMacBlock = cbData;
103 }
104}
VOID SYMCRYPT_CALL SymCryptGHashAppendData(_In_ PCSYMCRYPT_GHASH_EXPANDED_KEY expandedKey, _Inout_ PSYMCRYPT_GF128_ELEMENT pState, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData)
Definition: ghash.c:884
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define SYMCRYPT_GCM_BLOCK_SIZE
#define SYMCRYPT_MIN(_a, _b)
PCBYTE PBYTE SIZE_T cbData
#define SYMCRYPT_GCM_BLOCK_ROUND_MASK
PSYMCRYPT_COMMON_HASH_STATE pState
PCBYTE pbData
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by SymCryptGcmAuthPart(), SymCryptGcmDecryptPartTwoPass(), and SymCryptGcmEncryptPartTwoPass().

◆ SymCryptGcmAuthPart()

SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmAuthPart ( _Inout_ PSYMCRYPT_GCM_STATE  pState,
_In_reads_opt_(cbData) PCBYTE  pbAuthData,
SIZE_T  cbData 
)

Definition at line 435 of file gcm.c.

439{
441 SYMCRYPT_ASSERT( pState->cbData == 0 );
442
443 SymCryptGcmAddMacData( pState, pbAuthData, cbData );
444 pState->cbAuthData += cbData;
445}
VOID SYMCRYPT_CALL SymCryptGcmAddMacData(_Inout_ PSYMCRYPT_GCM_STATE pState, _In_reads_opt_(cbData) PCBYTE pbData, SIZE_T cbData)
Definition: gcm.c:65
#define SYMCRYPT_ASSERT(_x)
Definition: symcrypt.h:10807
#define SYMCRYPT_CHECK_MAGIC(p)

◆ SymCryptGcmComputeTag()

Definition at line 222 of file gcm.c.

225{
227
228 SYMCRYPT_STORE_MSBFIRST64( &buf[16], pState->cbAuthData * 8 );
229 SYMCRYPT_STORE_MSBFIRST64( &buf[24], pState->cbData * 8 );
230
231 if( pState->bytesInMacBlock > 0 )
232 {
233 //
234 // Pad the MAC data with zeroes until we hit the block size
235 //
237 memcpy( buf, &pState->macBlock[0], pState->bytesInMacBlock );
238
239 SymCryptGHashAppendData( &pState->pKey->ghashKey, &pState->ghashState, &buf[0], 2 * SYMCRYPT_GCM_BLOCK_SIZE );
240 }
241 else
242 {
243 SymCryptGHashAppendData( &pState->pKey->ghashKey, &pState->ghashState, &buf[16], SYMCRYPT_GCM_BLOCK_SIZE );
244 }
245
247
248 //
249 // Convert the GHash state to an array of bytes
250 //
251 SYMCRYPT_STORE_MSBFIRST64( &buf[0], pState->ghashState.ull[1] );
252 SYMCRYPT_STORE_MSBFIRST64( &buf[8], pState->ghashState.ull[0] );
253
254 SYMCRYPT_ASSERT( pState->pKey->pBlockCipher->blockSize == SYMCRYPT_GCM_BLOCK_SIZE );
255 SymCryptCtrMsb32( pState->pKey->pBlockCipher,
256 &pState->pKey->blockcipherKey,
257 &pState->counterBlock[0],
258 buf,
259 pbTag,
261
262 SymCryptWipeKnownSize( buf, sizeof( buf ) );
263}
VOID SYMCRYPT_CALL SymCryptCtrMsb32(_In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher, _In_ PCVOID pExpandedKey, _Inout_updates_(pBlockCipher->blockSize) PBYTE pbChainingValue, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData)
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
FORCEINLINE VOID SYMCRYPT_CALL SymCryptGcmResetCounterBlock(_Inout_ PSYMCRYPT_GCM_STATE pState)
Definition: gcm.c:203
FORCEINLINE VOID SYMCRYPT_CALL SymCryptWipeKnownSize(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
#define SYMCRYPT_STORE_MSBFIRST64(p, v)
Definition: symcrypt.h:312
#define SYMCRYPT_ALIGN
unsigned char BYTE
Definition: xxhash.c:193

Referenced by SymCryptGcmDecryptFinal(), and SymCryptGcmEncryptFinal().

◆ SymCryptGcmDecrypt()

SYMCRYPT_NOINLINE SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptGcmDecrypt ( _In_ PCSYMCRYPT_GCM_EXPANDED_KEY  pExpandedKey,
_In_reads_(cbNonce) PCBYTE  pbNonce,
SIZE_T  cbNonce,
_In_reads_opt_(cbAuthData) PCBYTE  pbAuthData,
SIZE_T  cbAuthData,
_In_reads_(cbData) PCBYTE  pbSrc,
_Out_writes_(cbData) PBYTE  pbDst,
SIZE_T  cbData,
_In_reads_(cbTag) PCBYTE  pbTag,
SIZE_T  cbTag 
)

Definition at line 731 of file gcm.c.

742{
747
748 // SymCryptGcmInit( &state, pExpandedKey, pbNonce, cbNonce );
749 UNREFERENCED_PARAMETER( cbNonce ); // It is used in an ASSERT, but only in CHKed builds.
750
753
755
756 pState->pKey = pExpandedKey;
757 pState->cbData = 0;
758 pState->cbAuthData = 0;
759 pState->bytesInMacBlock = 0;
760 SymCryptWipeKnownSize( &pState->ghashState, sizeof( pState->ghashState ) );
761
763
764 // SymCryptGcmAuthPart( &state, pbAuthData, cbAuthData );
765 pState->cbAuthData += cbAuthData;
767 {
769
770 SymCryptGHashAppendData( &pState->pKey->ghashKey, &pState->ghashState, pbAuthData, bytesToDo );
771
772 pbAuthData += bytesToDo;
773 cbAuthData -= bytesToDo;
774 }
775
776 if( cbAuthData > 0 )
777 {
778 //
779 // Pad the MAC data with zeroes until we hit the block size.
780 //
782 memcpy( &pState->macBlock[0], pbAuthData, cbAuthData );
783 SymCryptGHashAppendData( &pState->pKey->ghashKey, &pState->ghashState, &pState->macBlock[0], SYMCRYPT_GCM_BLOCK_SIZE );
784 }
785
786 // SymCryptGcmDecryptPart( &state, pbSrc, pbDst, cbData );
787 if ( pState->pKey->pBlockCipher->gcmDecryptPartFunc != NULL )
788 {
789 //
790 // Use optimized implementation if available
791 //
792 (*pState->pKey->pBlockCipher->gcmDecryptPartFunc) ( pState, pbSrc, pbDst, cbData );
793 }
794 else
795 {
797 }
798
799 //status = SymCryptGcmDecryptFinal( &state, pbTag, cbTag );
800 SYMCRYPT_STORE_MSBFIRST64( &buf[16], pState->cbAuthData * 8 );
801 SYMCRYPT_STORE_MSBFIRST64( &buf[24], pState->cbData * 8 );
802
803 if( pState->bytesInMacBlock > 0 )
804 {
805 //
806 // Pad the MAC data with zeroes until we hit the block size
807 //
809 memcpy( buf, &pState->macBlock[0], pState->bytesInMacBlock );
810
811 SymCryptGHashAppendData( &pState->pKey->ghashKey, &pState->ghashState, &buf[0], 2 * SYMCRYPT_GCM_BLOCK_SIZE );
812 }
813 else
814 {
815 SymCryptGHashAppendData( &pState->pKey->ghashKey, &pState->ghashState, &buf[16], SYMCRYPT_GCM_BLOCK_SIZE );
816 }
817
819
820 //
821 // Convert the GHash state to an array of bytes
822 //
823 SYMCRYPT_STORE_MSBFIRST64( &buf[0], pState->ghashState.ull[1] );
824 SYMCRYPT_STORE_MSBFIRST64( &buf[8], pState->ghashState.ull[0] );
825
826 SYMCRYPT_ASSERT( pState->pKey->pBlockCipher->blockSize == SYMCRYPT_GCM_BLOCK_SIZE );
827 SymCryptCtrMsb32( pState->pKey->pBlockCipher,
828 &pState->pKey->blockcipherKey,
829 &pState->counterBlock[0],
830 buf,
831 buf,
833
834 if( !SymCryptEqual( pbTag, buf, cbTag ) )
835 {
836 status = SYMCRYPT_AUTHENTICATION_FAILURE;
837 }
838 else
839 {
840 status = SYMCRYPT_NO_ERROR;
841 }
842
843 SymCryptWipeKnownSize( buf, sizeof( buf ) );
844 SymCryptWipeKnownSize( pState, sizeof( *pState ) );
845
846 if( status != SYMCRYPT_NO_ERROR )
847 {
849 }
850
851 return status;
852}
static int state
Definition: maze.c:121
#define NULL
Definition: types.h:112
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define GCM_MAX_TAG_SIZE
Definition: gcm.c:11
SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmDecryptPartTwoPass(_Inout_ PSYMCRYPT_GCM_STATE pState, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData)
Definition: gcm.c:543
#define GCM_MIN_TAG_SIZE
Definition: gcm.c:10
#define GCM_MIN_NONCE_SIZE
Definition: gcm.c:9
VOID SYMCRYPT_CALL SymCryptGcmSetNonce(_Out_ PSYMCRYPT_GCM_STATE pState, _In_reads_(cbNonce) PCBYTE pbNonce, SIZE_T cbNonce)
Definition: gcm.c:334
Definition: ps.c:97
VOID SYMCRYPT_CALL SymCryptWipe(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
Definition: libmain.c:137
BOOLEAN SYMCRYPT_CALL SymCryptEqual(_In_reads_(cbBytes) PCBYTE pbSrc1, _In_reads_(cbBytes) PCBYTE pbSrc2, SIZE_T cbBytes)
Definition: equal.c:11
SYMCRYPT_ERROR
Definition: symcrypt.h:227
SIZE_T cbTag
PCBYTE pbSrc
SYMCRYPT_MAGIC_FIELD * PSYMCRYPT_GCM_STATE
UINT64 cbAuthData
PCBYTE PBYTE pbDst
SIZE_T cbNonce
SYMCRYPT_MAGIC_FIELD SYMCRYPT_GCM_STATE
PCVOID pExpandedKey

Referenced by SymCryptGcmSelftest(), and SymCryptSessionGcmDecrypt().

◆ SymCryptGcmDecryptFinal()

SYMCRYPT_NOINLINE SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptGcmDecryptFinal ( _Inout_ PSYMCRYPT_GCM_STATE  pState,
_In_reads_(cbTag) PCBYTE  pbTag,
SIZE_T  cbTag 
)

Definition at line 585 of file gcm.c.

589{
592
594
596
597 if( !SymCryptEqual( pbTag, buf, cbTag ) )
598 {
599 status = SYMCRYPT_AUTHENTICATION_FAILURE;
600 }
601 else
602 {
603 status = SYMCRYPT_NO_ERROR;
604 }
605
606 SymCryptWipeKnownSize( buf, sizeof( buf ) );
607
608 SymCryptWipeKnownSize( pState, sizeof( *pState ) );
609 SYMCRYPT_ASSERT( pState->bytesInMacBlock == 0 );
610
611 return status;
612}
VOID SYMCRYPT_CALL SymCryptGcmComputeTag(_Inout_ PSYMCRYPT_GCM_STATE pState, _Out_writes_(SYMCRYPT_GCM_BLOCK_SIZE) PBYTE pbTag)
Definition: gcm.c:222

◆ SymCryptGcmDecryptPart()

SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmDecryptPart ( _Inout_ PSYMCRYPT_GCM_STATE  pState,
_In_reads_(cbData) PCBYTE  pbSrc,
_Out_writes_(cbData) PBYTE  pbDst,
SIZE_T  cbData 
)

Definition at line 512 of file gcm.c.

517{
518 if( pState->cbData == 0 )
519 {
520 //
521 // This is the first actual encryption data, pad the Auth data with zeroes if needed.
522 //
524 }
525
526 if ( pState->pKey->pBlockCipher->gcmDecryptPartFunc != NULL )
527 {
528 //
529 // Use optimized implementation if available
530 //
531 (*pState->pKey->pBlockCipher->gcmDecryptPartFunc) ( pState, pbSrc, pbDst, cbData );
532 SYMCRYPT_ASSERT( pState->bytesInMacBlock <= 15 );
533 }
534 else
535 {
537 }
538}
VOID SYMCRYPT_CALL SymCryptGcmPadMacData(_Inout_ PSYMCRYPT_GCM_STATE pState)
Definition: gcm.c:110

◆ SymCryptGcmDecryptPartTwoPass()

SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmDecryptPartTwoPass ( _Inout_ PSYMCRYPT_GCM_STATE  pState,
_In_reads_(cbData) PCBYTE  pbSrc,
_Out_writes_(cbData) PBYTE  pbDst,
SIZE_T  cbData 
)

Definition at line 543 of file gcm.c.

548{
550
551 //
552 // Do the actual decryption
553 // This violates the read-once rule, but it is safe for the same reasons as above
554 // in the encryption case.
555 //
556
558}
VOID SYMCRYPT_CALL SymCryptGcmEncryptDecryptPart(_Inout_ PSYMCRYPT_GCM_STATE pState, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData)
Definition: gcm.c:129

Referenced by SymCryptAesGcmDecryptPart(), SymCryptGcmDecrypt(), and SymCryptGcmDecryptPart().

◆ SymCryptGcmEncrypt()

SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmEncrypt ( _In_ PCSYMCRYPT_GCM_EXPANDED_KEY  pExpandedKey,
_In_reads_(cbNonce) PCBYTE  pbNonce,
SIZE_T  cbNonce,
_In_reads_opt_(cbAuthData) PCBYTE  pbAuthData,
SIZE_T  cbAuthData,
_In_reads_(cbData) PCBYTE  pbSrc,
_Out_writes_(cbData) PBYTE  pbDst,
SIZE_T  cbData,
_Out_writes_(cbTag) PBYTE  pbTag,
SIZE_T  cbTag 
)

Definition at line 618 of file gcm.c.

629{
633
634 // SymCryptGcmInit( &state, pExpandedKey, pbNonce, cbNonce );
635 UNREFERENCED_PARAMETER( cbNonce ); // It is used in an ASSERT, but only in CHKed builds.
636
639
641
642 pState->pKey = pExpandedKey;
643 pState->cbData = 0;
644 pState->cbAuthData = 0;
645 pState->bytesInMacBlock = 0;
646 SymCryptWipeKnownSize( &pState->ghashState, sizeof( pState->ghashState ) );
647
649
650 // SymCryptGcmAuthPart( &state, pbAuthData, cbAuthData );
651 pState->cbAuthData += cbAuthData;
653 {
655
656 SymCryptGHashAppendData( &pState->pKey->ghashKey, &pState->ghashState, pbAuthData, bytesToDo );
657
658 pbAuthData += bytesToDo;
659 cbAuthData -= bytesToDo;
660 }
661
662 if( cbAuthData > 0 )
663 {
664 //
665 // Pad the MAC data with zeroes until we hit the block size.
666 //
668 memcpy( &pState->macBlock[0], pbAuthData, cbAuthData );
669 SymCryptGHashAppendData( &pState->pKey->ghashKey, &pState->ghashState, &pState->macBlock[0], SYMCRYPT_GCM_BLOCK_SIZE );
670 }
671
672 // SymCryptGcmEncryptPart( &state, pbSrc, pbDst, cbData );
673 if ( pState->pKey->pBlockCipher->gcmEncryptPartFunc != NULL )
674 {
675 //
676 // Use optimized implementation if available
677 //
678 (*pState->pKey->pBlockCipher->gcmEncryptPartFunc) ( pState, pbSrc, pbDst, cbData );
679 }
680 else
681 {
683 }
684
685 // SymCryptGcmEncryptFinal( &state, pbTag, cbTag );
686 SYMCRYPT_STORE_MSBFIRST64( &buf[16], pState->cbAuthData * 8 );
687 SYMCRYPT_STORE_MSBFIRST64( &buf[24], pState->cbData * 8 );
688
689 if( pState->bytesInMacBlock > 0 )
690 {
691 //
692 // Pad the MAC data with zeroes until we hit the block size
693 //
695 memcpy( buf, &pState->macBlock[0], pState->bytesInMacBlock );
696
697 SymCryptGHashAppendData( &pState->pKey->ghashKey, &pState->ghashState, &buf[0], 2 * SYMCRYPT_GCM_BLOCK_SIZE );
698 }
699 else
700 {
701 SymCryptGHashAppendData( &pState->pKey->ghashKey, &pState->ghashState, &buf[16], SYMCRYPT_GCM_BLOCK_SIZE );
702 }
703
704 // Reset the counter block prior to computing the tag
706
707 //
708 // Convert the GHash state to an array of bytes
709 //
710 SYMCRYPT_STORE_MSBFIRST64( &buf[0], pState->ghashState.ull[1] );
711 SYMCRYPT_STORE_MSBFIRST64( &buf[8], pState->ghashState.ull[0] );
712
713 SYMCRYPT_ASSERT( pState->pKey->pBlockCipher->blockSize == SYMCRYPT_GCM_BLOCK_SIZE );
714 SymCryptCtrMsb32( pState->pKey->pBlockCipher,
715 &pState->pKey->blockcipherKey,
716 &pState->counterBlock[0],
717 buf,
718 buf,
720
721 memcpy( pbTag, buf, cbTag );
722
723 SymCryptWipeKnownSize( buf, sizeof( buf ) );
724 SymCryptWipeKnownSize( pState, sizeof( *pState ) );
725}
SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmEncryptPartTwoPass(_Inout_ PSYMCRYPT_GCM_STATE pState, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData)
Definition: gcm.c:481

Referenced by SymCryptGcmSelftest(), and SymCryptSessionGcmEncrypt().

◆ SymCryptGcmEncryptDecryptPart()

VOID SYMCRYPT_CALL SymCryptGcmEncryptDecryptPart ( _Inout_ PSYMCRYPT_GCM_STATE  pState,
_In_reads_(cbData) PCBYTE  pbSrc,
_Out_writes_(cbData) PBYTE  pbDst,
SIZE_T  cbData 
)

Definition at line 129 of file gcm.c.

134{
135 SIZE_T bytesToProcess;
136 SIZE_T bytesUsedInKeyStreamBuffer;
137
138 bytesUsedInKeyStreamBuffer = (SIZE_T) (pState->cbData & SYMCRYPT_GCM_BLOCK_MOD_MASK);
139
140 //
141 // We update pState->cbData once before we modify cbData.
142 // pState->cbData is not used in the rest of this function
143 //
145 pState->cbData += cbData;
146
147 if( bytesUsedInKeyStreamBuffer != 0 )
148 {
149 bytesToProcess = SYMCRYPT_MIN( cbData, SYMCRYPT_GCM_BLOCK_SIZE - bytesUsedInKeyStreamBuffer );
150 SymCryptXorBytes( pbSrc, &pState->keystreamBlock[bytesUsedInKeyStreamBuffer], pbDst, bytesToProcess );
151 pbSrc += bytesToProcess;
152 pbDst += bytesToProcess;
153 cbData -= bytesToProcess;
154
155 //
156 // If there are bytes left in the key stream buffer, then cbData == 0 and we're done.
157 // If we used up all the bytes, then we are fine, no need to compute the next key stream block
158 //
159 }
160
162 {
163 bytesToProcess = cbData & SYMCRYPT_GCM_BLOCK_ROUND_MASK;
164
165 SYMCRYPT_ASSERT( pState->pKey->pBlockCipher->blockSize == SYMCRYPT_GCM_BLOCK_SIZE );
166 SymCryptCtrMsb32( pState->pKey->pBlockCipher,
167 &pState->pKey->blockcipherKey,
168 &pState->counterBlock[0],
169 pbSrc,
170 pbDst,
171 bytesToProcess );
172
173 pbSrc += bytesToProcess;
174 pbDst += bytesToProcess;
175 cbData -= bytesToProcess;
176 }
177
178 if( cbData > 0 )
179 {
181
182 SYMCRYPT_ASSERT( pState->pKey->pBlockCipher->blockSize == SYMCRYPT_GCM_BLOCK_SIZE );
183 SymCryptCtrMsb32( pState->pKey->pBlockCipher,
184 &pState->pKey->blockcipherKey,
185 &pState->counterBlock[0],
186 &pState->keystreamBlock[0],
187 &pState->keystreamBlock[0],
189
190 SymCryptXorBytes( &pState->keystreamBlock[0], pbSrc, pbDst, cbData );
191
192 //
193 // pState->cbData contains the data length after this call already, so it knows how many
194 // bytes are left in the keystream block
195 //
196 }
197
198}
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_GCM_BLOCK_MOD_MASK
#define SYMCRYPT_GCM_MAX_DATA_SIZE

Referenced by SymCryptGcmDecryptPartTwoPass(), and SymCryptGcmEncryptPartTwoPass().

◆ SymCryptGcmEncryptFinal()

SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmEncryptFinal ( _Inout_ PSYMCRYPT_GCM_STATE  pState,
_Out_writes_(cbTag) PBYTE  pbTag,
SIZE_T  cbTag 
)

Definition at line 564 of file gcm.c.

568{
570
572
574 memcpy( pbTag, buf, cbTag );
575
576 SymCryptWipeKnownSize( buf, sizeof( buf ) );
577
578 SymCryptWipeKnownSize( pState, sizeof( *pState ) );
579 SYMCRYPT_ASSERT( pState->bytesInMacBlock == 0 );
580}

◆ SymCryptGcmEncryptPart()

SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmEncryptPart ( _Inout_ PSYMCRYPT_GCM_STATE  pState,
_In_reads_(cbData) PCBYTE  pbSrc,
_Out_writes_(cbData) PBYTE  pbDst,
SIZE_T  cbData 
)

Definition at line 450 of file gcm.c.

455{
456 if( pState->cbData == 0 )
457 {
458 //
459 // This is the first actual encryption data, pad the Auth data with zeroes if needed.
460 //
462 }
463
464 if ( pState->pKey->pBlockCipher->gcmEncryptPartFunc != NULL )
465 {
466 //
467 // Use optimized implementation if available
468 //
469 (*pState->pKey->pBlockCipher->gcmEncryptPartFunc) ( pState, pbSrc, pbDst, cbData );
470 SYMCRYPT_ASSERT( pState->bytesInMacBlock <= 15 );
471 }
472 else
473 {
475 }
476}

◆ SymCryptGcmEncryptPartTwoPass()

SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmEncryptPartTwoPass ( _Inout_ PSYMCRYPT_GCM_STATE  pState,
_In_reads_(cbData) PCBYTE  pbSrc,
_Out_writes_(cbData) PBYTE  pbDst,
SIZE_T  cbData 
)

Definition at line 481 of file gcm.c.

486{
487 //
488 // Do the actual encryption
489 //
491
492 //
493 // We break the read-once/write once rule here by reading the pbDst data back.
494 // In this particular situation this is safe, and avoiding it is expensive as it
495 // requires an extra copy and an extra memory buffer.
496 // The first write exposes the GCM key stream, independent of the underlying data that
497 // we are processing. From an attacking point of view we can think of this as literally
498 // handing over the key stream. So encryption consists of two steps:
499 // - hand over the key stream
500 // - MAC some ciphertext
501 // In this view (which has equivalent security properties to GCM) is obviously doesn't
502 // matter that we read pbDst back.
503 //
504
506}

Referenced by SymCryptAesGcmEncryptPart(), SymCryptGcmEncrypt(), and SymCryptGcmEncryptPart().

◆ SymCryptGcmExpandKey()

SYMCRYPT_NOINLINE SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptGcmExpandKey ( _Out_ PSYMCRYPT_GCM_EXPANDED_KEY  pExpandedKey,
_In_ PCSYMCRYPT_BLOCKCIPHER  pBlockCipher,
_In_reads_(cbKey) PCBYTE  pbKey,
SIZE_T  cbKey 
)

Definition at line 268 of file gcm.c.

273{
275 SYMCRYPT_ERROR status = SYMCRYPT_NO_ERROR;
276
278 {
279 status = SYMCRYPT_WRONG_KEY_SIZE;
280 goto cleanup;
281 }
282
283 //
284 // Perform the Block cipher key expansion first
285 //
286 pExpandedKey->pBlockCipher = pBlockCipher;
287 status = pBlockCipher->expandKeyFunc( &pExpandedKey->blockcipherKey, pbKey, cbKey );
288
289 if( status != SYMCRYPT_NO_ERROR )
290 {
291 goto cleanup;
292 }
293
294 //
295 // We keep a copy of the key to make it easy to
296 // implement the SymCryptGcmKeyCopy function
297 //
298 pExpandedKey->cbKey = cbKey;
299 memcpy( &pExpandedKey->abKey[0], pbKey, cbKey );
300
301 //
302 // Compute H and the GHASH expanded key
303 //
304 SymCryptWipeKnownSize( H, sizeof( H ) );
305 pBlockCipher->encryptFunc( &pExpandedKey->blockcipherKey, H, H );
306
307
309
310
312
313 SymCryptWipeKnownSize( H, sizeof( H ) );
314
315cleanup:
316
317 return status;
318}
static void cleanup(void)
Definition: main.c:1335
VOID SYMCRYPT_CALL SymCryptGHashExpandKey(_Out_ PSYMCRYPT_GHASH_EXPANDED_KEY expandedKey, _In_reads_(SYMCRYPT_GF128_BLOCK_SIZE) PCBYTE pH)
Definition: ghash.c:816
#define H
PSYMCRYPT_BLOCKCIPHER_CRYPT encryptFunc
PSYMCRYPT_BLOCKCIPHER_EXPAND_KEY expandKeyFunc
PCBYTE pbKey
PCBYTE SIZE_T cbKey
PCSYMCRYPT_BLOCKCIPHER pBlockCipher
#define SYMCRYPT_SET_MAGIC(p)
#define SYMCRYPT_GCM_MAX_KEY_SIZE

Referenced by SymCryptGcmKeyCopy(), and SymCryptGcmSelftest().

◆ SymCryptGcmInit()

SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmInit ( _Out_ PSYMCRYPT_GCM_STATE  pState,
_In_ PCSYMCRYPT_GCM_EXPANDED_KEY  pExpandedKey,
_In_reads_(cbNonce) PCBYTE  pbNonce,
SIZE_T  cbNonce 
)

Definition at line 391 of file gcm.c.

396{
397 UNREFERENCED_PARAMETER( cbNonce ); // It is used in an ASSERT, but only in CHKed builds.
398
400
401 pState->pKey = pExpandedKey;
402 pState->cbData = 0;
403 pState->cbAuthData = 0;
404 pState->bytesInMacBlock = 0;
405 SymCryptWipeKnownSize( &pState->ghashState, sizeof( pState->ghashState ) );
406
408
410}

◆ SymCryptGcmKeyCopy()

Definition at line 322 of file gcm.c.

323{
325
326 SYMCRYPT_CHECK_MAGIC( pSrc );
327
328 status = SymCryptGcmExpandKey( pDst, pSrc->pBlockCipher, &pSrc->abKey[0], pSrc->cbKey );
329 SYMCRYPT_ASSERT( status == SYMCRYPT_NO_ERROR );
330}
SYMCRYPT_NOINLINE SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptGcmExpandKey(_Out_ PSYMCRYPT_GCM_EXPANDED_KEY pExpandedKey, _In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher, _In_reads_(cbKey) PCBYTE pbKey, SIZE_T cbKey)
Definition: gcm.c:268

◆ SymCryptGcmPadMacData()

VOID SYMCRYPT_CALL SymCryptGcmPadMacData ( _Inout_ PSYMCRYPT_GCM_STATE  pState)

Definition at line 110 of file gcm.c.

111{
112 SIZE_T nBytes;
113 //
114 // Pad the MAC data with zeroes until we hit the block size.
115 //
116 nBytes = pState->bytesInMacBlock;
117 if( nBytes > 0 )
118 {
119 SymCryptWipe( &pState->macBlock[nBytes], SYMCRYPT_GCM_BLOCK_SIZE - nBytes );
120 SymCryptGHashAppendData( &pState->pKey->ghashKey, &pState->ghashState, &pState->macBlock[0], SYMCRYPT_GCM_BLOCK_SIZE );
121 pState->bytesInMacBlock = 0;
122 }
123}

Referenced by SymCryptGcmDecryptPart(), and SymCryptGcmEncryptPart().

◆ SymCryptGcmResetCounterBlock()

FORCEINLINE VOID SYMCRYPT_CALL SymCryptGcmResetCounterBlock ( _Inout_ PSYMCRYPT_GCM_STATE  pState)

Definition at line 203 of file gcm.c.

205{
206 // Computing the tag for GCM requires invoking the GCTR function with the pre-counter
207 // block which was computed when the nonce was set. Historically, we only supported 12-byte
208 // nonces, so we could trivially reset the counter block by just setting the last 4 bytes to
209 // (DWORD) 1. With support for larger IVs, the pre-counter block is computed from a GHash of
210 // the nonce, and we don't store the value. Adding a field in the GCM struct to store the value
211 // would be ABI-breaking, so instead we can recompute the value by decrementing the last 32 bits
212 // of the counter block by the number of blocks that have been processed (since the counter is
213 // incremented once per block), plus one for the initial increment.
214 UINT32 preCounter32 = SYMCRYPT_LOAD_MSBFIRST32(&pState->counterBlock[12]) -
216
217 SYMCRYPT_STORE_MSBFIRST32(&pState->counterBlock[12], preCounter32);
218}
#define SYMCRYPT_LOAD_MSBFIRST32(p)
Definition: symcrypt.h:303
#define SYMCRYPT_STORE_MSBFIRST32(p, v)
Definition: symcrypt.h:311
uint32_t UINT32
Definition: typedefs.h:59

Referenced by SymCryptGcmComputeTag(), SymCryptGcmDecrypt(), and SymCryptGcmEncrypt().

◆ SymCryptGcmSelftest()

VOID SYMCRYPT_CALL SymCryptGcmSelftest ( void  )

Definition at line 863 of file gcm.c.

864{
868
869 if( SymCryptGcmExpandKey( &key, SymCryptAesBlockCipher, SymCryptTestKey32, 16 ) != SYMCRYPT_NO_ERROR )
870 {
871 SymCryptFatal( 'gcm0' );
872 }
873
875 &SymCryptTestKey32[16], 12,
876 NULL, 0,
877 &SymCryptTestMsg3[0], buf, 3,
879
880 SymCryptInjectError( buf, sizeof( buf ) );
881 if( memcmp( buf, SymCryptGcmSelftestResult, sizeof( buf ) ) != 0 )
882 {
883 SymCryptFatal( 'gcm1' );
884 }
885
886 // inject error into the ciphertext or tag
887 SymCryptInjectError( buf, sizeof( buf ) );
888
890 &SymCryptTestKey32[16], 12,
891 NULL, 0,
892 buf, buf, 3,
894
896
897 if( err != SYMCRYPT_NO_ERROR || memcmp( buf, SymCryptTestMsg3, 3 ) != 0 )
898 {
899 SymCryptFatal( 'gcm2' );
900 }
901
902}
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
#define err(...)
VOID SYMCRYPT_CALL SymCryptInjectError(PBYTE pbData, SIZE_T cbData)
const BYTE SymCryptTestKey32[32]
Definition: selftest.c:10
const BYTE SymCryptTestMsg3[3]
Definition: selftest.c:8
SYMCRYPT_NOINLINE SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptGcmDecrypt(_In_ PCSYMCRYPT_GCM_EXPANDED_KEY pExpandedKey, _In_reads_(cbNonce) PCBYTE pbNonce, SIZE_T cbNonce, _In_reads_opt_(cbAuthData) PCBYTE pbAuthData, SIZE_T cbAuthData, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData, _In_reads_(cbTag) PCBYTE pbTag, SIZE_T cbTag)
Definition: gcm.c:731
static const BYTE SymCryptGcmSelftestResult[3+SYMCRYPT_AES_BLOCK_SIZE]
Definition: gcm.c:855
SYMCRYPT_NOINLINE VOID SYMCRYPT_CALL SymCryptGcmEncrypt(_In_ PCSYMCRYPT_GCM_EXPANDED_KEY pExpandedKey, _In_reads_(cbNonce) PCBYTE pbNonce, SIZE_T cbNonce, _In_reads_opt_(cbAuthData) PCBYTE pbAuthData, SIZE_T cbAuthData, _In_reads_(cbData) PCBYTE pbSrc, _Out_writes_(cbData) PBYTE pbDst, SIZE_T cbData, _Out_writes_(cbTag) PBYTE pbTag, SIZE_T cbTag)
Definition: gcm.c:618
Definition: copy.c:22
const PCSYMCRYPT_BLOCKCIPHER SymCryptAesBlockCipher
_Analysis_noreturn_ VOID SYMCRYPT_CALL SymCryptFatal(UINT32 fatalCode)
#define SYMCRYPT_AES_BLOCK_SIZE
Definition: symcrypt.h:4255
SYMCRYPT_MAGIC_FIELD SYMCRYPT_GCM_EXPANDED_KEY

◆ SymCryptGcmSetNonce()

VOID SYMCRYPT_CALL SymCryptGcmSetNonce ( _Out_ PSYMCRYPT_GCM_STATE  pState,
_In_reads_(cbNonce) PCBYTE  pbNonce,
SIZE_T  cbNonce 
)

Definition at line 334 of file gcm.c.

338{
340
341 // Handle the nonce depending on its size, as specified in NIST SP800-38D
342 if( cbNonce == 12 )
343 {
344 // If len(nonce) = 96 bits (12 bytes), pre-counter block = nonce || (DWORD) 1
345 memcpy( &pState->counterBlock[0], pbNonce, cbNonce );
346 SymCryptWipeKnownSize( &pState->counterBlock[12], 4 );
347 pState->counterBlock[15] = 1;
348 }
349 else
350 {
351 // If len(nonce) != 96 bits (12 bytes),
352 // pre-counter block = GHASH(nonce padded to a multiple of 128 bits || (QWORD) len(nonce))
354 SIZE_T cbNonceRemainder = cbNonce & (SYMCRYPT_GF128_BLOCK_SIZE - 1);
355
356 // Process all full blocks of the nonce, i.e. all nonce bytes up to a multiple of
357 // SYMCRYPT_GF128_BLOCK_SIZE. SymCryptGHashAppendData ignores additional data that are
358 // not a multiple of the block size. We will handle any such remaining data below.
359 // (This also works if the nonce is less than the block size.)
360 SymCryptGHashAppendData( &pState->pKey->ghashKey, &pState->ghashState, pbNonce, cbNonce );
361
362 // If the nonce length is not a multiple of SYMCRYPT_GF128_BLOCK_SIZE, we need to pad any
363 // remaining data to a multiple of the block size.
364 if(cbNonceRemainder > 0)
365 {
366 SymCryptWipeKnownSize( buf, sizeof(buf) );
367 memcpy(buf, pbNonce + cbNonce - cbNonceRemainder, cbNonceRemainder);
368 SymCryptGHashAppendData( &pState->pKey->ghashKey, &pState->ghashState, buf, sizeof(buf) );
369 }
370
371 // Now we append the length of the nonce in bits. We take the length as a 64-bit integer,
372 // but it too must be padded to 128 bits for use in GHASH.
375 SymCryptGHashAppendData( &pState->pKey->ghashKey, &pState->ghashState, buf, sizeof(buf) );
376
377 SymCryptGHashResult( &pState->ghashState, pState->counterBlock );
378 SymCryptWipeKnownSize( &pState->ghashState, sizeof( pState->ghashState ) );
379 }
380
381 // Increment the last 32 bits of the counter. We'll recalculate the pre-counter block later
382 // when computing the tag.
384 &pState->counterBlock[12],
385 1 + SYMCRYPT_LOAD_MSBFIRST32( &pState->counterBlock[12] ) );
386}
VOID SYMCRYPT_CALL SymCryptGHashResult(_In_ PCSYMCRYPT_GF128_ELEMENT pState, _Out_writes_(SYMCRYPT_GF128_BLOCK_SIZE) PBYTE pbResult)
Definition: ghash.c:108
#define SYMCRYPT_GF128_BLOCK_SIZE

Referenced by SymCryptGcmDecrypt(), SymCryptGcmEncrypt(), and SymCryptGcmInit().

◆ SymCryptGcmStateCopy()

VOID SYMCRYPT_CALL SymCryptGcmStateCopy ( _In_ PCSYMCRYPT_GCM_STATE  pSrc,
_In_opt_ PCSYMCRYPT_GCM_EXPANDED_KEY  pExpandedKeyCopy,
_Out_ PSYMCRYPT_GCM_STATE  pDst 
)

Definition at line 415 of file gcm.c.

419{
420 SYMCRYPT_CHECK_MAGIC( pSrc );
421
422 *pDst = *pSrc;
423 if( pExpandedKeyCopy != NULL )
424 {
425 pDst->pKey = pExpandedKeyCopy;
426 }
427
428 SYMCRYPT_SET_MAGIC( pDst );
429}

◆ SymCryptGcmValidateParameters()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptGcmValidateParameters ( _In_ PCSYMCRYPT_BLOCKCIPHER  pBlockCipher,
_In_ SIZE_T  cbNonce,
_In_ UINT64  cbAssociatedData,
_In_ UINT64  cbData,
_In_ SIZE_T  cbTag 
)

Definition at line 16 of file gcm.c.

22{
23 if( pBlockCipher->blockSize != SYMCRYPT_GCM_BLOCK_SIZE )
24 {
25 return SYMCRYPT_WRONG_BLOCK_SIZE;
26 }
27
28 //
29 // SP800-38D specifies that the nonce must be at least one bit, but we operate on bytes,
30 // so the minimum is one byte.
31 //
33 {
34 return SYMCRYPT_WRONG_NONCE_SIZE;
35 }
36
37 //
38 // cbAssociatedData is limited to <2^61 bytes
39 //
40 if( (cbAssociatedData >> 61) > 0 )
41 {
42 return SYMCRYPT_WRONG_DATA_SIZE;
43 }
44
45 //
46 // per SP800-38D cbData is limited to 2^36 - 32 bytes
47 //
49 {
50 return SYMCRYPT_WRONG_DATA_SIZE;
51 }
52
53 if( cbTag < GCM_MIN_TAG_SIZE || cbTag > GCM_MAX_TAG_SIZE )
54 {
55 return SYMCRYPT_WRONG_TAG_SIZE;
56 }
57
58 return SYMCRYPT_NO_ERROR;
59}

Variable Documentation

◆ SymCryptGcmSelftestResult

const BYTE SymCryptGcmSelftestResult[3+SYMCRYPT_AES_BLOCK_SIZE]
static
Initial value:
=
{
0xa5, 0x4c, 0x60,
0x80, 0xb0, 0x48, 0x6d, 0x03, 0x9f, 0xea, 0xc3, 0x3c, 0x28, 0x96, 0x3f, 0x99, 0x8a, 0x77, 0x43,
}

Definition at line 855 of file gcm.c.

Referenced by SymCryptGcmSelftest().