xref: /titanic_41/usr/src/cmd/lms/heci/PTHICommand.cpp (revision 835ee2195df075073d2670eb95a6eab413d6c789)
1 /*******************************************************************************
2  * Copyright (C) 2004-2008 Intel Corp. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *  - Redistributions of source code must retain the above copyright notice,
8  *    this list of conditions and the following disclaimer.
9  *
10  *  - Redistributions in binary form must reproduce the above copyright notice,
11  *    this list of conditions and the following disclaimer in the documentation
12  *    and/or other materials provided with the distribution.
13  *
14  *  - Neither the name of Intel Corp. nor the names of its
15  *    contributors may be used to endorse or promote products derived from this
16  *    software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  *******************************************************************************/
30 
31 //----------------------------------------------------------------------------
32 //
33 //  File:       PTHICommand.cpp
34 //
35 //----------------------------------------------------------------------------
36 
37 #ifdef HAVE_CONFIG_H
38 #include "config.h"
39 #endif
40 #include <cstdio>
41 #include <cstdlib>
42 #include "PTHICommand.h"
43 
44 
45 PTHICommand::PTHICommand(bool verbose, unsigned long sendTimeout) :
46 PTHIClient(HECI_PTHI, verbose),
47 m_sendTimeout(sendTimeout)
48 {
49 }
50 
51 PTHICommand::~PTHICommand(void)
52 {
53 }
54 
55 AMT_STATUS PTHICommand::_call(const unsigned char *command, UINT32 command_size, UINT8 **readBuffer, UINT32 rcmd, unsigned int expSize)
56 {
57 	UINT32 inBuffSize;
58 	UINT32 outBuffSize = 0;
59 
60 	inBuffSize = PTHIClient.GetBufferSize();
61 	*readBuffer = (UINT8 *)malloc(sizeof(UINT8) * inBuffSize);
62 	if (NULL == *readBuffer)
63 	{
64 		return PTSDK_STATUS_RESOURCES;
65 	}
66 	memset(*readBuffer, 0, inBuffSize);
67 
68 	int bytesWritten = PTHIClient.SendMessage(command, command_size, m_sendTimeout);
69 	if ((UINT32)bytesWritten != command_size)
70 	{
71 		return AMT_STATUS_INTERNAL_ERROR;
72 	}
73 	outBuffSize = PTHIClient.ReceiveMessage(*readBuffer, inBuffSize);
74 	if (0 == outBuffSize)
75 	{
76 		return PTHI_STATUS_EMPTY_RESPONSE;
77 	}
78 	AMT_STATUS status = ((PTHI_RESPONSE_MESSAGE_HEADER *)*readBuffer)->Status;
79 	if (status != AMT_STATUS_SUCCESS)
80 	{
81 		return status;
82 	}
83 	status = _verifyResponseHeader(rcmd, ((PTHI_RESPONSE_MESSAGE_HEADER *)*readBuffer)->Header, outBuffSize);
84 	if (status != AMT_STATUS_SUCCESS)
85 	{
86 		return status;
87 	}
88 	if ((expSize != 0) && (expSize != outBuffSize))
89 	{
90 		return PTSDK_STATUS_INTERNAL_ERROR;
91 	}
92 	return AMT_STATUS_SUCCESS;
93 }
94 
95 /*
96 * Confirms the correctness of the response message header
97 * and the response message size
98 * Arguments:
99 *	command	- appropriate Host interface command
100 *	response_header	- reference to the response message header
101 *	response_size	- value that holds the actual size of the
102 *                         response message
103 *	expected_size	- value that holds the expected size of the
104 *                         response message
105 * Return values:
106 *	AMT_STATUS_SUCCESS - on success
107 *	PTSDK_STATUS_INTERNAL_ERROR - on failure
108 */
109 AMT_STATUS PTHICommand::_verifyResponseHeader(
110 	const UINT32 command, const PTHI_MESSAGE_HEADER &response_header,
111 	UINT32 response_size)
112 {
113 	AMT_STATUS status = AMT_STATUS_SUCCESS;
114 
115 	if (response_size < sizeof(PTHI_RESPONSE_MESSAGE_HEADER)) {
116 		status = AMT_STATUS_INTERNAL_ERROR;
117 	} else if (response_size != (response_header.Length + sizeof(PTHI_MESSAGE_HEADER))) {
118 		status = AMT_STATUS_INTERNAL_ERROR;
119 	} else if (response_header.Command.cmd.val != command) {
120 		status = AMT_STATUS_INTERNAL_ERROR;
121 	} else if (response_header.Reserved != 0) {
122 		status = AMT_STATUS_INTERNAL_ERROR;
123 	} else if (response_header.Version.MajorNumber != AMT_MAJOR_VERSION
124 		|| response_header.Version.MinorNumber < AMT_MINOR_VERSION) {
125 			status = AMT_STATUS_INTERNAL_ERROR;
126 	}
127 
128 	return status;
129 }
130 
131 /*
132 * Confirms the correctness of the GetCodeVersions response message
133 * Arguments:
134 *	response - reference to the response message
135 * Return values:
136 *	AMT_STATUS_SUCCESS - on success
137 *	PTSDK_STATUS_INTERNAL_ERROR - on failure
138 */
139 AMT_STATUS PTHICommand::_verifyCodeVersions(
140 	const CFG_GET_CODE_VERSIONS_RESPONSE &response)
141 {
142 	AMT_STATUS status = AMT_STATUS_SUCCESS;
143 	UINT32 codeVerLen;
144 	UINT32 ptVerTypeCount;
145 	UINT32 len = 0;
146 	UINT32 i;
147 
148 	do {
149 		codeVerLen = response.Header.Header.Length - sizeof(AMT_STATUS);
150 		ptVerTypeCount = codeVerLen - sizeof(response.CodeVersions.BiosVersion)- sizeof(response.CodeVersions.VersionsCount);
151 		if (response.CodeVersions.VersionsCount != (ptVerTypeCount/sizeof(AMT_VERSION_TYPE)))
152 		{
153 			status = AMT_STATUS_INTERNAL_ERROR;
154 			break;
155 		}
156 
157 		for (i = 0; i < (response.CodeVersions.VersionsCount); i ++)
158 		{
159 			len = response.CodeVersions.Versions[i].Description.Length;
160 
161 			if (len > UNICODE_STRING_LEN)
162 			{
163 				status = AMT_STATUS_INTERNAL_ERROR;
164 				break;
165 			}
166 
167 			len = response.CodeVersions.Versions[i].Version.Length;
168 			if (response.CodeVersions.Versions[i].Version.String[len] != '\0' ||
169 				(len != strlen((CHAR *)(response.CodeVersions.Versions[i].Version.String))))
170 			{
171 				status = AMT_STATUS_INTERNAL_ERROR;
172 				break;
173 			}
174 		}
175 	} while (0);
176 
177 	return status;
178 }
179 
180 /*
181 * GetVersions response message PTHI command
182 * Arguments:
183 *	response - reference to the CODE_VERSIONS struct
184 * Return values:
185 *	AMT_STATUS_SUCCESS - on success
186 *	AMT_STATUS_INTERNAL_ERROR - on failure
187 */
188 AMT_STATUS PTHICommand::GetCodeVersions(CODE_VERSIONS &codeVersions)
189 {
190 	UINT8 *readBuffer = NULL;
191 	const UINT32 command_size = sizeof(GET_CODE_VERSION_HEADER);
192 	unsigned char command[command_size];
193 	memcpy(command, &(GET_CODE_VERSION_HEADER), sizeof(GET_CODE_VERSION_HEADER));
194 
195 	AMT_STATUS status = _call(command, command_size, &readBuffer, CODE_VERSIONS_RESPONSE, 0);
196 	do {
197 		if (status != AMT_STATUS_SUCCESS)
198 		{
199 			break;
200 		}
201 		CFG_GET_CODE_VERSIONS_RESPONSE *tmp_response = (CFG_GET_CODE_VERSIONS_RESPONSE *)readBuffer;
202 		status = _verifyCodeVersions(*tmp_response);
203 		if (status != AMT_STATUS_SUCCESS)
204 		{
205 			break;
206 		}
207 
208 		memcpy(&codeVersions, &(tmp_response->CodeVersions), sizeof(CODE_VERSIONS));
209 
210 	} while (0);
211 	if (readBuffer != NULL)
212 	{
213 		free(readBuffer);
214 	}
215 	return status;
216 }
217 
218 /*
219 * Calls to GetProvisioningMode Host interface command
220 * Arguments:
221 *	mode - reference to the pre-allocated structure
222 *       which will hold the result
223 * Return values:
224 *	AMT_STATUS_SUCCESS - on success
225 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
226 */
227 AMT_STATUS PTHICommand::GetProvisioningMode(CFG_PROVISIONING_MODE &mode)
228 {
229 	UINT8 *readBuffer = NULL;
230 	const UINT32 command_size = sizeof(GET_PROVISIONING_MODE_HEADER);
231 	unsigned char command[command_size];
232 	memcpy(command, &(GET_PROVISIONING_MODE_HEADER), sizeof(GET_PROVISIONING_MODE_HEADER));
233 
234 	AMT_STATUS status = _call(command, command_size, &readBuffer, PROVISIONING_MODE_RESPONSE, sizeof(CFG_GET_PROVISIONING_MODE_RESPONSE));
235 	do {
236 		if (status != AMT_STATUS_SUCCESS)
237 		{
238 			break;
239 		}
240 		CFG_GET_PROVISIONING_MODE_RESPONSE *tmp_response = (CFG_GET_PROVISIONING_MODE_RESPONSE *)readBuffer;
241 
242 		mode = tmp_response->ProvisioningMode;
243 
244 	} while (0);
245 	if (readBuffer != NULL)
246 	{
247 		free(readBuffer);
248 	}
249 	return status;
250 }
251 AMT_STATUS PTHICommand::GetProvisioningMode(CFG_PROVISIONING_MODE &mode, AMT_BOOLEAN &legacy)
252 {
253 	UINT8 *readBuffer = NULL;
254 	const UINT32 command_size = sizeof(GET_PROVISIONING_MODE_HEADER);
255 	unsigned char command[command_size];
256 	memcpy(command, &(GET_PROVISIONING_MODE_HEADER), sizeof(GET_PROVISIONING_MODE_HEADER));
257 
258 	AMT_STATUS status = _call(command, command_size, &readBuffer, PROVISIONING_MODE_RESPONSE, sizeof(CFG_GET_PROVISIONING_MODE_RESPONSE));
259 	do {
260 		if (status != AMT_STATUS_SUCCESS)
261 		{
262 			break;
263 		}
264 		CFG_GET_PROVISIONING_MODE_RESPONSE *tmp_response = (CFG_GET_PROVISIONING_MODE_RESPONSE *)readBuffer;
265 
266 		mode = tmp_response->ProvisioningMode;
267 		legacy = tmp_response->LegacyMode;
268 
269 	} while (0);
270 	if (readBuffer != NULL)
271 	{
272 		free(readBuffer);
273 	}
274 	return status;
275 }
276 
277 /*
278 * Calls to GetProvisioningState Host interface command
279 * Arguments:
280 *	state - reference to the pre-allocated structure
281 *       which will hold the result
282 * Return values:
283 *	AMT_STATUS_SUCCESS - on success
284 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
285 */
286 AMT_STATUS PTHICommand::GetProvisioningState(AMT_PROVISIONING_STATE &state)
287 {
288 	UINT8 *readBuffer = NULL;
289 	const UINT32 command_size = sizeof(GET_PROVISIONING_STATE_HEADER);
290 	unsigned char command[command_size];
291 	memcpy(command, &(GET_PROVISIONING_STATE_HEADER), sizeof(GET_PROVISIONING_STATE_HEADER));
292 
293 	AMT_STATUS status = _call(command, command_size, &readBuffer, PROVISIONING_STATE_RESPONSE, sizeof(CFG_GET_PROVISIONING_STATE_RESPONSE));
294 	do {
295 		if (status != AMT_STATUS_SUCCESS)
296 		{
297 			break;
298 		}
299 		CFG_GET_PROVISIONING_STATE_RESPONSE *tmp_response = (CFG_GET_PROVISIONING_STATE_RESPONSE *)readBuffer;
300 
301 		state = tmp_response->ProvisioningState;
302 
303 	} while (0);
304 	if (readBuffer != NULL)
305 	{
306 		free(readBuffer);
307 	}
308 	return status;
309 }
310 
311 /*
312 * Calls to GetFeatureState Host interface command
313 * Arguments:
314 *	requestID Indicates what feature status to query:
315 *		0	Redirection Sessions Status
316 *		1	System Defense Status
317 *		2	WebUI Status
318 *  requestStatus The requested feature state(the size depand on the requestID).(OUT)
319 *
320 * Return values:
321 *	AMT_STATUS_SUCCESS - on success
322 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
323 */
324 AMT_STATUS PTHICommand::GetFeaturesState(UINT32 requestID, AMT_BOOLEAN (&requestStatus)[2])
325 {
326 	UINT8 *readBuffer = NULL;
327 	const UINT32 command_size = sizeof(CFG_GET_FEATURES_STATE_REQUEST);
328 	unsigned char command[command_size];
329 
330 	memcpy(command, &GET_FEATURES_STATE_HEADER, sizeof(GET_FEATURES_STATE_HEADER));
331 	memcpy(command + sizeof(GET_FEATURES_STATE_HEADER), &(requestID), sizeof(UINT32));
332 
333 	AMT_STATUS status = _call(command, command_size, &readBuffer, GET_FEATURES_STATE_RESPONSE, sizeof(CFG_GET_FEATURES_STATE_RESPONSE));
334 	do {
335 		if (status != AMT_STATUS_SUCCESS)
336 		{
337 			break;
338 		}
339 		CFG_GET_FEATURES_STATE_RESPONSE *tmp_response = (CFG_GET_FEATURES_STATE_RESPONSE *)readBuffer;
340 
341 		GET_FEATURES_REDIRECTION_SESSION_STATUS redirectionState;
342 		GET_FEATURES_SYSTEM_DEFENSE_STATUS_RESPONSE systemDefenseState;
343 		GET_FEATURES_WEB_UI_STATUS_RESPONSE webUIState;
344 		switch (requestID)
345 		{
346 		case REDIRECTION_SESSION:
347 			redirectionState = tmp_response->Data.rs;
348 			requestStatus[0] = redirectionState.SolOpen;
349 			requestStatus[1] = redirectionState.IderOpen;
350 			break;
351 
352 		case SYSTEM_DEFENSE:
353 			systemDefenseState = tmp_response->Data.sd;
354 			requestStatus[0] = systemDefenseState.SystemDefenseActivated;
355 			break;
356 
357 		case WEB_UI:
358 			webUIState = tmp_response->Data.webUI;
359 			requestStatus[0] = webUIState.WebUiEnabled;
360 			break;
361 		}
362 	} while (0);
363 	if (readBuffer != NULL)
364 	{
365 		free(readBuffer);
366 	}
367 	return status;
368 }
369 
370 /*
371 * Calls to GetLastHostResetReason Host interface command
372 * Arguments:
373 *	reason Indicates whether the last host reason was because of remote control operation(0)
374 *		or other reason(1). (OUT)
375 *  remoteControlTimeStamp In case the reason was due to remote control then this field
376 *		indicates the timestamp of when the remote control command has been executed.
377 *		(The timestamp is the number of seconds since 1/1/1970)
378 *
379 * Return values:
380 *	AMT_STATUS_SUCCESS - on success
381 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
382 */
383 AMT_STATUS PTHICommand::GetLastHostResetReason(UINT32 &reason, UINT32 &remoteControlTimeStamp)
384 {
385 	UINT8 *readBuffer = NULL;
386 	const UINT32 command_size = sizeof(GET_LAST_HOST_RESET_REASON_HEADER);
387 	unsigned char command[command_size];
388 	memcpy(command, &(GET_LAST_HOST_RESET_REASON_HEADER), sizeof(GET_LAST_HOST_RESET_REASON_HEADER));
389 
390 	AMT_STATUS status = _call(command, command_size, &readBuffer, GET_LAST_HOST_RESET_REASON_RESPONSE, sizeof(CFG_GET_LAST_HOST_RESET_REASON_RESPONSE));
391 	do {
392 		if (status != AMT_STATUS_SUCCESS)
393 		{
394 			break;
395 		}
396 		CFG_GET_LAST_HOST_RESET_REASON_RESPONSE *tmp_response = (CFG_GET_LAST_HOST_RESET_REASON_RESPONSE *)readBuffer;
397 
398 		reason = tmp_response->Reason;
399 		remoteControlTimeStamp = tmp_response->RemoteControlTimeStamp;
400 
401 	} while (0);
402 	if (readBuffer != NULL)
403 	{
404 		free(readBuffer);
405 	}
406 	return status;
407 }
408 
409 /*
410 * Calls to GetCurrentPowerPolicy Host interface command
411 * Arguments:
412 *	 policyName The power policy name. (OUT)
413 * Return values:
414 *	AMT_STATUS_SUCCESS - on success
415 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
416 */
417 AMT_STATUS PTHICommand::GetCurrentPowerPolicy(AMT_ANSI_STRING &policyName)
418 {
419 	UINT8 *readBuffer = NULL;
420 	const UINT32 command_size = sizeof(GET_CURRENT_POWER_POLICY_HEADER);
421 	unsigned char command[command_size];
422 	memcpy(command, &(GET_CURRENT_POWER_POLICY_HEADER), sizeof(GET_CURRENT_POWER_POLICY_HEADER));
423 
424 	AMT_STATUS status = _call(command, command_size, &readBuffer, GET_CURRENT_POWER_POLICY_RESPONSE, 0);
425 	do {
426 		if (status != AMT_STATUS_SUCCESS)
427 		{
428 			break;
429 		}
430 		CFG_GET_CURRENT_POWER_POLICY_RESPONSE *tmp_response = (CFG_GET_CURRENT_POWER_POLICY_RESPONSE *)readBuffer;
431 		status = _verifyCurrentPowerPolicy(*tmp_response);
432 		if (status != AMT_STATUS_SUCCESS)
433 		{
434 			break;
435 		}
436 
437 		policyName.Length = tmp_response->PolicyName.Length;
438 		policyName.Buffer = (CHAR *)malloc(policyName.Length * sizeof(CHAR));
439 		if (NULL == policyName.Buffer) {
440 			status = AMT_STATUS_INTERNAL_ERROR;
441 		} else {
442 			memcpy(policyName.Buffer, &(tmp_response->PolicyName.Buffer),
443 			       policyName.Length * sizeof(CHAR));
444 		}
445 	} while (0);
446 	if (readBuffer != NULL)
447 	{
448 		free(readBuffer);
449 	}
450 	return status;
451 }
452 
453 /*
454 * Confirms the correctness of the GetCurrentPowerPolicy response message
455 * Arguments:
456 *	response - reference to the response message
457 * Return values:
458 *	AMT_STATUS_SUCCESS - on success
459 *	PTSDK_STATUS_INTERNAL_ERROR - on failure
460 */
461 AMT_STATUS PTHICommand::_verifyCurrentPowerPolicy(const CFG_GET_CURRENT_POWER_POLICY_RESPONSE &response)
462 {
463 	ULONG ByteCount = response.Header.Header.Length;
464 	if (ByteCount != (sizeof(CFG_GET_CURRENT_POWER_POLICY_RESPONSE)
465 	                  - sizeof(PTHI_MESSAGE_HEADER) - sizeof(CHAR *)
466 	                  + response.PolicyName.Length))
467 	{
468 		return PTSDK_STATUS_INTERNAL_ERROR;
469 	}
470 	return AMT_STATUS_SUCCESS;
471 }
472 
473 /*
474 * Calls to GetLanInterfaceSttings Host interface command
475 * Arguments:
476 *	 interfaceSettings The interface to get the settings for.
477 *	 lanSettings reference to a pre allocated struct which will hold the lan settings. (OUT)
478 * Return values:
479 *	AMT_STATUS_SUCCESS - on success
480 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
481 */
482 AMT_STATUS PTHICommand::GetLanInterfaceSettings(UINT32 interfaceSettings, LAN_SETTINGS &lanSettings)
483 {
484 	UINT8 *readBuffer = NULL;
485 	const UINT32 command_size = sizeof(CFG_GET_LAN_INTERFACE_SETTINGS_REQUEST);
486 	unsigned char command[command_size];
487 
488 	memcpy(command, &(GET_LAN_INTERFACE_SETTINGS_HEADER), sizeof(GET_LAN_INTERFACE_SETTINGS_HEADER));
489 	memcpy(command + sizeof(GET_LAN_INTERFACE_SETTINGS_HEADER),
490 	       &(interfaceSettings), sizeof(UINT32));
491 
492 	AMT_STATUS status = _call(command, command_size, &readBuffer, GET_LAN_INTERFACE_SETTINGS_RESPONSE, sizeof(CFG_GET_LAN_INTERFACE_SETTINGS_RESPONSE));
493 	do {
494 		if (status != AMT_STATUS_SUCCESS)
495 		{
496 			break;
497 		}
498 		CFG_GET_LAN_INTERFACE_SETTINGS_RESPONSE *tmp_response = (CFG_GET_LAN_INTERFACE_SETTINGS_RESPONSE *)readBuffer;
499 
500 		lanSettings.Enabled = tmp_response->Enabled;
501 		lanSettings.Ipv4Address = tmp_response->Ipv4Address;
502 		lanSettings.DhcpEnabled = tmp_response->DhcpEnabled;
503 		lanSettings.DhcpIpMode = tmp_response->DhcpIpMode;
504 		lanSettings.LinkStatus = tmp_response->LinkStatus;
505 		memcpy(lanSettings.MacAddress, tmp_response->MacAddress, sizeof(tmp_response->MacAddress));
506 
507 	} while (0);
508 	if (readBuffer != NULL)
509 	{
510 		free(readBuffer);
511 	}
512 	return status;
513 }
514 
515 /**
516 * Gets the HECI driver version
517 * Arguments:
518 *	heciVersion - pointewr to HECI_VERSION struct (out)
519 * Return values:
520 *	AMT_STATUS_SUCCESS - on success
521 *	PTSDK_STATUS_INVALID_PARAM - on failure
522 */
523 AMT_STATUS PTHICommand::GetHeciVersion(HECI_VERSION &heciVersion)
524 {
525 	if (PTHIClient.GetHeciVersion(heciVersion)) {
526 		return AMT_STATUS_SUCCESS;
527 	}
528 	return AMT_STATUS_INTERNAL_ERROR;
529 }
530 
531 /*
532 * Calls to GetSecurityParameters Host interface command
533 * Arguments:
534 *	tlsEnabled true if AMT on TLS mode. (OUT)
535 * Return values:
536 *	AMT_STATUS_SUCCESS - on success
537 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
538 */
539 AMT_STATUS PTHICommand::GetTLSEnabled(AMT_BOOLEAN &tlsEnabled)
540 {
541 	UINT8 *readBuffer = NULL;
542 	const UINT32 command_size = sizeof(GET_SECURITY_PARAMETERS_HEADER);
543 	unsigned char command[command_size];
544 	memcpy(command, &(GET_SECURITY_PARAMETERS_HEADER), sizeof(GET_SECURITY_PARAMETERS_HEADER));
545 
546 	AMT_STATUS status = _call(command, command_size, &readBuffer, GET_SECURITY_PARAMETERS_RESPONSE, sizeof(CFG_GET_SECURITY_PARAMETERS_RESPONSE));
547 	do {
548 		if (status != AMT_STATUS_SUCCESS)
549 		{
550 			break;
551 		}
552 		CFG_GET_SECURITY_PARAMETERS_RESPONSE *tmp_response = (CFG_GET_SECURITY_PARAMETERS_RESPONSE *)readBuffer;
553 
554 		tlsEnabled = tmp_response->TLSEnabled;
555 
556 	} while (0);
557 	if (readBuffer != NULL)
558 	{
559 		free(readBuffer);
560 	}
561 	return status;
562 }
563 
564 /*
565 * Calls to GetDNSSuffixList Host interface command
566 * Arguments:
567 *	 dnsSuffixList reference to list of DNS suffix strings. (OUT)
568 * Return values:
569 *	AMT_STATUS_SUCCESS - on success
570 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
571 */
572 AMT_STATUS PTHICommand::GetDNSSuffixList(std::list<std::string> &dnsSuffixList)
573 {
574 	UINT8 *readBuffer = NULL;
575 	const UINT32 command_size = sizeof(GET_DNS_SUFFIX_LIST_HEADER);
576 	unsigned char command[command_size];
577 	memcpy(command, &(GET_DNS_SUFFIX_LIST_HEADER), sizeof(GET_DNS_SUFFIX_LIST_HEADER));
578 
579 	AMT_STATUS status = _call(command, command_size, &readBuffer, GET_DNS_SUFFIX_LIST_RESPONSE, 0);
580 	do {
581 		if (status != AMT_STATUS_SUCCESS)
582 		{
583 			break;
584 		}
585 		CFG_GET_DNS_SUFFIX_LIST_RESPONSE *tmp_response = (CFG_GET_DNS_SUFFIX_LIST_RESPONSE *)readBuffer;
586 		status = _verifyGetDNSSuffixList(*tmp_response);
587 		if (status != AMT_STATUS_SUCCESS)
588 		{
589 			break;
590 		}
591 
592 		char *current = (char *)tmp_response->Data;
593 		while (current < (char *)tmp_response->Data + tmp_response->DataLength)
594 		{
595 			std::string dnsSuffix = current;
596 			if (dnsSuffix.length() > tmp_response->DataLength)
597 			{
598 				status = PTSDK_STATUS_INTERNAL_ERROR;
599 				break;
600 			}
601 			if (!dnsSuffix.empty())
602 			{
603 				dnsSuffixList.push_back(dnsSuffix);
604 			}
605 			current += dnsSuffix.length() + 1;
606 		}
607 	} while (0);
608 
609 	if (readBuffer != NULL)
610 	{
611 		free(readBuffer);
612 	}
613 	return status;
614 }
615 
616 /*
617 * Confirms the correctness of the GetDNSSuffixList response message
618 * Arguments:
619 *	response - reference to the response message
620 * Return values:
621 *	AMT_STATUS_SUCCESS - on success
622 *	PTSDK_STATUS_INTERNAL_ERROR - on failure
623 */
624 AMT_STATUS PTHICommand::_verifyGetDNSSuffixList(const CFG_GET_DNS_SUFFIX_LIST_RESPONSE &response)
625 {
626 	ULONG ByteCount = response.Header.Header.Length;
627 	if (ByteCount != (sizeof(CFG_GET_DNS_SUFFIX_LIST_RESPONSE)
628 	                  - sizeof(PTHI_MESSAGE_HEADER)
629 	                  + response.DataLength))
630 	{
631 		return PTSDK_STATUS_INTERNAL_ERROR;
632 	}
633 	return AMT_STATUS_SUCCESS;
634 }
635 
636 /*
637 * Calls to SetEnterpriseAccess Host interface command
638 * Arguments:
639 *	Flags flags
640 *	HostIPAddress host IP address for enterprise access
641 *	EnterpriseAccess enterprise access mode
642 * Return values:
643 *	AMT_STATUS_SUCCESS - on success
644 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
645 */
646 AMT_STATUS PTHICommand::SetEnterpriseAccess(UINT8 Flags, UINT8 HostIPAddress[16], UINT8 EnterpriseAccess)
647 {
648 	UINT8 *readBuffer = NULL;
649 	const UINT32 command_size = sizeof(CFG_SET_ENTERPRISE_ACCESS_REQUEST);
650 	unsigned char command[command_size];
651 
652 	memcpy(command, &(SET_ENTERPRISE_ACCESS_HEADER), sizeof(SET_ENTERPRISE_ACCESS_HEADER));
653 	memcpy(command + sizeof(SET_ENTERPRISE_ACCESS_HEADER), &(Flags), sizeof(UINT8));
654 	memcpy(command + sizeof(SET_ENTERPRISE_ACCESS_HEADER) + sizeof(UINT8), HostIPAddress, sizeof(HostIPAddress));
655 	memcpy(command + sizeof(SET_ENTERPRISE_ACCESS_HEADER) + sizeof(UINT8) + sizeof(HostIPAddress), &(EnterpriseAccess), sizeof(UINT8));
656 
657 	AMT_STATUS status = _call(command, command_size, &readBuffer, SET_ENTERPRISE_ACCESS_RESPONSE, sizeof(CFG_SET_ENTERPRISE_ACCESS_RESPONSE));
658 
659 	if (readBuffer != NULL)
660 	{
661 		free(readBuffer);
662 	}
663 	return status;
664 }
665 
666 /*
667 * Get FW last reset reason
668 * Arguments:
669 *	reason - last FW reason
670 * Return values:
671 *	AMT_STATUS_SUCCESS - on success
672 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
673 */
674 AMT_STATUS PTHICommand::GetFWResetReason(UINT8 &MEResetReason)
675 {
676 	UINT8 *readBuffer = NULL;
677 	const UINT32 command_size = sizeof(STATE_GET_AMT_STATE_REQUEST);
678 	unsigned char command[command_size];
679 	memcpy(command, &(GET_AMT_STATE_HEADER), sizeof(GET_AMT_STATE_HEADER));
680 	memcpy(command + sizeof(GET_AMT_STATE_HEADER), &(AMT_UUID_LINK_STATE), sizeof(AMT_UUID));
681 
682 	AMT_STATUS status = _call(command, command_size, &readBuffer, GET_AMT_STATE_RESPONSE, sizeof(STATE_GET_AMT_STATE_RESPONSE));
683 	do {
684 		if (status != AMT_STATUS_SUCCESS)
685 		{
686 			break;
687 		}
688 		STATE_GET_AMT_STATE_RESPONSE *tmp_response = (STATE_GET_AMT_STATE_RESPONSE *)readBuffer;
689 
690 		MEResetReason = tmp_response->StateData.LastMEResetReason;
691 
692 	} while (0);
693 	if (readBuffer != NULL)
694 	{
695 		free(readBuffer);
696 	}
697 	return status;
698 }
699 
700 /* Calls to OpenUserInitiatedConnection Host interface command
701 * Return values:
702 *	AMT_STATUS_SUCCESS - on success
703 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
704 */
705 AMT_STATUS PTHICommand::OpenUserInitiatedConnection()
706 {
707 	UINT8 *readBuffer = NULL;
708 	const UINT32 command_size = sizeof(OPEN_USER_INITIATED_CONNECTION_HEADER);
709 	unsigned char command[command_size];
710 	memcpy(command, &(OPEN_USER_INITIATED_CONNECTION_HEADER), sizeof(OPEN_USER_INITIATED_CONNECTION_HEADER));
711 
712 	AMT_STATUS status = _call(command, command_size, &readBuffer, OPEN_USER_INITIATED_CONNECTION_RESPONSE, sizeof(CFG_OPEN_USER_INITIATED_CONNECTION_RESPONSE));
713 
714 	if (readBuffer != NULL)
715 	{
716 		free(readBuffer);
717 	}
718 	return status;
719 }
720 
721 /* Calls to CloseUserInitiatedConnection Host interface command
722 * Return values:
723 *	AMT_STATUS_SUCCESS - on success
724 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
725 */
726 AMT_STATUS PTHICommand::CloseUserInitiatedConnection()
727 {
728 	UINT8 *readBuffer = NULL;
729 	const UINT32 command_size = sizeof(CLOSE_USER_INITIATED_CONNECTION_HEADER);
730 	unsigned char command[command_size];
731 	memcpy(command, &(CLOSE_USER_INITIATED_CONNECTION_HEADER), sizeof(CLOSE_USER_INITIATED_CONNECTION_HEADER));
732 
733 	AMT_STATUS status = _call(command, command_size, &readBuffer, CLOSE_USER_INITIATED_CONNECTION_RESPONSE, sizeof(CFG_CLOSE_USER_INITIATED_CONNECTION_RESPONSE));
734 
735 	if (readBuffer != NULL)
736 	{
737 		free(readBuffer);
738 	}
739 	return status;
740 }
741 
742 /* Calls to GetRemoteAccessConnectionStatus Host interface command
743 * Return values:
744 *	AMT_STATUS_SUCCESS - on success
745 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
746 */
747 AMT_STATUS PTHICommand::GetRemoteAccessConnectionStatus(REMOTE_ACCESS_STATUS &remoteAccessStatus)
748 {
749 	UINT8 *readBuffer = NULL;
750 	const UINT32 command_size = sizeof(GET_REMOTE_ACCESS_CONNECTION_STATUS_HEADER);
751 	unsigned char command[command_size];
752 	memcpy(command, &(GET_REMOTE_ACCESS_CONNECTION_STATUS_HEADER), sizeof(GET_REMOTE_ACCESS_CONNECTION_STATUS_HEADER));
753 
754 	AMT_STATUS status = _call(command, command_size, &readBuffer, GET_REMOTE_ACCESS_CONNECTION_STATUS_RESPONSE, 0);
755 	do {
756 		if (status != AMT_STATUS_SUCCESS)
757 		{
758 			break;
759 		}
760 		CFG_GET_REMOTE_ACCESS_CONNECTION_STATUS_RESPONSE *tmp_response = (CFG_GET_REMOTE_ACCESS_CONNECTION_STATUS_RESPONSE *)readBuffer;
761 		status = _verifyRemoteAccessConnectionStatus(*tmp_response);
762 		if (status != AMT_STATUS_SUCCESS)
763 		{
764 			break;
765 		}
766 
767 		remoteAccessStatus.AmtNetworkConnectionStatus    = tmp_response->AmtNetworkConnectionStatus;
768 		remoteAccessStatus.RemoteAccessConnectionStatus  = tmp_response->RemoteAccessConnectionStatus;
769 		remoteAccessStatus.RemoteAccessConnectionTrigger = tmp_response->RemoteAccessConnectionTrigger;
770 
771 		remoteAccessStatus.MpsHostname.Length = tmp_response->MpsHostname.Length;
772 		remoteAccessStatus.MpsHostname.Buffer = (CHAR *)malloc(remoteAccessStatus.MpsHostname.Length * sizeof(CHAR));
773 		if (NULL == remoteAccessStatus.MpsHostname.Buffer) {
774 			status = AMT_STATUS_INTERNAL_ERROR;
775 		} else {
776 			memcpy(remoteAccessStatus.MpsHostname.Buffer,
777 			       &(tmp_response->MpsHostname.Buffer),
778 			       tmp_response->MpsHostname.Length * sizeof(CHAR));
779 		}
780 	} while (0);
781 	if (readBuffer != NULL)
782 	{
783 		free(readBuffer);
784 	}
785 	return status;
786 }
787 
788 /*
789 * Confirms the correctness of the GetRemoteAccessConnectionStatus response message
790 * Arguments:
791 *	response - reference to the response message
792 * Return values:
793 *	AMT_STATUS_SUCCESS - on success
794 *	PTSDK_STATUS_INTERNAL_ERROR - on failure
795 */
796 AMT_STATUS PTHICommand::_verifyRemoteAccessConnectionStatus(const CFG_GET_REMOTE_ACCESS_CONNECTION_STATUS_RESPONSE &response)
797 {
798 	ULONG ByteCount = response.Header.Header.Length;
799 	if (ByteCount != (sizeof(CFG_GET_REMOTE_ACCESS_CONNECTION_STATUS_RESPONSE)
800 			  - sizeof(PTHI_MESSAGE_HEADER) - sizeof(CHAR *)
801 			  + response.MpsHostname.Length))
802 	{
803 		return PTSDK_STATUS_INTERNAL_ERROR;
804 	}
805 	return AMT_STATUS_SUCCESS;
806 }
807 
808 /*
809 * Calls to GenerateRngKey Host interface command
810 * Arguments:
811 *	None
812 * Return values:
813 *	AMT_STATUS_SUCCESS - or AMT_STATUS_IN_PROGRESS on success
814 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
815 */
816 AMT_STATUS PTHICommand::GenerateRngKey()
817 {
818 	UINT8 *readBuffer = NULL;
819 	const UINT32 command_size = sizeof(GENERATE_RNG_SEED_HEADER);
820 	unsigned char command[command_size];
821 	memcpy(command, &(GENERATE_RNG_SEED_HEADER), sizeof(GENERATE_RNG_SEED_HEADER));
822 
823 	AMT_STATUS status = _call(command, command_size, &readBuffer, GENERATE_RNG_SEED_RESPONSE, sizeof(CFG_GENERATE_RNG_SEED_RESPONSE));
824 
825 	if (readBuffer != NULL)
826 	{
827 		free(readBuffer);
828 	}
829 	return status;
830 }
831 
832 /*
833 * Calls to GetRngSeedStatus Host interface command
834 * Arguments:
835 *	rngStatus - reference to the pre-allocated structure
836 *	   which will hold the result
837 * Return values:
838 *	AMT_STATUS_SUCCESS - on success
839 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
840 */
841 AMT_STATUS PTHICommand::GetRngSeedStatus(AMT_RNG_STATUS &rngStatus)
842 {
843 	UINT8 *readBuffer = NULL;
844 	const UINT32 command_size = sizeof(GET_RNG_SEED_STATUS_HEADER);
845 	unsigned char command[command_size];
846 	memcpy(command, &(GET_RNG_SEED_STATUS_HEADER), sizeof(GET_RNG_SEED_STATUS_HEADER));
847 
848 	AMT_STATUS status = _call(command, command_size, &readBuffer, GET_RNG_SEED_STATUS_RESPONSE, sizeof(CFG_GET_RNG_SEED_STATUS_RESPONSE));
849 
850 	CFG_GET_RNG_SEED_STATUS_RESPONSE *tmp_response = (CFG_GET_RNG_SEED_STATUS_RESPONSE *)readBuffer;
851 
852 	rngStatus = tmp_response->RngStatus;
853 
854 	if (readBuffer != NULL)
855 	{
856 		free(readBuffer);
857 	}
858 	return status;
859 }
860 
861 /*
862 * Calls to ZeroTouchEnabled Host interface command
863 * Arguments:
864 *	zeroTouchEnabled - reference to the pre-allocated structure
865 *	   which will hold the result
866 * Return values:
867 *	AMT_STATUS_SUCCESS - on success
868 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
869 */
870 AMT_STATUS PTHICommand::GetZeroTouchEnabled(AMT_BOOLEAN &zeroTouchEnabled)
871 {
872 	UINT8 *readBuffer = NULL;
873 	const UINT32 command_size = sizeof(GET_ZERO_TOUCH_ENABLED_HEADER);
874 	unsigned char command[command_size];
875 	memcpy(command, &(GET_ZERO_TOUCH_ENABLED_HEADER), sizeof(GET_ZERO_TOUCH_ENABLED_HEADER));
876 
877 	AMT_STATUS status = _call(command, command_size, &readBuffer, GET_ZERO_TOUCH_ENABLED_RESPONSE, sizeof(CFG_GET_ZERO_TOUCH_ENABLED_RESPONSE));
878 
879 	CFG_GET_ZERO_TOUCH_ENABLED_RESPONSE *tmp_response = (CFG_GET_ZERO_TOUCH_ENABLED_RESPONSE *)readBuffer;
880 
881 	zeroTouchEnabled = tmp_response->ZeroTouchEnabled;
882 
883 	if (readBuffer != NULL)
884 	{
885 		free(readBuffer);
886 	}
887 	return status;
888 }
889 
890 /*
891 * Calls to GetProvisioningTlsMode Host interface command
892 * Arguments:
893 *	provisioningTlsMode - reference to the pre-allocated structure
894 *	   which will hold the result
895 * Return values:
896 *	AMT_STATUS_SUCCESS - on success
897 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
898 */
899 AMT_STATUS PTHICommand::GetProvisioningTlsMode(AMT_PROVISIONING_TLS_MODE &provisioningTlsMode)
900 {
901 	UINT8 *readBuffer = NULL;
902 	const UINT32 command_size = sizeof(GET_PROVISIONING_TLS_MODE_HEADER);
903 	unsigned char command[command_size];
904 	memcpy(command, &(GET_PROVISIONING_TLS_MODE_HEADER), sizeof(GET_PROVISIONING_TLS_MODE_HEADER));
905 
906 	AMT_STATUS status = _call(command, command_size, &readBuffer, GET_PROVISIONING_TLS_MODE_RESPONSE, sizeof(CFG_GET_PROVISIONING_TLS_MODE_RESPONSE));
907 
908 	CFG_GET_PROVISIONING_TLS_MODE_RESPONSE *tmp_response = (CFG_GET_PROVISIONING_TLS_MODE_RESPONSE *)readBuffer;
909 
910 	provisioningTlsMode = tmp_response->ProvisioningTlsMode;
911 
912 	if (readBuffer != NULL)
913 	{
914 		free(readBuffer);
915 	}
916 	return status;
917 }
918 
919 /*
920 * Calls to StartConfiguration Host interface command
921 * Arguments:
922 *	None
923 * Return values:
924 *	AMT_STATUS_SUCCESS - or AMT_STATUS_CERTIFICATE_NOT_READY on success
925 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
926 */
927 AMT_STATUS PTHICommand::StartConfiguration()
928 {
929 	UINT8 *readBuffer = NULL;
930 	const UINT32 command_size = sizeof(START_CONFIGURATION_HEADER);
931 	unsigned char command[command_size];
932 	memcpy(command, &(START_CONFIGURATION_HEADER), sizeof(START_CONFIGURATION_HEADER));
933 
934 	AMT_STATUS status = _call(command, command_size, &readBuffer, START_CONFIGURATION_RESPONSE, sizeof(CFG_START_CONFIGURATION_RESPONSE));
935 
936 	if (readBuffer != NULL)
937 	{
938 		free(readBuffer);
939 	}
940 	return status;
941 }
942 
943 /*
944 * Calls to SetProvisioningServerOTP Host interface command
945 * Arguments:
946 *	passwordOTP AMT_ANSI_STRING structure of OTP password
947 * Return values:
948 *	AMT_STATUS_SUCCESS - on success
949 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
950 */
951 AMT_STATUS PTHICommand::SetProvisioningServerOTP(AMT_ANSI_STRING passwordOTP)
952 {
953 	if (NULL == passwordOTP.Buffer)
954 	{
955 		return PTSDK_STATUS_INVALID_PARAM;
956 	}
957 
958 	UINT8 *readBuffer = NULL;
959 	UINT32 msgLength = sizeof(passwordOTP.Length) + (passwordOTP.Length * sizeof(CHAR));
960 	PTHI_MESSAGE_HEADER SET_PROVISIONING_SERVER_OTP_HEADER = {
961 		{AMT_MAJOR_VERSION, AMT_MINOR_VERSION}, 0, {{SET_PROVISIONING_SERVER_OTP_REQUEST}}, msgLength
962 	};
963 
964 	const UINT32 command_size = sizeof(SET_PROVISIONING_SERVER_OTP_HEADER) + msgLength;
965 	unsigned char *command;
966 	command = (unsigned char *)malloc(command_size);
967 	if (NULL == command)
968 	{
969 		return PTSDK_STATUS_INTERNAL_ERROR;
970 	}
971 	memcpy(command, &SET_PROVISIONING_SERVER_OTP_HEADER, sizeof(SET_PROVISIONING_SERVER_OTP_HEADER));
972 	memcpy(command + sizeof(SET_PROVISIONING_SERVER_OTP_HEADER), &(passwordOTP.Length), sizeof(passwordOTP.Length));
973 	memcpy(command + sizeof(SET_PROVISIONING_SERVER_OTP_HEADER) + sizeof(passwordOTP.Length),
974 		passwordOTP.Buffer, passwordOTP.Length);
975 
976 	AMT_STATUS status = _call(command, command_size, &readBuffer, SET_PROVISIONING_SERVER_OTP_RESPONSE, sizeof(CFG_SET_PROVISIONING_SERVER_OTP_RESPONSE));
977 
978 	if (NULL != command)
979 	{
980 		free(command);
981 	}
982 	if (readBuffer != NULL)
983 	{
984 		free(readBuffer);
985 	}
986 	return status;
987 }
988 
989 /*
990 * Calls to SetDnsSuffix Host interface command
991 * Arguments:
992 *	dnsSuffix AMT_ANSI_STRING structure of DNS suffix
993 * Return values:
994 *	AMT_STATUS_SUCCESS - on success
995 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
996 */
997 AMT_STATUS PTHICommand::SetDnsSuffix(AMT_ANSI_STRING dnsSuffix)
998 {
999 	if (NULL == dnsSuffix.Buffer)
1000 	{
1001 		return PTSDK_STATUS_INVALID_PARAM;
1002 	}
1003 
1004 	UINT8 *readBuffer = NULL;
1005 	UINT32 msgLength = sizeof(dnsSuffix.Length) + (dnsSuffix.Length * sizeof(CHAR));
1006 	PTHI_MESSAGE_HEADER SET_DNS_SUFFIX_HEADER = {
1007 		{AMT_MAJOR_VERSION, AMT_MINOR_VERSION}, 0, {{SET_DNS_SUFFIX_REQUEST}}, msgLength
1008 	};
1009 
1010 	const UINT32 command_size = sizeof(SET_DNS_SUFFIX_HEADER) + msgLength;
1011 	unsigned char *command;
1012 	command = (unsigned char *)malloc(command_size);
1013 	if (NULL == command)
1014 	{
1015 		return PTSDK_STATUS_INTERNAL_ERROR;
1016 	}
1017 	memcpy(command, &SET_DNS_SUFFIX_HEADER, sizeof(SET_DNS_SUFFIX_HEADER));
1018 	memcpy(command + sizeof(SET_DNS_SUFFIX_HEADER), &(dnsSuffix.Length), sizeof(dnsSuffix.Length));
1019 	memcpy(command + sizeof(SET_DNS_SUFFIX_HEADER) + sizeof(dnsSuffix.Length), dnsSuffix.Buffer, dnsSuffix.Length);
1020 
1021 	AMT_STATUS status = _call(command, command_size, &readBuffer, SET_DNS_SUFFIX_RESPONSE, sizeof(CFG_SET_DNS_SUFFIX_RESPONSE));
1022 
1023 	if (NULL != command)
1024 	{
1025 		free(command);
1026 	}
1027 	if (readBuffer != NULL)
1028 	{
1029 		free(readBuffer);
1030 	}
1031 	return status;
1032 }
1033 
1034 /*
1035 * Calls to EnumerateHashHandles Host interface command
1036 * Arguments:
1037 *	hashHandles - reference to the pre-allocated structure
1038 *	   which will hold the result
1039 * Return values:
1040 *	AMT_STATUS_SUCCESS - on success
1041 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
1042 */
1043 AMT_STATUS PTHICommand::EnumerateHashHandles(AMT_HASH_HANDLES &hashHandles)
1044 {
1045 	UINT8 *readBuffer = NULL;
1046 	const UINT32 command_size = sizeof(ENUMERATE_HASH_HANDLES_HEADER);
1047 	unsigned char command[command_size];
1048 	memcpy(command, &(ENUMERATE_HASH_HANDLES_HEADER), sizeof(ENUMERATE_HASH_HANDLES_HEADER));
1049 
1050 	AMT_STATUS status = _call(command, command_size, &readBuffer, ENUMERATE_HASH_HANDLES_RESPONSE, 0);
1051 	do {
1052 		if (status != AMT_STATUS_SUCCESS)
1053 		{
1054 			break;
1055 		}
1056 		CFG_GET_HASH_HANDLES_RESPONSE *tmp_response = (CFG_GET_HASH_HANDLES_RESPONSE *)readBuffer;
1057 		status = _verifyHashHandles(*tmp_response);
1058 		if (status != AMT_STATUS_SUCCESS)
1059 		{
1060 			break;
1061 		}
1062 
1063 		memset(hashHandles.Handles, 0, sizeof(UINT32) * CERT_HASH_MAX_NUMBER);
1064 		hashHandles.Length = tmp_response->HashHandles.Length;
1065 		if (CERT_HASH_MAX_NUMBER < hashHandles.Length)
1066 		{
1067 			status = PTSDK_STATUS_INTERNAL_ERROR;
1068 			break;
1069 		}
1070 
1071 		memcpy(hashHandles.Handles, tmp_response->HashHandles.Handles, sizeof(UINT32) * hashHandles.Length);
1072 
1073 	} while (0);
1074 	if (readBuffer != NULL)
1075 	{
1076 		free(readBuffer);
1077 	}
1078 	return status;
1079 }
1080 
1081 /*
1082 * Confirms the correctness of the EnumerateHashHandles response message
1083 * Arguments:
1084 *	response - reference to the response message
1085 * Return values:
1086 *	AMT_STATUS_SUCCESS - on success
1087 *	PTSDK_STATUS_INTERNAL_ERROR - on failure
1088 */
1089 AMT_STATUS PTHICommand::_verifyHashHandles(const CFG_GET_HASH_HANDLES_RESPONSE &response)
1090 {
1091 	ULONG ByteCount = response.Header.Header.Length;
1092 
1093 	if (ByteCount !=
1094 		sizeof(AMT_STATUS) + sizeof(response.HashHandles.Length) + (sizeof(UINT32) * response.HashHandles.Length))
1095 	{
1096 		return PTSDK_STATUS_INTERNAL_ERROR;
1097 	}
1098 	return AMT_STATUS_SUCCESS;
1099 }
1100 
1101 
1102 /*
1103 * Calls to GetCertificateHashEntry Host interface command
1104 * Arguments:
1105 *	passwordOTP AMT_ANSI_STRING structure of DNS suffix
1106 * Return values:
1107 *	AMT_STATUS_SUCCESS - on success
1108 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
1109 */
1110 AMT_STATUS PTHICommand::GetCertificateHashEntry(UINT32 hashHandle, CERTHASH_ENTRY &hashEntry)
1111 {
1112 	UINT8 *readBuffer = NULL;
1113 	const UINT32 command_size = sizeof(CFG_GET_CERTHASH_ENTRY_REQUEST);
1114 	unsigned char command[command_size];
1115 	memcpy(command, &(GET_CERTHASH_ENTRY_HEADER), sizeof(GET_CERTHASH_ENTRY_HEADER));
1116 	memcpy(command + sizeof(GET_CERTHASH_ENTRY_HEADER), &(hashHandle), sizeof(hashHandle));
1117 
1118 	AMT_STATUS status = _call(command, command_size, &readBuffer, GET_CERTHASH_ENTRY_RESPONSE, 0);
1119 	do {
1120 		if (status != AMT_STATUS_SUCCESS)
1121 		{
1122 			break;
1123 		}
1124 		CFG_GET_CERTHASH_ENTRY_RESPONSE *tmp_response = (CFG_GET_CERTHASH_ENTRY_RESPONSE *)readBuffer;
1125 		status = _verifyGetCertificateHashEntry(*tmp_response);
1126 		if (status != AMT_STATUS_SUCCESS)
1127 		{
1128 			break;
1129 		}
1130 
1131 		hashEntry.IsActive = tmp_response->Hash.IsActive;
1132 		hashEntry.IsDefault = tmp_response->Hash.IsDefault;
1133 		hashEntry.Name.Length = tmp_response->Hash.Name.Length;
1134 		hashEntry.HashAlgorithm = tmp_response->Hash.HashAlgorithm;
1135 		memcpy(hashEntry.CertificateHash, tmp_response->Hash.CertificateHash, sizeof(tmp_response->Hash.CertificateHash));
1136 		hashEntry.Name.Buffer = (CHAR *)malloc(hashEntry.Name.Length * sizeof(CHAR));
1137 		if (NULL == hashEntry.Name.Buffer)
1138 		{
1139 			status = PTSDK_STATUS_INTERNAL_ERROR;
1140 			break;
1141 		}
1142 		memcpy(hashEntry.Name.Buffer, &(tmp_response->Hash.Name.Buffer), hashEntry.Name.Length * sizeof(CHAR));
1143 
1144 	} while (0);
1145 	if (readBuffer != NULL)
1146 	{
1147 		free(readBuffer);
1148 	}
1149 	return status;
1150 }
1151 /*
1152 * Confirms the correctness of the GetCertificateHashEntry response message
1153 * Arguments:
1154 *	response - reference to the response message
1155 * Return values:
1156 *	AMT_STATUS_SUCCESS - on success
1157 *	PTSDK_STATUS_INTERNAL_ERROR - on failure
1158 */
1159 AMT_STATUS PTHICommand::_verifyGetCertificateHashEntry(const CFG_GET_CERTHASH_ENTRY_RESPONSE &response)
1160 {
1161 	ULONG ByteCount = response.Header.Header.Length;
1162 
1163 	if (ByteCount !=
1164 		(sizeof(CFG_GET_CERTHASH_ENTRY_RESPONSE) - sizeof(PTHI_MESSAGE_HEADER)
1165 		- sizeof(CHAR *) + response.Hash.Name.Length))
1166 	{
1167 		return PTSDK_STATUS_INTERNAL_ERROR;
1168 	}
1169 	return AMT_STATUS_SUCCESS;
1170 }
1171 
1172 /*
1173 * Calls to GetDnsSuffix Host interface command
1174 * Arguments:
1175 *	dnsSuffix - reference to the pre-allocated structure
1176 *	   which will hold the result
1177 * Return values:
1178 *	AMT_STATUS_SUCCESS - on success
1179 *	appropriate error value defined in StatusCodeDefinitions.h - on failure
1180 */
1181 AMT_STATUS PTHICommand::GetDnsSuffix(AMT_ANSI_STRING &dnsSuffix)
1182 {
1183 	UINT8 *readBuffer = NULL;
1184 	const UINT32 command_size = sizeof(GET_PKI_FQDN_SUFFIX_HEADER);
1185 	unsigned char command[command_size];
1186 	memcpy(command, &(GET_PKI_FQDN_SUFFIX_HEADER), sizeof(GET_PKI_FQDN_SUFFIX_HEADER));
1187 
1188 	AMT_STATUS status = _call(command, command_size, &readBuffer, GET_PKI_FQDN_SUFFIX_RESPONSE, 0);
1189 	do {
1190 		if (status != AMT_STATUS_SUCCESS)
1191 		{
1192 			break;
1193 		}
1194 		CFG_GET_PKI_FQDN_SUFFIX_RESPONSE *tmp_response = (CFG_GET_PKI_FQDN_SUFFIX_RESPONSE *)readBuffer;
1195 		status = _verifyGetDnsSuffix(*tmp_response);
1196 		if (status != AMT_STATUS_SUCCESS)
1197 		{
1198 			break;
1199 		}
1200 
1201 		dnsSuffix.Length = tmp_response->Suffix.Length;
1202 		dnsSuffix.Buffer = (CHAR *)malloc(dnsSuffix.Length * sizeof(CHAR));
1203 		if (NULL == dnsSuffix.Buffer)
1204 		{
1205 			status = PTSDK_STATUS_INTERNAL_ERROR;
1206 			break;
1207 		}
1208 		memcpy(dnsSuffix.Buffer, &(tmp_response->Suffix.Buffer), dnsSuffix.Length * sizeof(CHAR));
1209 
1210 	} while (0);
1211 	if (readBuffer != NULL)
1212 	{
1213 		free(readBuffer);
1214 	}
1215 	return status;
1216 }
1217 /*
1218 * Confirms the correctness of the GetDnsSuffix response message
1219 * Arguments:
1220 *	response - reference to the response message
1221 * Return values:
1222 *	AMT_STATUS_SUCCESS - on success
1223 *	PTSDK_STATUS_INTERNAL_ERROR - on failure
1224 */
1225 AMT_STATUS PTHICommand::_verifyGetDnsSuffix(const CFG_GET_PKI_FQDN_SUFFIX_RESPONSE &response)
1226 {
1227 	ULONG ByteCount = response.Header.Header.Length;
1228 
1229 	if (ByteCount  !=
1230 		sizeof(AMT_STATUS) + sizeof(response.Suffix.Length) + response.Suffix.Length * sizeof(CHAR))
1231 	{
1232 		return PTSDK_STATUS_INTERNAL_ERROR;
1233 	}
1234 	return AMT_STATUS_SUCCESS;
1235 }
1236 
1237