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);   * @a:		a multi precision integer   * @sgl:	scatterlist to write to. Needs to be at least   *		mpi_get_size(a) long. - * @nbytes:	in/out param - it has the be set to the maximum number of - *		bytes that can be written to sgl. This has to be at least - *		the size of the integer a. On return it receives the actual - *		length of the data written on success or the data that would - *		be written if buffer was too small. + * @nbytes:	the number of bytes to write.  Leading bytes will be + *		filled with zero.   * @sign:	if not NULL, it will be set to the sign of a.   *   * Return:	0 on success or error code in case of error   */ -int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned *nbytes, +int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned nbytes,  		     int *sign)  {  	u8 *p, *p2; @@ -258,43 +255,44 @@ int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned *nbytes,  #error please implement for this limb size.  #endif  	unsigned int n = mpi_get_size(a); -	int i, x, y = 0, lzeros, buf_len; - -	if (!nbytes) -		return -EINVAL; +	int i, x, buf_len;  	if (sign)  		*sign = a->sign; -	lzeros = count_lzeros(a); - -	if (*nbytes < n - lzeros) { -		*nbytes = n - lzeros; +	if (nbytes < n)  		return -EOVERFLOW; -	} -	*nbytes = n - lzeros;  	buf_len = sgl->length;  	p2 = sg_virt(sgl); -	for (i = a->nlimbs - 1 - lzeros / BYTES_PER_MPI_LIMB, -			lzeros %= BYTES_PER_MPI_LIMB; -		i >= 0; i--) { +	while (nbytes > n) { +		if (!buf_len) { +			sgl = sg_next(sgl); +			if (!sgl) +				return -EINVAL; +			buf_len = sgl->length; +			p2 = sg_virt(sgl); +		} + +		i = min_t(unsigned, nbytes - n, buf_len); +		memset(p2, 0, i); +		p2 += i; +		buf_len -= i; +		nbytes -= i; +	} + +	for (i = a->nlimbs - 1; i >= 0; i--) {  #if BYTES_PER_MPI_LIMB == 4 -		alimb = cpu_to_be32(a->d[i]); +		alimb = a->d[i] ? cpu_to_be32(a->d[i]) : 0;  #elif BYTES_PER_MPI_LIMB == 8 -		alimb = cpu_to_be64(a->d[i]); +		alimb = a->d[i] ? cpu_to_be64(a->d[i]) : 0;  #else  #error please implement for this limb size.  #endif -		if (lzeros) { -			y = lzeros; -			lzeros = 0; -		} - -		p = (u8 *)&alimb + y; +		p = (u8 *)&alimb; -		for (x = 0; x < sizeof(alimb) - y; x++) { +		for (x = 0; x < sizeof(alimb); x++) {  			if (!buf_len) {  				sgl = sg_next(sgl);  				if (!sgl) @@ -305,7 +303,6 @@ int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned *nbytes,  			*p2++ = *p++;  			buf_len--;  		} -		y = 0;  	}  	return 0;  }  | 
