xref: /netbsd-src/crypto/external/cpl/trousers/dist/src/tcs/tcs_key_ps.c (revision 2d5f7628c5531eb583b9313ac2fd1cf8582b4479)
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 #include <unistd.h>
16 #include <errno.h>
17 
18 #include "trousers/tss.h"
19 #include "trousers_types.h"
20 #include "trousers_types.h"
21 #include "tcs_tsp.h"
22 #include "tcs_utils.h"
23 #include "tcs_int_literals.h"
24 #include "capabilities.h"
25 #include "tcslog.h"
26 #include "tcsps.h"
27 #include "req_mgr.h"
28 
29 
30 TSS_RESULT
ps_init_disk_cache(void)31 ps_init_disk_cache(void)
32 {
33 	int fd;
34 	TSS_RESULT rc;
35 
36 	MUTEX_INIT(disk_cache_lock);
37 
38 	if ((fd = get_file()) < 0)
39 		return TCSERR(TSS_E_INTERNAL_ERROR);
40 
41 	if ((rc = init_disk_cache(fd)))
42 		return rc;
43 
44 	/* this is temporary, to clear out a PS file from trousers
45 	 * versions before 0.2.1 */
46 	if ((rc = clean_disk_cache(fd)))
47 		return rc;
48 
49 	put_file(fd);
50 	return TSS_SUCCESS;
51 }
52 
53 void
ps_close_disk_cache(void)54 ps_close_disk_cache(void)
55 {
56 	int fd;
57 
58 	if ((fd = get_file()) < 0) {
59 		LogError("get_file() failed while trying to close disk cache.");
60 		return;
61 	}
62 
63 	close_disk_cache(fd);
64 
65 	put_file(fd);
66 }
67 
68 TSS_BOOL
ps_is_key_registered(TCPA_STORE_PUBKEY * pub)69 ps_is_key_registered(TCPA_STORE_PUBKEY *pub)
70 {
71 	TSS_UUID *uuid;
72 	int fd;
73 	TSS_RESULT rc;
74 	TSS_BOOL is_reg = FALSE;
75 
76 	if ((fd = get_file()) < 0)
77 		return FALSE;
78 
79 	if ((rc = psfile_get_uuid_by_pub(fd, pub, &uuid))) {
80 		put_file(fd);
81 		return FALSE;
82 	}
83 
84 	put_file(fd);
85 
86 	if ((isUUIDRegistered(uuid, &is_reg)))
87 		is_reg = FALSE;
88 
89 	free(uuid);
90 	return is_reg;
91 }
92 
93 TSS_RESULT
getParentUUIDByUUID(TSS_UUID * uuid,TSS_UUID * ret_uuid)94 getParentUUIDByUUID(TSS_UUID *uuid, TSS_UUID *ret_uuid)
95 {
96 	struct key_disk_cache *disk_tmp;
97 
98 	/* check the registered key disk cache */
99 	MUTEX_LOCK(disk_cache_lock);
100 
101 	for (disk_tmp = key_disk_cache_head; disk_tmp; disk_tmp = disk_tmp->next) {
102 		if ((disk_tmp->flags & CACHE_FLAG_VALID) &&
103 		    !memcmp(&disk_tmp->uuid, uuid, sizeof(TSS_UUID))) {
104 			memcpy(ret_uuid, &disk_tmp->parent_uuid, sizeof(TSS_UUID));
105 			MUTEX_UNLOCK(disk_cache_lock);
106 			return TSS_SUCCESS;
107 		}
108 	}
109 	MUTEX_UNLOCK(disk_cache_lock);
110 
111 	return TCSERR(TSS_E_FAIL);
112 }
113 
114 TSS_RESULT
isUUIDRegistered(TSS_UUID * uuid,TSS_BOOL * is_reg)115 isUUIDRegistered(TSS_UUID *uuid, TSS_BOOL *is_reg)
116 {
117 	struct key_disk_cache *disk_tmp;
118 
119 	/* check the registered key disk cache */
120 	MUTEX_LOCK(disk_cache_lock);
121 
122 	for (disk_tmp = key_disk_cache_head; disk_tmp; disk_tmp = disk_tmp->next) {
123 		if ((disk_tmp->flags & CACHE_FLAG_VALID) &&
124 		    !memcmp(&disk_tmp->uuid, uuid, sizeof(TSS_UUID))) {
125 			*is_reg = TRUE;
126 			MUTEX_UNLOCK(disk_cache_lock);
127 			return TSS_SUCCESS;
128 		}
129 	}
130 	MUTEX_UNLOCK(disk_cache_lock);
131 	*is_reg = FALSE;
132 
133 	return TSS_SUCCESS;
134 }
135 
136 void
disk_cache_shift(struct key_disk_cache * c)137 disk_cache_shift(struct key_disk_cache *c)
138 {
139 	UINT32 key_size, offset;
140 	struct key_disk_cache *tmp = key_disk_cache_head;
141 
142 	/* offset is the end of the key location in the file */
143 	offset = TSSPS_VENDOR_DATA_OFFSET(c) + c->vendor_data_size;
144 	/* key_size is the size of the key entry on disk */
145 	key_size = offset - TSSPS_UUID_OFFSET(c);
146 
147 	/* for each disk cache entry, if the data for that entry is at an
148 	 * offset greater than the key beign removed, then the entry needs to
149 	 * be decremented by the size of key's disk footprint (the key_size
150 	 * variable) */
151 	while (tmp) {
152 		if (tmp->offset >= offset) {
153 			tmp->offset -= key_size;
154 		}
155 
156 		tmp = tmp->next;
157 	}
158 }
159 
160 TSS_RESULT
ps_remove_key(TSS_UUID * uuid)161 ps_remove_key(TSS_UUID *uuid)
162 {
163 	struct key_disk_cache *tmp, *prev = NULL;
164 	TSS_RESULT rc;
165         int fd = -1;
166 
167 	MUTEX_LOCK(disk_cache_lock);
168 	tmp = key_disk_cache_head;
169 
170 	for (; tmp; prev = tmp, tmp = tmp->next) {
171 		if ((tmp->flags & CACHE_FLAG_VALID) &&
172 		    !memcmp(uuid, &tmp->uuid, sizeof(TSS_UUID))) {
173 			if ((fd = get_file()) < 0) {
174 				rc = TCSERR(TSS_E_INTERNAL_ERROR);
175 				break;
176 			}
177 
178 			rc = psfile_remove_key(fd, tmp);
179 
180 			put_file(fd);
181 
182 			/* if moving the file contents around succeeded, then
183 			 * change the offsets of the keys in the cache in
184 			 * mem_cache_shift() and remove the key from the
185 			 * cache. */
186 			if (!rc) {
187 				disk_cache_shift(tmp);
188 				if (prev) {
189 					prev->next = tmp->next;
190 				} else {
191 					key_disk_cache_head = tmp->next;
192 				}
193 				free(tmp);
194 			} else {
195 				LogError("Error removing registered key.");
196 			}
197 
198 			MUTEX_UNLOCK(disk_cache_lock);
199 			return rc;
200 		}
201 	}
202 
203 	MUTEX_UNLOCK(disk_cache_lock);
204 
205 	return TCSERR(TCSERR(TSS_E_PS_KEY_NOTFOUND));
206 }
207 
208 /*
209  * temporary function to clean out blanked keys from a PS file from
210  * trousers 0.2.0 and before
211  */
212 TSS_RESULT
clean_disk_cache(int fd)213 clean_disk_cache(int fd)
214 {
215 	struct key_disk_cache *tmp, *prev = NULL;
216 	TSS_RESULT rc;
217 
218 	MUTEX_LOCK(disk_cache_lock);
219 	tmp = key_disk_cache_head;
220 
221 	for (; tmp; prev = tmp, tmp = tmp->next) {
222 		if (!(tmp->flags & CACHE_FLAG_VALID)) {
223 			rc = psfile_remove_key(fd, tmp);
224 
225 			/* if moving the file contents around succeeded, then
226 			 * change the offsets of the keys in the cache in
227 			 * mem_cache_shift() and remove the key from the
228 			 * cache. */
229 			if (!rc) {
230 				disk_cache_shift(tmp);
231 				if (prev) {
232 					prev->next = tmp->next;
233 				}
234 				free(tmp);
235 			} else {
236 				LogError("Error removing blank key.");
237 			}
238 
239 			MUTEX_UNLOCK(disk_cache_lock);
240 			return rc;
241 		}
242 	}
243 
244 	MUTEX_UNLOCK(disk_cache_lock);
245 	return TSS_SUCCESS;
246 }
247 
248 TSS_RESULT
ps_get_key_by_uuid(TSS_UUID * uuid,BYTE * blob,UINT16 * blob_size)249 ps_get_key_by_uuid(TSS_UUID *uuid, BYTE *blob, UINT16 *blob_size)
250 {
251         int fd = -1;
252         TSS_RESULT rc = TSS_SUCCESS;
253 
254         if ((fd = get_file()) < 0)
255                 return TCSERR(TSS_E_INTERNAL_ERROR);
256 
257         rc = psfile_get_key_by_uuid(fd, uuid, blob, blob_size);
258 
259         put_file(fd);
260         return rc;
261 }
262 
263 TSS_RESULT
ps_get_key_by_cache_entry(struct key_disk_cache * c,BYTE * blob,UINT16 * blob_size)264 ps_get_key_by_cache_entry(struct key_disk_cache *c, BYTE *blob, UINT16 *blob_size)
265 {
266         int fd = -1;
267         TSS_RESULT rc = TSS_SUCCESS;
268 
269         if ((fd = get_file()) < 0)
270                 return TCSERR(TSS_E_INTERNAL_ERROR);
271 
272         rc = psfile_get_key_by_cache_entry(fd, c, blob, blob_size);
273 
274         put_file(fd);
275         return rc;
276 }
277 
278 TSS_RESULT
ps_get_vendor_data(struct key_disk_cache * c,UINT32 * size,BYTE ** data)279 ps_get_vendor_data(struct key_disk_cache *c, UINT32 *size, BYTE **data)
280 {
281         int fd = -1;
282         TSS_RESULT rc;
283 
284         if ((fd = get_file()) < 0)
285                 return TCSERR(TSS_E_INTERNAL_ERROR);
286 
287         rc = psfile_get_vendor_data(fd, c, size, data);
288 
289         put_file(fd);
290         return rc;
291 }
292 
293 TSS_RESULT
ps_is_pub_registered(TCPA_STORE_PUBKEY * key)294 ps_is_pub_registered(TCPA_STORE_PUBKEY *key)
295 {
296         int fd = -1;
297         TSS_BOOL answer;
298 
299         if ((fd = get_file()) < 0)
300                 return FALSE;
301 
302         if (psfile_is_pub_registered(fd, key, &answer)) {
303                 put_file(fd);
304                 return FALSE;
305         }
306 
307         put_file(fd);
308         return answer;
309 }
310 
311 TSS_RESULT
ps_get_uuid_by_pub(TCPA_STORE_PUBKEY * pub,TSS_UUID ** uuid)312 ps_get_uuid_by_pub(TCPA_STORE_PUBKEY *pub, TSS_UUID **uuid)
313 {
314         int fd = -1;
315 	TSS_RESULT ret;
316 
317         if ((fd = get_file()) < 0)
318                 return TCSERR(TSS_E_INTERNAL_ERROR);
319 
320         ret = psfile_get_uuid_by_pub(fd, pub, uuid);
321 
322         put_file(fd);
323         return ret;
324 }
325 
326 TSS_RESULT
ps_get_key_by_pub(TCPA_STORE_PUBKEY * pub,UINT32 * size,BYTE ** key)327 ps_get_key_by_pub(TCPA_STORE_PUBKEY *pub, UINT32 *size, BYTE **key)
328 {
329         int fd = -1;
330 	TSS_RESULT ret;
331 
332         if ((fd = get_file()) < 0)
333                 return TCSERR(TSS_E_INTERNAL_ERROR);
334 
335         ret = psfile_get_key_by_pub(fd, pub, size, key);
336 
337         put_file(fd);
338         return ret;
339 }
340 
341 TSS_RESULT
ps_write_key(TSS_UUID * uuid,TSS_UUID * parent_uuid,BYTE * vendor_data,UINT32 vendor_size,BYTE * blob,UINT32 blob_size)342 ps_write_key(TSS_UUID *uuid, TSS_UUID *parent_uuid, BYTE *vendor_data,
343 	     UINT32 vendor_size, BYTE *blob, UINT32 blob_size)
344 {
345         int fd = -1;
346         TSS_RESULT rc;
347 	UINT32 parent_ps;
348 	UINT16 short_blob_size = (UINT16)blob_size;
349 
350         if ((fd = get_file()) < 0)
351                 return TCSERR(TSS_E_INTERNAL_ERROR);
352 
353 	/* this case needed for PS file init. if the key file doesn't yet exist, the
354 	 * psfile_get_parent_ps_type_by_uuid() call would fail. */
355 	if (!memcmp(parent_uuid, &NULL_UUID, sizeof(TSS_UUID))) {
356 		parent_ps = TSS_PS_TYPE_SYSTEM;
357 	} else {
358 		if ((rc = psfile_get_ps_type_by_uuid(fd, parent_uuid, &parent_ps)))
359 			return rc;
360 	}
361 
362         rc = psfile_write_key(fd, uuid, parent_uuid, &parent_ps, vendor_data,
363 			      vendor_size, blob, short_blob_size);
364 
365         put_file(fd);
366         return TSS_SUCCESS;
367 }
368