aboutsummaryrefslogtreecommitdiffstats
path: root/lib/mpi/mpicoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mpi/mpicoder.c')
-rw-r--r--lib/mpi/mpicoder.c55
1 files changed, 26 insertions, 29 deletions
diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c
index 823cf5f5196b..7150e5c23604 100644
--- a/lib/mpi/mpicoder.c
+++ b/lib/mpi/mpicoder.c
@@ -237,16 +237,13 @@ EXPORT_SYMBOL_GPL(mpi_get_buffer);
237 * @a: a multi precision integer 237 * @a: a multi precision integer
238 * @sgl: scatterlist to write to. Needs to be at least 238 * @sgl: scatterlist to write to. Needs to be at least
239 * mpi_get_size(a) long. 239 * mpi_get_size(a) long.
240 * @nbytes: in/out param - it has the be set to the maximum number of 240 * @nbytes: the number of bytes to write. Leading bytes will be
241 * bytes that can be written to sgl. This has to be at least 241 * filled with zero.
242 * the size of the integer a. On return it receives the actual
243 * length of the data written on success or the data that would
244 * be written if buffer was too small.
245 * @sign: if not NULL, it will be set to the sign of a. 242 * @sign: if not NULL, it will be set to the sign of a.
246 * 243 *
247 * Return: 0 on success or error code in case of error 244 * Return: 0 on success or error code in case of error
248 */ 245 */
249int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned *nbytes, 246int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned nbytes,
250 int *sign) 247 int *sign)
251{ 248{
252 u8 *p, *p2; 249 u8 *p, *p2;
@@ -258,43 +255,44 @@ int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned *nbytes,
258#error please implement for this limb size. 255#error please implement for this limb size.
259#endif 256#endif
260 unsigned int n = mpi_get_size(a); 257 unsigned int n = mpi_get_size(a);
261 int i, x, y = 0, lzeros, buf_len; 258 int i, x, buf_len;
262
263 if (!nbytes)
264 return -EINVAL;
265 259
266 if (sign) 260 if (sign)
267 *sign = a->sign; 261 *sign = a->sign;
268 262
269 lzeros = count_lzeros(a); 263 if (nbytes < n)
270
271 if (*nbytes < n - lzeros) {
272 *nbytes = n - lzeros;
273 return -EOVERFLOW; 264 return -EOVERFLOW;
274 }
275 265
276 *nbytes = n - lzeros;
277 buf_len = sgl->length; 266 buf_len = sgl->length;
278 p2 = sg_virt(sgl); 267 p2 = sg_virt(sgl);
279 268
280 for (i = a->nlimbs - 1 - lzeros / BYTES_PER_MPI_LIMB, 269 while (nbytes > n) {
281 lzeros %= BYTES_PER_MPI_LIMB; 270 if (!buf_len) {
282 i >= 0; i--) { 271 sgl = sg_next(sgl);
272 if (!sgl)
273 return -EINVAL;
274 buf_len = sgl->length;
275 p2 = sg_virt(sgl);
276 }
277
278 i = min_t(unsigned, nbytes - n, buf_len);
279 memset(p2, 0, i);
280 p2 += i;
281 buf_len -= i;
282 nbytes -= i;
283 }
284
285 for (i = a->nlimbs - 1; i >= 0; i--) {
283#if BYTES_PER_MPI_LIMB == 4 286#if BYTES_PER_MPI_LIMB == 4
284 alimb = cpu_to_be32(a->d[i]); 287 alimb = a->d[i] ? cpu_to_be32(a->d[i]) : 0;
285#elif BYTES_PER_MPI_LIMB == 8 288#elif BYTES_PER_MPI_LIMB == 8
286 alimb = cpu_to_be64(a->d[i]); 289 alimb = a->d[i] ? cpu_to_be64(a->d[i]) : 0;
287#else 290#else
288#error please implement for this limb size. 291#error please implement for this limb size.
289#endif 292#endif
290 if (lzeros) { 293 p = (u8 *)&alimb;
291 y = lzeros;
292 lzeros = 0;
293 }
294
295 p = (u8 *)&alimb + y;
296 294
297 for (x = 0; x < sizeof(alimb) - y; x++) { 295 for (x = 0; x < sizeof(alimb); x++) {
298 if (!buf_len) { 296 if (!buf_len) {
299 sgl = sg_next(sgl); 297 sgl = sg_next(sgl);
300 if (!sgl) 298 if (!sgl)
@@ -305,7 +303,6 @@ int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned *nbytes,
305 *p2++ = *p++; 303 *p2++ = *p++;
306 buf_len--; 304 buf_len--;
307 } 305 }
308 y = 0;
309 } 306 }
310 return 0; 307 return 0;
311} 308}