diff options
Diffstat (limited to 'lib/mpi/mpicoder.c')
| -rw-r--r-- | lib/mpi/mpicoder.c | 52 |
1 files changed, 34 insertions, 18 deletions
diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c index 3db76b8c1115..eb15e7dc7b65 100644 --- a/lib/mpi/mpicoder.c +++ b/lib/mpi/mpicoder.c | |||
| @@ -128,6 +128,23 @@ leave: | |||
| 128 | } | 128 | } |
| 129 | EXPORT_SYMBOL_GPL(mpi_read_from_buffer); | 129 | EXPORT_SYMBOL_GPL(mpi_read_from_buffer); |
| 130 | 130 | ||
| 131 | static int count_lzeros(MPI a) | ||
| 132 | { | ||
| 133 | mpi_limb_t alimb; | ||
| 134 | int i, lzeros = 0; | ||
| 135 | |||
| 136 | for (i = a->nlimbs - 1; i >= 0; i--) { | ||
| 137 | alimb = a->d[i]; | ||
| 138 | if (alimb == 0) { | ||
| 139 | lzeros += sizeof(mpi_limb_t); | ||
| 140 | } else { | ||
| 141 | lzeros += count_leading_zeros(alimb) / 8; | ||
| 142 | break; | ||
| 143 | } | ||
| 144 | } | ||
| 145 | return lzeros; | ||
| 146 | } | ||
| 147 | |||
| 131 | /** | 148 | /** |
| 132 | * mpi_read_buffer() - read MPI to a bufer provided by user (msb first) | 149 | * mpi_read_buffer() - read MPI to a bufer provided by user (msb first) |
| 133 | * | 150 | * |
| @@ -135,7 +152,9 @@ EXPORT_SYMBOL_GPL(mpi_read_from_buffer); | |||
| 135 | * @buf: bufer to which the output will be written to. Needs to be at | 152 | * @buf: bufer to which the output will be written to. Needs to be at |
| 136 | * leaset mpi_get_size(a) long. | 153 | * leaset mpi_get_size(a) long. |
| 137 | * @buf_len: size of the buf. | 154 | * @buf_len: size of the buf. |
| 138 | * @nbytes: receives the actual length of the data written. | 155 | * @nbytes: receives the actual length of the data written on success and |
| 156 | * the data to-be-written on -EOVERFLOW in case buf_len was too | ||
| 157 | * small. | ||
| 139 | * @sign: if not NULL, it will be set to the sign of a. | 158 | * @sign: if not NULL, it will be set to the sign of a. |
| 140 | * | 159 | * |
| 141 | * Return: 0 on success or error code in case of error | 160 | * Return: 0 on success or error code in case of error |
| @@ -146,21 +165,19 @@ int mpi_read_buffer(MPI a, uint8_t *buf, unsigned buf_len, unsigned *nbytes, | |||
| 146 | uint8_t *p; | 165 | uint8_t *p; |
| 147 | mpi_limb_t alimb; | 166 | mpi_limb_t alimb; |
| 148 | unsigned int n = mpi_get_size(a); | 167 | unsigned int n = mpi_get_size(a); |
| 149 | int i, lzeros = 0; | 168 | int i, lzeros; |
| 150 | 169 | ||
| 151 | if (buf_len < n || !buf || !nbytes) | 170 | if (!buf || !nbytes) |
| 152 | return -EINVAL; | 171 | return -EINVAL; |
| 153 | 172 | ||
| 154 | if (sign) | 173 | if (sign) |
| 155 | *sign = a->sign; | 174 | *sign = a->sign; |
| 156 | 175 | ||
| 157 | p = (void *)&a->d[a->nlimbs] - 1; | 176 | lzeros = count_lzeros(a); |
| 158 | 177 | ||
| 159 | for (i = a->nlimbs * sizeof(alimb) - 1; i >= 0; i--, p--) { | 178 | if (buf_len < n - lzeros) { |
| 160 | if (!*p) | 179 | *nbytes = n - lzeros; |
| 161 | lzeros++; | 180 | return -EOVERFLOW; |
| 162 | else | ||
| 163 | break; | ||
| 164 | } | 181 | } |
| 165 | 182 | ||
| 166 | p = buf; | 183 | p = buf; |
| @@ -332,7 +349,8 @@ EXPORT_SYMBOL_GPL(mpi_set_buffer); | |||
| 332 | * @nbytes: in/out param - it has the be set to the maximum number of | 349 | * @nbytes: in/out param - it has the be set to the maximum number of |
| 333 | * bytes that can be written to sgl. This has to be at least | 350 | * bytes that can be written to sgl. This has to be at least |
| 334 | * the size of the integer a. On return it receives the actual | 351 | * the size of the integer a. On return it receives the actual |
| 335 | * length of the data written. | 352 | * length of the data written on success or the data that would |
| 353 | * be written if buffer was too small. | ||
| 336 | * @sign: if not NULL, it will be set to the sign of a. | 354 | * @sign: if not NULL, it will be set to the sign of a. |
| 337 | * | 355 | * |
| 338 | * Return: 0 on success or error code in case of error | 356 | * Return: 0 on success or error code in case of error |
| @@ -343,21 +361,19 @@ int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned *nbytes, | |||
| 343 | u8 *p, *p2; | 361 | u8 *p, *p2; |
| 344 | mpi_limb_t alimb, alimb2; | 362 | mpi_limb_t alimb, alimb2; |
| 345 | unsigned int n = mpi_get_size(a); | 363 | unsigned int n = mpi_get_size(a); |
| 346 | int i, x, y = 0, lzeros = 0, buf_len; | 364 | int i, x, y = 0, lzeros, buf_len; |
| 347 | 365 | ||
| 348 | if (!nbytes || *nbytes < n) | 366 | if (!nbytes) |
| 349 | return -EINVAL; | 367 | return -EINVAL; |
| 350 | 368 | ||
| 351 | if (sign) | 369 | if (sign) |
| 352 | *sign = a->sign; | 370 | *sign = a->sign; |
| 353 | 371 | ||
| 354 | p = (void *)&a->d[a->nlimbs] - 1; | 372 | lzeros = count_lzeros(a); |
| 355 | 373 | ||
| 356 | for (i = a->nlimbs * sizeof(alimb) - 1; i >= 0; i--, p--) { | 374 | if (*nbytes < n - lzeros) { |
| 357 | if (!*p) | 375 | *nbytes = n - lzeros; |
| 358 | lzeros++; | 376 | return -EOVERFLOW; |
| 359 | else | ||
| 360 | break; | ||
| 361 | } | 377 | } |
| 362 | 378 | ||
| 363 | *nbytes = n - lzeros; | 379 | *nbytes = n - lzeros; |
