diff options
Diffstat (limited to 'lib/mpi/mpicoder.c')
-rw-r--r-- | lib/mpi/mpicoder.c | 55 |
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 | */ |
249 | int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned *nbytes, | 246 | int 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 | } |