diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-26 16:40:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-26 16:40:17 -0400 |
commit | bbce2ad2d711c12d93145a7bbdf086e73f414bcd (patch) | |
tree | 35432a39f68f4c5df44ed38037cbf05adadb923e /lib/mpi/mpicoder.c | |
parent | 0f776dc377f6c87f4e4d4a5f63602f33fb93b31e (diff) | |
parent | 0f95e2ffc58f5d32a90eb1051d17aeebc21cf91d (diff) |
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto updates from Herbert Xu:
"Here is the crypto update for 4.8:
API:
- first part of skcipher low-level conversions
- add KPP (Key-agreement Protocol Primitives) interface.
Algorithms:
- fix IPsec/cryptd reordering issues that affects aesni
- RSA no longer does explicit leading zero removal
- add SHA3
- add DH
- add ECDH
- improve DRBG performance by not doing CTR by hand
Drivers:
- add x86 AVX2 multibuffer SHA256/512
- add POWER8 optimised crc32c
- add xts support to vmx
- add DH support to qat
- add RSA support to caam
- add Layerscape support to caam
- add SEC1 AEAD support to talitos
- improve performance by chaining requests in marvell/cesa
- add support for Araneus Alea I USB RNG
- add support for Broadcom BCM5301 RNG
- add support for Amlogic Meson RNG
- add support Broadcom NSP SoC RNG"
* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (180 commits)
crypto: vmx - Fix aes_p8_xts_decrypt build failure
crypto: vmx - Ignore generated files
crypto: vmx - Adding support for XTS
crypto: vmx - Adding asm subroutines for XTS
crypto: skcipher - add comment for skcipher_alg->base
crypto: testmgr - Print akcipher algorithm name
crypto: marvell - Fix wrong flag used for GFP in mv_cesa_dma_add_iv_op
crypto: nx - off by one bug in nx_of_update_msc()
crypto: rsa-pkcs1pad - fix rsa-pkcs1pad request struct
crypto: scatterwalk - Inline start/map/done
crypto: scatterwalk - Remove unnecessary BUG in scatterwalk_start
crypto: scatterwalk - Remove unnecessary advance in scatterwalk_pagedone
crypto: scatterwalk - Fix test in scatterwalk_done
crypto: api - Optimise away crypto_yield when hard preemption is on
crypto: scatterwalk - add no-copy support to copychunks
crypto: scatterwalk - Remove scatterwalk_bytes_sglen
crypto: omap - Stop using crypto scatterwalk_bytes_sglen
crypto: skcipher - Remove top-level givcipher interface
crypto: user - Remove crypto_lookup_skcipher call
crypto: cts - Convert to skcipher
...
Diffstat (limited to 'lib/mpi/mpicoder.c')
-rw-r--r-- | lib/mpi/mpicoder.c | 249 |
1 files changed, 81 insertions, 168 deletions
diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c index 747606f9e4a3..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 | ||
@@ -50,9 +51,7 @@ MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes) | |||
50 | return NULL; | 51 | return NULL; |
51 | } | 52 | } |
52 | if (nbytes > 0) | 53 | if (nbytes > 0) |
53 | nbits -= count_leading_zeros(buffer[0]); | 54 | nbits -= count_leading_zeros(buffer[0]) - (BITS_PER_LONG - 8); |
54 | else | ||
55 | nbits = 0; | ||
56 | 55 | ||
57 | nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB); | 56 | nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB); |
58 | val = mpi_alloc(nlimbs); | 57 | val = mpi_alloc(nlimbs); |
@@ -82,50 +81,30 @@ EXPORT_SYMBOL_GPL(mpi_read_raw_data); | |||
82 | MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread) | 81 | MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread) |
83 | { | 82 | { |
84 | const uint8_t *buffer = xbuffer; | 83 | const uint8_t *buffer = xbuffer; |
85 | int i, j; | 84 | unsigned int nbits, nbytes; |
86 | unsigned nbits, nbytes, nlimbs, nread = 0; | 85 | MPI val; |
87 | mpi_limb_t a; | ||
88 | MPI val = NULL; | ||
89 | 86 | ||
90 | if (*ret_nread < 2) | 87 | if (*ret_nread < 2) |
91 | goto leave; | 88 | return ERR_PTR(-EINVAL); |
92 | nbits = buffer[0] << 8 | buffer[1]; | 89 | nbits = buffer[0] << 8 | buffer[1]; |
93 | 90 | ||
94 | if (nbits > MAX_EXTERN_MPI_BITS) { | 91 | if (nbits > MAX_EXTERN_MPI_BITS) { |
95 | pr_info("MPI: mpi too large (%u bits)\n", nbits); | 92 | pr_info("MPI: mpi too large (%u bits)\n", nbits); |
96 | goto leave; | 93 | return ERR_PTR(-EINVAL); |
97 | } | 94 | } |
98 | buffer += 2; | ||
99 | nread = 2; | ||
100 | 95 | ||
101 | nbytes = DIV_ROUND_UP(nbits, 8); | 96 | nbytes = DIV_ROUND_UP(nbits, 8); |
102 | nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB); | 97 | if (nbytes + 2 > *ret_nread) { |
103 | val = mpi_alloc(nlimbs); | 98 | pr_info("MPI: mpi larger than buffer nbytes=%u ret_nread=%u\n", |
104 | if (!val) | 99 | nbytes, *ret_nread); |
105 | return NULL; | 100 | return ERR_PTR(-EINVAL); |
106 | i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB; | ||
107 | i %= BYTES_PER_MPI_LIMB; | ||
108 | val->nbits = nbits; | ||
109 | j = val->nlimbs = nlimbs; | ||
110 | val->sign = 0; | ||
111 | for (; j > 0; j--) { | ||
112 | a = 0; | ||
113 | for (; i < BYTES_PER_MPI_LIMB; i++) { | ||
114 | if (++nread > *ret_nread) { | ||
115 | printk | ||
116 | ("MPI: mpi larger than buffer nread=%d ret_nread=%d\n", | ||
117 | nread, *ret_nread); | ||
118 | goto leave; | ||
119 | } | ||
120 | a <<= 8; | ||
121 | a |= *buffer++; | ||
122 | } | ||
123 | i = 0; | ||
124 | val->d[j - 1] = a; | ||
125 | } | 101 | } |
126 | 102 | ||
127 | leave: | 103 | val = mpi_read_raw_data(buffer + 2, nbytes); |
128 | *ret_nread = nread; | 104 | if (!val) |
105 | return ERR_PTR(-ENOMEM); | ||
106 | |||
107 | *ret_nread = nbytes + 2; | ||
129 | return val; | 108 | return val; |
130 | } | 109 | } |
131 | EXPORT_SYMBOL_GPL(mpi_read_from_buffer); | 110 | EXPORT_SYMBOL_GPL(mpi_read_from_buffer); |
@@ -250,82 +229,6 @@ void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign) | |||
250 | } | 229 | } |
251 | EXPORT_SYMBOL_GPL(mpi_get_buffer); | 230 | EXPORT_SYMBOL_GPL(mpi_get_buffer); |
252 | 231 | ||
253 | /**************** | ||
254 | * Use BUFFER to update MPI. | ||
255 | */ | ||
256 | int mpi_set_buffer(MPI a, const void *xbuffer, unsigned nbytes, int sign) | ||
257 | { | ||
258 | const uint8_t *buffer = xbuffer, *p; | ||
259 | mpi_limb_t alimb; | ||
260 | int nlimbs; | ||
261 | int i; | ||
262 | |||
263 | nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB); | ||
264 | if (RESIZE_IF_NEEDED(a, nlimbs) < 0) | ||
265 | return -ENOMEM; | ||
266 | a->sign = sign; | ||
267 | |||
268 | for (i = 0, p = buffer + nbytes - 1; p >= buffer + BYTES_PER_MPI_LIMB;) { | ||
269 | #if BYTES_PER_MPI_LIMB == 4 | ||
270 | alimb = (mpi_limb_t) *p--; | ||
271 | alimb |= (mpi_limb_t) *p-- << 8; | ||
272 | alimb |= (mpi_limb_t) *p-- << 16; | ||
273 | alimb |= (mpi_limb_t) *p-- << 24; | ||
274 | #elif BYTES_PER_MPI_LIMB == 8 | ||
275 | alimb = (mpi_limb_t) *p--; | ||
276 | alimb |= (mpi_limb_t) *p-- << 8; | ||
277 | alimb |= (mpi_limb_t) *p-- << 16; | ||
278 | alimb |= (mpi_limb_t) *p-- << 24; | ||
279 | alimb |= (mpi_limb_t) *p-- << 32; | ||
280 | alimb |= (mpi_limb_t) *p-- << 40; | ||
281 | alimb |= (mpi_limb_t) *p-- << 48; | ||
282 | alimb |= (mpi_limb_t) *p-- << 56; | ||
283 | #else | ||
284 | #error please implement for this limb size. | ||
285 | #endif | ||
286 | a->d[i++] = alimb; | ||
287 | } | ||
288 | if (p >= buffer) { | ||
289 | #if BYTES_PER_MPI_LIMB == 4 | ||
290 | alimb = *p--; | ||
291 | if (p >= buffer) | ||
292 | alimb |= (mpi_limb_t) *p-- << 8; | ||
293 | if (p >= buffer) | ||
294 | alimb |= (mpi_limb_t) *p-- << 16; | ||
295 | if (p >= buffer) | ||
296 | alimb |= (mpi_limb_t) *p-- << 24; | ||
297 | #elif BYTES_PER_MPI_LIMB == 8 | ||
298 | alimb = (mpi_limb_t) *p--; | ||
299 | if (p >= buffer) | ||
300 | alimb |= (mpi_limb_t) *p-- << 8; | ||
301 | if (p >= buffer) | ||
302 | alimb |= (mpi_limb_t) *p-- << 16; | ||
303 | if (p >= buffer) | ||
304 | alimb |= (mpi_limb_t) *p-- << 24; | ||
305 | if (p >= buffer) | ||
306 | alimb |= (mpi_limb_t) *p-- << 32; | ||
307 | if (p >= buffer) | ||
308 | alimb |= (mpi_limb_t) *p-- << 40; | ||
309 | if (p >= buffer) | ||
310 | alimb |= (mpi_limb_t) *p-- << 48; | ||
311 | if (p >= buffer) | ||
312 | alimb |= (mpi_limb_t) *p-- << 56; | ||
313 | #else | ||
314 | #error please implement for this limb size. | ||
315 | #endif | ||
316 | a->d[i++] = alimb; | ||
317 | } | ||
318 | a->nlimbs = i; | ||
319 | |||
320 | if (i != nlimbs) { | ||
321 | pr_emerg("MPI: mpi_set_buffer: Assertion failed (%d != %d)", i, | ||
322 | nlimbs); | ||
323 | BUG(); | ||
324 | } | ||
325 | return 0; | ||
326 | } | ||
327 | EXPORT_SYMBOL_GPL(mpi_set_buffer); | ||
328 | |||
329 | /** | 232 | /** |
330 | * mpi_write_to_sgl() - Funnction exports MPI to an sgl (msb first) | 233 | * mpi_write_to_sgl() - Funnction exports MPI to an sgl (msb first) |
331 | * | 234 | * |
@@ -335,16 +238,13 @@ EXPORT_SYMBOL_GPL(mpi_set_buffer); | |||
335 | * @a: a multi precision integer | 238 | * @a: a multi precision integer |
336 | * @sgl: scatterlist to write to. Needs to be at least | 239 | * @sgl: scatterlist to write to. Needs to be at least |
337 | * mpi_get_size(a) long. | 240 | * mpi_get_size(a) long. |
338 | * @nbytes: in/out param - it has the be set to the maximum number of | 241 | * @nbytes: the number of bytes to write. Leading bytes will be |
339 | * bytes that can be written to sgl. This has to be at least | 242 | * filled with zero. |
340 | * the size of the integer a. On return it receives the actual | ||
341 | * length of the data written on success or the data that would | ||
342 | * be written if buffer was too small. | ||
343 | * @sign: if not NULL, it will be set to the sign of a. | 243 | * @sign: if not NULL, it will be set to the sign of a. |
344 | * | 244 | * |
345 | * Return: 0 on success or error code in case of error | 245 | * Return: 0 on success or error code in case of error |
346 | */ | 246 | */ |
347 | int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned *nbytes, | 247 | int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned nbytes, |
348 | int *sign) | 248 | int *sign) |
349 | { | 249 | { |
350 | u8 *p, *p2; | 250 | u8 *p, *p2; |
@@ -356,55 +256,60 @@ int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned *nbytes, | |||
356 | #error please implement for this limb size. | 256 | #error please implement for this limb size. |
357 | #endif | 257 | #endif |
358 | unsigned int n = mpi_get_size(a); | 258 | unsigned int n = mpi_get_size(a); |
359 | int i, x, y = 0, lzeros, buf_len; | 259 | struct sg_mapping_iter miter; |
360 | 260 | int i, x, buf_len; | |
361 | if (!nbytes) | 261 | int nents; |
362 | return -EINVAL; | ||
363 | 262 | ||
364 | if (sign) | 263 | if (sign) |
365 | *sign = a->sign; | 264 | *sign = a->sign; |
366 | 265 | ||
367 | lzeros = count_lzeros(a); | 266 | if (nbytes < n) |
368 | |||
369 | if (*nbytes < n - lzeros) { | ||
370 | *nbytes = n - lzeros; | ||
371 | return -EOVERFLOW; | 267 | return -EOVERFLOW; |
372 | } | ||
373 | 268 | ||
374 | *nbytes = n - lzeros; | 269 | nents = sg_nents_for_len(sgl, nbytes); |
375 | buf_len = sgl->length; | 270 | if (nents < 0) |
376 | p2 = sg_virt(sgl); | 271 | return -EINVAL; |
377 | 272 | ||
378 | for (i = a->nlimbs - 1 - lzeros / BYTES_PER_MPI_LIMB, | 273 | sg_miter_start(&miter, sgl, nents, SG_MITER_ATOMIC | SG_MITER_TO_SG); |
379 | lzeros %= BYTES_PER_MPI_LIMB; | 274 | sg_miter_next(&miter); |
380 | i >= 0; i--) { | 275 | buf_len = miter.length; |
276 | p2 = miter.addr; | ||
277 | |||
278 | while (nbytes > n) { | ||
279 | i = min_t(unsigned, nbytes - n, buf_len); | ||
280 | memset(p2, 0, i); | ||
281 | p2 += 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 | } | ||
290 | } | ||
291 | |||
292 | for (i = a->nlimbs - 1; i >= 0; i--) { | ||
381 | #if BYTES_PER_MPI_LIMB == 4 | 293 | #if BYTES_PER_MPI_LIMB == 4 |
382 | alimb = cpu_to_be32(a->d[i]); | 294 | alimb = a->d[i] ? cpu_to_be32(a->d[i]) : 0; |
383 | #elif BYTES_PER_MPI_LIMB == 8 | 295 | #elif BYTES_PER_MPI_LIMB == 8 |
384 | alimb = cpu_to_be64(a->d[i]); | 296 | alimb = a->d[i] ? cpu_to_be64(a->d[i]) : 0; |
385 | #else | 297 | #else |
386 | #error please implement for this limb size. | 298 | #error please implement for this limb size. |
387 | #endif | 299 | #endif |
388 | if (lzeros) { | 300 | p = (u8 *)&alimb; |
389 | y = lzeros; | ||
390 | lzeros = 0; | ||
391 | } | ||
392 | 301 | ||
393 | p = (u8 *)&alimb + y; | 302 | for (x = 0; x < sizeof(alimb); x++) { |
394 | |||
395 | for (x = 0; x < sizeof(alimb) - y; x++) { | ||
396 | if (!buf_len) { | ||
397 | sgl = sg_next(sgl); | ||
398 | if (!sgl) | ||
399 | return -EINVAL; | ||
400 | buf_len = sgl->length; | ||
401 | p2 = sg_virt(sgl); | ||
402 | } | ||
403 | *p2++ = *p++; | 303 | *p2++ = *p++; |
404 | buf_len--; | 304 | if (!--buf_len) { |
305 | sg_miter_next(&miter); | ||
306 | buf_len = miter.length; | ||
307 | p2 = miter.addr; | ||
308 | } | ||
405 | } | 309 | } |
406 | y = 0; | ||
407 | } | 310 | } |
311 | |||
312 | sg_miter_stop(&miter); | ||
408 | return 0; | 313 | return 0; |
409 | } | 314 | } |
410 | EXPORT_SYMBOL_GPL(mpi_write_to_sgl); | 315 | EXPORT_SYMBOL_GPL(mpi_write_to_sgl); |
@@ -424,19 +329,23 @@ EXPORT_SYMBOL_GPL(mpi_write_to_sgl); | |||
424 | */ | 329 | */ |
425 | MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes) | 330 | MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes) |
426 | { | 331 | { |
427 | struct scatterlist *sg; | 332 | struct sg_mapping_iter miter; |
428 | int x, i, j, z, lzeros, ents; | ||
429 | unsigned int nbits, nlimbs; | 333 | unsigned int nbits, nlimbs; |
334 | int x, j, z, lzeros, ents; | ||
335 | unsigned int len; | ||
336 | const u8 *buff; | ||
430 | mpi_limb_t a; | 337 | mpi_limb_t a; |
431 | MPI val = NULL; | 338 | MPI val = NULL; |
432 | 339 | ||
433 | lzeros = 0; | 340 | ents = sg_nents_for_len(sgl, nbytes); |
434 | ents = sg_nents(sgl); | 341 | if (ents < 0) |
342 | return NULL; | ||
435 | 343 | ||
436 | for_each_sg(sgl, sg, ents, i) { | 344 | sg_miter_start(&miter, sgl, ents, SG_MITER_ATOMIC | SG_MITER_FROM_SG); |
437 | const u8 *buff = sg_virt(sg); | ||
438 | int len = sg->length; | ||
439 | 345 | ||
346 | lzeros = 0; | ||
347 | len = 0; | ||
348 | while (nbytes > 0) { | ||
440 | while (len && !*buff) { | 349 | while (len && !*buff) { |
441 | lzeros++; | 350 | lzeros++; |
442 | len--; | 351 | len--; |
@@ -446,12 +355,14 @@ MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes) | |||
446 | if (len && *buff) | 355 | if (len && *buff) |
447 | break; | 356 | break; |
448 | 357 | ||
449 | ents--; | 358 | sg_miter_next(&miter); |
359 | buff = miter.addr; | ||
360 | len = miter.length; | ||
361 | |||
450 | nbytes -= lzeros; | 362 | nbytes -= lzeros; |
451 | lzeros = 0; | 363 | lzeros = 0; |
452 | } | 364 | } |
453 | 365 | ||
454 | sgl = sg; | ||
455 | nbytes -= lzeros; | 366 | nbytes -= lzeros; |
456 | nbits = nbytes * 8; | 367 | nbits = nbytes * 8; |
457 | if (nbits > MAX_EXTERN_MPI_BITS) { | 368 | if (nbits > MAX_EXTERN_MPI_BITS) { |
@@ -460,8 +371,7 @@ MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes) | |||
460 | } | 371 | } |
461 | 372 | ||
462 | if (nbytes > 0) | 373 | if (nbytes > 0) |
463 | nbits -= count_leading_zeros(*(u8 *)(sg_virt(sgl) + lzeros)) - | 374 | nbits -= count_leading_zeros(*buff) - (BITS_PER_LONG - 8); |
464 | (BITS_PER_LONG - 8); | ||
465 | 375 | ||
466 | nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB); | 376 | nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB); |
467 | val = mpi_alloc(nlimbs); | 377 | val = mpi_alloc(nlimbs); |
@@ -480,21 +390,24 @@ MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes) | |||
480 | z = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB; | 390 | z = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB; |
481 | z %= BYTES_PER_MPI_LIMB; | 391 | z %= BYTES_PER_MPI_LIMB; |
482 | 392 | ||
483 | for_each_sg(sgl, sg, ents, i) { | 393 | for (;;) { |
484 | const u8 *buffer = sg_virt(sg) + lzeros; | ||
485 | int len = sg->length - lzeros; | ||
486 | |||
487 | for (x = 0; x < len; x++) { | 394 | for (x = 0; x < len; x++) { |
488 | a <<= 8; | 395 | a <<= 8; |
489 | a |= *buffer++; | 396 | a |= *buff++; |
490 | if (((z + x + 1) % BYTES_PER_MPI_LIMB) == 0) { | 397 | if (((z + x + 1) % BYTES_PER_MPI_LIMB) == 0) { |
491 | val->d[j--] = a; | 398 | val->d[j--] = a; |
492 | a = 0; | 399 | a = 0; |
493 | } | 400 | } |
494 | } | 401 | } |
495 | z += x; | 402 | z += x; |
496 | lzeros = 0; | 403 | |
404 | if (!sg_miter_next(&miter)) | ||
405 | break; | ||
406 | |||
407 | buff = miter.addr; | ||
408 | len = miter.length; | ||
497 | } | 409 | } |
410 | |||
498 | return val; | 411 | return val; |
499 | } | 412 | } |
500 | EXPORT_SYMBOL_GPL(mpi_read_raw_from_sgl); | 413 | EXPORT_SYMBOL_GPL(mpi_read_raw_from_sgl); |