Merge tag 'gpio-v4.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux...
[deliverable/linux.git] / crypto / testmgr.c
index b86883aedca11a617ad2e19bafe646bfecac583a..c727fb0cb021595afcfee0d9df271f5558c5f16d 100644 (file)
 
 #include "internal.h"
 
+static bool notests;
+module_param(notests, bool, 0644);
+MODULE_PARM_DESC(notests, "disable crypto self-tests");
+
 #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
 
 /* a perfect nop */
@@ -1776,6 +1780,7 @@ static int alg_test_drbg(const struct alg_test_desc *desc, const char *driver,
 static int do_test_rsa(struct crypto_akcipher *tfm,
                       struct akcipher_testvec *vecs)
 {
+       char *xbuf[XBUFSIZE];
        struct akcipher_request *req;
        void *outbuf_enc = NULL;
        void *outbuf_dec = NULL;
@@ -1784,9 +1789,12 @@ static int do_test_rsa(struct crypto_akcipher *tfm,
        int err = -ENOMEM;
        struct scatterlist src, dst, src_tab[2];
 
+       if (testmgr_alloc_buf(xbuf))
+               return err;
+
        req = akcipher_request_alloc(tfm, GFP_KERNEL);
        if (!req)
-               return err;
+               goto free_xbuf;
 
        init_completion(&result.completion);
 
@@ -1804,9 +1812,14 @@ static int do_test_rsa(struct crypto_akcipher *tfm,
        if (!outbuf_enc)
                goto free_req;
 
+       if (WARN_ON(vecs->m_size > PAGE_SIZE))
+               goto free_all;
+
+       memcpy(xbuf[0], vecs->m, vecs->m_size);
+
        sg_init_table(src_tab, 2);
-       sg_set_buf(&src_tab[0], vecs->m, 8);
-       sg_set_buf(&src_tab[1], vecs->m + 8, vecs->m_size - 8);
+       sg_set_buf(&src_tab[0], xbuf[0], 8);
+       sg_set_buf(&src_tab[1], xbuf[0] + 8, vecs->m_size - 8);
        sg_init_one(&dst, outbuf_enc, out_len_max);
        akcipher_request_set_crypt(req, src_tab, &dst, vecs->m_size,
                                   out_len_max);
@@ -1825,7 +1838,7 @@ static int do_test_rsa(struct crypto_akcipher *tfm,
                goto free_all;
        }
        /* verify that encrypted message is equal to expected */
-       if (memcmp(vecs->c, sg_virt(req->dst), vecs->c_size)) {
+       if (memcmp(vecs->c, outbuf_enc, vecs->c_size)) {
                pr_err("alg: rsa: encrypt test failed. Invalid output\n");
                err = -EINVAL;
                goto free_all;
@@ -1840,7 +1853,13 @@ static int do_test_rsa(struct crypto_akcipher *tfm,
                err = -ENOMEM;
                goto free_all;
        }
-       sg_init_one(&src, vecs->c, vecs->c_size);
+
+       if (WARN_ON(vecs->c_size > PAGE_SIZE))
+               goto free_all;
+
+       memcpy(xbuf[0], vecs->c, vecs->c_size);
+
+       sg_init_one(&src, xbuf[0], vecs->c_size);
        sg_init_one(&dst, outbuf_dec, out_len_max);
        init_completion(&result.completion);
        akcipher_request_set_crypt(req, &src, &dst, vecs->c_size, out_len_max);
@@ -1867,6 +1886,8 @@ free_all:
        kfree(outbuf_enc);
 free_req:
        akcipher_request_free(req);
+free_xbuf:
+       testmgr_free_buf(xbuf);
        return err;
 }
 
@@ -3868,6 +3889,11 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
        int j;
        int rc;
 
+       if (!fips_enabled && notests) {
+               printk_once(KERN_INFO "alg: self-tests disabled\n");
+               return 0;
+       }
+
        alg_test_descs_check_order();
 
        if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
This page took 0.033677 seconds and 5 git commands to generate.