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 BASE_MARSHAL(type) \
22 TSS2_RC \
23 Tss2_MU_##type##_Marshal ( \
24     type           src, \
25     uint8_t        buffer [], \
26     size_t         buffer_size, \
27     size_t        *offset) \
28 { \
29     size_t  local_offset = 0; \
30 \
31     if (offset != NULL) { \
32         LOG_TRACE("offset non-NULL, initial value: %zu", *offset); \
33         local_offset = *offset; \
34     } \
35 \
36     if (buffer == NULL && offset == NULL) { \
37         LOG_ERROR("buffer and offset parameter are NULL"); \
38         return TSS2_MU_RC_BAD_REFERENCE; \
39     } else if (buffer == NULL && offset != NULL) { \
40         *offset += sizeof (src); \
41         LOG_TRACE("buffer NULL and offset non-NULL, updating offset to %zu", \
42              *offset); \
43         return TSS2_RC_SUCCESS; \
44     } else if (buffer_size < local_offset || \
45                buffer_size - local_offset < sizeof (src)) \
46     { \
47         LOG_WARNING(\
48              "buffer_size: %zu with offset: %zu are insufficient for object " \
49              "of size %zu", \
50              buffer_size, \
51              local_offset, \
52              sizeof (src)); \
53         return TSS2_MU_RC_INSUFFICIENT_BUFFER; \
54     } \
55 \
56     LOG_DEBUG(\
57          "Marshalling " #type " from 0x%" PRIxPTR " to buffer 0x%" PRIxPTR \
58          " at index 0x%zx", \
59          (uintptr_t)&src, \
60          (uintptr_t)buffer, \
61          local_offset); \
62 \
63     switch (sizeof (type)) { \
64         case 1: \
65             break; \
66         case 2: \
67             src = HOST_TO_BE_16(src); \
68             break; \
69         case 4: \
70             src = HOST_TO_BE_32(src); \
71             break; \
72         case 8: \
73             src = HOST_TO_BE_64(src); \
74             break; \
75 \
76     } \
77     memcpy (&buffer [local_offset], &src, sizeof (src)); \
78     if (offset != NULL) { \
79         *offset = local_offset + sizeof (src); \
80         LOG_DEBUG("offset parameter non-NULL, updated to %zu", *offset); \
81     } \
82 \
83     return TSS2_RC_SUCCESS; \
84 }
85 
86 #define BASE_UNMARSHAL(type) \
87 TSS2_RC \
88 Tss2_MU_##type##_Unmarshal ( \
89     uint8_t const buffer[], \
90     size_t        buffer_size, \
91     size_t       *offset, \
92     type         *dest) \
93 { \
94     size_t  local_offset = 0; \
95     type tmp = 0; \
96 \
97     if (offset != NULL) { \
98         LOG_TRACE("offset non-NULL, initial value: %zu", *offset); \
99         local_offset = *offset; \
100     } \
101 \
102     if (buffer == NULL || (dest == NULL && offset == NULL)) { \
103         LOG_ERROR("buffer or dest and offset parameter are NULL"); \
104         return TSS2_MU_RC_BAD_REFERENCE; \
105     } \
106     if (buffer_size < local_offset || \
107         sizeof (*dest) > buffer_size - local_offset) \
108     { \
109         LOG_WARNING(\
110              "buffer_size: %zu with offset: %zu are insufficient for object " \
111              "of size %zu", buffer_size, local_offset, sizeof (*dest)); \
112         return TSS2_MU_RC_INSUFFICIENT_BUFFER; \
113     } \
114     if (dest == NULL && offset != NULL) { \
115         *offset += sizeof (type); \
116         LOG_TRACE(\
117              "buffer NULL and offset non-NULL, updating offset to %zu", \
118              *offset); \
119         return TSS2_RC_SUCCESS; \
120     } \
121 \
122     LOG_DEBUG(\
123          "Unmarshaling " #type " from 0x%" PRIxPTR " to buffer 0x%" PRIxPTR \
124          " at index 0x%zx", \
125          (uintptr_t)buffer, \
126          (uintptr_t)dest, \
127          local_offset); \
128 \
129     memcpy (&tmp, &buffer [local_offset], sizeof (tmp)); \
130 \
131     switch (sizeof (type)) { \
132         case 1: \
133             *dest = (type)tmp; \
134             break; \
135         case 2: \
136             *dest = BE_TO_HOST_16(tmp); \
137             break; \
138         case 4: \
139             *dest = BE_TO_HOST_32(tmp); \
140             break; \
141         case 8: \
142             *dest = BE_TO_HOST_64(tmp); \
143             break; \
144 \
145     } \
146 \
147     if (offset != NULL) { \
148         *offset = local_offset + sizeof (*dest); \
149         LOG_DEBUG("offset parameter non-NULL, updated to %zu", *offset); \
150     } \
151 \
152     return TSS2_RC_SUCCESS; \
153 }
154 
155 /*
156  * These macros expand to (un)marshal functions for each of the base types
157  * the specification part 2, table 3: Definition of Base Types.
158  */
159 BASE_MARSHAL  (BYTE)
160 BASE_UNMARSHAL(BYTE)
161 BASE_MARSHAL  (INT8)
162 BASE_UNMARSHAL(INT8)
163 BASE_MARSHAL  (INT16)
164 BASE_UNMARSHAL(INT16)
165 BASE_MARSHAL  (INT32)
166 BASE_UNMARSHAL(INT32)
167 BASE_MARSHAL  (INT64)
168 BASE_UNMARSHAL(INT64)
169 BASE_MARSHAL  (UINT8)
170 BASE_UNMARSHAL(UINT8)
171 BASE_MARSHAL  (UINT16)
172 BASE_UNMARSHAL(UINT16)
173 BASE_MARSHAL  (UINT32)
174 BASE_UNMARSHAL(UINT32)
175 BASE_MARSHAL  (UINT64)
176 BASE_UNMARSHAL(UINT64)
177 BASE_MARSHAL  (TPM2_CC)
178 BASE_UNMARSHAL(TPM2_CC)
179 BASE_MARSHAL  (TPM2_ST)
180 BASE_UNMARSHAL(TPM2_ST)
181 BASE_MARSHAL  (TPM2_SE)
182 BASE_UNMARSHAL(TPM2_SE)
183 BASE_MARSHAL  (TPM2_NT)
184 BASE_UNMARSHAL(TPM2_NT)
185 BASE_MARSHAL  (TPM2_HANDLE)
186 BASE_UNMARSHAL(TPM2_HANDLE)
187 BASE_MARSHAL  (TPMI_ALG_HASH)
188 BASE_UNMARSHAL(TPMI_ALG_HASH)
189