Skip to content

Commit

Permalink
[release/2.1] make chacha optional on Linux (#3492)
Browse files Browse the repository at this point in the history
* make chacha optional on Linux (#3423)

* another attempt to fix quic loading when chacha is missing (#3447)

* Update src/platform/crypt_openssl.c

* CxPlatCryptInitialize

* CxPlatCryptUninitialize

---------

Co-authored-by: Nick Banks <nibanks@microsoft.com>
  • Loading branch information
wfurt and nibanks committed Mar 16, 2023
1 parent d936a5e commit c6931cb
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 21 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,10 @@ if(QUIC_TLS STREQUAL "openssl")
)
endif()

if (QUIC_USE_SYSTEM_LIBCRYPTO)
list(APPEND QUIC_COMMON_DEFINES CXPLAT_SYSTEM_CRYPTO)
endif()

if(QUIC_CODE_CHECK)
find_program(CLANGTIDY NAMES clang-tidy)
if(CLANGTIDY)
Expand Down
8 changes: 4 additions & 4 deletions src/generated/linux/tls_openssl.c.clog.h
Original file line number Diff line number Diff line change
Expand Up @@ -549,10 +549,10 @@ tracepoint(CLOG_TLS_OPENSSL_C, TlsErrorStatus , arg2, arg3, arg4);\
// Decoder Ring for LibraryErrorStatus
// [ lib] ERROR, %u, %s.
// QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
CredConfig->AllowedCipherSuites,
"No valid cipher suites presented");
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
CredConfig->AllowedCipherSuites,
"No valid cipher suites presented");
// arg2 = arg2 = CredConfig->AllowedCipherSuites = arg2
// arg3 = arg3 = "No valid cipher suites presented" = arg3
----------------------------------------------------------*/
Expand Down
8 changes: 4 additions & 4 deletions src/generated/linux/tls_openssl.c.clog.h.lttng.h
Original file line number Diff line number Diff line change
Expand Up @@ -587,10 +587,10 @@ TRACEPOINT_EVENT(CLOG_TLS_OPENSSL_C, TlsErrorStatus,
// Decoder Ring for LibraryErrorStatus
// [ lib] ERROR, %u, %s.
// QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
CredConfig->AllowedCipherSuites,
"No valid cipher suites presented");
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
CredConfig->AllowedCipherSuites,
"No valid cipher suites presented");
// arg2 = arg2 = CredConfig->AllowedCipherSuites = arg2
// arg3 = arg3 = "No valid cipher suites presented" = arg3
----------------------------------------------------------*/
Expand Down
5 changes: 5 additions & 0 deletions src/inc/quic_crypt.h
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,11 @@ CxPlatHashCompute(
uint8_t* const Output
);

BOOLEAN
CxPlatCryptSupports(
CXPLAT_AEAD_TYPE AeadType
);

#if defined(__cplusplus)
}
#endif
17 changes: 17 additions & 0 deletions src/platform/crypt_bcrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,23 @@ CxPlatCryptInitialize(
#endif
}

BOOLEAN
CxPlatCryptSupports(
CXPLAT_AEAD_TYPE AeadType
)
{
switch (AeadType) {
case CXPLAT_AEAD_AES_128_GCM:
return TRUE;
case CXPLAT_AEAD_AES_256_GCM:
return TRUE;
case CXPLAT_AEAD_CHACHA20_POLY1305:
return CXPLAT_CHACHA20_POLY1305_ALG_HANDLE != NULL;
default:
return FALSE;
}
}

void
CxPlatCryptUninitialize(
void
Expand Down
70 changes: 66 additions & 4 deletions src/platform/crypt_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable:4100) // Unreferenced parameter errcode in inline function
#else
#include <dlfcn.h>
#endif
#include "openssl/bio.h"
#ifdef IS_OPENSSL_3
Expand All @@ -41,11 +43,25 @@
#include "crypt_openssl.c.clog.h"
#endif

EVP_CIPHER *CXPLAT_CHACHA20_ALG_HANDLE;
EVP_CIPHER *CXPLAT_CHACHA20_POLY1305_ALG_HANDLE;

typedef struct CXPLAT_HP_KEY {
EVP_CIPHER_CTX* CipherCtx;
CXPLAT_AEAD_TYPE Aead;
} CXPLAT_HP_KEY;


#if defined CXPLAT_SYSTEM_CRYPTO && !defined _WIN32
// This is to fulfill link dependency in ssl_init.
// If system OpenSSL has chacha support, we will redirect it to loaded handle.
//
const EVP_CIPHER *EVP_chacha20_poly1305(void)
{
return CXPLAT_CHACHA20_POLY1305_ALG_HANDLE;
}
#endif

QUIC_STATUS
CxPlatCryptInitialize(
void
Expand All @@ -65,14 +81,52 @@ CxPlatCryptInitialize(
//

ERR_clear_error();
#if defined _WIN32 || !defined CXPLAT_SYSTEM_CRYPTO
CXPLAT_CHACHA20_ALG_HANDLE = (EVP_CIPHER *)EVP_chacha20();
CXPLAT_CHACHA20_POLY1305_ALG_HANDLE = (EVP_CIPHER *)EVP_chacha20_poly1305();
#else
CXPLAT_CHACHA20_ALG_HANDLE = NULL;
CXPLAT_CHACHA20_POLY1305_ALG_HANDLE = NULL;

//
// LINUX_TODO:Add Check for openssl library QUIC support.
// Try to load ChaCha20 ciphers dynamically. They may or may not exist when using system crypto.
//

void* handle = dlopen("libcrypto.so.1.1", RTLD_LAZY | RTLD_GLOBAL);
EVP_CIPHER* (*func)(void) = NULL;
if (handle != NULL) {
func = dlsym(handle, "EVP_chacha20");
if (func != NULL) {
CXPLAT_CHACHA20_ALG_HANDLE = (*func)();

func = dlsym(handle, "EVP_chacha20_poly1305");
if (func != NULL) {
CXPLAT_CHACHA20_POLY1305_ALG_HANDLE = (*func)();
EVP_add_cipher(CXPLAT_CHACHA20_POLY1305_ALG_HANDLE);
}
} else {
dlclose(handle);
}
}
#endif
return QUIC_STATUS_SUCCESS;
}

BOOLEAN
CxPlatCryptSupports(
CXPLAT_AEAD_TYPE AeadType
)
{
switch (AeadType) {
case CXPLAT_AEAD_AES_128_GCM:
case CXPLAT_AEAD_AES_256_GCM:
return TRUE;
case CXPLAT_AEAD_CHACHA20_POLY1305:
return CXPLAT_CHACHA20_ALG_HANDLE != NULL;
default:
return FALSE;
}
}

void
CxPlatCryptUninitialize(
void
Expand Down Expand Up @@ -112,7 +166,11 @@ CxPlatKeyCreate(
Aead = EVP_aes_256_gcm();
break;
case CXPLAT_AEAD_CHACHA20_POLY1305:
Aead = EVP_chacha20_poly1305();
if (CXPLAT_CHACHA20_POLY1305_ALG_HANDLE == NULL) {
Status = QUIC_STATUS_NOT_SUPPORTED;
goto Exit;
}
Aead = CXPLAT_CHACHA20_POLY1305_ALG_HANDLE;
break;
default:
Status = QUIC_STATUS_NOT_SUPPORTED;
Expand Down Expand Up @@ -338,7 +396,11 @@ CxPlatHpKeyCreate(
Aead = EVP_aes_256_ecb();
break;
case CXPLAT_AEAD_CHACHA20_POLY1305:
Aead = EVP_chacha20();
if (CXPLAT_CHACHA20_ALG_HANDLE == NULL) {
Status = QUIC_STATUS_NOT_SUPPORTED;
goto Exit;
}
Aead = CXPLAT_CHACHA20_ALG_HANDLE;
break;
default:
Status = QUIC_STATUS_NOT_SUPPORTED;
Expand Down
10 changes: 10 additions & 0 deletions src/platform/platform_posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,16 @@ CxPlatInitialize(
goto Exit;
}

Status = CxPlatCryptInitialize();
if (QUIC_FAILED(Status)) {
if (RandomFd != -1) {
close(RandomFd);
}
return Status;
}

if (!CxPlatWorkersInit()) {
CxPlatCryptUninitialize();
Status = QUIC_STATUS_OUT_OF_MEMORY;
goto Exit;
}
Expand Down Expand Up @@ -236,6 +245,7 @@ CxPlatUninitialize(
)
{
CxPlatWorkersUninit();
CxPlatCryptUninitialize();
close(RandomFd);
QuicTraceLogInfo(
PosixUninitialized,
Expand Down
36 changes: 27 additions & 9 deletions src/platform/tls_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1030,17 +1030,27 @@ CxPlatTlsSecConfigCreate(
return QUIC_STATUS_NOT_SUPPORTED;
}

if (CredConfigFlags & QUIC_CREDENTIAL_FLAG_SET_ALLOWED_CIPHER_SUITES &&
((CredConfig->AllowedCipherSuites &
if (CredConfigFlags & QUIC_CREDENTIAL_FLAG_SET_ALLOWED_CIPHER_SUITES) {
if ((CredConfig->AllowedCipherSuites &
(QUIC_ALLOWED_CIPHER_SUITE_AES_128_GCM_SHA256 |
QUIC_ALLOWED_CIPHER_SUITE_AES_256_GCM_SHA384 |
QUIC_ALLOWED_CIPHER_SUITE_CHACHA20_POLY1305_SHA256)) == 0)) {
QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
CredConfig->AllowedCipherSuites,
"No valid cipher suites presented");
return QUIC_STATUS_INVALID_PARAMETER;
QUIC_ALLOWED_CIPHER_SUITE_CHACHA20_POLY1305_SHA256)) == 0) {
QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
CredConfig->AllowedCipherSuites,
"No valid cipher suites presented");
return QUIC_STATUS_INVALID_PARAMETER;
}
if (CredConfig->AllowedCipherSuites == QUIC_ALLOWED_CIPHER_SUITE_CHACHA20_POLY1305_SHA256 &&
!CxPlatCryptSupports(CXPLAT_AEAD_CHACHA20_POLY1305)) {
QuicTraceEvent(
LibraryErrorStatus,
"[ lib] ERROR, %u, %s.",
CredConfig->AllowedCipherSuites,
"Only CHACHA requested but not available");
return QUIC_STATUS_NOT_SUPPORTED;
}
}

QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
Expand Down Expand Up @@ -1127,6 +1137,10 @@ CxPlatTlsSecConfigCreate(
AllowedCipherSuitesCount++;
}
if (CredConfig->AllowedCipherSuites & QUIC_ALLOWED_CIPHER_SUITE_CHACHA20_POLY1305_SHA256) {
if (AllowedCipherSuitesCount == 0 && !CxPlatCryptSupports(CXPLAT_AEAD_CHACHA20_POLY1305)) {
Status = QUIC_STATUS_NOT_SUPPORTED;
goto Exit;
}
CipherSuiteStringLength += (uint8_t)sizeof(CXPLAT_TLS_CHACHA20_POLY1305_SHA256);
AllowedCipherSuitesCount++;
}
Expand Down Expand Up @@ -1630,6 +1644,10 @@ CxPlatTlsInitialize(
UNREFERENCED_PARAMETER(State);

CXPLAT_DBG_ASSERT(Config->HkdfLabels);
if (Config->SecConfig == NULL) {
Status = QUIC_STATUS_INVALID_PARAMETER;
goto Exit;
}

TlsContext = CXPLAT_ALLOC_NONPAGED(sizeof(CXPLAT_TLS), QUIC_POOL_TLS_CTX);
if (TlsContext == NULL) {
Expand Down
2 changes: 2 additions & 0 deletions src/platform/unittest/TlsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -964,9 +964,11 @@ TEST_F(TlsTest, HandshakeParamInfoChaCha20)
CxPlatServerSecConfig ServerConfig(
QUIC_CREDENTIAL_FLAG_SET_ALLOWED_CIPHER_SUITES,
QUIC_ALLOWED_CIPHER_SUITE_CHACHA20_POLY1305_SHA256);

TlsContext ServerContext, ClientContext;
ClientContext.InitializeClient(ClientConfig);
ServerContext.InitializeServer(ServerConfig);
ASSERT_NE(ServerConfig.SecConfig, nullptr);
DoHandshake(ServerContext, ClientContext);

QUIC_HANDSHAKE_INFO HandshakeInfo;
Expand Down

0 comments on commit c6931cb

Please sign in to comment.