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 
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 "spi_utils.h"
20 #include "capabilities.h"
21 #include "tsplog.h"
22 #include "obj.h"
23 
24 
25 TSS_RESULT
Tspi_Hash_TickStampBlob(TSS_HHASH hHash,TSS_HKEY hIdentKey,TSS_VALIDATION * pValidationData)26 Tspi_Hash_TickStampBlob(TSS_HHASH       hHash,                        /* in */
27                               TSS_HKEY        hIdentKey,              /* in */
28                               TSS_VALIDATION* pValidationData)        /* in */
29 {
30           TSS_RESULT result;
31           TSS_HCONTEXT tspContext;
32           TCS_KEY_HANDLE tcsKey;
33           TSS_HPOLICY hPolicy;
34           TPM_DIGEST digest;
35           TSS_BOOL usesAuth;
36           TPM_AUTH auth, *pAuth;
37           UINT32 hashLen, sigLen, tcLen, signInfoLen;
38           BYTE *hash, *sig, *tc, *signInfo = NULL;
39           UINT64 offset;
40           Trspi_HashCtx hashCtx;
41 
42           if (pValidationData == NULL)
43                     return TSPERR(TSS_E_BAD_PARAMETER);
44 
45           if ((result = obj_hash_get_tsp_context(hHash, &tspContext)))
46                     return result;
47 
48           if (pValidationData->ulExternalDataLength != sizeof(TPM_NONCE))
49                     return TSPERR(TSS_E_BAD_PARAMETER);
50 
51           if ((result = obj_hash_get_value(hHash, &hashLen, &hash)))
52                     return result;
53 
54           if (hashLen != sizeof(TPM_DIGEST)) {
55                     free_tspi(tspContext, hash);
56                     return TSPERR(TSS_E_HASH_INVALID_LENGTH);
57           }
58 
59           if ((result = obj_rsakey_get_policy(hIdentKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth)))
60                     return result;
61 
62           if ((result = obj_rsakey_get_tcs_handle(hIdentKey, &tcsKey)))
63                     return result;
64 
65           if (usesAuth) {
66                     result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
67                     result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TickStampBlob);
68                     result |= Trspi_HashUpdate(&hashCtx, sizeof(TPM_NONCE),
69                                                      pValidationData->rgbExternalData);
70                     result |= Trspi_HashUpdate(&hashCtx, sizeof(TPM_DIGEST), hash);
71                     if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
72                               free_tspi(tspContext, hash);
73                               return result;
74                     }
75 
76                     if ((result = secret_PerformAuth_OIAP(hIdentKey, TPM_ORD_TickStampBlob, hPolicy,
77                                                                   FALSE, &digest, &auth))) {
78                               free_tspi(tspContext, hash);
79                               return result;
80                     }
81                     pAuth = &auth;
82           } else
83                     pAuth = NULL;
84 
85           if ((result = TCS_API(tspContext)->TickStampBlob(tspContext, tcsKey,
86                                                             (TPM_NONCE *)pValidationData->rgbExternalData,
87                                                             (TPM_DIGEST *)hash, pAuth, &sigLen, &sig, &tcLen,
88                                                             &tc))) {
89                     free_tspi(tspContext, hash);
90                     return result;
91           }
92 
93           if (usesAuth) {
94                     result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
95                     result |= Trspi_Hash_UINT32(&hashCtx, result);
96                     result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TickStampBlob);
97                     result |= Trspi_HashUpdate(&hashCtx, tcLen, tc);
98                     result |= Trspi_Hash_UINT32(&hashCtx, sigLen);
99                     result |= Trspi_HashUpdate(&hashCtx, sigLen, sig);
100                     if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
101                               free_tspi(tspContext, hash);
102                               free(sig);
103                               free(tc);
104                               return result;
105                     }
106 
107                     if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) {
108                               free_tspi(tspContext, hash);
109                               free(sig);
110                               free(tc);
111                               return result;
112                     }
113           }
114 
115           /*                 tag       fixed      replay          length(Data)                 Data        */
116           signInfoLen = sizeof(UINT16) + 4 + sizeof(TPM_NONCE) + sizeof(UINT32) + sizeof(TPM_DIGEST) + tcLen;
117           if ((signInfo = calloc_tspi(tspContext, signInfoLen)) == NULL) {
118                     free_tspi(tspContext, hash);
119                     free(sig);
120                     free(tc);
121                     return TSPERR(TSS_E_INTERNAL_ERROR);
122           }
123 
124           offset = 0;
125           Trspi_LoadBlob_UINT16(&offset, TPM_TAG_SIGNINFO, signInfo);
126           Trspi_LoadBlob_BYTE(&offset, 'T', signInfo);
127           Trspi_LoadBlob_BYTE(&offset, 'S', signInfo);
128           Trspi_LoadBlob_BYTE(&offset, 'T', signInfo);
129           Trspi_LoadBlob_BYTE(&offset, 'P', signInfo);
130           Trspi_LoadBlob(&offset, sizeof(TPM_NONCE), signInfo, pValidationData->rgbExternalData);
131           Trspi_LoadBlob_UINT32(&offset, sizeof(TPM_DIGEST) + tcLen, signInfo);
132           Trspi_LoadBlob(&offset, sizeof(TPM_DIGEST), signInfo, hash);
133           Trspi_LoadBlob(&offset, (size_t)tcLen, signInfo, tc);
134 
135           free(tc);
136           free_tspi(tspContext, hash);
137 
138           pValidationData->rgbData = signInfo;
139           pValidationData->ulDataLength = signInfoLen;
140 
141           /* tag sig so that it can be free'd by the app through Tspi_Context_FreeMemory */
142           if ((result = __tspi_add_mem_entry(tspContext, sig))) {
143                     free_tspi(tspContext, signInfo);
144                     free(sig);
145                     return result;
146           }
147 
148           pValidationData->rgbValidationData = sig;
149           pValidationData->ulValidationDataLength = sigLen;
150 
151           return TSS_SUCCESS;
152 }
153 
154 TSS_RESULT
Tspi_TPM_ReadCurrentTicks(TSS_HTPM hTPM,TPM_CURRENT_TICKS * tickCount)155 Tspi_TPM_ReadCurrentTicks(TSS_HTPM           hTPM,          /* in */
156                                 TPM_CURRENT_TICKS* tickCount)         /* out */
157 {
158           TSS_RESULT result;
159           TSS_HCONTEXT tspContext;
160           UINT32 tcLen;
161           BYTE *tc;
162           UINT64 offset;
163 
164           if (tickCount == NULL)
165                     return TSPERR(TSS_E_BAD_PARAMETER);
166 
167           if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
168                     return result;
169 
170           if ((result = TCS_API(tspContext)->ReadCurrentTicks(tspContext, &tcLen, &tc)))
171                     return result;
172 
173           offset = 0;
174           Trspi_UnloadBlob_CURRENT_TICKS(&offset, tc, tickCount);
175           free(tc);
176 
177           return result;
178 }
179