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