| /* |
| * SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & |
| * AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "base.h" |
| #include "debug-token.h" |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| TEST(provideToken, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_provide_token_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint8_t token[NSM_DEBUG_TOKEN_DATA_MAX_SIZE]; |
| for (uint32_t i = 0; i < NSM_DEBUG_TOKEN_DATA_MAX_SIZE; ++i) { |
| token[i] = i; |
| } |
| |
| auto rc = encode_nsm_provide_token_req( |
| 0, token, NSM_DEBUG_TOKEN_DATA_MAX_SIZE, request); |
| |
| nsm_provide_token_req *req = (nsm_provide_token_req *)request->payload; |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_PROVIDE_TOKEN, req->hdr.command); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_DATA_MAX_SIZE, req->hdr.data_size); |
| EXPECT_EQ( |
| 0, memcmp(token, req->token_data, NSM_DEBUG_TOKEN_DATA_MAX_SIZE)); |
| } |
| |
| TEST(provideToken, testBadEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_provide_token_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint8_t token[NSM_DEBUG_TOKEN_DATA_MAX_SIZE]; |
| for (uint32_t i = 0; i < NSM_DEBUG_TOKEN_DATA_MAX_SIZE; ++i) { |
| token[i] = i; |
| } |
| |
| auto rc = encode_nsm_provide_token_req(0, token, 0, request); |
| |
| EXPECT_EQ(NSM_ERR_INVALID_DATA, rc); |
| } |
| |
| TEST(provideToken, testGoodDecodeResponse) |
| { |
| std::vector<uint8_t> responseMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x00, // RQ=0, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x8A, // OCP_TYPE=8, OCP_VER=10 |
| NSM_TYPE_DIAGNOSTIC, // NVIDIA_MSG_TYPE |
| NSM_PROVIDE_TOKEN, // command |
| NSM_SUCCESS, // completion code |
| 0, |
| 0, // reserved |
| 0, |
| 0, // data size |
| }; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| auto rc = |
| decode_nsm_provide_token_resp(response, msg_len, &cc, &reason_code); |
| |
| EXPECT_EQ(NSM_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| EXPECT_EQ(0, reason_code); |
| } |
| |
| // Test to cover line 208 in debug-token.c (message length validation) |
| TEST(provideToken, DISABLED_testDecodeResponseShortMessage) |
| { |
| std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) + |
| NSM_RESPONSE_ERROR_LEN); // Too short |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| auto rc = decode_nsm_provide_token_resp(response, responseMsg.size(), |
| &cc, &reason_code); |
| |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |
| |
| // Test to cover line 203 in debug-token.c (error completion code path) |
| TEST(provideToken, decodeResponseErrorCompletionCode) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_non_success_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Set up valid response header |
| msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID); |
| msg->hdr.ocp_type = OCP_TYPE; |
| msg->hdr.ocp_version = OCP_VERSION; |
| |
| // Set up error response with reason code |
| auto resp = |
| reinterpret_cast<nsm_common_non_success_resp *>(msg->payload); |
| resp->command = NSM_PROVIDE_TOKEN; |
| resp->completion_code = NSM_ERR_INVALID_DATA; |
| resp->reason_code = htole16(0xCCCC); |
| |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| |
| auto rc = decode_nsm_provide_token_resp(msg, msgBuf.size(), &cc, |
| &reason_code); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(NSM_ERR_INVALID_DATA, cc); |
| EXPECT_EQ(0xCCCC, reason_code); |
| } |
| |
| TEST(disableTokens, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_disable_tokens_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| |
| auto rc = encode_nsm_disable_tokens_req(0, request); |
| |
| nsm_disable_tokens_req *req = |
| (nsm_disable_tokens_req *)request->payload; |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_DISABLE_TOKENS, req->command); |
| EXPECT_EQ(0, req->data_size); |
| } |
| |
| TEST(disableTokens, testBadEncodeRequest) |
| { |
| auto rc = encode_nsm_disable_tokens_req(0, nullptr); |
| |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| } |
| |
| TEST(disableTokens, testGoodDecodeResponse) |
| { |
| std::vector<uint8_t> responseMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x00, // RQ=0, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_DIAGNOSTIC, // NVIDIA_MSG_TYPE |
| NSM_DISABLE_TOKENS, // command |
| NSM_SUCCESS, // completion code |
| 0, |
| 0, // reserved |
| 0, |
| 0, // data size |
| }; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| auto rc = decode_nsm_disable_tokens_resp(response, msg_len, &cc, |
| &reason_code); |
| |
| EXPECT_EQ(NSM_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| EXPECT_EQ(0, reason_code); |
| } |
| |
| // Test to cover line 296 in debug-token.c (message length validation) |
| TEST(disableTokens, DISABLED_testDecodeResponseShortMessage) |
| { |
| std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) + |
| NSM_RESPONSE_ERROR_LEN); // Too short |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| auto rc = decode_nsm_disable_tokens_resp(response, responseMsg.size(), |
| &cc, &reason_code); |
| |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |
| |
| // Test to cover line 291 in debug-token.c (error completion code path) |
| TEST(disableTokens, decodeResponseErrorCompletionCode) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_non_success_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Set up valid response header |
| msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID); |
| msg->hdr.ocp_type = OCP_TYPE; |
| msg->hdr.ocp_version = OCP_VERSION; |
| |
| // Set up error response with reason code |
| auto resp = |
| reinterpret_cast<nsm_common_non_success_resp *>(msg->payload); |
| resp->command = NSM_DISABLE_TOKENS; |
| resp->completion_code = NSM_ERR_INVALID_DATA; |
| resp->reason_code = htole16(0xDDDD); |
| |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| |
| auto rc = decode_nsm_disable_tokens_resp(msg, msgBuf.size(), &cc, |
| &reason_code); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(NSM_ERR_INVALID_DATA, cc); |
| EXPECT_EQ(0xDDDD, reason_code); |
| } |
| |
| TEST(queryTokenStatus, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_status_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| nsm_debug_token_type token_type = NSM_DEBUG_TOKEN_TYPE_FRC; |
| |
| auto rc = encode_nsm_query_token_status_req(0, token_type, request); |
| |
| nsm_query_token_status_req *req = |
| (nsm_query_token_status_req *)request->payload; |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_QUERY_TOKEN_STATUS, req->hdr.command); |
| EXPECT_EQ(1, req->hdr.data_size); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_TYPE_FRC, req->token_type); |
| } |
| |
| TEST(queryTokenStatus, testBadEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_status_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint8_t token_type = 0xFF; |
| |
| auto rc = encode_nsm_query_token_status_req( |
| 0, static_cast<nsm_debug_token_type>(token_type), request); |
| |
| EXPECT_EQ(NSM_ERR_INVALID_DATA, rc); |
| } |
| |
| TEST(queryTokenStatus, testGoodDecodeResponse) |
| { |
| uint16_t data_size = |
| sizeof(nsm_query_token_status_resp) - sizeof(nsm_common_resp); |
| std::vector<uint8_t> responseMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x00, // RQ=0, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_DIAGNOSTIC, // NVIDIA_MSG_TYPE |
| NSM_QUERY_TOKEN_STATUS, // command |
| NSM_SUCCESS, // completion code |
| 0, |
| 0, // reserved |
| (uint8_t)(data_size & 0x00FF), // data size |
| (uint8_t)((data_size & 0xFF00) >> 8), // data size |
| NSM_DEBUG_TOKEN_TYPE_CRCS, // token type |
| 0, // reserved |
| NSM_DEBUG_TOKEN_STATUS_ADDITIONAL_INFO_NONE, // additional info |
| NSM_DEBUG_TOKEN_STATUS_NO_TOKEN_APPLIED, // status |
| 0x12, // time left |
| 0x34, // time left |
| 0x56, // time left |
| 0x78 // time left |
| }; |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| nsm_debug_token_status status; |
| nsm_debug_token_status_additional_info additional_info; |
| nsm_debug_token_type token_type; |
| uint32_t time_left; |
| |
| auto rc = decode_nsm_query_token_status_resp( |
| response, msg_len, &cc, &reason_code, &status, &additional_info, |
| &token_type, &time_left); |
| |
| EXPECT_EQ(NSM_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| EXPECT_EQ(0, reason_code); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_STATUS_NO_TOKEN_APPLIED, status); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_STATUS_ADDITIONAL_INFO_NONE, additional_info); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_TYPE_CRCS, token_type); |
| EXPECT_EQ(0x78563412, time_left); |
| } |
| |
| // Test to cover line 400 in debug-token.c (error completion code path) |
| TEST(queryTokenStatus, decodeResponseErrorCompletionCode) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_non_success_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Set up valid response header |
| msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID); |
| msg->hdr.ocp_type = OCP_TYPE; |
| msg->hdr.ocp_version = OCP_VERSION; |
| |
| // Set up error response with reason code |
| auto resp = |
| reinterpret_cast<nsm_common_non_success_resp *>(msg->payload); |
| resp->command = NSM_QUERY_TOKEN_STATUS; |
| resp->completion_code = NSM_ERR_INVALID_DATA; |
| resp->reason_code = htole16(0xBBBB); |
| |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| nsm_debug_token_status status; |
| nsm_debug_token_status_additional_info additional_info; |
| nsm_debug_token_type token_type; |
| uint32_t time_left; |
| |
| auto rc = decode_nsm_query_token_status_resp( |
| msg, msgBuf.size(), &cc, &reason_code, &status, &additional_info, |
| &token_type, &time_left); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(NSM_ERR_INVALID_DATA, cc); |
| EXPECT_EQ(0xBBBB, reason_code); |
| } |
| |
| TEST(queryTokenParameters, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_parameters_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| nsm_debug_token_opcode token_opcode = NSM_DEBUG_TOKEN_OPCODE_CRCS; |
| |
| auto rc = |
| encode_nsm_query_token_parameters_req(0, token_opcode, request); |
| |
| nsm_query_token_parameters_req *req = |
| (nsm_query_token_parameters_req *)request->payload; |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_QUERY_TOKEN_PARAMETERS, req->hdr.command); |
| EXPECT_EQ(1, req->hdr.data_size); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_OPCODE_CRCS, req->token_opcode); |
| } |
| |
| TEST(queryTokenParameters, testBadEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_parameters_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint8_t token_opcode = 0xFF; |
| |
| auto rc = encode_nsm_query_token_parameters_req( |
| 0, static_cast<nsm_debug_token_opcode>(token_opcode), request); |
| |
| EXPECT_EQ(NSM_ERR_INVALID_DATA, rc); |
| } |
| |
| TEST(queryTokenParameters, testGoodDecodeResponse) |
| { |
| std::vector<uint8_t> responseMsg{ |
| 0x10, 0xde, 0x00, 0x89, 0x04, 0x54, 0x00, 0x00, 0x00, 0x8c, 0x00, |
| 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x1c, 0x76, 0xc0, 0xc4, 0xfc, 0xaf, 0x17, 0x24, 0x03, |
| 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x59, 0xbf, 0x4a, 0x04, |
| 0x3d, 0xdd, 0x11, 0xef, 0xb9, 0x4f, 0xac, 0x1f, 0x6b, 0x01, 0xe5, |
| 0xae, 0x1c, 0x76, 0xc0, 0xc4, 0xfc, 0xaf, 0x17, 0x24, 0x4e, 0x56, |
| 0x44, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, 0x30, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x07, 0xde, 0x04, 0x48, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xfe, |
| 0x66, 0xd4, 0xb4, 0x5c, 0x4e, 0xae, 0xdc, 0x42, 0xdc, 0x25, 0xc7, |
| 0xc6, 0x8c, 0xcf, 0x7c, 0x1d, 0x85, 0x7d, 0x6f, 0x63, 0x66, 0x7b, |
| 0xaa, 0xdf, 0xb3, 0xcb, 0x4b, 0x37, 0x8d, 0x38}; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| nsm_debug_token_request token_request; |
| memset(&token_request, 0, sizeof(nsm_debug_token_request)); |
| |
| auto rc = decode_nsm_query_token_parameters_resp( |
| response, msg_len, &cc, &reason_code, &token_request); |
| |
| EXPECT_EQ(NSM_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| EXPECT_EQ(0, reason_code); |
| EXPECT_EQ(sizeof(nsm_debug_token_request), |
| token_request.token_request_size); |
| EXPECT_EQ(0, token_request.token_request_version); |
| EXPECT_EQ(0x1C, token_request.device_uuid[0]); |
| EXPECT_EQ(0x76, token_request.device_uuid[1]); |
| EXPECT_EQ(0xC0, token_request.device_uuid[2]); |
| EXPECT_EQ(0xC4, token_request.device_uuid[3]); |
| EXPECT_EQ(0xFC, token_request.device_uuid[4]); |
| EXPECT_EQ(0xAF, token_request.device_uuid[5]); |
| EXPECT_EQ(0x17, token_request.device_uuid[6]); |
| EXPECT_EQ(0x24, token_request.device_uuid[7]); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_DEVICE_TYPE_ID_NVSWITCH, |
| token_request.device_type); |
| EXPECT_EQ(0, token_request.device_index); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_CHALLENGE_QUERY_STATUS_OK, |
| token_request.status); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_OPCODE_CRDT, token_request.token_opcode); |
| EXPECT_EQ(0x23, token_request.fw_version[0]); |
| EXPECT_EQ(0x07, token_request.fw_version[1]); |
| EXPECT_EQ(0xDE, token_request.fw_version[2]); |
| EXPECT_EQ(0x04, token_request.fw_version[3]); |
| EXPECT_EQ(0x48, token_request.fw_version[4]); |
| EXPECT_EQ(0, token_request.session_id); |
| EXPECT_EQ(0, token_request.challenge_version); |
| } |
| |
| // Test to cover line 89 in debug-token.c (error completion code path) |
| TEST(queryTokenParameters, decodeResponseErrorCompletionCode) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_non_success_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Set up valid response header |
| msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID); |
| msg->hdr.ocp_type = OCP_TYPE; |
| msg->hdr.ocp_version = OCP_VERSION; |
| |
| // Set up error response with reason code |
| auto resp = |
| reinterpret_cast<nsm_common_non_success_resp *>(msg->payload); |
| resp->command = NSM_QUERY_TOKEN_PARAMETERS; |
| resp->completion_code = NSM_ERR_INVALID_DATA; |
| resp->reason_code = htole16(0xEEEE); |
| |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| nsm_debug_token_request token_request; |
| memset(&token_request, 0, sizeof(nsm_debug_token_request)); |
| |
| auto rc = decode_nsm_query_token_parameters_resp( |
| msg, msgBuf.size(), &cc, &reason_code, &token_request); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(NSM_ERR_INVALID_DATA, cc); |
| EXPECT_EQ(0xEEEE, reason_code); |
| } |
| |
| // Test to cover line 101 in debug-token.c (token_request_size validation) |
| TEST(queryTokenParameters, decodeResponseInvalidTokenRequestSize) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_parameters_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Set up valid response header |
| msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID); |
| msg->hdr.ocp_type = OCP_TYPE; |
| msg->hdr.ocp_version = OCP_VERSION; |
| |
| auto resp = |
| reinterpret_cast<nsm_query_token_parameters_resp *>(msg->payload); |
| resp->hdr.command = NSM_QUERY_TOKEN_PARAMETERS; |
| resp->hdr.completion_code = NSM_SUCCESS; |
| resp->hdr.data_size = htole16(sizeof(nsm_query_token_parameters_resp) - |
| sizeof(nsm_common_resp)); |
| |
| // Set invalid token_request_size (should be |
| // sizeof(nsm_debug_token_request)) |
| resp->token_request.token_request_size = 0; |
| |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| nsm_debug_token_request token_request; |
| memset(&token_request, 0, sizeof(nsm_debug_token_request)); |
| |
| auto rc = decode_nsm_query_token_parameters_resp( |
| msg, msgBuf.size(), &cc, &reason_code, &token_request); |
| |
| EXPECT_EQ(NSM_SW_ERROR_DATA, rc); |
| } |
| |
| TEST(queryDeviceIDs, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_device_ids_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| |
| auto rc = encode_nsm_query_device_ids_req(0, request); |
| |
| nsm_query_device_ids_req *req = |
| (nsm_query_device_ids_req *)request->payload; |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_QUERY_DEVICE_IDS, req->command); |
| EXPECT_EQ(0, req->data_size); |
| } |
| |
| TEST(queryDeviceIDs, testGoodEncodeResponse) |
| { |
| std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_device_ids_resp) + 8); |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| uint8_t device_id[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; |
| |
| auto rc = encode_nsm_query_device_ids_resp(0, cc, reason_code, |
| device_id, 8, response); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(0, response->hdr.request); |
| EXPECT_EQ(0, response->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, response->hdr.nvidia_msg_type); |
| |
| nsm_query_device_ids_resp *resp = |
| (nsm_query_device_ids_resp *)response->payload; |
| EXPECT_EQ(NSM_QUERY_DEVICE_IDS, resp->hdr.command); |
| EXPECT_EQ(cc, resp->hdr.completion_code); |
| EXPECT_EQ(8, le16toh(resp->hdr.data_size)); |
| EXPECT_EQ(0, memcmp(device_id, resp->data, 8)); |
| } |
| |
| TEST(queryDeviceIDs, testBadEncodeResponse) |
| { |
| uint8_t device_id[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; |
| |
| // null message |
| auto rc = encode_nsm_query_device_ids_resp(0, NSM_SUCCESS, ERR_NULL, |
| device_id, 8, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // null device_id |
| std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_device_ids_resp) + 8); |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| rc = encode_nsm_query_device_ids_resp(0, NSM_SUCCESS, ERR_NULL, nullptr, |
| 8, response); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // zero device_id_len |
| rc = encode_nsm_query_device_ids_resp(0, NSM_SUCCESS, ERR_NULL, |
| device_id, 0, response); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |
| |
| TEST(queryDeviceIDs, testEncodeResponseWithError) |
| { |
| std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_device_ids_resp) + 8); |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| uint8_t cc = NSM_ERROR; |
| uint16_t reason_code = NSM_ERR_INVALID_DATA; |
| uint8_t device_id[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; |
| |
| auto rc = encode_nsm_query_device_ids_resp(0, cc, reason_code, |
| device_id, 8, response); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(0, response->hdr.request); |
| EXPECT_EQ(0, response->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, response->hdr.nvidia_msg_type); |
| } |
| |
| TEST(queryDeviceIDs, testGoodDecodeResponse) |
| { |
| std::vector<uint8_t> responseMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x00, // RQ=0, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_DIAGNOSTIC, // NVIDIA_MSG_TYPE |
| NSM_QUERY_DEVICE_IDS, // command |
| NSM_SUCCESS, // completion code |
| 0, |
| 0, // reserved |
| 8, // data size (little endian) |
| 0, // data size |
| 0x01, // ID |
| 0x02, // ID |
| 0x03, // ID |
| 0x04, // ID |
| 0x05, // ID |
| 0x06, // ID |
| 0x07, // ID |
| 0x08, // ID |
| }; |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| uint8_t device_id[8]; |
| size_t device_id_len = 0; |
| |
| auto rc = decode_nsm_query_device_ids_resp( |
| response, msg_len, &cc, &reason_code, device_id, &device_id_len); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| EXPECT_EQ(0, reason_code); |
| EXPECT_EQ(8, device_id_len); |
| EXPECT_EQ(0x01, device_id[0]); |
| EXPECT_EQ(0x02, device_id[1]); |
| EXPECT_EQ(0x03, device_id[2]); |
| EXPECT_EQ(0x04, device_id[3]); |
| EXPECT_EQ(0x05, device_id[4]); |
| EXPECT_EQ(0x06, device_id[5]); |
| EXPECT_EQ(0x07, device_id[6]); |
| EXPECT_EQ(0x08, device_id[7]); |
| } |
| |
| TEST(queryDeviceIDs, testDecodeResponseWithNullDeviceId) |
| { |
| std::vector<uint8_t> responseMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x00, // RQ=0, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_DIAGNOSTIC, // NVIDIA_MSG_TYPE |
| NSM_QUERY_DEVICE_IDS, // command |
| NSM_SUCCESS, // completion code |
| 0, |
| 0, // reserved |
| 8, // data size (little endian) |
| 0, // data size |
| 0x01, // ID |
| 0x02, // ID |
| 0x03, // ID |
| 0x04, // ID |
| 0x05, // ID |
| 0x06, // ID |
| 0x07, // ID |
| 0x08, // ID |
| }; |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| size_t device_id_len = 0; |
| |
| // Test with null device_id pointer (should still work) |
| auto rc = decode_nsm_query_device_ids_resp( |
| response, msg_len, &cc, &reason_code, nullptr, &device_id_len); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| EXPECT_EQ(0, reason_code); |
| EXPECT_EQ(8, device_id_len); |
| } |
| |
| TEST(queryDeviceIDs, testBadDecodeResponse) |
| { |
| uint8_t cc; |
| uint16_t reason_code; |
| uint8_t device_id[8]; |
| size_t device_id_len; |
| |
| // null message |
| auto rc = decode_nsm_query_device_ids_resp( |
| nullptr, 100, &cc, &reason_code, device_id, &device_id_len); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // null parameters |
| std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_device_ids_resp) + 8); |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| |
| rc = decode_nsm_query_device_ids_resp(response, responseMsg.size(), |
| nullptr, &reason_code, device_id, |
| &device_id_len); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| rc = decode_nsm_query_device_ids_resp(response, responseMsg.size(), &cc, |
| nullptr, device_id, |
| &device_id_len); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| rc = decode_nsm_query_device_ids_resp(response, responseMsg.size(), &cc, |
| &reason_code, device_id, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // insufficient message length |
| rc = decode_nsm_query_device_ids_resp(response, 10, &cc, &reason_code, |
| device_id, &device_id_len); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |
| |
| TEST(queryDeviceIDs, testDecodeResponseWithError) |
| { |
| std::vector<uint8_t> responseMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x00, // RQ=0, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_DIAGNOSTIC, // NVIDIA_MSG_TYPE |
| NSM_QUERY_DEVICE_IDS, // command |
| NSM_ERROR, // completion code |
| ERR_TIMEOUT, // reason code |
| 0, |
| }; |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| uint8_t device_id[8]; |
| size_t device_id_len = 0; |
| |
| auto rc = decode_nsm_query_device_ids_resp( |
| response, msg_len, &cc, &reason_code, device_id, &device_id_len); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(NSM_ERROR, cc); |
| EXPECT_EQ(ERR_TIMEOUT, reason_code); |
| } |
| |
| TEST(installToken, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_install_token_req) + 100); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint32_t chunk_offset = 0x12345678; |
| uint32_t chunk_length = 64; |
| uint32_t length_remaining = 1024; |
| uint8_t data[64]; |
| for (uint32_t i = 0; i < chunk_length; ++i) { |
| data[i] = i & 0xFF; |
| } |
| |
| auto rc = encode_nsm_install_token_req(0, chunk_offset, chunk_length, |
| length_remaining, data, request); |
| nsm_install_token_req *req = (nsm_install_token_req *)request->payload; |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type); |
| EXPECT_EQ(NSM_INSTALL_TOKEN, req->hdr.command); |
| EXPECT_EQ(sizeof(chunk_offset) + sizeof(chunk_length) + |
| sizeof(length_remaining) + chunk_length, |
| le16toh(req->hdr.data_size)); |
| EXPECT_EQ(chunk_offset, le32toh(req->chunk_offset)); |
| EXPECT_EQ(chunk_length, le32toh(req->chunk_length)); |
| EXPECT_EQ(length_remaining, le32toh(req->length_remaining)); |
| EXPECT_EQ(0, memcmp(data, req->data, chunk_length)); |
| } |
| |
| TEST(installToken, testBadEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_install_token_req) + 100); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint8_t data[64]; |
| |
| // null message |
| auto rc = encode_nsm_install_token_req(0, 0, 64, 1024, data, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // null data |
| rc = encode_nsm_install_token_req(0, 0, 64, 1024, nullptr, request); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| } |
| |
| TEST(installToken, testGoodDecodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_install_token_req) + 100); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint32_t expected_chunk_offset = 0x12345678; |
| uint32_t expected_chunk_length = 64; |
| uint32_t expected_length_remaining = 1024; |
| uint8_t expected_data[64]; |
| for (uint32_t i = 0; i < expected_chunk_length; ++i) { |
| expected_data[i] = i & 0xFF; |
| } |
| auto rc = encode_nsm_install_token_req( |
| 0, expected_chunk_offset, expected_chunk_length, |
| expected_length_remaining, expected_data, request); |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| uint32_t chunk_offset; |
| uint32_t chunk_length; |
| uint32_t length_remaining; |
| uint8_t data[64]; |
| rc = decode_nsm_install_token_req(request, requestMsg.size(), |
| &chunk_offset, &chunk_length, |
| &length_remaining, data); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(expected_chunk_offset, chunk_offset); |
| EXPECT_EQ(expected_chunk_length, chunk_length); |
| EXPECT_EQ(expected_length_remaining, length_remaining); |
| EXPECT_EQ(0, memcmp(expected_data, data, expected_chunk_length)); |
| } |
| |
| TEST(installToken, testBadDecodeRequest) |
| { |
| uint32_t chunk_offset; |
| uint32_t chunk_length; |
| uint32_t length_remaining; |
| uint8_t data[64]; |
| |
| // null message |
| auto rc = decode_nsm_install_token_req(nullptr, 100, &chunk_offset, |
| &chunk_length, &length_remaining, |
| data); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // null parameters |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_install_token_req)); |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| |
| rc = decode_nsm_install_token_req(request, requestMsg.size(), nullptr, |
| &chunk_length, &length_remaining, |
| data); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| rc = decode_nsm_install_token_req(request, requestMsg.size(), |
| &chunk_offset, nullptr, |
| &length_remaining, data); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| rc = decode_nsm_install_token_req(request, requestMsg.size(), |
| &chunk_offset, &chunk_length, nullptr, |
| data); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // insufficient message length |
| rc = decode_nsm_install_token_req( |
| request, 10, &chunk_offset, &chunk_length, &length_remaining, data); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |
| |
| TEST(eraseToken, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_erase_token_req)); |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint32_t token_type = 0x12345678; |
| auto rc = encode_nsm_erase_token_req(0, token_type, request); |
| nsm_erase_token_req *req = (nsm_erase_token_req *)request->payload; |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type); |
| EXPECT_EQ(NSM_ERASE_TOKEN, req->hdr.command); |
| EXPECT_EQ(sizeof(token_type), req->hdr.data_size); |
| EXPECT_EQ(token_type, le32toh(req->token_type)); |
| } |
| |
| TEST(eraseToken, testBadEncodeRequest) |
| { |
| auto rc = encode_nsm_erase_token_req(0, 0x12345678, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| } |
| |
| TEST(eraseToken, testGoodDecodeRequest) |
| { |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_erase_token_req)); |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| uint32_t expected_token_type = 0x87654321; |
| auto rc = encode_nsm_erase_token_req(0, expected_token_type, request); |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| uint32_t token_type; |
| rc = |
| decode_nsm_erase_token_req(request, requestMsg.size(), &token_type); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(expected_token_type, token_type); |
| } |
| |
| TEST(eraseToken, testBadDecodeRequest) |
| { |
| uint32_t token_type; |
| |
| // null message |
| auto rc = decode_nsm_erase_token_req(nullptr, 100, &token_type); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // null parameter |
| std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_erase_token_req)); |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| |
| rc = decode_nsm_erase_token_req(request, requestMsg.size(), nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // insufficient message length |
| rc = decode_nsm_erase_token_req(request, 10, &token_type); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| |
| // invalid data size |
| nsm_erase_token_req *req = (nsm_erase_token_req *)request->payload; |
| req->hdr.data_size = 10; // Invalid size |
| rc = |
| decode_nsm_erase_token_req(request, requestMsg.size(), &token_type); |
| EXPECT_EQ(NSM_SW_ERROR_DATA, rc); |
| } |
| |
| TEST(queryToken, testGoodEncodeResponse) |
| { |
| std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_resp) + 100); |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| uint8_t tlv_payload[64]; |
| size_t tlv_payload_len = 32; |
| for (size_t i = 0; i < tlv_payload_len; ++i) { |
| tlv_payload[i] = i & 0xFF; |
| } |
| |
| auto rc = encode_nsm_query_token_resp(0, cc, reason_code, tlv_payload, |
| tlv_payload_len, response); |
| nsm_query_token_resp *resp = (nsm_query_token_resp *)response->payload; |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(0, response->hdr.request); |
| EXPECT_EQ(0, response->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, response->hdr.nvidia_msg_type); |
| EXPECT_EQ(NSM_QUERY_TOKEN, resp->hdr.command); |
| EXPECT_EQ(cc, resp->hdr.completion_code); |
| EXPECT_EQ(tlv_payload_len, le16toh(resp->hdr.data_size)); |
| EXPECT_EQ(0, memcmp(tlv_payload, resp->tlv_payload, tlv_payload_len)); |
| } |
| |
| TEST(queryToken, testBadEncodeResponse) |
| { |
| uint8_t tlv_payload[64] = {0}; |
| |
| auto rc = encode_nsm_query_token_resp(0, NSM_SUCCESS, ERR_NULL, |
| tlv_payload, 32, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| } |
| |
| // Test to cover line 862 in debug-token.c (error completion code path) |
| TEST(queryToken, errorCompletionCodeEncodeResponse) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + 256); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Test with non-success completion code to trigger error path |
| uint8_t cc = NSM_ERR_INVALID_DATA; |
| uint16_t reason_code = 0x8899; |
| uint8_t tlv_payload[64] = {0}; |
| |
| auto rc = encode_nsm_query_token_resp(0, cc, reason_code, tlv_payload, |
| 32, msg); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| // Verify error response structure |
| auto resp_payload = |
| reinterpret_cast<nsm_common_non_success_resp *>(msg->payload); |
| EXPECT_EQ(NSM_QUERY_TOKEN, resp_payload->command); |
| EXPECT_EQ(cc, resp_payload->completion_code); |
| EXPECT_EQ(reason_code, le16toh(resp_payload->reason_code)); |
| } |
| |
| TEST(queryToken, testGoodDecodeResponse) |
| { |
| uint16_t data_size = 32; |
| std::vector<uint8_t> responseMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x00, // RQ=0, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_DIAGNOSTIC, // NVIDIA_MSG_TYPE |
| NSM_QUERY_TOKEN, // command |
| NSM_SUCCESS, // completion code |
| 0, |
| 0, // reserved |
| (uint8_t)(data_size & 0x00FF), // data size |
| (uint8_t)((data_size & 0xFF00) >> 8) // data size |
| }; |
| for (uint16_t i = 0; i < data_size; ++i) { |
| responseMsg.push_back(i & 0xFF); |
| } |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| uint8_t tlv_payload[64]; |
| size_t tlv_payload_len = sizeof(tlv_payload); |
| auto rc = |
| decode_nsm_query_token_resp(response, msg_len, &cc, &reason_code, |
| tlv_payload, &tlv_payload_len); |
| EXPECT_EQ(NSM_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| EXPECT_EQ(0, reason_code); |
| EXPECT_EQ(data_size, tlv_payload_len); |
| for (uint16_t i = 0; i < data_size; ++i) { |
| EXPECT_EQ(i & 0xFF, tlv_payload[i]); |
| } |
| } |
| |
| TEST(queryToken, testBadDecodeResponse) |
| { |
| uint8_t cc; |
| uint16_t reason_code; |
| uint8_t tlv_payload[64]; |
| size_t tlv_payload_len; |
| |
| // null message |
| auto rc = decode_nsm_query_token_resp(nullptr, 100, &cc, &reason_code, |
| tlv_payload, &tlv_payload_len); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // null parameters |
| std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_resp)); |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| |
| rc = decode_nsm_query_token_resp(response, responseMsg.size(), nullptr, |
| &reason_code, tlv_payload, |
| &tlv_payload_len); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| rc = |
| decode_nsm_query_token_resp(response, responseMsg.size(), &cc, |
| nullptr, tlv_payload, &tlv_payload_len); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| rc = decode_nsm_query_token_resp(response, responseMsg.size(), &cc, |
| &reason_code, tlv_payload, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // insufficient message length |
| rc = decode_nsm_query_token_resp(response, 10, &cc, &reason_code, |
| tlv_payload, &tlv_payload_len); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |
| |
| // Test to cover line 821 in debug-token.c (error completion code path) |
| TEST(queryToken, decodeResponseErrorCompletionCode) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_non_success_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Set up valid response header |
| msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID); |
| msg->hdr.ocp_type = OCP_TYPE; |
| msg->hdr.ocp_version = OCP_VERSION; |
| |
| // Set up error response with reason code |
| auto resp = |
| reinterpret_cast<nsm_common_non_success_resp *>(msg->payload); |
| resp->command = NSM_QUERY_TOKEN; |
| resp->completion_code = NSM_ERR_INVALID_DATA; |
| resp->reason_code = htole16(0x9AAA); |
| |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| uint8_t tlv_payload[64]; |
| size_t tlv_payload_len = sizeof(tlv_payload); |
| |
| auto rc = |
| decode_nsm_query_token_resp(msg, msgBuf.size(), &cc, &reason_code, |
| tlv_payload, &tlv_payload_len); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(NSM_ERR_INVALID_DATA, cc); |
| EXPECT_EQ(0x9AAA, reason_code); |
| } |
| |
| // Tests for uncovered functions - Functional 90% coverage target |
| |
| TEST(queryTokenParameters, goodTestDecodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_parameters_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| auto req = |
| reinterpret_cast<nsm_query_token_parameters_req *>(msg->payload); |
| req->hdr.command = NSM_QUERY_TOKEN_PARAMETERS; |
| req->hdr.data_size = sizeof(req->token_opcode); |
| req->token_opcode = NSM_DEBUG_TOKEN_OPCODE_RMCS; |
| |
| enum nsm_debug_token_opcode token_opcode = |
| NSM_DEBUG_TOKEN_OPCODE_LINKX_FRC; |
| |
| auto rc = decode_nsm_query_token_parameters_req(msg, msgBuf.size(), |
| &token_opcode); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_OPCODE_RMCS, token_opcode); |
| } |
| |
| TEST(queryTokenParameters, badTestDecodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_parameters_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| enum nsm_debug_token_opcode token_opcode = |
| NSM_DEBUG_TOKEN_OPCODE_LINKX_FRC; |
| |
| // Null message |
| auto rc = decode_nsm_query_token_parameters_req(nullptr, msgBuf.size(), |
| &token_opcode); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // Null output parameter |
| rc = decode_nsm_query_token_parameters_req(msg, msgBuf.size(), nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // Invalid message length |
| rc = decode_nsm_query_token_parameters_req(msg, 1, &token_opcode); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |
| |
| // Test to cover line 38 in debug-token.c (data_size validation) |
| TEST(queryTokenParameters, decodeRequestInvalidDataSize) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_parameters_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| auto req = |
| reinterpret_cast<nsm_query_token_parameters_req *>(msg->payload); |
| req->hdr.command = NSM_QUERY_TOKEN_PARAMETERS; |
| req->hdr.data_size = |
| 0; // Invalid - should be at least sizeof(token_opcode) |
| req->token_opcode = NSM_DEBUG_TOKEN_OPCODE_CRCS; |
| |
| enum nsm_debug_token_opcode token_opcode = |
| NSM_DEBUG_TOKEN_OPCODE_LINKX_FRC; |
| |
| auto rc = decode_nsm_query_token_parameters_req(msg, msgBuf.size(), |
| &token_opcode); |
| |
| EXPECT_EQ(NSM_SW_ERROR_DATA, rc); |
| } |
| |
| TEST(queryTokenParameters, goodTestEncodeResponse) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_parameters_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| struct nsm_debug_token_request token_request = {}; |
| token_request.token_request_size = |
| sizeof(struct nsm_debug_token_request); |
| |
| auto rc = encode_nsm_query_token_parameters_resp(0, NSM_SUCCESS, 0, |
| &token_request, msg); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(0, msg->hdr.request); |
| EXPECT_EQ(0, msg->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, msg->hdr.nvidia_msg_type); |
| |
| auto resp = |
| reinterpret_cast<nsm_query_token_parameters_resp *>(msg->payload); |
| EXPECT_EQ(NSM_QUERY_TOKEN_PARAMETERS, resp->hdr.command); |
| EXPECT_EQ(NSM_SUCCESS, resp->hdr.completion_code); |
| } |
| |
| TEST(queryTokenParameters, badTestEncodeResponse) |
| { |
| struct nsm_debug_token_request token_request = {}; |
| |
| // Null message |
| auto rc = encode_nsm_query_token_parameters_resp( |
| 0, NSM_SUCCESS, 0, &token_request, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| } |
| |
| // Test to cover line 127 in debug-token.c (error completion code path) |
| TEST(queryTokenParameters, errorCompletionCodeEncodeResponse) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + 256); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| struct nsm_debug_token_request token_request = {}; |
| token_request.token_request_size = |
| sizeof(struct nsm_debug_token_request); |
| |
| // Test with non-success completion code to trigger error path |
| uint8_t cc = NSM_ERR_INVALID_DATA; |
| uint16_t reason_code = 0xABCD; |
| |
| auto rc = encode_nsm_query_token_parameters_resp(0, cc, reason_code, |
| &token_request, msg); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| // Verify error response structure |
| auto resp_payload = |
| reinterpret_cast<nsm_common_non_success_resp *>(msg->payload); |
| EXPECT_EQ(NSM_QUERY_TOKEN_PARAMETERS, resp_payload->command); |
| EXPECT_EQ(cc, resp_payload->completion_code); |
| EXPECT_EQ(reason_code, le16toh(resp_payload->reason_code)); |
| } |
| |
| TEST(provideToken, goodTestDecodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_provide_token_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| auto req = reinterpret_cast<nsm_provide_token_req *>(msg->payload); |
| req->hdr.command = NSM_PROVIDE_TOKEN; |
| req->hdr.data_size = 32; |
| memset(req->token_data, 0xAB, 32); |
| |
| uint8_t token_data[NSM_DEBUG_TOKEN_DATA_MAX_SIZE] = {0}; |
| uint8_t token_data_len = 0; |
| |
| auto rc = decode_nsm_provide_token_req(msg, msgBuf.size(), token_data, |
| &token_data_len); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(32, token_data_len); |
| EXPECT_EQ(0xAB, token_data[0]); |
| } |
| |
| TEST(provideToken, badTestDecodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_provide_token_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| uint8_t token_data[NSM_DEBUG_TOKEN_DATA_MAX_SIZE] = {0}; |
| uint8_t token_data_len = 0; |
| |
| // Null message |
| auto rc = decode_nsm_provide_token_req(nullptr, msgBuf.size(), |
| token_data, &token_data_len); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // Null output parameters |
| rc = decode_nsm_provide_token_req(msg, msgBuf.size(), nullptr, |
| &token_data_len); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| rc = decode_nsm_provide_token_req(msg, msgBuf.size(), token_data, |
| nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // Invalid message length |
| rc = decode_nsm_provide_token_req(msg, 1, token_data, &token_data_len); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |
| |
| // Test to cover line 156 in debug-token.c (data_size = 0 validation) |
| TEST(provideToken, decodeRequestZeroDataSize) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_provide_token_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| auto req = reinterpret_cast<nsm_provide_token_req *>(msg->payload); |
| req->hdr.command = NSM_PROVIDE_TOKEN; |
| req->hdr.data_size = 0; // Invalid - should be > 0 |
| |
| uint8_t token_data[NSM_DEBUG_TOKEN_DATA_MAX_SIZE] = {0}; |
| uint8_t token_data_len = 0; |
| |
| auto rc = decode_nsm_provide_token_req(msg, msgBuf.size(), token_data, |
| &token_data_len); |
| |
| EXPECT_EQ(NSM_SW_ERROR_DATA, rc); |
| } |
| |
| TEST(provideToken, goodTestEncodeResponse) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| auto rc = encode_nsm_provide_token_resp(0, NSM_SUCCESS, 0, msg); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(0, msg->hdr.request); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, msg->hdr.nvidia_msg_type); |
| } |
| |
| TEST(provideToken, badTestEncodeResponse) |
| { |
| // Null message |
| auto rc = encode_nsm_provide_token_resp(0, NSM_SUCCESS, 0, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| } |
| |
| // Test to cover line 232 in debug-token.c (error completion code path) |
| TEST(provideToken, errorCompletionCodeEncodeResponse) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + 256); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Test with non-success completion code to trigger error path |
| uint8_t cc = NSM_ERR_INVALID_DATA; |
| uint16_t reason_code = 0x9876; |
| |
| auto rc = encode_nsm_provide_token_resp(0, cc, reason_code, msg); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| // Verify error response structure |
| auto resp_payload = |
| reinterpret_cast<nsm_common_non_success_resp *>(msg->payload); |
| EXPECT_EQ(NSM_PROVIDE_TOKEN, resp_payload->command); |
| EXPECT_EQ(cc, resp_payload->completion_code); |
| EXPECT_EQ(reason_code, le16toh(resp_payload->reason_code)); |
| } |
| |
| TEST(disableTokens, goodTestDecodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_disable_tokens_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| auto rc = decode_nsm_disable_tokens_req(msg, msgBuf.size()); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| } |
| |
| TEST(disableTokens, badTestDecodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_disable_tokens_req)); |
| |
| // Null message |
| auto rc = decode_nsm_disable_tokens_req(nullptr, msgBuf.size()); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Invalid message length |
| rc = decode_nsm_disable_tokens_req(msg, 1); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |
| |
| TEST(disableTokens, goodTestEncodeResponse) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_disable_tokens_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| auto rc = encode_nsm_disable_tokens_resp(0, NSM_SUCCESS, 0, msg); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(0, msg->hdr.request); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, msg->hdr.nvidia_msg_type); |
| } |
| |
| TEST(disableTokens, badTestEncodeResponse) |
| { |
| // Null message |
| auto rc = encode_nsm_disable_tokens_resp(0, NSM_SUCCESS, 0, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| } |
| |
| // Test to cover line 320 in debug-token.c (error completion code path) |
| TEST(disableTokens, errorCompletionCodeEncodeResponse) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + 256); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Test with non-success completion code to trigger error path |
| uint8_t cc = NSM_ERR_INVALID_DATA; |
| uint16_t reason_code = 0x5432; |
| |
| auto rc = encode_nsm_disable_tokens_resp(0, cc, reason_code, msg); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| // Verify error response structure |
| auto resp_payload = |
| reinterpret_cast<nsm_common_non_success_resp *>(msg->payload); |
| EXPECT_EQ(NSM_DISABLE_TOKENS, resp_payload->command); |
| EXPECT_EQ(cc, resp_payload->completion_code); |
| EXPECT_EQ(reason_code, le16toh(resp_payload->reason_code)); |
| } |
| |
| TEST(queryTokenStatus, goodTestDecodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_status_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| auto req = reinterpret_cast<nsm_query_token_status_req *>(msg->payload); |
| req->hdr.command = NSM_QUERY_TOKEN_STATUS; |
| req->hdr.data_size = sizeof(req->token_type); |
| req->token_type = NSM_DEBUG_TOKEN_TYPE_FRC; |
| |
| enum nsm_debug_token_type token_type = NSM_DEBUG_TOKEN_TYPE_CRCS; |
| |
| auto rc = |
| decode_nsm_query_token_status_req(msg, msgBuf.size(), &token_type); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(NSM_DEBUG_TOKEN_TYPE_FRC, token_type); |
| } |
| |
| TEST(queryTokenStatus, badTestDecodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_status_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| enum nsm_debug_token_type token_type = NSM_DEBUG_TOKEN_TYPE_CRCS; |
| |
| // Null message |
| auto rc = decode_nsm_query_token_status_req(nullptr, msgBuf.size(), |
| &token_type); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // Null output parameter |
| rc = decode_nsm_query_token_status_req(msg, msgBuf.size(), nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // Invalid message length |
| rc = decode_nsm_query_token_status_req(msg, 1, &token_type); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |
| |
| // Test to cover line 347 in debug-token.c (data_size validation) |
| TEST(queryTokenStatus, decodeRequestInvalidDataSize) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_status_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| auto req = reinterpret_cast<nsm_query_token_status_req *>(msg->payload); |
| req->hdr.command = NSM_QUERY_TOKEN_STATUS; |
| req->hdr.data_size = |
| 0; // Invalid - should be at least sizeof(token_type) |
| req->token_type = NSM_DEBUG_TOKEN_TYPE_CRCS; |
| |
| enum nsm_debug_token_type token_type = NSM_DEBUG_TOKEN_TYPE_FRC; |
| |
| auto rc = |
| decode_nsm_query_token_status_req(msg, msgBuf.size(), &token_type); |
| |
| EXPECT_EQ(NSM_SW_ERROR_DATA, rc); |
| } |
| |
| TEST(queryTokenStatus, goodTestEncodeResponse) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_status_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| auto rc = encode_nsm_query_token_status_resp( |
| 0, NSM_SUCCESS, 0, NSM_DEBUG_TOKEN_STATUS_DEBUG_SESSION_ACTIVE, |
| NSM_DEBUG_TOKEN_STATUS_ADDITIONAL_INFO_NONE, |
| NSM_DEBUG_TOKEN_TYPE_FRC, 3600, msg); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(0, msg->hdr.request); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, msg->hdr.nvidia_msg_type); |
| |
| auto resp = |
| reinterpret_cast<nsm_query_token_status_resp *>(msg->payload); |
| EXPECT_EQ(NSM_QUERY_TOKEN_STATUS, resp->hdr.command); |
| EXPECT_EQ(NSM_SUCCESS, resp->hdr.completion_code); |
| } |
| |
| TEST(queryTokenStatus, badTestEncodeResponse) |
| { |
| // Null message |
| auto rc = encode_nsm_query_token_status_resp( |
| 0, NSM_SUCCESS, 0, NSM_DEBUG_TOKEN_STATUS_DEBUG_SESSION_ACTIVE, |
| NSM_DEBUG_TOKEN_STATUS_ADDITIONAL_INFO_NONE, |
| NSM_DEBUG_TOKEN_TYPE_FRC, 3600, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| } |
| |
| // Test to cover line 440 in debug-token.c (error completion code path) |
| TEST(queryTokenStatus, errorCompletionCodeEncodeResponse) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + 256); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Test with non-success completion code to trigger error path |
| uint8_t cc = NSM_ERR_INVALID_DATA; |
| uint16_t reason_code = 0x1122; |
| |
| auto rc = encode_nsm_query_token_status_resp( |
| 0, cc, reason_code, NSM_DEBUG_TOKEN_STATUS_DEBUG_SESSION_ACTIVE, |
| NSM_DEBUG_TOKEN_STATUS_ADDITIONAL_INFO_NONE, |
| NSM_DEBUG_TOKEN_TYPE_FRC, 3600, msg); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| // Verify error response structure |
| auto resp_payload = |
| reinterpret_cast<nsm_common_non_success_resp *>(msg->payload); |
| EXPECT_EQ(NSM_QUERY_TOKEN_STATUS, resp_payload->command); |
| EXPECT_EQ(cc, resp_payload->completion_code); |
| EXPECT_EQ(reason_code, le16toh(resp_payload->reason_code)); |
| } |
| |
| TEST(queryDeviceIds, goodTestDecodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_device_ids_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| auto rc = decode_nsm_query_device_ids_req(msg, msgBuf.size()); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| } |
| |
| TEST(queryDeviceIds, badTestDecodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_device_ids_req)); |
| |
| // Null message |
| auto rc = decode_nsm_query_device_ids_req(nullptr, msgBuf.size()); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Invalid message length |
| rc = decode_nsm_query_device_ids_req(msg, 1); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |
| |
| TEST(installToken, goodTestDecodeResponse) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_install_token_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Set up valid response header |
| msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID); |
| msg->hdr.ocp_type = OCP_TYPE; |
| msg->hdr.ocp_version = OCP_VERSION; |
| |
| auto resp = reinterpret_cast<nsm_install_token_resp *>(msg->payload); |
| resp->command = NSM_INSTALL_TOKEN; |
| resp->completion_code = NSM_SUCCESS; |
| |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| |
| auto rc = decode_nsm_install_token_resp(msg, msgBuf.size(), &cc, |
| &reason_code); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| } |
| |
| TEST(installToken, badTestDecodeResponse) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_install_token_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| |
| // Null message |
| auto rc = decode_nsm_install_token_resp(nullptr, msgBuf.size(), &cc, |
| &reason_code); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // Null output parameters |
| rc = decode_nsm_install_token_resp(msg, msgBuf.size(), nullptr, |
| &reason_code); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| rc = decode_nsm_install_token_resp(msg, msgBuf.size(), &cc, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| } |
| |
| // Test to cover line 640 in debug-token.c (error completion code path) |
| TEST(installToken, decodeResponseErrorCompletionCode) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_non_success_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Set up valid response header |
| msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID); |
| msg->hdr.ocp_type = OCP_TYPE; |
| msg->hdr.ocp_version = OCP_VERSION; |
| |
| // Set up error response with reason code |
| auto resp = |
| reinterpret_cast<nsm_common_non_success_resp *>(msg->payload); |
| resp->command = NSM_INSTALL_TOKEN; |
| resp->completion_code = NSM_ERR_INVALID_DATA; // Error completion code |
| resp->reason_code = htole16(0x3344); |
| |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| |
| // decode should succeed but return early due to cc != NSM_SUCCESS |
| auto rc = decode_nsm_install_token_resp(msg, msgBuf.size(), &cc, |
| &reason_code); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(NSM_ERR_INVALID_DATA, cc); |
| EXPECT_EQ(0x3344, reason_code); |
| } |
| |
| TEST(installToken, goodTestEncodeResponse) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_install_token_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| auto rc = encode_nsm_install_token_resp(0, NSM_SUCCESS, 0, msg); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(0, msg->hdr.request); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, msg->hdr.nvidia_msg_type); |
| } |
| |
| TEST(installToken, badTestEncodeResponse) |
| { |
| // Null message |
| auto rc = encode_nsm_install_token_resp(0, NSM_SUCCESS, 0, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| } |
| |
| // Test to cover line 664 in debug-token.c (error completion code path) |
| TEST(installToken, errorCompletionCodeEncodeResponse) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + 256); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Test with non-success completion code to trigger error path |
| uint8_t cc = NSM_ERR_INVALID_DATA; |
| uint16_t reason_code = 0x6677; |
| |
| auto rc = encode_nsm_install_token_resp(0, cc, reason_code, msg); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| // Verify error response structure |
| auto resp_payload = |
| reinterpret_cast<nsm_common_non_success_resp *>(msg->payload); |
| EXPECT_EQ(NSM_INSTALL_TOKEN, resp_payload->command); |
| EXPECT_EQ(cc, resp_payload->completion_code); |
| EXPECT_EQ(reason_code, le16toh(resp_payload->reason_code)); |
| } |
| |
| TEST(eraseToken, goodTestDecodeResponse) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_erase_token_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Set up valid response header |
| msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID); |
| msg->hdr.ocp_type = OCP_TYPE; |
| msg->hdr.ocp_version = OCP_VERSION; |
| |
| auto resp = reinterpret_cast<nsm_erase_token_resp *>(msg->payload); |
| resp->command = NSM_ERASE_TOKEN; |
| resp->completion_code = NSM_SUCCESS; |
| |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| |
| auto rc = |
| decode_nsm_erase_token_resp(msg, msgBuf.size(), &cc, &reason_code); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| } |
| |
| TEST(eraseToken, badTestDecodeResponse) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_erase_token_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| |
| // Null message |
| auto rc = decode_nsm_erase_token_resp(nullptr, msgBuf.size(), &cc, |
| &reason_code); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| // Null output parameters |
| rc = decode_nsm_erase_token_resp(msg, msgBuf.size(), nullptr, |
| &reason_code); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| rc = decode_nsm_erase_token_resp(msg, msgBuf.size(), &cc, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| } |
| |
| // Test to cover line 733 in debug-token.c (error completion code path) |
| TEST(eraseToken, decodeResponseErrorCompletionCode) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_non_success_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Set up valid response header |
| msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID); |
| msg->hdr.ocp_type = OCP_TYPE; |
| msg->hdr.ocp_version = OCP_VERSION; |
| |
| // Set up error response with reason code |
| auto resp = |
| reinterpret_cast<nsm_common_non_success_resp *>(msg->payload); |
| resp->command = NSM_ERASE_TOKEN; |
| resp->completion_code = NSM_ERR_INVALID_DATA; |
| resp->reason_code = htole16(0x5566); |
| |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| |
| auto rc = |
| decode_nsm_erase_token_resp(msg, msgBuf.size(), &cc, &reason_code); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(NSM_ERR_INVALID_DATA, cc); |
| EXPECT_EQ(0x5566, reason_code); |
| } |
| |
| TEST(eraseToken, goodTestEncodeResponse) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_erase_token_resp)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| auto rc = encode_nsm_erase_token_resp(0, NSM_SUCCESS, 0, msg); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(0, msg->hdr.request); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, msg->hdr.nvidia_msg_type); |
| } |
| |
| TEST(eraseToken, badTestEncodeResponse) |
| { |
| // Null message |
| auto rc = encode_nsm_erase_token_resp(0, NSM_SUCCESS, 0, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| } |
| |
| // Test to cover line 757 in debug-token.c (error completion code path) |
| TEST(eraseToken, errorCompletionCodeEncodeResponse) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + 256); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Test with non-success completion code to trigger error path |
| uint8_t cc = NSM_ERR_INVALID_DATA; |
| uint16_t reason_code = 0x7788; |
| |
| auto rc = encode_nsm_erase_token_resp(0, cc, reason_code, msg); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| |
| // Verify error response structure |
| auto resp_payload = |
| reinterpret_cast<nsm_common_non_success_resp *>(msg->payload); |
| EXPECT_EQ(NSM_ERASE_TOKEN, resp_payload->command); |
| EXPECT_EQ(cc, resp_payload->completion_code); |
| EXPECT_EQ(reason_code, le16toh(resp_payload->reason_code)); |
| } |
| |
| TEST(queryToken, goodTestDecodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| auto req = reinterpret_cast<nsm_query_token_req *>(msg->payload); |
| req->command = NSM_QUERY_TOKEN; |
| req->data_size = 0; |
| |
| auto rc = decode_nsm_query_token_req(msg, msgBuf.size()); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| } |
| |
| TEST(queryToken, badTestDecodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_req)); |
| |
| // Null message |
| auto rc = decode_nsm_query_token_req(nullptr, msgBuf.size()); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| // Invalid message length |
| rc = decode_nsm_query_token_req(msg, 1); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |
| |
| // Test to cover line 781 in debug-token.c (non-zero data_size validation) |
| TEST(queryToken, decodeRequestInvalidDataSize) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| auto req = reinterpret_cast<nsm_query_token_req *>(msg->payload); |
| req->command = NSM_QUERY_TOKEN; |
| req->data_size = 1; // Invalid - should be 0 |
| |
| auto rc = decode_nsm_query_token_req(msg, msgBuf.size()); |
| |
| EXPECT_EQ(NSM_SW_ERROR_DATA, rc); |
| } |
| |
| TEST(queryToken, goodTestEncodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_query_token_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| |
| auto rc = encode_nsm_query_token_req(0, msg); |
| |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| EXPECT_EQ(1, msg->hdr.request); |
| EXPECT_EQ(0, msg->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, msg->hdr.nvidia_msg_type); |
| |
| auto req = reinterpret_cast<nsm_query_token_req *>(msg->payload); |
| EXPECT_EQ(NSM_QUERY_TOKEN, req->command); |
| EXPECT_EQ(0, req->data_size); |
| } |
| |
| TEST(queryToken, badTestEncodeRequest) |
| { |
| // Null message |
| auto rc = encode_nsm_query_token_req(0, nullptr); |
| EXPECT_EQ(NSM_SW_ERROR_NULL, rc); |
| } |
| |
| // Simple decode tests |
| TEST(DisableTokens, DecodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| auto rc = decode_nsm_disable_tokens_req(msg, msgBuf.size()); |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| } |
| |
| TEST(QueryDeviceIds, DecodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| auto rc = decode_nsm_query_device_ids_req(msg, msgBuf.size()); |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| } |
| |
| TEST(QueryToken, DecodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| auto rc = decode_nsm_query_token_req(msg, msgBuf.size()); |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| } |
| |
| // More simple encode tests |
| TEST(DisableTokens, EncodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| auto rc = encode_nsm_disable_tokens_req(0, msg); |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| } |
| |
| TEST(QueryDeviceIds, EncodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| auto rc = encode_nsm_query_device_ids_req(0, msg); |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| } |
| |
| TEST(QueryToken, EncodeRequest) |
| { |
| std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + |
| sizeof(nsm_common_req)); |
| auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data()); |
| auto rc = encode_nsm_query_token_req(0, msg); |
| EXPECT_EQ(NSM_SW_SUCCESS, rc); |
| } |
| |
| // Branch coverage: encode_nsm_query_token_parameters_req L49 |
| TEST(DebugTokenNullBranch, EncodeQueryTokenParamReq_NullMsg) |
| { |
| auto rc = encode_nsm_query_token_parameters_req( |
| 0, NSM_DEBUG_TOKEN_OPCODE_RMCS, nullptr); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| // Branch coverage: encode_nsm_query_token_parameters_resp L112 |
| TEST(DebugTokenNullBranch, EncodeQueryTokenParamResp_NullMsg) |
| { |
| auto rc = encode_nsm_query_token_parameters_resp(0, NSM_SUCCESS, 0, |
| nullptr, nullptr); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| // Branch coverage: decode_nsm_query_token_parameters_resp L83 |
| // (msg == NULL || token_request == NULL) |
| TEST(DebugTokenNullBranch, DecodeQueryTokenParamResp_NullMsg) |
| { |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| struct nsm_debug_token_request token_request = {}; |
| auto rc = decode_nsm_query_token_parameters_resp( |
| nullptr, 0, &cc, &reason_code, &token_request); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| TEST(DebugTokenNullBranch, DecodeQueryTokenParamResp_NullTokenRequest) |
| { |
| std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + 32, 0); |
| auto *msg = reinterpret_cast<const nsm_msg *>(buf.data()); |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| auto rc = decode_nsm_query_token_parameters_resp(msg, buf.size(), &cc, |
| &reason_code, nullptr); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| // Branch coverage: encode_nsm_provide_token_req L168 |
| // (msg == NULL || token_data == NULL) |
| TEST(DebugTokenNullBranch, EncodeProvideTokenReq_NullMsg) |
| { |
| uint8_t token_data[4] = {}; |
| auto rc = encode_nsm_provide_token_req(0, token_data, 4, nullptr); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| TEST(DebugTokenNullBranch, EncodeProvideTokenReq_NullTokenData) |
| { |
| std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + 32, 0); |
| auto *msg = reinterpret_cast<nsm_msg *>(buf.data()); |
| auto rc = encode_nsm_provide_token_req(0, nullptr, 4, msg); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| // Branch coverage: encode_nsm_query_token_status_req L358 |
| TEST(DebugTokenNullBranch, EncodeQueryTokenStatusReq_NullMsg) |
| { |
| auto rc = encode_nsm_query_token_status_req(0, NSM_DEBUG_TOKEN_TYPE_FRC, |
| nullptr); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| // Branch coverage: decode_nsm_query_token_status_resp L393 |
| // (msg == NULL || status == NULL || additional_info == NULL || ...) |
| TEST(DebugTokenNullBranch, DecodeQueryTokenStatusResp_NullMsg) |
| { |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| enum nsm_debug_token_status status = {}; |
| enum nsm_debug_token_status_additional_info additional_info = {}; |
| enum nsm_debug_token_type token_type = {}; |
| uint32_t time_left = 0; |
| auto rc = decode_nsm_query_token_status_resp( |
| nullptr, 0, &cc, &reason_code, &status, &additional_info, |
| &token_type, &time_left); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| TEST(DebugTokenNullBranch, DecodeQueryTokenStatusResp_NullStatus) |
| { |
| std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + 32, 0); |
| auto *msg = reinterpret_cast<const nsm_msg *>(buf.data()); |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| enum nsm_debug_token_status_additional_info additional_info = {}; |
| enum nsm_debug_token_type token_type = {}; |
| uint32_t time_left = 0; |
| auto rc = decode_nsm_query_token_status_resp( |
| msg, buf.size(), &cc, &reason_code, nullptr, &additional_info, |
| &token_type, &time_left); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| // Branch coverage: encode_nsm_query_device_ids_req L474 |
| TEST(DebugTokenNullBranch, EncodeQueryDeviceIdsReq_NullMsg) |
| { |
| auto rc = encode_nsm_query_device_ids_req(0, nullptr); |
| EXPECT_EQ(rc, NSM_SW_ERROR_DATA); |
| } |
| |
| // --------------------------------------------------------------------------- |
| // Null checks for secondary conditions (cc/reason_code/time_left/etc == NULL) |
| // --------------------------------------------------------------------------- |
| |
| // decode_nsm_provide_token_resp L197: cc == NULL |
| TEST(DebugTokenNullBranch, DecodeProvideTokenResp_NullCc) |
| { |
| std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + 8, 0); |
| auto *msg = reinterpret_cast<const nsm_msg *>(buf.data()); |
| uint16_t reason_code = 0; |
| auto rc = decode_nsm_provide_token_resp(msg, buf.size(), nullptr, |
| &reason_code); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| // decode_nsm_disable_tokens_resp L285: cc == NULL |
| TEST(DebugTokenNullBranch, DecodeDisableTokensResp_NullCc) |
| { |
| std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + 8, 0); |
| auto *msg = reinterpret_cast<const nsm_msg *>(buf.data()); |
| uint16_t reason_code = 0; |
| auto rc = decode_nsm_disable_tokens_resp(msg, buf.size(), nullptr, |
| &reason_code); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| // decode_nsm_query_token_status_resp L394: token_type == NULL |
| TEST(DebugTokenNullBranch, DecodeQueryTokenStatusResp_NullTokenType) |
| { |
| std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + 8, 0); |
| auto *msg = reinterpret_cast<const nsm_msg *>(buf.data()); |
| uint8_t cc = 0; |
| uint16_t reason_code = 0; |
| enum nsm_debug_token_status status = {}; |
| enum nsm_debug_token_status_additional_info additional_info = {}; |
| uint32_t time_left = 0; |
| auto rc = decode_nsm_query_token_status_resp( |
| msg, buf.size(), &cc, &reason_code, &status, &additional_info, |
| nullptr, &time_left); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| // --------------------------------------------------------------------------- |
| // Pack-fail branches (instance_id > NSM_INSTANCE_MAX = 31) |
| // --------------------------------------------------------------------------- |
| |
| static std::vector<uint8_t> g_dbg_buf(1024, 0); |
| static nsm_msg *g_dbg_msg() |
| { |
| return reinterpret_cast<nsm_msg *>(g_dbg_buf.data()); |
| } |
| |
| // encode_nsm_query_token_parameters_req L66 |
| TEST(DebugTokenPackFailBranch, EncodeQueryTokenParamReq_PackFail) |
| { |
| auto rc = encode_nsm_query_token_parameters_req( |
| 32, NSM_DEBUG_TOKEN_OPCODE_RMCS, g_dbg_msg()); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // encode_nsm_query_token_parameters_resp L122 |
| TEST(DebugTokenPackFailBranch, EncodeQueryTokenParamResp_PackFail) |
| { |
| auto rc = encode_nsm_query_token_parameters_resp(32, NSM_SUCCESS, 0, |
| nullptr, g_dbg_msg()); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // encode_nsm_provide_token_req L181 |
| TEST(DebugTokenPackFailBranch, EncodeProvideTokenReq_PackFail) |
| { |
| uint8_t token_data[1] = {0}; |
| auto rc = encode_nsm_provide_token_req(32, token_data, 1, g_dbg_msg()); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // encode_nsm_provide_token_resp L227 |
| TEST(DebugTokenPackFailBranch, EncodeProvideTokenResp_PackFail) |
| { |
| auto rc = |
| encode_nsm_provide_token_resp(32, NSM_SUCCESS, 0, g_dbg_msg()); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // encode_nsm_disable_tokens_req L270 |
| TEST(DebugTokenPackFailBranch, EncodeDisableTokensReq_PackFail) |
| { |
| auto rc = encode_nsm_disable_tokens_req(32, g_dbg_msg()); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // encode_nsm_disable_tokens_resp L315 |
| TEST(DebugTokenPackFailBranch, EncodeDisableTokensResp_PackFail) |
| { |
| auto rc = |
| encode_nsm_disable_tokens_resp(32, NSM_SUCCESS, 0, g_dbg_msg()); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // encode_nsm_query_token_status_req L374 |
| TEST(DebugTokenPackFailBranch, EncodeQueryTokenStatusReq_PackFail) |
| { |
| auto rc = encode_nsm_query_token_status_req( |
| 32, NSM_DEBUG_TOKEN_TYPE_FRC, g_dbg_msg()); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // encode_nsm_query_token_status_resp L435 |
| TEST(DebugTokenPackFailBranch, EncodeQueryTokenStatusResp_PackFail) |
| { |
| auto rc = encode_nsm_query_token_status_resp( |
| 32, NSM_SUCCESS, 0, static_cast<nsm_debug_token_status>(0), |
| static_cast<nsm_debug_token_status_additional_info>(0), |
| static_cast<nsm_debug_token_type>(0), 0, g_dbg_msg()); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // encode_nsm_query_device_ids_req L484 |
| TEST(DebugTokenPackFailBranch, EncodeQueryDeviceIdsReq_PackFail) |
| { |
| auto rc = encode_nsm_query_device_ids_req(32, g_dbg_msg()); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // encode_nsm_query_device_ids_resp L543 |
| TEST(DebugTokenPackFailBranch, EncodeQueryDeviceIdsResp_PackFail) |
| { |
| uint8_t dev_id[1] = {0}; |
| auto rc = encode_nsm_query_device_ids_resp(32, NSM_SUCCESS, 0, dev_id, |
| 1, g_dbg_msg()); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // encode_nsm_install_token_req L613 |
| TEST(DebugTokenPackFailBranch, EncodeInstallTokenReq_PackFail) |
| { |
| uint8_t data[1] = {0}; |
| auto rc = encode_nsm_install_token_req(32, 0, 0, 0, data, g_dbg_msg()); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // encode_nsm_install_token_resp L659 |
| TEST(DebugTokenPackFailBranch, EncodeInstallTokenResp_PackFail) |
| { |
| auto rc = |
| encode_nsm_install_token_resp(32, NSM_SUCCESS, 0, g_dbg_msg()); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // encode_nsm_erase_token_req L711 |
| TEST(DebugTokenPackFailBranch, EncodeEraseTokenReq_PackFail) |
| { |
| auto rc = encode_nsm_erase_token_req(32, 0, g_dbg_msg()); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // encode_nsm_erase_token_resp L752 |
| TEST(DebugTokenPackFailBranch, EncodeEraseTokenResp_PackFail) |
| { |
| auto rc = encode_nsm_erase_token_resp(32, NSM_SUCCESS, 0, g_dbg_msg()); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // encode_nsm_query_token_req L799 |
| TEST(DebugTokenPackFailBranch, EncodeQueryTokenReq_PackFail) |
| { |
| auto rc = encode_nsm_query_token_req(32, g_dbg_msg()); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // encode_nsm_query_token_resp L857 |
| TEST(DebugTokenPackFailBranch, EncodeQueryTokenResp_PackFail) |
| { |
| uint8_t payload[1] = {0}; |
| auto rc = encode_nsm_query_token_resp(32, NSM_SUCCESS, 0, payload, 1, |
| g_dbg_msg()); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // =========================================================================== |
| // rc != NSM_SW_SUCCESS branches (B0 of || condition) |
| // Pass msg with error CC + wrong size → decode_reason_code_and_cc returns |
| // NSM_SW_ERROR_LENGTH, so rc != NSM_SW_SUCCESS → TRUE branch taken |
| // =========================================================================== |
| // Error-CC buffer helper: large buffer with completion_code = NSM_ERROR |
| // payload[1] (not payload[0]) is completion_code in nsm_common_resp |
| static std::vector<uint8_t> makeErrCcBuf(size_t size = sizeof(nsm_msg_hdr) + |
| 100) |
| { |
| std::vector<uint8_t> buf(size, 0); |
| buf[sizeof(nsm_msg_hdr) + 1] = 0xFF; // completion_code != NSM_SUCCESS |
| return buf; |
| } |
| |
| // decode_nsm_query_token_parameters_resp L88 — rc != NSM_SW_SUCCESS |
| TEST(DebugTokenBranches, DecodeQueryTokenParamResp_RcFail) |
| { |
| auto buf = makeErrCcBuf(); |
| auto *msg = reinterpret_cast<const nsm_msg *>(buf.data()); |
| uint8_t cc = 0; |
| uint16_t reason = 0; |
| struct nsm_debug_token_request token_req = {}; |
| auto rc = decode_nsm_query_token_parameters_resp(msg, buf.size(), &cc, |
| &reason, &token_req); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // decode_nsm_provide_token_resp L197 — rc != NSM_SW_SUCCESS |
| TEST(DebugTokenBranches, DecodeProvideTokenResp_RcFail) |
| { |
| auto buf = makeErrCcBuf(); |
| auto *msg = reinterpret_cast<const nsm_msg *>(buf.data()); |
| uint8_t cc = 0; |
| uint16_t reason = 0; |
| auto rc = decode_nsm_provide_token_resp(msg, buf.size(), &cc, &reason); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // decode_nsm_disable_tokens_resp L285 — reason_code=NULL |
| TEST(DebugTokenBranches, DecodeDisableTokensResp_NullReasonCode) |
| { |
| std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + 32, 0); |
| auto *msg = reinterpret_cast<const nsm_msg *>(buf.data()); |
| uint8_t cc = 0; |
| auto rc = decode_nsm_disable_tokens_resp(msg, buf.size(), &cc, nullptr); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| // decode_nsm_disable_tokens_resp L290 — rc != NSM_SW_SUCCESS |
| TEST(DebugTokenBranches, DecodeDisableTokensResp_RcFail) |
| { |
| auto buf = makeErrCcBuf(); |
| auto *msg = reinterpret_cast<const nsm_msg *>(buf.data()); |
| uint8_t cc = 0; |
| uint16_t reason = 0; |
| auto rc = decode_nsm_disable_tokens_resp(msg, buf.size(), &cc, &reason); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // decode_nsm_query_token_status_resp L394 — time_left=NULL |
| TEST(DebugTokenBranches, DecodeQueryTokenStatusResp_NullTimeLeft) |
| { |
| std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + 32, 0); |
| auto *msg = reinterpret_cast<const nsm_msg *>(buf.data()); |
| uint8_t cc = 0; |
| uint16_t reason = 0; |
| enum nsm_debug_token_status status = {}; |
| enum nsm_debug_token_status_additional_info additional_info = {}; |
| enum nsm_debug_token_type token_type = {}; |
| auto rc = decode_nsm_query_token_status_resp( |
| msg, buf.size(), &cc, &reason, &status, &additional_info, |
| &token_type, nullptr); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| // decode_nsm_query_token_status_resp L399 — rc != NSM_SW_SUCCESS |
| TEST(DebugTokenBranches, DecodeQueryTokenStatusResp_RcFail) |
| { |
| auto buf = makeErrCcBuf(); |
| auto *msg = reinterpret_cast<const nsm_msg *>(buf.data()); |
| uint8_t cc = 0; |
| uint16_t reason = 0; |
| enum nsm_debug_token_status status = {}; |
| enum nsm_debug_token_status_additional_info additional_info = {}; |
| enum nsm_debug_token_type token_type = {}; |
| uint32_t time_left = 0; |
| auto rc = decode_nsm_query_token_status_resp( |
| msg, buf.size(), &cc, &reason, &status, &additional_info, |
| &token_type, &time_left); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // decode_nsm_query_token_resp L820 — rc != NSM_SW_SUCCESS |
| TEST(DebugTokenBranches, DecodeQueryTokenResp_RcFail) |
| { |
| auto buf = makeErrCcBuf(); |
| auto *msg = reinterpret_cast<const nsm_msg *>(buf.data()); |
| uint8_t cc = 0; |
| uint16_t reason = 0; |
| size_t tlv_payload_len = 0; |
| auto rc = decode_nsm_query_token_resp(msg, buf.size(), &cc, &reason, |
| nullptr, &tlv_payload_len); |
| EXPECT_NE(rc, NSM_SW_SUCCESS); |
| } |
| |
| // =========================================================================== |
| // decode_nsm_install_token_req branch coverage |
| // L577: data_size too small, L588: size mismatch, L591: data=NULL |
| // =========================================================================== |
| |
| // L577 TRUE: data_size < minimum (zero-fill → data_size=0) |
| TEST(DebugTokenBranches, DecodeInstallTokenReq_DataSizeTooSmall) |
| { |
| std::vector<uint8_t> buf( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_install_token_req), 0); |
| // data_size = 0 (zero-fill) < 13 → L577 TRUE |
| auto *msg = reinterpret_cast<const nsm_msg *>(buf.data()); |
| uint32_t chunk_offset = 0, chunk_length = 0, length_remaining = 0; |
| auto rc = decode_nsm_install_token_req(msg, buf.size(), &chunk_offset, |
| &chunk_length, &length_remaining, |
| nullptr); |
| EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH); |
| } |
| |
| // L588 TRUE: data_size >= 13 but != expected (data_size=13, chunk_length=5) |
| TEST(DebugTokenBranches, DecodeInstallTokenReq_DataSizeMismatch) |
| { |
| std::vector<uint8_t> buf( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_install_token_req) + 10, 0); |
| // data_size at payload offset 2 = 13 (LE16): passes L577 |
| buf[sizeof(nsm_msg_hdr) + 2] = 13; |
| buf[sizeof(nsm_msg_hdr) + 3] = 0; |
| // chunk_length at payload offset 10 = 5: expected_size = 12+5=17 ≠ 13 |
| buf[sizeof(nsm_msg_hdr) + 10] = 5; |
| auto *msg = reinterpret_cast<const nsm_msg *>(buf.data()); |
| uint32_t chunk_offset = 0, chunk_length = 0, length_remaining = 0; |
| auto rc = decode_nsm_install_token_req(msg, buf.size(), &chunk_offset, |
| &chunk_length, &length_remaining, |
| nullptr); |
| EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH); |
| } |
| |
| // L591 FALSE: data=NULL, valid data_size=13, chunk_length=1 → skip copy |
| TEST(DebugTokenBranches, DecodeInstallTokenReq_NullData) |
| { |
| std::vector<uint8_t> buf( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_install_token_req) + 10, 0); |
| // data_size=13: passes L577 (>= 13) |
| buf[sizeof(nsm_msg_hdr) + 2] = 13; |
| buf[sizeof(nsm_msg_hdr) + 3] = 0; |
| // chunk_length=1: expected_size = 4+4+4+1 = 13 = data_size → passes |
| // L588 |
| buf[sizeof(nsm_msg_hdr) + 10] = 1; |
| auto *msg = reinterpret_cast<const nsm_msg *>(buf.data()); |
| uint32_t chunk_offset = 0, chunk_length = 0, length_remaining = 0; |
| // data=NULL → L591 FALSE → skip copy → NSM_SW_SUCCESS |
| auto rc = decode_nsm_install_token_req(msg, buf.size(), &chunk_offset, |
| &chunk_length, &length_remaining, |
| nullptr); |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| } |
| |
| // --------------------------------------------------------------------------- |
| // Buffer-overflow guard regression (nvbug 6232725): each decoder must reject |
| // a message whose on-wire payload length exceeds the bytes actually present |
| // in msg_len, returning NSM_SW_ERROR_LENGTH instead of an out-of-bounds copy. |
| // --------------------------------------------------------------------------- |
| |
| namespace |
| { |
| // Payload offset of the data_size field inside struct nsm_common_resp |
| // (command:1, completion_code:1, reserved:2, data_size:2). |
| constexpr size_t kRespDataSizeOff = sizeof(nsm_msg_hdr) + 4; |
| |
| void putU16(std::vector<uint8_t> &buf, size_t off, uint16_t v) |
| { |
| buf[off] = static_cast<uint8_t>(v & 0xFF); |
| buf[off + 1] = static_cast<uint8_t>((v >> 8) & 0xFF); |
| } |
| |
| void putU32(std::vector<uint8_t> &buf, size_t off, uint32_t v) |
| { |
| buf[off] = static_cast<uint8_t>(v & 0xFF); |
| buf[off + 1] = static_cast<uint8_t>((v >> 8) & 0xFF); |
| buf[off + 2] = static_cast<uint8_t>((v >> 16) & 0xFF); |
| buf[off + 3] = static_cast<uint8_t>((v >> 24) & 0xFF); |
| } |
| |
| std::vector<uint8_t> oversizedResp(size_t structSize, uint16_t dataSize) |
| { |
| std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + structSize, 0); |
| putU16(buf, kRespDataSizeOff, dataSize); |
| return buf; |
| } |
| |
| const nsm_msg *asMsg(const std::vector<uint8_t> &buf) |
| { |
| return reinterpret_cast<const nsm_msg *>(buf.data()); |
| } |
| } // namespace |
| |
| TEST(LibnsmOverreadGuard, ProvideTokenReqValidStillDecodes) |
| { |
| // The min-length check already guarantees the full token buffer is |
| // present, so the guard must never reject a well-formed request |
| // (no false positive). |
| std::vector<uint8_t> buf( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_provide_token_req), 0); |
| auto *msg = reinterpret_cast<nsm_msg *>(buf.data()); |
| std::vector<uint8_t> token(32, 0xAB); |
| ASSERT_EQ( |
| encode_nsm_provide_token_req( |
| 0, token.data(), static_cast<uint16_t>(token.size()), msg), |
| NSM_SW_SUCCESS); |
| std::vector<uint8_t> out(NSM_DEBUG_TOKEN_DATA_MAX_SIZE, 0); |
| uint8_t outLen = 0; |
| EXPECT_EQ( |
| decode_nsm_provide_token_req(msg, buf.size(), out.data(), &outLen), |
| NSM_SW_SUCCESS); |
| EXPECT_EQ(outLen, 32); |
| } |
| |
| TEST(LibnsmOverreadGuard, ProvideTokenReqRejectsShortMessage) |
| { |
| // nsm_provide_token_req carries a fixed-size token_data array, so the |
| // minimum-length check already mandates the full buffer; an |
| // over-declared length is therefore unreachable. A truncated message |
| // (smaller than the required fixed layout) must still be rejected with |
| // NSM_SW_ERROR_LENGTH rather than read out of bounds. |
| std::vector<uint8_t> buf( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_common_req_v2), 0); |
| uint8_t token[8] = {0}; |
| uint8_t tokenLen = 0; |
| EXPECT_EQ(decode_nsm_provide_token_req(asMsg(buf), buf.size(), token, |
| &tokenLen), |
| NSM_SW_ERROR_LENGTH); |
| } |
| |
| TEST(LibnsmOverreadGuard, QueryDeviceIdsResp) |
| { |
| auto buf = oversizedResp(sizeof(nsm_query_device_ids_resp), 0xFFFF); |
| uint8_t cc = 0xFF; |
| uint16_t rc = 0; |
| uint8_t id[8] = {0}; |
| size_t idLen = 0; |
| EXPECT_EQ(decode_nsm_query_device_ids_resp(asMsg(buf), buf.size(), &cc, |
| &rc, id, &idLen), |
| NSM_SW_ERROR_LENGTH); |
| } |
| |
| TEST(LibnsmOverreadGuard, InstallTokenReq) |
| { |
| // nsm_install_token_req: common_req_v2(6) + chunk_offset(4) + |
| // chunk_length(4) + length_remaining(4) + data[1]. Keep |
| // hdr.data_size consistent with chunk_length so the consistency |
| // check passes and the new guard is what fires. |
| std::vector<uint8_t> buf( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_install_token_req), 0); |
| putU16(buf, sizeof(nsm_msg_hdr) + 2, 1012); // hdr.data_size |
| putU32(buf, sizeof(nsm_msg_hdr) + 10, 1000); // chunk_length |
| uint32_t off = 0; |
| uint32_t len = 0; |
| uint32_t rem = 0; |
| uint8_t data[8] = {0}; |
| EXPECT_EQ(decode_nsm_install_token_req(asMsg(buf), buf.size(), &off, |
| &len, &rem, data), |
| NSM_SW_ERROR_LENGTH); |
| } |
| |
| TEST(LibnsmOverreadGuard, QueryTokenResp) |
| { |
| auto buf = oversizedResp(sizeof(nsm_query_token_resp), 0xFFFF); |
| uint8_t cc = 0xFF; |
| uint16_t rc = 0; |
| uint8_t tlv[8] = {0}; |
| size_t tlvLen = 0; |
| EXPECT_EQ(decode_nsm_query_token_resp(asMsg(buf), buf.size(), &cc, &rc, |
| tlv, &tlvLen), |
| NSM_SW_ERROR_LENGTH); |
| } |