diff options
Diffstat (limited to 'firmware/lib/secdata_tpm.c')
-rw-r--r-- | firmware/lib/secdata_tpm.c | 189 |
1 files changed, 0 insertions, 189 deletions
diff --git a/firmware/lib/secdata_tpm.c b/firmware/lib/secdata_tpm.c deleted file mode 100644 index b8f3522c..00000000 --- a/firmware/lib/secdata_tpm.c +++ /dev/null @@ -1,189 +0,0 @@ -/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Functions for querying, manipulating and locking secure data spaces - * stored in the TPM NVRAM. - */ - -#include "2api.h" -#include "2common.h" -#include "secdata_tpm.h" -#include "tlcl.h" -#include "tss_constants.h" -#include "vboot_test.h" - -#define RETURN_ON_FAILURE(tpm_command) do { \ - uint32_t result_; \ - if ((result_ = (tpm_command)) != TPM_SUCCESS) { \ - VB2_DEBUG("TPM: %#x returned by " #tpm_command \ - "\n", (int)result_); \ - return result_; \ - } \ - } while (0) - -#define PRINT_BYTES(title, value) do { \ - int i; \ - VB2_DEBUG(title); \ - VB2_DEBUG_RAW(":"); \ - for (i = 0; i < sizeof(*(value)); i++) \ - VB2_DEBUG_RAW(" %02x", *((uint8_t *)(value) + i)); \ - VB2_DEBUG_RAW("\n"); \ - } while (0) - -/* Keeps track of whether the kernel space has already been locked or not. */ -int secdata_kernel_locked = 0; - -/** - * Issue a TPM_Clear and reenable/reactivate the TPM. - */ -uint32_t tlcl_clear_and_reenable(void) -{ - VB2_DEBUG("TPM: clear_and_reenable\n"); - RETURN_ON_FAILURE(TlclForceClear()); - RETURN_ON_FAILURE(TlclSetEnable()); - RETURN_ON_FAILURE(TlclSetDeactivated(0)); - - return TPM_SUCCESS; -} - -/** - * Like TlclWrite(), but checks for write errors due to hitting the 64-write - * limit and clears the TPM when that happens. This can only happen when the - * TPM is unowned, so it is OK to clear it (and we really have no choice). - * This is not expected to happen frequently, but it could happen. - */ -uint32_t tlcl_safe_write(uint32_t index, const void *data, uint32_t length) -{ - uint32_t result = TlclWrite(index, data, length); - if (result == TPM_E_MAXNVWRITES) { - RETURN_ON_FAILURE(tlcl_clear_and_reenable()); - return TlclWrite(index, data, length); - } else { - return result; - } -} - -/* Functions to read and write firmware and kernel spaces. */ - -uint32_t secdata_firmware_write(struct vb2_context *ctx) -{ - if (!(ctx->flags & VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED)) { - VB2_DEBUG("TPM: secdata_firmware unchanged\n"); - return TPM_SUCCESS; - } - - if (!(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) { - VB2_DEBUG("Error: secdata_firmware modified " - "in non-recovery mode?\n"); - return TPM_E_AREA_LOCKED; - } - - PRINT_BYTES("TPM: write secdata_firmware", &ctx->secdata_firmware); - RETURN_ON_FAILURE(tlcl_safe_write(FIRMWARE_NV_INDEX, - ctx->secdata_firmware, - VB2_SECDATA_FIRMWARE_SIZE)); - - ctx->flags &= ~VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED; - return TPM_SUCCESS; -} - -uint32_t secdata_kernel_read(struct vb2_context *ctx) -{ -#ifndef TPM2_MODE - /* - * Before reading the kernel space, verify its permissions. If the - * kernel space has the wrong permission, we give up. This will need - * to be fixed by the recovery kernel. We will have to worry about - * this because at any time (even with PP turned off) the TPM owner can - * remove and redefine a PP-protected space (but not write to it). - */ - uint32_t perms; - - RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_NV_INDEX, &perms)); - if (perms != TPM_NV_PER_PPWRITE) { - VB2_DEBUG("TPM: invalid secdata_kernel permissions: %#x\n", - perms); - return TPM_E_CORRUPTED_STATE; - } -#endif - - RETURN_ON_FAILURE(TlclRead(KERNEL_NV_INDEX, ctx->secdata_kernel, - VB2_SECDATA_KERNEL_SIZE)); - - PRINT_BYTES("TPM: read secdata_kernel", &ctx->secdata_kernel); - - if (vb2api_secdata_kernel_check(ctx)) { - VB2_DEBUG("TPM: secdata_kernel invalid (corrupted?)\n"); - return TPM_E_CORRUPTED_STATE; - } - - return TPM_SUCCESS; -} - -uint32_t secdata_kernel_write(struct vb2_context *ctx) -{ - if (!(ctx->flags & VB2_CONTEXT_SECDATA_KERNEL_CHANGED)) { - VB2_DEBUG("TPM: secdata_kernel unchanged\n"); - return TPM_SUCCESS; - } - - PRINT_BYTES("TPM: write secdata_kernel", &ctx->secdata_kernel); - - RETURN_ON_FAILURE(tlcl_safe_write(KERNEL_NV_INDEX, ctx->secdata_kernel, - VB2_SECDATA_KERNEL_SIZE)); - - ctx->flags &= ~VB2_CONTEXT_SECDATA_KERNEL_CHANGED; - return TPM_SUCCESS; -} - -uint32_t secdata_kernel_lock(struct vb2_context *ctx) -{ - /* Skip if already locked */ - if (secdata_kernel_locked) { - VB2_DEBUG("TPM: secdata_kernel already locked; skipping\n"); - return TPM_SUCCESS; - } - - RETURN_ON_FAILURE(TlclLockPhysicalPresence()); - - VB2_DEBUG("TPM: secdata_kernel locked\n"); - secdata_kernel_locked = 1; - return TPM_SUCCESS; -} - -uint32_t secdata_fwmp_read(struct vb2_context *ctx) -{ - vb2_error_t rv; - uint8_t size = VB2_SECDATA_FWMP_MIN_SIZE; - uint32_t r; - - /* Try to read entire 1.0 struct */ - r = TlclRead(FWMP_NV_INDEX, ctx->secdata_fwmp, size); - if (TPM_E_BADINDEX == r) { - /* Missing space is not an error; tell vboot */ - VB2_DEBUG("TPM: no secdata_fwmp space\n"); - ctx->flags |= VB2_CONTEXT_NO_SECDATA_FWMP; - return TPM_SUCCESS; - } else if (TPM_SUCCESS != r) { - VB2_DEBUG("TPM: read secdata_fwmp returned %#x\n", r); - return r; - } - - /* Re-read more data if necessary */ - rv = vb2api_secdata_fwmp_check(ctx, &size); - if (rv == VB2_SUCCESS) - return VB2_SUCCESS; - - if (rv == VB2_ERROR_SECDATA_FWMP_INCOMPLETE) { - RETURN_ON_FAILURE(TlclRead(FWMP_NV_INDEX, ctx->secdata_fwmp, - size)); - - /* Check one more time */ - if (vb2api_secdata_fwmp_check(ctx, &size) == VB2_SUCCESS) - return VB2_SUCCESS; - } - - VB2_DEBUG("TPM: secdata_fwmp invalid (corrupted?)\n"); - return TPM_E_CORRUPTED_STATE; -} |