Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-tpm20.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-tpm20.c
2
 * Dissector for TPM20 protocol
3
 * Copyright (c) 2018, Intel Corporation
4
 * Tadeusz Struk <tadeusz.struk@intel.com>
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
#include "config.h"
14
15
#include <epan/packet.h>
16
#include <epan/tvbuff.h>
17
#include <epan/expert.h>
18
#include <epan/tfs.h>
19
#include <wsutil/array.h>
20
#include <epan/wmem_scopes.h>
21
22
typedef struct {
23
  uint32_t com_pnum;
24
  uint32_t resp_type;
25
  uint32_t command;
26
  uint32_t num_auths;
27
} tpm_entry;
28
29
static wmem_tree_t *cmd_tree;
30
static unsigned last_command_pnum;
31
static bool response_size = true;
32
33
/* sub tree items */
34
static int proto_tpm20;
35
static int proto_tpm20_header;
36
static int proto_tpm20_resp_header;
37
static int proto_tpm20_hndl_area;
38
static int proto_tpm20_auth_area;
39
static int proto_tpm20_params_area;
40
41
/* pdu fields */
42
static int hf_tpm20_platform_cmd;
43
static int hf_tpm20_platform_resp_code;
44
static int hf_tpm20_platform_resp_size;
45
static int hf_tpm20_tag;
46
static int hf_tpm20_size;
47
static int hf_tpm20_cc;
48
static int hf_tpm20_resp_tag;
49
static int hf_tpm20_resp_size;
50
static int hf_tpm20_resp_code;
51
static int hf_tpm20_startup_type;
52
static int hf_tpmi_rh_hierarhy;
53
static int hf_tpmi_rh_provision;
54
static int hf_tpmi_rh_platform;
55
static int hf_tpmi_rh_endorsment;
56
static int hf_tpmi_rh_nv_index;
57
static int hf_tpmi_rh_nv_auth;
58
static int hf_tpmi_rh_hierarhy_auth;
59
static int hf_tpmi_rh_clear;
60
static int hf_tpmi_rh_lockout;
61
static int hf_tpmi_dh_object;
62
static int hf_tpmi_dh_entity;
63
static int hf_tpmi_dh_context;
64
static int hf_tpmi_dh_parent;
65
static int hf_tpmi_dh_pcr;
66
static int hf_tpmi_ht_handle;
67
static int hf_tpmi_sh_auth_session;
68
static int hf_tpmi_rh_act;
69
static int hf_auth_area_size;
70
static int hf_session_nonce_size;
71
static int hf_session_nonce;
72
static int hf_session_attribs_cont;
73
static int hf_session_attribs_auditex;
74
static int hf_session_attribs_auditreset;
75
static int hf_session_attribs_res;
76
static int hf_session_attribs_decrypt;
77
static int hf_session_attribs_encrypt;
78
static int hf_session_attribs_audit;
79
static int hf_session_auth_size;
80
static int hf_session_auth;
81
static int hf_resp_param_size;
82
static int hf_encrypted_secret_size;
83
static int hf_encrypted_secret;
84
static int hf_session_type;
85
static int hf_alg_hash;
86
static int hf_alg_sym;
87
static int hf_alg_sym_keybits;
88
static int hf_alg_sym_mode;
89
static int hf_tpm_priv_size;
90
static int hf_tpm_priv;
91
static int hf_tpm_pub_size;
92
static int hf_tpm_pub;
93
static int hf_tpm_name_size;
94
static int hf_tpm_name;
95
static int hf_tpm_sensitive_crate_size;
96
static int hf_tpm_sensitive_crate;
97
static int hf_tpm_template_size;
98
static int hf_tpm_template;
99
static int hf_tpm_data_size;
100
static int hf_tpm_data;
101
static int hf_tpm_creation_data_size;
102
static int hf_tpm_creation_data;
103
static int hf_tpm_digest_size;
104
static int hf_tpm_digest;
105
static int hf_params;
106
107
/* sub trees */
108
static int ett_tpm;
109
static int ett_tpm_header;
110
static int ett_tpm_response_header;
111
static int ett_tpm_handles;
112
static int ett_tpm_auth;
113
static int ett_tpm_params;
114
static int ett_tpm_attrib;
115
116
static expert_field ei_invalid_tag;
117
static expert_field ei_invalid_auth_size;
118
static expert_field ei_invalid_num_sessions;
119
120
void proto_register_tpm20(void);
121
void proto_reg_handoff_tpm20(void);
122
123
static dissector_handle_t tpm20_handle;
124
125
#define TCP_TPM_PORT_PLATFORM_PORT    2321
126
#define TCP_TPM_PORT_COMMAND_PORT     2322
127
14
#define TCP_TPM_PORTS    "2321-2322"
128
#define MAX_HNDL 3
129
0
#define MAX_SESSIONS 3
130
0
#define TPM_ALG_NULL 0x0010
131
0
#define TPM_MIN_AUTH_LEN 9
132
0
#define TPM_COMMAND_HEADER_LEN 10
133
134
struct num_handles {
135
  uint32_t command;
136
  uint8_t num_req_handles;
137
  int *req_pd[MAX_HNDL];
138
  uint8_t num_resp_handles;
139
  int *resp_pd[MAX_HNDL];
140
};
141
142
static struct num_handles tpm_handles_map[] = {
143
  { 0x11f, 2, { &hf_tpmi_rh_provision, &hf_tpmi_dh_object, 0 }, 0, { 0, 0, 0}}, /* CC_NV_UndefineSpaceSpecial */
144
  { 0x120, 2, { &hf_tpmi_rh_provision, &hf_tpmi_dh_object, 0 }, 0, { 0, 0, 0}}, /* CC_EvictControl */
145
  { 0x121, 1, { &hf_tpmi_rh_hierarhy, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_HierarchyControl */
146
  { 0x122, 2, { &hf_tpmi_rh_provision, &hf_tpmi_rh_nv_index, 0 }, 0, { 0, 0, 0 }}, /* CC_NV_UndefineSpace */
147
  { 0x124, 1, { &hf_tpmi_rh_platform, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_ChangeEPS */
148
  { 0x125, 1, { &hf_tpmi_rh_platform, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_ChangePPS */
149
  { 0x126, 1, { &hf_tpmi_rh_clear, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_Clear */
150
  { 0x127, 1, { &hf_tpmi_rh_clear, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_ClearControl */
151
  { 0x128, 1, { &hf_tpmi_rh_provision, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_ClockSet */
152
  { 0x129, 1, { &hf_tpmi_rh_hierarhy_auth, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_HierarchyChangeAuth */
153
  { 0x12a, 1, { &hf_tpmi_rh_provision, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_NV_DefineSpace */
154
  { 0x12b, 1, { &hf_tpmi_rh_platform, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PCR_Allocate */
155
  { 0x12c, 1, { &hf_tpmi_rh_platform, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PCR_SetAuthPolicy */
156
  { 0x12d, 1, { &hf_tpmi_rh_platform, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PP_Commands */
157
  { 0x12e, 1, { &hf_tpmi_rh_hierarhy_auth, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_SetPrimaryPolicy */
158
  { 0x12f, 2, { &hf_tpmi_rh_platform, &hf_tpmi_dh_object, 0 }, 0, { 0, 0, 0 }}, /* CC_FieldUpgradeStart */
159
  { 0x130, 1, { &hf_tpmi_rh_platform, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_ClockRateAdjust */
160
  { 0x131, 1, { &hf_tpmi_rh_hierarhy, 0, 0 }, 1, { &hf_tpmi_ht_handle, 0, 0 }}, /* CC_CreatePrimary */
161
  { 0x132, 1, { &hf_tpmi_rh_provision, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_NV_GlobalWriteLock */
162
  { 0x133, 2, { &hf_tpmi_rh_endorsment, &hf_tpmi_dh_object, 0 }, 0, { 0, 0, 0 }}, /* CC_GetCommandAuditDigest */
163
  { 0x134, 2, { &hf_tpmi_rh_nv_auth, &hf_tpmi_rh_nv_index, 0 }, 0, { 0, 0, 0 }}, /* CC_NV_Increment */
164
  { 0x135, 2, { &hf_tpmi_rh_nv_auth, &hf_tpmi_rh_nv_index, 0 }, 0, { 0, 0, 0 }}, /* CC_NV_SetBits */
165
  { 0x136, 2, { &hf_tpmi_rh_nv_auth, &hf_tpmi_rh_nv_index, 0 }, 0, { 0, 0, 0 }}, /* CC_NV_Extend */
166
  { 0x137, 2, { &hf_tpmi_rh_nv_auth, &hf_tpmi_rh_nv_index, 0 }, 0, { 0, 0, 0 }}, /* CC_NV_Write */
167
  { 0x138, 2, { &hf_tpmi_rh_nv_auth, &hf_tpmi_rh_nv_index, 0 }, 0, { 0, 0, 0 }}, /* CC_NV_WriteLock */
168
  { 0x139, 1, { &hf_tpmi_rh_lockout, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_DictionaryAttackLockReset */
169
  { 0x13a, 1, { &hf_tpmi_rh_lockout, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_DictionaryAttackParameters */
170
  { 0x13b, 1, { &hf_tpmi_rh_nv_index, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_NV_ChangeAuth */
171
  { 0x13c, 1, { &hf_tpmi_dh_pcr, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PCR_Event */
172
  { 0x13d, 1, { &hf_tpmi_dh_pcr, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PCR_Reset */
173
  { 0x13e, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_SequenceComplete */
174
  { 0x13f, 1, { &hf_tpmi_rh_platform, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_SetAlgorithmSet */
175
  { 0x140, 1, { &hf_tpmi_rh_provision, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_SetCommandCodeAuditStatus */
176
  { 0x141, 0, { 0, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_FieldUpgradeData */
177
  { 0x142, 0, { 0, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_IncrementalSelfTest */
178
  { 0x143, 0, { 0, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_SelfTest */
179
  { 0x144, 0, { 0, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_Startup */
180
  { 0x145, 0, { 0, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_Shutdown */
181
  { 0x146, 0, { 0, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_StirRandom */
182
  { 0x147, 2, { &hf_tpmi_dh_object, &hf_tpmi_dh_object, 0 }, 0, { 0, 0, 0 }}, /* CC_ActivateCredential */
183
  { 0x148, 2, { &hf_tpmi_dh_object, &hf_tpmi_dh_object, 0 }, 0, { 0, 0, 0 }}, /* CC_Certify */
184
  { 0x149, 3, { &hf_tpmi_rh_nv_auth, &hf_tpmi_rh_nv_index, &hf_tpmi_sh_auth_session}, 0, { 0, 0, 0 }}, /* CC_PolicyNV */
185
  { 0x14a, 2, { &hf_tpmi_dh_object, &hf_tpmi_dh_object, 0 }, 0, { 0, 0, 0 }}, /* CC_CertifyCreation */
186
  { 0x14b, 2, { &hf_tpmi_dh_object, &hf_tpmi_dh_object, 0 }, 0, { 0, 0, 0 }}, /* CC_Duplicate */
187
  { 0x14c, 2, { &hf_tpmi_rh_endorsment, &hf_tpmi_dh_object, 0 }, 0, { 0, 0, 0 }}, /* CC_GetTime */
188
  { 0x14d, 3, { &hf_tpmi_rh_endorsment, &hf_tpmi_dh_object, &hf_tpmi_sh_auth_session }, 0, { 0, 0, 0 }}, /* CC_GetSessionAuditDigest */
189
  { 0x14e, 1, { &hf_tpmi_rh_nv_index, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_NV_Read */
190
  { 0x14f, 2, { &hf_tpmi_rh_nv_auth, &hf_tpmi_rh_nv_index, 0 }, 0, { 0, 0, 0 }}, /* CC_NV_ReadLock */
191
  { 0x150, 2, { &hf_tpmi_dh_object, &hf_tpmi_dh_object, 0 }, 0, { 0, 0, 0 }}, /* CC_ObjectChangeAuth */
192
  { 0x151, 2, { &hf_tpmi_dh_entity, &hf_tpmi_sh_auth_session, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicySecret */
193
  { 0x152, 2, { &hf_tpmi_dh_object, &hf_tpmi_dh_object, 0 }, 0, { 0, 0, 0 }}, /* CC_Rewrap */
194
  { 0x153, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_Create */
195
  { 0x154, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_ECDH_ZGen */
196
  { 0x155, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_HMAC */
197
  { 0x156, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_Import */
198
  { 0x157, 1, { &hf_tpmi_dh_object, 0, 0 }, 1, { &hf_tpmi_ht_handle, 0, 0 }}, /* CC_Load */
199
  { 0x158, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_Quote */
200
  { 0x159, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_RSA_Decrypt */
201
  { 0x15b, 1, { &hf_tpmi_dh_object, 0, 0 }, 1, { &hf_tpmi_dh_object, 0, 0 }}, /* CC_HMAC_Start */
202
  { 0x15c, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_SequenceUpdate */
203
  { 0x15d, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_Sign */
204
  { 0x15e, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_Unseal */
205
  { 0x160, 2, { &hf_tpmi_dh_object, &hf_tpmi_sh_auth_session, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicySigned */
206
  { 0x161, 0, { 0, 0, 0 }, 1, { &hf_tpmi_dh_context, 0, 0 }}, /* CC_ContextLoad */
207
  { 0x162, 1, { &hf_tpmi_dh_context, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_ContextSave */
208
  { 0x163, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_ECDH_KeyGen */
209
  { 0x164, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_EncryptDecrypt */
210
  { 0x165, 1, { &hf_tpmi_dh_context, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_FlushContext */
211
  { 0x167, 0, { 0, 0, 0 }, 1, { &hf_tpmi_dh_object, 0, 0 }}, /* CC_LoadExternal */
212
  { 0x168, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_MakeCredential */
213
  { 0x169, 1, { &hf_tpmi_rh_nv_index, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_NV_ReadPublic */
214
  { 0x16a, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicyAuthorize */
215
  { 0x16b, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicyAuthValue */
216
  { 0x16c, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicyCommandCode */
217
  { 0x16d, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicyCounterTimer" */
218
  { 0x16e, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicyCpHash */
219
  { 0x16f, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicyLocality */
220
  { 0x170, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicyNameHash */
221
  { 0x171, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicyOR */
222
  { 0x172, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicyTicket */
223
  { 0x173, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_ReadPublic */
224
  { 0x174, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_RSA_Encrypt */
225
  { 0x176, 2, { &hf_tpmi_dh_object, &hf_tpmi_dh_entity, 0 }, 1, { &hf_tpmi_sh_auth_session, 0, 0 }}, /* CC_StartAuthSession */
226
  { 0x177, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_VerifySignature */
227
  { 0x178, 0, { 0, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_ECC_Parameters */
228
  { 0x179, 0, { 0, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_FirmwareRead */
229
  { 0x17a, 0, { 0, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_GetCapability */
230
  { 0x17b, 0, { 0, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_GetRandom */
231
  { 0x17c, 0, { 0, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_GetTestResult */
232
  { 0x17d, 0, { 0, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_Hash */
233
  { 0x17e, 0, { 0, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PCR_Read */
234
  { 0x17f, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicyPCR */
235
  { 0x180, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicyRestart */
236
  { 0x181, 0, { 0, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_ReadClock */
237
  { 0x182, 1, { &hf_tpmi_dh_pcr, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PCR_Extend */
238
  { 0x183, 1, { &hf_tpmi_dh_pcr, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PCR_SetAuthValue */
239
  { 0x184, 3, { &hf_tpmi_dh_object, &hf_tpmi_rh_nv_auth, &hf_tpmi_rh_nv_index }, 0, { 0, 0, 0 }}, /* CC_NV_Certify */
240
  { 0x185, 2, { &hf_tpmi_dh_pcr, &hf_tpmi_dh_object, 0 }, 0, { 0, 0, 0 }}, /* CC_EventSequenceComplete */
241
  { 0x186, 0, { 0, 0, 0 }, 1, { &hf_tpmi_dh_object, 0, 0 }}, /* CC_HashSequenceStart */
242
  { 0x187, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicyPhysicalPresence */
243
  { 0x188, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicyDuplicationSelect */
244
  { 0x189, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicyGetDigest */
245
  { 0x18a, 0, { 0, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_TestParms */
246
  { 0x18b, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_Commit */
247
  { 0x18c, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicyPassword */
248
  { 0x18d, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_ZGen_2Phase */
249
  { 0x18e, 0, { 0, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_EC_Ephemeral */
250
  { 0x18f, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicyNvWritten */
251
  { 0x190, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_PolicyTemplate */
252
  { 0x191, 1, { &hf_tpmi_rh_hierarhy, 0, 0 }, 1, { &hf_tpmi_dh_parent, 0, 0 }}, /* CC_CreateLoaded */
253
  { 0x192, 3, { &hf_tpmi_rh_nv_auth, &hf_tpmi_rh_nv_index, &hf_tpmi_sh_auth_session }, 0, { 0, 0, 0 }}, /* CC_PolicyAuthorizeNV */
254
  { 0x193, 1, { &hf_tpmi_dh_object, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_EncryptDecrypt2 */
255
  { 0x194, 1, { &hf_tpmi_ht_handle, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_AC_GetCapability */
256
  { 0x195, 3, { &hf_tpmi_dh_object, &hf_tpmi_rh_nv_auth, &hf_tpmi_ht_handle }, 0, { 0, 0, 0 }}, /* CC_AC_Send */
257
  { 0x196, 1, { &hf_tpmi_sh_auth_session, 0, 0 }, 0, { 0, 0, 0 }}, /* CC_Policy_AC_SendSelect */
258
  { 0x197, 2, { &hf_tpmi_dh_object, &hf_tpmi_dh_object, 0 }, 0, { 0, 0, 0 }}, /* CC_CertifyX509 */
259
  { 0x198, 1, { &hf_tpmi_rh_act, 0, 0 }, 0, { 0, 0, 0 }}, /* TPM_CC_ACT_SetTimeout */
260
};
261
262
static void get_num_hndl(struct num_handles *map)
263
0
{
264
0
  uint8_t i, y;
265
266
0
  for (i = 0; i < array_length(tpm_handles_map); i++) {
267
0
    if (map->command == tpm_handles_map[i].command) {
268
0
      map->num_req_handles = tpm_handles_map[i].num_req_handles;
269
0
      map->num_resp_handles = tpm_handles_map[i].num_resp_handles;
270
0
      for (y = 0; y < map->num_req_handles; y++)
271
0
        map->req_pd[y] = tpm_handles_map[i].req_pd[y];
272
0
      for (y = 0; y < map->num_resp_handles; y++)
273
0
        map->resp_pd[y] = tpm_handles_map[i].resp_pd[y];
274
0
    }
275
0
  }
276
0
}
277
278
static const value_string handles[] = {
279
  { 0x40000000, "TPM2_RH_SRK" },
280
  { 0x40000001, "TPM2_RH_OWNER" },
281
  { 0x40000002, "TPM2_RH_REVOKE" },
282
  { 0x40000003, "TPM2_RH_TRANSPORT" },
283
  { 0x40000004, "TPM2_RH_OPERATOR" },
284
  { 0x40000005, "TPM2_RH_ADMIN" },
285
  { 0x40000006, "TPM2_RH_EK" },
286
  { 0x40000007, "TPM2_RH_NULL" },
287
  { 0x40000008, "TPM2_RH_UNASSIGNED" },
288
  { 0x40000009, "TPM2_RS_PW" },
289
  { 0x4000000A, "TPM2_RH_LOCKOUT" },
290
  { 0x4000000B, "TPM2_RH_ENDORSEMENT" },
291
  { 0x4000000C, "TPM2_RH_PLATFORM" },
292
  { 0x4000000D, "TPM2_RH_PLATFORM_NV" },
293
  { 0x40000010, "TPM2_RH_AUTH_00" },
294
  { 0x4000010F, "TPM2_RH_AUTH_FF" },
295
  { 0x40000110, "TPM_RH_ACT_0" },
296
  { 0x40000111, "TPM_RH_ACT_1" },
297
  { 0x40000112, "TPM_RH_ACT_2" },
298
  { 0x40000113, "TPM_RH_ACT_3" },
299
  { 0x40000114, "TPM_RH_ACT_4" },
300
  { 0x40000115, "TPM_RH_ACT_5" },
301
  { 0x40000116, "TPM_RH_ACT_6" },
302
  { 0x40000117, "TPM_RH_ACT_7" },
303
  { 0x40000118, "TPM_RH_ACT_8" },
304
  { 0x40000119, "TPM_RH_ACT_9" },
305
  { 0x4000011A, "TPM_RH_ACT_10" },
306
  { 0x4000011B, "TPM_RH_ACT_11" },
307
  { 0x4000011C, "TPM_RH_ACT_12" },
308
  { 0x4000011D, "TPM_RH_ACT_13" },
309
  { 0x4000011E, "TPM_RH_ACT_14" },
310
  { 0x4000011F, "TPM_RH_ACT_15" },
311
  { 0, NULL }
312
};
313
314
static const value_string startup_types[] = {
315
  { 0x0000, "TPM_SU_CLEAR" },
316
  { 0x0001, "TPM_SU_STATE" },
317
  { 0, NULL }
318
};
319
320
static const value_string platform_commands[] = {
321
  { 0x01, "TPM_POWER_ON" },
322
  { 0x02, "TPM_POWER_OFF" },
323
  { 0x08, "TPM_SEND_COMMAND" },
324
  { 0x09, "TPM_CANCEL_ON" },
325
  { 0x0a, "TPM_CANCEL_OFF" },
326
  { 0x0b, "TPM_NV_ON" },
327
  { 0x14, "TPM_SESSION_END" },
328
  { 0, NULL }
329
};
330
331
static const value_string tags[] = {
332
  { 0x8001, "Command with no authorization Sessions" },
333
  { 0x8002, "Command with authorization Sessions" },
334
  { 0, NULL }
335
};
336
337
static const value_string hierarhies[] = {
338
  { 0x40000001, "TPM2_RH_OWNER" },
339
  { 0x40000007, "TPM2_RH_NULL" },
340
  { 0x4000000B, "TPM2_RH_ENDORSEMENT" },
341
  { 0x4000000C, "TPM2_RH_PLATFORM" },
342
  { 0, NULL }
343
};
344
345
static const value_string algs[] = {
346
  { 0x0001, "TPM2_ALG_RSA" },
347
  { 0x0004, "TPM2_ALG_SHA" },
348
  { 0x0005, "TPM2_ALG_HMAC" },
349
  { 0x0006, "TPM2_ALG_AES" },
350
  { 0x0007, "TPM2_ALG_MGF1" },
351
  { 0x0008, "TPM2_ALG_KEYEDHASH" },
352
  { 0x000A, "TPM2_ALG_XOR" },
353
  { 0x000B, "TPM2_ALG_SHA256" },
354
  { 0x000C, "TPM2_ALG_SHA384" },
355
  { 0x000D, "TPM2_ALG_SHA512" },
356
  { 0x0010, "TPM2_ALG_NULL" },
357
  { 0x0012, "TPM2_ALG_SM3_256" },
358
  { 0x0013, "TPM2_ALG_SM4" },
359
  { 0x0014, "TPM2_ALG_RSASSA" },
360
  { 0x0015, "TPM2_ALG_RSAES" },
361
  { 0x0016, "TPM2_ALG_RSAPSS" },
362
  { 0x0017, "TPM2_ALG_OAEP" },
363
  { 0x0018, "TPM2_ALG_ECDSA" },
364
  { 0x0019, "TPM2_ALG_ECDH" },
365
  { 0x001A, "TPM2_ALG_ECDAA" },
366
  { 0x001B, "TPM2_ALG_SM2" },
367
  { 0x001C, "TPM2_ALG_ECSCHNORR" },
368
  { 0x001D, "TPM2_ALG_ECMQV" },
369
  { 0x0020, "TPM2_ALG_KDF1_SP800_56A" },
370
  { 0x0021, "TPM2_ALG_KDF2" },
371
  { 0x0022, "TPM2_ALG_KDF1_SP800_108" },
372
  { 0x0023, "TPM2_ALG_ECC" },
373
  { 0x0025, "TPM2_ALG_SYMCIPHER" },
374
  { 0x0026, "TPM2_ALG_CAMELLIA" },
375
  { 0x0040, "TPM2_ALG_CTR" },
376
  { 0x0027, "TPM2_ALG_SHA3_256" },
377
  { 0x0028, "TPM2_ALG_SHA3_384" },
378
  { 0x0029, "TPM2_ALG_SHA3_512" },
379
  { 0x0041, "TPM2_ALG_OFB" },
380
  { 0x0042, "TPM2_ALG_CBC" },
381
  { 0x0043, "TPM2_ALG_CFB" },
382
  { 0x0044, "TPM2_ALG_ECB" },
383
  { 0, NULL }
384
};
385
386
static const value_string commands[] = {
387
  { 0x11f, "TPM2_CC_NV_UndefineSpaceSpecial" },
388
  { 0x120, "TPM2_CC_EvictControl" },
389
  { 0x121, "TPM2_CC_HierarchyControl" },
390
  { 0x122, "TPM2_CC_NV_UndefineSpace" },
391
  { 0x124, "TPM2_CC_ChangeEPS" },
392
  { 0x125, "TPM2_CC_ChangePPS" },
393
  { 0x126, "TPM2_CC_Clear" },
394
  { 0x127, "TPM2_CC_ClearControl" },
395
  { 0x128, "TPM2_CC_ClockSet" },
396
  { 0x129, "TPM2_CC_HierarchyChangeAuth" },
397
  { 0x12a, "TPM2_CC_NV_DefineSpace" },
398
  { 0x12b, "TPM2_CC_PCR_Allocate" },
399
  { 0x12c, "TPM2_CC_PCR_SetAuthPolicy" },
400
  { 0x12d, "TPM2_CC_PP_Commands" },
401
  { 0x12e, "TPM2_CC_SetPrimaryPolicy" },
402
  { 0x12f, "TPM2_CC_FieldUpgradeStart" },
403
  { 0x130, "TPM2_CC_ClockRateAdjust" },
404
  { 0x131, "TPM2_CC_CreatePrimary" },
405
  { 0x132, "TPM2_CC_NV_GlobalWriteLock" },
406
  { 0x133, "TPM2_CC_GetCommandAuditDigest" },
407
  { 0x134, "TPM2_CC_NV_Increment" },
408
  { 0x135, "TPM2_CC_NV_SetBits" },
409
  { 0x136, "TPM2_CC_NV_Extend" },
410
  { 0x137, "TPM2_CC_NV_Write" },
411
  { 0x138, "TPM2_CC_NV_WriteLock" },
412
  { 0x139, "TPM2_CC_DictionaryAttackLockReset" },
413
  { 0x13a, "TPM2_CC_DictionaryAttackParameters" },
414
  { 0x13b, "TPM2_CC_NV_ChangeAuth" },
415
  { 0x13c, "TPM2_CC_PCR_Event" },
416
  { 0x13d, "TPM2_CC_PCR_Reset" },
417
  { 0x13e, "TPM2_CC_SequenceComplete" },
418
  { 0x13f, "TPM2_CC_SetAlgorithmSet" },
419
  { 0x140, "TPM2_CC_SetCommandCodeAuditStatus" },
420
  { 0x141, "TPM2_CC_FieldUpgradeData" },
421
  { 0x142, "TPM2_CC_IncrementalSelfTest" },
422
  { 0x143, "TPM2_CC_SelfTest" },
423
  { 0x144, "TPM2_CC_Startup" },
424
  { 0x145, "TPM2_CC_Shutdown" },
425
  { 0x146, "TPM2_CC_StirRandom" },
426
  { 0x147, "TPM2_CC_ActivateCredential" },
427
  { 0x148, "TPM2_CC_Certify" },
428
  { 0x149, "TPM2_CC_PolicyNV" },
429
  { 0x14a, "TPM2_CC_CertifyCreation" },
430
  { 0x14b, "TPM2_CC_Duplicate" },
431
  { 0x14c, "TPM2_CC_GetTime" },
432
  { 0x14d, "TPM2_CC_GetSessionAuditDigest" },
433
  { 0x14e, "TPM2_CC_NV_Read" },
434
  { 0x14f, "TPM2_CC_NV_ReadLock" },
435
  { 0x150, "TPM2_CC_ObjectChangeAuth" },
436
  { 0x151, "TPM2_CC_PolicySecret" },
437
  { 0x152, "TPM2_CC_Rewrap" },
438
  { 0x153, "TPM2_CC_Create" },
439
  { 0x154, "TPM2_CC_ECDH_ZGen" },
440
  { 0x155, "TPM2_CC_HMAC" },
441
  { 0x156, "TPM2_CC_Import" },
442
  { 0x157, "TPM2_CC_Load" },
443
  { 0x158, "TPM2_CC_Quote" },
444
  { 0x159, "TPM2_CC_RSA_Decrypt" },
445
  { 0x15b, "TPM2_CC_HMAC_Start" },
446
  { 0x15c, "TPM2_CC_SequenceUpdate" },
447
  { 0x15d, "TPM2_CC_Sign" },
448
  { 0x15e, "TPM2_CC_Unseal" },
449
  { 0x160, "TPM2_CC_PolicySigned" },
450
  { 0x161, "TPM2_CC_ContextLoad" },
451
  { 0x162, "TPM2_CC_ContextSave" },
452
  { 0x163, "TPM2_CC_ECDH_KeyGen" },
453
  { 0x164, "TPM2_CC_EncryptDecrypt" },
454
  { 0x165, "TPM2_CC_FlushContext" },
455
  { 0x167, "TPM2_CC_LoadExternal" },
456
  { 0x168, "TPM2_CC_MakeCredential" },
457
  { 0x169, "TPM2_CC_NV_ReadPublic" },
458
  { 0x16a, "TPM2_CC_PolicyAuthorize" },
459
  { 0x16b, "TPM2_CC_PolicyAuthValue" },
460
  { 0x16c, "TPM2_CC_PolicyCommandCode" },
461
  { 0x16d, "TPM2_CC_PolicyCounterTimer" },
462
  { 0x16e, "TPM2_CC_PolicyCpHash" },
463
  { 0x16f, "TPM2_CC_PolicyLocality" },
464
  { 0x170, "TPM2_CC_PolicyNameHash" },
465
  { 0x171, "TPM2_CC_PolicyOR" },
466
  { 0x172, "TPM2_CC_PolicyTicket" },
467
  { 0x173, "TPM2_CC_ReadPublic" },
468
  { 0x174, "TPM2_CC_RSA_Encrypt" },
469
  { 0x176, "TPM2_CC_StartAuthSession" },
470
  { 0x177, "TPM2_CC_VerifySignature" },
471
  { 0x178, "TPM2_CC_ECC_Parameters" },
472
  { 0x179, "TPM2_CC_FirmwareRead" },
473
  { 0x17a, "TPM2_CC_GetCapability" },
474
  { 0x17b, "TPM2_CC_GetRandom" },
475
  { 0x17c, "TPM2_CC_GetTestResult" },
476
  { 0x17d, "TPM2_CC_Hash" },
477
  { 0x17e, "TPM2_CC_PCR_Read" },
478
  { 0x17f, "TPM2_CC_PolicyPCR" },
479
  { 0x180, "TPM2_CC_PolicyRestart" },
480
  { 0x181, "TPM2_CC_ReadClock" },
481
  { 0x182, "TPM2_CC_PCR_Extend" },
482
  { 0x183, "TPM2_CC_PCR_SetAuthValue" },
483
  { 0x184, "TPM2_CC_NV_Certify" },
484
  { 0x185, "TPM2_CC_EventSequenceComplete" },
485
  { 0x186, "TPM2_CC_HashSequenceStart" },
486
  { 0x187, "TPM2_CC_PolicyPhysicalPresence" },
487
  { 0x188, "TPM2_CC_PolicyDuplicationSelect" },
488
  { 0x189, "TPM2_CC_PolicyGetDigest" },
489
  { 0x18a, "TPM2_CC_TestParms" },
490
  { 0x18b, "TPM2_CC_Commit" },
491
  { 0x18c, "TPM2_CC_PolicyPassword" },
492
  { 0x18d, "TPM2_CC_ZGen_2Phase" },
493
  { 0x18e, "TPM2_CC_EC_Ephemeral" },
494
  { 0x18f, "TPM2_CC_PolicyNvWritten" },
495
  { 0x190, "TPM2_CC_PolicyTemplate" },
496
  { 0x191, "TPM2_CC_CreateLoaded" },
497
  { 0x192, "TPM2_CC_PolicyAuthorizeNV" },
498
  { 0x193, "TPM2_CC_EncryptDecrypt2" },
499
  { 0x194, "TPM2_CC_AC_GetCapability" },
500
  { 0x195, "TPM2_CC_AC_Send" },
501
  { 0x196, "TPM2_CC_Policy_AC_SendSelect" },
502
  { 0x197, "TPM2_CC_CertifyX509" },
503
  { 0x198, "TPM2_CC_ACT_SetTimeout" },
504
  { 0, NULL }
505
};
506
507
static const value_string session_type [] = {
508
  { 0x00, "TPM2_SE_HMAC" },
509
  { 0x01, "TPM2_SE_POLICY" },
510
  { 0x03, "TPM2_SE_TRIAL" },
511
  { 0, NULL }
512
};
513
514
static const value_string responses [] = {
515
  { 0x00, "TPM2 Success" },
516
  { 0x100, "TPM2_RC_INITIALIZE, TPM not initialized by TPM2_Startup or already initialized" },
517
  { 0x101, "TPM2_RC_FAILURE, Commands not being accepted because of a TPM failure" },
518
  { 0x103, "TPM2_RC_SEQUENCE, Improper use of a sequence handle" },
519
  { 0x10B, "TPM2_RC_PRIVATE" },
520
  { 0x119, "TPM2_RC_HMAC" },
521
  { 0x120, "TPM2_RC_DISABLED, The command is disabled" },
522
  { 0x121, "TPM2_RC_EXCLUSIVE, Command failed because audit sequence required exclusivity" },
523
  { 0x124, "TPM2_RC_AUTH_TYPE, Authorization handle is not correct for command" },
524
  { 0x125, "TPM2_RC_AUTH_MISSING, Command requires an authorization session for handle and it is not present" },
525
  { 0x126, "TPM2_RC_POLICY, Policy failure in math operation or an invalid authPolicy value" },
526
  { 0x127, "TPM2_RC_PCR, PCR check fail" },
527
  { 0x128, "TPM2_RC_PCR_CHANGED, PCR have changed since checked" },
528
  { 0x12D, "TPM2_RC_UPGRADE, TPM is in field upgrade mode" },
529
  { 0x12E, "TPM2_RC_TOO_MANY_CONTEXTS, Context ID counter is at maximum" },
530
  { 0x12F, "TPM2_RC_AUTH_UNAVAILABLE, AuthValue or authPolicy is not available for selected entity" },
531
  { 0x130, "TPM2_RC_REBOOT, _TPM_Init and StartupCLEAR is required before the TPM can resume operation" },
532
  { 0x131, "TPM2_RC_UNBALANCED, The digest size of must be larger than the symmetric key size" },
533
  { 0x142, "TPM2_RC_COMMAND_SIZE, Command Size value is inconsistent with contents of the command buffer" },
534
  { 0x143, "TPM2_RC_COMMAND_CODE, Command code not supported" },
535
  { 0x144, "TPM2_RC_AUTHSIZE, The value of authorization size is out of range" },
536
  { 0x145, "TPM2_RC_AUTH_CONTEXT, Use of an authorization session with a context that cannot have an authorization session" },
537
  { 0x146, "TPM2_RC_NV_RANGE, NV offset + size is out of range" },
538
  { 0x147, "TPM2_RC_NV_SIZE, Requested allocation size is larger than allowed" },
539
  { 0x148, "TPM2_RC_NV_LOCKED, NV access locked" },
540
  { 0x149, "TPM2_RC_NV_AUTHORIZATION, NV access authorization fails in command actions" },
541
  { 0x14A, "TPM2_RC_NV_UNINITIALIZED, An NV Index is used before being initialized or the state could not be restored" },
542
  { 0x14B, "TPM2_RC_NV_SPACE, Insufficient space for NV allocation" },
543
  { 0x14C, "TPM2_RC_NV_DEFINED, NV Index or persistent object already defined" },
544
  { 0x150, "TPM2_RC_BAD_CONTEXT, Context in TPM2_ContextLoad is not valid" },
545
  { 0x151, "TPM2_RC_CPHASH, cpHash value already set or not correct for use" },
546
  { 0x152, "TPM2_RC_PARENT, Handle for parent is not a valid parent" },
547
  { 0x153, "TPM2_RC_NEEDS_TEST, Some function needs testing" },
548
  { 0x154, "TPM2_RC_NO_RESULT, Internal function cannot process a request due to an unspecified problem" },
549
  { 0x155, "TPM2_RC_SENSITIVE, The sensitive area did not unmarshal correctly after decryption" },
550
  { 0x801, "TPM2_RC_ASYMMETRIC, Asymmetric algorithm not supported or not correct" },
551
  { 0x802, "TPM2_RC_ATTRIBUTES, Inconsistent attributes" },
552
  { 0x803, "TPM2_RC_HASH, Hash algorithm not supported or not appropriate" },
553
  { 0x804, "TPM2_RC_VALUE, Value is out of range or is not correct for the context" },
554
  { 0x805, "TPM2_RC_HIERARCHY, Hierarchy is not enabled or is not correct for the use" },
555
  { 0x807, "TPM2_RC_KEY_SIZE, Key size is not supported" },
556
  { 0x808, "TPM2_RC_MGF, Mask generation function not supported" },
557
  { 0x809, "TPM2_RC_MODE, Mode of operation not supported" },
558
  { 0x80A, "TPM2_RC_TYPE, The type of the value is not appropriate for the use" },
559
  { 0x80B, "TPM2_RC_HANDLE, The handle is not correct for the use" },
560
  { 0x80C, "TPM2_RC_KDF, Unsupported key derivation function or function not appropriate for use" },
561
  { 0x80D, "TPM2_RC_RANGE, Value was out of allowed range" },
562
  { 0x80E, "TPM2_RC_AUTH_FAIL, The authorization HMAC check failed" },
563
  { 0x80F, "TPM2_RC_NONCE, invalid nonce size or nonce value mismatch" },
564
  { 0x810, "TPM2_RC_PP, Authorization requires assertion of PP" },
565
  { 0x812, "TPM2_RC_SCHEME, Unsupported or incompatible scheme" },
566
  { 0x815, "TPM2_RC_SIZE, Structure is the wrong size" },
567
  { 0x816, "TPM2_RC_SYMMETRIC, Unsupported symmetric algorithm or key size or not appropriate for instance" },
568
  { 0x817, "TPM2_RC_TAG, Incorrect structure tag" },
569
  { 0x818, "TPM2_RC_SELECTOR, Union selector is incorrect" },
570
  { 0x81A, "TPM2_RC_INSUFFICIENT, Unable to unmarshal a value because there were not enough octets in the input buffer" },
571
  { 0x81B, "TPM2_RC_SIGNATURE, The signature is not valid" },
572
  { 0x81C, "TPM2_RC_KEY, Key fields are not compatible with the selected use" },
573
  { 0x81D, "TPM2_RC_POLICY_FAIL, Policy check failed" },
574
  { 0x81F, "TPM2_RC_INTEGRITY, Integrity check failed" },
575
  { 0x820, "TPM2_RC_TICKET, Invalid ticket" },
576
  { 0x821, "TPM2_RC_RESERVED_BITS, Reserved bits not set to zero as required" },
577
  { 0x822, "TPM2_RC_BAD_AUTH, Authorization failure without DA implications" },
578
  { 0x823, "TPM2_RC_EXPIRED, The policy has expired" },
579
  { 0x824, "TPM2_RC_POLICY_CC, The commandCode in the policy is not the commandCode of the command or command not implemented" },
580
  { 0x825, "TPM2_RC_BINDING, Public and sensitive portions of an object are not cryptographically bound" },
581
  { 0x826, "TPM2_RC_CURVE, Curve not supported" },
582
  { 0x827, "TPM2_RC_ECC_POINT, Point is not on the required curve" },
583
  { 0x901, "TPM2_RC_CONTEXT_GAP, Gap for context ID is too large" },
584
  { 0x902, "TPM2_RC_OBJECT_MEMORY, Out of memory for object contexts" },
585
  { 0x903, "TPM2_RC_SESSION_MEMORY, Out of memory for session contexts" },
586
  { 0x904, "TPM2_RC_MEMORY, Out of shared objectsession memory or need space for internal operations" },
587
  { 0x905, "TPM2_RC_SESSION_HANDLES, Out of session handles. A session must be flushed before a new session may be created" },
588
  { 0x906, "TPM2_RC_OBJECT_HANDLES, Out of object handles. A reboot is required" },
589
  { 0x907, "TPM2_RC_LOCALITY, Bad locality" },
590
  { 0x908, "TPM2_RC_YIELDED, TPM has suspended operation on the command" },
591
  { 0x909, "TPM2_RC_CANCELED, The command was canceled" },
592
  { 0x90A, "TPM2_RC_TESTING, TPM is performing selftests" },
593
  { 0x910, "TPM2_RC_REFERENCE_H0, The 1st handle references a transient object or session that is not loaded" },
594
  { 0x911, "TPM2_RC_REFERENCE_H1, The 2nd handle references a transient object or session that is not loaded" },
595
  { 0x912, "TPM2_RC_REFERENCE_H2, The 3rd handle references a transient object or session that is not loaded" },
596
  { 0x913, "TPM2_RC_REFERENCE_H3, The 4th handle references a transient object or session that is not loaded" },
597
  { 0x914, "TPM2_RC_REFERENCE_H4, The 5th handle references a transient object or session that is not loaded" },
598
  { 0x915, "TPM2_RC_REFERENCE_H5, The 6th handle references a transient object or session that is not loaded" },
599
  { 0x916, "TPM2_RC_REFERENCE_H6, The 7th handle references a transient object or session that is not loaded" },
600
  { 0x918, "TPM2_RC_REFERENCE_S0, The 1st authorization session handle references a session that is not loaded" },
601
  { 0x919, "TPM2_RC_REFERENCE_S1, The 2nd authorization session handle references a session that is not loaded" },
602
  { 0x91A, "TPM2_RC_REFERENCE_S2, The 3rd authorization session handle references a session that is not loaded" },
603
  { 0x91B, "TPM2_RC_REFERENCE_S3, The 4th authorization session handle references a session that is not loaded" },
604
  { 0x91C, "TPM2_RC_REFERENCE_S4, The 5th session handle references a session that is not loaded" },
605
  { 0x91D, "TPM2_RC_REFERENCE_S5, The 6th session handle references a session that is not loaded" },
606
  { 0x91E, "TPM2_RC_REFERENCE_S6, The 7th authorization session handle references a session that is not loaded" },
607
  { 0x920, "TPM2_RC_NV_RATE, The TPM is ratelimiting accesses to prevent wearout of NV" },
608
  { 0x921, "TPM2_RC_LOCKOUT, Authorizations for objects subject to DA protection are not allowed at this time. TPM is in DA lockout mode" },
609
  { 0x922, "TPM2_RC_RETRY - the TPM was not able to start the command" },
610
  { 0x923, "TPM2_RC_NV_UNAVAILABLE - the command may require writing of NV and NV is not current accessible" },
611
  { 0, NULL }
612
};
613
614
#define TPMA_SESSION_CONTINUESESSION 0x01
615
#define TPMA_SESSION_AUDITEXCLUSIVE  0x02
616
#define TPMA_SESSION_AUDITRESET      0x04
617
#define TPMA_SESSION_RESERVED1_MASK  0x18
618
#define TPMA_SESSION_DECRYPT         0x20
619
#define TPMA_SESSION_ENCRYPT         0x40
620
#define TPMA_SESSION_AUDIT           0x80
621
622
static tpm_entry *get_command_entry(wmem_tree_t *tree, uint32_t pnum)
623
0
{
624
0
  tpm_entry *entry = (tpm_entry *)wmem_tree_lookup32(tree, pnum);
625
0
  DISSECTOR_ASSERT(entry != NULL);
626
0
  tpm_entry *command_entry = (tpm_entry *)wmem_tree_lookup32(tree, entry->com_pnum);
627
0
  DISSECTOR_ASSERT(command_entry != NULL);
628
629
0
  return command_entry;
630
0
}
631
632
static void
633
dissect_tpm20_platform_command(tvbuff_t *tvb, packet_info *pinfo,
634
  proto_tree *tree)
635
0
{
636
0
  uint32_t command;
637
638
0
  proto_tree_add_item_ret_uint(tree, hf_tpm20_platform_cmd, tvb, 0,
639
0
        4, ENC_BIG_ENDIAN, &command);
640
641
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", Platform Command %s",
642
0
    val_to_str(command, platform_commands, "Unknown (0x%02x)"));
643
644
0
  proto_item_append_text(tree, ", %s", val_to_str(command,
645
0
        platform_commands, "Unknown (0x%02x)"));
646
0
  response_size = false;
647
0
}
648
649
static void
650
dissect_auth_common(tvbuff_t *tvb, packet_info *pinfo _U_,
651
  proto_tree *auth, proto_tree *tree _U_, int *offset)
652
0
{
653
0
  unsigned nonce_size, auth_size;
654
0
  static int * const attrib_fields[] = {
655
0
    &hf_session_attribs_cont,
656
0
    &hf_session_attribs_auditex,
657
0
    &hf_session_attribs_auditreset,
658
0
    &hf_session_attribs_res,
659
0
    &hf_session_attribs_decrypt,
660
0
    &hf_session_attribs_encrypt,
661
0
    &hf_session_attribs_audit,
662
0
    NULL
663
0
  };
664
665
0
  proto_tree_add_item_ret_uint(auth, hf_session_nonce_size, tvb, *offset, 2,
666
0
      ENC_BIG_ENDIAN, &nonce_size);
667
0
  *offset += 2;
668
0
  proto_tree_add_item(auth, hf_session_nonce, tvb, *offset, nonce_size, ENC_NA);
669
0
  *offset += nonce_size;
670
0
  proto_tree_add_bitmask_text(auth, tvb, *offset, 1, "Session attributes", NULL,
671
0
      ett_tpm_attrib, attrib_fields, ENC_NA, BMT_NO_APPEND);
672
0
  *offset += 1;
673
0
  proto_tree_add_item_ret_uint(auth, hf_session_auth_size, tvb, *offset, 2,
674
0
      ENC_BIG_ENDIAN, &auth_size);
675
0
  *offset += 2;
676
0
  proto_tree_add_item(auth, hf_session_auth, tvb, *offset, auth_size, ENC_NA);
677
0
  *offset += auth_size;
678
0
}
679
680
static void
681
dissect_auth_resp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *auth,
682
  proto_tree *tree, int *offset)
683
0
{
684
0
  tpm_entry *command_entry = get_command_entry(cmd_tree, pinfo->num);
685
0
  uint32_t i;
686
687
0
  for (i = 0; i < command_entry->num_auths; i++)
688
0
    dissect_auth_common(tvb, pinfo, auth, tree, offset);
689
0
}
690
691
static void
692
dissect_auth_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *auth,
693
    proto_tree *tree, int *offset)
694
0
{
695
0
  uint32_t auth_area_size;
696
0
  uint32_t num_auths = 0;
697
0
  tpm_entry *entry = (tpm_entry *)wmem_tree_lookup32(cmd_tree, pinfo->num);
698
0
  DISSECTOR_ASSERT(entry != NULL);
699
700
0
  proto_tree_add_item_ret_uint(auth, hf_auth_area_size, tvb, *offset,
701
0
        4, ENC_BIG_ENDIAN, &auth_area_size);
702
0
  *offset += 4;
703
704
0
  if (auth_area_size < TPM_MIN_AUTH_LEN)
705
0
    proto_tree_add_expert_format(auth, pinfo, &ei_invalid_auth_size, tvb, 0, 0,
706
0
          "Error: Auth size: %d", auth_area_size);
707
0
  while (auth_area_size) {
708
0
    uint32_t size;
709
0
    proto_tree_add_item(auth, hf_tpmi_sh_auth_session, tvb, *offset, 4, ENC_BIG_ENDIAN);
710
0
    *offset += 4;
711
0
    auth_area_size -= 4;
712
0
    size = *offset;
713
0
    dissect_auth_common(tvb, pinfo, auth, tree, offset);
714
0
    auth_area_size -= *offset - size;
715
0
    num_auths++;
716
0
  }
717
718
0
  if (num_auths > MAX_SESSIONS)
719
0
    proto_tree_add_expert_format(auth, pinfo, &ei_invalid_num_sessions, tvb, 0, 0,
720
0
          "Error: Invalid Number of sessions: %d", num_auths);
721
0
  entry->num_auths = num_auths;
722
0
}
723
724
static void
725
dissect_startup(tvbuff_t *tvb, packet_info *pinfo _U_,
726
  proto_tree *header, proto_tree *tree _U_, int *offset)
727
0
{
728
0
  proto_tree_add_item(header, hf_tpm20_startup_type, tvb, *offset, 2, ENC_BIG_ENDIAN);
729
0
  *offset += 2;
730
0
}
731
732
static void
733
dissect_start_auth_session(tvbuff_t *tvb, packet_info *pinfo _U_,
734
  proto_tree *header _U_, proto_tree *tree, int *offset)
735
0
{
736
0
  uint32_t nonce_size, encrypted, sym_alg;
737
0
  proto_tree_add_item_ret_uint(tree, hf_session_nonce_size, tvb, *offset, 2,
738
0
      ENC_BIG_ENDIAN, &nonce_size);
739
0
  *offset += 2;
740
0
  proto_tree_add_item(tree, hf_session_nonce, tvb, *offset, nonce_size, ENC_NA);
741
0
  *offset += nonce_size;
742
743
0
  proto_tree_add_item_ret_uint(tree, hf_encrypted_secret_size, tvb, *offset, 2,
744
0
      ENC_BIG_ENDIAN, &encrypted);
745
0
  *offset += 2;
746
0
  proto_tree_add_item(tree, hf_encrypted_secret, tvb, *offset, encrypted, ENC_NA);
747
0
  *offset += encrypted;
748
0
  proto_tree_add_item(tree, hf_session_type, tvb, *offset, 1, ENC_NA);
749
0
  *offset += 1;
750
751
0
  proto_tree_add_item_ret_uint(tree, hf_alg_sym, tvb, *offset, 2, ENC_BIG_ENDIAN, &sym_alg);
752
0
  *offset += 2;
753
0
  if (sym_alg != TPM_ALG_NULL) {
754
0
    proto_tree_add_item(tree, hf_alg_sym_keybits, tvb, *offset, 2, ENC_BIG_ENDIAN);
755
0
    *offset += 2;
756
0
    proto_tree_add_item(tree, hf_alg_sym_mode, tvb, *offset, 2, ENC_BIG_ENDIAN);
757
0
    *offset += 2;
758
0
  }
759
0
  proto_tree_add_item(tree, hf_alg_hash, tvb, *offset, 2, ENC_NA);
760
0
  *offset += 2;
761
0
}
762
763
static void
764
dissect_create_primary(tvbuff_t *tvb, packet_info *pinfo _U_,
765
  proto_tree *header _U_, proto_tree *tree, int *offset)
766
0
{
767
0
  uint32_t sensitive_size, pub_size, data_size;
768
769
0
  proto_tree_add_item_ret_uint(tree, hf_tpm_sensitive_crate_size, tvb, *offset, 2,
770
0
      ENC_BIG_ENDIAN, &sensitive_size);
771
0
  *offset += 2;
772
0
  proto_tree_add_item(tree, hf_tpm_sensitive_crate, tvb, *offset, sensitive_size, ENC_NA);
773
0
  *offset += sensitive_size;
774
775
0
  proto_tree_add_item_ret_uint(tree, hf_tpm_pub_size, tvb, *offset, 2,
776
0
      ENC_BIG_ENDIAN, &pub_size);
777
0
  *offset += 2;
778
0
  proto_tree_add_item(tree, hf_tpm_pub, tvb, *offset, pub_size, ENC_NA);
779
0
  *offset += pub_size;
780
781
0
  proto_tree_add_item_ret_uint(tree, hf_tpm_data_size, tvb, *offset, 2,
782
0
      ENC_BIG_ENDIAN, &data_size);
783
0
  *offset += 2;
784
0
  proto_tree_add_item(tree, hf_tpm_data, tvb, *offset, data_size, ENC_NA);
785
0
  *offset += data_size;
786
0
}
787
788
static void
789
dissect_create_loaded(tvbuff_t *tvb, packet_info *pinfo _U_,
790
  proto_tree *header _U_, proto_tree *tree, int *offset)
791
0
{
792
0
  uint32_t sensitive_size, template_size;
793
794
0
  proto_tree_add_item_ret_uint(tree, hf_tpm_sensitive_crate_size, tvb, *offset, 2,
795
0
      ENC_BIG_ENDIAN, &sensitive_size);
796
0
  *offset += 2;
797
0
  proto_tree_add_item(tree, hf_tpm_sensitive_crate, tvb, *offset, sensitive_size, ENC_NA);
798
0
  *offset += sensitive_size;
799
800
0
  proto_tree_add_item_ret_uint(tree, hf_tpm_template_size, tvb, *offset, 2,
801
0
      ENC_BIG_ENDIAN, &template_size);
802
0
  *offset += 2;
803
0
  proto_tree_add_item(tree, hf_tpm_template, tvb, *offset, template_size, ENC_NA);
804
0
  *offset += template_size;
805
0
}
806
807
static void
808
dissect_command(uint32_t command, tvbuff_t *tvb, packet_info *pinfo,
809
  proto_tree *header, proto_tree *tree, int *offset)
810
0
{
811
0
  last_command_pnum = pinfo->num;
812
813
0
  switch (command) {
814
0
  case 0x144: /* TPM Start Up */
815
0
    dissect_startup(tvb, pinfo, header, tree, offset);
816
0
    break;
817
0
  case 0x12e: /* Create Primary */
818
0
    dissect_create_primary(tvb, pinfo, header, tree, offset);
819
0
    break;
820
0
  case 0x176: /* Start Auth Session */
821
0
    dissect_start_auth_session(tvb, pinfo, header, tree, offset);
822
0
    break;
823
0
  case 0x191: /* Create Loaded */
824
0
    dissect_create_loaded(tvb, pinfo, header, tree, offset);
825
0
    break;
826
0
  }
827
0
}
828
829
static void
830
dissect_tpm20_tpm_command(tvbuff_t *tvb, packet_info *pinfo _U_,
831
  proto_tree *tree)
832
0
{
833
0
  int offset = 0;
834
0
  uint32_t command = tvb_get_uint32(tvb, 6, ENC_BIG_ENDIAN);
835
0
  uint16_t tag = tvb_get_uint16(tvb, 0, ENC_BIG_ENDIAN);
836
0
  struct num_handles handl_map;
837
0
  unsigned int i;
838
839
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", Command %s",
840
0
      val_to_str(command, commands, "Unknown (0x%02x)"));
841
842
0
  proto_item *item = proto_tree_add_item(tree, proto_tpm20_header,
843
0
            tvb, 0, -1, ENC_NA);
844
0
  proto_item_append_text(item, ", %s", val_to_str(command, commands,
845
0
        "Unknown (0x%02x)"));
846
0
  proto_tree *header = proto_item_add_subtree(item, ett_tpm_header);
847
0
  proto_tree_add_item(header, hf_tpm20_tag, tvb, offset, 2, ENC_BIG_ENDIAN);
848
0
  offset += 2;
849
0
  proto_tree_add_item(header, hf_tpm20_size, tvb, offset, 4, ENC_BIG_ENDIAN);
850
0
  offset += 4;
851
0
  proto_tree_add_item(header, hf_tpm20_cc, tvb, offset, 4, ENC_BIG_ENDIAN);
852
0
  offset += 4;
853
854
0
  tpm_entry *entry = (tpm_entry *)wmem_tree_lookup32(cmd_tree, pinfo->num);
855
0
  DISSECTOR_ASSERT(entry != NULL);
856
0
  entry->command = command;
857
858
0
  handl_map.command = command;
859
0
  handl_map.num_req_handles = 0;
860
0
  handl_map.num_resp_handles = 0;
861
0
  get_num_hndl(&handl_map);
862
863
0
  if (handl_map.num_req_handles) {
864
0
    proto_item *hndls = proto_tree_add_item(tree, proto_tpm20_hndl_area,
865
0
              tvb, 0, -1, ENC_NA);
866
0
    proto_tree *hndl_tree = proto_item_add_subtree(hndls, ett_tpm_handles);
867
0
    for (i = 0; i < handl_map.num_req_handles; i++) {
868
0
      proto_tree_add_item(hndl_tree, *handl_map.req_pd[i], tvb,
869
0
          offset, 4, ENC_BIG_ENDIAN);
870
0
      offset += 4;
871
0
    }
872
0
  }
873
0
  if (tag == 0x8002) {
874
0
    proto_item *auth = proto_tree_add_item(tree, proto_tpm20_auth_area,
875
0
              tvb, 0, -1, ENC_NA);
876
0
    proto_tree *auth_tree = proto_item_add_subtree(auth, ett_tpm_auth);
877
0
    dissect_auth_command(tvb, pinfo, auth_tree, tree, &offset);
878
0
  } else if (tag != 0x8001) {
879
0
    proto_tree_add_expert_format(tree, pinfo, &ei_invalid_tag, tvb, 0, 0,
880
0
        "Error: Invalid Tag: %x", tag);
881
0
  }
882
883
0
  dissect_command(command, tvb, pinfo, header, tree, &offset);
884
0
  response_size = true;
885
0
}
886
887
0
#define PNUM_UNINIT 0xFFFFFFFF
888
0
#define RESP_CODE 1
889
0
#define RESP_SIZE 2
890
static void
891
dissect_tpm20_platform_response(tvbuff_t *tvb, packet_info *pinfo _U_,
892
  proto_tree *tree)
893
0
{
894
0
  uint32_t rc = tvb_get_uint32(tvb, 0, ENC_BIG_ENDIAN);
895
896
0
  tpm_entry *entry = (tpm_entry *)wmem_tree_lookup32(cmd_tree, pinfo->num);
897
0
  DISSECTOR_ASSERT(entry != NULL);
898
899
0
  if (entry->resp_type == PNUM_UNINIT) {
900
0
    if (response_size == true) {
901
0
      entry->resp_type = RESP_SIZE;
902
0
      response_size = false;
903
0
    } else {
904
0
      entry->resp_type = RESP_CODE;
905
0
      response_size = true;
906
0
    }
907
0
  }
908
909
0
  if (entry->resp_type == RESP_SIZE) {
910
0
    col_append_fstr(pinfo->cinfo, COL_INFO, ", Response size %d", rc);
911
0
    proto_item_append_text(tree, ", Response size %d", rc);
912
0
    proto_tree_add_item(tree, hf_tpm20_platform_resp_size, tvb, 0, 4, ENC_BIG_ENDIAN);
913
0
  } else {
914
0
    col_append_fstr(pinfo->cinfo, COL_INFO, ", Response code %d", rc);
915
0
    proto_item_append_text(tree, ", Response code %s",
916
0
               val_to_str(rc, responses, "Unknown (0x%02x)"));
917
0
    proto_tree_add_item(tree, hf_tpm20_platform_resp_code, tvb, 0, 4, ENC_BIG_ENDIAN);
918
0
  }
919
0
}
920
921
static void
922
dissect_start_auth_session_resp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
923
  int *offset, uint32_t param_size _U_)
924
0
{
925
0
  uint32_t nonce_size;
926
927
0
  proto_tree_add_item_ret_uint(tree, hf_session_nonce_size, tvb, *offset, 2,
928
0
      ENC_BIG_ENDIAN, &nonce_size);
929
0
  *offset += 2;
930
0
  proto_tree_add_item(tree, hf_session_nonce, tvb, *offset, nonce_size, ENC_NA);
931
0
  *offset += nonce_size;
932
0
}
933
934
static void
935
dissect_create_primary_resp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
936
  int *offset, uint32_t param_size _U_)
937
0
{
938
0
  uint32_t pub_size, creation_data_size, digest_size, name_size;
939
940
0
  proto_tree_add_item_ret_uint(tree, hf_tpm_pub_size, tvb, *offset, 2,
941
0
      ENC_BIG_ENDIAN, &pub_size);
942
0
  *offset += 2;
943
0
  proto_tree_add_item(tree, hf_tpm_pub, tvb, *offset, pub_size, ENC_NA);
944
0
  *offset += pub_size;
945
946
0
  proto_tree_add_item_ret_uint(tree, hf_tpm_creation_data_size, tvb, *offset, 2,
947
0
      ENC_BIG_ENDIAN, &creation_data_size);
948
0
  *offset += 2;
949
0
  proto_tree_add_item(tree, hf_tpm_creation_data, tvb, *offset, creation_data_size, ENC_NA);
950
0
  *offset += creation_data_size;
951
952
0
  proto_tree_add_item_ret_uint(tree, hf_tpm_digest_size, tvb, *offset, 2,
953
0
      ENC_BIG_ENDIAN, &digest_size);
954
0
  *offset += 2;
955
0
  proto_tree_add_item(tree, hf_tpm_digest, tvb, *offset, digest_size, ENC_NA);
956
0
  *offset += digest_size;
957
958
0
  proto_tree_add_item_ret_uint(tree, hf_tpm_name_size, tvb, *offset, 2,
959
0
      ENC_BIG_ENDIAN, &name_size);
960
0
  *offset += 2;
961
0
  proto_tree_add_item(tree, hf_tpm_name, tvb, *offset, name_size, ENC_NA);
962
0
  *offset += name_size;
963
0
}
964
965
static void
966
dissect_create_loaded_resp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
967
  int *offset, uint32_t param_size _U_)
968
0
{
969
0
  uint32_t priv_size, pub_size, name_size;
970
971
0
  proto_tree_add_item_ret_uint(tree, hf_tpm_priv_size, tvb, *offset, 2,
972
0
      ENC_BIG_ENDIAN, &priv_size);
973
0
  *offset += 2;
974
0
  proto_tree_add_item(tree, hf_tpm_priv, tvb, *offset, priv_size, ENC_NA);
975
0
  *offset += priv_size;
976
977
0
  proto_tree_add_item_ret_uint(tree, hf_tpm_pub_size, tvb, *offset, 2,
978
0
      ENC_BIG_ENDIAN, &pub_size);
979
0
  *offset += 2;
980
0
  proto_tree_add_item(tree, hf_tpm_pub, tvb, *offset, pub_size, ENC_NA);
981
0
  *offset += pub_size;
982
983
0
  proto_tree_add_item_ret_uint(tree, hf_tpm_name_size, tvb, *offset, 2,
984
0
      ENC_BIG_ENDIAN, &name_size);
985
0
  *offset += 2;
986
0
  proto_tree_add_item(tree, hf_tpm_name, tvb, *offset, name_size, ENC_NA);
987
0
  *offset += name_size;
988
0
}
989
990
static void
991
dissect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
992
  int *offset, uint32_t param_size)
993
0
{
994
0
  tpm_entry *entry = get_command_entry(cmd_tree, pinfo->num);
995
996
0
  switch (entry->command) {
997
0
  case 0x12e: /* Create Primary */
998
0
    dissect_create_primary_resp(tvb, pinfo, tree, offset, param_size);
999
0
    break;
1000
0
  case 0x176: /* Start Auth Session */
1001
0
    dissect_start_auth_session_resp(tvb, pinfo, tree, offset, param_size);
1002
0
    break;
1003
0
  case 0x191: /* Create Loaded */
1004
0
    dissect_create_loaded_resp(tvb, pinfo, tree, offset, param_size);
1005
0
    break;
1006
0
  case 0x144: /* TPM Start Up */
1007
0
    break;
1008
0
  default:
1009
    /* For now dissect everything else and 'params'.
1010
     * This will allow to process the response auth section */
1011
0
    proto_tree_add_item(tree, hf_params, tvb, *offset, param_size, ENC_NA);
1012
0
    *offset += param_size;
1013
0
  }
1014
0
}
1015
1016
static void
1017
dissect_tpm20_tpm_response(tvbuff_t *tvb, packet_info *pinfo _U_,
1018
  proto_tree *tree)
1019
0
{
1020
0
  int offset = 0;
1021
0
  struct num_handles handl_map;
1022
0
  uint16_t tag = tvb_get_uint16(tvb, 0, ENC_BIG_ENDIAN);
1023
0
  uint32_t rc = tvb_get_uint32(tvb, 6, ENC_BIG_ENDIAN);
1024
0
  uint32_t param_size;
1025
0
  unsigned int i;
1026
1027
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", Response Code %s",
1028
0
      val_to_str(rc, responses, "Unknown (0x%02x)"));
1029
1030
0
  proto_item *item = proto_tree_add_item(tree, proto_tpm20_resp_header,
1031
0
            tvb, 0, -1, ENC_NA);
1032
0
  proto_item_append_text(item, ", %s", val_to_str(rc, responses, "Unknown (0x%02x)"));
1033
0
  proto_tree *header = proto_item_add_subtree(item, ett_tpm_response_header);
1034
1035
0
  proto_tree_add_item(header, hf_tpm20_resp_tag, tvb, offset, 2, ENC_BIG_ENDIAN);
1036
0
  offset += 2;
1037
0
  proto_tree_add_item(header, hf_tpm20_resp_size, tvb, offset, 4, ENC_BIG_ENDIAN);
1038
0
  offset += 4;
1039
0
  proto_tree_add_item(header, hf_tpm20_resp_code, tvb, offset, 4, ENC_BIG_ENDIAN);
1040
0
  offset += 4;
1041
  /* if response code says error stop now */
1042
0
  if (rc)
1043
0
    return;
1044
1045
  /* find a corresponding request */
1046
0
  tpm_entry *entry = (tpm_entry *)wmem_tree_lookup32(cmd_tree, pinfo->num);
1047
0
  DISSECTOR_ASSERT(entry != NULL);
1048
0
  if (entry->com_pnum == PNUM_UNINIT) {
1049
0
    entry->com_pnum = last_command_pnum;
1050
0
  }
1051
0
  tpm_entry *command_entry = (tpm_entry *)wmem_tree_lookup32(cmd_tree, entry->com_pnum);
1052
0
  DISSECTOR_ASSERT(command_entry != NULL);
1053
1054
0
  handl_map.command = command_entry->command;
1055
0
  handl_map.num_req_handles = 0;
1056
0
  handl_map.num_resp_handles = 0;
1057
0
  get_num_hndl(&handl_map);
1058
1059
  /* Dissect response handles */
1060
0
  if (handl_map.num_resp_handles) {
1061
0
    proto_item *hndls = proto_tree_add_item(tree, proto_tpm20_hndl_area,
1062
0
              tvb, 0, -1, ENC_NA);
1063
0
    proto_tree *hndl_tree = proto_item_add_subtree(hndls, ett_tpm_handles);
1064
0
    for (i = 0; i < handl_map.num_resp_handles; i++) {
1065
0
      proto_tree_add_item(hndl_tree, *handl_map.resp_pd[i], tvb,
1066
0
          offset, 4, ENC_BIG_ENDIAN);
1067
0
      offset += 4;
1068
0
    }
1069
0
  }
1070
1071
0
  if (tag == 0x8002) {
1072
    /* Dissect response params size and params */
1073
0
    param_size = tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN);
1074
0
    proto_tree_add_item(tree, hf_resp_param_size, tvb, offset, 4,
1075
0
        ENC_BIG_ENDIAN);
1076
0
    offset += 4;
1077
1078
0
    if (param_size) {
1079
0
      proto_item *params = proto_tree_add_item(tree, proto_tpm20_params_area,
1080
0
               tvb, 0, -1, ENC_NA);
1081
0
      proto_tree *param_tree = proto_item_add_subtree(params, ett_tpm_params);
1082
0
      dissect_response(tvb, pinfo, param_tree, &offset, param_size);
1083
0
    }
1084
1085
    /* Dissect response auth area */
1086
0
    proto_item *auth = proto_tree_add_item(tree, proto_tpm20_auth_area,
1087
0
              tvb, 0, -1, ENC_NA);
1088
0
    proto_tree *auth_tree = proto_item_add_subtree(auth, ett_tpm_auth);
1089
0
    dissect_auth_resp(tvb, pinfo, auth_tree, tree, &offset);
1090
0
  } else if (tag == 0x8001) {
1091
1092
    /* Dissect rest of the response */
1093
0
    dissect_response(tvb, pinfo, tree, &offset, 0);
1094
0
  } else {
1095
0
    proto_tree_add_expert_format(tree, pinfo, &ei_invalid_tag, tvb, 0, 0,
1096
0
          "Error: Invalid Tag: %x", tag);
1097
0
  }
1098
0
}
1099
1100
static int
1101
dissect_tpm20(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1102
  void* data _U_)
1103
0
{
1104
0
  tpm_entry *entry;
1105
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPM");
1106
0
  col_clear(pinfo->cinfo, COL_INFO);
1107
0
  col_append_ports(pinfo->cinfo, COL_INFO, PT_NONE, pinfo->srcport,
1108
0
       pinfo->destport);
1109
1110
0
  int length = tvb_reported_length(tvb);
1111
0
  entry = (tpm_entry *)wmem_tree_lookup32(cmd_tree, pinfo->num);
1112
1113
0
  if (entry == NULL) {
1114
0
    entry = wmem_new(wmem_file_scope(), tpm_entry);
1115
0
    entry->com_pnum = PNUM_UNINIT;
1116
0
    entry->resp_type = PNUM_UNINIT;
1117
0
    entry->command = 0;
1118
0
    entry->num_auths = 0;
1119
0
    wmem_tree_insert32(cmd_tree, pinfo->num, entry);
1120
0
  }
1121
1122
0
  proto_item *item = proto_tree_add_item(tree, proto_tpm20, tvb, 0, -1, ENC_NA);
1123
0
  proto_tree *tpm_tree = proto_item_add_subtree(item, ett_tpm);
1124
1125
0
  if (pinfo->srcport > pinfo->destport) {
1126
0
    col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, " [TPM Request]");
1127
0
    if (length >= TPM_COMMAND_HEADER_LEN)
1128
0
      dissect_tpm20_tpm_command(tvb, pinfo, tpm_tree);
1129
0
    else
1130
0
      dissect_tpm20_platform_command(tvb, pinfo, tpm_tree);
1131
1132
0
  } else {
1133
0
    col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, " [TPM Response]");
1134
0
    if (length >= TPM_COMMAND_HEADER_LEN)
1135
0
      dissect_tpm20_tpm_response(tvb, pinfo, tpm_tree);
1136
0
    else
1137
0
      dissect_tpm20_platform_response(tvb, pinfo, tpm_tree);
1138
0
  }
1139
0
  col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "len(%d)", length);
1140
1141
0
  return tvb_captured_length(tvb);
1142
0
}
1143
1144
static hf_register_info hf[] = {
1145
  { &proto_tpm20_header,
1146
  { "TPM2.0 Header", "tpm.req.header", FT_NONE, BASE_NONE, NULL,
1147
     0x0, "Tpm header", HFILL }},
1148
  { &hf_tpm20_tag,
1149
  { "Tag", "tpm.req.tag", FT_UINT16, BASE_HEX, VALS(tags),
1150
     0x0, NULL, HFILL }},
1151
  { &hf_tpm20_size,
1152
  { "Command size", "tpm.req.size", FT_UINT32, BASE_DEC, NULL,
1153
     0x0, NULL, HFILL }},
1154
  { &hf_tpm20_cc,
1155
  { "Command Code", "tpm.req.cc", FT_UINT32, BASE_HEX, VALS(commands),
1156
     0x0, NULL, HFILL }},
1157
  { &proto_tpm20_auth_area,
1158
  { "Authorization Area", "tpm.req.auth", FT_NONE, BASE_NONE, NULL,
1159
     0x0, NULL, HFILL }},
1160
  { &proto_tpm20_hndl_area,
1161
  { "Handle Area", "tpm.req.hndl", FT_NONE, BASE_NONE, NULL,
1162
     0x0, NULL, HFILL }},
1163
  { &proto_tpm20_params_area,
1164
  { "Parameters Area", "tpm.resp.params", FT_NONE, BASE_NONE, NULL,
1165
     0x0, NULL, HFILL }},
1166
  { &hf_tpm20_platform_cmd,
1167
  { "Platform Command", "tpm.platform_req.cc", FT_UINT32, BASE_HEX, VALS(platform_commands),
1168
     0x0, NULL, HFILL }},
1169
  { &proto_tpm20_resp_header,
1170
  { "TPM2.0 Header", "tpm.resp.header", FT_NONE, BASE_NONE, NULL,
1171
     0x0, "Tpm header", HFILL }},
1172
  { &hf_tpm20_platform_resp_code,
1173
  { "Platform Response Code", "tpm.resp.code", FT_UINT32, BASE_HEX, VALS(responses),
1174
     0x0, NULL, HFILL }},
1175
  { &hf_tpm20_platform_resp_size,
1176
  { "Platform Response size", "tpm.resp.size", FT_UINT32, BASE_HEX, NULL,
1177
     0x0, NULL, HFILL }},
1178
  { &hf_tpm20_resp_tag,
1179
  { "Response Tag", "tpm.resp.tag", FT_UINT16, BASE_HEX, VALS(tags),
1180
     0x0, NULL, HFILL }},
1181
  { &hf_tpm20_resp_size,
1182
  { "Response size", "tpm.resp.size", FT_UINT32, BASE_DEC, NULL,
1183
     0x0, NULL, HFILL }},
1184
  { &hf_tpm20_resp_code,
1185
  { "Response rc", "tpm.resp.rc", FT_UINT32, BASE_HEX, VALS(responses),
1186
     0x0, NULL, HFILL }},
1187
  { &hf_tpm20_startup_type,
1188
  { "Startup type", "tpm.startup.type", FT_UINT16, BASE_HEX, VALS(startup_types),
1189
     0x0, NULL, HFILL }},
1190
  { &hf_tpmi_dh_object,
1191
  { "TPMI_DH_OBJECT", "tpm.handle.TPMI_DH_OBJECT", FT_UINT32, BASE_HEX, VALS(handles),
1192
     0x0, NULL, HFILL }},
1193
  { &hf_tpmi_dh_entity,
1194
  { "TPMI_DH_ENTITY", "tpm.handle.TPMI_DH_ENTITY", FT_UINT32, BASE_HEX, VALS(handles),
1195
     0x0, NULL, HFILL }},
1196
  { &hf_tpmi_dh_context,
1197
  { "TPMI_DH_CONTEXT", "tpm.handle.TPMI_DH_CONTEXT", FT_UINT32, BASE_HEX, NULL,
1198
     0x0, NULL, HFILL }},
1199
  { &hf_tpmi_dh_parent,
1200
  { "TPMI_DH_PARENT", "tpm.handle.TPMI_DH_PARENT", FT_UINT32, BASE_HEX, VALS(hierarhies),
1201
     0x0, NULL, HFILL }},
1202
  { &hf_tpmi_dh_pcr,
1203
  { "TPMI_DH_PCR", "tpm.handle.TPMI_DH_PCR", FT_UINT32, BASE_HEX, NULL,
1204
     0x0, NULL, HFILL }},
1205
  { &hf_tpmi_sh_auth_session,
1206
  { "TPMI_SH_AUTH_SESSION", "tpm.handle.TPMI_SH_AUTH_SESSION", FT_UINT32, BASE_HEX, VALS(handles),
1207
     0x0, NULL, HFILL }},
1208
  { &hf_tpmi_rh_act,
1209
  { "TPMI_RH_ACT", "tpm.handle.TPMI_RH_ACT", FT_UINT32, BASE_HEX, VALS(handles),
1210
     0x0, NULL, HFILL }},
1211
  { &hf_tpmi_rh_hierarhy,
1212
  { "TPMI_RH_HIERARCHY", "tpm.handle.TPMI_RH_HIERARCHY", FT_UINT32, BASE_HEX, VALS(hierarhies),
1213
     0x0, NULL, HFILL }},
1214
  { &hf_tpmi_rh_provision,
1215
  { "TPMI_RH_PROVISION", "tpm.handle.TPMI_RH_PROVISION", FT_UINT32, BASE_HEX, VALS(handles),
1216
     0x0, NULL, HFILL }},
1217
  { &hf_tpmi_rh_platform,
1218
  { "TPMI_RH_PLATFORM", "tpm.handle.TPMI_RH_PLATFORM", FT_UINT32, BASE_HEX, VALS(handles),
1219
     0x0, NULL, HFILL }},
1220
  { &hf_tpmi_rh_clear,
1221
  { "TPMI_RH_CLEAR", "tpm.handle.TPMI_RH_CLEAR", FT_UINT32, BASE_HEX, VALS(handles),
1222
     0x0, NULL, HFILL }},
1223
  { &hf_tpmi_rh_hierarhy_auth,
1224
  { "TPMI_RH_HIERARCHY_AUTH", "tpm.handle.TPMI_RH_HIERARCHY_AUTH", FT_UINT32, BASE_HEX, VALS(handles),
1225
     0x0, NULL, HFILL }},
1226
  { &hf_tpmi_rh_nv_auth,
1227
  { "TPMI_RH_NV_AUTH", "tpm.handle.TPMI_RH_NV_AUTH", FT_UINT32, BASE_HEX, NULL,
1228
     0x0, NULL, HFILL }},
1229
  { &hf_tpmi_rh_nv_index,
1230
  { "TPMI_RH_NV_INDEX", "tpm.handle.TPMI_RH_NV_INDEX", FT_UINT32, BASE_HEX, NULL,
1231
     0x0, NULL, HFILL }},
1232
  { &hf_tpmi_rh_lockout,
1233
  { "TPMI_RH_LOCKOUT", "tpm.handle.TPMI_RH_LOCKOUT", FT_UINT32, BASE_HEX, NULL,
1234
     0x0, NULL, HFILL }},
1235
  { &hf_tpmi_ht_handle,
1236
  { "TPM_HANDLE", "tpm.handle.TPM_HANDLE", FT_UINT32, BASE_HEX, NULL,
1237
     0x0, NULL, HFILL }},
1238
  { &hf_tpmi_rh_endorsment,
1239
  { "TPMI_RH_ENDORSEMENT", "tpm.handle.TPMI_RH_ENDORSEMENT", FT_UINT32, BASE_HEX, NULL,
1240
     0x0, NULL, HFILL }},
1241
  { &hf_auth_area_size,
1242
  { "AUTHAREA SIZE", "tpm.autharea_size", FT_UINT32, BASE_DEC, NULL,
1243
     0x0, NULL, HFILL }},
1244
  { &hf_session_nonce_size,
1245
  { "AUTH NONCE SIZE", "tpm.auth_nonce_size", FT_UINT16, BASE_DEC, NULL,
1246
     0x0, NULL, HFILL }},
1247
  { &hf_session_nonce,
1248
  { "AUTH NONCE", "tpm.auth_nonce", FT_BYTES, BASE_ALLOW_ZERO | BASE_NONE, NULL,
1249
     0x0, NULL, HFILL }},
1250
  { &hf_session_attribs_cont,
1251
  { "SESSION_CONTINUESESSION", "tpm.auth_attribs_cont", FT_BOOLEAN, 8, TFS(&tfs_set_notset),
1252
     TPMA_SESSION_CONTINUESESSION, NULL, HFILL }},
1253
  { &hf_session_attribs_auditex,
1254
  { "SESSION_AUDITEXCLUSIVE", "tpm.auth_attribs_auditex", FT_BOOLEAN, 8, TFS(&tfs_set_notset),
1255
     TPMA_SESSION_AUDITEXCLUSIVE, NULL, HFILL }},
1256
  { &hf_session_attribs_auditreset,
1257
  { "SESSION_AUDITRESET", "tpm.auth_attribs_auditreset", FT_BOOLEAN, 8, TFS(&tfs_set_notset),
1258
     TPMA_SESSION_AUDITRESET, NULL, HFILL }},
1259
  { &hf_session_attribs_res,
1260
  { "SESSION_RESERVED", "tpm.auth_attribs_res", FT_BOOLEAN, 8, TFS(&tfs_set_notset),
1261
     TPMA_SESSION_RESERVED1_MASK, NULL, HFILL }},
1262
  { &hf_session_attribs_decrypt,
1263
  { "SESSION_DECRYPT", "tpm.auth_attribs_decrypt", FT_BOOLEAN, 8, TFS(&tfs_set_notset),
1264
     TPMA_SESSION_DECRYPT, NULL, HFILL }},
1265
  { &hf_session_attribs_encrypt,
1266
  { "SESSION_ENCRYPT", "tpm.auth_attribs_encrypt", FT_BOOLEAN, 8, TFS(&tfs_set_notset),
1267
     TPMA_SESSION_ENCRYPT, NULL, HFILL }},
1268
  { &hf_session_attribs_audit,
1269
  { "SESSION_AUDIT", "tpm.auth_attribs_audit", FT_BOOLEAN, 8, TFS(&tfs_set_notset),
1270
     TPMA_SESSION_AUDIT, NULL, HFILL }},
1271
  { &hf_session_auth_size,
1272
  { "SESSION AUTH SIZE", "tpm.session_auth_size", FT_UINT16, BASE_DEC, NULL,
1273
     0x0, NULL, HFILL }},
1274
  { &hf_session_auth,
1275
  { "SESSION AUTH", "tpm.session_auth", FT_BYTES, BASE_ALLOW_ZERO | BASE_NONE, NULL,
1276
     0x0, NULL, HFILL }},
1277
  { &hf_resp_param_size,
1278
  { "RESP PARAM SIZE", "tpm.resp_param_size", FT_UINT32, BASE_DEC, NULL,
1279
     0x0, NULL, HFILL }},
1280
  { &hf_encrypted_secret_size,
1281
  { "ENCRYPTED SECRET SIZE", "tpm.enc_secret_size", FT_UINT32, BASE_DEC, NULL,
1282
     0x0, NULL, HFILL }},
1283
  { &hf_encrypted_secret,
1284
  { "ENCRYPTED SECRET", "tpm.enc_secret", FT_BYTES, BASE_ALLOW_ZERO | BASE_NONE, NULL,
1285
     0x0, NULL, HFILL }},
1286
  { &hf_session_type,
1287
  { "SESSION TYPE", "tpm.session_type", FT_UINT8, BASE_HEX, VALS(session_type),
1288
     0x0, NULL, HFILL }},
1289
  { &hf_alg_sym,
1290
  { "SYM ALG", "tpm.sym_alg", FT_UINT16, BASE_HEX, VALS(algs),
1291
     0x0, NULL, HFILL }},
1292
  { &hf_alg_sym_mode,
1293
  { "SYM ALG MODE", "tpm.sym_alg_mode", FT_UINT16, BASE_HEX, VALS(algs),
1294
     0x0, NULL, HFILL }},
1295
  { &hf_alg_sym_keybits,
1296
  { "SYM ALG MODE", "tpm.sym_alg_keybits", FT_UINT16, BASE_DEC, NULL,
1297
     0x0, NULL, HFILL }},
1298
  { &hf_alg_hash,
1299
  { "ALG HASH", "tpm.alg_hash", FT_UINT16, BASE_HEX, VALS(algs),
1300
     0x0, NULL, HFILL }},
1301
  { &hf_tpm_priv_size,
1302
  { "TPM PRIVATE SIZE", "tpm.private_size", FT_UINT16, BASE_DEC, NULL,
1303
     0x0, NULL, HFILL }},
1304
  { &hf_tpm_priv,
1305
  { "TPM PRIVATE", "tpm.private", FT_BYTES, BASE_ALLOW_ZERO | BASE_NONE, NULL,
1306
     0x0, NULL, HFILL }},
1307
  { &hf_tpm_pub_size,
1308
  { "TPM PUBLIC SIZE", "tpm.public_size", FT_UINT16, BASE_DEC, NULL,
1309
     0x0, NULL, HFILL }},
1310
  { &hf_tpm_pub,
1311
  { "TPM PUBLIC", "tpm.public", FT_BYTES, BASE_ALLOW_ZERO | BASE_NONE, NULL,
1312
     0x0, NULL, HFILL }},
1313
  { &hf_tpm_name_size,
1314
  { "TPM NAME SIZE", "tpm.name_size", FT_UINT16, BASE_DEC, NULL,
1315
     0x0, NULL, HFILL }},
1316
  { &hf_tpm_name,
1317
  { "TPM NAME", "tpm.name", FT_BYTES, BASE_ALLOW_ZERO | BASE_NONE, NULL,
1318
     0x0, NULL, HFILL }},
1319
  { &hf_tpm_sensitive_crate_size,
1320
  { "TPM SENSITIVE CREATE SIZE", "tpm.sensitive_create_size", FT_UINT16, BASE_DEC, NULL,
1321
     0x0, NULL, HFILL }},
1322
  { &hf_tpm_sensitive_crate,
1323
  { "TPM SENSITIVE CREATE", "tpm.sensitive_create", FT_BYTES, BASE_ALLOW_ZERO | BASE_NONE, NULL,
1324
     0x0, NULL, HFILL }},
1325
  { &hf_tpm_template_size,
1326
  { "TPM TEMPLATE SIZE", "tpm.template_size", FT_UINT16, BASE_DEC, NULL,
1327
     0x0, NULL, HFILL }},
1328
  { &hf_tpm_template,
1329
  { "TPM TEMPLATE", "tpm.template", FT_BYTES, BASE_ALLOW_ZERO | BASE_NONE, NULL,
1330
     0x0, NULL, HFILL }},
1331
  { &hf_tpm_data_size,
1332
  { "TPM DATA SIZE", "tpm.data_size", FT_UINT16, BASE_DEC, NULL,
1333
     0x0, NULL, HFILL }},
1334
  { &hf_tpm_data,
1335
  { "TPM DATA", "tpm.data", FT_BYTES, BASE_ALLOW_ZERO | BASE_NONE, NULL,
1336
     0x0, NULL, HFILL }},
1337
  { &hf_tpm_creation_data_size,
1338
  { "TPM CREATION DATA SIZE", "tpm.creation_data_size", FT_UINT16, BASE_DEC, NULL,
1339
     0x0, NULL, HFILL }},
1340
  { &hf_tpm_creation_data,
1341
  { "TPM CREATION DATA", "tpm.creation_data", FT_BYTES, BASE_ALLOW_ZERO | BASE_NONE, NULL,
1342
     0x0, NULL, HFILL }},
1343
  { &hf_tpm_digest_size,
1344
  { "TPM DIGEST SIZE", "tpm.digest_size", FT_UINT16, BASE_DEC, NULL,
1345
     0x0, NULL, HFILL }},
1346
  { &hf_tpm_digest,
1347
  { "TPM DIGEST", "tpm.digest", FT_BYTES, BASE_ALLOW_ZERO | BASE_NONE, NULL,
1348
     0x0, NULL, HFILL }},
1349
  { &hf_params,
1350
  { "RESPONSE PARAMS", "tpm.PARAMS", FT_BYTES, BASE_NONE, NULL,
1351
     0x0, NULL, HFILL }},
1352
};
1353
1354
static int *ett[] = {
1355
  &ett_tpm,
1356
  &ett_tpm_header,
1357
  &ett_tpm_response_header,
1358
  &ett_tpm_handles,
1359
  &ett_tpm_auth,
1360
  &ett_tpm_params,
1361
  &ett_tpm_attrib
1362
};
1363
1364
static ei_register_info ei[] = {
1365
  { &ei_invalid_tag, { "tpm.invalid_tag", PI_PROTOCOL, PI_ERROR, "Invalid Header Tag", EXPFILL }},
1366
  { &ei_invalid_auth_size, { "tpm.invalid_auth_size", PI_PROTOCOL, PI_ERROR, "Auth area size too small", EXPFILL }},
1367
  { &ei_invalid_num_sessions, { "tpm.invalid_num_sessions", PI_PROTOCOL, PI_ERROR, "Maximum number of sessions exceeded", EXPFILL }},
1368
};
1369
1370
static void
1371
tpm_init(void)
1372
14
{
1373
14
  cmd_tree = wmem_tree_new(wmem_file_scope());
1374
14
}
1375
1376
void
1377
proto_register_tpm20(void)
1378
14
{
1379
14
  proto_tpm20 = proto_register_protocol("TPM2.0 Protocol", "TPM2.0", "tpm");
1380
14
  proto_register_field_array(proto_tpm20, hf, array_length(hf));
1381
14
  proto_register_subtree_array(ett, array_length(ett));
1382
14
  expert_module_t* expert_mod = expert_register_protocol(proto_tpm20);
1383
14
  expert_register_field_array(expert_mod, ei, array_length(ei));
1384
14
  register_init_routine(tpm_init);
1385
14
  tpm20_handle = register_dissector("tpm", dissect_tpm20, proto_tpm20);
1386
14
}
1387
1388
void
1389
proto_reg_handoff_tpm20(void)
1390
14
{
1391
14
  dissector_add_uint_range_with_preference("tcp.port", TCP_TPM_PORTS, tpm20_handle);
1392
14
}
1393
1394
/*
1395
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1396
 *
1397
 * Local variables:
1398
 * c-basic-offset: 8
1399
 * tab-width: 8
1400
 * indent-tabs-mode: t
1401
 * End:
1402
 *
1403
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1404
 * :indentSize=8:tabSize=8:noTabs=false:
1405
 */