Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for TLSLib, to cover: TLS connection and service creation, Cipher lists settings #1257

Draft
wants to merge 4 commits into
base: dev/202405
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
AuthenticodeTests.c
TSTests.c
DhTests.c
TLSTests.c
RandTests.c
Pkcs7EkuTests.c
OaepEncryptTests.c
Expand All @@ -53,6 +54,7 @@
UnitTestLib
PrintLib
BaseCryptLib
TlsLib

[FixedPcd]
gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceHmacSha256New ## CONSUMES # MU_CHANGE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ SUITE_DESC mSuiteDesc[] = {
{ "Authenticode verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mAuthenticodeTestNum, mAuthenticodeTest },
{ "ImageTimestamp verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mImageTimestampTestNum, mImageTimestampTest },
{ "DH verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mDhTestNum, mDhTest },
{ "TLS verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mTlsTestNum, mTlsTest },
{ "PRNG verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mPrngTestNum, mPrngTest },
{ "OAEP encrypt verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mOaepTestNum, mOaepTest },
{ "Hkdf extract and expand tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mHkdfTestNum, mHkdfTest },
Expand Down
374 changes: 374 additions & 0 deletions CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TLSTests.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,374 @@
/** @file
This is a unit test for RSA OAEP encrypt/decrypt.

Copyright (c) Microsoft Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include "TestBaseCryptLib.h"
#include <Library/TlsLib.h>
// #include <Library/TlsLibNull/InternalTlsLib.h>


typedef void *TLS_OBJ;

// List of Ciphers as appears in TLS Cipher Suite Registry of the IANA
// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml

// TODO: Verify order of bytes is correct in all cases (or use UINT8)
UINT16 mCipherId[] = { 0xC030, // TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
0xC02F, // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
0xC028, // TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
0xC027 // TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
};
#define CIPHER_COUNT (sizeof(mCipherId) / sizeof(mCipherId[0]))


// TODO: Check if we need to test other versions then SSL3.1

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to this https://github.com/microsoft/mu_basecore/blob/dev/202405/MdePkg/Include/IndustryStandard/Tls1.h#L62
it seems that these values correspond to TLS1.0

#define TLS_PROTOCOL_VERSION_MAJOR 0x03
#define TLS_PROTOCOL_VERSION_MINOR 0x01

#define EfiTlsClient 0


UNIT_TEST_STATUS
EFIAPI
TestVerifyTlsPreReq (
UNIT_TEST_CONTEXT Context
)
{
// TODO: Flags to be removed with the refactoring of UEFI PCDs
/*
if (!PcdGetBool (PcdCryptoServiceTlsInitialize) || !PcdGetBool (PcdCryptoServiceTlsCtxNew) || !PcdGetBool (PcdCryptoServiceTlsCtxFree)) {
return UNIT_TEST_ERROR_PREREQUISITE_NOT_MET;
}
*/

return UNIT_TEST_PASSED;
}

VOID
EFIAPI
TestVerifyTlsCleanUp (
UNIT_TEST_CONTEXT Context
)
{
// TODO: Fill in in case needed
}

UNIT_TEST_STATUS
EFIAPI
TestTls31CreatCtxObjNewFree (
IN UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status = TlsInitialize();
UT_ASSERT_TRUE (Status);

TLS_OBJ SslCtxObj = TlsCtxNew(TLS_PROTOCOL_VERSION_MAJOR,TLS_PROTOCOL_VERSION_MINOR);
UT_ASSERT_NOT_NULL(SslCtxObj);

TLS_OBJ TlsObj = TlsNew(SslCtxObj);
UT_ASSERT_NOT_NULL(TlsObj);

// Cleanup
TlsFree(TlsObj);
TlsCtxFree(SslCtxObj);

return UNIT_TEST_PASSED;
}

UNIT_TEST_STATUS
EFIAPI
TestTls31CreateConnection (
IN UNIT_TEST_CONTEXT Context
)
{
EFI_STATUS Status;
BOOLEAN Result;

Result = TlsInitialize();
UT_ASSERT_TRUE (Result);

TLS_OBJ TlsCtx = TlsCtxNew(TLS_PROTOCOL_VERSION_MAJOR,TLS_PROTOCOL_VERSION_MINOR);
UT_ASSERT_NOT_NULL(TlsCtx);

TLS_OBJ TlsConn = TlsNew(TlsCtx);
UT_ASSERT_NOT_NULL(TlsConn);

Status = TlsSetConnectionEnd (TlsConn, EfiTlsClient);
UT_ASSERT_EQUAL(EFI_SUCCESS, Status);

// Cleanup
// NOTE: this is aligned with other tests, but will not be called if test fails
TlsFree(TlsConn);
TlsCtxFree(TlsCtx);

return UNIT_TEST_PASSED;
}


// TODO: Check if we need to call other stages to establish connection
// For example: Handshake, etc.

UNIT_TEST_STATUS
EFIAPI
TestTls31VerifySetCipherList (
IN UNIT_TEST_CONTEXT Context
)
{
UINT16 CipherId = 0;
EFI_STATUS Status;
BOOLEAN Result;

Result = TlsInitialize();
UT_ASSERT_TRUE (Result);

TLS_OBJ TlsCtx = TlsCtxNew(TLS_PROTOCOL_VERSION_MAJOR,TLS_PROTOCOL_VERSION_MINOR);
UT_ASSERT_NOT_NULL(TlsCtx);

TLS_OBJ TlsConn = TlsNew(TlsCtx);
UT_ASSERT_NOT_NULL(TlsConn);

Status = TlsSetConnectionEnd (TlsConn, EfiTlsClient);
UT_ASSERT_EQUAL(EFI_SUCCESS, Status);

Status = TlsSetCipherList (TlsConn, mCipherId, CIPHER_COUNT);
UT_ASSERT_EQUAL(EFI_SUCCESS, Status);

TlsGetCurrentCipher(TlsConn, &CipherId);
UT_ASSERT_EQUAL(EFI_SUCCESS, Status);

BOOLEAN Found = FALSE;

for (int i = 0 ; i < CIPHER_COUNT ; i++) {
if (mCipherId[i] == CipherId) {
Found = TRUE;
break;
}
}
UT_ASSERT_TRUE(Found);

// Cleanup
// NOTE: this is aligned with other tests, but will not be called if test fails
TlsFree(TlsConn);
TlsCtxFree(TlsCtx);

return UNIT_TEST_PASSED;
}

UNIT_TEST_STATUS
EFIAPI
TestTls31GetCurrentCipher (
IN UNIT_TEST_CONTEXT Context
)
{
UINT16 CipherId = 0;
EFI_STATUS Status;
BOOLEAN Result;

Result = TlsInitialize();
UT_ASSERT_TRUE (Result);

TLS_OBJ TlsCtx = TlsCtxNew(TLS_PROTOCOL_VERSION_MAJOR,TLS_PROTOCOL_VERSION_MINOR);
UT_ASSERT_NOT_NULL(TlsCtx);

TLS_OBJ TlsConn = TlsNew(TlsCtx);
UT_ASSERT_NOT_NULL(TlsConn);

TlsGetCurrentCipher(TlsConn, &CipherId);
UT_ASSERT_EQUAL(EFI_SUCCESS, Status);

BOOLEAN Found = FALSE;
// Check if default config support ciphers
for (int i = 0 ; i < CIPHER_COUNT ; i++) {
if (mCipherId[i] == CipherId) {
Found = TRUE;
break;
}
}
UT_ASSERT_TRUE(Found);

Status = TlsSetConnectionEnd (TlsConn, EfiTlsClient);
UT_ASSERT_EQUAL(EFI_SUCCESS, Status);

// Cleanup
// NOTE: this is aligned with other tests, but will not be called if test fails
TlsFree(TlsConn);
TlsCtxFree(TlsCtx);

return UNIT_TEST_PASSED;
}


TEST_DESC mTlsTest[] = {
//
// -----Description--------------------------------Class---------------------Function----------------Pre-----------------Post------------Context
//
{ "TestTls31CreatCtxObjNewFree()", "CryptoPkg.BaseCryptLib.Tls", TestTls31CreatCtxObjNewFree, TestVerifyTlsPreReq, NULL, NULL},
{ "TestTls31CreateConnection()", "CryptoPkg.BaseCryptLib.Tls", TestTls31CreateConnection, TestVerifyTlsPreReq, NULL, NULL},
{ "TestTls31VerifySetCipherList()", "CryptoPkg.BaseCryptLib.Tls", TestTls31VerifySetCipherList, TestVerifyTlsPreReq, NULL, NULL},
{ "TestTls31GetCurrentCipher()", "CryptoPkg.BaseCryptLib.Tls", TestTls31GetCurrentCipher, TestVerifyTlsPreReq, NULL, NULL}
};

UINTN mTlsTestNum = ARRAY_SIZE (mTlsTest);



// ~~~~ TODO: check if any of these tests are needed ~~~~

/*
UNIT_TEST_STATUS
EFIAPI
TestTlsHandleAlert (
VOID
)
{
BOOLEAN Status = TlsInitialize();
UT_ASSERT_TRUE (Status);

auto SslCtxObj = TlsCtxNew(3,1);
UT_ASSERT_NOT_NULL(SslCtxObj);

auto TlsObj = TlsNew(SslCtxObj);
UT_ASSERT_NOT_NULL(TlsObj);

Status = TlsHandleAlert(TlsObj, NULL, 0, NULL, NULL);
UT_ASSERT_TRUE(Status);

// Cleanup
TlsFree(TlsObj);
TlsCtxFree(SslCtxObj);

return UNIT_TEST_PASSED;
}

UNIT_TEST_STATUS
EFIAPI
TestTlsCloseNotify (
VOID
)
{
BOOLEAN Status = TlsInitialize();
UT_ASSERT_TRUE (Status);

auto SslCtxObj = TlsCtxNew(3,1);
UT_ASSERT_NOT_NULL(SslCtxObj);

auto TlsObj = TlsNew(SslCtxObj);
UT_ASSERT_NOT_NULL(TlsObj);

Status = TlsCloseNotify(TlsObj, NULL, NULL);
UT_ASSERT_TRUE(Status);

// Cleanup
TlsFree(TlsObj);
TlsCtxFree(SslCtxObj);

return UNIT_TEST_PASSED;
}

UNIT_TEST_STATUS
EFIAPI
TestTlsCtrlTrafficOut (
VOID
)
{
BOOLEAN Status = TlsInitialize();
UT_ASSERT_TRUE (Status);

auto SslCtxObj = TlsCtxNew(3,1);
UT_ASSERT_NOT_NULL(SslCtxObj);

auto TlsObj = TlsNew(SslCtxObj);
UT_ASSERT_NOT_NULL(TlsObj);

Status = TlsCtrlTrafficOut(TlsObj, NULL, 0);
UT_ASSERT_TRUE(Status);

// Cleanup
TlsFree(TlsObj);
TlsCtxFree(SslCtxObj);

return UNIT_TEST_PASSED;
}

UNIT_TEST_STATUS
EFIAPI
TestTlsCtrlTrafficIn (
VOID
)
{
BOOLEAN Status = TlsInitialize();
UT_ASSERT_TRUE (Status);

auto SslCtxObj = TlsCtxNew(3,1);
UT_ASSERT_NOT_NULL(SslCtxObj);

auto TlsObj = TlsNew(SslCtxObj);
UT_ASSERT_NOT_NULL(TlsObj);

Status = TlsCtrlTrafficIn(TlsObj, NULL, 0);
UT_ASSERT_TRUE(Status);

// Cleanup
TlsFree(TlsObj);
TlsCtxFree(SslCtxObj);

return UNIT_TEST_PASSED;
}

UNIT_TEST_STATUS
EFIAPI
TestTlsRead (
VOID
)
{
BOOLEAN Status = TlsInitialize();
UT_ASSERT_TRUE (Status);

auto SslCtxObj = TlsCtxNew(3,1);
UT_ASSERT_NOT_NULL(SslCtxObj);

auto TlsObj = TlsNew(SslCtxObj);
UT_ASSERT_NOT_NULL(TlsObj);

UINT8 Buffer[256];
UINTN BufferSize = sizeof(Buffer);
Status = TlsRead(TlsObj, Buffer, &BufferSize);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UT_ASSERT_TRUE(Status);

// Cleanup
TlsFree(TlsObj);
TlsCtxFree(SslCtxObj);

return UNIT_TEST_PASSED;
}

UNIT_TEST_STATUS
EFIAPI
TestTlsWrite (
VOID
)
{
BOOLEAN Status = TlsInitialize();
UT_ASSERT_TRUE (Status);

auto SslCtxObj = TlsCtxNew(3,1);
UT_ASSERT_NOT_NULL(SslCtxObj);

auto TlsObj = TlsNew(SslCtxObj);
UT_ASSERT_NOT_NULL(TlsObj);

UINT8 Buffer[256] = {0};
UINTN BufferSize = sizeof(Buffer);
Status = TlsWrite(SslCtxObj, Buffer, BufferSize);
UT_ASSERT_TRUE(Status);

// Cleanup
TlsFree(TlsObj);
TlsCtxFree(SslCtxObj);

return UNIT_TEST_PASSED;
}
*/
Loading
Loading