Passing signature size to the tools looks very clumsy. How does the
user know the signature size? Can we somehow determine it
programmatically ourselves?

On Wed, Dec 18, 2024 at 5:58 PM Sudhakar Kuppusamy
<sudha...@linux.ibm.com> wrote:
>
> From: Rashmica Gupta <rashmic...@gmail.com>
>
> Add infrastructure to allow firmware to verify the integrity of grub
> by use of a Linux-kernel-module-style appended signature. We initially
> target powerpc-ieee1275, but the code should be extensible to other
> platforms.
>
> Usually these signatures are appended to a file without modifying the
> ELF file itself. (This is what the 'sign-file' tool does, for example.)
> The verifier loads the signed file from the file system and looks at the
> end of the file for the appended signature. However, on powerpc-ieee1275
> platforms, the bootloader is often stored directly in the PReP partition
> as raw bytes without a file-system. This makes determining the location
> of an appended signature more difficult.
>
> To address this, we add a new ELF note.
>
> The name field of shall be the string "Appended-Signature", zero-padded
> to 4 byte alignment. The type field shall be 0x41536967 (the ASCII values
> for the string "ASig"). It must be the final section in the ELF binary.
>
> The description shall contain the appended signature structure as defined
> by the Linux kernel. The description will also be padded to be a multiple
> of 4 bytes. The padding shall be added before the appended signature
> structure (not at the end) so that the final bytes of a signed ELF file
> are the appended signature magic.
>
> A subsequent patch documents how to create a grub core.img validly signed
> under this scheme.
>
> Signed-off-by: Rashmica Gupta <rashmic...@gmail.com>
> Signed-off-by: Daniel Axtens <d...@axtens.net>
> Signed-off-by: Sudhakar Kuppusamy <sudha...@linux.ibm.com>
> ---
>  include/grub/util/install.h |  7 +++++--
>  include/grub/util/mkimage.h |  4 ++--
>  util/grub-install-common.c  | 15 ++++++++++++---
>  util/grub-mkimage.c         | 11 +++++++++++
>  util/grub-mkimagexx.c       | 38 ++++++++++++++++++++++++++++++++++++-
>  util/mkimage.c              |  6 +++---
>  6 files changed, 70 insertions(+), 11 deletions(-)
>
> diff --git a/include/grub/util/install.h b/include/grub/util/install.h
> index 5c0a52ca2..3aabc4285 100644
> --- a/include/grub/util/install.h
> +++ b/include/grub/util/install.h
> @@ -69,6 +69,8 @@
>        N_("disable shim_lock verifier"), 0 },                           \
>    { "disable-cli", GRUB_INSTALL_OPTIONS_DISABLE_CLI, 0, 0,             \
>      N_("disabled command line interface access"), 0 },                 \
> +  { "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE, 
>  \
> +    "SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended 
> signature"), 1}, \
>    { "verbose", 'v', 0, 0,                                              \
>      N_("print verbose messages."), 1 }
>
> @@ -132,7 +134,8 @@ enum grub_install_options {
>    GRUB_INSTALL_OPTIONS_DTB,
>    GRUB_INSTALL_OPTIONS_SBAT,
>    GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK,
> -  GRUB_INSTALL_OPTIONS_DISABLE_CLI
> +  GRUB_INSTALL_OPTIONS_DISABLE_CLI,
> +  GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE
>  };
>
>  extern char *grub_install_source_directory;
> @@ -192,7 +195,7 @@ grub_install_generate_image (const char *dir, const char 
> *prefix,
>                              size_t npubkeys,
>                              char *config_path,
>                              const struct grub_install_image_target_desc 
> *image_target,
> -                            int note,
> +                            int note, size_t appsig_size,
>                              grub_compression_t comp, const char *dtb_file,
>                              const char *sbat_path, const int 
> disable_shim_lock,
>                              const int disable_cli);
> diff --git a/include/grub/util/mkimage.h b/include/grub/util/mkimage.h
> index 9d74f82c5..0d40383eb 100644
> --- a/include/grub/util/mkimage.h
> +++ b/include/grub/util/mkimage.h
> @@ -51,12 +51,12 @@ grub_mkimage_load_image64 (const char *kernel_path,
>                            const struct grub_install_image_target_desc 
> *image_target);
>  void
>  grub_mkimage_generate_elf32 (const struct grub_install_image_target_desc 
> *image_target,
> -                            int note, char *sbat, char **core_img, size_t 
> *core_size,
> +                            int note, char *sbat, size_t appsig_size, char 
> **core_img, size_t *core_size,
>                              Elf32_Addr target_addr,
>                              struct grub_mkimage_layout *layout);
>  void
>  grub_mkimage_generate_elf64 (const struct grub_install_image_target_desc 
> *image_target,
> -                            int note, char *sbat, char **core_img, size_t 
> *core_size,
> +                            int note, char *sbat, size_t appsig_size, char 
> **core_img, size_t *core_size,
>                              Elf64_Addr target_addr,
>                              struct grub_mkimage_layout *layout);
>
> diff --git a/util/grub-install-common.c b/util/grub-install-common.c
> index 22bccb6a3..22f0e56cb 100644
> --- a/util/grub-install-common.c
> +++ b/util/grub-install-common.c
> @@ -467,10 +467,12 @@ static char *sbat;
>  static int disable_shim_lock;
>  static grub_compression_t compression;
>  static int disable_cli;
> +static size_t appsig_size;
>
>  int
>  grub_install_parse (int key, char *arg)
>  {
> +  const char *end;
>    switch (key)
>      {
>      case GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS:
> @@ -571,6 +573,12 @@ grub_install_parse (int key, char *arg)
>        grub_util_error (_("Unrecognized compression `%s'"), arg);
>      case GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE:
>        return 1;
> +    case GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE:
> +      grub_errno = 0;
> +      appsig_size = grub_strtol (arg, &end, 10);
> +      if (grub_errno)
> +        return 0;
> +      return 1;
>      default:
>        return 0;
>      }
> @@ -683,9 +691,10 @@ grub_install_make_image_wrap_file (const char *dir, 
> const char *prefix,
>    *p = '\0';
>
>    grub_util_info ("grub-mkimage --directory '%s' --prefix '%s' --output '%s'"
> -                 " --format '%s' --compression '%s'%s%s%s%s\n",
> +                 " --format '%s' --compression '%s'"
> +                 " --appended-signature-size %zu %s %s %s %s\n",
>                   dir, prefix, outname,
> -                 mkimage_target, compnames[compression],
> +                 mkimage_target, compnames[compression], appsig_size,
>                   note ? " --note" : "",
>                   disable_shim_lock ? " --disable-shim-lock" : "",
>                   disable_cli ? " --disable-cli" : "", s);
> @@ -698,7 +707,7 @@ grub_install_make_image_wrap_file (const char *dir, const 
> char *prefix,
>    grub_install_generate_image (dir, prefix, fp, outname,
>                                modules.entries, memdisk_path,
>                                pubkeys, npubkeys, config_path, tgt,
> -                              note, compression, dtb, sbat,
> +                              note, appsig_size, compression, dtb, sbat,
>                                disable_shim_lock, disable_cli);
>    while (dc--)
>      grub_install_pop_module ();
> diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
> index 547f7310f..6c5063ac2 100644
> --- a/util/grub-mkimage.c
> +++ b/util/grub-mkimage.c
> @@ -84,6 +84,7 @@ static struct argp_option options[] = {
>    {"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0},
>    {"disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, 
> N_("disable shim_lock verifier"), 0},
>    {"disable-cli", GRUB_INSTALL_OPTIONS_DISABLE_CLI, 0, 0, N_("disable 
> command line interface access"), 0},
> +  {"appended-signature-size", 'S', N_("SIZE"), 0, N_("Add a note segment 
> reserving SIZE bytes for an appended signature"), 0},
>    {"verbose",     'v', 0,      0, N_("print verbose messages."), 0},
>    { 0, 0, 0, 0, 0, 0 }
>  };
> @@ -130,6 +131,7 @@ struct arguments
>    int note;
>    int disable_shim_lock;
>    int disable_cli;
> +  size_t appsig_size;
>    const struct grub_install_image_target_desc *image_target;
>    grub_compression_t comp;
>  };
> @@ -140,6 +142,7 @@ argp_parser (int key, char *arg, struct argp_state *state)
>    /* Get the input argument from argp_parse, which we
>       know is a pointer to our arguments structure. */
>    struct arguments *arguments = state->input;
> +  const char* end;
>
>    switch (key)
>      {
> @@ -172,6 +175,13 @@ argp_parser (int key, char *arg, struct argp_state 
> *state)
>        arguments->note = 1;
>        break;
>
> +    case 'S':
> +      grub_errno = 0;
> +      arguments->appsig_size = grub_strtol (arg, &end, 10);
> +      if (grub_errno)
> +        return 0;
> +      break;
> +
>      case 'm':
>        if (arguments->memdisk)
>         free (arguments->memdisk);
> @@ -330,6 +340,7 @@ main (int argc, char *argv[])
>                                arguments.memdisk, arguments.pubkeys,
>                                arguments.npubkeys, arguments.config,
>                                arguments.image_target, arguments.note,
> +                              arguments.appsig_size,
>                                arguments.comp, arguments.dtb,
>                                arguments.sbat, arguments.disable_shim_lock,
>                                arguments.disable_cli);
> diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
> index 448862b2e..6fe348e5b 100644
> --- a/util/grub-mkimagexx.c
> +++ b/util/grub-mkimagexx.c
> @@ -115,6 +115,14 @@ struct grub_sbat_note {
>    char name[ALIGN_UP(sizeof(GRUB_SBAT_NOTE_NAME), 4)];
>  };
>
> +#define GRUB_APPENDED_SIGNATURE_NOTE_NAME "Appended-Signature"
> +#define GRUB_APPENDED_SIGNATURE_NOTE_TYPE 0x41536967 /* "ASig" */
> +struct grub_appended_signature_note
> +{
> +  Elf32_Nhdr header;
> +  char name[ALIGN_UP (sizeof (GRUB_APPENDED_SIGNATURE_NOTE_NAME), 4)];
> +};
> +
>  static int
>  is_relocatable (const struct grub_install_image_target_desc *image_target)
>  {
> @@ -216,7 +224,7 @@ grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr 
> sym_addr)
>
>  void
>  SUFFIX (grub_mkimage_generate_elf) (const struct 
> grub_install_image_target_desc *image_target,
> -                                   int note, char *sbat, char **core_img, 
> size_t *core_size,
> +                                   int note, char *sbat, size_t appsig_size, 
> char **core_img, size_t *core_size,
>                                     Elf_Addr target_addr,
>                                     struct grub_mkimage_layout *layout)
>  {
> @@ -237,6 +245,12 @@ SUFFIX (grub_mkimage_generate_elf) (const struct 
> grub_install_image_target_desc
>        footer_size += ALIGN_UP (sizeof (struct grub_sbat_note) + 
> layout->sbat_size, 4);
>      }
>
> +  if (appsig_size)
> +    {
> +      phnum++;
> +      footer_size += ALIGN_UP (sizeof (struct grub_appended_signature_note) 
> + appsig_size, 4);
> +    }
> +
>    if (image_target->id != IMAGE_LOONGSON_ELF)
>      phnum += 2;
>
> @@ -527,6 +541,28 @@ SUFFIX (grub_mkimage_generate_elf) (const struct 
> grub_install_image_target_desc
>        phdr->p_filesz = grub_host_to_target32 (note_size);
>        phdr->p_memsz = 0;
>        phdr->p_offset = grub_host_to_target32 (header_size + program_size + 
> footer_offset);
> +      footer += note_size;
> +      footer_offset += note_size;
> +    }
> +
> +  if (appsig_size)
> +    {
> +      int note_size = ALIGN_UP (sizeof (struct grub_appended_signature_note) 
> + appsig_size, 4);
> +      struct grub_appended_signature_note *note_ptr = (struct 
> grub_appended_signature_note *) footer;
> +      note_ptr->header.n_namesz = grub_host_to_target32 (sizeof 
> (GRUB_APPENDED_SIGNATURE_NOTE_NAME));
> +      /* needs to sit at the end, so we round this up and sign some zero 
> padding */
> +      note_ptr->header.n_descsz = grub_host_to_target32 (ALIGN_UP 
> (appsig_size, 4));
> +      note_ptr->header.n_type = grub_host_to_target32 
> (GRUB_APPENDED_SIGNATURE_NOTE_TYPE);
> +      strcpy (note_ptr->name, GRUB_APPENDED_SIGNATURE_NOTE_NAME);
> +      phdr++;
> +      phdr->p_type = grub_host_to_target32 (PT_NOTE);
> +      phdr->p_flags = grub_host_to_target32 (PF_R);
> +      phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof);
> +      phdr->p_vaddr = 0;
> +      phdr->p_paddr = 0;
> +      phdr->p_filesz = grub_host_to_target32 (note_size);
> +      phdr->p_memsz = 0;
> +      phdr->p_offset = grub_host_to_target32 (header_size + program_size + 
> footer_offset);
>      }
>
>    {
> diff --git a/util/mkimage.c b/util/mkimage.c
> index b46df2909..f5c59f563 100644
> --- a/util/mkimage.c
> +++ b/util/mkimage.c
> @@ -885,7 +885,7 @@ grub_install_generate_image (const char *dir, const char 
> *prefix,
>                              char *memdisk_path, char **pubkey_paths,
>                              size_t npubkeys, char *config_path,
>                              const struct grub_install_image_target_desc 
> *image_target,
> -                            int note, grub_compression_t comp, const char 
> *dtb_path,
> +                            int note, size_t appsig_size, grub_compression_t 
> comp, const char *dtb_path,
>                              const char *sbat_path, int disable_shim_lock,
>                              int disable_cli)
>  {
> @@ -1833,10 +1833,10 @@ grub_install_generate_image (const char *dir, const 
> char *prefix,
>         else
>           target_addr = image_target->link_addr;
>         if (image_target->voidp_sizeof == 4)
> -         grub_mkimage_generate_elf32 (image_target, note, sbat, &core_img, 
> &core_size,
> +         grub_mkimage_generate_elf32 (image_target, note, sbat, appsig_size, 
> &core_img, &core_size,
>                                        target_addr, &layout);
>         else
> -         grub_mkimage_generate_elf64 (image_target, note, sbat, &core_img, 
> &core_size,
> +         grub_mkimage_generate_elf64 (image_target, note, sbat, appsig_size, 
> &core_img, &core_size,
>                                        target_addr, &layout);
>        }
>        break;
> --
> 2.43.5
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel



-- 
Regards
Vladimir 'phcoder' Serbinenko

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to