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 
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
15 
16 #include "trousers/tss.h"
17 #include "trousers/trousers.h"
18 #include "trousers_types.h"
19 #include "trousers_types.h"
20 #include "spi_utils.h"
21 #include "capabilities.h"
22 #include "tsplog.h"
23 #include "obj.h"
24 
25 
26 TSS_RESULT
Tspi_Key_CertifyKey(TSS_HKEY hKey,TSS_HKEY hCertifyingKey,TSS_VALIDATION * pValidationData)27 Tspi_Key_CertifyKey(TSS_HKEY hKey,			/* in */
28 		    TSS_HKEY hCertifyingKey,		/* in */
29 		    TSS_VALIDATION * pValidationData)	/* in, out */
30 {
31 	TCPA_RESULT result;
32 	TPM_AUTH certAuth;
33 	TPM_AUTH keyAuth;
34 	TCPA_DIGEST digest;
35 	TCPA_NONCE antiReplay;
36 	UINT32 CertifyInfoSize;
37 	BYTE *CertifyInfo;
38 	UINT32 outDataSize;
39 	BYTE *outData;
40 	TSS_HPOLICY hPolicy;
41 	TSS_HPOLICY hCertPolicy;
42 	TCS_KEY_HANDLE certifyTCSKeyHandle, keyTCSKeyHandle;
43 	TSS_BOOL useAuthCert;
44 	TSS_BOOL useAuthKey;
45 	TPM_AUTH *pCertAuth = &certAuth;
46 	TPM_AUTH *pKeyAuth = &keyAuth;
47 	TSS_HCONTEXT tspContext;
48 	Trspi_HashCtx hashCtx;
49 
50 
51 	if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext)))
52 		return result;
53 
54 	if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE,
55 					    &hPolicy, &useAuthKey)))
56 		return result;
57 
58 	if ((result = obj_rsakey_get_policy(hCertifyingKey, TSS_POLICY_USAGE,
59 					    &hCertPolicy, &useAuthCert)))
60 		return result;
61 
62 	if ((result = obj_rsakey_get_tcs_handle(hCertifyingKey, &certifyTCSKeyHandle)))
63 		return result;
64 
65 	if ((result = obj_rsakey_get_tcs_handle(hKey, &keyTCSKeyHandle)))
66 		return result;
67 
68 	if (pValidationData == NULL) {
69 		LogDebug("Internal Verify");
70 		if ((result = get_local_random(tspContext, FALSE, sizeof(TCPA_NONCE),
71 					       (BYTE **)antiReplay.nonce)))
72 			return result;
73 	} else {
74 		LogDebug("External Verify");
75 		if (pValidationData->ulExternalDataLength < sizeof(antiReplay.nonce))
76 			return TSPERR(TSS_E_BAD_PARAMETER);
77 
78 		memcpy(antiReplay.nonce, pValidationData->rgbExternalData,
79 		       sizeof(antiReplay.nonce));
80 	}
81 
82 	if (useAuthCert && !useAuthKey)
83 		return TSPERR(TSS_E_BAD_PARAMETER);
84 
85 	/* Setup the auths */
86 	if (useAuthCert || useAuthKey) {
87 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
88 		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CertifyKey);
89 		result |= Trspi_HashUpdate(&hashCtx, sizeof(antiReplay.nonce), antiReplay.nonce);
90 		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
91 			return result;
92 	}
93 
94 	if (useAuthKey) {
95 		if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_CertifyKey, hPolicy, FALSE,
96 						      &digest, &keyAuth)))
97 			return result;
98 	} else
99 		pKeyAuth = NULL;
100 
101 	if (useAuthCert) {
102 		if ((result = secret_PerformAuth_OIAP(hCertifyingKey, TPM_ORD_CertifyKey,
103 						      hCertPolicy, FALSE, &digest,
104 						      &certAuth)))
105 			return result;
106 	} else
107 		pCertAuth = NULL;
108 
109 	/* XXX free CertifyInfo */
110 	if ((result = TCS_API(tspContext)->CertifyKey(tspContext, certifyTCSKeyHandle,
111 						      keyTCSKeyHandle, &antiReplay, pCertAuth,
112 						      pKeyAuth, &CertifyInfoSize, &CertifyInfo,
113 						      &outDataSize, &outData)))
114 		return result;
115 
116 	/* Validate auth */
117 	if (useAuthCert || useAuthKey) {
118 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
119 		result |= Trspi_Hash_UINT32(&hashCtx, result);
120 		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CertifyKey);
121 		result |= Trspi_HashUpdate(&hashCtx, CertifyInfoSize, CertifyInfo);
122 		result |= Trspi_Hash_UINT32(&hashCtx, outDataSize);
123 		result |= Trspi_HashUpdate(&hashCtx, outDataSize, outData);
124 		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
125 			goto cleanup;
126 
127 		if (useAuthKey)
128 			if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &keyAuth)))
129 				goto cleanup;
130 
131 		if (useAuthCert)
132 			if ((result = obj_policy_validate_auth_oiap(hCertPolicy, &digest,
133 								    &certAuth)))
134 				goto cleanup;
135 	}
136 
137 	if (pValidationData == NULL) {
138 		if ((result = Trspi_Hash(TSS_HASH_SHA1, CertifyInfoSize, CertifyInfo,
139 					 digest.digest)))
140 			goto cleanup;
141 
142 
143 		if ((result = __tspi_rsa_verify(hCertifyingKey, TSS_HASH_SHA1, TPM_SHA1_160_HASH_LEN,
144 					 digest.digest, outDataSize, outData))){
145 			result = TSPERR(TSS_E_VERIFICATION_FAILED);
146 			goto cleanup;
147 		}
148 	} else {
149 		pValidationData->ulDataLength = CertifyInfoSize;
150 		pValidationData->rgbData = calloc_tspi(tspContext, CertifyInfoSize);
151 		if (pValidationData->rgbData == NULL) {
152 			LogError("malloc of %u bytes failed.", CertifyInfoSize);
153 			result = TSPERR(TSS_E_OUTOFMEMORY);
154 			goto cleanup;
155 		}
156 		memcpy(pValidationData->rgbData, CertifyInfo, CertifyInfoSize);
157 		pValidationData->ulValidationDataLength = outDataSize;
158 		pValidationData->rgbValidationData = calloc_tspi(tspContext, outDataSize);
159 		if (pValidationData->rgbValidationData == NULL) {
160 			LogError("malloc of %u bytes failed.", outDataSize);
161 			result = TSPERR(TSS_E_OUTOFMEMORY);
162 			goto cleanup;
163 		}
164 		memcpy(pValidationData->rgbValidationData, outData, outDataSize);
165 	}
166 
167 	result = TSS_SUCCESS;
168 
169 	cleanup:
170 	free(CertifyInfo);
171 	free(outData);
172 	return result;
173 }
174 
175