diff options
Diffstat (limited to 'crypto/testmgr.c')
-rw-r--r-- | crypto/testmgr.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/crypto/testmgr.c b/crypto/testmgr.c index b773a563809b..ff79eb887fd0 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <crypto/rng.h> | 32 | #include <crypto/rng.h> |
33 | #include <crypto/drbg.h> | 33 | #include <crypto/drbg.h> |
34 | #include <crypto/akcipher.h> | 34 | #include <crypto/akcipher.h> |
35 | #include <crypto/kpp.h> | ||
35 | 36 | ||
36 | #include "internal.h" | 37 | #include "internal.h" |
37 | 38 | ||
@@ -120,6 +121,11 @@ struct akcipher_test_suite { | |||
120 | unsigned int count; | 121 | unsigned int count; |
121 | }; | 122 | }; |
122 | 123 | ||
124 | struct kpp_test_suite { | ||
125 | struct kpp_testvec *vecs; | ||
126 | unsigned int count; | ||
127 | }; | ||
128 | |||
123 | struct alg_test_desc { | 129 | struct alg_test_desc { |
124 | const char *alg; | 130 | const char *alg; |
125 | int (*test)(const struct alg_test_desc *desc, const char *driver, | 131 | int (*test)(const struct alg_test_desc *desc, const char *driver, |
@@ -134,6 +140,7 @@ struct alg_test_desc { | |||
134 | struct cprng_test_suite cprng; | 140 | struct cprng_test_suite cprng; |
135 | struct drbg_test_suite drbg; | 141 | struct drbg_test_suite drbg; |
136 | struct akcipher_test_suite akcipher; | 142 | struct akcipher_test_suite akcipher; |
143 | struct kpp_test_suite kpp; | ||
137 | } suite; | 144 | } suite; |
138 | }; | 145 | }; |
139 | 146 | ||
@@ -1777,6 +1784,133 @@ static int alg_test_drbg(const struct alg_test_desc *desc, const char *driver, | |||
1777 | 1784 | ||
1778 | } | 1785 | } |
1779 | 1786 | ||
1787 | static int do_test_kpp(struct crypto_kpp *tfm, struct kpp_testvec *vec, | ||
1788 | const char *alg) | ||
1789 | { | ||
1790 | struct kpp_request *req; | ||
1791 | void *input_buf = NULL; | ||
1792 | void *output_buf = NULL; | ||
1793 | struct tcrypt_result result; | ||
1794 | unsigned int out_len_max; | ||
1795 | int err = -ENOMEM; | ||
1796 | struct scatterlist src, dst; | ||
1797 | |||
1798 | req = kpp_request_alloc(tfm, GFP_KERNEL); | ||
1799 | if (!req) | ||
1800 | return err; | ||
1801 | |||
1802 | init_completion(&result.completion); | ||
1803 | |||
1804 | err = crypto_kpp_set_secret(tfm, vec->secret, vec->secret_size); | ||
1805 | if (err < 0) | ||
1806 | goto free_req; | ||
1807 | |||
1808 | out_len_max = crypto_kpp_maxsize(tfm); | ||
1809 | output_buf = kzalloc(out_len_max, GFP_KERNEL); | ||
1810 | if (!output_buf) { | ||
1811 | err = -ENOMEM; | ||
1812 | goto free_req; | ||
1813 | } | ||
1814 | |||
1815 | /* Use appropriate parameter as base */ | ||
1816 | kpp_request_set_input(req, NULL, 0); | ||
1817 | sg_init_one(&dst, output_buf, out_len_max); | ||
1818 | kpp_request_set_output(req, &dst, out_len_max); | ||
1819 | kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | ||
1820 | tcrypt_complete, &result); | ||
1821 | |||
1822 | /* Compute public key */ | ||
1823 | err = wait_async_op(&result, crypto_kpp_generate_public_key(req)); | ||
1824 | if (err) { | ||
1825 | pr_err("alg: %s: generate public key test failed. err %d\n", | ||
1826 | alg, err); | ||
1827 | goto free_output; | ||
1828 | } | ||
1829 | /* Verify calculated public key */ | ||
1830 | if (memcmp(vec->expected_a_public, sg_virt(req->dst), | ||
1831 | vec->expected_a_public_size)) { | ||
1832 | pr_err("alg: %s: generate public key test failed. Invalid output\n", | ||
1833 | alg); | ||
1834 | err = -EINVAL; | ||
1835 | goto free_output; | ||
1836 | } | ||
1837 | |||
1838 | /* Calculate shared secret key by using counter part (b) public key. */ | ||
1839 | input_buf = kzalloc(vec->b_public_size, GFP_KERNEL); | ||
1840 | if (!input_buf) { | ||
1841 | err = -ENOMEM; | ||
1842 | goto free_output; | ||
1843 | } | ||
1844 | |||
1845 | memcpy(input_buf, vec->b_public, vec->b_public_size); | ||
1846 | sg_init_one(&src, input_buf, vec->b_public_size); | ||
1847 | sg_init_one(&dst, output_buf, out_len_max); | ||
1848 | kpp_request_set_input(req, &src, vec->b_public_size); | ||
1849 | kpp_request_set_output(req, &dst, out_len_max); | ||
1850 | kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | ||
1851 | tcrypt_complete, &result); | ||
1852 | err = wait_async_op(&result, crypto_kpp_compute_shared_secret(req)); | ||
1853 | if (err) { | ||
1854 | pr_err("alg: %s: compute shard secret test failed. err %d\n", | ||
1855 | alg, err); | ||
1856 | goto free_all; | ||
1857 | } | ||
1858 | /* | ||
1859 | * verify shared secret from which the user will derive | ||
1860 | * secret key by executing whatever hash it has chosen | ||
1861 | */ | ||
1862 | if (memcmp(vec->expected_ss, sg_virt(req->dst), | ||
1863 | vec->expected_ss_size)) { | ||
1864 | pr_err("alg: %s: compute shared secret test failed. Invalid output\n", | ||
1865 | alg); | ||
1866 | err = -EINVAL; | ||
1867 | } | ||
1868 | |||
1869 | free_all: | ||
1870 | kfree(input_buf); | ||
1871 | free_output: | ||
1872 | kfree(output_buf); | ||
1873 | free_req: | ||
1874 | kpp_request_free(req); | ||
1875 | return err; | ||
1876 | } | ||
1877 | |||
1878 | static int test_kpp(struct crypto_kpp *tfm, const char *alg, | ||
1879 | struct kpp_testvec *vecs, unsigned int tcount) | ||
1880 | { | ||
1881 | int ret, i; | ||
1882 | |||
1883 | for (i = 0; i < tcount; i++) { | ||
1884 | ret = do_test_kpp(tfm, vecs++, alg); | ||
1885 | if (ret) { | ||
1886 | pr_err("alg: %s: test failed on vector %d, err=%d\n", | ||
1887 | alg, i + 1, ret); | ||
1888 | return ret; | ||
1889 | } | ||
1890 | } | ||
1891 | return 0; | ||
1892 | } | ||
1893 | |||
1894 | static int alg_test_kpp(const struct alg_test_desc *desc, const char *driver, | ||
1895 | u32 type, u32 mask) | ||
1896 | { | ||
1897 | struct crypto_kpp *tfm; | ||
1898 | int err = 0; | ||
1899 | |||
1900 | tfm = crypto_alloc_kpp(driver, type | CRYPTO_ALG_INTERNAL, mask); | ||
1901 | if (IS_ERR(tfm)) { | ||
1902 | pr_err("alg: kpp: Failed to load tfm for %s: %ld\n", | ||
1903 | driver, PTR_ERR(tfm)); | ||
1904 | return PTR_ERR(tfm); | ||
1905 | } | ||
1906 | if (desc->suite.kpp.vecs) | ||
1907 | err = test_kpp(tfm, desc->alg, desc->suite.kpp.vecs, | ||
1908 | desc->suite.kpp.count); | ||
1909 | |||
1910 | crypto_free_kpp(tfm); | ||
1911 | return err; | ||
1912 | } | ||
1913 | |||
1780 | static int do_test_rsa(struct crypto_akcipher *tfm, | 1914 | static int do_test_rsa(struct crypto_akcipher *tfm, |
1781 | struct akcipher_testvec *vecs) | 1915 | struct akcipher_testvec *vecs) |
1782 | { | 1916 | { |
@@ -2729,6 +2863,16 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
2729 | } | 2863 | } |
2730 | } | 2864 | } |
2731 | }, { | 2865 | }, { |
2866 | .alg = "dh", | ||
2867 | .test = alg_test_kpp, | ||
2868 | .fips_allowed = 1, | ||
2869 | .suite = { | ||
2870 | .kpp = { | ||
2871 | .vecs = dh_tv_template, | ||
2872 | .count = DH_TEST_VECTORS | ||
2873 | } | ||
2874 | } | ||
2875 | }, { | ||
2732 | .alg = "digest_null", | 2876 | .alg = "digest_null", |
2733 | .test = alg_test_null, | 2877 | .test = alg_test_null, |
2734 | }, { | 2878 | }, { |