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
26TSS_RESULT
27Tspi_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