certs: Check that builtin blacklist hashes are valid

Add and use a check-blacklist-hashes.awk script to make sure that the
builtin blacklist hashes set with CONFIG_SYSTEM_BLACKLIST_HASH_LIST will
effectively be taken into account as blacklisted hashes.  This is useful
to debug invalid hash formats, and it make sure that previous hashes
which could have been loaded in the kernel, but silently ignored, are
now noticed and deal with by the user at kernel build time.

This also prevent stricter blacklist key description checking (provided
by following commits) to failed for builtin hashes.

Update CONFIG_SYSTEM_BLACKLIST_HASH_LIST help to explain the content of
a hash string and how to generate certificate ones.

Cc: David Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Eric Snowberg <eric.snowberg@oracle.com>
Cc: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Mickaël Salaün <mic@linux.microsoft.com>
Link: https://lore.kernel.org/r/20210712170313.884724-3-mic@digikod.net
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
This commit is contained in:
Mickaël Salaün 2021-07-12 19:03:10 +02:00 committed by Jarkko Sakkinen
parent bf21dc591b
commit addf466389
5 changed files with 57 additions and 3 deletions

View File

@ -4575,6 +4575,7 @@ L: keyrings@vger.kernel.org
S: Maintained S: Maintained
F: Documentation/admin-guide/module-signing.rst F: Documentation/admin-guide/module-signing.rst
F: certs/ F: certs/
F: scripts/check-blacklist-hashes.awk
F: scripts/sign-file.c F: scripts/sign-file.c
F: tools/certs/ F: tools/certs/

1
certs/.gitignore vendored
View File

@ -1,4 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
/blacklist_hashes_checked
/extract-cert /extract-cert
/x509_certificate_list /x509_certificate_list
/x509_revocation_list /x509_revocation_list

View File

@ -104,8 +104,11 @@ config SYSTEM_BLACKLIST_HASH_LIST
help help
If set, this option should be the filename of a list of hashes in the If set, this option should be the filename of a list of hashes in the
form "<hash>", "<hash>", ... . This will be included into a C form "<hash>", "<hash>", ... . This will be included into a C
wrapper to incorporate the list into the kernel. Each <hash> should wrapper to incorporate the list into the kernel. Each <hash> must be a
be a string of hex digits. string starting with a prefix ("tbs" or "bin"), then a colon (":"), and
finally an even number of hexadecimal lowercase characters (up to 128).
Certificate hashes can be generated with
tools/certs/print-cert-tbs-hash.sh .
config SYSTEM_REVOCATION_LIST config SYSTEM_REVOCATION_LIST
bool "Provide system-wide ring of revocation certificates" bool "Provide system-wide ring of revocation certificates"

View File

@ -7,6 +7,18 @@ obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o c
obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o common.o obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o common.o
obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o
ifneq ($(CONFIG_SYSTEM_BLACKLIST_HASH_LIST),) ifneq ($(CONFIG_SYSTEM_BLACKLIST_HASH_LIST),)
quiet_cmd_check_blacklist_hashes = CHECK $(patsubst "%",%,$(2))
cmd_check_blacklist_hashes = $(AWK) -f $(srctree)/scripts/check-blacklist-hashes.awk $(2); touch $@
$(eval $(call config_filename,SYSTEM_BLACKLIST_HASH_LIST))
$(obj)/blacklist_hashes.o: $(obj)/blacklist_hashes_checked
CFLAGS_blacklist_hashes.o += -I$(srctree)
targets += blacklist_hashes_checked
$(obj)/blacklist_hashes_checked: $(SYSTEM_BLACKLIST_HASH_LIST_SRCPREFIX)$(SYSTEM_BLACKLIST_HASH_LIST_FILENAME) scripts/check-blacklist-hashes.awk FORCE
$(call if_changed,check_blacklist_hashes,$(SYSTEM_BLACKLIST_HASH_LIST_SRCPREFIX)$(CONFIG_SYSTEM_BLACKLIST_HASH_LIST))
obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o
else else
obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_nohashes.o obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_nohashes.o
@ -21,7 +33,7 @@ $(obj)/system_certificates.o: $(obj)/x509_certificate_list
$(obj)/x509_certificate_list: $(CONFIG_SYSTEM_TRUSTED_KEYS) $(obj)/extract-cert FORCE $(obj)/x509_certificate_list: $(CONFIG_SYSTEM_TRUSTED_KEYS) $(obj)/extract-cert FORCE
$(call if_changed,extract_certs) $(call if_changed,extract_certs)
targets += x509_certificate_list targets += x509_certificate_list blacklist_hashes_checked
# If module signing is requested, say by allyesconfig, but a key has not been # If module signing is requested, say by allyesconfig, but a key has not been
# supplied, then one will need to be generated to make sure the build does not # supplied, then one will need to be generated to make sure the build does not

View File

@ -0,0 +1,37 @@
#!/usr/bin/awk -f
# SPDX-License-Identifier: GPL-2.0
#
# Copyright © 2020, Microsoft Corporation. All rights reserved.
#
# Author: Mickaël Salaün <mic@linux.microsoft.com>
#
# Check that a CONFIG_SYSTEM_BLACKLIST_HASH_LIST file contains a valid array of
# hash strings. Such string must start with a prefix ("tbs" or "bin"), then a
# colon (":"), and finally an even number of hexadecimal lowercase characters
# (up to 128).
BEGIN {
RS = ","
}
{
if (!match($0, "^[ \t\n\r]*\"([^\"]*)\"[ \t\n\r]*$", part1)) {
print "Not a string (item " NR "):", $0;
exit 1;
}
if (!match(part1[1], "^(tbs|bin):(.*)$", part2)) {
print "Unknown prefix (item " NR "):", part1[1];
exit 1;
}
if (!match(part2[2], "^([0-9a-f]+)$", part3)) {
print "Not a lowercase hexadecimal string (item " NR "):", part2[2];
exit 1;
}
if (length(part3[1]) > 128) {
print "Hash string too long (item " NR "):", part3[1];
exit 1;
}
if (length(part3[1]) % 2 == 1) {
print "Not an even number of hexadecimal characters (item " NR "):", part3[1];
exit 1;
}
}