diff options
| author | Matthew Garrett <mjg59@google.com> | 2017-05-22 15:36:48 -0700 |
|---|---|---|
| committer | Peter Jones <pjones@redhat.com> | 2017-08-01 12:54:49 -0400 |
| commit | 8af7c4cacaf753f38f2564b26b962a7a2942d664 (patch) | |
| tree | 91852f5250854949db0532c744fc67d9b1435c86 /shim.c | |
| parent | a8f3dc82be8e16d24ceab416c1b0af897c083f56 (diff) | |
| download | efi-boot-shim-8af7c4cacaf753f38f2564b26b962a7a2942d664.tar.gz efi-boot-shim-8af7c4cacaf753f38f2564b26b962a7a2942d664.zip | |
Extend PCR 7
It's desirable to be able to use PCR 7 for all TPM policy on Secure Boot
systems, but right now Shim doesn't record any information about its
configuration or the signature used to launch the second stage loader. Add
support for that.
Diffstat (limited to 'shim.c')
| -rw-r--r-- | shim.c | 41 |
1 files changed, 31 insertions, 10 deletions
@@ -428,7 +428,8 @@ static BOOLEAN verify_eku(UINT8 *Cert, UINTN CertSize) static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList, UINTN dbsize, WIN_CERTIFICATE_EFI_PKCS *data, - UINT8 *hash) + UINT8 *hash, CHAR16 *dbname, + EFI_GUID guid) { EFI_SIGNATURE_DATA *Cert; UINTN CertSize; @@ -446,8 +447,10 @@ static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList, Cert->SignatureData, CertSize, hash, SHA256_DIGEST_SIZE); - if (IsFound) + if (IsFound) { + tpm_measure_variable(dbname, guid, CertSize, Cert->SignatureData); return DATA_FOUND; + } } } else if (verbose) { console_notify(L"Not a DER encoding x.509 Certificate"); @@ -477,7 +480,7 @@ static CHECK_STATUS check_db_cert(CHAR16 *dbname, EFI_GUID guid, CertList = (EFI_SIGNATURE_LIST *)db; - rc = check_db_cert_in_ram(CertList, dbsize, data, hash); + rc = check_db_cert_in_ram(CertList, dbsize, data, hash, dbname, guid); FreePool(db); @@ -489,7 +492,8 @@ static CHECK_STATUS check_db_cert(CHAR16 *dbname, EFI_GUID guid, */ static CHECK_STATUS check_db_hash_in_ram(EFI_SIGNATURE_LIST *CertList, UINTN dbsize, UINT8 *data, - int SignatureSize, EFI_GUID CertType) + int SignatureSize, EFI_GUID CertType, + CHAR16 *dbname, EFI_GUID guid) { EFI_SIGNATURE_DATA *Cert; UINTN CertCount, Index; @@ -505,6 +509,7 @@ static CHECK_STATUS check_db_hash_in_ram(EFI_SIGNATURE_LIST *CertList, // Find the signature in database. // IsFound = TRUE; + tpm_measure_variable(dbname, guid, SignatureSize, data); break; } @@ -545,7 +550,8 @@ static CHECK_STATUS check_db_hash(CHAR16 *dbname, EFI_GUID guid, UINT8 *data, CertList = (EFI_SIGNATURE_LIST *)db; CHECK_STATUS rc = check_db_hash_in_ram(CertList, dbsize, data, - SignatureSize, CertType); + SignatureSize, CertType, + dbname, guid); FreePool(db); return rc; @@ -563,15 +569,18 @@ static EFI_STATUS check_blacklist (WIN_CERTIFICATE_EFI_PKCS *cert, EFI_SIGNATURE_LIST *dbx = (EFI_SIGNATURE_LIST *)vendor_dbx; if (check_db_hash_in_ram(dbx, vendor_dbx_size, sha256hash, - SHA256_DIGEST_SIZE, EFI_CERT_SHA256_GUID) == + SHA256_DIGEST_SIZE, EFI_CERT_SHA256_GUID, + L"dbx", secure_var) == DATA_FOUND) return EFI_SECURITY_VIOLATION; if (check_db_hash_in_ram(dbx, vendor_dbx_size, sha1hash, - SHA1_DIGEST_SIZE, EFI_CERT_SHA1_GUID) == + SHA1_DIGEST_SIZE, EFI_CERT_SHA1_GUID, + L"dbx", secure_var) == DATA_FOUND) return EFI_SECURITY_VIOLATION; if (cert && check_db_cert_in_ram(dbx, vendor_dbx_size, cert, - sha256hash) == DATA_FOUND) + sha256hash, L"dbx", + secure_var) == DATA_FOUND) return EFI_SECURITY_VIOLATION; if (check_db_hash(L"dbx", secure_var, sha256hash, SHA256_DIGEST_SIZE, @@ -960,6 +969,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize, EFI_STATUS status = EFI_SECURITY_VIOLATION; WIN_CERTIFICATE_EFI_PKCS *cert = NULL; unsigned int size = datasize; + EFI_GUID shim_var = SHIM_LOCK_GUID; if (context->SecDir->Size != 0) { if (context->SecDir->Size >= size) { @@ -1026,6 +1036,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize, shim_cert, sizeof(shim_cert), sha256hash, SHA256_DIGEST_SIZE)) { update_verification_method(VERIFIED_BY_CERT); + tpm_measure_variable(L"Shim", shim_var, sizeof(shim_cert), shim_cert); status = EFI_SUCCESS; return status; } @@ -1039,6 +1050,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize, vendor_cert, vendor_cert_size, sha256hash, SHA256_DIGEST_SIZE)) { update_verification_method(VERIFIED_BY_CERT); + tpm_measure_variable(L"Shim", shim_var, vendor_cert_size, vendor_cert); status = EFI_SUCCESS; return status; } @@ -1888,7 +1900,11 @@ EFI_STATUS init_grub(EFI_HANDLE image_handle) } /* - * Measure some of the MOK variables into the TPM + * Measure some of the MOK variables into the TPM. We measure the entirety + * of MokList into PCR 14, and also measure the raw MokSBState there. PCR 7 + * will be extended with MokSBState in the Microsoft format, and we'll + * measure any matching hashes or certificates later on in order to behave + * consistently with the PCR 7 spec. */ EFI_STATUS measure_mok() { @@ -1915,9 +1931,14 @@ EFI_STATUS measure_mok() if (efi_status != EFI_SUCCESS) return efi_status; + efi_status = tpm_measure_variable(L"MokSBState", shim_lock_guid, + DataSize, Data); + if (efi_status != EFI_SUCCESS) + goto out; + efi_status = tpm_log_event((EFI_PHYSICAL_ADDRESS)(UINTN)Data, DataSize, 14, (CHAR8 *)"MokSBState"); - +out: FreePool(Data); return efi_status; |
