summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig4
-rw-r--r--lib/Makefile2
-rw-r--r--lib/bug.c2
-rw-r--r--lib/clz_tab.c18
-rw-r--r--lib/digsig.c52
-rw-r--r--lib/mpi/longlong.h44
-rw-r--r--lib/mpi/mpi-bit.c19
-rw-r--r--lib/mpi/mpi-div.c5
-rw-r--r--lib/mpi/mpi-pow.c2
-rw-r--r--lib/mpi/mpicoder.c91
-rw-r--r--lib/mpi/mpih-div.c4
-rw-r--r--lib/mpi/mpiutil.c5
12 files changed, 97 insertions, 151 deletions
diff --git a/lib/Kconfig b/lib/Kconfig
index 169eb7c598e5..d69d321a0997 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -279,6 +279,9 @@ config AVERAGE
 
 	  If unsure, say N.
 
+config CLZ_TAB
+	bool
+
 config CORDIC
 	tristate "CORDIC algorithm"
 	help
@@ -287,6 +290,7 @@ config CORDIC
 
 config MPILIB
 	tristate
+	select CLZ_TAB
 	help
 	  Multiprecision maths library from GnuPG.
 	  It is used to implement RSA digital signature verification,
diff --git a/lib/Makefile b/lib/Makefile
index d71aae1b01b3..18515f0267c4 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -121,6 +121,8 @@ obj-$(CONFIG_DQL) += dynamic_queue_limits.o
 obj-$(CONFIG_MPILIB) += mpi/
 obj-$(CONFIG_SIGNATURE) += digsig.o
 
+obj-$(CONFIG_CLZ_TAB) += clz_tab.o
+
 hostprogs-y	:= gen_crc32table
 clean-files	:= crc32table.h
 
diff --git a/lib/bug.c b/lib/bug.c
index 19552096d16b..a28c1415357c 100644
--- a/lib/bug.c
+++ b/lib/bug.c
@@ -169,7 +169,7 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
 		return BUG_TRAP_TYPE_WARN;
 	}
 
-	printk(KERN_EMERG "------------[ cut here ]------------\n");
+	printk(KERN_DEFAULT "------------[ cut here ]------------\n");
 
 	if (file)
 		printk(KERN_CRIT "kernel BUG at %s:%u!\n",
diff --git a/lib/clz_tab.c b/lib/clz_tab.c
new file mode 100644
index 000000000000..7287b4a991a7
--- /dev/null
+++ b/lib/clz_tab.c
@@ -0,0 +1,18 @@
+const unsigned char __clz_tab[] = {
+	0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
+	    5, 5, 5, 5, 5, 5, 5, 5,
+	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+	    6, 6, 6, 6, 6, 6, 6, 6,
+	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+	    7, 7, 7, 7, 7, 7, 7, 7,
+	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+	    7, 7, 7, 7, 7, 7, 7, 7,
+	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+	    8, 8, 8, 8, 8, 8, 8, 8,
+	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+	    8, 8, 8, 8, 8, 8, 8, 8,
+	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+	    8, 8, 8, 8, 8, 8, 8, 8,
+	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+	    8, 8, 8, 8, 8, 8, 8, 8,
+};
diff --git a/lib/digsig.c b/lib/digsig.c
index fd2402f67f89..286d558033e2 100644
--- a/lib/digsig.c
+++ b/lib/digsig.c
@@ -34,14 +34,9 @@ static int pkcs_1_v1_5_decode_emsa(const unsigned char *msg,
 			unsigned long  msglen,
 			unsigned long  modulus_bitlen,
 			unsigned char *out,
-			unsigned long *outlen,
-			int *is_valid)
+			unsigned long *outlen)
 {
 	unsigned long modulus_len, ps_len, i;
-	int result;
-
-	/* default to invalid packet */
-	*is_valid = 0;
 
 	modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
 
@@ -50,39 +45,30 @@ static int pkcs_1_v1_5_decode_emsa(const unsigned char *msg,
 		return -EINVAL;
 
 	/* separate encoded message */
-	if ((msg[0] != 0x00) || (msg[1] != (unsigned char)1)) {
-		result = -EINVAL;
-		goto bail;
-	}
+	if ((msg[0] != 0x00) || (msg[1] != (unsigned char)1))
+		return -EINVAL;
 
 	for (i = 2; i < modulus_len - 1; i++)
 		if (msg[i] != 0xFF)
 			break;
 
 	/* separator check */
-	if (msg[i] != 0) {
+	if (msg[i] != 0)
 		/* There was no octet with hexadecimal value 0x00
 		to separate ps from m. */
-		result = -EINVAL;
-		goto bail;
-	}
+		return -EINVAL;
 
 	ps_len = i - 2;
 
 	if (*outlen < (msglen - (2 + ps_len + 1))) {
 		*outlen = msglen - (2 + ps_len + 1);
-		result = -EOVERFLOW;
-		goto bail;
+		return -EOVERFLOW;
 	}
 
 	*outlen = (msglen - (2 + ps_len + 1));
 	memcpy(out, &msg[2 + ps_len + 1], *outlen);
 
-	/* valid packet */
-	*is_valid = 1;
-	result    = 0;
-bail:
-	return result;
+	return 0;
 }
 
 /*
@@ -96,7 +82,7 @@ static int digsig_verify_rsa(struct key *key,
 	unsigned long len;
 	unsigned long mlen, mblen;
 	unsigned nret, l;
-	int valid, head, i;
+	int head, i;
 	unsigned char *out1 = NULL, *out2 = NULL;
 	MPI in = NULL, res = NULL, pkey[2];
 	uint8_t *p, *datap, *endp;
@@ -105,6 +91,10 @@ static int digsig_verify_rsa(struct key *key,
 
 	down_read(&key->sem);
 	ukp = key->payload.data;
+
+	if (ukp->datalen < sizeof(*pkh))
+		goto err1;
+
 	pkh = (struct pubkey_hdr *)ukp->data;
 
 	if (pkh->version != 1)
@@ -117,18 +107,23 @@ static int digsig_verify_rsa(struct key *key,
 		goto err1;
 
 	datap = pkh->mpi;
-	endp = datap + ukp->datalen;
+	endp = ukp->data + ukp->datalen;
+
+	err = -ENOMEM;
 
 	for (i = 0; i < pkh->nmpi; i++) {
 		unsigned int remaining = endp - datap;
 		pkey[i] = mpi_read_from_buffer(datap, &remaining);
+		if (!pkey[i])
+			goto err;
 		datap += remaining;
 	}
 
 	mblen = mpi_get_nbits(pkey[0]);
 	mlen = (mblen + 7)/8;
 
-	err = -ENOMEM;
+	if (mlen == 0)
+		goto err;
 
 	out1 = kzalloc(mlen, GFP_KERNEL);
 	if (!out1)
@@ -167,10 +162,9 @@ static int digsig_verify_rsa(struct key *key,
 	memset(out1, 0, head);
 	memcpy(out1 + head, p, l);
 
-	err = -EINVAL;
-	pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len, &valid);
+	err = pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len);
 
-	if (valid && len == hlen)
+	if (!err && len == hlen)
 		err = memcmp(out2, h, hlen);
 
 err:
@@ -178,8 +172,8 @@ err:
 	mpi_free(res);
 	kfree(out1);
 	kfree(out2);
-	mpi_free(pkey[0]);
-	mpi_free(pkey[1]);
+	while (--i >= 0)
+		mpi_free(pkey[i]);
 err1:
 	up_read(&key->sem);
 
diff --git a/lib/mpi/longlong.h b/lib/mpi/longlong.h
index b87487b40a8b..29f98624ef93 100644
--- a/lib/mpi/longlong.h
+++ b/lib/mpi/longlong.h
@@ -1200,18 +1200,40 @@ do { \
 	"r" ((USItype)(v)) \
 	: "%g1", "%g2" __AND_CLOBBER_CC)
 #define UMUL_TIME 39		/* 39 instructions */
-#endif
-#ifndef udiv_qrnnd
-#ifndef LONGLONG_STANDALONE
+/* It's quite necessary to add this much assembler for the sparc.
+   The default udiv_qrnnd (in C) is more than 10 times slower!  */
 #define udiv_qrnnd(q, r, n1, n0, d) \
-do { USItype __r; \
-	(q) = __udiv_qrnnd(&__r, (n1), (n0), (d)); \
-	(r) = __r; \
-} while (0)
-	extern USItype __udiv_qrnnd();
-#define UDIV_TIME 140
-#endif /* LONGLONG_STANDALONE */
-#endif /* udiv_qrnnd */
+  __asm__ ("! Inlined udiv_qrnnd\n\t"					\
+	   "mov	32,%%g1\n\t"						\
+	   "subcc	%1,%2,%%g0\n\t"					\
+	   "1:	bcs	5f\n\t"						\
+	   "addxcc %0,%0,%0	! shift n1n0 and a q-bit in lsb\n\t"	\
+	   "sub	%1,%2,%1	! this kills msb of n\n\t"		\
+	   "addx	%1,%1,%1	! so this can't give carry\n\t"	\
+	   "subcc	%%g1,1,%%g1\n\t"				\
+	   "2:	bne	1b\n\t"						\
+	   "subcc	%1,%2,%%g0\n\t"					\
+	   "bcs	3f\n\t"							\
+	   "addxcc %0,%0,%0	! shift n1n0 and a q-bit in lsb\n\t"	\
+	   "b		3f\n\t"						\
+	   "sub	%1,%2,%1	! this kills msb of n\n\t"		\
+	   "4:	sub	%1,%2,%1\n\t"					\
+	   "5:	addxcc	%1,%1,%1\n\t"					\
+	   "bcc	2b\n\t"							\
+	   "subcc	%%g1,1,%%g1\n\t"				\
+	   "! Got carry from n.  Subtract next step to cancel this carry.\n\t" \
+	   "bne	4b\n\t"							\
+	   "addcc	%0,%0,%0	! shift n1n0 and a 0-bit in lsb\n\t" \
+	   "sub	%1,%2,%1\n\t"						\
+	   "3:	xnor	%0,0,%0\n\t"					\
+	   "! End of inline udiv_qrnnd\n"				\
+	   : "=&r" ((USItype)(q)),					\
+	     "=&r" ((USItype)(r))					\
+	   : "r" ((USItype)(d)),					\
+	     "1" ((USItype)(n1)),					\
+	     "0" ((USItype)(n0)) : "%g1", "cc")
+#define UDIV_TIME (3+7*32)      /* 7 instructions/iteration. 32 iterations.  */
+#endif
 #endif /* __sparc__ */
 
 /***************************************
diff --git a/lib/mpi/mpi-bit.c b/lib/mpi/mpi-bit.c
index 854c9c6da025..2f526627e4f5 100644
--- a/lib/mpi/mpi-bit.c
+++ b/lib/mpi/mpi-bit.c
@@ -21,25 +21,6 @@
 #include "mpi-internal.h"
 #include "longlong.h"
 
-const unsigned char __clz_tab[] = {
-	0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
-	    5, 5, 5, 5, 5, 5, 5, 5,
-	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-	    6, 6, 6, 6, 6, 6, 6, 6,
-	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-	    7, 7, 7, 7, 7, 7, 7, 7,
-	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-	    7, 7, 7, 7, 7, 7, 7, 7,
-	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-	    8, 8, 8, 8, 8, 8, 8, 8,
-	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-	    8, 8, 8, 8, 8, 8, 8, 8,
-	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-	    8, 8, 8, 8, 8, 8, 8, 8,
-	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-	    8, 8, 8, 8, 8, 8, 8, 8,
-};
-
 #define A_LIMB_1 ((mpi_limb_t) 1)
 
 /****************
diff --git a/lib/mpi/mpi-div.c b/lib/mpi/mpi-div.c
index c3087d1390ce..f68cbbb4d4a4 100644
--- a/lib/mpi/mpi-div.c
+++ b/lib/mpi/mpi-div.c
@@ -149,6 +149,9 @@ int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den)
 	mpi_ptr_t marker[5];
 	int markidx = 0;
 
+	if (!dsize)
+		return -EINVAL;
+
 	memset(marker, 0, sizeof(marker));
 
 	/* Ensure space is enough for quotient and remainder.
@@ -207,6 +210,8 @@ int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den)
 		 * numerator would be gradually overwritten by the quotient limbs.  */
 		if (qp == np) {	/* Copy NP object to temporary space.  */
 			np = marker[markidx++] = mpi_alloc_limb_space(nsize);
+			if (!np)
+				goto nomem;
 			MPN_COPY(np, qp, nsize);
 		}
 	} else			/* Put quotient at top of remainder. */
diff --git a/lib/mpi/mpi-pow.c b/lib/mpi/mpi-pow.c
index b04a3cf80080..67f3e79af914 100644
--- a/lib/mpi/mpi-pow.c
+++ b/lib/mpi/mpi-pow.c
@@ -59,7 +59,7 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
 	ep = exp->d;
 
 	if (!msize)
-		msize = 1 / msize;	/* provoke a signal */
+		return -EINVAL;
 
 	if (!esize) {
 		/* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0
diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c
index 716802b774ea..f26b41fcb48c 100644
--- a/lib/mpi/mpicoder.c
+++ b/lib/mpi/mpicoder.c
@@ -20,78 +20,15 @@
 
 #include "mpi-internal.h"
 
-#define DIM(v) (sizeof(v)/sizeof((v)[0]))
 #define MAX_EXTERN_MPI_BITS 16384
 
-static uint8_t asn[15] =	/* Object ID is 1.3.14.3.2.26 */
-{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
-	0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
-};
-
-MPI do_encode_md(const void *sha_buffer, unsigned nbits)
-{
-	int nframe = (nbits + 7) / 8;
-	uint8_t *frame, *fr_pt;
-	int i = 0, n;
-	size_t asnlen = DIM(asn);
-	MPI a = MPI_NULL;
-
-	if (SHA1_DIGEST_LENGTH + asnlen + 4 > nframe)
-		pr_info("MPI: can't encode a %d bit MD into a %d bits frame\n",
-		       (int)(SHA1_DIGEST_LENGTH * 8), (int)nbits);
-
-	/* We encode the MD in this way:
-	 *
-	 *       0  A PAD(n bytes)   0  ASN(asnlen bytes)  MD(len bytes)
-	 *
-	 * PAD consists of FF bytes.
-	 */
-	frame = kmalloc(nframe, GFP_KERNEL);
-	if (!frame)
-		return MPI_NULL;
-	n = 0;
-	frame[n++] = 0;
-	frame[n++] = 1;		/* block type */
-	i = nframe - SHA1_DIGEST_LENGTH - asnlen - 3;
-
-	if (i <= 1) {
-		pr_info("MPI: message digest encoding failed\n");
-		kfree(frame);
-		return a;
-	}
-
-	memset(frame + n, 0xff, i);
-	n += i;
-	frame[n++] = 0;
-	memcpy(frame + n, &asn, asnlen);
-	n += asnlen;
-	memcpy(frame + n, sha_buffer, SHA1_DIGEST_LENGTH);
-	n += SHA1_DIGEST_LENGTH;
-
-	i = nframe;
-	fr_pt = frame;
-
-	if (n != nframe) {
-		printk
-		    ("MPI: message digest encoding failed, frame length is wrong\n");
-		kfree(frame);
-		return a;
-	}
-
-	a = mpi_alloc((nframe + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB);
-	mpi_set_buffer(a, frame, nframe, 0);
-	kfree(frame);
-
-	return a;
-}
-
 MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread)
 {
 	const uint8_t *buffer = xbuffer;
 	int i, j;
 	unsigned nbits, nbytes, nlimbs, nread = 0;
 	mpi_limb_t a;
-	MPI val = MPI_NULL;
+	MPI val = NULL;
 
 	if (*ret_nread < 2)
 		goto leave;
@@ -108,7 +45,7 @@ MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread)
 	nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
 	val = mpi_alloc(nlimbs);
 	if (!val)
-		return MPI_NULL;
+		return NULL;
 	i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
 	i %= BYTES_PER_MPI_LIMB;
 	val->nbits = nbits;
@@ -212,30 +149,6 @@ int mpi_fromstr(MPI val, const char *str)
 EXPORT_SYMBOL_GPL(mpi_fromstr);
 
 /****************
- * Special function to get the low 8 bytes from an mpi.
- * This can be used as a keyid; KEYID is an 2 element array.
- * Return the low 4 bytes.
- */
-u32 mpi_get_keyid(const MPI a, u32 *keyid)
-{
-#if BYTES_PER_MPI_LIMB == 4
-	if (keyid) {
-		keyid[0] = a->nlimbs >= 2 ? a->d[1] : 0;
-		keyid[1] = a->nlimbs >= 1 ? a->d[0] : 0;
-	}
-	return a->nlimbs >= 1 ? a->d[0] : 0;
-#elif BYTES_PER_MPI_LIMB == 8
-	if (keyid) {
-		keyid[0] = a->nlimbs ? (u32) (a->d[0] >> 32) : 0;
-		keyid[1] = a->nlimbs ? (u32) (a->d[0] & 0xffffffff) : 0;
-	}
-	return a->nlimbs ? (u32) (a->d[0] & 0xffffffff) : 0;
-#else
-#error Make this function work with other LIMB sizes
-#endif
-}
-
-/****************
  * Return an allocated buffer with the MPI (msb first).
  * NBYTES receives the length of this buffer. Caller must free the
  * return string (This function does return a 0 byte buffer with NBYTES
diff --git a/lib/mpi/mpih-div.c b/lib/mpi/mpih-div.c
index 87ede162dfab..cde1aaec18da 100644
--- a/lib/mpi/mpih-div.c
+++ b/lib/mpi/mpih-div.c
@@ -217,6 +217,10 @@ mpihelp_divrem(mpi_ptr_t qp, mpi_size_t qextra_limbs,
 	case 0:
 		/* We are asked to divide by zero, so go ahead and do it!  (To make
 		   the compiler not remove this statement, return the value.)  */
+		/*
+		 * existing clients of this function have been modified
+		 * not to call it with dsize == 0, so this should not happen
+		 */
 		return 1 / dsize;
 
 	case 1:
diff --git a/lib/mpi/mpiutil.c b/lib/mpi/mpiutil.c
index eefc55d6b7f5..26e4ed31e256 100644
--- a/lib/mpi/mpiutil.c
+++ b/lib/mpi/mpiutil.c
@@ -58,6 +58,9 @@ mpi_ptr_t mpi_alloc_limb_space(unsigned nlimbs)
 {
 	size_t len = nlimbs * sizeof(mpi_limb_t);
 
+	if (!len)
+		return NULL;
+
 	return kmalloc(len, GFP_KERNEL);
 }
 
@@ -135,7 +138,7 @@ int mpi_copy(MPI *copied, const MPI a)
 	size_t i;
 	MPI b;
 
-	*copied = MPI_NULL;
+	*copied = NULL;
 
 	if (a) {
 		b = mpi_alloc(a->nlimbs);