17
17
*/
18
18
19
19
#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>
21
29
#include <crypto/skcipher.h>
22
30
#include <linux/err.h>
23
31
#include <linux/fips.h>
32
+ #include <linux/kernel.h>
24
33
#include <linux/module.h>
25
34
#include <linux/once.h>
26
35
#include <linux/prandom.h>
27
36
#include <linux/scatterlist.h>
28
37
#include <linux/slab.h>
29
38
#include <linux/string.h>
30
39
#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>
39
40
40
41
#include "internal.h"
41
42
@@ -1464,6 +1465,49 @@ static int check_nonfinal_ahash_op(const char *op, int err,
1464
1465
return 0 ;
1465
1466
}
1466
1467
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
+
1467
1511
/* Test one hash test vector in one configuration, using the ahash API */
1468
1512
static int test_ahash_vec_cfg (const struct hash_testvec * vec ,
1469
1513
const char * vec_name ,
@@ -1609,6 +1653,10 @@ static int test_ahash_vec_cfg(const struct hash_testvec *vec,
1609
1653
driver , vec_name , cfg );
1610
1654
if (err )
1611
1655
return err ;
1656
+ err = check_ahash_export (req , vec , vec_name , cfg ,
1657
+ driver , hashstate );
1658
+ if (err )
1659
+ return err ;
1612
1660
err = do_ahash_op (crypto_ahash_final , req , & wait , cfg -> nosimd );
1613
1661
if (err ) {
1614
1662
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,
1732
1780
vec -> digest_error = crypto_hash_digest (
1733
1781
crypto_ahash_reqtfm (req ), vec -> plaintext ,
1734
1782
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
+
1735
1794
done :
1736
1795
snprintf (name , max_namelen , "\"random: psize=%u ksize=%u\"" ,
1737
1796
vec -> psize , vec -> ksize );
@@ -1750,6 +1809,7 @@ static int test_hash_vs_generic_impl(const char *generic_driver,
1750
1809
{
1751
1810
struct crypto_ahash * tfm = crypto_ahash_reqtfm (req );
1752
1811
const unsigned int digestsize = crypto_ahash_digestsize (tfm );
1812
+ const unsigned int statesize = crypto_ahash_statesize (tfm );
1753
1813
const unsigned int blocksize = crypto_ahash_blocksize (tfm );
1754
1814
const unsigned int maxdatasize = (2 * PAGE_SIZE ) - TESTMGR_POISON_LEN ;
1755
1815
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,
1822
1882
goto out ;
1823
1883
}
1824
1884
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
+
1825
1901
/*
1826
1902
* Now generate test vectors using the generic implementation, and test
1827
1903
* the other implementation against them.
@@ -1854,6 +1930,7 @@ static int test_hash_vs_generic_impl(const char *generic_driver,
1854
1930
kfree (vec .key );
1855
1931
kfree (vec .plaintext );
1856
1932
kfree (vec .digest );
1933
+ kfree (vec .state );
1857
1934
ahash_request_free (generic_req );
1858
1935
crypto_free_ahash (generic_tfm );
1859
1936
return err ;
0 commit comments