diff --git a/include/efi_variable.h b/include/efi_variable.h index 5eec407a2b689c5043e51e39fc2215346afa6d8a..021a74f309b0996ad92edf969e4835487ec129fe 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 36e31b4d4548156e6a7b9abfaa69e2b28f494346..ee2e67bc8cbf59fa4bcc6c79d6408988b788bae1 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 64dc3d6df95b215b59cd72a0f440fcebfa98f0a2..ecbc4f7f542decc5c680fda727ceee4a0eccd6ac 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;