1 /* 2 * Licensed Materials - Property of IBM 3 * 4 * trousers - An open source TCG Software Stack 5 * 6 * (C) Copyright International Business Machines Corp. 2004 7 * 8 */ 9 10 11 #include <stdlib.h> 12 #include <stdio.h> 13 #include <unistd.h> 14 #include <sys/types.h> 15 #include <sys/stat.h> 16 #if defined (HAVE_BYTEORDER_H) 17 #include <sys/byteorder.h> 18 #elif defined (HTOLE_DEFINED) 19 20 #ifndef __APPLE__ 21 #include <endian.h> 22 #else 23 #include "portable_endian.h" 24 #endif 25 26 #define LE_16 htole16 27 #define LE_32 htole32 28 #define LE_64 htole64 29 #else 30 #define LE_16(x) (x) 31 #define LE_32(x) (x) 32 #define LE_64(x) (x) 33 #endif 34 #include <fcntl.h> 35 #include <string.h> 36 #include <limits.h> 37 #include <assert.h> 38 #include <errno.h> 39 40 #include "trousers/tss.h" 41 #include "trousers_types.h" 42 #include "tcs_int_literals.h" 43 #include "tcsps.h" 44 #include "tcs_tsp.h" 45 #include "tcs_utils.h" 46 #include "tcslog.h" 47 48 struct key_disk_cache *key_disk_cache_head = NULL; 49 50 51 TSS_RESULT 52 read_data(int fd, void *data, UINT32 size) 53 { 54 int rc; 55 56 rc = read(fd, data, size); 57 if (rc == -1) { 58 LogError("read of %d bytes: %s", size, strerror(errno)); 59 return TCSERR(TSS_E_INTERNAL_ERROR); 60 } else if ((unsigned)rc != size) { 61 LogError("read of %d bytes (only %d read)", size, rc); 62 return TCSERR(TSS_E_INTERNAL_ERROR); 63 } 64 65 return TSS_SUCCESS; 66 } 67 68 69 TSS_RESULT 70 write_data(int fd, void *data, UINT32 size) 71 { 72 int rc; 73 74 rc = write(fd, data, size); 75 if (rc == -1) { 76 LogError("write of %d bytes: %s", size, strerror(errno)); 77 return TCSERR(TSS_E_INTERNAL_ERROR); 78 } else if ((unsigned)rc != size) { 79 LogError("write of %d bytes (only %d written)", size, rc); 80 return TCSERR(TSS_E_INTERNAL_ERROR); 81 } 82 83 return TSS_SUCCESS; 84 } 85 86 /* 87 * called by write_key_init to find the next available location in the PS file to 88 * write a new key to. 89 */ 90 int 91 find_write_offset(UINT32 pub_data_size, UINT32 blob_size, UINT32 vendor_data_size) 92 { 93 struct key_disk_cache *tmp; 94 unsigned int offset; 95 96 MUTEX_LOCK(disk_cache_lock); 97 98 tmp = key_disk_cache_head; 99 while (tmp) { 100 /* if we find a deleted key of the right size, return its offset */ 101 if (!(tmp->flags & CACHE_FLAG_VALID) && 102 tmp->pub_data_size == pub_data_size && 103 tmp->blob_size == blob_size && 104 tmp->vendor_data_size == vendor_data_size) { 105 offset = tmp->offset; 106 MUTEX_UNLOCK(disk_cache_lock); 107 return offset; 108 } 109 tmp = tmp->next; 110 } 111 112 MUTEX_UNLOCK(disk_cache_lock); 113 114 /* no correctly sized holes */ 115 return -1; 116 } 117 118 /* 119 * move the file pointer to the point where the next key can be written and return 120 * that offset 121 */ 122 int 123 write_key_init(int fd, UINT32 pub_data_size, UINT32 blob_size, UINT32 vendor_data_size) 124 { 125 UINT32 num_keys; 126 BYTE version; 127 int rc, offset; 128 129 /* seek to the PS version */ 130 rc = lseek(fd, TSSPS_VERSION_OFFSET, SEEK_SET); 131 if (rc == ((off_t) - 1)) { 132 LogError("lseek: %s", strerror(errno)); 133 return -1; 134 } 135 136 /* go to NUM_KEYS */ 137 rc = lseek(fd, TSSPS_NUM_KEYS_OFFSET, SEEK_SET); 138 if (rc == ((off_t) - 1)) { 139 LogError("lseek: %s", strerror(errno)); 140 return -1; 141 } 142 143 /* read the number of keys */ 144 rc = read(fd, &num_keys, sizeof(UINT32)); 145 num_keys = LE_32(num_keys); 146 if (rc == -1) { 147 LogError("read of %zd bytes: %s", sizeof(UINT32), strerror(errno)); 148 return -1; 149 } else if (rc == 0) { 150 /* This is the first key being written */ 151 num_keys = 1; 152 version = 1; 153 154 /* seek to the PS version */ 155 rc = lseek(fd, TSSPS_VERSION_OFFSET, SEEK_SET); 156 if (rc == ((off_t) - 1)) { 157 LogError("lseek: %s", strerror(errno)); 158 return -1; 159 } 160 161 /* write out the version info byte */ 162 if ((rc = write_data(fd, &version, sizeof(BYTE)))) { 163 LogError("%s", __FUNCTION__); 164 return rc; 165 } 166 167 rc = lseek(fd, TSSPS_NUM_KEYS_OFFSET, SEEK_SET); 168 if (rc == ((off_t) - 1)) { 169 LogError("lseek: %s", strerror(errno)); 170 return -1; 171 } 172 173 num_keys = LE_32(num_keys); 174 if ((rc = write_data(fd, &num_keys, sizeof(UINT32)))) { 175 LogError("%s", __FUNCTION__); 176 return rc; 177 } 178 179 /* return the offset */ 180 return (TSSPS_NUM_KEYS_OFFSET + sizeof(UINT32)); 181 } 182 183 /* if there is a hole in the file we can write to, find it */ 184 offset = find_write_offset(pub_data_size, blob_size, vendor_data_size); 185 186 if (offset != -1) { 187 /* we found a hole, seek to it and don't increment the # of keys on disk */ 188 rc = lseek(fd, offset, SEEK_SET); 189 } else { 190 /* we didn't find a hole, increment the number of keys on disk and seek 191 * to the end of the file 192 */ 193 num_keys++; 194 195 /* go to the beginning */ 196 rc = lseek(fd, TSSPS_NUM_KEYS_OFFSET, SEEK_SET); 197 if (rc == ((off_t) - 1)) { 198 LogError("lseek: %s", strerror(errno)); 199 return -1; 200 } 201 num_keys = LE_32(num_keys); 202 if ((rc = write_data(fd, &num_keys, sizeof(UINT32)))) { 203 LogError("%s", __FUNCTION__); 204 return rc; 205 } 206 207 rc = lseek(fd, 0, SEEK_END); 208 } 209 if (rc == ((off_t) - 1)) { 210 LogError("lseek: %s", strerror(errno)); 211 return -1; 212 } 213 214 /* lseek returns the number of bytes of offset from the beginning of the file */ 215 return rc; 216 } 217 218 /* 219 * add a new cache entry for a written key 220 */ 221 TSS_RESULT 222 cache_key(UINT32 offset, UINT16 flags, 223 TSS_UUID *uuid, TSS_UUID *parent_uuid, 224 UINT16 pub_data_size, UINT32 blob_size, 225 UINT32 vendor_data_size) 226 { 227 struct key_disk_cache *tmp; 228 229 MUTEX_LOCK(disk_cache_lock); 230 231 tmp = key_disk_cache_head; 232 233 for (; tmp; tmp = tmp->next) { 234 /* reuse an invalidated key cache entry */ 235 if (!(tmp->flags & CACHE_FLAG_VALID)) 236 goto fill_cache_entry; 237 } 238 239 tmp = malloc(sizeof(struct key_disk_cache)); 240 if (tmp == NULL) { 241 LogError("malloc of %zd bytes failed.", sizeof(struct key_disk_cache)); 242 MUTEX_UNLOCK(disk_cache_lock); 243 return TCSERR(TSS_E_OUTOFMEMORY); 244 } 245 tmp->next = key_disk_cache_head; 246 key_disk_cache_head = tmp; 247 248 fill_cache_entry: 249 tmp->offset = offset; 250 #ifdef TSS_DEBUG 251 if (offset == 0) 252 LogDebug("Storing key with file offset==0!!!"); 253 #endif 254 tmp->flags = flags; 255 tmp->blob_size = blob_size; 256 tmp->pub_data_size = pub_data_size; 257 tmp->vendor_data_size = vendor_data_size; 258 memcpy(&tmp->uuid, uuid, sizeof(TSS_UUID)); 259 memcpy(&tmp->parent_uuid, parent_uuid, sizeof(TSS_UUID)); 260 261 MUTEX_UNLOCK(disk_cache_lock); 262 return TSS_SUCCESS; 263 } 264 265 /* 266 * read into the PS file and return the number of keys 267 */ 268 int 269 get_num_keys_in_file(int fd) 270 { 271 UINT32 num_keys; 272 int rc; 273 274 /* go to the number of keys */ 275 rc = lseek(fd, TSSPS_NUM_KEYS_OFFSET, SEEK_SET); 276 if (rc == ((off_t) - 1)) { 277 LogError("lseek: %s", strerror(errno)); 278 return 0; 279 } 280 281 rc = read(fd, &num_keys, sizeof(UINT32)); 282 if (rc < 0) { 283 LogError("read of %zd bytes: %s", sizeof(UINT32), strerror(errno)); 284 return 0; 285 } else if ((unsigned)rc < sizeof(UINT32)) { 286 num_keys = 0; 287 } 288 num_keys = LE_32(num_keys); 289 290 return num_keys; 291 } 292 293 /* 294 * count the number of valid keys in the cache 295 */ 296 int 297 get_num_keys() 298 { 299 int num_keys = 0; 300 struct key_disk_cache *tmp; 301 302 MUTEX_LOCK(disk_cache_lock); 303 304 tmp = key_disk_cache_head; 305 306 for (; tmp; tmp = tmp->next) { 307 if (tmp->flags & CACHE_FLAG_VALID) 308 num_keys++; 309 } 310 311 MUTEX_UNLOCK(disk_cache_lock); 312 return num_keys; 313 } 314 315 /* 316 * disk store format: 317 * 318 * TrouSerS 0.2.0 and before: 319 * Version 0: cached? 320 * [UINT32 num_keys_on_disk] 321 * [TSS_UUID uuid0 ] yes 322 * [TSS_UUID uuid_parent0 ] yes 323 * [UINT16 pub_data_size0 ] yes 324 * [UINT16 blob_size0 ] yes 325 * [UINT16 cache_flags0 ] yes 326 * [BYTE[] pub_data0 ] 327 * [BYTE[] blob0 ] 328 * [...] 329 * 330 * TrouSerS 0.2.1+ 331 * Version 1: cached? 332 * [BYTE PS version = '\1'] 333 * [UINT32 num_keys_on_disk ] 334 * [TSS_UUID uuid0 ] yes 335 * [TSS_UUID uuid_parent0 ] yes 336 * [UINT16 pub_data_size0 ] yes 337 * [UINT16 blob_size0 ] yes 338 * [UINT32 vendor_data_size0] yes 339 * [UINT16 cache_flags0 ] yes 340 * [BYTE[] pub_data0 ] 341 * [BYTE[] blob0 ] 342 * [BYTE[] vendor_data0 ] 343 * [...] 344 * 345 */ 346 /* 347 * read the PS file pointed to by fd and create a cache based on it 348 */ 349 int 350 init_disk_cache(int fd) 351 { 352 UINT32 num_keys = get_num_keys_in_file(fd); 353 UINT16 i; 354 UINT64 tmp_offset; 355 int rc = 0, offset; 356 struct key_disk_cache *tmp, *prev = NULL; 357 BYTE srk_blob[2048]; 358 TSS_KEY srk_key; 359 #ifdef TSS_DEBUG 360 int valid_keys = 0; 361 #endif 362 363 MUTEX_LOCK(disk_cache_lock); 364 365 if (num_keys == 0) { 366 key_disk_cache_head = NULL; 367 MUTEX_UNLOCK(disk_cache_lock); 368 return 0; 369 } else { 370 key_disk_cache_head = tmp = calloc(1, sizeof(struct key_disk_cache)); 371 if (tmp == NULL) { 372 LogError("malloc of %zd bytes failed.", 373 sizeof(struct key_disk_cache)); 374 rc = -1; 375 goto err_exit; 376 } 377 } 378 379 /* make sure the file pointer is where we expect, just after the number 380 * of keys on disk at the head of the file 381 */ 382 offset = lseek(fd, TSSPS_KEYS_OFFSET, SEEK_SET); 383 if (offset == ((off_t) - 1)) { 384 LogError("lseek: %s", strerror(errno)); 385 rc = -1; 386 goto err_exit; 387 } 388 389 for (i=0; i<num_keys; i++) { 390 offset = lseek(fd, 0, SEEK_CUR); 391 if (offset == ((off_t) - 1)) { 392 LogError("lseek: %s", strerror(errno)); 393 rc = -1; 394 goto err_exit; 395 } 396 tmp->offset = offset; 397 #ifdef TSS_DEBUG 398 if (offset == 0) 399 LogDebug("Storing key with file offset==0!!!"); 400 #endif 401 /* read UUID */ 402 if ((rc = read_data(fd, (void *)&tmp->uuid, sizeof(TSS_UUID)))) { 403 LogError("%s", __FUNCTION__); 404 goto err_exit; 405 } 406 407 /* read parent UUID */ 408 if ((rc = read_data(fd, (void *)&tmp->parent_uuid, sizeof(TSS_UUID)))) { 409 LogError("%s", __FUNCTION__); 410 goto err_exit; 411 } 412 413 /* pub data size */ 414 if ((rc = read_data(fd, &tmp->pub_data_size, sizeof(UINT16)))) { 415 LogError("%s", __FUNCTION__); 416 goto err_exit; 417 } 418 tmp->pub_data_size = LE_16(tmp->pub_data_size); 419 420 DBG_ASSERT(tmp->pub_data_size <= 2048 && tmp->pub_data_size > 0); 421 422 /* blob size */ 423 if ((rc = read_data(fd, &tmp->blob_size, sizeof(UINT16)))) { 424 LogError("%s", __FUNCTION__); 425 goto err_exit; 426 } 427 tmp->blob_size = LE_16(tmp->blob_size); 428 DBG_ASSERT(tmp->blob_size <= 4096 && tmp->blob_size > 0); 429 430 /* vendor data size */ 431 if ((rc = read_data(fd, &tmp->vendor_data_size, sizeof(UINT32)))) { 432 LogError("%s", __FUNCTION__); 433 goto err_exit; 434 } 435 tmp->vendor_data_size = LE_32(tmp->vendor_data_size); 436 437 /* cache flags */ 438 if ((rc = read_data(fd, &tmp->flags, sizeof(UINT16)))) { 439 LogError("%s", __FUNCTION__); 440 goto err_exit; 441 } 442 tmp->flags = LE_16(tmp->flags); 443 444 #ifdef TSS_DEBUG 445 if (tmp->flags & CACHE_FLAG_VALID) 446 valid_keys++; 447 #endif 448 /* fast forward over the pub key */ 449 offset = lseek(fd, tmp->pub_data_size, SEEK_CUR); 450 if (offset == ((off_t) - 1)) { 451 LogError("lseek: %s", strerror(errno)); 452 rc = -1; 453 goto err_exit; 454 } 455 456 /* if this is the SRK, load it into memory, since its already loaded in 457 * the chip */ 458 if (!memcmp(&SRK_UUID, &tmp->uuid, sizeof(TSS_UUID))) { 459 /* read SRK blob from disk */ 460 if ((rc = read_data(fd, srk_blob, tmp->blob_size))) { 461 LogError("%s", __FUNCTION__); 462 goto err_exit; 463 } 464 465 tmp_offset = 0; 466 if ((rc = UnloadBlob_TSS_KEY(&tmp_offset, srk_blob, &srk_key))) 467 goto err_exit; 468 /* add to the mem cache */ 469 if ((rc = mc_add_entry_init(SRK_TPM_HANDLE, SRK_TPM_HANDLE, &srk_key, 470 &SRK_UUID))) { 471 LogError("Error adding SRK to mem cache."); 472 destroy_key_refs(&srk_key); 473 goto err_exit; 474 } 475 destroy_key_refs(&srk_key); 476 } else { 477 /* fast forward over the blob */ 478 offset = lseek(fd, tmp->blob_size, SEEK_CUR); 479 if (offset == ((off_t) - 1)) { 480 LogError("lseek: %s", strerror(errno)); 481 rc = -1; 482 goto err_exit; 483 } 484 485 /* fast forward over the vendor data */ 486 offset = lseek(fd, tmp->vendor_data_size, SEEK_CUR); 487 if (offset == ((off_t) - 1)) { 488 LogError("lseek: %s", strerror(errno)); 489 rc = -1; 490 goto err_exit; 491 } 492 } 493 494 tmp->next = calloc(1, sizeof(struct key_disk_cache)); 495 if (tmp->next == NULL) { 496 LogError("malloc of %zd bytes failed.", 497 sizeof(struct key_disk_cache)); 498 rc = -1; 499 goto err_exit; 500 } 501 prev = tmp; 502 tmp = tmp->next; 503 } 504 505 /* delete the dangling, unfilled cache entry */ 506 free(tmp); 507 prev->next = NULL; 508 rc = 0; 509 LogDebug("%s: found %d valid key(s) on disk.\n", __FUNCTION__, valid_keys); 510 511 err_exit: 512 MUTEX_UNLOCK(disk_cache_lock); 513 return rc; 514 } 515 516 int 517 close_disk_cache(int fd) 518 { 519 struct key_disk_cache *tmp, *tmp_next; 520 521 if (key_disk_cache_head == NULL) 522 return 0; 523 524 MUTEX_LOCK(disk_cache_lock); 525 tmp = key_disk_cache_head; 526 527 do { 528 tmp_next = tmp->next; 529 free(tmp); 530 tmp = tmp_next; 531 } while (tmp); 532 533 MUTEX_UNLOCK(disk_cache_lock); 534 535 return 0; 536 } 537