Skip to contentSkip to conversation

evm: digital signature extension

RFC In review Dmitry Kasatkin 4 participants 15 messages Aug 11, 2011 – Aug 17, 2011

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

cover evm: digital signature extension

Hello,

As EVM patches were recently merged to security-testing-2.6#next, it is a good time to resend evm signature verification patches for active discussion. Last time I forgot --cc linux-crypto. Here it is.

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.

The motivation for integrity protection, in general, is to protect against offline modifications. The runtime protection is ensured via access control mechanisms. Of particular importance is protecting users or owners from being sold or given tampered 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. The EVM digital signature extension makes this feasible for consumerelectronics/embedded devices.

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 (3.x.x) 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.

#2 lore raw

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

Hi,

Can anyone please tell why this patch did not appear in archives? I have received it in my 2 accounts, but I cannot see it in archive. Is any size limitations??

- Dmitry

Quoted 10 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.

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

#3 lore raw

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

Quoted 8 lines · Dmitry Kasatkin
Quoted 7 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. This library is used to implemenet RSA digital signature verification used in IMA/EVM integrity protection subsystem.

Was there a particular reason to select the GnuPG mpi lib? Why not include gmp (the gnupg mpi lib is a very old fork of gmp), or some other big number library?

regards,
Nikos

#4 lore raw

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

Quoted 5 lines · Nikos Mavrogiannopoulos
Quoted 3 lines · Dmitry Kasatkin
Quoted 2 lines · Dmitry Kasatkin

From: Dmitry Kasatkin <[email protected]>

Quoted 9 lines
Quoted 5 lines
Quoted 5 lines

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.

Was there a particular reason to select the GnuPG mpi lib? Why not include gmp (the gnupg mpi lib is a very old fork of gmp), or some other big number library?

GNUPG MPI kernel port was available and has shown the best performance comparing to other kernel implementations
such as LibTomMath and once other rsa implementation..

In fact I took libtommath from your cryptodev-linux#newapi project. I have patches and RSA implementation in my git trees. IIRC performance was about twice worse than in Gnupg MPI lib...

- Dmitry

- Dmitry

Quoted 6 lines

regards,
Nikos
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#5 lore raw

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

Quoted 9 lines · Dmitry Kasatkin
Quoted 3 lines

Was there a particular reason to select the GnuPG mpi lib? Why not include gmp (the gnupg mpi lib is a very old fork of gmp), or some other big number library?

GNUPG MPI kernel port was available and has shown the best performance comparing to other kernel implementations
such as LibTomMath and once other rsa implementation..
In fact I took libtommath from your cryptodev-linux#newapi project. I have patches and RSA implementation in my git trees.
IIRC performance was about twice worse than in Gnupg MPI lib...

Quite impressive [0]. In GnuTLS we had the same (2x) performance optimization by switching to gmp from the gnupg mpi. I remember some projects ported gmp to linux kernel, but I don't know how wise that would be. Gmp (and the original gnupg mpi - don't know about the port) have no easy way to indicate memory allocation failure. That was my reason to select libtommath instead of them.

regards,
Nikos

[0]. There is a limitation in libtommath as I ported it in the linux kernel. It uses 32-bit numbers even in x86-64. Libtommath required an 128-bit type to support 64-bit numbers that was available to user-space via gcc but not in linux-kernel. Performance of mpi was not my goal then, so I didn't investigate it more.

maintainer
#6 lore raw

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

In reply to Dmitry Kasatkin
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.

First thing -- this code needs to be formatted using kernel coding style.

- James

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

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

Quoted 4 lines · James Morris
Quoted 2 lines · Dmitry Kasatkin

From: Dmitry Kasatkin <[email protected]>

Quoted 8 lines
Quoted 3 lines

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.

First thing -- this code needs to be formatted using kernel coding style.

- James

The code is inherited from GnuPG which does not follow kernel coding standard. There are lots of "checkpatch" errors and warnings.. Do you say it must be reformatted?

- Dmitry

#8 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
maintainer
#9 lore raw

Re: [RFC v1.1 2/5] crypto: ksign - digital signature verification support

Quoted 14 lines · Dmitry Kasatkin
crypto/ksign.c new file +14 -0
+static int ksign_verify_rsa(struct key *key,
+		    const char *sig, int siglen,
+		       const char *h, int hlen)
+{
+	int err = -ENOMEM;
+	unsigned long len;
+	unsigned long mlen, mblen;
+	unsigned nret, l;
+	int valid, head, i;
+	unsigned char *out1 = NULL, *out2 = NULL;
+	MPI in = NULL, res = NULL, pkey[2];
+	uint8_t *p, *datap, *endp;
+	struct user_key_payload *ukp;
+	struct pubkey_hdr *pkh;

crypto/ksign.c line 108

Quoted 10 lines
crypto/ksign.c new file +10 -0
+
+	down_read(&key->sem);
+	ukp = key->payload.data;
+	pkh = (struct pubkey_hdr *)ukp->data;
+
+	if (pkh->version != 1)
+		return -EINVAL;
+
+	if (pkh->algo != PUBKEY_ALGO_RSA)
+		return -EINVAL;

Are you supposed to be still holding key->sem here?

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

Re: [RFC v1.1 2/5] crypto: ksign - digital signature verification support

Quoted 19 lines · James Morris
Quoted 17 lines · Dmitry Kasatkin
crypto/ksign.c new file +17 -0
+static int ksign_verify_rsa(struct key *key,
+		    const char *sig, int siglen,
+		       const char *h, int hlen)
+{
+	int err = -ENOMEM;
+	unsigned long len;
+	unsigned long mlen, mblen;
+	unsigned nret, l;
+	int valid, head, i;
+	unsigned char *out1 = NULL, *out2 = NULL;
+	MPI in = NULL, res = NULL, pkey[2];
+	uint8_t *p, *datap, *endp;
+	struct user_key_payload *ukp;
+	struct pubkey_hdr *pkh;
+
+	down_read(&key->sem);
+	ukp = key->payload.data;
Quoted 9 lines

crypto/ksign.c line 108

Quoted 7 lines
crypto/ksign.c new file +7 -0
+	pkh = (struct pubkey_hdr *)ukp->data;
+
+	if (pkh->version != 1)
+		return -EINVAL;
+
+	if (pkh->algo != PUBKEY_ALGO_RSA)
+		return -EINVAL;

Are you supposed to be still holding key->sem here?

Of course not.
that was late addition. Should be goto as in following cases...

- Dmitry

#11 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
maintainer
#12 lore raw

Re: [RFC v1.1 3/5] evm: digital signature support

Quoted 6 lines · 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.

This description (also the kconfig text) is not very clear. Perhaps start with what the feature does rather than what the lack of it doesn't.

Signature · 2 lines
James Morris
<[email protected]>
#13 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
#14 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 a99c644..73c0568 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