/******************************************************************************* * Copyright (C) 2004-2008 Intel Corp. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of Intel Corp. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ //---------------------------------------------------------------------------- // // File: PTHICommand.cpp // //---------------------------------------------------------------------------- #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "PTHICommand.h" PTHICommand::PTHICommand(bool verbose, unsigned long sendTimeout) : PTHIClient(HECI_PTHI, verbose), m_sendTimeout(sendTimeout) { } PTHICommand::~PTHICommand(void) { } AMT_STATUS PTHICommand::_call(const unsigned char *command, UINT32 command_size, UINT8 **readBuffer, UINT32 rcmd, unsigned int expSize) { UINT32 inBuffSize; UINT32 outBuffSize = 0; inBuffSize = PTHIClient.GetBufferSize(); *readBuffer = (UINT8 *)malloc(sizeof(UINT8) * inBuffSize); if (NULL == *readBuffer) { return PTSDK_STATUS_RESOURCES; } memset(*readBuffer, 0, inBuffSize); int bytesWritten = PTHIClient.SendMessage(command, command_size, m_sendTimeout); if ((UINT32)bytesWritten != command_size) { return AMT_STATUS_INTERNAL_ERROR; } outBuffSize = PTHIClient.ReceiveMessage(*readBuffer, inBuffSize); if (0 == outBuffSize) { return PTHI_STATUS_EMPTY_RESPONSE; } AMT_STATUS status = ((PTHI_RESPONSE_MESSAGE_HEADER *)*readBuffer)->Status; if (status != AMT_STATUS_SUCCESS) { return status; } status = _verifyResponseHeader(rcmd, ((PTHI_RESPONSE_MESSAGE_HEADER *)*readBuffer)->Header, outBuffSize); if (status != AMT_STATUS_SUCCESS) { return status; } if ((expSize != 0) && (expSize != outBuffSize)) { return PTSDK_STATUS_INTERNAL_ERROR; } return AMT_STATUS_SUCCESS; } /* * Confirms the correctness of the response message header * and the response message size * Arguments: * command - appropriate Host interface command * response_header - reference to the response message header * response_size - value that holds the actual size of the * response message * expected_size - value that holds the expected size of the * response message * Return values: * AMT_STATUS_SUCCESS - on success * PTSDK_STATUS_INTERNAL_ERROR - on failure */ AMT_STATUS PTHICommand::_verifyResponseHeader( const UINT32 command, const PTHI_MESSAGE_HEADER &response_header, UINT32 response_size) { AMT_STATUS status = AMT_STATUS_SUCCESS; if (response_size < sizeof(PTHI_RESPONSE_MESSAGE_HEADER)) { status = AMT_STATUS_INTERNAL_ERROR; } else if (response_size != (response_header.Length + sizeof(PTHI_MESSAGE_HEADER))) { status = AMT_STATUS_INTERNAL_ERROR; } else if (response_header.Command.cmd.val != command) { status = AMT_STATUS_INTERNAL_ERROR; } else if (response_header.Reserved != 0) { status = AMT_STATUS_INTERNAL_ERROR; } else if (response_header.Version.MajorNumber != AMT_MAJOR_VERSION || response_header.Version.MinorNumber < AMT_MINOR_VERSION) { status = AMT_STATUS_INTERNAL_ERROR; } return status; } /* * Confirms the correctness of the GetCodeVersions response message * Arguments: * response - reference to the response message * Return values: * AMT_STATUS_SUCCESS - on success * PTSDK_STATUS_INTERNAL_ERROR - on failure */ AMT_STATUS PTHICommand::_verifyCodeVersions( const CFG_GET_CODE_VERSIONS_RESPONSE &response) { AMT_STATUS status = AMT_STATUS_SUCCESS; UINT32 codeVerLen; UINT32 ptVerTypeCount; UINT32 len = 0; UINT32 i; do { codeVerLen = response.Header.Header.Length - sizeof(AMT_STATUS); ptVerTypeCount = codeVerLen - sizeof(response.CodeVersions.BiosVersion)- sizeof(response.CodeVersions.VersionsCount); if (response.CodeVersions.VersionsCount != (ptVerTypeCount/sizeof(AMT_VERSION_TYPE))) { status = AMT_STATUS_INTERNAL_ERROR; break; } for (i = 0; i < (response.CodeVersions.VersionsCount); i ++) { len = response.CodeVersions.Versions[i].Description.Length; if (len > UNICODE_STRING_LEN) { status = AMT_STATUS_INTERNAL_ERROR; break; } len = response.CodeVersions.Versions[i].Version.Length; if (response.CodeVersions.Versions[i].Version.String[len] != '\0' || (len != strlen((CHAR *)(response.CodeVersions.Versions[i].Version.String)))) { status = AMT_STATUS_INTERNAL_ERROR; break; } } } while (0); return status; } /* * GetVersions response message PTHI command * Arguments: * response - reference to the CODE_VERSIONS struct * Return values: * AMT_STATUS_SUCCESS - on success * AMT_STATUS_INTERNAL_ERROR - on failure */ AMT_STATUS PTHICommand::GetCodeVersions(CODE_VERSIONS &codeVersions) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(GET_CODE_VERSION_HEADER); unsigned char command[command_size]; memcpy(command, &(GET_CODE_VERSION_HEADER), sizeof(GET_CODE_VERSION_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, CODE_VERSIONS_RESPONSE, 0); do { if (status != AMT_STATUS_SUCCESS) { break; } CFG_GET_CODE_VERSIONS_RESPONSE *tmp_response = (CFG_GET_CODE_VERSIONS_RESPONSE *)readBuffer; status = _verifyCodeVersions(*tmp_response); if (status != AMT_STATUS_SUCCESS) { break; } memcpy(&codeVersions, &(tmp_response->CodeVersions), sizeof(CODE_VERSIONS)); } while (0); if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Calls to GetProvisioningMode Host interface command * Arguments: * mode - reference to the pre-allocated structure * which will hold the result * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::GetProvisioningMode(CFG_PROVISIONING_MODE &mode) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(GET_PROVISIONING_MODE_HEADER); unsigned char command[command_size]; memcpy(command, &(GET_PROVISIONING_MODE_HEADER), sizeof(GET_PROVISIONING_MODE_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, PROVISIONING_MODE_RESPONSE, sizeof(CFG_GET_PROVISIONING_MODE_RESPONSE)); do { if (status != AMT_STATUS_SUCCESS) { break; } CFG_GET_PROVISIONING_MODE_RESPONSE *tmp_response = (CFG_GET_PROVISIONING_MODE_RESPONSE *)readBuffer; mode = tmp_response->ProvisioningMode; } while (0); if (readBuffer != NULL) { free(readBuffer); } return status; } AMT_STATUS PTHICommand::GetProvisioningMode(CFG_PROVISIONING_MODE &mode, AMT_BOOLEAN &legacy) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(GET_PROVISIONING_MODE_HEADER); unsigned char command[command_size]; memcpy(command, &(GET_PROVISIONING_MODE_HEADER), sizeof(GET_PROVISIONING_MODE_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, PROVISIONING_MODE_RESPONSE, sizeof(CFG_GET_PROVISIONING_MODE_RESPONSE)); do { if (status != AMT_STATUS_SUCCESS) { break; } CFG_GET_PROVISIONING_MODE_RESPONSE *tmp_response = (CFG_GET_PROVISIONING_MODE_RESPONSE *)readBuffer; mode = tmp_response->ProvisioningMode; legacy = tmp_response->LegacyMode; } while (0); if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Calls to GetProvisioningState Host interface command * Arguments: * state - reference to the pre-allocated structure * which will hold the result * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::GetProvisioningState(AMT_PROVISIONING_STATE &state) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(GET_PROVISIONING_STATE_HEADER); unsigned char command[command_size]; memcpy(command, &(GET_PROVISIONING_STATE_HEADER), sizeof(GET_PROVISIONING_STATE_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, PROVISIONING_STATE_RESPONSE, sizeof(CFG_GET_PROVISIONING_STATE_RESPONSE)); do { if (status != AMT_STATUS_SUCCESS) { break; } CFG_GET_PROVISIONING_STATE_RESPONSE *tmp_response = (CFG_GET_PROVISIONING_STATE_RESPONSE *)readBuffer; state = tmp_response->ProvisioningState; } while (0); if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Calls to GetFeatureState Host interface command * Arguments: * requestID Indicates what feature status to query: * 0 Redirection Sessions Status * 1 System Defense Status * 2 WebUI Status * requestStatus The requested feature state(the size depand on the requestID).(OUT) * * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::GetFeaturesState(UINT32 requestID, AMT_BOOLEAN (&requestStatus)[2]) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(CFG_GET_FEATURES_STATE_REQUEST); unsigned char command[command_size]; memcpy(command, &GET_FEATURES_STATE_HEADER, sizeof(GET_FEATURES_STATE_HEADER)); memcpy(command + sizeof(GET_FEATURES_STATE_HEADER), &(requestID), sizeof(UINT32)); AMT_STATUS status = _call(command, command_size, &readBuffer, GET_FEATURES_STATE_RESPONSE, sizeof(CFG_GET_FEATURES_STATE_RESPONSE)); do { if (status != AMT_STATUS_SUCCESS) { break; } CFG_GET_FEATURES_STATE_RESPONSE *tmp_response = (CFG_GET_FEATURES_STATE_RESPONSE *)readBuffer; GET_FEATURES_REDIRECTION_SESSION_STATUS redirectionState; GET_FEATURES_SYSTEM_DEFENSE_STATUS_RESPONSE systemDefenseState; GET_FEATURES_WEB_UI_STATUS_RESPONSE webUIState; switch (requestID) { case REDIRECTION_SESSION: redirectionState = tmp_response->Data.rs; requestStatus[0] = redirectionState.SolOpen; requestStatus[1] = redirectionState.IderOpen; break; case SYSTEM_DEFENSE: systemDefenseState = tmp_response->Data.sd; requestStatus[0] = systemDefenseState.SystemDefenseActivated; break; case WEB_UI: webUIState = tmp_response->Data.webUI; requestStatus[0] = webUIState.WebUiEnabled; break; } } while (0); if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Calls to GetLastHostResetReason Host interface command * Arguments: * reason Indicates whether the last host reason was because of remote control operation(0) * or other reason(1). (OUT) * remoteControlTimeStamp In case the reason was due to remote control then this field * indicates the timestamp of when the remote control command has been executed. * (The timestamp is the number of seconds since 1/1/1970) * * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::GetLastHostResetReason(UINT32 &reason, UINT32 &remoteControlTimeStamp) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(GET_LAST_HOST_RESET_REASON_HEADER); unsigned char command[command_size]; memcpy(command, &(GET_LAST_HOST_RESET_REASON_HEADER), sizeof(GET_LAST_HOST_RESET_REASON_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, GET_LAST_HOST_RESET_REASON_RESPONSE, sizeof(CFG_GET_LAST_HOST_RESET_REASON_RESPONSE)); do { if (status != AMT_STATUS_SUCCESS) { break; } CFG_GET_LAST_HOST_RESET_REASON_RESPONSE *tmp_response = (CFG_GET_LAST_HOST_RESET_REASON_RESPONSE *)readBuffer; reason = tmp_response->Reason; remoteControlTimeStamp = tmp_response->RemoteControlTimeStamp; } while (0); if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Calls to GetCurrentPowerPolicy Host interface command * Arguments: * policyName The power policy name. (OUT) * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::GetCurrentPowerPolicy(AMT_ANSI_STRING &policyName) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(GET_CURRENT_POWER_POLICY_HEADER); unsigned char command[command_size]; memcpy(command, &(GET_CURRENT_POWER_POLICY_HEADER), sizeof(GET_CURRENT_POWER_POLICY_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, GET_CURRENT_POWER_POLICY_RESPONSE, 0); do { if (status != AMT_STATUS_SUCCESS) { break; } CFG_GET_CURRENT_POWER_POLICY_RESPONSE *tmp_response = (CFG_GET_CURRENT_POWER_POLICY_RESPONSE *)readBuffer; status = _verifyCurrentPowerPolicy(*tmp_response); if (status != AMT_STATUS_SUCCESS) { break; } policyName.Length = tmp_response->PolicyName.Length; policyName.Buffer = (CHAR *)malloc(policyName.Length * sizeof(CHAR)); if (NULL == policyName.Buffer) { status = AMT_STATUS_INTERNAL_ERROR; } else { memcpy(policyName.Buffer, &(tmp_response->PolicyName.Buffer), policyName.Length * sizeof(CHAR)); } } while (0); if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Confirms the correctness of the GetCurrentPowerPolicy response message * Arguments: * response - reference to the response message * Return values: * AMT_STATUS_SUCCESS - on success * PTSDK_STATUS_INTERNAL_ERROR - on failure */ AMT_STATUS PTHICommand::_verifyCurrentPowerPolicy(const CFG_GET_CURRENT_POWER_POLICY_RESPONSE &response) { ULONG ByteCount = response.Header.Header.Length; if (ByteCount != (sizeof(CFG_GET_CURRENT_POWER_POLICY_RESPONSE) - sizeof(PTHI_MESSAGE_HEADER) - sizeof(CHAR *) + response.PolicyName.Length)) { return PTSDK_STATUS_INTERNAL_ERROR; } return AMT_STATUS_SUCCESS; } /* * Calls to GetLanInterfaceSttings Host interface command * Arguments: * interfaceSettings The interface to get the settings for. * lanSettings reference to a pre allocated struct which will hold the lan settings. (OUT) * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::GetLanInterfaceSettings(UINT32 interfaceSettings, LAN_SETTINGS &lanSettings) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(CFG_GET_LAN_INTERFACE_SETTINGS_REQUEST); unsigned char command[command_size]; memcpy(command, &(GET_LAN_INTERFACE_SETTINGS_HEADER), sizeof(GET_LAN_INTERFACE_SETTINGS_HEADER)); memcpy(command + sizeof(GET_LAN_INTERFACE_SETTINGS_HEADER), &(interfaceSettings), sizeof(UINT32)); AMT_STATUS status = _call(command, command_size, &readBuffer, GET_LAN_INTERFACE_SETTINGS_RESPONSE, sizeof(CFG_GET_LAN_INTERFACE_SETTINGS_RESPONSE)); do { if (status != AMT_STATUS_SUCCESS) { break; } CFG_GET_LAN_INTERFACE_SETTINGS_RESPONSE *tmp_response = (CFG_GET_LAN_INTERFACE_SETTINGS_RESPONSE *)readBuffer; lanSettings.Enabled = tmp_response->Enabled; lanSettings.Ipv4Address = tmp_response->Ipv4Address; lanSettings.DhcpEnabled = tmp_response->DhcpEnabled; lanSettings.DhcpIpMode = tmp_response->DhcpIpMode; lanSettings.LinkStatus = tmp_response->LinkStatus; memcpy(lanSettings.MacAddress, tmp_response->MacAddress, sizeof(tmp_response->MacAddress)); } while (0); if (readBuffer != NULL) { free(readBuffer); } return status; } /** * Gets the HECI driver version * Arguments: * heciVersion - pointewr to HECI_VERSION struct (out) * Return values: * AMT_STATUS_SUCCESS - on success * PTSDK_STATUS_INVALID_PARAM - on failure */ AMT_STATUS PTHICommand::GetHeciVersion(HECI_VERSION &heciVersion) { if (PTHIClient.GetHeciVersion(heciVersion)) { return AMT_STATUS_SUCCESS; } return AMT_STATUS_INTERNAL_ERROR; } /* * Calls to GetSecurityParameters Host interface command * Arguments: * tlsEnabled true if AMT on TLS mode. (OUT) * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::GetTLSEnabled(AMT_BOOLEAN &tlsEnabled) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(GET_SECURITY_PARAMETERS_HEADER); unsigned char command[command_size]; memcpy(command, &(GET_SECURITY_PARAMETERS_HEADER), sizeof(GET_SECURITY_PARAMETERS_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, GET_SECURITY_PARAMETERS_RESPONSE, sizeof(CFG_GET_SECURITY_PARAMETERS_RESPONSE)); do { if (status != AMT_STATUS_SUCCESS) { break; } CFG_GET_SECURITY_PARAMETERS_RESPONSE *tmp_response = (CFG_GET_SECURITY_PARAMETERS_RESPONSE *)readBuffer; tlsEnabled = tmp_response->TLSEnabled; } while (0); if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Calls to GetDNSSuffixList Host interface command * Arguments: * dnsSuffixList reference to list of DNS suffix strings. (OUT) * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::GetDNSSuffixList(std::list &dnsSuffixList) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(GET_DNS_SUFFIX_LIST_HEADER); unsigned char command[command_size]; memcpy(command, &(GET_DNS_SUFFIX_LIST_HEADER), sizeof(GET_DNS_SUFFIX_LIST_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, GET_DNS_SUFFIX_LIST_RESPONSE, 0); do { if (status != AMT_STATUS_SUCCESS) { break; } CFG_GET_DNS_SUFFIX_LIST_RESPONSE *tmp_response = (CFG_GET_DNS_SUFFIX_LIST_RESPONSE *)readBuffer; status = _verifyGetDNSSuffixList(*tmp_response); if (status != AMT_STATUS_SUCCESS) { break; } char *current = (char *)tmp_response->Data; while (current < (char *)tmp_response->Data + tmp_response->DataLength) { std::string dnsSuffix = current; if (dnsSuffix.length() > tmp_response->DataLength) { status = PTSDK_STATUS_INTERNAL_ERROR; break; } if (!dnsSuffix.empty()) { dnsSuffixList.push_back(dnsSuffix); } current += dnsSuffix.length() + 1; } } while (0); if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Confirms the correctness of the GetDNSSuffixList response message * Arguments: * response - reference to the response message * Return values: * AMT_STATUS_SUCCESS - on success * PTSDK_STATUS_INTERNAL_ERROR - on failure */ AMT_STATUS PTHICommand::_verifyGetDNSSuffixList(const CFG_GET_DNS_SUFFIX_LIST_RESPONSE &response) { ULONG ByteCount = response.Header.Header.Length; if (ByteCount != (sizeof(CFG_GET_DNS_SUFFIX_LIST_RESPONSE) - sizeof(PTHI_MESSAGE_HEADER) + response.DataLength)) { return PTSDK_STATUS_INTERNAL_ERROR; } return AMT_STATUS_SUCCESS; } /* * Calls to SetEnterpriseAccess Host interface command * Arguments: * Flags flags * HostIPAddress host IP address for enterprise access * EnterpriseAccess enterprise access mode * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::SetEnterpriseAccess(UINT8 Flags, UINT8 HostIPAddress[16], UINT8 EnterpriseAccess) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(CFG_SET_ENTERPRISE_ACCESS_REQUEST); unsigned char command[command_size]; memcpy(command, &(SET_ENTERPRISE_ACCESS_HEADER), sizeof(SET_ENTERPRISE_ACCESS_HEADER)); memcpy(command + sizeof(SET_ENTERPRISE_ACCESS_HEADER), &(Flags), sizeof(UINT8)); memcpy(command + sizeof(SET_ENTERPRISE_ACCESS_HEADER) + sizeof(UINT8), HostIPAddress, sizeof(HostIPAddress)); memcpy(command + sizeof(SET_ENTERPRISE_ACCESS_HEADER) + sizeof(UINT8) + sizeof(HostIPAddress), &(EnterpriseAccess), sizeof(UINT8)); AMT_STATUS status = _call(command, command_size, &readBuffer, SET_ENTERPRISE_ACCESS_RESPONSE, sizeof(CFG_SET_ENTERPRISE_ACCESS_RESPONSE)); if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Get FW last reset reason * Arguments: * reason - last FW reason * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::GetFWResetReason(UINT8 &MEResetReason) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(STATE_GET_AMT_STATE_REQUEST); unsigned char command[command_size]; memcpy(command, &(GET_AMT_STATE_HEADER), sizeof(GET_AMT_STATE_HEADER)); memcpy(command + sizeof(GET_AMT_STATE_HEADER), &(AMT_UUID_LINK_STATE), sizeof(AMT_UUID)); AMT_STATUS status = _call(command, command_size, &readBuffer, GET_AMT_STATE_RESPONSE, sizeof(STATE_GET_AMT_STATE_RESPONSE)); do { if (status != AMT_STATUS_SUCCESS) { break; } STATE_GET_AMT_STATE_RESPONSE *tmp_response = (STATE_GET_AMT_STATE_RESPONSE *)readBuffer; MEResetReason = tmp_response->StateData.LastMEResetReason; } while (0); if (readBuffer != NULL) { free(readBuffer); } return status; } /* Calls to OpenUserInitiatedConnection Host interface command * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::OpenUserInitiatedConnection() { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(OPEN_USER_INITIATED_CONNECTION_HEADER); unsigned char command[command_size]; memcpy(command, &(OPEN_USER_INITIATED_CONNECTION_HEADER), sizeof(OPEN_USER_INITIATED_CONNECTION_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, OPEN_USER_INITIATED_CONNECTION_RESPONSE, sizeof(CFG_OPEN_USER_INITIATED_CONNECTION_RESPONSE)); if (readBuffer != NULL) { free(readBuffer); } return status; } /* Calls to CloseUserInitiatedConnection Host interface command * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::CloseUserInitiatedConnection() { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(CLOSE_USER_INITIATED_CONNECTION_HEADER); unsigned char command[command_size]; memcpy(command, &(CLOSE_USER_INITIATED_CONNECTION_HEADER), sizeof(CLOSE_USER_INITIATED_CONNECTION_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, CLOSE_USER_INITIATED_CONNECTION_RESPONSE, sizeof(CFG_CLOSE_USER_INITIATED_CONNECTION_RESPONSE)); if (readBuffer != NULL) { free(readBuffer); } return status; } /* Calls to GetRemoteAccessConnectionStatus Host interface command * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::GetRemoteAccessConnectionStatus(REMOTE_ACCESS_STATUS &remoteAccessStatus) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(GET_REMOTE_ACCESS_CONNECTION_STATUS_HEADER); unsigned char command[command_size]; memcpy(command, &(GET_REMOTE_ACCESS_CONNECTION_STATUS_HEADER), sizeof(GET_REMOTE_ACCESS_CONNECTION_STATUS_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, GET_REMOTE_ACCESS_CONNECTION_STATUS_RESPONSE, 0); do { if (status != AMT_STATUS_SUCCESS) { break; } CFG_GET_REMOTE_ACCESS_CONNECTION_STATUS_RESPONSE *tmp_response = (CFG_GET_REMOTE_ACCESS_CONNECTION_STATUS_RESPONSE *)readBuffer; status = _verifyRemoteAccessConnectionStatus(*tmp_response); if (status != AMT_STATUS_SUCCESS) { break; } remoteAccessStatus.AmtNetworkConnectionStatus = tmp_response->AmtNetworkConnectionStatus; remoteAccessStatus.RemoteAccessConnectionStatus = tmp_response->RemoteAccessConnectionStatus; remoteAccessStatus.RemoteAccessConnectionTrigger = tmp_response->RemoteAccessConnectionTrigger; remoteAccessStatus.MpsHostname.Length = tmp_response->MpsHostname.Length; remoteAccessStatus.MpsHostname.Buffer = (CHAR *)malloc(remoteAccessStatus.MpsHostname.Length * sizeof(CHAR)); if (NULL == remoteAccessStatus.MpsHostname.Buffer) { status = AMT_STATUS_INTERNAL_ERROR; } else { memcpy(remoteAccessStatus.MpsHostname.Buffer, &(tmp_response->MpsHostname.Buffer), tmp_response->MpsHostname.Length * sizeof(CHAR)); } } while (0); if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Confirms the correctness of the GetRemoteAccessConnectionStatus response message * Arguments: * response - reference to the response message * Return values: * AMT_STATUS_SUCCESS - on success * PTSDK_STATUS_INTERNAL_ERROR - on failure */ AMT_STATUS PTHICommand::_verifyRemoteAccessConnectionStatus(const CFG_GET_REMOTE_ACCESS_CONNECTION_STATUS_RESPONSE &response) { ULONG ByteCount = response.Header.Header.Length; if (ByteCount != (sizeof(CFG_GET_REMOTE_ACCESS_CONNECTION_STATUS_RESPONSE) - sizeof(PTHI_MESSAGE_HEADER) - sizeof(CHAR *) + response.MpsHostname.Length)) { return PTSDK_STATUS_INTERNAL_ERROR; } return AMT_STATUS_SUCCESS; } /* * Calls to GenerateRngKey Host interface command * Arguments: * None * Return values: * AMT_STATUS_SUCCESS - or AMT_STATUS_IN_PROGRESS on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::GenerateRngKey() { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(GENERATE_RNG_SEED_HEADER); unsigned char command[command_size]; memcpy(command, &(GENERATE_RNG_SEED_HEADER), sizeof(GENERATE_RNG_SEED_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, GENERATE_RNG_SEED_RESPONSE, sizeof(CFG_GENERATE_RNG_SEED_RESPONSE)); if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Calls to GetRngSeedStatus Host interface command * Arguments: * rngStatus - reference to the pre-allocated structure * which will hold the result * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::GetRngSeedStatus(AMT_RNG_STATUS &rngStatus) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(GET_RNG_SEED_STATUS_HEADER); unsigned char command[command_size]; memcpy(command, &(GET_RNG_SEED_STATUS_HEADER), sizeof(GET_RNG_SEED_STATUS_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, GET_RNG_SEED_STATUS_RESPONSE, sizeof(CFG_GET_RNG_SEED_STATUS_RESPONSE)); CFG_GET_RNG_SEED_STATUS_RESPONSE *tmp_response = (CFG_GET_RNG_SEED_STATUS_RESPONSE *)readBuffer; rngStatus = tmp_response->RngStatus; if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Calls to ZeroTouchEnabled Host interface command * Arguments: * zeroTouchEnabled - reference to the pre-allocated structure * which will hold the result * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::GetZeroTouchEnabled(AMT_BOOLEAN &zeroTouchEnabled) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(GET_ZERO_TOUCH_ENABLED_HEADER); unsigned char command[command_size]; memcpy(command, &(GET_ZERO_TOUCH_ENABLED_HEADER), sizeof(GET_ZERO_TOUCH_ENABLED_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, GET_ZERO_TOUCH_ENABLED_RESPONSE, sizeof(CFG_GET_ZERO_TOUCH_ENABLED_RESPONSE)); CFG_GET_ZERO_TOUCH_ENABLED_RESPONSE *tmp_response = (CFG_GET_ZERO_TOUCH_ENABLED_RESPONSE *)readBuffer; zeroTouchEnabled = tmp_response->ZeroTouchEnabled; if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Calls to GetProvisioningTlsMode Host interface command * Arguments: * provisioningTlsMode - reference to the pre-allocated structure * which will hold the result * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::GetProvisioningTlsMode(AMT_PROVISIONING_TLS_MODE &provisioningTlsMode) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(GET_PROVISIONING_TLS_MODE_HEADER); unsigned char command[command_size]; memcpy(command, &(GET_PROVISIONING_TLS_MODE_HEADER), sizeof(GET_PROVISIONING_TLS_MODE_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, GET_PROVISIONING_TLS_MODE_RESPONSE, sizeof(CFG_GET_PROVISIONING_TLS_MODE_RESPONSE)); CFG_GET_PROVISIONING_TLS_MODE_RESPONSE *tmp_response = (CFG_GET_PROVISIONING_TLS_MODE_RESPONSE *)readBuffer; provisioningTlsMode = tmp_response->ProvisioningTlsMode; if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Calls to StartConfiguration Host interface command * Arguments: * None * Return values: * AMT_STATUS_SUCCESS - or AMT_STATUS_CERTIFICATE_NOT_READY on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::StartConfiguration() { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(START_CONFIGURATION_HEADER); unsigned char command[command_size]; memcpy(command, &(START_CONFIGURATION_HEADER), sizeof(START_CONFIGURATION_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, START_CONFIGURATION_RESPONSE, sizeof(CFG_START_CONFIGURATION_RESPONSE)); if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Calls to SetProvisioningServerOTP Host interface command * Arguments: * passwordOTP AMT_ANSI_STRING structure of OTP password * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::SetProvisioningServerOTP(AMT_ANSI_STRING passwordOTP) { if (NULL == passwordOTP.Buffer) { return PTSDK_STATUS_INVALID_PARAM; } UINT8 *readBuffer = NULL; UINT32 msgLength = sizeof(passwordOTP.Length) + (passwordOTP.Length * sizeof(CHAR)); PTHI_MESSAGE_HEADER SET_PROVISIONING_SERVER_OTP_HEADER = { {AMT_MAJOR_VERSION, AMT_MINOR_VERSION}, 0, {{SET_PROVISIONING_SERVER_OTP_REQUEST}}, msgLength }; const UINT32 command_size = sizeof(SET_PROVISIONING_SERVER_OTP_HEADER) + msgLength; unsigned char *command; command = (unsigned char *)malloc(command_size); if (NULL == command) { return PTSDK_STATUS_INTERNAL_ERROR; } memcpy(command, &SET_PROVISIONING_SERVER_OTP_HEADER, sizeof(SET_PROVISIONING_SERVER_OTP_HEADER)); memcpy(command + sizeof(SET_PROVISIONING_SERVER_OTP_HEADER), &(passwordOTP.Length), sizeof(passwordOTP.Length)); memcpy(command + sizeof(SET_PROVISIONING_SERVER_OTP_HEADER) + sizeof(passwordOTP.Length), passwordOTP.Buffer, passwordOTP.Length); AMT_STATUS status = _call(command, command_size, &readBuffer, SET_PROVISIONING_SERVER_OTP_RESPONSE, sizeof(CFG_SET_PROVISIONING_SERVER_OTP_RESPONSE)); if (NULL != command) { free(command); } if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Calls to SetDnsSuffix Host interface command * Arguments: * dnsSuffix AMT_ANSI_STRING structure of DNS suffix * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::SetDnsSuffix(AMT_ANSI_STRING dnsSuffix) { if (NULL == dnsSuffix.Buffer) { return PTSDK_STATUS_INVALID_PARAM; } UINT8 *readBuffer = NULL; UINT32 msgLength = sizeof(dnsSuffix.Length) + (dnsSuffix.Length * sizeof(CHAR)); PTHI_MESSAGE_HEADER SET_DNS_SUFFIX_HEADER = { {AMT_MAJOR_VERSION, AMT_MINOR_VERSION}, 0, {{SET_DNS_SUFFIX_REQUEST}}, msgLength }; const UINT32 command_size = sizeof(SET_DNS_SUFFIX_HEADER) + msgLength; unsigned char *command; command = (unsigned char *)malloc(command_size); if (NULL == command) { return PTSDK_STATUS_INTERNAL_ERROR; } memcpy(command, &SET_DNS_SUFFIX_HEADER, sizeof(SET_DNS_SUFFIX_HEADER)); memcpy(command + sizeof(SET_DNS_SUFFIX_HEADER), &(dnsSuffix.Length), sizeof(dnsSuffix.Length)); memcpy(command + sizeof(SET_DNS_SUFFIX_HEADER) + sizeof(dnsSuffix.Length), dnsSuffix.Buffer, dnsSuffix.Length); AMT_STATUS status = _call(command, command_size, &readBuffer, SET_DNS_SUFFIX_RESPONSE, sizeof(CFG_SET_DNS_SUFFIX_RESPONSE)); if (NULL != command) { free(command); } if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Calls to EnumerateHashHandles Host interface command * Arguments: * hashHandles - reference to the pre-allocated structure * which will hold the result * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::EnumerateHashHandles(AMT_HASH_HANDLES &hashHandles) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(ENUMERATE_HASH_HANDLES_HEADER); unsigned char command[command_size]; memcpy(command, &(ENUMERATE_HASH_HANDLES_HEADER), sizeof(ENUMERATE_HASH_HANDLES_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, ENUMERATE_HASH_HANDLES_RESPONSE, 0); do { if (status != AMT_STATUS_SUCCESS) { break; } CFG_GET_HASH_HANDLES_RESPONSE *tmp_response = (CFG_GET_HASH_HANDLES_RESPONSE *)readBuffer; status = _verifyHashHandles(*tmp_response); if (status != AMT_STATUS_SUCCESS) { break; } memset(hashHandles.Handles, 0, sizeof(UINT32) * CERT_HASH_MAX_NUMBER); hashHandles.Length = tmp_response->HashHandles.Length; if (CERT_HASH_MAX_NUMBER < hashHandles.Length) { status = PTSDK_STATUS_INTERNAL_ERROR; break; } memcpy(hashHandles.Handles, tmp_response->HashHandles.Handles, sizeof(UINT32) * hashHandles.Length); } while (0); if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Confirms the correctness of the EnumerateHashHandles response message * Arguments: * response - reference to the response message * Return values: * AMT_STATUS_SUCCESS - on success * PTSDK_STATUS_INTERNAL_ERROR - on failure */ AMT_STATUS PTHICommand::_verifyHashHandles(const CFG_GET_HASH_HANDLES_RESPONSE &response) { ULONG ByteCount = response.Header.Header.Length; if (ByteCount != sizeof(AMT_STATUS) + sizeof(response.HashHandles.Length) + (sizeof(UINT32) * response.HashHandles.Length)) { return PTSDK_STATUS_INTERNAL_ERROR; } return AMT_STATUS_SUCCESS; } /* * Calls to GetCertificateHashEntry Host interface command * Arguments: * passwordOTP AMT_ANSI_STRING structure of DNS suffix * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::GetCertificateHashEntry(UINT32 hashHandle, CERTHASH_ENTRY &hashEntry) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(CFG_GET_CERTHASH_ENTRY_REQUEST); unsigned char command[command_size]; memcpy(command, &(GET_CERTHASH_ENTRY_HEADER), sizeof(GET_CERTHASH_ENTRY_HEADER)); memcpy(command + sizeof(GET_CERTHASH_ENTRY_HEADER), &(hashHandle), sizeof(hashHandle)); AMT_STATUS status = _call(command, command_size, &readBuffer, GET_CERTHASH_ENTRY_RESPONSE, 0); do { if (status != AMT_STATUS_SUCCESS) { break; } CFG_GET_CERTHASH_ENTRY_RESPONSE *tmp_response = (CFG_GET_CERTHASH_ENTRY_RESPONSE *)readBuffer; status = _verifyGetCertificateHashEntry(*tmp_response); if (status != AMT_STATUS_SUCCESS) { break; } hashEntry.IsActive = tmp_response->Hash.IsActive; hashEntry.IsDefault = tmp_response->Hash.IsDefault; hashEntry.Name.Length = tmp_response->Hash.Name.Length; hashEntry.HashAlgorithm = tmp_response->Hash.HashAlgorithm; memcpy(hashEntry.CertificateHash, tmp_response->Hash.CertificateHash, sizeof(tmp_response->Hash.CertificateHash)); hashEntry.Name.Buffer = (CHAR *)malloc(hashEntry.Name.Length * sizeof(CHAR)); if (NULL == hashEntry.Name.Buffer) { status = PTSDK_STATUS_INTERNAL_ERROR; break; } memcpy(hashEntry.Name.Buffer, &(tmp_response->Hash.Name.Buffer), hashEntry.Name.Length * sizeof(CHAR)); } while (0); if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Confirms the correctness of the GetCertificateHashEntry response message * Arguments: * response - reference to the response message * Return values: * AMT_STATUS_SUCCESS - on success * PTSDK_STATUS_INTERNAL_ERROR - on failure */ AMT_STATUS PTHICommand::_verifyGetCertificateHashEntry(const CFG_GET_CERTHASH_ENTRY_RESPONSE &response) { ULONG ByteCount = response.Header.Header.Length; if (ByteCount != (sizeof(CFG_GET_CERTHASH_ENTRY_RESPONSE) - sizeof(PTHI_MESSAGE_HEADER) - sizeof(CHAR *) + response.Hash.Name.Length)) { return PTSDK_STATUS_INTERNAL_ERROR; } return AMT_STATUS_SUCCESS; } /* * Calls to GetDnsSuffix Host interface command * Arguments: * dnsSuffix - reference to the pre-allocated structure * which will hold the result * Return values: * AMT_STATUS_SUCCESS - on success * appropriate error value defined in StatusCodeDefinitions.h - on failure */ AMT_STATUS PTHICommand::GetDnsSuffix(AMT_ANSI_STRING &dnsSuffix) { UINT8 *readBuffer = NULL; const UINT32 command_size = sizeof(GET_PKI_FQDN_SUFFIX_HEADER); unsigned char command[command_size]; memcpy(command, &(GET_PKI_FQDN_SUFFIX_HEADER), sizeof(GET_PKI_FQDN_SUFFIX_HEADER)); AMT_STATUS status = _call(command, command_size, &readBuffer, GET_PKI_FQDN_SUFFIX_RESPONSE, 0); do { if (status != AMT_STATUS_SUCCESS) { break; } CFG_GET_PKI_FQDN_SUFFIX_RESPONSE *tmp_response = (CFG_GET_PKI_FQDN_SUFFIX_RESPONSE *)readBuffer; status = _verifyGetDnsSuffix(*tmp_response); if (status != AMT_STATUS_SUCCESS) { break; } dnsSuffix.Length = tmp_response->Suffix.Length; dnsSuffix.Buffer = (CHAR *)malloc(dnsSuffix.Length * sizeof(CHAR)); if (NULL == dnsSuffix.Buffer) { status = PTSDK_STATUS_INTERNAL_ERROR; break; } memcpy(dnsSuffix.Buffer, &(tmp_response->Suffix.Buffer), dnsSuffix.Length * sizeof(CHAR)); } while (0); if (readBuffer != NULL) { free(readBuffer); } return status; } /* * Confirms the correctness of the GetDnsSuffix response message * Arguments: * response - reference to the response message * Return values: * AMT_STATUS_SUCCESS - on success * PTSDK_STATUS_INTERNAL_ERROR - on failure */ AMT_STATUS PTHICommand::_verifyGetDnsSuffix(const CFG_GET_PKI_FQDN_SUFFIX_RESPONSE &response) { ULONG ByteCount = response.Header.Header.Length; if (ByteCount != sizeof(AMT_STATUS) + sizeof(response.Suffix.Length) + response.Suffix.Length * sizeof(CHAR)) { return PTSDK_STATUS_INTERNAL_ERROR; } return AMT_STATUS_SUCCESS; }