summaryrefslogtreecommitdiffstats
path: root/recipes-extended/xen/files
diff options
context:
space:
mode:
authorKurt Bodiker <kurt.bodiker@braintrust-us.com>2018-05-01 10:05:33 -0400
committerBruce Ashfield <bruce.ashfield@windriver.com>2018-05-01 23:17:29 -0400
commit230198a7d1f9d3cc7df986b4fbc4ab1cc4211640 (patch)
tree8576114fc3bebd740646afabfedaba55379aa3b9 /recipes-extended/xen/files
parent299c5243ddcdbf6028e44e0fa3e3ff314d97cc38 (diff)
downloadmeta-virtualization-230198a7d1f9d3cc7df986b4fbc4ab1cc4211640.tar.gz
xen: TPM Emulator for Xen stubdoms
TPM Emulator is a software-based TPM and MTM emulator. This TPM Emulator recipe creates a static library that is cross-compiled against MiniOS, Xen, LWIP, Newlib, PolarSSL, and the stubdom-specific GMP headers and subsequently used during the cross-compilation and linking of the Xen vTPM and vTPM Manager stubdomains. The current Xen source code is hardcoded to fetch a specific version of this package. The patch files originate from the Xen/stubdom source tree. This recipe provides the flexibility to change version or modify the patches. Signed-off-by: Kurt Bodiker <kurt.bodiker@braintrust-us.com> Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
Diffstat (limited to 'recipes-extended/xen/files')
-rw-r--r--recipes-extended/xen/files/tpmemu-0.7.4.patch12
-rw-r--r--recipes-extended/xen/files/vtpm-bufsize.patch13
-rw-r--r--recipes-extended/xen/files/vtpm-cmake-Wextra.patch21
-rw-r--r--recipes-extended/xen/files/vtpm-deepquote-anyloc.patch127
-rw-r--r--recipes-extended/xen/files/vtpm-deepquote.patch187
-rw-r--r--recipes-extended/xen/files/vtpm-implicit-fallthrough.patch10
-rw-r--r--recipes-extended/xen/files/vtpm-locality.patch50
-rw-r--r--recipes-extended/xen/files/vtpm-parent-sign-ek.patch196
8 files changed, 616 insertions, 0 deletions
diff --git a/recipes-extended/xen/files/tpmemu-0.7.4.patch b/recipes-extended/xen/files/tpmemu-0.7.4.patch
new file mode 100644
index 00000000..622b34f5
--- /dev/null
+++ b/recipes-extended/xen/files/tpmemu-0.7.4.patch
@@ -0,0 +1,12 @@
1diff -Naur tpm_emulator-x86_64-back/tpm/tpm_emulator_extern.c tpm_emulator-x86_64/tpm/tpm_emulator_extern.c
2--- a/tpm/tpm_emulator_extern.c 2012-04-27 10:55:46.581963398 -0400
3+++ b/tpm/tpm_emulator_extern.c 2012-04-27 10:56:02.193034152 -0400
4@@ -249,7 +249,7 @@
5 #else /* TPM_NO_EXTERN */
6
7 int (*tpm_extern_init)(void) = NULL;
8-int (*tpm_extern_release)(void) = NULL;
9+void (*tpm_extern_release)(void) = NULL;
10 void* (*tpm_malloc)(size_t size) = NULL;
11 void (*tpm_free)(/*const*/ void *ptr) = NULL;
12 void (*tpm_log)(int priority, const char *fmt, ...) = NULL;
diff --git a/recipes-extended/xen/files/vtpm-bufsize.patch b/recipes-extended/xen/files/vtpm-bufsize.patch
new file mode 100644
index 00000000..9c9304cf
--- /dev/null
+++ b/recipes-extended/xen/files/vtpm-bufsize.patch
@@ -0,0 +1,13 @@
1diff --git a/config.h.in b/config.h.in
2index d16a997..8088a2a 100644
3--- a/config.h.in
4+++ b/config.h.in
5@@ -27,7 +27,7 @@
6 #define TPM_STORAGE_NAME "${TPM_STORAGE_NAME}"
7 #define TPM_DEVICE_NAME "${TPM_DEVICE_NAME}"
8 #define TPM_LOG_FILE "${TPM_LOG_FILE}"
9-#define TPM_CMD_BUF_SIZE 4096
10+#define TPM_CMD_BUF_SIZE 4088
11
12 #endif /* _CONFIG_H_ */
13
diff --git a/recipes-extended/xen/files/vtpm-cmake-Wextra.patch b/recipes-extended/xen/files/vtpm-cmake-Wextra.patch
new file mode 100644
index 00000000..5fee4e9a
--- /dev/null
+++ b/recipes-extended/xen/files/vtpm-cmake-Wextra.patch
@@ -0,0 +1,21 @@
1---
2 CMakeLists.txt | 3 ++-
3 1 file changed, 2 insertions(+), 1 deletion(-)
4
5Index: tpm_emulator-x86_64/CMakeLists.txt
6===================================================================
7--- a/CMakeLists.txt
8+++ b/CMakeLists.txt
9@@ -40,10 +40,11 @@ set(TPM_STORAGE_NAME "/var/lib/tpm/tpm_e
10 set(TPM_DEVICE_NAME "/dev/tpm")
11 endif()
12 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
13-add_definitions(-Wall -Werror -Wno-unused-parameter -Wpointer-arith -Wcast-align -Wwrite-strings)
14+add_definitions(-Wall -Werror)
15 if("${CMAKE_SYSTEM}" MATCHES "Linux")
16 add_definitions(-Wextra)
17 endif()
18+add_definitions(-Wno-unused-parameter -Wpointer-arith -Wcast-align -Wwrite-strings)
19 if(USE_OPENSSL)
20 add_definitions(-DUSE_OPENSSL)
21 endif()
diff --git a/recipes-extended/xen/files/vtpm-deepquote-anyloc.patch b/recipes-extended/xen/files/vtpm-deepquote-anyloc.patch
new file mode 100644
index 00000000..7b37d512
--- /dev/null
+++ b/recipes-extended/xen/files/vtpm-deepquote-anyloc.patch
@@ -0,0 +1,127 @@
1diff --git a/tpm/tpm_cmd_handler.c b/tpm/tpm_cmd_handler.c
2index 69511d1..7545d51 100644
3--- a/tpm/tpm_cmd_handler.c
4+++ b/tpm/tpm_cmd_handler.c
5@@ -3347,12 +3347,13 @@ static TPM_RESULT execute_TPM_DeepQuote(TPM_REQUEST *req, TPM_RESPONSE *rsp)
6 {
7 TPM_NONCE nonce;
8 TPM_RESULT res;
9- UINT32 sigSize;
10- BYTE *sig;
11+ UINT32 quote_blob_size;
12+ BYTE *quote_blob;
13 BYTE *ptr;
14 UINT32 len;
15 TPM_PCR_SELECTION myPCR;
16 TPM_PCR_SELECTION ptPCR;
17+ UINT32 extraInfoFlags = 0;
18
19 tpm_compute_in_param_digest(req);
20
21@@ -3361,17 +3362,19 @@ static TPM_RESULT execute_TPM_DeepQuote(TPM_REQUEST *req, TPM_RESPONSE *rsp)
22 if (tpm_unmarshal_TPM_NONCE(&ptr, &len, &nonce)
23 || tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &myPCR)
24 || tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &ptPCR)
25+ || tpm_unmarshal_TPM_DEEP_QUOTE_INFO(&ptr, &len, &extraInfoFlags)
26 || len != 0) return TPM_BAD_PARAMETER;
27
28- res = TPM_DeepQuote(&nonce, &myPCR, &ptPCR, &req->auth1, &sigSize, &sig);
29+ res = TPM_DeepQuote(&nonce, &myPCR, &ptPCR, &req->auth1, extraInfoFlags,
30+ &quote_blob_size, &quote_blob);
31 if (res != TPM_SUCCESS) return res;
32- rsp->paramSize = len = sigSize;
33+ rsp->paramSize = len = quote_blob_size;
34 rsp->param = ptr = tpm_malloc(len);
35- if (ptr == NULL || tpm_marshal_BLOB(&ptr, &len, sig, sigSize)) {
36+ if (ptr == NULL || tpm_marshal_BLOB(&ptr, &len, quote_blob, quote_blob_size)) {
37 tpm_free(rsp->param);
38 res = TPM_FAIL;
39 }
40- tpm_free(sig);
41+ tpm_free(quote_blob);
42
43 return res;
44 }
45diff --git a/tpm/tpm_commands.h b/tpm/tpm_commands.h
46index 328d1be..a56dd5f 100644
47--- a/tpm/tpm_commands.h
48+++ b/tpm/tpm_commands.h
49@@ -3077,6 +3077,7 @@ TPM_RESULT TPM_ParentSignEK(
50 * @myPCR: [in] PCR selection for the virtual TPM
51 * @ptPCR: [in] PCR selection for the hardware TPM
52 * @auth1: [in, out] Authorization protocol parameters
53+ * @extraInfoFlags [in] Flags for including, kernel hash, group info, etc
54 * @sigSize: [out] The length of the returned digital signature
55 * @sig: [out] The resulting digital signature and PCR values
56 * Returns: TPM_SUCCESS on success, a TPM error code otherwise.
57@@ -3086,6 +3087,7 @@ TPM_RESULT TPM_DeepQuote(
58 TPM_PCR_SELECTION *myPCR,
59 TPM_PCR_SELECTION *ptPCR,
60 TPM_AUTH *auth1,
61+ UINT32 extraInfoFlags,
62 UINT32 *sigSize,
63 BYTE **sig
64 );
65diff --git a/tpm/tpm_credentials.c b/tpm/tpm_credentials.c
66index c0d62e7..6586c22 100644
67--- a/tpm/tpm_credentials.c
68+++ b/tpm/tpm_credentials.c
69@@ -183,7 +183,8 @@ TPM_RESULT TPM_OwnerReadInternalPub(TPM_KEY_HANDLE keyHandle, TPM_AUTH *auth1,
70
71 int endorsementKeyFresh = 0;
72
73-TPM_RESULT VTPM_GetParentQuote(TPM_DIGEST* data, TPM_PCR_SELECTION *sel, UINT32 *sigSize, BYTE **sig);
74+TPM_RESULT VTPM_GetParentQuote(TPM_NONCE *data, TPM_PCR_SELECTION *sel,
75+ UINT32 extraInfoFlags, UINT32 *sigSize, BYTE **sig);
76
77 TPM_RESULT TPM_ParentSignEK(TPM_NONCE *externalData, TPM_PCR_SELECTION *sel,
78 TPM_AUTH *auth1, UINT32 *sigSize, BYTE **sig)
79@@ -191,7 +192,7 @@ TPM_RESULT TPM_ParentSignEK(TPM_NONCE *externalData, TPM_PCR_SELECTION *sel,
80 TPM_PUBKEY pubKey;
81 TPM_RESULT res;
82 TPM_DIGEST hres;
83-
84+ UINT32 extraInfoFlags = 0;
85 info("TPM_ParentSignEK()");
86
87 res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
88@@ -206,7 +207,7 @@ TPM_RESULT TPM_ParentSignEK(TPM_NONCE *externalData, TPM_PCR_SELECTION *sel,
89 res = TPM_FAIL;
90
91 if (res == TPM_SUCCESS)
92- res = VTPM_GetParentQuote(&hres, sel, sigSize, sig);
93+ res = VTPM_GetParentQuote((TPM_NONCE*)&hres, sel, extraInfoFlags, sigSize, sig);
94
95 free_TPM_PUBKEY(pubKey);
96 return res;
97@@ -218,7 +219,7 @@ static const BYTE dquot_hdr[] = {
98
99 TPM_RESULT TPM_DeepQuote(TPM_NONCE *externalData, TPM_PCR_SELECTION *myPCR,
100 TPM_PCR_SELECTION *ptPCR, TPM_AUTH *auth1,
101- UINT32 *sigSize, BYTE **sig)
102+ UINT32 extraInfoFlags, UINT32 *quote_blob_size, BYTE **quote_blob)
103 {
104 TPM_RESULT res;
105 TPM_DIGEST hres;
106@@ -253,7 +254,7 @@ TPM_RESULT TPM_DeepQuote(TPM_NONCE *externalData, TPM_PCR_SELECTION *myPCR,
107
108 tpm_free(buf);
109
110- res = VTPM_GetParentQuote(&hres, ptPCR, sigSize, sig);
111+ res = VTPM_GetParentQuote((TPM_NONCE*)&hres, ptPCR, extraInfoFlags, quote_blob_size, quote_blob);
112
113 return res;
114 }
115diff --git a/tpm/tpm_marshalling.h b/tpm/tpm_marshalling.h
116index d510ebe..2e0c008 100644
117--- a/tpm/tpm_marshalling.h
118+++ b/tpm/tpm_marshalling.h
119@@ -268,6 +268,8 @@ static inline int tpm_unmarshal_BOOL(BYTE **ptr, UINT32 *length, BOOL *v)
120 #define tpm_unmarshal_TPM_REDIR_COMMAND tpm_unmarshal_UINT32
121 #define tpm_marshal_DAAHANDLE tpm_marshal_UINT32
122 #define tpm_unmarshal_DAAHANDLE tpm_unmarshal_UINT32
123+#define tpm_marshal_TPM_DEEP_QUOTE_INFO tpm_marshal_UINT32
124+#define tpm_unmarshal_TPM_DEEP_QUOTE_INFO tpm_unmarshal_UINT32
125
126 int tpm_marshal_UINT32_ARRAY(BYTE **ptr, UINT32 *length, UINT32 *v, UINT32 n);
127 int tpm_unmarshal_UINT32_ARRAY(BYTE **ptr, UINT32 *length, UINT32 *v, UINT32 n);
diff --git a/recipes-extended/xen/files/vtpm-deepquote.patch b/recipes-extended/xen/files/vtpm-deepquote.patch
new file mode 100644
index 00000000..6344f387
--- /dev/null
+++ b/recipes-extended/xen/files/vtpm-deepquote.patch
@@ -0,0 +1,187 @@
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:
diff --git a/recipes-extended/xen/files/vtpm-implicit-fallthrough.patch b/recipes-extended/xen/files/vtpm-implicit-fallthrough.patch
new file mode 100644
index 00000000..e95d41fc
--- /dev/null
+++ b/recipes-extended/xen/files/vtpm-implicit-fallthrough.patch
@@ -0,0 +1,10 @@
1--- a/tpm/tpm_cmd_handler.c.orig 2017-04-27 13:37:14.408000000 +0200
2+++ b/tpm/tpm_cmd_handler.c 2017-04-27 13:39:53.585000000 +0200
3@@ -3397,6 +3397,7 @@
4 sizeof(rsp->auth2->nonceOdd.nonce));
5 tpm_hmac_update(&hmac, (BYTE*)&rsp->auth2->continueAuthSession, 1);
6 tpm_hmac_final(&hmac, rsp->auth2->auth);
7+ /* fall-thru */
8 case TPM_TAG_RSP_AUTH1_COMMAND:
9 tpm_hmac_init(&hmac, rsp->auth1->secret, sizeof(rsp->auth1->secret));
10 tpm_hmac_update(&hmac, rsp->auth1->digest, sizeof(rsp->auth1->digest));
diff --git a/recipes-extended/xen/files/vtpm-locality.patch b/recipes-extended/xen/files/vtpm-locality.patch
new file mode 100644
index 00000000..8ab7dea6
--- /dev/null
+++ b/recipes-extended/xen/files/vtpm-locality.patch
@@ -0,0 +1,50 @@
1diff --git a/tpm/tpm_capability.c b/tpm/tpm_capability.c
2index 60bbb90..f8f7f0f 100644
3--- a/tpm/tpm_capability.c
4+++ b/tpm/tpm_capability.c
5@@ -949,6 +949,8 @@ static TPM_RESULT set_vendor(UINT32 subCap, BYTE *setValue,
6 UINT32 setValueSize, BOOL ownerAuth,
7 BOOL deactivated, BOOL disabled)
8 {
9+ if (tpmData.stany.flags.localityModifier != 8)
10+ return TPM_BAD_PARAMETER;
11 /* set the capability area with the specified data, on failure
12 deactivate the TPM */
13 switch (subCap) {
14diff --git a/tpm/tpm_cmd_handler.c b/tpm/tpm_cmd_handler.c
15index 288d1ce..9e1cfb4 100644
16--- a/tpm/tpm_cmd_handler.c
17+++ b/tpm/tpm_cmd_handler.c
18@@ -4132,7 +4132,7 @@ void tpm_emulator_shutdown()
19 tpm_extern_release();
20 }
21
22-int tpm_handle_command(const uint8_t *in, uint32_t in_size, uint8_t **out, uint32_t *out_size)
23+int tpm_handle_command(const uint8_t *in, uint32_t in_size, uint8_t **out, uint32_t *out_size, int locality)
24 {
25 TPM_REQUEST req;
26 TPM_RESPONSE rsp;
27@@ -4140,7 +4140,9 @@ int tpm_handle_command(const uint8_t *in, uint32_t in_size, uint8_t **out, uint3
28 UINT32 len;
29 BOOL free_out;
30
31- debug("tpm_handle_command()");
32+ debug("tpm_handle_command(%d)", locality);
33+ if (locality != -1)
34+ tpmData.stany.flags.localityModifier = locality;
35
36 /* we need the whole packet at once, otherwise unmarshalling will fail */
37 if (tpm_unmarshal_TPM_REQUEST((uint8_t**)&in, &in_size, &req) != 0) {
38diff --git a/tpm/tpm_emulator.h b/tpm/tpm_emulator.h
39index eed749e..4c228bd 100644
40--- a/tpm/tpm_emulator.h
41+++ b/tpm/tpm_emulator.h
42@@ -59,7 +59,7 @@ void tpm_emulator_shutdown(void);
43 * its usage. In case of an error, all internally allocated memory
44 * is released and the the state of out and out_size is unspecified.
45 */
46-int tpm_handle_command(const uint8_t *in, uint32_t in_size, uint8_t **out, uint32_t *out_size);
47+int tpm_handle_command(const uint8_t *in, uint32_t in_size, uint8_t **out, uint32_t *out_size, int locality);
48
49 #endif /* _TPM_EMULATOR_H_ */
50
diff --git a/recipes-extended/xen/files/vtpm-parent-sign-ek.patch b/recipes-extended/xen/files/vtpm-parent-sign-ek.patch
new file mode 100644
index 00000000..14e66eee
--- /dev/null
+++ b/recipes-extended/xen/files/vtpm-parent-sign-ek.patch
@@ -0,0 +1,196 @@
1diff --git a/tpm/tpm_cmd_handler.c b/tpm/tpm_cmd_handler.c
2index 9e1cfb4..0fabf98 100644
3--- a/tpm/tpm_cmd_handler.c
4+++ b/tpm/tpm_cmd_handler.c
5@@ -3312,6 +3312,37 @@ static TPM_RESULT execute_TPM_OwnerReadPubek(TPM_REQUEST *req, TPM_RESPONSE *rsp
6 return res;
7 }
8
9+static TPM_RESULT execute_TPM_ParentSignEK(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 targetPCR;
18+
19+ tpm_compute_in_param_digest(req);
20+
21+ ptr = req->param;
22+ len = req->paramSize;
23+ if (tpm_unmarshal_TPM_NONCE(&ptr, &len, &nonce)
24+ || tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &targetPCR)
25+ || len != 0) return TPM_BAD_PARAMETER;
26+
27+ res = TPM_ParentSignEK(&nonce, &targetPCR, &req->auth1, &sigSize, &sig);
28+ if (res != TPM_SUCCESS) return res;
29+ rsp->paramSize = len = sigSize;
30+ rsp->param = ptr = tpm_malloc(len);
31+ if (ptr == NULL || tpm_marshal_BLOB(&ptr, &len, sig, sigSize)) {
32+ tpm_free(rsp->param);
33+ res = TPM_FAIL;
34+ }
35+ tpm_free(sig);
36+
37+ return res;
38+}
39+
40 static void tpm_setup_rsp_auth(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp)
41 {
42 tpm_hmac_ctx_t hmac;
43@@ -4062,6 +4093,11 @@ void tpm_execute_command(TPM_REQUEST *req, TPM_RESPONSE *rsp)
44 res = execute_TPM_OwnerReadPubek(req, rsp);
45 break;
46
47+ case TPM_ORD_ParentSignEK:
48+ debug("[TPM_ORD_ParentSignEK]");
49+ res = execute_TPM_ParentSignEK(req, rsp);
50+ break;
51+
52 default:
53 #ifdef MTM_EMULATOR
54 res = mtm_execute_command(req, rsp);
55diff --git a/tpm/tpm_commands.h b/tpm/tpm_commands.h
56index a7666f6..7fef934 100644
57--- a/tpm/tpm_commands.h
58+++ b/tpm/tpm_commands.h
59@@ -3054,6 +3054,23 @@ TPM_RESULT TPM_OwnerReadPubek(
60 TPM_PUBKEY *pubEndorsementKey
61 );
62
63+/**
64+ * TPM_ParentSignEK - gets a hardware TPM quote of a vTPM's EK
65+ * @externalData: [in] AntiReplay nonce to prevent replay of messages
66+ * @sel: [in] PCR selection for the hardware TPM's quote
67+ * @auth1: [in, out] Authorization protocol parameters
68+ * @sigSize: [out] The length of the returned digital signature
69+ * @sig: [out] The resulting digital signature and PCR values
70+ * Returns: TPM_SUCCESS on success, a TPM error code otherwise.
71+ */
72+TPM_RESULT TPM_ParentSignEK(
73+ TPM_NONCE *externalData,
74+ TPM_PCR_SELECTION *sel,
75+ TPM_AUTH *auth1,
76+ UINT32 *sigSize,
77+ BYTE **sig
78+);
79+
80 /*
81 * Error handling
82 * [tpm_error.c]
83diff --git a/tpm/tpm_credentials.c b/tpm/tpm_credentials.c
84index 9cd64af..01f29e6 100644
85--- a/tpm/tpm_credentials.c
86+++ b/tpm/tpm_credentials.c
87@@ -180,3 +180,34 @@ TPM_RESULT TPM_OwnerReadInternalPub(TPM_KEY_HANDLE keyHandle, TPM_AUTH *auth1,
88 return TPM_BAD_PARAMETER;
89 }
90 }
91+
92+int endorsementKeyFresh = 0;
93+
94+TPM_RESULT VTPM_GetParentQuote(TPM_DIGEST* data, TPM_PCR_SELECTION *sel, UINT32 *sigSize, BYTE **sig);
95+
96+TPM_RESULT TPM_ParentSignEK(TPM_NONCE *externalData, TPM_PCR_SELECTION *sel,
97+ TPM_AUTH *auth1, UINT32 *sigSize, BYTE **sig)
98+{
99+ TPM_PUBKEY pubKey;
100+ TPM_RESULT res;
101+ TPM_DIGEST hres;
102+
103+ info("TPM_ParentSignEK()");
104+
105+ res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
106+ if (res != TPM_SUCCESS) return res;
107+
108+ if (!endorsementKeyFresh) return TPM_DISABLED_CMD;
109+
110+ res = tpm_get_pubek(&pubKey);
111+ if (res != TPM_SUCCESS) return res;
112+
113+ if (tpm_compute_pubkey_checksum(externalData, &pubKey, &hres))
114+ res = TPM_FAIL;
115+
116+ if (res == TPM_SUCCESS)
117+ res = VTPM_GetParentQuote(&hres, sel, sigSize, sig);
118+
119+ free_TPM_PUBKEY(pubKey);
120+ return res;
121+}
122diff --git a/tpm/tpm_data.c b/tpm/tpm_data.c
123index 50c9697..6a0c499 100644
124--- a/tpm/tpm_data.c
125+++ b/tpm/tpm_data.c
126@@ -76,6 +76,8 @@ static void init_timeouts(void)
127 tpmData.permanent.data.cmd_durations[2] = 1000;
128 }
129
130+extern int endorsementKeyFresh;
131+
132 void tpm_init_data(void)
133 {
134 /* endorsement key */
135@@ -157,6 +159,7 @@ void tpm_init_data(void)
136 if (tpmConf & TPM_CONF_GENERATE_EK) {
137 /* generate a new endorsement key */
138 tpm_rsa_generate_key(&tpmData.permanent.data.endorsementKey, 2048);
139+ endorsementKeyFresh = 1;
140 } else {
141 /* setup endorsement key */
142 tpm_rsa_import_key(&tpmData.permanent.data.endorsementKey,
143diff --git a/tpm/tpm_structures.h b/tpm/tpm_structures.h
144index f746c05..b0f4625 100644
145--- a/tpm/tpm_structures.h
146+++ b/tpm/tpm_structures.h
147@@ -658,6 +658,49 @@ typedef struct tdTPM_CMK_MA_APPROVAL {
148 #define TPM_ORD_TickStampBlob 242
149 #define TPM_ORD_MAX 256
150
151+/* VTPM-only commands: */
152+/*
153+ * ParentSignEK - Proof of fresh provisioning and EK value
154+ *
155+ * Input:
156+ * TPM_TAG tag TPM_TAG_RQU_AUTH1_COMMAND
157+ * UINT32 paramSize Total size of request
158+ * TPM_COMMAND_CODE ordinal TPM_ORD_ParentSignEK
159+ * TPM_NONCE externData 20 bytes of external data
160+ * TPM_PCR_SELECTION ptSel PCR selection for physical TPM
161+ * ---
162+ * UINT32 authHandle Owner authorization session (OIAP)
163+ * TPM_NONCE nonceOdd Nonce for authHandle
164+ * BOOL continueAuth Continue flag for authHandle
165+ * TPM_AUTHDATA privAuth Authorization digest for command
166+ *
167+ * Output:
168+ * TPM_TAG tag TPM_TAG_RSP_AUTH1_COMMAND
169+ * UINT32 paramSize Total size of response
170+ * TPM_RESULT returnCode Return code of the operation
171+ * BYTE[] sig Signature provided by physical TPM
172+ * TPM_PCRVALUE[] pcrValue Values of hardware PCRs used in the quote
173+ * ---
174+ * TPM_NONCE nonceEven Nonce for authHandle
175+ * BOOL continueAuth Continue flag for authHandle
176+ * TPM_AUTHDATA resAuth Authorization digest for response
177+ *
178+ * This command is only valid on the first boot of a vTPM; on any subsequent
179+ * boot, the command returns TPM_DISABLED_CMD. It is intended to be used to
180+ * provide evidence of proper platform configuration to the verifier/CA which is
181+ * responsible for the creation of the vTPM's endorsement credential, which will
182+ * be used on subsequent boots to certify AIKs via the usual Privacy CA protocol.
183+ *
184+ * The values of the virtual TPM's PCRs are not included in the response.
185+ * The signature is a standard TPM_Quote response from the physical TPM; its
186+ * externalData is the SHA1 hash of the following structure:
187+ * TPM_PUBKEY pubEK The vTPM's public EK
188+ * TPM_NONCE externData From input to the deep quote
189+ *
190+ * This structure was chosen to match the return of TPM_ReadPubek
191+ */
192+#define TPM_ORD_ParentSignEK (TPM_VENDOR_COMMAND | TPM_ORD_ReadPubek)
193+
194 /*
195 * TCS Ordinals ([TPM_Part2], Section 17.1)
196 *