diff --git a/tpm/tpm_cmd_handler.c b/tpm/tpm_cmd_handler.c
index 9e1cfb4..0fabf98 100644
--- a/tpm/tpm_cmd_handler.c
+++ b/tpm/tpm_cmd_handler.c
@@ -3312,6 +3312,37 @@ static TPM_RESULT execute_TPM_OwnerReadPubek(TPM_REQUEST *req, TPM_RESPONSE *rsp
   return res;
 }
 
+static TPM_RESULT execute_TPM_ParentSignEK(TPM_REQUEST *req, TPM_RESPONSE *rsp)
+{
+	TPM_NONCE nonce;
+	TPM_RESULT res;
+	UINT32 sigSize;
+	BYTE *sig;
+	BYTE *ptr;
+	UINT32 len;
+	TPM_PCR_SELECTION targetPCR;
+
+	tpm_compute_in_param_digest(req);
+
+	ptr = req->param;
+	len = req->paramSize;
+	if (tpm_unmarshal_TPM_NONCE(&ptr, &len, &nonce)
+		|| tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &targetPCR)
+		|| len != 0) return TPM_BAD_PARAMETER;
+
+	res = TPM_ParentSignEK(&nonce, &targetPCR, &req->auth1, &sigSize, &sig);
+	if (res != TPM_SUCCESS) return res;
+	rsp->paramSize = len = sigSize;
+	rsp->param = ptr = tpm_malloc(len);
+	if (ptr == NULL || tpm_marshal_BLOB(&ptr, &len, sig, sigSize)) {
+		tpm_free(rsp->param);
+		res = TPM_FAIL;
+	}
+	tpm_free(sig);
+
+	return res;
+}
+
 static void tpm_setup_rsp_auth(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp) 
 {
   tpm_hmac_ctx_t hmac;
@@ -4062,6 +4093,11 @@ void tpm_execute_command(TPM_REQUEST *req, TPM_RESPONSE *rsp)
       res = execute_TPM_OwnerReadPubek(req, rsp);
     break;
 
+    case TPM_ORD_ParentSignEK:
+      debug("[TPM_ORD_ParentSignEK]");
+      res = execute_TPM_ParentSignEK(req, rsp);
+    break;
+
     default:
 #ifdef MTM_EMULATOR
       res = mtm_execute_command(req, rsp);
diff --git a/tpm/tpm_commands.h b/tpm/tpm_commands.h
index a7666f6..7fef934 100644
--- a/tpm/tpm_commands.h
+++ b/tpm/tpm_commands.h
@@ -3054,6 +3054,23 @@ TPM_RESULT TPM_OwnerReadPubek(
   TPM_PUBKEY *pubEndorsementKey 
 );
 
+/**
+ * TPM_ParentSignEK - gets a hardware TPM quote of a vTPM's EK
+ * @externalData: [in] AntiReplay nonce to prevent replay of messages
+ * @sel: [in] PCR selection for the hardware TPM's quote
+ * @auth1: [in, out] Authorization protocol parameters
+ * @sigSize: [out] The length of the returned digital signature
+ * @sig: [out] The resulting digital signature and PCR values
+ * Returns: TPM_SUCCESS on success, a TPM error code otherwise.
+ */
+TPM_RESULT TPM_ParentSignEK(
+  TPM_NONCE *externalData,
+  TPM_PCR_SELECTION *sel,
+  TPM_AUTH *auth1,
+  UINT32 *sigSize,
+  BYTE **sig
+);
+
 /*
  * Error handling
  * [tpm_error.c]
diff --git a/tpm/tpm_credentials.c b/tpm/tpm_credentials.c
index 9cd64af..01f29e6 100644
--- a/tpm/tpm_credentials.c
+++ b/tpm/tpm_credentials.c
@@ -180,3 +180,34 @@ TPM_RESULT TPM_OwnerReadInternalPub(TPM_KEY_HANDLE keyHandle, TPM_AUTH *auth1,
     return TPM_BAD_PARAMETER;
   }
 }
+
+int endorsementKeyFresh = 0;
+
+TPM_RESULT VTPM_GetParentQuote(TPM_DIGEST* data, TPM_PCR_SELECTION *sel, UINT32 *sigSize, BYTE **sig);
+
+TPM_RESULT TPM_ParentSignEK(TPM_NONCE *externalData, TPM_PCR_SELECTION *sel,
+                            TPM_AUTH *auth1, UINT32 *sigSize, BYTE **sig)
+{
+	TPM_PUBKEY pubKey;
+	TPM_RESULT res;
+	TPM_DIGEST hres;
+
+	info("TPM_ParentSignEK()");
+
+	res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
+	if (res != TPM_SUCCESS) return res;
+
+	if (!endorsementKeyFresh) return TPM_DISABLED_CMD;
+
+	res = tpm_get_pubek(&pubKey);
+	if (res != TPM_SUCCESS) return res;
+
+	if (tpm_compute_pubkey_checksum(externalData, &pubKey, &hres))
+		res = TPM_FAIL;
+
+	if (res == TPM_SUCCESS)
+		res = VTPM_GetParentQuote(&hres, sel, sigSize, sig);
+
+	free_TPM_PUBKEY(pubKey);
+	return res;
+}
diff --git a/tpm/tpm_data.c b/tpm/tpm_data.c
index 50c9697..6a0c499 100644
--- a/tpm/tpm_data.c
+++ b/tpm/tpm_data.c
@@ -76,6 +76,8 @@ static void init_timeouts(void)
   tpmData.permanent.data.cmd_durations[2] = 1000;
 }
 
+extern int endorsementKeyFresh;
+
 void tpm_init_data(void)
 {
   /* endorsement key */
@@ -157,6 +159,7 @@ void tpm_init_data(void)
   if (tpmConf & TPM_CONF_GENERATE_EK) {
     /* generate a new endorsement key */
     tpm_rsa_generate_key(&tpmData.permanent.data.endorsementKey, 2048);
+    endorsementKeyFresh = 1;
   } else {
     /* setup endorsement key */
     tpm_rsa_import_key(&tpmData.permanent.data.endorsementKey, 
diff --git a/tpm/tpm_structures.h b/tpm/tpm_structures.h
index f746c05..b0f4625 100644
--- a/tpm/tpm_structures.h
+++ b/tpm/tpm_structures.h
@@ -658,6 +658,49 @@ typedef struct tdTPM_CMK_MA_APPROVAL {
 #define TPM_ORD_TickStampBlob                   242
 #define TPM_ORD_MAX                             256
 
+/* VTPM-only commands: */
+/*
+ * ParentSignEK - Proof of fresh provisioning and EK value
+ *
+ * Input:
+ *   TPM_TAG             tag           TPM_TAG_RQU_AUTH1_COMMAND
+ *   UINT32              paramSize     Total size of request
+ *   TPM_COMMAND_CODE    ordinal       TPM_ORD_ParentSignEK
+ *   TPM_NONCE           externData    20 bytes of external data
+ *   TPM_PCR_SELECTION   ptSel         PCR selection for physical TPM
+ *   ---
+ *   UINT32              authHandle    Owner authorization session (OIAP)
+ *   TPM_NONCE           nonceOdd      Nonce for authHandle
+ *   BOOL                continueAuth  Continue flag for authHandle
+ *   TPM_AUTHDATA        privAuth      Authorization digest for command
+ *
+ * Output:
+ *   TPM_TAG             tag           TPM_TAG_RSP_AUTH1_COMMAND
+ *   UINT32              paramSize     Total size of response
+ *   TPM_RESULT          returnCode    Return code of the operation
+ *   BYTE[]              sig           Signature provided by physical TPM
+ *   TPM_PCRVALUE[]      pcrValue      Values of hardware PCRs used in the quote
+ *   ---
+ *   TPM_NONCE           nonceEven     Nonce for authHandle
+ *   BOOL                continueAuth  Continue flag for authHandle
+ *   TPM_AUTHDATA        resAuth       Authorization digest for response
+ *
+ * This command is only valid on the first boot of a vTPM; on any subsequent
+ * boot, the command returns TPM_DISABLED_CMD. It is intended to be used to
+ * provide evidence of proper platform configuration to the verifier/CA which is
+ * responsible for the creation of the vTPM's endorsement credential, which will
+ * be used on subsequent boots to certify AIKs via the usual Privacy CA protocol.
+ *
+ * The values of the virtual TPM's PCRs are not included in the response.
+ * The signature is a standard TPM_Quote response from the physical TPM; its
+ * externalData is the SHA1 hash of the following structure:
+ *   TPM_PUBKEY          pubEK         The vTPM's public EK
+ *   TPM_NONCE           externData    From input to the deep quote
+ *
+ * This structure was chosen to match the return of TPM_ReadPubek
+ */
+#define TPM_ORD_ParentSignEK                    (TPM_VENDOR_COMMAND | TPM_ORD_ReadPubek)
+
 /*
  * TCS Ordinals ([TPM_Part2], Section 17.1)
  *
