~ubuntu-branches/ubuntu/karmic/trousers/karmic

« back to all changes in this revision

Viewing changes to src/tspi/tspi_quote2.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2008-01-23 22:03:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080123220300-fhtqja3c0oq0gp6z
Tags: 0.3.1-4
* Added patch from Aaron M. Ucko <ucko@debian.org> to allow trousers to
  build successfully on amd64, and presumably also other 64-bit
  architectures (Closes: #457400).
* Including udev rule for /dev/tpm from William Lima
  <wlima.amadeus@gmail.com> as suggested by David Smith <dds@google.com>
  (Closes: #459682).
* Added lintian overrides.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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-2007
 
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
TSS_RESULT
 
25
Tspi_TPM_Quote2(TSS_HTPM        hTPM,            // in
 
26
                TSS_HKEY        hIdentKey,       // in
 
27
                TSS_BOOL        fAddVersion,     // in
 
28
                TSS_HPCRS       hPcrComposite,   // in
 
29
                TSS_VALIDATION* pValidationData, // in, out
 
30
                UINT32*         versionInfoSize, // out
 
31
                BYTE**          versionInfo)     // out
 
32
{
 
33
        TPM_RESULT result;
 
34
        TSS_HCONTEXT tspContext;
 
35
        TPM_AUTH privAuth;
 
36
        TPM_AUTH *pPrivAuth = &privAuth;
 
37
        UINT64 offset;
 
38
        TPM_DIGEST digest;
 
39
        TSS_BOOL usesAuth;
 
40
        TCS_KEY_HANDLE tcsKeyHandle;
 
41
        TSS_HPOLICY hPolicy;
 
42
        TPM_NONCE antiReplay;
 
43
        UINT32 pcrDataSize;
 
44
        BYTE pcrData[128];
 
45
        UINT32 sigSize = 0;
 
46
        BYTE *sig = NULL;
 
47
        UINT32 pcrDataOutSize;
 
48
        BYTE *pcrDataOut;
 
49
        BYTE quoteinfo[1024];
 
50
        Trspi_HashCtx hashCtx;
 
51
 
 
52
        LogDebug("Tspi_TPM_Quote2 Start:");
 
53
 
 
54
        /* Takes the context that this TPM handle is on */
 
55
        if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
 
56
                return result;
 
57
 
 
58
        /* Test if the hPcrComposite is valid */
 
59
        if ((hPcrComposite) && !obj_is_pcrs(hPcrComposite))
 
60
                return TSPERR(TSS_E_INVALID_HANDLE);
 
61
 
 
62
        /*  get the identKey Policy */
 
63
        if ((result = obj_rsakey_get_policy(hIdentKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth)))
 
64
                return result;
 
65
 
 
66
        /*  get the Identity TCS keyHandle */
 
67
        if ((result = obj_rsakey_get_tcs_handle(hIdentKey, &tcsKeyHandle)))
 
68
                return result;
 
69
 
 
70
        /* Sets the validation data - if NULL, TSS provides it's own random value. If
 
71
         * not NULL, takes the validation external data and sets the antiReplay data
 
72
         * with this */
 
73
        if (pValidationData == NULL) {
 
74
                LogDebug("Internal Verify:");
 
75
                if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE),
 
76
                                               (BYTE **)antiReplay.nonce)))
 
77
                        return result;
 
78
        } else {
 
79
                LogDebug("External Verify:");
 
80
                if (pValidationData->ulExternalDataLength < sizeof(antiReplay.nonce))
 
81
                        return TSPERR(TSS_E_BAD_PARAMETER);
 
82
 
 
83
                memcpy(antiReplay.nonce, pValidationData->rgbExternalData,
 
84
                                sizeof(antiReplay.nonce));
 
85
        }
 
86
 
 
87
        /* Create the TPM_PCR_COMPOSITE object */
 
88
        pcrDataSize = 0;
 
89
        if (hPcrComposite) {
 
90
                /* Load the PCR Selection Object into the pcrData */
 
91
                if ((result = obj_pcrs_get_selection(hPcrComposite, &pcrDataSize, pcrData)))
 
92
                        return result;
 
93
        }
 
94
 
 
95
        if (usesAuth) {
 
96
                result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
 
97
                result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Quote2);
 
98
                result |= Trspi_HashUpdate(&hashCtx, TPM_SHA1_160_HASH_LEN, antiReplay.nonce);
 
99
                result |= Trspi_HashUpdate(&hashCtx, pcrDataSize, pcrData);
 
100
                result |= Trspi_Hash_BOOL(&hashCtx,fAddVersion);
 
101
                if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
 
102
                        return result;
 
103
                if ((result = secret_PerformAuth_OIAP(hIdentKey, TPM_ORD_Quote2, hPolicy, FALSE,
 
104
                                                      &digest, &privAuth))) {
 
105
                        return result;
 
106
                }
 
107
                pPrivAuth = &privAuth;
 
108
        } else {
 
109
                pPrivAuth = NULL;
 
110
        }
 
111
 
 
112
        /* Send to TCS */
 
113
        if ((result = TCS_API(tspContext)->Quote2(tspContext, tcsKeyHandle, &antiReplay,
 
114
                                                  pcrDataSize, pcrData, fAddVersion, pPrivAuth,
 
115
                                                  &pcrDataOutSize, &pcrDataOut, versionInfoSize,
 
116
                                                  versionInfo, &sigSize, &sig)))
 
117
                return result;
 
118
 
 
119
#ifdef TSS_DEBUG
 
120
        LogDebug("Got TCS Response:");
 
121
        LogDebug("              pcrDataOutSize: %u",pcrDataOutSize);
 
122
        LogDebug("              pcrDataOut:");
 
123
        LogDebugData(pcrDataOutSize,pcrDataOut);
 
124
        LogDebug("              versionInfoSize: %u",*versionInfoSize);
 
125
        LogDebug("              versionInfo:");
 
126
        if (*versionInfoSize >0) 
 
127
                LogDebugData(*versionInfoSize,*versionInfo);
 
128
        LogDebug("              sigSize: %u",sigSize);
 
129
        LogDebug("              sig:");
 
130
        LogDebugData(sigSize,sig);
 
131
#endif
 
132
 
 
133
        if (usesAuth) {
 
134
                result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
 
135
                result |= Trspi_Hash_UINT32(&hashCtx, result);
 
136
                result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Quote2);
 
137
                result |= Trspi_HashUpdate(&hashCtx, pcrDataOutSize, pcrDataOut);
 
138
                result |= Trspi_Hash_UINT32(&hashCtx,*versionInfoSize);
 
139
                if (*versionInfoSize > 0)
 
140
                        result |= Trspi_HashUpdate(&hashCtx, *versionInfoSize,*versionInfo);
 
141
                result |= Trspi_Hash_UINT32(&hashCtx, sigSize);
 
142
                result |= Trspi_HashUpdate(&hashCtx, sigSize, sig);
 
143
                if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
 
144
                        return result;
 
145
                if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &privAuth))) {
 
146
                        free(pcrDataOut);
 
147
                        if (*versionInfoSize > 0)
 
148
                                free(*versionInfo);
 
149
                        free(sig);
 
150
                        return result;
 
151
                }
 
152
        }
 
153
 
 
154
        /* Set the pcrDataOut back to the TSS */
 
155
        if (hPcrComposite){
 
156
                TPM_PCR_INFO_SHORT pcrInfo;
 
157
 
 
158
                offset = 0;
 
159
                if ((result = Trspi_UnloadBlob_PCR_INFO_SHORT(&offset, pcrDataOut, &pcrInfo))) {
 
160
                        free(pcrDataOut);
 
161
                        if (*versionInfoSize > 0)
 
162
                                free(*versionInfo);
 
163
                        free(sig);
 
164
                        return result;
 
165
                }
 
166
 
 
167
                /* Set both digestAtRelease and localityAtRelease */
 
168
                if ((result = obj_pcrs_set_locality(hPcrComposite, pcrInfo.localityAtRelease))) {
 
169
                        free(pcrDataOut);
 
170
                        if (*versionInfoSize > 0)
 
171
                                free(*versionInfo);
 
172
                        free(sig);
 
173
                        return result;
 
174
                }
 
175
 
 
176
                if ((result = obj_pcrs_set_digest_at_release(hPcrComposite,
 
177
                                                             pcrInfo.digestAtRelease))) {
 
178
                        free(pcrDataOut);
 
179
                        if (*versionInfoSize > 0)
 
180
                                free(*versionInfo);
 
181
                        free(sig);
 
182
                        return result;
 
183
                }
 
184
        }
 
185
 
 
186
        /* generate TPM_QUOTE_INFO2 struct */
 
187
        memset(&quoteinfo, 0, sizeof(quoteinfo));
 
188
        offset = 0;
 
189
        /* 1. Add Structure TAG */
 
190
        quoteinfo[offset++] = 0x00;
 
191
        quoteinfo[offset++] = (BYTE) TPM_TAG_QUOTE_INFO2;
 
192
 
 
193
        /* 2. add "QUT2" */
 
194
        quoteinfo[offset++]='Q';
 
195
        quoteinfo[offset++]='U';
 
196
        quoteinfo[offset++]='T';
 
197
        quoteinfo[offset++]='2';
 
198
 
 
199
        /* 3. AntiReplay Nonce - add the external data*/
 
200
        Trspi_LoadBlob(&offset, TCPA_SHA1_160_HASH_LEN, quoteinfo,
 
201
                        antiReplay.nonce);
 
202
        /* 4. add the infoshort TPM_PCR_INFO_SHORT data */
 
203
        Trspi_LoadBlob(&offset,pcrDataOutSize,quoteinfo,pcrDataOut);
 
204
 
 
205
        if (fAddVersion)
 
206
                Trspi_LoadBlob(&offset,*versionInfoSize,quoteinfo,*versionInfo);
 
207
        else {
 
208
                /* versionInfo was not allocated and versionInfoSize has invalid value */
 
209
                *versionInfoSize = 0;
 
210
                *versionInfo = NULL;
 
211
        }
 
212
 
 
213
        LogDebug("TPM_QUOTE_INFO2 data: ");
 
214
        LogDebugData(offset,quoteinfo);
 
215
 
 
216
        if (pValidationData == NULL) {
 
217
                if ((result = Trspi_Hash(TSS_HASH_SHA1, offset, quoteinfo, digest.digest)))
 
218
                        return result;
 
219
                if ((result = rsa_verify(hIdentKey,TSS_HASH_SHA1,sizeof(digest.digest),
 
220
                                         digest.digest, sigSize, sig))) {
 
221
                        free(sig);
 
222
                        if (*versionInfoSize > 0)
 
223
                                free(*versionInfo);
 
224
                        return TSPERR(TSS_E_VERIFICATION_FAILED);
 
225
                }
 
226
        } else {
 
227
                pValidationData->rgbValidationData = calloc_tspi(tspContext, sigSize);
 
228
                if (pValidationData->rgbValidationData == NULL) {
 
229
                        LogError("malloc of %u bytes failed.", sigSize);
 
230
                        if (*versionInfoSize > 0)
 
231
                                free(*versionInfo);
 
232
                        return TSPERR(TSS_E_OUTOFMEMORY);
 
233
                }
 
234
                pValidationData->ulValidationDataLength = sigSize;
 
235
                memcpy(pValidationData->rgbValidationData, sig, sigSize);
 
236
                free(sig);
 
237
 
 
238
                pValidationData->rgbData = calloc_tspi(tspContext, offset);
 
239
                if (pValidationData->rgbData == NULL) {
 
240
                        LogError("malloc of %" PRIu64 " bytes failed.", offset);
 
241
                        free_tspi(tspContext, pValidationData->rgbValidationData);
 
242
                        pValidationData->rgbValidationData = NULL;
 
243
                        pValidationData->ulValidationDataLength = 0;
 
244
                        if (*versionInfoSize > 0)
 
245
                                free(*versionInfo);
 
246
                        return TSPERR(TSS_E_OUTOFMEMORY);
 
247
                }
 
248
                pValidationData->ulDataLength = (UINT32)offset;
 
249
                memcpy(pValidationData->rgbData, quoteinfo, offset);
 
250
        }
 
251
 
 
252
        LogDebug("Tspi_TPM_Quote2 End");
 
253
        return TSS_SUCCESS;
 
254
}