| /* |
| * 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 "firmware-utils.h" |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| TEST(GetRotInformation, testGoodEncodeRequest) |
| { |
| uint16_t classification = 0x1234; |
| uint8_t classification_index = 0x56; |
| uint16_t component_identifier = 0xABCD; |
| |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_firmware_get_erot_state_info_req)); |
| nsm_firmware_erot_state_info_req nsm_req; |
| nsm_req.component_classification = classification; |
| nsm_req.component_classification_index = classification_index; |
| nsm_req.component_identifier = component_identifier; |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| auto rc = encode_nsm_query_get_erot_state_parameters_req(0, &nsm_req, |
| request); |
| |
| struct nsm_firmware_get_erot_state_info_req *requestTest = |
| (struct nsm_firmware_get_erot_state_info_req *)(request->payload); |
| |
| struct nsm_firmware_erot_state_info_req *req = |
| (struct nsm_firmware_erot_state_info_req *)&(requestTest->fq_req); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_FIRMWARE, request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_FW_GET_EROT_STATE_INFORMATION, requestTest->hdr.command); |
| EXPECT_EQ(5, requestTest->hdr.data_size); |
| |
| EXPECT_EQ(classification, req->component_classification); |
| EXPECT_EQ(classification_index, req->component_classification_index); |
| EXPECT_EQ(component_identifier, req->component_identifier); |
| } |
| |
| TEST(GetRotInformation, testGoodDecodeRequest) |
| { |
| std::vector<uint8_t> requestMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x80, // RQ=1, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_FIRMWARE, // NVIDIA_MSG_TYPE |
| NSM_FW_GET_EROT_STATE_INFORMATION, // command |
| 5, // data size |
| 0x12, // component classification 0x3412 |
| 0x34, // |
| 0x56, // component identifier 0x7856 |
| 0x78, // |
| 0x9A, // classification index 0x9A |
| }; |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| |
| size_t msg_len = requestMsg.size(); |
| |
| struct nsm_firmware_erot_state_info_req fw_req; |
| auto rc = decode_nsm_query_get_erot_state_parameters_req( |
| request, msg_len, &fw_req); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| EXPECT_EQ(0x3412, fw_req.component_classification); |
| EXPECT_EQ(0x9A, fw_req.component_classification_index); |
| EXPECT_EQ(0x7856, fw_req.component_identifier); |
| } |
| |
| TEST(GetRotInformation, testBadDecodeRequest) |
| { |
| std::vector<uint8_t> requestMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x80, // RQ=1, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_FIRMWARE, // NVIDIA_MSG_TYPE |
| NSM_FW_GET_EROT_STATE_INFORMATION, // command |
| 2, // data size |
| 0x12, // component classification 0x3412 |
| 0x34, // |
| 0x56, // component identifier 0x7856 |
| 0x78, // |
| 0x9A, // classification index 0x9A |
| }; |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| |
| size_t msg_len = requestMsg.size(); |
| |
| struct nsm_firmware_erot_state_info_req fw_req; |
| auto rc = decode_nsm_query_get_erot_state_parameters_req( |
| request, msg_len, &fw_req); |
| |
| EXPECT_EQ(rc, NSM_SW_ERROR_DATA); |
| } |
| |
| TEST(GetRotInformation, testTooShortDecodeRequest) |
| { |
| std::vector<uint8_t> requestMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x80, // RQ=1, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_FIRMWARE, // NVIDIA_MSG_TYPE |
| NSM_FW_GET_EROT_STATE_INFORMATION, // command |
| 5, // data size |
| 0x12, // component classification 0x3412s |
| 0x34, // |
| 0x56, // component identifier 0x7856 |
| 0x78, // |
| 0x9A, // classification index 0x9A |
| }; |
| |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| |
| size_t msg_len = requestMsg.size() - 1; |
| |
| struct nsm_firmware_erot_state_info_req fw_req; |
| auto rc = decode_nsm_query_get_erot_state_parameters_req( |
| request, msg_len, &fw_req); |
| |
| EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH); |
| } |
| |
| TEST(GetRotInformation, testNullDecodeRequest) |
| { |
| auto rc = decode_nsm_query_get_erot_state_parameters_req(NULL, 0, NULL); |
| |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| TEST(GetRotInformation, testGoodEncodeResponse) |
| { |
| const char *firmware_version1 = "Version ABCDE"; |
| const char *firmware_version2 = "Version 12345"; |
| |
| /* Exact message size will be counted in the encode function, |
| just, make sure this buffer is big enough to cover |
| the number of slots */ |
| uint16_t msg_size = sizeof(struct nsm_msg_hdr) + 250; |
| std::vector<uint8_t> response(msg_size, 0); |
| auto responseMsg = reinterpret_cast<nsm_msg *>(response.data()); |
| uint16_t reason_code = ERR_NULL; |
| |
| // Example response with firmware state |
| struct nsm_firmware_erot_state_info_resp fq_resp = {}; |
| |
| /* Emulate an answer with all possible fields, |
| but random content */ |
| fq_resp.fq_resp_hdr.background_copy_policy = 0x30; |
| fq_resp.fq_resp_hdr.active_slot = 0x1; |
| fq_resp.fq_resp_hdr.active_keyset = 0x32; |
| fq_resp.fq_resp_hdr.minimum_security_version = 0x3334; |
| fq_resp.fq_resp_hdr.inband_update_policy = 0x35; |
| fq_resp.fq_resp_hdr.boot_status_code = 0x0102030405060708; |
| fq_resp.fq_resp_hdr.firmware_slot_count = 2; |
| |
| fq_resp.slot_info = (struct nsm_firmware_slot_info *)malloc( |
| fq_resp.fq_resp_hdr.firmware_slot_count * |
| sizeof(struct nsm_firmware_slot_info)); |
| memset((char *)(fq_resp.slot_info), 0, |
| fq_resp.fq_resp_hdr.firmware_slot_count * |
| sizeof(struct nsm_firmware_slot_info)); |
| |
| fq_resp.slot_info[0].slot_id = 0x40; |
| strcpy((char *)(&(fq_resp.slot_info[0].firmware_version_string[0])), |
| firmware_version1); |
| fq_resp.slot_info[0].version_comparison_stamp = 0x09ABCDEF; |
| fq_resp.slot_info[0].build_type = 0x1; |
| fq_resp.slot_info[0].signing_type = 0x42; |
| fq_resp.slot_info[0].write_protect_state = 0x43; |
| fq_resp.slot_info[0].firmware_state = 0x44; |
| fq_resp.slot_info[0].security_version_number = 0x4546; |
| fq_resp.slot_info[0].signing_key_index = 0x4748; |
| |
| fq_resp.slot_info[1].slot_id = 0x50; |
| strcpy((char *)(&(fq_resp.slot_info[1].firmware_version_string[0])), |
| firmware_version2); |
| fq_resp.slot_info[1].version_comparison_stamp = 0x23456789; |
| fq_resp.slot_info[1].build_type = 0x1; |
| fq_resp.slot_info[1].signing_type = 0x52; |
| fq_resp.slot_info[1].write_protect_state = 0x53; |
| fq_resp.slot_info[1].firmware_state = 0x54; |
| fq_resp.slot_info[1].security_version_number = 0x5556; |
| fq_resp.slot_info[1].signing_key_index = 0x5758; |
| |
| reason_code = encode_nsm_query_get_erot_state_parameters_resp( |
| 0, NSM_SUCCESS, NSM_SW_SUCCESS, &fq_resp, responseMsg); |
| |
| free(fq_resp.slot_info); |
| |
| EXPECT_EQ(reason_code, NSM_SW_SUCCESS); |
| |
| struct nsm_firmware_get_erot_state_info_resp *responseTest = |
| (struct nsm_firmware_get_erot_state_info_resp *) |
| responseMsg->payload; |
| |
| EXPECT_EQ(0, responseMsg->hdr.request); |
| EXPECT_EQ(0, responseMsg->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_FIRMWARE, responseMsg->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_FW_GET_EROT_STATE_INFORMATION, responseTest->hdr.command); |
| EXPECT_EQ(25, responseTest->hdr.telemetry_count); |
| } |
| |
| TEST(GetRotInformation, testGoodEncodeResponse2) |
| { |
| const char *firmware_version1 = "Version ABCDE"; |
| const char *firmware_version2 = "Version 12345"; |
| |
| /* Exact message size will be counted in the encode function, |
| just, make sure this buffer is big enough to cover |
| the number of slots */ |
| uint16_t msg_size = sizeof(struct nsm_msg_hdr) + 250; |
| std::vector<uint8_t> response(msg_size, 0); |
| nsm_msg *responseMsg = reinterpret_cast<nsm_msg *>(response.data()); |
| uint16_t reason_code = ERR_NULL; |
| |
| // Example response with firmware state |
| struct nsm_firmware_erot_state_info_resp fq_resp = {}; |
| |
| /* Emulate an answer with all possible fields, |
| but random content */ |
| fq_resp.fq_resp_hdr.background_copy_policy = 0x30; |
| fq_resp.fq_resp_hdr.active_slot = 0x1; |
| fq_resp.fq_resp_hdr.active_keyset = 0x32; |
| fq_resp.fq_resp_hdr.minimum_security_version = 0x3334; |
| fq_resp.fq_resp_hdr.inband_update_policy = 0x35; |
| fq_resp.fq_resp_hdr.boot_status_code = 0x0102030405060708; |
| fq_resp.fq_resp_hdr.firmware_slot_count = 2; |
| |
| fq_resp.slot_info = (struct nsm_firmware_slot_info *)malloc( |
| fq_resp.fq_resp_hdr.firmware_slot_count * |
| sizeof(struct nsm_firmware_slot_info)); |
| memset((char *)(fq_resp.slot_info), 0, |
| fq_resp.fq_resp_hdr.firmware_slot_count * |
| sizeof(struct nsm_firmware_slot_info)); |
| |
| fq_resp.slot_info[0].slot_id = 0x40; |
| strcpy((char *)(&(fq_resp.slot_info[0].firmware_version_string[0])), |
| firmware_version1); |
| fq_resp.slot_info[0].version_comparison_stamp = 0x09ABCDEF; |
| fq_resp.slot_info[0].build_type = 0x1; |
| fq_resp.slot_info[0].signing_type = 0x42; |
| fq_resp.slot_info[0].write_protect_state = 0x43; |
| fq_resp.slot_info[0].firmware_state = 0x44; |
| fq_resp.slot_info[0].security_version_number = 0x4546; |
| fq_resp.slot_info[0].signing_key_index = 0x4748; |
| |
| fq_resp.slot_info[1].slot_id = 0x50; |
| strcpy((char *)(&(fq_resp.slot_info[1].firmware_version_string[0])), |
| firmware_version2); |
| fq_resp.slot_info[1].version_comparison_stamp = 0x23456789; |
| fq_resp.slot_info[1].build_type = 0x1; |
| fq_resp.slot_info[1].signing_type = 0x52; |
| fq_resp.slot_info[1].write_protect_state = 0x53; |
| fq_resp.slot_info[1].firmware_state = 0x54; |
| fq_resp.slot_info[1].security_version_number = 0x5556; |
| fq_resp.slot_info[1].signing_key_index = 0x5758; |
| |
| reason_code = encode_nsm_query_get_erot_state_parameters_resp( |
| 0, NSM_SUCCESS, NSM_SW_SUCCESS, &fq_resp, responseMsg); |
| |
| free(fq_resp.slot_info); |
| |
| EXPECT_EQ(reason_code, NSM_SW_SUCCESS); |
| |
| struct nsm_firmware_get_erot_state_info_resp *responseTest = |
| (struct nsm_firmware_get_erot_state_info_resp *) |
| responseMsg->payload; |
| |
| EXPECT_EQ(0, responseMsg->hdr.request); |
| EXPECT_EQ(0, responseMsg->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_FIRMWARE, responseMsg->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_FW_GET_EROT_STATE_INFORMATION, responseTest->hdr.command); |
| EXPECT_EQ(25, responseTest->hdr.telemetry_count); |
| } |
| |
| TEST(GetRotInformation, 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_FIRMWARE, // NVIDIA_MSG_TYPE |
| NSM_FW_GET_EROT_STATE_INFORMATION, // command |
| 0, |
| 10, |
| 0, // number of tags: 11 |
| NSM_FIRMWARE_ACTIVE_FIRMWARE_SLOT, |
| 1, |
| 1, // active slot: 1 |
| NSM_FIRMWARE_FIRMWARE_SLOT_COUNT, |
| 1, |
| 2, // number of slots: 2 |
| NSM_FIRMWARE_FIRMWARE_SLOT_ID, |
| 1, |
| 0, // slot 0 tag |
| NSM_FIRMWARE_FIRMWARE_VERSION_STRING, |
| 0x0B, |
| 0x30, |
| 0x31, |
| 0x2E, |
| 0x30, |
| 0x33, |
| 0x2E, |
| 0x30, |
| 0x32, |
| 0x31, |
| 0x30, |
| 0x2E, |
| 0x30, |
| 0x30, |
| 0x30, |
| 0x33, |
| 0x5F, |
| 0x6E, |
| 0x30, |
| 0x33, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| NSM_FIRMWARE_BUILD_TYPE, |
| 1, |
| 1, // build type: 1 |
| NSM_FIRMWARE_FIRMWARE_STATE, |
| 1, |
| 1, // firmware state: 1 |
| NSM_FIRMWARE_FIRMWARE_SLOT_ID, |
| 1, |
| 1, // slot 1 tag |
| NSM_FIRMWARE_FIRMWARE_VERSION_STRING, |
| 0x0B, |
| 0x30, |
| 0x31, |
| 0x2E, |
| 0x30, |
| 0x33, |
| 0x2E, |
| 0x30, |
| 0x32, |
| 0x31, |
| 0x30, |
| 0x2E, |
| 0x30, |
| 0x30, |
| 0x30, |
| 0x33, |
| 0x5F, |
| 0x6E, |
| 0x30, |
| 0x33, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| NSM_FIRMWARE_BUILD_TYPE, |
| 1, |
| 2, // build type: 2 |
| NSM_FIRMWARE_FIRMWARE_STATE, |
| 1, |
| 2 // firmware state: 2 |
| }; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| struct nsm_firmware_erot_state_info_resp erot_info = {}; |
| |
| auto rc = decode_nsm_query_get_erot_state_parameters_resp( |
| response, msg_len, &cc, &reason_code, &erot_info); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| EXPECT_EQ(cc, NSM_SUCCESS); |
| |
| EXPECT_EQ(2, erot_info.fq_resp_hdr.firmware_slot_count); |
| EXPECT_EQ(1, erot_info.fq_resp_hdr.active_slot); |
| EXPECT_NE(nullptr, erot_info.slot_info); |
| EXPECT_EQ(1, erot_info.slot_info[0].build_type); |
| EXPECT_EQ(2, erot_info.slot_info[1].build_type); |
| |
| free(erot_info.slot_info); |
| } |
| |
| TEST(GetRotInformation, testGoodDecodeResponseRealErot213v) |
| { |
| std::vector<uint8_t> responseMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x00, // RQ=0, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x81, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_FIRMWARE, // NVIDIA_MSG_TYPE |
| NSM_FW_GET_EROT_STATE_INFORMATION, // command |
| 0, |
| 11, |
| 0, // number of tags: 11 |
| NSM_FIRMWARE_BOOT_STATUS_CODE, |
| 7, |
| 0x00, |
| 0x05, |
| 0x01, |
| 0xFD, |
| 0x00, |
| 0x40, |
| 0x11, |
| 0x20, |
| NSM_FIRMWARE_ACTIVE_FIRMWARE_SLOT, |
| 1, |
| 0, // active slot: 1 |
| NSM_FIRMWARE_FIRMWARE_SLOT_COUNT, |
| 1, |
| 2, // number of slots: 2 |
| NSM_FIRMWARE_FIRMWARE_SLOT_ID, |
| 1, |
| 0, // slot 0 tag |
| NSM_FIRMWARE_FIRMWARE_VERSION_STRING, |
| 0x0B, |
| 0x30, |
| 0x31, |
| 0x2E, |
| 0x30, |
| 0x33, |
| 0x2E, |
| 0x30, |
| 0x32, |
| 0x31, |
| 0x30, |
| 0x2E, |
| 0x30, |
| 0x30, |
| 0x30, |
| 0x33, |
| 0x5F, |
| 0x6E, |
| 0x30, |
| 0x33, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| NSM_FIRMWARE_BUILD_TYPE, |
| 1, |
| 1, // build type: 1 |
| NSM_FIRMWARE_FIRMWARE_STATE, |
| 1, |
| 1, // firmware state: 1 |
| NSM_FIRMWARE_FIRMWARE_SLOT_ID, |
| 1, |
| 1, // slot 1 tag |
| NSM_FIRMWARE_FIRMWARE_VERSION_STRING, |
| 0x0B, |
| 0x30, |
| 0x31, |
| 0x2E, |
| 0x30, |
| 0x33, |
| 0x2E, |
| 0x30, |
| 0x32, |
| 0x31, |
| 0x30, |
| 0x2E, |
| 0x30, |
| 0x30, |
| 0x30, |
| 0x33, |
| 0x5F, |
| 0x6E, |
| 0x30, |
| 0x33, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| NSM_FIRMWARE_BUILD_TYPE, |
| 1, |
| 2, // build type: 2 |
| NSM_FIRMWARE_FIRMWARE_STATE, |
| 1, |
| 2 // firmware state: 2 |
| }; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| struct nsm_firmware_erot_state_info_resp erot_info = {}; |
| |
| auto rc = decode_nsm_query_get_erot_state_parameters_resp( |
| response, msg_len, &cc, &reason_code, &erot_info); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| EXPECT_EQ(cc, NSM_SUCCESS); |
| |
| EXPECT_EQ(2, erot_info.fq_resp_hdr.firmware_slot_count); |
| EXPECT_EQ(0, erot_info.fq_resp_hdr.active_slot); |
| EXPECT_NE(nullptr, erot_info.slot_info); |
| EXPECT_EQ(1, erot_info.slot_info[0].build_type); |
| EXPECT_EQ(2, erot_info.slot_info[1].build_type); |
| |
| free(erot_info.slot_info); |
| } |
| |
| TEST(GetRotInformation, testBadDecodeResponse) |
| { |
| 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_FIRMWARE, // NVIDIA_MSG_TYPE |
| NSM_FW_GET_EROT_STATE_INFORMATION, // command |
| 0, // completion code |
| 26, |
| 0, // number of tags |
| NSM_FIRMWARE_BACKGROUND_COPY_POLICY, |
| 1, |
| 1, |
| NSM_FIRMWARE_ACTIVE_KEY_SET, |
| 1, |
| 2, |
| NSM_FIRMWARE_MINIMUM_SECURITY_VERSION_NUMBER, |
| 3, |
| 0xC0, |
| 0xC1, |
| NSM_FIRMWARE_INBAND_UPDATE_POLICY, |
| 1, |
| 99, |
| NSM_FIRMWARE_BOOT_STATUS_CODE, |
| 7, |
| 0x08, |
| 0x07, |
| 0x06, |
| 0x05, |
| 0x04, |
| 0x03, |
| 0x02, |
| 0x01, |
| NSM_FIRMWARE_ACTIVE_FIRMWARE_SLOT, |
| 1, |
| 1, // active slot: 1 |
| NSM_FIRMWARE_FIRMWARE_SLOT_COUNT, |
| 1, |
| 2, // number of slots: 2 |
| NSM_FIRMWARE_FIRMWARE_SLOT_ID, |
| 1, |
| 0, // slot 0 tag |
| NSM_FIRMWARE_FIRMWARE_VERSION_STRING, |
| 0x0B, |
| 0x30, |
| 0x31, |
| 0x2E, |
| 0x30, |
| 0x33, |
| 0x2E, |
| 0x30, |
| 0x32, |
| 0x31, |
| 0x30, |
| 0x2E, |
| 0x30, |
| 0x30, |
| 0x30, |
| 0x33, |
| 0x5F, |
| 0x6E, |
| 0x30, |
| 0x33, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| NSM_FIRMWARE_BUILD_TYPE, |
| 1, |
| 1, // build type: 1 |
| NSM_FIRMWARE_FIRMWARE_STATE, |
| 1, |
| 1, // firmware state: 1 |
| NSM_FIRMWARE_VERSION_COMPARISON_STAMP, |
| 5, |
| 0xD0, |
| 0xD1, |
| 0xD2, |
| 0xD3, |
| NSM_FIRMWARE_SIGNING_TYPE, |
| 1, |
| 0xA1, |
| NSM_FIRMWARE_WRITE_PROTECT_STATE, |
| 1, |
| 0xA2, |
| NSM_FIRMWARE_SECURITY_VERSION_NUMBER, |
| 3, |
| 0xA3, |
| 0xA4, |
| NSM_FIRMWARE_SIGNING_KEY_INDEX, |
| 3, |
| 0xA5, |
| 0xA6, |
| NSM_FIRMWARE_FIRMWARE_SLOT_ID, |
| 1, |
| 1, // slot 1 tag |
| NSM_FIRMWARE_FIRMWARE_VERSION_STRING, |
| 0x0B, |
| 0x30, |
| 0x31, |
| 0x2E, |
| 0x30, |
| 0x33, |
| 0x2E, |
| 0x30, |
| 0x32, |
| 0x31, |
| 0x30, |
| 0x2E, |
| 0x30, |
| 0x30, |
| 0x30, |
| 0x33, |
| 0x5F, |
| 0x6E, |
| 0x30, |
| 0x33, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| NSM_FIRMWARE_BUILD_TYPE, |
| 1, |
| 2, // build type: 2 |
| NSM_FIRMWARE_FIRMWARE_STATE, |
| 1, |
| 2, // firmware state: 2 |
| NSM_FIRMWARE_VERSION_COMPARISON_STAMP, |
| 5, |
| 0xE0, |
| 0xE1, |
| 0xE2, |
| 0xE3, |
| NSM_FIRMWARE_SIGNING_TYPE, |
| 1, |
| 0xB1, |
| NSM_FIRMWARE_WRITE_PROTECT_STATE, |
| 1, |
| 0xB2, |
| NSM_FIRMWARE_SECURITY_VERSION_NUMBER, |
| 3, |
| 0xB3, |
| 0xB4, |
| NSM_FIRMWARE_SIGNING_KEY_INDEX, |
| 3, |
| 0xB5, |
| 0xB6, |
| 23, |
| 1, |
| 1 // unsupported tag number |
| }; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| struct nsm_firmware_erot_state_info_resp erot_info = {}; |
| |
| reason_code = decode_nsm_query_get_erot_state_parameters_resp( |
| NULL, msg_len, &cc, &reason_code, &erot_info); |
| EXPECT_EQ(reason_code, NSM_SW_ERROR_NULL); |
| |
| reason_code = decode_nsm_query_get_erot_state_parameters_resp( |
| response, msg_len, &cc, NULL, &erot_info); |
| EXPECT_EQ(reason_code, NSM_SW_ERROR_NULL); |
| |
| reason_code = decode_nsm_query_get_erot_state_parameters_resp( |
| response, msg_len, &cc, &reason_code, NULL); |
| EXPECT_EQ(reason_code, NSM_SW_ERROR_NULL); |
| |
| cc = NSM_SUCCESS; |
| reason_code = ERR_NULL; |
| reason_code = decode_nsm_query_get_erot_state_parameters_resp( |
| response, msg_len - 20, &cc, &reason_code, &erot_info); |
| /* In this case there is not enough data to decode one of the tags |
| * properly */ |
| EXPECT_EQ(reason_code, NSM_SW_ERROR_LENGTH); |
| /* Though, some tags should be decoded properly */ |
| EXPECT_EQ(0x0102030405060708, erot_info.fq_resp_hdr.boot_status_code); |
| EXPECT_NE(nullptr, erot_info.slot_info); |
| free(erot_info.slot_info); |
| erot_info.slot_info = nullptr; |
| |
| cc = NSM_SUCCESS; |
| reason_code = ERR_NULL; |
| reason_code = decode_nsm_query_get_erot_state_parameters_resp( |
| response, msg_len, &cc, &reason_code, &erot_info); |
| /* The last tag has an unsupported id */ |
| EXPECT_EQ(reason_code, NSM_SW_SUCCESS); |
| EXPECT_NE(nullptr, erot_info.slot_info); |
| free(erot_info.slot_info); |
| } |
| |
| TEST(GetRotInformation, testDecodeResponseWithUnsupportedTag) |
| { |
| 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_FIRMWARE, // NVIDIA_MSG_TYPE |
| NSM_FW_GET_EROT_STATE_INFORMATION, // command |
| 0, // completion code |
| 27, |
| 0, // number of tags |
| NSM_FIRMWARE_BACKGROUND_COPY_POLICY, |
| 1, |
| 1, |
| NSM_FIRMWARE_ACTIVE_KEY_SET, |
| 1, |
| 2, |
| NSM_FIRMWARE_MINIMUM_SECURITY_VERSION_NUMBER, |
| 3, |
| 0xC0, |
| 0xC1, |
| NSM_FIRMWARE_INBAND_UPDATE_POLICY, |
| 1, |
| 99, |
| NSM_FIRMWARE_BOOT_STATUS_CODE, |
| 7, |
| 0x08, |
| 0x07, |
| 0x06, |
| 0x05, |
| 0x04, |
| 0x03, |
| 0x02, |
| 0x01, |
| NSM_FIRMWARE_ACTIVE_FIRMWARE_SLOT, |
| 1, |
| 1, // active slot: 1 |
| 99, // unsupported tag number |
| 1, // value |
| 1, // value |
| NSM_FIRMWARE_FIRMWARE_SLOT_COUNT, |
| 1, |
| 2, // number of slots: 2 |
| NSM_FIRMWARE_FIRMWARE_SLOT_ID, |
| 1, |
| 0, // slot 0 tag |
| NSM_FIRMWARE_FIRMWARE_VERSION_STRING, |
| 0x0B, |
| 0x30, |
| 0x31, |
| 0x2E, |
| 0x30, |
| 0x33, |
| 0x2E, |
| 0x30, |
| 0x32, |
| 0x31, |
| 0x30, |
| 0x2E, |
| 0x30, |
| 0x30, |
| 0x30, |
| 0x33, |
| 0x5F, |
| 0x6E, |
| 0x30, |
| 0x33, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| NSM_FIRMWARE_BUILD_TYPE, |
| 1, |
| 1, // build type: 1 |
| NSM_FIRMWARE_FIRMWARE_STATE, |
| 1, |
| 1, // firmware state: 1 |
| NSM_FIRMWARE_VERSION_COMPARISON_STAMP, |
| 5, |
| 0xD0, |
| 0xD1, |
| 0xD2, |
| 0xD3, |
| NSM_FIRMWARE_SIGNING_TYPE, |
| 1, |
| 0xA1, |
| NSM_FIRMWARE_WRITE_PROTECT_STATE, |
| 1, |
| 0xA2, |
| NSM_FIRMWARE_SECURITY_VERSION_NUMBER, |
| 3, |
| 0xA3, |
| 0xA4, |
| NSM_FIRMWARE_SIGNING_KEY_INDEX, |
| 3, |
| 0xA5, |
| 0xA6, |
| NSM_FIRMWARE_FIRMWARE_SLOT_ID, |
| 1, |
| 1, // slot 1 tag |
| NSM_FIRMWARE_FIRMWARE_VERSION_STRING, |
| 0x0B, |
| 0x30, |
| 0x31, |
| 0x2E, |
| 0x30, |
| 0x33, |
| 0x2E, |
| 0x30, |
| 0x32, |
| 0x31, |
| 0x30, |
| 0x2E, |
| 0x30, |
| 0x30, |
| 0x30, |
| 0x33, |
| 0x5F, |
| 0x6E, |
| 0x30, |
| 0x33, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| 0, |
| NSM_FIRMWARE_BUILD_TYPE, |
| 1, |
| 2, // build type: 2 |
| NSM_FIRMWARE_FIRMWARE_STATE, |
| 1, |
| 2, // firmware state: 2 |
| NSM_FIRMWARE_VERSION_COMPARISON_STAMP, |
| 5, |
| 0xE0, |
| 0xE1, |
| 0xE2, |
| 0xE3, |
| NSM_FIRMWARE_SIGNING_TYPE, |
| 1, |
| 0xB1, |
| NSM_FIRMWARE_WRITE_PROTECT_STATE, |
| 1, |
| 0xB2, |
| NSM_FIRMWARE_SECURITY_VERSION_NUMBER, |
| 3, |
| 0xB3, |
| 0xB4, |
| NSM_FIRMWARE_SIGNING_KEY_INDEX, |
| 3, |
| 0xB5, |
| 0xB6, |
| 23, |
| 1, |
| 1 // unsupported tag number |
| }; |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| struct nsm_firmware_erot_state_info_resp erot_info = {}; |
| |
| reason_code = decode_nsm_query_get_erot_state_parameters_resp( |
| response, msg_len, &cc, &reason_code, &erot_info); |
| /* The last tag has an unsupported id */ |
| EXPECT_EQ(reason_code, NSM_SW_SUCCESS); |
| EXPECT_NE(nullptr, erot_info.slot_info); |
| free(erot_info.slot_info); |
| } |
| |
| TEST(codeAuthKeyPermQuery, testGoodEncodeRequest) |
| { |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_code_auth_key_perm_query_req)); |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| |
| uint16_t component_classification = 0x0001; |
| uint16_t component_identifier = 0x0002; |
| uint8_t component_classification_index = 0x03; |
| auto rc = encode_nsm_code_auth_key_perm_query_req( |
| 0, component_classification, component_identifier, |
| component_classification_index, request); |
| |
| nsm_code_auth_key_perm_query_req *req = |
| (nsm_code_auth_key_perm_query_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_FIRMWARE, request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_FW_QUERY_CODE_AUTH_KEY_PERM, req->hdr.command); |
| EXPECT_EQ(sizeof(nsm_code_auth_key_perm_query_req) - |
| sizeof(nsm_common_req), |
| req->hdr.data_size); |
| EXPECT_EQ(req->component_classification, component_classification); |
| EXPECT_EQ(req->component_identifier, component_identifier); |
| EXPECT_EQ(req->component_classification_index, |
| component_classification_index); |
| } |
| |
| TEST(codeAuthKeyPermQuery, 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_FIRMWARE, // NVIDIA_MSG_TYPE |
| NSM_FW_QUERY_CODE_AUTH_KEY_PERM, // command |
| NSM_SUCCESS, // completion code |
| 0, |
| 0, // reserved |
| 13, // data size |
| 0, // data size |
| 0x12, // active_component_key_index |
| 0x34, // active_component_key_index |
| 0x56, // pending_component_key_index |
| 0x78, // pending_component_key_index |
| 2, // permission_bitmap_length |
| 0x01, // active_component_key_perm_bitmap |
| 0x02, // active_component_key_perm_bitmap |
| 0x03, // pending_component_key_perm_bitmap |
| 0x04, // pending_component_key_perm_bitmap |
| 0x05, // efuse_key_perm_bitmap |
| 0x06, // efuse_key_perm_bitmap |
| 0x07, // pending_efuse_key_perm_bitmap |
| 0x08, // pending_efuse_key_perm_bitmap |
| }; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| uint16_t active_component_key_index; |
| uint16_t pending_component_key_index; |
| uint8_t permission_bitmap_length; |
| auto rc = decode_nsm_code_auth_key_perm_query_resp( |
| response, msg_len, &cc, &reason_code, &active_component_key_index, |
| &pending_component_key_index, &permission_bitmap_length, NULL, NULL, |
| NULL, NULL); |
| EXPECT_EQ(NSM_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| EXPECT_EQ(0, reason_code); |
| EXPECT_EQ(0x3412, active_component_key_index); |
| EXPECT_EQ(0x7856, pending_component_key_index); |
| EXPECT_EQ(2, permission_bitmap_length); |
| |
| std::unique_ptr<uint8_t[]> active_component_key_perm_bitmap( |
| new uint8_t[permission_bitmap_length]); |
| std::unique_ptr<uint8_t[]> pending_component_key_perm_bitmap( |
| new uint8_t[permission_bitmap_length]); |
| std::unique_ptr<uint8_t[]> efuse_key_perm_bitmap( |
| new uint8_t[permission_bitmap_length]); |
| std::unique_ptr<uint8_t[]> pending_efuse_key_perm_bitmap( |
| new uint8_t[permission_bitmap_length]); |
| |
| rc = decode_nsm_code_auth_key_perm_query_resp( |
| response, msg_len, &cc, &reason_code, &active_component_key_index, |
| &pending_component_key_index, &permission_bitmap_length, |
| active_component_key_perm_bitmap.get(), |
| pending_component_key_perm_bitmap.get(), |
| efuse_key_perm_bitmap.get(), pending_efuse_key_perm_bitmap.get()); |
| EXPECT_EQ(NSM_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| EXPECT_EQ(0, reason_code); |
| EXPECT_EQ(0x3412, active_component_key_index); |
| EXPECT_EQ(0x7856, pending_component_key_index); |
| EXPECT_EQ(2, permission_bitmap_length); |
| EXPECT_EQ(0x01, active_component_key_perm_bitmap.get()[0]); |
| EXPECT_EQ(0x02, active_component_key_perm_bitmap.get()[1]); |
| EXPECT_EQ(0x03, pending_component_key_perm_bitmap.get()[0]); |
| EXPECT_EQ(0x04, pending_component_key_perm_bitmap.get()[1]); |
| EXPECT_EQ(0x05, efuse_key_perm_bitmap.get()[0]); |
| EXPECT_EQ(0x06, efuse_key_perm_bitmap.get()[1]); |
| EXPECT_EQ(0x07, pending_efuse_key_perm_bitmap.get()[0]); |
| EXPECT_EQ(0x08, pending_efuse_key_perm_bitmap.get()[1]); |
| } |
| |
| TEST(codeAuthKeyPermQuery, testBadDecodeResponse) |
| { |
| 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_FIRMWARE, // NVIDIA_MSG_TYPE |
| NSM_FW_QUERY_CODE_AUTH_KEY_PERM, // command |
| NSM_SUCCESS, // completion code |
| 0, |
| 0, // reserved |
| 13, // data size |
| 0, // data size |
| 0x12, // active_component_key_index |
| 0x34, // active_component_key_index |
| 0x56, // pending_component_key_index |
| 0x78, // pending_component_key_index |
| 8, // permission_bitmap_length (incorrect) |
| 0x01, // active_component_key_perm_bitmap |
| 0x02, // active_component_key_perm_bitmap |
| 0x03, // pending_component_key_perm_bitmap |
| 0x04, // pending_component_key_perm_bitmap |
| 0x05, // efuse_key_perm_bitmap |
| 0x06, // efuse_key_perm_bitmap |
| 0x07, // pending_efuse_key_perm_bitmap |
| 0x08, // pending_efuse_key_perm_bitmap |
| }; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| uint16_t active_component_key_index; |
| uint16_t pending_component_key_index; |
| uint8_t permission_bitmap_length; |
| auto rc = decode_nsm_code_auth_key_perm_query_resp( |
| response, msg_len, &cc, &reason_code, &active_component_key_index, |
| &pending_component_key_index, &permission_bitmap_length, NULL, NULL, |
| NULL, NULL); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |
| |
| TEST(codeAuthKeyPermUpdate, testGoodEncodeRequest) |
| { |
| size_t dataLength = 16; |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_code_auth_key_perm_update_req) + |
| dataLength); |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| |
| nsm_code_auth_key_perm_request_type request_type = |
| NSM_CODE_AUTH_KEY_PERM_REQUEST_TYPE_SPECIFIED_VALUE; |
| uint16_t component_classification = 0x0001; |
| uint16_t component_identifier = 0x0002; |
| uint8_t component_classification_index = 0x03; |
| uint64_t nonce = 0x0123456789abcdef; |
| uint8_t permission_bitmap_length = dataLength; |
| std::unique_ptr<uint8_t[]> permission_bitmap( |
| new uint8_t[permission_bitmap_length]); |
| for (size_t i = 0; i < permission_bitmap_length; ++i) { |
| permission_bitmap.get()[i] = i; |
| } |
| auto rc = encode_nsm_code_auth_key_perm_update_req( |
| 0, request_type, component_classification, component_identifier, |
| component_classification_index, nonce, permission_bitmap_length, |
| permission_bitmap.get(), request); |
| |
| nsm_code_auth_key_perm_update_req *req = |
| (nsm_code_auth_key_perm_update_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_FIRMWARE, request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_FW_UPDATE_CODE_AUTH_KEY_PERM, req->hdr.command); |
| EXPECT_EQ(sizeof(nsm_code_auth_key_perm_update_req) - |
| sizeof(nsm_common_req) + permission_bitmap_length, |
| req->hdr.data_size); |
| EXPECT_EQ(req->request_type, request_type); |
| EXPECT_EQ(req->component_classification, component_classification); |
| EXPECT_EQ(req->component_identifier, component_identifier); |
| EXPECT_EQ(req->component_classification_index, |
| component_classification_index); |
| EXPECT_EQ(req->nonce, nonce); |
| EXPECT_EQ(req->permission_bitmap_length, permission_bitmap_length); |
| uint8_t *bitmap_ptr = |
| request->payload + sizeof(struct nsm_code_auth_key_perm_update_req); |
| EXPECT_EQ(0, memcmp(permission_bitmap.get(), bitmap_ptr, |
| permission_bitmap_length)); |
| } |
| |
| TEST(codeAuthKeyPermUpdate, testBadEncodeRequest) |
| { |
| size_t dataLength = 16; |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + sizeof(nsm_code_auth_key_perm_update_req) + |
| dataLength); |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| |
| uint16_t component_classification = 0x0001; |
| uint16_t component_identifier = 0x0002; |
| uint8_t component_classification_index = 0x03; |
| uint64_t nonce = 0x0123456789abcdef; |
| uint8_t permission_bitmap_length = dataLength; |
| std::unique_ptr<uint8_t[]> permission_bitmap( |
| new uint8_t[permission_bitmap_length]); |
| for (size_t i = 0; i < permission_bitmap_length; ++i) { |
| permission_bitmap.get()[i] = i; |
| } |
| int rc; |
| |
| // most restrictive value requested but bitmap is specified |
| rc = encode_nsm_code_auth_key_perm_update_req( |
| 0, NSM_CODE_AUTH_KEY_PERM_REQUEST_TYPE_MOST_RESTRICTIVE_VALUE, |
| component_classification, component_identifier, |
| component_classification_index, nonce, permission_bitmap_length, |
| permission_bitmap.get(), request); |
| EXPECT_EQ(NSM_SW_ERROR_DATA, rc); |
| |
| // specified value requested but bitmap is of zero length |
| rc = encode_nsm_code_auth_key_perm_update_req( |
| 0, NSM_CODE_AUTH_KEY_PERM_REQUEST_TYPE_SPECIFIED_VALUE, |
| component_classification, component_identifier, |
| component_classification_index, nonce, 0, permission_bitmap.get(), |
| request); |
| EXPECT_EQ(NSM_SW_ERROR_DATA, rc); |
| |
| // specified value requested but bitmap is nullptr |
| rc = encode_nsm_code_auth_key_perm_update_req( |
| 0, NSM_CODE_AUTH_KEY_PERM_REQUEST_TYPE_SPECIFIED_VALUE, |
| component_classification, component_identifier, |
| component_classification_index, nonce, permission_bitmap_length, |
| nullptr, request); |
| EXPECT_EQ(NSM_SW_ERROR_DATA, rc); |
| |
| // specified value requested but bitmap is not specified |
| rc = encode_nsm_code_auth_key_perm_update_req( |
| 0, NSM_CODE_AUTH_KEY_PERM_REQUEST_TYPE_SPECIFIED_VALUE, |
| component_classification, component_identifier, |
| component_classification_index, nonce, 0, nullptr, request); |
| EXPECT_EQ(NSM_SW_ERROR_DATA, rc); |
| |
| // incorrect request type |
| rc = encode_nsm_code_auth_key_perm_update_req( |
| 0, static_cast<nsm_code_auth_key_perm_request_type>(0xFF), |
| component_classification, component_identifier, |
| component_classification_index, nonce, permission_bitmap_length, |
| permission_bitmap.get(), request); |
| EXPECT_EQ(NSM_SW_ERROR_DATA, rc); |
| } |
| |
| TEST(codeAuthKeyPermUpdate, testGoodDecodeResponse) |
| { |
| uint32_t method = NSM_EFUSE_UPDATE_METHOD_SYSTEM_REBOOT | |
| NSM_EFUSE_UPDATE_METHOD_FUNCTION_LEVEL_RESET; |
| 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_FIRMWARE, // NVIDIA_MSG_TYPE |
| NSM_FW_UPDATE_CODE_AUTH_KEY_PERM, // command |
| NSM_SUCCESS, // completion code |
| 0, |
| 0, // reserved |
| 4, // data size |
| 0, // data size |
| static_cast<uint8_t>(method & 0xFF), // update_method |
| static_cast<uint8_t>((method >> 8) & 0xFF), // update_method |
| static_cast<uint8_t>((method >> 16) & 0xFF), // update_method |
| static_cast<uint8_t>((method >> 24) & 0xFF), // update_method |
| }; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| uint32_t update_method = 0; |
| auto rc = decode_nsm_code_auth_key_perm_update_resp( |
| response, msg_len, &cc, &reason_code, &update_method); |
| EXPECT_EQ(NSM_SUCCESS, rc); |
| EXPECT_EQ(NSM_SUCCESS, cc); |
| EXPECT_EQ(0, reason_code); |
| EXPECT_EQ(NSM_EFUSE_UPDATE_METHOD_SYSTEM_REBOOT | |
| NSM_EFUSE_UPDATE_METHOD_FUNCTION_LEVEL_RESET, |
| update_method); |
| } |
| |
| TEST(codeAuthKeyPermUpdate, testBadDecodeResponse) |
| { |
| uint32_t method = NSM_EFUSE_UPDATE_METHOD_SYSTEM_REBOOT | |
| NSM_EFUSE_UPDATE_METHOD_FUNCTION_LEVEL_RESET; |
| 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_FIRMWARE, // NVIDIA_MSG_TYPE |
| NSM_FW_UPDATE_CODE_AUTH_KEY_PERM, // command |
| NSM_SUCCESS, // completion code |
| 0, |
| 0, // reserved |
| 2, // data size |
| 0, // data size |
| static_cast<uint8_t>(method & 0xFF), // update_method |
| static_cast<uint8_t>((method >> 8) & 0xFF), // update_method |
| }; |
| |
| auto response = reinterpret_cast<nsm_msg *>(responseMsg.data()); |
| size_t msg_len = responseMsg.size(); |
| uint8_t cc = 0; |
| uint16_t reason_code = ERR_NULL; |
| uint32_t update_method = 0; |
| auto rc = decode_nsm_code_auth_key_perm_update_resp( |
| response, msg_len, &cc, &reason_code, &update_method); |
| EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc); |
| } |
| |
| TEST(QueryFirmwareSecurityVersion, testEncodeRequest) |
| { |
| uint16_t classification = 0xA; |
| uint8_t index = 0x0; |
| uint16_t identifier = 0x10; |
| |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + |
| sizeof(nsm_firmware_security_version_number_req_command)); |
| nsm_firmware_security_version_number_req nsm_req; |
| nsm_req.component_classification = classification; |
| nsm_req.component_classification_index = index; |
| nsm_req.component_identifier = identifier; |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| auto rc = encode_nsm_query_firmware_security_version_number_req( |
| 0, &nsm_req, request); |
| |
| struct nsm_firmware_security_version_number_req_command *requestTest = |
| (struct nsm_firmware_security_version_number_req_command |
| *)(request->payload); |
| |
| struct nsm_firmware_security_version_number_req *req = |
| (struct nsm_firmware_security_version_number_req *)&( |
| requestTest->fq_req); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_FIRMWARE, request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_FW_QUERY_MIN_SECURITY_VERSION_NUMBER, |
| requestTest->hdr.command); |
| EXPECT_EQ(5, requestTest->hdr.data_size); |
| |
| EXPECT_EQ(classification, req->component_classification); |
| EXPECT_EQ(index, req->component_classification_index); |
| EXPECT_EQ(identifier, req->component_identifier); |
| |
| // Negative test case |
| rc = encode_nsm_query_firmware_security_version_number_req(0, &nsm_req, |
| NULL); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |
| |
| TEST(QueryFirmwareSecurityVersion, testDecodeRequest) |
| { |
| std::vector<uint8_t> requestMsg{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x80, // RQ=1, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_FIRMWARE, // NVIDIA_MSG_TYPE |
| NSM_FW_QUERY_MIN_SECURITY_VERSION_NUMBER, // command |
| 0x5, // data size |
| 0x0A, // component classification 0x000A |
| 0x00, // |
| 0x00, // component identifier 0xFF00 |
| 0xFF, // |
| 0x0, // classification index 0x00 |
| }; |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| |
| size_t msg_len = requestMsg.size(); |
| |
| struct nsm_firmware_security_version_number_req fw_req; |
| auto rc = decode_nsm_query_firmware_security_version_number_req( |
| request, msg_len, &fw_req); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| EXPECT_EQ(0x0A, fw_req.component_classification); |
| EXPECT_EQ(0xFF00, fw_req.component_identifier); |
| EXPECT_EQ(0x0, fw_req.component_classification_index); |
| |
| // Negative test cases |
| rc = decode_nsm_query_firmware_security_version_number_req( |
| NULL, msg_len, &fw_req); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| rc = decode_nsm_query_firmware_security_version_number_req( |
| request, msg_len, NULL); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| rc = decode_nsm_query_firmware_security_version_number_req( |
| request, msg_len - 2, &fw_req); |
| EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH); |
| } |
| |
| TEST(QueryFirmwareSecurityVersion, testEncodeResponse) |
| { |
| struct nsm_firmware_security_version_number_resp sec_resp{}; |
| sec_resp.active_component_security_version = 3; |
| sec_resp.pending_component_security_version = 4; |
| sec_resp.minimum_security_version = 1; |
| sec_resp.pending_minimum_security_version = 2; |
| uint16_t msg_size = |
| sizeof(nsm_msg_hdr) + |
| sizeof(nsm_firmware_security_version_number_resp_command); |
| |
| std::vector<uint8_t> response(msg_size, 0); |
| auto responseMsg = reinterpret_cast<nsm_msg *>(response.data()); |
| uint16_t reason_code = ERR_NULL; |
| |
| auto rc = encode_nsm_query_firmware_security_version_number_resp( |
| 0, NSM_SUCCESS, reason_code, &sec_resp, responseMsg); |
| |
| struct nsm_firmware_security_version_number_resp_command *responseTest = |
| (struct nsm_firmware_security_version_number_resp_command |
| *)(responseMsg->payload); |
| |
| struct nsm_firmware_security_version_number_resp *resp = |
| (struct nsm_firmware_security_version_number_resp *)&( |
| responseTest->sec_ver_resp); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| |
| EXPECT_EQ(0, responseMsg->hdr.request); |
| EXPECT_EQ(0, responseMsg->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_FIRMWARE, responseMsg->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_FW_QUERY_MIN_SECURITY_VERSION_NUMBER, |
| responseTest->hdr.command); |
| EXPECT_EQ(sizeof(struct nsm_common_resp) + |
| sizeof(struct nsm_firmware_security_version_number_resp), |
| responseTest->hdr.data_size); |
| EXPECT_EQ(resp->active_component_security_version, 3); |
| EXPECT_EQ(resp->pending_component_security_version, 4); |
| EXPECT_EQ(resp->minimum_security_version, 1); |
| EXPECT_EQ(resp->pending_minimum_security_version, 2); |
| |
| // Negative test case |
| rc = encode_nsm_query_firmware_security_version_number_resp( |
| 0, NSM_SUCCESS, reason_code, &sec_resp, NULL); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| |
| reason_code = NSM_SW_ERROR_COMMAND_FAIL; |
| rc = encode_nsm_query_firmware_security_version_number_resp( |
| 0, NSM_ERROR, reason_code, &sec_resp, responseMsg); |
| struct nsm_common_non_success_resp *responseFail = |
| (struct nsm_common_non_success_resp *)responseMsg->payload; |
| EXPECT_EQ(reason_code, responseFail->reason_code); |
| } |
| |
| TEST(QueryFirmwareSecurityVersion, testDecodeResponse) |
| { |
| uint8_t cc = NSM_SUCCESS; |
| uint16_t reason_code = ERR_NULL; |
| std::vector<uint8_t> response{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x80, // RQ=1, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_FIRMWARE, // NVIDIA_MSG_TYPE |
| NSM_FW_QUERY_MIN_SECURITY_VERSION_NUMBER, // command |
| 0x00, // completion_code |
| 0x00, |
| 0x00, // reserved |
| 0x08, |
| 0x00, // data size |
| 0x03, |
| 0x00, // active_component_security_version |
| 0x04, |
| 0x00, // pending_component_security_version |
| 0x01, |
| 0x00, // minimum_security_version |
| 0x02, |
| 0x00 // pending_minimum_security_version |
| }; |
| auto responseMsg = reinterpret_cast<nsm_msg *>(response.data()); |
| size_t msg_len = response.size(); |
| |
| struct nsm_firmware_security_version_number_resp sec_resp; |
| auto rc = decode_nsm_query_firmware_security_version_number_resp( |
| responseMsg, msg_len, &cc, &reason_code, &sec_resp); |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| EXPECT_EQ(cc, NSM_SUCCESS); |
| EXPECT_EQ(reason_code, ERR_NULL); |
| EXPECT_EQ(sec_resp.active_component_security_version, 3); |
| EXPECT_EQ(sec_resp.pending_component_security_version, 4); |
| EXPECT_EQ(sec_resp.minimum_security_version, 1); |
| EXPECT_EQ(sec_resp.pending_minimum_security_version, 2); |
| |
| // Negative test cases |
| rc = decode_nsm_query_firmware_security_version_number_resp( |
| NULL, msg_len, &cc, &reason_code, &sec_resp); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| |
| std::vector<uint8_t> response1{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x80, // RQ=1, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_FIRMWARE, // NVIDIA_MSG_TYPE |
| NSM_FW_QUERY_MIN_SECURITY_VERSION_NUMBER, // command |
| NSM_ERROR, // completion_code |
| 0x00, |
| 0x00, // reserved |
| 0x08, |
| 0x00, // data size |
| 0x03, |
| 0x00, // active_component_security_version |
| 0x04, |
| 0x00, // pending_component_security_version |
| 0x01, |
| 0x00, // minimum_security_version |
| 0x02, |
| 0x00 // pending_minimum_security_version |
| }; |
| auto responseMsg1 = reinterpret_cast<nsm_msg *>(response1.data()); |
| size_t msg_len1 = response1.size(); |
| rc = decode_nsm_query_firmware_security_version_number_resp( |
| responseMsg1, msg_len1, &cc, &reason_code, &sec_resp); |
| EXPECT_EQ(cc, NSM_ERROR); |
| |
| std::vector<uint8_t> response2{ |
| 0x10, |
| 0xDE, // PCI VID: NVIDIA 0x10DE |
| 0x80, // RQ=1, D=0, RSVD=0, INSTANCE_ID=0 |
| 0x89, // OCP_TYPE=8, OCP_VER=9 |
| NSM_TYPE_FIRMWARE, // NVIDIA_MSG_TYPE |
| NSM_FW_QUERY_MIN_SECURITY_VERSION_NUMBER, // command |
| 0x00, // completion_code |
| 0x00, |
| 0x00, // reserved |
| 0x02, |
| 0x00, // data size |
| 0x03, |
| 0x00, // active_component_security_version --> Truncated response |
| }; |
| auto responseMsg2 = reinterpret_cast<nsm_msg *>(response2.data()); |
| size_t msg_len2 = response2.size(); |
| rc = decode_nsm_query_firmware_security_version_number_resp( |
| responseMsg2, msg_len2, &cc, &reason_code, &sec_resp); |
| EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH); |
| } |
| |
| TEST(UpdateFirmwareSecurityVersion, testEncodeRequest) |
| { |
| uint8_t requestType = 0x1; |
| uint16_t classification = 0xA; |
| uint8_t index = 0x0; |
| uint16_t identifier = 0x10; |
| uint64_t nonce = 0x12345678; |
| uint16_t reqMinSecVersion = 0x3; |
| |
| std::vector<uint8_t> requestMsg( |
| sizeof(nsm_msg_hdr) + |
| sizeof(nsm_firmware_update_min_sec_ver_req_command)); |
| nsm_firmware_update_min_sec_ver_req nsm_req; |
| nsm_req.request_type = requestType; |
| nsm_req.component_classification = classification; |
| nsm_req.component_classification_index = index; |
| nsm_req.component_identifier = identifier; |
| nsm_req.nonce = nonce; |
| nsm_req.req_min_security_version = reqMinSecVersion; |
| auto request = reinterpret_cast<nsm_msg *>(requestMsg.data()); |
| auto rc = encode_nsm_firmware_update_sec_ver_req(0, &nsm_req, request); |
| |
| struct nsm_firmware_update_min_sec_ver_req_command *requestTest = |
| (struct nsm_firmware_update_min_sec_ver_req_command |
| *)(request->payload); |
| |
| struct nsm_firmware_update_min_sec_ver_req *req = |
| (struct nsm_firmware_update_min_sec_ver_req *)&( |
| requestTest->ver_update_req); |
| |
| EXPECT_EQ(rc, NSM_SW_SUCCESS); |
| |
| EXPECT_EQ(1, request->hdr.request); |
| EXPECT_EQ(0, request->hdr.datagram); |
| EXPECT_EQ(NSM_TYPE_FIRMWARE, request->hdr.nvidia_msg_type); |
| |
| EXPECT_EQ(NSM_FW_UPDATE_MIN_SECURITY_VERSION_NUMBER, |
| requestTest->hdr.command); |
| EXPECT_EQ(sizeof(nsm_firmware_update_min_sec_ver_req), |
| requestTest->hdr.data_size); |
| |
| EXPECT_EQ(requestType, req->request_type); |
| EXPECT_EQ(classification, req->component_classification); |
| EXPECT_EQ(index, req->component_classification_index); |
| EXPECT_EQ(identifier, req->component_identifier); |
| EXPECT_EQ(nonce, req->nonce); |
| EXPECT_EQ(reqMinSecVersion, req->req_min_security_version); |
| |
| // Negative test case |
| rc = encode_nsm_firmware_update_sec_ver_req(0, &nsm_req, NULL); |
| EXPECT_EQ(rc, NSM_SW_ERROR_NULL); |
| } |