3
* Licensed Materials - Property of IBM
5
* trousers - An open source TCG Software Stack
7
* (C) Copyright International Business Machines Corp. 2004-2006
14
#include <sys/socket.h>
15
#include <sys/types.h>
16
#include <netinet/in.h>
17
#include <arpa/inet.h>
24
#include "trousers/tss.h"
25
#include "trousers/trousers.h"
26
#include "trousers_types.h"
27
#include "spi_utils.h"
28
#include "capabilities.h"
30
#include "hosttable.h"
31
#include "tcsd_wrap.h"
33
#include "rpc_tcstp_tsp.h"
37
initData(struct tcsd_comm_data *comm, int parm_count)
39
/* min packet size should be the size of the header */
40
memset(&comm->hdr, 0, sizeof(struct tcsd_packet_hdr));
41
comm->hdr.packet_size = sizeof(struct tcsd_packet_hdr);
43
comm->hdr.type_offset = sizeof(struct tcsd_packet_hdr);
44
comm->hdr.parm_offset = comm->hdr.type_offset +
45
(sizeof(TCSD_PACKET_TYPE) * parm_count);
46
comm->hdr.packet_size = comm->hdr.parm_offset;
49
memset(comm->buf, 0, comm->buf_size);
53
loadData(UINT64 *offset, TCSD_PACKET_TYPE data_type, void *data, int data_size, BYTE *blob)
56
case TCSD_PACKET_TYPE_BYTE:
57
Trspi_LoadBlob_BYTE(offset, *((BYTE *) (data)), blob);
59
case TCSD_PACKET_TYPE_BOOL:
60
Trspi_LoadBlob_BOOL(offset, *((TSS_BOOL *) (data)), blob);
62
case TCSD_PACKET_TYPE_UINT16:
63
Trspi_LoadBlob_UINT16(offset, *((UINT16 *) (data)), blob);
65
case TCSD_PACKET_TYPE_UINT32:
66
Trspi_LoadBlob_UINT32(offset, *((UINT32 *) (data)), blob);
68
case TCSD_PACKET_TYPE_PBYTE:
69
Trspi_LoadBlob(offset, data_size, blob, (BYTE *)data);
71
case TCSD_PACKET_TYPE_NONCE:
72
Trspi_LoadBlob(offset, 20, blob, ((TCPA_NONCE *)data)->nonce);
74
case TCSD_PACKET_TYPE_DIGEST:
75
Trspi_LoadBlob(offset, 20, blob, ((TCPA_DIGEST *)data)->digest);
77
case TCSD_PACKET_TYPE_AUTH:
78
LoadBlob_AUTH(offset, blob, ((TPM_AUTH *)data));
80
case TCSD_PACKET_TYPE_UUID:
81
Trspi_LoadBlob_UUID(offset, blob, *((TSS_UUID *)data));
83
case TCSD_PACKET_TYPE_ENCAUTH:
84
Trspi_LoadBlob(offset, 20, blob, ((TCPA_ENCAUTH *)data)->authdata);
86
case TCSD_PACKET_TYPE_VERSION:
87
Trspi_LoadBlob_TCPA_VERSION(offset, blob, *((TCPA_VERSION *)data));
89
case TCSD_PACKET_TYPE_LOADKEY_INFO:
90
LoadBlob_LOADKEY_INFO(offset, blob, ((TCS_LOADKEY_INFO *)data));
92
case TCSD_PACKET_TYPE_PCR_EVENT:
93
Trspi_LoadBlob_PCR_EVENT(offset, blob, ((TSS_PCR_EVENT *)data));
95
case TCSD_PACKET_TYPE_COUNTER_VALUE:
96
Trspi_LoadBlob_COUNTER_VALUE(offset, blob, ((TPM_COUNTER_VALUE *)data));
98
case TCSD_PACKET_TYPE_SECRET:
99
Trspi_LoadBlob(offset, 20, blob, ((TCPA_SECRET *)data)->authdata);
102
LogError("TCSD packet type unknown! (0x%x)", data_type & 0xff);
103
return TCSERR(TSS_E_INTERNAL_ERROR);
110
setData(TCSD_PACKET_TYPE dataType,
114
struct tcsd_comm_data *comm)
116
UINT64 old_offset, offset;
118
TCSD_PACKET_TYPE *type;
120
/* Calculate the size of the area needed (use NULL for blob address) */
122
if ((result = loadData(&offset, dataType, theData, theDataSize, NULL)))
124
if (((int)comm->hdr.packet_size + (int)offset) < 0) {
125
LogError("Too much data to be transmitted!");
126
return TCSERR(TSS_E_INTERNAL_ERROR);
128
if (((int)comm->hdr.packet_size + (int)offset) > comm->buf_size) {
129
/* reallocate the buffer */
131
int buffer_size = comm->hdr.packet_size + offset;
133
LogDebug("Increasing communication buffer to %d bytes.", buffer_size);
134
buffer = realloc(comm->buf, buffer_size);
135
if (buffer == NULL) {
136
LogError("realloc of %d bytes failed.", buffer_size);
137
return TCSERR(TSS_E_INTERNAL_ERROR);
139
comm->buf_size = buffer_size;
143
offset = old_offset = comm->hdr.parm_offset + comm->hdr.parm_size;
144
if ((result = loadData(&offset, dataType, theData, theDataSize, comm->buf)))
146
type = (TCSD_PACKET_TYPE *)(comm->buf + comm->hdr.type_offset) + index;
148
comm->hdr.type_size += sizeof(TCSD_PACKET_TYPE);
149
comm->hdr.parm_size += (offset - old_offset);
151
comm->hdr.packet_size = offset;
152
comm->hdr.num_parms++;
158
getData(TCSD_PACKET_TYPE dataType,
162
struct tcsd_comm_data *comm)
165
UINT64 old_offset, offset;
166
TCSD_PACKET_TYPE *type = (TCSD_PACKET_TYPE *)(comm->buf + comm->hdr.type_offset) + index;
168
if ((UINT32)index >= comm->hdr.num_parms || dataType != *type) {
169
LogDebug("Data type of TCS packet element %d doesn't match.", index);
170
return TSS_TCP_RPC_BAD_PACKET_TYPE;
172
old_offset = offset = comm->hdr.parm_offset;
174
case TCSD_PACKET_TYPE_BYTE:
175
Trspi_UnloadBlob_BYTE(&offset, (BYTE *)theData, comm->buf);
177
case TCSD_PACKET_TYPE_BOOL:
178
Trspi_UnloadBlob_BOOL(&offset, (TSS_BOOL *)theData, comm->buf);
180
case TCSD_PACKET_TYPE_UINT16:
181
Trspi_UnloadBlob_UINT16(&offset, (UINT16 *)theData, comm->buf);
183
case TCSD_PACKET_TYPE_UINT32:
184
Trspi_UnloadBlob_UINT32(&offset, (UINT32 *)theData, comm->buf);
186
case TCSD_PACKET_TYPE_UINT64:
187
Trspi_UnloadBlob_UINT64(&offset, (UINT64 *)theData, comm->buf);
189
case TCSD_PACKET_TYPE_PBYTE:
190
Trspi_UnloadBlob(&offset, theDataSize, comm->buf, (BYTE *)theData);
192
case TCSD_PACKET_TYPE_NONCE:
193
Trspi_UnloadBlob_NONCE(&offset, comm->buf, (TPM_NONCE *)theData);
195
case TCSD_PACKET_TYPE_DIGEST:
196
Trspi_UnloadBlob(&offset, sizeof(TCPA_DIGEST), comm->buf,
197
((TCPA_DIGEST *)theData)->digest);
199
case TCSD_PACKET_TYPE_AUTH:
200
UnloadBlob_AUTH(&offset, comm->buf, ((TPM_AUTH *)theData));
202
case TCSD_PACKET_TYPE_UUID:
203
Trspi_UnloadBlob_UUID(&offset, comm->buf, ((TSS_UUID *)theData));
205
case TCSD_PACKET_TYPE_ENCAUTH:
206
Trspi_UnloadBlob(&offset, sizeof(TCPA_ENCAUTH), comm->buf,
207
((TCPA_ENCAUTH *)theData)->authdata);
209
case TCSD_PACKET_TYPE_VERSION:
210
Trspi_UnloadBlob_TCPA_VERSION(&offset, comm->buf,
211
((TCPA_VERSION *)theData));
213
case TCSD_PACKET_TYPE_KM_KEYINFO:
214
if ((result = Trspi_UnloadBlob_KM_KEYINFO(&offset, comm->buf,
215
((TSS_KM_KEYINFO *)theData))))
218
case TCSD_PACKET_TYPE_KM_KEYINFO2:
219
if ((result = Trspi_UnloadBlob_KM_KEYINFO2(&offset, comm->buf,
220
((TSS_KM_KEYINFO2 *)theData))))
223
case TCSD_PACKET_TYPE_LOADKEY_INFO:
224
UnloadBlob_LOADKEY_INFO(&offset, comm->buf, ((TCS_LOADKEY_INFO *)theData));
226
case TCSD_PACKET_TYPE_PCR_EVENT:
227
if ((result = Trspi_UnloadBlob_PCR_EVENT(&offset, comm->buf,
228
((TSS_PCR_EVENT *)theData))))
231
case TCSD_PACKET_TYPE_COUNTER_VALUE:
232
Trspi_UnloadBlob_COUNTER_VALUE(&offset, comm->buf,
233
((TPM_COUNTER_VALUE *)theData));
235
case TCSD_PACKET_TYPE_SECRET:
236
Trspi_UnloadBlob(&offset, sizeof(TCPA_SECRET), comm->buf,
237
((TCPA_SECRET *)theData)->authdata);
240
LogError("unknown data type (%d) in TCSD packet!", dataType);
243
comm->hdr.parm_offset = offset;
244
comm->hdr.parm_size -= (offset - old_offset);
250
sendTCSDPacket(struct host_table_entry *hte)
255
Trspi_LoadBlob_UINT32(&offset, hte->comm.hdr.packet_size, hte->comm.buf);
256
Trspi_LoadBlob_UINT32(&offset, hte->comm.hdr.u.ordinal, hte->comm.buf);
257
Trspi_LoadBlob_UINT32(&offset, hte->comm.hdr.num_parms, hte->comm.buf);
258
Trspi_LoadBlob_UINT32(&offset, hte->comm.hdr.type_size, hte->comm.buf);
259
Trspi_LoadBlob_UINT32(&offset, hte->comm.hdr.type_offset, hte->comm.buf);
260
Trspi_LoadBlob_UINT32(&offset, hte->comm.hdr.parm_size, hte->comm.buf);
261
Trspi_LoadBlob_UINT32(&offset, hte->comm.hdr.parm_offset, hte->comm.buf);
265
printBuffer(hte->comm.buf, hte->comm.hdr.packet_size);
266
LogInfo("Sending Packet with TCSD ordinal 0x%X", hte->comm.hdr.u.ordinal);
268
/* if the ordinal is open context, there are some host table entry
269
* manipulations that must be done, so call _init
271
if (hte->comm.hdr.u.ordinal == TCSD_ORD_OPENCONTEXT) {
272
if ((rc = send_init(hte))) {
273
LogError("Failed to send packet");
277
if ((rc = sendit(hte))) {
278
LogError("Failed to send packet");
283
/* create a platform version of the tcsd header */
285
Trspi_UnloadBlob_UINT32(&offset, &hte->comm.hdr.packet_size, hte->comm.buf);
286
Trspi_UnloadBlob_UINT32(&offset, &hte->comm.hdr.u.result, hte->comm.buf);
287
Trspi_UnloadBlob_UINT32(&offset, &hte->comm.hdr.num_parms, hte->comm.buf);
288
Trspi_UnloadBlob_UINT32(&offset, &hte->comm.hdr.type_size, hte->comm.buf);
289
Trspi_UnloadBlob_UINT32(&offset, &hte->comm.hdr.type_offset, hte->comm.buf);
290
Trspi_UnloadBlob_UINT32(&offset, &hte->comm.hdr.parm_size, hte->comm.buf);
291
Trspi_UnloadBlob_UINT32(&offset, &hte->comm.hdr.parm_offset, hte->comm.buf);
297
recv_from_socket(int sock, void *buffer, int size)
299
int recv_size = 0, recv_total = 0;
301
while (recv_total < size) {
303
if ((recv_size = recv(sock, buffer+recv_total, size-recv_total, 0)) <= 0) {
307
LogError("Socket receive connection error: %s.", strerror(errno));
309
LogDebug("Socket connection closed.");
314
recv_total += recv_size;
321
send_to_socket(int sock, void *buffer, int size)
323
int send_size = 0, send_total = 0;
325
while (send_total < size) {
326
if ((send_size = send(sock, buffer+send_total, size-send_total, 0)) < 0) {
327
LogError("Socket send connection error: %s.", strerror(errno));
330
send_total += send_size;
337
send_init(struct host_table_entry *hte)
344
struct sockaddr_in addr;
345
struct hostent *hEnt = NULL;
347
sd = socket(PF_INET, SOCK_STREAM, 0);
349
LogError("socket: %s", strerror(errno));
350
result = TSPERR(TSS_E_COMM_FAILURE);
354
memset(&addr, 0, sizeof(addr));
355
addr.sin_family = AF_INET;
356
addr.sin_port = htons(get_port());
358
LogDebug("Sending TSP packet to host %s.", hte->hostname);
360
/* try to resolve by hostname first */
361
hEnt = gethostbyname((char *)hte->hostname);
363
/* if by hostname fails, try by dot notation */
364
if (inet_aton((char *)hte->hostname, &addr.sin_addr) == 0) {
365
LogError("hostname %s does not resolve to a valid address.", hte->hostname);
366
result = TSPERR(TSS_E_CONNECTION_FAILED);
370
memcpy(&addr.sin_addr, hEnt->h_addr_list[0], 4);
373
LogDebug("Connecting to %s", inet_ntoa(addr.sin_addr));
375
if (connect(sd, (struct sockaddr *) &addr, sizeof (addr))) {
376
LogError("connect: %s", strerror(errno));
377
result = TSPERR(TSS_E_COMM_FAILURE);
381
if (send_to_socket(sd, hte->comm.buf, hte->comm.hdr.packet_size) < 0) {
382
result = TSPERR(TSS_E_COMM_FAILURE);
386
buffer = hte->comm.buf;
387
recv_size = sizeof(struct tcsd_packet_hdr);
388
if ((recv_size = recv_from_socket(sd, buffer, recv_size)) < 0) {
389
result = TSPERR(TSS_E_COMM_FAILURE);
392
buffer += sizeof(struct tcsd_packet_hdr); /* increment the receive buffer pointer */
394
/* check the packet size */
395
recv_size = Decode_UINT32(hte->comm.buf);
396
if (recv_size < (int)sizeof(struct tcsd_packet_hdr)) {
397
LogError("Packet to receive from socket %d is too small (%d bytes)",
399
result = TSPERR(TSS_E_COMM_FAILURE);
403
if (recv_size > hte->comm.buf_size ) {
406
LogDebug("Increasing communication buffer to %d bytes.", recv_size);
407
new_buffer = realloc(hte->comm.buf, recv_size);
408
if (new_buffer == NULL) {
409
LogError("realloc of %d bytes failed.", recv_size);
410
result = TSPERR(TSS_E_OUTOFMEMORY);
413
buffer = new_buffer + sizeof(struct tcsd_packet_hdr);
414
hte->comm.buf_size = recv_size;
415
hte->comm.buf = new_buffer;
418
/* get the rest of the packet */
419
recv_size -= sizeof(struct tcsd_packet_hdr); /* already received the header */
420
if ((recv_size = recv_from_socket(sd, buffer, recv_size)) < 0) {
421
result = TSPERR(TSS_E_COMM_FAILURE);
435
sendit(struct host_table_entry *hte)
441
if (send_to_socket(hte->socket, hte->comm.buf, hte->comm.hdr.packet_size) < 0) {
442
result = TSPERR(TSS_E_COMM_FAILURE);
446
buffer = hte->comm.buf;
447
recv_size = sizeof(struct tcsd_packet_hdr);
448
if ((recv_size = recv_from_socket(hte->socket, buffer, recv_size)) < 0) {
449
result = TSPERR(TSS_E_COMM_FAILURE);
452
buffer += recv_size; /* increment the receive buffer pointer */
454
/* check the packet size */
455
recv_size = Decode_UINT32(hte->comm.buf);
456
if (recv_size < (int)sizeof(struct tcsd_packet_hdr)) {
457
LogError("Packet to receive from socket %d is too small (%d bytes)",
458
hte->socket, recv_size);
459
result = TSPERR(TSS_E_COMM_FAILURE);
463
if (recv_size > hte->comm.buf_size ) {
466
LogDebug("Increasing communication buffer to %d bytes.", recv_size);
467
new_buffer = realloc(hte->comm.buf, recv_size);
468
if (new_buffer == NULL) {
469
LogError("realloc of %d bytes failed.", recv_size);
470
result = TSPERR(TSS_E_OUTOFMEMORY);
473
buffer = new_buffer + sizeof(struct tcsd_packet_hdr);
474
hte->comm.buf_size = recv_size;
475
hte->comm.buf = new_buffer;
478
/* get the rest of the packet */
479
recv_size -= sizeof(struct tcsd_packet_hdr); /* already received the header */
480
if ((recv_size = recv_from_socket(hte->socket, buffer, recv_size)) < 0) {
481
result = TSPERR(TSS_E_COMM_FAILURE);
491
/* XXX this should be moved out of an RPC-specific file */
498
env_port = getenv("TSS_TCSD_PORT");
500
if (env_port == NULL)
501
return TCSD_DEFAULT_PORT;
503
port = atoi(env_port);
505
if (port == 0 || port > 65535)
506
return TCSD_DEFAULT_PORT;