Commit ce106ad3 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus2' of git://git.kernel.org/pub/scm/linux/kernel/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
parents 18d3e0d7 a99e7e5f
...@@ -33,6 +33,7 @@ config SPARC ...@@ -33,6 +33,7 @@ config SPARC
config SPARC32 config SPARC32
def_bool !64BIT def_bool !64BIT
select GENERIC_ATOMIC64 select GENERIC_ATOMIC64
select CLZ_TAB
config SPARC64 config SPARC64
def_bool 64BIT def_bool 64BIT
......
...@@ -17,23 +17,9 @@ along with GNU CC; see the file COPYING. If not, write to ...@@ -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, the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ 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 .text
.align 4 .align 4
.global .udiv
.globl __divdi3 .globl __divdi3
__divdi3: __divdi3:
save %sp,-104,%sp save %sp,-104,%sp
......
...@@ -57,8 +57,6 @@ struct gcry_mpi { ...@@ -57,8 +57,6 @@ struct gcry_mpi {
typedef struct gcry_mpi *MPI; typedef struct gcry_mpi *MPI;
#define MPI_NULL NULL
#define mpi_get_nlimbs(a) ((a)->nlimbs) #define mpi_get_nlimbs(a) ((a)->nlimbs)
#define mpi_is_neg(a) ((a)->sign) #define mpi_is_neg(a) ((a)->sign)
......
...@@ -279,6 +279,9 @@ config AVERAGE ...@@ -279,6 +279,9 @@ config AVERAGE
If unsure, say N. If unsure, say N.
config CLZ_TAB
bool
config CORDIC config CORDIC
tristate "CORDIC algorithm" tristate "CORDIC algorithm"
help help
...@@ -287,6 +290,7 @@ config CORDIC ...@@ -287,6 +290,7 @@ config CORDIC
config MPILIB config MPILIB
tristate tristate
select CLZ_TAB
help help
Multiprecision maths library from GnuPG. Multiprecision maths library from GnuPG.
It is used to implement RSA digital signature verification, It is used to implement RSA digital signature verification,
......
...@@ -121,6 +121,8 @@ obj-$(CONFIG_DQL) += dynamic_queue_limits.o ...@@ -121,6 +121,8 @@ obj-$(CONFIG_DQL) += dynamic_queue_limits.o
obj-$(CONFIG_MPILIB) += mpi/ obj-$(CONFIG_MPILIB) += mpi/
obj-$(CONFIG_SIGNATURE) += digsig.o obj-$(CONFIG_SIGNATURE) += digsig.o
obj-$(CONFIG_CLZ_TAB) += clz_tab.o
hostprogs-y := gen_crc32table hostprogs-y := gen_crc32table
clean-files := crc32table.h clean-files := crc32table.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,
};
...@@ -34,14 +34,9 @@ static int pkcs_1_v1_5_decode_emsa(const unsigned char *msg, ...@@ -34,14 +34,9 @@ static int pkcs_1_v1_5_decode_emsa(const unsigned char *msg,
unsigned long msglen, unsigned long msglen,
unsigned long modulus_bitlen, unsigned long modulus_bitlen,
unsigned char *out, unsigned char *out,
unsigned long *outlen, unsigned long *outlen)
int *is_valid)
{ {
unsigned long modulus_len, ps_len, i; 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); 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, ...@@ -50,39 +45,30 @@ static int pkcs_1_v1_5_decode_emsa(const unsigned char *msg,
return -EINVAL; return -EINVAL;
/* separate encoded message */ /* separate encoded message */
if ((msg[0] != 0x00) || (msg[1] != (unsigned char)1)) { if ((msg[0] != 0x00) || (msg[1] != (unsigned char)1))
result = -EINVAL; return -EINVAL;
goto bail;
}
for (i = 2; i < modulus_len - 1; i++) for (i = 2; i < modulus_len - 1; i++)
if (msg[i] != 0xFF) if (msg[i] != 0xFF)
break; break;
/* separator check */ /* separator check */
if (msg[i] != 0) { if (msg[i] != 0)
/* There was no octet with hexadecimal value 0x00 /* There was no octet with hexadecimal value 0x00
to separate ps from m. */ to separate ps from m. */
result = -EINVAL; return -EINVAL;
goto bail;
}
ps_len = i - 2; ps_len = i - 2;
if (*outlen < (msglen - (2 + ps_len + 1))) { if (*outlen < (msglen - (2 + ps_len + 1))) {
*outlen = msglen - (2 + ps_len + 1); *outlen = msglen - (2 + ps_len + 1);
result = -EOVERFLOW; return -EOVERFLOW;
goto bail;
} }
*outlen = (msglen - (2 + ps_len + 1)); *outlen = (msglen - (2 + ps_len + 1));
memcpy(out, &msg[2 + ps_len + 1], *outlen); memcpy(out, &msg[2 + ps_len + 1], *outlen);
/* valid packet */ return 0;
*is_valid = 1;
result = 0;
bail:
return result;
} }
/* /*
...@@ -96,7 +82,7 @@ static int digsig_verify_rsa(struct key *key, ...@@ -96,7 +82,7 @@ static int digsig_verify_rsa(struct key *key,
unsigned long len; unsigned long len;
unsigned long mlen, mblen; unsigned long mlen, mblen;
unsigned nret, l; unsigned nret, l;
int valid, head, i; int head, i;
unsigned char *out1 = NULL, *out2 = NULL; unsigned char *out1 = NULL, *out2 = NULL;
MPI in = NULL, res = NULL, pkey[2]; MPI in = NULL, res = NULL, pkey[2];
uint8_t *p, *datap, *endp; uint8_t *p, *datap, *endp;
...@@ -105,6 +91,10 @@ static int digsig_verify_rsa(struct key *key, ...@@ -105,6 +91,10 @@ static int digsig_verify_rsa(struct key *key,
down_read(&key->sem); down_read(&key->sem);
ukp = key->payload.data; ukp = key->payload.data;
if (ukp->datalen < sizeof(*pkh))
goto err1;
pkh = (struct pubkey_hdr *)ukp->data; pkh = (struct pubkey_hdr *)ukp->data;
if (pkh->version != 1) if (pkh->version != 1)
...@@ -117,18 +107,23 @@ static int digsig_verify_rsa(struct key *key, ...@@ -117,18 +107,23 @@ static int digsig_verify_rsa(struct key *key,
goto err1; goto err1;
datap = pkh->mpi; datap = pkh->mpi;
endp = datap + ukp->datalen; endp = ukp->data + ukp->datalen;
err = -ENOMEM;
for (i = 0; i < pkh->nmpi; i++) { for (i = 0; i < pkh->nmpi; i++) {
unsigned int remaining = endp - datap; unsigned int remaining = endp - datap;
pkey[i] = mpi_read_from_buffer(datap, &remaining); pkey[i] = mpi_read_from_buffer(datap, &remaining);
if (!pkey[i])
goto err;
datap += remaining; datap += remaining;
} }
mblen = mpi_get_nbits(pkey[0]); mblen = mpi_get_nbits(pkey[0]);
mlen = (mblen + 7)/8; mlen = (mblen + 7)/8;
err = -ENOMEM; if (mlen == 0)
goto err;
out1 = kzalloc(mlen, GFP_KERNEL); out1 = kzalloc(mlen, GFP_KERNEL);
if (!out1) if (!out1)
...@@ -167,10 +162,9 @@ static int digsig_verify_rsa(struct key *key, ...@@ -167,10 +162,9 @@ static int digsig_verify_rsa(struct key *key,
memset(out1, 0, head); memset(out1, 0, head);
memcpy(out1 + head, p, l); memcpy(out1 + head, p, l);
err = -EINVAL; err = pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len);
pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len, &valid);
if (valid && len == hlen) if (!err && len == hlen)
err = memcmp(out2, h, hlen); err = memcmp(out2, h, hlen);
err: err:
...@@ -178,8 +172,8 @@ static int digsig_verify_rsa(struct key *key, ...@@ -178,8 +172,8 @@ static int digsig_verify_rsa(struct key *key,
mpi_free(res); mpi_free(res);
kfree(out1); kfree(out1);
kfree(out2); kfree(out2);
mpi_free(pkey[0]); while (--i >= 0)
mpi_free(pkey[1]); mpi_free(pkey[i]);
err1: err1:
up_read(&key->sem); up_read(&key->sem);
......
...@@ -1200,18 +1200,40 @@ do { \ ...@@ -1200,18 +1200,40 @@ do { \
"r" ((USItype)(v)) \ "r" ((USItype)(v)) \
: "%g1", "%g2" __AND_CLOBBER_CC) : "%g1", "%g2" __AND_CLOBBER_CC)
#define UMUL_TIME 39 /* 39 instructions */ #define UMUL_TIME 39 /* 39 instructions */
#endif /* It's quite necessary to add this much assembler for the sparc.
#ifndef udiv_qrnnd The default udiv_qrnnd (in C) is more than 10 times slower! */
#ifndef LONGLONG_STANDALONE
#define udiv_qrnnd(q, r, n1, n0, d) \ #define udiv_qrnnd(q, r, n1, n0, d) \
do { USItype __r; \ __asm__ ("! Inlined udiv_qrnnd\n\t" \
(q) = __udiv_qrnnd(&__r, (n1), (n0), (d)); \ "mov 32,%%g1\n\t" \
(r) = __r; \ "subcc %1,%2,%%g0\n\t" \
} while (0) "1: bcs 5f\n\t" \
extern USItype __udiv_qrnnd(); "addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n\t" \
#define UDIV_TIME 140 "sub %1,%2,%1 ! this kills msb of n\n\t" \
#endif /* LONGLONG_STANDALONE */ "addx %1,%1,%1 ! so this can't give carry\n\t" \
#endif /* udiv_qrnnd */ "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__ */ #endif /* __sparc__ */
/*************************************** /***************************************
......
...@@ -21,25 +21,6 @@ ...@@ -21,25 +21,6 @@
#include "mpi-internal.h" #include "mpi-internal.h"
#include "longlong.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) #define A_LIMB_1 ((mpi_limb_t) 1)
/**************** /****************
......
...@@ -149,6 +149,9 @@ int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den) ...@@ -149,6 +149,9 @@ int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den)
mpi_ptr_t marker[5]; mpi_ptr_t marker[5];
int markidx = 0; int markidx = 0;
if (!dsize)
return -EINVAL;
memset(marker, 0, sizeof(marker)); memset(marker, 0, sizeof(marker));
/* Ensure space is enough for quotient and remainder. /* Ensure space is enough for quotient and remainder.
...@@ -207,6 +210,8 @@ int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den) ...@@ -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. */ * numerator would be gradually overwritten by the quotient limbs. */
if (qp == np) { /* Copy NP object to temporary space. */ if (qp == np) { /* Copy NP object to temporary space. */
np = marker[markidx++] = mpi_alloc_limb_space(nsize); np = marker[markidx++] = mpi_alloc_limb_space(nsize);
if (!np)
goto nomem;
MPN_COPY(np, qp, nsize); MPN_COPY(np, qp, nsize);
} }
} else /* Put quotient at top of remainder. */ } else /* Put quotient at top of remainder. */
......
...@@ -59,7 +59,7 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod) ...@@ -59,7 +59,7 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
ep = exp->d; ep = exp->d;
if (!msize) if (!msize)
msize = 1 / msize; /* provoke a signal */ return -EINVAL;
if (!esize) { if (!esize) {
/* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0
......
...@@ -20,78 +20,15 @@ ...@@ -20,78 +20,15 @@
#include "mpi-internal.h" #include "mpi-internal.h"
#define DIM(v) (sizeof(v)/sizeof((v)[0]))
#define MAX_EXTERN_MPI_BITS 16384 #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) MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread)
{ {
const uint8_t *buffer = xbuffer; const uint8_t *buffer = xbuffer;
int i, j; int i, j;
unsigned nbits, nbytes, nlimbs, nread = 0; unsigned nbits, nbytes, nlimbs, nread = 0;
mpi_limb_t a; mpi_limb_t a;
MPI val = MPI_NULL; MPI val = NULL;
if (*ret_nread < 2) if (*ret_nread < 2)
goto leave; goto leave;
...@@ -108,7 +45,7 @@ MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread) ...@@ -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; nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
val = mpi_alloc(nlimbs); val = mpi_alloc(nlimbs);
if (!val) if (!val)
return MPI_NULL; return NULL;
i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB; i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
i %= BYTES_PER_MPI_LIMB; i %= BYTES_PER_MPI_LIMB;
val->nbits = nbits; val->nbits = nbits;
...@@ -211,30 +148,6 @@ int mpi_fromstr(MPI val, const char *str) ...@@ -211,30 +148,6 @@ int mpi_fromstr(MPI val, const char *str)
} }
EXPORT_SYMBOL_GPL(mpi_fromstr); 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). * Return an allocated buffer with the MPI (msb first).
* NBYTES receives the length of this buffer. Caller must free the * NBYTES receives the length of this buffer. Caller must free the
......
...@@ -217,6 +217,10 @@ mpihelp_divrem(mpi_ptr_t qp, mpi_size_t qextra_limbs, ...@@ -217,6 +217,10 @@ mpihelp_divrem(mpi_ptr_t qp, mpi_size_t qextra_limbs,
case 0: case 0:
/* We are asked to divide by zero, so go ahead and do it! (To make /* We are asked to divide by zero, so go ahead and do it! (To make
the compiler not remove this statement, return the value.) */ 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; return 1 / dsize;
case 1: case 1:
......
...@@ -58,6 +58,9 @@ mpi_ptr_t mpi_alloc_limb_space(unsigned nlimbs) ...@@ -58,6 +58,9 @@ mpi_ptr_t mpi_alloc_limb_space(unsigned nlimbs)
{ {
size_t len = nlimbs * sizeof(mpi_limb_t); size_t len = nlimbs * sizeof(mpi_limb_t);
if (!len)
return NULL;
return kmalloc(len, GFP_KERNEL); return kmalloc(len, GFP_KERNEL);
} }
...@@ -135,7 +138,7 @@ int mpi_copy(MPI *copied, const MPI a) ...@@ -135,7 +138,7 @@ int mpi_copy(MPI *copied, const MPI a)
size_t i; size_t i;
MPI b; MPI b;
*copied = MPI_NULL; *copied = NULL;
if (a) { if (a) {
b = mpi_alloc(a->nlimbs); b = mpi_alloc(a->nlimbs);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment