1 | /* |
2 | * tpm_ioctl.h |
3 | * |
4 | * (c) Copyright IBM Corporation 2014, 2015. |
5 | * |
6 | * This file is licensed under the terms of the 3-clause BSD license |
7 | */ |
8 | |
9 | #ifndef TPM_IOCTL_H |
10 | #define TPM_IOCTL_H |
11 | |
12 | #include <sys/uio.h> |
13 | #include <sys/ioctl.h> |
14 | |
15 | /* |
16 | * Every response from a command involving a TPM command execution must hold |
17 | * the ptm_res as the first element. |
18 | * ptm_res corresponds to the error code of a command executed by the TPM. |
19 | */ |
20 | |
21 | typedef uint32_t ptm_res; |
22 | |
23 | /* PTM_GET_TPMESTABLISHED: get the establishment bit */ |
24 | struct ptm_est { |
25 | union { |
26 | struct { |
27 | ptm_res tpm_result; |
28 | unsigned char bit; /* TPM established bit */ |
29 | } resp; /* response */ |
30 | } u; |
31 | }; |
32 | |
33 | /* PTM_RESET_TPMESTABLISHED: reset establishment bit */ |
34 | struct ptm_reset_est { |
35 | union { |
36 | struct { |
37 | uint8_t loc; /* locality to use */ |
38 | } req; /* request */ |
39 | struct { |
40 | ptm_res tpm_result; |
41 | } resp; /* response */ |
42 | } u; |
43 | }; |
44 | |
45 | /* PTM_INIT */ |
46 | struct ptm_init { |
47 | union { |
48 | struct { |
49 | uint32_t init_flags; /* see definitions below */ |
50 | } req; /* request */ |
51 | struct { |
52 | ptm_res tpm_result; |
53 | } resp; /* response */ |
54 | } u; |
55 | }; |
56 | |
57 | /* above init_flags */ |
58 | #define PTM_INIT_FLAG_DELETE_VOLATILE (1 << 0) |
59 | /* delete volatile state file after reading it */ |
60 | |
61 | /* PTM_SET_LOCALITY */ |
62 | struct ptm_loc { |
63 | union { |
64 | struct { |
65 | uint8_t loc; /* locality to set */ |
66 | } req; /* request */ |
67 | struct { |
68 | ptm_res tpm_result; |
69 | } resp; /* response */ |
70 | } u; |
71 | }; |
72 | |
73 | /* PTM_HASH_DATA: hash given data */ |
74 | struct ptm_hdata { |
75 | union { |
76 | struct { |
77 | uint32_t length; |
78 | uint8_t data[4096]; |
79 | } req; /* request */ |
80 | struct { |
81 | ptm_res tpm_result; |
82 | } resp; /* response */ |
83 | } u; |
84 | }; |
85 | |
86 | /* |
87 | * size of the TPM state blob to transfer; x86_64 can handle 8k, |
88 | * ppc64le only ~7k; keep the response below a 4k page size |
89 | */ |
90 | #define PTM_STATE_BLOB_SIZE (3 * 1024) |
91 | |
92 | /* |
93 | * The following is the data structure to get state blobs from the TPM. |
94 | * If the size of the state blob exceeds the PTM_STATE_BLOB_SIZE, multiple reads |
95 | * with this ioctl and with adjusted offset are necessary. All bytes |
96 | * must be transferred and the transfer is done once the last byte has been |
97 | * returned. |
98 | * It is possible to use the read() interface for reading the data; however, the |
99 | * first bytes of the state blob will be part of the response to the ioctl(); a |
100 | * subsequent read() is only necessary if the total length (totlength) exceeds |
101 | * the number of received bytes. seek() is not supported. |
102 | */ |
103 | struct ptm_getstate { |
104 | union { |
105 | struct { |
106 | uint32_t state_flags; /* may be: PTM_STATE_FLAG_DECRYPTED */ |
107 | uint32_t type; /* which blob to pull */ |
108 | uint32_t offset; /* offset from where to read */ |
109 | } req; /* request */ |
110 | struct { |
111 | ptm_res tpm_result; |
112 | uint32_t state_flags; /* may be: PTM_STATE_FLAG_ENCRYPTED */ |
113 | uint32_t totlength; /* total length that will be transferred */ |
114 | uint32_t length; /* number of bytes in following buffer */ |
115 | uint8_t data[PTM_STATE_BLOB_SIZE]; |
116 | } resp; /* response */ |
117 | } u; |
118 | }; |
119 | |
120 | /* TPM state blob types */ |
121 | #define PTM_BLOB_TYPE_PERMANENT 1 |
122 | #define PTM_BLOB_TYPE_VOLATILE 2 |
123 | #define PTM_BLOB_TYPE_SAVESTATE 3 |
124 | |
125 | /* state_flags above : */ |
126 | #define PTM_STATE_FLAG_DECRYPTED 1 /* on input: get decrypted state */ |
127 | #define PTM_STATE_FLAG_ENCRYPTED 2 /* on output: state is encrypted */ |
128 | |
129 | /* |
130 | * The following is the data structure to set state blobs in the TPM. |
131 | * If the size of the state blob exceeds the PTM_STATE_BLOB_SIZE, multiple |
132 | * 'writes' using this ioctl are necessary. The last packet is indicated |
133 | * by the length being smaller than the PTM_STATE_BLOB_SIZE. |
134 | * The very first packet may have a length indicator of '0' enabling |
135 | * a write() with all the bytes from a buffer. If the write() interface |
136 | * is used, a final ioctl with a non-full buffer must be made to indicate |
137 | * that all data were transferred (a write with 0 bytes would not work). |
138 | */ |
139 | struct ptm_setstate { |
140 | union { |
141 | struct { |
142 | uint32_t state_flags; /* may be PTM_STATE_FLAG_ENCRYPTED */ |
143 | uint32_t type; /* which blob to set */ |
144 | uint32_t length; /* length of the data; |
145 | use 0 on the first packet to |
146 | transfer using write() */ |
147 | uint8_t data[PTM_STATE_BLOB_SIZE]; |
148 | } req; /* request */ |
149 | struct { |
150 | ptm_res tpm_result; |
151 | } resp; /* response */ |
152 | } u; |
153 | }; |
154 | |
155 | /* |
156 | * PTM_GET_CONFIG: Data structure to get runtime configuration information |
157 | * such as which keys are applied. |
158 | */ |
159 | struct ptm_getconfig { |
160 | union { |
161 | struct { |
162 | ptm_res tpm_result; |
163 | uint32_t flags; |
164 | } resp; /* response */ |
165 | } u; |
166 | }; |
167 | |
168 | #define PTM_CONFIG_FLAG_FILE_KEY 0x1 |
169 | #define PTM_CONFIG_FLAG_MIGRATION_KEY 0x2 |
170 | |
171 | /* |
172 | * PTM_SET_BUFFERSIZE: Set the buffer size to be used by the TPM. |
173 | * A 0 on input queries for the current buffer size. Any other |
174 | * number will try to set the buffer size. The returned number is |
175 | * the buffer size that will be used, which can be larger than the |
176 | * requested one, if it was below the minimum, or smaller than the |
177 | * requested one, if it was above the maximum. |
178 | */ |
179 | struct ptm_setbuffersize { |
180 | union { |
181 | struct { |
182 | uint32_t buffersize; /* 0 to query for current buffer size */ |
183 | } req; /* request */ |
184 | struct { |
185 | ptm_res tpm_result; |
186 | uint32_t buffersize; /* buffer size in use */ |
187 | uint32_t minsize; /* min. supported buffer size */ |
188 | uint32_t maxsize; /* max. supported buffer size */ |
189 | } resp; /* response */ |
190 | } u; |
191 | }; |
192 | |
193 | |
194 | typedef uint64_t ptm_cap; |
195 | typedef struct ptm_est ptm_est; |
196 | typedef struct ptm_reset_est ptm_reset_est; |
197 | typedef struct ptm_loc ptm_loc; |
198 | typedef struct ptm_hdata ptm_hdata; |
199 | typedef struct ptm_init ptm_init; |
200 | typedef struct ptm_getstate ptm_getstate; |
201 | typedef struct ptm_setstate ptm_setstate; |
202 | typedef struct ptm_getconfig ptm_getconfig; |
203 | typedef struct ptm_setbuffersize ptm_setbuffersize; |
204 | |
205 | /* capability flags returned by PTM_GET_CAPABILITY */ |
206 | #define PTM_CAP_INIT (1) |
207 | #define PTM_CAP_SHUTDOWN (1 << 1) |
208 | #define PTM_CAP_GET_TPMESTABLISHED (1 << 2) |
209 | #define PTM_CAP_SET_LOCALITY (1 << 3) |
210 | #define PTM_CAP_HASHING (1 << 4) |
211 | #define PTM_CAP_CANCEL_TPM_CMD (1 << 5) |
212 | #define PTM_CAP_STORE_VOLATILE (1 << 6) |
213 | #define PTM_CAP_RESET_TPMESTABLISHED (1 << 7) |
214 | #define PTM_CAP_GET_STATEBLOB (1 << 8) |
215 | #define PTM_CAP_SET_STATEBLOB (1 << 9) |
216 | #define PTM_CAP_STOP (1 << 10) |
217 | #define PTM_CAP_GET_CONFIG (1 << 11) |
218 | #define PTM_CAP_SET_DATAFD (1 << 12) |
219 | #define PTM_CAP_SET_BUFFERSIZE (1 << 13) |
220 | |
221 | enum { |
222 | PTM_GET_CAPABILITY = _IOR('P', 0, ptm_cap), |
223 | PTM_INIT = _IOWR('P', 1, ptm_init), |
224 | PTM_SHUTDOWN = _IOR('P', 2, ptm_res), |
225 | PTM_GET_TPMESTABLISHED = _IOR('P', 3, ptm_est), |
226 | PTM_SET_LOCALITY = _IOWR('P', 4, ptm_loc), |
227 | PTM_HASH_START = _IOR('P', 5, ptm_res), |
228 | PTM_HASH_DATA = _IOWR('P', 6, ptm_hdata), |
229 | PTM_HASH_END = _IOR('P', 7, ptm_res), |
230 | PTM_CANCEL_TPM_CMD = _IOR('P', 8, ptm_res), |
231 | PTM_STORE_VOLATILE = _IOR('P', 9, ptm_res), |
232 | PTM_RESET_TPMESTABLISHED = _IOWR('P', 10, ptm_reset_est), |
233 | PTM_GET_STATEBLOB = _IOWR('P', 11, ptm_getstate), |
234 | PTM_SET_STATEBLOB = _IOWR('P', 12, ptm_setstate), |
235 | PTM_STOP = _IOR('P', 13, ptm_res), |
236 | PTM_GET_CONFIG = _IOR('P', 14, ptm_getconfig), |
237 | PTM_SET_DATAFD = _IOR('P', 15, ptm_res), |
238 | PTM_SET_BUFFERSIZE = _IOWR('P', 16, ptm_setbuffersize), |
239 | }; |
240 | |
241 | /* |
242 | * Commands used by the non-CUSE TPMs |
243 | * |
244 | * All messages container big-endian data. |
245 | * |
246 | * The return messages only contain the 'resp' part of the unions |
247 | * in the data structures above. Besides that the limits in the |
248 | * buffers above (ptm_hdata:u.req.data and ptm_get_state:u.resp.data |
249 | * and ptm_set_state:u.req.data) are 0xffffffff. |
250 | */ |
251 | enum { |
252 | CMD_GET_CAPABILITY = 1, |
253 | CMD_INIT, |
254 | CMD_SHUTDOWN, |
255 | CMD_GET_TPMESTABLISHED, |
256 | CMD_SET_LOCALITY, |
257 | CMD_HASH_START, |
258 | CMD_HASH_DATA, |
259 | CMD_HASH_END, |
260 | CMD_CANCEL_TPM_CMD, |
261 | CMD_STORE_VOLATILE, |
262 | CMD_RESET_TPMESTABLISHED, |
263 | CMD_GET_STATEBLOB, |
264 | CMD_SET_STATEBLOB, |
265 | CMD_STOP, |
266 | CMD_GET_CONFIG, |
267 | CMD_SET_DATAFD, |
268 | CMD_SET_BUFFERSIZE, |
269 | }; |
270 | |
271 | #endif /* TPM_IOCTL_H */ |
272 | |