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

Go to the source code of this file.

Functions

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSessionSenderInit (_Inout_ PSYMCRYPT_SESSION pSession, UINT32 senderId, UINT32 flags)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSessionReceiverInit (_Inout_ PSYMCRYPT_SESSION pSession, UINT32 senderId, UINT32 flags)
 
VOID SYMCRYPT_CALL SymCryptSessionDestroy (_Inout_ PSYMCRYPT_SESSION pSession)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSessionGcmEncrypt (_Inout_ PSYMCRYPT_SESSION pSession, _In_ PCSYMCRYPT_GCM_EXPANDED_KEY pExpandedKey, _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, _Out_opt_ PUINT64 pu64MessageNumber)
 
FORCEINLINE SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSessionDecryptComputeDesiredReplayState (_In_ PCSYMCRYPT_SESSION_REPLAY_STATE observedState, _Out_ PSYMCRYPT_SESSION_REPLAY_STATE desiredState, UINT64 messageNumber)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSessionDecryptUpdateStateLock (_Inout_ PSYMCRYPT_SESSION pSession, UINT64 messageNumber)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSessionDecryptUpdateState (_Inout_ PSYMCRYPT_SESSION pSession, UINT64 messageNumber)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSessionGcmDecrypt (_Inout_ PSYMCRYPT_SESSION pSession, UINT64 messageNumber, _In_ PCSYMCRYPT_GCM_EXPANDED_KEY pExpandedKey, _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)
 

Function Documentation

◆ SymCryptSessionDecryptComputeDesiredReplayState()

FORCEINLINE SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSessionDecryptComputeDesiredReplayState ( _In_ PCSYMCRYPT_SESSION_REPLAY_STATE  observedState,
_Out_ PSYMCRYPT_SESSION_REPLAY_STATE  desiredState,
UINT64  messageNumber 
)

Definition at line 150 of file session.c.

154{
155 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
156 UINT64 messageMask;
157 UINT64 shiftAmount;
158 UINT64 shiftedMask;
159
160 if ( messageNumber > observedState->messageNumber )
161 {
162 // The observed message number is behind messageNumber that we want to mark successful
163 // Shift replayMask appropriately to preserve previously seen message numbers
164 shiftedMask = 0;
165 shiftAmount = messageNumber - observedState->messageNumber;
166 if( shiftAmount < 64 )
167 {
168 shiftedMask = observedState->replayMask << shiftAmount;
169 }
170 // Mark messageNumber as seen in the replayMask
171 desiredState->replayMask = shiftedMask | 1;
172 desiredState->messageNumber = messageNumber;
173 }
174 else if ( messageNumber <= observedState->messageNumber - 64 )
175 {
176 // The observed message number is too far ahead of messageNumber
177 // We cannot hope to succeed
178 scError = SYMCRYPT_SESSION_REPLAY_FAILURE;
179 goto cleanup;
180 }
181 else
182 {
183 // The observed message number is ahead of or equal to messageNumber
184 // Check if messageNumber has already been used
185 messageMask = 1ull << (observedState->messageNumber - messageNumber); // shiftAmount is in [0, 63]
186 if ((messageMask & observedState->replayMask) == messageMask)
187 {
188 scError = SYMCRYPT_SESSION_REPLAY_FAILURE;
189 goto cleanup;
190 }
191 // This is first time we have seen messageNumber - set the replayMask bit appropriately
192 desiredState->replayMask = observedState->replayMask | messageMask;
193 desiredState->messageNumber = observedState->messageNumber;
194 }
195
196cleanup:
197 return scError;
198}
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
static void cleanup(void)
Definition: main.c:1335
SYMCRYPT_ERROR
Definition: symcrypt.h:227
UINT64 messageNumber

Referenced by SymCryptSessionDecryptUpdateStateLock().

◆ SymCryptSessionDecryptUpdateState()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSessionDecryptUpdateState ( _Inout_ PSYMCRYPT_SESSION  pSession,
UINT64  messageNumber 
)

Definition at line 285 of file session.c.

288{
289 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
290
291#if SYMCRYPT_CPU_AMD64
292 if ( SYMCRYPT_CPU_FEATURES_PRESENT( SYMCRYPT_CPU_FEATURE_CMPXCHG16B ) )
293 {
294 scError = SymCryptSessionDecryptUpdateStateCAS128( pSession, messageNumber );
295 }
296 else
297 {
299 }
300#elif SYMCRYPT_CPU_ARM64 // Arm64 always has support for CAS128 (possibly via LDXP + STXP)
301 scError = SymCryptSessionDecryptUpdateStateCAS128( pSession, messageNumber );
302#else // 32b and generic platforms will always need to use a lock
304#endif
305
306 return scError;
307}
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSessionDecryptUpdateStateLock(_Inout_ PSYMCRYPT_SESSION pSession, UINT64 messageNumber)
Definition: session.c:247
#define SYMCRYPT_CPU_FEATURES_PRESENT(x)

Referenced by SymCryptSessionGcmDecrypt().

◆ SymCryptSessionDecryptUpdateStateLock()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSessionDecryptUpdateStateLock ( _Inout_ PSYMCRYPT_SESSION  pSession,
UINT64  messageNumber 
)

Definition at line 247 of file session.c.

250{
251 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
253
254 if ( pSession->pMutex == NULL )
255 {
256 return SYMCRYPT_INVALID_ARGUMENT;
257 }
258
259 // Check whether we are definitely too late to proceed before attempting to acquire mutex
260 // Do not need atomic read of full replayState here, but do need atomic 64b read of
261 // pSession->replayState.messageNumber
262 if ( messageNumber <= (UINT64) SYMCRYPT_ATOMIC_LOAD64_RELAXED(&pSession->replayState.messageNumber) - 64 )
263 {
264 return SYMCRYPT_SESSION_REPLAY_FAILURE;
265 }
266
269 // !!! Do not return until we have called SymCryptCallbackReleaseMutexFastInproc !!!
271
272 scError = SymCryptSessionDecryptComputeDesiredReplayState(&pSession->replayState, &desiredState, messageNumber);
273 if ( scError == SYMCRYPT_NO_ERROR )
274 {
275 pSession->replayState = desiredState;
276 }
277
279
280 return scError;
281}
#define NULL
Definition: types.h:112
FORCEINLINE SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSessionDecryptComputeDesiredReplayState(_In_ PCSYMCRYPT_SESSION_REPLAY_STATE observedState, _Out_ PSYMCRYPT_SESSION_REPLAY_STATE desiredState, UINT64 messageNumber)
Definition: session.c:150
VOID SYMCRYPT_CALL SymCryptCallbackAcquireMutexFastInproc(_Inout_ PVOID pMutex)
VOID SYMCRYPT_CALL SymCryptCallbackReleaseMutexFastInproc(_Inout_ PVOID pMutex)
SYMCRYPT_SESSION_REPLAY_STATE

Referenced by SymCryptSessionDecryptUpdateState().

◆ SymCryptSessionDestroy()

VOID SYMCRYPT_CALL SymCryptSessionDestroy ( _Inout_ PSYMCRYPT_SESSION  pSession)

Definition at line 76 of file session.c.

77{
78 if ( pSession->pMutex != NULL )
79 {
81 }
82 SymCryptWipeKnownSize(pSession, sizeof(*pSession));
83}
VOID SYMCRYPT_CALL SymCryptCallbackFreeMutexFastInproc(_Inout_ PVOID pMutex)
FORCEINLINE VOID SYMCRYPT_CALL SymCryptWipeKnownSize(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)

◆ SymCryptSessionGcmDecrypt()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSessionGcmDecrypt ( _Inout_ PSYMCRYPT_SESSION  pSession,
UINT64  messageNumber,
_In_ PCSYMCRYPT_GCM_EXPANDED_KEY  pExpandedKey,
_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 311 of file session.c.

322{
323 BYTE nonce[12];
324 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
325
326 if ( (pSession->flags & SYMCRYPT_FLAG_SESSION_ENCRYPT) != 0 )
327 {
328 scError = SYMCRYPT_INVALID_ARGUMENT;
329 goto cleanup;
330 }
331
332 // Check for messageNumbers which are too high or not valid
334 {
335 scError = SYMCRYPT_INVALID_ARGUMENT;
336 goto cleanup;
337 }
338
339 // Check whether we are definitely too late to proceed before attempting to acquire mutex
340 // Do not need atomic read of full replayState here, but do need atomic 64b read of
341 // pSession->replayState.messageNumber
342 if ( messageNumber <= (UINT64) SYMCRYPT_ATOMIC_LOAD64_RELAXED(&pSession->replayState.messageNumber) - 64 )
343 {
344 scError = SYMCRYPT_SESSION_REPLAY_FAILURE;
345 goto cleanup;
346 }
347
348 SYMCRYPT_STORE_MSBFIRST32(&nonce[0], pSession->senderId);
350
351 scError = SymCryptGcmDecrypt(
353 nonce,
354 sizeof(nonce),
355 pbAuthData,
357 pbSrc,
358 pbDst,
359 cbData,
360 pbTag,
361 cbTag);
362
363 if ( scError != SYMCRYPT_NO_ERROR )
364 {
365 goto cleanup; // wipes pbDst twice, but we don't care about performance in the error case
366 }
367
369
370cleanup:
371 if ( scError != SYMCRYPT_NO_ERROR )
372 {
374 }
375
376 return scError;
377}
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSessionDecryptUpdateState(_Inout_ PSYMCRYPT_SESSION pSession, UINT64 messageNumber)
Definition: session.c:285
VOID SYMCRYPT_CALL SymCryptWipe(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
Definition: libmain.c:137
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
#define SYMCRYPT_STORE_MSBFIRST32(p, v)
Definition: symcrypt.h:311
#define SYMCRYPT_STORE_MSBFIRST64(p, v)
Definition: symcrypt.h:312
SIZE_T cbTag
PCBYTE pbSrc
#define SYMCRYPT_SESSION_MAX_MESSAGE_NUMBER
#define SYMCRYPT_FLAG_SESSION_ENCRYPT
UINT64 cbAuthData
PCBYTE PBYTE SIZE_T cbData
PCBYTE PBYTE pbDst
UINT32 nonce[3]
PCVOID pExpandedKey
unsigned char BYTE
Definition: xxhash.c:193

◆ SymCryptSessionGcmEncrypt()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSessionGcmEncrypt ( _Inout_ PSYMCRYPT_SESSION  pSession,
_In_ PCSYMCRYPT_GCM_EXPANDED_KEY  pExpandedKey,
_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,
_Out_opt_ PUINT64  pu64MessageNumber 
)

Definition at line 87 of file session.c.

98{
99 BYTE nonce[12];
101
103 {
104 return SYMCRYPT_INVALID_ARGUMENT;
105 }
106
107 messageNumber = SYMCRYPT_ATOMIC_ADD64_POST_RELAXED(&pSession->replayState.messageNumber, 1);
108
109 // We do not allow messageNumber to go above some maximum value (currently 2^64 - 2^32)
111 {
112 // Decrement the session messageNumber on the error path so that this session will continue
113 // to only generate errors
114 SYMCRYPT_ATOMIC_ADD64_POST_RELAXED(&pSession->replayState.messageNumber, -1ll);
115 return SYMCRYPT_INVALID_ARGUMENT;
116 }
117
118 SYMCRYPT_STORE_MSBFIRST32(&nonce[0], pSession->senderId);
120
123 nonce,
124 sizeof(nonce),
125 pbAuthData,
127 pbSrc,
128 pbDst,
129 cbData,
130 pbTag,
131 cbTag);
132
133 if( pu64MessageNumber != NULL )
134 {
135 *pu64MessageNumber = messageNumber;
136 }
137
138 return SYMCRYPT_NO_ERROR;
139}
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

◆ SymCryptSessionReceiverInit()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSessionReceiverInit ( _Inout_ PSYMCRYPT_SESSION  pSession,
UINT32  senderId,
UINT32  flags 
)

Definition at line 32 of file session.c.

36{
38
39 // Make sure we only specify the correct flags
40 if (flags != 0)
41 {
42 return SYMCRYPT_INVALID_ARGUMENT;
43 }
44
45#if SYMCRYPT_CPU_AMD64
46 if ( !SYMCRYPT_CPU_FEATURES_PRESENT( SYMCRYPT_CPU_FEATURE_CMPXCHG16B ) )
47 {
49 if( pMutex == NULL )
50 {
51 return SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
52 }
53 }
54#elif SYMCRYPT_CPU_ARM64 // Arm64 always has support for CAS128 - so never need a lock
55#else // 32b and generic platforms will always need to use a lock
57 if( pMutex == NULL )
58 {
59 return SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
60 }
61#endif
62 pSession->pMutex = pMutex;
63
64 // This represents that the message numbers 1-64 inclusive have not yet been successfully use in decryption
65 pSession->replayState.replayMask = 0;
66 pSession->replayState.messageNumber = 64;
67
68 pSession->senderId = senderId;
69 pSession->flags = 0;
70
71 return SYMCRYPT_NO_ERROR;
72}
GLbitfield flags
Definition: glext.h:7161
PVOID SYMCRYPT_CALL SymCryptCallbackAllocateMutexFastInproc(void)
PVOID pMutex
UINT32 senderId

◆ SymCryptSessionSenderInit()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSessionSenderInit ( _Inout_ PSYMCRYPT_SESSION  pSession,
UINT32  senderId,
UINT32  flags 
)

Definition at line 11 of file session.c.

15{
16 // Make sure we only specify the correct flags
17 if (flags != 0)
18 {
19 return SYMCRYPT_INVALID_ARGUMENT;
20 }
21
22 pSession->replayState.messageNumber = 0;
23 pSession->senderId = senderId;
24 pSession->flags = SYMCRYPT_FLAG_SESSION_ENCRYPT;
25 pSession->pMutex = NULL;
26
27 return SYMCRYPT_NO_ERROR;
28}