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