Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Sep 2017 17:30:03 +0000 (10:30 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Sep 2017 17:30:03 +0000 (10:30 -0700)
Pull crypto fixes from Herbert Xu:
 "This fixes the following issues:

   - Regression in chacha20 handling of chunked input

   - Crash in algif_skcipher when used with async io

   - Potential bogus pointer dereference in lib/mpi"

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
  crypto: algif_skcipher - only call put_page on referenced and used pages
  crypto: testmgr - add chunked test cases for chacha20
  crypto: chacha20 - fix handling of chunked input
  lib/mpi: kunmap after finishing accessing buffer

crypto/algif_skcipher.c
crypto/chacha20_generic.c
crypto/testmgr.h
lib/mpi/mpicoder.c

index 43839b00fe6c42fff5f8afbc04ffdff4e61a147d..903605dbc1a50282e8e3d7ced0bba148ec7ebe9c 100644 (file)
@@ -87,8 +87,13 @@ static void skcipher_free_async_sgls(struct skcipher_async_req *sreq)
        }
        sgl = sreq->tsg;
        n = sg_nents(sgl);
-       for_each_sg(sgl, sg, n, i)
-               put_page(sg_page(sg));
+       for_each_sg(sgl, sg, n, i) {
+               struct page *page = sg_page(sg);
+
+               /* some SGs may not have a page mapped */
+               if (page && page_ref_count(page))
+                       put_page(page);
+       }
 
        kfree(sreq->tsg);
 }
index 8b3c04d625c3bb0ee667a8a61a0c1e4499b0b486..4a45fa4890c0e45eb74124d39b9fee35823ac4dd 100644 (file)
@@ -91,9 +91,14 @@ int crypto_chacha20_crypt(struct skcipher_request *req)
        crypto_chacha20_init(state, ctx, walk.iv);
 
        while (walk.nbytes > 0) {
+               unsigned int nbytes = walk.nbytes;
+
+               if (nbytes < walk.total)
+                       nbytes = round_down(nbytes, walk.stride);
+
                chacha20_docrypt(state, walk.dst.virt.addr, walk.src.virt.addr,
-                                walk.nbytes);
-               err = skcipher_walk_done(&walk, 0);
+                                nbytes);
+               err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
        }
 
        return err;
index 6ceb0e2758bbccd4f0542a5f9628e9f3e987ce7c..d54971d2d1c8694805bb8618b8673c8490f9e8bb 100644 (file)
@@ -32675,6 +32675,10 @@ static const struct cipher_testvec chacha20_enc_tv_template[] = {
                          "\x5b\x86\x2f\x37\x30\xe3\x7c\xfd"
                          "\xc4\xfd\x80\x6c\x22\xf2\x21",
                .rlen   = 375,
+               .also_non_np = 1,
+               .np     = 3,
+               .tap    = { 375 - 20, 4, 16 },
+
        }, { /* RFC7539 A.2. Test Vector #3 */
                .key    = "\x1c\x92\x40\xa5\xeb\x55\xd3\x8a"
                          "\xf3\x33\x88\x86\x04\xf6\xb5\xf0"
@@ -33049,6 +33053,9 @@ static const struct cipher_testvec chacha20_enc_tv_template[] = {
                          "\xa1\xed\xad\xd5\x76\xfa\x24\x8f"
                          "\x98",
                .rlen   = 1281,
+               .also_non_np = 1,
+               .np     = 3,
+               .tap    = { 1200, 1, 80 },
        },
 };
 
index 5a0f75a3bf01c1b259fb125fbe7266c186d83a71..eead4b339466854f51db30a17f17ee0472ebe6d3 100644 (file)
@@ -364,11 +364,11 @@ MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes)
        }
 
        miter.consumed = lzeros;
-       sg_miter_stop(&miter);
 
        nbytes -= lzeros;
        nbits = nbytes * 8;
        if (nbits > MAX_EXTERN_MPI_BITS) {
+               sg_miter_stop(&miter);
                pr_info("MPI: mpi too large (%u bits)\n", nbits);
                return NULL;
        }
@@ -376,6 +376,8 @@ MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes)
        if (nbytes > 0)
                nbits -= count_leading_zeros(*buff) - (BITS_PER_LONG - 8);
 
+       sg_miter_stop(&miter);
+
        nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB);
        val = mpi_alloc(nlimbs);
        if (!val)