xref: /linux-6.15/lib/crypto/mpi/mpicoder.c (revision fca5cb4d)
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