[PATCH v2 5/6] efi_loader: writing AuditMode, DeployedMode

Heinrich Schuchardt xypron.glpk at gmx.de
Fri Aug 27 06:09:25 CEST 2021


On 8/27/21 5:05 AM, AKASHI Takahiro wrote:
> Heinrich,
>
> On Thu, Aug 26, 2021 at 03:48:04PM +0200, Heinrich Schuchardt wrote:
>> Writing variables AuditMode or Deployed Mode must update the secure boot
>> state.
>>
>> Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
>> ---
>> v2:
>> 	correct variable name in lib/efi_loader/efi_variable_tee.c
>> ---
>>   include/efi_variable.h            | 1 +
>>   lib/efi_loader/efi_var_common.c   | 2 ++
>>   lib/efi_loader/efi_variable.c     | 6 +++---
>>   lib/efi_loader/efi_variable_tee.c | 4 +++-
>>   4 files changed, 9 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/efi_variable.h b/include/efi_variable.h
>> index 2d97655e1f..0440d356bc 100644
>> --- a/include/efi_variable.h
>> +++ b/include/efi_variable.h
>> @@ -12,6 +12,7 @@
>>
>>   enum efi_auth_var_type {
>>   	EFI_AUTH_VAR_NONE = 0,
>> +	EFI_AUTH_MODE,
>>   	EFI_AUTH_VAR_PK,
>>   	EFI_AUTH_VAR_KEK,
>>   	EFI_AUTH_VAR_DB,
>> diff --git a/lib/efi_loader/efi_var_common.c b/lib/efi_loader/efi_var_common.c
>> index 63ad6fea9e..6fabcfe72c 100644
>> --- a/lib/efi_loader/efi_var_common.c
>> +++ b/lib/efi_loader/efi_var_common.c
>> @@ -34,6 +34,8 @@ static const struct efi_auth_var_name_type name_type[] = {
>>   	{u"dbx",  &efi_guid_image_security_database, EFI_AUTH_VAR_DBX},
>>   	{u"dbt",  &efi_guid_image_security_database, EFI_AUTH_VAR_DBT},
>>   	{u"dbr",  &efi_guid_image_security_database, EFI_AUTH_VAR_DBR},
>> +	{u"AuditMode", &efi_global_variable_guid, EFI_AUTH_MODE},
>> +	{u"DeployedMode", &efi_global_variable_guid, EFI_AUTH_MODE},
>>   };
>>
>>   static bool efi_secure_boot;
>> diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
>> index a7d305ffbc..80996d0f47 100644
>> --- a/lib/efi_loader/efi_variable.c
>> +++ b/lib/efi_loader/efi_variable.c
>> @@ -247,7 +247,7 @@ efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor,
>>   			return EFI_WRITE_PROTECTED;
>>
>>   		if (IS_ENABLED(CONFIG_EFI_VARIABLES_PRESEED)) {
>> -			if (var_type != EFI_AUTH_VAR_NONE)
>> +			if (var_type >= EFI_AUTH_VAR_PK)
>
> This change is irrelevant to the purpose of this commit.

Thank you for reviewing the series.

EFI_AUTH_MODE is needed in the implementation of this patch and requires
this change. But I can split the patch in two.

>
>>   				return EFI_WRITE_PROTECTED;
>>   		}
>>
>> @@ -268,7 +268,7 @@ efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor,
>>   			return EFI_NOT_FOUND;
>>   	}
>>
>> -	if (var_type != EFI_AUTH_VAR_NONE) {
>> +	if (var_type >= EFI_AUTH_VAR_PK) {
>>   		/* authentication is mandatory */
>>   		if (!(attributes &
>>   		      EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) {
>> @@ -328,7 +328,7 @@ efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor,
>>   	if (ret != EFI_SUCCESS)
>>   		return ret;
>>
>> -	if (var_type == EFI_AUTH_VAR_PK)
>> +	if (var_type == EFI_AUTH_VAR_PK || var_type == EFI_AUTH_MODE)
>>   		ret = efi_init_secure_state();
>
> As I said, calling efi_init_secure_state() is not a good idea.
>
> The scheme that I have in mind:
> * if some event takes place, then trigger the transition.
> * efi_transfer_secure_state() handles/take actions for the transition.
>
> Looking at "Figure 32-4 Secure Boot Modes", there are a couple of events
> defined:
> 1) Enroll PKpub
> 2) Platform Specific PKpub Clear/Delete PKpub
> 3) Audit := 1
> 4) DeployedMode := 1
> 5) Platform Specific DeployedMode Clear
>
> (Please note that "enroll/platform specific" operations should end up
> modifying a relevant UEFI variable, any way.)
>
> So, in the case above, we should do like this:
>    if ("PK" is added/modified)
>       if (SetupMode)
>          efi_transfer_secure_state(UserMode)
>       else (AuditMode)
>          efi_transfer_secure_state(DeployedMode)
>    else if ("AuditMode" is set)
>       if (SetupMode || UserMode)
>          efi_transfer_secure_state(AuditMode)
>    else if
>       and so on

Here we are in efi_set_variable_int(). efi_transfer_secure_state()
itself calls efi_set_variable_int() repeatedly.

Hence we need a way for a user to call SetVariable() with the side
effects you described above and a way to alter the state variables
without side effects.

There are different ways to implement this:

1) As we are on a single threaded system we can use a static
    state variable. This is the approach in patch 1.
2) We can add a parameter to efi_set_variable_int() indicating that
    the variable change shall not have side effects.
3) We can carve out a function for setting a variable without side
    effects.

We have two implementations of efi_set_variable_int():

* One for file based variables in lib/efi_loader/efi_variable.c.
* Another for StMM based variables in lib/efi_loader/efi_variable_tee.c.

Whatever we do must work for both implementations of variables.

lib/efi_loader/efi_variable_tee.c has two calls to
efi_init_secure_state() currently matching the calls in
lib/efi_loader/efi_variable.c.

@Ilias:
Which part of the logic described in Figure 32-4 Secure Boot Modes of
UEFI spec 2.9 exists inside StMM?
Where is it coded?

Best regards

Heinrich

>
> The logic is clear and the code directly renders what the figure 32-4 shows.
> What's more, it will make it much easier for reviewers (and users)
> to confirm the code is fully compliant with the specification
> in terms of the "conditions" vs. resultant system status.
>
> Then, each of the system's secure status can be always maintained
> within efi_transfer_secure_state().
>
> In addition, we will not have to have a hacky "lock" in
> efi_init_secure_state().
>
> Those are the reason why I want to stick to the scheme above.
>
> -Takahiro Akashi
>
>
>>   	else
>>   		ret = EFI_SUCCESS;
>> diff --git a/lib/efi_loader/efi_variable_tee.c b/lib/efi_loader/efi_variable_tee.c
>> index 51920bcb51..a6d5752045 100644
>> --- a/lib/efi_loader/efi_variable_tee.c
>> +++ b/lib/efi_loader/efi_variable_tee.c
>> @@ -512,6 +512,7 @@ efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor,
>>   	efi_uintn_t payload_size;
>>   	efi_uintn_t name_size;
>>   	u8 *comm_buf = NULL;
>> +	enum efi_auth_var_type var_type;
>>   	bool ro;
>>
>>   	if (!variable_name || variable_name[0] == 0 || !vendor) {
>> @@ -590,7 +591,8 @@ efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor,
>>   	if (alt_ret != EFI_SUCCESS)
>>   		goto out;
>>
>> -	if (!u16_strcmp(variable_name, L"PK"))
>> +	var_type = efi_auth_var_get_type(variable_name, vendor);
>> +	if (var_type == EFI_AUTH_VAR_PK || var_type == EFI_AUTH_MODE)
>>   		alt_ret = efi_init_secure_state();
>>   out:
>>   	free(comm_buf);
>> --
>> 2.30.2
>>



More information about the U-Boot mailing list