[PATCH v7 04/17] efi_loader: variable: support variable authentication
Sughosh Ganu
sughosh.ganu at linaro.org
Mon Apr 20 21:22:33 CEST 2020
On Tue, 14 Apr 2020 at 08:23, AKASHI Takahiro <takahiro.akashi at linaro.org>
wrote:
> With this commit, EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
> is supported for authenticated variables and the system secure state
> will transfer between setup mode and user mode as UEFI specification
> section 32.3 describes.
>
> Internally, authentication data is stored as part of authenticated
> variable's value. It is nothing but a pkcs7 message (but we need some
> wrapper, see efi_variable_parse_signature()) and will be validated by
> efi_variable_authenticate(), hence efi_signature_verify_with_db().
>
> Associated time value will be encoded in "{...,time=...}" along with
> other UEFI variable's attributes.
>
> Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
> ---
> include/efi_loader.h | 3 +
> lib/efi_loader/efi_variable.c | 666 ++++++++++++++++++++++++++++------
> 2 files changed, 565 insertions(+), 104 deletions(-)
>
<snip>
> diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
> index fe2f26459136..adb78470f2d6 100644
> --- a/lib/efi_loader/efi_variable.c
> +++ b/lib/efi_loader/efi_variable.c
> @@ -10,8 +10,14 @@
> #include <env_internal.h>
> #include <hexdump.h>
> #include <malloc.h>
> +#include <rtc.h>
> #include <search.h>
> +#include <linux/compat.h>
> #include <u-boot/crc.h>
> +#include "../lib/crypto/pkcs7_parser.h"
> +
> +const efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
> +static bool efi_secure_boot;
>
> #define READ_ONLY BIT(31)
>
> @@ -106,9 +112,10 @@ static const char *prefix(const char *str, const char
> *prefix)
> *
> * @str: value of U-Boot variable
> * @attrp: pointer to UEFI attributes
> + * @timep: pointer to time attribute
> * Return: pointer to remainder of U-Boot variable value
> */
> -static const char *parse_attr(const char *str, u32 *attrp)
> +static const char *parse_attr(const char *str, u32 *attrp, u64 *timep)
> {
> u32 attr = 0;
> char sep = '{';
> @@ -131,6 +138,12 @@ static const char *parse_attr(const char *str, u32
> *attrp)
> attr |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
> } else if ((s = prefix(str, "run"))) {
> attr |= EFI_VARIABLE_RUNTIME_ACCESS;
> + } else if ((s = prefix(str, "time="))) {
> + attr |=
> EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
> + hex2bin((u8 *)timep, s, sizeof(*timep));
> + s += sizeof(*timep) * 2;
> + } else if (*str == '}') {
> + break;
> } else {
> printf("invalid attribute: %s\n", str);
> break;
> @@ -148,48 +161,291 @@ static const char *parse_attr(const char *str, u32
> *attrp)
> }
>
> /**
> - * efi_get_variable() - retrieve value of a UEFI variable
> + * efi_secure_boot_enabled - return if secure boot is enabled or not
> *
> - * This function implements the GetVariable runtime service.
> + * Return: true if enabled, false if disabled
> + */
> +bool efi_secure_boot_enabled(void)
> +{
> + return efi_secure_boot;
> +}
> +
> +#ifdef CONFIG_EFI_SECURE_BOOT
> +static u8 pkcs7_hdr[] = {
> + /* SEQUENCE */
> + 0x30, 0x82, 0x05, 0xc7,
> + /* OID: pkcs7-signedData */
> + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02,
> + /* Context Structured? */
> + 0xa0, 0x82, 0x05, 0xb8,
> +};
> +
> +/**
> + * efi_variable_parse_signature - parse a signature in variable
> + * @buf: Pointer to variable's value
> + * @buflen: Length of @buf
> *
> - * See the Unified Extensible Firmware Interface (UEFI) specification for
> - * details.
> + * Parse a signature embedded in variable's value and instantiate
> + * a pkcs7_message structure. Since pkcs7_parse_message() accepts only
> + * pkcs7's signedData, some header needed be prepended for correctly
> + * parsing authentication data, particularly for variable's.
> *
> - * @variable_name: name of the variable
> - * @vendor: vendor GUID
> - * @attributes: attributes of the variable
> - * @data_size: size of the buffer to which the variable value is
> copied
> - * @data: buffer to which the variable value is copied
> - * Return: status code
> + * Return: Pointer to pkcs7_message structure on success, NULL on
> error
> */
> -efi_status_t EFIAPI efi_get_variable(u16 *variable_name,
> - const efi_guid_t *vendor, u32
> *attributes,
> - efi_uintn_t *data_size, void *data)
> +static struct pkcs7_message *efi_variable_parse_signature(const void *buf,
> + size_t buflen)
>
This is a generic function used for parsing the pkcs7 header. This will
also be used for capsule authentication. Can you move this under
efi_signature.c as an api, and change the name to something like
efi_parse_pkcs7_header.
-sughosh
More information about the U-Boot
mailing list