File 0006-appended-signature-infrastructure.patch of Package qemu

From 9b5c7a09d60b394e03b2da2578970190d35ad329 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Wed, 8 Apr 2020 12:18:49 +1000
Subject: [PATCH 06/12] appended signature: infrastructure

Detects if one exists and prints info if it's there.

Signed-off-by: Daniel Axtens <dja@axtens.net>
---
 include/libelf.h   |  1 +
 lib/libelf/elf32.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/roms/SLOF/include/libelf.h b/roms/SLOF/include/libelf.h
index 48ff4d7..603662e 100644
--- a/roms/SLOF/include/libelf.h
+++ b/roms/SLOF/include/libelf.h
@@ -68,6 +68,7 @@ struct ehdr {
 #define PT_INTERP	3	/* Program interpreter path name */
 #define PT_NOTE 	4	/* Note sections */
 
+#define APPENDED_SIGNATURE_NOTE_TYPE 0x41536967 /* "ASig" */
 
 int elf_load_file(void *file_addr, unsigned long *entry,
                   int (*pre_load)(void*, long),
diff --git a/roms/SLOF/lib/libelf/elf32.c b/roms/SLOF/lib/libelf/elf32.c
index be9a94f..f378db0 100644
--- a/roms/SLOF/lib/libelf/elf32.c
+++ b/roms/SLOF/lib/libelf/elf32.c
@@ -19,6 +19,10 @@
 #include <byteorder.h>
 #include <helpers.h>
 
+#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
+
+static char appsig_magic[] = "~Module signature appended~\n";
+
 struct ehdr32 {
 	uint32_t ei_ident;
 	uint8_t ei_class;
@@ -64,6 +68,22 @@ struct shdr32 {
 	uint32_t sh_entsize;
 };
 
+struct nhdr32 {
+	uint32_t n_namesz;
+	uint32_t n_descsz;
+	uint32_t n_type;
+};
+
+struct module_signature {
+	uint8_t		algo;		/* Public-key crypto algorithm [0] */
+	uint8_t		hash;		/* Digest algorithm [0] */
+	uint8_t		id_type;	/* Key identifier type [PKEY_ID_PKCS7] */
+	uint8_t		signer_len;	/* Length of signer's name [0] */
+	uint8_t		key_id_len;	/* Length of key identifier [0] */
+	uint8_t		__pad[3];
+	uint32_t	sig_len;	/* Length of signature data */
+};
+
 static struct phdr32*
 get_phdr32(void *file_addr)
 {
@@ -123,6 +143,51 @@ elf_load_segments32(void *file_addr, signed long offset,
 			/* copy segment */
 			load_segment(file_addr, phdr, offset, pre_load,
 			             post_load);
+		} else if (phdr->p_type == PT_NOTE) {
+			struct nhdr32 *nhdr = (struct nhdr32 *)(file_addr + phdr->p_offset);
+			char *ptr;
+			struct module_signature *modsig;
+			//printf("%x %x %x\n", nhdr->n_namesz, nhdr->n_descsz, nhdr->n_type);
+
+			// todo - endiansafeness
+			// todo, verify it is over the whole file (elf headers vs where this is)
+			if (nhdr->n_type == APPENDED_SIGNATURE_NOTE_TYPE) {
+				// todo, verify name
+
+				// check for magic
+				// go to start of appsig block
+				ptr = (char *)(nhdr) + sizeof(struct nhdr32) + ALIGN(nhdr->n_namesz, 4);
+				// go to start of sig
+				ptr += nhdr->n_descsz - sizeof(appsig_magic) + 1; // appsig_magic contains null-term
+				
+				if (strncmp(ptr, appsig_magic, sizeof(appsig_magic))) {
+					printf("ELF32: appended signature note present but magic string missing. Aborting.\n");
+					return 0;
+				}
+
+				// now load the sig info
+				ptr -= sizeof(struct module_signature);
+				modsig = (struct module_signature *)ptr;
+
+				//printf("%x %x %x %x %x\n", modsig->algo, modsig->hash, modsig->id_type, modsig->key_id_len, modsig->signer_len);
+				if (modsig->id_type != 2) { // pkcs7
+					printf("ELF32: appended signature is in an unexpected format (not PKCS#7). Aborting.\n");
+					return 0;
+				}
+
+				if (modsig->algo != 0 || modsig->hash != 0 || modsig->key_id_len != 0 || modsig->signer_len != 0) {
+					printf("ELF32: appended signature has an unexpected parameter inconsistend with PKCS#7. Aborting.\n");
+					return 0;
+				}
+
+				//printf("%u %u %u -1 = %u\n", modsig->sig_len, sizeof(struct module_signature), sizeof(appsig_magic), nhdr->n_descsz);
+				if (ALIGN(modsig->sig_len + sizeof(struct module_signature) + sizeof(appsig_magic) - 1, 4) != nhdr->n_descsz) {
+					printf("ELF32: Appended signature component sizes don't add up as expected. Aborting.\n");
+					return 0;
+				}
+
+				
+			}
 		}
 		/* step to next header */
 		phdr = (struct phdr32 *)(((uint8_t *)phdr) + ehdr->e_phentsize);
-- 
2.33.1

openSUSE Build Service is sponsored by