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
This commit is contained in:
Коммит
ce106ad310
|
@ -33,6 +33,7 @@ config SPARC
|
|||
config SPARC32
|
||||
def_bool !64BIT
|
||||
select GENERIC_ATOMIC64
|
||||
select CLZ_TAB
|
||||
|
||||
config SPARC64
|
||||
def_bool 64BIT
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
lib/digsig.c
52
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);
|
||||
|
||||
|
|
|
@ -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__ */
|
||||
|
||||
/***************************************
|
||||
|
|
|
@ -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)
|
||||
|
||||
/****************
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
@ -211,30 +148,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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче