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
25TSS_RESULT
26Tspi_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
116TSS_RESULT
117Tspi_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