Skip to content

Commit

Permalink
lib/mpi: Endianness fix
Browse files Browse the repository at this point in the history
The limbs are integers in the host endianness, so we can't simply
iterate over the individual bytes. The current code happens to work on
little-endian, because the order of the limbs in the MPI array is the
same as the order of the bytes in each limb, but it breaks on
big-endian.

Fixes: 0f74fbf ("MPI: Fix mpi_read_buffer")
Signed-off-by: Michal Marek <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
  • Loading branch information
Michal Marek authored and herbertx committed Feb 27, 2016
1 parent bfd927f commit 3ee0cb5
Showing 1 changed file with 21 additions and 18 deletions.
39 changes: 21 additions & 18 deletions lib/mpi/mpicoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,23 @@ MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread)
}
EXPORT_SYMBOL_GPL(mpi_read_from_buffer);

static int count_lzeros(MPI a)
{
mpi_limb_t alimb;
int i, lzeros = 0;

for (i = a->nlimbs - 1; i >= 0; i--) {
alimb = a->d[i];
if (alimb == 0) {
lzeros += sizeof(mpi_limb_t);
} else {
lzeros += count_leading_zeros(alimb) / 8;
break;
}
}
return lzeros;
}

/**
* mpi_read_buffer() - read MPI to a bufer provided by user (msb first)
*
Expand All @@ -148,22 +165,15 @@ int mpi_read_buffer(MPI a, uint8_t *buf, unsigned buf_len, unsigned *nbytes,
uint8_t *p;
mpi_limb_t alimb;
unsigned int n = mpi_get_size(a);
int i, lzeros = 0;
int i, lzeros;

if (!buf || !nbytes)
return -EINVAL;

if (sign)
*sign = a->sign;

p = (void *)&a->d[a->nlimbs] - 1;

for (i = a->nlimbs * sizeof(alimb) - 1; i >= 0; i--, p--) {
if (!*p)
lzeros++;
else
break;
}
lzeros = count_lzeros(a);

if (buf_len < n - lzeros) {
*nbytes = n - lzeros;
Expand Down Expand Up @@ -351,22 +361,15 @@ int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned *nbytes,
u8 *p, *p2;
mpi_limb_t alimb, alimb2;
unsigned int n = mpi_get_size(a);
int i, x, y = 0, lzeros = 0, buf_len;
int i, x, y = 0, lzeros, buf_len;

if (!nbytes)
return -EINVAL;

if (sign)
*sign = a->sign;

p = (void *)&a->d[a->nlimbs] - 1;

for (i = a->nlimbs * sizeof(alimb) - 1; i >= 0; i--, p--) {
if (!*p)
lzeros++;
else
break;
}
lzeros = count_lzeros(a);

if (*nbytes < n - lzeros) {
*nbytes = n - lzeros;
Expand Down

0 comments on commit 3ee0cb5

Please sign in to comment.