From 99bfab8b5832273d66d724f906be43fe5bd7c1ba Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 15 Jul 2020 12:40:35 +0200 Subject: [PATCH] efi_loader: identify PK, KEK, db, dbx correctly To determine if a varible is on the of the authentication variables PK, KEK, db, dbx we have to check both the name and the GUID. Provide a function converting the variable-name/guid pair to an enum and use it consistently. Signed-off-by: Heinrich Schuchardt --- include/efi_variable.h | 19 +++++++++++++++++++ lib/efi_loader/efi_var_common.c | 27 +++++++++++++++++++++++++++ lib/efi_loader/efi_variable.c | 27 ++++++++++++++------------- 3 files changed, 60 insertions(+), 13 deletions(-) diff --git a/include/efi_variable.h b/include/efi_variable.h index 5eec407..021a74f 100644 --- a/include/efi_variable.h +++ b/include/efi_variable.h @@ -10,6 +10,16 @@ #define EFI_VARIABLE_READ_ONLY BIT(31) +enum efi_auth_var_type { + EFI_AUTH_VAR_NONE = 0, + EFI_AUTH_VAR_PK, + EFI_AUTH_VAR_KEK, + EFI_AUTH_VAR_DB, + EFI_AUTH_VAR_DBX, + EFI_AUTH_VAR_DBT, + EFI_AUTH_VAR_DBR, +}; + /** * efi_get_variable() - retrieve value of a UEFI variable * @@ -202,4 +212,13 @@ u64 efi_var_mem_free(void); */ efi_status_t efi_init_secure_state(void); +/** + * efi_auth_var_get_type() - convert variable name and guid to enum + * + * @name: name of UEFI variable + * @guid: guid of UEFI variable + * Return: identifier for authentication related variables + */ +enum efi_auth_var_type efi_auth_var_get_type(u16 *name, const efi_guid_t *guid); + #endif diff --git a/lib/efi_loader/efi_var_common.c b/lib/efi_loader/efi_var_common.c index 36e31b4..ee2e67b 100644 --- a/lib/efi_loader/efi_var_common.c +++ b/lib/efi_loader/efi_var_common.c @@ -16,6 +16,23 @@ enum efi_secure_mode { EFI_MODE_DEPLOYED, }; +struct efi_auth_var_name_type { + const u16 *name; + const efi_guid_t *guid; + const enum efi_auth_var_type type; +}; + +static const struct efi_auth_var_name_type name_type[] = { + {u"PK", &efi_global_variable_guid, EFI_AUTH_VAR_PK}, + {u"KEK", &efi_global_variable_guid, EFI_AUTH_VAR_KEK}, + {u"db", &efi_guid_image_security_database, EFI_AUTH_VAR_DB}, + {u"dbx", &efi_guid_image_security_database, EFI_AUTH_VAR_DBX}, + /* not used yet + {u"dbt", &efi_guid_image_security_database, EFI_AUTH_VAR_DBT}, + {u"dbr", &efi_guid_image_security_database, EFI_AUTH_VAR_DBR}, + */ +}; + static bool efi_secure_boot; static enum efi_secure_mode efi_secure_mode; @@ -293,3 +310,13 @@ bool efi_secure_boot_enabled(void) { return efi_secure_boot; } + +enum efi_auth_var_type efi_auth_var_get_type(u16 *name, const efi_guid_t *guid) +{ + for (size_t i = 0; i < ARRAY_SIZE(name_type); ++i) { + if (!u16_strcmp(name, name_type[i].name) && + !guidcmp(guid, name_type[i].guid)) + return name_type[i].type; + } + return EFI_AUTH_VAR_NONE; +} diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index 64dc3d6..ecbc4f7 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -133,6 +133,7 @@ static efi_status_t efi_variable_authenticate(u16 *variable, struct efi_time timestamp; struct rtc_time tm; u64 new_time; + enum efi_auth_var_type var_type; efi_status_t ret; var_sig = NULL; @@ -209,18 +210,20 @@ static efi_status_t efi_variable_authenticate(u16 *variable, } /* signature database used for authentication */ - if (u16_strcmp(variable, L"PK") == 0 || - u16_strcmp(variable, L"KEK") == 0) { + var_type = efi_auth_var_get_type(variable, vendor); + switch (var_type) { + case EFI_AUTH_VAR_PK: + case EFI_AUTH_VAR_KEK: /* with PK */ truststore = efi_sigstore_parse_sigdb(L"PK"); if (!truststore) goto err; - } else if (u16_strcmp(variable, L"db") == 0 || - u16_strcmp(variable, L"dbx") == 0) { + break; + case EFI_AUTH_VAR_DB: + case EFI_AUTH_VAR_DBX: /* with PK and KEK */ truststore = efi_sigstore_parse_sigdb(L"KEK"); truststore2 = efi_sigstore_parse_sigdb(L"PK"); - if (!truststore) { if (!truststore2) goto err; @@ -228,7 +231,8 @@ static efi_status_t efi_variable_authenticate(u16 *variable, truststore = truststore2; truststore2 = NULL; } - } else { + break; + default: /* TODO: support private authenticated variables */ goto err; } @@ -347,6 +351,7 @@ efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor, efi_uintn_t ret; bool append, delete; u64 time = 0; + enum efi_auth_var_type var_type; if (!variable_name || !*variable_name || !vendor || ((attributes & EFI_VARIABLE_RUNTIME_ACCESS) && @@ -381,12 +386,8 @@ efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor, return EFI_NOT_FOUND; } - if (((!u16_strcmp(variable_name, L"PK") || - !u16_strcmp(variable_name, L"KEK")) && - !guidcmp(vendor, &efi_global_variable_guid)) || - ((!u16_strcmp(variable_name, L"db") || - !u16_strcmp(variable_name, L"dbx")) && - !guidcmp(vendor, &efi_guid_image_security_database))) { + var_type = efi_auth_var_get_type(variable_name, vendor); + if (var_type != EFI_AUTH_VAR_NONE) { /* authentication is mandatory */ if (!(attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) { @@ -445,7 +446,7 @@ efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor, if (ret != EFI_SUCCESS) return ret; - if (!u16_strcmp(variable_name, L"PK")) + if (var_type == EFI_AUTH_VAR_PK) ret = efi_init_secure_state(); else ret = EFI_SUCCESS; -- 2.7.4