Skip to content

Commit c0a7fbd

Browse files
committed
Add ChaCha20-Poly1305 cipher algorithm
Latest WDK includes compile-time support for it, and it is available in runtime starting from Windows 11. While on it, add missing BCryptCloseAlorighmProvider calls. Bump version to 0.6.7. Signed-off-by: Lev Stipakov <[email protected]>
1 parent 3630308 commit c0a7fbd

File tree

4 files changed

+55
-13
lines changed

4 files changed

+55
-13
lines changed

PropertySheet.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<PropertyGroup Label="UserMacros">
55
<OVPN_DCO_VERSION_MAJOR>0</OVPN_DCO_VERSION_MAJOR>
66
<OVPN_DCO_VERSION_MINOR>6</OVPN_DCO_VERSION_MINOR>
7-
<OVPN_DCO_VERSION_PATCH>6</OVPN_DCO_VERSION_PATCH>
7+
<OVPN_DCO_VERSION_PATCH>7</OVPN_DCO_VERSION_PATCH>
88
<NETADAPTER_INC_PATH>$(DDK_INC_PATH)\netcx\kmdf\adapter\2.0\</NETADAPTER_INC_PATH>
99
<NETADAPTER_LIB_PATH>$(DDK_LIB_PATH)\netcx\kmdf\adapter\2.0\</NETADAPTER_LIB_PATH>
1010
</PropertyGroup>

crypto.cpp

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,31 @@ OvpnCryptoEncryptNone(OvpnCryptoKeySlot* keySlot, UCHAR* buf, SIZE_T len)
8686

8787
_Use_decl_annotations_
8888
NTSTATUS
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));
9597
done:
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;

crypto.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ typedef OVPN_CRYPTO_DECRYPT* POVPN_CRYPTO_DECRYPT;
7575

7676
struct OvpnCryptoContext
7777
{
78-
BCRYPT_ALG_HANDLE AlgHandle;
78+
BCRYPT_ALG_HANDLE AesAlgHandle;
79+
BCRYPT_ALG_HANDLE ChachaAlgHandle;
7980

8081
OvpnCryptoKeySlot Primary;
8182
OvpnCryptoKeySlot Secondary;
@@ -89,7 +90,11 @@ struct OvpnCryptoContext
8990
_Must_inspect_result_
9091
_IRQL_requires_(PASSIVE_LEVEL)
9192
NTSTATUS
92-
OvpnCryptoInitAlgHandle(_Outptr_ BCRYPT_ALG_HANDLE* algHandle);
93+
OvpnCryptoInitAlgHandles(_Outptr_ BCRYPT_ALG_HANDLE* aesAlgHandle, _Outptr_ BCRYPT_ALG_HANDLE* chachaAlgHandle);
94+
95+
_IRQL_requires_(PASSIVE_LEVEL)
96+
VOID
97+
OvpnCryptoUninitAlgHandles(_In_ BCRYPT_ALG_HANDLE aesAlgHandle, BCRYPT_ALG_HANDLE chachaAlgHandle);
9398

9499
VOID
95100
OvpnCryptoUninit(_In_ OvpnCryptoContext* cryptoContext);

peer.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,13 @@ OvpnPeerNew(POVPN_DEVICE device, WDFREQUEST request)
7272
GOTO_IF_NOT_NT_SUCCESS(done, status, OvpnSocketInit(&driver->WskProviderNpi, peer->Local.Addr4.sin_family, proto_tcp, (PSOCKADDR)&peer->Local,
7373
(PSOCKADDR)&peer->Remote, remoteAddrSize, device, &socket));
7474

75-
BCRYPT_ALG_HANDLE algHandle;
76-
GOTO_IF_NOT_NT_SUCCESS(done, status, OvpnCryptoInitAlgHandle(&algHandle));
75+
BCRYPT_ALG_HANDLE aesAlgHandle = NULL, chachaAlgHandle = NULL;
76+
GOTO_IF_NOT_NT_SUCCESS(done, status, OvpnCryptoInitAlgHandles(&aesAlgHandle, &chachaAlgHandle));
7777

7878
KIRQL kirql = ExAcquireSpinLockExclusive(&device->SpinLock);
7979
RtlZeroMemory(&device->CryptoContext, sizeof(OvpnCryptoContext));
80-
device->CryptoContext.AlgHandle = algHandle;
80+
device->CryptoContext.AesAlgHandle = aesAlgHandle;
81+
device->CryptoContext.ChachaAlgHandle = chachaAlgHandle;
8182
device->Socket.Socket = socket;
8283
device->Socket.Tcp = proto_tcp;
8384
RtlZeroMemory(&device->Socket.TcpState, sizeof(OvpnSocketTcpState));
@@ -221,6 +222,8 @@ OvpnPeerUninit(POVPN_DEVICE device)
221222

222223
LOG_INFO("Uninitializing peer");
223224

225+
BCRYPT_ALG_HANDLE aesAlgHandle = NULL, chachaAlgHandle = NULL;
226+
224227
KIRQL kirql = ExAcquireSpinLockExclusive(&device->SpinLock);
225228

226229
PWSK_SOCKET socket = device->Socket.Socket;
@@ -229,13 +232,18 @@ OvpnPeerUninit(POVPN_DEVICE device)
229232
OvpnTimerDestroy(&device->KeepaliveXmitTimer);
230233
OvpnTimerDestroy(&device->KeepaliveRecvTimer);
231234

235+
aesAlgHandle = device->CryptoContext.AesAlgHandle;
236+
chachaAlgHandle = device->CryptoContext.ChachaAlgHandle;
237+
232238
OvpnCryptoUninit(&device->CryptoContext);
233239

234240
InterlockedExchange(&device->UserspacePid, 0);
235241

236242
// OvpnAdapterDestroy and OvpnUdpCloseSocket require PASSIVE_LEVEL, so must release lock
237243
ExReleaseSpinLockExclusive(&device->SpinLock, kirql);
238244

245+
OvpnCryptoUninitAlgHandles(aesAlgHandle, chachaAlgHandle);
246+
239247
LOG_IF_NOT_NT_SUCCESS(OvpnSocketClose(socket));
240248

241249
OvpnAdapterDestroy(device->Adapter);

0 commit comments

Comments
 (0)