Skip to content

Commit 18c438b

Browse files
committed
crypto: testmgr - Add hash export format testing
Ensure that the hash state can be exported to and imported from the generic algorithm. Signed-off-by: Herbert Xu <[email protected]>
1 parent c2a8135 commit 18c438b

File tree

3 files changed

+94
-9
lines changed

3 files changed

+94
-9
lines changed

crypto/testmgr.c

Lines changed: 86 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,26 @@
1717
*/
1818

1919
#include <crypto/aead.h>
20-
#include <crypto/hash.h>
20+
#include <crypto/acompress.h>
21+
#include <crypto/akcipher.h>
22+
#include <crypto/drbg.h>
23+
#include <crypto/internal/cipher.h>
24+
#include <crypto/internal/hash.h>
25+
#include <crypto/internal/simd.h>
26+
#include <crypto/kpp.h>
27+
#include <crypto/rng.h>
28+
#include <crypto/sig.h>
2129
#include <crypto/skcipher.h>
2230
#include <linux/err.h>
2331
#include <linux/fips.h>
32+
#include <linux/kernel.h>
2433
#include <linux/module.h>
2534
#include <linux/once.h>
2635
#include <linux/prandom.h>
2736
#include <linux/scatterlist.h>
2837
#include <linux/slab.h>
2938
#include <linux/string.h>
3039
#include <linux/uio.h>
31-
#include <crypto/rng.h>
32-
#include <crypto/drbg.h>
33-
#include <crypto/akcipher.h>
34-
#include <crypto/kpp.h>
35-
#include <crypto/acompress.h>
36-
#include <crypto/sig.h>
37-
#include <crypto/internal/cipher.h>
38-
#include <crypto/internal/simd.h>
3940

4041
#include "internal.h"
4142

@@ -1464,6 +1465,49 @@ static int check_nonfinal_ahash_op(const char *op, int err,
14641465
return 0;
14651466
}
14661467

1468+
static int check_ahash_export(struct ahash_request *req,
1469+
const struct hash_testvec *vec,
1470+
const char *vec_name,
1471+
const struct testvec_config *cfg,
1472+
const char *driver, u8 *hashstate)
1473+
{
1474+
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
1475+
const unsigned int digestsize = crypto_ahash_digestsize(tfm);
1476+
HASH_FBREQ_ON_STACK(fbreq, req);
1477+
int err;
1478+
1479+
if (!vec->state)
1480+
return 0;
1481+
1482+
err = crypto_ahash_export(req, hashstate);
1483+
if (err) {
1484+
pr_err("alg: ahash: %s mixed export() failed with err %d on test vector %s, cfg=\"%s\"\n",
1485+
driver, err, vec_name, cfg->name);
1486+
return err;
1487+
}
1488+
err = crypto_ahash_import(req, vec->state);
1489+
if (err) {
1490+
pr_err("alg: ahash: %s mixed import() failed with err %d on test vector %s, cfg=\"%s\"\n",
1491+
driver, err, vec_name, cfg->name);
1492+
return err;
1493+
}
1494+
err = crypto_ahash_import(fbreq, hashstate);
1495+
if (err) {
1496+
pr_err("alg: ahash: %s fallback import() failed with err %d on test vector %s, cfg=\"%s\"\n",
1497+
crypto_ahash_driver_name(crypto_ahash_reqtfm(fbreq)), err, vec_name, cfg->name);
1498+
return err;
1499+
}
1500+
ahash_request_set_crypt(fbreq, NULL, hashstate, 0);
1501+
testmgr_poison(hashstate, digestsize + TESTMGR_POISON_LEN);
1502+
err = crypto_ahash_final(fbreq);
1503+
if (err) {
1504+
pr_err("alg: ahash: %s fallback final() failed with err %d on test vector %s, cfg=\"%s\"\n",
1505+
crypto_ahash_driver_name(crypto_ahash_reqtfm(fbreq)), err, vec_name, cfg->name);
1506+
return err;
1507+
}
1508+
return check_hash_result("ahash export", hashstate, digestsize, vec, vec_name, driver, cfg);
1509+
}
1510+
14671511
/* Test one hash test vector in one configuration, using the ahash API */
14681512
static int test_ahash_vec_cfg(const struct hash_testvec *vec,
14691513
const char *vec_name,
@@ -1609,6 +1653,10 @@ static int test_ahash_vec_cfg(const struct hash_testvec *vec,
16091653
driver, vec_name, cfg);
16101654
if (err)
16111655
return err;
1656+
err = check_ahash_export(req, vec, vec_name, cfg,
1657+
driver, hashstate);
1658+
if (err)
1659+
return err;
16121660
err = do_ahash_op(crypto_ahash_final, req, &wait, cfg->nosimd);
16131661
if (err) {
16141662
pr_err("alg: ahash: %s final() failed with err %d on test vector %s, cfg=\"%s\"\n",
@@ -1732,6 +1780,17 @@ static void generate_random_hash_testvec(struct rnd_state *rng,
17321780
vec->digest_error = crypto_hash_digest(
17331781
crypto_ahash_reqtfm(req), vec->plaintext,
17341782
vec->psize, (u8 *)vec->digest);
1783+
1784+
if (vec->digest_error || !vec->state)
1785+
goto done;
1786+
1787+
ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
1788+
ahash_request_set_virt(req, vec->plaintext, (u8 *)vec->digest,
1789+
vec->psize);
1790+
crypto_ahash_init(req);
1791+
crypto_ahash_update(req);
1792+
crypto_ahash_export(req, (u8 *)vec->state);
1793+
17351794
done:
17361795
snprintf(name, max_namelen, "\"random: psize=%u ksize=%u\"",
17371796
vec->psize, vec->ksize);
@@ -1750,6 +1809,7 @@ static int test_hash_vs_generic_impl(const char *generic_driver,
17501809
{
17511810
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
17521811
const unsigned int digestsize = crypto_ahash_digestsize(tfm);
1812+
const unsigned int statesize = crypto_ahash_statesize(tfm);
17531813
const unsigned int blocksize = crypto_ahash_blocksize(tfm);
17541814
const unsigned int maxdatasize = (2 * PAGE_SIZE) - TESTMGR_POISON_LEN;
17551815
const char *algname = crypto_hash_alg_common(tfm)->base.cra_name;
@@ -1822,6 +1882,22 @@ static int test_hash_vs_generic_impl(const char *generic_driver,
18221882
goto out;
18231883
}
18241884

1885+
if (crypto_hash_no_export_core(tfm) ||
1886+
crypto_hash_no_export_core(generic_tfm))
1887+
;
1888+
else if (statesize != crypto_ahash_statesize(generic_tfm)) {
1889+
pr_err("alg: hash: statesize for %s (%u) doesn't match generic impl (%u)\n",
1890+
driver, statesize,
1891+
crypto_ahash_statesize(generic_tfm));
1892+
err = -EINVAL;
1893+
goto out;
1894+
} else {
1895+
vec.state = kmalloc(statesize, GFP_KERNEL);
1896+
err = -ENOMEM;
1897+
if (!vec.state)
1898+
goto out;
1899+
}
1900+
18251901
/*
18261902
* Now generate test vectors using the generic implementation, and test
18271903
* the other implementation against them.
@@ -1854,6 +1930,7 @@ static int test_hash_vs_generic_impl(const char *generic_driver,
18541930
kfree(vec.key);
18551931
kfree(vec.plaintext);
18561932
kfree(vec.digest);
1933+
kfree(vec.state);
18571934
ahash_request_free(generic_req);
18581935
crypto_free_ahash(generic_tfm);
18591936
return err;

crypto/testmgr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
* hash_testvec: structure to describe a hash (message digest) test
3030
* @key: Pointer to key (NULL if none)
3131
* @plaintext: Pointer to source data
32+
* @state: Pointer to expected state
3233
* @digest: Pointer to expected digest
3334
* @psize: Length of source data in bytes
3435
* @ksize: Length of @key in bytes (0 if no key)
@@ -39,6 +40,7 @@
3940
struct hash_testvec {
4041
const char *key;
4142
const char *plaintext;
43+
const char *state;
4244
const char *digest;
4345
unsigned int psize;
4446
unsigned short ksize;

include/crypto/internal/hash.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ static inline bool crypto_hash_alg_needs_key(struct hash_alg_common *alg)
9191
!(alg->base.cra_flags & CRYPTO_ALG_OPTIONAL_KEY);
9292
}
9393

94+
static inline bool crypto_hash_no_export_core(struct crypto_ahash *tfm)
95+
{
96+
return crypto_hash_alg_common(tfm)->base.cra_flags &
97+
CRYPTO_AHASH_ALG_NO_EXPORT_CORE;
98+
}
99+
94100
int crypto_grab_ahash(struct crypto_ahash_spawn *spawn,
95101
struct crypto_instance *inst,
96102
const char *name, u32 type, u32 mask);

0 commit comments

Comments
 (0)