Re: [PATCH 1/2] KEYS: Reserve an extra certificate symbol for inserting without recompiling

2015-12-01 Thread Mehmet Kayaalp
Hi David,

New keys can be added to the keyring by signing them with existing ones, and 
existing ones come from UEFI or are compiled into the kernel.  With this patch,
we can add the "compiled in" ones without recompiling the kernel. The scenario
is, a key is inserted into a stock kernel and the resulting kernel image is 
re-signed
to create a custom image for secure boot that can trust that key. Instead of 
giving
away the signing key, we can give the inserted key to the user of the image.

Does this make sense?

Mehmet

> On Nov 26, 2015, at 10:00 AM, David Howells <dhowe...@redhat.com> wrote:
> 
> Mehmet Kayaalp <mkaya...@linux.vnet.ibm.com> wrote:
> 
>> 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.
> 
> Do you have a particular use case for this?
> 
> David
> --
> To unsubscribe from this list: send the line "unsubscribe keyrings" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

--
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] KEYS: Reserve an extra certificate symbol for inserting without recompiling

2015-11-24 Thread Mehmet Kayaalp
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

[PATCH 2/2] KEYS: Use the symbol value for list size, updated by scripts/insert-sys-cert

2015-11-24 Thread Mehmet Kayaalp
When a certificate is inserted to the image using scripts/writekey, the
value of __cert_list_end does not change. The updated size can be found
out by reading the value pointed by the system_certificate_list_size
symbol.

Signed-off-by: Mehmet Kayaalp <mkaya...@linux.vnet.ibm.com>
---
 scripts/extract-sys-certs.pl | 29 +
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/scripts/extract-sys-certs.pl b/scripts/extract-sys-certs.pl
index d476e7d1fd88..8227ca10a494 100755
--- a/scripts/extract-sys-certs.pl
+++ b/scripts/extract-sys-certs.pl
@@ -91,13 +91,15 @@ print "Have $nr_symbols symbols\n";
 
 die "Can't find system certificate list"
 unless (exists($symbols{"__cert_list_start"}) &&
-   exists($symbols{"__cert_list_end"}));
+   exists($symbols{"system_certificate_list_size"}));
 
 my $start = Math::BigInt->new($symbols{"__cert_list_start"});
-my $end = Math::BigInt->new($symbols{"__cert_list_end"});
-my $size = $end - $start;
+my $end;
+my $size;
+my $size_sym = Math::BigInt->new($symbols{"system_certificate_list_size"});
 
-printf "Have %u bytes of certs at VMA 0x%x\n", $size, $start;
+open FD, "<$vmlinux" || die $vmlinux;
+binmode(FD);
 
 my $s = undef;
 foreach my $sec (@sections) {
@@ -110,11 +112,24 @@ foreach my $sec (@sections) {
 next unless ($start >= $s_vma);
 next if ($start >= $s_vend);
 
-die "Cert object partially overflows section $s_name\n"
-   if ($end > $s_vend);
+die "Certificate list size was not found on the same section\n"
+   if ($size_sym < $s_vma || $size_sym > $s_vend);
 
 die "Cert object in multiple sections: ", $s_name, " and ", $s->{name}, 
"\n"
if ($s);
+
+my $size_off = $size_sym -$s_vma + $s_foff;
+my $packed;
+die $vmlinux if (!defined(sysseek(FD, $size_off, SEEK_SET)));
+sysread(FD, $packed, 8);
+$size = unpack 'L!', $packed;
+$end = $start + $size;
+
+printf "Have %u bytes of certs at VMA 0x%x\n", $size, $start;
+
+die "Cert object partially overflows section $s_name\n"
+   if ($end > $s_vend);
+
 $s = $sec;
 }
 
@@ -127,8 +142,6 @@ my $foff = $start - $s->{vma} + $s->{foff};
 
 printf "Certificate list at file offset 0x%x\n", $foff;
 
-open FD, "<$vmlinux" || die $vmlinux;
-binmode(FD);
 die $vmlinux if (!defined(sysseek(FD, $foff, SEEK_SET)));
 my $buf = "";
 my $len = sysread(FD, $buf, $size);
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html