[ICD] Add Nonce validation to Check-In protocol and parsing unit tests (#31080)

* Add Nonce validation and parsing unit tests

* Add missing comments

* Remove unused test signature

* fix comment

* remove include

* fix comment
diff --git a/src/protocols/secure_channel/CheckinMessage.cpp b/src/protocols/secure_channel/CheckinMessage.cpp
index 82f87cb..24fd07f 100644
--- a/src/protocols/secure_channel/CheckinMessage.cpp
+++ b/src/protocols/secure_channel/CheckinMessage.cpp
@@ -105,10 +105,25 @@
     }
 
     // Read decrypted counter and application data
-    counter = Encoding::LittleEndian::Get32(appData.data());
+    static_assert(sizeof(CounterType) == sizeof(uint32_t), "Expect counter to be 32 bits for correct decoding");
+    CounterType tempCounter = Encoding::LittleEndian::Get32(appData.data());
 
-    // TODO : Validate received nonce by calculating it with the hmacKeyHandle and received Counter value
+    // Validate that the received nonce is correct
+    {
+        uint8_t calculatedNonceBuffer[CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES] = { 0 };
+        Encoding::LittleEndian::BufferWriter writer(calculatedNonceBuffer, sizeof(calculatedNonceBuffer));
 
+        ReturnErrorOnFailure(GenerateCheckInMessageNonce(hmacKeyHandle, tempCounter, writer));
+
+        // Validate received nonce is the same as the calculated
+        ByteSpan nonce = payload.SubSpan(0, CHIP_CRYPTO_AEAD_NONCE_LENGTH_BYTES);
+        VerifyOrReturnError(memcmp(nonce.data(), calculatedNonceBuffer, sizeof(calculatedNonceBuffer)) == 0, CHIP_ERROR_INTERNAL);
+    }
+
+    // We have successfully decrypted and validated Check-In message
+    // Set output values
+
+    counter = tempCounter;
     // Shift to remove the counter from the appData
     memmove(appData.data(), sizeof(CounterType) + appData.data(), appDataSize);
     appData.reduce_size(appDataSize);
diff --git a/src/protocols/secure_channel/CheckinMessage.h b/src/protocols/secure_channel/CheckinMessage.h
index 530c601..a0123f3 100644
--- a/src/protocols/secure_channel/CheckinMessage.h
+++ b/src/protocols/secure_channel/CheckinMessage.h
@@ -74,13 +74,16 @@
      * @param[in]       hmac128KeyHandle  Key handle with which to verify the received nonce in the check-in payload (using HMAC).
      * @param[in]       payload           The received payload to decrypt and parse
      * @param[out]      counter           The counter value retrieved from the payload
+     *                                    If an error occurs, no value will be set.
      * @param[in,out]   appData           The optional application data decrypted. The input size of appData must be at least the
-     * size of GetAppDataSize(payload) + sizeof(CounterType), because appData is used as a work buffer for the decryption process.
-     * The output size on success will be GetAppDataSize(payload).
+     *                                    size of GetAppDataSize(payload) + sizeof(CounterType), because appData is used as a work
+     *                                    buffer for the decryption process. The output size on success will be
+     *                                    GetAppDataSize(payload). If an error occurs, appData might countain data,
+     *                                    but the data CANNOT be used since we were not able to validate it.
      *
      * @return CHIP_ERROR_INVALID_MESSAGE_LENGTH if the payload is shorter than the minimum payload size
      *         CHIP_ERROR_BUFFER_TOO_SMALL if appData buffer is too small
-     *         CHIP_ERROR_INVALID_ARGUMENT if the provided arguments cannot be used to parse the Check-In message
+     *         CHIP_ERROR_INTERNAL if we were not able to decrypt or validate the Check-In message
      */
     static CHIP_ERROR ParseCheckinMessagePayload(const Crypto::Aes128KeyHandle & aes128KeyHandle,
                                                  const Crypto::Hmac128KeyHandle & hmacKeyHandle, ByteSpan & payload,
diff --git a/src/protocols/secure_channel/tests/CheckIn_Message_test_vectors.h b/src/protocols/secure_channel/tests/CheckIn_Message_test_vectors.h
index c49bf4e..5563150 100644
--- a/src/protocols/secure_channel/tests/CheckIn_Message_test_vectors.h
+++ b/src/protocols/secure_channel/tests/CheckIn_Message_test_vectors.h
@@ -207,3 +207,45 @@
                                               .payload_len          = sizeof(kPayload5) };
 
 const CheckIn_Message_test_vector checkIn_message_test_vectors[]{ vector1, vector2, vector3, vector4, vector5 };
+
+/**
+ * Invalid Counter / Nonce Match vector
+ */
+
+const uint8_t kInvalidNonceKey[] = {
+    0xca, 0x67, 0xd4, 0x1f, 0xf7, 0x11, 0x29, 0x10, 0xfd, 0xd1, 0x8a, 0x1b, 0xf9, 0x9e, 0xa9, 0x74
+};
+
+const uint8_t kInvalidNonceApplicationData[] = { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x6c,
+                                                 0x6f, 0x6e, 0x67, 0x75, 0x65, 0x72, 0x20, 0x6c, 0x6f, 0x6e, 0x67,
+                                                 0x75, 0x65, 0x72, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67 };
+
+const uint8_t kInvalidNonceNonce[] = { 0x06, 0x34, 0x67, 0x6e, 0xa6, 0xe0, 0x70, 0x7b, 0x7a, 0xd7, 0x81, 0x4f, 0xf8 };
+
+const uint8_t kInvalidNonceCiphertext[] = { 0x29, 0x5b, 0x18, 0xd1, 0x9a, 0x23, 0xb2, 0xe4, 0xfa, 0xdf, 0x82, 0x92,
+                                            0x53, 0x51, 0x7f, 0xf3, 0xc9, 0x1d, 0x9d, 0x50, 0xd6, 0x62, 0x42, 0x03,
+                                            0x35, 0x01, 0xaa, 0x23, 0xad, 0x19, 0xcb, 0x6f, 0x5b, 0xee, 0x56, 0xb3 };
+
+const uint8_t kInvalidNonceMic[] = {
+    0xd5, 0x8a, 0x92, 0x2b, 0x66, 0x44, 0x89, 0x3e, 0x66, 0x31, 0x8b, 0xb5, 0x53, 0x79, 0x24, 0x8b
+};
+
+const uint8_t kInvalidNoncePayload[] = { 0x06, 0x34, 0x67, 0x6e, 0xa6, 0xe0, 0x70, 0x7b, 0x7a, 0xd7, 0x81, 0x4f, 0xf8,
+                                         0x29, 0x5b, 0x18, 0xd1, 0x9a, 0x23, 0xb2, 0xe4, 0xfa, 0xdf, 0x82, 0x92, 0x53,
+                                         0x51, 0x7f, 0xf3, 0xc9, 0x1d, 0x9d, 0x50, 0xd6, 0x62, 0x42, 0x03, 0x35, 0x01,
+                                         0xaa, 0x23, 0xad, 0x19, 0xcb, 0x6f, 0x5b, 0xee, 0x56, 0xb3, 0xd5, 0x8a, 0x92,
+                                         0x2b, 0x66, 0x44, 0x89, 0x3e, 0x66, 0x31, 0x8b, 0xb5, 0x53, 0x79, 0x24, 0x8b };
+
+const CheckIn_Message_test_vector invalidNonceVector = { .key                  = kInvalidNonceKey,
+                                                         .key_len              = sizeof(kInvalidNonceKey),
+                                                         .application_data     = kInvalidNonceApplicationData,
+                                                         .application_data_len = sizeof(kInvalidNonceApplicationData),
+                                                         .counter              = 12,
+                                                         .nonce                = kInvalidNonceNonce,
+                                                         .nonce_len            = sizeof(kInvalidNonceNonce),
+                                                         .ciphertext           = kInvalidNonceCiphertext,
+                                                         .ciphertext_len       = sizeof(kInvalidNonceCiphertext),
+                                                         .mic                  = kInvalidNonceMic,
+                                                         .mic_len              = sizeof(kInvalidNonceMic),
+                                                         .payload              = kInvalidNoncePayload,
+                                                         .payload_len          = sizeof(kInvalidNoncePayload) };
diff --git a/src/protocols/secure_channel/tests/TestCheckinMsg.cpp b/src/protocols/secure_channel/tests/TestCheckinMsg.cpp
index 8fe3a4e..f756b62 100644
--- a/src/protocols/secure_channel/tests/TestCheckinMsg.cpp
+++ b/src/protocols/secure_channel/tests/TestCheckinMsg.cpp
@@ -20,19 +20,15 @@
 #include <crypto/RandUtils.h>
 #include <lib/support/BufferWriter.h>
 #include <lib/support/CHIPMem.h>
+#include <lib/support/UnitTestExtendedAssertions.h>
 #include <lib/support/UnitTestRegistration.h>
+#include <nlunit-test.h>
 #include <protocols/Protocols.h>
 #include <protocols/secure_channel/CheckinMessage.h>
 #include <protocols/secure_channel/Constants.h>
 #include <protocols/secure_channel/StatusReport.h>
 #include <protocols/secure_channel/tests/CheckIn_Message_test_vectors.h>
 #include <transport/CryptoContext.h>
-// AES_CCM_128_test_vectors is being replaced by the CheckIn_Message_test_vectors
-// New tests need to use the CheckIn_Message_test_vectors
-#include <crypto/tests/AES_CCM_128_test_vectors.h>
-#include <lib/support/UnitTestExtendedAssertions.h>
-#include <lib/support/UnitTestRegistration.h>
-#include <nlunit-test.h>
 
 using namespace chip;
 using namespace chip::Protocols;
@@ -48,18 +44,25 @@
 public:
     static void TestCheckinMessageGenerate_ValidInputsSameSizeOutputAsPayload(nlTestSuite * inSuite, void * inContext);
     static void TestCheckinMessageGenerate_ValidInputsBiggerSizeOutput(nlTestSuite * inSuite, void * inContext);
-    static void TestCheckInMessagePayloadSize(nlTestSuite * inSuite, void * inContext);
-    static void TestCheckInMessagePayloadSizeNullBuffer(nlTestSuite * inSuite, void * inContext);
     static void TestCheckinMessageGenerate_ValidInputsTooSmallOutput(nlTestSuite * inSuite, void * inContext);
     static void TestCheckInMessageGenerate_EmptyAesKeyHandle(nlTestSuite * inSuite, void * inContext);
     static void TestCheckInMessageGenerate_EmptyHmacKeyHandle(nlTestSuite * inSuite, void * inContext);
-
-    static void TestCheckinParse(nlTestSuite * inSuite, void * inContext);
-    static void TestCheckinGenerateParse(nlTestSuite * inSuite, void * inContext);
+    static void TestCheckinMessageParse_ValidInputsSameSizeMinAppData(nlTestSuite * inSuite, void * inContext);
+    static void TestCheckinMessageParse_ValidInputsBiggerSizeMinAppData(nlTestSuite * inSuite, void * inContext);
+    static void TestCheckinMessageParse_ValidInputsTooSmallAppData(nlTestSuite * inSuite, void * inContext);
+    static void TestCheckInMessageParse_EmptyAesKeyHandle(nlTestSuite * inSuite, void * inContext);
+    static void TestCheckInMessageParse_EmptyHmacKeyHandle(nlTestSuite * inSuite, void * inContext);
+    static void TestCheckInMessagePayloadSize(nlTestSuite * inSuite, void * inContext);
+    static void TestCheckInMessagePayloadSizeNullBuffer(nlTestSuite * inSuite, void * inContext);
+    static void TestCheckinMessageParse_CorruptedNonce(nlTestSuite * inSuite, void * inContext);
+    static void TestCheckinMessageParse_InvalidNonce(nlTestSuite * inSuite, void * inContext);
 
 private:
     static CHIP_ERROR GenerateAndVerifyPayload(nlTestSuite * inSuite, MutableByteSpan & output,
                                                const CheckIn_Message_test_vector & vector);
+
+    static CHIP_ERROR ParseAndVerifyPayload(nlTestSuite * inSuite, MutableByteSpan & applicationData,
+                                            const CheckIn_Message_test_vector & vector, bool injectInvalidNonce);
 };
 
 /**
@@ -92,8 +95,15 @@
     ByteSpan applicationData(vector.application_data, vector.application_data_len);
 
     // Verify that the generation succeeded
-    ReturnErrorOnFailure(
-        CheckinMessage::GenerateCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, vector.counter, applicationData, output));
+    CHIP_ERROR err =
+        CheckinMessage::GenerateCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, vector.counter, applicationData, output);
+    if (err != CHIP_NO_ERROR)
+    {
+        keystore.DestroyKey(aes128KeyHandle);
+        keystore.DestroyKey(hmac128KeyHandle);
+
+        return err;
+    }
 
     // Validate Full payload
     NL_TEST_ASSERT_EQUALS(inSuite, output.size(), vector.payload_len);
@@ -120,7 +130,73 @@
     keystore.DestroyKey(aes128KeyHandle);
     keystore.DestroyKey(hmac128KeyHandle);
 
-    return CHIP_NO_ERROR;
+    return err;
+}
+
+/**
+ * @brief Helper function that parses the Check-In message based on the test vector
+ *        and verifies parsed Check-In message
+ *        Helper is to avoid having the same code in multiple tests
+ *
+ * @return CHIP_NO_ERROR if the parsing was successful
+ *         error code if the generation failed - see ParseCheckinMessagePayload
+ */
+CHIP_ERROR TestCheckInMsg::ParseAndVerifyPayload(nlTestSuite * inSuite, MutableByteSpan & applicationData,
+                                                 const CheckIn_Message_test_vector & vector, bool injectInvalidNonce)
+{
+    TestSessionKeystoreImpl keystore;
+
+    // Copy payload to be able to modify it for invalid nonce tests
+    uint8_t payloadBuffer[300] = { 0 };
+    memcpy(payloadBuffer, vector.payload, vector.payload_len);
+
+    if (injectInvalidNonce)
+    {
+        // Modify nonce to validate that the parsing can detect that the message was manipulated
+        payloadBuffer[0] ^= 0xFF;
+    }
+
+    // Create payload byte span
+    ByteSpan payload(payloadBuffer, vector.payload_len);
+
+    CounterType decryptedCounter = 0;
+
+    // Two distinct key material buffers to ensure crypto-hardware-assist with single-usage keys create two different handles.
+    Symmetric128BitsKeyByteArray aesKeyMaterial;
+    memcpy(aesKeyMaterial, vector.key, vector.key_len);
+
+    Symmetric128BitsKeyByteArray hmacKeyMaterial;
+    memcpy(hmacKeyMaterial, vector.key, vector.key_len);
+
+    Aes128KeyHandle aes128KeyHandle;
+    NL_TEST_ASSERT_SUCCESS(inSuite, keystore.CreateKey(aesKeyMaterial, aes128KeyHandle));
+
+    Hmac128KeyHandle hmac128KeyHandle;
+    NL_TEST_ASSERT_SUCCESS(inSuite, keystore.CreateKey(hmacKeyMaterial, hmac128KeyHandle));
+
+    // Verify that the Parsing succeeded
+    CHIP_ERROR err =
+        CheckinMessage::ParseCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, payload, decryptedCounter, applicationData);
+    if (err != CHIP_NO_ERROR)
+    {
+        keystore.DestroyKey(aes128KeyHandle);
+        keystore.DestroyKey(hmac128KeyHandle);
+
+        return err;
+    }
+
+    // Verify decrypted counter value
+    NL_TEST_ASSERT_EQUALS(inSuite, vector.counter, decryptedCounter);
+
+    // Verify application data
+    NL_TEST_ASSERT_EQUALS(inSuite, vector.application_data_len, applicationData.size());
+    NL_TEST_ASSERT(inSuite, memcmp(vector.application_data, applicationData.data(), applicationData.size()) == 0);
+
+    // Cleanup
+    keystore.DestroyKey(aes128KeyHandle);
+    keystore.DestroyKey(hmac128KeyHandle);
+
+    return err;
 }
 
 /**
@@ -203,16 +279,16 @@
     ByteSpan applicationData(vector.application_data, vector.application_data_len);
 
     /*
-        Passing an empty key handle while using PSA crypto will result in a failure.
-        When using OpenSSL this same test result in a success.
-        Issue #28986
-
-    Verify that the generation fails with an empty key handle
+        TODO(#28986): Passing an empty key handle while using PSA crypto will result in a failure.
+                      When using OpenSSL this same test result in a success.
+    */
+#if 0
+   // Verify that the generation fails with an empty key handle
     NL_TEST_ASSERT_(inSuite,
                     CHIP_NO_ERROR !=
                         CheckinMessage::GenerateCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, vector.counter,
                                                                       applicationData, output));
-    */
+#endif
 
     // Clean up
     keystore.DestroyKey(hmac128KeyHandle);
@@ -245,136 +321,191 @@
     ByteSpan applicationData(vector.application_data, vector.application_data_len);
 
     /*
-        Passing an empty key handle while using PSA crypto will result in a failure.
-        When using OpenSSL this same test result in a success.
-        Issue #28986
-
-    Verify that the generation fails with an empty key handle
+        TODO(#28986): Passing an empty key handle while using PSA crypto will result in a failure.
+                      When using OpenSSL this same test result in a success.
+    */
+#if 0
+    // Verify that the generation fails with an empty key handle
     NL_TEST_ASSERT_(inSuite,
                     CHIP_NO_ERROR !=
                         CheckinMessage::GenerateCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, vector.counter,
                                                                       applicationData, output));
-    */
+#endif
 
     // Clean up
     keystore.DestroyKey(aes128KeyHandle);
 }
 
-void TestCheckInMsg::TestCheckinParse(nlTestSuite * inSuite, void * inContext)
+/**
+ * @brief Test verifies that the Check-In message parsing succeeds with the Application buffer set to the minimum required size
+ */
+void TestCheckInMsg::TestCheckinMessageParse_ValidInputsSameSizeMinAppData(nlTestSuite * inSuite, void * inContext)
 {
-    uint8_t a[300] = { 0 };
-    uint8_t b[300] = { 0 };
-    MutableByteSpan outputBuffer{ a };
-    MutableByteSpan buffer{ b };
-    uint32_t counter = 0, decryptedCounter;
-    ByteSpan userData;
+    int numOfTestCases = ArraySize(checkIn_message_test_vectors);
+    for (int numOfTestsExecuted = 0; numOfTestsExecuted < numOfTestCases; numOfTestsExecuted++)
+    {
+        CheckIn_Message_test_vector vector = checkIn_message_test_vectors[numOfTestsExecuted];
 
-    CHIP_ERROR err = CHIP_NO_ERROR;
+        uint8_t applicationDataBuffer[128] = { 0 };
+        MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer));
+        applicationData.reduce_size(vector.application_data_len + sizeof(CounterType));
 
+        NL_TEST_ASSERT_SUCCESS(inSuite, ParseAndVerifyPayload(inSuite, applicationData, vector, false));
+    }
+}
+
+/**
+ * @brief Test verifies that the Check-In message parsing succeeds with the Application buffer set to a larger than necessary size
+ */
+void TestCheckInMsg::TestCheckinMessageParse_ValidInputsBiggerSizeMinAppData(nlTestSuite * inSuite, void * inContext)
+{
+    int numOfTestCases = ArraySize(checkIn_message_test_vectors);
+    for (int numOfTestsExecuted = 0; numOfTestsExecuted < numOfTestCases; numOfTestsExecuted++)
+    {
+        CheckIn_Message_test_vector vector = checkIn_message_test_vectors[numOfTestsExecuted];
+
+        uint8_t applicationDataBuffer[128] = { 0 };
+        MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer));
+
+        NL_TEST_ASSERT_SUCCESS(inSuite, ParseAndVerifyPayload(inSuite, applicationData, vector, false));
+    }
+}
+
+/**
+ * @brief Test verifies that the Check-In message throws an error if the application data buffer is too small
+ */
+void TestCheckInMsg::TestCheckinMessageParse_ValidInputsTooSmallAppData(nlTestSuite * inSuite, void * inContext)
+{
+    CheckIn_Message_test_vector vector = checkIn_message_test_vectors[0];
+
+    // Create applicationData buffer with 0 size
+    MutableByteSpan applicationData;
+
+    NL_TEST_ASSERT(inSuite, CHIP_ERROR_BUFFER_TOO_SMALL == ParseAndVerifyPayload(inSuite, applicationData, vector, false));
+}
+
+/**
+ * @brief Test verifies that the Check-In Message parsing returns an error if the AesKeyHandle is empty
+ */
+void TestCheckInMsg::TestCheckInMessageParse_EmptyAesKeyHandle(nlTestSuite * inSuite, void * inContexT)
+{
     TestSessionKeystoreImpl keystore;
+    CheckIn_Message_test_vector vector = checkIn_message_test_vectors[0];
 
-    // Verify User Data Encryption Decryption
-    uint8_t data[]                   = { "This is some user Data. It should be encrypted" };
-    userData                         = chip::ByteSpan(data);
-    const ccm_128_test_vector & test = *ccm_128_test_vectors[0];
+    // Create application data ByteSpan
+    uint8_t applicationDataBuffer[128] = { 0 };
+    MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer));
+    applicationData.reduce_size(vector.application_data_len + sizeof(CounterType));
 
-    // Two distinct key material buffers to ensure crypto-hardware-assist with single-usage keys create two different handles.
-    Symmetric128BitsKeyByteArray aesKeyMaterial;
-    memcpy(aesKeyMaterial, test.key, test.key_len);
+    // Create payload byte span
+    ByteSpan payload(vector.payload, vector.payload_len);
+
+    CounterType decryptedCounter = 0;
+    //
+    (void) decryptedCounter;
+
+    // Empty AES Key handle
+    Aes128KeyHandle aes128KeyHandle;
 
     Symmetric128BitsKeyByteArray hmacKeyMaterial;
-    memcpy(hmacKeyMaterial, test.key, test.key_len);
-
-    Aes128KeyHandle aes128KeyHandle;
-    NL_TEST_ASSERT_SUCCESS(inSuite, keystore.CreateKey(aesKeyMaterial, aes128KeyHandle));
+    memcpy(hmacKeyMaterial, vector.key, vector.key_len);
 
     Hmac128KeyHandle hmac128KeyHandle;
     NL_TEST_ASSERT_SUCCESS(inSuite, keystore.CreateKey(hmacKeyMaterial, hmac128KeyHandle));
 
-    //=================Encrypt=======================
+    /*
+        TODO(#28986): Passing an empty key handle while using PSA crypto will result in a failure.
+                      When using OpenSSL this same test result in a success.
+    */
+#if 0
+   // Verify that the generation fails with an empty key handle
+    NL_TEST_ASSERT_(inSuite,
+                    CHIP_ERROR err !=
+                        CheckinMessage::ParseCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, payload, decryptedCounter, applicationData));
+#endif
 
-    err = CheckinMessage::GenerateCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, counter, userData, outputBuffer);
-    ByteSpan payload = chip::ByteSpan(outputBuffer.data(), outputBuffer.size());
-    NL_TEST_ASSERT(inSuite, (CHIP_NO_ERROR == err));
-
-    //=================Decrypt=======================
-
-    MutableByteSpan empty;
-    err = CheckinMessage::ParseCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, payload, decryptedCounter, empty);
-    NL_TEST_ASSERT(inSuite, (CHIP_NO_ERROR != err));
-
-    ByteSpan emptyPayload;
-    err = CheckinMessage::ParseCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, emptyPayload, decryptedCounter, buffer);
-    NL_TEST_ASSERT(inSuite, (CHIP_NO_ERROR != err));
-
-    // Cleanup
-    keystore.DestroyKey(aes128KeyHandle);
+    // Clean up
     keystore.DestroyKey(hmac128KeyHandle);
 }
 
-void TestCheckInMsg::TestCheckinGenerateParse(nlTestSuite * inSuite, void * inContext)
+/**
+ * @brief Test verifies that the Check-In Message parsing returns an error if the HmacKeyHandle is empty
+ */
+void TestCheckInMsg::TestCheckInMessageParse_EmptyHmacKeyHandle(nlTestSuite * inSuite, void * inContexT)
 {
-    uint8_t a[300] = { 0 };
-    uint8_t b[300] = { 0 };
-    MutableByteSpan outputBuffer{ a };
-    MutableByteSpan buffer{ b };
-    uint32_t counter = 0xDEADBEEF;
-    ByteSpan userData;
-
-    CHIP_ERROR err = CHIP_NO_ERROR;
-
     TestSessionKeystoreImpl keystore;
+    CheckIn_Message_test_vector vector = checkIn_message_test_vectors[0];
 
-    // Verify User Data Encryption Decryption
-    uint8_t data[] = { "This is some user Data. It should be encrypted" };
-    userData       = chip::ByteSpan(data);
-    for (const ccm_128_test_vector * testPtr : ccm_128_test_vectors)
+    // Create application data ByteSpan
+    uint8_t applicationDataBuffer[128] = { 0 };
+    MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer));
+    applicationData.reduce_size(vector.application_data_len + sizeof(CounterType));
+
+    // Create payload byte span
+    ByteSpan payload(vector.payload, vector.payload_len);
+
+    CounterType decryptedCounter = 0;
+    //
+    (void) decryptedCounter;
+
+    // Empty Hmac Key handle
+    Hmac128KeyHandle hmac128KeyHandle;
+
+    Symmetric128BitsKeyByteArray aesKeyMaterial;
+    memcpy(aesKeyMaterial, vector.key, vector.key_len);
+
+    Aes128KeyHandle aes128KeyHandle;
+    NL_TEST_ASSERT_SUCCESS(inSuite, keystore.CreateKey(aesKeyMaterial, aes128KeyHandle));
+
+    /*
+        TODO(#28986): Passing an empty key handle while using PSA crypto will result in a failure.
+                      When using OpenSSL this same test result in a success.
+    */
+#if 0
+   // Verify that the generation fails with an empty key handle
+    NL_TEST_ASSERT_(inSuite,
+                    CHIP_ERROR err !=
+                        CheckinMessage::ParseCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, payload, decryptedCounter, applicationData));
+#endif
+
+    // Clean up
+    keystore.DestroyKey(aes128KeyHandle);
+}
+
+/**
+ * @brief Test verifies that the Check-In message processing throws an error if the nonce is corrupted
+ */
+void TestCheckInMsg::TestCheckinMessageParse_CorruptedNonce(nlTestSuite * inSuite, void * inContext)
+{
+    int numOfTestCases = ArraySize(checkIn_message_test_vectors);
+    for (int numOfTestsExecuted = 0; numOfTestsExecuted < numOfTestCases; numOfTestsExecuted++)
     {
-        const ccm_128_test_vector & test = *testPtr;
+        CheckIn_Message_test_vector vector = checkIn_message_test_vectors[numOfTestsExecuted];
 
-        // Two disctint key material to force the PSA unit tests to create two different Key IDs
-        Symmetric128BitsKeyByteArray aesKeyMaterial;
-        memcpy(aesKeyMaterial, test.key, test.key_len);
+        uint8_t applicationDataBuffer[128] = { 0 };
+        MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer));
+        applicationData.reduce_size(vector.application_data_len + sizeof(CounterType));
 
-        Symmetric128BitsKeyByteArray hmacKeyMaterial;
-        memcpy(hmacKeyMaterial, test.key, test.key_len);
-
-        Aes128KeyHandle aes128KeyHandle;
-        NL_TEST_ASSERT_SUCCESS(inSuite, keystore.CreateKey(aesKeyMaterial, aes128KeyHandle));
-
-        Hmac128KeyHandle hmac128KeyHandle;
-        NL_TEST_ASSERT_SUCCESS(inSuite, keystore.CreateKey(hmacKeyMaterial, hmac128KeyHandle));
-
-        //=================Encrypt=======================
-
-        err = CheckinMessage::GenerateCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, counter, userData, outputBuffer);
-        NL_TEST_ASSERT(inSuite, (CHIP_NO_ERROR == err));
-
-        //=================Decrypt=======================
-        uint32_t decryptedCounter = 0;
-        ByteSpan payload          = chip::ByteSpan(outputBuffer.data(), outputBuffer.size());
-
-        err = CheckinMessage::ParseCheckinMessagePayload(aes128KeyHandle, hmac128KeyHandle, payload, decryptedCounter, buffer);
-        NL_TEST_ASSERT(inSuite, (CHIP_NO_ERROR == err));
-
-        NL_TEST_ASSERT(inSuite, (memcmp(data, buffer.data(), sizeof(data)) == 0));
-        NL_TEST_ASSERT(inSuite, (counter == decryptedCounter));
-
-        // reset buffers
-        memset(a, 0, sizeof(a));
-        memset(b, 0, sizeof(b));
-        outputBuffer = MutableByteSpan(a);
-        buffer       = MutableByteSpan(b);
-
-        counter += chip::Crypto::GetRandU32() + 1;
-
-        // Cleanup
-        keystore.DestroyKey(aes128KeyHandle);
-        keystore.DestroyKey(hmac128KeyHandle);
+        NL_TEST_ASSERT(inSuite, CHIP_ERROR_INTERNAL == ParseAndVerifyPayload(inSuite, applicationData, vector, true));
     }
 }
 
 /**
+ * @brief Test verifies that the Check-In message processing throws an error if the nonce was not calculated with the counter in the
+ * payload
+ */
+void TestCheckInMsg::TestCheckinMessageParse_InvalidNonce(nlTestSuite * inSuite, void * inContext)
+{
+    CheckIn_Message_test_vector vector = invalidNonceVector;
+
+    uint8_t applicationDataBuffer[128] = { 0 };
+    MutableByteSpan applicationData(applicationDataBuffer, sizeof(applicationDataBuffer));
+    applicationData.reduce_size(vector.application_data_len + sizeof(CounterType));
+
+    NL_TEST_ASSERT(inSuite, CHIP_ERROR_INTERNAL == ParseAndVerifyPayload(inSuite, applicationData, vector, false));
+}
+
+/**
  * @brief test verifies that GetAppDataSize returns the correct application data size
  */
 void TestCheckInMsg::TestCheckInMessagePayloadSize(nlTestSuite * inSuite, void * inContext)
@@ -419,13 +550,17 @@
     NL_TEST_DEF("TestCheckinMessageGenerate_ValidInputsSameSizeOutputAsPayload", TestCheckInMsg::TestCheckinMessageGenerate_ValidInputsSameSizeOutputAsPayload),
     NL_TEST_DEF("TestCheckinMessageGenerate_ValidInputsBiggerSizeOutput", TestCheckInMsg::TestCheckinMessageGenerate_ValidInputsBiggerSizeOutput),
     NL_TEST_DEF("TestCheckinMessageGenerate_ValidInputsTooSmallOutput", TestCheckInMsg::TestCheckinMessageGenerate_ValidInputsTooSmallOutput),
-    NL_TEST_DEF("TestCheckinMessageGenerate_ValidInputsTooSmallOutput", TestCheckInMsg::TestCheckInMessageGenerate_EmptyAesKeyHandle),
-    NL_TEST_DEF("TestCheckinMessageGenerate_ValidInputsTooSmallOutput", TestCheckInMsg::TestCheckInMessageGenerate_EmptyHmacKeyHandle),
-    NL_TEST_DEF("TestCheckinParse", TestCheckInMsg::TestCheckinParse),
-    NL_TEST_DEF("TestCheckinGenerateParse", TestCheckInMsg::TestCheckinGenerateParse),
+    NL_TEST_DEF("TestCheckInMessageGenerate_EmptyAesKeyHandle", TestCheckInMsg::TestCheckInMessageGenerate_EmptyAesKeyHandle),
+    NL_TEST_DEF("TestCheckInMessageGenerate_EmptyHmacKeyHandle", TestCheckInMsg::TestCheckInMessageGenerate_EmptyHmacKeyHandle),
+    NL_TEST_DEF("TestCheckinMessageParse_ValidInputsSameSizeMinAppData", TestCheckInMsg::TestCheckinMessageParse_ValidInputsSameSizeMinAppData),
+    NL_TEST_DEF("TestCheckinMessageParse_ValidInputsBiggerSizeMinAppData", TestCheckInMsg::TestCheckinMessageParse_ValidInputsBiggerSizeMinAppData),
+    NL_TEST_DEF("TestCheckinMessageParse_ValidInputsTooSmallAppData", TestCheckInMsg::TestCheckinMessageParse_ValidInputsTooSmallAppData),
+    NL_TEST_DEF("TestCheckInMessageParse_EmptyAesKeyHandle", TestCheckInMsg::TestCheckInMessageParse_EmptyAesKeyHandle),
+    NL_TEST_DEF("TestCheckInMessageParse_EmptyHmacKeyHandle", TestCheckInMsg::TestCheckInMessageParse_EmptyHmacKeyHandle),
+    NL_TEST_DEF("TestCheckinMessageParse_CorruptedNonce", TestCheckInMsg::TestCheckinMessageParse_CorruptedNonce),
+    NL_TEST_DEF("TestCheckinMessageParse_InvalidNonce", TestCheckInMsg::TestCheckinMessageParse_InvalidNonce),
     NL_TEST_DEF("TestCheckInMessagePayloadSize", TestCheckInMsg::TestCheckInMessagePayloadSize),
     NL_TEST_DEF("TestCheckInMessagePayloadSizeNullBuffer", TestCheckInMsg::TestCheckInMessagePayloadSizeNullBuffer),
-
     NL_TEST_SENTINEL()
 };
 // clang-format on