aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2016-06-29 07:32:21 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2016-07-01 11:45:18 -0400
commit9b45b7bba3d22de52e09df63c50f390a193a3f53 (patch)
tree589fa304ec152558fc189f2da773154bd334e64c
parent50d2b643ea6675927435743633a57c2a9cfd8d83 (diff)
crypto: rsa - Generate fixed-length output
Every implementation of RSA that we have naturally generates output with leading zeroes. The one and only user of RSA, pkcs1pad wants to have those leading zeroes in place, in fact because they are currently absent it has to write those zeroes itself. So we shouldn't be stripping leading zeroes in the first place. In fact this patch makes rsa-generic produce output with fixed length so that pkcs1pad does not need to do any extra work. This patch also changes DH to use the new interface. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/dh.c2
-rw-r--r--crypto/rsa.c8
-rw-r--r--include/linux/mpi.h2
-rw-r--r--lib/mpi/mpicoder.c55
4 files changed, 32 insertions, 35 deletions
diff --git a/crypto/dh.c b/crypto/dh.c
index 5e960fe28681..9d19360e7189 100644
--- a/crypto/dh.c
+++ b/crypto/dh.c
@@ -129,7 +129,7 @@ static int dh_compute_value(struct kpp_request *req)
129 if (ret) 129 if (ret)
130 goto err_free_base; 130 goto err_free_base;
131 131
132 ret = mpi_write_to_sgl(val, req->dst, &req->dst_len, &sign); 132 ret = mpi_write_to_sgl(val, req->dst, req->dst_len, &sign);
133 if (ret) 133 if (ret)
134 goto err_free_base; 134 goto err_free_base;
135 135
diff --git a/crypto/rsa.c b/crypto/rsa.c
index dc692d43b666..4c280b6a3ea9 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -108,7 +108,7 @@ static int rsa_enc(struct akcipher_request *req)
108 if (ret) 108 if (ret)
109 goto err_free_m; 109 goto err_free_m;
110 110
111 ret = mpi_write_to_sgl(c, req->dst, &req->dst_len, &sign); 111 ret = mpi_write_to_sgl(c, req->dst, req->dst_len, &sign);
112 if (ret) 112 if (ret)
113 goto err_free_m; 113 goto err_free_m;
114 114
@@ -147,7 +147,7 @@ static int rsa_dec(struct akcipher_request *req)
147 if (ret) 147 if (ret)
148 goto err_free_c; 148 goto err_free_c;
149 149
150 ret = mpi_write_to_sgl(m, req->dst, &req->dst_len, &sign); 150 ret = mpi_write_to_sgl(m, req->dst, req->dst_len, &sign);
151 if (ret) 151 if (ret)
152 goto err_free_c; 152 goto err_free_c;
153 153
@@ -185,7 +185,7 @@ static int rsa_sign(struct akcipher_request *req)
185 if (ret) 185 if (ret)
186 goto err_free_m; 186 goto err_free_m;
187 187
188 ret = mpi_write_to_sgl(s, req->dst, &req->dst_len, &sign); 188 ret = mpi_write_to_sgl(s, req->dst, req->dst_len, &sign);
189 if (ret) 189 if (ret)
190 goto err_free_m; 190 goto err_free_m;
191 191
@@ -226,7 +226,7 @@ static int rsa_verify(struct akcipher_request *req)
226 if (ret) 226 if (ret)
227 goto err_free_s; 227 goto err_free_s;
228 228
229 ret = mpi_write_to_sgl(m, req->dst, &req->dst_len, &sign); 229 ret = mpi_write_to_sgl(m, req->dst, req->dst_len, &sign);
230 if (ret) 230 if (ret)
231 goto err_free_s; 231 goto err_free_s;
232 232
diff --git a/include/linux/mpi.h b/include/linux/mpi.h
index f219559e5e80..1cc5ffb769af 100644
--- a/include/linux/mpi.h
+++ b/include/linux/mpi.h
@@ -80,7 +80,7 @@ void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign);
80int mpi_read_buffer(MPI a, uint8_t *buf, unsigned buf_len, unsigned *nbytes, 80int mpi_read_buffer(MPI a, uint8_t *buf, unsigned buf_len, unsigned *nbytes,
81 int *sign); 81 int *sign);
82void *mpi_get_secure_buffer(MPI a, unsigned *nbytes, int *sign); 82void *mpi_get_secure_buffer(MPI a, unsigned *nbytes, int *sign);
83int mpi_write_to_sgl(MPI a, struct scatterlist *sg, unsigned *nbytes, 83int mpi_write_to_sgl(MPI a, struct scatterlist *sg, unsigned nbytes,
84 int *sign); 84 int *sign);
85 85
86#define log_mpidump g10_log_mpidump 86#define log_mpidump g10_log_mpidump
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}