blob: c7359cfb3cd748cf401c777a32825cab6cfa12a3 [file] [log] [blame]
Peter Huewed5a36f62018-06-12 00:59:26 +02001/* SPDX-License-Identifier: BSD-2 */
Philip Tricca21fa3212018-02-19 06:43:56 -08002/*
3 * Copyright (c) 2015 - 2018 Intel Corporation
Philip Triccaa003d762017-10-17 13:25:42 -07004 * All rights reserved.
Philip Tricca21fa3212018-02-19 06:43:56 -08005 */
Will Arthur54e04e42015-07-15 11:29:25 -04006
Philip Tricca77683c72017-12-04 16:05:52 -08007#include <inttypes.h>
8#include <limits.h>
Will Arthur54e04e42015-07-15 11:29:25 -04009#include <stdio.h>
Philip Triccaa003d762017-10-17 13:25:42 -070010#include <stdlib.h>
Safayet Ahmed17161292018-06-18 13:22:16 -040011#include <string.h>
Andreas Fuchs43a0d762017-11-30 15:41:05 +010012#include <inttypes.h>
David J. Maria06db5752018-06-19 14:52:37 -070013
14#ifndef _WIN32
15#include <sys/time.h>
Tadeusz Struk105c1a02018-03-09 11:10:36 -080016#include <unistd.h>
David J. Maria06db5752018-06-19 14:52:37 -070017#endif
Will Arthur54e04e42015-07-15 11:29:25 -040018
Philip Tricca8ffd3c42018-03-09 16:27:24 -080019#include "tss2_mu.h"
Philip Tricca8ffd3c42018-03-09 16:27:24 -080020#include "tss2_tcti_mssim.h"
Philip Tricca850bb592018-04-03 09:29:22 -070021
22#include "tcti-mssim.h"
23#include "tcti-common.h"
Philip Triccae394cff2018-04-18 08:36:06 -070024#include "util/key-value-parse.h"
Andreas Fuchs43a0d762017-11-30 15:41:05 +010025#define LOGMODULE tcti
Philip Triccaa7c51ce2018-03-10 18:28:25 -080026#include "util/log.h"
Will Arthur54e04e42015-07-15 11:29:25 -040027
Philip Tricca850bb592018-04-03 09:29:22 -070028/*
29 * This function wraps the "up-cast" of the opaque TCTI context type to the
30 * type for the mssim TCTI context. The only safeguard we have to ensure this
dantpm5358e372018-04-06 15:13:06 -070031 * operation is possible is the magic number in the mssim TCTI context.
Philip Tricca850bb592018-04-03 09:29:22 -070032 * If passed a NULL context, or the magic number check fails, this function
dantpm5358e372018-04-06 15:13:06 -070033 * will return NULL.
Philip Tricca850bb592018-04-03 09:29:22 -070034 */
35TSS2_TCTI_MSSIM_CONTEXT*
36tcti_mssim_context_cast (TSS2_TCTI_CONTEXT *tcti_ctx)
37{
38 if (tcti_ctx != NULL && TSS2_TCTI_MAGIC (tcti_ctx) == TCTI_MSSIM_MAGIC) {
39 return (TSS2_TCTI_MSSIM_CONTEXT*)tcti_ctx;
40 }
41 return NULL;
42}
43/*
44 * This function down-casts the mssim TCTI context to the common context
45 * defined in the tcti-common module.
46 */
47TSS2_TCTI_COMMON_CONTEXT*
48tcti_mssim_down_cast (TSS2_TCTI_MSSIM_CONTEXT *tcti_mssim)
49{
50 if (tcti_mssim == NULL) {
51 return NULL;
52 }
53 return &tcti_mssim->common;
54}
55/*
56 * This function is for sending one of the MS_SIM_* platform commands to the
dantpm5358e372018-04-06 15:13:06 -070057 * Microsoft TPM2 simulator. These are sent over the platform socket.
Philip Tricca850bb592018-04-03 09:29:22 -070058 */
Tadeusz Struk105c1a02018-03-09 11:10:36 -080059TSS2_RC tcti_platform_command (
60 TSS2_TCTI_CONTEXT *tctiContext,
61 UINT32 cmd)
62{
Philip Tricca850bb592018-04-03 09:29:22 -070063 TSS2_TCTI_MSSIM_CONTEXT *tcti_mssim = tcti_mssim_context_cast (tctiContext);
Tadeusz Struk105c1a02018-03-09 11:10:36 -080064 uint8_t buf [sizeof (cmd)] = { 0 };
65 UINT32 rsp = 0;
66 TSS2_RC rc = TSS2_RC_SUCCESS;
67 int ret;
68 ssize_t read_ret;
69
Philip Tricca850bb592018-04-03 09:29:22 -070070 if (tcti_mssim == NULL) {
71 return TSS2_TCTI_RC_BAD_CONTEXT;
72 }
Tadeusz Struk105c1a02018-03-09 11:10:36 -080073 rc = Tss2_MU_UINT32_Marshal (cmd, buf, sizeof (cmd), NULL);
74 if (rc != TSS2_RC_SUCCESS) {
75 LOG_ERROR ("Failed to marshal platform command %" PRIu32 ", rc: 0x%"
76 PRIx32, cmd, rc);
77 return rc;
78 }
79
80 LOGBLOB_DEBUG(buf, sizeof (cmd), "Sending %zu bytes to socket %" PRIu32
Philip Tricca850bb592018-04-03 09:29:22 -070081 ":", sizeof (cmd), tcti_mssim->platform_sock);
82 ret = write_all (tcti_mssim->platform_sock, buf, sizeof (cmd));
Andreas Fuchs450cf0b2018-03-29 15:48:27 +020083 if (ret < (ssize_t) sizeof (cmd)) {
Tadeusz Struk105c1a02018-03-09 11:10:36 -080084 LOG_ERROR("Failed to send platform command %d with error: %d",
85 cmd, ret);
86 return TSS2_TCTI_RC_IO_ERROR;
87 }
88
David J. Maria06db5752018-06-19 14:52:37 -070089#ifdef _WIN32
90 read_ret = recv (tcti_mssim->platform_sock, (char *) buf, sizeof (buf), 0);
Andreas Fuchs450cf0b2018-03-29 15:48:27 +020091 if (read_ret < (ssize_t) sizeof (buf)) {
David J. Maria06db5752018-06-19 14:52:37 -070092 LOG_ERROR ("Failed to get response to platform command, errno %d: %s",
93 WSAGetLastError(), strerror (WSAGetLastError()));
Tadeusz Struk105c1a02018-03-09 11:10:36 -080094 return TSS2_TCTI_RC_IO_ERROR;
95 }
David J. Maria06db5752018-06-19 14:52:37 -070096#else
97 read_ret = read(tcti_mssim->platform_sock, buf, sizeof (buf));
98 if (read_ret < (ssize_t) sizeof (buf)) {
99 LOG_ERROR ("Failed to get response to platform command, errno %d: %s",
100 errno, strerror (errno));
101 return TSS2_TCTI_RC_IO_ERROR;
102 }
103#endif
Tadeusz Struk105c1a02018-03-09 11:10:36 -0800104 LOGBLOB_DEBUG (buf, sizeof (buf), "Received %zu bytes from socket 0x%"
Philip Tricca850bb592018-04-03 09:29:22 -0700105 PRIx32 ":", read_ret, tcti_mssim->platform_sock);
Tadeusz Struk105c1a02018-03-09 11:10:36 -0800106 rc = Tss2_MU_UINT32_Unmarshal (buf, sizeof (rsp), NULL, &rsp);
107 if (rc != TSS2_RC_SUCCESS) {
108 LOG_ERROR ("Failed to unmarshal response to platform command. rc: 0x%"
109 PRIx32, rc);
110 return rc;
111 }
112 if (rsp != 0) {
113 LOG_INFO ("Platform command failed with error: %" PRIu32, rsp);
114 return TSS2_TCTI_RC_IO_ERROR;
115 }
116 return rc;
117}
Philip Tricca850bb592018-04-03 09:29:22 -0700118/*
119 * This function sends the special TPM_SESSION_END message over the provided
120 * socket.
121 */
Philip Triccacac4c3a2018-03-05 18:21:41 -0800122TSS2_RC
123send_sim_session_end (
Philip Triccabdc69452018-02-21 12:45:33 -0800124 SOCKET sock)
Will Arthur54e04e42015-07-15 11:29:25 -0400125{
Philip Triccabdc69452018-02-21 12:45:33 -0800126 uint8_t buf [4] = { 0, };
127 TSS2_RC rc;
Philip Triccadfa41a52016-07-20 17:43:57 -0700128
Philip Triccabdc69452018-02-21 12:45:33 -0800129 rc = Tss2_MU_UINT32_Marshal (TPM_SESSION_END, buf, sizeof (buf), NULL);
130 if (rc == TSS2_RC_SUCCESS) {
131 return rc;
Will Arthur54e04e42015-07-15 11:29:25 -0400132 }
Philip Tricca9bc025d2018-03-05 15:34:06 -0800133 return socket_xmit_buf (sock, buf, sizeof (buf));
Will Arthur54e04e42015-07-15 11:29:25 -0400134}
135
Philip Tricca72fba0b2018-02-21 14:14:32 -0800136/*
dantpm5358e372018-04-06 15:13:06 -0700137 * This function is used to send the simulator a sort of command message
Philip Triccad42e7232018-02-21 14:59:49 -0800138 * that tells it we're about to send it a TPM command. This requires that
139 * we first send it a 4 byte code that's defined by the simulator. Then
140 * another byte identifying the locality and finally the size of the TPM
141 * command buffer that we're about to send. After these 9 bytes are sent
142 * the simulator will accept a TPM command buffer.
143 */
Philip Tricca3a382922018-02-21 16:14:15 -0800144#define SIM_CMD_SIZE (sizeof (UINT32) + sizeof (UINT8) + sizeof (UINT32))
Philip Triccacac4c3a2018-03-05 18:21:41 -0800145TSS2_RC
146send_sim_cmd_setup (
Philip Tricca850bb592018-04-03 09:29:22 -0700147 TSS2_TCTI_MSSIM_CONTEXT *tcti_mssim,
Philip Triccad42e7232018-02-21 14:59:49 -0800148 UINT32 size)
149{
Philip Tricca850bb592018-04-03 09:29:22 -0700150 TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_mssim_down_cast (tcti_mssim);
Philip Tricca3a382922018-02-21 16:14:15 -0800151 uint8_t buf [SIM_CMD_SIZE] = { 0 };
152 size_t offset = 0;
Philip Triccad42e7232018-02-21 14:59:49 -0800153 TSS2_RC rc;
154
Philip Triccad42e7232018-02-21 14:59:49 -0800155 rc = Tss2_MU_UINT32_Marshal (MS_SIM_TPM_SEND_COMMAND,
156 buf,
Philip Tricca3a382922018-02-21 16:14:15 -0800157 sizeof (buf),
158 &offset);
Philip Triccad42e7232018-02-21 14:59:49 -0800159 if (rc != TSS2_RC_SUCCESS) {
160 return rc;
161 }
162
Philip Tricca850bb592018-04-03 09:29:22 -0700163 rc = Tss2_MU_UINT8_Marshal (tcti_common->locality,
Philip Tricca3a382922018-02-21 16:14:15 -0800164 buf,
165 sizeof (buf),
166 &offset);
Philip Triccad42e7232018-02-21 14:59:49 -0800167 if (rc != TSS2_RC_SUCCESS) {
168 return rc;
169 }
170
Philip Tricca3a382922018-02-21 16:14:15 -0800171 rc = Tss2_MU_UINT32_Marshal (size, buf, sizeof (buf), &offset);
Philip Triccad42e7232018-02-21 14:59:49 -0800172 if (rc != TSS2_RC_SUCCESS) {
173 return rc;
174 }
Philip Tricca3a382922018-02-21 16:14:15 -0800175
Philip Tricca850bb592018-04-03 09:29:22 -0700176 return socket_xmit_buf (tcti_mssim->tpm_sock, buf, sizeof (buf));
Philip Triccad42e7232018-02-21 14:59:49 -0800177}
178
Philip Triccacac4c3a2018-03-05 18:21:41 -0800179TSS2_RC
Philip Triccaaddad782018-03-09 11:42:05 -0800180tcti_mssim_transmit (
Philip Triccaaca82c92018-02-21 15:47:40 -0800181 TSS2_TCTI_CONTEXT *tcti_ctx,
182 size_t size,
183 const uint8_t *cmd_buf)
Will Arthur54e04e42015-07-15 11:29:25 -0400184{
Philip Tricca850bb592018-04-03 09:29:22 -0700185 TSS2_TCTI_MSSIM_CONTEXT *tcti_mssim = tcti_mssim_context_cast (tcti_ctx);
186 TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_mssim_down_cast (tcti_mssim);
Andreas Fuchs1c4a8112018-03-29 16:58:07 +0200187 tpm_header_t header;
Philip Triccaaca82c92018-02-21 15:47:40 -0800188 TSS2_RC rc;
Philip Triccadfa41a52016-07-20 17:43:57 -0700189
Philip Tricca850bb592018-04-03 09:29:22 -0700190 if (tcti_mssim == NULL) {
191 return TSS2_TCTI_RC_BAD_CONTEXT;
192 }
193 rc = tcti_common_transmit_checks (tcti_common, cmd_buf);
Philip Triccaaca82c92018-02-21 15:47:40 -0800194 if (rc != TSS2_RC_SUCCESS) {
195 return rc;
wcarthureedecd62015-11-20 16:59:45 -0500196 }
Philip Tricca9d4e41e2018-03-27 08:22:54 -0700197 rc = header_unmarshal (cmd_buf, &header);
Philip Triccaaca82c92018-02-21 15:47:40 -0800198 if (rc != TSS2_RC_SUCCESS) {
199 return rc;
Andreas Fuchsf8a66622017-11-29 14:27:25 +0100200 }
Philip Triccaaca82c92018-02-21 15:47:40 -0800201 if (header.size != size) {
Philip Tricca72fba0b2018-02-21 14:14:32 -0800202 LOG_ERROR ("Buffer size parameter: %zu, and TPM2 command header size "
Philip Triccaaca82c92018-02-21 15:47:40 -0800203 "field: %" PRIu32 " disagree.", size, header.size);
Philip Tricca72fba0b2018-02-21 14:14:32 -0800204 return TSS2_TCTI_RC_BAD_VALUE;
205 }
Will Arthur54e04e42015-07-15 11:29:25 -0400206
Philip Triccaaca82c92018-02-21 15:47:40 -0800207 LOG_DEBUG ("Sending command with TPM_CC 0x%" PRIx32 " and size %" PRIu32,
208 header.code, header.size);
Philip Tricca850bb592018-04-03 09:29:22 -0700209 rc = send_sim_cmd_setup (tcti_mssim, header.size);
Philip Triccaaca82c92018-02-21 15:47:40 -0800210 if (rc != TSS2_RC_SUCCESS) {
211 return rc;
Philip Triccaa003d762017-10-17 13:25:42 -0700212 }
Philip Tricca850bb592018-04-03 09:29:22 -0700213 rc = socket_xmit_buf (tcti_mssim->tpm_sock, cmd_buf, size);
Philip Triccaaca82c92018-02-21 15:47:40 -0800214 if (rc != TSS2_RC_SUCCESS) {
215 return rc;
Philip Triccaa003d762017-10-17 13:25:42 -0700216 }
Will Arthur54e04e42015-07-15 11:29:25 -0400217
Philip Tricca850bb592018-04-03 09:29:22 -0700218 tcti_common->state = TCTI_STATE_RECEIVE;
wcarthureedecd62015-11-20 16:59:45 -0500219
Philip Triccaaca82c92018-02-21 15:47:40 -0800220 return rc;
Will Arthur54e04e42015-07-15 11:29:25 -0400221}
222
Philip Triccacac4c3a2018-03-05 18:21:41 -0800223TSS2_RC
Philip Triccaaddad782018-03-09 11:42:05 -0800224tcti_mssim_cancel (
Philip Triccacac4c3a2018-03-05 18:21:41 -0800225 TSS2_TCTI_CONTEXT *tctiContext)
Will Arthur54e04e42015-07-15 11:29:25 -0400226{
Philip Tricca850bb592018-04-03 09:29:22 -0700227 TSS2_TCTI_MSSIM_CONTEXT *tcti_mssim = tcti_mssim_context_cast (tctiContext);
228 TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_mssim_down_cast (tcti_mssim);
Philip Tricca3f1828c2017-10-18 18:44:13 -0700229 TSS2_RC rc;
Will Arthur54e04e42015-07-15 11:29:25 -0400230
Philip Tricca850bb592018-04-03 09:29:22 -0700231 if (tcti_mssim == NULL) {
232 return TSS2_TCTI_RC_BAD_CONTEXT;
233 }
234 rc = tcti_common_cancel_checks (tcti_common);
Philip Tricca3f1828c2017-10-18 18:44:13 -0700235 if (rc != TSS2_RC_SUCCESS) {
236 return rc;
Will Arthur54e04e42015-07-15 11:29:25 -0400237 }
Tadeusz Struk105c1a02018-03-09 11:10:36 -0800238 rc = tcti_platform_command (tctiContext, MS_SIM_CANCEL_ON);
Philip Triccafa14abe2018-03-05 21:14:54 -0800239 if (rc != TSS2_RC_SUCCESS) {
240 return rc;
241 }
242
Philip Tricca850bb592018-04-03 09:29:22 -0700243 tcti_common->state = TCTI_STATE_TRANSMIT;
244 tcti_mssim->cancel = 1;
Tadeusz Struk262c1ef2018-03-08 09:56:34 -0800245
Philip Triccafa14abe2018-03-05 21:14:54 -0800246 return rc;
Will Arthur54e04e42015-07-15 11:29:25 -0400247}
248
Philip Triccacac4c3a2018-03-05 18:21:41 -0800249TSS2_RC
Philip Triccaaddad782018-03-09 11:42:05 -0800250tcti_mssim_set_locality (
Philip Triccaa003d762017-10-17 13:25:42 -0700251 TSS2_TCTI_CONTEXT *tctiContext,
Philip Triccacac4c3a2018-03-05 18:21:41 -0800252 uint8_t locality)
Will Arthur54e04e42015-07-15 11:29:25 -0400253{
Philip Tricca850bb592018-04-03 09:29:22 -0700254 TSS2_TCTI_MSSIM_CONTEXT *tcti_mssim = tcti_mssim_context_cast (tctiContext);
255 TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_mssim_down_cast (tcti_mssim);
Philip Tricca3f1828c2017-10-18 18:44:13 -0700256 TSS2_RC rc;
Will Arthur54e04e42015-07-15 11:29:25 -0400257
Philip Tricca850bb592018-04-03 09:29:22 -0700258 if (tcti_mssim == NULL) {
259 return TSS2_TCTI_RC_BAD_CONTEXT;
260 }
261 rc = tcti_common_set_locality_checks (tcti_common);
Philip Tricca3f1828c2017-10-18 18:44:13 -0700262 if (rc != TSS2_RC_SUCCESS) {
263 return rc;
Will Arthur54e04e42015-07-15 11:29:25 -0400264 }
Philip Tricca3f1828c2017-10-18 18:44:13 -0700265
Philip Tricca850bb592018-04-03 09:29:22 -0700266 tcti_common->locality = locality;
Philip Triccaa003d762017-10-17 13:25:42 -0700267 return TSS2_RC_SUCCESS;
Will Arthur54e04e42015-07-15 11:29:25 -0400268}
269
Philip Triccacac4c3a2018-03-05 18:21:41 -0800270TSS2_RC
Philip Triccaaddad782018-03-09 11:42:05 -0800271tcti_mssim_get_poll_handles (
Philip Triccaa003d762017-10-17 13:25:42 -0700272 TSS2_TCTI_CONTEXT *tctiContext,
Philip Tricca5917fbf2017-06-29 08:24:09 -0700273 TSS2_TCTI_POLL_HANDLE *handles,
Philip Triccaa003d762017-10-17 13:25:42 -0700274 size_t *num_handles)
Philip Tricca5917fbf2017-06-29 08:24:09 -0700275{
Andreas Fuchsbaeb2be2018-03-29 15:39:50 +0200276 (void)(tctiContext);
277 (void)(handles);
278 (void)(num_handles);
Philip Tricca5917fbf2017-06-29 08:24:09 -0700279 return TSS2_TCTI_RC_NOT_IMPLEMENTED;
280}
281
Philip Triccacac4c3a2018-03-05 18:21:41 -0800282void
Philip Triccaaddad782018-03-09 11:42:05 -0800283tcti_mssim_finalize(
Philip Triccacac4c3a2018-03-05 18:21:41 -0800284 TSS2_TCTI_CONTEXT *tctiContext)
Will Arthur54e04e42015-07-15 11:29:25 -0400285{
Philip Tricca850bb592018-04-03 09:29:22 -0700286 TSS2_TCTI_MSSIM_CONTEXT *tcti_mssim = tcti_mssim_context_cast (tctiContext);
Philip Tricca24f555c2017-10-13 17:51:53 -0700287
Philip Tricca850bb592018-04-03 09:29:22 -0700288 if (tcti_mssim == NULL) {
Philip Triccaa003d762017-10-17 13:25:42 -0700289 return;
wcarthurf979e352015-11-24 17:34:44 -0500290 }
Philip Tricca850bb592018-04-03 09:29:22 -0700291 send_sim_session_end (tcti_mssim->platform_sock);
292 send_sim_session_end (tcti_mssim->tpm_sock);
293 socket_close (&tcti_mssim->platform_sock);
294 socket_close (&tcti_mssim->tpm_sock);
Will Arthur54e04e42015-07-15 11:29:25 -0400295}
296
Philip Triccacac4c3a2018-03-05 18:21:41 -0800297TSS2_RC
Philip Triccaaddad782018-03-09 11:42:05 -0800298tcti_mssim_receive (
Philip Triccaa003d762017-10-17 13:25:42 -0700299 TSS2_TCTI_CONTEXT *tctiContext,
300 size_t *response_size,
301 unsigned char *response_buffer,
Philip Triccacac4c3a2018-03-05 18:21:41 -0800302 int32_t timeout)
Will Arthur54e04e42015-07-15 11:29:25 -0400303{
Philip Tricca850bb592018-04-03 09:29:22 -0700304 TSS2_TCTI_MSSIM_CONTEXT *tcti_mssim = tcti_mssim_context_cast (tctiContext);
305 TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_mssim_down_cast (tcti_mssim);
Philip Triccacac4c3a2018-03-05 18:21:41 -0800306 TSS2_RC rc;
Philip Tricca850bb592018-04-03 09:29:22 -0700307 UINT32 trash;
Philip Triccacac4c3a2018-03-05 18:21:41 -0800308 int ret;
wcarthureedecd62015-11-20 16:59:45 -0500309
Philip Tricca850bb592018-04-03 09:29:22 -0700310 if (tcti_mssim == NULL) {
311 return TSS2_TCTI_RC_BAD_CONTEXT;
312 }
313 rc = tcti_common_receive_checks (tcti_common, response_size);
Philip Triccacac4c3a2018-03-05 18:21:41 -0800314 if (rc != TSS2_RC_SUCCESS) {
Philip Tricca5477c2a2018-03-07 15:39:28 -0800315 return rc;
Philip Triccadfa41a52016-07-20 17:43:57 -0700316 }
317
Philip Tricca9eb86d52018-03-05 15:50:05 -0800318 if (timeout != TSS2_TCTI_TIMEOUT_BLOCK) {
319 LOG_WARNING ("Asynchronous I/O not implemented. The 'timeout' "
320 "parameter must be TSS2_TCTI_TIMEOUT_BLOCK.");
321 return TSS2_TCTI_RC_BAD_VALUE;
wcarthur74a92a42015-12-07 16:02:12 -0500322 }
Will Arthur54e04e42015-07-15 11:29:25 -0400323
Philip Tricca850bb592018-04-03 09:29:22 -0700324 if (tcti_common->header.size == 0) {
Philip Triccaa003d762017-10-17 13:25:42 -0700325 /* Receive the size of the response. */
Philip Tricca7ac36402018-03-05 16:21:28 -0800326 uint8_t size_buf [sizeof (UINT32)];
Philip Tricca850bb592018-04-03 09:29:22 -0700327 ret = socket_recv_buf (tcti_mssim->tpm_sock, size_buf, sizeof (UINT32));
Philip Triccacac4c3a2018-03-05 18:21:41 -0800328 if (ret != sizeof (UINT32)) {
329 rc = TSS2_TCTI_RC_IO_ERROR;
Philip Tricca850bb592018-04-03 09:29:22 -0700330 goto out;
Philip Triccaa003d762017-10-17 13:25:42 -0700331 }
wcarthureedecd62015-11-20 16:59:45 -0500332
Philip Triccacac4c3a2018-03-05 18:21:41 -0800333 rc = Tss2_MU_UINT32_Unmarshal (size_buf,
334 sizeof (size_buf),
335 0,
Philip Tricca850bb592018-04-03 09:29:22 -0700336 &tcti_common->header.size);
Philip Triccacac4c3a2018-03-05 18:21:41 -0800337 if (rc != TSS2_RC_SUCCESS) {
Philip Tricca7ac36402018-03-05 16:21:28 -0800338 LOG_WARNING ("Failed to unmarshal size from tpm2 simulator "
Philip Triccacac4c3a2018-03-05 18:21:41 -0800339 "protocol: 0x%" PRIu32, rc);
Philip Tricca850bb592018-04-03 09:29:22 -0700340 goto out;
Philip Tricca7ac36402018-03-05 16:21:28 -0800341 }
342
Philip Tricca850bb592018-04-03 09:29:22 -0700343 LOG_DEBUG ("response size: %" PRIu32, tcti_common->header.size);
Will Arthur54e04e42015-07-15 11:29:25 -0400344 }
345
Philip Tricca850bb592018-04-03 09:29:22 -0700346 *response_size = tcti_common->header.size;
Philip Triccaa003d762017-10-17 13:25:42 -0700347 if (response_buffer == NULL) {
Philip Tricca5477c2a2018-03-07 15:39:28 -0800348 return TSS2_RC_SUCCESS;
wcarthur74a92a42015-12-07 16:02:12 -0500349 }
350
Philip Tricca850bb592018-04-03 09:29:22 -0700351 if (*response_size < tcti_common->header.size) {
352 *response_size = tcti_common->header.size;
Philip Tricca5477c2a2018-03-07 15:39:28 -0800353 return TSS2_TCTI_RC_INSUFFICIENT_BUFFER;
Will Arthur54e04e42015-07-15 11:29:25 -0400354 }
355
Philip Tricca7ac36402018-03-05 16:21:28 -0800356 /* Receive the TPM response. */
Philip Tricca850bb592018-04-03 09:29:22 -0700357 LOG_DEBUG ("Reading response of size %" PRIu32, tcti_common->header.size);
358 ret = socket_recv_buf (tcti_mssim->tpm_sock,
Philip Triccacac4c3a2018-03-05 18:21:41 -0800359 (unsigned char *)response_buffer,
Philip Tricca850bb592018-04-03 09:29:22 -0700360 tcti_common->header.size);
Philip Tricca097cae62018-04-08 13:42:29 -0700361 if (ret < (ssize_t)tcti_common->header.size) {
Philip Triccacac4c3a2018-03-05 18:21:41 -0800362 rc = TSS2_TCTI_RC_IO_ERROR;
Philip Tricca850bb592018-04-03 09:29:22 -0700363 goto out;
Philip Tricca7ac36402018-03-05 16:21:28 -0800364 }
Philip Tricca850bb592018-04-03 09:29:22 -0700365 LOGBLOB_DEBUG(response_buffer, tcti_common->header.size,
Philip Tricca10b81162018-03-06 14:59:56 -0800366 "Response buffer received:");
Philip Tricca7ac36402018-03-05 16:21:28 -0800367
368 /* Receive the appended four bytes of 0's */
Philip Tricca850bb592018-04-03 09:29:22 -0700369 ret = socket_recv_buf (tcti_mssim->tpm_sock,
Philip Triccacac4c3a2018-03-05 18:21:41 -0800370 (unsigned char *)&trash,
371 4);
372 if (ret != 4) {
373 rc = TSS2_TCTI_RC_IO_ERROR;
Philip Tricca850bb592018-04-03 09:29:22 -0700374 goto out;
Will Arthur54e04e42015-07-15 11:29:25 -0400375 }
Philip Triccadfa41a52016-07-20 17:43:57 -0700376
Philip Tricca850bb592018-04-03 09:29:22 -0700377 if (tcti_mssim->cancel) {
Tadeusz Struk105c1a02018-03-09 11:10:36 -0800378 rc = tcti_platform_command (tctiContext, MS_SIM_CANCEL_OFF);
Philip Tricca850bb592018-04-03 09:29:22 -0700379 tcti_mssim->cancel = 0;
Tadeusz Struk262c1ef2018-03-08 09:56:34 -0800380 }
Philip Tricca5477c2a2018-03-07 15:39:28 -0800381 /*
382 * Executing code beyond this point transitions the state machine to
383 * TRANSMIT. Another call to this function will not be possible until
384 * another command is sent to the TPM.
385 */
Philip Tricca850bb592018-04-03 09:29:22 -0700386out:
387 tcti_common->header.size = 0;
388 tcti_common->state = TCTI_STATE_TRANSMIT;
Philip Triccadfa41a52016-07-20 17:43:57 -0700389
Philip Triccacac4c3a2018-03-05 18:21:41 -0800390 return rc;
Will Arthur54e04e42015-07-15 11:29:25 -0400391}
392
Philip Tricca40e926d2016-09-22 20:37:28 -0700393/**
394 * This function sends the Microsoft simulator the MS_SIM_POWER_ON and
Tadeusz Struk105c1a02018-03-09 11:10:36 -0800395 * MS_SIM_NV_ON commands using the platform command mechanism. Without
Philip Tricca40e926d2016-09-22 20:37:28 -0700396 * these the simulator will respond with zero sized buffer which causes
dantpm5358e372018-04-06 15:13:06 -0700397 * the TSS to freak out. Sending this command more than once is harmless,
Philip Tricca40e926d2016-09-22 20:37:28 -0700398 * so it's advisable to call this function as part of the TCTI context
399 * initialization just to be sure.
400 *
401 * NOTE: The caller will still need to call Tss2_Sys_Startup. If they
402 * don't, an error will be returned from each call till they do but
Andreas Fuchsbe5899d2017-11-13 17:14:36 +0100403 * the error will at least be meaningful (TPM2_RC_INITIALIZE).
Philip Tricca40e926d2016-09-22 20:37:28 -0700404 */
Philip Triccadc4ff842018-03-04 21:59:48 -0800405static TSS2_RC
406simulator_setup (
407 TSS2_TCTI_CONTEXT *tctiContext)
Philip Tricca40e926d2016-09-22 20:37:28 -0700408{
Philip Triccacac4c3a2018-03-05 18:21:41 -0800409 TSS2_RC rc;
Philip Tricca40e926d2016-09-22 20:37:28 -0700410
Philip Triccadc4ff842018-03-04 21:59:48 -0800411 LOG_TRACE ("Initializing TCTI context 0x%" PRIxPTR,
412 (uintptr_t)tctiContext);
Tadeusz Struk105c1a02018-03-09 11:10:36 -0800413 rc = tcti_platform_command (tctiContext, MS_SIM_POWER_ON);
Philip Triccacac4c3a2018-03-05 18:21:41 -0800414 if (rc != TSS2_RC_SUCCESS) {
Philip Triccadc4ff842018-03-04 21:59:48 -0800415 LOG_WARNING ("Failed to send MS_SIM_POWER_ON platform command.");
Philip Triccacac4c3a2018-03-05 18:21:41 -0800416 return rc;
Philip Tricca40e926d2016-09-22 20:37:28 -0700417 }
Philip Triccaa003d762017-10-17 13:25:42 -0700418
Tadeusz Struk105c1a02018-03-09 11:10:36 -0800419 rc = tcti_platform_command (tctiContext, MS_SIM_NV_ON);
Philip Triccacac4c3a2018-03-05 18:21:41 -0800420 if (rc != TSS2_RC_SUCCESS) {
Philip Triccadc4ff842018-03-04 21:59:48 -0800421 LOG_WARNING ("Failed to send MS_SIM_NV_ON platform command.");
Philip Triccaa003d762017-10-17 13:25:42 -0700422 }
Philip Tricca40e926d2016-09-22 20:37:28 -0700423
Philip Triccacac4c3a2018-03-05 18:21:41 -0800424 return rc;
Philip Tricca40e926d2016-09-22 20:37:28 -0700425}
426
Philip Tricca77683c72017-12-04 16:05:52 -0800427/*
428 * This is a utility function to extract a TCP port number from a string.
429 * The string must be 6 characters long. If the supplied string contains an
430 * invalid port number then 0 is returned.
431 */
432static uint16_t
433string_to_port (char port_str[6])
434{
435 uint32_t port = 0;
436
437 if (sscanf (port_str, "%" SCNu32, &port) == EOF || port > UINT16_MAX) {
438 return 0;
439 }
440 return port;
441}
Philip Triccac21dbf32018-03-03 09:07:48 -0800442/*
Philip Triccae394cff2018-04-18 08:36:06 -0700443 * This function is a callback conforming to the KeyValueFunc prototype. It
444 * is called by the key-value-parse module for each key / value pair extracted
445 * from the configuration string. Its sole purpose is to identify valid keys
446 * from the conf string and to store their corresponding values in the
447 * mssim_conf_t structure which is passed through the 'user_data' parameter.
Philip Triccac21dbf32018-03-03 09:07:48 -0800448 */
449TSS2_RC
Philip Triccae394cff2018-04-18 08:36:06 -0700450mssim_kv_callback (const key_value_t *key_value,
451 void *user_data)
Philip Tricca77683c72017-12-04 16:05:52 -0800452{
Philip Triccae394cff2018-04-18 08:36:06 -0700453 mssim_conf_t *mssim_conf = (mssim_conf_t*)user_data;
Philip Tricca77683c72017-12-04 16:05:52 -0800454
Philip Triccae394cff2018-04-18 08:36:06 -0700455 LOG_TRACE ("key_value: 0x%" PRIxPTR " and user_data: 0x%" PRIxPTR,
456 (uintptr_t)key_value, (uintptr_t)user_data);
457 if (key_value == NULL || user_data == NULL) {
458 LOG_WARNING ("%s passed NULL parameter", __func__);
459 return TSS2_TCTI_RC_GENERAL_FAILURE;
Philip Tricca77683c72017-12-04 16:05:52 -0800460 }
Philip Triccae394cff2018-04-18 08:36:06 -0700461 LOG_DEBUG ("key: %s / value: %s\n", key_value->key, key_value->value);
462 if (strcmp (key_value->key, "host") == 0) {
463 mssim_conf->host = key_value->value;
464 return TSS2_RC_SUCCESS;
465 } else if (strcmp (key_value->key, "port") == 0) {
466 mssim_conf->port = string_to_port (key_value->value);
467 if (mssim_conf->port == 0) {
468 return TSS2_TCTI_RC_BAD_VALUE;
469 }
470 return TSS2_RC_SUCCESS;
471 } else {
472 return TSS2_TCTI_RC_BAD_VALUE;
Philip Tricca77683c72017-12-04 16:05:52 -0800473 }
Philip Tricca77683c72017-12-04 16:05:52 -0800474}
Philip Triccac21dbf32018-03-03 09:07:48 -0800475void
Philip Triccaaddad782018-03-09 11:42:05 -0800476tcti_mssim_init_context_data (
Philip Tricca850bb592018-04-03 09:29:22 -0700477 TSS2_TCTI_COMMON_CONTEXT *tcti_common)
Philip Triccac21dbf32018-03-03 09:07:48 -0800478{
Philip Tricca850bb592018-04-03 09:29:22 -0700479 TSS2_TCTI_MAGIC (tcti_common) = TCTI_MSSIM_MAGIC;
480 TSS2_TCTI_VERSION (tcti_common) = TCTI_VERSION;
481 TSS2_TCTI_TRANSMIT (tcti_common) = tcti_mssim_transmit;
482 TSS2_TCTI_RECEIVE (tcti_common) = tcti_mssim_receive;
483 TSS2_TCTI_FINALIZE (tcti_common) = tcti_mssim_finalize;
484 TSS2_TCTI_CANCEL (tcti_common) = tcti_mssim_cancel;
485 TSS2_TCTI_GET_POLL_HANDLES (tcti_common) = tcti_mssim_get_poll_handles;
486 TSS2_TCTI_SET_LOCALITY (tcti_common) = tcti_mssim_set_locality;
487 TSS2_TCTI_MAKE_STICKY (tcti_common) = tcti_make_sticky_not_implemented;
488 tcti_common->state = TCTI_STATE_TRANSMIT;
489 tcti_common->locality = 3;
490 memset (&tcti_common->header, 0, sizeof (tcti_common->header));
Philip Triccac21dbf32018-03-03 09:07:48 -0800491}
492/*
493 * This is an implementation of the standard TCTI initialization function for
494 * this module.
495 */
496TSS2_RC
Philip Triccaaddad782018-03-09 11:42:05 -0800497Tss2_Tcti_Mssim_Init (
Philip Triccac21dbf32018-03-03 09:07:48 -0800498 TSS2_TCTI_CONTEXT *tctiContext,
499 size_t *size,
500 const char *conf)
501{
Philip Tricca850bb592018-04-03 09:29:22 -0700502 TSS2_TCTI_MSSIM_CONTEXT *tcti_mssim = (TSS2_TCTI_MSSIM_CONTEXT*)tctiContext;
503 TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_mssim_down_cast (tcti_mssim);
Philip Triccac21dbf32018-03-03 09:07:48 -0800504 TSS2_RC rc;
Philip Triccae394cff2018-04-18 08:36:06 -0700505 char *conf_copy = NULL;
506 mssim_conf_t mssim_conf = MSSIM_CONF_DEFAULT_INIT;
Philip Triccac21dbf32018-03-03 09:07:48 -0800507
Philip Triccaad8140e2018-11-11 15:10:19 -0800508 if (conf == NULL) {
Juergen Repp54090542018-09-12 16:25:43 +0200509 LOG_TRACE ("tctiContext: 0x%" PRIxPTR ", size: 0x%" PRIxPTR ""
510 " default configuration will be used.",
511 (uintptr_t)tctiContext, (uintptr_t)size);
Philip Triccaad8140e2018-11-11 15:10:19 -0800512 } else {
Juergen Repp54090542018-09-12 16:25:43 +0200513 LOG_TRACE ("tctiContext: 0x%" PRIxPTR ", size: 0x%" PRIxPTR ", conf: %s",
514 (uintptr_t)tctiContext, (uintptr_t)size, conf);
Philip Triccaad8140e2018-11-11 15:10:19 -0800515 }
Philip Tricca850bb592018-04-03 09:29:22 -0700516 if (size == NULL) {
Philip Triccac21dbf32018-03-03 09:07:48 -0800517 return TSS2_TCTI_RC_BAD_VALUE;
Philip Tricca850bb592018-04-03 09:29:22 -0700518 }
519 if (tctiContext == NULL) {
520 *size = sizeof (TSS2_TCTI_MSSIM_CONTEXT);
Philip Triccac21dbf32018-03-03 09:07:48 -0800521 return TSS2_RC_SUCCESS;
Philip Triccac21dbf32018-03-03 09:07:48 -0800522 }
523
Philip Triccae394cff2018-04-18 08:36:06 -0700524 if (conf != NULL) {
525 LOG_TRACE ("conf is not NULL");
526 if (strlen (conf) > TCTI_MSSIM_CONF_MAX) {
527 LOG_WARNING ("Provided conf string exceeds maximum of %u",
528 TCTI_MSSIM_CONF_MAX);
529 return TSS2_TCTI_RC_BAD_VALUE;
530 }
531 conf_copy = strdup (conf);
532 if (conf_copy == NULL) {
533 LOG_ERROR ("Failed to allocate buffer: %s", strerror (errno));
534 rc = TSS2_TCTI_RC_GENERAL_FAILURE;
535 goto fail_out;
536 }
537 LOG_DEBUG ("Dup'd conf string to: 0x%" PRIxPTR,
538 (uintptr_t)conf_copy);
539 rc = parse_key_value_string (conf_copy,
540 mssim_kv_callback,
541 &mssim_conf);
542 if (rc != TSS2_RC_SUCCESS) {
543 goto fail_out;
544 }
545 }
546 LOG_DEBUG ("Initializing mssim TCTI with host: %s, port: %" PRIu16,
547 mssim_conf.host, mssim_conf.port);
548
Tadeusz Strukc8887d52018-04-27 11:30:09 -0700549 tcti_mssim->tpm_sock = -1;
550 tcti_mssim->platform_sock = -1;
551
Philip Triccae394cff2018-04-18 08:36:06 -0700552 rc = socket_connect (mssim_conf.host,
553 mssim_conf.port,
554 &tcti_mssim->tpm_sock);
Philip Triccac21dbf32018-03-03 09:07:48 -0800555 if (rc != TSS2_RC_SUCCESS) {
Philip Triccae394cff2018-04-18 08:36:06 -0700556 goto fail_out;
Philip Triccac21dbf32018-03-03 09:07:48 -0800557 }
558
Philip Triccae394cff2018-04-18 08:36:06 -0700559 rc = socket_connect (mssim_conf.host,
560 mssim_conf.port + 1,
561 &tcti_mssim->platform_sock);
Philip Tricca2bec2a82018-03-04 21:27:30 -0800562 if (rc != TSS2_RC_SUCCESS) {
563 goto fail_out;
Philip Triccac21dbf32018-03-03 09:07:48 -0800564 }
565
Philip Tricca850bb592018-04-03 09:29:22 -0700566 tcti_mssim_init_context_data (tcti_common);
Philip Triccadc4ff842018-03-04 21:59:48 -0800567 rc = simulator_setup (tctiContext);
Philip Triccac21dbf32018-03-03 09:07:48 -0800568 if (rc != TSS2_RC_SUCCESS) {
Philip Tricca2bec2a82018-03-04 21:27:30 -0800569 goto fail_out;
Philip Triccac21dbf32018-03-03 09:07:48 -0800570 }
571
Philip Triccae394cff2018-04-18 08:36:06 -0700572 if (conf_copy != NULL) {
573 free (conf_copy);
574 }
Philip Tricca2bec2a82018-03-04 21:27:30 -0800575 return TSS2_RC_SUCCESS;
576
577fail_out:
Philip Triccae394cff2018-04-18 08:36:06 -0700578 if (conf_copy != NULL) {
579 free (conf_copy);
580 }
Philip Tricca850bb592018-04-03 09:29:22 -0700581 socket_close (&tcti_mssim->tpm_sock);
582 socket_close (&tcti_mssim->platform_sock);
Philip Tricca2bec2a82018-03-04 21:27:30 -0800583
Philip Triccae394cff2018-04-18 08:36:06 -0700584 return rc;
Philip Triccac21dbf32018-03-03 09:07:48 -0800585}
586
Philip Tricca77683c72017-12-04 16:05:52 -0800587/* public info structure */
Andreas Fuchs37b45c62018-03-29 16:54:33 +0200588const TSS2_TCTI_INFO tss2_tcti_info = {
Philip Triccadf1410e2018-04-23 13:07:17 -0700589 .version = TCTI_VERSION,
Philip Tricca77683c72017-12-04 16:05:52 -0800590 .name = "tcti-socket",
591 .description = "TCTI module for communication with the Microsoft TPM2 Simulator.",
Philip Triccae394cff2018-04-18 08:36:06 -0700592 .config_help = "Key / value string in the form \"host=localhost,port=2321\".",
Philip Triccaaddad782018-03-09 11:42:05 -0800593 .init = Tss2_Tcti_Mssim_Init,
Philip Tricca77683c72017-12-04 16:05:52 -0800594};
595
596const TSS2_TCTI_INFO*
597Tss2_Tcti_Info (void)
598{
599 return &tss2_tcti_info;
600}