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.c86
1 files changed, 50 insertions, 36 deletions
diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c
index 7150e5c23604..c6272ae2015e 100644
--- a/lib/mpi/mpicoder.c
+++ b/lib/mpi/mpicoder.c
@@ -21,6 +21,7 @@
21#include <linux/bitops.h> 21#include <linux/bitops.h>
22#include <linux/count_zeros.h> 22#include <linux/count_zeros.h>
23#include <linux/byteorder/generic.h> 23#include <linux/byteorder/generic.h>
24#include <linux/scatterlist.h>
24#include <linux/string.h> 25#include <linux/string.h>
25#include "mpi-internal.h" 26#include "mpi-internal.h"
26 27
@@ -255,7 +256,9 @@ int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned nbytes,
255#error please implement for this limb size. 256#error please implement for this limb size.
256#endif 257#endif
257 unsigned int n = mpi_get_size(a); 258 unsigned int n = mpi_get_size(a);
259 struct sg_mapping_iter miter;
258 int i, x, buf_len; 260 int i, x, buf_len;
261 int nents;
259 262
260 if (sign) 263 if (sign)
261 *sign = a->sign; 264 *sign = a->sign;
@@ -263,23 +266,27 @@ int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned nbytes,
263 if (nbytes < n) 266 if (nbytes < n)
264 return -EOVERFLOW; 267 return -EOVERFLOW;
265 268
266 buf_len = sgl->length; 269 nents = sg_nents_for_len(sgl, nbytes);
267 p2 = sg_virt(sgl); 270 if (nents < 0)
271 return -EINVAL;
268 272
269 while (nbytes > n) { 273 sg_miter_start(&miter, sgl, nents, SG_MITER_ATOMIC | SG_MITER_TO_SG);
270 if (!buf_len) { 274 sg_miter_next(&miter);
271 sgl = sg_next(sgl); 275 buf_len = miter.length;
272 if (!sgl) 276 p2 = miter.addr;
273 return -EINVAL;
274 buf_len = sgl->length;
275 p2 = sg_virt(sgl);
276 }
277 277
278 while (nbytes > n) {
278 i = min_t(unsigned, nbytes - n, buf_len); 279 i = min_t(unsigned, nbytes - n, buf_len);
279 memset(p2, 0, i); 280 memset(p2, 0, i);
280 p2 += i; 281 p2 += i;
281 buf_len -= i;
282 nbytes -= i; 282 nbytes -= i;
283
284 buf_len -= i;
285 if (!buf_len) {
286 sg_miter_next(&miter);
287 buf_len = miter.length;
288 p2 = miter.addr;
289 }
283 } 290 }
284 291
285 for (i = a->nlimbs - 1; i >= 0; i--) { 292 for (i = a->nlimbs - 1; i >= 0; i--) {
@@ -293,17 +300,16 @@ int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned nbytes,
293 p = (u8 *)&alimb; 300 p = (u8 *)&alimb;
294 301
295 for (x = 0; x < sizeof(alimb); x++) { 302 for (x = 0; x < sizeof(alimb); x++) {
296 if (!buf_len) {
297 sgl = sg_next(sgl);
298 if (!sgl)
299 return -EINVAL;
300 buf_len = sgl->length;
301 p2 = sg_virt(sgl);
302 }
303 *p2++ = *p++; 303 *p2++ = *p++;
304 buf_len--; 304 if (!--buf_len) {
305 sg_miter_next(&miter);
306 buf_len = miter.length;
307 p2 = miter.addr;
308 }
305 } 309 }
306 } 310 }
311
312 sg_miter_stop(&miter);
307 return 0; 313 return 0;
308} 314}
309EXPORT_SYMBOL_GPL(mpi_write_to_sgl); 315EXPORT_SYMBOL_GPL(mpi_write_to_sgl);
@@ -323,19 +329,23 @@ EXPORT_SYMBOL_GPL(mpi_write_to_sgl);
323 */ 329 */
324MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes) 330MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes)
325{ 331{
326 struct scatterlist *sg; 332 struct sg_mapping_iter miter;
327 int x, i, j, z, lzeros, ents;
328 unsigned int nbits, nlimbs; 333 unsigned int nbits, nlimbs;
334 int x, j, z, lzeros, ents;
335 unsigned int len;
336 const u8 *buff;
329 mpi_limb_t a; 337 mpi_limb_t a;
330 MPI val = NULL; 338 MPI val = NULL;
331 339
332 lzeros = 0; 340 ents = sg_nents_for_len(sgl, nbytes);
333 ents = sg_nents(sgl); 341 if (ents < 0)
342 return NULL;
334 343
335 for_each_sg(sgl, sg, ents, i) { 344 sg_miter_start(&miter, sgl, ents, SG_MITER_ATOMIC | SG_MITER_FROM_SG);
336 const u8 *buff = sg_virt(sg);
337 int len = sg->length;
338 345
346 lzeros = 0;
347 len = 0;
348 while (nbytes > 0) {
339 while (len && !*buff) { 349 while (len && !*buff) {
340 lzeros++; 350 lzeros++;
341 len--; 351 len--;
@@ -345,12 +355,14 @@ MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes)
345 if (len && *buff) 355 if (len && *buff)
346 break; 356 break;
347 357
348 ents--; 358 sg_miter_next(&miter);
359 buff = miter.addr;
360 len = miter.length;
361
349 nbytes -= lzeros; 362 nbytes -= lzeros;
350 lzeros = 0; 363 lzeros = 0;
351 } 364 }
352 365
353 sgl = sg;
354 nbytes -= lzeros; 366 nbytes -= lzeros;
355 nbits = nbytes * 8; 367 nbits = nbytes * 8;
356 if (nbits > MAX_EXTERN_MPI_BITS) { 368 if (nbits > MAX_EXTERN_MPI_BITS) {
@@ -359,8 +371,7 @@ MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes)
359 } 371 }
360 372
361 if (nbytes > 0) 373 if (nbytes > 0)
362 nbits -= count_leading_zeros(*(u8 *)(sg_virt(sgl) + lzeros)) - 374 nbits -= count_leading_zeros(*buff) - (BITS_PER_LONG - 8);
363 (BITS_PER_LONG - 8);
364 375
365 nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB); 376 nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB);
366 val = mpi_alloc(nlimbs); 377 val = mpi_alloc(nlimbs);
@@ -379,21 +390,24 @@ MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes)
379 z = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB; 390 z = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
380 z %= BYTES_PER_MPI_LIMB; 391 z %= BYTES_PER_MPI_LIMB;
381 392
382 for_each_sg(sgl, sg, ents, i) { 393 for (;;) {
383 const u8 *buffer = sg_virt(sg) + lzeros;
384 int len = sg->length - lzeros;
385
386 for (x = 0; x < len; x++) { 394 for (x = 0; x < len; x++) {
387 a <<= 8; 395 a <<= 8;
388 a |= *buffer++; 396 a |= *buff++;
389 if (((z + x + 1) % BYTES_PER_MPI_LIMB) == 0) { 397 if (((z + x + 1) % BYTES_PER_MPI_LIMB) == 0) {
390 val->d[j--] = a; 398 val->d[j--] = a;
391 a = 0; 399 a = 0;
392 } 400 }
393 } 401 }
394 z += x; 402 z += x;
395 lzeros = 0; 403
404 if (!sg_miter_next(&miter))
405 break;
406
407 buff = miter.addr;
408 len = miter.length;
396 } 409 }
410
397 return val; 411 return val;
398} 412}
399EXPORT_SYMBOL_GPL(mpi_read_raw_from_sgl); 413EXPORT_SYMBOL_GPL(mpi_read_raw_from_sgl);