Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8607c501 authored by Dmitry Kasatkin's avatar Dmitry Kasatkin
Browse files

integrity: digital signature verification using multiple keyrings



Define separate keyrings for each of the different use cases - evm, ima,
and modules. Using different keyrings improves search performance, and also
allows "locking" specific keyring to prevent adding new keys.
This is useful for evm and module keyrings, when keys are usually only
added from initramfs.

Signed-off-by: default avatarDmitry Kasatkin <dmitry.kasatkin@intel.com>
parent 051dbb91
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -3,5 +3,19 @@ config INTEGRITY
	def_bool y
	depends on IMA || EVM

config INTEGRITY_DIGSIG
	boolean "Digital signature verification using multiple keyrings"
	depends on INTEGRITY
	default n
	select DIGSIG
	help
	  This option enables digital signature verification support
	  using multiple keyrings. It defines separate keyrings for each
	  of the different use cases - evm, ima, and modules.
	  Different keyrings improves search performance, but also allow
	  to "lock" certain keyring to prevent adding new keys.
	  This is useful for evm and module keyrings, when keys are
	  usually only added from initramfs.

source security/integrity/ima/Kconfig
source security/integrity/evm/Kconfig
+1 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
#

obj-$(CONFIG_INTEGRITY) += integrity.o
obj-$(CONFIG_INTEGRITY_DIGSIG) += digsig.o

integrity-y := iint.o

+48 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 Intel Corporation
 *
 * Author:
 * Dmitry Kasatkin <dmitry.kasatkin@intel.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 2 of the License.
 *
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/err.h>
#include <linux/rbtree.h>
#include <linux/key-type.h>
#include <linux/digsig.h>

#include "integrity.h"

static struct key *keyring[INTEGRITY_KEYRING_MAX];

static const char *keyring_name[INTEGRITY_KEYRING_MAX] = {
	"_evm",
	"_module",
	"_ima",
};

int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
					const char *digest, int digestlen)
{
	if (id >= INTEGRITY_KEYRING_MAX)
		return -EINVAL;

	if (!keyring[id]) {
		keyring[id] =
			request_key(&key_type_keyring, keyring_name[id], NULL);
		if (IS_ERR(keyring[id])) {
			int err = PTR_ERR(keyring[id]);
			pr_err("no %s keyring: %d\n", keyring_name[id], err);
			keyring[id] = NULL;
			return err;
		}
	}

	return digsig_verify(keyring[id], sig, siglen, digest, digestlen);
}
+21 −0
Original line number Diff line number Diff line
@@ -46,5 +46,26 @@ struct integrity_iint_cache {
struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
struct integrity_iint_cache *integrity_iint_find(struct inode *inode);

#define INTEGRITY_KEYRING_EVM		0
#define INTEGRITY_KEYRING_MODULE	1
#define INTEGRITY_KEYRING_IMA		2
#define INTEGRITY_KEYRING_MAX		3

#ifdef CONFIG_INTEGRITY_DIGSIG

int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
					const char *digest, int digestlen);

#else

static inline int integrity_digsig_verify(const unsigned int id,
					  const char *sig, int siglen,
					  const char *digest, int digestlen)
{
	return -EOPNOTSUPP;
}

#endif /* CONFIG_INTEGRITY_DIGSIG */

/* set during initialization */
extern int iint_initialized;