1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /***********************************************************************
3  * Copyright (c) 2015 - 2017, Intel Corporation
4  *
5  * All rights reserved.
6  ***********************************************************************/
7 
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11 
12 #include <inttypes.h>
13 #include <string.h>
14 
15 #include "tss2_mu.h"
16 
17 #include "util/tss2_endian.h"
18 #define LOGMODULE marshal
19 #include "util/log.h"
20 
21 #define ADDR &
22 #define VAL
23 #define TAB_SIZE(tab) (sizeof(tab) / sizeof(tab[0]))
24 
25 #define TPML_MARSHAL(type, marshal_func, buf_name, op) \
26 TSS2_RC Tss2_MU_##type##_Marshal(type const *src, uint8_t buffer[], \
27                                  size_t buffer_size, size_t *offset) \
28 { \
29     size_t  local_offset = 0; \
30     UINT32 i, count = 0; \
31     TSS2_RC ret = TSS2_RC_SUCCESS; \
32 \
33     if (offset != NULL) { \
34         LOG_TRACE("offset non-NULL, initial value: %zu", *offset); \
35         local_offset = *offset; \
36     } \
37 \
38     if (src == NULL) { \
39         LOG_ERROR("src is NULL"); \
40         return TSS2_MU_RC_BAD_REFERENCE; \
41     } \
42 \
43     if (buffer == NULL && offset == NULL) { \
44         LOG_ERROR("buffer and offset parameter are NULL"); \
45         return TSS2_MU_RC_BAD_REFERENCE; \
46     } else if (buffer_size < local_offset || \
47                buffer_size - local_offset < sizeof(count)) { \
48         LOG_WARNING(\
49              "buffer_size: %zu with offset: %zu are insufficient for object " \
50              "of size %zu", \
51              buffer_size, \
52              local_offset, \
53              sizeof(count)); \
54         return TSS2_MU_RC_INSUFFICIENT_BUFFER; \
55     } \
56 \
57     if (src->count > TAB_SIZE(src->buf_name)) { \
58         LOG_WARNING("count too big"); \
59         return TSS2_SYS_RC_BAD_VALUE; \
60     } \
61 \
62     LOG_DEBUG(\
63          "Marshalling " #type " from 0x%" PRIxPTR " to buffer 0x%" PRIxPTR \
64          " at index 0x%zx", \
65          (uintptr_t)&src, \
66          (uintptr_t)buffer, \
67          local_offset); \
68 \
69     ret = Tss2_MU_UINT32_Marshal(src->count, buffer, buffer_size, &local_offset); \
70     if (ret) \
71         return ret; \
72 \
73     for (i = 0; i < src->count; i++) \
74     { \
75         ret = marshal_func(op src->buf_name[i], buffer, buffer_size, &local_offset); \
76         if (ret) \
77             return ret; \
78     } \
79     if (offset != NULL) { \
80         *offset = local_offset; \
81         LOG_DEBUG("offset parameter non-NULL updated to %zu", *offset); \
82     } \
83 \
84     return TSS2_RC_SUCCESS; \
85 }
86 
87 #define TPML_UNMARSHAL(type, unmarshal_func, buf_name) \
88 TSS2_RC Tss2_MU_##type##_Unmarshal(uint8_t const buffer[], size_t buffer_size, \
89                                    size_t *offset, type *dest) \
90 { \
91     size_t  local_offset = 0; \
92     UINT32 i, count = 0; \
93     TSS2_RC ret = TSS2_RC_SUCCESS; \
94 \
95     if (offset != NULL) { \
96         LOG_TRACE("offset non-NULL, initial value: %zu", *offset); \
97         local_offset = *offset; \
98     } \
99 \
100     if (buffer == NULL || (dest == NULL && offset == NULL)) { \
101         LOG_ERROR("buffer or dest and offset parameter are NULL"); \
102         return TSS2_MU_RC_BAD_REFERENCE; \
103     } else if (buffer_size < local_offset || \
104                sizeof(count) > buffer_size - local_offset) \
105     { \
106         LOG_WARNING(\
107              "buffer_size: %zu with offset: %zu are insufficient for object " \
108              "of size %zu", \
109              buffer_size, \
110              local_offset, \
111              sizeof(count)); \
112         return TSS2_MU_RC_INSUFFICIENT_BUFFER; \
113     } \
114 \
115     LOG_DEBUG(\
116          "Unmarshaling " #type " from 0x%" PRIxPTR " to buffer 0x%" PRIxPTR \
117          " at index 0x%zx", \
118          (uintptr_t)buffer, \
119          (uintptr_t)dest, \
120          local_offset); \
121 \
122     ret = Tss2_MU_UINT32_Unmarshal(buffer, buffer_size, &local_offset, &count); \
123     if (ret) \
124         return ret; \
125 \
126     if (count > TAB_SIZE(dest->buf_name)) { \
127         LOG_WARNING("count too big"); \
128         return TSS2_SYS_RC_MALFORMED_RESPONSE; \
129     } \
130 \
131     if (dest != NULL) { \
132         memset(dest, 0, sizeof(*dest)); \
133         dest->count = count; \
134     } \
135 \
136     for (i = 0; i < count; i++) \
137     { \
138         ret = unmarshal_func(buffer, buffer_size, &local_offset, \
139                              (dest == NULL)? NULL: &dest->buf_name[i]); \
140         if (ret) \
141             return ret; \
142     } \
143 \
144     if (offset != NULL) { \
145         *offset = local_offset; \
146         LOG_DEBUG("offset parameter non-NULL, updated to %zu", *offset); \
147     } \
148 \
149     return TSS2_RC_SUCCESS; \
150 }
151 
152 /*
153  * These macros expand to (un)marshal functions for each of the TPML types
154  * the specification part 2.
155  */
156 TPML_MARSHAL(TPML_CC, Tss2_MU_TPM2_CC_Marshal, commandCodes, VAL)
157 TPML_UNMARSHAL(TPML_CC, Tss2_MU_TPM2_CC_Unmarshal, commandCodes)
158 TPML_MARSHAL(TPML_CCA, Tss2_MU_TPMA_CC_Marshal, commandAttributes, VAL)
159 TPML_UNMARSHAL(TPML_CCA, Tss2_MU_TPMA_CC_Unmarshal, commandAttributes)
160 TPML_MARSHAL(TPML_ALG, Tss2_MU_UINT16_Marshal, algorithms, VAL)
161 TPML_UNMARSHAL(TPML_ALG, Tss2_MU_UINT16_Unmarshal, algorithms)
162 TPML_MARSHAL(TPML_HANDLE, Tss2_MU_UINT32_Marshal, handle, VAL)
163 TPML_UNMARSHAL(TPML_HANDLE, Tss2_MU_UINT32_Unmarshal, handle)
164 TPML_MARSHAL(TPML_DIGEST, Tss2_MU_TPM2B_DIGEST_Marshal, digests, ADDR)
165 TPML_UNMARSHAL(TPML_DIGEST, Tss2_MU_TPM2B_DIGEST_Unmarshal, digests)
166 TPML_MARSHAL(TPML_ALG_PROPERTY, Tss2_MU_TPMS_ALG_PROPERTY_Marshal, algProperties, ADDR)
167 TPML_UNMARSHAL(TPML_ALG_PROPERTY, Tss2_MU_TPMS_ALG_PROPERTY_Unmarshal, algProperties)
168 TPML_MARSHAL(TPML_ECC_CURVE, Tss2_MU_UINT16_Marshal, eccCurves, VAL)
169 TPML_UNMARSHAL(TPML_ECC_CURVE, Tss2_MU_UINT16_Unmarshal, eccCurves)
170 TPML_MARSHAL(TPML_TAGGED_TPM_PROPERTY, Tss2_MU_TPMS_TAGGED_PROPERTY_Marshal, tpmProperty, ADDR)
171 TPML_UNMARSHAL(TPML_TAGGED_TPM_PROPERTY, Tss2_MU_TPMS_TAGGED_PROPERTY_Unmarshal, tpmProperty)
172 TPML_MARSHAL(TPML_TAGGED_PCR_PROPERTY, Tss2_MU_TPMS_TAGGED_PCR_SELECT_Marshal, pcrProperty, ADDR)
173 TPML_UNMARSHAL(TPML_TAGGED_PCR_PROPERTY, Tss2_MU_TPMS_TAGGED_PCR_SELECT_Unmarshal, pcrProperty)
174 TPML_MARSHAL(TPML_PCR_SELECTION, Tss2_MU_TPMS_PCR_SELECTION_Marshal, pcrSelections, ADDR)
175 TPML_UNMARSHAL(TPML_PCR_SELECTION, Tss2_MU_TPMS_PCR_SELECTION_Unmarshal, pcrSelections)
176 TPML_MARSHAL(TPML_DIGEST_VALUES, Tss2_MU_TPMT_HA_Marshal, digests, ADDR)
177 TPML_UNMARSHAL(TPML_DIGEST_VALUES, Tss2_MU_TPMT_HA_Unmarshal, digests)
178 TPML_MARSHAL(TPML_INTEL_PTT_PROPERTY, Tss2_MU_UINT32_Marshal, property, VAL)
179 TPML_UNMARSHAL(TPML_INTEL_PTT_PROPERTY, Tss2_MU_UINT32_Unmarshal, property)
180 TPML_MARSHAL(TPML_AC_CAPABILITIES, Tss2_MU_TPMS_AC_OUTPUT_Marshal, acCapabilities, ADDR)
181 TPML_UNMARSHAL(TPML_AC_CAPABILITIES, Tss2_MU_TPMS_AC_OUTPUT_Unmarshal, acCapabilities)
182