diff options
-rw-r--r-- | utility/mount-encrypted.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/utility/mount-encrypted.c b/utility/mount-encrypted.c index 2c975a39..39777e9d 100644 --- a/utility/mount-encrypted.c +++ b/utility/mount-encrypted.c @@ -110,14 +110,40 @@ static gchar *encrypted_mount = NULL; static gchar *dmcrypt_name = NULL; static gchar *dmcrypt_dev = NULL; static int has_tpm = 0; +static int tpm_init_called = 0; static void tpm_init(void) { uint32_t result; + struct timespec delay; + int retries; + + if (tpm_init_called) + return; DEBUG("Opening TPM"); setenv("TPM_NO_EXIT", "1", 1); - result = TlclLibInit(); + + /* Retry TPM opening for 5 seconds (500 10ms sleeps). */ + for (retries = 0; retries < 500; ++ retries) { + errno = 0; + result = TlclLibInit(); + if (result == TPM_SUCCESS) + break; + + INFO("Could not open TPM: error 0x%02x (%s).", result, + strerror(errno)); + /* Assume ENOENT will never recover */ + if (errno == ENOENT) + break; + + /* Stall 10ms until TPM comes back. */ + delay.tv_sec = 0; + delay.tv_nsec = 10000000; + nanosleep(&delay, NULL); + } + + tpm_init_called = 1; has_tpm = (result == TPM_SUCCESS); INFO("TPM %s", has_tpm ? "ready" : "not available"); } @@ -129,6 +155,7 @@ static uint32_t tpm_owned(uint8_t *owned) { uint32_t result; + tpm_init(); DEBUG("Reading TPM Ownership Flag"); if (!has_tpm) result = TPM_E_NO_DEVICE; @@ -141,7 +168,10 @@ static uint32_t tpm_owned(uint8_t *owned) static void tpm_close(void) { + if (!has_tpm || !tpm_init_called) + return; TlclLibClose(); + tpm_init_called = 0; } static void sha256(char *string, uint8_t *digest) @@ -237,6 +267,7 @@ _read_nvram(uint8_t *buffer, size_t len, uint32_t index, uint32_t size) return 0; } + tpm_init(); DEBUG("Reading NVRAM area 0x%x (size %u)", index, size); if (!has_tpm) result = TPM_E_NO_DEVICE; @@ -425,6 +456,7 @@ static int get_random_bytes_tpm(unsigned char *buffer, int wanted) { uint32_t remaining = wanted; + tpm_init(); /* Read random bytes from TPM, which can return short reads. */ while (remaining) { uint32_t result, size; @@ -1258,7 +1290,6 @@ int main(int argc, char *argv[]) INFO_INIT("Starting."); prepare_paths(); - tpm_init(); if (argc > 1) { if (!strcmp(argv[1], "umount")) |