1*2a598d0bSHerbert Xu /* mpicoder.c - Coder for the external representation of MPIs
2*2a598d0bSHerbert Xu * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
3*2a598d0bSHerbert Xu *
4*2a598d0bSHerbert Xu * This file is part of GnuPG.
5*2a598d0bSHerbert Xu *
6*2a598d0bSHerbert Xu * GnuPG is free software; you can redistribute it and/or modify
7*2a598d0bSHerbert Xu * it under the terms of the GNU General Public License as published by
8*2a598d0bSHerbert Xu * the Free Software Foundation; either version 2 of the License, or
9*2a598d0bSHerbert Xu * (at your option) any later version.
10*2a598d0bSHerbert Xu *
11*2a598d0bSHerbert Xu * GnuPG is distributed in the hope that it will be useful,
12*2a598d0bSHerbert Xu * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*2a598d0bSHerbert Xu * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*2a598d0bSHerbert Xu * GNU General Public License for more details.
15*2a598d0bSHerbert Xu *
16*2a598d0bSHerbert Xu * You should have received a copy of the GNU General Public License
17*2a598d0bSHerbert Xu * along with this program; if not, write to the Free Software
18*2a598d0bSHerbert Xu * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19*2a598d0bSHerbert Xu */
20*2a598d0bSHerbert Xu
21*2a598d0bSHerbert Xu #include <linux/bitops.h>
22*2a598d0bSHerbert Xu #include <linux/count_zeros.h>
23*2a598d0bSHerbert Xu #include <linux/byteorder/generic.h>
24*2a598d0bSHerbert Xu #include <linux/scatterlist.h>
25*2a598d0bSHerbert Xu #include <linux/string.h>
26*2a598d0bSHerbert Xu #include "mpi-internal.h"
27*2a598d0bSHerbert Xu
28*2a598d0bSHerbert Xu #define MAX_EXTERN_MPI_BITS 16384
29*2a598d0bSHerbert Xu
30*2a598d0bSHerbert Xu /**
31*2a598d0bSHerbert Xu * mpi_read_raw_data - Read a raw byte stream as a positive integer
32*2a598d0bSHerbert Xu * @xbuffer: The data to read
33*2a598d0bSHerbert Xu * @nbytes: The amount of data to read
34*2a598d0bSHerbert Xu */
mpi_read_raw_data(const void * xbuffer,size_t nbytes)35*2a598d0bSHerbert Xu MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes)
36*2a598d0bSHerbert Xu {
37*2a598d0bSHerbert Xu const uint8_t *buffer = xbuffer;
38*2a598d0bSHerbert Xu int i, j;
39*2a598d0bSHerbert Xu unsigned nbits, nlimbs;
40*2a598d0bSHerbert Xu mpi_limb_t a;
41*2a598d0bSHerbert Xu MPI val = NULL;
42*2a598d0bSHerbert Xu
43*2a598d0bSHerbert Xu while (nbytes > 0 && buffer[0] == 0) {
44*2a598d0bSHerbert Xu buffer++;
45*2a598d0bSHerbert Xu nbytes--;
46*2a598d0bSHerbert Xu }
47*2a598d0bSHerbert Xu
48*2a598d0bSHerbert Xu nbits = nbytes * 8;
49*2a598d0bSHerbert Xu if (nbits > MAX_EXTERN_MPI_BITS) {
50*2a598d0bSHerbert Xu pr_info("MPI: mpi too large (%u bits)\n", nbits);
51*2a598d0bSHerbert Xu return NULL;
52*2a598d0bSHerbert Xu }
53*2a598d0bSHerbert Xu if (nbytes > 0)
54*2a598d0bSHerbert Xu nbits -= count_leading_zeros(buffer[0]) - (BITS_PER_LONG - 8);
55*2a598d0bSHerbert Xu
56*2a598d0bSHerbert Xu nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB);
57*2a598d0bSHerbert Xu val = mpi_alloc(nlimbs);
58*2a598d0bSHerbert Xu if (!val)
59*2a598d0bSHerbert Xu return NULL;
60*2a598d0bSHerbert Xu val->nbits = nbits;
61*2a598d0bSHerbert Xu val->sign = 0;
62*2a598d0bSHerbert Xu val->nlimbs = nlimbs;
63*2a598d0bSHerbert Xu
64*2a598d0bSHerbert Xu if (nbytes > 0) {
65*2a598d0bSHerbert Xu i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
66*2a598d0bSHerbert Xu i %= BYTES_PER_MPI_LIMB;
67*2a598d0bSHerbert Xu for (j = nlimbs; j > 0; j--) {
68*2a598d0bSHerbert Xu a = 0;
69*2a598d0bSHerbert Xu for (; i < BYTES_PER_MPI_LIMB; i++) {
70*2a598d0bSHerbert Xu a <<= 8;
71*2a598d0bSHerbert Xu a |= *buffer++;
72*2a598d0bSHerbert Xu }
73*2a598d0bSHerbert Xu i = 0;
74*2a598d0bSHerbert Xu val->d[j - 1] = a;
75*2a598d0bSHerbert Xu }
76*2a598d0bSHerbert Xu }
77*2a598d0bSHerbert Xu return val;
78*2a598d0bSHerbert Xu }
79*2a598d0bSHerbert Xu EXPORT_SYMBOL_GPL(mpi_read_raw_data);
80*2a598d0bSHerbert Xu
mpi_read_from_buffer(const void * xbuffer,unsigned * ret_nread)81*2a598d0bSHerbert Xu MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread)
82*2a598d0bSHerbert Xu {
83*2a598d0bSHerbert Xu const uint8_t *buffer = xbuffer;
84*2a598d0bSHerbert Xu unsigned int nbits, nbytes;
85*2a598d0bSHerbert Xu MPI val;
86*2a598d0bSHerbert Xu
87*2a598d0bSHerbert Xu if (*ret_nread < 2)
88*2a598d0bSHerbert Xu return ERR_PTR(-EINVAL);
89*2a598d0bSHerbert Xu nbits = buffer[0] << 8 | buffer[1];
90*2a598d0bSHerbert Xu
91*2a598d0bSHerbert Xu if (nbits > MAX_EXTERN_MPI_BITS) {
92*2a598d0bSHerbert Xu pr_info("MPI: mpi too large (%u bits)\n", nbits);
93*2a598d0bSHerbert Xu return ERR_PTR(-EINVAL);
94*2a598d0bSHerbert Xu }
95*2a598d0bSHerbert Xu
96*2a598d0bSHerbert Xu nbytes = DIV_ROUND_UP(nbits, 8);
97*2a598d0bSHerbert Xu if (nbytes + 2 > *ret_nread) {
98*2a598d0bSHerbert Xu pr_info("MPI: mpi larger than buffer nbytes=%u ret_nread=%u\n",
99*2a598d0bSHerbert Xu nbytes, *ret_nread);
100*2a598d0bSHerbert Xu return ERR_PTR(-EINVAL);
101*2a598d0bSHerbert Xu }
102*2a598d0bSHerbert Xu
103*2a598d0bSHerbert Xu val = mpi_read_raw_data(buffer + 2, nbytes);
104*2a598d0bSHerbert Xu if (!val)
105*2a598d0bSHerbert Xu return ERR_PTR(-ENOMEM);
106*2a598d0bSHerbert Xu
107*2a598d0bSHerbert Xu *ret_nread = nbytes + 2;
108*2a598d0bSHerbert Xu return val;
109*2a598d0bSHerbert Xu }
110*2a598d0bSHerbert Xu EXPORT_SYMBOL_GPL(mpi_read_from_buffer);
111*2a598d0bSHerbert Xu
count_lzeros(MPI a)112*2a598d0bSHerbert Xu static int count_lzeros(MPI a)
113*2a598d0bSHerbert Xu {
114*2a598d0bSHerbert Xu mpi_limb_t alimb;
115*2a598d0bSHerbert Xu int i, lzeros = 0;
116*2a598d0bSHerbert Xu
117*2a598d0bSHerbert Xu for (i = a->nlimbs - 1; i >= 0; i--) {
118*2a598d0bSHerbert Xu alimb = a->d[i];
119*2a598d0bSHerbert Xu if (alimb == 0) {
120*2a598d0bSHerbert Xu lzeros += sizeof(mpi_limb_t);
121*2a598d0bSHerbert Xu } else {
122*2a598d0bSHerbert Xu lzeros += count_leading_zeros(alimb) / 8;
123*2a598d0bSHerbert Xu break;
124*2a598d0bSHerbert Xu }
125*2a598d0bSHerbert Xu }
126*2a598d0bSHerbert Xu return lzeros;
127*2a598d0bSHerbert Xu }
128*2a598d0bSHerbert Xu
129*2a598d0bSHerbert Xu /**
130*2a598d0bSHerbert Xu * mpi_read_buffer() - read MPI to a buffer provided by user (msb first)
131*2a598d0bSHerbert Xu *
132*2a598d0bSHerbert Xu * @a: a multi precision integer
133*2a598d0bSHerbert Xu * @buf: buffer to which the output will be written to. Needs to be at
134*2a598d0bSHerbert Xu * least mpi_get_size(a) long.
135*2a598d0bSHerbert Xu * @buf_len: size of the buf.
136*2a598d0bSHerbert Xu * @nbytes: receives the actual length of the data written on success and
137*2a598d0bSHerbert Xu * the data to-be-written on -EOVERFLOW in case buf_len was too
138*2a598d0bSHerbert Xu * small.
139*2a598d0bSHerbert Xu * @sign: if not NULL, it will be set to the sign of a.
140*2a598d0bSHerbert Xu *
141*2a598d0bSHerbert Xu * Return: 0 on success or error code in case of error
142*2a598d0bSHerbert Xu */
mpi_read_buffer(MPI a,uint8_t * buf,unsigned buf_len,unsigned * nbytes,int * sign)143*2a598d0bSHerbert Xu int mpi_read_buffer(MPI a, uint8_t *buf, unsigned buf_len, unsigned *nbytes,
144*2a598d0bSHerbert Xu int *sign)
145*2a598d0bSHerbert Xu {
146*2a598d0bSHerbert Xu uint8_t *p;
147*2a598d0bSHerbert Xu #if BYTES_PER_MPI_LIMB == 4
148*2a598d0bSHerbert Xu __be32 alimb;
149*2a598d0bSHerbert Xu #elif BYTES_PER_MPI_LIMB == 8
150*2a598d0bSHerbert Xu __be64 alimb;
151*2a598d0bSHerbert Xu #else
152*2a598d0bSHerbert Xu #error please implement for this limb size.
153*2a598d0bSHerbert Xu #endif
154*2a598d0bSHerbert Xu unsigned int n = mpi_get_size(a);
155*2a598d0bSHerbert Xu int i, lzeros;
156*2a598d0bSHerbert Xu
157*2a598d0bSHerbert Xu if (!buf || !nbytes)
158*2a598d0bSHerbert Xu return -EINVAL;
159*2a598d0bSHerbert Xu
160*2a598d0bSHerbert Xu if (sign)
161*2a598d0bSHerbert Xu *sign = a->sign;
162*2a598d0bSHerbert Xu
163*2a598d0bSHerbert Xu lzeros = count_lzeros(a);
164*2a598d0bSHerbert Xu
165*2a598d0bSHerbert Xu if (buf_len < n - lzeros) {
166*2a598d0bSHerbert Xu *nbytes = n - lzeros;
167*2a598d0bSHerbert Xu return -EOVERFLOW;
168*2a598d0bSHerbert Xu }
169*2a598d0bSHerbert Xu
170*2a598d0bSHerbert Xu p = buf;
171*2a598d0bSHerbert Xu *nbytes = n - lzeros;
172*2a598d0bSHerbert Xu
173*2a598d0bSHerbert Xu for (i = a->nlimbs - 1 - lzeros / BYTES_PER_MPI_LIMB,
174*2a598d0bSHerbert Xu lzeros %= BYTES_PER_MPI_LIMB;
175*2a598d0bSHerbert Xu i >= 0; i--) {
176*2a598d0bSHerbert Xu #if BYTES_PER_MPI_LIMB == 4
177*2a598d0bSHerbert Xu alimb = cpu_to_be32(a->d[i]);
178*2a598d0bSHerbert Xu #elif BYTES_PER_MPI_LIMB == 8
179*2a598d0bSHerbert Xu alimb = cpu_to_be64(a->d[i]);
180*2a598d0bSHerbert Xu #else
181*2a598d0bSHerbert Xu #error please implement for this limb size.
182*2a598d0bSHerbert Xu #endif
183*2a598d0bSHerbert Xu memcpy(p, (u8 *)&alimb + lzeros, BYTES_PER_MPI_LIMB - lzeros);
184*2a598d0bSHerbert Xu p += BYTES_PER_MPI_LIMB - lzeros;
185*2a598d0bSHerbert Xu lzeros = 0;
186*2a598d0bSHerbert Xu }
187*2a598d0bSHerbert Xu return 0;
188*2a598d0bSHerbert Xu }
189*2a598d0bSHerbert Xu EXPORT_SYMBOL_GPL(mpi_read_buffer);
190*2a598d0bSHerbert Xu
191*2a598d0bSHerbert Xu /*
192*2a598d0bSHerbert Xu * mpi_get_buffer() - Returns an allocated buffer with the MPI (msb first).
193*2a598d0bSHerbert Xu * Caller must free the return string.
194*2a598d0bSHerbert Xu * This function does return a 0 byte buffer with nbytes set to zero if the
195*2a598d0bSHerbert Xu * value of A is zero.
196*2a598d0bSHerbert Xu *
197*2a598d0bSHerbert Xu * @a: a multi precision integer.
198*2a598d0bSHerbert Xu * @nbytes: receives the length of this buffer.
199*2a598d0bSHerbert Xu * @sign: if not NULL, it will be set to the sign of the a.
200*2a598d0bSHerbert Xu *
201*2a598d0bSHerbert Xu * Return: Pointer to MPI buffer or NULL on error
202*2a598d0bSHerbert Xu */
mpi_get_buffer(MPI a,unsigned * nbytes,int * sign)203*2a598d0bSHerbert Xu void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign)
204*2a598d0bSHerbert Xu {
205*2a598d0bSHerbert Xu uint8_t *buf;
206*2a598d0bSHerbert Xu unsigned int n;
207*2a598d0bSHerbert Xu int ret;
208*2a598d0bSHerbert Xu
209*2a598d0bSHerbert Xu if (!nbytes)
210*2a598d0bSHerbert Xu return NULL;
211*2a598d0bSHerbert Xu
212*2a598d0bSHerbert Xu n = mpi_get_size(a);
213*2a598d0bSHerbert Xu
214*2a598d0bSHerbert Xu if (!n)
215*2a598d0bSHerbert Xu n++;
216*2a598d0bSHerbert Xu
217*2a598d0bSHerbert Xu buf = kmalloc(n, GFP_KERNEL);
218*2a598d0bSHerbert Xu
219*2a598d0bSHerbert Xu if (!buf)
220*2a598d0bSHerbert Xu return NULL;
221*2a598d0bSHerbert Xu
222*2a598d0bSHerbert Xu ret = mpi_read_buffer(a, buf, n, nbytes, sign);
223*2a598d0bSHerbert Xu
224*2a598d0bSHerbert Xu if (ret) {
225*2a598d0bSHerbert Xu kfree(buf);
226*2a598d0bSHerbert Xu return NULL;
227*2a598d0bSHerbert Xu }
228*2a598d0bSHerbert Xu return buf;
229*2a598d0bSHerbert Xu }
230*2a598d0bSHerbert Xu EXPORT_SYMBOL_GPL(mpi_get_buffer);
231*2a598d0bSHerbert Xu
232*2a598d0bSHerbert Xu /**
233*2a598d0bSHerbert Xu * mpi_write_to_sgl() - Funnction exports MPI to an sgl (msb first)
234*2a598d0bSHerbert Xu *
235*2a598d0bSHerbert Xu * This function works in the same way as the mpi_read_buffer, but it
236*2a598d0bSHerbert Xu * takes an sgl instead of u8 * buf.
237*2a598d0bSHerbert Xu *
238*2a598d0bSHerbert Xu * @a: a multi precision integer
239*2a598d0bSHerbert Xu * @sgl: scatterlist to write to. Needs to be at least
240*2a598d0bSHerbert Xu * mpi_get_size(a) long.
241*2a598d0bSHerbert Xu * @nbytes: the number of bytes to write. Leading bytes will be
242*2a598d0bSHerbert Xu * filled with zero.
243*2a598d0bSHerbert Xu * @sign: if not NULL, it will be set to the sign of a.
244*2a598d0bSHerbert Xu *
245*2a598d0bSHerbert Xu * Return: 0 on success or error code in case of error
246*2a598d0bSHerbert Xu */
mpi_write_to_sgl(MPI a,struct scatterlist * sgl,unsigned nbytes,int * sign)247*2a598d0bSHerbert Xu int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned nbytes,
248*2a598d0bSHerbert Xu int *sign)
249*2a598d0bSHerbert Xu {
250*2a598d0bSHerbert Xu u8 *p, *p2;
251*2a598d0bSHerbert Xu #if BYTES_PER_MPI_LIMB == 4
252*2a598d0bSHerbert Xu __be32 alimb;
253*2a598d0bSHerbert Xu #elif BYTES_PER_MPI_LIMB == 8
254*2a598d0bSHerbert Xu __be64 alimb;
255*2a598d0bSHerbert Xu #else
256*2a598d0bSHerbert Xu #error please implement for this limb size.
257*2a598d0bSHerbert Xu #endif
258*2a598d0bSHerbert Xu unsigned int n = mpi_get_size(a);
259*2a598d0bSHerbert Xu struct sg_mapping_iter miter;
260*2a598d0bSHerbert Xu int i, x, buf_len;
261*2a598d0bSHerbert Xu int nents;
262*2a598d0bSHerbert Xu
263*2a598d0bSHerbert Xu if (sign)
264*2a598d0bSHerbert Xu *sign = a->sign;
265*2a598d0bSHerbert Xu
266*2a598d0bSHerbert Xu if (nbytes < n)
267*2a598d0bSHerbert Xu return -EOVERFLOW;
268*2a598d0bSHerbert Xu
269*2a598d0bSHerbert Xu nents = sg_nents_for_len(sgl, nbytes);
270*2a598d0bSHerbert Xu if (nents < 0)
271*2a598d0bSHerbert Xu return -EINVAL;
272*2a598d0bSHerbert Xu
273*2a598d0bSHerbert Xu sg_miter_start(&miter, sgl, nents, SG_MITER_ATOMIC | SG_MITER_TO_SG);
274*2a598d0bSHerbert Xu sg_miter_next(&miter);
275*2a598d0bSHerbert Xu buf_len = miter.length;
276*2a598d0bSHerbert Xu p2 = miter.addr;
277*2a598d0bSHerbert Xu
278*2a598d0bSHerbert Xu while (nbytes > n) {
279*2a598d0bSHerbert Xu i = min_t(unsigned, nbytes - n, buf_len);
280*2a598d0bSHerbert Xu memset(p2, 0, i);
281*2a598d0bSHerbert Xu p2 += i;
282*2a598d0bSHerbert Xu nbytes -= i;
283*2a598d0bSHerbert Xu
284*2a598d0bSHerbert Xu buf_len -= i;
285*2a598d0bSHerbert Xu if (!buf_len) {
286*2a598d0bSHerbert Xu sg_miter_next(&miter);
287*2a598d0bSHerbert Xu buf_len = miter.length;
288*2a598d0bSHerbert Xu p2 = miter.addr;
289*2a598d0bSHerbert Xu }
290*2a598d0bSHerbert Xu }
291*2a598d0bSHerbert Xu
292*2a598d0bSHerbert Xu for (i = a->nlimbs - 1; i >= 0; i--) {
293*2a598d0bSHerbert Xu #if BYTES_PER_MPI_LIMB == 4
294*2a598d0bSHerbert Xu alimb = a->d[i] ? cpu_to_be32(a->d[i]) : 0;
295*2a598d0bSHerbert Xu #elif BYTES_PER_MPI_LIMB == 8
296*2a598d0bSHerbert Xu alimb = a->d[i] ? cpu_to_be64(a->d[i]) : 0;
297*2a598d0bSHerbert Xu #else
298*2a598d0bSHerbert Xu #error please implement for this limb size.
299*2a598d0bSHerbert Xu #endif
300*2a598d0bSHerbert Xu p = (u8 *)&alimb;
301*2a598d0bSHerbert Xu
302*2a598d0bSHerbert Xu for (x = 0; x < sizeof(alimb); x++) {
303*2a598d0bSHerbert Xu *p2++ = *p++;
304*2a598d0bSHerbert Xu if (!--buf_len) {
305*2a598d0bSHerbert Xu sg_miter_next(&miter);
306*2a598d0bSHerbert Xu buf_len = miter.length;
307*2a598d0bSHerbert Xu p2 = miter.addr;
308*2a598d0bSHerbert Xu }
309*2a598d0bSHerbert Xu }
310*2a598d0bSHerbert Xu }
311*2a598d0bSHerbert Xu
312*2a598d0bSHerbert Xu sg_miter_stop(&miter);
313*2a598d0bSHerbert Xu return 0;
314*2a598d0bSHerbert Xu }
315*2a598d0bSHerbert Xu EXPORT_SYMBOL_GPL(mpi_write_to_sgl);
316*2a598d0bSHerbert Xu
317*2a598d0bSHerbert Xu /*
318*2a598d0bSHerbert Xu * mpi_read_raw_from_sgl() - Function allocates an MPI and populates it with
319*2a598d0bSHerbert Xu * data from the sgl
320*2a598d0bSHerbert Xu *
321*2a598d0bSHerbert Xu * This function works in the same way as the mpi_read_raw_data, but it
322*2a598d0bSHerbert Xu * takes an sgl instead of void * buffer. i.e. it allocates
323*2a598d0bSHerbert Xu * a new MPI and reads the content of the sgl to the MPI.
324*2a598d0bSHerbert Xu *
325*2a598d0bSHerbert Xu * @sgl: scatterlist to read from
326*2a598d0bSHerbert Xu * @nbytes: number of bytes to read
327*2a598d0bSHerbert Xu *
328*2a598d0bSHerbert Xu * Return: Pointer to a new MPI or NULL on error
329*2a598d0bSHerbert Xu */
mpi_read_raw_from_sgl(struct scatterlist * sgl,unsigned int nbytes)330*2a598d0bSHerbert Xu MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes)
331*2a598d0bSHerbert Xu {
332*2a598d0bSHerbert Xu struct sg_mapping_iter miter;
333*2a598d0bSHerbert Xu unsigned int nbits, nlimbs;
334*2a598d0bSHerbert Xu int x, j, z, lzeros, ents;
335*2a598d0bSHerbert Xu unsigned int len;
336*2a598d0bSHerbert Xu const u8 *buff;
337*2a598d0bSHerbert Xu mpi_limb_t a;
338*2a598d0bSHerbert Xu MPI val = NULL;
339*2a598d0bSHerbert Xu
340*2a598d0bSHerbert Xu ents = sg_nents_for_len(sgl, nbytes);
341*2a598d0bSHerbert Xu if (ents < 0)
342*2a598d0bSHerbert Xu return NULL;
343*2a598d0bSHerbert Xu
344*2a598d0bSHerbert Xu sg_miter_start(&miter, sgl, ents, SG_MITER_ATOMIC | SG_MITER_FROM_SG);
345*2a598d0bSHerbert Xu
346*2a598d0bSHerbert Xu lzeros = 0;
347*2a598d0bSHerbert Xu len = 0;
348*2a598d0bSHerbert Xu while (nbytes > 0) {
349*2a598d0bSHerbert Xu while (len && !*buff) {
350*2a598d0bSHerbert Xu lzeros++;
351*2a598d0bSHerbert Xu len--;
352*2a598d0bSHerbert Xu buff++;
353*2a598d0bSHerbert Xu }
354*2a598d0bSHerbert Xu
355*2a598d0bSHerbert Xu if (len && *buff)
356*2a598d0bSHerbert Xu break;
357*2a598d0bSHerbert Xu
358*2a598d0bSHerbert Xu sg_miter_next(&miter);
359*2a598d0bSHerbert Xu buff = miter.addr;
360*2a598d0bSHerbert Xu len = miter.length;
361*2a598d0bSHerbert Xu
362*2a598d0bSHerbert Xu nbytes -= lzeros;
363*2a598d0bSHerbert Xu lzeros = 0;
364*2a598d0bSHerbert Xu }
365*2a598d0bSHerbert Xu
366*2a598d0bSHerbert Xu miter.consumed = lzeros;
367*2a598d0bSHerbert Xu
368*2a598d0bSHerbert Xu nbytes -= lzeros;
369*2a598d0bSHerbert Xu nbits = nbytes * 8;
370*2a598d0bSHerbert Xu if (nbits > MAX_EXTERN_MPI_BITS) {
371*2a598d0bSHerbert Xu sg_miter_stop(&miter);
372*2a598d0bSHerbert Xu pr_info("MPI: mpi too large (%u bits)\n", nbits);
373*2a598d0bSHerbert Xu return NULL;
374*2a598d0bSHerbert Xu }
375*2a598d0bSHerbert Xu
376*2a598d0bSHerbert Xu if (nbytes > 0)
377*2a598d0bSHerbert Xu nbits -= count_leading_zeros(*buff) - (BITS_PER_LONG - 8);
378*2a598d0bSHerbert Xu
379*2a598d0bSHerbert Xu sg_miter_stop(&miter);
380*2a598d0bSHerbert Xu
381*2a598d0bSHerbert Xu nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB);
382*2a598d0bSHerbert Xu val = mpi_alloc(nlimbs);
383*2a598d0bSHerbert Xu if (!val)
384*2a598d0bSHerbert Xu return NULL;
385*2a598d0bSHerbert Xu
386*2a598d0bSHerbert Xu val->nbits = nbits;
387*2a598d0bSHerbert Xu val->sign = 0;
388*2a598d0bSHerbert Xu val->nlimbs = nlimbs;
389*2a598d0bSHerbert Xu
390*2a598d0bSHerbert Xu if (nbytes == 0)
391*2a598d0bSHerbert Xu return val;
392*2a598d0bSHerbert Xu
393*2a598d0bSHerbert Xu j = nlimbs - 1;
394*2a598d0bSHerbert Xu a = 0;
395*2a598d0bSHerbert Xu z = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
396*2a598d0bSHerbert Xu z %= BYTES_PER_MPI_LIMB;
397*2a598d0bSHerbert Xu
398*2a598d0bSHerbert Xu while (sg_miter_next(&miter)) {
399*2a598d0bSHerbert Xu buff = miter.addr;
400*2a598d0bSHerbert Xu len = min_t(unsigned, miter.length, nbytes);
401*2a598d0bSHerbert Xu nbytes -= len;
402*2a598d0bSHerbert Xu
403*2a598d0bSHerbert Xu for (x = 0; x < len; x++) {
404*2a598d0bSHerbert Xu a <<= 8;
405*2a598d0bSHerbert Xu a |= *buff++;
406*2a598d0bSHerbert Xu if (((z + x + 1) % BYTES_PER_MPI_LIMB) == 0) {
407*2a598d0bSHerbert Xu val->d[j--] = a;
408*2a598d0bSHerbert Xu a = 0;
409*2a598d0bSHerbert Xu }
410*2a598d0bSHerbert Xu }
411*2a598d0bSHerbert Xu z += x;
412*2a598d0bSHerbert Xu }
413*2a598d0bSHerbert Xu
414*2a598d0bSHerbert Xu return val;
415*2a598d0bSHerbert Xu }
416*2a598d0bSHerbert Xu EXPORT_SYMBOL_GPL(mpi_read_raw_from_sgl);
417