efi_loader: identify PK, KEK, db, dbx correctly
authorHeinrich Schuchardt <xypron.glpk@gmx.de>
Wed, 15 Jul 2020 10:40:35 +0000 (12:40 +0200)
committerHeinrich Schuchardt <xypron.glpk@gmx.de>
Thu, 16 Jul 2020 10:37:02 +0000 (12:37 +0200)
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 <xypron.glpk@gmx.de>
include/efi_variable.h
lib/efi_loader/efi_var_common.c
lib/efi_loader/efi_variable.c

index 5eec407..021a74f 100644 (file)
 
 #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
index 36e31b4..ee2e67b 100644 (file)
@@ -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;
+}
index 64dc3d6..ecbc4f7 100644 (file)
@@ -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;