Home | History | Annotate | Line # | Download | only in tcs
      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 <stdio.h>
     14 #include <string.h>
     15 #include <unistd.h>
     16 #include <sys/types.h>
     17 #include <sys/stat.h>
     18 #include <sys/mman.h>
     19 #include <fcntl.h>
     20 #include <errno.h>
     21 
     22 #include "trousers/tss.h"
     23 #include "trousers_types.h"
     24 #include "trousers_types.h"
     25 #include "tcs_tsp.h"
     26 #include "tcs_utils.h"
     27 #include "tcs_int_literals.h"
     28 #include "capabilities.h"
     29 #include "tcsps.h"
     30 #include "tcslog.h"
     31 
     32 
     33 TCS_CONTEXT_HANDLE InternalContext = 0x30000000;
     34 TSS_UUID SRK_UUID = TSS_UUID_SRK;
     35 
     36 
     37 void
     38 LogData(char *string, UINT32 data)
     39 {
     40 #if 0
     41 	/* commenting out temporarily, logs getting too chatty */
     42 	LogDebug("%s %08x", string, data);
     43 #endif
     44 }
     45 
     46 void
     47 LogResult(char *string, TCPA_RESULT result)
     48 {
     49 #if 0
     50 	/* commenting out temporarily, logs getting too chatty */
     51 	LogDebug("Leaving %s with result 0x%08x", string, result);
     52 #endif
     53 }
     54 
     55 UINT16
     56 Decode_UINT16(BYTE * in)
     57 {
     58 	UINT16 temp = 0;
     59 	temp = (in[1] & 0xFF);
     60 	temp |= (in[0] << 8);
     61 	return temp;
     62 }
     63 
     64 void
     65 UINT64ToArray(UINT64 i, BYTE * out)
     66 {
     67 	out[0] = (BYTE) ((i >> 56) & 0xFF);
     68 	out[1] = (BYTE) ((i >> 48) & 0xFF);
     69 	out[2] = (BYTE) ((i >> 40) & 0xFF);
     70 	out[3] = (BYTE) ((i >> 32) & 0xFF);
     71 	out[4] = (BYTE) ((i >> 24) & 0xFF);
     72 	out[5] = (BYTE) ((i >> 16) & 0xFF);
     73 	out[6] = (BYTE) ((i >> 8) & 0xFF);
     74 	out[7] = (BYTE) (i & 0xFF);
     75 }
     76 
     77 void
     78 UINT32ToArray(UINT32 i, BYTE * out)
     79 {
     80 	out[0] = (BYTE) ((i >> 24) & 0xFF);
     81 	out[1] = (BYTE) ((i >> 16) & 0xFF);
     82 	out[2] = (BYTE) ((i >> 8) & 0xFF);
     83 	out[3] = (BYTE) (i & 0xFF);
     84 }
     85 
     86 void
     87 UINT16ToArray(UINT16 i, BYTE * out)
     88 {
     89 	out[0] = (BYTE) ((i >> 8) & 0xFF);
     90 	out[1] = (BYTE) (i & 0xFF);
     91 }
     92 
     93 UINT32
     94 Decode_UINT32(BYTE * y)
     95 {
     96 	UINT32 x = 0;
     97 
     98 	x = y[0];
     99 	x = ((x << 8) | (y[1] & 0xFF));
    100 	x = ((x << 8) | (y[2] & 0xFF));
    101 	x = ((x << 8) | (y[3] & 0xFF));
    102 
    103 	return x;
    104 }
    105 
    106 UINT64
    107 Decode_UINT64(BYTE *y)
    108 {
    109 	UINT64 x = 0;
    110 
    111 	x = y[0];
    112 	x = ((x << 8) | (y[1] & 0xFF));
    113 	x = ((x << 8) | (y[2] & 0xFF));
    114 	x = ((x << 8) | (y[3] & 0xFF));
    115 	x = ((x << 8) | (y[4] & 0xFF));
    116 	x = ((x << 8) | (y[5] & 0xFF));
    117 	x = ((x << 8) | (y[6] & 0xFF));
    118 	x = ((x << 8) | (y[7] & 0xFF));
    119 
    120 	return x;
    121 }
    122 
    123 void
    124 LoadBlob_UINT64(UINT64 *offset, UINT64 in, BYTE * blob)
    125 {
    126 	if (blob)
    127 		UINT64ToArray(in, &blob[*offset]);
    128 	*offset += sizeof(UINT64);
    129 }
    130 
    131 void
    132 LoadBlob_UINT32(UINT64 *offset, UINT32 in, BYTE * blob)
    133 {
    134 	if (blob)
    135 		UINT32ToArray(in, &blob[*offset]);
    136 	*offset += sizeof(UINT32);
    137 }
    138 
    139 void
    140 LoadBlob_UINT16(UINT64 *offset, UINT16 in, BYTE * blob)
    141 {
    142 	if (blob)
    143 		UINT16ToArray(in, &blob[*offset]);
    144 	*offset += sizeof(UINT16);
    145 }
    146 
    147 void
    148 UnloadBlob_UINT64(UINT64 *offset, UINT64 * out, BYTE * blob)
    149 {
    150 	if (out)
    151 		*out = Decode_UINT64(&blob[*offset]);
    152 	*offset += sizeof(UINT64);
    153 }
    154 
    155 void
    156 UnloadBlob_UINT32(UINT64 *offset, UINT32 * out, BYTE * blob)
    157 {
    158 	if (out)
    159 		*out = Decode_UINT32(&blob[*offset]);
    160 	*offset += sizeof(UINT32);
    161 }
    162 
    163 void
    164 UnloadBlob_UINT16(UINT64 *offset, UINT16 * out, BYTE * blob)
    165 {
    166 	if (out)
    167 		*out = Decode_UINT16(&blob[*offset]);
    168 	*offset += sizeof(UINT16);
    169 }
    170 
    171 void
    172 LoadBlob_BYTE(UINT64 *offset, BYTE data, BYTE * blob)
    173 {
    174 	if (blob)
    175 		blob[*offset] = data;
    176 	(*offset)++;
    177 }
    178 
    179 void
    180 UnloadBlob_BYTE(UINT64 *offset, BYTE * dataOut, BYTE * blob)
    181 {
    182 	if (dataOut)
    183 		*dataOut = blob[*offset];
    184 	(*offset)++;
    185 }
    186 
    187 void
    188 LoadBlob_BOOL(UINT64 *offset, TSS_BOOL data, BYTE * blob)
    189 {
    190 	if (blob)
    191 		blob[*offset] = data;
    192 	(*offset)++;
    193 }
    194 
    195 void
    196 UnloadBlob_BOOL(UINT64 *offset, TSS_BOOL *dataOut, BYTE * blob)
    197 {
    198 	if (dataOut)
    199 		*dataOut = blob[*offset];
    200 	(*offset)++;
    201 }
    202 
    203 void
    204 LoadBlob(UINT64 *offset, UINT32 size, BYTE *container, BYTE *object)
    205 {
    206 	if (container)
    207 		memcpy(&container[*offset], object, size);
    208 	(*offset) += (UINT64) size;
    209 }
    210 
    211 void
    212 UnloadBlob(UINT64 *offset, UINT32 size, BYTE *container, BYTE *object)
    213 {
    214 	if (object)
    215 		memcpy(object, &container[*offset], size);
    216 	(*offset) += (UINT64) size;
    217 }
    218 
    219 void
    220 LoadBlob_Header(UINT16 tag, UINT32 paramSize, UINT32 ordinal, BYTE * blob)
    221 {
    222 
    223 	UINT16ToArray(tag, &blob[0]);
    224 	LogData("Header Tag:", tag);
    225 	UINT32ToArray(paramSize, &blob[2]);
    226 	LogData("Header ParamSize:", paramSize);
    227 	UINT32ToArray(ordinal, &blob[6]);
    228 	LogData("Header Ordinal:", ordinal);
    229 #if 0
    230 	LogInfo("Blob's TPM Ordinal: 0x%x", ordinal);
    231 #endif
    232 }
    233 
    234 #ifdef TSS_DEBUG
    235 TSS_RESULT
    236 LogUnloadBlob_Header(BYTE * blob, UINT32 * size, char *file, int line)
    237 {
    238 	TSS_RESULT result;
    239 
    240 	UINT16 temp = Decode_UINT16(blob);
    241 	LogData("UnloadBlob_Tag:", (temp));
    242 	*size = Decode_UINT32(&blob[2]);
    243 	LogData("UnloadBlob_Header, size:", *size);
    244 	LogData("UnloadBlob_Header, returnCode:", Decode_UINT32(&blob[6]));
    245 
    246 	if ((result = Decode_UINT32(&blob[6]))) {
    247 		LogTPMERR(result, file, line);
    248 	}
    249 
    250 	return result;
    251 }
    252 #else
    253 TSS_RESULT
    254 UnloadBlob_Header(BYTE * blob, UINT32 * size)
    255 {
    256 	UINT16 temp = Decode_UINT16(blob);
    257 	LogData("UnloadBlob_Tag:", (temp));
    258 	*size = Decode_UINT32(&blob[2]);
    259 	LogData("UnloadBlob_Header, size:", *size);
    260 	LogData("UnloadBlob_Header, returnCode:", Decode_UINT32(&blob[6]));
    261 	return Decode_UINT32(&blob[6]);
    262 }
    263 #endif
    264 
    265 void
    266 LoadBlob_Auth(UINT64 *offset, BYTE * blob, TPM_AUTH * auth)
    267 {
    268 	LoadBlob_UINT32(offset, auth->AuthHandle, blob);
    269 	LoadBlob(offset, TCPA_NONCE_SIZE, blob, auth->NonceOdd.nonce);
    270 	LoadBlob_BOOL(offset, auth->fContinueAuthSession, blob);
    271 	LoadBlob(offset, TCPA_AUTHDATA_SIZE, blob, (BYTE *)&auth->HMAC);
    272 }
    273 
    274 void
    275 UnloadBlob_Auth(UINT64 *offset, BYTE * blob, TPM_AUTH * auth)
    276 {
    277 	if (!auth) {
    278 		UnloadBlob(offset, TCPA_NONCE_SIZE, blob, NULL);
    279 		UnloadBlob_BOOL(offset, NULL, blob);
    280 		UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, NULL);
    281 
    282 		return;
    283 	}
    284 
    285 	UnloadBlob(offset, TCPA_NONCE_SIZE, blob, auth->NonceEven.nonce);
    286 	UnloadBlob_BOOL(offset, &auth->fContinueAuthSession, blob);
    287 	UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, (BYTE *)&auth->HMAC);
    288 }
    289 
    290 void
    291 UnloadBlob_VERSION(UINT64 *offset, BYTE *blob, TPM_VERSION *out)
    292 {
    293 	if (!out) {
    294 		*offset += (sizeof(BYTE) * 4);
    295 		return;
    296 	}
    297 
    298 	UnloadBlob_BYTE(offset, &out->major, blob);
    299 	UnloadBlob_BYTE(offset, &out->minor, blob);
    300 	UnloadBlob_BYTE(offset, &out->revMajor, blob);
    301 	UnloadBlob_BYTE(offset, &out->revMinor, blob);
    302 }
    303 
    304 void
    305 LoadBlob_VERSION(UINT64 *offset, BYTE *blob, TPM_VERSION *ver)
    306 {
    307 	LoadBlob_BYTE(offset, ver->major, blob);
    308 	LoadBlob_BYTE(offset, ver->minor, blob);
    309 	LoadBlob_BYTE(offset, ver->revMajor, blob);
    310 	LoadBlob_BYTE(offset, ver->revMinor, blob);
    311 }
    312 
    313 void
    314 UnloadBlob_TCPA_VERSION(UINT64 *offset, BYTE *blob, TCPA_VERSION *out)
    315 {
    316 	if (!out) {
    317 		*offset += (sizeof(BYTE) * 4);
    318 		return;
    319 	}
    320 
    321 	UnloadBlob_BYTE(offset, &out->major, blob);
    322 	UnloadBlob_BYTE(offset, &out->minor, blob);
    323 	UnloadBlob_BYTE(offset, &out->revMajor, blob);
    324 	UnloadBlob_BYTE(offset, &out->revMinor, blob);
    325 }
    326 
    327 void
    328 LoadBlob_TCPA_VERSION(UINT64 *offset, BYTE *blob, TCPA_VERSION *ver)
    329 {
    330 	LoadBlob_BYTE(offset, ver->major, blob);
    331 	LoadBlob_BYTE(offset, ver->minor, blob);
    332 	LoadBlob_BYTE(offset, ver->revMajor, blob);
    333 	LoadBlob_BYTE(offset, ver->revMinor, blob);
    334 }
    335 
    336 TSS_RESULT
    337 UnloadBlob_KEY_PARMS(UINT64 *offset, BYTE *blob, TCPA_KEY_PARMS *keyParms)
    338 {
    339 	if (!keyParms) {
    340 		UINT32 parmSize;
    341 
    342 		UnloadBlob_UINT32(offset, NULL, blob);
    343 		UnloadBlob_UINT16(offset, NULL, blob);
    344 		UnloadBlob_UINT16(offset, NULL, blob);
    345 		UnloadBlob_UINT32(offset, &parmSize, blob);
    346 
    347 		if (parmSize > 0)
    348 			UnloadBlob(offset, parmSize, blob, NULL);
    349 
    350 		return TSS_SUCCESS;
    351 	}
    352 
    353 	UnloadBlob_UINT32(offset, &keyParms->algorithmID, blob);
    354 	UnloadBlob_UINT16(offset, &keyParms->encScheme, blob);
    355 	UnloadBlob_UINT16(offset, &keyParms->sigScheme, blob);
    356 	UnloadBlob_UINT32(offset, &keyParms->parmSize, blob);
    357 
    358 	if (keyParms->parmSize == 0)
    359 		keyParms->parms = NULL;
    360 	else {
    361 		keyParms->parms = malloc(keyParms->parmSize);
    362 		if (keyParms->parms == NULL) {
    363 			LogError("malloc of %u bytes failed.", keyParms->parmSize);
    364 			keyParms->parmSize = 0;
    365 			return TCSERR(TSS_E_OUTOFMEMORY);
    366 		}
    367 
    368 		UnloadBlob(offset, keyParms->parmSize, blob, keyParms->parms);
    369 	}
    370 
    371 	return TSS_SUCCESS;
    372 }
    373 
    374 void
    375 UnloadBlob_KEY_FLAGS(UINT64 *offset, BYTE *blob, TCPA_KEY_FLAGS *flags)
    376 {
    377 	if (!flags) {
    378 		UnloadBlob_UINT32(offset, NULL, blob);
    379 
    380 		return;
    381 	}
    382 
    383 	UnloadBlob_UINT32(offset, flags, blob);
    384 }
    385 
    386 TSS_RESULT
    387 UnloadBlob_CERTIFY_INFO(UINT64 *offset, BYTE *blob, TCPA_CERTIFY_INFO *certify)
    388 {
    389 	TSS_RESULT rc;
    390 
    391 	if (!certify) {
    392 		TPM_VERSION version;
    393 		UINT32 size;
    394 
    395 		UnloadBlob_VERSION(offset, blob, &version);
    396 		UnloadBlob_UINT16(offset, NULL, blob);
    397 		UnloadBlob_KEY_FLAGS(offset, blob, NULL);
    398 		UnloadBlob_BOOL(offset, NULL, blob);
    399 
    400 		if ((rc = UnloadBlob_KEY_PARMS(offset, blob, NULL)))
    401 			return rc;
    402 
    403 		UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, NULL);
    404 		UnloadBlob(offset, TCPA_NONCE_SIZE, blob, NULL);
    405 		UnloadBlob_BOOL(offset, NULL, blob);
    406 		UnloadBlob_UINT32(offset, &size, blob);
    407 
    408 		if (size > 0)
    409 			UnloadBlob(offset, size, blob, NULL);
    410 
    411 		if (Decode_UINT16((BYTE *) &version) == TPM_TAG_CERTIFY_INFO2){
    412 			/* This is a TPM_CERTIFY_INFO2 structure. */
    413 			/* Read migrationAuthority. */
    414 			UnloadBlob_UINT32(offset, &size, blob);
    415 			if (size > 0)
    416 				UnloadBlob(offset, size, blob, NULL);
    417 		}
    418 
    419 		return TSS_SUCCESS;
    420 	}
    421 
    422 	UnloadBlob_VERSION(offset, blob, (TPM_VERSION *)&certify->version);
    423 	UnloadBlob_UINT16(offset, &certify->keyUsage, blob);
    424 	UnloadBlob_KEY_FLAGS(offset, blob, &certify->keyFlags);
    425 	UnloadBlob_BOOL(offset, (TSS_BOOL *)&certify->authDataUsage, blob);
    426 
    427 	if ((rc = UnloadBlob_KEY_PARMS(offset, blob, &certify->algorithmParms)))
    428 		return rc;
    429 
    430 	UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, certify->pubkeyDigest.digest);
    431 	UnloadBlob(offset, TCPA_NONCE_SIZE, blob, certify->data.nonce);
    432 	UnloadBlob_BOOL(offset, (TSS_BOOL *)&certify->parentPCRStatus, blob);
    433 	UnloadBlob_UINT32(offset, &certify->PCRInfoSize, blob);
    434 
    435 	if (certify->PCRInfoSize > 0) {
    436 		certify->PCRInfo = (BYTE *)malloc(certify->PCRInfoSize);
    437 		if (certify->PCRInfo == NULL) {
    438 			LogError("malloc of %u bytes failed.", certify->PCRInfoSize);
    439 			certify->PCRInfoSize = 0;
    440 			free(certify->algorithmParms.parms);
    441 			certify->algorithmParms.parms = NULL;
    442 			certify->algorithmParms.parmSize = 0;
    443 			return TCSERR(TSS_E_OUTOFMEMORY);
    444 		}
    445 		UnloadBlob(offset, certify->PCRInfoSize, blob, certify->PCRInfo);
    446 	} else {
    447 		certify->PCRInfo = NULL;
    448 	}
    449 
    450 	if (Decode_UINT16((BYTE *) &certify->version) == TPM_TAG_CERTIFY_INFO2){
    451 		/* This is a TPM_CERTIFY_INFO2 structure. */
    452 		/* Read migrationAuthority. */
    453 		UINT32 size;
    454 		UnloadBlob_UINT32(offset, &size, blob);
    455 		if (size > 0)
    456 			UnloadBlob(offset, size, blob, NULL);
    457 	}
    458 
    459 	return TSS_SUCCESS;
    460 }
    461 
    462 TSS_RESULT
    463 UnloadBlob_KEY_HANDLE_LIST(UINT64 *offset, BYTE *blob, TCPA_KEY_HANDLE_LIST *list)
    464 {
    465 	UINT16 i;
    466 
    467 	if (!list) {
    468 		UINT16 size;
    469 
    470 		UnloadBlob_UINT16(offset, &size, blob);
    471 
    472 		*offset += (size * sizeof(UINT32));
    473 
    474 		return TSS_SUCCESS;
    475 	}
    476 
    477 	UnloadBlob_UINT16(offset, &list->loaded, blob);
    478 	if (list->loaded == 0) {
    479 		list->handle = NULL;
    480 		return TSS_SUCCESS;
    481 	}
    482 
    483 	list->handle = malloc(list->loaded * sizeof (UINT32));
    484         if (list->handle == NULL) {
    485 		LogError("malloc of %zd bytes failed.", list->loaded * sizeof (UINT32));
    486 		list->loaded = 0;
    487                 return TCSERR(TSS_E_OUTOFMEMORY);
    488         }
    489 
    490 	for (i = 0; i < list->loaded; i++)
    491 		UnloadBlob_UINT32(offset, &list->handle[i], blob);
    492 
    493 	return TSS_SUCCESS;
    494 }
    495 
    496 void
    497 LoadBlob_DIGEST(UINT64 *offset, BYTE *blob, TPM_DIGEST *digest)
    498 {
    499 	LoadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, digest->digest);
    500 }
    501 
    502 void
    503 UnloadBlob_DIGEST(UINT64 *offset, BYTE *blob, TPM_DIGEST *digest)
    504 {
    505 	UnloadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, digest->digest);
    506 }
    507 
    508 void
    509 LoadBlob_NONCE(UINT64 *offset, BYTE *blob, TPM_NONCE *nonce)
    510 {
    511 	LoadBlob(offset, TCPA_NONCE_SIZE, blob, nonce->nonce);
    512 }
    513 
    514 void
    515 UnloadBlob_NONCE(UINT64 *offset, BYTE *blob, TPM_NONCE *nonce)
    516 {
    517 	UnloadBlob(offset, TCPA_NONCE_SIZE, blob, nonce->nonce);
    518 }
    519 
    520 void
    521 LoadBlob_AUTHDATA(UINT64 *offset, BYTE *blob, TPM_AUTHDATA *authdata)
    522 {
    523 	LoadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, authdata->authdata);
    524 }
    525 
    526 void
    527 UnloadBlob_AUTHDATA(UINT64 *offset, BYTE *blob, TPM_AUTHDATA *authdata)
    528 {
    529 	UnloadBlob(offset, TPM_SHA1_160_HASH_LEN, blob, authdata->authdata);
    530 }
    531 
    532