tracing/kprobes: Change trace_arg to probe_arg
[pandora-kernel.git] / crypto / testmgr.c
index 51bae62..e9e9d84 100644 (file)
@@ -180,11 +180,20 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
        ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
                                   tcrypt_complete, &tresult);
 
+       j = 0;
        for (i = 0; i < tcount; i++) {
+               if (template[i].np)
+                       continue;
+
+               j++;
                memset(result, 0, 64);
 
                hash_buff = xbuf[0];
 
+               ret = -EINVAL;
+               if (WARN_ON(template[i].psize > PAGE_SIZE))
+                       goto out;
+
                memcpy(hash_buff, template[i].plaintext, template[i].psize);
                sg_init_one(&sg[0], hash_buff, template[i].psize);
 
@@ -194,7 +203,7 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
                                                  template[i].ksize);
                        if (ret) {
                                printk(KERN_ERR "alg: hash: setkey failed on "
-                                      "test %d for %s: ret=%d\n", i + 1, algo,
+                                      "test %d for %s: ret=%d\n", j, algo,
                                       -ret);
                                goto out;
                        }
@@ -216,14 +225,14 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
                        /* fall through */
                default:
                        printk(KERN_ERR "alg: hash: digest failed on test %d "
-                              "for %s: ret=%d\n", i + 1, algo, -ret);
+                              "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: Test %d failed for %s\n",
-                              i + 1, algo);
+                              j, algo);
                        hexdump(result, crypto_ahash_digestsize(tfm));
                        ret = -EINVAL;
                        goto out;
@@ -238,7 +247,11 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
 
                        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]),
@@ -357,6 +370,11 @@ static int test_aead(struct crypto_aead *tfm, int enc,
                        input = xbuf[0];
                        assoc = axbuf[0];
 
+                       ret = -EINVAL;
+                       if (WARN_ON(template[i].ilen > PAGE_SIZE ||
+                                   template[i].alen > PAGE_SIZE))
+                               goto out;
+
                        memcpy(input, template[i].input, template[i].ilen);
                        memcpy(assoc, template[i].assoc, template[i].alen);
                        if (template[i].iv)
@@ -516,7 +534,11 @@ static int test_aead(struct crypto_aead *tfm, int enc,
                        }
 
                        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]),
@@ -650,6 +672,10 @@ static int test_cipher(struct crypto_cipher *tfm, int enc,
 
                j++;
 
+               ret = -EINVAL;
+               if (WARN_ON(template[i].ilen > PAGE_SIZE))
+                       goto out;
+
                data = xbuf[0];
                memcpy(data, template[i].input, template[i].ilen);
 
@@ -741,6 +767,10 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
                if (!(template[i].np)) {
                        j++;
 
+                       ret = -EINVAL;
+                       if (WARN_ON(template[i].ilen > PAGE_SIZE))
+                               goto out;
+
                        data = xbuf[0];
                        memcpy(data, template[i].input, template[i].ilen);
 
@@ -1002,24 +1032,25 @@ static int test_pcomp(struct crypto_pcomp *tfm,
        const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm));
        unsigned int i;
        char result[COMP_BUF_SIZE];
-       int error;
+       int res;
 
        for (i = 0; i < ctcount; i++) {
                struct comp_request req;
+               unsigned int produced = 0;
 
-               error = crypto_compress_setup(tfm, ctemplate[i].params,
-                                             ctemplate[i].paramsize);
-               if (error) {
+               res = crypto_compress_setup(tfm, ctemplate[i].params,
+                                           ctemplate[i].paramsize);
+               if (res) {
                        pr_err("alg: pcomp: compression setup failed on test "
-                              "%d for %s: error=%d\n", i + 1, algo, error);
-                       return error;
+                              "%d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
                }
 
-               error = crypto_compress_init(tfm);
-               if (error) {
+               res = crypto_compress_init(tfm);
+               if (res) {
                        pr_err("alg: pcomp: compression init failed on test "
-                              "%d for %s: error=%d\n", i + 1, algo, error);
-                       return error;
+                              "%d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
                }
 
                memset(result, 0, sizeof(result));
@@ -1029,32 +1060,37 @@ static int test_pcomp(struct crypto_pcomp *tfm,
                req.next_out = result;
                req.avail_out = ctemplate[i].outlen / 2;
 
-               error = crypto_compress_update(tfm, &req);
-               if (error && (error != -EAGAIN || req.avail_in)) {
+               res = crypto_compress_update(tfm, &req);
+               if (res < 0 && (res != -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;
+                              "%d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
                }
+               if (res > 0)
+                       produced += res;
 
                /* 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)) {
+               res = crypto_compress_update(tfm, &req);
+               if (res < 0 && (res != -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;
+                              "%d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
                }
+               if (res > 0)
+                       produced += res;
 
                /* Provide remaining output space */
                req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2;
 
-               error = crypto_compress_final(tfm, &req);
-               if (error) {
+               res = crypto_compress_final(tfm, &req);
+               if (res < 0) {
                        pr_err("alg: pcomp: compression final failed on test "
-                              "%d for %s: error=%d\n", i + 1, algo, error);
-                       return error;
+                              "%d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
                }
+               produced += res;
 
                if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) {
                        pr_err("alg: comp: Compression test %d failed for %s: "
@@ -1064,6 +1100,13 @@ static int test_pcomp(struct crypto_pcomp *tfm,
                        return -EINVAL;
                }
 
+               if (produced != ctemplate[i].outlen) {
+                       pr_err("alg: comp: Compression test %d failed for %s: "
+                              "returned len = %u (expected %d)\n", i + 1,
+                              algo, produced, 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);
@@ -1074,21 +1117,21 @@ static int test_pcomp(struct crypto_pcomp *tfm,
 
        for (i = 0; i < dtcount; i++) {
                struct comp_request req;
+               unsigned int produced = 0;
 
-               error = crypto_decompress_setup(tfm, dtemplate[i].params,
-                                               dtemplate[i].paramsize);
-               if (error) {
+               res = crypto_decompress_setup(tfm, dtemplate[i].params,
+                                             dtemplate[i].paramsize);
+               if (res) {
                        pr_err("alg: pcomp: decompression setup failed on "
-                              "test %d for %s: error=%d\n", i + 1, algo,
-                              error);
-                       return error;
+                              "test %d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
                }
 
-               error = crypto_decompress_init(tfm);
-               if (error) {
+               res = crypto_decompress_init(tfm);
+               if (res) {
                        pr_err("alg: pcomp: decompression init failed on test "
-                              "%d for %s: error=%d\n", i + 1, algo, error);
-                       return error;
+                              "%d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
                }
 
                memset(result, 0, sizeof(result));
@@ -1098,35 +1141,38 @@ static int test_pcomp(struct crypto_pcomp *tfm,
                req.next_out = result;
                req.avail_out = dtemplate[i].outlen / 2;
 
-               error = crypto_decompress_update(tfm, &req);
-               if (error  && (error != -EAGAIN || req.avail_in)) {
+               res = crypto_decompress_update(tfm, &req);
+               if (res < 0 && (res != -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;
+                              "test %d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
                }
+               if (res > 0)
+                       produced += res;
 
                /* 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)) {
+               res = crypto_decompress_update(tfm, &req);
+               if (res < 0 && (res != -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;
+                              "test %d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
                }
+               if (res > 0)
+                       produced += res;
 
                /* 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)) {
+               res = crypto_decompress_final(tfm, &req);
+               if (res < 0 && (res != -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;
+                              "test %d for %s: error=%d\n", i + 1, algo, res);
+                       return res;
                }
+               if (res > 0)
+                       produced += res;
 
                if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) {
                        pr_err("alg: comp: Decompression test %d failed for "
@@ -1136,6 +1182,13 @@ static int test_pcomp(struct crypto_pcomp *tfm,
                        return -EINVAL;
                }
 
+               if (produced != dtemplate[i].outlen) {
+                       pr_err("alg: comp: Decompression test %d failed for "
+                              "%s: returned len = %u (expected %d)\n", i + 1,
+                              algo, produced, 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);
@@ -2308,6 +2361,9 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
                if (i < 0)
                        goto notest;
 
+               if (fips_enabled && !alg_test_descs[i].fips_allowed)
+                       goto non_fips_alg;
+
                rc = alg_test_cipher(alg_test_descs + i, driver, type, mask);
                goto test_done;
        }
@@ -2316,6 +2372,9 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
        if (i < 0)
                goto notest;
 
+       if (fips_enabled && !alg_test_descs[i].fips_allowed)
+               goto non_fips_alg;
+
        rc = alg_test_descs[i].test(alg_test_descs + i, driver,
                                      type, mask);
 test_done:
@@ -2331,5 +2390,7 @@ test_done:
 notest:
        printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver);
        return 0;
+non_fips_alg:
+       return -EINVAL;
 }
 EXPORT_SYMBOL_GPL(alg_test);