de02777d9953e71ad9581a582a76d6d159e547f7
[aaf/sshsm.git] / TPM2-Plugin / lib / include / tpm2_util.h
1 //**********************************************************************;
2 // Copyright (c) 2017, Intel Corporation
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the name of Intel Corporation nor the names of its contributors
16 // may be used to endorse or promote products derived from this software without
17 // specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29 // THE POSSIBILITY OF SUCH DAMAGE.
30 //**********************************************************************;
31 #ifndef STRING_BYTES_H
32 #define STRING_BYTES_H
33
34 #include <stdbool.h>
35 #include <stdint.h>
36 #include <stdio.h>
37
38 #include <tss2/tss2_sys.h>
39
40 #include "tpm2_error.h"
41
42 #if defined (__GNUC__)
43 #define COMPILER_ATTR(...) __attribute__((__VA_ARGS__))
44 #else
45 #define COMPILER_ATTR(...)
46 #endif
47
48 #define xstr(s) str(s)
49 #define str(s) #s
50
51 #define UNUSED(x) (void)x
52
53 #define ARRAY_LEN(x) (sizeof(x)/sizeof(x[0]))
54
55 #define BUFFER_SIZE(type, field) (sizeof((((type *)NULL)->field)))
56
57 #define TSS2_APP_RC_LAYER TSS2_RC_LAYER(5)
58
59 #define TPM2B_TYPE_INIT(type, field) { .size = BUFFER_SIZE(type, field), }
60 #define TPM2B_INIT(xsize) { .size = xsize, }
61 #define TPM2B_EMPTY_INIT TPM2B_INIT(0)
62 #define TPM2B_SENSITIVE_CREATE_EMPTY_INIT { \
63            .sensitive = { \
64                 .data = {   \
65                     .size = 0 \
66                 }, \
67                 .userAuth = {   \
68                     .size = 0 \
69                 } \
70             } \
71     }
72
73 #define TPMS_AUTH_COMMAND_INIT(session_handle) { \
74         .sessionHandle = session_handle,\
75             .nonce = TPM2B_EMPTY_INIT, \
76             .sessionAttributes = TPMA_SESSION_CONTINUESESSION, \
77             .hmac = TPM2B_EMPTY_INIT \
78     }
79
80 #define TPMS_AUTH_COMMAND_EMPTY_INIT TPMS_AUTH_COMMAND_INIT(0)
81
82
83 #define TPMT_TK_CREATION_EMPTY_INIT { \
84         .tag = 0, \
85                 .hierarchy = 0, \
86                 .digest = TPM2B_EMPTY_INIT \
87     }
88
89 #define TPML_PCR_SELECTION_EMPTY_INIT { \
90         .count = 0, \
91     } //ignore pcrSelections since count is 0.
92
93 #define TPMS_CAPABILITY_DATA_EMPTY_INIT { \
94         .capability = 0, \
95     } // ignore data since capability is 0.
96
97 #define TPMT_TK_HASHCHECK_EMPTY_INIT { \
98                 .tag = 0, \
99                 .hierarchy = 0, \
100                 .digest = TPM2B_EMPTY_INIT \
101     }
102
103 #define TSS2L_SYS_AUTH_COMMAND_INIT(cnt, array) { \
104         .count = cnt, \
105         .auths = array, \
106     }
107
108 /*
109  * This macro is useful as a wrapper around SAPI functions to automatically
110  * retry function calls when the RC is TPM2_RC_RETRY.
111  */
112 #define TSS2_RETRY_EXP(expression)                         \
113     ({                                                     \
114         TSS2_RC __result = 0;                              \
115         do {                                               \
116             __result = (expression);                       \
117         } while (tpm2_error_get(__result) == TPM2_RC_RETRY); \
118         __result;                                          \
119     })
120
121 typedef struct {
122     UINT16 size;
123     BYTE buffer[0];
124 } TPM2B;
125
126 int tpm2_util_hex_to_byte_structure(const char *inStr, UINT16 *byteLenth, BYTE *byteBuffer);
127
128 /**
129  * Appends a TPM2B buffer to a MAX buffer.
130  * @param result
131  *  The MAX buffer to append to
132  * @param append
133  *  The buffer to append to result.
134  * @return
135  *  true on success, false otherwise.
136  */
137 bool tpm2_util_concat_buffer(TPM2B_MAX_BUFFER *result, TPM2B *append);
138
139 /**
140  * Converts a numerical string into a uint32 value.
141  * @param str
142  *  The numerical string to convert.
143  * @param value
144  *  The value to store the conversion into.
145  * @return
146  *  true on success, false otherwise.
147  */
148 bool tpm2_util_string_to_uint32(const char *str, uint32_t *value);
149
150 /**
151  * Converts a numerical string into a uint16 value.
152  * @param str
153  *  The numerical string to convert.
154  * @param value
155  *  The value to store the conversion into.
156  * @return
157  *  true on success, false otherwise.
158  */
159 bool tpm2_util_string_to_uint16(const char *str, uint16_t *value);
160
161 /**
162  * Prints an xxd compatible hexdump to stdout if output is enabled,
163  * ie no -Q option.
164  *
165  * @param data
166  *  The data to print.
167  * @param len
168  *  The length of the data.
169  */
170 void tpm2_util_hexdump(const BYTE *data, size_t len);
171
172 /**
173  * Prints a file as a hex string to stdout if quiet mode
174  * is not enabled.
175  * ie no -Q option.
176  *
177  * @param fd
178  *  A readable open file.
179  * @param len
180  *  The length of the data to read and print.
181  * @return
182  *  true if len bytes were successfully read and printed,
183  *  false otherwise
184  */
185 bool tpm2_util_hexdump_file(FILE *fd, size_t len);
186
187 /**
188  * Prints a TPM2B as a hex dump.
189  * @param buffer the TPM2B to print.
190  */
191 static inline void tpm2_util_print_tpm2b(TPM2B *buffer) {
192
193     return tpm2_util_hexdump(buffer->buffer, buffer->size);
194 }
195
196 /**
197  * Reads a TPM2B object from FILE* and prints data in hex.
198  * @param fd
199  *  A readable open file.
200  */
201 bool tpm2_util_print_tpm2b_file(FILE *fd);
202
203 /**
204  * Checks if the host is big endian
205  * @return
206  *  True of the host is big endian false otherwise.
207  */
208 bool tpm2_util_is_big_endian(void);
209
210 /**
211  * Swaps the endianess of 16 bit value.
212  * @param data
213  *  A 16 bit value to swap the endianess on.
214  * @return
215  * The 16 bit value with the endianess swapped.
216  */
217 UINT16 tpm2_util_endian_swap_16(UINT16 data);
218
219 /**
220  * Just like string_bytes_endian_convert_16 but for 32 bit values.
221  */
222 UINT32 tpm2_util_endian_swap_32(UINT32 data);
223
224 /**
225  * Just like string_bytes_endian_convert_16 but for 64 bit values.
226  */
227 UINT64 tpm2_util_endian_swap_64(UINT64 data);
228
229 /**
230  * Converts a 16 bit value from host endianess to network endianess.
231  * @param data
232  *  The data to possibly swap endianess.
233  * @return
234  *  The swapped data.
235  */
236 UINT16 tpm2_util_hton_16(UINT16 data);
237
238 /**
239  * Just like string_bytes_endian_hton_16 but for 32 bit values.
240  */
241 UINT32 tpm2_util_hton_32(UINT32 data);
242
243 /**
244  * Just like string_bytes_endian_hton_16 but for 64 bit values.
245  */
246 UINT64 tpm2_util_hton_64(UINT64 data);
247
248 /**
249  * Converts a 16 bit value from network endianess to host endianess.
250  * @param data
251  *  The data to possibly swap endianess.
252  * @return
253  *  The swapped data.
254  */
255 UINT16 tpm2_util_ntoh_16(UINT16 data);
256
257 /**
258  * Just like string_bytes_endian_ntoh_16 but for 32 bit values.
259  */
260 UINT32 tpm2_util_ntoh_32(UINT32 data);
261
262 /**
263  * Just like string_bytes_endian_ntoh_16 but for 64 bit values.
264  */
265 UINT64 tpm2_util_ntoh_64(UINT64 data);
266
267 /**
268  * Counts the number of set bits aka a population count.
269  * @param data
270  *  The data to count set bits in.
271  * @return
272  *  The number of set bits or population count.
273  */
274 UINT32 tpm2_util_pop_count(UINT32 data);
275
276 /**
277  * Prints whitespace indention for yaml output.
278  * @param indent_count
279  *  Number of times to indent
280  */
281 void print_yaml_indent(size_t indent_count);
282
283 /**
284  * Convert a TPM2B_PUBLIC into a yaml format and output if not quiet.
285  * @param public
286  *  The TPM2B_PUBLIC to output in YAML format.
287  */
288 void tpm2_util_public_to_yaml(TPM2B_PUBLIC *public);
289
290
291 /**
292  * Convert a TPMA_OBJECT to a yaml format and output if not quiet.
293  * @param obj
294  *  The TPMA_OBJECT attributes to print.
295  */
296 void tpm2_util_tpma_object_to_yaml(TPMA_OBJECT obj);
297
298 #endif /* STRING_BYTES_H */