1diff --git a/tpm/tpm_cmd_handler.c b/tpm/tpm_cmd_handler.c
2index 0fabf98..69511d1 100644
3--- a/tpm/tpm_cmd_handler.c
4+++ b/tpm/tpm_cmd_handler.c
5@@ -3343,6 +3343,39 @@ static TPM_RESULT execute_TPM_ParentSignEK(TPM_REQUEST *req, TPM_RESPONSE *rsp)
6 	return res;
7 }
8
9+static TPM_RESULT execute_TPM_DeepQuote(TPM_REQUEST *req, TPM_RESPONSE *rsp)
10+{
11+	TPM_NONCE nonce;
12+	TPM_RESULT res;
13+	UINT32 sigSize;
14+	BYTE *sig;
15+	BYTE *ptr;
16+	UINT32 len;
17+	TPM_PCR_SELECTION myPCR;
18+	TPM_PCR_SELECTION ptPCR;
19+
20+	tpm_compute_in_param_digest(req);
21+
22+	ptr = req->param;
23+	len = req->paramSize;
24+	if (tpm_unmarshal_TPM_NONCE(&ptr, &len, &nonce)
25+		|| tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &myPCR)
26+		|| tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &ptPCR)
27+		|| len != 0) return TPM_BAD_PARAMETER;
28+
29+	res = TPM_DeepQuote(&nonce, &myPCR, &ptPCR, &req->auth1, &sigSize, &sig);
30+	if (res != TPM_SUCCESS) return res;
31+	rsp->paramSize = len = sigSize;
32+	rsp->param = ptr = tpm_malloc(len);
33+	if (ptr == NULL || tpm_marshal_BLOB(&ptr, &len, sig, sigSize)) {
34+		tpm_free(rsp->param);
35+		res = TPM_FAIL;
36+	}
37+	tpm_free(sig);
38+
39+	return res;
40+}
41+
42 static void tpm_setup_rsp_auth(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp)
43 {
44   tpm_hmac_ctx_t hmac;
45@@ -4098,6 +4131,11 @@ void tpm_execute_command(TPM_REQUEST *req, TPM_RESPONSE *rsp)
46       res = execute_TPM_ParentSignEK(req, rsp);
47     break;
48
49+    case TPM_ORD_DeepQuote:
50+      debug("[TPM_ORD_DeepQuote]");
51+      res = execute_TPM_DeepQuote(req, rsp);
52+    break;
53+
54     default:
55 #ifdef MTM_EMULATOR
56       res = mtm_execute_command(req, rsp);
57diff --git a/tpm/tpm_commands.h b/tpm/tpm_commands.h
58index 7fef934..328d1be 100644
59--- a/tpm/tpm_commands.h
60+++ b/tpm/tpm_commands.h
61@@ -3071,6 +3071,25 @@ TPM_RESULT TPM_ParentSignEK(
62   BYTE **sig
63 );
64
65+/**
66+ * TPM_DeepQuote - gets a hardware TPM quote of a vTPM's PCRs
67+ * @externalData: [in] AntiReplay nonce to prevent replay of messages
68+ * @myPCR: [in] PCR selection for the virtual TPM
69+ * @ptPCR: [in] PCR selection for the hardware TPM
70+ * @auth1: [in, out] Authorization protocol parameters
71+ * @sigSize: [out] The length of the returned digital signature
72+ * @sig: [out] The resulting digital signature and PCR values
73+ * Returns: TPM_SUCCESS on success, a TPM error code otherwise.
74+ */
75+TPM_RESULT TPM_DeepQuote(
76+  TPM_NONCE *externalData,
77+  TPM_PCR_SELECTION *myPCR,
78+  TPM_PCR_SELECTION *ptPCR,
79+  TPM_AUTH *auth1,
80+  UINT32 *sigSize,
81+  BYTE **sig
82+);
83+
84 /*
85  * Error handling
86  * [tpm_error.c]
87diff --git a/tpm/tpm_credentials.c b/tpm/tpm_credentials.c
88index 01f29e6..c0d62e7 100644
89--- a/tpm/tpm_credentials.c
90+++ b/tpm/tpm_credentials.c
91@@ -211,3 +211,49 @@ TPM_RESULT TPM_ParentSignEK(TPM_NONCE *externalData, TPM_PCR_SELECTION *sel,
92 	free_TPM_PUBKEY(pubKey);
93 	return res;
94 }
95+
96+static const BYTE dquot_hdr[] = {
97+	0, 0, 0, 0, 'D', 'Q', 'U', 'T'
98+};
99+
100+TPM_RESULT TPM_DeepQuote(TPM_NONCE *externalData, TPM_PCR_SELECTION *myPCR,
101+                         TPM_PCR_SELECTION *ptPCR, TPM_AUTH *auth1,
102+                         UINT32 *sigSize, BYTE **sig)
103+{
104+	TPM_RESULT res;
105+	TPM_DIGEST hres;
106+	TPM_PCR_INFO_SHORT pcrData;
107+	tpm_sha1_ctx_t ctx;
108+	BYTE *buf, *ptr;
109+	UINT32 size, len;
110+
111+	info("TPM_DeepQuote()");
112+
113+	res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
114+	if (res != TPM_SUCCESS) return res;
115+
116+	res = tpm_compute_pcr_digest(myPCR, &pcrData.digestAtRelease, NULL);
117+	if (res != TPM_SUCCESS) return res;
118+
119+	pcrData.pcrSelection.sizeOfSelect = myPCR->sizeOfSelect;
120+	memcpy(pcrData.pcrSelection.pcrSelect, myPCR->pcrSelect, myPCR->sizeOfSelect);
121+	pcrData.localityAtRelease = 1 << tpmData.stany.flags.localityModifier;
122+
123+	size = len = sizeof_TPM_PCR_INFO_SHORT(pcrData);
124+	buf = ptr = tpm_malloc(size);
125+	if (buf == NULL) return TPM_NOSPACE;
126+	if (tpm_marshal_TPM_PCR_INFO_SHORT(&ptr, &len, &pcrData))
127+		return TPM_FAIL;
128+
129+	tpm_sha1_init(&ctx);
130+	tpm_sha1_update(&ctx, dquot_hdr, 8);
131+	tpm_sha1_update(&ctx, externalData->nonce, 20);
132+	tpm_sha1_update(&ctx, buf, size);
133+	tpm_sha1_final(&ctx, hres.digest);
134+
135+	tpm_free(buf);
136+
137+	res = VTPM_GetParentQuote(&hres, ptPCR, sigSize, sig);
138+
139+	return res;
140+}
141diff --git a/tpm/tpm_structures.h b/tpm/tpm_structures.h
142index b0f4625..dfb1894 100644
143--- a/tpm/tpm_structures.h
144+++ b/tpm/tpm_structures.h
145@@ -660,6 +660,42 @@ typedef struct tdTPM_CMK_MA_APPROVAL {
146
147 /* VTPM-only commands: */
148 /*
149+ * Deep Quote - Create quote of PCRs
150+ * Input:
151+ *   TPM_TAG             tag           TPM_TAG_RQU_AUTH1_COMMAND
152+ *   UINT32              paramSize     Total size of request
153+ *   TPM_COMMAND_CODE    ordinal       TPM_ORD_DeepQuote
154+ *   TPM_NONCE           externData    20 bytes of external data
155+ *   TPM_PCR_SELECTION   vtSel         PCR selection for virtual TPM
156+ *   TPM_PCR_SELECTION   ptSel         PCR selection for physical TPM
157+ *   ---
158+ *   UINT32              authHandle    Owner authorization session (OIAP)
159+ *   TPM_NONCE           nonceOdd      Nonce for authHandle
160+ *   BOOL                continueAuth  Continue flag for authHandle
161+ *   TPM_AUTHDATA        privAuth      Authorization digest for command
162+ *
163+ * Output:
164+ *   TPM_TAG             tag           TPM_TAG_RSP_AUTH1_COMMAND
165+ *   UINT32              paramSize     Total size of response
166+ *   TPM_RESULT          returnCode    Return code of the operation
167+ *   BYTE[]              sig           Signature provided by physical TPM
168+ *   TPM_PCRVALUE[]      pcrValue      Values of hardware PCRs used in the quote
169+ *   ---
170+ *   TPM_NONCE           nonceEven     Nonce for authHandle
171+ *   BOOL                continueAuth  Continue flag for authHandle
172+ *   TPM_AUTHDATA        resAuth       Authorization digest for response
173+ *
174+ * The values of the virutal TPM's PCRs are not included in the response.
175+ * The signature is a standard TPM_Quote response from the physical TPM; its
176+ * externalData is the SHA1 hash of the following structure:
177+ *   TPM_STRUCT_VER      version       MUST be 0.0.0.0
178+ *   BYTE[4]             fixed         MUST be the string "DQUT"
179+ *   TPM_NONCE           externData    From input to the deep quote
180+ *   TPM_PCR_INFO_SHORT  pcrData       Virtual TPM's PCRs
181+ */
182+#define TPM_ORD_DeepQuote                       (TPM_VENDOR_COMMAND | TPM_ORD_Quote)
183+
184+/*
185  * ParentSignEK - Proof of fresh provisioning and EK value
186  *
187  * Input:
188