Place a system_extra_cert buffer of configurable size, right after the
system_certificate_list, so that inserted keys can be readily processed by
the existing mechanism. Added script takes a key file and a kernel image
and inserts its contents to the reserved area. The
system_certificate_list_size is also adjusted accordingly.
Call the script as:
scripts/insert-sys-cert -b -c
If vmlinux has no symbol table, supply System.map file with -s flag.
Subsequent runs replace the previously inserted key, instead of appending
the new one.
Signed-off-by: Mehmet Kayaalp <mkaya...@linux.vnet.ibm.com>
---
certs/Kconfig | 16 ++
certs/system_certificates.S | 12 ++
scripts/.gitignore | 1 +
scripts/Makefile| 1 +
scripts/insert-sys-cert.c | 410
5 files changed, 440 insertions(+)
create mode 100644 scripts/insert-sys-cert.c
diff --git a/certs/Kconfig b/certs/Kconfig
index b030b9c7ed34..f0f8a4433685 100644
--- a/certs/Kconfig
+++ b/certs/Kconfig
@@ -39,4 +39,20 @@ config SYSTEM_TRUSTED_KEYS
form of DER-encoded *.x509 files in the top-level build directory,
those are no longer used. You will need to set this option instead.
+config SYSTEM_EXTRA_CERTIFICATE
+ bool "Reserve area for inserting a certificate without recompiling"
+ depends on SYSTEM_TRUSTED_KEYRING
+ help
+ If set, space for an extra certificate will be reserved in the kernel
+ image. This allows introducing a trusted certificate to the default
+ system keyring without recompiling the kernel.
+
+config SYSTEM_EXTRA_CERTIFICATE_SIZE
+ int "Number of bytes to reserve for the extra certificate"
+ depends on SYSTEM_EXTRA_CERTIFICATE
+ default 4096
+ help
+ This is the number of bytes reserved in the kernel image for a
+ certificate to be inserted.
+
endmenu
diff --git a/certs/system_certificates.S b/certs/system_certificates.S
index 9216e8c81764..f82e1b22eac4 100644
--- a/certs/system_certificates.S
+++ b/certs/system_certificates.S
@@ -13,6 +13,18 @@ __cert_list_start:
.incbin "certs/x509_certificate_list"
__cert_list_end:
+#ifdef CONFIG_SYSTEM_EXTRA_CERTIFICATE
+ .globl VMLINUX_SYMBOL(system_extra_cert)
+ .size system_extra_cert, CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE
+VMLINUX_SYMBOL(system_extra_cert):
+ .fill CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE, 1, 0
+
+ .globl VMLINUX_SYMBOL(system_extra_cert_used)
+VMLINUX_SYMBOL(system_extra_cert_used):
+ .int 0
+
+#endif /* CONFIG_SYSTEM_EXTRA_CERTIFICATE */
+
.align 8
.globl VMLINUX_SYMBOL(system_certificate_list_size)
VMLINUX_SYMBOL(system_certificate_list_size):
diff --git a/scripts/.gitignore b/scripts/.gitignore
index 1f78169d4254..e063daa3ec4a 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -13,3 +13,4 @@ sortextable
asn1_compiler
extract-cert
sign-file
+insert-sys-cert
diff --git a/scripts/Makefile b/scripts/Makefile
index fd0d53d4a234..822ab4a6a4aa 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -19,6 +19,7 @@ hostprogs-$(CONFIG_BUILDTIME_EXTABLE_SORT) += sortextable
hostprogs-$(CONFIG_ASN1)+= asn1_compiler
hostprogs-$(CONFIG_MODULE_SIG) += sign-file
hostprogs-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert
+hostprogs-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert
HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include
HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include
diff --git a/scripts/insert-sys-cert.c b/scripts/insert-sys-cert.c
new file mode 100644
index ..8902836c2342
--- /dev/null
+++ b/scripts/insert-sys-cert.c
@@ -0,0 +1,410 @@
+/* Write the contents of the into kernel symbol system_extra_cert
+ *
+ * Copyright (C) IBM Corporation, 2015
+ *
+ * Author: Mehmet Kayaalp <mkaya...@linux.vnet.ibm.com>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ * Usage: insert-sys-cert [-s -b -c
+ */
+
+#define _GNU_SOURCE
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define CERT_SYM "system_extra_cert"
+#define USED_SYM "system_extra_cert_used"
+#define LSIZE_SYM "system_certificate_list_size"
+
+#define info(format, args...) fprintf(stderr, "INFO:" format, ## args)
+#define warn(format, args...) fprintf(stdout, "WARNING: " format, ## args)
+#define err(format, args...) fprintf(stderr, "ERROR: " format, ## args)
+
+#if UINTPTR_MAX == 0x
+#define CURRENT_ELFCLASS ELFCLASS32
+#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Shdr Elf32_Shdr
+#define Elf_SymElf32_Sym
+#else
+#define CURRENT_ELFCLASS ELFCLASS64
+#define Elf_Ehdr Elf64_Ehdr
+#defi