On Sun, 2024-08-18 at 18:57 +0200, Roberto Sassu wrote: > From: Roberto Sassu <roberto.sassu@xxxxxxxxxx> > > Support for PGP keys and signatures was proposed by David long time ago, > before the decision of using PKCS#7 for kernel modules signatures > verification was made. After that, there has been not enough interest to > support PGP too. > > Lately, when discussing a proposal of introducing fsverity signatures in > Fedora [1], developers expressed their preference on not having a separate > key for signing, which would complicate the management of the distribution. > They would be more in favor of using the same PGP key, currently used for > signing RPM headers, also for file-based signatures (not only fsverity, but > also IMA ones). Update: since Fedora 39, IMA file signatures are supported on an independent key infrastructure. Roberto > Another envisioned use case would be to add the ability to appraise RPM > headers with their existing PGP signature, so that they can be used as an > authenticated source of reference values for appraising remaining > files [2]. > > To make these use cases possible, introduce support for PGP keys and > signatures in the kernel, and load provided PGP keys in the built-in > keyring, so that PGP signatures of RPM headers, fsverity digests, and IMA > digests can be verified from this trust anchor. > > In addition to the original version of the patch set, also introduce > support for signature verification of PGP keys, so that those keys can be > added to keyrings with a signature-based restriction (e.g. .ima). PGP keys > are searched with partial IDs, provided with signature subtype 16 (Issuer). > Search with full IDs could be supported with > draft-ietf-openpgp-rfc4880bis-10, by retrieving the information from > signature subtype 33 (Issuer Fingerprint). Due to the possibility of ID > collisions, the key_or_keyring restriction is not supported. > > The patch set includes two preliminary patches: patch 1 introduces > mpi_key_length(), to get the number of bits and bytes of an MPI; patch 2 > introduces rsa_parse_priv_key_raw() and rsa_parse_pub_key_raw(), to parse > an RSA key in RAW format if the ASN.1 parser returns an error. > > Patches 3-5 introduce the library necessary to parse PGP keys and > signatures, whose support is added with patches 6-10. Patch 11 introduces > verify_pgp_signature() to be used by kernel subsystems (e.g. fsverity and > IMA). Patch 12 is for testing of PGP signatures. Finally, patches 13-14 > allow loading a set of PGP keys from a supplied blob at boot time. > > Changelog > > v1 [4]: > - Remove quiet_cmd_extract_certs (redundant, likely leftover from > conflict resolution) > - Load PGP keys embedded in the kernel image within load_module_cert() > and load_system_certificate_list(), instead of using a separate initcall > - Style bug fixes found by checkpatch.pl > - Add <crypto/pgp.h> include in crypto/asymmetric_keys/pgp_preload.c, to > remove no previous prototype warning > - Correctly check returned tfm in pgp_generate_fingerprint() > - Fix printing message in pgp_generate_fingerprint() > - Don't create a public key if the key blob does not contain a PGP key > packet > - Remove unused pgp_pubkey_hash array > - Set KEY_EFLAG_DIGITALSIG key flag if the key has the capability > - Allow PGP_SIG_GENERAL_CERT_OF_UID_PUBKEY signature type (for key sigs) > - Add is_key_sig parameter to pgp_sig_get_sig() to ensure the key > signature type is PGP_SIG_GENERAL_CERT_OF_UID_PUBKEY or > PGP_SIG_POSTITIVE_CERT_OF_UID_PUBKEY > > v0 [3]: > - style fixes > - move include/linux/pgp.h and pgplib.h to crypto/asymmetric_keys > - introduce verify_pgp_signature() > - replace KEY_ALLOC_TRUSTED flag with KEY_ALLOC_BUILT_IN > - don't fetch PGP subkeys > - drop support for DSA > - store number of MPIs in pgp_key_algo_p_num_mpi array > - replace dynamic memory allocations with static ones in > pgp_generate_fingerprint() > - store only keys with capability of verifying signatures > - remember selection of PGP signature packet and don't repeat parsing > - move search of the PGP key to verify the signature from the beginning > to the end of the verification process (to be similar with PKCS#7) > - don't retry key search in the session keyring from the signature > verification code, let the caller pass the desired keyring > - for the PGP signature test key type, retry the key search in the session > keyring > - retry key search in restrict_link_by_signature() with a partial ID > (provided in the PGP signature) > > [1] https://fedoraproject.org/wiki/Changes/FsVerityRPM > [2] https://lore.kernel.org/linux-integrity/20240415142436.2545003-1-roberto.sassu@xxxxxxxxxxxxxxx/ > [3] https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-modsign.git/log/?h=pgp-parser > [4] https://lore.kernel.org/linux-integrity/20220111180318.591029-1-roberto.sassu@xxxxxxxxxx/ > > David Howells (8): > PGPLIB: PGP definitions (RFC 4880) > PGPLIB: Basic packet parser > PGPLIB: Signature parser > KEYS: PGP data parser > KEYS: Provide PGP key description autogeneration > KEYS: PGP-based public key signature verification > PGP: Provide a key type for testing PGP signatures > KEYS: Provide a function to load keys from a PGP keyring blob > > Roberto Sassu (6): > mpi: Introduce mpi_key_length() > rsa: add parser of raw format > KEYS: Retry asym key search with partial ID in > restrict_link_by_signature() > KEYS: Calculate key digest and get signature of the key > verification: introduce verify_pgp_signature() > KEYS: Introduce load_pgp_public_keyring() > > MAINTAINERS | 1 + > certs/Kconfig | 11 + > certs/Makefile | 7 + > certs/system_certificates.S | 18 + > certs/system_keyring.c | 93 ++++ > crypto/asymmetric_keys/Kconfig | 38 ++ > crypto/asymmetric_keys/Makefile | 13 + > crypto/asymmetric_keys/pgp.h | 206 ++++++++ > crypto/asymmetric_keys/pgp_library.c | 620 ++++++++++++++++++++++++ > crypto/asymmetric_keys/pgp_parser.h | 18 + > crypto/asymmetric_keys/pgp_preload.c | 111 +++++ > crypto/asymmetric_keys/pgp_public_key.c | 492 +++++++++++++++++++ > crypto/asymmetric_keys/pgp_signature.c | 505 +++++++++++++++++++ > crypto/asymmetric_keys/pgp_test_key.c | 129 +++++ > crypto/asymmetric_keys/pgplib.h | 74 +++ > crypto/asymmetric_keys/restrict.c | 10 +- > crypto/rsa.c | 14 +- > crypto/rsa_helper.c | 69 +++ > include/crypto/internal/rsa.h | 6 + > include/crypto/pgp.h | 36 ++ > include/linux/mpi.h | 2 + > include/linux/verification.h | 23 + > lib/crypto/mpi/mpicoder.c | 33 +- > 23 files changed, 2516 insertions(+), 13 deletions(-) > create mode 100644 crypto/asymmetric_keys/pgp.h > create mode 100644 crypto/asymmetric_keys/pgp_library.c > create mode 100644 crypto/asymmetric_keys/pgp_parser.h > create mode 100644 crypto/asymmetric_keys/pgp_preload.c > create mode 100644 crypto/asymmetric_keys/pgp_public_key.c > create mode 100644 crypto/asymmetric_keys/pgp_signature.c > create mode 100644 crypto/asymmetric_keys/pgp_test_key.c > create mode 100644 crypto/asymmetric_keys/pgplib.h > create mode 100644 include/crypto/pgp.h >