Merge tag 'imx-fixes-3.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/shawngu...
[cascardo/linux.git] / crypto / testmgr.c
index ac2b631..29a0cbd 100644 (file)
@@ -178,9 +178,7 @@ static void testmgr_free_buf(char *buf[XBUFSIZE])
                free_page((unsigned long)buf[i]);
 }
 
-static int do_one_async_hash_op(struct ahash_request *req,
-                               struct tcrypt_result *tr,
-                               int ret)
+static int wait_async_op(struct tcrypt_result *tr, int ret)
 {
        if (ret == -EINPROGRESS || ret == -EBUSY) {
                ret = wait_for_completion_interruptible(&tr->completion);
@@ -264,30 +262,26 @@ static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
 
                ahash_request_set_crypt(req, sg, result, template[i].psize);
                if (use_digest) {
-                       ret = do_one_async_hash_op(req, &tresult,
-                                                  crypto_ahash_digest(req));
+                       ret = wait_async_op(&tresult, crypto_ahash_digest(req));
                        if (ret) {
                                pr_err("alg: hash: digest failed on test %d "
                                       "for %s: ret=%d\n", j, algo, -ret);
                                goto out;
                        }
                } else {
-                       ret = do_one_async_hash_op(req, &tresult,
-                                                  crypto_ahash_init(req));
+                       ret = wait_async_op(&tresult, crypto_ahash_init(req));
                        if (ret) {
                                pr_err("alt: hash: init failed on test %d "
                                       "for %s: ret=%d\n", j, algo, -ret);
                                goto out;
                        }
-                       ret = do_one_async_hash_op(req, &tresult,
-                                                  crypto_ahash_update(req));
+                       ret = wait_async_op(&tresult, crypto_ahash_update(req));
                        if (ret) {
                                pr_err("alt: hash: update failed on test %d "
                                       "for %s: ret=%d\n", j, algo, -ret);
                                goto out;
                        }
-                       ret = do_one_async_hash_op(req, &tresult,
-                                                  crypto_ahash_final(req));
+                       ret = wait_async_op(&tresult, crypto_ahash_final(req));
                        if (ret) {
                                pr_err("alt: hash: final failed on test %d "
                                       "for %s: ret=%d\n", j, algo, -ret);
@@ -311,78 +305,75 @@ static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
                if (align_offset != 0)
                        break;
 
-               if (template[i].np) {
-                       j++;
-                       memset(result, 0, MAX_DIGEST_SIZE);
+               if (!template[i].np)
+                       continue;
 
-                       temp = 0;
-                       sg_init_table(sg, template[i].np);
-                       ret = -EINVAL;
-                       for (k = 0; k < template[i].np; k++) {
-                               if (WARN_ON(offset_in_page(IDX[k]) +
-                                           template[i].tap[k] > PAGE_SIZE))
-                                       goto out;
-                               sg_set_buf(&sg[k],
-                                          memcpy(xbuf[IDX[k] >> PAGE_SHIFT] +
-                                                 offset_in_page(IDX[k]),
-                                                 template[i].plaintext + temp,
-                                                 template[i].tap[k]),
-                                          template[i].tap[k]);
-                               temp += template[i].tap[k];
-                       }
-
-                       if (template[i].ksize) {
-                               if (template[i].ksize > MAX_KEYLEN) {
-                                       pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n",
-                                              j, algo, template[i].ksize,
-                                              MAX_KEYLEN);
-                                       ret = -EINVAL;
-                                       goto out;
-                               }
-                               crypto_ahash_clear_flags(tfm, ~0);
-                               memcpy(key, template[i].key, template[i].ksize);
-                               ret = crypto_ahash_setkey(tfm, key,
-                                                         template[i].ksize);
-
-                               if (ret) {
-                                       printk(KERN_ERR "alg: hash: setkey "
-                                              "failed on chunking test %d "
-                                              "for %s: ret=%d\n", j, algo,
-                                              -ret);
-                                       goto out;
-                               }
-                       }
-
-                       ahash_request_set_crypt(req, sg, result,
-                                               template[i].psize);
-                       ret = crypto_ahash_digest(req);
-                       switch (ret) {
-                       case 0:
-                               break;
-                       case -EINPROGRESS:
-                       case -EBUSY:
-                               ret = wait_for_completion_interruptible(
-                                       &tresult.completion);
-                               if (!ret && !(ret = tresult.err)) {
-                                       reinit_completion(&tresult.completion);
-                                       break;
-                               }
-                               /* fall through */
-                       default:
-                               printk(KERN_ERR "alg: hash: digest failed "
-                                      "on chunking test %d for %s: "
-                                      "ret=%d\n", j, algo, -ret);
+               j++;
+               memset(result, 0, MAX_DIGEST_SIZE);
+
+               temp = 0;
+               sg_init_table(sg, template[i].np);
+               ret = -EINVAL;
+               for (k = 0; k < template[i].np; k++) {
+                       if (WARN_ON(offset_in_page(IDX[k]) +
+                                   template[i].tap[k] > PAGE_SIZE))
                                goto out;
-                       }
+                       sg_set_buf(&sg[k],
+                                  memcpy(xbuf[IDX[k] >> PAGE_SHIFT] +
+                                         offset_in_page(IDX[k]),
+                                         template[i].plaintext + temp,
+                                         template[i].tap[k]),
+                                  template[i].tap[k]);
+                       temp += template[i].tap[k];
+               }
 
-                       if (memcmp(result, template[i].digest,
-                                  crypto_ahash_digestsize(tfm))) {
-                               printk(KERN_ERR "alg: hash: Chunking test %d "
-                                      "failed for %s\n", j, algo);
-                               hexdump(result, crypto_ahash_digestsize(tfm));
+               if (template[i].ksize) {
+                       if (template[i].ksize > MAX_KEYLEN) {
+                               pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n",
+                                      j, algo, template[i].ksize, MAX_KEYLEN);
                                ret = -EINVAL;
                                goto out;
                        }
+                       crypto_ahash_clear_flags(tfm, ~0);
+                       memcpy(key, template[i].key, template[i].ksize);
+                       ret = crypto_ahash_setkey(tfm, key, template[i].ksize);
+
+                       if (ret) {
+                               printk(KERN_ERR "alg: hash: setkey "
+                                      "failed on chunking test %d "
+                                      "for %s: ret=%d\n", j, algo, -ret);
+                               goto out;
+                       }
+               }
+
+               ahash_request_set_crypt(req, sg, result, template[i].psize);
+               ret = crypto_ahash_digest(req);
+               switch (ret) {
+               case 0:
+                       break;
+               case -EINPROGRESS:
+               case -EBUSY:
+                       ret = wait_for_completion_interruptible(
+                               &tresult.completion);
+                       if (!ret && !(ret = tresult.err)) {
+                               reinit_completion(&tresult.completion);
+                               break;
+                       }
+                       /* fall through */
+               default:
+                       printk(KERN_ERR "alg: hash: digest failed "
+                              "on chunking test %d for %s: "
+                              "ret=%d\n", j, algo, -ret);
+                       goto out;
+               }
+
+               if (memcmp(result, template[i].digest,
+                          crypto_ahash_digestsize(tfm))) {
+                       printk(KERN_ERR "alg: hash: Chunking test %d "
+                              "failed for %s\n", j, algo);
+                       hexdump(result, crypto_ahash_digestsize(tfm));
+                       ret = -EINVAL;
+                       goto out;
                }
        }
 
@@ -492,121 +483,116 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
                                  tcrypt_complete, &result);
 
        for (i = 0, j = 0; i < tcount; i++) {
-               if (!template[i].np) {
-                       j++;
+               if (template[i].np)
+                       continue;
 
-                       /* some templates have no input data but they will
-                        * touch input
-                        */
-                       input = xbuf[0];
-                       input += align_offset;
-                       assoc = axbuf[0];
+               j++;
 
-                       ret = -EINVAL;
-                       if (WARN_ON(align_offset + template[i].ilen >
-                                   PAGE_SIZE || template[i].alen > PAGE_SIZE))
-                               goto out;
+               /* some templates have no input data but they will
+                * touch input
+                */
+               input = xbuf[0];
+               input += align_offset;
+               assoc = axbuf[0];
 
-                       memcpy(input, template[i].input, template[i].ilen);
-                       memcpy(assoc, template[i].assoc, template[i].alen);
-                       if (template[i].iv)
-                               memcpy(iv, template[i].iv, MAX_IVLEN);
-                       else
-                               memset(iv, 0, MAX_IVLEN);
+               ret = -EINVAL;
+               if (WARN_ON(align_offset + template[i].ilen >
+                           PAGE_SIZE || template[i].alen > PAGE_SIZE))
+                       goto out;
 
-                       crypto_aead_clear_flags(tfm, ~0);
-                       if (template[i].wk)
-                               crypto_aead_set_flags(
-                                       tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+               memcpy(input, template[i].input, template[i].ilen);
+               memcpy(assoc, template[i].assoc, template[i].alen);
+               if (template[i].iv)
+                       memcpy(iv, template[i].iv, MAX_IVLEN);
+               else
+                       memset(iv, 0, MAX_IVLEN);
 
-                       if (template[i].klen > MAX_KEYLEN) {
-                               pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n",
-                                      d, j, algo, template[i].klen,
-                                      MAX_KEYLEN);
-                               ret = -EINVAL;
-                               goto out;
-                       }
-                       memcpy(key, template[i].key, template[i].klen);
+               crypto_aead_clear_flags(tfm, ~0);
+               if (template[i].wk)
+                       crypto_aead_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
 
-                       ret = crypto_aead_setkey(tfm, key,
-                                                template[i].klen);
-                       if (!ret == template[i].fail) {
-                               pr_err("alg: aead%s: setkey failed on test %d for %s: flags=%x\n",
-                                      d, j, algo, crypto_aead_get_flags(tfm));
-                               goto out;
-                       } else if (ret)
-                               continue;
+               if (template[i].klen > MAX_KEYLEN) {
+                       pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n",
+                              d, j, algo, template[i].klen,
+                              MAX_KEYLEN);
+                       ret = -EINVAL;
+                       goto out;
+               }
+               memcpy(key, template[i].key, template[i].klen);
 
-                       authsize = abs(template[i].rlen - template[i].ilen);
-                       ret = crypto_aead_setauthsize(tfm, authsize);
-                       if (ret) {
-                               pr_err("alg: aead%s: Failed to set authsize to %u on test %d for %s\n",
-                                      d, authsize, j, algo);
-                               goto out;
-                       }
+               ret = crypto_aead_setkey(tfm, key, template[i].klen);
+               if (!ret == template[i].fail) {
+                       pr_err("alg: aead%s: setkey failed on test %d for %s: flags=%x\n",
+                              d, j, algo, crypto_aead_get_flags(tfm));
+                       goto out;
+               } else if (ret)
+                       continue;
 
-                       if (diff_dst) {
-                               output = xoutbuf[0];
-                               output += align_offset;
-                               sg_init_one(&sg[0], input, template[i].ilen);
-                               sg_init_one(&sgout[0], output,
-                                           template[i].rlen);
-                       } else {
-                               sg_init_one(&sg[0], input,
-                                           template[i].ilen +
-                                               (enc ? authsize : 0));
-                               output = input;
-                       }
+               authsize = abs(template[i].rlen - template[i].ilen);
+               ret = crypto_aead_setauthsize(tfm, authsize);
+               if (ret) {
+                       pr_err("alg: aead%s: Failed to set authsize to %u on test %d for %s\n",
+                              d, authsize, j, algo);
+                       goto out;
+               }
 
-                       sg_init_one(&asg[0], assoc, template[i].alen);
+               if (diff_dst) {
+                       output = xoutbuf[0];
+                       output += align_offset;
+                       sg_init_one(&sg[0], input, template[i].ilen);
+                       sg_init_one(&sgout[0], output, template[i].rlen);
+               } else {
+                       sg_init_one(&sg[0], input,
+                                   template[i].ilen + (enc ? authsize : 0));
+                       output = input;
+               }
 
-                       aead_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
-                                              template[i].ilen, iv);
+               sg_init_one(&asg[0], assoc, template[i].alen);
 
-                       aead_request_set_assoc(req, asg, template[i].alen);
+               aead_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
+                                      template[i].ilen, iv);
 
-                       ret = enc ?
-                               crypto_aead_encrypt(req) :
-                               crypto_aead_decrypt(req);
+               aead_request_set_assoc(req, asg, template[i].alen);
 
-                       switch (ret) {
-                       case 0:
-                               if (template[i].novrfy) {
-                                       /* verification was supposed to fail */
-                                       pr_err("alg: aead%s: %s failed on test %d for %s: ret was 0, expected -EBADMSG\n",
-                                              d, e, j, algo);
-                                       /* so really, we got a bad message */
-                                       ret = -EBADMSG;
-                                       goto out;
-                               }
-                               break;
-                       case -EINPROGRESS:
-                       case -EBUSY:
-                               ret = wait_for_completion_interruptible(
-                                       &result.completion);
-                               if (!ret && !(ret = result.err)) {
-                                       reinit_completion(&result.completion);
-                                       break;
-                               }
-                       case -EBADMSG:
-                               if (template[i].novrfy)
-                                       /* verification failure was expected */
-                                       continue;
-                               /* fall through */
-                       default:
-                               pr_err("alg: aead%s: %s failed on test %d for %s: ret=%d\n",
-                                      d, e, j, algo, -ret);
-                               goto out;
-                       }
+               ret = enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req);
 
-                       q = output;
-                       if (memcmp(q, template[i].result, template[i].rlen)) {
-                               pr_err("alg: aead%s: Test %d failed on %s for %s\n",
-                                      d, j, e, algo);
-                               hexdump(q, template[i].rlen);
-                               ret = -EINVAL;
+               switch (ret) {
+               case 0:
+                       if (template[i].novrfy) {
+                               /* verification was supposed to fail */
+                               pr_err("alg: aead%s: %s failed on test %d for %s: ret was 0, expected -EBADMSG\n",
+                                      d, e, j, algo);
+                               /* so really, we got a bad message */
+                               ret = -EBADMSG;
                                goto out;
                        }
+                       break;
+               case -EINPROGRESS:
+               case -EBUSY:
+                       ret = wait_for_completion_interruptible(
+                               &result.completion);
+                       if (!ret && !(ret = result.err)) {
+                               reinit_completion(&result.completion);
+                               break;
+                       }
+               case -EBADMSG:
+                       if (template[i].novrfy)
+                               /* verification failure was expected */
+                               continue;
+                       /* fall through */
+               default:
+                       pr_err("alg: aead%s: %s failed on test %d for %s: ret=%d\n",
+                              d, e, j, algo, -ret);
+                       goto out;
+               }
+
+               q = output;
+               if (memcmp(q, template[i].result, template[i].rlen)) {
+                       pr_err("alg: aead%s: Test %d failed on %s for %s\n",
+                              d, j, e, algo);
+                       hexdump(q, template[i].rlen);
+                       ret = -EINVAL;
+                       goto out;
                }
        }
 
@@ -615,191 +601,182 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
                if (align_offset != 0)
                        break;
 
-               if (template[i].np) {
-                       j++;
-
-                       if (template[i].iv)
-                               memcpy(iv, template[i].iv, MAX_IVLEN);
-                       else
-                               memset(iv, 0, MAX_IVLEN);
-
-                       crypto_aead_clear_flags(tfm, ~0);
-                       if (template[i].wk)
-                               crypto_aead_set_flags(
-                                       tfm, CRYPTO_TFM_REQ_WEAK_KEY);
-                       if (template[i].klen > MAX_KEYLEN) {
-                               pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n",
-                                      d, j, algo, template[i].klen,
-                                      MAX_KEYLEN);
-                               ret = -EINVAL;
-                               goto out;
-                       }
-                       memcpy(key, template[i].key, template[i].klen);
+               if (!template[i].np)
+                       continue;
 
-                       ret = crypto_aead_setkey(tfm, key, template[i].klen);
-                       if (!ret == template[i].fail) {
-                               pr_err("alg: aead%s: setkey failed on chunk test %d for %s: flags=%x\n",
-                                      d, j, algo, crypto_aead_get_flags(tfm));
-                               goto out;
-                       } else if (ret)
-                               continue;
+               j++;
 
-                       authsize = abs(template[i].rlen - template[i].ilen);
+               if (template[i].iv)
+                       memcpy(iv, template[i].iv, MAX_IVLEN);
+               else
+                       memset(iv, 0, MAX_IVLEN);
 
+               crypto_aead_clear_flags(tfm, ~0);
+               if (template[i].wk)
+                       crypto_aead_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+               if (template[i].klen > MAX_KEYLEN) {
+                       pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n",
+                              d, j, algo, template[i].klen, MAX_KEYLEN);
                        ret = -EINVAL;
-                       sg_init_table(sg, template[i].np);
-                       if (diff_dst)
-                               sg_init_table(sgout, template[i].np);
-                       for (k = 0, temp = 0; k < template[i].np; k++) {
-                               if (WARN_ON(offset_in_page(IDX[k]) +
-                                           template[i].tap[k] > PAGE_SIZE))
-                                       goto out;
-
-                               q = xbuf[IDX[k] >> PAGE_SHIFT] +
-                                   offset_in_page(IDX[k]);
+                       goto out;
+               }
+               memcpy(key, template[i].key, template[i].klen);
 
-                               memcpy(q, template[i].input + temp,
-                                      template[i].tap[k]);
+               ret = crypto_aead_setkey(tfm, key, template[i].klen);
+               if (!ret == template[i].fail) {
+                       pr_err("alg: aead%s: setkey failed on chunk test %d for %s: flags=%x\n",
+                              d, j, algo, crypto_aead_get_flags(tfm));
+                       goto out;
+               } else if (ret)
+                       continue;
 
-                               sg_set_buf(&sg[k], q, template[i].tap[k]);
+               authsize = abs(template[i].rlen - template[i].ilen);
 
-                               if (diff_dst) {
-                                       q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
-                                           offset_in_page(IDX[k]);
+               ret = -EINVAL;
+               sg_init_table(sg, template[i].np);
+               if (diff_dst)
+                       sg_init_table(sgout, template[i].np);
+               for (k = 0, temp = 0; k < template[i].np; k++) {
+                       if (WARN_ON(offset_in_page(IDX[k]) +
+                                   template[i].tap[k] > PAGE_SIZE))
+                               goto out;
 
-                                       memset(q, 0, template[i].tap[k]);
+                       q = xbuf[IDX[k] >> PAGE_SHIFT] + offset_in_page(IDX[k]);
+                       memcpy(q, template[i].input + temp, template[i].tap[k]);
+                       sg_set_buf(&sg[k], q, template[i].tap[k]);
 
-                                       sg_set_buf(&sgout[k], q,
-                                                  template[i].tap[k]);
-                               }
+                       if (diff_dst) {
+                               q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
+                                   offset_in_page(IDX[k]);
 
-                               n = template[i].tap[k];
-                               if (k == template[i].np - 1 && enc)
-                                       n += authsize;
-                               if (offset_in_page(q) + n < PAGE_SIZE)
-                                       q[n] = 0;
+                               memset(q, 0, template[i].tap[k]);
 
-                               temp += template[i].tap[k];
+                               sg_set_buf(&sgout[k], q, template[i].tap[k]);
                        }
 
-                       ret = crypto_aead_setauthsize(tfm, authsize);
-                       if (ret) {
-                               pr_err("alg: aead%s: Failed to set authsize to %u on chunk test %d for %s\n",
-                                      d, authsize, j, algo);
+                       n = template[i].tap[k];
+                       if (k == template[i].np - 1 && enc)
+                               n += authsize;
+                       if (offset_in_page(q) + n < PAGE_SIZE)
+                               q[n] = 0;
+
+                       temp += template[i].tap[k];
+               }
+
+               ret = crypto_aead_setauthsize(tfm, authsize);
+               if (ret) {
+                       pr_err("alg: aead%s: Failed to set authsize to %u on chunk test %d for %s\n",
+                              d, authsize, j, algo);
+                       goto out;
+               }
+
+               if (enc) {
+                       if (WARN_ON(sg[k - 1].offset +
+                                   sg[k - 1].length + authsize >
+                                   PAGE_SIZE)) {
+                               ret = -EINVAL;
                                goto out;
                        }
 
-                       if (enc) {
-                               if (WARN_ON(sg[k - 1].offset +
-                                           sg[k - 1].length + authsize >
-                                           PAGE_SIZE)) {
-                                       ret = -EINVAL;
-                                       goto out;
-                               }
+                       if (diff_dst)
+                               sgout[k - 1].length += authsize;
+                       else
+                               sg[k - 1].length += authsize;
+               }
 
-                               if (diff_dst)
-                                       sgout[k - 1].length += authsize;
-                               else
-                                       sg[k - 1].length += authsize;
+               sg_init_table(asg, template[i].anp);
+               ret = -EINVAL;
+               for (k = 0, temp = 0; k < template[i].anp; k++) {
+                       if (WARN_ON(offset_in_page(IDX[k]) +
+                                   template[i].atap[k] > PAGE_SIZE))
+                               goto out;
+                       sg_set_buf(&asg[k],
+                                  memcpy(axbuf[IDX[k] >> PAGE_SHIFT] +
+                                         offset_in_page(IDX[k]),
+                                         template[i].assoc + temp,
+                                         template[i].atap[k]),
+                                  template[i].atap[k]);
+                       temp += template[i].atap[k];
+               }
+
+               aead_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
+                                      template[i].ilen,
+                                      iv);
+
+               aead_request_set_assoc(req, asg, template[i].alen);
+
+               ret = enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req);
+
+               switch (ret) {
+               case 0:
+                       if (template[i].novrfy) {
+                               /* verification was supposed to fail */
+                               pr_err("alg: aead%s: %s failed on chunk test %d for %s: ret was 0, expected -EBADMSG\n",
+                                      d, e, j, algo);
+                               /* so really, we got a bad message */
+                               ret = -EBADMSG;
+                               goto out;
                        }
-
-                       sg_init_table(asg, template[i].anp);
-                       ret = -EINVAL;
-                       for (k = 0, temp = 0; k < template[i].anp; k++) {
-                               if (WARN_ON(offset_in_page(IDX[k]) +
-                                           template[i].atap[k] > PAGE_SIZE))
-                                       goto out;
-                               sg_set_buf(&asg[k],
-                                          memcpy(axbuf[IDX[k] >> PAGE_SHIFT] +
-                                                 offset_in_page(IDX[k]),
-                                                 template[i].assoc + temp,
-                                                 template[i].atap[k]),
-                                          template[i].atap[k]);
-                               temp += template[i].atap[k];
-                       }
-
-                       aead_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
-                                              template[i].ilen,
-                                              iv);
-
-                       aead_request_set_assoc(req, asg, template[i].alen);
-
-                       ret = enc ?
-                               crypto_aead_encrypt(req) :
-                               crypto_aead_decrypt(req);
-
-                       switch (ret) {
-                       case 0:
-                               if (template[i].novrfy) {
-                                       /* verification was supposed to fail */
-                                       pr_err("alg: aead%s: %s failed on chunk test %d for %s: ret was 0, expected -EBADMSG\n",
-                                              d, e, j, algo);
-                                       /* so really, we got a bad message */
-                                       ret = -EBADMSG;
-                                       goto out;
-                               }
+                       break;
+               case -EINPROGRESS:
+               case -EBUSY:
+                       ret = wait_for_completion_interruptible(
+                               &result.completion);
+                       if (!ret && !(ret = result.err)) {
+                               reinit_completion(&result.completion);
                                break;
-                       case -EINPROGRESS:
-                       case -EBUSY:
-                               ret = wait_for_completion_interruptible(
-                                       &result.completion);
-                               if (!ret && !(ret = result.err)) {
-                                       reinit_completion(&result.completion);
-                                       break;
-                               }
-                       case -EBADMSG:
-                               if (template[i].novrfy)
-                                       /* verification failure was expected */
-                                       continue;
-                               /* fall through */
-                       default:
-                               pr_err("alg: aead%s: %s failed on chunk test %d for %s: ret=%d\n",
-                                      d, e, j, algo, -ret);
-                               goto out;
                        }
+               case -EBADMSG:
+                       if (template[i].novrfy)
+                               /* verification failure was expected */
+                               continue;
+                       /* fall through */
+               default:
+                       pr_err("alg: aead%s: %s failed on chunk test %d for %s: ret=%d\n",
+                              d, e, j, algo, -ret);
+                       goto out;
+               }
 
-                       ret = -EINVAL;
-                       for (k = 0, temp = 0; k < template[i].np; k++) {
-                               if (diff_dst)
-                                       q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
-                                           offset_in_page(IDX[k]);
-                               else
-                                       q = xbuf[IDX[k] >> PAGE_SHIFT] +
-                                           offset_in_page(IDX[k]);
-
-                               n = template[i].tap[k];
-                               if (k == template[i].np - 1)
-                                       n += enc ? authsize : -authsize;
+               ret = -EINVAL;
+               for (k = 0, temp = 0; k < template[i].np; k++) {
+                       if (diff_dst)
+                               q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
+                                   offset_in_page(IDX[k]);
+                       else
+                               q = xbuf[IDX[k] >> PAGE_SHIFT] +
+                                   offset_in_page(IDX[k]);
 
-                               if (memcmp(q, template[i].result + temp, n)) {
-                                       pr_err("alg: aead%s: Chunk test %d failed on %s at page %u for %s\n",
-                                              d, j, e, k, algo);
-                                       hexdump(q, n);
-                                       goto out;
-                               }
+                       n = template[i].tap[k];
+                       if (k == template[i].np - 1)
+                               n += enc ? authsize : -authsize;
 
-                               q += n;
-                               if (k == template[i].np - 1 && !enc) {
-                                       if (!diff_dst &&
-                                               memcmp(q, template[i].input +
-                                                     temp + n, authsize))
-                                               n = authsize;
-                                       else
-                                               n = 0;
-                               } else {
-                                       for (n = 0; offset_in_page(q + n) &&
-                                                   q[n]; n++)
-                                               ;
-                               }
-                               if (n) {
-                                       pr_err("alg: aead%s: Result buffer corruption in chunk test %d on %s at page %u for %s: %u bytes:\n",
-                                              d, j, e, k, algo, n);
-                                       hexdump(q, n);
-                                       goto out;
-                               }
+                       if (memcmp(q, template[i].result + temp, n)) {
+                               pr_err("alg: aead%s: Chunk test %d failed on %s at page %u for %s\n",
+                                      d, j, e, k, algo);
+                               hexdump(q, n);
+                               goto out;
+                       }
 
-                               temp += template[i].tap[k];
+                       q += n;
+                       if (k == template[i].np - 1 && !enc) {
+                               if (!diff_dst &&
+                                       memcmp(q, template[i].input +
+                                             temp + n, authsize))
+                                       n = authsize;
+                               else
+                                       n = 0;
+                       } else {
+                               for (n = 0; offset_in_page(q + n) && q[n]; n++)
+                                       ;
+                       }
+                       if (n) {
+                               pr_err("alg: aead%s: Result buffer corruption in chunk test %d on %s at page %u for %s: %u bytes:\n",
+                                      d, j, e, k, algo, n);
+                               hexdump(q, n);
+                               goto out;
                        }
+
+                       temp += template[i].tap[k];
                }
        }
 
@@ -978,78 +955,73 @@ static int __test_skcipher(struct crypto_ablkcipher *tfm, int enc,
 
        j = 0;
        for (i = 0; i < tcount; i++) {
+               if (template[i].np && !template[i].also_non_np)
+                       continue;
+
                if (template[i].iv)
                        memcpy(iv, template[i].iv, MAX_IVLEN);
                else
                        memset(iv, 0, MAX_IVLEN);
 
-               if (!(template[i].np) || (template[i].also_non_np)) {
-                       j++;
+               j++;
+               ret = -EINVAL;
+               if (WARN_ON(align_offset + template[i].ilen > PAGE_SIZE))
+                       goto out;
 
-                       ret = -EINVAL;
-                       if (WARN_ON(align_offset + template[i].ilen >
-                                   PAGE_SIZE))
-                               goto out;
+               data = xbuf[0];
+               data += align_offset;
+               memcpy(data, template[i].input, template[i].ilen);
 
-                       data = xbuf[0];
-                       data += align_offset;
-                       memcpy(data, template[i].input, template[i].ilen);
-
-                       crypto_ablkcipher_clear_flags(tfm, ~0);
-                       if (template[i].wk)
-                               crypto_ablkcipher_set_flags(
-                                       tfm, CRYPTO_TFM_REQ_WEAK_KEY);
-
-                       ret = crypto_ablkcipher_setkey(tfm, template[i].key,
-                                                      template[i].klen);
-                       if (!ret == template[i].fail) {
-                               pr_err("alg: skcipher%s: setkey failed on test %d for %s: flags=%x\n",
-                                      d, j, algo,
-                                      crypto_ablkcipher_get_flags(tfm));
-                               goto out;
-                       } else if (ret)
-                               continue;
+               crypto_ablkcipher_clear_flags(tfm, ~0);
+               if (template[i].wk)
+                       crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
 
-                       sg_init_one(&sg[0], data, template[i].ilen);
-                       if (diff_dst) {
-                               data = xoutbuf[0];
-                               data += align_offset;
-                               sg_init_one(&sgout[0], data, template[i].ilen);
-                       }
+               ret = crypto_ablkcipher_setkey(tfm, template[i].key,
+                                              template[i].klen);
+               if (!ret == template[i].fail) {
+                       pr_err("alg: skcipher%s: setkey failed on test %d for %s: flags=%x\n",
+                              d, j, algo, crypto_ablkcipher_get_flags(tfm));
+                       goto out;
+               } else if (ret)
+                       continue;
+
+               sg_init_one(&sg[0], data, template[i].ilen);
+               if (diff_dst) {
+                       data = xoutbuf[0];
+                       data += align_offset;
+                       sg_init_one(&sgout[0], data, template[i].ilen);
+               }
 
-                       ablkcipher_request_set_crypt(req, sg,
-                                                    (diff_dst) ? sgout : sg,
-                                                    template[i].ilen, iv);
-                       ret = enc ?
-                               crypto_ablkcipher_encrypt(req) :
-                               crypto_ablkcipher_decrypt(req);
+               ablkcipher_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
+                                            template[i].ilen, iv);
+               ret = enc ? crypto_ablkcipher_encrypt(req) :
+                           crypto_ablkcipher_decrypt(req);
 
-                       switch (ret) {
-                       case 0:
+               switch (ret) {
+               case 0:
+                       break;
+               case -EINPROGRESS:
+               case -EBUSY:
+                       ret = wait_for_completion_interruptible(
+                               &result.completion);
+                       if (!ret && !((ret = result.err))) {
+                               reinit_completion(&result.completion);
                                break;
-                       case -EINPROGRESS:
-                       case -EBUSY:
-                               ret = wait_for_completion_interruptible(
-                                       &result.completion);
-                               if (!ret && !((ret = result.err))) {
-                                       reinit_completion(&result.completion);
-                                       break;
-                               }
-                               /* fall through */
-                       default:
-                               pr_err("alg: skcipher%s: %s failed on test %d for %s: ret=%d\n",
-                                      d, e, j, algo, -ret);
-                               goto out;
                        }
+                       /* fall through */
+               default:
+                       pr_err("alg: skcipher%s: %s failed on test %d for %s: ret=%d\n",
+                              d, e, j, algo, -ret);
+                       goto out;
+               }
 
-                       q = data;
-                       if (memcmp(q, template[i].result, template[i].rlen)) {
-                               pr_err("alg: skcipher%s: Test %d failed on %s for %s\n",
-                                      d, j, e, algo);
-                               hexdump(q, template[i].rlen);
-                               ret = -EINVAL;
-                               goto out;
-                       }
+               q = data;
+               if (memcmp(q, template[i].result, template[i].rlen)) {
+                       pr_err("alg: skcipher%s: Test %d failed on %s for %s\n",
+                              d, j, e, algo);
+                       hexdump(q, template[i].rlen);
+                       ret = -EINVAL;
+                       goto out;
                }
        }
 
@@ -1059,121 +1031,113 @@ static int __test_skcipher(struct crypto_ablkcipher *tfm, int enc,
                if (align_offset != 0)
                        break;
 
+               if (!template[i].np)
+                       continue;
+
                if (template[i].iv)
                        memcpy(iv, template[i].iv, MAX_IVLEN);
                else
                        memset(iv, 0, MAX_IVLEN);
 
-               if (template[i].np) {
-                       j++;
+               j++;
+               crypto_ablkcipher_clear_flags(tfm, ~0);
+               if (template[i].wk)
+                       crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
 
-                       crypto_ablkcipher_clear_flags(tfm, ~0);
-                       if (template[i].wk)
-                               crypto_ablkcipher_set_flags(
-                                       tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+               ret = crypto_ablkcipher_setkey(tfm, template[i].key,
+                                              template[i].klen);
+               if (!ret == template[i].fail) {
+                       pr_err("alg: skcipher%s: setkey failed on chunk test %d for %s: flags=%x\n",
+                              d, j, algo, crypto_ablkcipher_get_flags(tfm));
+                       goto out;
+               } else if (ret)
+                       continue;
 
-                       ret = crypto_ablkcipher_setkey(tfm, template[i].key,
-                                                      template[i].klen);
-                       if (!ret == template[i].fail) {
-                               pr_err("alg: skcipher%s: setkey failed on chunk test %d for %s: flags=%x\n",
-                                      d, j, algo,
-                                      crypto_ablkcipher_get_flags(tfm));
+               temp = 0;
+               ret = -EINVAL;
+               sg_init_table(sg, template[i].np);
+               if (diff_dst)
+                       sg_init_table(sgout, template[i].np);
+               for (k = 0; k < template[i].np; k++) {
+                       if (WARN_ON(offset_in_page(IDX[k]) +
+                                   template[i].tap[k] > PAGE_SIZE))
                                goto out;
-                       } else if (ret)
-                               continue;
 
-                       temp = 0;
-                       ret = -EINVAL;
-                       sg_init_table(sg, template[i].np);
-                       if (diff_dst)
-                               sg_init_table(sgout, template[i].np);
-                       for (k = 0; k < template[i].np; k++) {
-                               if (WARN_ON(offset_in_page(IDX[k]) +
-                                           template[i].tap[k] > PAGE_SIZE))
-                                       goto out;
+                       q = xbuf[IDX[k] >> PAGE_SHIFT] + offset_in_page(IDX[k]);
 
-                               q = xbuf[IDX[k] >> PAGE_SHIFT] +
+                       memcpy(q, template[i].input + temp, template[i].tap[k]);
+
+                       if (offset_in_page(q) + template[i].tap[k] < PAGE_SIZE)
+                               q[template[i].tap[k]] = 0;
+
+                       sg_set_buf(&sg[k], q, template[i].tap[k]);
+                       if (diff_dst) {
+                               q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
                                    offset_in_page(IDX[k]);
 
-                               memcpy(q, template[i].input + temp,
-                                      template[i].tap[k]);
+                               sg_set_buf(&sgout[k], q, template[i].tap[k]);
 
-                               if (offset_in_page(q) + template[i].tap[k] <
-                                   PAGE_SIZE)
+                               memset(q, 0, template[i].tap[k]);
+                               if (offset_in_page(q) +
+                                   template[i].tap[k] < PAGE_SIZE)
                                        q[template[i].tap[k]] = 0;
+                       }
 
-                               sg_set_buf(&sg[k], q, template[i].tap[k]);
-                               if (diff_dst) {
-                                       q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
-                                           offset_in_page(IDX[k]);
+                       temp += template[i].tap[k];
+               }
 
-                                       sg_set_buf(&sgout[k], q,
-                                                  template[i].tap[k]);
+               ablkcipher_request_set_crypt(req, sg, (diff_dst) ? sgout : sg,
+                                            template[i].ilen, iv);
 
-                                       memset(q, 0, template[i].tap[k]);
-                                       if (offset_in_page(q) +
-                                           template[i].tap[k] < PAGE_SIZE)
-                                               q[template[i].tap[k]] = 0;
-                               }
+               ret = enc ? crypto_ablkcipher_encrypt(req) :
+                           crypto_ablkcipher_decrypt(req);
 
-                               temp += template[i].tap[k];
+               switch (ret) {
+               case 0:
+                       break;
+               case -EINPROGRESS:
+               case -EBUSY:
+                       ret = wait_for_completion_interruptible(
+                                       &result.completion);
+                       if (!ret && !((ret = result.err))) {
+                               reinit_completion(&result.completion);
+                               break;
                        }
+                       /* fall through */
+               default:
+                       pr_err("alg: skcipher%s: %s failed on chunk test %d for %s: ret=%d\n",
+                              d, e, j, algo, -ret);
+                       goto out;
+               }
 
-                       ablkcipher_request_set_crypt(req, sg,
-                                       (diff_dst) ? sgout : sg,
-                                       template[i].ilen, iv);
-
-                       ret = enc ?
-                               crypto_ablkcipher_encrypt(req) :
-                               crypto_ablkcipher_decrypt(req);
+               temp = 0;
+               ret = -EINVAL;
+               for (k = 0; k < template[i].np; k++) {
+                       if (diff_dst)
+                               q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
+                                   offset_in_page(IDX[k]);
+                       else
+                               q = xbuf[IDX[k] >> PAGE_SHIFT] +
+                                   offset_in_page(IDX[k]);
 
-                       switch (ret) {
-                       case 0:
-                               break;
-                       case -EINPROGRESS:
-                       case -EBUSY:
-                               ret = wait_for_completion_interruptible(
-                                       &result.completion);
-                               if (!ret && !((ret = result.err))) {
-                                       reinit_completion(&result.completion);
-                                       break;
-                               }
-                               /* fall through */
-                       default:
-                               pr_err("alg: skcipher%s: %s failed on chunk test %d for %s: ret=%d\n",
-                                      d, e, j, algo, -ret);
+                       if (memcmp(q, template[i].result + temp,
+                                  template[i].tap[k])) {
+                               pr_err("alg: skcipher%s: Chunk test %d failed on %s at page %u for %s\n",
+                                      d, j, e, k, algo);
+                               hexdump(q, template[i].tap[k]);
                                goto out;
                        }
 
-                       temp = 0;
-                       ret = -EINVAL;
-                       for (k = 0; k < template[i].np; k++) {
-                               if (diff_dst)
-                                       q = xoutbuf[IDX[k] >> PAGE_SHIFT] +
-                                           offset_in_page(IDX[k]);
-                               else
-                                       q = xbuf[IDX[k] >> PAGE_SHIFT] +
-                                           offset_in_page(IDX[k]);
-
-                               if (memcmp(q, template[i].result + temp,
-                                          template[i].tap[k])) {
-                                       pr_err("alg: skcipher%s: Chunk test %d failed on %s at page %u for %s\n",
-                                              d, j, e, k, algo);
-                                       hexdump(q, template[i].tap[k]);
-                                       goto out;
-                               }
-
-                               q += template[i].tap[k];
-                               for (n = 0; offset_in_page(q + n) && q[n]; n++)
-                                       ;
-                               if (n) {
-                                       pr_err("alg: skcipher%s: Result buffer corruption in chunk test %d on %s at page %u for %s: %u bytes:\n",
-                                              d, j, e, k, algo, n);
-                                       hexdump(q, n);
-                                       goto out;
-                               }
-                               temp += template[i].tap[k];
+                       q += template[i].tap[k];
+                       for (n = 0; offset_in_page(q + n) && q[n]; n++)
+                               ;
+                       if (n) {
+                               pr_err("alg: skcipher%s: Result buffer corruption in chunk test %d on %s at page %u for %s: %u bytes:\n",
+                                      d, j, e, k, algo, n);
+                               hexdump(q, n);
+                               goto out;
                        }
+                       temp += template[i].tap[k];
                }
        }
 
@@ -1714,16 +1678,14 @@ static int alg_test_crc32c(const struct alg_test_desc *desc,
        }
 
        do {
-               struct {
-                       struct shash_desc shash;
-                       char ctx[crypto_shash_descsize(tfm)];
-               } sdesc;
+               SHASH_DESC_ON_STACK(shash, tfm);
+               u32 *ctx = (u32 *)shash_desc_ctx(shash);
 
-               sdesc.shash.tfm = tfm;
-               sdesc.shash.flags = 0;
+               shash->tfm = tfm;
+               shash->flags = 0;
 
-               *(u32 *)sdesc.ctx = le32_to_cpu(420553207);
-               err = crypto_shash_final(&sdesc.shash, (u8 *)&val);
+               *ctx = le32_to_cpu(420553207);
+               err = crypto_shash_final(shash, (u8 *)&val);
                if (err) {
                        printk(KERN_ERR "alg: crc32c: Operation failed for "
                               "%s: %d\n", driver, err);
@@ -3212,6 +3174,38 @@ static const struct alg_test_desc alg_test_descs[] = {
                                }
                        }
                }
+       }, {
+               .alg = "lz4",
+               .test = alg_test_comp,
+               .fips_allowed = 1,
+               .suite = {
+                       .comp = {
+                               .comp = {
+                                       .vecs = lz4_comp_tv_template,
+                                       .count = LZ4_COMP_TEST_VECTORS
+                               },
+                               .decomp = {
+                                       .vecs = lz4_decomp_tv_template,
+                                       .count = LZ4_DECOMP_TEST_VECTORS
+                               }
+                       }
+               }
+       }, {
+               .alg = "lz4hc",
+               .test = alg_test_comp,
+               .fips_allowed = 1,
+               .suite = {
+                       .comp = {
+                               .comp = {
+                                       .vecs = lz4hc_comp_tv_template,
+                                       .count = LZ4HC_COMP_TEST_VECTORS
+                               },
+                               .decomp = {
+                                       .vecs = lz4hc_decomp_tv_template,
+                                       .count = LZ4HC_DECOMP_TEST_VECTORS
+                               }
+                       }
+               }
        }, {
                .alg = "lzo",
                .test = alg_test_comp,