Commit e1045992949160b56309b730b8bdc428f2f8b69e

Authored by David Howells
Committed by Rusty Russell
1 parent 42d5ec27f8

MPILIB: Provide a function to read raw data into an MPI

Provide a function to read raw data of a predetermined size into an MPI rather
than expecting the size to be encoded within the data.  The data is assumed to
represent an unsigned integer, and the resulting MPI will be positive.

The function looks like this:

	MPI mpi_read_raw_data(const void *, size_t);

This is useful for reading ASN.1 integer primitives where the length is encoded
in the ASN.1 metadata.

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

Showing 2 changed files with 56 additions and 0 deletions Side-by-side Diff

... ... @@ -76,6 +76,7 @@
76 76  
77 77 /*-- mpicoder.c --*/
78 78 MPI do_encode_md(const void *sha_buffer, unsigned nbits);
  79 +MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes);
79 80 MPI mpi_read_from_buffer(const void *buffer, unsigned *ret_nread);
80 81 int mpi_fromstr(MPI val, const char *str);
81 82 u32 mpi_get_keyid(MPI a, u32 *keyid);
... ... @@ -18,9 +18,64 @@
18 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 19 */
20 20  
  21 +#include <linux/bitops.h>
  22 +#include <asm-generic/bitops/count_zeros.h>
21 23 #include "mpi-internal.h"
22 24  
23 25 #define MAX_EXTERN_MPI_BITS 16384
  26 +
  27 +/**
  28 + * mpi_read_raw_data - Read a raw byte stream as a positive integer
  29 + * @xbuffer: The data to read
  30 + * @nbytes: The amount of data to read
  31 + */
  32 +MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes)
  33 +{
  34 + const uint8_t *buffer = xbuffer;
  35 + int i, j;
  36 + unsigned nbits, nlimbs;
  37 + mpi_limb_t a;
  38 + MPI val = NULL;
  39 +
  40 + while (nbytes >= 0 && buffer[0] == 0) {
  41 + buffer++;
  42 + nbytes--;
  43 + }
  44 +
  45 + nbits = nbytes * 8;
  46 + if (nbits > MAX_EXTERN_MPI_BITS) {
  47 + pr_info("MPI: mpi too large (%u bits)\n", nbits);
  48 + return NULL;
  49 + }
  50 + if (nbytes > 0)
  51 + nbits -= count_leading_zeros(buffer[0]);
  52 + else
  53 + nbits = 0;
  54 +
  55 + nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
  56 + val = mpi_alloc(nlimbs);
  57 + if (!val)
  58 + return NULL;
  59 + val->nbits = nbits;
  60 + val->sign = 0;
  61 + val->nlimbs = nlimbs;
  62 +
  63 + if (nbytes > 0) {
  64 + i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
  65 + i %= BYTES_PER_MPI_LIMB;
  66 + for (j = nlimbs; j > 0; j--) {
  67 + a = 0;
  68 + for (; i < BYTES_PER_MPI_LIMB; i++) {
  69 + a <<= 8;
  70 + a |= *buffer++;
  71 + }
  72 + i = 0;
  73 + val->d[j - 1] = a;
  74 + }
  75 + }
  76 + return val;
  77 +}
  78 +EXPORT_SYMBOL_GPL(mpi_read_raw_data);
24 79  
25 80 MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread)
26 81 {