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