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. 2005, 2007
8  *
9  */
10 
11 
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <errno.h>
15 #include <string.h>
16 
17 #include "trousers/tss.h"
18 #include "trousers/trousers.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 TSS_RESULT
obj_hash_add(TSS_HCONTEXT tspContext,UINT32 type,TSS_HOBJECT * phObject)26 obj_hash_add(TSS_HCONTEXT tspContext, UINT32 type, TSS_HOBJECT *phObject)
27 {
28           TSS_RESULT result;
29           struct tr_hash_obj *hash = calloc(1, sizeof(struct tr_hash_obj));
30 
31           if (hash == NULL) {
32                     LogError("malloc of %zd bytes failed.",
33                                         sizeof(struct tr_hash_obj));
34                     return TSPERR(TSS_E_OUTOFMEMORY);
35           }
36 
37           if ((type == TSS_HASH_SHA1) ||
38               (type == TSS_HASH_DEFAULT)) {
39                     hash->type = TSS_HASH_SHA1;
40                     hash->hashSize = 20;
41           } else if (type == TSS_HASH_OTHER) {
42                     hash->type = TSS_HASH_OTHER;
43                     hash->hashSize = 0;
44           }
45 
46           if ((result = obj_list_add(&hash_list, tspContext, 0, hash, phObject))) {
47                     free(hash);
48                     return result;
49           }
50 
51           return TSS_SUCCESS;
52 }
53 
54 TSS_BOOL
obj_is_hash(TSS_HOBJECT hObject)55 obj_is_hash(TSS_HOBJECT hObject)
56 {
57           TSS_BOOL answer = FALSE;
58 
59           if ((obj_list_get_obj(&hash_list, hObject))) {
60                     answer = TRUE;
61                     obj_list_put(&hash_list);
62           }
63 
64           return answer;
65 }
66 
67 TSS_RESULT
obj_hash_get_tsp_context(TSS_HHASH hHash,TSS_HCONTEXT * tspContext)68 obj_hash_get_tsp_context(TSS_HHASH hHash, TSS_HCONTEXT *tspContext)
69 {
70           struct tsp_object *obj;
71 
72           if ((obj = obj_list_get_obj(&hash_list, hHash)) == NULL)
73                     return TSPERR(TSS_E_INVALID_HANDLE);
74 
75           *tspContext = obj->tspContext;
76 
77           obj_list_put(&hash_list);
78 
79           return TSS_SUCCESS;
80 }
81 
82 TSS_RESULT
obj_hash_set_value(TSS_HHASH hHash,UINT32 size,BYTE * value)83 obj_hash_set_value(TSS_HHASH hHash, UINT32 size, BYTE *value)
84 {
85           struct tsp_object *obj;
86           struct tr_hash_obj *hash;
87           TSS_RESULT result = TSS_SUCCESS;
88 
89           if ((obj = obj_list_get_obj(&hash_list, hHash)) == NULL)
90                     return TSPERR(TSS_E_INVALID_HANDLE);
91 
92           hash = (struct tr_hash_obj *)obj->data;
93 
94           if (hash->type != TSS_HASH_OTHER &&
95               size != TCPA_SHA1_160_HASH_LEN) {
96                     result = TSPERR(TSS_E_HASH_INVALID_LENGTH);
97                     goto done;
98           }
99 
100           free(hash->hashData);
101 
102           if ((hash->hashData = calloc(1, size)) == NULL) {
103                     LogError("malloc of %d bytes failed.", size);
104                     result = TSPERR(TSS_E_OUTOFMEMORY);
105                     goto done;
106           }
107           hash->hashSize = size;
108           memcpy(hash->hashData, value, size);
109 
110 done:
111           obj_list_put(&hash_list);
112 
113           return result;
114 }
115 
116 TSS_RESULT
obj_hash_get_value(TSS_HHASH hHash,UINT32 * size,BYTE ** value)117 obj_hash_get_value(TSS_HHASH hHash, UINT32 *size, BYTE **value)
118 {
119           struct tsp_object *obj;
120           struct tr_hash_obj *hash;
121           TSS_RESULT result = TSS_SUCCESS;
122 
123           if ((obj = obj_list_get_obj(&hash_list, hHash)) == NULL)
124                     return TSPERR(TSS_E_INVALID_HANDLE);
125 
126           hash = (struct tr_hash_obj *)obj->data;
127 
128           if (hash->hashData == NULL) {
129                     result = TSPERR(TSS_E_HASH_NO_DATA);
130                     goto done;
131           }
132 
133           if ((*value = calloc_tspi(obj->tspContext, hash->hashSize)) == NULL) {
134                     LogError("malloc of %d bytes failed.", hash->hashSize);
135                     result = TSPERR(TSS_E_OUTOFMEMORY);
136                     goto done;
137           }
138           *size = hash->hashSize;
139           memcpy(*value, hash->hashData, *size);
140 
141 done:
142           obj_list_put(&hash_list);
143 
144           return result;
145 }
146 
147 TSS_RESULT
obj_hash_update_value(TSS_HHASH hHash,UINT32 size,BYTE * data)148 obj_hash_update_value(TSS_HHASH hHash, UINT32 size, BYTE *data)
149 {
150           struct tsp_object *obj;
151           struct tr_hash_obj *hash;
152           TSS_RESULT result = TSS_SUCCESS;
153 
154           if ((obj = obj_list_get_obj(&hash_list, hHash)) == NULL)
155                     return TSPERR(TSS_E_INVALID_HANDLE);
156 
157           hash = (struct tr_hash_obj *)obj->data;
158 
159           if (hash->type != TSS_HASH_SHA1 &&
160               hash->type != TSS_HASH_DEFAULT) {
161                     result = TSPERR(TSS_E_FAIL);
162                     goto done;
163           }
164 
165           if (hash->hashUpdateBuffer == NULL) {
166                     hash->hashUpdateBuffer = calloc(1, size);
167                     if (hash->hashUpdateBuffer == NULL) {
168                               LogError("malloc of %u bytes failed.", size);
169                               result = TSPERR(TSS_E_OUTOFMEMORY);
170                               goto done;
171                     }
172           } else {
173                     hash->hashUpdateBuffer = realloc(hash->hashUpdateBuffer,
174                                         size + hash->hashUpdateSize);
175 
176                     if (hash->hashUpdateBuffer == NULL) {
177                               LogError("malloc of %u bytes failed.", size + hash->hashUpdateSize);
178                               result = TSPERR(TSS_E_OUTOFMEMORY);
179                               goto done;
180                     }
181           }
182 
183           memcpy(&hash->hashUpdateBuffer[hash->hashUpdateSize], data, size);
184           hash->hashUpdateSize += size;
185 
186           if (hash->hashData == NULL) {
187                     hash->hashData = calloc(1, TCPA_SHA1_160_HASH_LEN);
188                     if (hash->hashData == NULL) {
189                               LogError("malloc of %d bytes failed.", TCPA_SHA1_160_HASH_LEN);
190                               result = TSPERR(TSS_E_OUTOFMEMORY);
191                               goto done;
192                     }
193           }
194 
195           result = Trspi_Hash(TSS_HASH_SHA1, hash->hashUpdateSize, hash->hashUpdateBuffer,
196                                   hash->hashData);
197 
198 done:
199           obj_list_put(&hash_list);
200 
201           return result;
202 }
203 
204 void
__tspi_hash_free(void * data)205 __tspi_hash_free(void *data)
206 {
207           struct tr_hash_obj *hash = (struct tr_hash_obj *)data;
208 
209           free(hash->hashData);
210           free(hash->hashUpdateBuffer);
211           free(hash);
212 }
213 
214 /*
215  * remove hash object hObject from the list
216  */
217 TSS_RESULT
obj_hash_remove(TSS_HOBJECT hObject,TSS_HCONTEXT tspContext)218 obj_hash_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext)
219 {
220           TSS_RESULT result;
221 
222           if ((result = obj_list_remove(&hash_list, &__tspi_hash_free, hObject, tspContext)))
223                     return result;
224 
225           return TSS_SUCCESS;
226 }
227 
228