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 "spi_utils.h"
20 #include "capabilities.h"
21 #include "tsplog.h"
22 #include "obj.h"
23 
24 
25 TSS_RESULT
Tspi_Data_Bind(TSS_HENCDATA hEncData,TSS_HKEY hEncKey,UINT32 ulDataLength,BYTE * rgbDataToBind)26 Tspi_Data_Bind(TSS_HENCDATA hEncData,   /* in */
27                  TSS_HKEY hEncKey,      /* in */
28                  UINT32 ulDataLength,   /* in */
29                  BYTE *rgbDataToBind)   /* in */
30 {
31           UINT32 encDataLength;
32           BYTE encData[256];
33           BYTE *keyData;
34           UINT32 keyDataLength;
35           TCPA_BOUND_DATA boundData;
36           UINT64 offset;
37           BYTE bdblob[256];
38           TCPA_RESULT result;
39           TSS_KEY keyContainer;
40           TSS_HCONTEXT tspContext;
41 
42           if (rgbDataToBind == NULL)
43                     return TSPERR(TSS_E_BAD_PARAMETER);
44 
45           if (!obj_is_encdata(hEncData))
46                     return TSPERR(TSS_E_INVALID_HANDLE);
47 
48           if ((result = obj_rsakey_get_tsp_context(hEncKey, &tspContext)))
49                     return result;
50 
51           /* XXX Just get the pubkey here */
52           if ((result = obj_rsakey_get_blob(hEncKey, &keyDataLength, &keyData)))
53                     return result;
54 
55           offset = 0;
56           if ((result = UnloadBlob_TSS_KEY(&offset, keyData, &keyContainer))) {
57                     free_tspi(tspContext, keyData);
58                     return result;
59           }
60           free_tspi(tspContext, keyData);
61 
62           if (keyContainer.keyUsage != TPM_KEY_BIND &&
63               keyContainer.keyUsage != TPM_KEY_LEGACY) {
64                     result = TSPERR(TSS_E_INVALID_KEYUSAGE);
65                     goto done;
66           }
67 
68           if (keyContainer.pubKey.keyLength < ulDataLength) {
69                     result = TSPERR(TSS_E_ENC_INVALID_LENGTH);
70                     goto done;
71           }
72 
73           if (keyContainer.algorithmParms.encScheme == TCPA_ES_RSAESPKCSv15 &&
74               keyContainer.keyUsage == TPM_KEY_LEGACY) {
75                     if ((result = Trspi_RSA_PKCS15_Encrypt(rgbDataToBind, ulDataLength, encData,
76                                                                    &encDataLength, keyContainer.pubKey.key,
77                                                                    keyContainer.pubKey.keyLength)))
78                               goto done;
79           } else if (keyContainer.algorithmParms.encScheme == TCPA_ES_RSAESPKCSv15 &&
80                        keyContainer.keyUsage == TPM_KEY_BIND) {
81                     boundData.payload = TCPA_PT_BIND;
82 
83                     memcpy(&boundData.ver, &VERSION_1_1, sizeof(TCPA_VERSION));
84 
85                     boundData.payloadData = malloc(ulDataLength);
86                     if (boundData.payloadData == NULL) {
87                               result = TSPERR(TSS_E_OUTOFMEMORY);
88                               goto done;
89                     }
90                     memcpy(boundData.payloadData, rgbDataToBind, ulDataLength);
91 
92                     offset = 0;
93                     Trspi_LoadBlob_BOUND_DATA(&offset, boundData, ulDataLength, bdblob);
94 
95                     if ((result = Trspi_RSA_PKCS15_Encrypt(bdblob, offset, encData,
96                                                                    &encDataLength, keyContainer.pubKey.key,
97                                                                    keyContainer.pubKey.keyLength))) {
98                               free(boundData.payloadData);
99                               goto done;
100                     }
101                     free(boundData.payloadData);
102           } else {
103                     boundData.payload = TCPA_PT_BIND;
104 
105                     memcpy(&boundData.ver, &VERSION_1_1, sizeof(TCPA_VERSION));
106 
107                     boundData.payloadData = malloc(ulDataLength);
108                     if (boundData.payloadData == NULL) {
109                               LogError("malloc of %u bytes failed.", ulDataLength);
110                               result = TSPERR(TSS_E_OUTOFMEMORY);
111                               goto done;
112                     }
113                     memcpy(boundData.payloadData, rgbDataToBind, ulDataLength);
114 
115                     offset = 0;
116                     Trspi_LoadBlob_BOUND_DATA(&offset, boundData, ulDataLength, bdblob);
117 
118                     if ((result = Trspi_RSA_Encrypt(bdblob, offset, encData, &encDataLength,
119                                                             keyContainer.pubKey.key,
120                                                             keyContainer.pubKey.keyLength))) {
121                               free(boundData.payloadData);
122                               goto done;
123                     }
124 
125                     free(boundData.payloadData);
126           }
127 
128           if ((result = obj_encdata_set_data(hEncData, encDataLength, encData))) {
129                     LogError("Error in calling SetAttribData on the encrypted data object.");
130                     result = TSPERR(TSS_E_INTERNAL_ERROR);
131                     goto done;
132           }
133 done:
134           free_key_refs(&keyContainer);
135           return result;
136 }
137 
138 TSS_RESULT
Tspi_Data_Unbind(TSS_HENCDATA hEncData,TSS_HKEY hKey,UINT32 * pulUnboundDataLength,BYTE ** prgbUnboundData)139 Tspi_Data_Unbind(TSS_HENCDATA hEncData,           /* in */
140                      TSS_HKEY hKey,                         /* in */
141                      UINT32 * pulUnboundDataLength,         /* out */
142                      BYTE ** prgbUnboundData)     /* out */
143 {
144           TCPA_RESULT result;
145           TPM_AUTH privAuth;
146           TCPA_DIGEST digest;
147           TSS_HPOLICY hPolicy;
148           BYTE *encData;
149           UINT32 encDataSize;
150           TCS_KEY_HANDLE tcsKeyHandle;
151           TSS_BOOL usesAuth;
152           TPM_AUTH *pPrivAuth;
153         TSS_HCONTEXT tspContext;
154           Trspi_HashCtx hashCtx;
155 
156           if (pulUnboundDataLength == NULL || prgbUnboundData == NULL)
157                     return TSPERR(TSS_E_BAD_PARAMETER);
158 
159           if ((result = obj_encdata_get_tsp_context(hEncData, &tspContext)))
160                     return result;
161 
162           if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth)))
163                     return result;
164 
165           if ((result = obj_encdata_get_data(hEncData, &encDataSize, &encData)))
166                     return result == (TSS_E_INVALID_OBJ_ACCESS | TSS_LAYER_TSP) ?
167                            TSPERR(TSS_E_ENC_NO_DATA) :
168                            result;
169 
170           if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle)))
171                     return result;
172 
173           if (usesAuth) {
174                     result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
175                     result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_UnBind);
176                     result |= Trspi_Hash_UINT32(&hashCtx, encDataSize);
177                     result |= Trspi_HashUpdate(&hashCtx, encDataSize, encData);
178                     if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
179                               return result;
180 
181                     if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_UnBind, hPolicy, FALSE, &digest,
182                                                                   &privAuth)))
183                               return result;
184                     pPrivAuth = &privAuth;
185           } else {
186                     pPrivAuth = NULL;
187           }
188 
189           if ((result = TCS_API(tspContext)->UnBind(tspContext, tcsKeyHandle, encDataSize, encData,
190                                                               pPrivAuth, pulUnboundDataLength,
191                                                               prgbUnboundData)))
192                     return result;
193 
194           if (usesAuth) {
195                     result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
196                     result |= Trspi_Hash_UINT32(&hashCtx, result);
197                     result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_UnBind);
198                     result |= Trspi_Hash_UINT32(&hashCtx, *pulUnboundDataLength);
199                     result |= Trspi_HashUpdate(&hashCtx, *pulUnboundDataLength, *prgbUnboundData);
200                     if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
201                               goto error;
202 
203                     if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &privAuth)))
204                               goto error;
205           }
206 
207           if ((result = __tspi_add_mem_entry(tspContext, *prgbUnboundData)))
208                     goto error;
209 
210           return TSS_SUCCESS;
211 error:
212           free(*prgbUnboundData);
213           *prgbUnboundData = NULL;
214           *pulUnboundDataLength = 0;
215           return result;
216 }
217 
218