summaryrefslogtreecommitdiff
path: root/src/tspi/tspi_own.c
blob: ef6a44c802583859de06b42f504425f9aa74c063 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163

/*
 * Licensed Materials - Property of IBM
 *
 * trousers - An open source TCG Software Stack
 *
 * (C) Copyright International Business Machines Corp. 2004-2006
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "trousers/tss.h"
#include "trousers/trousers.h"
#include "trousers_types.h"
#include "spi_utils.h"
#include "capabilities.h"
#include "tsplog.h"
#include "obj.h"


TSS_RESULT
Tspi_TPM_TakeOwnership(TSS_HTPM hTPM,			/* in */
		       TSS_HKEY hKeySRK,		/* in */
		       TSS_HKEY hEndorsementPubKey)	/* in */
{
	TPM_AUTH privAuth;
	BYTE encOwnerAuth[256];
	UINT32 encOwnerAuthLength;
	BYTE encSRKAuth[256];
	UINT32 encSRKAuthLength;
	TCPA_DIGEST digest;
	TSS_RESULT result;
	TSS_HCONTEXT tspContext;
	UINT32 srkKeyBlobLength;
	BYTE *srkKeyBlob;
	TSS_HPOLICY hOwnerPolicy;
	UINT32 newSrkBlobSize;
	BYTE *newSrkBlob = NULL;
	BYTE oldAuthDataUsage;
	TSS_HKEY hPubEK;
	Trspi_HashCtx hashCtx;


	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
		return result;

	if (hEndorsementPubKey == NULL_HKEY) {
		if ((result = Tspi_TPM_GetPubEndorsementKey(hTPM, FALSE, NULL, &hPubEK))) {
			return result;
		}
	} else {
		hPubEK = hEndorsementPubKey;
	}

	/* Get the srkKeyData */
	if ((result = obj_rsakey_get_blob(hKeySRK, &srkKeyBlobLength, &srkKeyBlob)))
		return result;

	/* Need to check for Atmel bug where authDataUsage is changed */
	oldAuthDataUsage = srkKeyBlob[10];
	LogDebug("oldAuthDataUsage is %.2X.  Wait to see if it changes", oldAuthDataUsage);

	/* Now call the module that will encrypt the secrets.  This
	 * will either get the secrets from the policy objects or
	 * use the callback function to encrypt the secrets */

	if ((result = secret_TakeOwnership(hPubEK, hTPM, hKeySRK, &privAuth, &encOwnerAuthLength,
					   encOwnerAuth, &encSRKAuthLength, encSRKAuth)))
		return result;

	/* Now, take ownership is ready to call.  The auth structure should be complete
	 * and the encrypted data structures should be ready */
	if ((result = RPC_TakeOwnership(tspContext, TPM_PID_OWNER, encOwnerAuthLength, encOwnerAuth,
					encSRKAuthLength, encSRKAuth, srkKeyBlobLength, srkKeyBlob,
					&privAuth, &newSrkBlobSize, &newSrkBlob)))
		return result;

	/* The final step is to validate the return Auth */
	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
	result |= Trspi_Hash_UINT32(&hashCtx, result);
	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TakeOwnership);
	result |= Trspi_HashUpdate(&hashCtx, newSrkBlobSize, newSrkBlob);
	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
		return result;

	if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy))) {
		free(newSrkBlob);
		return result;
	}
	if ((result = obj_policy_validate_auth_oiap(hOwnerPolicy, &digest, &privAuth))) {
		free(newSrkBlob);
		return result;
	}

	/* Now that it's all happy, stuff the keyBlob into the object
	 * If atmel, need to adjust the authDataUsage if it changed */
	if (oldAuthDataUsage != newSrkBlob[10]) {	/* hardcoded blob stuff */
		LogDebug("auth data usage changed. Atmel bug. Fixing in key object");
		newSrkBlob[10] = oldAuthDataUsage;	/* this will fix it  */
	}

	result = obj_rsakey_set_tcpakey(hKeySRK, newSrkBlobSize, newSrkBlob);
	free(newSrkBlob);

	if (result)
		return result;

	/* The SRK is loaded at this point, so insert it into the key handle list */
	return obj_rsakey_set_tcs_handle(hKeySRK, TPM_KEYHND_SRK);
}

TSS_RESULT
Tspi_TPM_ClearOwner(TSS_HTPM hTPM,		/* in */
		    TSS_BOOL fForcedClear)	/* in */
{
	TCPA_RESULT result;
	TPM_AUTH auth;
	TSS_HCONTEXT tspContext;
	TCPA_DIGEST hashDigest;
	TSS_HPOLICY hPolicy;
	Trspi_HashCtx hashCtx;

	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
		return result;

	if (!fForcedClear) {	/*  TPM_OwnerClear */
		if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy)))
			return result;

		/* Now do some Hash'ing */
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerClear);
		if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
			return result;

		/* hashDigest now has the hash result */
		if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerClear, hPolicy, FALSE,
						      &hashDigest, &auth)))
			return result;

		if ((result = TCS_API(tspContext)->OwnerClear(tspContext, &auth)))
			return result;

		/* validate auth */
		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
		result |= Trspi_Hash_UINT32(&hashCtx, result);
		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerClear);
		if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest)))
			return result;

		if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth)))
			return result;
	} else {
		if ((result = TCS_API(tspContext)->ForceClear(tspContext)))
			return result;
	}

	return TSS_SUCCESS;
}