@@ -58,6 +58,9 @@ module_param(fuzz_iterations, uint, 0644);
5858MODULE_PARM_DESC (fuzz_iterations , "number of fuzz test iterations" );
5959#endif
6060
61+ /* Multibuffer is unlimited. Set arbitrary limit for testing. */
62+ #define MAX_MB_MSGS 16
63+
6164#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
6265
6366/* a perfect nop */
@@ -299,6 +302,13 @@ struct test_sg_division {
299302 * @key_offset_relative_to_alignmask: if true, add the algorithm's alignmask to
300303 * the @key_offset
301304 * @finalization_type: what finalization function to use for hashes
305+ * @multibuffer: test with multibuffer
306+ * @multibuffer_index: random number used to generate the message index to use
307+ * for multibuffer.
308+ * @multibuffer_uneven: test with multibuffer using uneven lengths
309+ * @multibuffer_lens: random lengths to make chained request uneven
310+ * @multibuffer_count: random number used to generate the num_msgs parameter
311+ * for multibuffer
302312 * @nosimd: execute with SIMD disabled? Requires !CRYPTO_TFM_REQ_MAY_SLEEP.
303313 * This applies to the parts of the operation that aren't controlled
304314 * individually by @nosimd_setkey or @src_divs[].nosimd.
@@ -318,6 +328,11 @@ struct testvec_config {
318328 enum finalization_type finalization_type ;
319329 bool nosimd ;
320330 bool nosimd_setkey ;
331+ bool multibuffer ;
332+ unsigned int multibuffer_index ;
333+ unsigned int multibuffer_count ;
334+ bool multibuffer_uneven ;
335+ unsigned int multibuffer_lens [MAX_MB_MSGS ];
321336};
322337
323338#define TESTVEC_CONFIG_NAMELEN 192
@@ -557,6 +572,7 @@ struct test_sglist {
557572 char * bufs [XBUFSIZE ];
558573 struct scatterlist sgl [XBUFSIZE ];
559574 struct scatterlist sgl_saved [XBUFSIZE ];
575+ struct scatterlist full_sgl [XBUFSIZE ];
560576 struct scatterlist * sgl_ptr ;
561577 unsigned int nents ;
562578};
@@ -670,6 +686,11 @@ static int build_test_sglist(struct test_sglist *tsgl,
670686 sg_mark_end (& tsgl -> sgl [tsgl -> nents - 1 ]);
671687 tsgl -> sgl_ptr = tsgl -> sgl ;
672688 memcpy (tsgl -> sgl_saved , tsgl -> sgl , tsgl -> nents * sizeof (tsgl -> sgl [0 ]));
689+
690+ sg_init_table (tsgl -> full_sgl , XBUFSIZE );
691+ for (i = 0 ; i < XBUFSIZE ; i ++ )
692+ sg_set_buf (tsgl -> full_sgl , tsgl -> bufs [i ], PAGE_SIZE * 2 );
693+
673694 return 0 ;
674695}
675696
@@ -1146,6 +1167,27 @@ static void generate_random_testvec_config(struct rnd_state *rng,
11461167 break ;
11471168 }
11481169
1170+ if (prandom_bool (rng )) {
1171+ int i ;
1172+
1173+ cfg -> multibuffer = true;
1174+ cfg -> multibuffer_count = prandom_u32_state (rng );
1175+ cfg -> multibuffer_count %= MAX_MB_MSGS ;
1176+ if (cfg -> multibuffer_count ++ ) {
1177+ cfg -> multibuffer_index = prandom_u32_state (rng );
1178+ cfg -> multibuffer_index %= cfg -> multibuffer_count ;
1179+ }
1180+
1181+ cfg -> multibuffer_uneven = prandom_bool (rng );
1182+ for (i = 0 ; i < MAX_MB_MSGS ; i ++ )
1183+ cfg -> multibuffer_lens [i ] =
1184+ generate_random_length (rng , PAGE_SIZE * 2 * XBUFSIZE );
1185+
1186+ p += scnprintf (p , end - p , " multibuffer(%d/%d%s)" ,
1187+ cfg -> multibuffer_index , cfg -> multibuffer_count ,
1188+ cfg -> multibuffer_uneven ? "/uneven" : "" );
1189+ }
1190+
11491191 if (!(cfg -> req_flags & CRYPTO_TFM_REQ_MAY_SLEEP )) {
11501192 if (prandom_bool (rng )) {
11511193 cfg -> nosimd = true;
@@ -1450,6 +1492,7 @@ static int do_ahash_op(int (*op)(struct ahash_request *req),
14501492 struct ahash_request * req ,
14511493 struct crypto_wait * wait , bool nosimd )
14521494{
1495+ struct ahash_request * r2 ;
14531496 int err ;
14541497
14551498 if (nosimd )
@@ -1460,7 +1503,15 @@ static int do_ahash_op(int (*op)(struct ahash_request *req),
14601503 if (nosimd )
14611504 crypto_reenable_simd_for_test ();
14621505
1463- return crypto_wait_req (err , wait );
1506+ err = crypto_wait_req (err , wait );
1507+ if (err )
1508+ return err ;
1509+
1510+ list_for_each_entry (r2 , & req -> base .list , base .list )
1511+ if (r2 -> base .err )
1512+ return r2 -> base .err ;
1513+
1514+ return 0 ;
14641515}
14651516
14661517static int check_nonfinal_ahash_op (const char * op , int err ,
@@ -1481,27 +1532,75 @@ static int check_nonfinal_ahash_op(const char *op, int err,
14811532 return 0 ;
14821533}
14831534
1535+ static void setup_ahash_multibuffer (
1536+ struct ahash_request * reqs [MAX_MB_MSGS ],
1537+ const struct testvec_config * cfg ,
1538+ struct test_sglist * tsgl )
1539+ {
1540+ struct scatterlist * sg = tsgl -> full_sgl ;
1541+ static u8 trash [HASH_MAX_DIGESTSIZE ];
1542+ struct ahash_request * req = reqs [0 ];
1543+ unsigned int num_msgs ;
1544+ unsigned int msg_idx ;
1545+ int i ;
1546+
1547+ if (!cfg -> multibuffer )
1548+ return ;
1549+
1550+ num_msgs = cfg -> multibuffer_count ;
1551+ if (num_msgs == 1 )
1552+ return ;
1553+
1554+ msg_idx = cfg -> multibuffer_index ;
1555+ for (i = 1 ; i < num_msgs ; i ++ ) {
1556+ struct ahash_request * r2 = reqs [i ];
1557+ unsigned int nbytes = req -> nbytes ;
1558+
1559+ if (cfg -> multibuffer_uneven )
1560+ nbytes = cfg -> multibuffer_lens [i ];
1561+
1562+ ahash_request_set_callback (r2 , req -> base .flags , NULL , NULL );
1563+ ahash_request_set_crypt (r2 , sg , trash , nbytes );
1564+ ahash_request_chain (r2 , req );
1565+ }
1566+
1567+ if (msg_idx ) {
1568+ reqs [msg_idx ]-> src = req -> src ;
1569+ reqs [msg_idx ]-> nbytes = req -> nbytes ;
1570+ reqs [msg_idx ]-> result = req -> result ;
1571+ req -> src = sg ;
1572+ if (cfg -> multibuffer_uneven )
1573+ req -> nbytes = cfg -> multibuffer_lens [0 ];
1574+ req -> result = trash ;
1575+ }
1576+ }
1577+
14841578/* Test one hash test vector in one configuration, using the ahash API */
14851579static int test_ahash_vec_cfg (const struct hash_testvec * vec ,
14861580 const char * vec_name ,
14871581 const struct testvec_config * cfg ,
1488- struct ahash_request * req ,
1582+ struct ahash_request * reqs [ MAX_MB_MSGS ] ,
14891583 struct test_sglist * tsgl ,
14901584 u8 * hashstate )
14911585{
1586+ struct ahash_request * req = reqs [0 ];
14921587 struct crypto_ahash * tfm = crypto_ahash_reqtfm (req );
14931588 const unsigned int digestsize = crypto_ahash_digestsize (tfm );
14941589 const unsigned int statesize = crypto_ahash_statesize (tfm );
14951590 const char * driver = crypto_ahash_driver_name (tfm );
14961591 const u32 req_flags = CRYPTO_TFM_REQ_MAY_BACKLOG | cfg -> req_flags ;
14971592 const struct test_sg_division * divs [XBUFSIZE ];
1593+ struct ahash_request * reqi = req ;
14981594 DECLARE_CRYPTO_WAIT (wait );
14991595 unsigned int i ;
15001596 struct scatterlist * pending_sgl ;
15011597 unsigned int pending_len ;
15021598 u8 result [HASH_MAX_DIGESTSIZE + TESTMGR_POISON_LEN ];
15031599 int err ;
15041600
1601+ if (cfg -> multibuffer )
1602+ reqi = reqs [cfg -> multibuffer_index ];
1603+
15051604 /* Set the key, if specified */
15061605 if (vec -> ksize ) {
15071606 err = do_setkey (crypto_ahash_setkey , tfm , vec -> key , vec -> ksize ,
@@ -1531,7 +1630,7 @@ static int test_ahash_vec_cfg(const struct hash_testvec *vec,
15311630
15321631 /* Do the actual hashing */
15331632
1534- testmgr_poison (req -> __ctx , crypto_ahash_reqsize (tfm ));
1633+ testmgr_poison (reqi -> __ctx , crypto_ahash_reqsize (tfm ));
15351634 testmgr_poison (result , digestsize + TESTMGR_POISON_LEN );
15361635
15371636 if (cfg -> finalization_type == FINALIZATION_TYPE_DIGEST ||
@@ -1540,6 +1639,7 @@ static int test_ahash_vec_cfg(const struct hash_testvec *vec,
15401639 ahash_request_set_callback (req , req_flags , crypto_req_done ,
15411640 & wait );
15421641 ahash_request_set_crypt (req , tsgl -> sgl , result , vec -> psize );
1642+ setup_ahash_multibuffer (reqs , cfg , tsgl );
15431643 err = do_ahash_op (crypto_ahash_digest , req , & wait , cfg -> nosimd );
15441644 if (err ) {
15451645 if (err == vec -> digest_error )
@@ -1561,6 +1661,7 @@ static int test_ahash_vec_cfg(const struct hash_testvec *vec,
15611661
15621662 ahash_request_set_callback (req , req_flags , crypto_req_done , & wait );
15631663 ahash_request_set_crypt (req , NULL , result , 0 );
1664+ setup_ahash_multibuffer (reqs , cfg , tsgl );
15641665 err = do_ahash_op (crypto_ahash_init , req , & wait , cfg -> nosimd );
15651666 err = check_nonfinal_ahash_op ("init" , err , result , digestsize ,
15661667 driver , vec_name , cfg );
@@ -1577,6 +1678,7 @@ static int test_ahash_vec_cfg(const struct hash_testvec *vec,
15771678 crypto_req_done , & wait );
15781679 ahash_request_set_crypt (req , pending_sgl , result ,
15791680 pending_len );
1681+ setup_ahash_multibuffer (reqs , cfg , tsgl );
15801682 err = do_ahash_op (crypto_ahash_update , req , & wait ,
15811683 divs [i ]-> nosimd );
15821684 err = check_nonfinal_ahash_op ("update" , err ,
@@ -1591,7 +1693,7 @@ static int test_ahash_vec_cfg(const struct hash_testvec *vec,
15911693 /* Test ->export() and ->import() */
15921694 testmgr_poison (hashstate + statesize ,
15931695 TESTMGR_POISON_LEN );
1594- err = crypto_ahash_export (req , hashstate );
1696+ err = crypto_ahash_export (reqi , hashstate );
15951697 err = check_nonfinal_ahash_op ("export" , err ,
15961698 result , digestsize ,
15971699 driver , vec_name , cfg );
@@ -1604,8 +1706,8 @@ static int test_ahash_vec_cfg(const struct hash_testvec *vec,
16041706 return - EOVERFLOW ;
16051707 }
16061708
1607- testmgr_poison (req -> __ctx , crypto_ahash_reqsize (tfm ));
1608- err = crypto_ahash_import (req , hashstate );
1709+ testmgr_poison (reqi -> __ctx , crypto_ahash_reqsize (tfm ));
1710+ err = crypto_ahash_import (reqi , hashstate );
16091711 err = check_nonfinal_ahash_op ("import" , err ,
16101712 result , digestsize ,
16111713 driver , vec_name , cfg );
@@ -1619,6 +1721,7 @@ static int test_ahash_vec_cfg(const struct hash_testvec *vec,
16191721
16201722 ahash_request_set_callback (req , req_flags , crypto_req_done , & wait );
16211723 ahash_request_set_crypt (req , pending_sgl , result , pending_len );
1724+ setup_ahash_multibuffer (reqs , cfg , tsgl );
16221725 if (cfg -> finalization_type == FINALIZATION_TYPE_FINAL ) {
16231726 /* finish with update() and final() */
16241727 err = do_ahash_op (crypto_ahash_update , req , & wait , cfg -> nosimd );
@@ -1650,7 +1753,7 @@ static int test_ahash_vec_cfg(const struct hash_testvec *vec,
16501753static int test_hash_vec_cfg (const struct hash_testvec * vec ,
16511754 const char * vec_name ,
16521755 const struct testvec_config * cfg ,
1653- struct ahash_request * req ,
1756+ struct ahash_request * reqs [ MAX_MB_MSGS ] ,
16541757 struct shash_desc * desc ,
16551758 struct test_sglist * tsgl ,
16561759 u8 * hashstate )
@@ -1670,11 +1773,12 @@ static int test_hash_vec_cfg(const struct hash_testvec *vec,
16701773 return err ;
16711774 }
16721775
1673- return test_ahash_vec_cfg (vec , vec_name , cfg , req , tsgl , hashstate );
1776+ return test_ahash_vec_cfg (vec , vec_name , cfg , reqs , tsgl , hashstate );
16741777}
16751778
16761779static int test_hash_vec (const struct hash_testvec * vec , unsigned int vec_num ,
1677- struct ahash_request * req , struct shash_desc * desc ,
1780+ struct ahash_request * reqs [MAX_MB_MSGS ],
1781+ struct shash_desc * desc ,
16781782 struct test_sglist * tsgl , u8 * hashstate )
16791783{
16801784 char vec_name [16 ];
@@ -1686,7 +1790,7 @@ static int test_hash_vec(const struct hash_testvec *vec, unsigned int vec_num,
16861790 for (i = 0 ; i < ARRAY_SIZE (default_hash_testvec_configs ); i ++ ) {
16871791 err = test_hash_vec_cfg (vec , vec_name ,
16881792 & default_hash_testvec_configs [i ],
1689- req , desc , tsgl , hashstate );
1793+ reqs , desc , tsgl , hashstate );
16901794 if (err )
16911795 return err ;
16921796 }
@@ -1703,7 +1807,7 @@ static int test_hash_vec(const struct hash_testvec *vec, unsigned int vec_num,
17031807 generate_random_testvec_config (& rng , & cfg , cfgname ,
17041808 sizeof (cfgname ));
17051809 err = test_hash_vec_cfg (vec , vec_name , & cfg ,
1706- req , desc , tsgl , hashstate );
1810+ reqs , desc , tsgl , hashstate );
17071811 if (err )
17081812 return err ;
17091813 cond_resched ();
@@ -1762,11 +1866,12 @@ static void generate_random_hash_testvec(struct rnd_state *rng,
17621866 */
17631867static int test_hash_vs_generic_impl (const char * generic_driver ,
17641868 unsigned int maxkeysize ,
1765- struct ahash_request * req ,
1869+ struct ahash_request * reqs [ MAX_MB_MSGS ] ,
17661870 struct shash_desc * desc ,
17671871 struct test_sglist * tsgl ,
17681872 u8 * hashstate )
17691873{
1874+ struct ahash_request * req = reqs [0 ];
17701875 struct crypto_ahash * tfm = crypto_ahash_reqtfm (req );
17711876 const unsigned int digestsize = crypto_ahash_digestsize (tfm );
17721877 const unsigned int blocksize = crypto_ahash_blocksize (tfm );
@@ -1864,7 +1969,7 @@ static int test_hash_vs_generic_impl(const char *generic_driver,
18641969 sizeof (cfgname ));
18651970
18661971 err = test_hash_vec_cfg (& vec , vec_name , cfg ,
1867- req , desc , tsgl , hashstate );
1972+ reqs , desc , tsgl , hashstate );
18681973 if (err )
18691974 goto out ;
18701975 cond_resched ();
@@ -1882,7 +1987,7 @@ static int test_hash_vs_generic_impl(const char *generic_driver,
18821987#else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
18831988static int test_hash_vs_generic_impl (const char * generic_driver ,
18841989 unsigned int maxkeysize ,
1885- struct ahash_request * req ,
1990+ struct ahash_request * reqs [ MAX_MB_MSGS ] ,
18861991 struct shash_desc * desc ,
18871992 struct test_sglist * tsgl ,
18881993 u8 * hashstate )
@@ -1929,8 +2034,8 @@ static int __alg_test_hash(const struct hash_testvec *vecs,
19292034 u32 type , u32 mask ,
19302035 const char * generic_driver , unsigned int maxkeysize )
19312036{
2037+ struct ahash_request * reqs [MAX_MB_MSGS ] = {};
19322038 struct crypto_ahash * atfm = NULL ;
1933- struct ahash_request * req = NULL ;
19342039 struct crypto_shash * stfm = NULL ;
19352040 struct shash_desc * desc = NULL ;
19362041 struct test_sglist * tsgl = NULL ;
@@ -1954,12 +2059,14 @@ static int __alg_test_hash(const struct hash_testvec *vecs,
19542059 }
19552060 driver = crypto_ahash_driver_name (atfm );
19562061
1957- req = ahash_request_alloc (atfm , GFP_KERNEL );
1958- if (!req ) {
1959- pr_err ("alg: hash: failed to allocate request for %s\n" ,
1960- driver );
1961- err = - ENOMEM ;
1962- goto out ;
2062+ for (i = 0 ; i < MAX_MB_MSGS ; i ++ ) {
2063+ reqs [i ] = ahash_request_alloc (atfm , GFP_KERNEL );
2064+ if (!reqs [i ]) {
2065+ pr_err ("alg: hash: failed to allocate request for %s\n" ,
2066+ driver );
2067+ err = - ENOMEM ;
2068+ goto out ;
2069+ }
19632070 }
19642071
19652072 /*
@@ -1995,12 +2102,12 @@ static int __alg_test_hash(const struct hash_testvec *vecs,
19952102 if (fips_enabled && vecs [i ].fips_skip )
19962103 continue ;
19972104
1998- err = test_hash_vec (& vecs [i ], i , req , desc , tsgl , hashstate );
2105+ err = test_hash_vec (& vecs [i ], i , reqs , desc , tsgl , hashstate );
19992106 if (err )
20002107 goto out ;
20012108 cond_resched ();
20022109 }
2003- err = test_hash_vs_generic_impl (generic_driver , maxkeysize , req ,
2110+ err = test_hash_vs_generic_impl (generic_driver , maxkeysize , reqs ,
20042111 desc , tsgl , hashstate );
20052112out :
20062113 kfree (hashstate );
@@ -2010,7 +2117,12 @@ static int __alg_test_hash(const struct hash_testvec *vecs,
20102117 }
20112118 kfree (desc );
20122119 crypto_free_shash (stfm );
2013- ahash_request_free (req );
2120+ if (reqs [0 ]) {
2121+ ahash_request_set_callback (reqs [0 ], 0 , NULL , NULL );
2122+ for (i = 1 ; i < MAX_MB_MSGS && reqs [i ]; i ++ )
2123+ ahash_request_chain (reqs [i ], reqs [0 ]);
2124+ ahash_request_free (reqs [0 ]);
2125+ }
20142126 crypto_free_ahash (atfm );
20152127 return err ;
20162128}
0 commit comments