diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-06-21 20:13:53 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-06-21 20:13:53 +0300 |
commit | 0273fd423b2fe10af96ff713273137c63a7736c0 (patch) | |
tree | 8c77927d7714223a95a57037d05e912c5cbac5e7 /crypto/asymmetric_keys/x509_loader.c | |
parent | ff872b76b3d89a09a997cc45c133e4a3ddc12f90 (diff) | |
parent | 3cde3174eb910513d32a9ec8a9b95ea59be833df (diff) |
Merge tag 'certs-20220621' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull signature checking selftest from David Howells:
"The signature checking code, as used by module signing, kexec, etc.,
is non-FIPS compliant as there is no selftest.
For a kernel to be FIPS-compliant, signature checking would have to be
tested before being used, and the box would need to panic if it's not
available (probably reasonable as simply disabling signature checking
would prevent you from loading any driver modules).
Deal with this by adding a minimal test.
This is split into two patches: the first moves load_certificate_list()
to the same place as the X.509 code to make it more accessible
internally; the second adds a selftest"
* tag 'certs-20220621' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
certs: Add FIPS selftests
certs: Move load_certificate_list() to be with the asymmetric keys code
Diffstat (limited to 'crypto/asymmetric_keys/x509_loader.c')
-rw-r--r-- | crypto/asymmetric_keys/x509_loader.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/crypto/asymmetric_keys/x509_loader.c b/crypto/asymmetric_keys/x509_loader.c new file mode 100644 index 000000000000..1bc169dee22e --- /dev/null +++ b/crypto/asymmetric_keys/x509_loader.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <linux/kernel.h> +#include <linux/key.h> +#include <keys/asymmetric-type.h> + +int x509_load_certificate_list(const u8 cert_list[], + const unsigned long list_size, + const struct key *keyring) +{ + key_ref_t key; + const u8 *p, *end; + size_t plen; + + p = cert_list; + end = p + list_size; + while (p < end) { + /* Each cert begins with an ASN.1 SEQUENCE tag and must be more + * than 256 bytes in size. + */ + if (end - p < 4) + goto dodgy_cert; + if (p[0] != 0x30 && + p[1] != 0x82) + goto dodgy_cert; + plen = (p[2] << 8) | p[3]; + plen += 4; + if (plen > end - p) + goto dodgy_cert; + + key = key_create_or_update(make_key_ref(keyring, 1), + "asymmetric", + NULL, + p, + plen, + ((KEY_POS_ALL & ~KEY_POS_SETATTR) | + KEY_USR_VIEW | KEY_USR_READ), + KEY_ALLOC_NOT_IN_QUOTA | + KEY_ALLOC_BUILT_IN | + KEY_ALLOC_BYPASS_RESTRICTION); + if (IS_ERR(key)) { + pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", + PTR_ERR(key)); + } else { + pr_notice("Loaded X.509 cert '%s'\n", + key_ref_to_ptr(key)->description); + key_ref_put(key); + } + p += plen; + } + + return 0; + +dodgy_cert: + pr_err("Problem parsing in-kernel X.509 certificate list\n"); + return 0; +} |