dmaengine, async_tx: support alignment checks
[safe/jmp/linux-2.6] / crypto / testmgr.c
index e8666b3..b50c3c6 100644 (file)
@@ -72,6 +72,13 @@ struct comp_test_suite {
        } comp, decomp;
 };
 
+struct pcomp_test_suite {
+       struct {
+               struct pcomp_testvec *vecs;
+               unsigned int count;
+       } comp, decomp;
+};
+
 struct hash_test_suite {
        struct hash_testvec *vecs;
        unsigned int count;
@@ -86,6 +93,7 @@ struct alg_test_desc {
                struct aead_test_suite aead;
                struct cipher_test_suite cipher;
                struct comp_test_suite comp;
+               struct pcomp_test_suite pcomp;
                struct hash_test_suite hash;
        } suite;
 };
@@ -541,9 +549,74 @@ out:
        return ret;
 }
 
-static int test_cipher(struct crypto_ablkcipher *tfm, int enc,
+static int test_cipher(struct crypto_cipher *tfm, int enc,
                       struct cipher_testvec *template, unsigned int tcount)
 {
+       const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm));
+       unsigned int i, j, k;
+       int ret;
+       char *q;
+       const char *e;
+       void *data;
+
+       if (enc == ENCRYPT)
+               e = "encryption";
+       else
+               e = "decryption";
+
+       j = 0;
+       for (i = 0; i < tcount; i++) {
+               if (template[i].np)
+                       continue;
+
+               j++;
+
+               data = xbuf[0];
+               memcpy(data, template[i].input, template[i].ilen);
+
+               crypto_cipher_clear_flags(tfm, ~0);
+               if (template[i].wk)
+                       crypto_cipher_set_flags(tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+
+               ret = crypto_cipher_setkey(tfm, template[i].key,
+                                          template[i].klen);
+               if (!ret == template[i].fail) {
+                       printk(KERN_ERR "alg: cipher: setkey failed "
+                              "on test %d for %s: flags=%x\n", j,
+                              algo, crypto_cipher_get_flags(tfm));
+                       goto out;
+               } else if (ret)
+                       continue;
+
+               for (k = 0; k < template[i].ilen;
+                    k += crypto_cipher_blocksize(tfm)) {
+                       if (enc)
+                               crypto_cipher_encrypt_one(tfm, data + k,
+                                                         data + k);
+                       else
+                               crypto_cipher_decrypt_one(tfm, data + k,
+                                                         data + k);
+               }
+
+               q = data;
+               if (memcmp(q, template[i].result, template[i].rlen)) {
+                       printk(KERN_ERR "alg: cipher: Test %d failed "
+                              "on %s for %s\n", j, e, algo);
+                       hexdump(q, template[i].rlen);
+                       ret = -EINVAL;
+                       goto out;
+               }
+       }
+
+       ret = 0;
+
+out:
+       return ret;
+}
+
+static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
+                        struct cipher_testvec *template, unsigned int tcount)
+{
        const char *algo =
                crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm));
        unsigned int i, j, k, n, temp;
@@ -565,8 +638,8 @@ static int test_cipher(struct crypto_ablkcipher *tfm, int enc,
 
        req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
        if (!req) {
-               printk(KERN_ERR "alg: cipher: Failed to allocate request for "
-                      "%s\n", algo);
+               printk(KERN_ERR "alg: skcipher: Failed to allocate request "
+                      "for %s\n", algo);
                ret = -ENOMEM;
                goto out;
        }
@@ -595,7 +668,7 @@ static int test_cipher(struct crypto_ablkcipher *tfm, int enc,
                        ret = crypto_ablkcipher_setkey(tfm, template[i].key,
                                                       template[i].klen);
                        if (!ret == template[i].fail) {
-                               printk(KERN_ERR "alg: cipher: setkey failed "
+                               printk(KERN_ERR "alg: skcipher: setkey failed "
                                       "on test %d for %s: flags=%x\n", j,
                                       algo, crypto_ablkcipher_get_flags(tfm));
                                goto out;
@@ -623,7 +696,7 @@ static int test_cipher(struct crypto_ablkcipher *tfm, int enc,
                                }
                                /* fall through */
                        default:
-                               printk(KERN_ERR "alg: cipher: %s failed on "
+                               printk(KERN_ERR "alg: skcipher: %s failed on "
                                       "test %d for %s: ret=%d\n", e, j, algo,
                                       -ret);
                                goto out;
@@ -631,8 +704,8 @@ static int test_cipher(struct crypto_ablkcipher *tfm, int enc,
 
                        q = data;
                        if (memcmp(q, template[i].result, template[i].rlen)) {
-                               printk(KERN_ERR "alg: cipher: Test %d failed "
-                                      "on %s for %s\n", j, e, algo);
+                               printk(KERN_ERR "alg: skcipher: Test %d "
+                                      "failed on %s for %s\n", j, e, algo);
                                hexdump(q, template[i].rlen);
                                ret = -EINVAL;
                                goto out;
@@ -659,7 +732,7 @@ static int test_cipher(struct crypto_ablkcipher *tfm, int enc,
                        ret = crypto_ablkcipher_setkey(tfm, template[i].key,
                                                       template[i].klen);
                        if (!ret == template[i].fail) {
-                               printk(KERN_ERR "alg: cipher: setkey failed "
+                               printk(KERN_ERR "alg: skcipher: setkey failed "
                                       "on chunk test %d for %s: flags=%x\n",
                                       j, algo,
                                       crypto_ablkcipher_get_flags(tfm));
@@ -710,7 +783,7 @@ static int test_cipher(struct crypto_ablkcipher *tfm, int enc,
                                }
                                /* fall through */
                        default:
-                               printk(KERN_ERR "alg: cipher: %s failed on "
+                               printk(KERN_ERR "alg: skcipher: %s failed on "
                                       "chunk test %d for %s: ret=%d\n", e, j,
                                       algo, -ret);
                                goto out;
@@ -724,7 +797,7 @@ static int test_cipher(struct crypto_ablkcipher *tfm, int enc,
 
                                if (memcmp(q, template[i].result + temp,
                                           template[i].tap[k])) {
-                                       printk(KERN_ERR "alg: cipher: Chunk "
+                                       printk(KERN_ERR "alg: skcipher: Chunk "
                                               "test %d failed on %s at page "
                                               "%u for %s\n", j, e, k, algo);
                                        hexdump(q, template[i].tap[k]);
@@ -735,7 +808,7 @@ static int test_cipher(struct crypto_ablkcipher *tfm, int enc,
                                for (n = 0; offset_in_page(q + n) && q[n]; n++)
                                        ;
                                if (n) {
-                                       printk(KERN_ERR "alg: cipher: "
+                                       printk(KERN_ERR "alg: skcipher: "
                                               "Result buffer corruption in "
                                               "chunk test %d on %s at page "
                                               "%u for %s: %u bytes:\n", j, e,
@@ -778,6 +851,14 @@ static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
                        goto out;
                }
 
+               if (dlen != ctemplate[i].outlen) {
+                       printk(KERN_ERR "alg: comp: Compression test %d "
+                              "failed for %s: output len = %d\n", i + 1, algo,
+                              dlen);
+                       ret = -EINVAL;
+                       goto out;
+               }
+
                if (memcmp(result, ctemplate[i].output, dlen)) {
                        printk(KERN_ERR "alg: comp: Compression test %d "
                               "failed for %s\n", i + 1, algo);
@@ -788,7 +869,7 @@ static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
        }
 
        for (i = 0; i < dtcount; i++) {
-               int ilen, ret, dlen = COMP_BUF_SIZE;
+               int ilen, dlen = COMP_BUF_SIZE;
 
                memset(result, 0, sizeof (result));
 
@@ -802,6 +883,14 @@ static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
                        goto out;
                }
 
+               if (dlen != dtemplate[i].outlen) {
+                       printk(KERN_ERR "alg: comp: Decompression test %d "
+                              "failed for %s: output len = %d\n", i + 1, algo,
+                              dlen);
+                       ret = -EINVAL;
+                       goto out;
+               }
+
                if (memcmp(result, dtemplate[i].output, dlen)) {
                        printk(KERN_ERR "alg: comp: Decompression test %d "
                               "failed for %s\n", i + 1, algo);
@@ -817,6 +906,159 @@ out:
        return ret;
 }
 
+static int test_pcomp(struct crypto_pcomp *tfm,
+                     struct pcomp_testvec *ctemplate,
+                     struct pcomp_testvec *dtemplate, int ctcount,
+                     int dtcount)
+{
+       const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm));
+       unsigned int i;
+       char result[COMP_BUF_SIZE];
+       int error;
+
+       for (i = 0; i < ctcount; i++) {
+               struct comp_request req;
+
+               error = crypto_compress_setup(tfm, ctemplate[i].params,
+                                             ctemplate[i].paramsize);
+               if (error) {
+                       pr_err("alg: pcomp: compression setup failed on test "
+                              "%d for %s: error=%d\n", i + 1, algo, error);
+                       return error;
+               }
+
+               error = crypto_compress_init(tfm);
+               if (error) {
+                       pr_err("alg: pcomp: compression init failed on test "
+                              "%d for %s: error=%d\n", i + 1, algo, error);
+                       return error;
+               }
+
+               memset(result, 0, sizeof(result));
+
+               req.next_in = ctemplate[i].input;
+               req.avail_in = ctemplate[i].inlen / 2;
+               req.next_out = result;
+               req.avail_out = ctemplate[i].outlen / 2;
+
+               error = crypto_compress_update(tfm, &req);
+               if (error && (error != -EAGAIN || req.avail_in)) {
+                       pr_err("alg: pcomp: compression update failed on test "
+                              "%d for %s: error=%d\n", i + 1, algo, error);
+                       return error;
+               }
+
+               /* Add remaining input data */
+               req.avail_in += (ctemplate[i].inlen + 1) / 2;
+
+               error = crypto_compress_update(tfm, &req);
+               if (error && (error != -EAGAIN || req.avail_in)) {
+                       pr_err("alg: pcomp: compression update failed on test "
+                              "%d for %s: error=%d\n", i + 1, algo, error);
+                       return error;
+               }
+
+               /* Provide remaining output space */
+               req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2;
+
+               error = crypto_compress_final(tfm, &req);
+               if (error) {
+                       pr_err("alg: pcomp: compression final failed on test "
+                              "%d for %s: error=%d\n", i + 1, algo, error);
+                       return error;
+               }
+
+               if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) {
+                       pr_err("alg: comp: Compression test %d failed for %s: "
+                              "output len = %d (expected %d)\n", i + 1, algo,
+                              COMP_BUF_SIZE - req.avail_out,
+                              ctemplate[i].outlen);
+                       return -EINVAL;
+               }
+
+               if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) {
+                       pr_err("alg: pcomp: Compression test %d failed for "
+                              "%s\n", i + 1, algo);
+                       hexdump(result, ctemplate[i].outlen);
+                       return -EINVAL;
+               }
+       }
+
+       for (i = 0; i < dtcount; i++) {
+               struct comp_request req;
+
+               error = crypto_decompress_setup(tfm, dtemplate[i].params,
+                                               dtemplate[i].paramsize);
+               if (error) {
+                       pr_err("alg: pcomp: decompression setup failed on "
+                              "test %d for %s: error=%d\n", i + 1, algo,
+                              error);
+                       return error;
+               }
+
+               error = crypto_decompress_init(tfm);
+               if (error) {
+                       pr_err("alg: pcomp: decompression init failed on test "
+                              "%d for %s: error=%d\n", i + 1, algo, error);
+                       return error;
+               }
+
+               memset(result, 0, sizeof(result));
+
+               req.next_in = dtemplate[i].input;
+               req.avail_in = dtemplate[i].inlen / 2;
+               req.next_out = result;
+               req.avail_out = dtemplate[i].outlen / 2;
+
+               error = crypto_decompress_update(tfm, &req);
+               if (error  && (error != -EAGAIN || req.avail_in)) {
+                       pr_err("alg: pcomp: decompression update failed on "
+                              "test %d for %s: error=%d\n", i + 1, algo,
+                              error);
+                       return error;
+               }
+
+               /* Add remaining input data */
+               req.avail_in += (dtemplate[i].inlen + 1) / 2;
+
+               error = crypto_decompress_update(tfm, &req);
+               if (error  && (error != -EAGAIN || req.avail_in)) {
+                       pr_err("alg: pcomp: decompression update failed on "
+                              "test %d for %s: error=%d\n", i + 1, algo,
+                              error);
+                       return error;
+               }
+
+               /* Provide remaining output space */
+               req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2;
+
+               error = crypto_decompress_final(tfm, &req);
+               if (error  && (error != -EAGAIN || req.avail_in)) {
+                       pr_err("alg: pcomp: decompression final failed on "
+                              "test %d for %s: error=%d\n", i + 1, algo,
+                              error);
+                       return error;
+               }
+
+               if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) {
+                       pr_err("alg: comp: Decompression test %d failed for "
+                              "%s: output len = %d (expected %d)\n", i + 1,
+                              algo, COMP_BUF_SIZE - req.avail_out,
+                              dtemplate[i].outlen);
+                       return -EINVAL;
+               }
+
+               if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) {
+                       pr_err("alg: pcomp: Decompression test %d failed for "
+                              "%s\n", i + 1, algo);
+                       hexdump(result, dtemplate[i].outlen);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
 static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
                         u32 type, u32 mask)
 {
@@ -849,10 +1091,10 @@ out:
 static int alg_test_cipher(const struct alg_test_desc *desc,
                           const char *driver, u32 type, u32 mask)
 {
-       struct crypto_ablkcipher *tfm;
+       struct crypto_cipher *tfm;
        int err = 0;
 
-       tfm = crypto_alloc_ablkcipher(driver, type, mask);
+       tfm = crypto_alloc_cipher(driver, type, mask);
        if (IS_ERR(tfm)) {
                printk(KERN_ERR "alg: cipher: Failed to load transform for "
                       "%s: %ld\n", driver, PTR_ERR(tfm));
@@ -871,6 +1113,35 @@ static int alg_test_cipher(const struct alg_test_desc *desc,
                                  desc->suite.cipher.dec.count);
 
 out:
+       crypto_free_cipher(tfm);
+       return err;
+}
+
+static int alg_test_skcipher(const struct alg_test_desc *desc,
+                            const char *driver, u32 type, u32 mask)
+{
+       struct crypto_ablkcipher *tfm;
+       int err = 0;
+
+       tfm = crypto_alloc_ablkcipher(driver, type, mask);
+       if (IS_ERR(tfm)) {
+               printk(KERN_ERR "alg: skcipher: Failed to load transform for "
+                      "%s: %ld\n", driver, PTR_ERR(tfm));
+               return PTR_ERR(tfm);
+       }
+
+       if (desc->suite.cipher.enc.vecs) {
+               err = test_skcipher(tfm, ENCRYPT, desc->suite.cipher.enc.vecs,
+                                   desc->suite.cipher.enc.count);
+               if (err)
+                       goto out;
+       }
+
+       if (desc->suite.cipher.dec.vecs)
+               err = test_skcipher(tfm, DECRYPT, desc->suite.cipher.dec.vecs,
+                                   desc->suite.cipher.dec.count);
+
+out:
        crypto_free_ablkcipher(tfm);
        return err;
 }
@@ -897,6 +1168,28 @@ static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
        return err;
 }
 
+static int alg_test_pcomp(const struct alg_test_desc *desc, const char *driver,
+                         u32 type, u32 mask)
+{
+       struct crypto_pcomp *tfm;
+       int err;
+
+       tfm = crypto_alloc_pcomp(driver, type, mask);
+       if (IS_ERR(tfm)) {
+               pr_err("alg: pcomp: Failed to load transform for %s: %ld\n",
+                      driver, PTR_ERR(tfm));
+               return PTR_ERR(tfm);
+       }
+
+       err = test_pcomp(tfm, desc->suite.pcomp.comp.vecs,
+                        desc->suite.pcomp.decomp.vecs,
+                        desc->suite.pcomp.comp.count,
+                        desc->suite.pcomp.decomp.count);
+
+       crypto_free_pcomp(tfm);
+       return err;
+}
+
 static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
                         u32 type, u32 mask)
 {
@@ -916,11 +1209,60 @@ static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
        return err;
 }
 
+static int alg_test_crc32c(const struct alg_test_desc *desc,
+                          const char *driver, u32 type, u32 mask)
+{
+       struct crypto_shash *tfm;
+       u32 val;
+       int err;
+
+       err = alg_test_hash(desc, driver, type, mask);
+       if (err)
+               goto out;
+
+       tfm = crypto_alloc_shash(driver, type, mask);
+       if (IS_ERR(tfm)) {
+               printk(KERN_ERR "alg: crc32c: Failed to load transform for %s: "
+                      "%ld\n", driver, PTR_ERR(tfm));
+               err = PTR_ERR(tfm);
+               goto out;
+       }
+
+       do {
+               struct {
+                       struct shash_desc shash;
+                       char ctx[crypto_shash_descsize(tfm)];
+               } sdesc;
+
+               sdesc.shash.tfm = tfm;
+               sdesc.shash.flags = 0;
+
+               *(u32 *)sdesc.ctx = le32_to_cpu(420553207);
+               err = crypto_shash_final(&sdesc.shash, (u8 *)&val);
+               if (err) {
+                       printk(KERN_ERR "alg: crc32c: Operation failed for "
+                              "%s: %d\n", driver, err);
+                       break;
+               }
+
+               if (val != ~420553207) {
+                       printk(KERN_ERR "alg: crc32c: Test failed for %s: "
+                              "%d\n", driver, val);
+                       err = -EINVAL;
+               }
+       } while (0);
+
+       crypto_free_shash(tfm);
+
+out:
+       return err;
+}
+
 /* Please keep this list sorted by algorithm name. */
 static const struct alg_test_desc alg_test_descs[] = {
        {
                .alg = "cbc(aes)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -935,7 +1277,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "cbc(anubis)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -950,7 +1292,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "cbc(blowfish)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -965,7 +1307,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "cbc(camellia)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -980,7 +1322,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "cbc(des)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -995,7 +1337,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "cbc(des3_ede)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1010,7 +1352,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "cbc(twofish)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1040,7 +1382,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "crc32c",
-               .test = alg_test_hash,
+               .test = alg_test_crc32c,
                .suite = {
                        .hash = {
                                .vecs = crc32c_tv_template,
@@ -1049,7 +1391,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "cts(cbc(aes))",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1079,7 +1421,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecb(aes)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1094,7 +1436,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecb(anubis)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1109,7 +1451,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecb(arc4)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1124,7 +1466,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecb(blowfish)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1139,7 +1481,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecb(camellia)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1154,7 +1496,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecb(cast5)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1169,7 +1511,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecb(cast6)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1184,7 +1526,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecb(des)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1199,7 +1541,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecb(des3_ede)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1214,7 +1556,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecb(khazad)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1229,7 +1571,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecb(seed)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1244,7 +1586,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecb(serpent)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1259,7 +1601,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecb(tea)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1274,7 +1616,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecb(tnepres)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1289,7 +1631,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecb(twofish)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1304,7 +1646,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecb(xeta)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1319,7 +1661,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "ecb(xtea)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1421,7 +1763,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "lrw(aes)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1478,7 +1820,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "pcbc(fcrypt)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1493,7 +1835,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "rfc3686(ctr(aes))",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1544,7 +1886,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "salsa20",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1663,7 +2005,7 @@ static const struct alg_test_desc alg_test_descs[] = {
                }
        }, {
                .alg = "xts(aes)",
-               .test = alg_test_cipher,
+               .test = alg_test_skcipher,
                .suite = {
                        .cipher = {
                                .enc = {
@@ -1676,10 +2018,25 @@ static const struct alg_test_desc alg_test_descs[] = {
                                }
                        }
                }
+       }, {
+               .alg = "zlib",
+               .test = alg_test_pcomp,
+               .suite = {
+                       .pcomp = {
+                               .comp = {
+                                       .vecs = zlib_comp_tv_template,
+                                       .count = ZLIB_COMP_TEST_VECTORS
+                               },
+                               .decomp = {
+                                       .vecs = zlib_decomp_tv_template,
+                                       .count = ZLIB_DECOMP_TEST_VECTORS
+                               }
+                       }
+               }
        }
 };
 
-int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
+static int alg_find_test(const char *alg)
 {
        int start = 0;
        int end = ARRAY_SIZE(alg_test_descs);
@@ -1698,10 +2055,43 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
                        continue;
                }
 
-               return alg_test_descs[i].test(alg_test_descs + i, driver,
-                                             type, mask);
+               return i;
+       }
+
+       return -1;
+}
+
+int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
+{
+       int i;
+       int rc;
+
+       if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
+               char nalg[CRYPTO_MAX_ALG_NAME];
+
+               if (snprintf(nalg, sizeof(nalg), "ecb(%s)", alg) >=
+                   sizeof(nalg))
+                       return -ENAMETOOLONG;
+
+               i = alg_find_test(nalg);
+               if (i < 0)
+                       goto notest;
+
+               return alg_test_cipher(alg_test_descs + i, driver, type, mask);
        }
 
+       i = alg_find_test(alg);
+       if (i < 0)
+               goto notest;
+
+       rc = alg_test_descs[i].test(alg_test_descs + i, driver,
+                                     type, mask);
+       if (fips_enabled && rc)
+               panic("%s: %s alg self test failed in fips mode!\n", driver, alg);
+
+       return rc;
+
+notest:
        printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver);
        return 0;
 }