Home | History | Annotate | Line # | Download | only in tspi
      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 <string.h>
     14 #include <inttypes.h>
     15 
     16 #include "trousers/tss.h"
     17 #include "trousers/trousers.h"
     18 #include "trousers_types.h"
     19 #include "spi_utils.h"
     20 #include "capabilities.h"
     21 #include "tsplog.h"
     22 #include "obj.h"
     23 
     24 
     25 TSS_RESULT
     26 Tspi_TPM_TakeOwnership(TSS_HTPM hTPM,			/* in */
     27 		       TSS_HKEY hKeySRK,		/* in */
     28 		       TSS_HKEY hEndorsementPubKey)	/* in */
     29 {
     30 	TPM_AUTH privAuth;
     31 	BYTE encOwnerAuth[256];
     32 	UINT32 encOwnerAuthLength;
     33 	BYTE encSRKAuth[256];
     34 	UINT32 encSRKAuthLength;
     35 	TCPA_DIGEST digest;
     36 	TSS_RESULT result;
     37 	TSS_HCONTEXT tspContext;
     38 	UINT32 srkKeyBlobLength;
     39 	BYTE *srkKeyBlob;
     40 	TSS_HPOLICY hOwnerPolicy;
     41 	UINT32 newSrkBlobSize;
     42 	BYTE *newSrkBlob = NULL;
     43 	BYTE oldAuthDataUsage;
     44 	TSS_HKEY hPubEK;
     45 	Trspi_HashCtx hashCtx;
     46 
     47 
     48 	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
     49 		return result;
     50 
     51 	if (hEndorsementPubKey == NULL_HKEY) {
     52 		if ((result = Tspi_TPM_GetPubEndorsementKey(hTPM, FALSE, NULL, &hPubEK))) {
     53 			return result;
     54 		}
     55 	} else {
     56 		hPubEK = hEndorsementPubKey;
     57 	}
     58 
     59 	/* Get the srkKeyData */
     60 	if ((result = obj_rsakey_get_blob(hKeySRK, &srkKeyBlobLength, &srkKeyBlob)))
     61 		return result;
     62 
     63 	/* Need to check for Atmel bug where authDataUsage is changed */
     64 	oldAuthDataUsage = srkKeyBlob[10];
     65 	LogDebug("oldAuthDataUsage is %.2X.  Wait to see if it changes", oldAuthDataUsage);
     66 
     67 	/* Now call the module that will encrypt the secrets.  This
     68 	 * will either get the secrets from the policy objects or
     69 	 * use the callback function to encrypt the secrets */
     70 
     71 	if ((result = secret_TakeOwnership(hPubEK, hTPM, hKeySRK, &privAuth, &encOwnerAuthLength,
     72 					   encOwnerAuth, &encSRKAuthLength, encSRKAuth)))
     73 		return result;
     74 
     75 	/* Now, take ownership is ready to call.  The auth structure should be complete
     76 	 * and the encrypted data structures should be ready */
     77 	if ((result = RPC_TakeOwnership(tspContext, TPM_PID_OWNER, encOwnerAuthLength, encOwnerAuth,
     78 					encSRKAuthLength, encSRKAuth, srkKeyBlobLength, srkKeyBlob,
     79 					&privAuth, &newSrkBlobSize, &newSrkBlob)))
     80 		return result;
     81 
     82 	/* The final step is to validate the return Auth */
     83 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
     84 	result |= Trspi_Hash_UINT32(&hashCtx, result);
     85 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TakeOwnership);
     86 	result |= Trspi_HashUpdate(&hashCtx, newSrkBlobSize, newSrkBlob);
     87 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
     88 		return result;
     89 
     90 	if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy))) {
     91 		free(newSrkBlob);
     92 		return result;
     93 	}
     94 	if ((result = obj_policy_validate_auth_oiap(hOwnerPolicy, &digest, &privAuth))) {
     95 		free(newSrkBlob);
     96 		return result;
     97 	}
     98 
     99 	/* Now that it's all happy, stuff the keyBlob into the object
    100 	 * If atmel, need to adjust the authDataUsage if it changed */
    101 	if (oldAuthDataUsage != newSrkBlob[10]) {	/* hardcoded blob stuff */
    102 		LogDebug("auth data usage changed. Atmel bug. Fixing in key object");
    103 		newSrkBlob[10] = oldAuthDataUsage;	/* this will fix it  */
    104 	}
    105 
    106 	result = obj_rsakey_set_tcpakey(hKeySRK, newSrkBlobSize, newSrkBlob);
    107 	free(newSrkBlob);
    108 
    109 	if (result)
    110 		return result;
    111 
    112 	/* The SRK is loaded at this point, so insert it into the key handle list */
    113 	return obj_rsakey_set_tcs_handle(hKeySRK, TPM_KEYHND_SRK);
    114 }
    115 
    116 TSS_RESULT
    117 Tspi_TPM_ClearOwner(TSS_HTPM hTPM,		/* in */
    118 		    TSS_BOOL fForcedClear)	/* in */
    119 {
    120 	TCPA_RESULT result;
    121 	TPM_AUTH auth;
    122 	TSS_HCONTEXT tspContext;
    123 	TCPA_DIGEST hashDigest;
    124 	TSS_HPOLICY hPolicy;
    125 	Trspi_HashCtx hashCtx;
    126 
    127 	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
    128 		return result;
    129 
    130 	if (!fForcedClear) {	/*  TPM_OwnerClear */
    131 		if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy)))
    132 			return result;
    133 
    134 		/* Now do some Hash'ing */
    135 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
    136 		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerClear);
    137 		if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
    138 			return result;
    139 
    140 		/* hashDigest now has the hash result */
    141 		if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerClear, hPolicy, FALSE,
    142 						      &hashDigest, &auth)))
    143 			return result;
    144 
    145 		if ((result = TCS_API(tspContext)->OwnerClear(tspContext, &auth)))
    146 			return result;
    147 
    148 		/* validate auth */
    149 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
    150 		result |= Trspi_Hash_UINT32(&hashCtx, result);
    151 		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerClear);
    152 		if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
    153 			return result;
    154 
    155 		if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth)))
    156 			return result;
    157 	} else {
    158 		if ((result = TCS_API(tspContext)->ForceClear(tspContext)))
    159 			return result;
    160 	}
    161 
    162 	return TSS_SUCCESS;
    163 }
    164