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 8 * 9 */ 10 11 12 #include <stdlib.h> 13 #include <stdio.h> 14 #include <string.h> 15 #include <inttypes.h> 16 17 #include "trousers/tss.h" 18 #include "trousers_types.h" 19 #include "tcs_tsp.h" 20 #include "tcsps.h" 21 #include "tcs_utils.h" 22 #include "tcs_int_literals.h" 23 #include "capabilities.h" 24 #include "tcslog.h" 25 #include "req_mgr.h" 26 #include "tcsd_wrap.h" 27 #include "tcsd.h" 28 29 30 TSS_RESULT 31 TCSP_ChangeAuth_Internal(TCS_CONTEXT_HANDLE contextHandle, /* in */ 32 TCS_KEY_HANDLE parentHandle, /* in */ 33 TCPA_PROTOCOL_ID protocolID, /* in */ 34 TCPA_ENCAUTH newAuth, /* in */ 35 TCPA_ENTITY_TYPE entityType, /* in */ 36 UINT32 encDataSize, /* in */ 37 BYTE *encData, /* in */ 38 TPM_AUTH *ownerAuth, /* in, out */ 39 TPM_AUTH *entityAuth, /* in, out */ 40 UINT32 *outDataSize, /* out */ 41 BYTE **outData /* out */ 42 ) 43 { 44 UINT64 offset = 0; 45 UINT32 paramSize; 46 TSS_RESULT result; 47 TCPA_KEY_HANDLE keySlot; 48 TCS_KEY_HANDLE tcsKeyHandleToEvict; 49 BYTE txBlob[TSS_TPM_TXBLOB_SIZE]; 50 51 LogDebug("Entering Changeauth"); 52 if ((result = ctx_verify_context(contextHandle))) 53 goto done; 54 55 if ((result = auth_mgr_check(contextHandle, &ownerAuth->AuthHandle))) 56 goto done; 57 if ((result = auth_mgr_check(contextHandle, &entityAuth->AuthHandle))) 58 goto done; 59 60 if ((result = ensureKeyIsLoaded(contextHandle, parentHandle, &keySlot))) 61 goto done; 62 63 if ((result = tpm_rqu_build(TPM_ORD_ChangeAuth, &offset, txBlob, keySlot, protocolID, 64 newAuth.authdata, entityType, encDataSize, encData, ownerAuth, 65 entityAuth))) 66 goto done; 67 68 if ((result = req_mgr_submit_req(txBlob))) 69 goto done; 70 71 result = UnloadBlob_Header(txBlob, ¶mSize); 72 if (!result) { 73 result = tpm_rsp_parse(TPM_ORD_ChangeAuth, txBlob, paramSize, outDataSize, outData, 74 ownerAuth, entityAuth); 75 76 /* if the malloc above failed, terminate the 2 new auth handles and exit */ 77 if (result) 78 goto done; 79 80 /* 81 * Check if ET is a key. If it is, we need to 82 * 1 - Evict the key if loaded 83 * 2 - update the mem cache entry 84 */ 85 if (entityType == TCPA_ET_KEYHANDLE || entityType == TCPA_ET_KEY) { 86 LogDebug("entity type is a key. Check if mem cache needs updating..."); 87 tcsKeyHandleToEvict = mc_get_handle_by_encdata(encData); 88 LogDebug("tcsKeyHandle being evicted is %.8X", tcsKeyHandleToEvict); 89 /*--- If it was found in knowledge, replace it */ 90 if (tcsKeyHandleToEvict != 0) { 91 internal_EvictByKeySlot(keySlot); 92 mc_update_encdata(encData, *outData); 93 } 94 95 } 96 } 97 LogResult("ChangeAuth", result); 98 done: 99 auth_mgr_release_auth(ownerAuth, entityAuth, contextHandle); 100 return result; 101 } 102 103 TSS_RESULT 104 TCSP_ChangeAuthOwner_Internal(TCS_CONTEXT_HANDLE hContext, /* in */ 105 TCPA_PROTOCOL_ID protocolID, /* in */ 106 TCPA_ENCAUTH newAuth, /* in */ 107 TCPA_ENTITY_TYPE entityType, /* in */ 108 TPM_AUTH * ownerAuth /* in, out */ 109 ) 110 { 111 UINT64 offset = 0; 112 UINT32 paramSize; 113 TSS_RESULT result; 114 BYTE txBlob[TSS_TPM_TXBLOB_SIZE]; 115 116 LogDebug("Entering ChangeAuthOwner"); 117 118 if ((result = ctx_verify_context(hContext))) 119 goto done; 120 121 if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle))) 122 goto done; 123 124 if ((result = tpm_rqu_build(TPM_ORD_ChangeAuthOwner, &offset, txBlob, protocolID, 125 newAuth.authdata, entityType, ownerAuth))) 126 goto done; 127 128 if ((result = req_mgr_submit_req(txBlob))) 129 goto done; 130 131 result = UnloadBlob_Header(txBlob, ¶mSize); 132 if (!result) { 133 result = tpm_rsp_parse(TPM_ORD_ChangeAuthOwner, txBlob, paramSize, ownerAuth); 134 } 135 136 LogResult("ChangeAuthOwner", result); 137 done: 138 auth_mgr_release_auth(ownerAuth, NULL, hContext); 139 return result; 140 } 141 142 TSS_RESULT 143 TCSP_ChangeAuthAsymStart_Internal(TCS_CONTEXT_HANDLE hContext, /* in */ 144 TCS_KEY_HANDLE idHandle, /* in */ 145 TCPA_NONCE antiReplay, /* in */ 146 UINT32 KeySizeIn, /* in */ 147 BYTE * KeyDataIn, /* in */ 148 TPM_AUTH * pAuth, /* in, out */ 149 UINT32 * KeySizeOut, /* out */ 150 BYTE ** KeyDataOut, /* out */ 151 UINT32 * CertifyInfoSize, /* out */ 152 BYTE ** CertifyInfo, /* out */ 153 UINT32 * sigSize, /* out */ 154 BYTE ** sig, /* out */ 155 TCS_KEY_HANDLE * ephHandle /* out */ 156 ) 157 { 158 #if 0 159 #warning Locking trouble in evictFirstKey 160 UINT64 offset; 161 UINT32 paramSize; 162 TSS_RESULT result; 163 UINT32 keySlot; 164 TCPA_CERTIFY_INFO certifyInfo; 165 TSS_KEY tempKey; 166 UINT32 tempSize; 167 TCPA_KEY_PARMS keyParmsContainer; 168 TSS_BOOL canLoad; 169 BYTE txBlob[TSS_TPM_TXBLOB_SIZE]; 170 171 LogDebug("Entering ChangeAuthAsymStart"); 172 if ((result = ctx_verify_context(hContext))) 173 goto done; 174 175 if (pAuth != NULL) { 176 LogDebug("Auth Command"); 177 if ((result = auth_mgr_check(hContext, pAuth->AuthHandle))) 178 goto done; 179 } else { 180 LogDebug("No Auth"); 181 } 182 183 if ((result = ensureKeyIsLoaded(hContext, idHandle, &keySlot))) 184 goto done; 185 186 LogDebug("Checking for room to load the eph key"); 187 offset = 0; 188 if ((result = UnloadBlob_KEY_PARMS(&offset, KeyDataIn, &keyParmsContainer))) 189 goto done; 190 191 /* if we can't load the key, evict keys until we can */ 192 if ((result = canILoadThisKey(&keyParmsContainer, &canLoad))) 193 goto done; 194 195 while (canLoad == FALSE) { 196 /* Evict a key that isn't the parent */ 197 if ((result = evictFirstKey(idHandle))) 198 goto done; 199 200 if ((result = canILoadThisKey(&keyParmsContainer, &canLoad))) 201 goto done; 202 } 203 204 offset = 10; 205 LoadBlob_UINT32(&offset, keySlot, txBlob); 206 LoadBlob(&offset, TCPA_NONCE_SIZE, txBlob, antiReplay.nonce); 207 /* LoadBlob_KEY_PARMS( &offset, txBlob, &tempKeyParms ); */ 208 /* LoadBlob_UINT32( &offset, KeySizeIn, txBlob ); */ 209 LoadBlob(&offset, KeySizeIn, txBlob, KeyDataIn); 210 211 if (pAuth != NULL) { 212 LoadBlob_Auth(&offset, txBlob, pAuth); 213 LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset, 214 TPM_ORD_ChangeAuthAsymStart, txBlob); 215 } else { 216 LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset, 217 TPM_ORD_ChangeAuthAsymStart, txBlob); 218 } 219 220 if ((result = req_mgr_submit_req(txBlob))) 221 goto done; 222 223 offset = 10; 224 result = UnloadBlob_Header(txBlob, ¶mSize); 225 if (result == 0) { 226 UnloadBlob_CERTIFY_INFO(&offset, txBlob, &certifyInfo); 227 *CertifyInfoSize = offset - 10; 228 *CertifyInfo = malloc(*CertifyInfoSize); 229 if (*CertifyInfo == NULL) { 230 LogError("malloc of %u bytes failed.", *CertifyInfoSize); 231 result = TCSERR(TSS_E_OUTOFMEMORY); 232 goto done; 233 } 234 memcpy(*CertifyInfo, &txBlob[offset - *CertifyInfoSize], 235 *CertifyInfoSize); 236 UnloadBlob_UINT32(&offset, sigSize, txBlob); 237 *sig = malloc(*sigSize); 238 if (*sig == NULL) { 239 LogError("malloc of %u bytes failed.", *sigSize); 240 result = TCSERR(TSS_E_OUTOFMEMORY); 241 goto done; 242 } 243 UnloadBlob(&offset, *sigSize, txBlob, *sig); 244 UnloadBlob_UINT32(&offset, ephHandle, txBlob); 245 tempSize = offset; 246 UnloadBlob_TSS_KEY(&offset, txBlob, &tempKey); 247 *KeySizeOut = offset - tempSize; 248 *KeyDataOut = malloc(*KeySizeOut); 249 if (*KeyDataOut == NULL) { 250 LogError("malloc of %u bytes failed.", *KeySizeOut); 251 result = TCSERR(TSS_E_OUTOFMEMORY); 252 goto done; 253 } 254 memcpy(*KeyDataOut, &txBlob[offset - *KeySizeOut], *KeySizeOut); 255 if (pAuth != NULL) 256 UnloadBlob_Auth(&offset, txBlob, pAuth); 257 } 258 259 LogResult("ChangeAuthAsymStart", result); 260 done: 261 auth_mgr_release_auth(pAuth, NULL, hContext); 262 return result; 263 #else 264 return TCSERR(TSS_E_NOTIMPL); 265 #endif 266 } 267 268 TSS_RESULT 269 TCSP_ChangeAuthAsymFinish_Internal(TCS_CONTEXT_HANDLE hContext, /* in */ 270 TCS_KEY_HANDLE parentHandle, /* in */ 271 TCS_KEY_HANDLE ephHandle, /* in */ 272 TCPA_ENTITY_TYPE entityType, /* in */ 273 TCPA_HMAC newAuthLink, /* in */ 274 UINT32 newAuthSize, /* in */ 275 BYTE * encNewAuth, /* in */ 276 UINT32 encDataSizeIn, /* in */ 277 BYTE * encDataIn, /* in */ 278 TPM_AUTH * ownerAuth, /* in, out */ 279 UINT32 * encDataSizeOut, /* out */ 280 BYTE ** encDataOut, /* out */ 281 TCPA_SALT_NONCE * saltNonce, /* out */ 282 TCPA_DIGEST * changeProof /* out */ 283 ) 284 { 285 #if 0 286 UINT64 offset; 287 UINT32 paramSize; 288 TSS_RESULT result; 289 UINT32 keySlot; 290 #if 0 291 TCPA_CERTIFY_INFO certifyInfo; 292 TSS_KEY tempKey; 293 UINT32 tempSize; 294 TSS_UUID *uuidKeyToEvict; 295 #endif 296 TCS_KEY_HANDLE tcsKeyHandleToEvict; 297 BYTE txBlob[TSS_TPM_TXBLOB_SIZE]; 298 299 LogDebug("Entering ChangeAuthAsymFinish"); 300 if ((result = ctx_verify_context(hContext))) 301 goto done; 302 303 if (ownerAuth != NULL) { 304 LogDebug("Auth used"); 305 if ((result = auth_mgr_check(hContext, &ownerAuth->AuthHandle))) 306 goto done; 307 } else { 308 LogDebug("No Auth"); 309 } 310 if ((result = ensureKeyIsLoaded(hContext, parentHandle, &keySlot))) 311 goto done; 312 313 offset = 10; 314 LoadBlob_UINT32(&offset, keySlot, txBlob); 315 LoadBlob_UINT32(&offset, ephHandle, txBlob); 316 LoadBlob_UINT16(&offset, entityType, txBlob); 317 LoadBlob(&offset, 20, txBlob, newAuthLink.digest); 318 LoadBlob_UINT32(&offset, newAuthSize, txBlob); 319 LoadBlob(&offset, newAuthSize, txBlob, encNewAuth); 320 LoadBlob_UINT32(&offset, encDataSizeIn, txBlob); 321 LoadBlob(&offset, encDataSizeIn, txBlob, encDataIn); 322 323 if (ownerAuth != NULL) { 324 LoadBlob_Auth(&offset, txBlob, ownerAuth); 325 LoadBlob_Header(TPM_TAG_RQU_AUTH1_COMMAND, offset, 326 TPM_ORD_ChangeAuthAsymFinish, txBlob); 327 } else { 328 LoadBlob_Header(TPM_TAG_RQU_COMMAND, offset, 329 TPM_ORD_ChangeAuthAsymFinish, txBlob); 330 } 331 332 if ((result = req_mgr_submit_req(txBlob))) 333 goto done; 334 335 offset = 10; 336 result = UnloadBlob_Header(txBlob, ¶mSize); 337 if (!result) { 338 UnloadBlob_UINT32(&offset, encDataSizeOut, txBlob); 339 *encDataOut = calloc(1, *encDataSizeOut); 340 if (*encDataOut == NULL) { 341 LogError("malloc of %u bytes failed.", *encDataSizeOut); 342 result = TCSERR(TSS_E_OUTOFMEMORY); 343 goto done; 344 } 345 UnloadBlob(&offset, *encDataSizeOut, txBlob, *encDataOut); 346 UnloadBlob(&offset, 20, txBlob, saltNonce->nonce); 347 UnloadBlob(&offset, 20, txBlob, changeProof->digest); 348 if (ownerAuth != NULL) 349 UnloadBlob_Auth(&offset, txBlob, ownerAuth); 350 351 /* Check if ET is a key. If it is, we need to 352 * 1 - Evict the key if loaded 353 * 2 - update the mem cache entry 354 */ 355 if (entityType == TCPA_ET_KEYHANDLE || 356 entityType == TCPA_ET_KEY) { 357 tcsKeyHandleToEvict = mc_get_handle_by_encdata(encDataIn); 358 /* If it was found in mem cache, replace it */ 359 if (tcsKeyHandleToEvict != 0) { 360 key_mgr_evict(hContext, tcsKeyHandleToEvict); 361 mc_update_encdata(encDataIn, *encDataOut); 362 } 363 } 364 } 365 366 LogResult("ChangeAuthAsymFinish", result); 367 done: 368 auth_mgr_release_auth(ownerAuth, NULL, hContext); 369 return result; 370 #else 371 return TCSERR(TSS_E_NOTIMPL); 372 #endif 373 } 374 375