Home | History | Annotate | Line # | Download | only in tcstp
      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-2006
      8  *
      9  */
     10 
     11 #include <stdlib.h>
     12 #include <stdio.h>
     13 #include <syslog.h>
     14 #include <string.h>
     15 #include <netdb.h>
     16 
     17 #include "trousers/tss.h"
     18 #include "trousers_types.h"
     19 #include "tcs_tsp.h"
     20 #include "tcs_utils.h"
     21 #include "tcs_int_literals.h"
     22 #include "capabilities.h"
     23 #include "tcslog.h"
     24 #include "tcsd_wrap.h"
     25 #include "tcsd.h"
     26 #include "tcs_utils.h"
     27 #include "rpc_tcstp_tcs.h"
     28 
     29 
     30 TSS_RESULT
     31 tcs_wrap_RegisterKey(struct tcsd_thread_data *data)
     32 {
     33 	TCS_CONTEXT_HANDLE hContext;
     34 	TSS_UUID WrappingKeyUUID;
     35 	TSS_UUID KeyUUID;
     36 	UINT32 cKeySize;
     37 	BYTE *rgbKey;
     38 	UINT32 cVendorData;
     39 	BYTE *gbVendorData;
     40 	TSS_RESULT result;
     41 
     42 	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
     43 		return TCSERR(TSS_E_INTERNAL_ERROR);
     44 
     45 	if ((result = ctx_verify_context(hContext)))
     46 		goto done;
     47 
     48 	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);
     49 
     50 	if (getData(TCSD_PACKET_TYPE_UUID, 1, &WrappingKeyUUID, 0, &data->comm))
     51 		return TCSERR(TSS_E_INTERNAL_ERROR);
     52 	if (getData(TCSD_PACKET_TYPE_UUID, 2, &KeyUUID, 0, &data->comm))
     53 		return TCSERR(TSS_E_INTERNAL_ERROR);
     54 	if (getData(TCSD_PACKET_TYPE_UINT32, 3, &cKeySize, 0, &data->comm))
     55 		return TCSERR(TSS_E_INTERNAL_ERROR);
     56 
     57 	rgbKey = calloc(1, cKeySize);
     58 	if (rgbKey == NULL) {
     59 		LogError("malloc of %d bytes failed.", cKeySize);
     60 		return TCSERR(TSS_E_OUTOFMEMORY);
     61 	}
     62 	if (getData(TCSD_PACKET_TYPE_PBYTE, 4, rgbKey, cKeySize, &data->comm)) {
     63 		free(rgbKey);
     64 		return TCSERR(TSS_E_INTERNAL_ERROR);
     65 	}
     66 	if (getData(TCSD_PACKET_TYPE_UINT32, 5, &cVendorData, 0, &data->comm)) {
     67 		free(rgbKey);
     68 		return TCSERR(TSS_E_INTERNAL_ERROR);
     69 	}
     70 
     71 	if (cVendorData == 0)
     72 		gbVendorData = NULL;
     73 	else {
     74 		gbVendorData = calloc(1, cVendorData);
     75 		if (gbVendorData == NULL) {
     76 			LogError("malloc of %d bytes failed.", cVendorData);
     77 			free(rgbKey);
     78 			return TCSERR(TSS_E_OUTOFMEMORY);
     79 		}
     80 
     81 		if (getData(TCSD_PACKET_TYPE_PBYTE, 6, gbVendorData, cVendorData, &data->comm)) {
     82 			free(rgbKey);
     83 			free(gbVendorData);
     84 			return TCSERR(TSS_E_INTERNAL_ERROR);
     85 		}
     86 	}
     87 
     88 	result = TCS_RegisterKey_Internal(hContext, &WrappingKeyUUID, &KeyUUID,
     89 				     cKeySize, rgbKey, cVendorData,
     90 				     gbVendorData);
     91 	free(rgbKey);
     92 	free(gbVendorData);
     93 done:
     94 	initData(&data->comm, 0);
     95 	data->comm.hdr.u.result = result;
     96 	return TSS_SUCCESS;
     97 }
     98 
     99 TSS_RESULT
    100 tcs_wrap_UnregisterKey(struct tcsd_thread_data *data)
    101 {
    102 	TCS_CONTEXT_HANDLE hContext;
    103 	TSS_UUID uuid;
    104 	TSS_RESULT result;
    105 
    106 	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
    107 		return TCSERR(TSS_E_INTERNAL_ERROR);
    108 
    109 	if ((result = ctx_verify_context(hContext)))
    110 		goto done;
    111 
    112 	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);
    113 
    114 	if (getData(TCSD_PACKET_TYPE_UUID, 1, &uuid, 0, &data->comm))
    115 		return TCSERR(TSS_E_INTERNAL_ERROR);
    116 
    117 	result = TCS_UnregisterKey_Internal(hContext, uuid);
    118 done:
    119 	initData(&data->comm, 0);
    120 	data->comm.hdr.u.result = result;
    121 
    122 	return TSS_SUCCESS;
    123 }
    124 
    125 TSS_RESULT
    126 tcs_wrap_GetRegisteredKeyBlob(struct tcsd_thread_data *data)
    127 {
    128 	TCS_CONTEXT_HANDLE hContext;
    129 	TSS_UUID uuid;
    130 	UINT32 pcKeySize;
    131 	BYTE *prgbKey;
    132 	TSS_RESULT result;
    133 
    134 	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
    135 		return TCSERR(TSS_E_INTERNAL_ERROR);
    136 
    137 	if ((result = ctx_verify_context(hContext)))
    138 		goto done;
    139 
    140 	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);
    141 
    142 	if (getData(TCSD_PACKET_TYPE_UUID, 1, &uuid, 0, &data->comm))
    143 		return TCSERR(TSS_E_INTERNAL_ERROR);
    144 
    145 	result = TCS_GetRegisteredKeyBlob_Internal(hContext, &uuid, &pcKeySize,
    146 					      &prgbKey);
    147 
    148 	if (result == TSS_SUCCESS) {
    149 		initData(&data->comm, 2);
    150 		if (setData(TCSD_PACKET_TYPE_UINT32, 0, &pcKeySize, 0, &data->comm)) {
    151 			free(prgbKey);
    152 			return TCSERR(TSS_E_INTERNAL_ERROR);
    153 		}
    154 		if (setData(TCSD_PACKET_TYPE_PBYTE, 1, prgbKey, pcKeySize, &data->comm)) {
    155 			free(prgbKey);
    156 			return TCSERR(TSS_E_INTERNAL_ERROR);
    157 		}
    158 		free(prgbKey);
    159 	} else
    160 done:		initData(&data->comm, 0);
    161 
    162 	data->comm.hdr.u.result = result;
    163 	return TSS_SUCCESS;
    164 }
    165 
    166 TSS_RESULT
    167 tcs_wrap_LoadKeyByUUID(struct tcsd_thread_data *data)
    168 {
    169 	TCS_CONTEXT_HANDLE hContext;
    170 	TSS_UUID uuid;
    171 	TCS_LOADKEY_INFO info, *pInfo;
    172 	TCS_KEY_HANDLE phKeyTCSI;
    173 	TSS_RESULT result;
    174 
    175 	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
    176 		return TCSERR(TSS_E_INTERNAL_ERROR);
    177 
    178 	if ((result = ctx_verify_context(hContext)))
    179 		goto done;
    180 
    181 	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);
    182 
    183 	if (getData(TCSD_PACKET_TYPE_UUID, 1, &uuid, 0, &data->comm))
    184 		return TCSERR(TSS_E_INTERNAL_ERROR);
    185 
    186 	result = getData(TCSD_PACKET_TYPE_LOADKEY_INFO, 2, &info, 0, &data->comm);
    187 	if (result == TSS_TCP_RPC_BAD_PACKET_TYPE)
    188 		pInfo = NULL;
    189 	else if (result)
    190 		return result;
    191 	else
    192 		pInfo = &info;
    193 
    194 	result = key_mgr_load_by_uuid(hContext, &uuid, pInfo, &phKeyTCSI);
    195 
    196 	if (result == TSS_SUCCESS) {
    197 		initData(&data->comm, 2);
    198 		if (setData(TCSD_PACKET_TYPE_UINT32, 0, &phKeyTCSI, 0, &data->comm)) {
    199 			return TCSERR(TSS_E_INTERNAL_ERROR);
    200 		}
    201 		if (pInfo != NULL) {
    202 			if (setData(TCSD_PACKET_TYPE_LOADKEY_INFO, 1, pInfo, 0, &data->comm)) {
    203 				return TCSERR(TSS_E_INTERNAL_ERROR);
    204 			}
    205 		}
    206 	} else {
    207 		if (result == TCSERR(TCS_E_KM_LOADFAILED) && pInfo != NULL) {
    208 			initData(&data->comm, 1);
    209 			if (setData(TCSD_PACKET_TYPE_LOADKEY_INFO, 0, pInfo, 0, &data->comm)) {
    210 				return TCSERR(TSS_E_INTERNAL_ERROR);
    211 			}
    212 		} else
    213 done:			initData(&data->comm, 0);
    214 
    215 	}
    216 	data->comm.hdr.u.result = result;
    217 	return TSS_SUCCESS;
    218 }
    219 
    220 TSS_RESULT
    221 tcs_wrap_EnumRegisteredKeys(struct tcsd_thread_data *data)
    222 {
    223 	TCS_CONTEXT_HANDLE hContext;
    224 	TSS_UUID uuid, *pUuid;
    225 	UINT32 cKeyHierarchySize;
    226 	TSS_KM_KEYINFO *pKeyHierarchy;
    227 	unsigned int i, j;
    228 	TSS_RESULT result;
    229 
    230 	/* Receive */
    231 	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
    232 		return TCSERR(TSS_E_INTERNAL_ERROR);
    233 
    234 	if ((result = ctx_verify_context(hContext)))
    235 		goto done;
    236 
    237 	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);
    238 
    239 	result = getData(TCSD_PACKET_TYPE_UUID , 1, &uuid, 0, &data->comm);
    240 	if (result == TSS_TCP_RPC_BAD_PACKET_TYPE)
    241 		pUuid = NULL;
    242 	else if (result)
    243 		return result;
    244 	else
    245 		pUuid = &uuid;
    246 
    247 	result = TCS_EnumRegisteredKeys_Internal(
    248 			hContext,
    249 			pUuid,
    250 			&cKeyHierarchySize,
    251 			&pKeyHierarchy);
    252 
    253 	if (result == TSS_SUCCESS) {
    254 		i=0;
    255 		initData(&data->comm, cKeyHierarchySize + 1);
    256 		if (setData(TCSD_PACKET_TYPE_UINT32, i++, &cKeyHierarchySize, 0, &data->comm)) {
    257 			free(pKeyHierarchy);
    258 			return TCSERR(TSS_E_INTERNAL_ERROR);
    259 		}
    260 
    261 		for (j = 0; j < cKeyHierarchySize; j++) {
    262 			if (setData(TCSD_PACKET_TYPE_KM_KEYINFO, i++, &pKeyHierarchy[j], 0, &data->comm)) {
    263 				free(pKeyHierarchy);
    264 				return TCSERR(TSS_E_INTERNAL_ERROR);
    265 			}
    266 		}
    267 		free(pKeyHierarchy);
    268 	} else
    269 done:		initData(&data->comm, 0);
    270 
    271 	data->comm.hdr.u.result = result;
    272 
    273 	return TSS_SUCCESS;
    274 }
    275 
    276 TSS_RESULT
    277 tcs_wrap_EnumRegisteredKeys2(struct tcsd_thread_data *data)
    278 {
    279 	TCS_CONTEXT_HANDLE hContext;
    280 	TSS_UUID uuid, *pUuid;
    281 	UINT32 cKeyHierarchySize;
    282 	TSS_KM_KEYINFO2 *pKeyHierarchy;
    283 	unsigned int i, j;
    284 	TSS_RESULT result;
    285 
    286 	/* Receive */
    287 	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
    288 		return TCSERR(TSS_E_INTERNAL_ERROR);
    289 
    290 	if ((result = ctx_verify_context(hContext)))
    291 		goto done;
    292 
    293 	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);
    294 
    295 	result = getData(TCSD_PACKET_TYPE_UUID , 1, &uuid, 0, &data->comm);
    296 	if (result == TSS_TCP_RPC_BAD_PACKET_TYPE)
    297 		pUuid = NULL;
    298 	else if (result)
    299 		return result;
    300 	else
    301 		pUuid = &uuid;
    302 
    303 	result = TCS_EnumRegisteredKeys_Internal2(
    304 			hContext,
    305 			pUuid,
    306 			&cKeyHierarchySize,
    307 			&pKeyHierarchy);
    308 
    309 	if (result == TSS_SUCCESS) {
    310 		i=0;
    311 		initData(&data->comm, cKeyHierarchySize + 1);
    312 		if (setData(TCSD_PACKET_TYPE_UINT32, i++, &cKeyHierarchySize, 0, &data->comm)) {
    313 			free(pKeyHierarchy);
    314 			return TCSERR(TSS_E_INTERNAL_ERROR);
    315 		}
    316 
    317 		for (j = 0; j < cKeyHierarchySize; j++) {
    318 			if (setData(TCSD_PACKET_TYPE_KM_KEYINFO2, i++, &pKeyHierarchy[j], 0, &data->comm)) {
    319 				free(pKeyHierarchy);
    320 				return TCSERR(TSS_E_INTERNAL_ERROR);
    321 			}
    322 		}
    323 		free(pKeyHierarchy);
    324 	} else
    325 done:		initData(&data->comm, 0);
    326 
    327 	data->comm.hdr.u.result = result;
    328 
    329 	return TSS_SUCCESS;
    330 }
    331 
    332 TSS_RESULT
    333 tcs_wrap_GetRegisteredKeyByPublicInfo(struct tcsd_thread_data *data)
    334 {
    335 	TCS_CONTEXT_HANDLE hContext;
    336 	TSS_RESULT result;
    337 	UINT32 algId, ulPublicInfoLength, keySize;
    338 	BYTE *rgbPublicInfo, *keyBlob;
    339 
    340 	if (getData(TCSD_PACKET_TYPE_UINT32, 0, &hContext, 0, &data->comm))
    341 		return TCSERR(TSS_E_INTERNAL_ERROR);
    342 
    343 	if ((result = ctx_verify_context(hContext)))
    344 		goto done;
    345 
    346 	LogDebugFn("thread %ld context %x", THREAD_ID, hContext);
    347 
    348 	if (getData(TCSD_PACKET_TYPE_UINT32, 1, &algId, 0, &data->comm))
    349 		return TCSERR(TSS_E_INTERNAL_ERROR);
    350 	if (getData(TCSD_PACKET_TYPE_UINT32, 2, &ulPublicInfoLength, 0, &data->comm))
    351 		return TCSERR(TSS_E_INTERNAL_ERROR);
    352 
    353 	rgbPublicInfo = (BYTE *)calloc(1, ulPublicInfoLength);
    354 	if (rgbPublicInfo == NULL) {
    355 		LogError("malloc of %d bytes failed.", ulPublicInfoLength);
    356 		return TCSERR(TSS_E_INTERNAL_ERROR);
    357 	}
    358 	if (getData(TCSD_PACKET_TYPE_PBYTE, 3, rgbPublicInfo, ulPublicInfoLength, &data->comm)) {
    359 		free(rgbPublicInfo);
    360 		return TCSERR(TSS_E_INTERNAL_ERROR);
    361 	}
    362 
    363 	result = TCSP_GetRegisteredKeyByPublicInfo_Internal(hContext, algId,
    364 			ulPublicInfoLength, rgbPublicInfo, &keySize, &keyBlob);
    365 
    366 	free(rgbPublicInfo);
    367 	if (result == TSS_SUCCESS) {
    368 		initData(&data->comm, 2);
    369 		if (setData(TCSD_PACKET_TYPE_UINT32, 0, &keySize, 0, &data->comm)) {
    370 			free(keyBlob);
    371 			return TCSERR(TSS_E_INTERNAL_ERROR);
    372 		}
    373 		if (setData(TCSD_PACKET_TYPE_PBYTE, 1, keyBlob, keySize, &data->comm)) {
    374 			free(keyBlob);
    375 			return TCSERR(TSS_E_INTERNAL_ERROR);
    376 		}
    377 		free(keyBlob);
    378 	} else
    379 done:		initData(&data->comm, 0);
    380 
    381 	data->comm.hdr.u.result = result;
    382 
    383 	return TSS_SUCCESS;
    384 }
    385 
    386 void
    387 LoadBlob_LOADKEY_INFO(UINT64 *offset, BYTE *blob, TCS_LOADKEY_INFO *info)
    388 {
    389 	LoadBlob_UUID(offset, blob, info->keyUUID);
    390 	LoadBlob_UUID(offset, blob, info->parentKeyUUID);
    391 	LoadBlob(offset, TCPA_DIGEST_SIZE, blob, info->paramDigest.digest);
    392 	LoadBlob_UINT32(offset, info->authData.AuthHandle, blob);
    393 	LoadBlob(offset, TCPA_NONCE_SIZE, blob, info->authData.NonceOdd.nonce);
    394 	LoadBlob(offset, TCPA_NONCE_SIZE, blob, info->authData.NonceEven.nonce);
    395 	LoadBlob_BOOL(offset, info->authData.fContinueAuthSession, blob);
    396 	LoadBlob(offset, TCPA_AUTHDATA_SIZE, blob, (BYTE *)&info->authData.HMAC);
    397 }
    398 
    399 void
    400 UnloadBlob_LOADKEY_INFO(UINT64 *offset, BYTE *blob, TCS_LOADKEY_INFO *info)
    401 {
    402 	if (!info) {
    403 		UnloadBlob_UUID(offset, blob, NULL);
    404 		UnloadBlob_UUID(offset, blob, NULL);
    405 		UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, NULL);
    406 		UnloadBlob_UINT32(offset, NULL, blob);
    407 		UnloadBlob(offset, TCPA_NONCE_SIZE, blob, NULL);
    408 		UnloadBlob(offset, TCPA_NONCE_SIZE, blob, NULL);
    409 		UnloadBlob_BOOL(offset, NULL, blob);
    410 		UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, NULL);
    411 
    412 		return;
    413 	}
    414 
    415 	UnloadBlob_UUID(offset, blob, &info->keyUUID);
    416 	UnloadBlob_UUID(offset, blob, &info->parentKeyUUID);
    417 	UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, info->paramDigest.digest);
    418 	UnloadBlob_UINT32(offset, &info->authData.AuthHandle, blob);
    419 	UnloadBlob(offset, TCPA_NONCE_SIZE, blob, (BYTE *)&info->authData.NonceOdd.nonce);
    420 	UnloadBlob(offset, TCPA_NONCE_SIZE, blob, (BYTE *)&info->authData.NonceEven.nonce);
    421 	UnloadBlob_BOOL(offset, &info->authData.fContinueAuthSession, blob);
    422 	UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, (BYTE *)&info->authData.HMAC);
    423 }
    424 
    425 void
    426 LoadBlob_UUID(UINT64 *offset, BYTE * blob, TSS_UUID uuid)
    427 {
    428         LoadBlob_UINT32(offset, uuid.ulTimeLow, blob);
    429         LoadBlob_UINT16(offset, uuid.usTimeMid, blob);
    430         LoadBlob_UINT16(offset, uuid.usTimeHigh, blob);
    431         LoadBlob_BYTE(offset, uuid.bClockSeqHigh, blob);
    432         LoadBlob_BYTE(offset, uuid.bClockSeqLow, blob);
    433         LoadBlob(offset, 6, blob, uuid.rgbNode);
    434 }
    435 
    436 void
    437 UnloadBlob_UUID(UINT64 *offset, BYTE * blob, TSS_UUID *uuid)
    438 {
    439         if (!uuid) {
    440                 UnloadBlob_UINT32(offset, NULL, blob);
    441                 UnloadBlob_UINT16(offset, NULL, blob);
    442                 UnloadBlob_UINT16(offset, NULL, blob);
    443                 UnloadBlob_BYTE(offset, NULL, blob);
    444                 UnloadBlob_BYTE(offset, NULL, blob);
    445                 UnloadBlob(offset, 6, blob, NULL);
    446 
    447                 return;
    448         }
    449 
    450         memset(uuid, 0, sizeof(TSS_UUID));
    451         UnloadBlob_UINT32(offset, &uuid->ulTimeLow, blob);
    452         UnloadBlob_UINT16(offset, &uuid->usTimeMid, blob);
    453         UnloadBlob_UINT16(offset, &uuid->usTimeHigh, blob);
    454         UnloadBlob_BYTE(offset, &uuid->bClockSeqHigh, blob);
    455         UnloadBlob_BYTE(offset, &uuid->bClockSeqLow, blob);
    456         UnloadBlob(offset, 6, blob, uuid->rgbNode);
    457 }
    458 
    459 void
    460 LoadBlob_KM_KEYINFO(UINT64 *offset, BYTE *blob, TSS_KM_KEYINFO *info)
    461 {
    462 	LoadBlob_VERSION(offset, blob, (TPM_VERSION *)&(info->versionInfo));
    463 	LoadBlob_UUID(offset, blob, info->keyUUID);
    464 	LoadBlob_UUID(offset, blob, info->parentKeyUUID);
    465 	LoadBlob_BYTE(offset, info->bAuthDataUsage, blob);
    466 	LoadBlob_BOOL(offset, info->fIsLoaded, blob);
    467 	LoadBlob_UINT32(offset, info->ulVendorDataLength, blob);
    468 	LoadBlob(offset, info->ulVendorDataLength, blob, info->rgbVendorData);
    469 }
    470 
    471 void
    472 LoadBlob_KM_KEYINFO2(UINT64 *offset, BYTE *blob, TSS_KM_KEYINFO2 *info)
    473 {
    474 	LoadBlob_VERSION(offset, blob, (TPM_VERSION *)&(info->versionInfo));
    475 	LoadBlob_UUID(offset, blob, info->keyUUID);
    476 	LoadBlob_UUID(offset, blob, info->parentKeyUUID);
    477 	LoadBlob_BYTE(offset, info->bAuthDataUsage, blob);
    478 	/* Load the infos of the blob regarding the new data type TSS_KM_KEYINFO2 */
    479 	LoadBlob_UINT32(offset,info->persistentStorageType,blob);
    480 	LoadBlob_UINT32(offset, info->persistentStorageTypeParent,blob);
    481 
    482 	LoadBlob_BOOL(offset, info->fIsLoaded, blob);
    483 	LoadBlob_UINT32(offset, info->ulVendorDataLength, blob);
    484 	LoadBlob(offset, info->ulVendorDataLength, blob, info->rgbVendorData);
    485 }
    486 
    487 void
    488 UnloadBlob_KM_KEYINFO(UINT64 *offset, BYTE *blob, TSS_KM_KEYINFO *info)
    489 {
    490 	if (!info) {
    491 		UINT32 ulVendorDataLength;
    492 
    493 		UnloadBlob_VERSION(offset, blob, NULL);
    494 		UnloadBlob_UUID(offset, blob, NULL);
    495 		UnloadBlob_UUID(offset, blob, NULL);
    496 		UnloadBlob_BYTE(offset, blob, NULL);
    497 		UnloadBlob_BOOL(offset, NULL, blob);
    498 		UnloadBlob_UINT32(offset, &ulVendorDataLength, blob);
    499 
    500 		(*offset) += ulVendorDataLength;
    501 
    502 		return;
    503 	}
    504 
    505 	UnloadBlob_VERSION(offset, blob, (TPM_VERSION *)&(info->versionInfo));
    506 	UnloadBlob_UUID(offset, blob, &info->keyUUID);
    507 	UnloadBlob_UUID(offset, blob, &info->parentKeyUUID);
    508 	UnloadBlob_BYTE(offset, &info->bAuthDataUsage, blob);
    509 	UnloadBlob_BOOL(offset, &info->fIsLoaded, blob);
    510 	UnloadBlob_UINT32(offset, &info->ulVendorDataLength, blob);
    511 	UnloadBlob(offset, info->ulVendorDataLength, info->rgbVendorData, blob);
    512 }
    513 
    514 #if 0
    515 void
    516 UnloadBlob_KM_KEYINFO2(UINT64 *offset, BYTE *blob, TSS_KM_KEYINFO2 *info)
    517 {
    518 	UnloadBlob_VERSION(offset, blob, (TCPA_VERSION *)&(info->versionInfo));
    519 	UnloadBlob_UUID(offset, blob, &info->keyUUID);
    520 	UnloadBlob_UUID(offset, blob, &info->parentKeyUUID);
    521 	UnloadBlob_BYTE(offset, blob, &info->bAuthDataUsage);
    522 
    523 	/* Extract the infos of the blob regarding the new data type TSS_KM_KEYINFO2 */
    524 	UnloadBlob_UINT32(offset, &info->persistentStorageType, blob);
    525 	UnloadBlob_UINT32(offset, &info->persistentStorageTypeParent, blob);
    526 
    527 	UnloadBlob_BOOL(offset, &info->fIsLoaded, blob);
    528 	UnloadBlob_UINT32(offset, &info->ulVendorDataLength, blob);
    529 	UnloadBlob(offset, info->ulVendorDataLength, info->rgbVendorData, blob);
    530 }
    531 #endif
    532