@@ -86,16 +86,31 @@ OvpnCryptoEncryptNone(OvpnCryptoKeySlot* keySlot, UCHAR* buf, SIZE_T len)
8686
8787_Use_decl_annotations_
8888NTSTATUS
89- OvpnCryptoInitAlgHandle (BCRYPT_ALG_HANDLE* algHandle )
89+ OvpnCryptoInitAlgHandles (BCRYPT_ALG_HANDLE* aesAlgHandle, BCRYPT_ALG_HANDLE* chachaAlgHandle )
9090{
9191 NTSTATUS status;
92- GOTO_IF_NOT_NT_SUCCESS (done, status, BCryptOpenAlgorithmProvider (algHandle , BCRYPT_AES_ALGORITHM, NULL , BCRYPT_PROV_DISPATCH));
93- GOTO_IF_NOT_NT_SUCCESS (done, status, BCryptSetProperty (*algHandle , BCRYPT_CHAINING_MODE, (PUCHAR)BCRYPT_CHAIN_MODE_GCM, sizeof (BCRYPT_CHAIN_MODE_GCM), 0 ));
92+ GOTO_IF_NOT_NT_SUCCESS (done, status, BCryptOpenAlgorithmProvider (aesAlgHandle , BCRYPT_AES_ALGORITHM, NULL , BCRYPT_PROV_DISPATCH));
93+ GOTO_IF_NOT_NT_SUCCESS (done, status, BCryptSetProperty (*aesAlgHandle , BCRYPT_CHAINING_MODE, (PUCHAR)BCRYPT_CHAIN_MODE_GCM, sizeof (BCRYPT_CHAIN_MODE_GCM), 0 ));
9494
95+ // available starting from Windows 11
96+ LOG_IF_NOT_NT_SUCCESS (BCryptOpenAlgorithmProvider (chachaAlgHandle, BCRYPT_CHACHA20_POLY1305_ALGORITHM, NULL , BCRYPT_PROV_DISPATCH));
9597done:
9698 return status;
9799}
98100
101+ _Use_decl_annotations_
102+ VOID
103+ OvpnCryptoUninitAlgHandles (_In_ BCRYPT_ALG_HANDLE aesAlgHandle, BCRYPT_ALG_HANDLE chachaAlgHandle)
104+ {
105+ if (aesAlgHandle) {
106+ LOG_IF_NOT_NT_SUCCESS (BCryptCloseAlgorithmProvider (aesAlgHandle, 0 ));
107+ }
108+
109+ if (chachaAlgHandle) {
110+ LOG_IF_NOT_NT_SUCCESS (BCryptCloseAlgorithmProvider (chachaAlgHandle, 0 ));
111+ }
112+ }
113+
99114#define GET_SYSTEM_ADDRESS_MDL (buf, mdl ) { \
100115 buf = (PUCHAR)MmGetSystemAddressForMdlSafe (mdl, LowPagePriority | MdlMappingNoExecute); \
101116 if (buf == NULL ) { \
@@ -222,7 +237,7 @@ OvpnCryptoNewKey(OvpnCryptoContext* cryptoContext, POVPN_CRYPTO_DATA cryptoData)
222237 return STATUS_INVALID_DEVICE_REQUEST;
223238 }
224239
225- if (cryptoData->CipherAlg == OVPN_CIPHER_ALG_AES_GCM) {
240+ if (( cryptoData->CipherAlg == OVPN_CIPHER_ALG_AES_GCM) || (cryptoData-> CipherAlg == OVPN_CIPHER_ALG_CHACHA20_POLY1305) ) {
226241 // destroy previous keys
227242 if (keySlot->EncKey ) {
228243 BCryptDestroyKey (keySlot->EncKey );
@@ -234,9 +249,22 @@ OvpnCryptoNewKey(OvpnCryptoContext* cryptoContext, POVPN_CRYPTO_DATA cryptoData)
234249 keySlot->DecKey = NULL ;
235250 }
236251
252+ BCRYPT_ALG_HANDLE algHandle = NULL ;
253+ if (cryptoData->CipherAlg == OVPN_CIPHER_ALG_AES_GCM) {
254+ algHandle = cryptoContext->AesAlgHandle ;
255+ }
256+ else {
257+ if (cryptoContext->ChachaAlgHandle == NULL ) {
258+ LOG_ERROR (" CHACHA20-POLY1305 is not available" );
259+ status = STATUS_INVALID_DEVICE_REQUEST;
260+ goto done;
261+ }
262+ algHandle = cryptoContext->ChachaAlgHandle ;
263+ }
264+
237265 // generate keys from key materials
238- GOTO_IF_NOT_NT_SUCCESS (done, status, BCryptGenerateSymmetricKey (cryptoContext-> AlgHandle , &keySlot->EncKey , NULL , 0 , cryptoData->Encrypt .Key , cryptoData->Encrypt .KeyLen , 0 ));
239- GOTO_IF_NOT_NT_SUCCESS (done, status, BCryptGenerateSymmetricKey (cryptoContext-> AlgHandle , &keySlot->DecKey , NULL , 0 , cryptoData->Decrypt .Key , cryptoData->Decrypt .KeyLen , 0 ));
266+ GOTO_IF_NOT_NT_SUCCESS (done, status, BCryptGenerateSymmetricKey (algHandle , &keySlot->EncKey , NULL , 0 , cryptoData->Encrypt .Key , cryptoData->Encrypt .KeyLen , 0 ));
267+ GOTO_IF_NOT_NT_SUCCESS (done, status, BCryptGenerateSymmetricKey (algHandle , &keySlot->DecKey , NULL , 0 , cryptoData->Decrypt .Key , cryptoData->Decrypt .KeyLen , 0 ));
240268
241269 // copy nonce tails
242270 RtlCopyMemory (keySlot->EncNonceTail , cryptoData->Encrypt .NonceTail , sizeof (cryptoData->Encrypt .NonceTail ));
@@ -250,7 +278,8 @@ OvpnCryptoNewKey(OvpnCryptoContext* cryptoContext, POVPN_CRYPTO_DATA cryptoData)
250278
251279 cryptoContext->CryptoOverhead = AEAD_CRYPTO_OVERHEAD;
252280
253- LOG_INFO (" Key installed" , TraceLoggingValue (cryptoData->KeyId , " KeyId" ), TraceLoggingValue (cryptoData->KeyId , " PeerId" ));
281+ LOG_INFO (" New key" , TraceLoggingValue (cryptoData->CipherAlg == OVPN_CIPHER_ALG_AES_GCM ? " aes-gcm" : " chacha20-poly1305" , " alg" ),
282+ TraceLoggingValue (cryptoData->KeyId , " KeyId" ), TraceLoggingValue (cryptoData->KeyId , " PeerId" ));
254283 }
255284 else if (cryptoData->CipherAlg == OVPN_CIPHER_ALG_NONE) {
256285 cryptoContext->Encrypt = OvpnCryptoEncryptNone;
0 commit comments