[PATCH v2.1 0/7] evm: digital signature verification extension

2011-10-14 Thread Dmitry Kasatkin
Hello,

Changes to version 2.1:
* MPI lib moved to /lib directory.
* added configuration option CONFIG_MPILIB_EXTRA to exclude building
  a part of MPI library, which is not used in RSA impelementation.
* added API documentation
* added Documentation for digsig
* splitted evm digital signature verification patch into 2.
  Common code will be used by IMA digital singnature verification.

Changes to version 2.0:
* MPI patch has been split to smaller in order to go to mailing lists.
  First 2 patches include only source and header files which are needed
  to build ksign verification. Headers and sources are split just to
  meet 100k kernel.org limit.
  Last patch adds all rest soures from original ported MPI library.
  
Changes to version 1.1:
* GnuPG MPI library has been refactored with lindent and checkpatch errors
  and warnings has been fixed.
* creation of evm keyring has been remove. It is done now in user space.
* related ksign and evm patches has been squashed.
* patch descriptions has been updated.
 
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 GnuPG MPI library patch was posted here on linux-crypto back in
http://www.mail-archive.com/linux-crypto@vger.kernel.org/msg05613.html.
Reason for upstreaming was that it to be a solid in-kernel user of the API.
Now with the recent merging of the EVM patches in linux-next via
security-testing-2.6/#next, MPI library is required for EVM digital signature
verification extension.

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:
git://git.kernel.org/pub/scm/linux/kernel/git/kasatkin/ima-ksign.git
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 (7):
  crypto: GnuPG based MPI lib - source files (part 1)
  crypto: GnuPG based MPI lib - header files (part 2)
  crypto: GnuPG based MPI lib - make files (part 3)
  crypto: GnuPG based MPI lib - additional sources (part 4)
  crypto: digital signature verification support
  integrity: digital signature verification using multiple keyrings
  evm: digital signature verification support

 Documentation/digsig.txt|   97 +++
 include/linux/digsig.h  |   64 ++
 include/linux/mpi.h |  146 
 lib/Kconfig |   25 +
 lib/Makefile|3 +
 

[PATCH v2.1 4/7] crypto: GnuPG based MPI lib - additional sources (part 4)

2011-10-14 Thread Dmitry Kasatkin
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.
The difference is that checkpatch reported errors and warnings have been fixed.

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

Due to patch size limitation, the patch is divided into 4 parts.

This code is unnecessary for RSA digital signature verification,
but for completeness it is included here and can be compiled,
if CONFIG_MPILIB_EXTRA is enabled.

Signed-off-by: Dmitry Kasatkin dmitry.kasat...@intel.com
---
 lib/Kconfig|   10 ++
 lib/mpi/Makefile   |   12 ++
 lib/mpi/generic_mpi-asm-defs.h |4 +
 lib/mpi/generic_udiv-w-sdiv.c  |  106 +
 lib/mpi/mpi-add.c  |  234 
 lib/mpi/mpi-cmp.c  |   68 
 lib/mpi/mpi-div.c  |  333 
 lib/mpi/mpi-gcd.c  |   59 +++
 lib/mpi/mpi-inline.c   |   31 
 lib/mpi/mpi-inv.c  |  187 ++
 lib/mpi/mpi-mpow.c |  133 
 lib/mpi/mpi-mul.c  |  194 +++
 lib/mpi/mpi-scan.c |  136 
 13 files changed, 1507 insertions(+), 0 deletions(-)
 create mode 100644 lib/mpi/generic_mpi-asm-defs.h
 create mode 100644 lib/mpi/generic_udiv-w-sdiv.c
 create mode 100644 lib/mpi/mpi-add.c
 create mode 100644 lib/mpi/mpi-cmp.c
 create mode 100644 lib/mpi/mpi-div.c
 create mode 100644 lib/mpi/mpi-gcd.c
 create mode 100644 lib/mpi/mpi-inline.c
 create mode 100644 lib/mpi/mpi-inv.c
 create mode 100644 lib/mpi/mpi-mpow.c
 create mode 100644 lib/mpi/mpi-mul.c
 create mode 100644 lib/mpi/mpi-scan.c

diff --git a/lib/Kconfig b/lib/Kconfig
index f69ce08..b5dd7ef 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -286,4 +286,14 @@ config MPILIB
  It is used to implement RSA digital signature verification,
  which is used by IMA/EVM digital signature extension.
 
+config MPILIB_EXTRA
+   bool Multiprecision maths library - additional sources
+   depends on MPILIB
+   help
+ Multiprecision maths library from GnuPG.
+ It is used to implement RSA digital signature verification,
+ which is used by IMA/EVM digital signature extension.
+ This code in unnecessary for RSA digital signature verification,
+ and can be compiled if needed.  
+
 endmenu
diff --git a/lib/mpi/Makefile b/lib/mpi/Makefile
index 0c1c6c3..6ce238b 100644
--- a/lib/mpi/Makefile
+++ b/lib/mpi/Makefile
@@ -20,3 +20,15 @@ mpi-y = \
mpi-pow.o   \
mpiutil.o
 
+mpi-$(CONFIG_MPILIB_EXTRA) += \
+   generic_udiv-w-sdiv.o   \
+   mpi-add.o   \
+   mpi-div.o   \
+   mpi-cmp.o   \
+   mpi-gcd.o   \
+   mpi-inline.o\
+   mpi-inv.o   \
+   mpi-mpow.o  \
+   mpi-mul.o   \
+   mpi-scan.o  \
+
diff --git a/lib/mpi/generic_mpi-asm-defs.h b/lib/mpi/generic_mpi-asm-defs.h
new file mode 100644
index 000..047d1f5
--- /dev/null
+++ b/lib/mpi/generic_mpi-asm-defs.h
@@ -0,0 +1,4 @@
+/* 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)
diff --git a/lib/mpi/generic_udiv-w-sdiv.c b/lib/mpi/generic_udiv-w-sdiv.c
new file mode 100644
index 000..cb8f5f0
--- /dev/null
+++ b/lib/mpi/generic_udiv-w-sdiv.c
@@ -0,0 +1,106 @@
+/* mpihelp_udiv_w_sdiv -- implement udiv_qrnnd on machines with only signed
+ *   division.
+ * Copyright (C) 1992, 1994, 1996, 1998 Free Software Foundation, Inc.
+ * Contributed by Peter L. Montgomery.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include mpi-internal.h
+#include longlong.h
+
+#if 0  /* not yet ported to MPI */
+
+mpi_limb_t

[PATCH v2.1 3/7] crypto: GnuPG based MPI lib - make files (part 3)

2011-10-14 Thread Dmitry Kasatkin
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.
The difference is that checkpatch reported errors and warnings have been fixed.

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

Due to patch size limitation, the patch is divided into 4 parts.

Signed-off-by: Dmitry Kasatkin dmitry.kasat...@intel.com
---
 lib/Kconfig  |7 +++
 lib/Makefile |2 ++
 lib/mpi/Makefile |   22 ++
 3 files changed, 31 insertions(+), 0 deletions(-)
 create mode 100644 lib/mpi/Makefile

diff --git a/lib/Kconfig b/lib/Kconfig
index 6c695ff..f69ce08 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -279,4 +279,11 @@ config CORDIC
 config LLIST
bool
 
+config MPILIB
+   tristate Multiprecision maths library
+   help
+ Multiprecision maths library from GnuPG.
+ It is used to implement RSA digital signature verification,
+ which is used by IMA/EVM digital signature extension.
+
 endmenu
diff --git a/lib/Makefile b/lib/Makefile
index d5d175c..97705ae 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -117,6 +117,8 @@ obj-$(CONFIG_CORDIC) += cordic.o
 
 obj-$(CONFIG_LLIST) += llist.o
 
+obj-$(CONFIG_MPILIB) += mpi/
+
 hostprogs-y:= gen_crc32table
 clean-files:= crc32table.h
 
diff --git a/lib/mpi/Makefile b/lib/mpi/Makefile
new file mode 100644
index 000..0c1c6c3
--- /dev/null
+++ b/lib/mpi/Makefile
@@ -0,0 +1,22 @@
+#
+# MPI multiprecision maths library (from gpg)
+#
+
+obj-$(CONFIG_MPILIB) = mpi.o
+
+mpi-y = \
+   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 \
+   mpicoder.o  \
+   mpi-bit.o   \
+   mpih-cmp.o  \
+   mpih-div.o  \
+   mpih-mul.o  \
+   mpi-pow.o   \
+   mpiutil.o
+
-- 
1.7.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2.1 7/7] evm: digital signature verification support

2011-10-14 Thread Dmitry Kasatkin
This patch adds support for digital signature verification to EVM.
With this feature file metadata can be protected using digital
signature instead of an HMAC. When building an image,
which has to be flashed to different devices, an HMAC cannot
be used to sign file metadata, because the HMAC key should be
different on every device.

Signed-off-by: Dmitry Kasatkin dmitry.kasat...@intel.com
Acked-by: Mimi Zohar zo...@us.ibm.com
---
 security/integrity/evm/evm.h|   12 +
 security/integrity/evm/evm_crypto.c |   66 ++--
 security/integrity/evm/evm_main.c   |   94 ++-
 3 files changed, 142 insertions(+), 30 deletions(-)

diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
index d320f51..c885247 100644
--- a/security/integrity/evm/evm.h
+++ b/security/integrity/evm/evm.h
@@ -12,14 +12,21 @@
  * File: evm.h
  *
  */
+
+#ifndef __INTEGRITY_EVM_H
+#define __INTEGRITY_EVM_H
+
 #include linux/xattr.h
 #include linux/security.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 +39,12 @@ 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);
+
+#endif
diff --git a/security/integrity/evm/evm_crypto.c 
b/security/integrity/evm/evm_crypto.c
index 5dd5b140..847a2d7 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -26,34 +26,48 @@ static unsigned char evmkey[MAX_KEY_SIZE];
 static int evmkey_len = MAX_KEY_SIZE;
 
 struct crypto_shash *hmac_tfm;
+struct crypto_shash *hash_tfm;
 
-static struct shash_desc *init_desc(void)
+static struct shash_desc *init_desc(const char type)
 {
int rc;
+   char *algo;
+   struct crypto_shash **tfm;
struct shash_desc *desc;
 
-   if (hmac_tfm == NULL) {
-   hmac_tfm = crypto_alloc_shash(evm_hmac, 0, CRYPTO_ALG_ASYNC);
-   if (IS_ERR(hmac_tfm)) {
+   if (type == EVM_XATTR_HMAC) {
+   tfm = hmac_tfm;
+   algo = evm_hmac;
+   } else {
+   tfm = hash_tfm;
+   algo = evm_hash;
+   }
+
+   if (*tfm == NULL) {
+   *tfm = crypto_alloc_shash(algo, 0, CRYPTO_ALG_ASYNC);
+   if (IS_ERR(*tfm)) {
pr_err(Can not allocate %s (reason: %ld)\n,
-  evm_hmac, PTR_ERR(hmac_tfm));
-   rc = PTR_ERR(hmac_tfm);
-   hmac_tfm = NULL;
+  algo, PTR_ERR(*tfm));
+   rc = PTR_ERR(*tfm);
+   *tfm = NULL;
return ERR_PTR(rc);
}
}
 
-   desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac_tfm),
+   desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(*tfm),
GFP_KERNEL);
if (!desc)
return ERR_PTR(-ENOMEM);
 
-   desc-tfm = hmac_tfm;
+   desc-tfm = *tfm;
desc-flags = CRYPTO_TFM_REQ_MAY_SLEEP;
 
-   rc = crypto_shash_setkey(hmac_tfm, evmkey, evmkey_len);
-   if (rc)
-   goto out;
+   if (type == EVM_XATTR_HMAC) {
+   rc = crypto_shash_setkey(*tfm, evmkey, evmkey_len);
+   if (rc)
+   goto out;
+   }
+
rc = crypto_shash_init(desc);
 out:
if (rc) {
@@ -97,9 +111,11 @@ static void hmac_add_misc(struct shash_desc *desc, struct 
inode *inode,
  * the hmac using the requested xattr value. Don't alloc/free memory for
  * each xattr, but attempt to re-use the previously allocated memory.
  */
-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)
+static int evm_calc_hmac_or_hash(struct dentry *dentry,
+   const char *req_xattr_name,
+   const char *req_xattr_value,
+   size_t req_xattr_value_len,
+   char type, char *digest)
 {
struct inode *inode = dentry-d_inode;
struct shash_desc *desc;
@@ -111,7 +127,7 @@ int evm_calc_hmac(struct dentry *dentry, const char 

[PATCH v2.1 6/7] integrity: digital signature verification using multiple keyrings

2011-10-14 Thread Dmitry Kasatkin
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: Dmitry Kasatkin dmitry.kasat...@intel.com
---
 security/integrity/Kconfig |   14 +++
 security/integrity/Makefile|1 +
 security/integrity/digsig.c|   48 
 security/integrity/integrity.h |   20 
 4 files changed, 83 insertions(+), 0 deletions(-)
 create mode 100644 security/integrity/digsig.c

diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index 4bf00ac..d87fa2a 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -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
diff --git a/security/integrity/Makefile b/security/integrity/Makefile
index 0ae44ae..bece056 100644
--- a/security/integrity/Makefile
+++ b/security/integrity/Makefile
@@ -3,6 +3,7 @@
 #
 
 obj-$(CONFIG_INTEGRITY) += integrity.o
+obj-$(CONFIG_INTEGRITY_DIGSIG) += digsig.o
 
 integrity-y := iint.o
 
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
new file mode 100644
index 000..b5d1e01
--- /dev/null
+++ b/security/integrity/digsig.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 Intel Corporation
+ *
+ * Author:
+ * Dmitry Kasatkin dmitry.kasat...@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])) {
+   pr_err(no %s keyring: %ld\n, keyring_name[id],
+   PTR_ERR(keyring[id]));
+   keyring[id] = NULL;
+   return PTR_ERR(keyring[id]);
+   }
+   }
+
+   return digsig_verify(keyring[id], sig, siglen, digest, digestlen);
+}
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index e898094..9fc723b 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -51,5 +51,25 @@ 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;
-- 
1.7.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] crypto: ghash: Avoid null pointer dereference if no key is set.

2011-10-14 Thread Nick Bowler
On 2011-10-14 10:37 -0400, Nick Bowler wrote:
 The ghash_update function passes a pointer to gf128mul_4k_lle which will
 be NULL if ghash_setkey is not called or if the most recent call to
 ghash_setkey failed to allocate memory.  This causes an oops.  Fix this
 up by returning an error code in the null case.
 
 This is trivially triggered from unpriviliged userspace through the
 AF_ALG interface by simply writing to the socket without setting a key.

It looks like this can also happen in ghash_final if an evil user calls
setkey, update with a length that's not a multiple of the block size,
then setkey again (this time failing due to an allocation failure) then
final.  Thus, I suppose that final needs the same check.

v2 forthcoming...
-- 
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] crypto: ghash: Avoid null pointer dereference if no key is set.

2011-10-14 Thread Nick Bowler
The ghash_update function passes a pointer to gf128mul_4k_lle which will
be NULL if ghash_setkey is not called or if the most recent call to
ghash_setkey failed to allocate memory.  This causes an oops.  Fix this
up by returning an error code in the null case.

This is trivially triggered from unprivileged userspace through the
AF_ALG interface by simply writing to the socket without setting a key.

The ghash_final function has a similar issue, but triggering it requires
a memory allocation failure in ghash_setkey _after_ at least one
successful call to ghash_update.

  BUG: unable to handle kernel NULL pointer dereference at 0670
  IP: [d88c92d4] gf128mul_4k_lle+0x23/0x60 [gf128mul]
  *pde = 
  Oops:  [#1] PREEMPT SMP
  Modules linked in: ghash_generic gf128mul algif_hash af_alg nfs lockd nfs_acl 
sunrpc bridge ipv6 stp llc

  Pid: 1502, comm: hashatron Tainted: GW   3.1.0-rc9-00085-ge9308cf #32 
Bochs Bochs
  EIP: 0060:[d88c92d4] EFLAGS: 0202 CPU: 0
  EIP is at gf128mul_4k_lle+0x23/0x60 [gf128mul]
  EAX: d69db1f0 EBX: d6b8ddac ECX: 0004 EDX: 
  ESI: 0670 EDI: d6b8ddac EBP: d6b8ddc8 ESP: d6b8dda4
   DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
  Process hashatron (pid: 1502, ti=d6b8c000 task=d681 task.ti=d6b8c000)
  Stack:
    d69db1f0 0163  d6b8ddc8 c101a520 d69db1f0 d52aa000
   0ff0 d6b8dde8 d88d310f d6b8a3f8 d52aa000 1000 d88d502c d6b8ddfc
   1000 d6b8ddf4 c11676ed d69db1e8 d6b8de24 c11679ad d52aa000 
  Call Trace:
   [c101a520] ? kmap_atomic_prot+0x37/0xa6
   [d88d310f] ghash_update+0x85/0xbe [ghash_generic]
   [c11676ed] crypto_shash_update+0x18/0x1b
   [c11679ad] shash_ahash_update+0x22/0x36
   [c11679cc] shash_async_update+0xb/0xd
   [d88ce0ba] hash_sendpage+0xba/0xf2 [algif_hash]
   [c121b24c] kernel_sendpage+0x39/0x4e
   [d88ce000] ? 0xd88cdfff
   [c121b298] sock_sendpage+0x37/0x3e
   [c121b261] ? kernel_sendpage+0x4e/0x4e
   [c10b4dbc] pipe_to_sendpage+0x56/0x61
   [c10b4e1f] splice_from_pipe_feed+0x58/0xcd
   [c10b4d66] ? splice_from_pipe_begin+0x10/0x10
   [c10b51f5] __splice_from_pipe+0x36/0x55
   [c10b4d66] ? splice_from_pipe_begin+0x10/0x10
   [c10b6383] splice_from_pipe+0x51/0x64
   [c10b63c2] ? default_file_splice_write+0x2c/0x2c
   [c10b63d5] generic_splice_sendpage+0x13/0x15
   [c10b4d66] ? splice_from_pipe_begin+0x10/0x10
   [c10b527f] do_splice_from+0x5d/0x67
   [c10b6865] sys_splice+0x2bf/0x363
   [c129373b] ? sysenter_exit+0xf/0x16
   [c104dc1e] ? trace_hardirqs_on_caller+0x10e/0x13f
   [c129370c] sysenter_do_call+0x12/0x32
  Code: 83 c4 0c 5b 5e 5f c9 c3 55 b9 04 00 00 00 89 e5 57 8d 7d e4 56 53 8d 5d 
e4 83 ec 18 89 45 e0 89 55 dc 0f b6 70 0f c1 e6 04 01 d6 f3 a5 be 0f 00 00 00 
4e 89 d8 e8 48 ff ff ff 8b 45 e0 89 da 0f
  EIP: [d88c92d4] gf128mul_4k_lle+0x23/0x60 [gf128mul] SS:ESP 0068:d6b8dda4
  CR2: 0670
  ---[ end trace 4eaa2a86a8e2da24 ]---
  note: hashatron[1502] exited with preempt_count 1
  BUG: scheduling while atomic: hashatron/1502/0x1002
  INFO: lockdep is turned off.
  [...]

Signed-off-by: Nick Bowler nbow...@elliptictech.com
---
 crypto/ghash-generic.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

I checked all the other keyed hashes in crypto/ that I could see, and
none of them crash when run without a key.  However, they all produce
(presumably bogus) output in this case, so it may be prudent to make
them return an error, too, for consistency.  Alternately, we could try
to modify ghash so that it behaves like the other keyed hashes (and
doesn't crash) when no key is set.

I haven't had a chance to look for issues in any ciphers yet, or in
other hash modes.

diff --git a/crypto/ghash-generic.c b/crypto/ghash-generic.c
index be44256..7835b8f 100644
--- a/crypto/ghash-generic.c
+++ b/crypto/ghash-generic.c
@@ -67,6 +67,9 @@ static int ghash_update(struct shash_desc *desc,
struct ghash_ctx *ctx = crypto_shash_ctx(desc-tfm);
u8 *dst = dctx-buffer;
 
+   if (!ctx-gf128)
+   return -ENOKEY;
+
if (dctx-bytes) {
int n = min(srclen, dctx-bytes);
u8 *pos = dst + (GHASH_BLOCK_SIZE - dctx-bytes);
@@ -119,6 +122,9 @@ static int ghash_final(struct shash_desc *desc, u8 *dst)
struct ghash_ctx *ctx = crypto_shash_ctx(desc-tfm);
u8 *buf = dctx-buffer;
 
+   if (!ctx-gf128)
+   return -ENOKEY;
+
ghash_flush(ctx, dctx);
memcpy(dst, buf, GHASH_BLOCK_SIZE);
 
-- 
1.7.3.4

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2.1 4/7] crypto: GnuPG based MPI lib - additional sources (part 4)

2011-10-14 Thread James Morris
On Fri, 14 Oct 2011, Dmitry Kasatkin wrote:

 +#if 0/* not yet ported to MPI */
 +
 +mpi_limb_t
 +mpihelp_udiv_w_sdiv(mpi_limp_t *rp,
 + mpi_limp_t *a1, mpi_limp_t *a0, mpi_limp_t *d)

Drop this if it's not working.


-- 
James Morris
jmor...@namei.org
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html