diff options
Diffstat (limited to 'lib/variables.c')
-rw-r--r-- | lib/variables.c | 260 |
1 files changed, 127 insertions, 133 deletions
diff --git a/lib/variables.c b/lib/variables.c index 59d7d054..9c2e7d0a 100644 --- a/lib/variables.c +++ b/lib/variables.c @@ -11,23 +11,18 @@ * Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR> * This program and the accompanying materials * are licensed and made available under the terms and conditions of the BSD License - * which accompanies this distribution. The full text of the license may be found + * which accompanies this distribution. The full text of the license may be found * at * http://opensource.org/licenses/bsd-license.php * * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - * + * */ #include <efi.h> #include <efilib.h> -#include <efiauthenticated.h> - -#include <variables.h> -#include <guid.h> -#include <console.h> -#include <errors.h> +#include "shim.h" EFI_STATUS variable_create_esl(void *cert, int cert_len, EFI_GUID *type, EFI_GUID *owner, @@ -56,76 +51,75 @@ variable_create_esl(void *cert, int cert_len, EFI_GUID *type, EFI_GUID *owner, return EFI_SUCCESS; } - EFI_STATUS -CreateTimeBasedPayload ( - IN OUT UINTN *DataSize, - IN OUT UINT8 **Data - ) +CreateTimeBasedPayload(IN OUT UINTN * DataSize, IN OUT UINT8 ** Data) { - EFI_STATUS Status; - UINT8 *NewData; - UINT8 *Payload; - UINTN PayloadSize; - EFI_VARIABLE_AUTHENTICATION_2 *DescriptorData; - UINTN DescriptorSize; - EFI_TIME Time; - EFI_GUID efi_cert_type = EFI_CERT_TYPE_PKCS7_GUID; - - if (Data == NULL || DataSize == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // In Setup mode or Custom mode, the variable does not need to be signed but the - // parameters to the SetVariable() call still need to be prepared as authenticated - // variable. So we create EFI_VARIABLE_AUTHENTICATED_2 descriptor without certificate - // data in it. - // - Payload = *Data; - PayloadSize = *DataSize; - - DescriptorSize = OFFSET_OF(EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) + OFFSET_OF(WIN_CERTIFICATE_UEFI_GUID, CertData); - NewData = (UINT8*) AllocateZeroPool (DescriptorSize + PayloadSize); - if (NewData == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - if ((Payload != NULL) && (PayloadSize != 0)) { - CopyMem (NewData + DescriptorSize, Payload, PayloadSize); - } - - DescriptorData = (EFI_VARIABLE_AUTHENTICATION_2 *) (NewData); - - ZeroMem (&Time, sizeof (EFI_TIME)); - Status = uefi_call_wrapper(RT->GetTime,2, &Time, NULL); - if (EFI_ERROR (Status)) { - FreePool(NewData); - return Status; - } - Time.Pad1 = 0; - Time.Nanosecond = 0; - Time.TimeZone = 0; - Time.Daylight = 0; - Time.Pad2 = 0; - CopyMem (&DescriptorData->TimeStamp, &Time, sizeof (EFI_TIME)); - - DescriptorData->AuthInfo.Hdr.dwLength = OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData); - DescriptorData->AuthInfo.Hdr.wRevision = 0x0200; - DescriptorData->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID; - DescriptorData->AuthInfo.CertType = efi_cert_type; - - /* we're expecting an EFI signature list, so don't free the input since - * it might not be in a pool */ + EFI_STATUS efi_status; + UINT8 *NewData; + UINT8 *Payload; + UINTN PayloadSize; + EFI_VARIABLE_AUTHENTICATION_2 *DescriptorData; + UINTN DescriptorSize; + EFI_TIME Time; + + if (Data == NULL || DataSize == NULL) { + return EFI_INVALID_PARAMETER; + } + /* + * In Setup mode or Custom mode, the variable does not need to be + * signed but the + * parameters to the SetVariable() call still need to be prepared as + * authenticated variable. So we create EFI_VARIABLE_AUTHENTICATED_2 + * descriptor without certificate data in it. + */ + Payload = *Data; + PayloadSize = *DataSize; + + DescriptorSize = offsetof(EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) + + offsetof(WIN_CERTIFICATE_UEFI_GUID, CertData); + NewData = (UINT8 *) AllocateZeroPool(DescriptorSize + PayloadSize); + if (NewData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if ((Payload != NULL) && (PayloadSize != 0)) { + CopyMem(NewData + DescriptorSize, Payload, PayloadSize); + } + + DescriptorData = (EFI_VARIABLE_AUTHENTICATION_2 *) (NewData); + + ZeroMem(&Time, sizeof(EFI_TIME)); + efi_status = gRT->GetTime(&Time, NULL); + if (EFI_ERROR(efi_status)) { + FreePool(NewData); + return efi_status; + } + Time.Pad1 = 0; + Time.Nanosecond = 0; + Time.TimeZone = 0; + Time.Daylight = 0; + Time.Pad2 = 0; + CopyMem(&DescriptorData->TimeStamp, &Time, sizeof(EFI_TIME)); + + DescriptorData->AuthInfo.Hdr.dwLength = + offsetof(WIN_CERTIFICATE_UEFI_GUID, CertData); + DescriptorData->AuthInfo.Hdr.wRevision = 0x0200; + DescriptorData->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID; + DescriptorData->AuthInfo.CertType = EFI_CERT_TYPE_PKCS7_GUID; + + /* + * we're expecting an EFI signature list, so don't free the input + * since it might not be in a pool + */ #if 0 - if (Payload != NULL) { - FreePool(Payload); - } + if (Payload != NULL) { + FreePool(Payload); + } #endif - - *DataSize = DescriptorSize + PayloadSize; - *Data = NewData; - return EFI_SUCCESS; + + *DataSize = DescriptorSize + PayloadSize; + *Data = NewData; + return EFI_SUCCESS; } EFI_STATUS @@ -146,8 +140,9 @@ SetSecureVariable(CHAR16 *var, UINT8 *Data, UINTN len, EFI_GUID owner, int ds; efi_status = variable_create_esl(Data, len, &X509_GUID, NULL, (void **)&Cert, &ds); - if (efi_status != EFI_SUCCESS) { - Print(L"Failed to create %s certificate %d\n", var, efi_status); + if (EFI_ERROR(efi_status)) { + console_print(L"Failed to create %s certificate %d\n", + var, efi_status); return efi_status; } @@ -158,19 +153,18 @@ SetSecureVariable(CHAR16 *var, UINT8 *Data, UINTN len, EFI_GUID owner, DataSize = len; } efi_status = CreateTimeBasedPayload(&DataSize, (UINT8 **)&Cert); - if (efi_status != EFI_SUCCESS) { - Print(L"Failed to create time based payload %d\n", efi_status); + if (EFI_ERROR(efi_status)) { + console_print(L"Failed to create time based payload %d\n", + efi_status); return efi_status; } - efi_status = uefi_call_wrapper(RT->SetVariable, 5, var, &owner, - EFI_VARIABLE_NON_VOLATILE - | EFI_VARIABLE_RUNTIME_ACCESS - | EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS - | options, - DataSize, Cert); - + efi_status = gRT->SetVariable(var, &owner, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_RUNTIME_ACCESS | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | + options, DataSize, Cert); return efi_status; } @@ -181,8 +175,9 @@ GetOSIndications(void) UINTN DataSize = sizeof(indications); EFI_STATUS efi_status; - efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"OsIndicationsSupported", &GV_GUID, NULL, &DataSize, &indications); - if (efi_status != EFI_SUCCESS) + efi_status = gRT->GetVariable(L"OsIndicationsSupported", &GV_GUID, + NULL, &DataSize, &indications); + if (EFI_ERROR(efi_status)) return 0; return indications; @@ -194,17 +189,15 @@ SETOSIndicationsAndReboot(UINT64 indications) UINTN DataSize = sizeof(indications); EFI_STATUS efi_status; - efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"OsIndications", - &GV_GUID, - EFI_VARIABLE_NON_VOLATILE - | EFI_VARIABLE_RUNTIME_ACCESS - | EFI_VARIABLE_BOOTSERVICE_ACCESS, - DataSize, &indications); - - if (efi_status != EFI_SUCCESS) + efi_status = gRT->SetVariable(L"OsIndications", &GV_GUID, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_RUNTIME_ACCESS | + EFI_VARIABLE_BOOTSERVICE_ACCESS, + DataSize, &indications); + if (EFI_ERROR(efi_status)) return efi_status; - uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, EFI_SUCCESS, 0, NULL); + gRT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL); /* does not return */ return EFI_SUCCESS; @@ -218,19 +211,19 @@ get_variable_attr(CHAR16 *var, UINT8 **data, UINTN *len, EFI_GUID owner, *len = 0; - efi_status = uefi_call_wrapper(RT->GetVariable, 5, var, &owner, - NULL, len, NULL); - if (efi_status != EFI_BUFFER_TOO_SMALL) + efi_status = gRT->GetVariable(var, &owner, NULL, len, NULL); + if (efi_status != EFI_BUFFER_TOO_SMALL) { + if (!EFI_ERROR(efi_status)) /* this should never happen */ + return EFI_PROTOCOL_ERROR; return efi_status; + } *data = AllocateZeroPool(*len); if (!*data) return EFI_OUT_OF_RESOURCES; - - efi_status = uefi_call_wrapper(RT->GetVariable, 5, var, &owner, - attributes, len, *data); - if (efi_status != EFI_SUCCESS) { + efi_status = gRT->GetVariable(var, &owner, attributes, len, *data); + if (EFI_ERROR(efi_status)) { FreePool(*data); *data = NULL; } @@ -263,19 +256,19 @@ find_in_esl(UINT8 *Data, UINTN DataSize, UINT8 *key, UINTN keylen) EFI_STATUS find_in_variable_esl(CHAR16* var, EFI_GUID owner, UINT8 *key, UINTN keylen) { - UINTN DataSize; - UINT8 *Data; - EFI_STATUS status; + UINTN DataSize = 0; + UINT8 *Data = NULL; + EFI_STATUS efi_status; - status = get_variable(var, &Data, &DataSize, owner); - if (status != EFI_SUCCESS) - return status; + efi_status = get_variable(var, &Data, &DataSize, owner); + if (EFI_ERROR(efi_status)) + return efi_status; - status = find_in_esl(Data, DataSize, key, keylen); + efi_status = find_in_esl(Data, DataSize, key, keylen); FreePool(Data); - return status; + return efi_status; } int @@ -284,11 +277,11 @@ variable_is_setupmode(int default_return) /* set to 1 because we return true if SetupMode doesn't exist */ UINT8 SetupMode = default_return; UINTN DataSize = sizeof(SetupMode); - EFI_STATUS status; + EFI_STATUS efi_status; - status = uefi_call_wrapper(RT->GetVariable, 5, L"SetupMode", &GV_GUID, NULL, - &DataSize, &SetupMode); - if (EFI_ERROR(status)) + efi_status = gRT->GetVariable(L"SetupMode", &GV_GUID, NULL, + &DataSize, &SetupMode); + if (EFI_ERROR(efi_status)) return default_return; return SetupMode; @@ -300,12 +293,12 @@ variable_is_secureboot(void) /* return false if variable doesn't exist */ UINT8 SecureBoot = 0; UINTN DataSize; - EFI_STATUS status; + EFI_STATUS efi_status; DataSize = sizeof(SecureBoot); - status = uefi_call_wrapper(RT->GetVariable, 5, L"SecureBoot", &GV_GUID, NULL, - &DataSize, &SecureBoot); - if (EFI_ERROR(status)) + efi_status = gRT->GetVariable(L"SecureBoot", &GV_GUID, NULL, + &DataSize, &SecureBoot); + if (EFI_ERROR(efi_status)) return 0; return SecureBoot; @@ -315,14 +308,15 @@ EFI_STATUS variable_enroll_hash(CHAR16 *var, EFI_GUID owner, UINT8 hash[SHA256_DIGEST_SIZE]) { - EFI_STATUS status; + EFI_STATUS efi_status; - if (find_in_variable_esl(var, owner, hash, SHA256_DIGEST_SIZE) - == EFI_SUCCESS) + efi_status = find_in_variable_esl(var, owner, hash, SHA256_DIGEST_SIZE); + if (!EFI_ERROR(efi_status)) /* hash already present */ return EFI_ALREADY_STARTED; - UINT8 sig[sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA) - 1 + SHA256_DIGEST_SIZE]; + UINT8 sig[sizeof(EFI_SIGNATURE_LIST) + + sizeof(EFI_SIGNATURE_DATA) - 1 + SHA256_DIGEST_SIZE]; EFI_SIGNATURE_LIST *l = (void *)sig; EFI_SIGNATURE_DATA *d = (void *)sig + sizeof(EFI_SIGNATURE_LIST); SetMem(sig, 0, sizeof(sig)); @@ -330,16 +324,16 @@ variable_enroll_hash(CHAR16 *var, EFI_GUID owner, l->SignatureListSize = sizeof(sig); l->SignatureSize = 16 +32; /* UEFI defined */ CopyMem(&d->SignatureData, hash, SHA256_DIGEST_SIZE); - d->SignatureOwner = MOK_OWNER; + d->SignatureOwner = SHIM_LOCK_GUID; if (CompareGuid(&owner, &SIG_DB) == 0) - status = SetSecureVariable(var, sig, sizeof(sig), owner, - EFI_VARIABLE_APPEND_WRITE, 0); + efi_status = SetSecureVariable(var, sig, sizeof(sig), owner, + EFI_VARIABLE_APPEND_WRITE, 0); else - status = uefi_call_wrapper(RT->SetVariable, 5, var, &owner, - EFI_VARIABLE_NON_VOLATILE - | EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_APPEND_WRITE, - sizeof(sig), sig); - return status; + efi_status = gRT->SetVariable(var, &owner, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_APPEND_WRITE, + sizeof(sig), sig); + return efi_status; } |