Skip to content

Commit

Permalink
Merge branch 'for-linus2' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/jmorris/linux-security

* 'for-linus2' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
  lib: Fix 32-bit sparc udiv_qrnnd() definition in mpilib's longlong.h
  lib: Fix multiple definitions of clz_tab
  lib/digsig: checks for NULL return value
  lib/mpi: added missing NULL check
  lib/mpi: added comment on divide by 0 case
  lib/mpi: check for possible zero length
  lib/digsig: pkcs_1_v1_5_decode_emsa cleanup
  lib/digsig: additional sanity checks against badly formated key payload
  lib/mpi: removed unused functions
  lib/mpi: checks for zero divisor length
  lib/mpi: return error code on dividing by zero
  lib/mpi: replaced MPI_NULL with normal NULL
  lib/mpi: added missing NULL check
  • Loading branch information
torvalds committed Feb 2, 2012
2 parents 18d3e0d + a99e7e5 commit ce106ad
Show file tree
Hide file tree
Showing 14 changed files with 98 additions and 167 deletions.
1 change: 1 addition & 0 deletions arch/sparc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ config SPARC
config SPARC32
def_bool !64BIT
select GENERIC_ATOMIC64
select CLZ_TAB

config SPARC64
def_bool 64BIT
Expand Down
16 changes: 1 addition & 15 deletions arch/sparc/lib/divdi3.S
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,9 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */

.data
.align 8
.globl __clz_tab
__clz_tab:
.byte 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
.byte 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
.byte 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
.byte 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
.byte 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
.byte 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
.byte 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
.byte 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
.size __clz_tab,256
.global .udiv

.text
.align 4
.global .udiv
.globl __divdi3
__divdi3:
save %sp,-104,%sp
Expand Down
2 changes: 0 additions & 2 deletions include/linux/mpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,6 @@ struct gcry_mpi {

typedef struct gcry_mpi *MPI;

#define MPI_NULL NULL

#define mpi_get_nlimbs(a) ((a)->nlimbs)
#define mpi_is_neg(a) ((a)->sign)

Expand Down
4 changes: 4 additions & 0 deletions lib/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,9 @@ config AVERAGE

If unsure, say N.

config CLZ_TAB
bool

config CORDIC
tristate "CORDIC algorithm"
help
Expand All @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
18 changes: 18 additions & 0 deletions lib/clz_tab.c
Original file line number Diff line number Diff line change
@@ -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,
};
52 changes: 23 additions & 29 deletions lib/digsig.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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;
}

/*
Expand All @@ -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;
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -167,19 +162,18 @@ 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:
mpi_free(in);
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);

Expand Down
44 changes: 33 additions & 11 deletions lib/mpi/longlong.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__ */

/***************************************
Expand Down
19 changes: 0 additions & 19 deletions lib/mpi/mpi-bit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)

/****************
Expand Down
5 changes: 5 additions & 0 deletions lib/mpi/mpi-div.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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. */
Expand Down
2 changes: 1 addition & 1 deletion lib/mpi/mpi-pow.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit ce106ad

Please sign in to comment.