1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2015 - 2018 Intel Corporation
4  * All rights reserved.
5  * Copyright (c) 2019, Wind River Systems.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice,
12  * this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34 
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <inttypes.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <sys/stat.h>
42 #include <sys/types.h>
43 #ifdef __VXWORKS__
44 #include <sys/poll.h>
45 #else
46 #include <poll.h>
47 #endif
48 #include <unistd.h>
49 
50 #include "tss2_tcti.h"
51 #include "tss2_tcti_device.h"
52 #include "tss2_mu.h"
53 #include "tcti-common.h"
54 #include "tcti-device.h"
55 #include "util/io.h"
56 #define LOGMODULE tcti
57 #include "util/log.h"
58 
59 #define ARRAY_LEN(x) (sizeof(x)/sizeof(x[0]))
60 
61 static char *default_conf[] = {
62 #ifdef __VXWORKS__
63     "/tpm0"
64 #else
65     "/dev/tpmrm0",
66     "/dev/tpm0",
67 #endif /* __VX_WORKS__ */
68 };
69 
70 /*
71  * This function wraps the "up-cast" of the opaque TCTI context type to the
72  * type for the device TCTI context. The only safe-guard we have to ensure
73  * this operation is possible is the magic number for the device TCTI context.
74  * If passed a NULL context, or the magic number check fails, this function
75  * will return NULL.
76  */
77 TSS2_TCTI_DEVICE_CONTEXT*
tcti_device_context_cast(TSS2_TCTI_CONTEXT * tcti_ctx)78 tcti_device_context_cast (TSS2_TCTI_CONTEXT *tcti_ctx)
79 {
80     if (tcti_ctx != NULL && TSS2_TCTI_MAGIC (tcti_ctx) == TCTI_DEVICE_MAGIC) {
81         return (TSS2_TCTI_DEVICE_CONTEXT*)tcti_ctx;
82     }
83     return NULL;
84 }
85 /*
86  * This function down-casts the device TCTI context to the common context
87  * defined in the tcti-common module.
88  */
89 TSS2_TCTI_COMMON_CONTEXT*
tcti_device_down_cast(TSS2_TCTI_DEVICE_CONTEXT * tcti_dev)90 tcti_device_down_cast (TSS2_TCTI_DEVICE_CONTEXT *tcti_dev)
91 {
92     if (tcti_dev == NULL) {
93         return NULL;
94     }
95     return &tcti_dev->common;
96 }
97 
98 TSS2_RC
tcti_device_transmit(TSS2_TCTI_CONTEXT * tctiContext,size_t command_size,const uint8_t * command_buffer)99 tcti_device_transmit (
100     TSS2_TCTI_CONTEXT *tctiContext,
101     size_t command_size,
102     const uint8_t *command_buffer)
103 {
104     TSS2_TCTI_DEVICE_CONTEXT *tcti_dev = tcti_device_context_cast (tctiContext);
105     TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_device_down_cast (tcti_dev);
106     TSS2_RC rc = TSS2_RC_SUCCESS;
107     ssize_t size;
108 
109     if (tcti_dev == NULL) {
110         return TSS2_TCTI_RC_BAD_CONTEXT;
111     }
112     rc = tcti_common_transmit_checks (tcti_common, command_buffer);
113     if (rc != TSS2_RC_SUCCESS) {
114         return rc;
115     }
116     LOGBLOB_DEBUG (command_buffer,
117                    command_size,
118                    "sending %zu byte command buffer:",
119                    command_size);
120     size = write_all (tcti_dev->fd,
121                       command_buffer,
122                       command_size);
123     if (size < 0) {
124         return TSS2_TCTI_RC_IO_ERROR;
125     } else if ((size_t)size != command_size) {
126         LOG_ERROR ("wrong number of bytes written. Expected %zu, wrote %zd.",
127                    command_size,
128                    size);
129         return TSS2_TCTI_RC_IO_ERROR;
130     }
131 
132     tcti_common->state = TCTI_STATE_RECEIVE;
133     return TSS2_RC_SUCCESS;
134 }
135 /*
136  * This receive function deviates from the spec a bit. Calling this function
137  * with a NULL 'tctiContext' parameter *should* result in the required size for
138  * the response buffer being returned to the caller. We would typically do this
139  * by reading the response's header and then returning the size to the caller.
140  * We can't do that on account of the TPM2 kernel driver closing any connection
141  * that doesn't read the whole response buffer in one 'read' call.
142  *
143  * Instead, if the caller queries the size, we return 4k just to be on the
144  * safe side. We do *not* however verify that the provided buffer is large
145  * enough to hold the full response (we can't). If the caller provides us with
146  * a buffer less than 4k we'll read as much of the response as we can given
147  * the size of the buffer. If we get enough of the response to read the size
148  * field, we check to see if the buffer was large enough to get the full
149  * response. If the response header claims it's larger than the provided
150  * buffer we print a warning. This allows "expert applications" to
151  * precalculate the required response buffer size for whatever commands they
152  * may send.
153  */
154 TSS2_RC
tcti_device_receive(TSS2_TCTI_CONTEXT * tctiContext,size_t * response_size,uint8_t * response_buffer,int32_t timeout)155 tcti_device_receive (
156     TSS2_TCTI_CONTEXT *tctiContext,
157     size_t *response_size,
158     uint8_t *response_buffer,
159     int32_t timeout)
160 {
161     TSS2_TCTI_DEVICE_CONTEXT *tcti_dev = tcti_device_context_cast (tctiContext);
162     TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_device_down_cast (tcti_dev);
163     TSS2_RC rc = TSS2_RC_SUCCESS;
164     ssize_t size = 0;
165     struct pollfd fds;
166     int rc_poll, nfds = 1;
167 #ifdef TCTI_PARTIAL_READ
168     uint8_t header[TPM_HEADER_SIZE];
169     size_t offset = 2;
170     UINT32 partial_size;
171 #endif
172 
173     if (tcti_dev == NULL) {
174         return TSS2_TCTI_RC_BAD_CONTEXT;
175     }
176     rc = tcti_common_receive_checks (tcti_common, response_size);
177     if (rc != TSS2_RC_SUCCESS) {
178         return rc;
179     }
180 #ifndef TCTI_ASYNC
181     /* For async the valid timeout values are -1 - block forever,
182      * 0 - nonblocking, and any positive value - the actual timeout
183      * value in millisec.
184      * For sync the only valid value is -1 - block forever.
185      */
186     if (timeout != TSS2_TCTI_TIMEOUT_BLOCK) {
187         LOG_WARNING ("The underlying IPC mechanism does not support "
188                      "asynchronous I/O. The 'timeout' parameter is set to "
189                      "TSS2_TCTI_TIMEOUT_BLOCK");
190         timeout = TSS2_TCTI_TIMEOUT_BLOCK;
191     }
192 #endif
193     if (response_buffer == NULL) {
194 #ifndef TCTI_PARTIAL_READ
195         LOG_DEBUG ("Caller queried for size but linux kernel doesn't allow this. "
196                    "Returning 4k which is the max size for a response buffer.");
197         *response_size = 4096;
198         return TSS2_RC_SUCCESS;
199     }
200 #else
201         /* Read the header only and get the response size out of it */
202         LOG_DEBUG("Partial read - reading response size");
203         fds.fd = tcti_dev->fd;
204         fds.events = POLLIN;
205 
206         rc_poll = poll(&fds, nfds, timeout);
207         if (rc_poll < 0) {
208             LOG_ERROR ("Failed to poll for response from fd %d, got errno %d: %s",
209                        tcti_dev->fd, errno, strerror (errno));
210             return TSS2_TCTI_RC_IO_ERROR;
211         } else if (rc_poll == 0) {
212             LOG_INFO ("Poll timed out on fd %d.", tcti_dev->fd);
213             return TSS2_TCTI_RC_TRY_AGAIN;
214         } else if (fds.revents == POLLIN) {
215             TEMP_RETRY (size, read (tcti_dev->fd, header, TPM_HEADER_SIZE));
216             if (size < 0 || size != TPM_HEADER_SIZE) {
217                 LOG_ERROR ("Failed to get response size fd %d, got errno %d: %s",
218                        tcti_dev->fd, errno, strerror (errno));
219                 return TSS2_TCTI_RC_IO_ERROR;
220             }
221         }
222         LOG_DEBUG("Partial read - received header");
223             rc = Tss2_MU_UINT32_Unmarshal(header, TPM_HEADER_SIZE,
224                                           &offset, &partial_size);
225         if (rc != TSS2_RC_SUCCESS) {
226             LOG_ERROR ("Failed to unmarshal response size.");
227             return rc;
228         }
229         if (partial_size < TPM_HEADER_SIZE) {
230             LOG_ERROR ("Received %zu bytes, not enough to hold a TPM2 response "
231                        "header.", size);
232             return TSS2_TCTI_RC_GENERAL_FAILURE;
233         }
234 
235         LOG_DEBUG("Partial read - received response size %d.", partial_size);
236         tcti_common->partial = true;
237         *response_size = partial_size;
238         memcpy(&tcti_common->header, header, TPM_HEADER_SIZE);
239         return rc;
240     }
241 #endif
242 
243 #ifndef TCTI_PARTIAL_READ
244     if (*response_size < 4096) {
245 #else
246     if (*response_size < TPM_HEADER_SIZE) {
247 #endif
248         LOG_INFO ("Caller provided buffer that *may* not be large enough to "
249                   "hold the response buffer.");
250     }
251 
252     /* In case when the whole response is just the 10 bytes header
253      * and we have read it already to get the size, we don't need
254      * to call poll and read again. Just copy what we have read
255      * and return.
256      */
257     if (tcti_common->partial == true && *response_size == TPM_HEADER_SIZE) {
258         memcpy(response_buffer, &tcti_common->header, TPM_HEADER_SIZE);
259         tcti_common->partial = false;
260         goto out;
261     }
262 
263     /*
264      * The older kernel driver will only return a response buffer in a single
265      * read operation. If we try to read again before sending another command
266      * the kernel will close the file descriptor and we'll get an EOF.
267      * Newer kernels should have partial reads enabled.
268      */
269     fds.fd = tcti_dev->fd;
270     fds.events = POLLIN;
271 
272     rc_poll = poll(&fds, nfds, timeout);
273     if (rc_poll < 0) {
274         LOG_ERROR ("Failed to poll for response from fd %d, got errno %d: %s",
275                    tcti_dev->fd, errno, strerror (errno));
276         return TSS2_TCTI_RC_IO_ERROR;
277     } else if (rc_poll == 0) {
278         LOG_INFO ("Poll timed out on fd %d.", tcti_dev->fd);
279         return TSS2_TCTI_RC_TRY_AGAIN;
280     } else if (fds.revents == POLLIN) {
281         if (tcti_common->partial == true) {
282             memcpy(response_buffer, &tcti_common->header, TPM_HEADER_SIZE);
283             TEMP_RETRY (size, read (tcti_dev->fd, response_buffer +
284                         TPM_HEADER_SIZE, *response_size - TPM_HEADER_SIZE));
285         } else {
286             TEMP_RETRY (size, read (tcti_dev->fd, response_buffer,
287                         *response_size));
288         }
289         if (size < 0) {
290             LOG_ERROR ("Failed to read response from fd %d, got errno %d: %s",
291                tcti_dev->fd, errno, strerror (errno));
292             return TSS2_TCTI_RC_IO_ERROR;
293         }
294     }
295     if (size == 0) {
296         LOG_WARNING ("Got EOF instead of response.");
297         rc = TSS2_TCTI_RC_NO_CONNECTION;
298         goto out;
299     }
300 
301     size += tcti_common->partial ? TPM_HEADER_SIZE : 0;
302     LOGBLOB_DEBUG(response_buffer, size, "Response Received");
303     tcti_common->partial = false;
304 
305     if ((size_t)size < TPM_HEADER_SIZE) {
306         LOG_ERROR ("Received %zu bytes, not enough to hold a TPM2 response "
307                    "header.", size);
308         rc = TSS2_TCTI_RC_GENERAL_FAILURE;
309         goto out;
310     }
311 
312     rc = header_unmarshal (response_buffer, &tcti_common->header);
313     if (rc != TSS2_RC_SUCCESS)
314         goto out;
315 
316     LOG_DEBUG("Size from header %u bytes read %zu", tcti_common->header.size, size);
317 
318     if ((size_t)size != tcti_common->header.size) {
319         LOG_WARNING ("TPM2 response size disagrees with number of bytes read "
320                      "from fd %d. Header says %u but we read %zu bytes.",
321                      tcti_dev->fd, tcti_common->header.size, size);
322     }
323     if (*response_size < tcti_common->header.size) {
324         LOG_WARNING ("TPM2 response size is larger than the provided "
325                      "buffer: future use of this TCTI will likely fail.");
326         rc = TSS2_TCTI_RC_GENERAL_FAILURE;
327     }
328     *response_size = size;
329     /*
330      * Executing code beyond this point transitions the state machine to
331      * TRANSMIT. Another call to this function will not be possible until
332      * another command is sent to the TPM.
333      */
334 out:
335     tcti_common->state = TCTI_STATE_TRANSMIT;
336 
337     return rc;
338 }
339 
340 void
tcti_device_finalize(TSS2_TCTI_CONTEXT * tctiContext)341 tcti_device_finalize (
342     TSS2_TCTI_CONTEXT *tctiContext)
343 {
344     TSS2_TCTI_DEVICE_CONTEXT *tcti_dev = tcti_device_context_cast (tctiContext);
345     TSS2_TCTI_COMMON_CONTEXT *tcti_common = tcti_device_down_cast (tcti_dev);
346 
347     if (tcti_dev == NULL) {
348         return;
349     }
350     close (tcti_dev->fd);
351     tcti_common->state = TCTI_STATE_FINAL;
352 }
353 
354 TSS2_RC
tcti_device_cancel(TSS2_TCTI_CONTEXT * tctiContext)355 tcti_device_cancel (
356     TSS2_TCTI_CONTEXT *tctiContext)
357 {
358     /* Linux driver doesn't expose a mechanism to cancel commands. */
359     (void)(tctiContext);
360     return TSS2_TCTI_RC_NOT_IMPLEMENTED;
361 }
362 
363 TSS2_RC
tcti_device_get_poll_handles(TSS2_TCTI_CONTEXT * tctiContext,TSS2_TCTI_POLL_HANDLE * handles,size_t * num_handles)364 tcti_device_get_poll_handles (
365     TSS2_TCTI_CONTEXT *tctiContext,
366     TSS2_TCTI_POLL_HANDLE *handles,
367     size_t *num_handles)
368 {
369 #ifdef TCTI_ASYNC
370     TSS2_TCTI_DEVICE_CONTEXT *tcti_dev = tcti_device_context_cast (tctiContext);
371 
372     if (tcti_dev == NULL) {
373         return TSS2_TCTI_RC_BAD_CONTEXT;
374     }
375 
376     if (num_handles == NULL) {
377         return TSS2_TCTI_RC_BAD_REFERENCE;
378     }
379 
380     if (handles != NULL && *num_handles < 1) {
381         return TSS2_TCTI_RC_INSUFFICIENT_BUFFER;
382     }
383 
384     *num_handles = 1;
385     if (handles != NULL) {
386         handles->fd = tcti_dev->fd;
387     }
388 
389     return TSS2_RC_SUCCESS;
390 #else
391     (void)(tctiContext);
392     (void)(handles);
393     (void)(num_handles);
394     return TSS2_TCTI_RC_NOT_IMPLEMENTED;
395 #endif
396 }
397 
398 TSS2_RC
tcti_device_set_locality(TSS2_TCTI_CONTEXT * tctiContext,uint8_t locality)399 tcti_device_set_locality (
400     TSS2_TCTI_CONTEXT *tctiContext,
401     uint8_t locality)
402 {
403     /*
404      * Linux driver doesn't expose a mechanism for user space applications
405      * to set locality.
406      */
407     (void)(tctiContext);
408     (void)(locality);
409     return TSS2_TCTI_RC_NOT_IMPLEMENTED;
410 }
411 
open_tpm(const char * pathname)412 static int open_tpm (
413     const char* pathname) {
414 #ifdef __VXWORKS__
415         return open (pathname, O_RDWR, (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
416 #else
417         return open (pathname, O_RDWR | O_NONBLOCK);
418 #endif
419 }
420 
421 TSS2_RC
Tss2_Tcti_Device_Init(TSS2_TCTI_CONTEXT * tctiContext,size_t * size,const char * conf)422 Tss2_Tcti_Device_Init (
423     TSS2_TCTI_CONTEXT *tctiContext,
424     size_t *size,
425     const char *conf)
426 {
427     TSS2_TCTI_DEVICE_CONTEXT *tcti_dev;
428     TSS2_TCTI_COMMON_CONTEXT *tcti_common;
429 
430     if (tctiContext == NULL && size == NULL) {
431         return TSS2_TCTI_RC_BAD_VALUE;
432     } else if (tctiContext == NULL) {
433         *size = sizeof (TSS2_TCTI_DEVICE_CONTEXT);
434         return TSS2_RC_SUCCESS;
435     }
436 
437     /* Init TCTI context */
438     TSS2_TCTI_MAGIC (tctiContext) = TCTI_DEVICE_MAGIC;
439     TSS2_TCTI_VERSION (tctiContext) = TCTI_VERSION;
440     TSS2_TCTI_TRANSMIT (tctiContext) = tcti_device_transmit;
441     TSS2_TCTI_RECEIVE (tctiContext) = tcti_device_receive;
442     TSS2_TCTI_FINALIZE (tctiContext) = tcti_device_finalize;
443     TSS2_TCTI_CANCEL (tctiContext) = tcti_device_cancel;
444     TSS2_TCTI_GET_POLL_HANDLES (tctiContext) = tcti_device_get_poll_handles;
445     TSS2_TCTI_SET_LOCALITY (tctiContext) = tcti_device_set_locality;
446     TSS2_TCTI_MAKE_STICKY (tctiContext) = tcti_make_sticky_not_implemented;
447     tcti_dev = tcti_device_context_cast (tctiContext);
448     tcti_common = tcti_device_down_cast (tcti_dev);
449     tcti_common->state = TCTI_STATE_TRANSMIT;
450     memset (&tcti_common->header, 0, sizeof (tcti_common->header));
451     tcti_common->locality = 3;
452 
453     if (conf == NULL) {
454         LOG_TRACE ("No TCTI device file specified");
455 
456         for (size_t i = 0; i < ARRAY_LEN(default_conf); i++) {
457             LOG_DEBUG ("Trying to open default TCTI device file %s",
458                        default_conf[i]);
459             tcti_dev->fd = open_tpm (default_conf[i]);
460             if (tcti_dev->fd >= 0) {
461                 LOG_TRACE ("Successfully opened default TCTI device file %s",
462                            default_conf[i]);
463                     break;
464             } else {
465                     LOG_WARNING ("Failed to open default TCTI device file %s: %s",
466                                  default_conf[i], strerror (errno));
467                 }
468             }
469             if (tcti_dev->fd < 0) {
470                 LOG_ERROR ("Could not open any default TCTI device file");
471                 return TSS2_TCTI_RC_IO_ERROR;
472             }
473     } else {
474         LOG_DEBUG ("Trying to open specified TCTI device file %s", conf);
475         tcti_dev->fd = open_tpm (conf);
476         if (tcti_dev->fd < 0) {
477             LOG_ERROR ("Failed to open specified TCTI device file %s: %s",
478                        conf, strerror (errno));
479             return TSS2_TCTI_RC_IO_ERROR;
480         } else {
481             LOG_TRACE ("Successfully opened specified TCTI device file %s", conf);
482         }
483     }
484 
485 
486     return TSS2_RC_SUCCESS;
487 }
488 
489 const TSS2_TCTI_INFO tss2_tcti_info = {
490     .version = TCTI_VERSION,
491     .name = "tcti-device",
492     .description = "TCTI module for communication with Linux kernel interface.",
493     .config_help = "Path to TPM character device. Default value is: "
494         "TCTI_DEVICE_DEFAULT",
495     .init = Tss2_Tcti_Device_Init,
496 };
497 
498 const TSS2_TCTI_INFO*
Tss2_Tcti_Info(void)499 Tss2_Tcti_Info (void)
500 {
501     return &tss2_tcti_info;
502 }
503