Skip to contentSkip to conversation

evm: digital signature extension

RFC In review Dmitry Kasatkin 2 participants 8 messages Jun 8, 2011 – Jun 16, 2011

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover evm: digital signature extension

From: Dmitry Kasatkin <[email protected]>

This patchset introduces digital signature extensions for the IMA/EVM kernel integrity subsystem and is applied on the top of the EVM patches posted to LSM mailing list earlier.

Currently EVM stores the HMAC in security.evm to verify integrity of the file's metadata. This is quite sufficient for individually installed systems, where a system unique HMAC key can be provisioned and the initial filesystem labeling can be done.

Software installation for consumer electronics or embedded devices is usually done via flashing a filesystem image. Initial filesystem image labeling is done during image creation process. It either has to be done (1) using a system unique HMAC key or (2) using an image specific HMAC key. In first case, those keys are either unknown, or a unique image has to be created for thousand or millions of devices, which is not feasible. The second case, using an image specific HMAC key, would require (2.1) provisioning of the key to millions of devices, which is not easily feasible or (2.1) encrypting the key with a shared symmetric key which is not a strong security measure.

Digital signature extension for EVM provides a solution to perform labeling of the image using a single digital private key and use a known public key to verify the signature. For performance reasons, after verification, signature is replaced with local HMAC.

Digital signature verification uses RSA algorithm, implemented using cut-down port of multi-precision integers (MPI) library from GnuPG and has been taken from RedHat Enterprise Linux kernel (MODSIGN patches). Decision to use this library was made, because its performance was 2 times better than other ports such as libtommath library.

This is not related to these patches specifically, but gives some motivation for integrity protection in general. As runtime protection is ensured via access control mechanisms, the main purpose of integrity protection is to protect against offline modifications. Some people argue that protection against offline modifications is seen as locking down device against themselves. But that is not completely true. Yes, it might prevent the user from changing the functionality of the device, which might be seen as evil. But on other hand, the owner of the device, such as companies or operators, not the user of the device, might not like their devices being modified.

But the more important reason for integrity protection is protecting the users’ or owners’ from selling or giving them modified devices, which can do nasty things such as spying or stealing personal data. Integrity protection ensures that modifications of the system will not remain undetected.

There is also a second patchset which implements digital signature support for IMA-appraisal patchset, which is planned to be reviewed right after the IMA-appaisal review.

All patches on the top of ima-2.6 kernel are available here:
http://meego.gitorious.org/meego-platform-security/ima-ksign

Supporting utility for key handling and signing is available here:
http://meego.gitorious.org/meego-platform-security/evm-utils

Regards,
Dmitry

Dmitry Kasatkin (5):
crypto: GnuPG based MPI lib
crypto: ksign - digital signature verification support
evm: digital signature support
ksign: provides keyring to search in for the key
evm: creates dedicated evm keyring to store public keys

 crypto/Kconfig                      |   19 +
 crypto/Makefile                     |    4 +
 crypto/ksign.c                      |  270 +++++++
 crypto/mpi/Makefile                 |   30 +
 crypto/mpi/generic_mpi-asm-defs.h   |   10 +
 crypto/mpi/generic_mpih-add1.c      |   62 ++
 crypto/mpi/generic_mpih-lshift.c    |   66 ++
 crypto/mpi/generic_mpih-mul1.c      |   58 ++
 crypto/mpi/generic_mpih-mul2.c      |   63 ++
 crypto/mpi/generic_mpih-mul3.c      |   64 ++
 crypto/mpi/generic_mpih-rshift.c    |   65 ++
 crypto/mpi/generic_mpih-sub1.c      |   62 ++
 crypto/mpi/generic_udiv-w-sdiv.c    |  130 +++
 crypto/mpi/longlong.h               | 1502 +++++++++++++++++++++++++++++++++++
 crypto/mpi/mpi-add.c                |  258 ++++++
 crypto/mpi/mpi-bit.c                |  245 ++++++
 crypto/mpi/mpi-cmp.c                |   71 ++
 crypto/mpi/mpi-div.c                |  345 ++++++++
 crypto/mpi/mpi-gcd.c                |   60 ++
 crypto/mpi/mpi-inline.c             |   33 +
 crypto/mpi/mpi-inline.h             |  128 +++
 crypto/mpi/mpi-internal.h           |  265 ++++++
 crypto/mpi/mpi-inv.c                |  148 ++++
 crypto/mpi/mpi-mpow.c               |  113 +++
 crypto/mpi/mpi-mul.c                |  202 +++++
 crypto/mpi/mpi-pow.c                |  312 ++++++++
 crypto/mpi/mpi-scan.c               |  129 +++
 crypto/mpi/mpicoder.c               |  359 +++++++++
 crypto/mpi/mpih-cmp.c               |   58 ++
 crypto/mpi/mpih-div.c               |  534 +++++++++++++
 crypto/mpi/mpih-mul.c               |  546 +++++++++++++
 crypto/mpi/mpiutil.c                |  213 +++++
 include/linux/crypto/ksign.h        |   48 ++
 include/linux/crypto/mpi.h          |  147 ++++
 security/integrity/evm/Kconfig      |   14 +
 security/integrity/evm/evm.h        |   33 +
 security/integrity/evm/evm_crypto.c |   66 ++-
 security/integrity/evm/evm_main.c   |   83 ++-
 38 files changed, 6783 insertions(+), 32 deletions(-)
 create mode 100644 crypto/ksign.c
 create mode 100644 crypto/mpi/Makefile
 create mode 100644 crypto/mpi/generic_mpi-asm-defs.h
 create mode 100644 crypto/mpi/generic_mpih-add1.c
 create mode 100644 crypto/mpi/generic_mpih-lshift.c
 create mode 100644 crypto/mpi/generic_mpih-mul1.c
 create mode 100644 crypto/mpi/generic_mpih-mul2.c
 create mode 100644 crypto/mpi/generic_mpih-mul3.c
 create mode 100644 crypto/mpi/generic_mpih-rshift.c
 create mode 100644 crypto/mpi/generic_mpih-sub1.c
 create mode 100644 crypto/mpi/generic_udiv-w-sdiv.c
 create mode 100644 crypto/mpi/longlong.h
 create mode 100644 crypto/mpi/mpi-add.c
 create mode 100644 crypto/mpi/mpi-bit.c
 create mode 100644 crypto/mpi/mpi-cmp.c
 create mode 100644 crypto/mpi/mpi-div.c
 create mode 100644 crypto/mpi/mpi-gcd.c
 create mode 100644 crypto/mpi/mpi-inline.c
 create mode 100644 crypto/mpi/mpi-inline.h
 create mode 100644 crypto/mpi/mpi-internal.h
 create mode 100644 crypto/mpi/mpi-inv.c
 create mode 100644 crypto/mpi/mpi-mpow.c
 create mode 100644 crypto/mpi/mpi-mul.c
 create mode 100644 crypto/mpi/mpi-pow.c
 create mode 100644 crypto/mpi/mpi-scan.c
 create mode 100644 crypto/mpi/mpicoder.c
 create mode 100644 crypto/mpi/mpih-cmp.c
 create mode 100644 crypto/mpi/mpih-div.c
 create mode 100644 crypto/mpi/mpih-mul.c
 create mode 100644 crypto/mpi/mpiutil.c
 create mode 100644 include/linux/crypto/ksign.h
 create mode 100644 include/linux/crypto/mpi.h
Signature · 1 line
1.7.4.1
#1 lore raw

RFC 1/5 crypto: GnuPG based MPI lib

From: Dmitry Kasatkin <[email protected]>

Adds the multi-precision-integer maths library which was originally taken from GnuPG and ported to the kernel by (among others) David Howells. This version is taken from Fedora kernel 2.6.32-71.14.1.el6.

This library is used to implemenet RSA digital signature verification used in IMA/EVM integrity protection subsystem.

---
 crypto/Kconfig                    |    6 +
 crypto/Makefile                   |    1 +
 crypto/mpi/Makefile               |   30 +
 crypto/mpi/generic_mpi-asm-defs.h |   10 +
 crypto/mpi/generic_mpih-add1.c    |   62 ++
 crypto/mpi/generic_mpih-lshift.c  |   66 ++
 crypto/mpi/generic_mpih-mul1.c    |   58 ++
 crypto/mpi/generic_mpih-mul2.c    |   63 ++
 crypto/mpi/generic_mpih-mul3.c    |   64 ++
 crypto/mpi/generic_mpih-rshift.c  |   65 ++
 crypto/mpi/generic_mpih-sub1.c    |   62 ++
 crypto/mpi/generic_udiv-w-sdiv.c  |  130 ++++
 crypto/mpi/longlong.h             | 1502 +++++++++++++++++++++++++++++++++++++
 crypto/mpi/mpi-add.c              |  258 +++++++
 crypto/mpi/mpi-bit.c              |  245 ++++++
 crypto/mpi/mpi-cmp.c              |   71 ++
 crypto/mpi/mpi-div.c              |  345 +++++++++
 crypto/mpi/mpi-gcd.c              |   60 ++
 crypto/mpi/mpi-inline.c           |   33 +
 crypto/mpi/mpi-inline.h           |  128 ++++
 crypto/mpi/mpi-internal.h         |  265 +++++++
 crypto/mpi/mpi-inv.c              |  148 ++++
 crypto/mpi/mpi-mpow.c             |  113 +++
 crypto/mpi/mpi-mul.c              |  202 +++++
 crypto/mpi/mpi-pow.c              |  312 ++++++++
 crypto/mpi/mpi-scan.c             |  129 ++++
 crypto/mpi/mpicoder.c             |  359 +++++++++
 crypto/mpi/mpih-cmp.c             |   58 ++
 crypto/mpi/mpih-div.c             |  534 +++++++++++++
 crypto/mpi/mpih-mul.c             |  546 ++++++++++++++
 crypto/mpi/mpiutil.c              |  213 ++++++
 include/linux/crypto/mpi.h        |  147 ++++
 32 files changed, 6285 insertions(+), 0 deletions(-)
 create mode 100644 crypto/mpi/Makefile
 create mode 100644 crypto/mpi/generic_mpi-asm-defs.h
 create mode 100644 crypto/mpi/generic_mpih-add1.c
 create mode 100644 crypto/mpi/generic_mpih-lshift.c
 create mode 100644 crypto/mpi/generic_mpih-mul1.c
 create mode 100644 crypto/mpi/generic_mpih-mul2.c
 create mode 100644 crypto/mpi/generic_mpih-mul3.c
 create mode 100644 crypto/mpi/generic_mpih-rshift.c
 create mode 100644 crypto/mpi/generic_mpih-sub1.c
 create mode 100644 crypto/mpi/generic_udiv-w-sdiv.c
 create mode 100644 crypto/mpi/longlong.h
 create mode 100644 crypto/mpi/mpi-add.c
 create mode 100644 crypto/mpi/mpi-bit.c
 create mode 100644 crypto/mpi/mpi-cmp.c
 create mode 100644 crypto/mpi/mpi-div.c
 create mode 100644 crypto/mpi/mpi-gcd.c
 create mode 100644 crypto/mpi/mpi-inline.c
 create mode 100644 crypto/mpi/mpi-inline.h
 create mode 100644 crypto/mpi/mpi-internal.h
 create mode 100644 crypto/mpi/mpi-inv.c
 create mode 100644 crypto/mpi/mpi-mpow.c
 create mode 100644 crypto/mpi/mpi-mul.c
 create mode 100644 crypto/mpi/mpi-pow.c
 create mode 100644 crypto/mpi/mpi-scan.c
 create mode 100644 crypto/mpi/mpicoder.c
 create mode 100644 crypto/mpi/mpih-cmp.c
 create mode 100644 crypto/mpi/mpih-div.c
 create mode 100644 crypto/mpi/mpih-mul.c
 create mode 100644 crypto/mpi/mpiutil.c
 create mode 100644 include/linux/crypto/mpi.h
crypto/Kconfig +6 -0
index 87b22ca..4fb13ee 100644
@@ -857,6 +857,12 @@ config CRYPTO_USER_API_SKCIPHER
 	  This option enables the user-spaces interface for symmetric
 	  key cipher algorithms.
 
+config CRYPTO_MPILIB
+	bool "Multiprecision maths library (EXPERIMENTAL)"
+	depends on CRYPTO
+	help
+	  Multiprecision maths library from GnuPG
+
 source "drivers/crypto/Kconfig"
 
 endif	# if CRYPTO
crypto/Makefile +1 -0
index ce5a813..604006d 100644
@@ -88,6 +88,7 @@ obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o
 obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o
 obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o
 obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
+obj-$(CONFIG_CRYPTO_MPILIB) += mpi/
 
 #
 # generic algorithms and the async_tx api
crypto/mpi/Makefile new file +30 -0
new file mode 100644
index 0000000..d000949
@@ -0,0 +1,30 @@
+#
+# MPI multiprecision maths library (from gpg)
+#
+
+obj-$(CONFIG_CRYPTO_MPILIB) = \
+	generic_mpih-lshift.o		\
+	generic_mpih-mul1.o		\
+	generic_mpih-mul2.o		\
+	generic_mpih-mul3.o		\
+	generic_mpih-rshift.o		\
+	generic_mpih-sub1.o		\
+	generic_mpih-add1.o		\
+	generic_udiv-w-sdiv.o		\
+	mpicoder.o			\
+	mpi-add.o			\
+	mpi-bit.o			\
+	mpi-div.o			\
+	mpi-cmp.o			\
+	mpi-gcd.o			\
+	mpih-cmp.o			\
+	mpih-div.o			\
+	mpih-mul.o			\
+	mpi-inline.o			\
+	mpi-inv.o			\
+	mpi-mpow.o			\
+	mpi-mul.o			\
+	mpi-pow.o			\
+	mpi-scan.o			\
+	mpiutil.o
+
crypto/mpi/generic_mpi-asm-defs.h new file +10 -0
new file mode 100644
index 0000000..13424e2
@@ -0,0 +1,10 @@
+/* This file defines some basic constants for the MPI machinery.  We
+ * need to define the types on a per-CPU basis, so it is done with
+ * this file here.  */
+#define BYTES_PER_MPI_LIMB  (SIZEOF_UNSIGNED_LONG)
+
+
+
+
+
+
crypto/mpi/generic_mpih-add1.c new file +62 -0

62 lines not on this page · raw message

crypto/mpi/generic_mpih-lshift.c new file +66 -0

66 lines not on this page · raw message

crypto/mpi/generic_mpih-mul1.c new file +58 -0

58 lines not on this page · raw message

crypto/mpi/generic_mpih-mul2.c new file +63 -0

63 lines not on this page · raw message

crypto/mpi/generic_mpih-mul3.c new file +64 -0

64 lines not on this page · raw message

crypto/mpi/generic_mpih-rshift.c new file +65 -0

65 lines not on this page · raw message

crypto/mpi/generic_mpih-sub1.c new file +62 -0

62 lines not on this page · raw message

crypto/mpi/generic_udiv-w-sdiv.c new file +130 -0

130 lines not on this page · raw message

crypto/mpi/longlong.h new file +1502 -0

1,502 lines not on this page · raw message

crypto/mpi/mpi-add.c new file +258 -0

258 lines not on this page · raw message

crypto/mpi/mpi-bit.c new file +245 -0

245 lines not on this page · raw message

crypto/mpi/mpi-cmp.c new file +71 -0

71 lines not on this page · raw message

crypto/mpi/mpi-div.c new file +345 -0

295 lines not on this page · raw message

crypto/mpi/mpi-gcd.c new file +60 -0

60 lines not on this page · raw message

crypto/mpi/mpi-inline.c new file +33 -0
new file mode 100644
index 0000000..da53e2d

Lines of this file are not shown. View the raw message.

crypto/mpi/mpi-inline.h new file +128 -0

128 lines not on this page · raw message

crypto/mpi/mpi-internal.h new file +265 -0

265 lines not on this page · raw message

crypto/mpi/mpi-inv.c new file +148 -0

148 lines not on this page · raw message

crypto/mpi/mpi-mpow.c new file +113 -0

113 lines not on this page · raw message

crypto/mpi/mpi-mul.c new file +202 -0

202 lines not on this page · raw message

crypto/mpi/mpi-pow.c new file +312 -0

312 lines not on this page · raw message

crypto/mpi/mpi-scan.c new file +129 -0

129 lines not on this page · raw message

crypto/mpi/mpicoder.c new file +359 -0

359 lines not on this page · raw message

crypto/mpi/mpih-cmp.c new file +58 -0

58 lines not on this page · raw message

crypto/mpi/mpih-div.c new file +534 -0

534 lines not on this page · raw message

crypto/mpi/mpih-mul.c new file +546 -0

546 lines not on this page · raw message

crypto/mpi/mpiutil.c new file +213 -0

213 lines not on this page · raw message

include/linux/crypto/mpi.h new file +147 -0

147 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
1.7.4.1

Part of the diff is not shown here. View the raw message.

maintainer
#2 lore raw

Re: [RFC v1 1/5] crypto: GnuPG based MPI lib

Quoted 5 lines · Dmitry Kasatkin

From: Dmitry Kasatkin <[email protected]>

Adds the multi-precision-integer maths library which was originally taken from GnuPG and ported to the kernel by (among others) David Howells. This version is taken from Fedora kernel 2.6.32-71.14.1.el6.

FYI, any future postings should be cc'd to the linux-crypto list.

Signature · 2 lines
James Morris
<[email protected]>
#3 lore raw

Re: [RFC v1 1/5] crypto: GnuPG based MPI lib

Quoted 10 lines · James Morris
Quoted 5 lines · Dmitry Kasatkin

From: Dmitry Kasatkin <[email protected]>

Adds the multi-precision-integer maths library which was originally taken from GnuPG and ported to the kernel by (among others) David Howells. This version is taken from Fedora kernel 2.6.32-71.14.1.el6.

FYI, any future postings should be cc'd to the linux-crypto list.

Of course.. I missed it.

#4 lore raw

RFC 2/5 crypto: ksign - digital signature verification support

In reply to Dmitry Kasatkin

From: Dmitry Kasatkin <[email protected]>

This patch implements RSA digital signature verification using GnuPG library.

Signature and public key have a special format and have special headers. Signature header contains keyid, which is used to identify the key, needed for signature verification.
Payload of the signature and the key are multi-precision integers.

Signing and key management utility "evmctl" is available on
http://meego.gitorious.org/meego-platform-security/evm-utils

Key is added to the kernel keyring with the name equal to a keyid. evm-utils provide support to load PEM key into the keyring, to convert PEM key to the kernel format and to load it into the keyring.

---
 crypto/Kconfig               |   13 ++
 crypto/Makefile              |    3 +
 crypto/ksign.c               |  259 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/crypto/ksign.h |   48 ++++++++
 4 files changed, 323 insertions(+), 0 deletions(-)
 create mode 100644 crypto/ksign.c
 create mode 100644 include/linux/crypto/ksign.h
crypto/Kconfig +13 -0
index 4fb13ee..604b534 100644
@@ -863,6 +863,19 @@ config CRYPTO_MPILIB
 	help
 	  Multiprecision maths library from GnuPG
 
+config CRYPTO_KSIGN
+	bool "In-kernel signature checker (EXPERIMENTAL)"
+	depends on CRYPTO
+	help
+	  Signature checker (used for module sig checking).
+
+config CRYPTO_KSIGN_RSA
+	bool "Handle RSA signatures (EXPERIMENTAL)"
+	select CRYPTO_KSIGN
+	select CRYPTO_MPILIB
+	help
+	  RSA Signature checker.
+
 source "drivers/crypto/Kconfig"
 
 endif	# if CRYPTO
crypto/Makefile +3 -0
index 604006d..4ef05e8 100644
@@ -90,6 +90,9 @@ obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o
 obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
 obj-$(CONFIG_CRYPTO_MPILIB) += mpi/
 
+obj-$(CONFIG_CRYPTO_KSIGN) += ksignmod.o
+ksignmod-objs := ksign.o
+
 #
 # generic algorithms and the async_tx api
 #
crypto/ksign.c new file +259 -0

259 lines not on this page · raw message

include/linux/crypto/ksign.h new file +48 -0

48 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#5 lore raw

RFC 3/5 evm: digital signature support

In reply to Dmitry Kasatkin

From: Dmitry Kasatkin <[email protected]>

When building an image, which has to be flashed to different devices, an HMAC cannot be used to sign file metadata, as the HMAC key is different on every device. File metadata can be protected using digital signature. This patch enables RSA signature based integrity verification.

---
 security/integrity/evm/Kconfig      |   14 +++++++
 security/integrity/evm/evm.h        |   31 ++++++++++++++++
 security/integrity/evm/evm_crypto.c |   66 ++++++++++++++++++++++++++---------
 security/integrity/evm/evm_main.c   |   65 ++++++++++++++++++++++++++--------
 4 files changed, 144 insertions(+), 32 deletions(-)
security/integrity/evm/Kconfig +14 -0
index 73f6540..92221b1 100644
@@ -10,3 +10,17 @@ config EVM
 	  integrity attacks.
 
 	  If you are unsure how to answer this question, answer N.
+
+config EVM_DIGSIG
+	boolean "EVM Digital Signature support"
+	depends on EVM
+	default n
+	select CRYPTO_KSIGN_RSA
+	help
+	  When building an image, which has to be flashed to different
+	  devices, an HMAC cannot be used to sign file metadata, as
+	  the HMAC key is different on every device.
+	  File metadata can be protected using digital signature.
+	  This option enables RSA signature based integrity verification.
+
+	  If unsure, say N.
security/integrity/evm/evm.h +31 -0
index d320f51..6d297a1 100644
@@ -12,14 +12,22 @@
  * File: evm.h
  *
  */
+
+#ifndef __INTEGRITY_EVM_H
+#define __INTEGRITY_EVM_H
+
 #include <linux/xattr.h>
 #include <linux/security.h>
+#include <linux/crypto/ksign.h>
+
 #include "../integrity.h"
 
 extern int evm_initialized;
 extern char *evm_hmac;
+extern char *evm_hash;
 
 extern struct crypto_shash *hmac_tfm;
+extern struct crypto_shash *hash_tfm;
 
 /* List of EVM protected security xattrs */
 extern char *evm_config_xattrnames[];
@@ -32,7 +40,30 @@ extern int evm_update_evmxattr(struct dentry *dentry,
 extern int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
 			 const char *req_xattr_value,
 			 size_t req_xattr_value_len, char *digest);
+extern int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
+			 const char *req_xattr_value,
+			 size_t req_xattr_value_len, char *digest);
 extern int evm_init_hmac(struct inode *inode, const struct xattr *xattr,
 			 char *hmac_val);
 extern int evm_init_secfs(void);
 extern void evm_cleanup_secfs(void);
+
+#ifdef CONFIG_EVM_DIGSIG
+
+static inline int evm_sign_verify(const char *sig, int siglen,
+		       const char *digest, int digestlen)
+{
+	return ksign_verify(sig, siglen, digest, digestlen);
+}
+
+#else
+
+static inline int evm_sign_verify(const char *sig, int siglen,
+		       const char *digest, int digestlen)
+{
+	return -EOPNOTSUPP;
+}
+
+#endif /* CONFIG_EVM_DIGSIG */
+
+#endif
security/integrity/evm/evm_crypto.c +49 -17

112 lines not on this page · raw message

security/integrity/evm/evm_main.c +50 -15

101 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#6 lore raw

RFC 4/5 ksign: provides keyring to search in for the key

In reply to Dmitry Kasatkin

From: Dmitry Kasatkin <[email protected]>

Allows to specify keyring to search in for the key. Later patches will use special keyrings to store EVM and IMA public keys.

---
 crypto/ksign.c               |   17 ++++++++++++++---
 include/linux/crypto/ksign.h |    4 ++--
 security/integrity/evm/evm.h |    2 +-
 3 files changed, 17 insertions(+), 6 deletions(-)
crypto/ksign.c +14 -3
index 60ccfc9..ed355b7 100644
@@ -183,7 +183,7 @@ err1:
 /*
  * Signature verification with public key
  */
-int ksign_verify(const char *sig, int siglen,
+int ksign_verify(struct key *keyring, const char *sig, int siglen,
 		       const char *digest, int digestlen)
 {
 	int err = -ENOMEM;
@@ -201,10 +201,21 @@ int ksign_verify(const char *sig, int siglen,
 
 	sprintf(name, "%llX", __be64_to_cpup((uint64_t *)sh->keyid));
 
-	key = request_key(&key_type_user, name, NULL);
+	if (keyring) {
+		/* search in specific keyring */
+		key_ref_t kref;
+		kref = keyring_search(make_key_ref(keyring, 1UL),
+						&key_type_user, name);
+		if (IS_ERR(kref))
+			key = ERR_PTR(PTR_ERR(kref));
+		else
+			key = key_ref_to_ptr(kref);
+	} else {
+		key = request_key(&key_type_user, name, NULL);
+	}
 	if (IS_ERR(key)) {
 		pr_err("key not found, id: %s\n", name);
-		return -ENOENT;
+		return PTR_ERR(key);
 	}
 
 	desc = kzalloc(sizeof(*desc) + crypto_shash_descsize(shash),
include/linux/crypto/ksign.h +2 -2
index f1e47cb..ba23b2a 100644
@@ -32,12 +32,12 @@ struct signature_hdr {
 
 #ifdef CONFIG_CRYPTO_KSIGN
 
-int ksign_verify(const char *sig, int siglen,
+int ksign_verify(struct key *keyring, const char *sig, int siglen,
 		 const char *digest, int digestlen);
 
 #else
 
-static inline int ksign_verify(const char *sig, int siglen,
+static inline int ksign_verify(struct key *keyring, const char *sig, int siglen,
 		 const char *digest, int digestlen)
 {
 	return -EOPNOTSUPP;
security/integrity/evm/evm.h +1 -1
index 6d297a1..9e1bcba 100644
@@ -53,7 +53,7 @@ extern void evm_cleanup_secfs(void);
 static inline int evm_sign_verify(const char *sig, int siglen,
 		       const char *digest, int digestlen)
 {
-	return ksign_verify(sig, siglen, digest, digestlen);
+	return ksign_verify(NULL, sig, siglen, digest, digestlen);
 }
 
 #else
Signature · 1 line
1.7.4.1
#7 lore raw

RFC 5/5 evm: creates dedicated evm keyring to store public keys

In reply to Dmitry Kasatkin

From: Dmitry Kasatkin <[email protected]>

EVM/IMA might perform lots of signature verification operations. For that reason performance is very critical. This patch adds evm_keyring to store public keys used by EVM only.

---
 security/integrity/evm/evm.h      |    4 +++-
 security/integrity/evm/evm_main.c |   18 ++++++++++++++++++
 2 files changed, 21 insertions(+), 1 deletions(-)
security/integrity/evm/evm.h +3 -1
index 9e1bcba..4f4ba20 100644
@@ -32,6 +32,8 @@ extern struct crypto_shash *hash_tfm;
 /* List of EVM protected security xattrs */
 extern char *evm_config_xattrnames[];
 
+extern struct key *evm_keyring;
+
 extern int evm_init_key(void);
 extern int evm_update_evmxattr(struct dentry *dentry,
 			       const char *req_xattr_name,
@@ -53,7 +55,7 @@ extern void evm_cleanup_secfs(void);
 static inline int evm_sign_verify(const char *sig, int siglen,
 		       const char *digest, int digestlen)
 {
-	return ksign_verify(NULL, sig, siglen, digest, digestlen);
+	return ksign_verify(evm_keyring, sig, siglen, digest, digestlen);
 }
 
 #else
security/integrity/evm/evm_main.c +18 -0
index 65518fb..96794a0 100644
@@ -20,6 +20,7 @@
 #include <linux/integrity.h>
 #include <linux/evm.h>
 #include <crypto/hash.h>
+#include <linux/init_task.h>
 #include "evm.h"
 
 int evm_initialized;
@@ -38,6 +39,8 @@ char *evm_config_xattrnames[] = {
 	NULL
 };
 
+struct key *evm_keyring;
+
 static int evm_fixmode;
 static int __init evm_set_fixmode(char *str)
 {
@@ -382,18 +385,33 @@ static int __init init_evm(void)
 {
 	int error;
 
+#ifdef CONFIG_EVM_DIGSIG
+	evm_keyring = keyring_alloc("_evm", 0, 0, &init_cred,
+					KEY_ALLOC_NOT_IN_QUOTA, NULL);
+	if (IS_ERR(evm_keyring))
+		return PTR_ERR(evm_keyring);
+#endif
+
 	error = evm_init_secfs();
 	if (error < 0) {
 		printk(KERN_INFO "EVM: Error registering secfs\n");
 		goto err;
 	}
+
+	return 0;
 err:
+#ifdef CONFIG_EVM_DIGSIG
+	key_put(evm_keyring);
+#endif
 	return error;
 }
 
 static void __exit cleanup_evm(void)
 {
 	evm_cleanup_secfs();
+#ifdef CONFIG_EVM_DIGSIG
+	key_put(evm_keyring);
+#endif
 	if (hmac_tfm)
 		crypto_free_shash(hmac_tfm);
 	if (hash_tfm)
Signature · 1 line
1.7.4.1