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 */
14681512static 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+
17351794done :
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 ;
0 commit comments