blob: e84856dd6a839a9977b4ad243ba1613cf67289f9 [file]
/** @file
Application for ML-DSA Primitives Validation.
This file contains unit tests for the ML-DSA (Module-Lattice-Based Digital Signature Algorithm)
cryptographic functions defined in CryptMlDsa.c. ML-DSA is a post-quantum digital signature
scheme based on the CRYSTALS-Dilithium algorithm and standardized in FIPS 204.
The test vectors are provided in MlDsaTestVectors.h which contains:
- mMlDsa87TestCert[] - X.509 DER certificate with ML-DSA-87 public key
- mMlDsa87TestPemKey[] - PEM-encoded ML-DSA-87 private key
The test structure mirrors EdDsaTests.c and validates:
- Context creation and destruction (MlDsaNewByNid, MlDsaFree)
- Key setting and retrieval error cases (MlDsaSetPrivKey, MlDsaSetPubKey, MlDsaGetPubKey)
- Signature generation and verification via PEM/X509 (TestVerifyMlDsaPemX509)
- Error handling for invalid inputs
NOTE: TestVerifyMlDsaSignVerify() and TestVerifyMlDsaSignVerifyWithContext() are
currently skipped as they require raw key arrays. The main signing/verification test
is TestVerifyMlDsaPemX509() which uses real PEM and X509 test vectors.
Copyright (c) 2026, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "TestBaseCryptLib.h"
#define ML_DSA_87_PRIVATE_KEY_SIZE 4896
#define ML_DSA_87_PUBLIC_KEY_SIZE 2592
#define ML_DSA_87_SIGNATURE_SIZE 4627
#define ML_DSA_MAX_CONTEXT_SIZE 255
//
// ML-DSA-87 test vectors - include generated certificate and PEM key
//
#include "MlDsaTestVectors.h"
//
// Test message for signing and verification
//
CONST CHAR8 *mMlDsaTestMessage = "Test message for ML-DSA signing and verification";
//
// Optional context string for domain separation
//
CONST CHAR8 *mMlDsaTestContext = "ML-DSA test context";
VOID *MlDsaContext1;
VOID *MlDsaContext2;
/**
Prerequisite function for ML-DSA tests.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaPreReq (
UNIT_TEST_CONTEXT Context
)
{
MlDsaContext1 = NULL;
MlDsaContext2 = NULL;
return UNIT_TEST_PASSED;
}
/**
Cleanup function for ML-DSA tests.
@param[in] Context Unit test context.
**/
VOID
EFIAPI
TestVerifyMlDsaCleanUp (
UNIT_TEST_CONTEXT Context
)
{
if (MlDsaContext1 != NULL) {
MlDsaFree (MlDsaContext1);
MlDsaContext1 = NULL;
}
if (MlDsaContext2 != NULL) {
MlDsaFree (MlDsaContext2);
MlDsaContext2 = NULL;
}
}
/**
Validate UEFI-OpenSSL ML-DSA Context Creation.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaNew (
UNIT_TEST_CONTEXT Context
)
{
//
// Test MlDsaNewByNid with ML-DSA-87
//
MlDsaContext1 = MlDsaNewByNid (CRYPTO_NID_ML_DSA_87);
UT_ASSERT_NOT_NULL (MlDsaContext1);
//
// Test MlDsaNewByNid with invalid NID
//
MlDsaContext2 = MlDsaNewByNid (CRYPTO_NID_NULL);
UT_ASSERT_EQUAL ((UINTN)MlDsaContext2, (UINTN)NULL);
//
// Test MlDsaFree
//
MlDsaFree (MlDsaContext1);
MlDsaContext1 = NULL;
//
// Test MlDsaFree with NULL (should not crash)
//
MlDsaFree (NULL);
return UNIT_TEST_PASSED;
}
/**
Validate UEFI-OpenSSL ML-DSA Key Setting and Getting.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaKeySetGet (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
UINT8 PublicKey[ML_DSA_87_PUBLIC_KEY_SIZE];
UINTN PublicKeySize;
UINT8 TooSmallBuffer[10];
UINTN TooSmallSize;
//
// Create ML-DSA context
//
MlDsaContext1 = MlDsaNewByNid (CRYPTO_NID_ML_DSA_87);
UT_ASSERT_NOT_NULL (MlDsaContext1);
//
// Test MlDsaGetPubKey with too small buffer (before key is set)
//
TooSmallSize = sizeof (TooSmallBuffer);
Status = MlDsaGetPubKey (MlDsaContext1, TooSmallBuffer, &TooSmallSize);
UT_ASSERT_FALSE (Status);
UT_ASSERT_NOT_EQUAL (TooSmallSize, ML_DSA_87_PUBLIC_KEY_SIZE);
//
// Test MlDsaSetPrivKey with NULL context
//
Status = MlDsaSetPrivKey (NULL, (UINT8 *)mMlDsa87TestPemKey, 100);
UT_ASSERT_FALSE (Status);
//
// Test MlDsaSetPrivKey with NULL key
//
Status = MlDsaSetPrivKey (MlDsaContext1, NULL, ML_DSA_87_PRIVATE_KEY_SIZE);
UT_ASSERT_FALSE (Status);
//
// Test MlDsaSetPrivKey with wrong size
//
Status = MlDsaSetPrivKey (MlDsaContext1, (UINT8 *)mMlDsa87TestPemKey, 32);
UT_ASSERT_FALSE (Status);
//
// Test MlDsaSetPubKey with NULL context
//
Status = MlDsaSetPubKey (NULL, (UINT8 *)mMlDsa87TestCert, 100);
UT_ASSERT_FALSE (Status);
//
// Test MlDsaSetPubKey with NULL key
//
Status = MlDsaSetPubKey (MlDsaContext1, NULL, ML_DSA_87_PUBLIC_KEY_SIZE);
UT_ASSERT_FALSE (Status);
//
// Test MlDsaSetPubKey with wrong size
//
Status = MlDsaSetPubKey (MlDsaContext1, (UINT8 *)mMlDsa87TestCert, 32);
UT_ASSERT_FALSE (Status);
//
// Test MlDsaGetPubKey with NULL context
//
PublicKeySize = sizeof (PublicKey);
Status = MlDsaGetPubKey (NULL, PublicKey, &PublicKeySize);
UT_ASSERT_FALSE (Status);
//
// Test MlDsaGetPubKey with NULL size
//
Status = MlDsaGetPubKey (MlDsaContext1, PublicKey, NULL);
UT_ASSERT_FALSE (Status);
//
// Clean up context
//
MlDsaFree (MlDsaContext1);
MlDsaContext1 = NULL;
return UNIT_TEST_PASSED;
}
/**
Validate ML-DSA error cases.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaErrorCases (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
UINT8 Signature[ML_DSA_87_SIGNATURE_SIZE];
UINTN SigSize;
UINT8 TooSmallBuffer[10];
UINTN TooSmallSize;
//
// Create ML-DSA context
//
MlDsaContext1 = MlDsaNewByNid (CRYPTO_NID_ML_DSA_87);
UT_ASSERT_NOT_NULL (MlDsaContext1);
//
// Test MlDsaSign with NULL context
//
SigSize = sizeof (Signature);
Status = MlDsaSign (
NULL,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
AsciiStrLen (mMlDsaTestMessage),
Signature,
&SigSize
);
UT_ASSERT_FALSE (Status);
//
// Test MlDsaSign with NULL message
//
SigSize = sizeof (Signature);
Status = MlDsaSign (
MlDsaContext1,
NULL,
0,
NULL,
0,
Signature,
&SigSize
);
UT_ASSERT_FALSE (Status);
//
// Test MlDsaSign with too small buffer
//
TooSmallSize = sizeof (TooSmallBuffer);
Status = MlDsaSign (
MlDsaContext1,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
AsciiStrLen (mMlDsaTestMessage),
TooSmallBuffer,
&TooSmallSize
);
UT_ASSERT_FALSE (Status);
UT_ASSERT_NOT_EQUAL (TooSmallSize, sizeof (Signature));
//
// Test MlDsaVerify with NULL context
//
Status = MlDsaVerify (
NULL,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
AsciiStrLen (mMlDsaTestMessage),
Signature,
sizeof (Signature)
);
UT_ASSERT_FALSE (Status);
//
// Test MlDsaVerify with NULL message
//
Status = MlDsaVerify (
MlDsaContext1,
NULL,
0,
NULL,
0,
Signature,
sizeof (Signature)
);
UT_ASSERT_FALSE (Status);
//
// Test MlDsaVerify with NULL signature
//
Status = MlDsaVerify (
MlDsaContext1,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
AsciiStrLen (mMlDsaTestMessage),
NULL,
sizeof (Signature)
);
UT_ASSERT_FALSE (Status);
//
// Test MlDsaVerify with zero signature size
//
Status = MlDsaVerify (
MlDsaContext1,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
AsciiStrLen (mMlDsaTestMessage),
Signature,
0
);
UT_ASSERT_FALSE (Status);
return UNIT_TEST_PASSED;
}
/**
Validate ML-DSA key retrieval from PEM and X509.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaPemX509 (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *MlDsaPrivKey;
VOID *MlDsaPubKey;
UINT8 Signature[ML_DSA_87_SIGNATURE_SIZE];
UINTN SigSize;
UINTN MessageSize;
MlDsaPrivKey = NULL;
MlDsaPubKey = NULL;
MessageSize = AsciiStrLen (mMlDsaTestMessage);
//
// Retrieve ML-DSA private key from PEM data.
//
Status = MlDsaGetPrivateKeyFromPem (
mMlDsa87TestPemKey,
sizeof (mMlDsa87TestPemKey),
NULL,
&MlDsaPrivKey
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_NOT_NULL (MlDsaPrivKey);
//
// Retrieve ML-DSA public key from X509 certificate.
//
Status = MlDsaGetPublicKeyFromX509 (
mMlDsa87TestCert,
sizeof (mMlDsa87TestCert),
&MlDsaPubKey
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_NOT_NULL (MlDsaPubKey);
//
// ML-DSA signing with key from PEM (no context string)
//
SigSize = sizeof (Signature);
Status = MlDsaSign (
MlDsaPrivKey,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
MessageSize,
Signature,
&SigSize
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_EQUAL (SigSize, ML_DSA_87_SIGNATURE_SIZE);
//
// ML-DSA verification with key from X509
//
Status = MlDsaVerify (
MlDsaPubKey,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
MessageSize,
Signature,
SigSize
);
UT_ASSERT_TRUE (Status);
MlDsaFree (MlDsaPrivKey);
MlDsaFree (MlDsaPubKey);
return UNIT_TEST_PASSED;
}
/**
Validate ML-DSA signing and verification with context string.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaSignVerifyWithContext (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *MlDsaPrivKey;
VOID *MlDsaPubKey;
UINT8 Signature[ML_DSA_87_SIGNATURE_SIZE];
UINTN SigSize;
UINTN MessageSize;
UINTN ContextSize;
MlDsaPrivKey = NULL;
MlDsaPubKey = NULL;
MessageSize = AsciiStrLen (mMlDsaTestMessage);
ContextSize = AsciiStrLen (mMlDsaTestContext);
//
// Retrieve ML-DSA private key from PEM data.
//
Status = MlDsaGetPrivateKeyFromPem (
mMlDsa87TestPemKey,
sizeof (mMlDsa87TestPemKey),
NULL,
&MlDsaPrivKey
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_NOT_NULL (MlDsaPrivKey);
//
// Retrieve ML-DSA public key from X509 certificate.
//
Status = MlDsaGetPublicKeyFromX509 (
mMlDsa87TestCert,
sizeof (mMlDsa87TestCert),
&MlDsaPubKey
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_NOT_NULL (MlDsaPubKey);
//
// ML-DSA signing with context string
//
SigSize = sizeof (Signature);
Status = MlDsaSign (
MlDsaPrivKey,
(UINT8 *)mMlDsaTestContext,
ContextSize,
(UINT8 *)mMlDsaTestMessage,
MessageSize,
Signature,
&SigSize
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_EQUAL (SigSize, ML_DSA_87_SIGNATURE_SIZE);
//
// ML-DSA verification with matching context string
//
Status = MlDsaVerify (
MlDsaPubKey,
(UINT8 *)mMlDsaTestContext,
ContextSize,
(UINT8 *)mMlDsaTestMessage,
MessageSize,
Signature,
SigSize
);
UT_ASSERT_TRUE (Status);
//
// ML-DSA verification should fail with mismatched context string
//
Status = MlDsaVerify (
MlDsaPubKey,
(UINT8 *)"Different context",
AsciiStrLen ("Different context"),
(UINT8 *)mMlDsaTestMessage,
MessageSize,
Signature,
SigSize
);
UT_ASSERT_FALSE (Status);
//
// ML-DSA verification should fail with no context when signature used context
//
Status = MlDsaVerify (
MlDsaPubKey,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
MessageSize,
Signature,
SigSize
);
UT_ASSERT_FALSE (Status);
MlDsaFree (MlDsaPrivKey);
MlDsaFree (MlDsaPubKey);
return UNIT_TEST_PASSED;
}
/**
Validate ML-DSA public key extraction and generation.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaGetPubKey (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *MlDsaPrivKey;
UINT8 PublicKey[ML_DSA_87_PUBLIC_KEY_SIZE];
UINTN PublicKeySize;
MlDsaPrivKey = NULL;
//
// Retrieve ML-DSA private key from PEM data.
//
Status = MlDsaGetPrivateKeyFromPem (
mMlDsa87TestPemKey,
sizeof (mMlDsa87TestPemKey),
NULL,
&MlDsaPrivKey
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_NOT_NULL (MlDsaPrivKey);
//
// Get public key from private key context
//
PublicKeySize = sizeof (PublicKey);
Status = MlDsaGetPubKey (
MlDsaPrivKey,
PublicKey,
&PublicKeySize
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_EQUAL (PublicKeySize, ML_DSA_87_PUBLIC_KEY_SIZE);
//
// Verify the public key buffer is not all zeros
//
BOOLEAN AllZeros;
UINTN Index;
AllZeros = TRUE;
for (Index = 0; Index < PublicKeySize; Index++) {
if (PublicKey[Index] != 0) {
AllZeros = FALSE;
break;
}
}
UT_ASSERT_FALSE (AllZeros);
MlDsaFree (MlDsaPrivKey);
return UNIT_TEST_PASSED;
}
/**
Validate ML-DSA signature verification fails with tampered data.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaTamperedData (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *MlDsaPrivKey;
VOID *MlDsaPubKey;
UINT8 Signature[ML_DSA_87_SIGNATURE_SIZE];
UINT8 TamperedSignature[ML_DSA_87_SIGNATURE_SIZE];
CHAR8 TamperedMessage[100];
UINTN SigSize;
UINTN MessageSize;
MlDsaPrivKey = NULL;
MlDsaPubKey = NULL;
MessageSize = AsciiStrLen (mMlDsaTestMessage);
//
// Retrieve ML-DSA private key from PEM data.
//
Status = MlDsaGetPrivateKeyFromPem (
mMlDsa87TestPemKey,
sizeof (mMlDsa87TestPemKey),
NULL,
&MlDsaPrivKey
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_NOT_NULL (MlDsaPrivKey);
//
// Retrieve ML-DSA public key from X509 certificate.
//
Status = MlDsaGetPublicKeyFromX509 (
mMlDsa87TestCert,
sizeof (mMlDsa87TestCert),
&MlDsaPubKey
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_NOT_NULL (MlDsaPubKey);
//
// Generate valid signature
//
SigSize = sizeof (Signature);
Status = MlDsaSign (
MlDsaPrivKey,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
MessageSize,
Signature,
&SigSize
);
UT_ASSERT_TRUE (Status);
//
// Verify original signature works
//
Status = MlDsaVerify (
MlDsaPubKey,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
MessageSize,
Signature,
SigSize
);
UT_ASSERT_TRUE (Status);
//
// Test with tampered message (should fail)
//
AsciiStrCpyS (TamperedMessage, sizeof (TamperedMessage), mMlDsaTestMessage);
TamperedMessage[0] = 'X';
Status = MlDsaVerify (
MlDsaPubKey,
NULL,
0,
(UINT8 *)TamperedMessage,
MessageSize,
Signature,
SigSize
);
UT_ASSERT_FALSE (Status);
//
// Test with tampered signature (should fail)
//
CopyMem (TamperedSignature, Signature, sizeof (Signature));
TamperedSignature[0] ^= 0x01;
Status = MlDsaVerify (
MlDsaPubKey,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
MessageSize,
TamperedSignature,
SigSize
);
UT_ASSERT_FALSE (Status);
//
// Test with wrong signature size (should fail)
//
Status = MlDsaVerify (
MlDsaPubKey,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
MessageSize,
Signature,
SigSize - 1
);
UT_ASSERT_FALSE (Status);
MlDsaFree (MlDsaPrivKey);
MlDsaFree (MlDsaPubKey);
return UNIT_TEST_PASSED;
}
/**
Validate ML-DSA PEM loading error cases.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaPemErrors (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *MlDsaKey;
MlDsaKey = NULL;
//
// Test MlDsaGetPrivateKeyFromPem with NULL PEM data
//
Status = MlDsaGetPrivateKeyFromPem (
NULL,
100,
NULL,
&MlDsaKey
);
UT_ASSERT_FALSE (Status);
//
// Test MlDsaGetPrivateKeyFromPem with NULL context pointer
//
Status = MlDsaGetPrivateKeyFromPem (
mMlDsa87TestPemKey,
sizeof (mMlDsa87TestPemKey),
NULL,
NULL
);
UT_ASSERT_FALSE (Status);
//
// Test MlDsaGetPrivateKeyFromPem with invalid PEM data
//
Status = MlDsaGetPrivateKeyFromPem (
(UINT8 *)"Invalid PEM data",
16,
NULL,
&MlDsaKey
);
UT_ASSERT_FALSE (Status);
//
// Test MlDsaGetPublicKeyFromX509 with NULL certificate
//
Status = MlDsaGetPublicKeyFromX509 (
NULL,
100,
&MlDsaKey
);
UT_ASSERT_FALSE (Status);
//
// Test MlDsaGetPublicKeyFromX509 with NULL context pointer
//
Status = MlDsaGetPublicKeyFromX509 (
mMlDsa87TestCert,
sizeof (mMlDsa87TestCert),
NULL
);
UT_ASSERT_FALSE (Status);
//
// Test MlDsaGetPublicKeyFromX509 with invalid certificate data
//
Status = MlDsaGetPublicKeyFromX509 (
(UINT8 *)"Invalid cert data",
17,
&MlDsaKey
);
UT_ASSERT_FALSE (Status);
return UNIT_TEST_PASSED;
}
/**
Validate ML-DSA operations on context without keys.
This test validates that operations fail properly when no key is set.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaNoKeyOperations (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
UINT8 Signature[ML_DSA_87_SIGNATURE_SIZE];
UINT8 PublicKey[ML_DSA_87_PUBLIC_KEY_SIZE];
UINTN SigSize;
UINTN PublicKeySize;
//
// Create context without setting any key
//
MlDsaContext1 = MlDsaNewByNid (CRYPTO_NID_ML_DSA_87);
UT_ASSERT_NOT_NULL (MlDsaContext1);
//
// MlDsaSign should fail when EvpPkey is NULL
//
SigSize = sizeof (Signature);
Status = MlDsaSign (
MlDsaContext1,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
AsciiStrLen (mMlDsaTestMessage),
Signature,
&SigSize
);
UT_ASSERT_FALSE (Status);
//
// MlDsaVerify should fail when EvpPkey is NULL
//
Status = MlDsaVerify (
MlDsaContext1,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
AsciiStrLen (mMlDsaTestMessage),
Signature,
sizeof (Signature)
);
UT_ASSERT_FALSE (Status);
//
// MlDsaGetPubKey should fail when EvpPkey is NULL
//
PublicKeySize = sizeof (PublicKey);
Status = MlDsaGetPubKey (
MlDsaContext1,
PublicKey,
&PublicKeySize
);
UT_ASSERT_FALSE (Status);
MlDsaFree (MlDsaContext1);
MlDsaContext1 = NULL;
return UNIT_TEST_PASSED;
}
/**
Validate ML-DSA context string parameter validation.
This test validates the check: (ContextSize > 0) && (Context == NULL).
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaInvalidContextParams (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *MlDsaPrivKey;
VOID *MlDsaPubKey;
UINT8 Signature[ML_DSA_87_SIGNATURE_SIZE];
UINTN SigSize;
UINTN MessageSize;
MlDsaPrivKey = NULL;
MlDsaPubKey = NULL;
MessageSize = AsciiStrLen (mMlDsaTestMessage);
//
// Get valid keys
//
Status = MlDsaGetPrivateKeyFromPem (
mMlDsa87TestPemKey,
sizeof (mMlDsa87TestPemKey),
NULL,
&MlDsaPrivKey
);
UT_ASSERT_TRUE (Status);
Status = MlDsaGetPublicKeyFromX509 (
mMlDsa87TestCert,
sizeof (mMlDsa87TestCert),
&MlDsaPubKey
);
UT_ASSERT_TRUE (Status);
//
// Test MlDsaSign with NULL Context but ContextSize > 0 (invalid combination)
//
SigSize = sizeof (Signature);
Status = MlDsaSign (
MlDsaPrivKey,
NULL,
10,
(UINT8 *)mMlDsaTestMessage,
MessageSize,
Signature,
&SigSize
);
UT_ASSERT_FALSE (Status);
//
// Generate valid signature for verify test
//
SigSize = sizeof (Signature);
Status = MlDsaSign (
MlDsaPrivKey,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
MessageSize,
Signature,
&SigSize
);
UT_ASSERT_TRUE (Status);
//
// Test MlDsaVerify with NULL Context but ContextSize > 0 (invalid combination)
//
Status = MlDsaVerify (
MlDsaPubKey,
NULL,
5,
(UINT8 *)mMlDsaTestMessage,
MessageSize,
Signature,
SigSize
);
UT_ASSERT_FALSE (Status);
MlDsaFree (MlDsaPrivKey);
MlDsaFree (MlDsaPubKey);
return UNIT_TEST_PASSED;
}
/**
Validate MlDsaGetPubKey with NULL buffer parameter.
This test validates that NULL PublicKey buffer returns FALSE and sets size to 0.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaGetPubKeyNullBuffer (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *MlDsaPrivKey;
UINTN PublicKeySize;
MlDsaPrivKey = NULL;
//
// Get valid private key
//
Status = MlDsaGetPrivateKeyFromPem (
mMlDsa87TestPemKey,
sizeof (mMlDsa87TestPemKey),
NULL,
&MlDsaPrivKey
);
UT_ASSERT_TRUE (Status);
//
// Test MlDsaGetPubKey with NULL buffer
// Should return FALSE and set PublicKeySize to 0
//
PublicKeySize = 9999;
Status = MlDsaGetPubKey (
MlDsaPrivKey,
NULL,
&PublicKeySize
);
UT_ASSERT_FALSE (Status);
UT_ASSERT_EQUAL (PublicKeySize, 0);
MlDsaFree (MlDsaPrivKey);
return UNIT_TEST_PASSED;
}
/**
Validate ML-DSA signature size exact match validation.
This test validates that MlDsaVerify properly validates signature size.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaSignatureSizeExact (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *MlDsaPrivKey;
VOID *MlDsaPubKey;
UINT8 Signature[ML_DSA_87_SIGNATURE_SIZE];
UINTN SigSize;
UINTN MessageSize;
MlDsaPrivKey = NULL;
MlDsaPubKey = NULL;
MessageSize = AsciiStrLen (mMlDsaTestMessage);
//
// Get valid keys
//
Status = MlDsaGetPrivateKeyFromPem (
mMlDsa87TestPemKey,
sizeof (mMlDsa87TestPemKey),
NULL,
&MlDsaPrivKey
);
UT_ASSERT_TRUE (Status);
Status = MlDsaGetPublicKeyFromX509 (
mMlDsa87TestCert,
sizeof (mMlDsa87TestCert),
&MlDsaPubKey
);
UT_ASSERT_TRUE (Status);
//
// Generate valid signature
//
SigSize = sizeof (Signature);
Status = MlDsaSign (
MlDsaPrivKey,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
MessageSize,
Signature,
&SigSize
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_EQUAL (SigSize, ML_DSA_87_SIGNATURE_SIZE);
//
// Verify with exact size - should succeed
//
Status = MlDsaVerify (
MlDsaPubKey,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
MessageSize,
Signature,
ML_DSA_87_SIGNATURE_SIZE
);
UT_ASSERT_TRUE (Status);
//
// Verify with size + 1 - should fail
//
Status = MlDsaVerify (
MlDsaPubKey,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
MessageSize,
Signature,
ML_DSA_87_SIGNATURE_SIZE + 1
);
UT_ASSERT_FALSE (Status);
//
// Verify with size - 1 - should fail
//
Status = MlDsaVerify (
MlDsaPubKey,
NULL,
0,
(UINT8 *)mMlDsaTestMessage,
MessageSize,
Signature,
ML_DSA_87_SIGNATURE_SIZE - 1
);
UT_ASSERT_FALSE (Status);
MlDsaFree (MlDsaPrivKey);
MlDsaFree (MlDsaPubKey);
return UNIT_TEST_PASSED;
}
/**
Test ML-DSA context lifecycle with multiple allocations.
Tests proper resource management including multiple successive allocations,
cleanup verification, and null pointer safety.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaContextLifecycle (
UNIT_TEST_CONTEXT Context
)
{
VOID *TempCtx1;
VOID *TempCtx2;
VOID *TempCtx3;
//
// Test creating multiple contexts
//
TempCtx1 = MlDsaNewByNid (CRYPTO_NID_ML_DSA_87);
UT_ASSERT_NOT_NULL (TempCtx1);
TempCtx2 = MlDsaNewByNid (CRYPTO_NID_ML_DSA_87);
UT_ASSERT_NOT_NULL (TempCtx2);
TempCtx3 = MlDsaNewByNid (CRYPTO_NID_ML_DSA_87);
UT_ASSERT_NOT_NULL (TempCtx3);
//
// Free in different order
//
MlDsaFree (TempCtx2);
MlDsaFree (TempCtx1);
MlDsaFree (TempCtx3);
//
// Double-free safety (should not crash)
//
MlDsaFree (NULL);
MlDsaFree (NULL);
return UNIT_TEST_PASSED;
}
/**
Test ML-DSA empty message signing and verification.
Tests edge case of zero-length messages.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaEmptyMessage (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *PrivKey;
VOID *PubKey;
UINT8 Signature[ML_DSA_87_SIGNATURE_SIZE];
UINTN SigSize;
UINT8 EmptyMsg[1];
PrivKey = NULL;
PubKey = NULL;
//
// Load keys
//
Status = MlDsaGetPrivateKeyFromPem (
mMlDsa87TestPemKey,
sizeof (mMlDsa87TestPemKey),
NULL,
&PrivKey
);
UT_ASSERT_TRUE (Status);
Status = MlDsaGetPublicKeyFromX509 (
mMlDsa87TestCert,
sizeof (mMlDsa87TestCert),
&PubKey
);
UT_ASSERT_TRUE (Status);
//
// Sign empty message - should fail with NULL message
//
SigSize = sizeof (Signature);
Status = MlDsaSign (
PrivKey,
NULL,
0,
NULL,
0,
Signature,
&SigSize
);
UT_ASSERT_FALSE (Status);
//
// Sign with valid pointer but zero size - should succeed
//
SigSize = sizeof (Signature);
Status = MlDsaSign (
PrivKey,
NULL,
0,
EmptyMsg,
0,
Signature,
&SigSize
);
UT_ASSERT_TRUE (Status);
//
// Verify the zero-length message signature
//
Status = MlDsaVerify (
PubKey,
NULL,
0,
EmptyMsg,
0,
Signature,
SigSize
);
UT_ASSERT_TRUE (Status);
MlDsaFree (PrivKey);
MlDsaFree (PubKey);
return UNIT_TEST_PASSED;
}
/**
Test ML-DSA maximum length context string.
Tests the maximum allowed context string size per FIPS 204.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaMaxContextString (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *PrivKey;
VOID *PubKey;
UINT8 Signature[ML_DSA_87_SIGNATURE_SIZE];
UINTN SigSize;
UINT8 MaxContext[ML_DSA_MAX_CONTEXT_SIZE];
UINTN Index;
PrivKey = NULL;
PubKey = NULL;
//
// Fill context with pattern
//
for (Index = 0; Index < ML_DSA_MAX_CONTEXT_SIZE; Index++) {
MaxContext[Index] = (UINT8)(Index & 0xFF);
}
//
// Load keys
//
Status = MlDsaGetPrivateKeyFromPem (
mMlDsa87TestPemKey,
sizeof (mMlDsa87TestPemKey),
NULL,
&PrivKey
);
UT_ASSERT_TRUE (Status);
Status = MlDsaGetPublicKeyFromX509 (
mMlDsa87TestCert,
sizeof (mMlDsa87TestCert),
&PubKey
);
UT_ASSERT_TRUE (Status);
//
// Sign with maximum context
//
SigSize = sizeof (Signature);
Status = MlDsaSign (
PrivKey,
MaxContext,
ML_DSA_MAX_CONTEXT_SIZE,
(UINT8 *)mMlDsaTestMessage,
AsciiStrLen (mMlDsaTestMessage),
Signature,
&SigSize
);
UT_ASSERT_TRUE (Status);
//
// Verify with matching context
//
Status = MlDsaVerify (
PubKey,
MaxContext,
ML_DSA_MAX_CONTEXT_SIZE,
(UINT8 *)mMlDsaTestMessage,
AsciiStrLen (mMlDsaTestMessage),
Signature,
SigSize
);
UT_ASSERT_TRUE (Status);
//
// Verify should fail with one byte different
//
MaxContext[0] ^= 1;
Status = MlDsaVerify (
PubKey,
MaxContext,
ML_DSA_MAX_CONTEXT_SIZE,
(UINT8 *)mMlDsaTestMessage,
AsciiStrLen (mMlDsaTestMessage),
Signature,
SigSize
);
UT_ASSERT_FALSE (Status);
MlDsaFree (PrivKey);
MlDsaFree (PubKey);
return UNIT_TEST_PASSED;
}
/**
Test ML-DSA key replacement in context.
Tests that replacing keys properly frees old key and sets new key.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaKeyReplacement (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *PrivKey;
UINT8 PublicKey1[ML_DSA_87_PUBLIC_KEY_SIZE];
UINT8 PublicKey2[ML_DSA_87_PUBLIC_KEY_SIZE];
UINTN PubKeySize;
PrivKey = NULL;
//
// Load first key
//
Status = MlDsaGetPrivateKeyFromPem (
mMlDsa87TestPemKey,
sizeof (mMlDsa87TestPemKey),
NULL,
&PrivKey
);
UT_ASSERT_TRUE (Status);
//
// Get public key
//
PubKeySize = sizeof (PublicKey1);
Status = MlDsaGetPubKey (PrivKey, PublicKey1, &PubKeySize);
UT_ASSERT_TRUE (Status);
//
// Now replace with a public-only key
//
MlDsaContext1 = MlDsaNewByNid (CRYPTO_NID_ML_DSA_87);
UT_ASSERT_NOT_NULL (MlDsaContext1);
Status = MlDsaSetPubKey (MlDsaContext1, PublicKey1, ML_DSA_87_PUBLIC_KEY_SIZE);
UT_ASSERT_TRUE (Status);
//
// Replace with same public key again (tests EVP_PKEY_free path)
//
Status = MlDsaSetPubKey (MlDsaContext1, PublicKey1, ML_DSA_87_PUBLIC_KEY_SIZE);
UT_ASSERT_TRUE (Status);
//
// Verify we can still get the key
//
PubKeySize = sizeof (PublicKey2);
Status = MlDsaGetPubKey (MlDsaContext1, PublicKey2, &PubKeySize);
UT_ASSERT_TRUE (Status);
UT_ASSERT_EQUAL (PubKeySize, ML_DSA_87_PUBLIC_KEY_SIZE);
MlDsaFree (PrivKey);
MlDsaFree (MlDsaContext1);
MlDsaContext1 = NULL;
return UNIT_TEST_PASSED;
}
/**
Test ML-DSA multiple signatures with same key.
Tests that the same key can generate multiple signatures.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaMultipleSignatures (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *PrivKey;
VOID *PubKey;
UINT8 Sig1[ML_DSA_87_SIGNATURE_SIZE];
UINT8 Sig2[ML_DSA_87_SIGNATURE_SIZE];
UINT8 Sig3[ML_DSA_87_SIGNATURE_SIZE];
UINTN SigSize;
CHAR8 *Msg1 = "First message";
CHAR8 *Msg2 = "Second message";
CHAR8 *Msg3 = "Third message";
PrivKey = NULL;
PubKey = NULL;
Status = MlDsaGetPrivateKeyFromPem (
mMlDsa87TestPemKey,
sizeof (mMlDsa87TestPemKey),
NULL,
&PrivKey
);
UT_ASSERT_TRUE (Status);
Status = MlDsaGetPublicKeyFromX509 (
mMlDsa87TestCert,
sizeof (mMlDsa87TestCert),
&PubKey
);
UT_ASSERT_TRUE (Status);
//
// Generate three different signatures
//
SigSize = sizeof (Sig1);
Status = MlDsaSign (PrivKey, NULL, 0, (UINT8 *)Msg1, AsciiStrLen (Msg1), Sig1, &SigSize);
UT_ASSERT_TRUE (Status);
SigSize = sizeof (Sig2);
Status = MlDsaSign (PrivKey, NULL, 0, (UINT8 *)Msg2, AsciiStrLen (Msg2), Sig2, &SigSize);
UT_ASSERT_TRUE (Status);
SigSize = sizeof (Sig3);
Status = MlDsaSign (PrivKey, NULL, 0, (UINT8 *)Msg3, AsciiStrLen (Msg3), Sig3, &SigSize);
UT_ASSERT_TRUE (Status);
//
// Verify all three with correct messages
//
Status = MlDsaVerify (PubKey, NULL, 0, (UINT8 *)Msg1, AsciiStrLen (Msg1), Sig1, sizeof (Sig1));
UT_ASSERT_TRUE (Status);
Status = MlDsaVerify (PubKey, NULL, 0, (UINT8 *)Msg2, AsciiStrLen (Msg2), Sig2, sizeof (Sig2));
UT_ASSERT_TRUE (Status);
Status = MlDsaVerify (PubKey, NULL, 0, (UINT8 *)Msg3, AsciiStrLen (Msg3), Sig3, sizeof (Sig3));
UT_ASSERT_TRUE (Status);
//
// Cross-verify should fail (wrong message/signature pairs)
//
Status = MlDsaVerify (PubKey, NULL, 0, (UINT8 *)Msg1, AsciiStrLen (Msg1), Sig2, sizeof (Sig2));
UT_ASSERT_FALSE (Status);
Status = MlDsaVerify (PubKey, NULL, 0, (UINT8 *)Msg2, AsciiStrLen (Msg2), Sig3, sizeof (Sig3));
UT_ASSERT_FALSE (Status);
MlDsaFree (PrivKey);
MlDsaFree (PubKey);
return UNIT_TEST_PASSED;
}
/**
Test ML-DSA GetPubKey called multiple times.
Tests that repeated calls to GetPubKey return consistent results.
@param[in] Context Unit test context.
@retval UNIT_TEST_PASSED The unit test has completed successfully.
@retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestVerifyMlDsaGetPubKeyRepeated (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *PrivKey;
UINT8 PubKey1[ML_DSA_87_PUBLIC_KEY_SIZE];
UINT8 PubKey2[ML_DSA_87_PUBLIC_KEY_SIZE];
UINT8 PubKey3[ML_DSA_87_PUBLIC_KEY_SIZE];
UINTN Size1, Size2, Size3;
PrivKey = NULL;
Status = MlDsaGetPrivateKeyFromPem (
mMlDsa87TestPemKey,
sizeof (mMlDsa87TestPemKey),
NULL,
&PrivKey
);
UT_ASSERT_TRUE (Status);
//
// Get public key three times
//
Size1 = sizeof (PubKey1);
Status = MlDsaGetPubKey (PrivKey, PubKey1, &Size1);
UT_ASSERT_TRUE (Status);
Size2 = sizeof (PubKey2);
Status = MlDsaGetPubKey (PrivKey, PubKey2, &Size2);
UT_ASSERT_TRUE (Status);
Size3 = sizeof (PubKey3);
Status = MlDsaGetPubKey (PrivKey, PubKey3, &Size3);
UT_ASSERT_TRUE (Status);
//
// All should be identical
//
UT_ASSERT_EQUAL (Size1, Size2);
UT_ASSERT_EQUAL (Size2, Size3);
UT_ASSERT_MEM_EQUAL (PubKey1, PubKey2, Size1);
UT_ASSERT_MEM_EQUAL (PubKey2, PubKey3, Size2);
MlDsaFree (PrivKey);
return UNIT_TEST_PASSED;
}
TEST_DESC mMlDsaTest[] = {
//
// -----Description------------------------------------Class-------------------------Function----------------------------Pre-------------------Post--------------------Context
//
{ "TestVerifyMlDsaNew()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaNew, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
{ "TestVerifyMlDsaKeySetGet()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaKeySetGet, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
{ "TestVerifyMlDsaErrorCases()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaErrorCases, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
{ "TestVerifyMlDsaPemX509()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaPemX509, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
{ "TestVerifyMlDsaSignVerifyWithContext()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaSignVerifyWithContext, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
{ "TestVerifyMlDsaGetPubKey()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaGetPubKey, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
{ "TestVerifyMlDsaTamperedData()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaTamperedData, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
{ "TestVerifyMlDsaPemErrors()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaPemErrors, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
{ "TestVerifyMlDsaNoKeyOperations()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaNoKeyOperations, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
{ "TestVerifyMlDsaInvalidContextParams()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaInvalidContextParams, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
{ "TestVerifyMlDsaGetPubKeyNullBuffer()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaGetPubKeyNullBuffer, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
{ "TestVerifyMlDsaSignatureSizeExact()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaSignatureSizeExact, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
{ "TestVerifyMlDsaContextLifecycle()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaContextLifecycle, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
{ "TestVerifyMlDsaEmptyMessage()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaEmptyMessage, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
{ "TestVerifyMlDsaMaxContextString()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaMaxContextString, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
{ "TestVerifyMlDsaKeyReplacement()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaKeyReplacement, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
{ "TestVerifyMlDsaMultipleSignatures()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaMultipleSignatures, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
{ "TestVerifyMlDsaGetPubKeyRepeated()", "CryptoPkg.BaseCryptLib.MlDsa", TestVerifyMlDsaGetPubKeyRepeated, TestVerifyMlDsaPreReq, TestVerifyMlDsaCleanUp, NULL },
};
UINTN mMlDsaTestNum = ARRAY_SIZE (mMlDsaTest);