tpm2: add marshaling/unmarshaling and tlcl support
[vboot.git] / firmware / lib / tpm2_lite / tlcl.c
1 /*
2  * Copyright 2016 The Chromium OS Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  *
6  * Some TPM constants and type definitions for standalone compilation for use
7  * in the firmware
8  */
9
10 #include "tpm2_marshaling.h"
11 #include "utility.h"
12
13 static void *tpm_process_command(TPM_CC command, void *command_body)
14 {
15         /* Command/response buffer. */
16         static uint8_t cr_buffer[TPM_BUFFER_SIZE];
17         uint32_t out_size, in_size;
18
19         out_size = tpm_marshal_command(command, command_body,
20                                        cr_buffer, sizeof(cr_buffer));
21         if (out_size < 0) {
22                 VBDEBUG(("command %#x, cr size %d\n",
23                          command, out_size));
24                 return NULL;
25         }
26
27         in_size = sizeof(cr_buffer);
28         if (VbExTpmSendReceive(cr_buffer, out_size,
29                                cr_buffer, &in_size) != TPM_SUCCESS) {
30                 VBDEBUG(("tpm transaction failed\n"));
31                 return NULL;
32         }
33
34         return tpm_unmarshal_response(command, cr_buffer, in_size);
35 }
36
37 /**
38  * Issue a ForceClear.  The TPM error code is returned.
39  */
40 uint32_t TlclForceClear(void)
41 {
42         VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
43         return TPM_SUCCESS;
44 }
45
46 uint32_t TlclSetDeactivated(uint8_t flag)
47 {
48         VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
49         return TPM_SUCCESS;
50 }
51
52 uint32_t TlclSetEnable(void)
53 {
54         VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
55         return TPM_SUCCESS;
56 }
57
58
59 /**
60  * Get the permission bits for the NVRAM space with |index|.
61  */
62 uint32_t TlclGetPermissions(uint32_t index, uint32_t *permissions)
63 {
64         *permissions = 0;
65         VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
66         return TPM_SUCCESS;
67 }
68
69 /**
70  * Turn off physical presence and locks it off until next reboot.  The TPM
71  * error code is returned.
72  */
73 uint32_t TlclLockPhysicalPresence(void)
74 {
75         VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
76         return TPM_SUCCESS;
77 }
78
79 uint32_t TlclRead(uint32_t index, void* data, uint32_t length)
80 {
81         struct tpm2_nv_read_cmd nv_readc;
82         struct tpm2_response *response;
83
84         Memset(&nv_readc, 0, sizeof(nv_readc));
85
86         nv_readc.nvIndex = HR_NV_INDEX + index;
87         nv_readc.size = length;
88
89         response = tpm_process_command(TPM2_NV_Read, &nv_readc);
90
91         /* Need to map tpm error codes into internal values. */
92         if (!response)
93                 return TPM_E_READ_FAILURE;
94
95         VBDEBUG(("%s:%d index %#x return code %x\n",
96                  __FILE__, __LINE__, index, response->hdr.tpm_code));
97         switch (response->hdr.tpm_code) {
98         case 0:
99                 break;
100
101         case 0x28b:
102                 return TPM_E_BADINDEX;
103
104         default:
105                 return TPM_E_READ_FAILURE;
106         }
107
108         if (length > response->nvr.buffer.t.size)
109                 return TPM_E_RESPONSE_TOO_LARGE;
110
111         if (length < response->nvr.buffer.t.size)
112                 return TPM_E_READ_EMPTY;
113
114         Memcpy(data, response->nvr.buffer.t.buffer, length);
115
116         return TPM_SUCCESS;
117 }
118
119 uint32_t TlclWrite(uint32_t index, const void *data, uint32_t length)
120 {
121         struct tpm2_nv_write_cmd nv_writec;
122         struct tpm2_response *response;
123
124         Memset(&nv_writec, 0, sizeof(nv_writec));
125
126         nv_writec.nvIndex = HR_NV_INDEX + index;
127         nv_writec.data.t.size = length;
128         nv_writec.data.t.buffer = data;
129
130         response = tpm_process_command(TPM2_NV_Write, &nv_writec);
131
132         /* Need to map tpm error codes into internal values. */
133         if (!response)
134                 return TPM_E_WRITE_FAILURE;
135
136         VBDEBUG(("%s:%d return code %x\n", __func__, __LINE__,
137                  response->hdr.tpm_code));
138
139         return TPM_SUCCESS;
140 }