diff mbox series

eficonfig: EFI_VARIABLE_APPEND_WRITE is not set for null key

Message ID 20221219151257.23623-1-masahisa.kojima@linaro.org
State Superseded
Headers show
Series eficonfig: EFI_VARIABLE_APPEND_WRITE is not set for null key | expand

Commit Message

Masahisa Kojima Dec. 19, 2022, 3:12 p.m. UTC
The signed null key with authenticated header is used to clear
the PK, KEK, db and dbx. When CONFIG_EFI_MM_COMM_TEE is enabled
(StMM and OP-TEE based RPMB storage is used as the EFI variable
storage), clearing KEK, db and dbx by enrolling a signed null
key does not work as expected if EFI_VARIABLE_APPEND_WRITE
attritube is set.

This commit checks the selected file is null key, then
EFI_VARIABLE_APPEND_WRITE attibute will not be used for the null key.

Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
---
 cmd/eficonfig_sbkey.c | 40 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)

Comments

Ilias Apalodimas Dec. 20, 2022, 6:56 a.m. UTC | #1
On Tue, Dec 20, 2022 at 12:12:56AM +0900, Masahisa Kojima wrote:
> The signed null key with authenticated header is used to clear
> the PK, KEK, db and dbx. When CONFIG_EFI_MM_COMM_TEE is enabled
> (StMM and OP-TEE based RPMB storage is used as the EFI variable
> storage), clearing KEK, db and dbx by enrolling a signed null
> key does not work as expected if EFI_VARIABLE_APPEND_WRITE
> attritube is set.
>
> This commit checks the selected file is null key, then
> EFI_VARIABLE_APPEND_WRITE attibute will not be used for the null key.
>
> Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
> ---
>  cmd/eficonfig_sbkey.c | 40 ++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 38 insertions(+), 2 deletions(-)
>
> diff --git a/cmd/eficonfig_sbkey.c b/cmd/eficonfig_sbkey.c
> index 6e0bebf1d4..bd2671bf8f 100644
> --- a/cmd/eficonfig_sbkey.c
> +++ b/cmd/eficonfig_sbkey.c
> @@ -72,6 +72,30 @@ static bool file_have_auth_header(void *buf, efi_uintn_t size)
>  	return true;
>  }
>
> +/**
> + * file_is_null_key() - check the file is an authenticated and signed null key
> + * @auth:	pointer to the file
> + * @size:	file size
> + * @null_key:	pointer to store the result
> + * Return:	status code
> + */
> +static efi_status_t file_is_null_key(struct efi_variable_authentication_2 *auth,
> +				     efi_uintn_t size, bool *null_key)
> +{
> +	efi_status_t ret = EFI_SUCCESS;
> +
> +	if (size < (sizeof(auth->time_stamp) + auth->auth_info.hdr.dwLength))
> +		return EFI_INVALID_PARAMETER;
> +
> +	size -= (sizeof(auth->time_stamp) + auth->auth_info.hdr.dwLength);
> +	if (size == 0) /* No payload */

s/size == 0/!size

> +		*null_key = true;
> +	else
> +		*null_key = false;
> +
> +	return ret;
> +}
> +
>  /**
>   * eficonfig_process_enroll_key() - enroll key into signature database
>   *
> @@ -84,6 +108,7 @@ static efi_status_t eficonfig_process_enroll_key(void *data)
>  	char *buf = NULL;
>  	efi_uintn_t size;
>  	efi_status_t ret;
> +	bool null_key = false;
>  	struct efi_file_handle *f = NULL;
>  	struct efi_device_path *full_dp = NULL;
>  	struct eficonfig_select_file_info file_info;
> @@ -149,13 +174,24 @@ static efi_status_t eficonfig_process_enroll_key(void *data)
>  		goto out;
>  	}
>
> +	ret = file_is_null_key((struct efi_variable_authentication_2 *)buf,
> +			       size, &null_key);
> +	if (ret != EFI_SUCCESS) {
> +		eficonfig_print_msg("ERROR! Invalid file format.");
> +		goto out;
> +	}
> +
>  	attr = EFI_VARIABLE_NON_VOLATILE |
>  	       EFI_VARIABLE_BOOTSERVICE_ACCESS |
>  	       EFI_VARIABLE_RUNTIME_ACCESS |
>  	       EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
>
> -	/* PK can enroll only one certificate */
> -	if (u16_strcmp(data, u"PK")) {
> +	/*
> +	 * PK can enroll only one certificate.
> +	 * The signed null key is used to clear KEK, db and dbx.
> +	 * EFI_VARIABLE_APPEND_WRITE attribute must not be set in these cases.
> +	 */
> +	if (u16_strcmp(data, u"PK") && !null_key) {
>  		efi_uintn_t db_size = 0;
>
>  		/* check the variable exists. If exists, add APPEND_WRITE attribute */
> --
> 2.17.1
>

Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Masahisa Kojima Dec. 20, 2022, 10:20 a.m. UTC | #2
Hi Ilias,

On Tue, 20 Dec 2022 at 15:56, Ilias Apalodimas
<ilias.apalodimas@linaro.org> wrote:
>
> On Tue, Dec 20, 2022 at 12:12:56AM +0900, Masahisa Kojima wrote:
> > The signed null key with authenticated header is used to clear
> > the PK, KEK, db and dbx. When CONFIG_EFI_MM_COMM_TEE is enabled
> > (StMM and OP-TEE based RPMB storage is used as the EFI variable
> > storage), clearing KEK, db and dbx by enrolling a signed null
> > key does not work as expected if EFI_VARIABLE_APPEND_WRITE
> > attritube is set.
> >
> > This commit checks the selected file is null key, then
> > EFI_VARIABLE_APPEND_WRITE attibute will not be used for the null key.
> >
> > Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
> > ---
> >  cmd/eficonfig_sbkey.c | 40 ++++++++++++++++++++++++++++++++++++++--
> >  1 file changed, 38 insertions(+), 2 deletions(-)
> >
> > diff --git a/cmd/eficonfig_sbkey.c b/cmd/eficonfig_sbkey.c
> > index 6e0bebf1d4..bd2671bf8f 100644
> > --- a/cmd/eficonfig_sbkey.c
> > +++ b/cmd/eficonfig_sbkey.c
> > @@ -72,6 +72,30 @@ static bool file_have_auth_header(void *buf, efi_uintn_t size)
> >       return true;
> >  }
> >
> > +/**
> > + * file_is_null_key() - check the file is an authenticated and signed null key
> > + * @auth:    pointer to the file
> > + * @size:    file size
> > + * @null_key:        pointer to store the result
> > + * Return:   status code
> > + */
> > +static efi_status_t file_is_null_key(struct efi_variable_authentication_2 *auth,
> > +                                  efi_uintn_t size, bool *null_key)
> > +{
> > +     efi_status_t ret = EFI_SUCCESS;
> > +
> > +     if (size < (sizeof(auth->time_stamp) + auth->auth_info.hdr.dwLength))
> > +             return EFI_INVALID_PARAMETER;
> > +
> > +     size -= (sizeof(auth->time_stamp) + auth->auth_info.hdr.dwLength);
> > +     if (size == 0) /* No payload */
>
> s/size == 0/!size

OK.

Thank you for your review.

Regards,
Masahisa Kojima

>
> > +             *null_key = true;
> > +     else
> > +             *null_key = false;
> > +
> > +     return ret;
> > +}
> > +
> >  /**
> >   * eficonfig_process_enroll_key() - enroll key into signature database
> >   *
> > @@ -84,6 +108,7 @@ static efi_status_t eficonfig_process_enroll_key(void *data)
> >       char *buf = NULL;
> >       efi_uintn_t size;
> >       efi_status_t ret;
> > +     bool null_key = false;
> >       struct efi_file_handle *f = NULL;
> >       struct efi_device_path *full_dp = NULL;
> >       struct eficonfig_select_file_info file_info;
> > @@ -149,13 +174,24 @@ static efi_status_t eficonfig_process_enroll_key(void *data)
> >               goto out;
> >       }
> >
> > +     ret = file_is_null_key((struct efi_variable_authentication_2 *)buf,
> > +                            size, &null_key);
> > +     if (ret != EFI_SUCCESS) {
> > +             eficonfig_print_msg("ERROR! Invalid file format.");
> > +             goto out;
> > +     }
> > +
> >       attr = EFI_VARIABLE_NON_VOLATILE |
> >              EFI_VARIABLE_BOOTSERVICE_ACCESS |
> >              EFI_VARIABLE_RUNTIME_ACCESS |
> >              EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
> >
> > -     /* PK can enroll only one certificate */
> > -     if (u16_strcmp(data, u"PK")) {
> > +     /*
> > +      * PK can enroll only one certificate.
> > +      * The signed null key is used to clear KEK, db and dbx.
> > +      * EFI_VARIABLE_APPEND_WRITE attribute must not be set in these cases.
> > +      */
> > +     if (u16_strcmp(data, u"PK") && !null_key) {
> >               efi_uintn_t db_size = 0;
> >
> >               /* check the variable exists. If exists, add APPEND_WRITE attribute */
> > --
> > 2.17.1
> >
>
> Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
>
diff mbox series

Patch

diff --git a/cmd/eficonfig_sbkey.c b/cmd/eficonfig_sbkey.c
index 6e0bebf1d4..bd2671bf8f 100644
--- a/cmd/eficonfig_sbkey.c
+++ b/cmd/eficonfig_sbkey.c
@@ -72,6 +72,30 @@  static bool file_have_auth_header(void *buf, efi_uintn_t size)
 	return true;
 }
 
+/**
+ * file_is_null_key() - check the file is an authenticated and signed null key
+ * @auth:	pointer to the file
+ * @size:	file size
+ * @null_key:	pointer to store the result
+ * Return:	status code
+ */
+static efi_status_t file_is_null_key(struct efi_variable_authentication_2 *auth,
+				     efi_uintn_t size, bool *null_key)
+{
+	efi_status_t ret = EFI_SUCCESS;
+
+	if (size < (sizeof(auth->time_stamp) + auth->auth_info.hdr.dwLength))
+		return EFI_INVALID_PARAMETER;
+
+	size -= (sizeof(auth->time_stamp) + auth->auth_info.hdr.dwLength);
+	if (size == 0) /* No payload */
+		*null_key = true;
+	else
+		*null_key = false;
+
+	return ret;
+}
+
 /**
  * eficonfig_process_enroll_key() - enroll key into signature database
  *
@@ -84,6 +108,7 @@  static efi_status_t eficonfig_process_enroll_key(void *data)
 	char *buf = NULL;
 	efi_uintn_t size;
 	efi_status_t ret;
+	bool null_key = false;
 	struct efi_file_handle *f = NULL;
 	struct efi_device_path *full_dp = NULL;
 	struct eficonfig_select_file_info file_info;
@@ -149,13 +174,24 @@  static efi_status_t eficonfig_process_enroll_key(void *data)
 		goto out;
 	}
 
+	ret = file_is_null_key((struct efi_variable_authentication_2 *)buf,
+			       size, &null_key);
+	if (ret != EFI_SUCCESS) {
+		eficonfig_print_msg("ERROR! Invalid file format.");
+		goto out;
+	}
+
 	attr = EFI_VARIABLE_NON_VOLATILE |
 	       EFI_VARIABLE_BOOTSERVICE_ACCESS |
 	       EFI_VARIABLE_RUNTIME_ACCESS |
 	       EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
 
-	/* PK can enroll only one certificate */
-	if (u16_strcmp(data, u"PK")) {
+	/*
+	 * PK can enroll only one certificate.
+	 * The signed null key is used to clear KEK, db and dbx.
+	 * EFI_VARIABLE_APPEND_WRITE attribute must not be set in these cases.
+	 */
+	if (u16_strcmp(data, u"PK") && !null_key) {
 		efi_uintn_t db_size = 0;
 
 		/* check the variable exists. If exists, add APPEND_WRITE attribute */