Commit 60740acc authored by Nayna Jain's avatar Nayna Jain Committed by Mimi Zohar
Browse files

integrity: Load certs to the platform keyring



The patch refactors integrity_load_x509(), making it a wrapper for a new
function named integrity_add_key(). This patch also defines a new
function named integrity_load_cert() for loading the platform keys.

Signed-off-by: default avatarNayna Jain <nayna@linux.ibm.com>
Reviewed-by: default avatarMimi Zohar <zohar@linux.ibm.com>
Acked-by: default avatarSerge Hallyn <serge@hallyn.com>
Reviewed-by: default avatarJames Morris <james.morris@microsoft.com>
Reviewed-by: default avatarThiago Jung Bauermann <bauerman@linux.ibm.com>
Signed-off-by: default avatarMimi Zohar <zohar@linux.ibm.com>
parent 9dc92c45
Loading
Loading
Loading
Loading
+43 −24
Original line number Diff line number Diff line
@@ -82,8 +82,7 @@ static int __integrity_init_keyring(const unsigned int id, key_perm_t perm,

	keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
				    KGIDT_INIT(0), cred, perm,
				    KEY_ALLOC_NOT_IN_QUOTA,
				    restriction, NULL);
				    KEY_ALLOC_NOT_IN_QUOTA, restriction, NULL);
	if (IS_ERR(keyring[id])) {
		err = PTR_ERR(keyring[id]);
		pr_info("Can't allocate %s keyring (%d)\n",
@@ -121,16 +120,38 @@ out:
	return __integrity_init_keyring(id, perm, restriction);
}

int __init integrity_load_x509(const unsigned int id, const char *path)
int __init integrity_add_key(const unsigned int id, const void *data,
			     off_t size, key_perm_t perm)
{
	key_ref_t key;
	void *data;
	loff_t size;
	int rc;
	int rc = 0;

	if (!keyring[id])
		return -EINVAL;

	key = key_create_or_update(make_key_ref(keyring[id], 1), "asymmetric",
				   NULL, data, size, perm,
				   KEY_ALLOC_NOT_IN_QUOTA);
	if (IS_ERR(key)) {
		rc = PTR_ERR(key);
		pr_err("Problem loading X.509 certificate %d\n", rc);
	} else {
		pr_notice("Loaded X.509 cert '%s'\n",
			  key_ref_to_ptr(key)->description);
		key_ref_put(key);
	}

	return rc;

}

int __init integrity_load_x509(const unsigned int id, const char *path)
{
	void *data;
	loff_t size;
	int rc;
	key_perm_t perm;

	rc = kernel_read_file_from_path(path, &data, &size, 0,
					READING_X509_CERTIFICATE);
	if (rc < 0) {
@@ -138,23 +159,21 @@ int __init integrity_load_x509(const unsigned int id, const char *path)
		return rc;
	}

	key = key_create_or_update(make_key_ref(keyring[id], 1),
				   "asymmetric",
				   NULL,
				   data,
				   size,
				   ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
				    KEY_USR_VIEW | KEY_USR_READ),
				   KEY_ALLOC_NOT_IN_QUOTA);
	if (IS_ERR(key)) {
		rc = PTR_ERR(key);
		pr_err("Problem loading X.509 certificate (%d): %s\n",
		       rc, path);
	} else {
		pr_notice("Loaded X.509 cert '%s': %s\n",
			  key_ref_to_ptr(key)->description, path);
		key_ref_put(key);
	}
	perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ;

	pr_info("Loading X.509 certificate: %s\n", path);
	rc = integrity_add_key(id, (const void *)data, size, perm);

	vfree(data);
	return 0;
	return rc;
}

int __init integrity_load_cert(const unsigned int id, const char *source,
			       const void *data, size_t len, key_perm_t perm)
{
	if (!data)
		return -EINVAL;

	pr_info("Loading X.509 certificate: %s\n", source);
	return integrity_add_key(id, data, len, perm);
}
+20 −0
Original line number Diff line number Diff line
@@ -154,6 +154,8 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,

int __init integrity_init_keyring(const unsigned int id);
int __init integrity_load_x509(const unsigned int id, const char *path);
int __init integrity_load_cert(const unsigned int id, const char *source,
			       const void *data, size_t len, key_perm_t perm);
#else

static inline int integrity_digsig_verify(const unsigned int id,
@@ -167,6 +169,14 @@ static inline int integrity_init_keyring(const unsigned int id)
{
	return 0;
}

static inline int __init integrity_load_cert(const unsigned int id,
					     const char *source,
					     const void *data, size_t len,
					     key_perm_t perm)
{
	return 0;
}
#endif /* CONFIG_INTEGRITY_SIGNATURE */

#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
@@ -223,3 +233,13 @@ integrity_audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type)
}

#endif

#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
void __init add_to_platform_keyring(const char *source, const void *data,
				    size_t len);
#else
static inline void __init add_to_platform_keyring(const char *source,
						  const void *data, size_t len)
{
}
#endif
+23 −0
Original line number Diff line number Diff line
@@ -14,6 +14,29 @@
#include <linux/slab.h>
#include "../integrity.h"

/**
 * add_to_platform_keyring - Add to platform keyring without validation.
 * @source: Source of key
 * @data: The blob holding the key
 * @len: The length of the data blob
 *
 * Add a key to the platform keyring without checking its trust chain.  This
 * is available only during kernel initialisation.
 */
void __init add_to_platform_keyring(const char *source, const void *data,
				    size_t len)
{
	key_perm_t perm;
	int rc;

	perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW;

	rc = integrity_load_cert(INTEGRITY_KEYRING_PLATFORM, source, data, len,
				 perm);
	if (rc)
		pr_info("Error adding keys to platform keyring %s\n", source);
}

/*
 * Create the trusted keyrings.
 */