summaryrefslogtreecommitdiffstats
path: root/crypto/testmgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/testmgr.c')
-rw-r--r--crypto/testmgr.c197
1 files changed, 197 insertions, 0 deletions
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index cafeba6ba16c..fe0cdf162d99 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -2124,6 +2124,186 @@ static int test_skcipher_vec(const char *driver, int enc,
2124 return 0; 2124 return 0;
2125} 2125}
2126 2126
2127#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
2128/*
2129 * Generate a symmetric cipher test vector from the given implementation.
2130 * Assumes the buffers in 'vec' were already allocated.
2131 */
2132static void generate_random_cipher_testvec(struct skcipher_request *req,
2133 struct cipher_testvec *vec,
2134 unsigned int maxdatasize,
2135 char *name, size_t max_namelen)
2136{
2137 struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
2138 const unsigned int maxkeysize = tfm->keysize;
2139 const unsigned int ivsize = crypto_skcipher_ivsize(tfm);
2140 struct scatterlist src, dst;
2141 u8 iv[MAX_IVLEN];
2142 DECLARE_CRYPTO_WAIT(wait);
2143
2144 /* Key: length in [0, maxkeysize], but usually choose maxkeysize */
2145 vec->klen = maxkeysize;
2146 if (prandom_u32() % 4 == 0)
2147 vec->klen = prandom_u32() % (maxkeysize + 1);
2148 generate_random_bytes((u8 *)vec->key, vec->klen);
2149 vec->setkey_error = crypto_skcipher_setkey(tfm, vec->key, vec->klen);
2150
2151 /* IV */
2152 generate_random_bytes((u8 *)vec->iv, ivsize);
2153
2154 /* Plaintext */
2155 vec->len = generate_random_length(maxdatasize);
2156 generate_random_bytes((u8 *)vec->ptext, vec->len);
2157
2158 /* If the key couldn't be set, no need to continue to encrypt. */
2159 if (vec->setkey_error)
2160 goto done;
2161
2162 /* Ciphertext */
2163 sg_init_one(&src, vec->ptext, vec->len);
2164 sg_init_one(&dst, vec->ctext, vec->len);
2165 memcpy(iv, vec->iv, ivsize);
2166 skcipher_request_set_callback(req, 0, crypto_req_done, &wait);
2167 skcipher_request_set_crypt(req, &src, &dst, vec->len, iv);
2168 vec->crypt_error = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
2169done:
2170 snprintf(name, max_namelen, "\"random: len=%u klen=%u\"",
2171 vec->len, vec->klen);
2172}
2173
2174/*
2175 * Test the skcipher algorithm represented by @req against the corresponding
2176 * generic implementation, if one is available.
2177 */
2178static int test_skcipher_vs_generic_impl(const char *driver,
2179 const char *generic_driver,
2180 struct skcipher_request *req,
2181 struct cipher_test_sglists *tsgls)
2182{
2183 struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
2184 const unsigned int ivsize = crypto_skcipher_ivsize(tfm);
2185 const unsigned int blocksize = crypto_skcipher_blocksize(tfm);
2186 const unsigned int maxdatasize = (2 * PAGE_SIZE) - TESTMGR_POISON_LEN;
2187 const char *algname = crypto_skcipher_alg(tfm)->base.cra_name;
2188 char _generic_driver[CRYPTO_MAX_ALG_NAME];
2189 struct crypto_skcipher *generic_tfm = NULL;
2190 struct skcipher_request *generic_req = NULL;
2191 unsigned int i;
2192 struct cipher_testvec vec = { 0 };
2193 char vec_name[64];
2194 struct testvec_config cfg;
2195 char cfgname[TESTVEC_CONFIG_NAMELEN];
2196 int err;
2197
2198 if (noextratests)
2199 return 0;
2200
2201 /* Keywrap isn't supported here yet as it handles its IV differently. */
2202 if (strncmp(algname, "kw(", 3) == 0)
2203 return 0;
2204
2205 if (!generic_driver) { /* Use default naming convention? */
2206 err = build_generic_driver_name(algname, _generic_driver);
2207 if (err)
2208 return err;
2209 generic_driver = _generic_driver;
2210 }
2211
2212 if (strcmp(generic_driver, driver) == 0) /* Already the generic impl? */
2213 return 0;
2214
2215 generic_tfm = crypto_alloc_skcipher(generic_driver, 0, 0);
2216 if (IS_ERR(generic_tfm)) {
2217 err = PTR_ERR(generic_tfm);
2218 if (err == -ENOENT) {
2219 pr_warn("alg: skcipher: skipping comparison tests for %s because %s is unavailable\n",
2220 driver, generic_driver);
2221 return 0;
2222 }
2223 pr_err("alg: skcipher: error allocating %s (generic impl of %s): %d\n",
2224 generic_driver, algname, err);
2225 return err;
2226 }
2227
2228 generic_req = skcipher_request_alloc(generic_tfm, GFP_KERNEL);
2229 if (!generic_req) {
2230 err = -ENOMEM;
2231 goto out;
2232 }
2233
2234 /* Check the algorithm properties for consistency. */
2235
2236 if (tfm->keysize != generic_tfm->keysize) {
2237 pr_err("alg: skcipher: max keysize for %s (%u) doesn't match generic impl (%u)\n",
2238 driver, tfm->keysize, generic_tfm->keysize);
2239 err = -EINVAL;
2240 goto out;
2241 }
2242
2243 if (ivsize != crypto_skcipher_ivsize(generic_tfm)) {
2244 pr_err("alg: skcipher: ivsize for %s (%u) doesn't match generic impl (%u)\n",
2245 driver, ivsize, crypto_skcipher_ivsize(generic_tfm));
2246 err = -EINVAL;
2247 goto out;
2248 }
2249
2250 if (blocksize != crypto_skcipher_blocksize(generic_tfm)) {
2251 pr_err("alg: skcipher: blocksize for %s (%u) doesn't match generic impl (%u)\n",
2252 driver, blocksize,
2253 crypto_skcipher_blocksize(generic_tfm));
2254 err = -EINVAL;
2255 goto out;
2256 }
2257
2258 /*
2259 * Now generate test vectors using the generic implementation, and test
2260 * the other implementation against them.
2261 */
2262
2263 vec.key = kmalloc(tfm->keysize, GFP_KERNEL);
2264 vec.iv = kmalloc(ivsize, GFP_KERNEL);
2265 vec.ptext = kmalloc(maxdatasize, GFP_KERNEL);
2266 vec.ctext = kmalloc(maxdatasize, GFP_KERNEL);
2267 if (!vec.key || !vec.iv || !vec.ptext || !vec.ctext) {
2268 err = -ENOMEM;
2269 goto out;
2270 }
2271
2272 for (i = 0; i < fuzz_iterations * 8; i++) {
2273 generate_random_cipher_testvec(generic_req, &vec, maxdatasize,
2274 vec_name, sizeof(vec_name));
2275 generate_random_testvec_config(&cfg, cfgname, sizeof(cfgname));
2276
2277 err = test_skcipher_vec_cfg(driver, ENCRYPT, &vec, vec_name,
2278 &cfg, req, tsgls);
2279 if (err)
2280 goto out;
2281 err = test_skcipher_vec_cfg(driver, DECRYPT, &vec, vec_name,
2282 &cfg, req, tsgls);
2283 if (err)
2284 goto out;
2285 cond_resched();
2286 }
2287 err = 0;
2288out:
2289 kfree(vec.key);
2290 kfree(vec.iv);
2291 kfree(vec.ptext);
2292 kfree(vec.ctext);
2293 crypto_free_skcipher(generic_tfm);
2294 skcipher_request_free(generic_req);
2295 return err;
2296}
2297#else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
2298static int test_skcipher_vs_generic_impl(const char *driver,
2299 const char *generic_driver,
2300 struct skcipher_request *req,
2301 struct cipher_test_sglists *tsgls)
2302{
2303 return 0;
2304}
2305#endif /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
2306
2127static int test_skcipher(const char *driver, int enc, 2307static int test_skcipher(const char *driver, int enc,
2128 const struct cipher_test_suite *suite, 2308 const struct cipher_test_suite *suite,
2129 struct skcipher_request *req, 2309 struct skcipher_request *req,
@@ -2183,6 +2363,11 @@ static int alg_test_skcipher(const struct alg_test_desc *desc,
2183 goto out; 2363 goto out;
2184 2364
2185 err = test_skcipher(driver, DECRYPT, suite, req, tsgls); 2365 err = test_skcipher(driver, DECRYPT, suite, req, tsgls);
2366 if (err)
2367 goto out;
2368
2369 err = test_skcipher_vs_generic_impl(driver, desc->generic_driver, req,
2370 tsgls);
2186out: 2371out:
2187 free_cipher_test_sglists(tsgls); 2372 free_cipher_test_sglists(tsgls);
2188 skcipher_request_free(req); 2373 skcipher_request_free(req);
@@ -3164,12 +3349,14 @@ static int alg_test_null(const struct alg_test_desc *desc,
3164static const struct alg_test_desc alg_test_descs[] = { 3349static const struct alg_test_desc alg_test_descs[] = {
3165 { 3350 {
3166 .alg = "adiantum(xchacha12,aes)", 3351 .alg = "adiantum(xchacha12,aes)",
3352 .generic_driver = "adiantum(xchacha12-generic,aes-generic,nhpoly1305-generic)",
3167 .test = alg_test_skcipher, 3353 .test = alg_test_skcipher,
3168 .suite = { 3354 .suite = {
3169 .cipher = __VECS(adiantum_xchacha12_aes_tv_template) 3355 .cipher = __VECS(adiantum_xchacha12_aes_tv_template)
3170 }, 3356 },
3171 }, { 3357 }, {
3172 .alg = "adiantum(xchacha20,aes)", 3358 .alg = "adiantum(xchacha20,aes)",
3359 .generic_driver = "adiantum(xchacha20-generic,aes-generic,nhpoly1305-generic)",
3173 .test = alg_test_skcipher, 3360 .test = alg_test_skcipher,
3174 .suite = { 3361 .suite = {
3175 .cipher = __VECS(adiantum_xchacha20_aes_tv_template) 3362 .cipher = __VECS(adiantum_xchacha20_aes_tv_template)
@@ -3948,30 +4135,35 @@ static const struct alg_test_desc alg_test_descs[] = {
3948 } 4135 }
3949 }, { 4136 }, {
3950 .alg = "lrw(aes)", 4137 .alg = "lrw(aes)",
4138 .generic_driver = "lrw(ecb(aes-generic))",
3951 .test = alg_test_skcipher, 4139 .test = alg_test_skcipher,
3952 .suite = { 4140 .suite = {
3953 .cipher = __VECS(aes_lrw_tv_template) 4141 .cipher = __VECS(aes_lrw_tv_template)
3954 } 4142 }
3955 }, { 4143 }, {
3956 .alg = "lrw(camellia)", 4144 .alg = "lrw(camellia)",
4145 .generic_driver = "lrw(ecb(camellia-generic))",
3957 .test = alg_test_skcipher, 4146 .test = alg_test_skcipher,
3958 .suite = { 4147 .suite = {
3959 .cipher = __VECS(camellia_lrw_tv_template) 4148 .cipher = __VECS(camellia_lrw_tv_template)
3960 } 4149 }
3961 }, { 4150 }, {
3962 .alg = "lrw(cast6)", 4151 .alg = "lrw(cast6)",
4152 .generic_driver = "lrw(ecb(cast6-generic))",
3963 .test = alg_test_skcipher, 4153 .test = alg_test_skcipher,
3964 .suite = { 4154 .suite = {
3965 .cipher = __VECS(cast6_lrw_tv_template) 4155 .cipher = __VECS(cast6_lrw_tv_template)
3966 } 4156 }
3967 }, { 4157 }, {
3968 .alg = "lrw(serpent)", 4158 .alg = "lrw(serpent)",
4159 .generic_driver = "lrw(ecb(serpent-generic))",
3969 .test = alg_test_skcipher, 4160 .test = alg_test_skcipher,
3970 .suite = { 4161 .suite = {
3971 .cipher = __VECS(serpent_lrw_tv_template) 4162 .cipher = __VECS(serpent_lrw_tv_template)
3972 } 4163 }
3973 }, { 4164 }, {
3974 .alg = "lrw(twofish)", 4165 .alg = "lrw(twofish)",
4166 .generic_driver = "lrw(ecb(twofish-generic))",
3975 .test = alg_test_skcipher, 4167 .test = alg_test_skcipher,
3976 .suite = { 4168 .suite = {
3977 .cipher = __VECS(tf_lrw_tv_template) 4169 .cipher = __VECS(tf_lrw_tv_template)
@@ -4306,6 +4498,7 @@ static const struct alg_test_desc alg_test_descs[] = {
4306 }, 4498 },
4307 }, { 4499 }, {
4308 .alg = "xts(aes)", 4500 .alg = "xts(aes)",
4501 .generic_driver = "xts(ecb(aes-generic))",
4309 .test = alg_test_skcipher, 4502 .test = alg_test_skcipher,
4310 .fips_allowed = 1, 4503 .fips_allowed = 1,
4311 .suite = { 4504 .suite = {
@@ -4313,12 +4506,14 @@ static const struct alg_test_desc alg_test_descs[] = {
4313 } 4506 }
4314 }, { 4507 }, {
4315 .alg = "xts(camellia)", 4508 .alg = "xts(camellia)",
4509 .generic_driver = "xts(ecb(camellia-generic))",
4316 .test = alg_test_skcipher, 4510 .test = alg_test_skcipher,
4317 .suite = { 4511 .suite = {
4318 .cipher = __VECS(camellia_xts_tv_template) 4512 .cipher = __VECS(camellia_xts_tv_template)
4319 } 4513 }
4320 }, { 4514 }, {
4321 .alg = "xts(cast6)", 4515 .alg = "xts(cast6)",
4516 .generic_driver = "xts(ecb(cast6-generic))",
4322 .test = alg_test_skcipher, 4517 .test = alg_test_skcipher,
4323 .suite = { 4518 .suite = {
4324 .cipher = __VECS(cast6_xts_tv_template) 4519 .cipher = __VECS(cast6_xts_tv_template)
@@ -4332,12 +4527,14 @@ static const struct alg_test_desc alg_test_descs[] = {
4332 .fips_allowed = 1, 4527 .fips_allowed = 1,
4333 }, { 4528 }, {
4334 .alg = "xts(serpent)", 4529 .alg = "xts(serpent)",
4530 .generic_driver = "xts(ecb(serpent-generic))",
4335 .test = alg_test_skcipher, 4531 .test = alg_test_skcipher,
4336 .suite = { 4532 .suite = {
4337 .cipher = __VECS(serpent_xts_tv_template) 4533 .cipher = __VECS(serpent_xts_tv_template)
4338 } 4534 }
4339 }, { 4535 }, {
4340 .alg = "xts(twofish)", 4536 .alg = "xts(twofish)",
4537 .generic_driver = "xts(ecb(twofish-generic))",
4341 .test = alg_test_skcipher, 4538 .test = alg_test_skcipher,
4342 .suite = { 4539 .suite = {
4343 .cipher = __VECS(tf_xts_tv_template) 4540 .cipher = __VECS(tf_xts_tv_template)