]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
MPILIB: Provide a function to read raw data into an MPI
authorDavid Howells <dhowells@redhat.com>
Mon, 24 Sep 2012 16:11:27 +0000 (17:11 +0100)
committerRusty Russell <rusty@rustcorp.com.au>
Mon, 8 Oct 2012 03:20:21 +0000 (13:50 +1030)
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>
include/linux/mpi.h
lib/mpi/mpicoder.c

index d02cca6cc8ce0552bcf652a29b5562979f72f056..5af1b81def49f6f98ec5783c60fb4fabe0a62c46 100644 (file)
@@ -76,6 +76,7 @@ void mpi_swap(MPI a, MPI b);
 
 /*-- mpicoder.c --*/
 MPI do_encode_md(const void *sha_buffer, unsigned nbits);
+MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes);
 MPI mpi_read_from_buffer(const void *buffer, unsigned *ret_nread);
 int mpi_fromstr(MPI val, const char *str);
 u32 mpi_get_keyid(MPI a, u32 *keyid);
index f0fa659958002ca824d47144e6ecba3fdcdc7e38..3962b7f7fe3f08ec4b639e328ddc6dcf4baa05fd 100644 (file)
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  */
 
+#include <linux/bitops.h>
+#include <asm-generic/bitops/count_zeros.h>
 #include "mpi-internal.h"
 
 #define MAX_EXTERN_MPI_BITS 16384
 
+/**
+ * mpi_read_raw_data - Read a raw byte stream as a positive integer
+ * @xbuffer: The data to read
+ * @nbytes: The amount of data to read
+ */
+MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes)
+{
+       const uint8_t *buffer = xbuffer;
+       int i, j;
+       unsigned nbits, nlimbs;
+       mpi_limb_t a;
+       MPI val = NULL;
+
+       while (nbytes >= 0 && buffer[0] == 0) {
+               buffer++;
+               nbytes--;
+       }
+
+       nbits = nbytes * 8;
+       if (nbits > MAX_EXTERN_MPI_BITS) {
+               pr_info("MPI: mpi too large (%u bits)\n", nbits);
+               return NULL;
+       }
+       if (nbytes > 0)
+               nbits -= count_leading_zeros(buffer[0]);
+       else
+               nbits = 0;
+
+       nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
+       val = mpi_alloc(nlimbs);
+       if (!val)
+               return NULL;
+       val->nbits = nbits;
+       val->sign = 0;
+       val->nlimbs = nlimbs;
+
+       if (nbytes > 0) {
+               i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
+               i %= BYTES_PER_MPI_LIMB;
+               for (j = nlimbs; j > 0; j--) {
+                       a = 0;
+                       for (; i < BYTES_PER_MPI_LIMB; i++) {
+                               a <<= 8;
+                               a |= *buffer++;
+                       }
+                       i = 0;
+                       val->d[j - 1] = a;
+               }
+       }
+       return val;
+}
+EXPORT_SYMBOL_GPL(mpi_read_raw_data);
+
 MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread)
 {
        const uint8_t *buffer = xbuffer;