OLD | NEW |
1 /* TPM Device Driver Library for the TPM Emulator | 1 /* Software-based Trusted Platform Module (TPM) Emulator |
2 * Copyright (C) 2006 Mario Strasser <mast@gmx.net>, | 2 * Copyright (C) 2004-2010 Mario Strasser <mast@gmx.net> |
3 * Swiss Federal Institute of Technology (ETH) Zurich | |
4 * | 3 * |
5 * This module is free software; you can redistribute it and/or modify | 4 * This module is free software; you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License as published | 5 * it under the terms of the GNU General Public License as published |
7 * by the Free Software Foundation; either version 2 of the License, | 6 * by the Free Software Foundation; either version 2 of the License, |
8 * or (at your option) any later version. | 7 * or (at your option) any later version. |
9 * | 8 * |
10 * This module is distributed in the hope that it will be useful, | 9 * This module is distributed in the hope that it will be useful, |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
14 * | 13 * |
15 * $Id$ | 14 * $Id: tddl.c 364 2010-02-11 10:24:45Z mast $ |
16 */ | 15 */ |
17 | 16 |
18 #include <sys/types.h> | |
19 #include <sys/socket.h> | |
20 #include <sys/un.h> | |
21 #include <fcntl.h> | |
22 #include <unistd.h> | 17 #include <unistd.h> |
23 #include <string.h> | 18 #include <string.h> |
24 #include <errno.h> | |
25 #include <pthread.h> | |
26 #include <config.h> | 19 #include <config.h> |
27 #include "tddl.h" | 20 #include "tddl.h" |
28 | 21 |
29 /* device and socket names */ | 22 /* device and socket names */ |
30 static const char *tpm_device_name = TPM_DEVICE_NAME; | 23 static const char *tpm_device_name = TPM_DEVICE_NAME; |
31 static const char *tpmd_socket_name = TPM_SOCKET_NAME; | 24 static const char *tpmd_socket_name = TPM_SOCKET_NAME; |
32 | 25 |
33 /* TPM device handle */ | 26 /* TPM device handle */ |
34 static int tddli_dh = -1; | 27 static int tddli_dh = -1; |
35 | 28 |
36 /* status of the TPM device driver and the TPM itself */ | 29 /* status of the TPM device driver and the TPM itself */ |
37 static TSS_RESULT tddli_driver_status = TDDL_DRIVER_FAILED; | 30 static TSS_RESULT tddli_driver_status = TDDL_DRIVER_FAILED; |
38 static TSS_RESULT tddli_device_status = TDDL_DEVICE_NOT_FOUND; | 31 static TSS_RESULT tddli_device_status = TDDL_DEVICE_NOT_FOUND; |
39 | 32 |
40 /* library lock */ | 33 #if defined(_WIN32) || defined(_WIN64) |
41 static pthread_mutex_t tddli_lock = PTHREAD_MUTEX_INITIALIZER; | 34 #include "tddl_windows.h" |
42 | 35 #else |
43 static TSS_RESULT open_device(const char *device_name) | 36 #include "tddl_unix.h" |
44 { | 37 #endif |
45 tddli_dh = open(device_name, O_RDWR); | |
46 if (tddli_dh < 0) { | |
47 if (errno == ENOENT || errno == ENXIO) { | |
48 tddli_driver_status = TDDL_DRIVER_FAILED; | |
49 tddli_device_status = TDDL_DEVICE_NOT_FOUND; | |
50 } else { | |
51 tddli_driver_status = TDDL_DRIVER_NOT_OPENED; | |
52 tddli_device_status = TDDL_DEVICE_RECOVERABLE; | |
53 } | |
54 return TDDL_E_FAIL; | |
55 } else { | |
56 tddli_driver_status = TDDL_DRIVER_OK; | |
57 tddli_device_status = TDDL_DEVICE_OK; | |
58 return TDDL_SUCCESS; | |
59 } | |
60 } | |
61 | |
62 static TSS_RESULT open_socket(const char *socket_name) | |
63 { | |
64 struct sockaddr_un addr; | |
65 tddli_dh = socket(AF_UNIX, SOCK_STREAM, 0); | |
66 if (tddli_dh < 0) { | |
67 tddli_driver_status = TDDL_DRIVER_FAILED; | |
68 tddli_device_status = TDDL_DEVICE_NOT_FOUND; | |
69 return TDDL_E_FAIL; | |
70 } | |
71 addr.sun_family = AF_UNIX; | |
72 strncpy(addr.sun_path, socket_name, sizeof(addr.sun_path)); | |
73 if (connect(tddli_dh, (struct sockaddr*)&addr, sizeof(struct sockaddr_un)) < 0
) { | |
74 tddli_driver_status = TDDL_DRIVER_FAILED; | |
75 tddli_device_status = TDDL_DEVICE_NOT_FOUND; | |
76 return TDDL_E_FAIL; | |
77 } | |
78 tddli_driver_status = TDDL_DRIVER_OK; | |
79 tddli_device_status = TDDL_DEVICE_OK; | |
80 return TDDL_SUCCESS; | |
81 } | |
82 | 38 |
83 TSS_RESULT Tddli_Open() | 39 TSS_RESULT Tddli_Open() |
84 { | 40 { |
85 TSS_RESULT res; | 41 TSS_RESULT res; |
86 pthread_mutex_lock(&tddli_lock); | 42 tddli_mutex_lock(&tddli_lock); |
87 if (tddli_dh != -1) { | 43 if (tddli_dh != -1) { |
88 res = TDDL_E_ALREADY_OPENED; | 44 res = TDDL_E_ALREADY_OPENED; |
89 } else { | 45 } else { |
90 res = open_socket(tpmd_socket_name); | 46 res = open_socket(tpmd_socket_name); |
91 if (res != TDDL_SUCCESS) { | 47 if (res != TDDL_SUCCESS) { |
92 res = open_device(tpm_device_name); | 48 res = open_device(tpm_device_name); |
93 } | 49 } |
94 } | 50 } |
95 pthread_mutex_unlock(&tddli_lock); | 51 tddli_mutex_unlock(&tddli_lock); |
96 return res; | 52 return res; |
97 } | 53 } |
98 | 54 |
99 TSS_RESULT Tddli_Close() | 55 TSS_RESULT Tddli_Close() |
100 { | 56 { |
101 TSS_RESULT res = TDDL_SUCCESS; | 57 TSS_RESULT res = TDDL_SUCCESS; |
102 pthread_mutex_lock(&tddli_lock); | 58 tddli_mutex_lock(&tddli_lock); |
103 if (tddli_dh >= 0) { | 59 if (tddli_dh >= 0) { |
104 close(tddli_dh); | 60 close(tddli_dh); |
105 tddli_dh = -1; | 61 tddli_dh = -1; |
106 } else { | 62 } else { |
107 res = TDDL_E_ALREADY_CLOSED; | 63 res = TDDL_E_ALREADY_CLOSED; |
108 } | 64 } |
109 pthread_mutex_unlock(&tddli_lock); | 65 tddli_mutex_unlock(&tddli_lock); |
110 return res; | 66 return res; |
111 } | 67 } |
112 | 68 |
113 TSS_RESULT Tddli_Cancel() | 69 TSS_RESULT Tddli_Cancel() |
114 { | 70 { |
115 /* this is not supported by the TPM emulator */ | 71 /* this is not supported by the TPM emulator */ |
116 return TDDL_E_NOTIMPL; | 72 return TDDL_E_NOTIMPL; |
117 } | 73 } |
118 | 74 |
119 static TSS_RESULT send_to_tpm(BYTE* pTransmitBuf, UINT32 TransmitBufLen) | 75 static TSS_RESULT send_to_tpm(BYTE* pTransmitBuf, UINT32 TransmitBufLen) |
(...skipping 15 matching lines...) Expand all Loading... |
135 len = ((uint32_t)pReceiveBuf[2] << 24) | ((uint32_t)pReceiveBuf[3] << 16) | 91 len = ((uint32_t)pReceiveBuf[2] << 24) | ((uint32_t)pReceiveBuf[3] << 16) |
136 | ((uint32_t)pReceiveBuf[4] << 8) | (uint32_t)pReceiveBuf[5]; | 92 | ((uint32_t)pReceiveBuf[4] << 8) | (uint32_t)pReceiveBuf[5]; |
137 if (len != *puntReceiveBufLen) return TDDL_E_INSUFFICIENT_BUFFER; | 93 if (len != *puntReceiveBufLen) return TDDL_E_INSUFFICIENT_BUFFER; |
138 return TDDL_SUCCESS; | 94 return TDDL_SUCCESS; |
139 } | 95 } |
140 | 96 |
141 TSS_RESULT Tddli_TransmitData(BYTE* pTransmitBuf, UINT32 TransmitBufLen, | 97 TSS_RESULT Tddli_TransmitData(BYTE* pTransmitBuf, UINT32 TransmitBufLen, |
142 BYTE* pReceiveBuf, UINT32* puntReceiveBufLen) | 98 BYTE* pReceiveBuf, UINT32* puntReceiveBufLen) |
143 { | 99 { |
144 TSS_RESULT res; | 100 TSS_RESULT res; |
145 pthread_mutex_lock(&tddli_lock); | 101 tddli_mutex_lock(&tddli_lock); |
146 if (tddli_dh >= 0) { | 102 if (tddli_dh >= 0) { |
147 res = send_to_tpm(pTransmitBuf, TransmitBufLen); | 103 res = send_to_tpm(pTransmitBuf, TransmitBufLen); |
148 if (res == TDDL_SUCCESS) | 104 if (res == TDDL_SUCCESS) |
149 res = receive_from_tpm(pReceiveBuf, puntReceiveBufLen); | 105 res = receive_from_tpm(pReceiveBuf, puntReceiveBufLen); |
150 } else { | 106 } else { |
151 res = TDDL_E_FAIL; | 107 res = TDDL_E_FAIL; |
152 } | 108 } |
153 pthread_mutex_unlock(&tddli_lock); | 109 tddli_mutex_unlock(&tddli_lock); |
154 return res; | 110 return res; |
155 } | 111 } |
156 | 112 |
157 static TSS_RESULT cap_version(UINT32 SubCap, BYTE* pCapBuf, | 113 static TSS_RESULT cap_version(UINT32 SubCap, BYTE* pCapBuf, |
158 UINT32* puntCapBufLen) | 114 UINT32* puntCapBufLen) |
159 { | 115 { |
160 TSS_RESULT res; | 116 TSS_RESULT res; |
161 UINT32 len = 18; | 117 UINT32 len = 18; |
162 BYTE buf[18]; | 118 BYTE buf[18]; |
163 | 119 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 default: | 168 default: |
213 return TDDL_E_BAD_PARAMETER; | 169 return TDDL_E_BAD_PARAMETER; |
214 } | 170 } |
215 } | 171 } |
216 | 172 |
217 TSS_RESULT Tddli_GetCapability(UINT32 CapArea, UINT32 SubCap, | 173 TSS_RESULT Tddli_GetCapability(UINT32 CapArea, UINT32 SubCap, |
218 BYTE* pCapBuf, UINT32* puntCapBufLen) | 174 BYTE* pCapBuf, UINT32* puntCapBufLen) |
219 { | 175 { |
220 TSS_RESULT res = TDDL_SUCCESS; | 176 TSS_RESULT res = TDDL_SUCCESS; |
221 if (tddli_dh < 0) return TDDL_E_FAIL; | 177 if (tddli_dh < 0) return TDDL_E_FAIL; |
222 pthread_mutex_lock(&tddli_lock); | 178 tddli_mutex_lock(&tddli_lock); |
223 switch (CapArea) { | 179 switch (CapArea) { |
224 case TDDL_CAP_VERSION: | 180 case TDDL_CAP_VERSION: |
225 res = cap_version(SubCap, pCapBuf, puntCapBufLen); | 181 res = cap_version(SubCap, pCapBuf, puntCapBufLen); |
226 break; | 182 break; |
227 case TDDL_CAP_PROPERTY: | 183 case TDDL_CAP_PROPERTY: |
228 res = cap_property(SubCap, pCapBuf, puntCapBufLen); | 184 res = cap_property(SubCap, pCapBuf, puntCapBufLen); |
229 break; | 185 break; |
230 default: | 186 default: |
231 res = TDDL_E_BAD_PARAMETER; | 187 res = TDDL_E_BAD_PARAMETER; |
232 } | 188 } |
233 pthread_mutex_unlock(&tddli_lock); | 189 tddli_mutex_unlock(&tddli_lock); |
234 return res; | 190 return res; |
235 } | 191 } |
236 | 192 |
237 TSS_RESULT Tddli_SetCapability(UINT32 CapArea, UINT32 SubCap, | 193 TSS_RESULT Tddli_SetCapability(UINT32 CapArea, UINT32 SubCap, |
238 BYTE* pCapBuf, UINT32* puntCapBufLen) | 194 BYTE* pCapBuf, UINT32* puntCapBufLen) |
239 { | 195 { |
240 /* no vendor-specific capabilities available, yet */ | 196 /* no vendor-specific capabilities available, yet */ |
241 return TDDL_E_BAD_PARAMETER; | 197 return TDDL_E_BAD_PARAMETER; |
242 } | 198 } |
243 | 199 |
244 TSS_RESULT Tddli_GetStatus(UINT32 ReqStatusType, UINT32* puntStatus) | 200 TSS_RESULT Tddli_GetStatus(UINT32 ReqStatusType, UINT32* puntStatus) |
245 { | 201 { |
246 TSS_RESULT res = TDDL_SUCCESS; | 202 TSS_RESULT res = TDDL_SUCCESS; |
247 pthread_mutex_lock(&tddli_lock); | 203 tddli_mutex_lock(&tddli_lock); |
248 switch (ReqStatusType) { | 204 switch (ReqStatusType) { |
249 case TDDL_DRIVER_STATUS: | 205 case TDDL_DRIVER_STATUS: |
250 *puntStatus = tddli_driver_status; | 206 *puntStatus = tddli_driver_status; |
251 break; | 207 break; |
252 case TDDL_DEVICE_STATUS: | 208 case TDDL_DEVICE_STATUS: |
253 *puntStatus = tddli_device_status; | 209 *puntStatus = tddli_device_status; |
254 break; | 210 break; |
255 default: | 211 default: |
256 res = TDDL_E_BAD_PARAMETER; | 212 res = TDDL_E_BAD_PARAMETER; |
257 } | 213 } |
258 pthread_mutex_unlock(&tddli_lock); | 214 tddli_mutex_unlock(&tddli_lock); |
259 return res; | 215 return res; |
260 } | 216 } |
261 | 217 |
262 TSS_RESULT Tddli_SetPowerManagement(TSS_BOOL SendSaveStateCommand, | 218 TSS_RESULT Tddli_SetPowerManagement(TSS_BOOL SendSaveStateCommand, |
263 UINT32 *QuerySetNewTPMPowerState) | 219 UINT32 *QuerySetNewTPMPowerState) |
264 { | 220 { |
265 return TDDL_E_NOTIMPL; | 221 return TDDL_E_NOTIMPL; |
266 } | 222 } |
267 | 223 |
268 TSS_RESULT Tddli_PowerManagementControl(TSS_BOOL SendPowerManager, | 224 TSS_RESULT Tddli_PowerManagementControl(TSS_BOOL SendPowerManager, |
269 UINT32 DriverManagesPowerStates) | 225 UINT32 DriverManagesPowerStates) |
270 { | 226 { |
271 return TDDL_E_NOTIMPL; | 227 return TDDL_E_NOTIMPL; |
272 } | 228 } |
273 | 229 |
| 230 /* |
| 231 * Export also TDDL_* function aliases as they are |
| 232 * used by some non standard-conform applications. |
| 233 */ |
| 234 |
| 235 TSS_RESULT TDDL_Open() |
| 236 { |
| 237 return Tddli_Open(); |
| 238 } |
| 239 |
| 240 |
| 241 TSS_RESULT TDDL_Close() |
| 242 { |
| 243 return Tddli_Close(); |
| 244 } |
| 245 |
| 246 TSS_RESULT TDDL_Cancel() |
| 247 { |
| 248 return Tddli_Cancel(); |
| 249 } |
| 250 |
| 251 TSS_RESULT TDDL_TransmitData(BYTE* pTransmitBuf, UINT32 TransmitBufLen, |
| 252 BYTE* pReceiveBuf, UINT32* puntReceiveBufLen) |
| 253 { |
| 254 return Tddli_TransmitData(pTransmitBuf, TransmitBufLen, |
| 255 pReceiveBuf, puntReceiveBufLen); |
| 256 } |
| 257 |
| 258 TSS_RESULT TDDL_GetCapability(UINT32 CapArea, UINT32 SubCap, |
| 259 BYTE* pCapBuf, UINT32* puntCapBufLen) |
| 260 { |
| 261 return Tddli_GetCapability(CapArea, SubCap, pCapBuf, puntCapBufLen); |
| 262 } |
| 263 |
| 264 TSS_RESULT TDDL_SetCapability(UINT32 CapArea, UINT32 SubCap, |
| 265 BYTE* pCapBuf, UINT32* puntCapBufLen) |
| 266 { |
| 267 return Tddli_SetCapability(CapArea, SubCap, pCapBuf, puntCapBufLen); |
| 268 } |
| 269 |
| 270 TSS_RESULT TDDL_GetStatus(UINT32 ReqStatusType, UINT32* puntStatus) |
| 271 { |
| 272 return Tddli_GetStatus(ReqStatusType, puntStatus); |
| 273 } |
| 274 |
| 275 TSS_RESULT TDDL_SetPowerManagement(TSS_BOOL SendSaveStateCommand, |
| 276 UINT32 *QuerySetNewTPMPowerState) |
| 277 { |
| 278 return Tddli_SetPowerManagement(SendSaveStateCommand, QuerySetNewTPMPowerState
); |
| 279 } |
| 280 |
| 281 TSS_RESULT TDDL_PowerManagementControl(TSS_BOOL SendPowerManager, |
| 282 UINT32 DriverManagesPowerStates) |
| 283 { |
| 284 return Tddli_PowerManagementControl(SendPowerManager, DriverManagesPowerStates
); |
| 285 } |
| 286 |
OLD | NEW |