1 2 /* 3 * Licensed Materials - Property of IBM 4 * 5 * trousers - An open source TCG Software Stack 6 * 7 * (C) Copyright International Business Machines Corp. 2004-2007 8 * 9 */ 10 11 12 #include <stdlib.h> 13 #include <string.h> 14 15 #include "trousers/tss.h" 16 #include "trousers/trousers.h" 17 #include "trousers_types.h" 18 #include "spi_utils.h" 19 #include "capabilities.h" 20 #include "tsplog.h" 21 #include "obj.h" 22 23 24 void 25 free_key_refs(TSS_KEY *key) 26 { 27 free(key->algorithmParms.parms); 28 key->algorithmParms.parms = NULL; 29 key->algorithmParms.parmSize = 0; 30 31 free(key->pubKey.key); 32 key->pubKey.key = NULL; 33 key->pubKey.keyLength = 0; 34 35 free(key->encData); 36 key->encData = NULL; 37 key->encSize = 0; 38 39 free(key->PCRInfo); 40 key->PCRInfo = NULL; 41 key->PCRInfoSize = 0; 42 } 43 44 void 45 LoadBlob_TSS_KEY(UINT64 *offset, BYTE *blob, TSS_KEY *key) 46 { 47 if (key->hdr.key12.tag == TPM_TAG_KEY12) 48 Trspi_LoadBlob_KEY12(offset, blob, (TPM_KEY12 *)key); 49 else 50 Trspi_LoadBlob_KEY(offset, blob, (TCPA_KEY *)key); 51 } 52 53 TSS_RESULT 54 UnloadBlob_TSS_KEY(UINT64 *offset, BYTE *blob, TSS_KEY *key) 55 { 56 UINT16 tag; 57 UINT64 keyOffset = *offset; 58 TSS_RESULT result; 59 60 Trspi_UnloadBlob_UINT16(&keyOffset, &tag, blob); 61 if (tag == TPM_TAG_KEY12) 62 result = Trspi_UnloadBlob_KEY12(offset, blob, (TPM_KEY12 *)key); 63 else 64 result = Trspi_UnloadBlob_KEY(offset, blob, (TCPA_KEY *)key); 65 66 return result; 67 } 68 69 TSS_RESULT 70 Hash_TSS_KEY(Trspi_HashCtx *c, TSS_KEY *key) 71 { 72 TSS_RESULT result; 73 74 if (key->hdr.key12.tag == TPM_TAG_KEY12) 75 result = Trspi_Hash_KEY12(c, (TPM_KEY12 *)key); 76 else 77 result = Trspi_Hash_KEY(c, (TCPA_KEY *)key); 78 79 return result; 80 } 81 82 void 83 LoadBlob_TSS_PRIVKEY_DIGEST(UINT64 *offset, BYTE *blob, TSS_KEY *key) 84 { 85 if (key->hdr.key12.tag == TPM_TAG_KEY12) 86 Trspi_LoadBlob_PRIVKEY_DIGEST12(offset, blob, (TPM_KEY12 *)key); 87 else 88 Trspi_LoadBlob_PRIVKEY_DIGEST(offset, blob, (TCPA_KEY *)key); 89 } 90 91 TSS_RESULT 92 Hash_TSS_PRIVKEY_DIGEST(Trspi_HashCtx *c, TSS_KEY *key) 93 { 94 TSS_RESULT result; 95 96 if (key->hdr.key12.tag == TPM_TAG_KEY12) 97 result = Trspi_Hash_PRIVKEY_DIGEST12(c, (TPM_KEY12 *)key); 98 else 99 result = Trspi_Hash_PRIVKEY_DIGEST(c, (TCPA_KEY *)key); 100 101 return result; 102 } 103 104 #ifdef TSS_BUILD_TRANSPORT 105 TSS_RESULT 106 Transport_EvictKey(TSS_HCONTEXT tspContext, 107 TCS_KEY_HANDLE hKey) 108 { 109 TSS_RESULT result; 110 UINT32 handlesLen; 111 TCS_HANDLE *handles, handle; 112 TPM_DIGEST pubKeyHash; 113 Trspi_HashCtx hashCtx; 114 115 116 if ((result = obj_context_transport_init(tspContext))) 117 return result; 118 119 LogDebugFn("Executing in a transport session"); 120 121 if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest))) 122 return result; 123 124 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 125 result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); 126 if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) 127 return result; 128 129 handlesLen = 1; 130 handle = hKey; 131 handles = &handle; 132 133 result = obj_context_transport_execute(tspContext, TPM_ORD_EvictKey, 0, NULL, &pubKeyHash, 134 &handlesLen, &handles, NULL, NULL, NULL, NULL); 135 136 return result; 137 } 138 139 TSS_RESULT 140 Transport_GetPubKey(TSS_HCONTEXT tspContext, 141 TCS_KEY_HANDLE hKey, 142 TPM_AUTH *pAuth, 143 UINT32 *pcPubKeySize, 144 BYTE **prgbPubKey) 145 { 146 TSS_RESULT result; 147 UINT32 handlesLen, decLen; 148 TCS_HANDLE *handles, handle; 149 BYTE *dec = NULL; 150 TPM_DIGEST pubKeyHash; 151 Trspi_HashCtx hashCtx; 152 153 154 if ((result = obj_context_transport_init(tspContext))) 155 return result; 156 157 LogDebugFn("Executing in a transport session"); 158 159 if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest))) 160 return result; 161 162 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 163 result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); 164 if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) 165 return result; 166 167 handlesLen = 1; 168 handle = hKey; 169 handles = &handle; 170 171 if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetPubKey, 0, NULL, 172 &pubKeyHash, &handlesLen, &handles, pAuth, NULL, 173 &decLen, &dec))) 174 return result; 175 176 *prgbPubKey = dec; 177 *pcPubKeySize = decLen; 178 179 return result; 180 } 181 182 TSS_RESULT 183 Transport_CreateWrapKey(TSS_HCONTEXT tspContext, /* in */ 184 TCS_KEY_HANDLE hWrappingKey, /* in */ 185 TPM_ENCAUTH *KeyUsageAuth, /* in */ 186 TPM_ENCAUTH *KeyMigrationAuth, /* in */ 187 UINT32 keyInfoSize, /* in */ 188 BYTE * keyInfo, /* in */ 189 UINT32 * keyDataSize, /* out */ 190 BYTE ** keyData, /* out */ 191 TPM_AUTH * pAuth) /* in, out */ 192 { 193 TSS_RESULT result; 194 UINT32 handlesLen, decLen; 195 TCS_HANDLE *handles, handle; 196 BYTE *dec = NULL; 197 TPM_DIGEST pubKeyHash; 198 Trspi_HashCtx hashCtx; 199 UINT64 offset; 200 BYTE *data; 201 202 203 if ((result = obj_context_transport_init(tspContext))) 204 return result; 205 206 LogDebugFn("Executing in a transport session"); 207 208 if ((result = obj_tcskey_get_pubkeyhash(hWrappingKey, pubKeyHash.digest))) 209 return result; 210 211 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 212 result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); 213 if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) 214 return result; 215 216 handlesLen = 1; 217 handle = hWrappingKey; 218 handles = &handle; 219 220 if ((data = malloc(2 * sizeof(TPM_ENCAUTH) + keyInfoSize)) == NULL) { 221 LogError("malloc of %zd bytes failed", 2 * sizeof(TPM_ENCAUTH) + keyInfoSize); 222 return TSPERR(TSS_E_OUTOFMEMORY); 223 } 224 225 offset = 0; 226 Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, KeyUsageAuth->authdata); 227 Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, KeyMigrationAuth->authdata); 228 Trspi_LoadBlob(&offset, keyInfoSize, data, keyInfo); 229 230 if ((result = obj_context_transport_execute(tspContext, TPM_ORD_CreateWrapKey, 231 (2 * sizeof(TPM_ENCAUTH) + keyInfoSize), data, 232 &pubKeyHash, &handlesLen, &handles, pAuth, NULL, 233 &decLen, &dec))) 234 goto done; 235 236 *keyDataSize = decLen; 237 *keyData = dec; 238 done: 239 free(data); 240 241 return result; 242 } 243 244 TSS_RESULT 245 Transport_LoadKeyByBlob(TSS_HCONTEXT tspContext, 246 TCS_KEY_HANDLE hParentKey, 247 UINT32 ulBlobLength, 248 BYTE* rgbBlobData, 249 TPM_AUTH* pAuth, 250 TCS_KEY_HANDLE* phKey, 251 TPM_KEY_HANDLE* phSlot) 252 { 253 TSS_RESULT result; 254 UINT32 handlesLen, decLen; 255 TCS_HANDLE *handles, handle; 256 BYTE *dec = NULL; 257 TPM_DIGEST pubKeyHash; 258 Trspi_HashCtx hashCtx; 259 260 261 if ((result = obj_context_transport_init(tspContext))) 262 return result; 263 264 LogDebugFn("Executing in a transport session"); 265 266 if ((result = obj_tcskey_get_pubkeyhash(hParentKey, pubKeyHash.digest))) 267 return result; 268 269 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 270 result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); 271 if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) 272 return result; 273 274 handlesLen = 1; 275 handle = hParentKey; 276 handles = &handle; 277 278 if ((result = obj_context_transport_execute(tspContext, TPM_ORD_LoadKey2, ulBlobLength, 279 rgbBlobData, &pubKeyHash, &handlesLen, 280 &handles, pAuth, NULL, &decLen, &dec))) 281 return result; 282 283 if (handlesLen == 1) 284 *phKey = *(TCS_KEY_HANDLE *)handles; 285 else 286 result = TSPERR(TSS_E_INTERNAL_ERROR); 287 288 free(dec); 289 290 return result; 291 } 292 293 /* This function both encrypts the handle of the pubkey being requested and requires the hash 294 * of that pubkey for the transport log when logging is enabled. */ 295 TSS_RESULT 296 Transport_OwnerReadInternalPub(TSS_HCONTEXT tspContext, /* in */ 297 TCS_KEY_HANDLE hKey, /* in */ 298 TPM_AUTH* pOwnerAuth, /* in, out */ 299 UINT32* punPubKeySize, /* out */ 300 BYTE** ppbPubKeyData) /* out */ 301 { 302 UINT64 offset; 303 TSS_RESULT result; 304 UINT32 handlesLen = 0, decLen; 305 TPM_DIGEST pubKeyHash; 306 Trspi_HashCtx hashCtx; 307 BYTE *dec = NULL, data[sizeof(TCS_KEY_HANDLE)]; 308 309 310 if ((result = obj_context_transport_init(tspContext))) 311 return result; 312 313 LogDebugFn("Executing in a transport session"); 314 315 if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest))) 316 return result; 317 318 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); 319 result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); 320 if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) 321 return result; 322 323 offset = 0; 324 Trspi_LoadBlob_UINT32(&offset, hKey, data); 325 326 if ((result = obj_context_transport_execute(tspContext, TPM_ORD_OwnerReadInternalPub, 327 sizeof(data), data, &pubKeyHash, &handlesLen, 328 NULL, pOwnerAuth, NULL, &decLen, &dec))) 329 return result; 330 331 *punPubKeySize = decLen; 332 *ppbPubKeyData = dec; 333 334 return result; 335 } 336 #endif 337 338