📄 ps_utils.c
字号:
/* * Licensed Materials - Property of IBM * * trousers - An open source TCG Software Stack * * (C) Copyright International Business Machines Corp. 2004 * */#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <limits.h>#include <assert.h>#include <pthread.h>#include <errno.h>#include "trousers/tss.h"#include "trousers_types.h"#include "tcs_int_literals.h"#include "tcs_internal_types.h"#include "tcs_utils.h"#include "tcsps.h"#include "tcs_tsp.h"#include "tcslog.h"struct key_disk_cache *key_disk_cache_head = NULL;voidLoadBlob_TCPA_VERSION(UINT16 * offset, BYTE * blob, TCPA_VERSION version){ blob[(*offset)++] = version.major; blob[(*offset)++] = version.minor; blob[(*offset)++] = version.revMajor; blob[(*offset)++] = version.revMinor;}voidUnloadBlob_TCPA_VERSION(UINT16 * offset, BYTE * blob, TCPA_VERSION * out){ out->major = blob[(*offset)++]; out->minor = blob[(*offset)++]; out->revMajor = blob[(*offset)++]; out->revMinor = blob[(*offset)++];}TSS_RESULTUnloadBlob_KEY_PARMS_PS(UINT16 *offset, BYTE *blob, TCPA_KEY_PARMS *keyParms){ UnloadBlob_UINT32(offset, &keyParms->algorithmID, blob, NULL); UnloadBlob_UINT16(offset, &keyParms->encScheme, blob, NULL); UnloadBlob_UINT16(offset, &keyParms->sigScheme, blob, NULL); UnloadBlob_UINT32(offset, &keyParms->parmSize, blob, NULL); if (keyParms->parmSize == 0) keyParms->parms = NULL; else { keyParms->parms = malloc(keyParms->parmSize); if (keyParms->parms == NULL) { LogError("malloc of %u bytes failed.", keyParms->parmSize); return TCSERR(TSS_E_OUTOFMEMORY); } UnloadBlob(offset, keyParms->parmSize, blob, keyParms->parms, NULL); } return TSS_SUCCESS;}TSS_RESULTUnloadBlob_STORE_PUBKEY_PS(UINT16 *offset, BYTE *blob, TCPA_STORE_PUBKEY *store){ UnloadBlob_UINT32(offset, &store->keyLength, blob, NULL); if (store->keyLength == 0) { LogWarn("Unloading public key of size 0!"); store->key = NULL; } else { store->key = malloc(store->keyLength); if (store->key == NULL) { LogError("malloc of %u bytes failed.", store->keyLength); return TCSERR(TSS_E_OUTOFMEMORY); } UnloadBlob(offset, store->keyLength, blob, store->key, NULL); } return TSS_SUCCESS;}TSS_RESULTUnloadBlob_KEY_PS(UINT16 *offset, BYTE *blob, TCPA_KEY *key){ TSS_RESULT rc = TSS_SUCCESS; memset(key, 0, sizeof(TCPA_KEY)); UnloadBlob_TCPA_VERSION(offset, blob, &key->ver); UnloadBlob_UINT16(offset, &key->keyUsage, blob, NULL); UnloadBlob_KEY_FLAGS(offset, blob, &key->keyFlags); UnloadBlob_BOOL(offset, (TSS_BOOL *)&key->authDataUsage, blob, NULL); if (UnloadBlob_KEY_PARMS_PS(offset, blob, &key->algorithmParms)) return rc; UnloadBlob_UINT32(offset, &key->PCRInfoSize, blob, NULL); if (key->PCRInfoSize == 0) key->PCRInfo = NULL; else { key->PCRInfo = malloc(key->PCRInfoSize); if (key->PCRInfo == NULL) { LogError("malloc of %u bytes failed.", key->PCRInfoSize); return TCSERR(TSS_E_OUTOFMEMORY); } UnloadBlob(offset, key->PCRInfoSize, blob, key->PCRInfo, NULL); } if ((rc = UnloadBlob_STORE_PUBKEY_PS(offset, blob, &key->pubKey))) return rc; UnloadBlob_UINT32(offset, &key->encSize, blob, NULL); if (key->encSize == 0) key->encData = NULL; else { key->encData = malloc(key->encSize); if (key->encData == NULL) { LogError("malloc of %u bytes failed.", key->encSize); return TCSERR(TSS_E_OUTOFMEMORY); } UnloadBlob(offset, key->encSize, blob, key->encData, NULL); } return TSS_SUCCESS;}voidLoadBlob_KEY_PS(UINT16 *offset, BYTE *blob, TCPA_KEY *key){ LoadBlob_TCPA_VERSION(offset, blob, key->ver); LoadBlob_UINT16(offset, key->keyUsage, blob, NULL); LoadBlob_KEY_FLAGS(offset, blob, &key->keyFlags); LoadBlob_BOOL(offset, key->authDataUsage, blob, NULL); LoadBlob_KEY_PARMS(offset, blob, &key->algorithmParms); LoadBlob_UINT32(offset, key->PCRInfoSize, blob, NULL); LoadBlob(offset, key->PCRInfoSize, blob, key->PCRInfo, NULL); LoadBlob_STORE_PUBKEY(offset, blob, &key->pubKey); LoadBlob_UINT32(offset, key->encSize, blob, NULL); LoadBlob(offset, key->encSize, blob, key->encData, NULL);}inline TSS_RESULTread_data(int fd, void *data, UINT32 size){ int rc; rc = read(fd, data, size); if (rc == -1) { LogError("read of %d bytes: %s", size, strerror(errno)); return TCSERR(TSS_E_INTERNAL_ERROR); } else if ((unsigned)rc != size) { LogError("read of %d bytes (only %d read)", size, rc); return TCSERR(TSS_E_INTERNAL_ERROR); } return TSS_SUCCESS;}inline TSS_RESULTwrite_data(int fd, void *data, UINT32 size){ int rc; rc = write(fd, data, size); if (rc == -1) { LogError("write of %d bytes: %s", size, strerror(errno)); return TCSERR(TSS_E_INTERNAL_ERROR); } else if ((unsigned)rc != size) { LogError("write of %d bytes (only %d written)", size, rc); return TCSERR(TSS_E_INTERNAL_ERROR); } return TSS_SUCCESS;}/* * called by write_key_init to find the next available location in the PS file to * write a new key to. */intfind_write_offset(UINT32 pub_data_size, UINT32 blob_size, UINT32 vendor_data_size){ struct key_disk_cache *tmp; unsigned int offset; pthread_mutex_lock(&disk_cache_lock); tmp = key_disk_cache_head; while (tmp) { /* if we find a deleted key of the right size, return its offset */ if (!(tmp->flags & CACHE_FLAG_VALID) && tmp->pub_data_size == pub_data_size && tmp->blob_size == blob_size && tmp->vendor_data_size == vendor_data_size) { offset = tmp->offset; pthread_mutex_unlock(&disk_cache_lock); return offset; } tmp = tmp->next; } pthread_mutex_unlock(&disk_cache_lock); /* no correctly sized holes */ return -1;}/* * move the file pointer to the point where the next key can be written and return * that offset */intwrite_key_init(int fd, UINT32 pub_data_size, UINT32 blob_size, UINT32 vendor_data_size){ UINT32 num_keys; BYTE version; int rc, offset; /* seek to the PS version */ rc = lseek(fd, VERSION_OFFSET, SEEK_SET); if (rc == ((off_t) - 1)) { LogError("lseek: %s", strerror(errno)); return -1; } /* go to NUM_KEYS */ rc = lseek(fd, NUM_KEYS_OFFSET, SEEK_SET); if (rc == ((off_t) - 1)) { LogError("lseek: %s", strerror(errno)); return -1; } /* read the number of keys */ rc = read(fd, &num_keys, sizeof(UINT32)); if (rc == -1) { LogError("read of %zd bytes: %s", sizeof(UINT32), strerror(errno)); return -1; } else if (rc == 0) { /* This is the first key being written */ num_keys = 1; version = 1; /* seek to the PS version */ rc = lseek(fd, VERSION_OFFSET, SEEK_SET); if (rc == ((off_t) - 1)) { LogError("lseek: %s", strerror(errno)); return -1; } /* write out the version info byte */ if ((rc = write_data(fd, &version, sizeof(BYTE)))) { LogError("%s", __FUNCTION__); return rc; } rc = lseek(fd, NUM_KEYS_OFFSET, SEEK_SET); if (rc == ((off_t) - 1)) { LogError("lseek: %s", strerror(errno)); return -1; } if ((rc = write_data(fd, &num_keys, sizeof(UINT32)))) { LogError("%s", __FUNCTION__); return rc; } /* return the offset */ return (NUM_KEYS_OFFSET + sizeof(UINT32)); } /* if there is a hole in the file we can write to, find it */ offset = find_write_offset(pub_data_size, blob_size, vendor_data_size); if (offset != -1) { /* we found a hole, seek to it and don't increment the # of keys on disk */ rc = lseek(fd, offset, SEEK_SET); } else { /* we didn't find a hole, increment the number of keys on disk and seek * to the end of the file */ num_keys++; /* go to the beginning */ rc = lseek(fd, NUM_KEYS_OFFSET, SEEK_SET); if (rc == ((off_t) - 1)) { LogError("lseek: %s", strerror(errno)); return -1; } if ((rc = write_data(fd, &num_keys, sizeof(UINT32)))) { LogError("%s", __FUNCTION__); return rc; } rc = lseek(fd, 0, SEEK_END); } if (rc == ((off_t) - 1)) { LogError("lseek: %s", strerror(errno)); return -1; } /* lseek returns the number of bytes of offset from the beginning of the file */ return rc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -