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
25TSS_RESULT
26obj_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
54TSS_BOOL
55obj_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
67TSS_RESULT
68obj_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
82TSS_RESULT
83obj_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
110done:
111	obj_list_put(&hash_list);
112
113	return result;
114}
115
116TSS_RESULT
117obj_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
141done:
142	obj_list_put(&hash_list);
143
144	return result;
145}
146
147TSS_RESULT
148obj_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
198done:
199	obj_list_put(&hash_list);
200
201	return result;
202}
203
204void
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 */
217TSS_RESULT
218obj_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