blob: 83d1aec6f3b552c4c2ccb758c31898b9e737dd2e [file]
/** @file
Application for SLH-DSA Primitives Validation.
This file contains unit tests for the SLH-DSA (Stateless Hash-Based Digital Signature Algorithm)
cryptographic functions defined in CryptSlhDsa.c. SLH-DSA is a post-quantum digital signature
scheme based on the SPHINCS+ algorithm and standardized in FIPS 205.
The test vectors are provided in SlhDsaTestVectors.h which contains:
- mSlhDsaShake256sTestCert[] - X.509 DER certificate with SLH-DSA-SHAKE-256s public key
- mSlhDsaShake256sTestPemKey[] - PEM-encoded SLH-DSA-SHAKE-256s private key
The test structure mirrors SlhDsaTests.c and validates:
- Context creation and destruction (SlhDsaNewByNid, SlhDsaFree)
- Key setting and retrieval error cases (SlhDsaSetPrivKey, SlhDsaSetPubKey, SlhDsaGetPubKey)
- Signature generation and verification via PEM/X509 (TestVerifySlhDsaPemX509)
- Error handling for invalid inputs
Copyright (c) 2026, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "TestBaseCryptLib.h"
#define SLH_DSA_SHAKE_256S_PRIVATE_KEY_SIZE 128
#define SLH_DSA_SHAKE_256S_PUBLIC_KEY_SIZE 64
#define SLH_DSA_SHAKE_256S_SIGNATURE_SIZE 29792
#define SLH_DSA_MAX_CONTEXT_SIZE 255
//
// SLH-DSA-SHAKE-256s test vectors - include generated certificate and PEM key
//
#include "SlhDsaTestVectors.h"
//
// Test message for signing and verification
//
CONST CHAR8 *mSlhDsaTestMessage = "Test message for SLH-DSA signing and verification";
//
// Optional context string for domain separation
//
CONST CHAR8 *mSlhDsaTestContext = "SLH-DSA test context";
VOID *SlhDsaContext1;
VOID *SlhDsaContext2;
/**
Prerequisite function for SLH-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
TestVerifySlhDsaPreReq (
UNIT_TEST_CONTEXT Context
)
{
SlhDsaContext1 = NULL;
SlhDsaContext2 = NULL;
return UNIT_TEST_PASSED;
}
/**
Cleanup function for SLH-DSA tests.
@param[in] Context Unit test context.
**/
VOID
EFIAPI
TestVerifySlhDsaCleanUp (
UNIT_TEST_CONTEXT Context
)
{
if (SlhDsaContext1 != NULL) {
SlhDsaFree (SlhDsaContext1);
SlhDsaContext1 = NULL;
}
if (SlhDsaContext2 != NULL) {
SlhDsaFree (SlhDsaContext2);
SlhDsaContext2 = NULL;
}
}
/**
Validate UEFI-OpenSSL SLH-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
TestVerifySlhDsaNew (
UNIT_TEST_CONTEXT Context
)
{
//
// Test SlhDsaNewByNid with SLH-DSA-87
//
SlhDsaContext1 = SlhDsaNewByNid (CRYPTO_NID_SLH_DSA_SHAKE_256S);
UT_ASSERT_NOT_NULL (SlhDsaContext1);
//
// Test SlhDsaNewByNid with invalid NID
//
SlhDsaContext2 = SlhDsaNewByNid (CRYPTO_NID_NULL);
UT_ASSERT_EQUAL ((UINTN)SlhDsaContext2, (UINTN)NULL);
//
// Test SlhDsaFree
//
SlhDsaFree (SlhDsaContext1);
SlhDsaContext1 = NULL;
//
// Test SlhDsaFree with NULL (should not crash)
//
SlhDsaFree (NULL);
return UNIT_TEST_PASSED;
}
/**
Validate UEFI-OpenSSL SLH-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
TestVerifySlhDsaKeySetGet (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
UINT8 PublicKey[SLH_DSA_SHAKE_256S_PUBLIC_KEY_SIZE];
UINTN PublicKeySize;
UINT8 TooSmallBuffer[10];
UINTN TooSmallSize;
//
// Create SLH-DSA context
//
SlhDsaContext1 = SlhDsaNewByNid (CRYPTO_NID_SLH_DSA_SHAKE_256S);
UT_ASSERT_NOT_NULL (SlhDsaContext1);
//
// Test SlhDsaGetPubKey with too small buffer (before key is set)
//
TooSmallSize = sizeof (TooSmallBuffer);
Status = SlhDsaGetPubKey (SlhDsaContext1, TooSmallBuffer, &TooSmallSize);
UT_ASSERT_FALSE (Status);
UT_ASSERT_NOT_EQUAL (TooSmallSize, SLH_DSA_SHAKE_256S_PUBLIC_KEY_SIZE);
//
// Test SlhDsaSetPrivKey with NULL context
//
Status = SlhDsaSetPrivKey (NULL, (UINT8 *)mSlhDsaShake256sTestPemKey, 100);
UT_ASSERT_FALSE (Status);
//
// Test SlhDsaSetPrivKey with NULL key
//
Status = SlhDsaSetPrivKey (SlhDsaContext1, NULL, SLH_DSA_SHAKE_256S_PRIVATE_KEY_SIZE);
UT_ASSERT_FALSE (Status);
//
// Test SlhDsaSetPrivKey with wrong size
//
Status = SlhDsaSetPrivKey (SlhDsaContext1, (UINT8 *)mSlhDsaShake256sTestPemKey, 32);
UT_ASSERT_FALSE (Status);
//
// Test SlhDsaSetPubKey with NULL context
//
Status = SlhDsaSetPubKey (NULL, (UINT8 *)mSlhDsaShake256sTestCert, 100);
UT_ASSERT_FALSE (Status);
//
// Test SlhDsaSetPubKey with NULL key
//
Status = SlhDsaSetPubKey (SlhDsaContext1, NULL, SLH_DSA_SHAKE_256S_PUBLIC_KEY_SIZE);
UT_ASSERT_FALSE (Status);
//
// Test SlhDsaSetPubKey with wrong size
//
Status = SlhDsaSetPubKey (SlhDsaContext1, (UINT8 *)mSlhDsaShake256sTestCert, 32);
UT_ASSERT_FALSE (Status);
//
// Test SlhDsaGetPubKey with NULL context
//
PublicKeySize = sizeof (PublicKey);
Status = SlhDsaGetPubKey (NULL, PublicKey, &PublicKeySize);
UT_ASSERT_FALSE (Status);
//
// Test SlhDsaGetPubKey with NULL size
//
Status = SlhDsaGetPubKey (SlhDsaContext1, PublicKey, NULL);
UT_ASSERT_FALSE (Status);
//
// Clean up context
//
SlhDsaFree (SlhDsaContext1);
SlhDsaContext1 = NULL;
return UNIT_TEST_PASSED;
}
/**
Validate SLH-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
TestVerifySlhDsaErrorCases (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
UINT8 *Signature;
UINTN SigSize;
UINT8 TooSmallBuffer[10];
UINTN TooSmallSize;
//
// Allocate signature buffer on the heap to avoid large stack frames.
//
Signature = AllocatePool (SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
UT_ASSERT_NOT_NULL (Signature);
if (Signature == NULL) {
return UNIT_TEST_ERROR_TEST_FAILED;
}
//
// Create SLH-DSA context
//
SlhDsaContext1 = SlhDsaNewByNid (CRYPTO_NID_SLH_DSA_SHAKE_256S);
UT_ASSERT_NOT_NULL (SlhDsaContext1);
//
// Test SlhDsaSign with NULL context
//
SigSize = SLH_DSA_SHAKE_256S_SIGNATURE_SIZE;
Status = SlhDsaSign (
NULL,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
AsciiStrLen (mSlhDsaTestMessage),
Signature,
&SigSize
);
UT_ASSERT_FALSE (Status);
//
// Test SlhDsaSign with NULL message
//
SigSize = SLH_DSA_SHAKE_256S_SIGNATURE_SIZE;
Status = SlhDsaSign (
SlhDsaContext1,
NULL,
0,
NULL,
0,
Signature,
&SigSize
);
UT_ASSERT_FALSE (Status);
//
// Test SlhDsaSign with too small buffer
//
TooSmallSize = sizeof (TooSmallBuffer);
Status = SlhDsaSign (
SlhDsaContext1,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
AsciiStrLen (mSlhDsaTestMessage),
TooSmallBuffer,
&TooSmallSize
);
UT_ASSERT_FALSE (Status);
UT_ASSERT_NOT_EQUAL (TooSmallSize, SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
//
// Test SlhDsaVerify with NULL context
//
Status = SlhDsaVerify (
NULL,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
AsciiStrLen (mSlhDsaTestMessage),
Signature,
SLH_DSA_SHAKE_256S_SIGNATURE_SIZE
);
UT_ASSERT_FALSE (Status);
//
// Test SlhDsaVerify with NULL message
//
Status = SlhDsaVerify (
SlhDsaContext1,
NULL,
0,
NULL,
0,
Signature,
SLH_DSA_SHAKE_256S_SIGNATURE_SIZE
);
UT_ASSERT_FALSE (Status);
//
// Test SlhDsaVerify with NULL signature
//
Status = SlhDsaVerify (
SlhDsaContext1,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
AsciiStrLen (mSlhDsaTestMessage),
NULL,
SLH_DSA_SHAKE_256S_SIGNATURE_SIZE
);
UT_ASSERT_FALSE (Status);
//
// Test SlhDsaVerify with zero signature size
//
Status = SlhDsaVerify (
SlhDsaContext1,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
AsciiStrLen (mSlhDsaTestMessage),
Signature,
0
);
UT_ASSERT_FALSE (Status);
FreePool (Signature);
return UNIT_TEST_PASSED;
}
/**
Validate SLH-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
TestVerifySlhDsaPemX509 (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *SlhDsaPrivKey;
VOID *SlhDsaPubKey;
UINT8 *Signature;
UINTN SigSize;
UINTN MessageSize;
SlhDsaPrivKey = NULL;
SlhDsaPubKey = NULL;
MessageSize = AsciiStrLen (mSlhDsaTestMessage);
//
// Allocate signature buffer on the heap to avoid large stack frames.
//
Signature = AllocatePool (SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
UT_ASSERT_NOT_NULL (Signature);
if (Signature == NULL) {
return UNIT_TEST_ERROR_TEST_FAILED;
}
//
// Retrieve SLH-DSA private key from PEM data.
//
Status = SlhDsaGetPrivateKeyFromPem (
mSlhDsaShake256sTestPemKey,
sizeof (mSlhDsaShake256sTestPemKey),
NULL,
&SlhDsaPrivKey
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_NOT_NULL (SlhDsaPrivKey);
//
// Retrieve SLH-DSA public key from X509 certificate.
//
Status = SlhDsaGetPublicKeyFromX509 (
mSlhDsaShake256sTestCert,
sizeof (mSlhDsaShake256sTestCert),
&SlhDsaPubKey
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_NOT_NULL (SlhDsaPubKey);
//
// SLH-DSA signing with key from PEM (no context string)
//
SigSize = SLH_DSA_SHAKE_256S_SIGNATURE_SIZE;
Status = SlhDsaSign (
SlhDsaPrivKey,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
MessageSize,
Signature,
&SigSize
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_EQUAL (SigSize, SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
//
// SLH-DSA verification with key from X509
//
Status = SlhDsaVerify (
SlhDsaPubKey,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
MessageSize,
Signature,
SigSize
);
UT_ASSERT_TRUE (Status);
SlhDsaFree (SlhDsaPrivKey);
SlhDsaFree (SlhDsaPubKey);
FreePool (Signature);
return UNIT_TEST_PASSED;
}
/**
Validate SLH-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
TestVerifySlhDsaSignVerifyWithContext (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *SlhDsaPrivKey;
VOID *SlhDsaPubKey;
UINT8 *Signature;
UINTN SigSize;
UINTN MessageSize;
UINTN ContextSize;
SlhDsaPrivKey = NULL;
SlhDsaPubKey = NULL;
MessageSize = AsciiStrLen (mSlhDsaTestMessage);
ContextSize = AsciiStrLen (mSlhDsaTestContext);
//
// Allocate signature buffer on the heap to avoid large stack frames.
//
Signature = AllocatePool (SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
UT_ASSERT_NOT_NULL (Signature);
if (Signature == NULL) {
return UNIT_TEST_ERROR_TEST_FAILED;
}
//
// Retrieve SLH-DSA private key from PEM data.
//
Status = SlhDsaGetPrivateKeyFromPem (
mSlhDsaShake256sTestPemKey,
sizeof (mSlhDsaShake256sTestPemKey),
NULL,
&SlhDsaPrivKey
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_NOT_NULL (SlhDsaPrivKey);
//
// Retrieve SLH-DSA public key from X509 certificate.
//
Status = SlhDsaGetPublicKeyFromX509 (
mSlhDsaShake256sTestCert,
sizeof (mSlhDsaShake256sTestCert),
&SlhDsaPubKey
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_NOT_NULL (SlhDsaPubKey);
//
// SLH-DSA signing with context string
//
SigSize = SLH_DSA_SHAKE_256S_SIGNATURE_SIZE;
Status = SlhDsaSign (
SlhDsaPrivKey,
(UINT8 *)mSlhDsaTestContext,
ContextSize,
(UINT8 *)mSlhDsaTestMessage,
MessageSize,
Signature,
&SigSize
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_EQUAL (SigSize, SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
//
// SLH-DSA verification with matching context string
//
Status = SlhDsaVerify (
SlhDsaPubKey,
(UINT8 *)mSlhDsaTestContext,
ContextSize,
(UINT8 *)mSlhDsaTestMessage,
MessageSize,
Signature,
SigSize
);
UT_ASSERT_TRUE (Status);
//
// SLH-DSA verification should fail with mismatched context string
//
Status = SlhDsaVerify (
SlhDsaPubKey,
(UINT8 *)"Different context",
AsciiStrLen ("Different context"),
(UINT8 *)mSlhDsaTestMessage,
MessageSize,
Signature,
SigSize
);
UT_ASSERT_FALSE (Status);
//
// SLH-DSA verification should fail with no context when signature used context
//
Status = SlhDsaVerify (
SlhDsaPubKey,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
MessageSize,
Signature,
SigSize
);
UT_ASSERT_FALSE (Status);
SlhDsaFree (SlhDsaPrivKey);
SlhDsaFree (SlhDsaPubKey);
FreePool (Signature);
return UNIT_TEST_PASSED;
}
/**
Validate SLH-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
TestVerifySlhDsaGetPubKey (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *SlhDsaPrivKey;
UINT8 PublicKey[SLH_DSA_SHAKE_256S_PUBLIC_KEY_SIZE];
UINTN PublicKeySize;
SlhDsaPrivKey = NULL;
//
// Retrieve SLH-DSA private key from PEM data.
//
Status = SlhDsaGetPrivateKeyFromPem (
mSlhDsaShake256sTestPemKey,
sizeof (mSlhDsaShake256sTestPemKey),
NULL,
&SlhDsaPrivKey
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_NOT_NULL (SlhDsaPrivKey);
//
// Get public key from private key context
//
PublicKeySize = sizeof (PublicKey);
Status = SlhDsaGetPubKey (
SlhDsaPrivKey,
PublicKey,
&PublicKeySize
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_EQUAL (PublicKeySize, SLH_DSA_SHAKE_256S_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);
SlhDsaFree (SlhDsaPrivKey);
return UNIT_TEST_PASSED;
}
/**
Validate SLH-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
TestVerifySlhDsaTamperedData (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *SlhDsaPrivKey;
VOID *SlhDsaPubKey;
UINT8 *Signature;
UINT8 *TamperedSignature;
CHAR8 TamperedMessage[100];
UINTN SigSize;
UINTN MessageSize;
SlhDsaPrivKey = NULL;
SlhDsaPubKey = NULL;
MessageSize = AsciiStrLen (mSlhDsaTestMessage);
//
// Allocate signature buffers on the heap to avoid large stack frames.
//
Signature = AllocatePool (SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
TamperedSignature = AllocatePool (SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
if ((Signature == NULL) || (TamperedSignature == NULL)) {
if (Signature != NULL) {
FreePool (Signature);
}
if (TamperedSignature != NULL) {
FreePool (TamperedSignature);
}
UT_ASSERT_TRUE ((Signature != NULL) && (TamperedSignature != NULL));
return UNIT_TEST_ERROR_TEST_FAILED;
}
//
// Retrieve SLH-DSA private key from PEM data.
//
Status = SlhDsaGetPrivateKeyFromPem (
mSlhDsaShake256sTestPemKey,
sizeof (mSlhDsaShake256sTestPemKey),
NULL,
&SlhDsaPrivKey
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_NOT_NULL (SlhDsaPrivKey);
//
// Retrieve SLH-DSA public key from X509 certificate.
//
Status = SlhDsaGetPublicKeyFromX509 (
mSlhDsaShake256sTestCert,
sizeof (mSlhDsaShake256sTestCert),
&SlhDsaPubKey
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_NOT_NULL (SlhDsaPubKey);
//
// Generate valid signature
//
SigSize = SLH_DSA_SHAKE_256S_SIGNATURE_SIZE;
Status = SlhDsaSign (
SlhDsaPrivKey,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
MessageSize,
Signature,
&SigSize
);
UT_ASSERT_TRUE (Status);
//
// Verify original signature works
//
Status = SlhDsaVerify (
SlhDsaPubKey,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
MessageSize,
Signature,
SigSize
);
UT_ASSERT_TRUE (Status);
//
// Test with tampered message (should fail)
//
AsciiStrCpyS (TamperedMessage, sizeof (TamperedMessage), mSlhDsaTestMessage);
TamperedMessage[0] = 'X';
Status = SlhDsaVerify (
SlhDsaPubKey,
NULL,
0,
(UINT8 *)TamperedMessage,
MessageSize,
Signature,
SigSize
);
UT_ASSERT_FALSE (Status);
//
// Test with tampered signature (should fail)
//
CopyMem (TamperedSignature, Signature, SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
TamperedSignature[0] ^= 0x01;
Status = SlhDsaVerify (
SlhDsaPubKey,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
MessageSize,
TamperedSignature,
SigSize
);
UT_ASSERT_FALSE (Status);
//
// Test with wrong signature size (should fail)
//
Status = SlhDsaVerify (
SlhDsaPubKey,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
MessageSize,
Signature,
SigSize - 1
);
UT_ASSERT_FALSE (Status);
SlhDsaFree (SlhDsaPrivKey);
SlhDsaFree (SlhDsaPubKey);
FreePool (Signature);
FreePool (TamperedSignature);
return UNIT_TEST_PASSED;
}
/**
Validate SLH-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
TestVerifySlhDsaPemErrors (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *SlhDsaKey;
SlhDsaKey = NULL;
//
// Test SlhDsaGetPrivateKeyFromPem with NULL PEM data
//
Status = SlhDsaGetPrivateKeyFromPem (
NULL,
100,
NULL,
&SlhDsaKey
);
UT_ASSERT_FALSE (Status);
//
// Test SlhDsaGetPrivateKeyFromPem with NULL context pointer
//
Status = SlhDsaGetPrivateKeyFromPem (
mSlhDsaShake256sTestPemKey,
sizeof (mSlhDsaShake256sTestPemKey),
NULL,
NULL
);
UT_ASSERT_FALSE (Status);
//
// Test SlhDsaGetPrivateKeyFromPem with invalid PEM data
//
Status = SlhDsaGetPrivateKeyFromPem (
(UINT8 *)"Invalid PEM data",
16,
NULL,
&SlhDsaKey
);
UT_ASSERT_FALSE (Status);
//
// Test SlhDsaGetPublicKeyFromX509 with NULL certificate
//
Status = SlhDsaGetPublicKeyFromX509 (
NULL,
100,
&SlhDsaKey
);
UT_ASSERT_FALSE (Status);
//
// Test SlhDsaGetPublicKeyFromX509 with NULL context pointer
//
Status = SlhDsaGetPublicKeyFromX509 (
mSlhDsaShake256sTestCert,
sizeof (mSlhDsaShake256sTestCert),
NULL
);
UT_ASSERT_FALSE (Status);
//
// Test SlhDsaGetPublicKeyFromX509 with invalid certificate data
//
Status = SlhDsaGetPublicKeyFromX509 (
(UINT8 *)"Invalid cert data",
17,
&SlhDsaKey
);
UT_ASSERT_FALSE (Status);
return UNIT_TEST_PASSED;
}
/**
Validate SLH-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
TestVerifySlhDsaNoKeyOperations (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
UINT8 *Signature;
UINT8 PublicKey[SLH_DSA_SHAKE_256S_PUBLIC_KEY_SIZE];
UINTN SigSize;
UINTN PublicKeySize;
//
// Allocate signature buffer on the heap to avoid large stack frames.
//
Signature = AllocatePool (SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
UT_ASSERT_NOT_NULL (Signature);
if (Signature == NULL) {
return UNIT_TEST_ERROR_TEST_FAILED;
}
//
// Create context without setting any key
//
SlhDsaContext1 = SlhDsaNewByNid (CRYPTO_NID_SLH_DSA_SHAKE_256S);
UT_ASSERT_NOT_NULL (SlhDsaContext1);
//
// SlhDsaSign should fail when EvpPkey is NULL
//
SigSize = SLH_DSA_SHAKE_256S_SIGNATURE_SIZE;
Status = SlhDsaSign (
SlhDsaContext1,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
AsciiStrLen (mSlhDsaTestMessage),
Signature,
&SigSize
);
UT_ASSERT_FALSE (Status);
//
// SlhDsaVerify should fail when EvpPkey is NULL
//
Status = SlhDsaVerify (
SlhDsaContext1,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
AsciiStrLen (mSlhDsaTestMessage),
Signature,
SLH_DSA_SHAKE_256S_SIGNATURE_SIZE
);
UT_ASSERT_FALSE (Status);
//
// SlhDsaGetPubKey should fail when EvpPkey is NULL
//
PublicKeySize = sizeof (PublicKey);
Status = SlhDsaGetPubKey (
SlhDsaContext1,
PublicKey,
&PublicKeySize
);
UT_ASSERT_FALSE (Status);
SlhDsaFree (SlhDsaContext1);
SlhDsaContext1 = NULL;
FreePool (Signature);
return UNIT_TEST_PASSED;
}
/**
Validate SLH-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
TestVerifySlhDsaInvalidContextParams (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *SlhDsaPrivKey;
VOID *SlhDsaPubKey;
UINT8 *Signature;
UINTN SigSize;
UINTN MessageSize;
SlhDsaPrivKey = NULL;
SlhDsaPubKey = NULL;
MessageSize = AsciiStrLen (mSlhDsaTestMessage);
//
// Allocate signature buffer on the heap to avoid large stack frames.
//
Signature = AllocatePool (SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
UT_ASSERT_NOT_NULL (Signature);
if (Signature == NULL) {
return UNIT_TEST_ERROR_TEST_FAILED;
}
//
// Get valid keys
//
Status = SlhDsaGetPrivateKeyFromPem (
mSlhDsaShake256sTestPemKey,
sizeof (mSlhDsaShake256sTestPemKey),
NULL,
&SlhDsaPrivKey
);
UT_ASSERT_TRUE (Status);
Status = SlhDsaGetPublicKeyFromX509 (
mSlhDsaShake256sTestCert,
sizeof (mSlhDsaShake256sTestCert),
&SlhDsaPubKey
);
UT_ASSERT_TRUE (Status);
//
// Test SlhDsaSign with NULL Context but ContextSize > 0 (invalid combination)
//
SigSize = SLH_DSA_SHAKE_256S_SIGNATURE_SIZE;
Status = SlhDsaSign (
SlhDsaPrivKey,
NULL,
10,
(UINT8 *)mSlhDsaTestMessage,
MessageSize,
Signature,
&SigSize
);
UT_ASSERT_FALSE (Status);
//
// Generate valid signature for verify test
//
SigSize = SLH_DSA_SHAKE_256S_SIGNATURE_SIZE;
Status = SlhDsaSign (
SlhDsaPrivKey,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
MessageSize,
Signature,
&SigSize
);
UT_ASSERT_TRUE (Status);
//
// Test SlhDsaVerify with NULL Context but ContextSize > 0 (invalid combination)
//
Status = SlhDsaVerify (
SlhDsaPubKey,
NULL,
5,
(UINT8 *)mSlhDsaTestMessage,
MessageSize,
Signature,
SigSize
);
UT_ASSERT_FALSE (Status);
SlhDsaFree (SlhDsaPrivKey);
SlhDsaFree (SlhDsaPubKey);
FreePool (Signature);
return UNIT_TEST_PASSED;
}
/**
Validate SlhDsaGetPubKey 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
TestVerifySlhDsaGetPubKeyNullBuffer (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *SlhDsaPrivKey;
UINTN PublicKeySize;
SlhDsaPrivKey = NULL;
//
// Get valid private key
//
Status = SlhDsaGetPrivateKeyFromPem (
mSlhDsaShake256sTestPemKey,
sizeof (mSlhDsaShake256sTestPemKey),
NULL,
&SlhDsaPrivKey
);
UT_ASSERT_TRUE (Status);
//
// Test SlhDsaGetPubKey with NULL buffer
// Should return FALSE and set PublicKeySize to 0
//
PublicKeySize = 9999;
Status = SlhDsaGetPubKey (
SlhDsaPrivKey,
NULL,
&PublicKeySize
);
UT_ASSERT_FALSE (Status);
UT_ASSERT_EQUAL (PublicKeySize, 0);
SlhDsaFree (SlhDsaPrivKey);
return UNIT_TEST_PASSED;
}
/**
Validate SLH-DSA signature size exact match validation.
This test validates that SlhDsaVerify 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
TestVerifySlhDsaSignatureSizeExact (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *SlhDsaPrivKey;
VOID *SlhDsaPubKey;
UINT8 *Signature;
UINTN SigSize;
UINTN MessageSize;
SlhDsaPrivKey = NULL;
SlhDsaPubKey = NULL;
MessageSize = AsciiStrLen (mSlhDsaTestMessage);
//
// Allocate signature buffer on the heap to avoid large stack frames.
//
Signature = AllocatePool (SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
UT_ASSERT_NOT_NULL (Signature);
if (Signature == NULL) {
return UNIT_TEST_ERROR_TEST_FAILED;
}
//
// Get valid keys
//
Status = SlhDsaGetPrivateKeyFromPem (
mSlhDsaShake256sTestPemKey,
sizeof (mSlhDsaShake256sTestPemKey),
NULL,
&SlhDsaPrivKey
);
UT_ASSERT_TRUE (Status);
Status = SlhDsaGetPublicKeyFromX509 (
mSlhDsaShake256sTestCert,
sizeof (mSlhDsaShake256sTestCert),
&SlhDsaPubKey
);
UT_ASSERT_TRUE (Status);
//
// Generate valid signature
//
SigSize = SLH_DSA_SHAKE_256S_SIGNATURE_SIZE;
Status = SlhDsaSign (
SlhDsaPrivKey,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
MessageSize,
Signature,
&SigSize
);
UT_ASSERT_TRUE (Status);
UT_ASSERT_EQUAL (SigSize, SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
//
// Verify with exact size - should succeed
//
Status = SlhDsaVerify (
SlhDsaPubKey,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
MessageSize,
Signature,
SLH_DSA_SHAKE_256S_SIGNATURE_SIZE
);
UT_ASSERT_TRUE (Status);
//
// Verify with size + 1 - should fail
//
Status = SlhDsaVerify (
SlhDsaPubKey,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
MessageSize,
Signature,
SLH_DSA_SHAKE_256S_SIGNATURE_SIZE + 1
);
UT_ASSERT_FALSE (Status);
//
// Verify with size - 1 - should fail
//
Status = SlhDsaVerify (
SlhDsaPubKey,
NULL,
0,
(UINT8 *)mSlhDsaTestMessage,
MessageSize,
Signature,
SLH_DSA_SHAKE_256S_SIGNATURE_SIZE - 1
);
UT_ASSERT_FALSE (Status);
SlhDsaFree (SlhDsaPrivKey);
SlhDsaFree (SlhDsaPubKey);
FreePool (Signature);
return UNIT_TEST_PASSED;
}
/**
Test SLH-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
TestVerifySlhDsaContextLifecycle (
UNIT_TEST_CONTEXT Context
)
{
VOID *TempCtx1;
VOID *TempCtx2;
VOID *TempCtx3;
//
// Test creating multiple contexts
//
TempCtx1 = SlhDsaNewByNid (CRYPTO_NID_SLH_DSA_SHAKE_256S);
UT_ASSERT_NOT_NULL (TempCtx1);
TempCtx2 = SlhDsaNewByNid (CRYPTO_NID_SLH_DSA_SHAKE_256S);
UT_ASSERT_NOT_NULL (TempCtx2);
TempCtx3 = SlhDsaNewByNid (CRYPTO_NID_SLH_DSA_SHAKE_256S);
UT_ASSERT_NOT_NULL (TempCtx3);
//
// Free in different order
//
SlhDsaFree (TempCtx2);
SlhDsaFree (TempCtx1);
SlhDsaFree (TempCtx3);
//
// Double-free safety (should not crash)
//
SlhDsaFree (NULL);
SlhDsaFree (NULL);
return UNIT_TEST_PASSED;
}
/**
Test SLH-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
TestVerifySlhDsaEmptyMessage (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *PrivKey;
VOID *PubKey;
UINT8 *Signature;
UINTN SigSize;
UINT8 EmptyMsg[1];
PrivKey = NULL;
PubKey = NULL;
//
// Allocate signature buffer on the heap to avoid large stack frames.
//
Signature = AllocatePool (SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
UT_ASSERT_NOT_NULL (Signature);
if (Signature == NULL) {
return UNIT_TEST_ERROR_TEST_FAILED;
}
//
// Load keys
//
Status = SlhDsaGetPrivateKeyFromPem (
mSlhDsaShake256sTestPemKey,
sizeof (mSlhDsaShake256sTestPemKey),
NULL,
&PrivKey
);
UT_ASSERT_TRUE (Status);
Status = SlhDsaGetPublicKeyFromX509 (
mSlhDsaShake256sTestCert,
sizeof (mSlhDsaShake256sTestCert),
&PubKey
);
UT_ASSERT_TRUE (Status);
//
// Sign empty message - should fail with NULL message
//
SigSize = SLH_DSA_SHAKE_256S_SIGNATURE_SIZE;
Status = SlhDsaSign (
PrivKey,
NULL,
0,
NULL,
0,
Signature,
&SigSize
);
UT_ASSERT_FALSE (Status);
//
// Sign with valid pointer but zero size - should succeed
//
SigSize = SLH_DSA_SHAKE_256S_SIGNATURE_SIZE;
Status = SlhDsaSign (
PrivKey,
NULL,
0,
EmptyMsg,
0,
Signature,
&SigSize
);
UT_ASSERT_TRUE (Status);
//
// Verify the zero-length message signature
//
Status = SlhDsaVerify (
PubKey,
NULL,
0,
EmptyMsg,
0,
Signature,
SigSize
);
UT_ASSERT_TRUE (Status);
SlhDsaFree (PrivKey);
SlhDsaFree (PubKey);
FreePool (Signature);
return UNIT_TEST_PASSED;
}
/**
Test SLH-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
TestVerifySlhDsaMaxContextString (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *PrivKey;
VOID *PubKey;
UINT8 *Signature;
UINTN SigSize;
UINT8 MaxContext[SLH_DSA_MAX_CONTEXT_SIZE];
UINTN Index;
PrivKey = NULL;
PubKey = NULL;
//
// Allocate signature buffer on the heap to avoid large stack frames.
//
Signature = AllocatePool (SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
UT_ASSERT_NOT_NULL (Signature);
if (Signature == NULL) {
return UNIT_TEST_ERROR_TEST_FAILED;
}
//
// Fill context with pattern
//
for (Index = 0; Index < SLH_DSA_MAX_CONTEXT_SIZE; Index++) {
MaxContext[Index] = (UINT8)(Index & 0xFF);
}
//
// Load keys
//
Status = SlhDsaGetPrivateKeyFromPem (
mSlhDsaShake256sTestPemKey,
sizeof (mSlhDsaShake256sTestPemKey),
NULL,
&PrivKey
);
UT_ASSERT_TRUE (Status);
Status = SlhDsaGetPublicKeyFromX509 (
mSlhDsaShake256sTestCert,
sizeof (mSlhDsaShake256sTestCert),
&PubKey
);
UT_ASSERT_TRUE (Status);
//
// Sign with maximum context
//
SigSize = SLH_DSA_SHAKE_256S_SIGNATURE_SIZE;
Status = SlhDsaSign (
PrivKey,
MaxContext,
SLH_DSA_MAX_CONTEXT_SIZE,
(UINT8 *)mSlhDsaTestMessage,
AsciiStrLen (mSlhDsaTestMessage),
Signature,
&SigSize
);
UT_ASSERT_TRUE (Status);
//
// Verify with matching context
//
Status = SlhDsaVerify (
PubKey,
MaxContext,
SLH_DSA_MAX_CONTEXT_SIZE,
(UINT8 *)mSlhDsaTestMessage,
AsciiStrLen (mSlhDsaTestMessage),
Signature,
SigSize
);
UT_ASSERT_TRUE (Status);
//
// Verify should fail with one byte different
//
MaxContext[0] ^= 1;
Status = SlhDsaVerify (
PubKey,
MaxContext,
SLH_DSA_MAX_CONTEXT_SIZE,
(UINT8 *)mSlhDsaTestMessage,
AsciiStrLen (mSlhDsaTestMessage),
Signature,
SigSize
);
UT_ASSERT_FALSE (Status);
SlhDsaFree (PrivKey);
SlhDsaFree (PubKey);
FreePool (Signature);
return UNIT_TEST_PASSED;
}
/**
Test SLH-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
TestVerifySlhDsaKeyReplacement (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *PrivKey;
UINT8 PublicKey1[SLH_DSA_SHAKE_256S_PUBLIC_KEY_SIZE];
UINT8 PublicKey2[SLH_DSA_SHAKE_256S_PUBLIC_KEY_SIZE];
UINTN PubKeySize;
PrivKey = NULL;
//
// Load first key
//
Status = SlhDsaGetPrivateKeyFromPem (
mSlhDsaShake256sTestPemKey,
sizeof (mSlhDsaShake256sTestPemKey),
NULL,
&PrivKey
);
UT_ASSERT_TRUE (Status);
//
// Get public key
//
PubKeySize = sizeof (PublicKey1);
Status = SlhDsaGetPubKey (PrivKey, PublicKey1, &PubKeySize);
UT_ASSERT_TRUE (Status);
//
// Now replace with a public-only key
//
SlhDsaContext1 = SlhDsaNewByNid (CRYPTO_NID_SLH_DSA_SHAKE_256S);
UT_ASSERT_NOT_NULL (SlhDsaContext1);
Status = SlhDsaSetPubKey (SlhDsaContext1, PublicKey1, SLH_DSA_SHAKE_256S_PUBLIC_KEY_SIZE);
UT_ASSERT_TRUE (Status);
//
// Replace with same public key again (tests EVP_PKEY_free path)
//
Status = SlhDsaSetPubKey (SlhDsaContext1, PublicKey1, SLH_DSA_SHAKE_256S_PUBLIC_KEY_SIZE);
UT_ASSERT_TRUE (Status);
//
// Verify we can still get the key
//
PubKeySize = sizeof (PublicKey2);
Status = SlhDsaGetPubKey (SlhDsaContext1, PublicKey2, &PubKeySize);
UT_ASSERT_TRUE (Status);
UT_ASSERT_EQUAL (PubKeySize, SLH_DSA_SHAKE_256S_PUBLIC_KEY_SIZE);
SlhDsaFree (PrivKey);
SlhDsaFree (SlhDsaContext1);
SlhDsaContext1 = NULL;
return UNIT_TEST_PASSED;
}
/**
Test SLH-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
TestVerifySlhDsaMultipleSignatures (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *PrivKey;
VOID *PubKey;
UINT8 *Sig1;
UINT8 *Sig2;
UINT8 *Sig3;
UINTN SigSize;
CHAR8 *Msg1 = "First message";
CHAR8 *Msg2 = "Second message";
CHAR8 *Msg3 = "Third message";
PrivKey = NULL;
PubKey = NULL;
//
// Allocate signature buffers on the heap to avoid large stack frames.
//
Sig1 = AllocatePool (SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
Sig2 = AllocatePool (SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
Sig3 = AllocatePool (SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
if ((Sig1 == NULL) || (Sig2 == NULL) || (Sig3 == NULL)) {
if (Sig1 != NULL) {
FreePool (Sig1);
}
if (Sig2 != NULL) {
FreePool (Sig2);
}
if (Sig3 != NULL) {
FreePool (Sig3);
}
UT_ASSERT_TRUE ((Sig1 != NULL) && (Sig2 != NULL) && (Sig3 != NULL));
return UNIT_TEST_ERROR_TEST_FAILED;
}
Status = SlhDsaGetPrivateKeyFromPem (
mSlhDsaShake256sTestPemKey,
sizeof (mSlhDsaShake256sTestPemKey),
NULL,
&PrivKey
);
UT_ASSERT_TRUE (Status);
Status = SlhDsaGetPublicKeyFromX509 (
mSlhDsaShake256sTestCert,
sizeof (mSlhDsaShake256sTestCert),
&PubKey
);
UT_ASSERT_TRUE (Status);
//
// Generate three different signatures
//
SigSize = SLH_DSA_SHAKE_256S_SIGNATURE_SIZE;
Status = SlhDsaSign (PrivKey, NULL, 0, (UINT8 *)Msg1, AsciiStrLen (Msg1), Sig1, &SigSize);
UT_ASSERT_TRUE (Status);
SigSize = SLH_DSA_SHAKE_256S_SIGNATURE_SIZE;
Status = SlhDsaSign (PrivKey, NULL, 0, (UINT8 *)Msg2, AsciiStrLen (Msg2), Sig2, &SigSize);
UT_ASSERT_TRUE (Status);
SigSize = SLH_DSA_SHAKE_256S_SIGNATURE_SIZE;
Status = SlhDsaSign (PrivKey, NULL, 0, (UINT8 *)Msg3, AsciiStrLen (Msg3), Sig3, &SigSize);
UT_ASSERT_TRUE (Status);
//
// Verify all three with correct messages
//
Status = SlhDsaVerify (PubKey, NULL, 0, (UINT8 *)Msg1, AsciiStrLen (Msg1), Sig1, SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
UT_ASSERT_TRUE (Status);
Status = SlhDsaVerify (PubKey, NULL, 0, (UINT8 *)Msg2, AsciiStrLen (Msg2), Sig2, SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
UT_ASSERT_TRUE (Status);
Status = SlhDsaVerify (PubKey, NULL, 0, (UINT8 *)Msg3, AsciiStrLen (Msg3), Sig3, SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
UT_ASSERT_TRUE (Status);
//
// Cross-verify should fail (wrong message/signature pairs)
//
Status = SlhDsaVerify (PubKey, NULL, 0, (UINT8 *)Msg1, AsciiStrLen (Msg1), Sig2, SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
UT_ASSERT_FALSE (Status);
Status = SlhDsaVerify (PubKey, NULL, 0, (UINT8 *)Msg2, AsciiStrLen (Msg2), Sig3, SLH_DSA_SHAKE_256S_SIGNATURE_SIZE);
UT_ASSERT_FALSE (Status);
SlhDsaFree (PrivKey);
SlhDsaFree (PubKey);
FreePool (Sig1);
FreePool (Sig2);
FreePool (Sig3);
return UNIT_TEST_PASSED;
}
/**
Test SLH-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
TestVerifySlhDsaGetPubKeyRepeated (
UNIT_TEST_CONTEXT Context
)
{
BOOLEAN Status;
VOID *PrivKey;
UINT8 PubKey1[SLH_DSA_SHAKE_256S_PUBLIC_KEY_SIZE];
UINT8 PubKey2[SLH_DSA_SHAKE_256S_PUBLIC_KEY_SIZE];
UINT8 PubKey3[SLH_DSA_SHAKE_256S_PUBLIC_KEY_SIZE];
UINTN Size1, Size2, Size3;
PrivKey = NULL;
Status = SlhDsaGetPrivateKeyFromPem (
mSlhDsaShake256sTestPemKey,
sizeof (mSlhDsaShake256sTestPemKey),
NULL,
&PrivKey
);
UT_ASSERT_TRUE (Status);
//
// Get public key three times
//
Size1 = sizeof (PubKey1);
Status = SlhDsaGetPubKey (PrivKey, PubKey1, &Size1);
UT_ASSERT_TRUE (Status);
Size2 = sizeof (PubKey2);
Status = SlhDsaGetPubKey (PrivKey, PubKey2, &Size2);
UT_ASSERT_TRUE (Status);
Size3 = sizeof (PubKey3);
Status = SlhDsaGetPubKey (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);
SlhDsaFree (PrivKey);
return UNIT_TEST_PASSED;
}
TEST_DESC mSlhDsaTest[] = {
//
// -----Description------------------------------------Class-------------------------Function----------------------------Pre-------------------Post--------------------Context
//
{ "TestVerifySlhDsaNew()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaNew, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
{ "TestVerifySlhDsaKeySetGet()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaKeySetGet, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
{ "TestVerifySlhDsaErrorCases()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaErrorCases, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
{ "TestVerifySlhDsaPemX509()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaPemX509, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
{ "TestVerifySlhDsaSignVerifyWithContext()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaSignVerifyWithContext, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
{ "TestVerifySlhDsaGetPubKey()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaGetPubKey, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
{ "TestVerifySlhDsaTamperedData()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaTamperedData, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
{ "TestVerifySlhDsaPemErrors()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaPemErrors, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
{ "TestVerifySlhDsaNoKeyOperations()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaNoKeyOperations, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
{ "TestVerifySlhDsaInvalidContextParams()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaInvalidContextParams, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
{ "TestVerifySlhDsaGetPubKeyNullBuffer()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaGetPubKeyNullBuffer, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
{ "TestVerifySlhDsaSignatureSizeExact()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaSignatureSizeExact, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
{ "TestVerifySlhDsaContextLifecycle()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaContextLifecycle, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
{ "TestVerifySlhDsaEmptyMessage()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaEmptyMessage, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
{ "TestVerifySlhDsaMaxContextString()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaMaxContextString, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
{ "TestVerifySlhDsaKeyReplacement()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaKeyReplacement, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
{ "TestVerifySlhDsaMultipleSignatures()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaMultipleSignatures, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
{ "TestVerifySlhDsaGetPubKeyRepeated()", "CryptoPkg.BaseCryptLib.SlhDsa", TestVerifySlhDsaGetPubKeyRepeated, TestVerifySlhDsaPreReq, TestVerifySlhDsaCleanUp, NULL },
};
UINTN mSlhDsaTestNum = ARRAY_SIZE (mSlhDsaTest);