1 /*
2  * Copyright (c) 2010-2012 United States Government, as represented by
3  * the Secretary of Defense.  All rights reserved.
4  *
5  * based off of the original tools/vtpm_manager code base which is:
6  * Copyright (c) 2005, Intel Corp.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  *   * Redistributions of source code must retain the above copyright
14  *     notice, this list of conditions and the following disclaimer.
15  *   * Redistributions in binary form must reproduce the above
16  *     copyright notice, this list of conditions and the following
17  *     disclaimer in the documentation and/or other materials provided
18  *     with the distribution.
19  *   * Neither the name of Intel Corporation nor the names of its
20  *     contributors may be used to endorse or promote products derived
21  *     from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
34  * OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36 
37 #ifndef VTPM_MANAGER_H
38 #define VTPM_MANAGER_H
39 
40 #define VTPM_TAG_REQ 0x01c1
41 #define VTPM_TAG_REQ2 0x01c2
42 #define VTPM_TAG_RSP 0x01c4
43 #define VTPM_TAG_RSP2 0x01c5
44 #define COMMAND_BUFFER_SIZE 4096
45 
46 // Header size
47 #define VTPM_COMMAND_HEADER_SIZE ( 2 + 4 + 4)
48 
49 //************************ Command Params ***************************
50 #define VTPM_QUOTE_FLAGS_HASH_UUID                  0x00000001
51 #define VTPM_QUOTE_FLAGS_VTPM_MEASUREMENTS          0x00000002
52 #define VTPM_QUOTE_FLAGS_GROUP_INFO                 0x00000004
53 #define VTPM_QUOTE_FLAGS_GROUP_PUBKEY               0x00000008
54 
55 //************************ Command Codes ****************************
56 #define VTPM_ORD_BASE       0x0000
57 #define TPM_VENDOR_COMMAND  0x02000000 // TPM Main, part 2, section 17.
58 #define VTPM_PRIV_BASE      (VTPM_ORD_BASE | TPM_VENDOR_COMMAND)
59 
60 /*
61  * Non-priviledged VTPM Commands:
62  *
63  * The PCRs available to read, extend, or quote may be limited to a given vTPM
64  * based on a local security policy (this is not yet implemented).
65  *
66  * vTPMs may request the following commands which will be forwarded directly to
67  * the physical TPM:
68  *
69  *   TPM_ORD_GetRandom
70  *   TPM_ORD_PcrRead
71  *   TPM_ORD_Extend
72  *
73  * In addition, the following command are available to all vTPMs:
74  */
75 
76 /**
77  * Store a persistent key blob to TPM Manager storage
78  * Input:
79  *  TPM_TAG         tag          VTPM_TAG_REQ
80  *  UINT32          paramSize    total size
81  *  UINT32          ordinal      VTPM_ORD_SAVEHASHKEY
82  *  BYTE[]          keyblob      52 or 64 bytes of key data
83  * Output:
84  *  TPM_TAG         tag          VTPM_TAG_RSP
85  *  UINT32          paramSize    total size
86  *  UINT32          status       return code
87  */
88 #define VTPM_ORD_SAVEHASHKEY      (VTPM_ORD_BASE + 1)
89 /**
90  * Load the persistent key blob from TPM Manager storage
91  * Input:
92  *  TPM_TAG         tag          VTPM_TAG_REQ
93  *  UINT32          paramSize    total size
94  *  UINT32          ordinal      VTPM_ORD_LOADHASHKEY
95  * Output:
96  *  TPM_TAG         tag          VTPM_TAG_RSP
97  *  UINT32          paramSize    total size
98  *  UINT32          status       return code
99  *  BYTE[]          keyblob      52 or 64 bytes of key data
100  */
101 #define VTPM_ORD_LOADHASHKEY      (VTPM_ORD_BASE + 2)
102 /**
103  * Get a kernel hash of the control domain for this vTPM
104  * Input:
105  *  TPM_TAG         tag          VTPM_TAG_REQ
106  *  UINT32          paramSize    total size
107  *  UINT32          ordinal      VTPM_ORD_GET_BOOT_HASH
108  * Output:
109  *  TPM_TAG         tag          VTPM_TAG_RSP
110  *  UINT32          paramSize    total size
111  *  UINT32          status       return code
112  *  TPM_DIGEST      digest       hash for the initial extend of PCR0
113  */
114 #define VTPM_ORD_GET_BOOT_HASH    (VTPM_ORD_BASE + 3)
115 /**
116  * Get a hardware TPM quote for this vTPM.  The quote will use the AIK
117  * associated with the group this vTPM was created in. Values specific to the
118  * vTPM will be extended to certain resettable PCRs.
119  * Additional info can be included when creating the signature by using
120  * quoteSelect as PCR selection and by setting flags param. The externData
121  * param for TPM_Quote is calculated as:
122  * externData = SHA1 (
123  *       extraInfoFlags
124  *       requestData
125  *       [SHA1 (
126  *          [SHA1 (UUIDs if requested)]
127  *          [SHA1 (vTPM measurements if requested)]
128  *          [SHA1 (vTPM group update policy if requested)]
129  *          [SHA1 (vTPM group public key if requested)]
130  *       ) if flags !=0 ]
131  * )
132  * The response param pcrValues is an array containing requested hashes used
133  * for externData calculation : UUIDs, vTPM measurements, vTPM group update
134  * policy, group public key. At the end of these hashes the PCR values are
135  * appended.
136  *
137  * Input:
138  *  TPM_TAG         tag          VTPM_TAG_REQ
139  *  UINT32          paramSize    total size
140  *  UINT32          ordinal      VTPM_ORD_GET_QUOTE
141  *  TPM_NONCE       externData   Data to be quoted
142  *  PCR_SELECTION   quoteSelect  PCR selection for quote.
143  *  UINT32          flags        Bit mask of VTPM_QUOTE_FLAGS_*
144  * Output:
145  *  TPM_TAG         tag          VTPM_TAG_RSP
146  *  UINT32          paramSize    total size
147  *  UINT32          status       return code
148  *  BYTE[]          signature    256 bytes of signature data
149  *  TPM_PCRVALUE[]  pcrValues    Values of additional SHA1 hashes requested,
150  *                               concatenated with PCRs selected by the request
151  */
152 #define VTPM_ORD_GET_QUOTE        (VTPM_ORD_BASE + 4)
153 
154 /*
155  * Resettable PCR values in TPM Manager quotes (VTPM_ORD_GET_QUOTE):
156  *
157  * PCR#16:
158  *     unused - debug PCR
159  *
160  * PCR#17-19: (cannot be reset by locality 2)
161  *     DRTM measurements
162  *
163  * PCR#20: Remains constant over the life of the vTPM group
164  *     SHA1(SAA pubkey)
165  *
166  * PCR#21: May change during the life; must be approved by SAA
167  *     SHA1(TPM_MGR_CFG_LIST)
168  *
169  * PCR#22: May change during the life; must be in the cfg_list
170  *     vTPM kernel build hash (truncated SHA256)
171  *     Note: this is currently set to 20 zero bytes
172  *
173  * PCR#23: Remains constant over the life of the vTPM; system-specific
174  *     group UUID || 00 00 00 00
175  *     vTPM UUID || 00 00 00 00
176  *
177  *
178  * Group-only PCR values (VTPM_ORD_GROUP_*) are the same except:
179  *
180  * PCR#22: unused (value is zero)
181  * PCR#23:
182  *     group UUID || 00 00 00 00
183  *
184  * The value of externalData for quotes using these PCRs is defined below; it is
185  * always a hash whose first 4 bytes identify the rest of the structure.
186  *
187  *
188  * The configuration list signed by a System Approval Agent (SAA) is:
189  *
190  * TPM_MGR_CFG_LIST:
191  *  UINT64               sequence      Monotonic sequence number
192  *  UINT32               pltCfgSize    Size of pltCfgs array
193  *  TPM_COMPOSITE_HASH[] pltCfgs       Valid platform configurations
194  *  UINT32               kernSize      Size of kernList array
195  *  TPM_HASH[]           kernList      Valid vTPM kernels
196  */
197 
198 /************************************\
199  * TPM Manager Management Interface *
200 \************************************/
201 
202 /**
203  * List groups
204  *
205  * Input:
206  *  TPM_TAG           tag          VTPM_TAG_REQ2
207  *  UINT32            paramSize    total size
208  *  UINT32            ordinal      VTPM_ORD_GROUP_LIST
209  * Output:
210  *  TPM_TAG           tag          VTPM_TAG_RSP
211  *  UINT32            paramSize    total size
212  *  UINT32            status       return code
213  *  UINT32            count        number of valid groups
214  */
215 #define VTPM_ORD_GROUP_LIST        (VTPM_PRIV_BASE + 0x101)
216 /**
217  * Create a group
218  *
219  * Input:
220  *  TPM_TAG           tag          VTPM_TAG_REQ2
221  *  UINT32            paramSize    total size
222  *  UINT32            ordinal      VTPM_ORD_GROUP_NEW
223  *  TPM_CHOSENID_HASH labelDigest  Data for the privacy CA
224  *  BYTE[256]         SAASigKey    RSA public signature key for the SAA
225  * Output:
226  *  TPM_TAG           tag          VTPM_TAG_RSP
227  *  UINT32            paramSize    total size
228  *  UINT32            status       return code
229  *  BYTE[16]          groupUUID    UUID for the group
230  *  BYTE[256]         aikPubKey    Public key of the AIK
231  *  BYTE[256]         aikBinding   TPM_IDENTITY_CONTENTS signature
232  */
233 #define VTPM_ORD_GROUP_NEW         (VTPM_PRIV_BASE + 0x102)
234 /**
235  * Delete a group
236  *
237  * Input:
238  *  TPM_TAG           tag          VTPM_TAG_REQ2
239  *  UINT32            paramSize    total size
240  *  UINT32            ordinal      VTPM_ORD_GROUP_DEL
241  *  UINT32            groupID      ID of the group to delete
242  * Output:
243  *  TPM_TAG           tag          VTPM_TAG_RSP
244  *  UINT32            paramSize    total size
245  *  UINT32            status       return code
246  */
247 #define VTPM_ORD_GROUP_DEL         (VTPM_PRIV_BASE + 0x103)
248 /**
249  * Activate the group's AIK (message from privacy CA)
250  *
251  * Input:
252  *  TPM_TAG           tag          VTPM_TAG_REQ2
253  *  UINT32            paramSize    total size
254  *  UINT32            ordinal      VTPM_ORD_GROUP_ACTIVATE
255  *  UINT32            groupID      ID of the group to activate
256  *  UINT32            blobSize
257  *  BYTE[]            blob         Blob from the privay CA
258  * Output:
259  *  TPM_TAG           tag          VTPM_TAG_RSP
260  *  UINT32            paramSize    total size
261  *  UINT32            status       return code
262  *  TPM_SYMMETRIC_KEY key          Output from TPM_ActivateIdentity
263  */
264 #define VTPM_ORD_GROUP_ACTIVATE    (VTPM_PRIV_BASE + 0x104)
265 /**
266  * Register this TPM manager slot with the SAA and provision its recovery data.
267  * The initial registration must be done with no reboots between the creation of
268  * the group and the execution of this command; it can only be done once.
269  *
270  * The ExternalData value is SHA1("REGR" || dhkx_1 || dhkx_2 || recoverBlob)
271  *
272  * Input:
273  *  TPM_TAG           tag          VTPM_TAG_REQ2
274  *  UINT32            paramSize    total size
275  *  UINT32            ordinal      VTPM_ORD_GROUP_REGISTER
276  *  UINT32            groupID      ID of the group to register
277  *  BYTE[256]         dhkx_1       One half of a diffie-hellman key exchange
278  *  BYTE[256]         SAAProof     Signature (using SAASigKey) of derivData
279  *  PCR_SELECTION     quoteSelect  PCR selection for quote.
280  * Output:
281  *  TPM_TAG           tag          VTPM_TAG_RSP
282  *  UINT32            paramSize    total size
283  *  UINT32            status       return code
284  *  BYTE[256]         dhkx_2       One half of a diffie-hellman key exchange
285  *  BYTE[32]          recoverBlob  Encrypted blob (using key derived from DH)
286  *  BYTE[256]         regProof     Quote using the group's AIK
287  */
288 #define VTPM_ORD_GROUP_REGISTER    (VTPM_PRIV_BASE + 0x105)
289 /**
290  * Update the configuration list
291  *
292  * Input:
293  *  TPM_TAG           tag          VTPM_TAG_REQ2
294  *  UINT32            paramSize    total size
295  *  UINT32            ordinal      VTPM_ORD_GROUP_UPDATE
296  *  UINT32            groupID      ID of the group to update
297  *  BYTE[256]         cfgListSig   Signature (using SAASigKey) of cfgList
298  *  TPM_MGR_CFG_LIST  cfgList      Configurations the group is valid in
299  *  PCR_SELECTION[]   selForCfgs   PCR selections used in the cfgList.pltCfgs
300  * Output:
301  *  TPM_TAG           tag          VTPM_TAG_RSP
302  *  UINT32            paramSize    total size
303  *  UINT32            status       return code
304  */
305 #define VTPM_ORD_GROUP_UPDATE      (VTPM_PRIV_BASE + 0x106)
306 /**
307  * Get the current contents of the group structure.
308  *
309  * Input:
310  *  TPM_TAG           tag          VTPM_TAG_REQ2
311  *  UINT32            paramSize    total size
312  *  UINT32            ordinal      VTPM_ORD_GROUP_SHOW
313  *  UINT32            groupID      ID of the group to view
314  * Output:
315  *  TPM_TAG           tag          VTPM_TAG_RSP
316  *  UINT32            paramSize    total size
317  *  UINT32            status       return code
318  *  BYTE[16]          groupUUID    UUID for the group
319  *  BYTE[256]         pubkey       public key of the SAA
320  *  TPM_MGR_CFG_LIST  cfgList      current list for this group
321  */
322 #define VTPM_ORD_GROUP_SHOW        (VTPM_PRIV_BASE + 0x107)
323 /**
324  * Get a quote of the current status of the TMA structure. This can be used to
325  * prove that an update has been applied; it is similar to VTPM_ORD_GET_QUOTE,
326  * but does not include measurements specific to any vTPM.
327  *
328  * The ExternalData value for the quote is SHA1("SHOW" || nonce)
329  *
330  * Input:
331  *  TPM_TAG           tag          VTPM_TAG_REQ2
332  *  UINT32            paramSize    total size
333  *  UINT32            ordinal      VTPM_ORD_GROUP_QUOTE
334  *  UINT32            groupID      ID of the group to view
335  *  TPM_NONCE         nonce        Anti-replay
336  *  PCR_SELECTION     quoteSelect  PCR selection for quote.
337  * Output:
338  *  TPM_TAG           tag          VTPM_TAG_RSP
339  *  UINT32            paramSize    total size
340  *  UINT32            status       return code
341  *  BYTE[]            signature    256 bytes of signature data
342  *  TPM_PCRVALUE[]    pcrValues    Values of PCRs selected by the request
343  */
344 #define VTPM_ORD_GROUP_QUOTE       (VTPM_PRIV_BASE + 0x108)
345 /**
346  * Prepare to use recovery data to open a currently-closed group.
347  *
348  * The ExternalData value is SHA1("RCVR" || nonce || dhkx_1)
349  *
350  * Input:
351  *  TPM_TAG           tag          VTPM_TAG_REQ2
352  *  UINT32            paramSize    total size
353  *  UINT32            ordinal      VTPM_ORD_GROUP_RECOVER1
354  *  UINT32            groupID      ID of the group to recover
355  *  TPM_KEY           proxyAIK     AIK to use for recovery quote
356  *  TPM_NONCE         nonce        Anti-replay by challenger
357  *  PCR_SELECTION     quoteSelect  PCR selection for quote
358  * Output:
359  *  TPM_TAG           tag          VTPM_TAG_RSP
360  *  UINT32            paramSize    total size
361  *  UINT32            status       return code
362  *  BYTE[256]         dhkx_1       One half of a diffie-hellman key exchange
363  *  BYTE[256]         signature    quote using proxyAIK
364  */
365 #define VTPM_ORD_GROUP_RECOVER1    (VTPM_PRIV_BASE + 0x109)
366 /**
367  * Use recovery data to open a currently-closed group
368  *
369  * Input:
370  *  TPM_TAG           tag          VTPM_TAG_REQ2
371  *  UINT32            paramSize    total size
372  *  UINT32            ordinal      VTPM_ORD_GROUP_RECOVER2
373  *  UINT32            groupID      ID of the group to recover
374  *  BYTE[256]         dhkx_2       One half of a diffie-hellman key exchange
375  *  BYTE[32]          recoverBlob  Encrypted blob (using key derived from DH)
376  * Output:
377  *  TPM_TAG           tag          VTPM_TAG_RSP
378  *  UINT32            paramSize    total size
379  *  UINT32            status       return code
380  */
381 #define VTPM_ORD_GROUP_RECOVER2    (VTPM_PRIV_BASE + 0x10A)
382 
383 /**
384  * List the UUIDs of vTPMs in an group. Multiple calls may be required to list
385  * all the vTPMs in an group; if the returned list is shorter than totalCount
386  * would imply, additional requests using the offest will be required
387  * to build the full list.
388  *
389  * Input:
390  *  TPM_TAG           tag          VTPM_TAG_REQ2
391  *  UINT32            paramSize    total size
392  *  UINT32            ordinal      VTPM_ORD_VTPM_LIST
393  *  UINT32            groupID      ID of the group to list
394  *  UINT32            offset       Offset to start the list at
395  * Output:
396  *  TPM_TAG           tag          VTPM_TAG_RSP
397  *  UINT32            paramSize    total size
398  *  UINT32            status       return code
399  *  UINT32            totalCount   Count of all vTPMs under this group
400  *  BYTE[]            uuids        List of UUIDs (16 bytes each)
401  */
402 #define VTPM_ORD_VTPM_LIST         (VTPM_PRIV_BASE + 0x201)
403 #define VTPM_ORD_VTPM_SHOW         (VTPM_PRIV_BASE + 0x202)
404 #define VTPM_ORD_VTPM_EDIT         (VTPM_PRIV_BASE + 0x203)
405 /**
406  * Input:
407  *  TPM_TAG           tag          VTPM_TAG_REQ2
408  *  UINT32            paramSize    total size
409  *  UINT32            ordinal      VTPM_ORD_VTPM_NEW
410  *  UINT32            groupID      ID of the group to modify
411  * Output:
412  *  TPM_TAG           tag          VTPM_TAG_RSP
413  *  UINT32            paramSize    total size
414  *  UINT32            status       return code
415  *  BYTE[16]          vtpmUUID     UUID for the vTPM
416  */
417 #define VTPM_ORD_VTPM_NEW          (VTPM_PRIV_BASE + 0x204)
418 /**
419  * Input:
420  *  TPM_TAG           tag          VTPM_TAG_REQ2
421  *  UINT32            paramSize    total size
422  *  UINT32            ordinal      VTPM_ORD_VTPM_DEL
423  ## UINT32            groupID      ID of the group to modify
424  *  BYTE[16]          vtpmUUID     UUID for the vTPM to delete
425  * Output:
426  *  TPM_TAG           tag          VTPM_TAG_RSP
427  *  UINT32            paramSize    total size
428  *  UINT32            status       return code
429  */
430 #define VTPM_ORD_VTPM_DEL          (VTPM_PRIV_BASE + 0x205)
431 
432 /**
433  * Generate an unbound AIK for the pTPM
434  *
435  * This unbound AIK can be used in the GROUP_RECOVER1 operation.
436  */
437 #define VTPM_ORD_MakeIdentity      (VTPM_PRIV_BASE + 0x301)
438 /**
439  * Activate an unbound AIK for the pTPM
440  */
441 #define VTPM_ORD_ActivateIdentity  (VTPM_PRIV_BASE + 0x302)
442 /**
443  * Get the EK from the pTPM
444  *
445  * Used for any AIK activation
446  */
447 #define VTPM_ORD_ReadPubek         (VTPM_PRIV_BASE + 0x303)
448 /**
449  * Define an NVRAM slot
450  */
451 #define VTPM_NV_DefineSpace        (VTPM_PRIV_BASE + 0x304)
452 /**
453  * Write to NVRAM
454  */
455 #define VTPM_NV_WriteValue         (VTPM_PRIV_BASE + 0x305)
456 /**
457  * Read from NVRAM
458  */
459 #define VTPM_NV_ReadValue          (VTPM_PRIV_BASE + 0x306)
460 
461 
462 //************************ Return Codes ****************************
463 #define VTPM_SUCCESS               0
464 #define VTPM_FAIL                  1
465 #define VTPM_UNSUPPORTED           2
466 #define VTPM_FORBIDDEN             3
467 #define VTPM_RESTORE_CONTEXT_FAILED    4
468 #define VTPM_INVALID_REQUEST       5
469 
470 #endif
471