| 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 |